1 /* Display generation from window structure and buffer text.
3 Copyright (C) 1985-1988, 1993-1995, 1997-2013 Free Software Foundation,
6 This file is part of GNU Emacs.
8 GNU Emacs is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
13 GNU Emacs is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
21 /* New redisplay written by Gerd Moellmann <gerd@gnu.org>.
25 Emacs separates the task of updating the display from code
26 modifying global state, e.g. buffer text. This way functions
27 operating on buffers don't also have to be concerned with updating
30 Updating the display is triggered by the Lisp interpreter when it
31 decides it's time to do it. This is done either automatically for
32 you as part of the interpreter's command loop or as the result of
33 calling Lisp functions like `sit-for'. The C function `redisplay'
34 in xdisp.c is the only entry into the inner redisplay code.
36 The following diagram shows how redisplay code is invoked. As you
37 can see, Lisp calls redisplay and vice versa. Under window systems
38 like X, some portions of the redisplay code are also called
39 asynchronously during mouse movement or expose events. It is very
40 important that these code parts do NOT use the C library (malloc,
41 free) because many C libraries under Unix are not reentrant. They
42 may also NOT call functions of the Lisp interpreter which could
43 change the interpreter's state. If you don't follow these rules,
44 you will encounter bugs which are very hard to explain.
46 +--------------+ redisplay +----------------+
47 | Lisp machine |---------------->| Redisplay code |<--+
48 +--------------+ (xdisp.c) +----------------+ |
50 +----------------------------------+ |
51 Don't use this path when called |
54 expose_window (asynchronous) |
56 X expose events -----+
58 What does redisplay do? Obviously, it has to figure out somehow what
59 has been changed since the last time the display has been updated,
60 and to make these changes visible. Preferably it would do that in
61 a moderately intelligent way, i.e. fast.
63 Changes in buffer text can be deduced from window and buffer
64 structures, and from some global variables like `beg_unchanged' and
65 `end_unchanged'. The contents of the display are additionally
66 recorded in a `glyph matrix', a two-dimensional matrix of glyph
67 structures. Each row in such a matrix corresponds to a line on the
68 display, and each glyph in a row corresponds to a column displaying
69 a character, an image, or what else. This matrix is called the
70 `current glyph matrix' or `current matrix' in redisplay
73 For buffer parts that have been changed since the last update, a
74 second glyph matrix is constructed, the so called `desired glyph
75 matrix' or short `desired matrix'. Current and desired matrix are
76 then compared to find a cheap way to update the display, e.g. by
77 reusing part of the display by scrolling lines.
79 You will find a lot of redisplay optimizations when you start
80 looking at the innards of redisplay. The overall goal of all these
81 optimizations is to make redisplay fast because it is done
82 frequently. Some of these optimizations are implemented by the
87 This function tries to update the display if the text in the
88 window did not change and did not scroll, only point moved, and
89 it did not move off the displayed portion of the text.
91 . try_window_reusing_current_matrix
93 This function reuses the current matrix of a window when text
94 has not changed, but the window start changed (e.g., due to
99 This function attempts to redisplay a window by reusing parts of
100 its existing display. It finds and reuses the part that was not
101 changed, and redraws the rest.
105 This function performs the full redisplay of a single window
106 assuming that its fonts were not changed and that the cursor
107 will not end up in the scroll margins. (Loading fonts requires
108 re-adjustment of dimensions of glyph matrices, which makes this
109 method impossible to use.)
111 These optimizations are tried in sequence (some can be skipped if
112 it is known that they are not applicable). If none of the
113 optimizations were successful, redisplay calls redisplay_windows,
114 which performs a full redisplay of all windows.
118 Desired matrices are always built per Emacs window. The function
119 `display_line' is the central function to look at if you are
120 interested. It constructs one row in a desired matrix given an
121 iterator structure containing both a buffer position and a
122 description of the environment in which the text is to be
123 displayed. But this is too early, read on.
125 Characters and pixmaps displayed for a range of buffer text depend
126 on various settings of buffers and windows, on overlays and text
127 properties, on display tables, on selective display. The good news
128 is that all this hairy stuff is hidden behind a small set of
129 interface functions taking an iterator structure (struct it)
132 Iteration over things to be displayed is then simple. It is
133 started by initializing an iterator with a call to init_iterator,
134 passing it the buffer position where to start iteration. For
135 iteration over strings, pass -1 as the position to init_iterator,
136 and call reseat_to_string when the string is ready, to initialize
137 the iterator for that string. Thereafter, calls to
138 get_next_display_element fill the iterator structure with relevant
139 information about the next thing to display. Calls to
140 set_iterator_to_next move the iterator to the next thing.
142 Besides this, an iterator also contains information about the
143 display environment in which glyphs for display elements are to be
144 produced. It has fields for the width and height of the display,
145 the information whether long lines are truncated or continued, a
146 current X and Y position, and lots of other stuff you can better
149 Glyphs in a desired matrix are normally constructed in a loop
150 calling get_next_display_element and then PRODUCE_GLYPHS. The call
151 to PRODUCE_GLYPHS will fill the iterator structure with pixel
152 information about the element being displayed and at the same time
153 produce glyphs for it. If the display element fits on the line
154 being displayed, set_iterator_to_next is called next, otherwise the
155 glyphs produced are discarded. The function display_line is the
156 workhorse of filling glyph rows in the desired matrix with glyphs.
157 In addition to producing glyphs, it also handles line truncation
158 and continuation, word wrap, and cursor positioning (for the
159 latter, see also set_cursor_from_row).
163 That just couldn't be all, could it? What about terminal types not
164 supporting operations on sub-windows of the screen? To update the
165 display on such a terminal, window-based glyph matrices are not
166 well suited. To be able to reuse part of the display (scrolling
167 lines up and down), we must instead have a view of the whole
168 screen. This is what `frame matrices' are for. They are a trick.
170 Frames on terminals like above have a glyph pool. Windows on such
171 a frame sub-allocate their glyph memory from their frame's glyph
172 pool. The frame itself is given its own glyph matrices. By
173 coincidence---or maybe something else---rows in window glyph
174 matrices are slices of corresponding rows in frame matrices. Thus
175 writing to window matrices implicitly updates a frame matrix which
176 provides us with the view of the whole screen that we originally
177 wanted to have without having to move many bytes around. To be
178 honest, there is a little bit more done, but not much more. If you
179 plan to extend that code, take a look at dispnew.c. The function
180 build_frame_matrix is a good starting point.
182 Bidirectional display.
184 Bidirectional display adds quite some hair to this already complex
185 design. The good news are that a large portion of that hairy stuff
186 is hidden in bidi.c behind only 3 interfaces. bidi.c implements a
187 reordering engine which is called by set_iterator_to_next and
188 returns the next character to display in the visual order. See
189 commentary on bidi.c for more details. As far as redisplay is
190 concerned, the effect of calling bidi_move_to_visually_next, the
191 main interface of the reordering engine, is that the iterator gets
192 magically placed on the buffer or string position that is to be
193 displayed next. In other words, a linear iteration through the
194 buffer/string is replaced with a non-linear one. All the rest of
195 the redisplay is oblivious to the bidi reordering.
197 Well, almost oblivious---there are still complications, most of
198 them due to the fact that buffer and string positions no longer
199 change monotonously with glyph indices in a glyph row. Moreover,
200 for continued lines, the buffer positions may not even be
201 monotonously changing with vertical positions. Also, accounting
202 for face changes, overlays, etc. becomes more complex because
203 non-linear iteration could potentially skip many positions with
204 changes, and then cross them again on the way back...
206 One other prominent effect of bidirectional display is that some
207 paragraphs of text need to be displayed starting at the right
208 margin of the window---the so-called right-to-left, or R2L
209 paragraphs. R2L paragraphs are displayed with R2L glyph rows,
210 which have their reversed_p flag set. The bidi reordering engine
211 produces characters in such rows starting from the character which
212 should be the rightmost on display. PRODUCE_GLYPHS then reverses
213 the order, when it fills up the glyph row whose reversed_p flag is
214 set, by prepending each new glyph to what is already there, instead
215 of appending it. When the glyph row is complete, the function
216 extend_face_to_end_of_line fills the empty space to the left of the
217 leftmost character with special glyphs, which will display as,
218 well, empty. On text terminals, these special glyphs are simply
219 blank characters. On graphics terminals, there's a single stretch
220 glyph of a suitably computed width. Both the blanks and the
221 stretch glyph are given the face of the background of the line.
222 This way, the terminal-specific back-end can still draw the glyphs
223 left to right, even for R2L lines.
225 Bidirectional display and character compositions
227 Some scripts cannot be displayed by drawing each character
228 individually, because adjacent characters change each other's shape
229 on display. For example, Arabic and Indic scripts belong to this
232 Emacs display supports this by providing "character compositions",
233 most of which is implemented in composite.c. During the buffer
234 scan that delivers characters to PRODUCE_GLYPHS, if the next
235 character to be delivered is a composed character, the iteration
236 calls composition_reseat_it and next_element_from_composition. If
237 they succeed to compose the character with one or more of the
238 following characters, the whole sequence of characters that where
239 composed is recorded in the `struct composition_it' object that is
240 part of the buffer iterator. The composed sequence could produce
241 one or more font glyphs (called "grapheme clusters") on the screen.
242 Each of these grapheme clusters is then delivered to PRODUCE_GLYPHS
243 in the direction corresponding to the current bidi scan direction
244 (recorded in the scan_dir member of the `struct bidi_it' object
245 that is part of the buffer iterator). In particular, if the bidi
246 iterator currently scans the buffer backwards, the grapheme
247 clusters are delivered back to front. This reorders the grapheme
248 clusters as appropriate for the current bidi context. Note that
249 this means that the grapheme clusters are always stored in the
250 LGSTRING object (see composite.c) in the logical order.
252 Moving an iterator in bidirectional text
253 without producing glyphs
255 Note one important detail mentioned above: that the bidi reordering
256 engine, driven by the iterator, produces characters in R2L rows
257 starting at the character that will be the rightmost on display.
258 As far as the iterator is concerned, the geometry of such rows is
259 still left to right, i.e. the iterator "thinks" the first character
260 is at the leftmost pixel position. The iterator does not know that
261 PRODUCE_GLYPHS reverses the order of the glyphs that the iterator
262 delivers. This is important when functions from the move_it_*
263 family are used to get to certain screen position or to match
264 screen coordinates with buffer coordinates: these functions use the
265 iterator geometry, which is left to right even in R2L paragraphs.
266 This works well with most callers of move_it_*, because they need
267 to get to a specific column, and columns are still numbered in the
268 reading order, i.e. the rightmost character in a R2L paragraph is
269 still column zero. But some callers do not get well with this; a
270 notable example is mouse clicks that need to find the character
271 that corresponds to certain pixel coordinates. See
272 buffer_posn_from_coords in dispnew.c for how this is handled. */
280 #include "keyboard.h"
283 #include "termchar.h"
284 #include "dispextern.h"
285 #include "character.h"
289 #include "commands.h"
293 #include "termhooks.h"
294 #include "termopts.h"
295 #include "intervals.h"
298 #include "region-cache.h"
301 #include "blockinput.h"
302 #ifdef HAVE_WINDOW_SYSTEM
304 #endif /* HAVE_WINDOW_SYSTEM */
306 #ifndef FRAME_X_OUTPUT
307 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
310 #define INFINITY 10000000
312 Lisp_Object Qoverriding_local_map
, Qoverriding_terminal_local_map
;
313 Lisp_Object Qwindow_scroll_functions
;
314 static Lisp_Object Qwindow_text_change_functions
;
315 static Lisp_Object Qredisplay_end_trigger_functions
;
316 Lisp_Object Qinhibit_point_motion_hooks
;
317 static Lisp_Object QCeval
, QCpropertize
;
318 Lisp_Object QCfile
, QCdata
;
319 static Lisp_Object Qfontified
;
320 static Lisp_Object Qgrow_only
;
321 static Lisp_Object Qinhibit_eval_during_redisplay
;
322 static Lisp_Object Qbuffer_position
, Qposition
, Qobject
;
323 static Lisp_Object Qright_to_left
, Qleft_to_right
;
326 Lisp_Object Qbar
, Qhbar
, Qbox
, Qhollow
;
328 /* Pointer shapes. */
329 static Lisp_Object Qarrow
, Qhand
;
332 /* Holds the list (error). */
333 static Lisp_Object list_of_error
;
335 static Lisp_Object Qfontification_functions
;
337 static Lisp_Object Qwrap_prefix
;
338 static Lisp_Object Qline_prefix
;
339 static Lisp_Object Qredisplay_internal
;
341 /* Non-nil means don't actually do any redisplay. */
343 Lisp_Object Qinhibit_redisplay
;
345 /* Names of text properties relevant for redisplay. */
347 Lisp_Object Qdisplay
;
349 Lisp_Object Qspace
, QCalign_to
;
350 static Lisp_Object QCrelative_width
, QCrelative_height
;
351 Lisp_Object Qleft_margin
, Qright_margin
;
352 static Lisp_Object Qspace_width
, Qraise
;
353 static Lisp_Object Qslice
;
355 static Lisp_Object Qmargin
, Qpointer
;
356 static Lisp_Object Qline_height
;
358 #ifdef HAVE_WINDOW_SYSTEM
360 /* Test if overflow newline into fringe. Called with iterator IT
361 at or past right window margin, and with IT->current_x set. */
363 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(IT) \
364 (!NILP (Voverflow_newline_into_fringe) \
365 && FRAME_WINDOW_P ((IT)->f) \
366 && ((IT)->bidi_it.paragraph_dir == R2L \
367 ? (WINDOW_LEFT_FRINGE_WIDTH ((IT)->w) > 0) \
368 : (WINDOW_RIGHT_FRINGE_WIDTH ((IT)->w) > 0)) \
369 && (IT)->current_x == (IT)->last_visible_x)
371 #else /* !HAVE_WINDOW_SYSTEM */
372 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) 0
373 #endif /* HAVE_WINDOW_SYSTEM */
375 /* Test if the display element loaded in IT, or the underlying buffer
376 or string character, is a space or a TAB character. This is used
377 to determine where word wrapping can occur. */
379 #define IT_DISPLAYING_WHITESPACE(it) \
380 ((it->what == IT_CHARACTER && (it->c == ' ' || it->c == '\t')) \
381 || ((STRINGP (it->string) \
382 && (SREF (it->string, IT_STRING_BYTEPOS (*it)) == ' ' \
383 || SREF (it->string, IT_STRING_BYTEPOS (*it)) == '\t')) \
385 && (it->s[IT_BYTEPOS (*it)] == ' ' \
386 || it->s[IT_BYTEPOS (*it)] == '\t')) \
387 || (IT_BYTEPOS (*it) < ZV_BYTE \
388 && (*BYTE_POS_ADDR (IT_BYTEPOS (*it)) == ' ' \
389 || *BYTE_POS_ADDR (IT_BYTEPOS (*it)) == '\t')))) \
391 /* Name of the face used to highlight trailing whitespace. */
393 static Lisp_Object Qtrailing_whitespace
;
395 /* Name and number of the face used to highlight escape glyphs. */
397 static Lisp_Object Qescape_glyph
;
399 /* Name and number of the face used to highlight non-breaking spaces. */
401 static Lisp_Object Qnobreak_space
;
403 /* The symbol `image' which is the car of the lists used to represent
404 images in Lisp. Also a tool bar style. */
408 /* The image map types. */
410 static Lisp_Object QCpointer
;
411 static Lisp_Object Qrect
, Qcircle
, Qpoly
;
413 /* Tool bar styles */
414 Lisp_Object Qboth
, Qboth_horiz
, Qtext_image_horiz
;
416 /* Non-zero means print newline to stdout before next mini-buffer
419 int noninteractive_need_newline
;
421 /* Non-zero means print newline to message log before next message. */
423 static int message_log_need_newline
;
425 /* Three markers that message_dolog uses.
426 It could allocate them itself, but that causes trouble
427 in handling memory-full errors. */
428 static Lisp_Object message_dolog_marker1
;
429 static Lisp_Object message_dolog_marker2
;
430 static Lisp_Object message_dolog_marker3
;
432 /* The buffer position of the first character appearing entirely or
433 partially on the line of the selected window which contains the
434 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
435 redisplay optimization in redisplay_internal. */
437 static struct text_pos this_line_start_pos
;
439 /* Number of characters past the end of the line above, including the
440 terminating newline. */
442 static struct text_pos this_line_end_pos
;
444 /* The vertical positions and the height of this line. */
446 static int this_line_vpos
;
447 static int this_line_y
;
448 static int this_line_pixel_height
;
450 /* X position at which this display line starts. Usually zero;
451 negative if first character is partially visible. */
453 static int this_line_start_x
;
455 /* The smallest character position seen by move_it_* functions as they
456 move across display lines. Used to set MATRIX_ROW_START_CHARPOS of
457 hscrolled lines, see display_line. */
459 static struct text_pos this_line_min_pos
;
461 /* Buffer that this_line_.* variables are referring to. */
463 static struct buffer
*this_line_buffer
;
466 /* Values of those variables at last redisplay are stored as
467 properties on `overlay-arrow-position' symbol. However, if
468 Voverlay_arrow_position is a marker, last-arrow-position is its
469 numerical position. */
471 static Lisp_Object Qlast_arrow_position
, Qlast_arrow_string
;
473 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
474 properties on a symbol in overlay-arrow-variable-list. */
476 static Lisp_Object Qoverlay_arrow_string
, Qoverlay_arrow_bitmap
;
478 Lisp_Object Qmenu_bar_update_hook
;
480 /* Nonzero if an overlay arrow has been displayed in this window. */
482 static int overlay_arrow_seen
;
484 /* Vector containing glyphs for an ellipsis `...'. */
486 static Lisp_Object default_invis_vector
[3];
488 /* This is the window where the echo area message was displayed. It
489 is always a mini-buffer window, but it may not be the same window
490 currently active as a mini-buffer. */
492 Lisp_Object echo_area_window
;
494 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
495 pushes the current message and the value of
496 message_enable_multibyte on the stack, the function restore_message
497 pops the stack and displays MESSAGE again. */
499 static Lisp_Object Vmessage_stack
;
501 /* Nonzero means multibyte characters were enabled when the echo area
502 message was specified. */
504 static int message_enable_multibyte
;
506 /* Nonzero if we should redraw the mode lines on the next redisplay. */
508 int update_mode_lines
;
510 /* Nonzero if window sizes or contents have changed since last
511 redisplay that finished. */
513 int windows_or_buffers_changed
;
515 /* Nonzero after display_mode_line if %l was used and it displayed a
518 static int line_number_displayed
;
520 /* The name of the *Messages* buffer, a string. */
522 static Lisp_Object Vmessages_buffer_name
;
524 /* Current, index 0, and last displayed echo area message. Either
525 buffers from echo_buffers, or nil to indicate no message. */
527 Lisp_Object echo_area_buffer
[2];
529 /* The buffers referenced from echo_area_buffer. */
531 static Lisp_Object echo_buffer
[2];
533 /* A vector saved used in with_area_buffer to reduce consing. */
535 static Lisp_Object Vwith_echo_area_save_vector
;
537 /* Non-zero means display_echo_area should display the last echo area
538 message again. Set by redisplay_preserve_echo_area. */
540 static int display_last_displayed_message_p
;
542 /* Nonzero if echo area is being used by print; zero if being used by
545 static int message_buf_print
;
547 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
549 static Lisp_Object Qinhibit_menubar_update
;
550 static Lisp_Object Qmessage_truncate_lines
;
552 /* Set to 1 in clear_message to make redisplay_internal aware
553 of an emptied echo area. */
555 static int message_cleared_p
;
557 /* A scratch glyph row with contents used for generating truncation
558 glyphs. Also used in direct_output_for_insert. */
560 #define MAX_SCRATCH_GLYPHS 100
561 static struct glyph_row scratch_glyph_row
;
562 static struct glyph scratch_glyphs
[MAX_SCRATCH_GLYPHS
];
564 /* Ascent and height of the last line processed by move_it_to. */
566 static int last_height
;
568 /* Non-zero if there's a help-echo in the echo area. */
570 int help_echo_showing_p
;
572 /* The maximum distance to look ahead for text properties. Values
573 that are too small let us call compute_char_face and similar
574 functions too often which is expensive. Values that are too large
575 let us call compute_char_face and alike too often because we
576 might not be interested in text properties that far away. */
578 #define TEXT_PROP_DISTANCE_LIMIT 100
580 /* SAVE_IT and RESTORE_IT are called when we save a snapshot of the
581 iterator state and later restore it. This is needed because the
582 bidi iterator on bidi.c keeps a stacked cache of its states, which
583 is really a singleton. When we use scratch iterator objects to
584 move around the buffer, we can cause the bidi cache to be pushed or
585 popped, and therefore we need to restore the cache state when we
586 return to the original iterator. */
587 #define SAVE_IT(ITCOPY,ITORIG,CACHE) \
590 bidi_unshelve_cache (CACHE, 1); \
592 CACHE = bidi_shelve_cache (); \
595 #define RESTORE_IT(pITORIG,pITCOPY,CACHE) \
597 if (pITORIG != pITCOPY) \
598 *(pITORIG) = *(pITCOPY); \
599 bidi_unshelve_cache (CACHE, 0); \
605 /* Non-zero means print traces of redisplay if compiled with
606 GLYPH_DEBUG defined. */
608 int trace_redisplay_p
;
610 #endif /* GLYPH_DEBUG */
612 #ifdef DEBUG_TRACE_MOVE
613 /* Non-zero means trace with TRACE_MOVE to stderr. */
616 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
618 #define TRACE_MOVE(x) (void) 0
621 static Lisp_Object Qauto_hscroll_mode
;
623 /* Buffer being redisplayed -- for redisplay_window_error. */
625 static struct buffer
*displayed_buffer
;
627 /* Value returned from text property handlers (see below). */
632 HANDLED_RECOMPUTE_PROPS
,
633 HANDLED_OVERLAY_STRING_CONSUMED
,
637 /* A description of text properties that redisplay is interested
642 /* The name of the property. */
645 /* A unique index for the property. */
648 /* A handler function called to set up iterator IT from the property
649 at IT's current position. Value is used to steer handle_stop. */
650 enum prop_handled (*handler
) (struct it
*it
);
653 static enum prop_handled
handle_face_prop (struct it
*);
654 static enum prop_handled
handle_invisible_prop (struct it
*);
655 static enum prop_handled
handle_display_prop (struct it
*);
656 static enum prop_handled
handle_composition_prop (struct it
*);
657 static enum prop_handled
handle_overlay_change (struct it
*);
658 static enum prop_handled
handle_fontified_prop (struct it
*);
660 /* Properties handled by iterators. */
662 static struct props it_props
[] =
664 {&Qfontified
, FONTIFIED_PROP_IDX
, handle_fontified_prop
},
665 /* Handle `face' before `display' because some sub-properties of
666 `display' need to know the face. */
667 {&Qface
, FACE_PROP_IDX
, handle_face_prop
},
668 {&Qdisplay
, DISPLAY_PROP_IDX
, handle_display_prop
},
669 {&Qinvisible
, INVISIBLE_PROP_IDX
, handle_invisible_prop
},
670 {&Qcomposition
, COMPOSITION_PROP_IDX
, handle_composition_prop
},
674 /* Value is the position described by X. If X is a marker, value is
675 the marker_position of X. Otherwise, value is X. */
677 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
679 /* Enumeration returned by some move_it_.* functions internally. */
683 /* Not used. Undefined value. */
686 /* Move ended at the requested buffer position or ZV. */
687 MOVE_POS_MATCH_OR_ZV
,
689 /* Move ended at the requested X pixel position. */
692 /* Move within a line ended at the end of a line that must be
696 /* Move within a line ended at the end of a line that would
697 be displayed truncated. */
700 /* Move within a line ended at a line end. */
704 /* This counter is used to clear the face cache every once in a while
705 in redisplay_internal. It is incremented for each redisplay.
706 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
709 #define CLEAR_FACE_CACHE_COUNT 500
710 static int clear_face_cache_count
;
712 /* Similarly for the image cache. */
714 #ifdef HAVE_WINDOW_SYSTEM
715 #define CLEAR_IMAGE_CACHE_COUNT 101
716 static int clear_image_cache_count
;
718 /* Null glyph slice */
719 static struct glyph_slice null_glyph_slice
= { 0, 0, 0, 0 };
722 /* True while redisplay_internal is in progress. */
726 static Lisp_Object Qinhibit_free_realized_faces
;
727 static Lisp_Object Qmode_line_default_help_echo
;
729 /* If a string, XTread_socket generates an event to display that string.
730 (The display is done in read_char.) */
732 Lisp_Object help_echo_string
;
733 Lisp_Object help_echo_window
;
734 Lisp_Object help_echo_object
;
735 ptrdiff_t help_echo_pos
;
737 /* Temporary variable for XTread_socket. */
739 Lisp_Object previous_help_echo_string
;
741 /* Platform-independent portion of hourglass implementation. */
743 #ifdef HAVE_WINDOW_SYSTEM
745 /* Non-zero means an hourglass cursor is currently shown. */
746 int hourglass_shown_p
;
748 /* If non-null, an asynchronous timer that, when it expires, displays
749 an hourglass cursor on all frames. */
750 struct atimer
*hourglass_atimer
;
752 #endif /* HAVE_WINDOW_SYSTEM */
754 /* Name of the face used to display glyphless characters. */
755 Lisp_Object Qglyphless_char
;
757 /* Symbol for the purpose of Vglyphless_char_display. */
758 static Lisp_Object Qglyphless_char_display
;
760 /* Method symbols for Vglyphless_char_display. */
761 static Lisp_Object Qhex_code
, Qempty_box
, Qthin_space
, Qzero_width
;
763 /* Default number of seconds to wait before displaying an hourglass
765 #define DEFAULT_HOURGLASS_DELAY 1
767 #ifdef HAVE_WINDOW_SYSTEM
769 /* Default pixel width of `thin-space' display method. */
770 #define THIN_SPACE_WIDTH 1
772 #endif /* HAVE_WINDOW_SYSTEM */
774 /* Function prototypes. */
776 static void setup_for_ellipsis (struct it
*, int);
777 static void set_iterator_to_next (struct it
*, int);
778 static void mark_window_display_accurate_1 (struct window
*, int);
779 static int single_display_spec_string_p (Lisp_Object
, Lisp_Object
);
780 static int display_prop_string_p (Lisp_Object
, Lisp_Object
);
781 static int row_for_charpos_p (struct glyph_row
*, ptrdiff_t);
782 static int cursor_row_p (struct glyph_row
*);
783 static int redisplay_mode_lines (Lisp_Object
, int);
784 static char *decode_mode_spec_coding (Lisp_Object
, char *, int);
786 static Lisp_Object
get_it_property (struct it
*it
, Lisp_Object prop
);
788 static void handle_line_prefix (struct it
*);
790 static void pint2str (char *, int, ptrdiff_t);
791 static void pint2hrstr (char *, int, ptrdiff_t);
792 static struct text_pos
run_window_scroll_functions (Lisp_Object
,
794 static int text_outside_line_unchanged_p (struct window
*,
795 ptrdiff_t, ptrdiff_t);
796 static void store_mode_line_noprop_char (char);
797 static int store_mode_line_noprop (const char *, int, int);
798 static void handle_stop (struct it
*);
799 static void handle_stop_backwards (struct it
*, ptrdiff_t);
800 static void vmessage (const char *, va_list) ATTRIBUTE_FORMAT_PRINTF (1, 0);
801 static void ensure_echo_area_buffers (void);
802 static void unwind_with_echo_area_buffer (Lisp_Object
);
803 static Lisp_Object
with_echo_area_buffer_unwind_data (struct window
*);
804 static int with_echo_area_buffer (struct window
*, int,
805 int (*) (ptrdiff_t, Lisp_Object
),
806 ptrdiff_t, Lisp_Object
);
807 static void clear_garbaged_frames (void);
808 static int current_message_1 (ptrdiff_t, Lisp_Object
);
809 static int truncate_message_1 (ptrdiff_t, Lisp_Object
);
810 static void set_message (Lisp_Object
);
811 static int set_message_1 (ptrdiff_t, Lisp_Object
);
812 static int display_echo_area (struct window
*);
813 static int display_echo_area_1 (ptrdiff_t, Lisp_Object
);
814 static int resize_mini_window_1 (ptrdiff_t, Lisp_Object
);
815 static void unwind_redisplay (void);
816 static int string_char_and_length (const unsigned char *, int *);
817 static struct text_pos
display_prop_end (struct it
*, Lisp_Object
,
819 static int compute_window_start_on_continuation_line (struct window
*);
820 static void insert_left_trunc_glyphs (struct it
*);
821 static struct glyph_row
*get_overlay_arrow_glyph_row (struct window
*,
823 static void extend_face_to_end_of_line (struct it
*);
824 static int append_space_for_newline (struct it
*, int);
825 static int cursor_row_fully_visible_p (struct window
*, int, int);
826 static int try_scrolling (Lisp_Object
, int, ptrdiff_t, ptrdiff_t, int, int);
827 static int try_cursor_movement (Lisp_Object
, struct text_pos
, int *);
828 static int trailing_whitespace_p (ptrdiff_t);
829 static intmax_t message_log_check_duplicate (ptrdiff_t, ptrdiff_t);
830 static void push_it (struct it
*, struct text_pos
*);
831 static void iterate_out_of_display_property (struct it
*);
832 static void pop_it (struct it
*);
833 static void sync_frame_with_window_matrix_rows (struct window
*);
834 static void redisplay_internal (void);
835 static int echo_area_display (int);
836 static void redisplay_windows (Lisp_Object
);
837 static void redisplay_window (Lisp_Object
, int);
838 static Lisp_Object
redisplay_window_error (Lisp_Object
);
839 static Lisp_Object
redisplay_window_0 (Lisp_Object
);
840 static Lisp_Object
redisplay_window_1 (Lisp_Object
);
841 static int set_cursor_from_row (struct window
*, struct glyph_row
*,
842 struct glyph_matrix
*, ptrdiff_t, ptrdiff_t,
844 static int update_menu_bar (struct frame
*, int, int);
845 static int try_window_reusing_current_matrix (struct window
*);
846 static int try_window_id (struct window
*);
847 static int display_line (struct it
*);
848 static int display_mode_lines (struct window
*);
849 static int display_mode_line (struct window
*, enum face_id
, Lisp_Object
);
850 static int display_mode_element (struct it
*, int, int, int, Lisp_Object
, Lisp_Object
, int);
851 static int store_mode_line_string (const char *, Lisp_Object
, int, int, int, Lisp_Object
);
852 static const char *decode_mode_spec (struct window
*, int, int, Lisp_Object
*);
853 static void display_menu_bar (struct window
*);
854 static ptrdiff_t display_count_lines (ptrdiff_t, ptrdiff_t, ptrdiff_t,
856 static int display_string (const char *, Lisp_Object
, Lisp_Object
,
857 ptrdiff_t, ptrdiff_t, struct it
*, int, int, int, int);
858 static void compute_line_metrics (struct it
*);
859 static void run_redisplay_end_trigger_hook (struct it
*);
860 static int get_overlay_strings (struct it
*, ptrdiff_t);
861 static int get_overlay_strings_1 (struct it
*, ptrdiff_t, int);
862 static void next_overlay_string (struct it
*);
863 static void reseat (struct it
*, struct text_pos
, int);
864 static void reseat_1 (struct it
*, struct text_pos
, int);
865 static void back_to_previous_visible_line_start (struct it
*);
866 static void reseat_at_next_visible_line_start (struct it
*, int);
867 static int next_element_from_ellipsis (struct it
*);
868 static int next_element_from_display_vector (struct it
*);
869 static int next_element_from_string (struct it
*);
870 static int next_element_from_c_string (struct it
*);
871 static int next_element_from_buffer (struct it
*);
872 static int next_element_from_composition (struct it
*);
873 static int next_element_from_image (struct it
*);
874 static int next_element_from_stretch (struct it
*);
875 static void load_overlay_strings (struct it
*, ptrdiff_t);
876 static int init_from_display_pos (struct it
*, struct window
*,
877 struct display_pos
*);
878 static void reseat_to_string (struct it
*, const char *,
879 Lisp_Object
, ptrdiff_t, ptrdiff_t, int, int);
880 static int get_next_display_element (struct it
*);
881 static enum move_it_result
882 move_it_in_display_line_to (struct it
*, ptrdiff_t, int,
883 enum move_operation_enum
);
884 static void get_visually_first_element (struct it
*);
885 static void init_to_row_start (struct it
*, struct window
*,
887 static int init_to_row_end (struct it
*, struct window
*,
889 static void back_to_previous_line_start (struct it
*);
890 static int forward_to_next_line_start (struct it
*, int *, struct bidi_it
*);
891 static struct text_pos
string_pos_nchars_ahead (struct text_pos
,
892 Lisp_Object
, ptrdiff_t);
893 static struct text_pos
string_pos (ptrdiff_t, Lisp_Object
);
894 static struct text_pos
c_string_pos (ptrdiff_t, const char *, bool);
895 static ptrdiff_t number_of_chars (const char *, bool);
896 static void compute_stop_pos (struct it
*);
897 static void compute_string_pos (struct text_pos
*, struct text_pos
,
899 static int face_before_or_after_it_pos (struct it
*, int);
900 static ptrdiff_t next_overlay_change (ptrdiff_t);
901 static int handle_display_spec (struct it
*, Lisp_Object
, Lisp_Object
,
902 Lisp_Object
, struct text_pos
*, ptrdiff_t, int);
903 static int handle_single_display_spec (struct it
*, Lisp_Object
,
904 Lisp_Object
, Lisp_Object
,
905 struct text_pos
*, ptrdiff_t, int, int);
906 static int underlying_face_id (struct it
*);
907 static int in_ellipses_for_invisible_text_p (struct display_pos
*,
910 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
911 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
913 #ifdef HAVE_WINDOW_SYSTEM
915 static void x_consider_frame_title (Lisp_Object
);
916 static void update_tool_bar (struct frame
*, int);
917 static int redisplay_tool_bar (struct frame
*);
918 static void notice_overwritten_cursor (struct window
*,
921 static void append_stretch_glyph (struct it
*, Lisp_Object
,
925 #endif /* HAVE_WINDOW_SYSTEM */
927 static void produce_special_glyphs (struct it
*, enum display_element_type
);
928 static void show_mouse_face (Mouse_HLInfo
*, enum draw_glyphs_face
);
929 static int coords_in_mouse_face_p (struct window
*, int, int);
933 /***********************************************************************
934 Window display dimensions
935 ***********************************************************************/
937 /* Return the bottom boundary y-position for text lines in window W.
938 This is the first y position at which a line cannot start.
939 It is relative to the top of the window.
941 This is the height of W minus the height of a mode line, if any. */
944 window_text_bottom_y (struct window
*w
)
946 int height
= WINDOW_TOTAL_HEIGHT (w
);
948 if (WINDOW_WANTS_MODELINE_P (w
))
949 height
-= CURRENT_MODE_LINE_HEIGHT (w
);
953 /* Return the pixel width of display area AREA of window W.
954 ANY_AREA means return the total width of W, not including
955 fringes to the left and right of the window. */
958 window_box_width (struct window
*w
, enum glyph_row_area area
)
960 int cols
= w
->total_cols
;
963 if (!w
->pseudo_window_p
)
965 cols
-= WINDOW_SCROLL_BAR_COLS (w
);
967 if (area
== TEXT_AREA
)
969 cols
-= max (0, w
->left_margin_cols
);
970 cols
-= max (0, w
->right_margin_cols
);
971 pixels
= -WINDOW_TOTAL_FRINGE_WIDTH (w
);
973 else if (area
== LEFT_MARGIN_AREA
)
975 cols
= max (0, w
->left_margin_cols
);
978 else if (area
== RIGHT_MARGIN_AREA
)
980 cols
= max (0, w
->right_margin_cols
);
985 return cols
* WINDOW_FRAME_COLUMN_WIDTH (w
) + pixels
;
989 /* Return the pixel height of the display area of window W, not
990 including mode lines of W, if any. */
993 window_box_height (struct window
*w
)
995 struct frame
*f
= XFRAME (w
->frame
);
996 int height
= WINDOW_TOTAL_HEIGHT (w
);
998 eassert (height
>= 0);
1000 /* Note: the code below that determines the mode-line/header-line
1001 height is essentially the same as that contained in the macro
1002 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1003 the appropriate glyph row has its `mode_line_p' flag set,
1004 and if it doesn't, uses estimate_mode_line_height instead. */
1006 if (WINDOW_WANTS_MODELINE_P (w
))
1008 struct glyph_row
*ml_row
1009 = (w
->current_matrix
&& w
->current_matrix
->rows
1010 ? MATRIX_MODE_LINE_ROW (w
->current_matrix
)
1012 if (ml_row
&& ml_row
->mode_line_p
)
1013 height
-= ml_row
->height
;
1015 height
-= estimate_mode_line_height (f
, CURRENT_MODE_LINE_FACE_ID (w
));
1018 if (WINDOW_WANTS_HEADER_LINE_P (w
))
1020 struct glyph_row
*hl_row
1021 = (w
->current_matrix
&& w
->current_matrix
->rows
1022 ? MATRIX_HEADER_LINE_ROW (w
->current_matrix
)
1024 if (hl_row
&& hl_row
->mode_line_p
)
1025 height
-= hl_row
->height
;
1027 height
-= estimate_mode_line_height (f
, HEADER_LINE_FACE_ID
);
1030 /* With a very small font and a mode-line that's taller than
1031 default, we might end up with a negative height. */
1032 return max (0, height
);
1035 /* Return the window-relative coordinate of the left edge of display
1036 area AREA of window W. ANY_AREA means return the left edge of the
1037 whole window, to the right of the left fringe of W. */
1040 window_box_left_offset (struct window
*w
, enum glyph_row_area area
)
1044 if (w
->pseudo_window_p
)
1047 x
= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w
);
1049 if (area
== TEXT_AREA
)
1050 x
+= (WINDOW_LEFT_FRINGE_WIDTH (w
)
1051 + window_box_width (w
, LEFT_MARGIN_AREA
));
1052 else if (area
== RIGHT_MARGIN_AREA
)
1053 x
+= (WINDOW_LEFT_FRINGE_WIDTH (w
)
1054 + window_box_width (w
, LEFT_MARGIN_AREA
)
1055 + window_box_width (w
, TEXT_AREA
)
1056 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
1058 : WINDOW_RIGHT_FRINGE_WIDTH (w
)));
1059 else if (area
== LEFT_MARGIN_AREA
1060 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
))
1061 x
+= WINDOW_LEFT_FRINGE_WIDTH (w
);
1067 /* Return the window-relative coordinate of the right edge of display
1068 area AREA of window W. ANY_AREA means return the right edge of the
1069 whole window, to the left of the right fringe of W. */
1072 window_box_right_offset (struct window
*w
, enum glyph_row_area area
)
1074 return window_box_left_offset (w
, area
) + window_box_width (w
, area
);
1077 /* Return the frame-relative coordinate of the left edge of display
1078 area AREA of window W. ANY_AREA means return the left edge of the
1079 whole window, to the right of the left fringe of W. */
1082 window_box_left (struct window
*w
, enum glyph_row_area area
)
1084 struct frame
*f
= XFRAME (w
->frame
);
1087 if (w
->pseudo_window_p
)
1088 return FRAME_INTERNAL_BORDER_WIDTH (f
);
1090 x
= (WINDOW_LEFT_EDGE_X (w
)
1091 + window_box_left_offset (w
, area
));
1097 /* Return the frame-relative coordinate of the right edge of display
1098 area AREA of window W. ANY_AREA means return the right edge of the
1099 whole window, to the left of the right fringe of W. */
1102 window_box_right (struct window
*w
, enum glyph_row_area area
)
1104 return window_box_left (w
, area
) + window_box_width (w
, area
);
1107 /* Get the bounding box of the display area AREA of window W, without
1108 mode lines, in frame-relative coordinates. ANY_AREA means the
1109 whole window, not including the left and right fringes of
1110 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1111 coordinates of the upper-left corner of the box. Return in
1112 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1115 window_box (struct window
*w
, enum glyph_row_area area
, int *box_x
,
1116 int *box_y
, int *box_width
, int *box_height
)
1119 *box_width
= window_box_width (w
, area
);
1121 *box_height
= window_box_height (w
);
1123 *box_x
= window_box_left (w
, area
);
1126 *box_y
= WINDOW_TOP_EDGE_Y (w
);
1127 if (WINDOW_WANTS_HEADER_LINE_P (w
))
1128 *box_y
+= CURRENT_HEADER_LINE_HEIGHT (w
);
1132 #ifdef HAVE_WINDOW_SYSTEM
1134 /* Get the bounding box of the display area AREA of window W, without
1135 mode lines and both fringes of the window. Return in *TOP_LEFT_X
1136 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1137 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1138 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1142 window_box_edges (struct window
*w
, int *top_left_x
, int *top_left_y
,
1143 int *bottom_right_x
, int *bottom_right_y
)
1145 window_box (w
, ANY_AREA
, top_left_x
, top_left_y
,
1146 bottom_right_x
, bottom_right_y
);
1147 *bottom_right_x
+= *top_left_x
;
1148 *bottom_right_y
+= *top_left_y
;
1151 #endif /* HAVE_WINDOW_SYSTEM */
1153 /***********************************************************************
1155 ***********************************************************************/
1157 /* Return the bottom y-position of the line the iterator IT is in.
1158 This can modify IT's settings. */
1161 line_bottom_y (struct it
*it
)
1163 int line_height
= it
->max_ascent
+ it
->max_descent
;
1164 int line_top_y
= it
->current_y
;
1166 if (line_height
== 0)
1169 line_height
= last_height
;
1170 else if (IT_CHARPOS (*it
) < ZV
)
1172 move_it_by_lines (it
, 1);
1173 line_height
= (it
->max_ascent
|| it
->max_descent
1174 ? it
->max_ascent
+ it
->max_descent
1179 struct glyph_row
*row
= it
->glyph_row
;
1181 /* Use the default character height. */
1182 it
->glyph_row
= NULL
;
1183 it
->what
= IT_CHARACTER
;
1186 PRODUCE_GLYPHS (it
);
1187 line_height
= it
->ascent
+ it
->descent
;
1188 it
->glyph_row
= row
;
1192 return line_top_y
+ line_height
;
1195 DEFUN ("line-pixel-height", Fline_pixel_height
,
1196 Sline_pixel_height
, 0, 0, 0,
1197 doc
: /* Return height in pixels of text line in the selected window.
1199 Value is the height in pixels of the line at point. */)
1204 struct window
*w
= XWINDOW (selected_window
);
1206 SET_TEXT_POS (pt
, PT
, PT_BYTE
);
1207 start_display (&it
, w
, pt
);
1208 it
.vpos
= it
.current_y
= 0;
1210 return make_number (line_bottom_y (&it
));
1213 /* Return the default pixel height of text lines in window W. The
1214 value is the canonical height of the W frame's default font, plus
1215 any extra space required by the line-spacing variable or frame
1218 Implementation note: this ignores any line-spacing text properties
1219 put on the newline characters. This is because those properties
1220 only affect the _screen_ line ending in the newline (i.e., in a
1221 continued line, only the last screen line will be affected), which
1222 means only a small number of lines in a buffer can ever use this
1223 feature. Since this function is used to compute the default pixel
1224 equivalent of text lines in a window, we can safely ignore those
1225 few lines. For the same reasons, we ignore the line-height
1228 default_line_pixel_height (struct window
*w
)
1230 struct frame
*f
= WINDOW_XFRAME (w
);
1231 int height
= FRAME_LINE_HEIGHT (f
);
1233 if (!FRAME_INITIAL_P (f
) && BUFFERP (w
->contents
))
1235 struct buffer
*b
= XBUFFER (w
->contents
);
1236 Lisp_Object val
= BVAR (b
, extra_line_spacing
);
1239 val
= BVAR (&buffer_defaults
, extra_line_spacing
);
1242 if (RANGED_INTEGERP (0, val
, INT_MAX
))
1243 height
+= XFASTINT (val
);
1244 else if (FLOATP (val
))
1246 int addon
= XFLOAT_DATA (val
) * height
+ 0.5;
1253 height
+= f
->extra_line_spacing
;
1259 /* Subroutine of pos_visible_p below. Extracts a display string, if
1260 any, from the display spec given as its argument. */
1262 string_from_display_spec (Lisp_Object spec
)
1266 while (CONSP (spec
))
1268 if (STRINGP (XCAR (spec
)))
1273 else if (VECTORP (spec
))
1277 for (i
= 0; i
< ASIZE (spec
); i
++)
1279 if (STRINGP (AREF (spec
, i
)))
1280 return AREF (spec
, i
);
1289 /* Limit insanely large values of W->hscroll on frame F to the largest
1290 value that will still prevent first_visible_x and last_visible_x of
1291 'struct it' from overflowing an int. */
1293 window_hscroll_limited (struct window
*w
, struct frame
*f
)
1295 ptrdiff_t window_hscroll
= w
->hscroll
;
1296 int window_text_width
= window_box_width (w
, TEXT_AREA
);
1297 int colwidth
= FRAME_COLUMN_WIDTH (f
);
1299 if (window_hscroll
> (INT_MAX
- window_text_width
) / colwidth
- 1)
1300 window_hscroll
= (INT_MAX
- window_text_width
) / colwidth
- 1;
1302 return window_hscroll
;
1305 /* Return 1 if position CHARPOS is visible in window W.
1306 CHARPOS < 0 means return info about WINDOW_END position.
1307 If visible, set *X and *Y to pixel coordinates of top left corner.
1308 Set *RTOP and *RBOT to pixel height of an invisible area of glyph at POS.
1309 Set *ROWH and *VPOS to row's visible height and VPOS (row number). */
1312 pos_visible_p (struct window
*w
, ptrdiff_t charpos
, int *x
, int *y
,
1313 int *rtop
, int *rbot
, int *rowh
, int *vpos
)
1316 void *itdata
= bidi_shelve_cache ();
1317 struct text_pos top
;
1319 struct buffer
*old_buffer
= NULL
;
1321 if (FRAME_INITIAL_P (XFRAME (WINDOW_FRAME (w
))))
1324 if (XBUFFER (w
->contents
) != current_buffer
)
1326 old_buffer
= current_buffer
;
1327 set_buffer_internal_1 (XBUFFER (w
->contents
));
1330 SET_TEXT_POS_FROM_MARKER (top
, w
->start
);
1331 /* Scrolling a minibuffer window via scroll bar when the echo area
1332 shows long text sometimes resets the minibuffer contents behind
1334 if (CHARPOS (top
) > ZV
)
1335 SET_TEXT_POS (top
, BEGV
, BEGV_BYTE
);
1337 /* Compute exact mode line heights. */
1338 if (WINDOW_WANTS_MODELINE_P (w
))
1340 = display_mode_line (w
, CURRENT_MODE_LINE_FACE_ID (w
),
1341 BVAR (current_buffer
, mode_line_format
));
1343 if (WINDOW_WANTS_HEADER_LINE_P (w
))
1344 w
->header_line_height
1345 = display_mode_line (w
, HEADER_LINE_FACE_ID
,
1346 BVAR (current_buffer
, header_line_format
));
1348 start_display (&it
, w
, top
);
1349 move_it_to (&it
, charpos
, -1, it
.last_visible_y
- 1, -1,
1350 (charpos
>= 0 ? MOVE_TO_POS
: 0) | MOVE_TO_Y
);
1353 && (((!it
.bidi_p
|| it
.bidi_it
.scan_dir
== 1)
1354 && IT_CHARPOS (it
) >= charpos
)
1355 /* When scanning backwards under bidi iteration, move_it_to
1356 stops at or _before_ CHARPOS, because it stops at or to
1357 the _right_ of the character at CHARPOS. */
1358 || (it
.bidi_p
&& it
.bidi_it
.scan_dir
== -1
1359 && IT_CHARPOS (it
) <= charpos
)))
1361 /* We have reached CHARPOS, or passed it. How the call to
1362 move_it_to can overshoot: (i) If CHARPOS is on invisible text
1363 or covered by a display property, move_it_to stops at the end
1364 of the invisible text, to the right of CHARPOS. (ii) If
1365 CHARPOS is in a display vector, move_it_to stops on its last
1367 int top_x
= it
.current_x
;
1368 int top_y
= it
.current_y
;
1369 /* Calling line_bottom_y may change it.method, it.position, etc. */
1370 enum it_method it_method
= it
.method
;
1371 int bottom_y
= (last_height
= 0, line_bottom_y (&it
));
1372 int window_top_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
1374 if (top_y
< window_top_y
)
1375 visible_p
= bottom_y
> window_top_y
;
1376 else if (top_y
< it
.last_visible_y
)
1378 if (bottom_y
>= it
.last_visible_y
1379 && it
.bidi_p
&& it
.bidi_it
.scan_dir
== -1
1380 && IT_CHARPOS (it
) < charpos
)
1382 /* When the last line of the window is scanned backwards
1383 under bidi iteration, we could be duped into thinking
1384 that we have passed CHARPOS, when in fact move_it_to
1385 simply stopped short of CHARPOS because it reached
1386 last_visible_y. To see if that's what happened, we call
1387 move_it_to again with a slightly larger vertical limit,
1388 and see if it actually moved vertically; if it did, we
1389 didn't really reach CHARPOS, which is beyond window end. */
1390 struct it save_it
= it
;
1391 /* Why 10? because we don't know how many canonical lines
1392 will the height of the next line(s) be. So we guess. */
1393 int ten_more_lines
= 10 * default_line_pixel_height (w
);
1395 move_it_to (&it
, charpos
, -1, bottom_y
+ ten_more_lines
, -1,
1396 MOVE_TO_POS
| MOVE_TO_Y
);
1397 if (it
.current_y
> top_y
)
1404 if (it_method
== GET_FROM_DISPLAY_VECTOR
)
1406 /* We stopped on the last glyph of a display vector.
1407 Try and recompute. Hack alert! */
1408 if (charpos
< 2 || top
.charpos
>= charpos
)
1409 top_x
= it
.glyph_row
->x
;
1412 struct it it2
, it2_prev
;
1413 /* The idea is to get to the previous buffer
1414 position, consume the character there, and use
1415 the pixel coordinates we get after that. But if
1416 the previous buffer position is also displayed
1417 from a display vector, we need to consume all of
1418 the glyphs from that display vector. */
1419 start_display (&it2
, w
, top
);
1420 move_it_to (&it2
, charpos
- 1, -1, -1, -1, MOVE_TO_POS
);
1421 /* If we didn't get to CHARPOS - 1, there's some
1422 replacing display property at that position, and
1423 we stopped after it. That is exactly the place
1424 whose coordinates we want. */
1425 if (IT_CHARPOS (it2
) != charpos
- 1)
1429 /* Iterate until we get out of the display
1430 vector that displays the character at
1433 get_next_display_element (&it2
);
1434 PRODUCE_GLYPHS (&it2
);
1436 set_iterator_to_next (&it2
, 1);
1437 } while (it2
.method
== GET_FROM_DISPLAY_VECTOR
1438 && IT_CHARPOS (it2
) < charpos
);
1440 if (ITERATOR_AT_END_OF_LINE_P (&it2_prev
)
1441 || it2_prev
.current_x
> it2_prev
.last_visible_x
)
1442 top_x
= it
.glyph_row
->x
;
1445 top_x
= it2_prev
.current_x
;
1446 top_y
= it2_prev
.current_y
;
1450 else if (IT_CHARPOS (it
) != charpos
)
1452 Lisp_Object cpos
= make_number (charpos
);
1453 Lisp_Object spec
= Fget_char_property (cpos
, Qdisplay
, Qnil
);
1454 Lisp_Object string
= string_from_display_spec (spec
);
1455 struct text_pos tpos
;
1456 int replacing_spec_p
;
1457 bool newline_in_string
1459 && memchr (SDATA (string
), '\n', SBYTES (string
)));
1461 SET_TEXT_POS (tpos
, charpos
, CHAR_TO_BYTE (charpos
));
1464 && handle_display_spec (NULL
, spec
, Qnil
, Qnil
, &tpos
,
1465 charpos
, FRAME_WINDOW_P (it
.f
)));
1466 /* The tricky code below is needed because there's a
1467 discrepancy between move_it_to and how we set cursor
1468 when PT is at the beginning of a portion of text
1469 covered by a display property or an overlay with a
1470 display property, or the display line ends in a
1471 newline from a display string. move_it_to will stop
1472 _after_ such display strings, whereas
1473 set_cursor_from_row conspires with cursor_row_p to
1474 place the cursor on the first glyph produced from the
1477 /* We have overshoot PT because it is covered by a
1478 display property that replaces the text it covers.
1479 If the string includes embedded newlines, we are also
1480 in the wrong display line. Backtrack to the correct
1481 line, where the display property begins. */
1482 if (replacing_spec_p
)
1484 Lisp_Object startpos
, endpos
;
1485 EMACS_INT start
, end
;
1489 /* Find the first and the last buffer positions
1490 covered by the display string. */
1492 Fnext_single_char_property_change (cpos
, Qdisplay
,
1495 Fprevious_single_char_property_change (endpos
, Qdisplay
,
1497 start
= XFASTINT (startpos
);
1498 end
= XFASTINT (endpos
);
1499 /* Move to the last buffer position before the
1500 display property. */
1501 start_display (&it3
, w
, top
);
1502 move_it_to (&it3
, start
- 1, -1, -1, -1, MOVE_TO_POS
);
1503 /* Move forward one more line if the position before
1504 the display string is a newline or if it is the
1505 rightmost character on a line that is
1506 continued or word-wrapped. */
1507 if (it3
.method
== GET_FROM_BUFFER
1509 || FETCH_BYTE (IT_BYTEPOS (it3
)) == '\n'))
1510 move_it_by_lines (&it3
, 1);
1511 else if (move_it_in_display_line_to (&it3
, -1,
1515 == MOVE_LINE_CONTINUED
)
1517 move_it_by_lines (&it3
, 1);
1518 /* When we are under word-wrap, the #$@%!
1519 move_it_by_lines moves 2 lines, so we need to
1521 if (it3
.line_wrap
== WORD_WRAP
)
1522 move_it_by_lines (&it3
, -1);
1525 /* Record the vertical coordinate of the display
1526 line where we wound up. */
1527 top_y
= it3
.current_y
;
1530 /* When characters are reordered for display,
1531 the character displayed to the left of the
1532 display string could be _after_ the display
1533 property in the logical order. Use the
1534 smallest vertical position of these two. */
1535 start_display (&it3
, w
, top
);
1536 move_it_to (&it3
, end
+ 1, -1, -1, -1, MOVE_TO_POS
);
1537 if (it3
.current_y
< top_y
)
1538 top_y
= it3
.current_y
;
1540 /* Move from the top of the window to the beginning
1541 of the display line where the display string
1543 start_display (&it3
, w
, top
);
1544 move_it_to (&it3
, -1, 0, top_y
, -1, MOVE_TO_X
| MOVE_TO_Y
);
1545 /* If it3_moved stays zero after the 'while' loop
1546 below, that means we already were at a newline
1547 before the loop (e.g., the display string begins
1548 with a newline), so we don't need to (and cannot)
1549 inspect the glyphs of it3.glyph_row, because
1550 PRODUCE_GLYPHS will not produce anything for a
1551 newline, and thus it3.glyph_row stays at its
1552 stale content it got at top of the window. */
1554 /* Finally, advance the iterator until we hit the
1555 first display element whose character position is
1556 CHARPOS, or until the first newline from the
1557 display string, which signals the end of the
1559 while (get_next_display_element (&it3
))
1561 PRODUCE_GLYPHS (&it3
);
1562 if (IT_CHARPOS (it3
) == charpos
1563 || ITERATOR_AT_END_OF_LINE_P (&it3
))
1566 set_iterator_to_next (&it3
, 0);
1568 top_x
= it3
.current_x
- it3
.pixel_width
;
1569 /* Normally, we would exit the above loop because we
1570 found the display element whose character
1571 position is CHARPOS. For the contingency that we
1572 didn't, and stopped at the first newline from the
1573 display string, move back over the glyphs
1574 produced from the string, until we find the
1575 rightmost glyph not from the string. */
1577 && newline_in_string
1578 && IT_CHARPOS (it3
) != charpos
&& EQ (it3
.object
, string
))
1580 struct glyph
*g
= it3
.glyph_row
->glyphs
[TEXT_AREA
]
1581 + it3
.glyph_row
->used
[TEXT_AREA
];
1583 while (EQ ((g
- 1)->object
, string
))
1586 top_x
-= g
->pixel_width
;
1588 eassert (g
< it3
.glyph_row
->glyphs
[TEXT_AREA
]
1589 + it3
.glyph_row
->used
[TEXT_AREA
]);
1595 *y
= max (top_y
+ max (0, it
.max_ascent
- it
.ascent
), window_top_y
);
1596 *rtop
= max (0, window_top_y
- top_y
);
1597 *rbot
= max (0, bottom_y
- it
.last_visible_y
);
1598 *rowh
= max (0, (min (bottom_y
, it
.last_visible_y
)
1599 - max (top_y
, window_top_y
)));
1605 /* We were asked to provide info about WINDOW_END. */
1607 void *it2data
= NULL
;
1609 SAVE_IT (it2
, it
, it2data
);
1610 if (IT_CHARPOS (it
) < ZV
&& FETCH_BYTE (IT_BYTEPOS (it
)) != '\n')
1611 move_it_by_lines (&it
, 1);
1612 if (charpos
< IT_CHARPOS (it
)
1613 || (it
.what
== IT_EOB
&& charpos
== IT_CHARPOS (it
)))
1616 RESTORE_IT (&it2
, &it2
, it2data
);
1617 move_it_to (&it2
, charpos
, -1, -1, -1, MOVE_TO_POS
);
1619 *y
= it2
.current_y
+ it2
.max_ascent
- it2
.ascent
;
1620 *rtop
= max (0, -it2
.current_y
);
1621 *rbot
= max (0, ((it2
.current_y
+ it2
.max_ascent
+ it2
.max_descent
)
1622 - it
.last_visible_y
));
1623 *rowh
= max (0, (min (it2
.current_y
+ it2
.max_ascent
+ it2
.max_descent
,
1625 - max (it2
.current_y
,
1626 WINDOW_HEADER_LINE_HEIGHT (w
))));
1630 bidi_unshelve_cache (it2data
, 1);
1632 bidi_unshelve_cache (itdata
, 0);
1635 set_buffer_internal_1 (old_buffer
);
1637 if (visible_p
&& w
->hscroll
> 0)
1639 window_hscroll_limited (w
, WINDOW_XFRAME (w
))
1640 * WINDOW_FRAME_COLUMN_WIDTH (w
);
1643 /* Debugging code. */
1645 fprintf (stderr
, "+pv pt=%d vs=%d --> x=%d y=%d rt=%d rb=%d rh=%d vp=%d\n",
1646 charpos
, w
->vscroll
, *x
, *y
, *rtop
, *rbot
, *rowh
, *vpos
);
1648 fprintf (stderr
, "-pv pt=%d vs=%d\n", charpos
, w
->vscroll
);
1655 /* Return the next character from STR. Return in *LEN the length of
1656 the character. This is like STRING_CHAR_AND_LENGTH but never
1657 returns an invalid character. If we find one, we return a `?', but
1658 with the length of the invalid character. */
1661 string_char_and_length (const unsigned char *str
, int *len
)
1665 c
= STRING_CHAR_AND_LENGTH (str
, *len
);
1666 if (!CHAR_VALID_P (c
))
1667 /* We may not change the length here because other places in Emacs
1668 don't use this function, i.e. they silently accept invalid
1677 /* Given a position POS containing a valid character and byte position
1678 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1680 static struct text_pos
1681 string_pos_nchars_ahead (struct text_pos pos
, Lisp_Object string
, ptrdiff_t nchars
)
1683 eassert (STRINGP (string
) && nchars
>= 0);
1685 if (STRING_MULTIBYTE (string
))
1687 const unsigned char *p
= SDATA (string
) + BYTEPOS (pos
);
1692 string_char_and_length (p
, &len
);
1695 BYTEPOS (pos
) += len
;
1699 SET_TEXT_POS (pos
, CHARPOS (pos
) + nchars
, BYTEPOS (pos
) + nchars
);
1705 /* Value is the text position, i.e. character and byte position,
1706 for character position CHARPOS in STRING. */
1708 static struct text_pos
1709 string_pos (ptrdiff_t charpos
, Lisp_Object string
)
1711 struct text_pos pos
;
1712 eassert (STRINGP (string
));
1713 eassert (charpos
>= 0);
1714 SET_TEXT_POS (pos
, charpos
, string_char_to_byte (string
, charpos
));
1719 /* Value is a text position, i.e. character and byte position, for
1720 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1721 means recognize multibyte characters. */
1723 static struct text_pos
1724 c_string_pos (ptrdiff_t charpos
, const char *s
, bool multibyte_p
)
1726 struct text_pos pos
;
1728 eassert (s
!= NULL
);
1729 eassert (charpos
>= 0);
1735 SET_TEXT_POS (pos
, 0, 0);
1738 string_char_and_length ((const unsigned char *) s
, &len
);
1741 BYTEPOS (pos
) += len
;
1745 SET_TEXT_POS (pos
, charpos
, charpos
);
1751 /* Value is the number of characters in C string S. MULTIBYTE_P
1752 non-zero means recognize multibyte characters. */
1755 number_of_chars (const char *s
, bool multibyte_p
)
1761 ptrdiff_t rest
= strlen (s
);
1763 const unsigned char *p
= (const unsigned char *) s
;
1765 for (nchars
= 0; rest
> 0; ++nchars
)
1767 string_char_and_length (p
, &len
);
1768 rest
-= len
, p
+= len
;
1772 nchars
= strlen (s
);
1778 /* Compute byte position NEWPOS->bytepos corresponding to
1779 NEWPOS->charpos. POS is a known position in string STRING.
1780 NEWPOS->charpos must be >= POS.charpos. */
1783 compute_string_pos (struct text_pos
*newpos
, struct text_pos pos
, Lisp_Object string
)
1785 eassert (STRINGP (string
));
1786 eassert (CHARPOS (*newpos
) >= CHARPOS (pos
));
1788 if (STRING_MULTIBYTE (string
))
1789 *newpos
= string_pos_nchars_ahead (pos
, string
,
1790 CHARPOS (*newpos
) - CHARPOS (pos
));
1792 BYTEPOS (*newpos
) = CHARPOS (*newpos
);
1796 Return an estimation of the pixel height of mode or header lines on
1797 frame F. FACE_ID specifies what line's height to estimate. */
1800 estimate_mode_line_height (struct frame
*f
, enum face_id face_id
)
1802 #ifdef HAVE_WINDOW_SYSTEM
1803 if (FRAME_WINDOW_P (f
))
1805 int height
= FONT_HEIGHT (FRAME_FONT (f
));
1807 /* This function is called so early when Emacs starts that the face
1808 cache and mode line face are not yet initialized. */
1809 if (FRAME_FACE_CACHE (f
))
1811 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1815 height
= FONT_HEIGHT (face
->font
);
1816 if (face
->box_line_width
> 0)
1817 height
+= 2 * face
->box_line_width
;
1828 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1829 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1830 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1831 not force the value into range. */
1834 pixel_to_glyph_coords (struct frame
*f
, register int pix_x
, register int pix_y
,
1835 int *x
, int *y
, NativeRectangle
*bounds
, int noclip
)
1838 #ifdef HAVE_WINDOW_SYSTEM
1839 if (FRAME_WINDOW_P (f
))
1841 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1842 even for negative values. */
1844 pix_x
-= FRAME_COLUMN_WIDTH (f
) - 1;
1846 pix_y
-= FRAME_LINE_HEIGHT (f
) - 1;
1848 pix_x
= FRAME_PIXEL_X_TO_COL (f
, pix_x
);
1849 pix_y
= FRAME_PIXEL_Y_TO_LINE (f
, pix_y
);
1852 STORE_NATIVE_RECT (*bounds
,
1853 FRAME_COL_TO_PIXEL_X (f
, pix_x
),
1854 FRAME_LINE_TO_PIXEL_Y (f
, pix_y
),
1855 FRAME_COLUMN_WIDTH (f
) - 1,
1856 FRAME_LINE_HEIGHT (f
) - 1);
1862 else if (pix_x
> FRAME_TOTAL_COLS (f
))
1863 pix_x
= FRAME_TOTAL_COLS (f
);
1867 else if (pix_y
> FRAME_LINES (f
))
1868 pix_y
= FRAME_LINES (f
);
1878 /* Find the glyph under window-relative coordinates X/Y in window W.
1879 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1880 strings. Return in *HPOS and *VPOS the row and column number of
1881 the glyph found. Return in *AREA the glyph area containing X.
1882 Value is a pointer to the glyph found or null if X/Y is not on
1883 text, or we can't tell because W's current matrix is not up to
1888 x_y_to_hpos_vpos (struct window
*w
, int x
, int y
, int *hpos
, int *vpos
,
1889 int *dx
, int *dy
, int *area
)
1891 struct glyph
*glyph
, *end
;
1892 struct glyph_row
*row
= NULL
;
1895 /* Find row containing Y. Give up if some row is not enabled. */
1896 for (i
= 0; i
< w
->current_matrix
->nrows
; ++i
)
1898 row
= MATRIX_ROW (w
->current_matrix
, i
);
1899 if (!row
->enabled_p
)
1901 if (y
>= row
->y
&& y
< MATRIX_ROW_BOTTOM_Y (row
))
1908 /* Give up if Y is not in the window. */
1909 if (i
== w
->current_matrix
->nrows
)
1912 /* Get the glyph area containing X. */
1913 if (w
->pseudo_window_p
)
1920 if (x
< window_box_left_offset (w
, TEXT_AREA
))
1922 *area
= LEFT_MARGIN_AREA
;
1923 x0
= window_box_left_offset (w
, LEFT_MARGIN_AREA
);
1925 else if (x
< window_box_right_offset (w
, TEXT_AREA
))
1928 x0
= window_box_left_offset (w
, TEXT_AREA
) + min (row
->x
, 0);
1932 *area
= RIGHT_MARGIN_AREA
;
1933 x0
= window_box_left_offset (w
, RIGHT_MARGIN_AREA
);
1937 /* Find glyph containing X. */
1938 glyph
= row
->glyphs
[*area
];
1939 end
= glyph
+ row
->used
[*area
];
1941 while (glyph
< end
&& x
>= glyph
->pixel_width
)
1943 x
-= glyph
->pixel_width
;
1953 *dy
= y
- (row
->y
+ row
->ascent
- glyph
->ascent
);
1956 *hpos
= glyph
- row
->glyphs
[*area
];
1960 /* Convert frame-relative x/y to coordinates relative to window W.
1961 Takes pseudo-windows into account. */
1964 frame_to_window_pixel_xy (struct window
*w
, int *x
, int *y
)
1966 if (w
->pseudo_window_p
)
1968 /* A pseudo-window is always full-width, and starts at the
1969 left edge of the frame, plus a frame border. */
1970 struct frame
*f
= XFRAME (w
->frame
);
1971 *x
-= FRAME_INTERNAL_BORDER_WIDTH (f
);
1972 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
1976 *x
-= WINDOW_LEFT_EDGE_X (w
);
1977 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
1981 #ifdef HAVE_WINDOW_SYSTEM
1984 Return in RECTS[] at most N clipping rectangles for glyph string S.
1985 Return the number of stored rectangles. */
1988 get_glyph_string_clip_rects (struct glyph_string
*s
, NativeRectangle
*rects
, int n
)
1995 if (s
->row
->full_width_p
)
1997 /* Draw full-width. X coordinates are relative to S->w->left_col. */
1998 r
.x
= WINDOW_LEFT_EDGE_X (s
->w
);
1999 r
.width
= WINDOW_TOTAL_WIDTH (s
->w
);
2001 /* Unless displaying a mode or menu bar line, which are always
2002 fully visible, clip to the visible part of the row. */
2003 if (s
->w
->pseudo_window_p
)
2004 r
.height
= s
->row
->visible_height
;
2006 r
.height
= s
->height
;
2010 /* This is a text line that may be partially visible. */
2011 r
.x
= window_box_left (s
->w
, s
->area
);
2012 r
.width
= window_box_width (s
->w
, s
->area
);
2013 r
.height
= s
->row
->visible_height
;
2017 if (r
.x
< s
->clip_head
->x
)
2019 if (r
.width
>= s
->clip_head
->x
- r
.x
)
2020 r
.width
-= s
->clip_head
->x
- r
.x
;
2023 r
.x
= s
->clip_head
->x
;
2026 if (r
.x
+ r
.width
> s
->clip_tail
->x
+ s
->clip_tail
->background_width
)
2028 if (s
->clip_tail
->x
+ s
->clip_tail
->background_width
>= r
.x
)
2029 r
.width
= s
->clip_tail
->x
+ s
->clip_tail
->background_width
- r
.x
;
2034 /* If S draws overlapping rows, it's sufficient to use the top and
2035 bottom of the window for clipping because this glyph string
2036 intentionally draws over other lines. */
2037 if (s
->for_overlaps
)
2039 r
.y
= WINDOW_HEADER_LINE_HEIGHT (s
->w
);
2040 r
.height
= window_text_bottom_y (s
->w
) - r
.y
;
2042 /* Alas, the above simple strategy does not work for the
2043 environments with anti-aliased text: if the same text is
2044 drawn onto the same place multiple times, it gets thicker.
2045 If the overlap we are processing is for the erased cursor, we
2046 take the intersection with the rectangle of the cursor. */
2047 if (s
->for_overlaps
& OVERLAPS_ERASED_CURSOR
)
2049 XRectangle rc
, r_save
= r
;
2051 rc
.x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (s
->w
, s
->w
->phys_cursor
.x
);
2052 rc
.y
= s
->w
->phys_cursor
.y
;
2053 rc
.width
= s
->w
->phys_cursor_width
;
2054 rc
.height
= s
->w
->phys_cursor_height
;
2056 x_intersect_rectangles (&r_save
, &rc
, &r
);
2061 /* Don't use S->y for clipping because it doesn't take partially
2062 visible lines into account. For example, it can be negative for
2063 partially visible lines at the top of a window. */
2064 if (!s
->row
->full_width_p
2065 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s
->w
, s
->row
))
2066 r
.y
= WINDOW_HEADER_LINE_HEIGHT (s
->w
);
2068 r
.y
= max (0, s
->row
->y
);
2071 r
.y
= WINDOW_TO_FRAME_PIXEL_Y (s
->w
, r
.y
);
2073 /* If drawing the cursor, don't let glyph draw outside its
2074 advertised boundaries. Cleartype does this under some circumstances. */
2075 if (s
->hl
== DRAW_CURSOR
)
2077 struct glyph
*glyph
= s
->first_glyph
;
2082 r
.width
-= s
->x
- r
.x
;
2085 r
.width
= min (r
.width
, glyph
->pixel_width
);
2087 /* If r.y is below window bottom, ensure that we still see a cursor. */
2088 height
= min (glyph
->ascent
+ glyph
->descent
,
2089 min (FRAME_LINE_HEIGHT (s
->f
), s
->row
->visible_height
));
2090 max_y
= window_text_bottom_y (s
->w
) - height
;
2091 max_y
= WINDOW_TO_FRAME_PIXEL_Y (s
->w
, max_y
);
2092 if (s
->ybase
- glyph
->ascent
> max_y
)
2099 /* Don't draw cursor glyph taller than our actual glyph. */
2100 height
= max (FRAME_LINE_HEIGHT (s
->f
), glyph
->ascent
+ glyph
->descent
);
2101 if (height
< r
.height
)
2103 max_y
= r
.y
+ r
.height
;
2104 r
.y
= min (max_y
, max (r
.y
, s
->ybase
+ glyph
->descent
- height
));
2105 r
.height
= min (max_y
- r
.y
, height
);
2112 XRectangle r_save
= r
;
2114 if (! x_intersect_rectangles (&r_save
, s
->row
->clip
, &r
))
2118 if ((s
->for_overlaps
& OVERLAPS_BOTH
) == 0
2119 || ((s
->for_overlaps
& OVERLAPS_BOTH
) == OVERLAPS_BOTH
&& n
== 1))
2121 #ifdef CONVERT_FROM_XRECT
2122 CONVERT_FROM_XRECT (r
, *rects
);
2130 /* If we are processing overlapping and allowed to return
2131 multiple clipping rectangles, we exclude the row of the glyph
2132 string from the clipping rectangle. This is to avoid drawing
2133 the same text on the environment with anti-aliasing. */
2134 #ifdef CONVERT_FROM_XRECT
2137 XRectangle
*rs
= rects
;
2139 int i
= 0, row_y
= WINDOW_TO_FRAME_PIXEL_Y (s
->w
, s
->row
->y
);
2141 if (s
->for_overlaps
& OVERLAPS_PRED
)
2144 if (r
.y
+ r
.height
> row_y
)
2147 rs
[i
].height
= row_y
- r
.y
;
2153 if (s
->for_overlaps
& OVERLAPS_SUCC
)
2156 if (r
.y
< row_y
+ s
->row
->visible_height
)
2158 if (r
.y
+ r
.height
> row_y
+ s
->row
->visible_height
)
2160 rs
[i
].y
= row_y
+ s
->row
->visible_height
;
2161 rs
[i
].height
= r
.y
+ r
.height
- rs
[i
].y
;
2170 #ifdef CONVERT_FROM_XRECT
2171 for (i
= 0; i
< n
; i
++)
2172 CONVERT_FROM_XRECT (rs
[i
], rects
[i
]);
2179 Return in *NR the clipping rectangle for glyph string S. */
2182 get_glyph_string_clip_rect (struct glyph_string
*s
, NativeRectangle
*nr
)
2184 get_glyph_string_clip_rects (s
, nr
, 1);
2189 Return the position and height of the phys cursor in window W.
2190 Set w->phys_cursor_width to width of phys cursor.
2194 get_phys_cursor_geometry (struct window
*w
, struct glyph_row
*row
,
2195 struct glyph
*glyph
, int *xp
, int *yp
, int *heightp
)
2197 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
2198 int x
, y
, wd
, h
, h0
, y0
;
2200 /* Compute the width of the rectangle to draw. If on a stretch
2201 glyph, and `x-stretch-block-cursor' is nil, don't draw a
2202 rectangle as wide as the glyph, but use a canonical character
2204 wd
= glyph
->pixel_width
- 1;
2205 #if defined (HAVE_NTGUI) || defined (HAVE_NS)
2209 x
= w
->phys_cursor
.x
;
2216 if (glyph
->type
== STRETCH_GLYPH
2217 && !x_stretch_cursor_p
)
2218 wd
= min (FRAME_COLUMN_WIDTH (f
), wd
);
2219 w
->phys_cursor_width
= wd
;
2221 y
= w
->phys_cursor
.y
+ row
->ascent
- glyph
->ascent
;
2223 /* If y is below window bottom, ensure that we still see a cursor. */
2224 h0
= min (FRAME_LINE_HEIGHT (f
), row
->visible_height
);
2226 h
= max (h0
, glyph
->ascent
+ glyph
->descent
);
2227 h0
= min (h0
, glyph
->ascent
+ glyph
->descent
);
2229 y0
= WINDOW_HEADER_LINE_HEIGHT (w
);
2232 h
= max (h
- (y0
- y
) + 1, h0
);
2237 y0
= window_text_bottom_y (w
) - h0
;
2245 *xp
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, x
);
2246 *yp
= WINDOW_TO_FRAME_PIXEL_Y (w
, y
);
2251 * Remember which glyph the mouse is over.
2255 remember_mouse_glyph (struct frame
*f
, int gx
, int gy
, NativeRectangle
*rect
)
2259 struct glyph_row
*r
, *gr
, *end_row
;
2260 enum window_part part
;
2261 enum glyph_row_area area
;
2262 int x
, y
, width
, height
;
2264 /* Try to determine frame pixel position and size of the glyph under
2265 frame pixel coordinates X/Y on frame F. */
2267 if (!f
->glyphs_initialized_p
2268 || (window
= window_from_coordinates (f
, gx
, gy
, &part
, 0),
2271 width
= FRAME_SMALLEST_CHAR_WIDTH (f
);
2272 height
= FRAME_SMALLEST_FONT_HEIGHT (f
);
2276 w
= XWINDOW (window
);
2277 width
= WINDOW_FRAME_COLUMN_WIDTH (w
);
2278 height
= WINDOW_FRAME_LINE_HEIGHT (w
);
2280 x
= window_relative_x_coord (w
, part
, gx
);
2281 y
= gy
- WINDOW_TOP_EDGE_Y (w
);
2283 r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
2284 end_row
= MATRIX_BOTTOM_TEXT_ROW (w
->current_matrix
, w
);
2286 if (w
->pseudo_window_p
)
2289 part
= ON_MODE_LINE
; /* Don't adjust margin. */
2295 case ON_LEFT_MARGIN
:
2296 area
= LEFT_MARGIN_AREA
;
2299 case ON_RIGHT_MARGIN
:
2300 area
= RIGHT_MARGIN_AREA
;
2303 case ON_HEADER_LINE
:
2305 gr
= (part
== ON_HEADER_LINE
2306 ? MATRIX_HEADER_LINE_ROW (w
->current_matrix
)
2307 : MATRIX_MODE_LINE_ROW (w
->current_matrix
));
2310 goto text_glyph_row_found
;
2317 for (; r
<= end_row
&& r
->enabled_p
; ++r
)
2318 if (r
->y
+ r
->height
> y
)
2324 text_glyph_row_found
:
2327 struct glyph
*g
= gr
->glyphs
[area
];
2328 struct glyph
*end
= g
+ gr
->used
[area
];
2330 height
= gr
->height
;
2331 for (gx
= gr
->x
; g
< end
; gx
+= g
->pixel_width
, ++g
)
2332 if (gx
+ g
->pixel_width
> x
)
2337 if (g
->type
== IMAGE_GLYPH
)
2339 /* Don't remember when mouse is over image, as
2340 image may have hot-spots. */
2341 STORE_NATIVE_RECT (*rect
, 0, 0, 0, 0);
2344 width
= g
->pixel_width
;
2348 /* Use nominal char spacing at end of line. */
2350 gx
+= (x
/ width
) * width
;
2353 if (part
!= ON_MODE_LINE
&& part
!= ON_HEADER_LINE
)
2354 gx
+= window_box_left_offset (w
, area
);
2358 /* Use nominal line height at end of window. */
2359 gx
= (x
/ width
) * width
;
2361 gy
+= (y
/ height
) * height
;
2365 case ON_LEFT_FRINGE
:
2366 gx
= (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
2367 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w
)
2368 : window_box_right_offset (w
, LEFT_MARGIN_AREA
));
2369 width
= WINDOW_LEFT_FRINGE_WIDTH (w
);
2372 case ON_RIGHT_FRINGE
:
2373 gx
= (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
2374 ? window_box_right_offset (w
, RIGHT_MARGIN_AREA
)
2375 : window_box_right_offset (w
, TEXT_AREA
));
2376 width
= WINDOW_RIGHT_FRINGE_WIDTH (w
);
2380 gx
= (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w
)
2382 : (window_box_right_offset (w
, RIGHT_MARGIN_AREA
)
2383 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
2384 ? WINDOW_RIGHT_FRINGE_WIDTH (w
)
2386 width
= WINDOW_SCROLL_BAR_AREA_WIDTH (w
);
2390 for (; r
<= end_row
&& r
->enabled_p
; ++r
)
2391 if (r
->y
+ r
->height
> y
)
2398 height
= gr
->height
;
2401 /* Use nominal line height at end of window. */
2403 gy
+= (y
/ height
) * height
;
2410 /* If there is no glyph under the mouse, then we divide the screen
2411 into a grid of the smallest glyph in the frame, and use that
2414 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to
2415 round down even for negative values. */
2421 gx
= (gx
/ width
) * width
;
2422 gy
= (gy
/ height
) * height
;
2427 gx
+= WINDOW_LEFT_EDGE_X (w
);
2428 gy
+= WINDOW_TOP_EDGE_Y (w
);
2431 STORE_NATIVE_RECT (*rect
, gx
, gy
, width
, height
);
2433 /* Visible feedback for debugging. */
2436 XDrawRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2437 f
->output_data
.x
->normal_gc
,
2438 gx
, gy
, width
, height
);
2444 #endif /* HAVE_WINDOW_SYSTEM */
2447 adjust_window_ends (struct window
*w
, struct glyph_row
*row
, bool current
)
2450 w
->window_end_pos
= Z
- MATRIX_ROW_END_CHARPOS (row
);
2451 w
->window_end_bytepos
= Z_BYTE
- MATRIX_ROW_END_BYTEPOS (row
);
2453 = MATRIX_ROW_VPOS (row
, current
? w
->current_matrix
: w
->desired_matrix
);
2456 /***********************************************************************
2457 Lisp form evaluation
2458 ***********************************************************************/
2460 /* Error handler for safe_eval and safe_call. */
2463 safe_eval_handler (Lisp_Object arg
, ptrdiff_t nargs
, Lisp_Object
*args
)
2465 add_to_log ("Error during redisplay: %S signaled %S",
2466 Flist (nargs
, args
), arg
);
2470 /* Call function FUNC with the rest of NARGS - 1 arguments
2471 following. Return the result, or nil if something went
2472 wrong. Prevent redisplay during the evaluation. */
2475 safe_call (ptrdiff_t nargs
, Lisp_Object func
, ...)
2479 if (inhibit_eval_during_redisplay
)
2485 ptrdiff_t count
= SPECPDL_INDEX ();
2486 struct gcpro gcpro1
;
2487 Lisp_Object
*args
= alloca (nargs
* word_size
);
2490 va_start (ap
, func
);
2491 for (i
= 1; i
< nargs
; i
++)
2492 args
[i
] = va_arg (ap
, Lisp_Object
);
2496 gcpro1
.nvars
= nargs
;
2497 specbind (Qinhibit_redisplay
, Qt
);
2498 /* Use Qt to ensure debugger does not run,
2499 so there is no possibility of wanting to redisplay. */
2500 val
= internal_condition_case_n (Ffuncall
, nargs
, args
, Qt
,
2503 val
= unbind_to (count
, val
);
2510 /* Call function FN with one argument ARG.
2511 Return the result, or nil if something went wrong. */
2514 safe_call1 (Lisp_Object fn
, Lisp_Object arg
)
2516 return safe_call (2, fn
, arg
);
2519 static Lisp_Object Qeval
;
2522 safe_eval (Lisp_Object sexpr
)
2524 return safe_call1 (Qeval
, sexpr
);
2527 /* Call function FN with two arguments ARG1 and ARG2.
2528 Return the result, or nil if something went wrong. */
2531 safe_call2 (Lisp_Object fn
, Lisp_Object arg1
, Lisp_Object arg2
)
2533 return safe_call (3, fn
, arg1
, arg2
);
2538 /***********************************************************************
2540 ***********************************************************************/
2544 /* Define CHECK_IT to perform sanity checks on iterators.
2545 This is for debugging. It is too slow to do unconditionally. */
2548 check_it (struct it
*it
)
2550 if (it
->method
== GET_FROM_STRING
)
2552 eassert (STRINGP (it
->string
));
2553 eassert (IT_STRING_CHARPOS (*it
) >= 0);
2557 eassert (IT_STRING_CHARPOS (*it
) < 0);
2558 if (it
->method
== GET_FROM_BUFFER
)
2560 /* Check that character and byte positions agree. */
2561 eassert (IT_CHARPOS (*it
) == BYTE_TO_CHAR (IT_BYTEPOS (*it
)));
2566 eassert (it
->current
.dpvec_index
>= 0);
2568 eassert (it
->current
.dpvec_index
< 0);
2571 #define CHECK_IT(IT) check_it ((IT))
2575 #define CHECK_IT(IT) (void) 0
2580 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
2582 /* Check that the window end of window W is what we expect it
2583 to be---the last row in the current matrix displaying text. */
2586 check_window_end (struct window
*w
)
2588 if (!MINI_WINDOW_P (w
) && w
->window_end_valid
)
2590 struct glyph_row
*row
;
2591 eassert ((row
= MATRIX_ROW (w
->current_matrix
, w
->window_end_vpos
),
2593 || MATRIX_ROW_DISPLAYS_TEXT_P (row
)
2594 || MATRIX_ROW_VPOS (row
, w
->current_matrix
) == 0));
2598 #define CHECK_WINDOW_END(W) check_window_end ((W))
2602 #define CHECK_WINDOW_END(W) (void) 0
2604 #endif /* GLYPH_DEBUG and ENABLE_CHECKING */
2606 /* Return mark position if current buffer has the region of non-zero length,
2610 markpos_of_region (void)
2612 if (!NILP (Vtransient_mark_mode
)
2613 && !NILP (BVAR (current_buffer
, mark_active
))
2614 && XMARKER (BVAR (current_buffer
, mark
))->buffer
!= NULL
)
2616 ptrdiff_t markpos
= XMARKER (BVAR (current_buffer
, mark
))->charpos
;
2624 /***********************************************************************
2625 Iterator initialization
2626 ***********************************************************************/
2628 /* Initialize IT for displaying current_buffer in window W, starting
2629 at character position CHARPOS. CHARPOS < 0 means that no buffer
2630 position is specified which is useful when the iterator is assigned
2631 a position later. BYTEPOS is the byte position corresponding to
2634 If ROW is not null, calls to produce_glyphs with IT as parameter
2635 will produce glyphs in that row.
2637 BASE_FACE_ID is the id of a base face to use. It must be one of
2638 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2639 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2640 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2642 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2643 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2644 will be initialized to use the corresponding mode line glyph row of
2645 the desired matrix of W. */
2648 init_iterator (struct it
*it
, struct window
*w
,
2649 ptrdiff_t charpos
, ptrdiff_t bytepos
,
2650 struct glyph_row
*row
, enum face_id base_face_id
)
2653 enum face_id remapped_base_face_id
= base_face_id
;
2655 /* Some precondition checks. */
2656 eassert (w
!= NULL
&& it
!= NULL
);
2657 eassert (charpos
< 0 || (charpos
>= BUF_BEG (current_buffer
)
2660 /* If face attributes have been changed since the last redisplay,
2661 free realized faces now because they depend on face definitions
2662 that might have changed. Don't free faces while there might be
2663 desired matrices pending which reference these faces. */
2664 if (face_change_count
&& !inhibit_free_realized_faces
)
2666 face_change_count
= 0;
2667 free_all_realized_faces (Qnil
);
2670 /* Perhaps remap BASE_FACE_ID to a user-specified alternative. */
2671 if (! NILP (Vface_remapping_alist
))
2672 remapped_base_face_id
2673 = lookup_basic_face (XFRAME (w
->frame
), base_face_id
);
2675 /* Use one of the mode line rows of W's desired matrix if
2679 if (base_face_id
== MODE_LINE_FACE_ID
2680 || base_face_id
== MODE_LINE_INACTIVE_FACE_ID
)
2681 row
= MATRIX_MODE_LINE_ROW (w
->desired_matrix
);
2682 else if (base_face_id
== HEADER_LINE_FACE_ID
)
2683 row
= MATRIX_HEADER_LINE_ROW (w
->desired_matrix
);
2687 memset (it
, 0, sizeof *it
);
2688 it
->current
.overlay_string_index
= -1;
2689 it
->current
.dpvec_index
= -1;
2690 it
->base_face_id
= remapped_base_face_id
;
2692 IT_STRING_CHARPOS (*it
) = IT_STRING_BYTEPOS (*it
) = -1;
2693 it
->paragraph_embedding
= L2R
;
2694 it
->bidi_it
.string
.lstring
= Qnil
;
2695 it
->bidi_it
.string
.s
= NULL
;
2696 it
->bidi_it
.string
.bufpos
= 0;
2699 /* The window in which we iterate over current_buffer: */
2700 XSETWINDOW (it
->window
, w
);
2702 it
->f
= XFRAME (w
->frame
);
2706 /* Extra space between lines (on window systems only). */
2707 if (base_face_id
== DEFAULT_FACE_ID
2708 && FRAME_WINDOW_P (it
->f
))
2710 if (NATNUMP (BVAR (current_buffer
, extra_line_spacing
)))
2711 it
->extra_line_spacing
= XFASTINT (BVAR (current_buffer
, extra_line_spacing
));
2712 else if (FLOATP (BVAR (current_buffer
, extra_line_spacing
)))
2713 it
->extra_line_spacing
= (XFLOAT_DATA (BVAR (current_buffer
, extra_line_spacing
))
2714 * FRAME_LINE_HEIGHT (it
->f
));
2715 else if (it
->f
->extra_line_spacing
> 0)
2716 it
->extra_line_spacing
= it
->f
->extra_line_spacing
;
2717 it
->max_extra_line_spacing
= 0;
2720 /* If realized faces have been removed, e.g. because of face
2721 attribute changes of named faces, recompute them. When running
2722 in batch mode, the face cache of the initial frame is null. If
2723 we happen to get called, make a dummy face cache. */
2724 if (FRAME_FACE_CACHE (it
->f
) == NULL
)
2725 init_frame_faces (it
->f
);
2726 if (FRAME_FACE_CACHE (it
->f
)->used
== 0)
2727 recompute_basic_faces (it
->f
);
2729 /* Current value of the `slice', `space-width', and 'height' properties. */
2730 it
->slice
.x
= it
->slice
.y
= it
->slice
.width
= it
->slice
.height
= Qnil
;
2731 it
->space_width
= Qnil
;
2732 it
->font_height
= Qnil
;
2733 it
->override_ascent
= -1;
2735 /* Are control characters displayed as `^C'? */
2736 it
->ctl_arrow_p
= !NILP (BVAR (current_buffer
, ctl_arrow
));
2738 /* -1 means everything between a CR and the following line end
2739 is invisible. >0 means lines indented more than this value are
2741 it
->selective
= (INTEGERP (BVAR (current_buffer
, selective_display
))
2743 (-1, XINT (BVAR (current_buffer
, selective_display
)),
2745 : (!NILP (BVAR (current_buffer
, selective_display
))
2747 it
->selective_display_ellipsis_p
2748 = !NILP (BVAR (current_buffer
, selective_display_ellipses
));
2750 /* Display table to use. */
2751 it
->dp
= window_display_table (w
);
2753 /* Are multibyte characters enabled in current_buffer? */
2754 it
->multibyte_p
= !NILP (BVAR (current_buffer
, enable_multibyte_characters
));
2756 /* If visible region is of non-zero length, set IT->region_beg_charpos
2757 and IT->region_end_charpos to the start and end of a visible region
2758 in window IT->w. Set both to -1 to indicate no region. */
2759 markpos
= markpos_of_region ();
2761 /* Maybe highlight only in selected window. */
2762 && (/* Either show region everywhere. */
2763 highlight_nonselected_windows
2764 /* Or show region in the selected window. */
2765 || w
== XWINDOW (selected_window
)
2766 /* Or show the region if we are in the mini-buffer and W is
2767 the window the mini-buffer refers to. */
2768 || (MINI_WINDOW_P (XWINDOW (selected_window
))
2769 && WINDOWP (minibuf_selected_window
)
2770 && w
== XWINDOW (minibuf_selected_window
))))
2772 it
->region_beg_charpos
= min (PT
, markpos
);
2773 it
->region_end_charpos
= max (PT
, markpos
);
2776 it
->region_beg_charpos
= it
->region_end_charpos
= -1;
2778 /* Get the position at which the redisplay_end_trigger hook should
2779 be run, if it is to be run at all. */
2780 if (MARKERP (w
->redisplay_end_trigger
)
2781 && XMARKER (w
->redisplay_end_trigger
)->buffer
!= 0)
2782 it
->redisplay_end_trigger_charpos
2783 = marker_position (w
->redisplay_end_trigger
);
2784 else if (INTEGERP (w
->redisplay_end_trigger
))
2785 it
->redisplay_end_trigger_charpos
=
2786 clip_to_bounds (PTRDIFF_MIN
, XINT (w
->redisplay_end_trigger
), PTRDIFF_MAX
);
2788 it
->tab_width
= SANE_TAB_WIDTH (current_buffer
);
2790 /* Are lines in the display truncated? */
2791 if (base_face_id
!= DEFAULT_FACE_ID
2793 || (! WINDOW_FULL_WIDTH_P (it
->w
)
2794 && ((!NILP (Vtruncate_partial_width_windows
)
2795 && !INTEGERP (Vtruncate_partial_width_windows
))
2796 || (INTEGERP (Vtruncate_partial_width_windows
)
2797 && (WINDOW_TOTAL_COLS (it
->w
)
2798 < XINT (Vtruncate_partial_width_windows
))))))
2799 it
->line_wrap
= TRUNCATE
;
2800 else if (NILP (BVAR (current_buffer
, truncate_lines
)))
2801 it
->line_wrap
= NILP (BVAR (current_buffer
, word_wrap
))
2802 ? WINDOW_WRAP
: WORD_WRAP
;
2804 it
->line_wrap
= TRUNCATE
;
2806 /* Get dimensions of truncation and continuation glyphs. These are
2807 displayed as fringe bitmaps under X, but we need them for such
2808 frames when the fringes are turned off. But leave the dimensions
2809 zero for tooltip frames, as these glyphs look ugly there and also
2810 sabotage calculations of tooltip dimensions in x-show-tip. */
2811 #ifdef HAVE_WINDOW_SYSTEM
2812 if (!(FRAME_WINDOW_P (it
->f
)
2813 && FRAMEP (tip_frame
)
2814 && it
->f
== XFRAME (tip_frame
)))
2817 if (it
->line_wrap
== TRUNCATE
)
2819 /* We will need the truncation glyph. */
2820 eassert (it
->glyph_row
== NULL
);
2821 produce_special_glyphs (it
, IT_TRUNCATION
);
2822 it
->truncation_pixel_width
= it
->pixel_width
;
2826 /* We will need the continuation glyph. */
2827 eassert (it
->glyph_row
== NULL
);
2828 produce_special_glyphs (it
, IT_CONTINUATION
);
2829 it
->continuation_pixel_width
= it
->pixel_width
;
2833 /* Reset these values to zero because the produce_special_glyphs
2834 above has changed them. */
2835 it
->pixel_width
= it
->ascent
= it
->descent
= 0;
2836 it
->phys_ascent
= it
->phys_descent
= 0;
2838 /* Set this after getting the dimensions of truncation and
2839 continuation glyphs, so that we don't produce glyphs when calling
2840 produce_special_glyphs, above. */
2841 it
->glyph_row
= row
;
2842 it
->area
= TEXT_AREA
;
2844 /* Forget any previous info about this row being reversed. */
2846 it
->glyph_row
->reversed_p
= 0;
2848 /* Get the dimensions of the display area. The display area
2849 consists of the visible window area plus a horizontally scrolled
2850 part to the left of the window. All x-values are relative to the
2851 start of this total display area. */
2852 if (base_face_id
!= DEFAULT_FACE_ID
)
2854 /* Mode lines, menu bar in terminal frames. */
2855 it
->first_visible_x
= 0;
2856 it
->last_visible_x
= WINDOW_TOTAL_WIDTH (w
);
2860 it
->first_visible_x
=
2861 window_hscroll_limited (it
->w
, it
->f
) * FRAME_COLUMN_WIDTH (it
->f
);
2862 it
->last_visible_x
= (it
->first_visible_x
2863 + window_box_width (w
, TEXT_AREA
));
2865 /* If we truncate lines, leave room for the truncation glyph(s) at
2866 the right margin. Otherwise, leave room for the continuation
2867 glyph(s). Done only if the window has no fringes. Since we
2868 don't know at this point whether there will be any R2L lines in
2869 the window, we reserve space for truncation/continuation glyphs
2870 even if only one of the fringes is absent. */
2871 if (WINDOW_RIGHT_FRINGE_WIDTH (it
->w
) == 0
2872 || (it
->bidi_p
&& WINDOW_LEFT_FRINGE_WIDTH (it
->w
) == 0))
2874 if (it
->line_wrap
== TRUNCATE
)
2875 it
->last_visible_x
-= it
->truncation_pixel_width
;
2877 it
->last_visible_x
-= it
->continuation_pixel_width
;
2880 it
->header_line_p
= WINDOW_WANTS_HEADER_LINE_P (w
);
2881 it
->current_y
= WINDOW_HEADER_LINE_HEIGHT (w
) + w
->vscroll
;
2884 /* Leave room for a border glyph. */
2885 if (!FRAME_WINDOW_P (it
->f
)
2886 && !WINDOW_RIGHTMOST_P (it
->w
))
2887 it
->last_visible_x
-= 1;
2889 it
->last_visible_y
= window_text_bottom_y (w
);
2891 /* For mode lines and alike, arrange for the first glyph having a
2892 left box line if the face specifies a box. */
2893 if (base_face_id
!= DEFAULT_FACE_ID
)
2897 it
->face_id
= remapped_base_face_id
;
2899 /* If we have a boxed mode line, make the first character appear
2900 with a left box line. */
2901 face
= FACE_FROM_ID (it
->f
, remapped_base_face_id
);
2902 if (face
->box
!= FACE_NO_BOX
)
2903 it
->start_of_box_run_p
= 1;
2906 /* If a buffer position was specified, set the iterator there,
2907 getting overlays and face properties from that position. */
2908 if (charpos
>= BUF_BEG (current_buffer
))
2910 it
->end_charpos
= ZV
;
2911 eassert (charpos
== BYTE_TO_CHAR (bytepos
));
2912 IT_CHARPOS (*it
) = charpos
;
2913 IT_BYTEPOS (*it
) = bytepos
;
2915 /* We will rely on `reseat' to set this up properly, via
2916 handle_face_prop. */
2917 it
->face_id
= it
->base_face_id
;
2919 it
->start
= it
->current
;
2920 /* Do we need to reorder bidirectional text? Not if this is a
2921 unibyte buffer: by definition, none of the single-byte
2922 characters are strong R2L, so no reordering is needed. And
2923 bidi.c doesn't support unibyte buffers anyway. Also, don't
2924 reorder while we are loading loadup.el, since the tables of
2925 character properties needed for reordering are not yet
2929 && !NILP (BVAR (current_buffer
, bidi_display_reordering
))
2932 /* If we are to reorder bidirectional text, init the bidi
2936 /* Note the paragraph direction that this buffer wants to
2938 if (EQ (BVAR (current_buffer
, bidi_paragraph_direction
),
2940 it
->paragraph_embedding
= L2R
;
2941 else if (EQ (BVAR (current_buffer
, bidi_paragraph_direction
),
2943 it
->paragraph_embedding
= R2L
;
2945 it
->paragraph_embedding
= NEUTRAL_DIR
;
2946 bidi_unshelve_cache (NULL
, 0);
2947 bidi_init_it (charpos
, IT_BYTEPOS (*it
), FRAME_WINDOW_P (it
->f
),
2951 /* Compute faces etc. */
2952 reseat (it
, it
->current
.pos
, 1);
2959 /* Initialize IT for the display of window W with window start POS. */
2962 start_display (struct it
*it
, struct window
*w
, struct text_pos pos
)
2964 struct glyph_row
*row
;
2965 int first_vpos
= WINDOW_WANTS_HEADER_LINE_P (w
) ? 1 : 0;
2967 row
= w
->desired_matrix
->rows
+ first_vpos
;
2968 init_iterator (it
, w
, CHARPOS (pos
), BYTEPOS (pos
), row
, DEFAULT_FACE_ID
);
2969 it
->first_vpos
= first_vpos
;
2971 /* Don't reseat to previous visible line start if current start
2972 position is in a string or image. */
2973 if (it
->method
== GET_FROM_BUFFER
&& it
->line_wrap
!= TRUNCATE
)
2975 int start_at_line_beg_p
;
2976 int first_y
= it
->current_y
;
2978 /* If window start is not at a line start, skip forward to POS to
2979 get the correct continuation lines width. */
2980 start_at_line_beg_p
= (CHARPOS (pos
) == BEGV
2981 || FETCH_BYTE (BYTEPOS (pos
) - 1) == '\n');
2982 if (!start_at_line_beg_p
)
2986 reseat_at_previous_visible_line_start (it
);
2987 move_it_to (it
, CHARPOS (pos
), -1, -1, -1, MOVE_TO_POS
);
2989 new_x
= it
->current_x
+ it
->pixel_width
;
2991 /* If lines are continued, this line may end in the middle
2992 of a multi-glyph character (e.g. a control character
2993 displayed as \003, or in the middle of an overlay
2994 string). In this case move_it_to above will not have
2995 taken us to the start of the continuation line but to the
2996 end of the continued line. */
2997 if (it
->current_x
> 0
2998 && it
->line_wrap
!= TRUNCATE
/* Lines are continued. */
2999 && (/* And glyph doesn't fit on the line. */
3000 new_x
> it
->last_visible_x
3001 /* Or it fits exactly and we're on a window
3003 || (new_x
== it
->last_visible_x
3004 && FRAME_WINDOW_P (it
->f
)
3005 && ((it
->bidi_p
&& it
->bidi_it
.paragraph_dir
== R2L
)
3006 ? WINDOW_LEFT_FRINGE_WIDTH (it
->w
)
3007 : WINDOW_RIGHT_FRINGE_WIDTH (it
->w
)))))
3009 if ((it
->current
.dpvec_index
>= 0
3010 || it
->current
.overlay_string_index
>= 0)
3011 /* If we are on a newline from a display vector or
3012 overlay string, then we are already at the end of
3013 a screen line; no need to go to the next line in
3014 that case, as this line is not really continued.
3015 (If we do go to the next line, C-e will not DTRT.) */
3018 set_iterator_to_next (it
, 1);
3019 move_it_in_display_line_to (it
, -1, -1, 0);
3022 it
->continuation_lines_width
+= it
->current_x
;
3024 /* If the character at POS is displayed via a display
3025 vector, move_it_to above stops at the final glyph of
3026 IT->dpvec. To make the caller redisplay that character
3027 again (a.k.a. start at POS), we need to reset the
3028 dpvec_index to the beginning of IT->dpvec. */
3029 else if (it
->current
.dpvec_index
>= 0)
3030 it
->current
.dpvec_index
= 0;
3032 /* We're starting a new display line, not affected by the
3033 height of the continued line, so clear the appropriate
3034 fields in the iterator structure. */
3035 it
->max_ascent
= it
->max_descent
= 0;
3036 it
->max_phys_ascent
= it
->max_phys_descent
= 0;
3038 it
->current_y
= first_y
;
3040 it
->current_x
= it
->hpos
= 0;
3046 /* Return 1 if POS is a position in ellipses displayed for invisible
3047 text. W is the window we display, for text property lookup. */
3050 in_ellipses_for_invisible_text_p (struct display_pos
*pos
, struct window
*w
)
3052 Lisp_Object prop
, window
;
3054 ptrdiff_t charpos
= CHARPOS (pos
->pos
);
3056 /* If POS specifies a position in a display vector, this might
3057 be for an ellipsis displayed for invisible text. We won't
3058 get the iterator set up for delivering that ellipsis unless
3059 we make sure that it gets aware of the invisible text. */
3060 if (pos
->dpvec_index
>= 0
3061 && pos
->overlay_string_index
< 0
3062 && CHARPOS (pos
->string_pos
) < 0
3064 && (XSETWINDOW (window
, w
),
3065 prop
= Fget_char_property (make_number (charpos
),
3066 Qinvisible
, window
),
3067 !TEXT_PROP_MEANS_INVISIBLE (prop
)))
3069 prop
= Fget_char_property (make_number (charpos
- 1), Qinvisible
,
3071 ellipses_p
= 2 == TEXT_PROP_MEANS_INVISIBLE (prop
);
3078 /* Initialize IT for stepping through current_buffer in window W,
3079 starting at position POS that includes overlay string and display
3080 vector/ control character translation position information. Value
3081 is zero if there are overlay strings with newlines at POS. */
3084 init_from_display_pos (struct it
*it
, struct window
*w
, struct display_pos
*pos
)
3086 ptrdiff_t charpos
= CHARPOS (pos
->pos
), bytepos
= BYTEPOS (pos
->pos
);
3087 int i
, overlay_strings_with_newlines
= 0;
3089 /* If POS specifies a position in a display vector, this might
3090 be for an ellipsis displayed for invisible text. We won't
3091 get the iterator set up for delivering that ellipsis unless
3092 we make sure that it gets aware of the invisible text. */
3093 if (in_ellipses_for_invisible_text_p (pos
, w
))
3099 /* Keep in mind: the call to reseat in init_iterator skips invisible
3100 text, so we might end up at a position different from POS. This
3101 is only a problem when POS is a row start after a newline and an
3102 overlay starts there with an after-string, and the overlay has an
3103 invisible property. Since we don't skip invisible text in
3104 display_line and elsewhere immediately after consuming the
3105 newline before the row start, such a POS will not be in a string,
3106 but the call to init_iterator below will move us to the
3108 init_iterator (it
, w
, charpos
, bytepos
, NULL
, DEFAULT_FACE_ID
);
3110 /* This only scans the current chunk -- it should scan all chunks.
3111 However, OVERLAY_STRING_CHUNK_SIZE has been increased from 3 in 21.1
3112 to 16 in 22.1 to make this a lesser problem. */
3113 for (i
= 0; i
< it
->n_overlay_strings
&& i
< OVERLAY_STRING_CHUNK_SIZE
; ++i
)
3115 const char *s
= SSDATA (it
->overlay_strings
[i
]);
3116 const char *e
= s
+ SBYTES (it
->overlay_strings
[i
]);
3118 while (s
< e
&& *s
!= '\n')
3123 overlay_strings_with_newlines
= 1;
3128 /* If position is within an overlay string, set up IT to the right
3130 if (pos
->overlay_string_index
>= 0)
3134 /* If the first overlay string happens to have a `display'
3135 property for an image, the iterator will be set up for that
3136 image, and we have to undo that setup first before we can
3137 correct the overlay string index. */
3138 if (it
->method
== GET_FROM_IMAGE
)
3141 /* We already have the first chunk of overlay strings in
3142 IT->overlay_strings. Load more until the one for
3143 pos->overlay_string_index is in IT->overlay_strings. */
3144 if (pos
->overlay_string_index
>= OVERLAY_STRING_CHUNK_SIZE
)
3146 ptrdiff_t n
= pos
->overlay_string_index
/ OVERLAY_STRING_CHUNK_SIZE
;
3147 it
->current
.overlay_string_index
= 0;
3150 load_overlay_strings (it
, 0);
3151 it
->current
.overlay_string_index
+= OVERLAY_STRING_CHUNK_SIZE
;
3155 it
->current
.overlay_string_index
= pos
->overlay_string_index
;
3156 relative_index
= (it
->current
.overlay_string_index
3157 % OVERLAY_STRING_CHUNK_SIZE
);
3158 it
->string
= it
->overlay_strings
[relative_index
];
3159 eassert (STRINGP (it
->string
));
3160 it
->current
.string_pos
= pos
->string_pos
;
3161 it
->method
= GET_FROM_STRING
;
3162 it
->end_charpos
= SCHARS (it
->string
);
3163 /* Set up the bidi iterator for this overlay string. */
3166 it
->bidi_it
.string
.lstring
= it
->string
;
3167 it
->bidi_it
.string
.s
= NULL
;
3168 it
->bidi_it
.string
.schars
= SCHARS (it
->string
);
3169 it
->bidi_it
.string
.bufpos
= it
->overlay_strings_charpos
;
3170 it
->bidi_it
.string
.from_disp_str
= it
->string_from_display_prop_p
;
3171 it
->bidi_it
.string
.unibyte
= !it
->multibyte_p
;
3172 it
->bidi_it
.w
= it
->w
;
3173 bidi_init_it (IT_STRING_CHARPOS (*it
), IT_STRING_BYTEPOS (*it
),
3174 FRAME_WINDOW_P (it
->f
), &it
->bidi_it
);
3176 /* Synchronize the state of the bidi iterator with
3177 pos->string_pos. For any string position other than
3178 zero, this will be done automagically when we resume
3179 iteration over the string and get_visually_first_element
3180 is called. But if string_pos is zero, and the string is
3181 to be reordered for display, we need to resync manually,
3182 since it could be that the iteration state recorded in
3183 pos ended at string_pos of 0 moving backwards in string. */
3184 if (CHARPOS (pos
->string_pos
) == 0)
3186 get_visually_first_element (it
);
3187 if (IT_STRING_CHARPOS (*it
) != 0)
3190 eassert (it
->bidi_it
.charpos
< it
->bidi_it
.string
.schars
);
3191 bidi_move_to_visually_next (&it
->bidi_it
);
3192 } while (it
->bidi_it
.charpos
!= 0);
3194 eassert (IT_STRING_CHARPOS (*it
) == it
->bidi_it
.charpos
3195 && IT_STRING_BYTEPOS (*it
) == it
->bidi_it
.bytepos
);
3199 if (CHARPOS (pos
->string_pos
) >= 0)
3201 /* Recorded position is not in an overlay string, but in another
3202 string. This can only be a string from a `display' property.
3203 IT should already be filled with that string. */
3204 it
->current
.string_pos
= pos
->string_pos
;
3205 eassert (STRINGP (it
->string
));
3207 bidi_init_it (IT_STRING_CHARPOS (*it
), IT_STRING_BYTEPOS (*it
),
3208 FRAME_WINDOW_P (it
->f
), &it
->bidi_it
);
3211 /* Restore position in display vector translations, control
3212 character translations or ellipses. */
3213 if (pos
->dpvec_index
>= 0)
3215 if (it
->dpvec
== NULL
)
3216 get_next_display_element (it
);
3217 eassert (it
->dpvec
&& it
->current
.dpvec_index
== 0);
3218 it
->current
.dpvec_index
= pos
->dpvec_index
;
3222 return !overlay_strings_with_newlines
;
3226 /* Initialize IT for stepping through current_buffer in window W
3227 starting at ROW->start. */
3230 init_to_row_start (struct it
*it
, struct window
*w
, struct glyph_row
*row
)
3232 init_from_display_pos (it
, w
, &row
->start
);
3233 it
->start
= row
->start
;
3234 it
->continuation_lines_width
= row
->continuation_lines_width
;
3239 /* Initialize IT for stepping through current_buffer in window W
3240 starting in the line following ROW, i.e. starting at ROW->end.
3241 Value is zero if there are overlay strings with newlines at ROW's
3245 init_to_row_end (struct it
*it
, struct window
*w
, struct glyph_row
*row
)
3249 if (init_from_display_pos (it
, w
, &row
->end
))
3251 if (row
->continued_p
)
3252 it
->continuation_lines_width
3253 = row
->continuation_lines_width
+ row
->pixel_width
;
3264 /***********************************************************************
3266 ***********************************************************************/
3268 /* Called when IT reaches IT->stop_charpos. Handle text property and
3269 overlay changes. Set IT->stop_charpos to the next position where
3273 handle_stop (struct it
*it
)
3275 enum prop_handled handled
;
3276 int handle_overlay_change_p
;
3280 it
->current
.dpvec_index
= -1;
3281 handle_overlay_change_p
= !it
->ignore_overlay_strings_at_pos_p
;
3282 it
->ignore_overlay_strings_at_pos_p
= 0;
3285 /* Use face of preceding text for ellipsis (if invisible) */
3286 if (it
->selective_display_ellipsis_p
)
3287 it
->saved_face_id
= it
->face_id
;
3291 handled
= HANDLED_NORMALLY
;
3293 /* Call text property handlers. */
3294 for (p
= it_props
; p
->handler
; ++p
)
3296 handled
= p
->handler (it
);
3298 if (handled
== HANDLED_RECOMPUTE_PROPS
)
3300 else if (handled
== HANDLED_RETURN
)
3302 /* We still want to show before and after strings from
3303 overlays even if the actual buffer text is replaced. */
3304 if (!handle_overlay_change_p
3306 /* Don't call get_overlay_strings_1 if we already
3307 have overlay strings loaded, because doing so
3308 will load them again and push the iterator state
3309 onto the stack one more time, which is not
3310 expected by the rest of the code that processes
3312 || (it
->current
.overlay_string_index
< 0
3313 ? !get_overlay_strings_1 (it
, 0, 0)
3317 setup_for_ellipsis (it
, 0);
3318 /* When handling a display spec, we might load an
3319 empty string. In that case, discard it here. We
3320 used to discard it in handle_single_display_spec,
3321 but that causes get_overlay_strings_1, above, to
3322 ignore overlay strings that we must check. */
3323 if (STRINGP (it
->string
) && !SCHARS (it
->string
))
3327 else if (STRINGP (it
->string
) && !SCHARS (it
->string
))
3331 it
->ignore_overlay_strings_at_pos_p
= 1;
3332 it
->string_from_display_prop_p
= 0;
3333 it
->from_disp_prop_p
= 0;
3334 handle_overlay_change_p
= 0;
3336 handled
= HANDLED_RECOMPUTE_PROPS
;
3339 else if (handled
== HANDLED_OVERLAY_STRING_CONSUMED
)
3340 handle_overlay_change_p
= 0;
3343 if (handled
!= HANDLED_RECOMPUTE_PROPS
)
3345 /* Don't check for overlay strings below when set to deliver
3346 characters from a display vector. */
3347 if (it
->method
== GET_FROM_DISPLAY_VECTOR
)
3348 handle_overlay_change_p
= 0;
3350 /* Handle overlay changes.
3351 This sets HANDLED to HANDLED_RECOMPUTE_PROPS
3352 if it finds overlays. */
3353 if (handle_overlay_change_p
)
3354 handled
= handle_overlay_change (it
);
3359 setup_for_ellipsis (it
, 0);
3363 while (handled
== HANDLED_RECOMPUTE_PROPS
);
3365 /* Determine where to stop next. */
3366 if (handled
== HANDLED_NORMALLY
)
3367 compute_stop_pos (it
);
3371 /* Compute IT->stop_charpos from text property and overlay change
3372 information for IT's current position. */
3375 compute_stop_pos (struct it
*it
)
3377 register INTERVAL iv
, next_iv
;
3378 Lisp_Object object
, limit
, position
;
3379 ptrdiff_t charpos
, bytepos
;
3381 if (STRINGP (it
->string
))
3383 /* Strings are usually short, so don't limit the search for
3385 it
->stop_charpos
= it
->end_charpos
;
3386 object
= it
->string
;
3388 charpos
= IT_STRING_CHARPOS (*it
);
3389 bytepos
= IT_STRING_BYTEPOS (*it
);
3395 /* If end_charpos is out of range for some reason, such as a
3396 misbehaving display function, rationalize it (Bug#5984). */
3397 if (it
->end_charpos
> ZV
)
3398 it
->end_charpos
= ZV
;
3399 it
->stop_charpos
= it
->end_charpos
;
3401 /* If next overlay change is in front of the current stop pos
3402 (which is IT->end_charpos), stop there. Note: value of
3403 next_overlay_change is point-max if no overlay change
3405 charpos
= IT_CHARPOS (*it
);
3406 bytepos
= IT_BYTEPOS (*it
);
3407 pos
= next_overlay_change (charpos
);
3408 if (pos
< it
->stop_charpos
)
3409 it
->stop_charpos
= pos
;
3411 /* If showing the region, we have to stop at the region
3412 start or end because the face might change there. */
3413 if (it
->region_beg_charpos
> 0)
3415 if (IT_CHARPOS (*it
) < it
->region_beg_charpos
)
3416 it
->stop_charpos
= min (it
->stop_charpos
, it
->region_beg_charpos
);
3417 else if (IT_CHARPOS (*it
) < it
->region_end_charpos
)
3418 it
->stop_charpos
= min (it
->stop_charpos
, it
->region_end_charpos
);
3421 /* Set up variables for computing the stop position from text
3422 property changes. */
3423 XSETBUFFER (object
, current_buffer
);
3424 limit
= make_number (IT_CHARPOS (*it
) + TEXT_PROP_DISTANCE_LIMIT
);
3427 /* Get the interval containing IT's position. Value is a null
3428 interval if there isn't such an interval. */
3429 position
= make_number (charpos
);
3430 iv
= validate_interval_range (object
, &position
, &position
, 0);
3433 Lisp_Object values_here
[LAST_PROP_IDX
];
3436 /* Get properties here. */
3437 for (p
= it_props
; p
->handler
; ++p
)
3438 values_here
[p
->idx
] = textget (iv
->plist
, *p
->name
);
3440 /* Look for an interval following iv that has different
3442 for (next_iv
= next_interval (iv
);
3445 || XFASTINT (limit
) > next_iv
->position
));
3446 next_iv
= next_interval (next_iv
))
3448 for (p
= it_props
; p
->handler
; ++p
)
3450 Lisp_Object new_value
;
3452 new_value
= textget (next_iv
->plist
, *p
->name
);
3453 if (!EQ (values_here
[p
->idx
], new_value
))
3463 if (INTEGERP (limit
)
3464 && next_iv
->position
>= XFASTINT (limit
))
3465 /* No text property change up to limit. */
3466 it
->stop_charpos
= min (XFASTINT (limit
), it
->stop_charpos
);
3468 /* Text properties change in next_iv. */
3469 it
->stop_charpos
= min (it
->stop_charpos
, next_iv
->position
);
3473 if (it
->cmp_it
.id
< 0)
3475 ptrdiff_t stoppos
= it
->end_charpos
;
3477 if (it
->bidi_p
&& it
->bidi_it
.scan_dir
< 0)
3479 composition_compute_stop_pos (&it
->cmp_it
, charpos
, bytepos
,
3480 stoppos
, it
->string
);
3483 eassert (STRINGP (it
->string
)
3484 || (it
->stop_charpos
>= BEGV
3485 && it
->stop_charpos
>= IT_CHARPOS (*it
)));
3489 /* Return the position of the next overlay change after POS in
3490 current_buffer. Value is point-max if no overlay change
3491 follows. This is like `next-overlay-change' but doesn't use
3495 next_overlay_change (ptrdiff_t pos
)
3497 ptrdiff_t i
, noverlays
;
3499 Lisp_Object
*overlays
;
3501 /* Get all overlays at the given position. */
3502 GET_OVERLAYS_AT (pos
, overlays
, noverlays
, &endpos
, 1);
3504 /* If any of these overlays ends before endpos,
3505 use its ending point instead. */
3506 for (i
= 0; i
< noverlays
; ++i
)
3511 oend
= OVERLAY_END (overlays
[i
]);
3512 oendpos
= OVERLAY_POSITION (oend
);
3513 endpos
= min (endpos
, oendpos
);
3519 /* How many characters forward to search for a display property or
3520 display string. Searching too far forward makes the bidi display
3521 sluggish, especially in small windows. */
3522 #define MAX_DISP_SCAN 250
3524 /* Return the character position of a display string at or after
3525 position specified by POSITION. If no display string exists at or
3526 after POSITION, return ZV. A display string is either an overlay
3527 with `display' property whose value is a string, or a `display'
3528 text property whose value is a string. STRING is data about the
3529 string to iterate; if STRING->lstring is nil, we are iterating a
3530 buffer. FRAME_WINDOW_P is non-zero when we are displaying a window
3531 on a GUI frame. DISP_PROP is set to zero if we searched
3532 MAX_DISP_SCAN characters forward without finding any display
3533 strings, non-zero otherwise. It is set to 2 if the display string
3534 uses any kind of `(space ...)' spec that will produce a stretch of
3535 white space in the text area. */
3537 compute_display_string_pos (struct text_pos
*position
,
3538 struct bidi_string_data
*string
,
3540 int frame_window_p
, int *disp_prop
)
3542 /* OBJECT = nil means current buffer. */
3543 Lisp_Object object
, object1
;
3544 Lisp_Object pos
, spec
, limpos
;
3545 int string_p
= (string
&& (STRINGP (string
->lstring
) || string
->s
));
3546 ptrdiff_t eob
= string_p
? string
->schars
: ZV
;
3547 ptrdiff_t begb
= string_p
? 0 : BEGV
;
3548 ptrdiff_t bufpos
, charpos
= CHARPOS (*position
);
3550 (charpos
< eob
- MAX_DISP_SCAN
) ? charpos
+ MAX_DISP_SCAN
: eob
;
3551 struct text_pos tpos
;
3554 if (string
&& STRINGP (string
->lstring
))
3555 object1
= object
= string
->lstring
;
3556 else if (w
&& !string_p
)
3558 XSETWINDOW (object
, w
);
3562 object1
= object
= Qnil
;
3567 /* We don't support display properties whose values are strings
3568 that have display string properties. */
3569 || string
->from_disp_str
3570 /* C strings cannot have display properties. */
3571 || (string
->s
&& !STRINGP (object
)))
3577 /* If the character at CHARPOS is where the display string begins,
3579 pos
= make_number (charpos
);
3580 if (STRINGP (object
))
3581 bufpos
= string
->bufpos
;
3585 if (!NILP (spec
= Fget_char_property (pos
, Qdisplay
, object
))
3587 || !EQ (Fget_char_property (make_number (charpos
- 1), Qdisplay
,
3590 && (rv
= handle_display_spec (NULL
, spec
, object
, Qnil
, &tpos
, bufpos
,
3598 /* Look forward for the first character with a `display' property
3599 that will replace the underlying text when displayed. */
3600 limpos
= make_number (lim
);
3602 pos
= Fnext_single_char_property_change (pos
, Qdisplay
, object1
, limpos
);
3603 CHARPOS (tpos
) = XFASTINT (pos
);
3604 if (CHARPOS (tpos
) >= lim
)
3609 if (STRINGP (object
))
3610 BYTEPOS (tpos
) = string_char_to_byte (object
, CHARPOS (tpos
));
3612 BYTEPOS (tpos
) = CHAR_TO_BYTE (CHARPOS (tpos
));
3613 spec
= Fget_char_property (pos
, Qdisplay
, object
);
3614 if (!STRINGP (object
))
3615 bufpos
= CHARPOS (tpos
);
3616 } while (NILP (spec
)
3617 || !(rv
= handle_display_spec (NULL
, spec
, object
, Qnil
, &tpos
,
3618 bufpos
, frame_window_p
)));
3622 return CHARPOS (tpos
);
3625 /* Return the character position of the end of the display string that
3626 started at CHARPOS. If there's no display string at CHARPOS,
3627 return -1. A display string is either an overlay with `display'
3628 property whose value is a string or a `display' text property whose
3629 value is a string. */
3631 compute_display_string_end (ptrdiff_t charpos
, struct bidi_string_data
*string
)
3633 /* OBJECT = nil means current buffer. */
3634 Lisp_Object object
=
3635 (string
&& STRINGP (string
->lstring
)) ? string
->lstring
: Qnil
;
3636 Lisp_Object pos
= make_number (charpos
);
3638 (STRINGP (object
) || (string
&& string
->s
)) ? string
->schars
: ZV
;
3640 if (charpos
>= eob
|| (string
->s
&& !STRINGP (object
)))
3643 /* It could happen that the display property or overlay was removed
3644 since we found it in compute_display_string_pos above. One way
3645 this can happen is if JIT font-lock was called (through
3646 handle_fontified_prop), and jit-lock-functions remove text
3647 properties or overlays from the portion of buffer that includes
3648 CHARPOS. Muse mode is known to do that, for example. In this
3649 case, we return -1 to the caller, to signal that no display
3650 string is actually present at CHARPOS. See bidi_fetch_char for
3651 how this is handled.
3653 An alternative would be to never look for display properties past
3654 it->stop_charpos. But neither compute_display_string_pos nor
3655 bidi_fetch_char that calls it know or care where the next
3657 if (NILP (Fget_char_property (pos
, Qdisplay
, object
)))
3660 /* Look forward for the first character where the `display' property
3662 pos
= Fnext_single_char_property_change (pos
, Qdisplay
, object
, Qnil
);
3664 return XFASTINT (pos
);
3669 /***********************************************************************
3671 ***********************************************************************/
3673 /* Handle changes in the `fontified' property of the current buffer by
3674 calling hook functions from Qfontification_functions to fontify
3677 static enum prop_handled
3678 handle_fontified_prop (struct it
*it
)
3680 Lisp_Object prop
, pos
;
3681 enum prop_handled handled
= HANDLED_NORMALLY
;
3683 if (!NILP (Vmemory_full
))
3686 /* Get the value of the `fontified' property at IT's current buffer
3687 position. (The `fontified' property doesn't have a special
3688 meaning in strings.) If the value is nil, call functions from
3689 Qfontification_functions. */
3690 if (!STRINGP (it
->string
)
3692 && !NILP (Vfontification_functions
)
3693 && !NILP (Vrun_hooks
)
3694 && (pos
= make_number (IT_CHARPOS (*it
)),
3695 prop
= Fget_char_property (pos
, Qfontified
, Qnil
),
3696 /* Ignore the special cased nil value always present at EOB since
3697 no amount of fontifying will be able to change it. */
3698 NILP (prop
) && IT_CHARPOS (*it
) < Z
))
3700 ptrdiff_t count
= SPECPDL_INDEX ();
3702 struct buffer
*obuf
= current_buffer
;
3703 int begv
= BEGV
, zv
= ZV
;
3704 int old_clip_changed
= current_buffer
->clip_changed
;
3706 val
= Vfontification_functions
;
3707 specbind (Qfontification_functions
, Qnil
);
3709 eassert (it
->end_charpos
== ZV
);
3711 if (!CONSP (val
) || EQ (XCAR (val
), Qlambda
))
3712 safe_call1 (val
, pos
);
3715 Lisp_Object fns
, fn
;
3716 struct gcpro gcpro1
, gcpro2
;
3721 for (; CONSP (val
); val
= XCDR (val
))
3727 /* A value of t indicates this hook has a local
3728 binding; it means to run the global binding too.
3729 In a global value, t should not occur. If it
3730 does, we must ignore it to avoid an endless
3732 for (fns
= Fdefault_value (Qfontification_functions
);
3738 safe_call1 (fn
, pos
);
3742 safe_call1 (fn
, pos
);
3748 unbind_to (count
, Qnil
);
3750 /* Fontification functions routinely call `save-restriction'.
3751 Normally, this tags clip_changed, which can confuse redisplay
3752 (see discussion in Bug#6671). Since we don't perform any
3753 special handling of fontification changes in the case where
3754 `save-restriction' isn't called, there's no point doing so in
3755 this case either. So, if the buffer's restrictions are
3756 actually left unchanged, reset clip_changed. */
3757 if (obuf
== current_buffer
)
3759 if (begv
== BEGV
&& zv
== ZV
)
3760 current_buffer
->clip_changed
= old_clip_changed
;
3762 /* There isn't much we can reasonably do to protect against
3763 misbehaving fontification, but here's a fig leaf. */
3764 else if (BUFFER_LIVE_P (obuf
))
3765 set_buffer_internal_1 (obuf
);
3767 /* The fontification code may have added/removed text.
3768 It could do even a lot worse, but let's at least protect against
3769 the most obvious case where only the text past `pos' gets changed',
3770 as is/was done in grep.el where some escapes sequences are turned
3771 into face properties (bug#7876). */
3772 it
->end_charpos
= ZV
;
3774 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
3775 something. This avoids an endless loop if they failed to
3776 fontify the text for which reason ever. */
3777 if (!NILP (Fget_char_property (pos
, Qfontified
, Qnil
)))
3778 handled
= HANDLED_RECOMPUTE_PROPS
;
3786 /***********************************************************************
3788 ***********************************************************************/
3790 /* Set up iterator IT from face properties at its current position.
3791 Called from handle_stop. */
3793 static enum prop_handled
3794 handle_face_prop (struct it
*it
)
3797 ptrdiff_t next_stop
;
3799 if (!STRINGP (it
->string
))
3802 = face_at_buffer_position (it
->w
,
3804 it
->region_beg_charpos
,
3805 it
->region_end_charpos
,
3808 + TEXT_PROP_DISTANCE_LIMIT
),
3809 0, it
->base_face_id
);
3811 /* Is this a start of a run of characters with box face?
3812 Caveat: this can be called for a freshly initialized
3813 iterator; face_id is -1 in this case. We know that the new
3814 face will not change until limit, i.e. if the new face has a
3815 box, all characters up to limit will have one. But, as
3816 usual, we don't know whether limit is really the end. */
3817 if (new_face_id
!= it
->face_id
)
3819 struct face
*new_face
= FACE_FROM_ID (it
->f
, new_face_id
);
3820 /* If it->face_id is -1, old_face below will be NULL, see
3821 the definition of FACE_FROM_ID. This will happen if this
3822 is the initial call that gets the face. */
3823 struct face
*old_face
= FACE_FROM_ID (it
->f
, it
->face_id
);
3825 /* If the value of face_id of the iterator is -1, we have to
3826 look in front of IT's position and see whether there is a
3827 face there that's different from new_face_id. */
3828 if (!old_face
&& IT_CHARPOS (*it
) > BEG
)
3830 int prev_face_id
= face_before_it_pos (it
);
3832 old_face
= FACE_FROM_ID (it
->f
, prev_face_id
);
3835 /* If the new face has a box, but the old face does not,
3836 this is the start of a run of characters with box face,
3837 i.e. this character has a shadow on the left side. */
3838 it
->start_of_box_run_p
= (new_face
->box
!= FACE_NO_BOX
3839 && (old_face
== NULL
|| !old_face
->box
));
3840 it
->face_box_p
= new_face
->box
!= FACE_NO_BOX
;
3848 Lisp_Object from_overlay
3849 = (it
->current
.overlay_string_index
>= 0
3850 ? it
->string_overlays
[it
->current
.overlay_string_index
3851 % OVERLAY_STRING_CHUNK_SIZE
]
3854 /* See if we got to this string directly or indirectly from
3855 an overlay property. That includes the before-string or
3856 after-string of an overlay, strings in display properties
3857 provided by an overlay, their text properties, etc.
3859 FROM_OVERLAY is the overlay that brought us here, or nil if none. */
3860 if (! NILP (from_overlay
))
3861 for (i
= it
->sp
- 1; i
>= 0; i
--)
3863 if (it
->stack
[i
].current
.overlay_string_index
>= 0)
3865 = it
->string_overlays
[it
->stack
[i
].current
.overlay_string_index
3866 % OVERLAY_STRING_CHUNK_SIZE
];
3867 else if (! NILP (it
->stack
[i
].from_overlay
))
3868 from_overlay
= it
->stack
[i
].from_overlay
;
3870 if (!NILP (from_overlay
))
3874 if (! NILP (from_overlay
))
3876 bufpos
= IT_CHARPOS (*it
);
3877 /* For a string from an overlay, the base face depends
3878 only on text properties and ignores overlays. */
3880 = face_for_overlay_string (it
->w
,
3882 it
->region_beg_charpos
,
3883 it
->region_end_charpos
,
3886 + TEXT_PROP_DISTANCE_LIMIT
),
3894 /* For strings from a `display' property, use the face at
3895 IT's current buffer position as the base face to merge
3896 with, so that overlay strings appear in the same face as
3897 surrounding text, unless they specify their own faces.
3898 For strings from wrap-prefix and line-prefix properties,
3899 use the default face, possibly remapped via
3900 Vface_remapping_alist. */
3901 base_face_id
= it
->string_from_prefix_prop_p
3902 ? (!NILP (Vface_remapping_alist
)
3903 ? lookup_basic_face (it
->f
, DEFAULT_FACE_ID
)
3905 : underlying_face_id (it
);
3908 new_face_id
= face_at_string_position (it
->w
,
3910 IT_STRING_CHARPOS (*it
),
3912 it
->region_beg_charpos
,
3913 it
->region_end_charpos
,
3917 /* Is this a start of a run of characters with box? Caveat:
3918 this can be called for a freshly allocated iterator; face_id
3919 is -1 is this case. We know that the new face will not
3920 change until the next check pos, i.e. if the new face has a
3921 box, all characters up to that position will have a
3922 box. But, as usual, we don't know whether that position
3923 is really the end. */
3924 if (new_face_id
!= it
->face_id
)
3926 struct face
*new_face
= FACE_FROM_ID (it
->f
, new_face_id
);
3927 struct face
*old_face
= FACE_FROM_ID (it
->f
, it
->face_id
);
3929 /* If new face has a box but old face hasn't, this is the
3930 start of a run of characters with box, i.e. it has a
3931 shadow on the left side. */
3932 it
->start_of_box_run_p
3933 = new_face
->box
&& (old_face
== NULL
|| !old_face
->box
);
3934 it
->face_box_p
= new_face
->box
!= FACE_NO_BOX
;
3938 it
->face_id
= new_face_id
;
3939 return HANDLED_NORMALLY
;
3943 /* Return the ID of the face ``underlying'' IT's current position,
3944 which is in a string. If the iterator is associated with a
3945 buffer, return the face at IT's current buffer position.
3946 Otherwise, use the iterator's base_face_id. */
3949 underlying_face_id (struct it
*it
)
3951 int face_id
= it
->base_face_id
, i
;
3953 eassert (STRINGP (it
->string
));
3955 for (i
= it
->sp
- 1; i
>= 0; --i
)
3956 if (NILP (it
->stack
[i
].string
))
3957 face_id
= it
->stack
[i
].face_id
;
3963 /* Compute the face one character before or after the current position
3964 of IT, in the visual order. BEFORE_P non-zero means get the face
3965 in front (to the left in L2R paragraphs, to the right in R2L
3966 paragraphs) of IT's screen position. Value is the ID of the face. */
3969 face_before_or_after_it_pos (struct it
*it
, int before_p
)
3972 ptrdiff_t next_check_charpos
;
3974 void *it_copy_data
= NULL
;
3976 eassert (it
->s
== NULL
);
3978 if (STRINGP (it
->string
))
3980 ptrdiff_t bufpos
, charpos
;
3983 /* No face change past the end of the string (for the case
3984 we are padding with spaces). No face change before the
3986 if (IT_STRING_CHARPOS (*it
) >= SCHARS (it
->string
)
3987 || (IT_STRING_CHARPOS (*it
) == 0 && before_p
))
3992 /* Set charpos to the position before or after IT's current
3993 position, in the logical order, which in the non-bidi
3994 case is the same as the visual order. */
3996 charpos
= IT_STRING_CHARPOS (*it
) - 1;
3997 else if (it
->what
== IT_COMPOSITION
)
3998 /* For composition, we must check the character after the
4000 charpos
= IT_STRING_CHARPOS (*it
) + it
->cmp_it
.nchars
;
4002 charpos
= IT_STRING_CHARPOS (*it
) + 1;
4008 /* With bidi iteration, the character before the current
4009 in the visual order cannot be found by simple
4010 iteration, because "reverse" reordering is not
4011 supported. Instead, we need to use the move_it_*
4012 family of functions. */
4013 /* Ignore face changes before the first visible
4014 character on this display line. */
4015 if (it
->current_x
<= it
->first_visible_x
)
4017 SAVE_IT (it_copy
, *it
, it_copy_data
);
4018 /* Implementation note: Since move_it_in_display_line
4019 works in the iterator geometry, and thinks the first
4020 character is always the leftmost, even in R2L lines,
4021 we don't need to distinguish between the R2L and L2R
4023 move_it_in_display_line (&it_copy
, SCHARS (it_copy
.string
),
4024 it_copy
.current_x
- 1, MOVE_TO_X
);
4025 charpos
= IT_STRING_CHARPOS (it_copy
);
4026 RESTORE_IT (it
, it
, it_copy_data
);
4030 /* Set charpos to the string position of the character
4031 that comes after IT's current position in the visual
4033 int n
= (it
->what
== IT_COMPOSITION
? it
->cmp_it
.nchars
: 1);
4037 bidi_move_to_visually_next (&it_copy
.bidi_it
);
4039 charpos
= it_copy
.bidi_it
.charpos
;
4042 eassert (0 <= charpos
&& charpos
<= SCHARS (it
->string
));
4044 if (it
->current
.overlay_string_index
>= 0)
4045 bufpos
= IT_CHARPOS (*it
);
4049 base_face_id
= underlying_face_id (it
);
4051 /* Get the face for ASCII, or unibyte. */
4052 face_id
= face_at_string_position (it
->w
,
4056 it
->region_beg_charpos
,
4057 it
->region_end_charpos
,
4058 &next_check_charpos
,
4061 /* Correct the face for charsets different from ASCII. Do it
4062 for the multibyte case only. The face returned above is
4063 suitable for unibyte text if IT->string is unibyte. */
4064 if (STRING_MULTIBYTE (it
->string
))
4066 struct text_pos pos1
= string_pos (charpos
, it
->string
);
4067 const unsigned char *p
= SDATA (it
->string
) + BYTEPOS (pos1
);
4069 struct face
*face
= FACE_FROM_ID (it
->f
, face_id
);
4071 c
= string_char_and_length (p
, &len
);
4072 face_id
= FACE_FOR_CHAR (it
->f
, face
, c
, charpos
, it
->string
);
4077 struct text_pos pos
;
4079 if ((IT_CHARPOS (*it
) >= ZV
&& !before_p
)
4080 || (IT_CHARPOS (*it
) <= BEGV
&& before_p
))
4083 limit
= IT_CHARPOS (*it
) + TEXT_PROP_DISTANCE_LIMIT
;
4084 pos
= it
->current
.pos
;
4089 DEC_TEXT_POS (pos
, it
->multibyte_p
);
4092 if (it
->what
== IT_COMPOSITION
)
4094 /* For composition, we must check the position after
4096 pos
.charpos
+= it
->cmp_it
.nchars
;
4097 pos
.bytepos
+= it
->len
;
4100 INC_TEXT_POS (pos
, it
->multibyte_p
);
4107 /* With bidi iteration, the character before the current
4108 in the visual order cannot be found by simple
4109 iteration, because "reverse" reordering is not
4110 supported. Instead, we need to use the move_it_*
4111 family of functions. */
4112 /* Ignore face changes before the first visible
4113 character on this display line. */
4114 if (it
->current_x
<= it
->first_visible_x
)
4116 SAVE_IT (it_copy
, *it
, it_copy_data
);
4117 /* Implementation note: Since move_it_in_display_line
4118 works in the iterator geometry, and thinks the first
4119 character is always the leftmost, even in R2L lines,
4120 we don't need to distinguish between the R2L and L2R
4122 move_it_in_display_line (&it_copy
, ZV
,
4123 it_copy
.current_x
- 1, MOVE_TO_X
);
4124 pos
= it_copy
.current
.pos
;
4125 RESTORE_IT (it
, it
, it_copy_data
);
4129 /* Set charpos to the buffer position of the character
4130 that comes after IT's current position in the visual
4132 int n
= (it
->what
== IT_COMPOSITION
? it
->cmp_it
.nchars
: 1);
4136 bidi_move_to_visually_next (&it_copy
.bidi_it
);
4139 it_copy
.bidi_it
.charpos
, it_copy
.bidi_it
.bytepos
);
4142 eassert (BEGV
<= CHARPOS (pos
) && CHARPOS (pos
) <= ZV
);
4144 /* Determine face for CHARSET_ASCII, or unibyte. */
4145 face_id
= face_at_buffer_position (it
->w
,
4147 it
->region_beg_charpos
,
4148 it
->region_end_charpos
,
4149 &next_check_charpos
,
4152 /* Correct the face for charsets different from ASCII. Do it
4153 for the multibyte case only. The face returned above is
4154 suitable for unibyte text if current_buffer is unibyte. */
4155 if (it
->multibyte_p
)
4157 int c
= FETCH_MULTIBYTE_CHAR (BYTEPOS (pos
));
4158 struct face
*face
= FACE_FROM_ID (it
->f
, face_id
);
4159 face_id
= FACE_FOR_CHAR (it
->f
, face
, c
, CHARPOS (pos
), Qnil
);
4168 /***********************************************************************
4170 ***********************************************************************/
4172 /* Set up iterator IT from invisible properties at its current
4173 position. Called from handle_stop. */
4175 static enum prop_handled
4176 handle_invisible_prop (struct it
*it
)
4178 enum prop_handled handled
= HANDLED_NORMALLY
;
4182 if (STRINGP (it
->string
))
4184 Lisp_Object end_charpos
, limit
, charpos
;
4186 /* Get the value of the invisible text property at the
4187 current position. Value will be nil if there is no such
4189 charpos
= make_number (IT_STRING_CHARPOS (*it
));
4190 prop
= Fget_text_property (charpos
, Qinvisible
, it
->string
);
4191 invis_p
= TEXT_PROP_MEANS_INVISIBLE (prop
);
4193 if (invis_p
&& IT_STRING_CHARPOS (*it
) < it
->end_charpos
)
4195 /* Record whether we have to display an ellipsis for the
4197 int display_ellipsis_p
= (invis_p
== 2);
4198 ptrdiff_t len
, endpos
;
4200 handled
= HANDLED_RECOMPUTE_PROPS
;
4202 /* Get the position at which the next visible text can be
4203 found in IT->string, if any. */
4204 endpos
= len
= SCHARS (it
->string
);
4205 XSETINT (limit
, len
);
4208 end_charpos
= Fnext_single_property_change (charpos
, Qinvisible
,
4210 if (INTEGERP (end_charpos
))
4212 endpos
= XFASTINT (end_charpos
);
4213 prop
= Fget_text_property (end_charpos
, Qinvisible
, it
->string
);
4214 invis_p
= TEXT_PROP_MEANS_INVISIBLE (prop
);
4216 display_ellipsis_p
= 1;
4219 while (invis_p
&& endpos
< len
);
4221 if (display_ellipsis_p
)
4226 /* Text at END_CHARPOS is visible. Move IT there. */
4227 struct text_pos old
;
4230 old
= it
->current
.string_pos
;
4231 oldpos
= CHARPOS (old
);
4234 if (it
->bidi_it
.first_elt
4235 && it
->bidi_it
.charpos
< SCHARS (it
->string
))
4236 bidi_paragraph_init (it
->paragraph_embedding
,
4238 /* Bidi-iterate out of the invisible text. */
4241 bidi_move_to_visually_next (&it
->bidi_it
);
4243 while (oldpos
<= it
->bidi_it
.charpos
4244 && it
->bidi_it
.charpos
< endpos
);
4246 IT_STRING_CHARPOS (*it
) = it
->bidi_it
.charpos
;
4247 IT_STRING_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
4248 if (IT_CHARPOS (*it
) >= endpos
)
4249 it
->prev_stop
= endpos
;
4253 IT_STRING_CHARPOS (*it
) = XFASTINT (end_charpos
);
4254 compute_string_pos (&it
->current
.string_pos
, old
, it
->string
);
4259 /* The rest of the string is invisible. If this is an
4260 overlay string, proceed with the next overlay string
4261 or whatever comes and return a character from there. */
4262 if (it
->current
.overlay_string_index
>= 0
4263 && !display_ellipsis_p
)
4265 next_overlay_string (it
);
4266 /* Don't check for overlay strings when we just
4267 finished processing them. */
4268 handled
= HANDLED_OVERLAY_STRING_CONSUMED
;
4272 IT_STRING_CHARPOS (*it
) = SCHARS (it
->string
);
4273 IT_STRING_BYTEPOS (*it
) = SBYTES (it
->string
);
4280 ptrdiff_t newpos
, next_stop
, start_charpos
, tem
;
4281 Lisp_Object pos
, overlay
;
4283 /* First of all, is there invisible text at this position? */
4284 tem
= start_charpos
= IT_CHARPOS (*it
);
4285 pos
= make_number (tem
);
4286 prop
= get_char_property_and_overlay (pos
, Qinvisible
, it
->window
,
4288 invis_p
= TEXT_PROP_MEANS_INVISIBLE (prop
);
4290 /* If we are on invisible text, skip over it. */
4291 if (invis_p
&& start_charpos
< it
->end_charpos
)
4293 /* Record whether we have to display an ellipsis for the
4295 int display_ellipsis_p
= invis_p
== 2;
4297 handled
= HANDLED_RECOMPUTE_PROPS
;
4299 /* Loop skipping over invisible text. The loop is left at
4300 ZV or with IT on the first char being visible again. */
4303 /* Try to skip some invisible text. Return value is the
4304 position reached which can be equal to where we start
4305 if there is nothing invisible there. This skips both
4306 over invisible text properties and overlays with
4307 invisible property. */
4308 newpos
= skip_invisible (tem
, &next_stop
, ZV
, it
->window
);
4310 /* If we skipped nothing at all we weren't at invisible
4311 text in the first place. If everything to the end of
4312 the buffer was skipped, end the loop. */
4313 if (newpos
== tem
|| newpos
>= ZV
)
4317 /* We skipped some characters but not necessarily
4318 all there are. Check if we ended up on visible
4319 text. Fget_char_property returns the property of
4320 the char before the given position, i.e. if we
4321 get invis_p = 0, this means that the char at
4322 newpos is visible. */
4323 pos
= make_number (newpos
);
4324 prop
= Fget_char_property (pos
, Qinvisible
, it
->window
);
4325 invis_p
= TEXT_PROP_MEANS_INVISIBLE (prop
);
4328 /* If we ended up on invisible text, proceed to
4329 skip starting with next_stop. */
4333 /* If there are adjacent invisible texts, don't lose the
4334 second one's ellipsis. */
4336 display_ellipsis_p
= 1;
4340 /* The position newpos is now either ZV or on visible text. */
4343 ptrdiff_t bpos
= CHAR_TO_BYTE (newpos
);
4345 bpos
== ZV_BYTE
|| FETCH_BYTE (bpos
) == '\n';
4347 newpos
<= BEGV
|| FETCH_BYTE (bpos
- 1) == '\n';
4349 /* If the invisible text ends on a newline or on a
4350 character after a newline, we can avoid the costly,
4351 character by character, bidi iteration to NEWPOS, and
4352 instead simply reseat the iterator there. That's
4353 because all bidi reordering information is tossed at
4354 the newline. This is a big win for modes that hide
4355 complete lines, like Outline, Org, etc. */
4356 if (on_newline
|| after_newline
)
4358 struct text_pos tpos
;
4359 bidi_dir_t pdir
= it
->bidi_it
.paragraph_dir
;
4361 SET_TEXT_POS (tpos
, newpos
, bpos
);
4362 reseat_1 (it
, tpos
, 0);
4363 /* If we reseat on a newline/ZV, we need to prep the
4364 bidi iterator for advancing to the next character
4365 after the newline/EOB, keeping the current paragraph
4366 direction (so that PRODUCE_GLYPHS does TRT wrt
4367 prepending/appending glyphs to a glyph row). */
4370 it
->bidi_it
.first_elt
= 0;
4371 it
->bidi_it
.paragraph_dir
= pdir
;
4372 it
->bidi_it
.ch
= (bpos
== ZV_BYTE
) ? -1 : '\n';
4373 it
->bidi_it
.nchars
= 1;
4374 it
->bidi_it
.ch_len
= 1;
4377 else /* Must use the slow method. */
4379 /* With bidi iteration, the region of invisible text
4380 could start and/or end in the middle of a
4381 non-base embedding level. Therefore, we need to
4382 skip invisible text using the bidi iterator,
4383 starting at IT's current position, until we find
4384 ourselves outside of the invisible text.
4385 Skipping invisible text _after_ bidi iteration
4386 avoids affecting the visual order of the
4387 displayed text when invisible properties are
4388 added or removed. */
4389 if (it
->bidi_it
.first_elt
&& it
->bidi_it
.charpos
< ZV
)
4391 /* If we were `reseat'ed to a new paragraph,
4392 determine the paragraph base direction. We
4393 need to do it now because
4394 next_element_from_buffer may not have a
4395 chance to do it, if we are going to skip any
4396 text at the beginning, which resets the
4398 bidi_paragraph_init (it
->paragraph_embedding
,
4403 bidi_move_to_visually_next (&it
->bidi_it
);
4405 while (it
->stop_charpos
<= it
->bidi_it
.charpos
4406 && it
->bidi_it
.charpos
< newpos
);
4407 IT_CHARPOS (*it
) = it
->bidi_it
.charpos
;
4408 IT_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
4409 /* If we overstepped NEWPOS, record its position in
4410 the iterator, so that we skip invisible text if
4411 later the bidi iteration lands us in the
4412 invisible region again. */
4413 if (IT_CHARPOS (*it
) >= newpos
)
4414 it
->prev_stop
= newpos
;
4419 IT_CHARPOS (*it
) = newpos
;
4420 IT_BYTEPOS (*it
) = CHAR_TO_BYTE (newpos
);
4423 /* If there are before-strings at the start of invisible
4424 text, and the text is invisible because of a text
4425 property, arrange to show before-strings because 20.x did
4426 it that way. (If the text is invisible because of an
4427 overlay property instead of a text property, this is
4428 already handled in the overlay code.) */
4430 && get_overlay_strings (it
, it
->stop_charpos
))
4432 handled
= HANDLED_RECOMPUTE_PROPS
;
4433 it
->stack
[it
->sp
- 1].display_ellipsis_p
= display_ellipsis_p
;
4435 else if (display_ellipsis_p
)
4437 /* Make sure that the glyphs of the ellipsis will get
4438 correct `charpos' values. If we would not update
4439 it->position here, the glyphs would belong to the
4440 last visible character _before_ the invisible
4441 text, which confuses `set_cursor_from_row'.
4443 We use the last invisible position instead of the
4444 first because this way the cursor is always drawn on
4445 the first "." of the ellipsis, whenever PT is inside
4446 the invisible text. Otherwise the cursor would be
4447 placed _after_ the ellipsis when the point is after the
4448 first invisible character. */
4449 if (!STRINGP (it
->object
))
4451 it
->position
.charpos
= newpos
- 1;
4452 it
->position
.bytepos
= CHAR_TO_BYTE (it
->position
.charpos
);
4455 /* Let the ellipsis display before
4456 considering any properties of the following char.
4457 Fixes jasonr@gnu.org 01 Oct 07 bug. */
4458 handled
= HANDLED_RETURN
;
4467 /* Make iterator IT return `...' next.
4468 Replaces LEN characters from buffer. */
4471 setup_for_ellipsis (struct it
*it
, int len
)
4473 /* Use the display table definition for `...'. Invalid glyphs
4474 will be handled by the method returning elements from dpvec. */
4475 if (it
->dp
&& VECTORP (DISP_INVIS_VECTOR (it
->dp
)))
4477 struct Lisp_Vector
*v
= XVECTOR (DISP_INVIS_VECTOR (it
->dp
));
4478 it
->dpvec
= v
->contents
;
4479 it
->dpend
= v
->contents
+ v
->header
.size
;
4483 /* Default `...'. */
4484 it
->dpvec
= default_invis_vector
;
4485 it
->dpend
= default_invis_vector
+ 3;
4488 it
->dpvec_char_len
= len
;
4489 it
->current
.dpvec_index
= 0;
4490 it
->dpvec_face_id
= -1;
4492 /* Remember the current face id in case glyphs specify faces.
4493 IT's face is restored in set_iterator_to_next.
4494 saved_face_id was set to preceding char's face in handle_stop. */
4495 if (it
->saved_face_id
< 0 || it
->saved_face_id
!= it
->face_id
)
4496 it
->saved_face_id
= it
->face_id
= DEFAULT_FACE_ID
;
4498 it
->method
= GET_FROM_DISPLAY_VECTOR
;
4504 /***********************************************************************
4506 ***********************************************************************/
4508 /* Set up iterator IT from `display' property at its current position.
4509 Called from handle_stop.
4510 We return HANDLED_RETURN if some part of the display property
4511 overrides the display of the buffer text itself.
4512 Otherwise we return HANDLED_NORMALLY. */
4514 static enum prop_handled
4515 handle_display_prop (struct it
*it
)
4517 Lisp_Object propval
, object
, overlay
;
4518 struct text_pos
*position
;
4520 /* Nonzero if some property replaces the display of the text itself. */
4521 int display_replaced_p
= 0;
4523 if (STRINGP (it
->string
))
4525 object
= it
->string
;
4526 position
= &it
->current
.string_pos
;
4527 bufpos
= CHARPOS (it
->current
.pos
);
4531 XSETWINDOW (object
, it
->w
);
4532 position
= &it
->current
.pos
;
4533 bufpos
= CHARPOS (*position
);
4536 /* Reset those iterator values set from display property values. */
4537 it
->slice
.x
= it
->slice
.y
= it
->slice
.width
= it
->slice
.height
= Qnil
;
4538 it
->space_width
= Qnil
;
4539 it
->font_height
= Qnil
;
4542 /* We don't support recursive `display' properties, i.e. string
4543 values that have a string `display' property, that have a string
4544 `display' property etc. */
4545 if (!it
->string_from_display_prop_p
)
4546 it
->area
= TEXT_AREA
;
4548 propval
= get_char_property_and_overlay (make_number (position
->charpos
),
4549 Qdisplay
, object
, &overlay
);
4551 return HANDLED_NORMALLY
;
4552 /* Now OVERLAY is the overlay that gave us this property, or nil
4553 if it was a text property. */
4555 if (!STRINGP (it
->string
))
4556 object
= it
->w
->contents
;
4558 display_replaced_p
= handle_display_spec (it
, propval
, object
, overlay
,
4560 FRAME_WINDOW_P (it
->f
));
4562 return display_replaced_p
? HANDLED_RETURN
: HANDLED_NORMALLY
;
4565 /* Subroutine of handle_display_prop. Returns non-zero if the display
4566 specification in SPEC is a replacing specification, i.e. it would
4567 replace the text covered by `display' property with something else,
4568 such as an image or a display string. If SPEC includes any kind or
4569 `(space ...) specification, the value is 2; this is used by
4570 compute_display_string_pos, which see.
4572 See handle_single_display_spec for documentation of arguments.
4573 frame_window_p is non-zero if the window being redisplayed is on a
4574 GUI frame; this argument is used only if IT is NULL, see below.
4576 IT can be NULL, if this is called by the bidi reordering code
4577 through compute_display_string_pos, which see. In that case, this
4578 function only examines SPEC, but does not otherwise "handle" it, in
4579 the sense that it doesn't set up members of IT from the display
4582 handle_display_spec (struct it
*it
, Lisp_Object spec
, Lisp_Object object
,
4583 Lisp_Object overlay
, struct text_pos
*position
,
4584 ptrdiff_t bufpos
, int frame_window_p
)
4586 int replacing_p
= 0;
4590 /* Simple specifications. */
4591 && !EQ (XCAR (spec
), Qimage
)
4592 && !EQ (XCAR (spec
), Qspace
)
4593 && !EQ (XCAR (spec
), Qwhen
)
4594 && !EQ (XCAR (spec
), Qslice
)
4595 && !EQ (XCAR (spec
), Qspace_width
)
4596 && !EQ (XCAR (spec
), Qheight
)
4597 && !EQ (XCAR (spec
), Qraise
)
4598 /* Marginal area specifications. */
4599 && !(CONSP (XCAR (spec
)) && EQ (XCAR (XCAR (spec
)), Qmargin
))
4600 && !EQ (XCAR (spec
), Qleft_fringe
)
4601 && !EQ (XCAR (spec
), Qright_fringe
)
4602 && !NILP (XCAR (spec
)))
4604 for (; CONSP (spec
); spec
= XCDR (spec
))
4606 if ((rv
= handle_single_display_spec (it
, XCAR (spec
), object
,
4607 overlay
, position
, bufpos
,
4608 replacing_p
, frame_window_p
)))
4611 /* If some text in a string is replaced, `position' no
4612 longer points to the position of `object'. */
4613 if (!it
|| STRINGP (object
))
4618 else if (VECTORP (spec
))
4621 for (i
= 0; i
< ASIZE (spec
); ++i
)
4622 if ((rv
= handle_single_display_spec (it
, AREF (spec
, i
), object
,
4623 overlay
, position
, bufpos
,
4624 replacing_p
, frame_window_p
)))
4627 /* If some text in a string is replaced, `position' no
4628 longer points to the position of `object'. */
4629 if (!it
|| STRINGP (object
))
4635 if ((rv
= handle_single_display_spec (it
, spec
, object
, overlay
,
4636 position
, bufpos
, 0,
4644 /* Value is the position of the end of the `display' property starting
4645 at START_POS in OBJECT. */
4647 static struct text_pos
4648 display_prop_end (struct it
*it
, Lisp_Object object
, struct text_pos start_pos
)
4651 struct text_pos end_pos
;
4653 end
= Fnext_single_char_property_change (make_number (CHARPOS (start_pos
)),
4654 Qdisplay
, object
, Qnil
);
4655 CHARPOS (end_pos
) = XFASTINT (end
);
4656 if (STRINGP (object
))
4657 compute_string_pos (&end_pos
, start_pos
, it
->string
);
4659 BYTEPOS (end_pos
) = CHAR_TO_BYTE (XFASTINT (end
));
4665 /* Set up IT from a single `display' property specification SPEC. OBJECT
4666 is the object in which the `display' property was found. *POSITION
4667 is the position in OBJECT at which the `display' property was found.
4668 BUFPOS is the buffer position of OBJECT (different from POSITION if
4669 OBJECT is not a buffer). DISPLAY_REPLACED_P non-zero means that we
4670 previously saw a display specification which already replaced text
4671 display with something else, for example an image; we ignore such
4672 properties after the first one has been processed.
4674 OVERLAY is the overlay this `display' property came from,
4675 or nil if it was a text property.
4677 If SPEC is a `space' or `image' specification, and in some other
4678 cases too, set *POSITION to the position where the `display'
4681 If IT is NULL, only examine the property specification in SPEC, but
4682 don't set up IT. In that case, FRAME_WINDOW_P non-zero means SPEC
4683 is intended to be displayed in a window on a GUI frame.
4685 Value is non-zero if something was found which replaces the display
4686 of buffer or string text. */
4689 handle_single_display_spec (struct it
*it
, Lisp_Object spec
, Lisp_Object object
,
4690 Lisp_Object overlay
, struct text_pos
*position
,
4691 ptrdiff_t bufpos
, int display_replaced_p
,
4695 Lisp_Object location
, value
;
4696 struct text_pos start_pos
= *position
;
4699 /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
4700 If the result is non-nil, use VALUE instead of SPEC. */
4702 if (CONSP (spec
) && EQ (XCAR (spec
), Qwhen
))
4711 if (!NILP (form
) && !EQ (form
, Qt
))
4713 ptrdiff_t count
= SPECPDL_INDEX ();
4714 struct gcpro gcpro1
;
4716 /* Bind `object' to the object having the `display' property, a
4717 buffer or string. Bind `position' to the position in the
4718 object where the property was found, and `buffer-position'
4719 to the current position in the buffer. */
4722 XSETBUFFER (object
, current_buffer
);
4723 specbind (Qobject
, object
);
4724 specbind (Qposition
, make_number (CHARPOS (*position
)));
4725 specbind (Qbuffer_position
, make_number (bufpos
));
4727 form
= safe_eval (form
);
4729 unbind_to (count
, Qnil
);
4735 /* Handle `(height HEIGHT)' specifications. */
4737 && EQ (XCAR (spec
), Qheight
)
4738 && CONSP (XCDR (spec
)))
4742 if (!FRAME_WINDOW_P (it
->f
))
4745 it
->font_height
= XCAR (XCDR (spec
));
4746 if (!NILP (it
->font_height
))
4748 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
4749 int new_height
= -1;
4751 if (CONSP (it
->font_height
)
4752 && (EQ (XCAR (it
->font_height
), Qplus
)
4753 || EQ (XCAR (it
->font_height
), Qminus
))
4754 && CONSP (XCDR (it
->font_height
))
4755 && RANGED_INTEGERP (0, XCAR (XCDR (it
->font_height
)), INT_MAX
))
4757 /* `(+ N)' or `(- N)' where N is an integer. */
4758 int steps
= XINT (XCAR (XCDR (it
->font_height
)));
4759 if (EQ (XCAR (it
->font_height
), Qplus
))
4761 it
->face_id
= smaller_face (it
->f
, it
->face_id
, steps
);
4763 else if (FUNCTIONP (it
->font_height
))
4765 /* Call function with current height as argument.
4766 Value is the new height. */
4768 height
= safe_call1 (it
->font_height
,
4769 face
->lface
[LFACE_HEIGHT_INDEX
]);
4770 if (NUMBERP (height
))
4771 new_height
= XFLOATINT (height
);
4773 else if (NUMBERP (it
->font_height
))
4775 /* Value is a multiple of the canonical char height. */
4778 f
= FACE_FROM_ID (it
->f
,
4779 lookup_basic_face (it
->f
, DEFAULT_FACE_ID
));
4780 new_height
= (XFLOATINT (it
->font_height
)
4781 * XINT (f
->lface
[LFACE_HEIGHT_INDEX
]));
4785 /* Evaluate IT->font_height with `height' bound to the
4786 current specified height to get the new height. */
4787 ptrdiff_t count
= SPECPDL_INDEX ();
4789 specbind (Qheight
, face
->lface
[LFACE_HEIGHT_INDEX
]);
4790 value
= safe_eval (it
->font_height
);
4791 unbind_to (count
, Qnil
);
4793 if (NUMBERP (value
))
4794 new_height
= XFLOATINT (value
);
4798 it
->face_id
= face_with_height (it
->f
, it
->face_id
, new_height
);
4805 /* Handle `(space-width WIDTH)'. */
4807 && EQ (XCAR (spec
), Qspace_width
)
4808 && CONSP (XCDR (spec
)))
4812 if (!FRAME_WINDOW_P (it
->f
))
4815 value
= XCAR (XCDR (spec
));
4816 if (NUMBERP (value
) && XFLOATINT (value
) > 0)
4817 it
->space_width
= value
;
4823 /* Handle `(slice X Y WIDTH HEIGHT)'. */
4825 && EQ (XCAR (spec
), Qslice
))
4831 if (!FRAME_WINDOW_P (it
->f
))
4834 if (tem
= XCDR (spec
), CONSP (tem
))
4836 it
->slice
.x
= XCAR (tem
);
4837 if (tem
= XCDR (tem
), CONSP (tem
))
4839 it
->slice
.y
= XCAR (tem
);
4840 if (tem
= XCDR (tem
), CONSP (tem
))
4842 it
->slice
.width
= XCAR (tem
);
4843 if (tem
= XCDR (tem
), CONSP (tem
))
4844 it
->slice
.height
= XCAR (tem
);
4853 /* Handle `(raise FACTOR)'. */
4855 && EQ (XCAR (spec
), Qraise
)
4856 && CONSP (XCDR (spec
)))
4860 if (!FRAME_WINDOW_P (it
->f
))
4863 #ifdef HAVE_WINDOW_SYSTEM
4864 value
= XCAR (XCDR (spec
));
4865 if (NUMBERP (value
))
4867 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
4868 it
->voffset
= - (XFLOATINT (value
)
4869 * (FONT_HEIGHT (face
->font
)));
4871 #endif /* HAVE_WINDOW_SYSTEM */
4877 /* Don't handle the other kinds of display specifications
4878 inside a string that we got from a `display' property. */
4879 if (it
&& it
->string_from_display_prop_p
)
4882 /* Characters having this form of property are not displayed, so
4883 we have to find the end of the property. */
4886 start_pos
= *position
;
4887 *position
= display_prop_end (it
, object
, start_pos
);
4891 /* Stop the scan at that end position--we assume that all
4892 text properties change there. */
4894 it
->stop_charpos
= position
->charpos
;
4896 /* Handle `(left-fringe BITMAP [FACE])'
4897 and `(right-fringe BITMAP [FACE])'. */
4899 && (EQ (XCAR (spec
), Qleft_fringe
)
4900 || EQ (XCAR (spec
), Qright_fringe
))
4901 && CONSP (XCDR (spec
)))
4907 if (!FRAME_WINDOW_P (it
->f
))
4908 /* If we return here, POSITION has been advanced
4909 across the text with this property. */
4911 /* Synchronize the bidi iterator with POSITION. This is
4912 needed because we are not going to push the iterator
4913 on behalf of this display property, so there will be
4914 no pop_it call to do this synchronization for us. */
4917 it
->position
= *position
;
4918 iterate_out_of_display_property (it
);
4919 *position
= it
->position
;
4924 else if (!frame_window_p
)
4927 #ifdef HAVE_WINDOW_SYSTEM
4928 value
= XCAR (XCDR (spec
));
4929 if (!SYMBOLP (value
)
4930 || !(fringe_bitmap
= lookup_fringe_bitmap (value
)))
4931 /* If we return here, POSITION has been advanced
4932 across the text with this property. */
4934 if (it
&& it
->bidi_p
)
4936 it
->position
= *position
;
4937 iterate_out_of_display_property (it
);
4938 *position
= it
->position
;
4945 int face_id
= lookup_basic_face (it
->f
, DEFAULT_FACE_ID
);;
4947 if (CONSP (XCDR (XCDR (spec
))))
4949 Lisp_Object face_name
= XCAR (XCDR (XCDR (spec
)));
4950 int face_id2
= lookup_derived_face (it
->f
, face_name
,
4956 /* Save current settings of IT so that we can restore them
4957 when we are finished with the glyph property value. */
4958 push_it (it
, position
);
4960 it
->area
= TEXT_AREA
;
4961 it
->what
= IT_IMAGE
;
4962 it
->image_id
= -1; /* no image */
4963 it
->position
= start_pos
;
4964 it
->object
= NILP (object
) ? it
->w
->contents
: object
;
4965 it
->method
= GET_FROM_IMAGE
;
4966 it
->from_overlay
= Qnil
;
4967 it
->face_id
= face_id
;
4968 it
->from_disp_prop_p
= 1;
4970 /* Say that we haven't consumed the characters with
4971 `display' property yet. The call to pop_it in
4972 set_iterator_to_next will clean this up. */
4973 *position
= start_pos
;
4975 if (EQ (XCAR (spec
), Qleft_fringe
))
4977 it
->left_user_fringe_bitmap
= fringe_bitmap
;
4978 it
->left_user_fringe_face_id
= face_id
;
4982 it
->right_user_fringe_bitmap
= fringe_bitmap
;
4983 it
->right_user_fringe_face_id
= face_id
;
4986 #endif /* HAVE_WINDOW_SYSTEM */
4990 /* Prepare to handle `((margin left-margin) ...)',
4991 `((margin right-margin) ...)' and `((margin nil) ...)'
4992 prefixes for display specifications. */
4993 location
= Qunbound
;
4994 if (CONSP (spec
) && CONSP (XCAR (spec
)))
4998 value
= XCDR (spec
);
5000 value
= XCAR (value
);
5003 if (EQ (XCAR (tem
), Qmargin
)
5004 && (tem
= XCDR (tem
),
5005 tem
= CONSP (tem
) ? XCAR (tem
) : Qnil
,
5007 || EQ (tem
, Qleft_margin
)
5008 || EQ (tem
, Qright_margin
))))
5012 if (EQ (location
, Qunbound
))
5018 /* After this point, VALUE is the property after any
5019 margin prefix has been stripped. It must be a string,
5020 an image specification, or `(space ...)'.
5022 LOCATION specifies where to display: `left-margin',
5023 `right-margin' or nil. */
5025 valid_p
= (STRINGP (value
)
5026 #ifdef HAVE_WINDOW_SYSTEM
5027 || ((it
? FRAME_WINDOW_P (it
->f
) : frame_window_p
)
5028 && valid_image_p (value
))
5029 #endif /* not HAVE_WINDOW_SYSTEM */
5030 || (CONSP (value
) && EQ (XCAR (value
), Qspace
)));
5032 if (valid_p
&& !display_replaced_p
)
5038 /* Callers need to know whether the display spec is any kind
5039 of `(space ...)' spec that is about to affect text-area
5041 if (CONSP (value
) && EQ (XCAR (value
), Qspace
) && NILP (location
))
5046 /* Save current settings of IT so that we can restore them
5047 when we are finished with the glyph property value. */
5048 push_it (it
, position
);
5049 it
->from_overlay
= overlay
;
5050 it
->from_disp_prop_p
= 1;
5052 if (NILP (location
))
5053 it
->area
= TEXT_AREA
;
5054 else if (EQ (location
, Qleft_margin
))
5055 it
->area
= LEFT_MARGIN_AREA
;
5057 it
->area
= RIGHT_MARGIN_AREA
;
5059 if (STRINGP (value
))
5062 it
->multibyte_p
= STRING_MULTIBYTE (it
->string
);
5063 it
->current
.overlay_string_index
= -1;
5064 IT_STRING_CHARPOS (*it
) = IT_STRING_BYTEPOS (*it
) = 0;
5065 it
->end_charpos
= it
->string_nchars
= SCHARS (it
->string
);
5066 it
->method
= GET_FROM_STRING
;
5067 it
->stop_charpos
= 0;
5069 it
->base_level_stop
= 0;
5070 it
->string_from_display_prop_p
= 1;
5071 /* Say that we haven't consumed the characters with
5072 `display' property yet. The call to pop_it in
5073 set_iterator_to_next will clean this up. */
5074 if (BUFFERP (object
))
5075 *position
= start_pos
;
5077 /* Force paragraph direction to be that of the parent
5078 object. If the parent object's paragraph direction is
5079 not yet determined, default to L2R. */
5080 if (it
->bidi_p
&& it
->bidi_it
.paragraph_dir
== R2L
)
5081 it
->paragraph_embedding
= it
->bidi_it
.paragraph_dir
;
5083 it
->paragraph_embedding
= L2R
;
5085 /* Set up the bidi iterator for this display string. */
5088 it
->bidi_it
.string
.lstring
= it
->string
;
5089 it
->bidi_it
.string
.s
= NULL
;
5090 it
->bidi_it
.string
.schars
= it
->end_charpos
;
5091 it
->bidi_it
.string
.bufpos
= bufpos
;
5092 it
->bidi_it
.string
.from_disp_str
= 1;
5093 it
->bidi_it
.string
.unibyte
= !it
->multibyte_p
;
5094 it
->bidi_it
.w
= it
->w
;
5095 bidi_init_it (0, 0, FRAME_WINDOW_P (it
->f
), &it
->bidi_it
);
5098 else if (CONSP (value
) && EQ (XCAR (value
), Qspace
))
5100 it
->method
= GET_FROM_STRETCH
;
5102 *position
= it
->position
= start_pos
;
5103 retval
= 1 + (it
->area
== TEXT_AREA
);
5105 #ifdef HAVE_WINDOW_SYSTEM
5108 it
->what
= IT_IMAGE
;
5109 it
->image_id
= lookup_image (it
->f
, value
);
5110 it
->position
= start_pos
;
5111 it
->object
= NILP (object
) ? it
->w
->contents
: object
;
5112 it
->method
= GET_FROM_IMAGE
;
5114 /* Say that we haven't consumed the characters with
5115 `display' property yet. The call to pop_it in
5116 set_iterator_to_next will clean this up. */
5117 *position
= start_pos
;
5119 #endif /* HAVE_WINDOW_SYSTEM */
5124 /* Invalid property or property not supported. Restore
5125 POSITION to what it was before. */
5126 *position
= start_pos
;
5130 /* Check if PROP is a display property value whose text should be
5131 treated as intangible. OVERLAY is the overlay from which PROP
5132 came, or nil if it came from a text property. CHARPOS and BYTEPOS
5133 specify the buffer position covered by PROP. */
5136 display_prop_intangible_p (Lisp_Object prop
, Lisp_Object overlay
,
5137 ptrdiff_t charpos
, ptrdiff_t bytepos
)
5139 int frame_window_p
= FRAME_WINDOW_P (XFRAME (selected_frame
));
5140 struct text_pos position
;
5142 SET_TEXT_POS (position
, charpos
, bytepos
);
5143 return handle_display_spec (NULL
, prop
, Qnil
, overlay
,
5144 &position
, charpos
, frame_window_p
);
5148 /* Return 1 if PROP is a display sub-property value containing STRING.
5150 Implementation note: this and the following function are really
5151 special cases of handle_display_spec and
5152 handle_single_display_spec, and should ideally use the same code.
5153 Until they do, these two pairs must be consistent and must be
5154 modified in sync. */
5157 single_display_spec_string_p (Lisp_Object prop
, Lisp_Object string
)
5159 if (EQ (string
, prop
))
5162 /* Skip over `when FORM'. */
5163 if (CONSP (prop
) && EQ (XCAR (prop
), Qwhen
))
5168 /* Actually, the condition following `when' should be eval'ed,
5169 like handle_single_display_spec does, and we should return
5170 zero if it evaluates to nil. However, this function is
5171 called only when the buffer was already displayed and some
5172 glyph in the glyph matrix was found to come from a display
5173 string. Therefore, the condition was already evaluated, and
5174 the result was non-nil, otherwise the display string wouldn't
5175 have been displayed and we would have never been called for
5176 this property. Thus, we can skip the evaluation and assume
5177 its result is non-nil. */
5182 /* Skip over `margin LOCATION'. */
5183 if (EQ (XCAR (prop
), Qmargin
))
5194 return EQ (prop
, string
) || (CONSP (prop
) && EQ (XCAR (prop
), string
));
5198 /* Return 1 if STRING appears in the `display' property PROP. */
5201 display_prop_string_p (Lisp_Object prop
, Lisp_Object string
)
5204 && !EQ (XCAR (prop
), Qwhen
)
5205 && !(CONSP (XCAR (prop
)) && EQ (Qmargin
, XCAR (XCAR (prop
)))))
5207 /* A list of sub-properties. */
5208 while (CONSP (prop
))
5210 if (single_display_spec_string_p (XCAR (prop
), string
))
5215 else if (VECTORP (prop
))
5217 /* A vector of sub-properties. */
5219 for (i
= 0; i
< ASIZE (prop
); ++i
)
5220 if (single_display_spec_string_p (AREF (prop
, i
), string
))
5224 return single_display_spec_string_p (prop
, string
);
5229 /* Look for STRING in overlays and text properties in the current
5230 buffer, between character positions FROM and TO (excluding TO).
5231 BACK_P non-zero means look back (in this case, TO is supposed to be
5233 Value is the first character position where STRING was found, or
5234 zero if it wasn't found before hitting TO.
5236 This function may only use code that doesn't eval because it is
5237 called asynchronously from note_mouse_highlight. */
5240 string_buffer_position_lim (Lisp_Object string
,
5241 ptrdiff_t from
, ptrdiff_t to
, int back_p
)
5243 Lisp_Object limit
, prop
, pos
;
5246 pos
= make_number (max (from
, BEGV
));
5248 if (!back_p
) /* looking forward */
5250 limit
= make_number (min (to
, ZV
));
5251 while (!found
&& !EQ (pos
, limit
))
5253 prop
= Fget_char_property (pos
, Qdisplay
, Qnil
);
5254 if (!NILP (prop
) && display_prop_string_p (prop
, string
))
5257 pos
= Fnext_single_char_property_change (pos
, Qdisplay
, Qnil
,
5261 else /* looking back */
5263 limit
= make_number (max (to
, BEGV
));
5264 while (!found
&& !EQ (pos
, limit
))
5266 prop
= Fget_char_property (pos
, Qdisplay
, Qnil
);
5267 if (!NILP (prop
) && display_prop_string_p (prop
, string
))
5270 pos
= Fprevious_single_char_property_change (pos
, Qdisplay
, Qnil
,
5275 return found
? XINT (pos
) : 0;
5278 /* Determine which buffer position in current buffer STRING comes from.
5279 AROUND_CHARPOS is an approximate position where it could come from.
5280 Value is the buffer position or 0 if it couldn't be determined.
5282 This function is necessary because we don't record buffer positions
5283 in glyphs generated from strings (to keep struct glyph small).
5284 This function may only use code that doesn't eval because it is
5285 called asynchronously from note_mouse_highlight. */
5288 string_buffer_position (Lisp_Object string
, ptrdiff_t around_charpos
)
5290 const int MAX_DISTANCE
= 1000;
5291 ptrdiff_t found
= string_buffer_position_lim (string
, around_charpos
,
5292 around_charpos
+ MAX_DISTANCE
,
5296 found
= string_buffer_position_lim (string
, around_charpos
,
5297 around_charpos
- MAX_DISTANCE
, 1);
5303 /***********************************************************************
5304 `composition' property
5305 ***********************************************************************/
5307 /* Set up iterator IT from `composition' property at its current
5308 position. Called from handle_stop. */
5310 static enum prop_handled
5311 handle_composition_prop (struct it
*it
)
5313 Lisp_Object prop
, string
;
5314 ptrdiff_t pos
, pos_byte
, start
, end
;
5316 if (STRINGP (it
->string
))
5320 pos
= IT_STRING_CHARPOS (*it
);
5321 pos_byte
= IT_STRING_BYTEPOS (*it
);
5322 string
= it
->string
;
5323 s
= SDATA (string
) + pos_byte
;
5324 it
->c
= STRING_CHAR (s
);
5328 pos
= IT_CHARPOS (*it
);
5329 pos_byte
= IT_BYTEPOS (*it
);
5331 it
->c
= FETCH_CHAR (pos_byte
);
5334 /* If there's a valid composition and point is not inside of the
5335 composition (in the case that the composition is from the current
5336 buffer), draw a glyph composed from the composition components. */
5337 if (find_composition (pos
, -1, &start
, &end
, &prop
, string
)
5338 && composition_valid_p (start
, end
, prop
)
5339 && (STRINGP (it
->string
) || (PT
<= start
|| PT
>= end
)))
5342 /* As we can't handle this situation (perhaps font-lock added
5343 a new composition), we just return here hoping that next
5344 redisplay will detect this composition much earlier. */
5345 return HANDLED_NORMALLY
;
5348 if (STRINGP (it
->string
))
5349 pos_byte
= string_char_to_byte (it
->string
, start
);
5351 pos_byte
= CHAR_TO_BYTE (start
);
5353 it
->cmp_it
.id
= get_composition_id (start
, pos_byte
, end
- start
,
5356 if (it
->cmp_it
.id
>= 0)
5359 it
->cmp_it
.nchars
= COMPOSITION_LENGTH (prop
);
5360 it
->cmp_it
.nglyphs
= -1;
5364 return HANDLED_NORMALLY
;
5369 /***********************************************************************
5371 ***********************************************************************/
5373 /* The following structure is used to record overlay strings for
5374 later sorting in load_overlay_strings. */
5376 struct overlay_entry
5378 Lisp_Object overlay
;
5385 /* Set up iterator IT from overlay strings at its current position.
5386 Called from handle_stop. */
5388 static enum prop_handled
5389 handle_overlay_change (struct it
*it
)
5391 if (!STRINGP (it
->string
) && get_overlay_strings (it
, 0))
5392 return HANDLED_RECOMPUTE_PROPS
;
5394 return HANDLED_NORMALLY
;
5398 /* Set up the next overlay string for delivery by IT, if there is an
5399 overlay string to deliver. Called by set_iterator_to_next when the
5400 end of the current overlay string is reached. If there are more
5401 overlay strings to display, IT->string and
5402 IT->current.overlay_string_index are set appropriately here.
5403 Otherwise IT->string is set to nil. */
5406 next_overlay_string (struct it
*it
)
5408 ++it
->current
.overlay_string_index
;
5409 if (it
->current
.overlay_string_index
== it
->n_overlay_strings
)
5411 /* No more overlay strings. Restore IT's settings to what
5412 they were before overlay strings were processed, and
5413 continue to deliver from current_buffer. */
5415 it
->ellipsis_p
= (it
->stack
[it
->sp
- 1].display_ellipsis_p
!= 0);
5418 || (NILP (it
->string
)
5419 && it
->method
== GET_FROM_BUFFER
5420 && it
->stop_charpos
>= BEGV
5421 && it
->stop_charpos
<= it
->end_charpos
));
5422 it
->current
.overlay_string_index
= -1;
5423 it
->n_overlay_strings
= 0;
5424 it
->overlay_strings_charpos
= -1;
5425 /* If there's an empty display string on the stack, pop the
5426 stack, to resync the bidi iterator with IT's position. Such
5427 empty strings are pushed onto the stack in
5428 get_overlay_strings_1. */
5429 if (it
->sp
> 0 && STRINGP (it
->string
) && !SCHARS (it
->string
))
5432 /* If we're at the end of the buffer, record that we have
5433 processed the overlay strings there already, so that
5434 next_element_from_buffer doesn't try it again. */
5435 if (NILP (it
->string
) && IT_CHARPOS (*it
) >= it
->end_charpos
)
5436 it
->overlay_strings_at_end_processed_p
= 1;
5440 /* There are more overlay strings to process. If
5441 IT->current.overlay_string_index has advanced to a position
5442 where we must load IT->overlay_strings with more strings, do
5443 it. We must load at the IT->overlay_strings_charpos where
5444 IT->n_overlay_strings was originally computed; when invisible
5445 text is present, this might not be IT_CHARPOS (Bug#7016). */
5446 int i
= it
->current
.overlay_string_index
% OVERLAY_STRING_CHUNK_SIZE
;
5448 if (it
->current
.overlay_string_index
&& i
== 0)
5449 load_overlay_strings (it
, it
->overlay_strings_charpos
);
5451 /* Initialize IT to deliver display elements from the overlay
5453 it
->string
= it
->overlay_strings
[i
];
5454 it
->multibyte_p
= STRING_MULTIBYTE (it
->string
);
5455 SET_TEXT_POS (it
->current
.string_pos
, 0, 0);
5456 it
->method
= GET_FROM_STRING
;
5457 it
->stop_charpos
= 0;
5458 it
->end_charpos
= SCHARS (it
->string
);
5459 if (it
->cmp_it
.stop_pos
>= 0)
5460 it
->cmp_it
.stop_pos
= 0;
5462 it
->base_level_stop
= 0;
5464 /* Set up the bidi iterator for this overlay string. */
5467 it
->bidi_it
.string
.lstring
= it
->string
;
5468 it
->bidi_it
.string
.s
= NULL
;
5469 it
->bidi_it
.string
.schars
= SCHARS (it
->string
);
5470 it
->bidi_it
.string
.bufpos
= it
->overlay_strings_charpos
;
5471 it
->bidi_it
.string
.from_disp_str
= it
->string_from_display_prop_p
;
5472 it
->bidi_it
.string
.unibyte
= !it
->multibyte_p
;
5473 it
->bidi_it
.w
= it
->w
;
5474 bidi_init_it (0, 0, FRAME_WINDOW_P (it
->f
), &it
->bidi_it
);
5482 /* Compare two overlay_entry structures E1 and E2. Used as a
5483 comparison function for qsort in load_overlay_strings. Overlay
5484 strings for the same position are sorted so that
5486 1. All after-strings come in front of before-strings, except
5487 when they come from the same overlay.
5489 2. Within after-strings, strings are sorted so that overlay strings
5490 from overlays with higher priorities come first.
5492 2. Within before-strings, strings are sorted so that overlay
5493 strings from overlays with higher priorities come last.
5495 Value is analogous to strcmp. */
5499 compare_overlay_entries (const void *e1
, const void *e2
)
5501 struct overlay_entry
const *entry1
= e1
;
5502 struct overlay_entry
const *entry2
= e2
;
5505 if (entry1
->after_string_p
!= entry2
->after_string_p
)
5507 /* Let after-strings appear in front of before-strings if
5508 they come from different overlays. */
5509 if (EQ (entry1
->overlay
, entry2
->overlay
))
5510 result
= entry1
->after_string_p
? 1 : -1;
5512 result
= entry1
->after_string_p
? -1 : 1;
5514 else if (entry1
->priority
!= entry2
->priority
)
5516 if (entry1
->after_string_p
)
5517 /* After-strings sorted in order of decreasing priority. */
5518 result
= entry2
->priority
< entry1
->priority
? -1 : 1;
5520 /* Before-strings sorted in order of increasing priority. */
5521 result
= entry1
->priority
< entry2
->priority
? -1 : 1;
5530 /* Load the vector IT->overlay_strings with overlay strings from IT's
5531 current buffer position, or from CHARPOS if that is > 0. Set
5532 IT->n_overlays to the total number of overlay strings found.
5534 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
5535 a time. On entry into load_overlay_strings,
5536 IT->current.overlay_string_index gives the number of overlay
5537 strings that have already been loaded by previous calls to this
5540 IT->add_overlay_start contains an additional overlay start
5541 position to consider for taking overlay strings from, if non-zero.
5542 This position comes into play when the overlay has an `invisible'
5543 property, and both before and after-strings. When we've skipped to
5544 the end of the overlay, because of its `invisible' property, we
5545 nevertheless want its before-string to appear.
5546 IT->add_overlay_start will contain the overlay start position
5549 Overlay strings are sorted so that after-string strings come in
5550 front of before-string strings. Within before and after-strings,
5551 strings are sorted by overlay priority. See also function
5552 compare_overlay_entries. */
5555 load_overlay_strings (struct it
*it
, ptrdiff_t charpos
)
5557 Lisp_Object overlay
, window
, str
, invisible
;
5558 struct Lisp_Overlay
*ov
;
5559 ptrdiff_t start
, end
;
5560 ptrdiff_t size
= 20;
5561 ptrdiff_t n
= 0, i
, j
;
5563 struct overlay_entry
*entries
= alloca (size
* sizeof *entries
);
5567 charpos
= IT_CHARPOS (*it
);
5569 /* Append the overlay string STRING of overlay OVERLAY to vector
5570 `entries' which has size `size' and currently contains `n'
5571 elements. AFTER_P non-zero means STRING is an after-string of
5573 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
5576 Lisp_Object priority; \
5580 struct overlay_entry *old = entries; \
5581 SAFE_NALLOCA (entries, 2, size); \
5582 memcpy (entries, old, size * sizeof *entries); \
5586 entries[n].string = (STRING); \
5587 entries[n].overlay = (OVERLAY); \
5588 priority = Foverlay_get ((OVERLAY), Qpriority); \
5589 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
5590 entries[n].after_string_p = (AFTER_P); \
5595 /* Process overlay before the overlay center. */
5596 for (ov
= current_buffer
->overlays_before
; ov
; ov
= ov
->next
)
5598 XSETMISC (overlay
, ov
);
5599 eassert (OVERLAYP (overlay
));
5600 start
= OVERLAY_POSITION (OVERLAY_START (overlay
));
5601 end
= OVERLAY_POSITION (OVERLAY_END (overlay
));
5606 /* Skip this overlay if it doesn't start or end at IT's current
5608 if (end
!= charpos
&& start
!= charpos
)
5611 /* Skip this overlay if it doesn't apply to IT->w. */
5612 window
= Foverlay_get (overlay
, Qwindow
);
5613 if (WINDOWP (window
) && XWINDOW (window
) != it
->w
)
5616 /* If the text ``under'' the overlay is invisible, both before-
5617 and after-strings from this overlay are visible; start and
5618 end position are indistinguishable. */
5619 invisible
= Foverlay_get (overlay
, Qinvisible
);
5620 invis_p
= TEXT_PROP_MEANS_INVISIBLE (invisible
);
5622 /* If overlay has a non-empty before-string, record it. */
5623 if ((start
== charpos
|| (end
== charpos
&& invis_p
))
5624 && (str
= Foverlay_get (overlay
, Qbefore_string
), STRINGP (str
))
5626 RECORD_OVERLAY_STRING (overlay
, str
, 0);
5628 /* If overlay has a non-empty after-string, record it. */
5629 if ((end
== charpos
|| (start
== charpos
&& invis_p
))
5630 && (str
= Foverlay_get (overlay
, Qafter_string
), STRINGP (str
))
5632 RECORD_OVERLAY_STRING (overlay
, str
, 1);
5635 /* Process overlays after the overlay center. */
5636 for (ov
= current_buffer
->overlays_after
; ov
; ov
= ov
->next
)
5638 XSETMISC (overlay
, ov
);
5639 eassert (OVERLAYP (overlay
));
5640 start
= OVERLAY_POSITION (OVERLAY_START (overlay
));
5641 end
= OVERLAY_POSITION (OVERLAY_END (overlay
));
5643 if (start
> charpos
)
5646 /* Skip this overlay if it doesn't start or end at IT's current
5648 if (end
!= charpos
&& start
!= charpos
)
5651 /* Skip this overlay if it doesn't apply to IT->w. */
5652 window
= Foverlay_get (overlay
, Qwindow
);
5653 if (WINDOWP (window
) && XWINDOW (window
) != it
->w
)
5656 /* If the text ``under'' the overlay is invisible, it has a zero
5657 dimension, and both before- and after-strings apply. */
5658 invisible
= Foverlay_get (overlay
, Qinvisible
);
5659 invis_p
= TEXT_PROP_MEANS_INVISIBLE (invisible
);
5661 /* If overlay has a non-empty before-string, record it. */
5662 if ((start
== charpos
|| (end
== charpos
&& invis_p
))
5663 && (str
= Foverlay_get (overlay
, Qbefore_string
), STRINGP (str
))
5665 RECORD_OVERLAY_STRING (overlay
, str
, 0);
5667 /* If overlay has a non-empty after-string, record it. */
5668 if ((end
== charpos
|| (start
== charpos
&& invis_p
))
5669 && (str
= Foverlay_get (overlay
, Qafter_string
), STRINGP (str
))
5671 RECORD_OVERLAY_STRING (overlay
, str
, 1);
5674 #undef RECORD_OVERLAY_STRING
5678 qsort (entries
, n
, sizeof *entries
, compare_overlay_entries
);
5680 /* Record number of overlay strings, and where we computed it. */
5681 it
->n_overlay_strings
= n
;
5682 it
->overlay_strings_charpos
= charpos
;
5684 /* IT->current.overlay_string_index is the number of overlay strings
5685 that have already been consumed by IT. Copy some of the
5686 remaining overlay strings to IT->overlay_strings. */
5688 j
= it
->current
.overlay_string_index
;
5689 while (i
< OVERLAY_STRING_CHUNK_SIZE
&& j
< n
)
5691 it
->overlay_strings
[i
] = entries
[j
].string
;
5692 it
->string_overlays
[i
++] = entries
[j
++].overlay
;
5700 /* Get the first chunk of overlay strings at IT's current buffer
5701 position, or at CHARPOS if that is > 0. Value is non-zero if at
5702 least one overlay string was found. */
5705 get_overlay_strings_1 (struct it
*it
, ptrdiff_t charpos
, int compute_stop_p
)
5707 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
5708 process. This fills IT->overlay_strings with strings, and sets
5709 IT->n_overlay_strings to the total number of strings to process.
5710 IT->pos.overlay_string_index has to be set temporarily to zero
5711 because load_overlay_strings needs this; it must be set to -1
5712 when no overlay strings are found because a zero value would
5713 indicate a position in the first overlay string. */
5714 it
->current
.overlay_string_index
= 0;
5715 load_overlay_strings (it
, charpos
);
5717 /* If we found overlay strings, set up IT to deliver display
5718 elements from the first one. Otherwise set up IT to deliver
5719 from current_buffer. */
5720 if (it
->n_overlay_strings
)
5722 /* Make sure we know settings in current_buffer, so that we can
5723 restore meaningful values when we're done with the overlay
5726 compute_stop_pos (it
);
5727 eassert (it
->face_id
>= 0);
5729 /* Save IT's settings. They are restored after all overlay
5730 strings have been processed. */
5731 eassert (!compute_stop_p
|| it
->sp
== 0);
5733 /* When called from handle_stop, there might be an empty display
5734 string loaded. In that case, don't bother saving it. But
5735 don't use this optimization with the bidi iterator, since we
5736 need the corresponding pop_it call to resync the bidi
5737 iterator's position with IT's position, after we are done
5738 with the overlay strings. (The corresponding call to pop_it
5739 in case of an empty display string is in
5740 next_overlay_string.) */
5742 && STRINGP (it
->string
) && !SCHARS (it
->string
)))
5745 /* Set up IT to deliver display elements from the first overlay
5747 IT_STRING_CHARPOS (*it
) = IT_STRING_BYTEPOS (*it
) = 0;
5748 it
->string
= it
->overlay_strings
[0];
5749 it
->from_overlay
= Qnil
;
5750 it
->stop_charpos
= 0;
5751 eassert (STRINGP (it
->string
));
5752 it
->end_charpos
= SCHARS (it
->string
);
5754 it
->base_level_stop
= 0;
5755 it
->multibyte_p
= STRING_MULTIBYTE (it
->string
);
5756 it
->method
= GET_FROM_STRING
;
5757 it
->from_disp_prop_p
= 0;
5759 /* Force paragraph direction to be that of the parent
5761 if (it
->bidi_p
&& it
->bidi_it
.paragraph_dir
== R2L
)
5762 it
->paragraph_embedding
= it
->bidi_it
.paragraph_dir
;
5764 it
->paragraph_embedding
= L2R
;
5766 /* Set up the bidi iterator for this overlay string. */
5769 ptrdiff_t pos
= (charpos
> 0 ? charpos
: IT_CHARPOS (*it
));
5771 it
->bidi_it
.string
.lstring
= it
->string
;
5772 it
->bidi_it
.string
.s
= NULL
;
5773 it
->bidi_it
.string
.schars
= SCHARS (it
->string
);
5774 it
->bidi_it
.string
.bufpos
= pos
;
5775 it
->bidi_it
.string
.from_disp_str
= it
->string_from_display_prop_p
;
5776 it
->bidi_it
.string
.unibyte
= !it
->multibyte_p
;
5777 it
->bidi_it
.w
= it
->w
;
5778 bidi_init_it (0, 0, FRAME_WINDOW_P (it
->f
), &it
->bidi_it
);
5783 it
->current
.overlay_string_index
= -1;
5788 get_overlay_strings (struct it
*it
, ptrdiff_t charpos
)
5791 it
->method
= GET_FROM_BUFFER
;
5793 (void) get_overlay_strings_1 (it
, charpos
, 1);
5797 /* Value is non-zero if we found at least one overlay string. */
5798 return STRINGP (it
->string
);
5803 /***********************************************************************
5804 Saving and restoring state
5805 ***********************************************************************/
5807 /* Save current settings of IT on IT->stack. Called, for example,
5808 before setting up IT for an overlay string, to be able to restore
5809 IT's settings to what they were after the overlay string has been
5810 processed. If POSITION is non-NULL, it is the position to save on
5811 the stack instead of IT->position. */
5814 push_it (struct it
*it
, struct text_pos
*position
)
5816 struct iterator_stack_entry
*p
;
5818 eassert (it
->sp
< IT_STACK_SIZE
);
5819 p
= it
->stack
+ it
->sp
;
5821 p
->stop_charpos
= it
->stop_charpos
;
5822 p
->prev_stop
= it
->prev_stop
;
5823 p
->base_level_stop
= it
->base_level_stop
;
5824 p
->cmp_it
= it
->cmp_it
;
5825 eassert (it
->face_id
>= 0);
5826 p
->face_id
= it
->face_id
;
5827 p
->string
= it
->string
;
5828 p
->method
= it
->method
;
5829 p
->from_overlay
= it
->from_overlay
;
5832 case GET_FROM_IMAGE
:
5833 p
->u
.image
.object
= it
->object
;
5834 p
->u
.image
.image_id
= it
->image_id
;
5835 p
->u
.image
.slice
= it
->slice
;
5837 case GET_FROM_STRETCH
:
5838 p
->u
.stretch
.object
= it
->object
;
5841 p
->position
= position
? *position
: it
->position
;
5842 p
->current
= it
->current
;
5843 p
->end_charpos
= it
->end_charpos
;
5844 p
->string_nchars
= it
->string_nchars
;
5846 p
->multibyte_p
= it
->multibyte_p
;
5847 p
->avoid_cursor_p
= it
->avoid_cursor_p
;
5848 p
->space_width
= it
->space_width
;
5849 p
->font_height
= it
->font_height
;
5850 p
->voffset
= it
->voffset
;
5851 p
->string_from_display_prop_p
= it
->string_from_display_prop_p
;
5852 p
->string_from_prefix_prop_p
= it
->string_from_prefix_prop_p
;
5853 p
->display_ellipsis_p
= 0;
5854 p
->line_wrap
= it
->line_wrap
;
5855 p
->bidi_p
= it
->bidi_p
;
5856 p
->paragraph_embedding
= it
->paragraph_embedding
;
5857 p
->from_disp_prop_p
= it
->from_disp_prop_p
;
5860 /* Save the state of the bidi iterator as well. */
5862 bidi_push_it (&it
->bidi_it
);
5866 iterate_out_of_display_property (struct it
*it
)
5868 int buffer_p
= !STRINGP (it
->string
);
5869 ptrdiff_t eob
= (buffer_p
? ZV
: it
->end_charpos
);
5870 ptrdiff_t bob
= (buffer_p
? BEGV
: 0);
5872 eassert (eob
>= CHARPOS (it
->position
) && CHARPOS (it
->position
) >= bob
);
5874 /* Maybe initialize paragraph direction. If we are at the beginning
5875 of a new paragraph, next_element_from_buffer may not have a
5876 chance to do that. */
5877 if (it
->bidi_it
.first_elt
&& it
->bidi_it
.charpos
< eob
)
5878 bidi_paragraph_init (it
->paragraph_embedding
, &it
->bidi_it
, 1);
5879 /* prev_stop can be zero, so check against BEGV as well. */
5880 while (it
->bidi_it
.charpos
>= bob
5881 && it
->prev_stop
<= it
->bidi_it
.charpos
5882 && it
->bidi_it
.charpos
< CHARPOS (it
->position
)
5883 && it
->bidi_it
.charpos
< eob
)
5884 bidi_move_to_visually_next (&it
->bidi_it
);
5885 /* Record the stop_pos we just crossed, for when we cross it
5887 if (it
->bidi_it
.charpos
> CHARPOS (it
->position
))
5888 it
->prev_stop
= CHARPOS (it
->position
);
5889 /* If we ended up not where pop_it put us, resync IT's
5890 positional members with the bidi iterator. */
5891 if (it
->bidi_it
.charpos
!= CHARPOS (it
->position
))
5892 SET_TEXT_POS (it
->position
, it
->bidi_it
.charpos
, it
->bidi_it
.bytepos
);
5894 it
->current
.pos
= it
->position
;
5896 it
->current
.string_pos
= it
->position
;
5899 /* Restore IT's settings from IT->stack. Called, for example, when no
5900 more overlay strings must be processed, and we return to delivering
5901 display elements from a buffer, or when the end of a string from a
5902 `display' property is reached and we return to delivering display
5903 elements from an overlay string, or from a buffer. */
5906 pop_it (struct it
*it
)
5908 struct iterator_stack_entry
*p
;
5909 int from_display_prop
= it
->from_disp_prop_p
;
5911 eassert (it
->sp
> 0);
5913 p
= it
->stack
+ it
->sp
;
5914 it
->stop_charpos
= p
->stop_charpos
;
5915 it
->prev_stop
= p
->prev_stop
;
5916 it
->base_level_stop
= p
->base_level_stop
;
5917 it
->cmp_it
= p
->cmp_it
;
5918 it
->face_id
= p
->face_id
;
5919 it
->current
= p
->current
;
5920 it
->position
= p
->position
;
5921 it
->string
= p
->string
;
5922 it
->from_overlay
= p
->from_overlay
;
5923 if (NILP (it
->string
))
5924 SET_TEXT_POS (it
->current
.string_pos
, -1, -1);
5925 it
->method
= p
->method
;
5928 case GET_FROM_IMAGE
:
5929 it
->image_id
= p
->u
.image
.image_id
;
5930 it
->object
= p
->u
.image
.object
;
5931 it
->slice
= p
->u
.image
.slice
;
5933 case GET_FROM_STRETCH
:
5934 it
->object
= p
->u
.stretch
.object
;
5936 case GET_FROM_BUFFER
:
5937 it
->object
= it
->w
->contents
;
5939 case GET_FROM_STRING
:
5940 it
->object
= it
->string
;
5942 case GET_FROM_DISPLAY_VECTOR
:
5944 it
->method
= GET_FROM_C_STRING
;
5945 else if (STRINGP (it
->string
))
5946 it
->method
= GET_FROM_STRING
;
5949 it
->method
= GET_FROM_BUFFER
;
5950 it
->object
= it
->w
->contents
;
5953 it
->end_charpos
= p
->end_charpos
;
5954 it
->string_nchars
= p
->string_nchars
;
5956 it
->multibyte_p
= p
->multibyte_p
;
5957 it
->avoid_cursor_p
= p
->avoid_cursor_p
;
5958 it
->space_width
= p
->space_width
;
5959 it
->font_height
= p
->font_height
;
5960 it
->voffset
= p
->voffset
;
5961 it
->string_from_display_prop_p
= p
->string_from_display_prop_p
;
5962 it
->string_from_prefix_prop_p
= p
->string_from_prefix_prop_p
;
5963 it
->line_wrap
= p
->line_wrap
;
5964 it
->bidi_p
= p
->bidi_p
;
5965 it
->paragraph_embedding
= p
->paragraph_embedding
;
5966 it
->from_disp_prop_p
= p
->from_disp_prop_p
;
5969 bidi_pop_it (&it
->bidi_it
);
5970 /* Bidi-iterate until we get out of the portion of text, if any,
5971 covered by a `display' text property or by an overlay with
5972 `display' property. (We cannot just jump there, because the
5973 internal coherency of the bidi iterator state can not be
5974 preserved across such jumps.) We also must determine the
5975 paragraph base direction if the overlay we just processed is
5976 at the beginning of a new paragraph. */
5977 if (from_display_prop
5978 && (it
->method
== GET_FROM_BUFFER
|| it
->method
== GET_FROM_STRING
))
5979 iterate_out_of_display_property (it
);
5981 eassert ((BUFFERP (it
->object
)
5982 && IT_CHARPOS (*it
) == it
->bidi_it
.charpos
5983 && IT_BYTEPOS (*it
) == it
->bidi_it
.bytepos
)
5984 || (STRINGP (it
->object
)
5985 && IT_STRING_CHARPOS (*it
) == it
->bidi_it
.charpos
5986 && IT_STRING_BYTEPOS (*it
) == it
->bidi_it
.bytepos
)
5987 || (CONSP (it
->object
) && it
->method
== GET_FROM_STRETCH
));
5993 /***********************************************************************
5995 ***********************************************************************/
5997 /* Set IT's current position to the previous line start. */
6000 back_to_previous_line_start (struct it
*it
)
6002 ptrdiff_t cp
= IT_CHARPOS (*it
), bp
= IT_BYTEPOS (*it
);
6005 IT_CHARPOS (*it
) = find_newline_no_quit (cp
, bp
, -1, &IT_BYTEPOS (*it
));
6009 /* Move IT to the next line start.
6011 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
6012 we skipped over part of the text (as opposed to moving the iterator
6013 continuously over the text). Otherwise, don't change the value
6016 If BIDI_IT_PREV is non-NULL, store into it the state of the bidi
6017 iterator on the newline, if it was found.
6019 Newlines may come from buffer text, overlay strings, or strings
6020 displayed via the `display' property. That's the reason we can't
6021 simply use find_newline_no_quit.
6023 Note that this function may not skip over invisible text that is so
6024 because of text properties and immediately follows a newline. If
6025 it would, function reseat_at_next_visible_line_start, when called
6026 from set_iterator_to_next, would effectively make invisible
6027 characters following a newline part of the wrong glyph row, which
6028 leads to wrong cursor motion. */
6031 forward_to_next_line_start (struct it
*it
, int *skipped_p
,
6032 struct bidi_it
*bidi_it_prev
)
6034 ptrdiff_t old_selective
;
6035 int newline_found_p
, n
;
6036 const int MAX_NEWLINE_DISTANCE
= 500;
6038 /* If already on a newline, just consume it to avoid unintended
6039 skipping over invisible text below. */
6040 if (it
->what
== IT_CHARACTER
6042 && CHARPOS (it
->position
) == IT_CHARPOS (*it
))
6044 if (it
->bidi_p
&& bidi_it_prev
)
6045 *bidi_it_prev
= it
->bidi_it
;
6046 set_iterator_to_next (it
, 0);
6051 /* Don't handle selective display in the following. It's (a)
6052 unnecessary because it's done by the caller, and (b) leads to an
6053 infinite recursion because next_element_from_ellipsis indirectly
6054 calls this function. */
6055 old_selective
= it
->selective
;
6058 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
6059 from buffer text. */
6060 for (n
= newline_found_p
= 0;
6061 !newline_found_p
&& n
< MAX_NEWLINE_DISTANCE
;
6062 n
+= STRINGP (it
->string
) ? 0 : 1)
6064 if (!get_next_display_element (it
))
6066 newline_found_p
= it
->what
== IT_CHARACTER
&& it
->c
== '\n';
6067 if (newline_found_p
&& it
->bidi_p
&& bidi_it_prev
)
6068 *bidi_it_prev
= it
->bidi_it
;
6069 set_iterator_to_next (it
, 0);
6072 /* If we didn't find a newline near enough, see if we can use a
6074 if (!newline_found_p
)
6076 ptrdiff_t bytepos
, start
= IT_CHARPOS (*it
);
6077 ptrdiff_t limit
= find_newline_no_quit (start
, IT_BYTEPOS (*it
),
6081 eassert (!STRINGP (it
->string
));
6083 /* If there isn't any `display' property in sight, and no
6084 overlays, we can just use the position of the newline in
6086 if (it
->stop_charpos
>= limit
6087 || ((pos
= Fnext_single_property_change (make_number (start
),
6089 make_number (limit
)),
6091 && next_overlay_change (start
) == ZV
))
6095 IT_CHARPOS (*it
) = limit
;
6096 IT_BYTEPOS (*it
) = bytepos
;
6100 struct bidi_it bprev
;
6102 /* Help bidi.c avoid expensive searches for display
6103 properties and overlays, by telling it that there are
6104 none up to `limit'. */
6105 if (it
->bidi_it
.disp_pos
< limit
)
6107 it
->bidi_it
.disp_pos
= limit
;
6108 it
->bidi_it
.disp_prop
= 0;
6111 bprev
= it
->bidi_it
;
6112 bidi_move_to_visually_next (&it
->bidi_it
);
6113 } while (it
->bidi_it
.charpos
!= limit
);
6114 IT_CHARPOS (*it
) = limit
;
6115 IT_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
6117 *bidi_it_prev
= bprev
;
6119 *skipped_p
= newline_found_p
= 1;
6123 while (get_next_display_element (it
)
6124 && !newline_found_p
)
6126 newline_found_p
= ITERATOR_AT_END_OF_LINE_P (it
);
6127 if (newline_found_p
&& it
->bidi_p
&& bidi_it_prev
)
6128 *bidi_it_prev
= it
->bidi_it
;
6129 set_iterator_to_next (it
, 0);
6134 it
->selective
= old_selective
;
6135 return newline_found_p
;
6139 /* Set IT's current position to the previous visible line start. Skip
6140 invisible text that is so either due to text properties or due to
6141 selective display. Caution: this does not change IT->current_x and
6145 back_to_previous_visible_line_start (struct it
*it
)
6147 while (IT_CHARPOS (*it
) > BEGV
)
6149 back_to_previous_line_start (it
);
6151 if (IT_CHARPOS (*it
) <= BEGV
)
6154 /* If selective > 0, then lines indented more than its value are
6156 if (it
->selective
> 0
6157 && indented_beyond_p (IT_CHARPOS (*it
), IT_BYTEPOS (*it
),
6161 /* Check the newline before point for invisibility. */
6164 prop
= Fget_char_property (make_number (IT_CHARPOS (*it
) - 1),
6165 Qinvisible
, it
->window
);
6166 if (TEXT_PROP_MEANS_INVISIBLE (prop
))
6170 if (IT_CHARPOS (*it
) <= BEGV
)
6175 void *it2data
= NULL
;
6178 Lisp_Object val
, overlay
;
6180 SAVE_IT (it2
, *it
, it2data
);
6182 /* If newline is part of a composition, continue from start of composition */
6183 if (find_composition (IT_CHARPOS (*it
), -1, &beg
, &end
, &val
, Qnil
)
6184 && beg
< IT_CHARPOS (*it
))
6187 /* If newline is replaced by a display property, find start of overlay
6188 or interval and continue search from that point. */
6189 pos
= --IT_CHARPOS (it2
);
6192 bidi_unshelve_cache (NULL
, 0);
6193 it2
.string_from_display_prop_p
= 0;
6194 it2
.from_disp_prop_p
= 0;
6195 if (handle_display_prop (&it2
) == HANDLED_RETURN
6196 && !NILP (val
= get_char_property_and_overlay
6197 (make_number (pos
), Qdisplay
, Qnil
, &overlay
))
6198 && (OVERLAYP (overlay
)
6199 ? (beg
= OVERLAY_POSITION (OVERLAY_START (overlay
)))
6200 : get_property_and_range (pos
, Qdisplay
, &val
, &beg
, &end
, Qnil
)))
6202 RESTORE_IT (it
, it
, it2data
);
6206 /* Newline is not replaced by anything -- so we are done. */
6207 RESTORE_IT (it
, it
, it2data
);
6213 IT_CHARPOS (*it
) = beg
;
6214 IT_BYTEPOS (*it
) = buf_charpos_to_bytepos (current_buffer
, beg
);
6218 it
->continuation_lines_width
= 0;
6220 eassert (IT_CHARPOS (*it
) >= BEGV
);
6221 eassert (IT_CHARPOS (*it
) == BEGV
6222 || FETCH_BYTE (IT_BYTEPOS (*it
) - 1) == '\n');
6227 /* Reseat iterator IT at the previous visible line start. Skip
6228 invisible text that is so either due to text properties or due to
6229 selective display. At the end, update IT's overlay information,
6230 face information etc. */
6233 reseat_at_previous_visible_line_start (struct it
*it
)
6235 back_to_previous_visible_line_start (it
);
6236 reseat (it
, it
->current
.pos
, 1);
6241 /* Reseat iterator IT on the next visible line start in the current
6242 buffer. ON_NEWLINE_P non-zero means position IT on the newline
6243 preceding the line start. Skip over invisible text that is so
6244 because of selective display. Compute faces, overlays etc at the
6245 new position. Note that this function does not skip over text that
6246 is invisible because of text properties. */
6249 reseat_at_next_visible_line_start (struct it
*it
, int on_newline_p
)
6251 int newline_found_p
, skipped_p
= 0;
6252 struct bidi_it bidi_it_prev
;
6254 newline_found_p
= forward_to_next_line_start (it
, &skipped_p
, &bidi_it_prev
);
6256 /* Skip over lines that are invisible because they are indented
6257 more than the value of IT->selective. */
6258 if (it
->selective
> 0)
6259 while (IT_CHARPOS (*it
) < ZV
6260 && indented_beyond_p (IT_CHARPOS (*it
), IT_BYTEPOS (*it
),
6263 eassert (IT_BYTEPOS (*it
) == BEGV
6264 || FETCH_BYTE (IT_BYTEPOS (*it
) - 1) == '\n');
6266 forward_to_next_line_start (it
, &skipped_p
, &bidi_it_prev
);
6269 /* Position on the newline if that's what's requested. */
6270 if (on_newline_p
&& newline_found_p
)
6272 if (STRINGP (it
->string
))
6274 if (IT_STRING_CHARPOS (*it
) > 0)
6278 --IT_STRING_CHARPOS (*it
);
6279 --IT_STRING_BYTEPOS (*it
);
6283 /* We need to restore the bidi iterator to the state
6284 it had on the newline, and resync the IT's
6285 position with that. */
6286 it
->bidi_it
= bidi_it_prev
;
6287 IT_STRING_CHARPOS (*it
) = it
->bidi_it
.charpos
;
6288 IT_STRING_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
6292 else if (IT_CHARPOS (*it
) > BEGV
)
6301 /* We need to restore the bidi iterator to the state it
6302 had on the newline and resync IT with that. */
6303 it
->bidi_it
= bidi_it_prev
;
6304 IT_CHARPOS (*it
) = it
->bidi_it
.charpos
;
6305 IT_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
6307 reseat (it
, it
->current
.pos
, 0);
6311 reseat (it
, it
->current
.pos
, 0);
6318 /***********************************************************************
6319 Changing an iterator's position
6320 ***********************************************************************/
6322 /* Change IT's current position to POS in current_buffer. If FORCE_P
6323 is non-zero, always check for text properties at the new position.
6324 Otherwise, text properties are only looked up if POS >=
6325 IT->check_charpos of a property. */
6328 reseat (struct it
*it
, struct text_pos pos
, int force_p
)
6330 ptrdiff_t original_pos
= IT_CHARPOS (*it
);
6332 reseat_1 (it
, pos
, 0);
6334 /* Determine where to check text properties. Avoid doing it
6335 where possible because text property lookup is very expensive. */
6337 || CHARPOS (pos
) > it
->stop_charpos
6338 || CHARPOS (pos
) < original_pos
)
6342 /* For bidi iteration, we need to prime prev_stop and
6343 base_level_stop with our best estimations. */
6344 /* Implementation note: Of course, POS is not necessarily a
6345 stop position, so assigning prev_pos to it is a lie; we
6346 should have called compute_stop_backwards. However, if
6347 the current buffer does not include any R2L characters,
6348 that call would be a waste of cycles, because the
6349 iterator will never move back, and thus never cross this
6350 "fake" stop position. So we delay that backward search
6351 until the time we really need it, in next_element_from_buffer. */
6352 if (CHARPOS (pos
) != it
->prev_stop
)
6353 it
->prev_stop
= CHARPOS (pos
);
6354 if (CHARPOS (pos
) < it
->base_level_stop
)
6355 it
->base_level_stop
= 0; /* meaning it's unknown */
6361 it
->prev_stop
= it
->base_level_stop
= 0;
6370 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
6371 IT->stop_pos to POS, also. */
6374 reseat_1 (struct it
*it
, struct text_pos pos
, int set_stop_p
)
6376 /* Don't call this function when scanning a C string. */
6377 eassert (it
->s
== NULL
);
6379 /* POS must be a reasonable value. */
6380 eassert (CHARPOS (pos
) >= BEGV
&& CHARPOS (pos
) <= ZV
);
6382 it
->current
.pos
= it
->position
= pos
;
6383 it
->end_charpos
= ZV
;
6385 it
->current
.dpvec_index
= -1;
6386 it
->current
.overlay_string_index
= -1;
6387 IT_STRING_CHARPOS (*it
) = -1;
6388 IT_STRING_BYTEPOS (*it
) = -1;
6390 it
->method
= GET_FROM_BUFFER
;
6391 it
->object
= it
->w
->contents
;
6392 it
->area
= TEXT_AREA
;
6393 it
->multibyte_p
= !NILP (BVAR (current_buffer
, enable_multibyte_characters
));
6395 it
->string_from_display_prop_p
= 0;
6396 it
->string_from_prefix_prop_p
= 0;
6398 it
->from_disp_prop_p
= 0;
6399 it
->face_before_selective_p
= 0;
6402 bidi_init_it (IT_CHARPOS (*it
), IT_BYTEPOS (*it
), FRAME_WINDOW_P (it
->f
),
6404 bidi_unshelve_cache (NULL
, 0);
6405 it
->bidi_it
.paragraph_dir
= NEUTRAL_DIR
;
6406 it
->bidi_it
.string
.s
= NULL
;
6407 it
->bidi_it
.string
.lstring
= Qnil
;
6408 it
->bidi_it
.string
.bufpos
= 0;
6409 it
->bidi_it
.string
.unibyte
= 0;
6410 it
->bidi_it
.w
= it
->w
;
6415 it
->stop_charpos
= CHARPOS (pos
);
6416 it
->base_level_stop
= CHARPOS (pos
);
6418 /* This make the information stored in it->cmp_it invalidate. */
6423 /* Set up IT for displaying a string, starting at CHARPOS in window W.
6424 If S is non-null, it is a C string to iterate over. Otherwise,
6425 STRING gives a Lisp string to iterate over.
6427 If PRECISION > 0, don't return more then PRECISION number of
6428 characters from the string.
6430 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
6431 characters have been returned. FIELD_WIDTH < 0 means an infinite
6434 MULTIBYTE = 0 means disable processing of multibyte characters,
6435 MULTIBYTE > 0 means enable it,
6436 MULTIBYTE < 0 means use IT->multibyte_p.
6438 IT must be initialized via a prior call to init_iterator before
6439 calling this function. */
6442 reseat_to_string (struct it
*it
, const char *s
, Lisp_Object string
,
6443 ptrdiff_t charpos
, ptrdiff_t precision
, int field_width
,
6446 /* No region in strings. */
6447 it
->region_beg_charpos
= it
->region_end_charpos
= -1;
6449 /* No text property checks performed by default, but see below. */
6450 it
->stop_charpos
= -1;
6452 /* Set iterator position and end position. */
6453 memset (&it
->current
, 0, sizeof it
->current
);
6454 it
->current
.overlay_string_index
= -1;
6455 it
->current
.dpvec_index
= -1;
6456 eassert (charpos
>= 0);
6458 /* If STRING is specified, use its multibyteness, otherwise use the
6459 setting of MULTIBYTE, if specified. */
6461 it
->multibyte_p
= multibyte
> 0;
6463 /* Bidirectional reordering of strings is controlled by the default
6464 value of bidi-display-reordering. Don't try to reorder while
6465 loading loadup.el, as the necessary character property tables are
6466 not yet available. */
6469 && !NILP (BVAR (&buffer_defaults
, bidi_display_reordering
));
6473 eassert (STRINGP (string
));
6474 it
->string
= string
;
6476 it
->end_charpos
= it
->string_nchars
= SCHARS (string
);
6477 it
->method
= GET_FROM_STRING
;
6478 it
->current
.string_pos
= string_pos (charpos
, string
);
6482 it
->bidi_it
.string
.lstring
= string
;
6483 it
->bidi_it
.string
.s
= NULL
;
6484 it
->bidi_it
.string
.schars
= it
->end_charpos
;
6485 it
->bidi_it
.string
.bufpos
= 0;
6486 it
->bidi_it
.string
.from_disp_str
= 0;
6487 it
->bidi_it
.string
.unibyte
= !it
->multibyte_p
;
6488 it
->bidi_it
.w
= it
->w
;
6489 bidi_init_it (charpos
, IT_STRING_BYTEPOS (*it
),
6490 FRAME_WINDOW_P (it
->f
), &it
->bidi_it
);
6495 it
->s
= (const unsigned char *) s
;
6498 /* Note that we use IT->current.pos, not it->current.string_pos,
6499 for displaying C strings. */
6500 IT_STRING_CHARPOS (*it
) = IT_STRING_BYTEPOS (*it
) = -1;
6501 if (it
->multibyte_p
)
6503 it
->current
.pos
= c_string_pos (charpos
, s
, 1);
6504 it
->end_charpos
= it
->string_nchars
= number_of_chars (s
, 1);
6508 IT_CHARPOS (*it
) = IT_BYTEPOS (*it
) = charpos
;
6509 it
->end_charpos
= it
->string_nchars
= strlen (s
);
6514 it
->bidi_it
.string
.lstring
= Qnil
;
6515 it
->bidi_it
.string
.s
= (const unsigned char *) s
;
6516 it
->bidi_it
.string
.schars
= it
->end_charpos
;
6517 it
->bidi_it
.string
.bufpos
= 0;
6518 it
->bidi_it
.string
.from_disp_str
= 0;
6519 it
->bidi_it
.string
.unibyte
= !it
->multibyte_p
;
6520 it
->bidi_it
.w
= it
->w
;
6521 bidi_init_it (charpos
, IT_BYTEPOS (*it
), FRAME_WINDOW_P (it
->f
),
6524 it
->method
= GET_FROM_C_STRING
;
6527 /* PRECISION > 0 means don't return more than PRECISION characters
6529 if (precision
> 0 && it
->end_charpos
- charpos
> precision
)
6531 it
->end_charpos
= it
->string_nchars
= charpos
+ precision
;
6533 it
->bidi_it
.string
.schars
= it
->end_charpos
;
6536 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
6537 characters have been returned. FIELD_WIDTH == 0 means don't pad,
6538 FIELD_WIDTH < 0 means infinite field width. This is useful for
6539 padding with `-' at the end of a mode line. */
6540 if (field_width
< 0)
6541 field_width
= INFINITY
;
6542 /* Implementation note: We deliberately don't enlarge
6543 it->bidi_it.string.schars here to fit it->end_charpos, because
6544 the bidi iterator cannot produce characters out of thin air. */
6545 if (field_width
> it
->end_charpos
- charpos
)
6546 it
->end_charpos
= charpos
+ field_width
;
6548 /* Use the standard display table for displaying strings. */
6549 if (DISP_TABLE_P (Vstandard_display_table
))
6550 it
->dp
= XCHAR_TABLE (Vstandard_display_table
);
6552 it
->stop_charpos
= charpos
;
6553 it
->prev_stop
= charpos
;
6554 it
->base_level_stop
= 0;
6557 it
->bidi_it
.first_elt
= 1;
6558 it
->bidi_it
.paragraph_dir
= NEUTRAL_DIR
;
6559 it
->bidi_it
.disp_pos
= -1;
6561 if (s
== NULL
&& it
->multibyte_p
)
6563 ptrdiff_t endpos
= SCHARS (it
->string
);
6564 if (endpos
> it
->end_charpos
)
6565 endpos
= it
->end_charpos
;
6566 composition_compute_stop_pos (&it
->cmp_it
, charpos
, -1, endpos
,
6574 /***********************************************************************
6576 ***********************************************************************/
6578 /* Map enum it_method value to corresponding next_element_from_* function. */
6580 static int (* get_next_element
[NUM_IT_METHODS
]) (struct it
*it
) =
6582 next_element_from_buffer
,
6583 next_element_from_display_vector
,
6584 next_element_from_string
,
6585 next_element_from_c_string
,
6586 next_element_from_image
,
6587 next_element_from_stretch
6590 #define GET_NEXT_DISPLAY_ELEMENT(it) (*get_next_element[(it)->method]) (it)
6593 /* Return 1 iff a character at CHARPOS (and BYTEPOS) is composed
6594 (possibly with the following characters). */
6596 #define CHAR_COMPOSED_P(IT,CHARPOS,BYTEPOS,END_CHARPOS) \
6597 ((IT)->cmp_it.id >= 0 \
6598 || ((IT)->cmp_it.stop_pos == (CHARPOS) \
6599 && composition_reseat_it (&(IT)->cmp_it, CHARPOS, BYTEPOS, \
6600 END_CHARPOS, (IT)->w, \
6601 FACE_FROM_ID ((IT)->f, (IT)->face_id), \
6605 /* Lookup the char-table Vglyphless_char_display for character C (-1
6606 if we want information for no-font case), and return the display
6607 method symbol. By side-effect, update it->what and
6608 it->glyphless_method. This function is called from
6609 get_next_display_element for each character element, and from
6610 x_produce_glyphs when no suitable font was found. */
6613 lookup_glyphless_char_display (int c
, struct it
*it
)
6615 Lisp_Object glyphless_method
= Qnil
;
6617 if (CHAR_TABLE_P (Vglyphless_char_display
)
6618 && CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display
)) >= 1)
6622 glyphless_method
= CHAR_TABLE_REF (Vglyphless_char_display
, c
);
6623 if (CONSP (glyphless_method
))
6624 glyphless_method
= FRAME_WINDOW_P (it
->f
)
6625 ? XCAR (glyphless_method
)
6626 : XCDR (glyphless_method
);
6629 glyphless_method
= XCHAR_TABLE (Vglyphless_char_display
)->extras
[0];
6633 if (NILP (glyphless_method
))
6636 /* The default is to display the character by a proper font. */
6638 /* The default for the no-font case is to display an empty box. */
6639 glyphless_method
= Qempty_box
;
6641 if (EQ (glyphless_method
, Qzero_width
))
6644 return glyphless_method
;
6645 /* This method can't be used for the no-font case. */
6646 glyphless_method
= Qempty_box
;
6648 if (EQ (glyphless_method
, Qthin_space
))
6649 it
->glyphless_method
= GLYPHLESS_DISPLAY_THIN_SPACE
;
6650 else if (EQ (glyphless_method
, Qempty_box
))
6651 it
->glyphless_method
= GLYPHLESS_DISPLAY_EMPTY_BOX
;
6652 else if (EQ (glyphless_method
, Qhex_code
))
6653 it
->glyphless_method
= GLYPHLESS_DISPLAY_HEX_CODE
;
6654 else if (STRINGP (glyphless_method
))
6655 it
->glyphless_method
= GLYPHLESS_DISPLAY_ACRONYM
;
6658 /* Invalid value. We use the default method. */
6659 glyphless_method
= Qnil
;
6662 it
->what
= IT_GLYPHLESS
;
6663 return glyphless_method
;
6666 /* Merge escape glyph face and cache the result. */
6668 static struct frame
*last_escape_glyph_frame
= NULL
;
6669 static int last_escape_glyph_face_id
= (1 << FACE_ID_BITS
);
6670 static int last_escape_glyph_merged_face_id
= 0;
6673 merge_escape_glyph_face (struct it
*it
)
6677 if (it
->f
== last_escape_glyph_frame
6678 && it
->face_id
== last_escape_glyph_face_id
)
6679 face_id
= last_escape_glyph_merged_face_id
;
6682 /* Merge the `escape-glyph' face into the current face. */
6683 face_id
= merge_faces (it
->f
, Qescape_glyph
, 0, it
->face_id
);
6684 last_escape_glyph_frame
= it
->f
;
6685 last_escape_glyph_face_id
= it
->face_id
;
6686 last_escape_glyph_merged_face_id
= face_id
;
6691 /* Likewise for glyphless glyph face. */
6693 static struct frame
*last_glyphless_glyph_frame
= NULL
;
6694 static int last_glyphless_glyph_face_id
= (1 << FACE_ID_BITS
);
6695 static int last_glyphless_glyph_merged_face_id
= 0;
6698 merge_glyphless_glyph_face (struct it
*it
)
6702 if (it
->f
== last_glyphless_glyph_frame
6703 && it
->face_id
== last_glyphless_glyph_face_id
)
6704 face_id
= last_glyphless_glyph_merged_face_id
;
6707 /* Merge the `glyphless-char' face into the current face. */
6708 face_id
= merge_faces (it
->f
, Qglyphless_char
, 0, it
->face_id
);
6709 last_glyphless_glyph_frame
= it
->f
;
6710 last_glyphless_glyph_face_id
= it
->face_id
;
6711 last_glyphless_glyph_merged_face_id
= face_id
;
6716 /* Load IT's display element fields with information about the next
6717 display element from the current position of IT. Value is zero if
6718 end of buffer (or C string) is reached. */
6721 get_next_display_element (struct it
*it
)
6723 /* Non-zero means that we found a display element. Zero means that
6724 we hit the end of what we iterate over. Performance note: the
6725 function pointer `method' used here turns out to be faster than
6726 using a sequence of if-statements. */
6730 success_p
= GET_NEXT_DISPLAY_ELEMENT (it
);
6732 if (it
->what
== IT_CHARACTER
)
6734 /* UAX#9, L4: "A character is depicted by a mirrored glyph if
6735 and only if (a) the resolved directionality of that character
6737 /* FIXME: Do we need an exception for characters from display
6739 if (it
->bidi_p
&& it
->bidi_it
.type
== STRONG_R
)
6740 it
->c
= bidi_mirror_char (it
->c
);
6741 /* Map via display table or translate control characters.
6742 IT->c, IT->len etc. have been set to the next character by
6743 the function call above. If we have a display table, and it
6744 contains an entry for IT->c, translate it. Don't do this if
6745 IT->c itself comes from a display table, otherwise we could
6746 end up in an infinite recursion. (An alternative could be to
6747 count the recursion depth of this function and signal an
6748 error when a certain maximum depth is reached.) Is it worth
6750 if (success_p
&& it
->dpvec
== NULL
)
6753 struct charset
*unibyte
= CHARSET_FROM_ID (charset_unibyte
);
6754 int nonascii_space_p
= 0;
6755 int nonascii_hyphen_p
= 0;
6756 int c
= it
->c
; /* This is the character to display. */
6758 if (! it
->multibyte_p
&& ! ASCII_CHAR_P (c
))
6760 eassert (SINGLE_BYTE_CHAR_P (c
));
6761 if (unibyte_display_via_language_environment
)
6763 c
= DECODE_CHAR (unibyte
, c
);
6765 c
= BYTE8_TO_CHAR (it
->c
);
6768 c
= BYTE8_TO_CHAR (it
->c
);
6772 && (dv
= DISP_CHAR_VECTOR (it
->dp
, c
),
6775 struct Lisp_Vector
*v
= XVECTOR (dv
);
6777 /* Return the first character from the display table
6778 entry, if not empty. If empty, don't display the
6779 current character. */
6782 it
->dpvec_char_len
= it
->len
;
6783 it
->dpvec
= v
->contents
;
6784 it
->dpend
= v
->contents
+ v
->header
.size
;
6785 it
->current
.dpvec_index
= 0;
6786 it
->dpvec_face_id
= -1;
6787 it
->saved_face_id
= it
->face_id
;
6788 it
->method
= GET_FROM_DISPLAY_VECTOR
;
6793 set_iterator_to_next (it
, 0);
6798 if (! NILP (lookup_glyphless_char_display (c
, it
)))
6800 if (it
->what
== IT_GLYPHLESS
)
6802 /* Don't display this character. */
6803 set_iterator_to_next (it
, 0);
6807 /* If `nobreak-char-display' is non-nil, we display
6808 non-ASCII spaces and hyphens specially. */
6809 if (! ASCII_CHAR_P (c
) && ! NILP (Vnobreak_char_display
))
6812 nonascii_space_p
= 1;
6813 else if (c
== 0xAD || c
== 0x2010 || c
== 0x2011)
6814 nonascii_hyphen_p
= 1;
6817 /* Translate control characters into `\003' or `^C' form.
6818 Control characters coming from a display table entry are
6819 currently not translated because we use IT->dpvec to hold
6820 the translation. This could easily be changed but I
6821 don't believe that it is worth doing.
6823 The characters handled by `nobreak-char-display' must be
6826 Non-printable characters and raw-byte characters are also
6827 translated to octal form. */
6828 if (((c
< ' ' || c
== 127) /* ASCII control chars */
6829 ? (it
->area
!= TEXT_AREA
6830 /* In mode line, treat \n, \t like other crl chars. */
6833 && (it
->glyph_row
->mode_line_p
|| it
->avoid_cursor_p
))
6834 || (c
!= '\n' && c
!= '\t'))
6836 || nonascii_hyphen_p
6838 || ! CHAR_PRINTABLE_P (c
))))
6840 /* C is a control character, non-ASCII space/hyphen,
6841 raw-byte, or a non-printable character which must be
6842 displayed either as '\003' or as `^C' where the '\\'
6843 and '^' can be defined in the display table. Fill
6844 IT->ctl_chars with glyphs for what we have to
6845 display. Then, set IT->dpvec to these glyphs. */
6852 /* Handle control characters with ^. */
6854 if (ASCII_CHAR_P (c
) && it
->ctl_arrow_p
)
6858 g
= '^'; /* default glyph for Control */
6859 /* Set IT->ctl_chars[0] to the glyph for `^'. */
6861 && (gc
= DISP_CTRL_GLYPH (it
->dp
), GLYPH_CODE_P (gc
)))
6863 g
= GLYPH_CODE_CHAR (gc
);
6864 lface_id
= GLYPH_CODE_FACE (gc
);
6868 ? merge_faces (it
->f
, Qt
, lface_id
, it
->face_id
)
6869 : merge_escape_glyph_face (it
));
6871 XSETINT (it
->ctl_chars
[0], g
);
6872 XSETINT (it
->ctl_chars
[1], c
^ 0100);
6874 goto display_control
;
6877 /* Handle non-ascii space in the mode where it only gets
6880 if (nonascii_space_p
&& EQ (Vnobreak_char_display
, Qt
))
6882 /* Merge `nobreak-space' into the current face. */
6883 face_id
= merge_faces (it
->f
, Qnobreak_space
, 0,
6885 XSETINT (it
->ctl_chars
[0], ' ');
6887 goto display_control
;
6890 /* Handle sequences that start with the "escape glyph". */
6892 /* the default escape glyph is \. */
6893 escape_glyph
= '\\';
6896 && (gc
= DISP_ESCAPE_GLYPH (it
->dp
), GLYPH_CODE_P (gc
)))
6898 escape_glyph
= GLYPH_CODE_CHAR (gc
);
6899 lface_id
= GLYPH_CODE_FACE (gc
);
6903 ? merge_faces (it
->f
, Qt
, lface_id
, it
->face_id
)
6904 : merge_escape_glyph_face (it
));
6906 /* Draw non-ASCII hyphen with just highlighting: */
6908 if (nonascii_hyphen_p
&& EQ (Vnobreak_char_display
, Qt
))
6910 XSETINT (it
->ctl_chars
[0], '-');
6912 goto display_control
;
6915 /* Draw non-ASCII space/hyphen with escape glyph: */
6917 if (nonascii_space_p
|| nonascii_hyphen_p
)
6919 XSETINT (it
->ctl_chars
[0], escape_glyph
);
6920 XSETINT (it
->ctl_chars
[1], nonascii_space_p
? ' ' : '-');
6922 goto display_control
;
6929 if (CHAR_BYTE8_P (c
))
6930 /* Display \200 instead of \17777600. */
6931 c
= CHAR_TO_BYTE8 (c
);
6932 len
= sprintf (str
, "%03o", c
);
6934 XSETINT (it
->ctl_chars
[0], escape_glyph
);
6935 for (i
= 0; i
< len
; i
++)
6936 XSETINT (it
->ctl_chars
[i
+ 1], str
[i
]);
6941 /* Set up IT->dpvec and return first character from it. */
6942 it
->dpvec_char_len
= it
->len
;
6943 it
->dpvec
= it
->ctl_chars
;
6944 it
->dpend
= it
->dpvec
+ ctl_len
;
6945 it
->current
.dpvec_index
= 0;
6946 it
->dpvec_face_id
= face_id
;
6947 it
->saved_face_id
= it
->face_id
;
6948 it
->method
= GET_FROM_DISPLAY_VECTOR
;
6952 it
->char_to_display
= c
;
6956 it
->char_to_display
= it
->c
;
6960 /* Adjust face id for a multibyte character. There are no multibyte
6961 character in unibyte text. */
6962 if ((it
->what
== IT_CHARACTER
|| it
->what
== IT_COMPOSITION
)
6965 && FRAME_WINDOW_P (it
->f
))
6967 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
6969 if (it
->what
== IT_COMPOSITION
&& it
->cmp_it
.ch
>= 0)
6971 /* Automatic composition with glyph-string. */
6972 Lisp_Object gstring
= composition_gstring_from_id (it
->cmp_it
.id
);
6974 it
->face_id
= face_for_font (it
->f
, LGSTRING_FONT (gstring
), face
);
6978 ptrdiff_t pos
= (it
->s
? -1
6979 : STRINGP (it
->string
) ? IT_STRING_CHARPOS (*it
)
6980 : IT_CHARPOS (*it
));
6983 if (it
->what
== IT_CHARACTER
)
6984 c
= it
->char_to_display
;
6987 struct composition
*cmp
= composition_table
[it
->cmp_it
.id
];
6991 for (i
= 0; i
< cmp
->glyph_len
; i
++)
6992 /* TAB in a composition means display glyphs with
6993 padding space on the left or right. */
6994 if ((c
= COMPOSITION_GLYPH (cmp
, i
)) != '\t')
6997 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, c
, pos
, it
->string
);
7002 /* Is this character the last one of a run of characters with
7003 box? If yes, set IT->end_of_box_run_p to 1. */
7007 if (it
->method
== GET_FROM_STRING
&& it
->sp
)
7009 int face_id
= underlying_face_id (it
);
7010 struct face
*face
= FACE_FROM_ID (it
->f
, face_id
);
7014 if (face
->box
== FACE_NO_BOX
)
7016 /* If the box comes from face properties in a
7017 display string, check faces in that string. */
7018 int string_face_id
= face_after_it_pos (it
);
7019 it
->end_of_box_run_p
7020 = (FACE_FROM_ID (it
->f
, string_face_id
)->box
7023 /* Otherwise, the box comes from the underlying face.
7024 If this is the last string character displayed, check
7025 the next buffer location. */
7026 else if ((IT_STRING_CHARPOS (*it
) >= SCHARS (it
->string
) - 1)
7027 && (it
->current
.overlay_string_index
7028 == it
->n_overlay_strings
- 1))
7032 struct text_pos pos
= it
->current
.pos
;
7033 INC_TEXT_POS (pos
, it
->multibyte_p
);
7035 next_face_id
= face_at_buffer_position
7036 (it
->w
, CHARPOS (pos
), it
->region_beg_charpos
,
7037 it
->region_end_charpos
, &ignore
,
7038 (IT_CHARPOS (*it
) + TEXT_PROP_DISTANCE_LIMIT
), 0,
7040 it
->end_of_box_run_p
7041 = (FACE_FROM_ID (it
->f
, next_face_id
)->box
7046 /* next_element_from_display_vector sets this flag according to
7047 faces of the display vector glyphs, see there. */
7048 else if (it
->method
!= GET_FROM_DISPLAY_VECTOR
)
7050 int face_id
= face_after_it_pos (it
);
7051 it
->end_of_box_run_p
7052 = (face_id
!= it
->face_id
7053 && FACE_FROM_ID (it
->f
, face_id
)->box
== FACE_NO_BOX
);
7056 /* If we reached the end of the object we've been iterating (e.g., a
7057 display string or an overlay string), and there's something on
7058 IT->stack, proceed with what's on the stack. It doesn't make
7059 sense to return zero if there's unprocessed stuff on the stack,
7060 because otherwise that stuff will never be displayed. */
7061 if (!success_p
&& it
->sp
> 0)
7063 set_iterator_to_next (it
, 0);
7064 success_p
= get_next_display_element (it
);
7067 /* Value is 0 if end of buffer or string reached. */
7072 /* Move IT to the next display element.
7074 RESEAT_P non-zero means if called on a newline in buffer text,
7075 skip to the next visible line start.
7077 Functions get_next_display_element and set_iterator_to_next are
7078 separate because I find this arrangement easier to handle than a
7079 get_next_display_element function that also increments IT's
7080 position. The way it is we can first look at an iterator's current
7081 display element, decide whether it fits on a line, and if it does,
7082 increment the iterator position. The other way around we probably
7083 would either need a flag indicating whether the iterator has to be
7084 incremented the next time, or we would have to implement a
7085 decrement position function which would not be easy to write. */
7088 set_iterator_to_next (struct it
*it
, int reseat_p
)
7090 /* Reset flags indicating start and end of a sequence of characters
7091 with box. Reset them at the start of this function because
7092 moving the iterator to a new position might set them. */
7093 it
->start_of_box_run_p
= it
->end_of_box_run_p
= 0;
7097 case GET_FROM_BUFFER
:
7098 /* The current display element of IT is a character from
7099 current_buffer. Advance in the buffer, and maybe skip over
7100 invisible lines that are so because of selective display. */
7101 if (ITERATOR_AT_END_OF_LINE_P (it
) && reseat_p
)
7102 reseat_at_next_visible_line_start (it
, 0);
7103 else if (it
->cmp_it
.id
>= 0)
7105 /* We are currently getting glyphs from a composition. */
7110 IT_CHARPOS (*it
) += it
->cmp_it
.nchars
;
7111 IT_BYTEPOS (*it
) += it
->cmp_it
.nbytes
;
7112 if (it
->cmp_it
.to
< it
->cmp_it
.nglyphs
)
7114 it
->cmp_it
.from
= it
->cmp_it
.to
;
7119 composition_compute_stop_pos (&it
->cmp_it
, IT_CHARPOS (*it
),
7121 it
->end_charpos
, Qnil
);
7124 else if (! it
->cmp_it
.reversed_p
)
7126 /* Composition created while scanning forward. */
7127 /* Update IT's char/byte positions to point to the first
7128 character of the next grapheme cluster, or to the
7129 character visually after the current composition. */
7130 for (i
= 0; i
< it
->cmp_it
.nchars
; i
++)
7131 bidi_move_to_visually_next (&it
->bidi_it
);
7132 IT_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
7133 IT_CHARPOS (*it
) = it
->bidi_it
.charpos
;
7135 if (it
->cmp_it
.to
< it
->cmp_it
.nglyphs
)
7137 /* Proceed to the next grapheme cluster. */
7138 it
->cmp_it
.from
= it
->cmp_it
.to
;
7142 /* No more grapheme clusters in this composition.
7143 Find the next stop position. */
7144 ptrdiff_t stop
= it
->end_charpos
;
7145 if (it
->bidi_it
.scan_dir
< 0)
7146 /* Now we are scanning backward and don't know
7149 composition_compute_stop_pos (&it
->cmp_it
, IT_CHARPOS (*it
),
7150 IT_BYTEPOS (*it
), stop
, Qnil
);
7155 /* Composition created while scanning backward. */
7156 /* Update IT's char/byte positions to point to the last
7157 character of the previous grapheme cluster, or the
7158 character visually after the current composition. */
7159 for (i
= 0; i
< it
->cmp_it
.nchars
; i
++)
7160 bidi_move_to_visually_next (&it
->bidi_it
);
7161 IT_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
7162 IT_CHARPOS (*it
) = it
->bidi_it
.charpos
;
7163 if (it
->cmp_it
.from
> 0)
7165 /* Proceed to the previous grapheme cluster. */
7166 it
->cmp_it
.to
= it
->cmp_it
.from
;
7170 /* No more grapheme clusters in this composition.
7171 Find the next stop position. */
7172 ptrdiff_t stop
= it
->end_charpos
;
7173 if (it
->bidi_it
.scan_dir
< 0)
7174 /* Now we are scanning backward and don't know
7177 composition_compute_stop_pos (&it
->cmp_it
, IT_CHARPOS (*it
),
7178 IT_BYTEPOS (*it
), stop
, Qnil
);
7184 eassert (it
->len
!= 0);
7188 IT_BYTEPOS (*it
) += it
->len
;
7189 IT_CHARPOS (*it
) += 1;
7193 int prev_scan_dir
= it
->bidi_it
.scan_dir
;
7194 /* If this is a new paragraph, determine its base
7195 direction (a.k.a. its base embedding level). */
7196 if (it
->bidi_it
.new_paragraph
)
7197 bidi_paragraph_init (it
->paragraph_embedding
, &it
->bidi_it
, 0);
7198 bidi_move_to_visually_next (&it
->bidi_it
);
7199 IT_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
7200 IT_CHARPOS (*it
) = it
->bidi_it
.charpos
;
7201 if (prev_scan_dir
!= it
->bidi_it
.scan_dir
)
7203 /* As the scan direction was changed, we must
7204 re-compute the stop position for composition. */
7205 ptrdiff_t stop
= it
->end_charpos
;
7206 if (it
->bidi_it
.scan_dir
< 0)
7208 composition_compute_stop_pos (&it
->cmp_it
, IT_CHARPOS (*it
),
7209 IT_BYTEPOS (*it
), stop
, Qnil
);
7212 eassert (IT_BYTEPOS (*it
) == CHAR_TO_BYTE (IT_CHARPOS (*it
)));
7216 case GET_FROM_C_STRING
:
7217 /* Current display element of IT is from a C string. */
7219 /* If the string position is beyond string's end, it means
7220 next_element_from_c_string is padding the string with
7221 blanks, in which case we bypass the bidi iterator,
7222 because it cannot deal with such virtual characters. */
7223 || IT_CHARPOS (*it
) >= it
->bidi_it
.string
.schars
)
7225 IT_BYTEPOS (*it
) += it
->len
;
7226 IT_CHARPOS (*it
) += 1;
7230 bidi_move_to_visually_next (&it
->bidi_it
);
7231 IT_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
7232 IT_CHARPOS (*it
) = it
->bidi_it
.charpos
;
7236 case GET_FROM_DISPLAY_VECTOR
:
7237 /* Current display element of IT is from a display table entry.
7238 Advance in the display table definition. Reset it to null if
7239 end reached, and continue with characters from buffers/
7241 ++it
->current
.dpvec_index
;
7243 /* Restore face of the iterator to what they were before the
7244 display vector entry (these entries may contain faces). */
7245 it
->face_id
= it
->saved_face_id
;
7247 if (it
->dpvec
+ it
->current
.dpvec_index
>= it
->dpend
)
7249 int recheck_faces
= it
->ellipsis_p
;
7252 it
->method
= GET_FROM_C_STRING
;
7253 else if (STRINGP (it
->string
))
7254 it
->method
= GET_FROM_STRING
;
7257 it
->method
= GET_FROM_BUFFER
;
7258 it
->object
= it
->w
->contents
;
7262 it
->current
.dpvec_index
= -1;
7264 /* Skip over characters which were displayed via IT->dpvec. */
7265 if (it
->dpvec_char_len
< 0)
7266 reseat_at_next_visible_line_start (it
, 1);
7267 else if (it
->dpvec_char_len
> 0)
7269 if (it
->method
== GET_FROM_STRING
7270 && it
->current
.overlay_string_index
>= 0
7271 && it
->n_overlay_strings
> 0)
7272 it
->ignore_overlay_strings_at_pos_p
= 1;
7273 it
->len
= it
->dpvec_char_len
;
7274 set_iterator_to_next (it
, reseat_p
);
7277 /* Maybe recheck faces after display vector */
7279 it
->stop_charpos
= IT_CHARPOS (*it
);
7283 case GET_FROM_STRING
:
7284 /* Current display element is a character from a Lisp string. */
7285 eassert (it
->s
== NULL
&& STRINGP (it
->string
));
7286 /* Don't advance past string end. These conditions are true
7287 when set_iterator_to_next is called at the end of
7288 get_next_display_element, in which case the Lisp string is
7289 already exhausted, and all we want is pop the iterator
7291 if (it
->current
.overlay_string_index
>= 0)
7293 /* This is an overlay string, so there's no padding with
7294 spaces, and the number of characters in the string is
7295 where the string ends. */
7296 if (IT_STRING_CHARPOS (*it
) >= SCHARS (it
->string
))
7297 goto consider_string_end
;
7301 /* Not an overlay string. There could be padding, so test
7302 against it->end_charpos . */
7303 if (IT_STRING_CHARPOS (*it
) >= it
->end_charpos
)
7304 goto consider_string_end
;
7306 if (it
->cmp_it
.id
>= 0)
7312 IT_STRING_CHARPOS (*it
) += it
->cmp_it
.nchars
;
7313 IT_STRING_BYTEPOS (*it
) += it
->cmp_it
.nbytes
;
7314 if (it
->cmp_it
.to
< it
->cmp_it
.nglyphs
)
7315 it
->cmp_it
.from
= it
->cmp_it
.to
;
7319 composition_compute_stop_pos (&it
->cmp_it
,
7320 IT_STRING_CHARPOS (*it
),
7321 IT_STRING_BYTEPOS (*it
),
7322 it
->end_charpos
, it
->string
);
7325 else if (! it
->cmp_it
.reversed_p
)
7327 for (i
= 0; i
< it
->cmp_it
.nchars
; i
++)
7328 bidi_move_to_visually_next (&it
->bidi_it
);
7329 IT_STRING_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
7330 IT_STRING_CHARPOS (*it
) = it
->bidi_it
.charpos
;
7332 if (it
->cmp_it
.to
< it
->cmp_it
.nglyphs
)
7333 it
->cmp_it
.from
= it
->cmp_it
.to
;
7336 ptrdiff_t stop
= it
->end_charpos
;
7337 if (it
->bidi_it
.scan_dir
< 0)
7339 composition_compute_stop_pos (&it
->cmp_it
,
7340 IT_STRING_CHARPOS (*it
),
7341 IT_STRING_BYTEPOS (*it
), stop
,
7347 for (i
= 0; i
< it
->cmp_it
.nchars
; i
++)
7348 bidi_move_to_visually_next (&it
->bidi_it
);
7349 IT_STRING_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
7350 IT_STRING_CHARPOS (*it
) = it
->bidi_it
.charpos
;
7351 if (it
->cmp_it
.from
> 0)
7352 it
->cmp_it
.to
= it
->cmp_it
.from
;
7355 ptrdiff_t stop
= it
->end_charpos
;
7356 if (it
->bidi_it
.scan_dir
< 0)
7358 composition_compute_stop_pos (&it
->cmp_it
,
7359 IT_STRING_CHARPOS (*it
),
7360 IT_STRING_BYTEPOS (*it
), stop
,
7368 /* If the string position is beyond string's end, it
7369 means next_element_from_string is padding the string
7370 with blanks, in which case we bypass the bidi
7371 iterator, because it cannot deal with such virtual
7373 || IT_STRING_CHARPOS (*it
) >= it
->bidi_it
.string
.schars
)
7375 IT_STRING_BYTEPOS (*it
) += it
->len
;
7376 IT_STRING_CHARPOS (*it
) += 1;
7380 int prev_scan_dir
= it
->bidi_it
.scan_dir
;
7382 bidi_move_to_visually_next (&it
->bidi_it
);
7383 IT_STRING_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
7384 IT_STRING_CHARPOS (*it
) = it
->bidi_it
.charpos
;
7385 if (prev_scan_dir
!= it
->bidi_it
.scan_dir
)
7387 ptrdiff_t stop
= it
->end_charpos
;
7389 if (it
->bidi_it
.scan_dir
< 0)
7391 composition_compute_stop_pos (&it
->cmp_it
,
7392 IT_STRING_CHARPOS (*it
),
7393 IT_STRING_BYTEPOS (*it
), stop
,
7399 consider_string_end
:
7401 if (it
->current
.overlay_string_index
>= 0)
7403 /* IT->string is an overlay string. Advance to the
7404 next, if there is one. */
7405 if (IT_STRING_CHARPOS (*it
) >= SCHARS (it
->string
))
7408 next_overlay_string (it
);
7410 setup_for_ellipsis (it
, 0);
7415 /* IT->string is not an overlay string. If we reached
7416 its end, and there is something on IT->stack, proceed
7417 with what is on the stack. This can be either another
7418 string, this time an overlay string, or a buffer. */
7419 if (IT_STRING_CHARPOS (*it
) == SCHARS (it
->string
)
7423 if (it
->method
== GET_FROM_STRING
)
7424 goto consider_string_end
;
7429 case GET_FROM_IMAGE
:
7430 case GET_FROM_STRETCH
:
7431 /* The position etc with which we have to proceed are on
7432 the stack. The position may be at the end of a string,
7433 if the `display' property takes up the whole string. */
7434 eassert (it
->sp
> 0);
7436 if (it
->method
== GET_FROM_STRING
)
7437 goto consider_string_end
;
7441 /* There are no other methods defined, so this should be a bug. */
7445 eassert (it
->method
!= GET_FROM_STRING
7446 || (STRINGP (it
->string
)
7447 && IT_STRING_CHARPOS (*it
) >= 0));
7450 /* Load IT's display element fields with information about the next
7451 display element which comes from a display table entry or from the
7452 result of translating a control character to one of the forms `^C'
7455 IT->dpvec holds the glyphs to return as characters.
7456 IT->saved_face_id holds the face id before the display vector--it
7457 is restored into IT->face_id in set_iterator_to_next. */
7460 next_element_from_display_vector (struct it
*it
)
7463 int prev_face_id
= it
->face_id
;
7467 eassert (it
->dpvec
&& it
->current
.dpvec_index
>= 0);
7469 it
->face_id
= it
->saved_face_id
;
7471 /* KFS: This code used to check ip->dpvec[0] instead of the current element.
7472 That seemed totally bogus - so I changed it... */
7473 gc
= it
->dpvec
[it
->current
.dpvec_index
];
7475 if (GLYPH_CODE_P (gc
))
7477 struct face
*this_face
, *prev_face
, *next_face
;
7479 it
->c
= GLYPH_CODE_CHAR (gc
);
7480 it
->len
= CHAR_BYTES (it
->c
);
7482 /* The entry may contain a face id to use. Such a face id is
7483 the id of a Lisp face, not a realized face. A face id of
7484 zero means no face is specified. */
7485 if (it
->dpvec_face_id
>= 0)
7486 it
->face_id
= it
->dpvec_face_id
;
7489 int lface_id
= GLYPH_CODE_FACE (gc
);
7491 it
->face_id
= merge_faces (it
->f
, Qt
, lface_id
,
7495 /* Glyphs in the display vector could have the box face, so we
7496 need to set the related flags in the iterator, as
7498 this_face
= FACE_FROM_ID (it
->f
, it
->face_id
);
7499 prev_face
= FACE_FROM_ID (it
->f
, prev_face_id
);
7501 /* Is this character the first character of a box-face run? */
7502 it
->start_of_box_run_p
= (this_face
&& this_face
->box
!= FACE_NO_BOX
7504 || prev_face
->box
== FACE_NO_BOX
));
7506 /* For the last character of the box-face run, we need to look
7507 either at the next glyph from the display vector, or at the
7508 face we saw before the display vector. */
7509 next_face_id
= it
->saved_face_id
;
7510 if (it
->current
.dpvec_index
< it
->dpend
- it
->dpvec
- 1)
7512 if (it
->dpvec_face_id
>= 0)
7513 next_face_id
= it
->dpvec_face_id
;
7517 GLYPH_CODE_FACE (it
->dpvec
[it
->current
.dpvec_index
+ 1]);
7520 next_face_id
= merge_faces (it
->f
, Qt
, lface_id
,
7524 next_face
= FACE_FROM_ID (it
->f
, next_face_id
);
7525 it
->end_of_box_run_p
= (this_face
&& this_face
->box
!= FACE_NO_BOX
7527 || next_face
->box
== FACE_NO_BOX
));
7528 it
->face_box_p
= this_face
&& this_face
->box
!= FACE_NO_BOX
;
7531 /* Display table entry is invalid. Return a space. */
7532 it
->c
= ' ', it
->len
= 1;
7534 /* Don't change position and object of the iterator here. They are
7535 still the values of the character that had this display table
7536 entry or was translated, and that's what we want. */
7537 it
->what
= IT_CHARACTER
;
7541 /* Get the first element of string/buffer in the visual order, after
7542 being reseated to a new position in a string or a buffer. */
7544 get_visually_first_element (struct it
*it
)
7546 int string_p
= STRINGP (it
->string
) || it
->s
;
7547 ptrdiff_t eob
= (string_p
? it
->bidi_it
.string
.schars
: ZV
);
7548 ptrdiff_t bob
= (string_p
? 0 : BEGV
);
7550 if (STRINGP (it
->string
))
7552 it
->bidi_it
.charpos
= IT_STRING_CHARPOS (*it
);
7553 it
->bidi_it
.bytepos
= IT_STRING_BYTEPOS (*it
);
7557 it
->bidi_it
.charpos
= IT_CHARPOS (*it
);
7558 it
->bidi_it
.bytepos
= IT_BYTEPOS (*it
);
7561 if (it
->bidi_it
.charpos
== eob
)
7563 /* Nothing to do, but reset the FIRST_ELT flag, like
7564 bidi_paragraph_init does, because we are not going to
7566 it
->bidi_it
.first_elt
= 0;
7568 else if (it
->bidi_it
.charpos
== bob
7570 && (FETCH_CHAR (it
->bidi_it
.bytepos
- 1) == '\n'
7571 || FETCH_CHAR (it
->bidi_it
.bytepos
) == '\n')))
7573 /* If we are at the beginning of a line/string, we can produce
7574 the next element right away. */
7575 bidi_paragraph_init (it
->paragraph_embedding
, &it
->bidi_it
, 1);
7576 bidi_move_to_visually_next (&it
->bidi_it
);
7580 ptrdiff_t orig_bytepos
= it
->bidi_it
.bytepos
;
7582 /* We need to prime the bidi iterator starting at the line's or
7583 string's beginning, before we will be able to produce the
7586 it
->bidi_it
.charpos
= it
->bidi_it
.bytepos
= 0;
7588 it
->bidi_it
.charpos
= find_newline_no_quit (IT_CHARPOS (*it
),
7589 IT_BYTEPOS (*it
), -1,
7590 &it
->bidi_it
.bytepos
);
7591 bidi_paragraph_init (it
->paragraph_embedding
, &it
->bidi_it
, 1);
7594 /* Now return to buffer/string position where we were asked
7595 to get the next display element, and produce that. */
7596 bidi_move_to_visually_next (&it
->bidi_it
);
7598 while (it
->bidi_it
.bytepos
!= orig_bytepos
7599 && it
->bidi_it
.charpos
< eob
);
7602 /* Adjust IT's position information to where we ended up. */
7603 if (STRINGP (it
->string
))
7605 IT_STRING_CHARPOS (*it
) = it
->bidi_it
.charpos
;
7606 IT_STRING_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
7610 IT_CHARPOS (*it
) = it
->bidi_it
.charpos
;
7611 IT_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
7614 if (STRINGP (it
->string
) || !it
->s
)
7616 ptrdiff_t stop
, charpos
, bytepos
;
7618 if (STRINGP (it
->string
))
7621 stop
= SCHARS (it
->string
);
7622 if (stop
> it
->end_charpos
)
7623 stop
= it
->end_charpos
;
7624 charpos
= IT_STRING_CHARPOS (*it
);
7625 bytepos
= IT_STRING_BYTEPOS (*it
);
7629 stop
= it
->end_charpos
;
7630 charpos
= IT_CHARPOS (*it
);
7631 bytepos
= IT_BYTEPOS (*it
);
7633 if (it
->bidi_it
.scan_dir
< 0)
7635 composition_compute_stop_pos (&it
->cmp_it
, charpos
, bytepos
, stop
,
7640 /* Load IT with the next display element from Lisp string IT->string.
7641 IT->current.string_pos is the current position within the string.
7642 If IT->current.overlay_string_index >= 0, the Lisp string is an
7646 next_element_from_string (struct it
*it
)
7648 struct text_pos position
;
7650 eassert (STRINGP (it
->string
));
7651 eassert (!it
->bidi_p
|| EQ (it
->string
, it
->bidi_it
.string
.lstring
));
7652 eassert (IT_STRING_CHARPOS (*it
) >= 0);
7653 position
= it
->current
.string_pos
;
7655 /* With bidi reordering, the character to display might not be the
7656 character at IT_STRING_CHARPOS. BIDI_IT.FIRST_ELT non-zero means
7657 that we were reseat()ed to a new string, whose paragraph
7658 direction is not known. */
7659 if (it
->bidi_p
&& it
->bidi_it
.first_elt
)
7661 get_visually_first_element (it
);
7662 SET_TEXT_POS (position
, IT_STRING_CHARPOS (*it
), IT_STRING_BYTEPOS (*it
));
7665 /* Time to check for invisible text? */
7666 if (IT_STRING_CHARPOS (*it
) < it
->end_charpos
)
7668 if (IT_STRING_CHARPOS (*it
) >= it
->stop_charpos
)
7671 || BIDI_AT_BASE_LEVEL (it
->bidi_it
)
7672 || IT_STRING_CHARPOS (*it
) == it
->stop_charpos
))
7674 /* With bidi non-linear iteration, we could find
7675 ourselves far beyond the last computed stop_charpos,
7676 with several other stop positions in between that we
7677 missed. Scan them all now, in buffer's logical
7678 order, until we find and handle the last stop_charpos
7679 that precedes our current position. */
7680 handle_stop_backwards (it
, it
->stop_charpos
);
7681 return GET_NEXT_DISPLAY_ELEMENT (it
);
7687 /* Take note of the stop position we just moved
7688 across, for when we will move back across it. */
7689 it
->prev_stop
= it
->stop_charpos
;
7690 /* If we are at base paragraph embedding level, take
7691 note of the last stop position seen at this
7693 if (BIDI_AT_BASE_LEVEL (it
->bidi_it
))
7694 it
->base_level_stop
= it
->stop_charpos
;
7698 /* Since a handler may have changed IT->method, we must
7700 return GET_NEXT_DISPLAY_ELEMENT (it
);
7704 /* If we are before prev_stop, we may have overstepped
7705 on our way backwards a stop_pos, and if so, we need
7706 to handle that stop_pos. */
7707 && IT_STRING_CHARPOS (*it
) < it
->prev_stop
7708 /* We can sometimes back up for reasons that have nothing
7709 to do with bidi reordering. E.g., compositions. The
7710 code below is only needed when we are above the base
7711 embedding level, so test for that explicitly. */
7712 && !BIDI_AT_BASE_LEVEL (it
->bidi_it
))
7714 /* If we lost track of base_level_stop, we have no better
7715 place for handle_stop_backwards to start from than string
7716 beginning. This happens, e.g., when we were reseated to
7717 the previous screenful of text by vertical-motion. */
7718 if (it
->base_level_stop
<= 0
7719 || IT_STRING_CHARPOS (*it
) < it
->base_level_stop
)
7720 it
->base_level_stop
= 0;
7721 handle_stop_backwards (it
, it
->base_level_stop
);
7722 return GET_NEXT_DISPLAY_ELEMENT (it
);
7726 if (it
->current
.overlay_string_index
>= 0)
7728 /* Get the next character from an overlay string. In overlay
7729 strings, there is no field width or padding with spaces to
7731 if (IT_STRING_CHARPOS (*it
) >= SCHARS (it
->string
))
7736 else if (CHAR_COMPOSED_P (it
, IT_STRING_CHARPOS (*it
),
7737 IT_STRING_BYTEPOS (*it
),
7738 it
->bidi_it
.scan_dir
< 0
7740 : SCHARS (it
->string
))
7741 && next_element_from_composition (it
))
7745 else if (STRING_MULTIBYTE (it
->string
))
7747 const unsigned char *s
= (SDATA (it
->string
)
7748 + IT_STRING_BYTEPOS (*it
));
7749 it
->c
= string_char_and_length (s
, &it
->len
);
7753 it
->c
= SREF (it
->string
, IT_STRING_BYTEPOS (*it
));
7759 /* Get the next character from a Lisp string that is not an
7760 overlay string. Such strings come from the mode line, for
7761 example. We may have to pad with spaces, or truncate the
7762 string. See also next_element_from_c_string. */
7763 if (IT_STRING_CHARPOS (*it
) >= it
->end_charpos
)
7768 else if (IT_STRING_CHARPOS (*it
) >= it
->string_nchars
)
7770 /* Pad with spaces. */
7771 it
->c
= ' ', it
->len
= 1;
7772 CHARPOS (position
) = BYTEPOS (position
) = -1;
7774 else if (CHAR_COMPOSED_P (it
, IT_STRING_CHARPOS (*it
),
7775 IT_STRING_BYTEPOS (*it
),
7776 it
->bidi_it
.scan_dir
< 0
7778 : it
->string_nchars
)
7779 && next_element_from_composition (it
))
7783 else if (STRING_MULTIBYTE (it
->string
))
7785 const unsigned char *s
= (SDATA (it
->string
)
7786 + IT_STRING_BYTEPOS (*it
));
7787 it
->c
= string_char_and_length (s
, &it
->len
);
7791 it
->c
= SREF (it
->string
, IT_STRING_BYTEPOS (*it
));
7796 /* Record what we have and where it came from. */
7797 it
->what
= IT_CHARACTER
;
7798 it
->object
= it
->string
;
7799 it
->position
= position
;
7804 /* Load IT with next display element from C string IT->s.
7805 IT->string_nchars is the maximum number of characters to return
7806 from the string. IT->end_charpos may be greater than
7807 IT->string_nchars when this function is called, in which case we
7808 may have to return padding spaces. Value is zero if end of string
7809 reached, including padding spaces. */
7812 next_element_from_c_string (struct it
*it
)
7817 eassert (!it
->bidi_p
|| it
->s
== it
->bidi_it
.string
.s
);
7818 it
->what
= IT_CHARACTER
;
7819 BYTEPOS (it
->position
) = CHARPOS (it
->position
) = 0;
7822 /* With bidi reordering, the character to display might not be the
7823 character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that
7824 we were reseated to a new string, whose paragraph direction is
7826 if (it
->bidi_p
&& it
->bidi_it
.first_elt
)
7827 get_visually_first_element (it
);
7829 /* IT's position can be greater than IT->string_nchars in case a
7830 field width or precision has been specified when the iterator was
7832 if (IT_CHARPOS (*it
) >= it
->end_charpos
)
7834 /* End of the game. */
7838 else if (IT_CHARPOS (*it
) >= it
->string_nchars
)
7840 /* Pad with spaces. */
7841 it
->c
= ' ', it
->len
= 1;
7842 BYTEPOS (it
->position
) = CHARPOS (it
->position
) = -1;
7844 else if (it
->multibyte_p
)
7845 it
->c
= string_char_and_length (it
->s
+ IT_BYTEPOS (*it
), &it
->len
);
7847 it
->c
= it
->s
[IT_BYTEPOS (*it
)], it
->len
= 1;
7853 /* Set up IT to return characters from an ellipsis, if appropriate.
7854 The definition of the ellipsis glyphs may come from a display table
7855 entry. This function fills IT with the first glyph from the
7856 ellipsis if an ellipsis is to be displayed. */
7859 next_element_from_ellipsis (struct it
*it
)
7861 if (it
->selective_display_ellipsis_p
)
7862 setup_for_ellipsis (it
, it
->len
);
7865 /* The face at the current position may be different from the
7866 face we find after the invisible text. Remember what it
7867 was in IT->saved_face_id, and signal that it's there by
7868 setting face_before_selective_p. */
7869 it
->saved_face_id
= it
->face_id
;
7870 it
->method
= GET_FROM_BUFFER
;
7871 it
->object
= it
->w
->contents
;
7872 reseat_at_next_visible_line_start (it
, 1);
7873 it
->face_before_selective_p
= 1;
7876 return GET_NEXT_DISPLAY_ELEMENT (it
);
7880 /* Deliver an image display element. The iterator IT is already
7881 filled with image information (done in handle_display_prop). Value
7886 next_element_from_image (struct it
*it
)
7888 it
->what
= IT_IMAGE
;
7889 it
->ignore_overlay_strings_at_pos_p
= 0;
7894 /* Fill iterator IT with next display element from a stretch glyph
7895 property. IT->object is the value of the text property. Value is
7899 next_element_from_stretch (struct it
*it
)
7901 it
->what
= IT_STRETCH
;
7905 /* Scan backwards from IT's current position until we find a stop
7906 position, or until BEGV. This is called when we find ourself
7907 before both the last known prev_stop and base_level_stop while
7908 reordering bidirectional text. */
7911 compute_stop_pos_backwards (struct it
*it
)
7913 const int SCAN_BACK_LIMIT
= 1000;
7914 struct text_pos pos
;
7915 struct display_pos save_current
= it
->current
;
7916 struct text_pos save_position
= it
->position
;
7917 ptrdiff_t charpos
= IT_CHARPOS (*it
);
7918 ptrdiff_t where_we_are
= charpos
;
7919 ptrdiff_t save_stop_pos
= it
->stop_charpos
;
7920 ptrdiff_t save_end_pos
= it
->end_charpos
;
7922 eassert (NILP (it
->string
) && !it
->s
);
7923 eassert (it
->bidi_p
);
7927 it
->end_charpos
= min (charpos
+ 1, ZV
);
7928 charpos
= max (charpos
- SCAN_BACK_LIMIT
, BEGV
);
7929 SET_TEXT_POS (pos
, charpos
, CHAR_TO_BYTE (charpos
));
7930 reseat_1 (it
, pos
, 0);
7931 compute_stop_pos (it
);
7932 /* We must advance forward, right? */
7933 if (it
->stop_charpos
<= charpos
)
7936 while (charpos
> BEGV
&& it
->stop_charpos
>= it
->end_charpos
);
7938 if (it
->stop_charpos
<= where_we_are
)
7939 it
->prev_stop
= it
->stop_charpos
;
7941 it
->prev_stop
= BEGV
;
7943 it
->current
= save_current
;
7944 it
->position
= save_position
;
7945 it
->stop_charpos
= save_stop_pos
;
7946 it
->end_charpos
= save_end_pos
;
7949 /* Scan forward from CHARPOS in the current buffer/string, until we
7950 find a stop position > current IT's position. Then handle the stop
7951 position before that. This is called when we bump into a stop
7952 position while reordering bidirectional text. CHARPOS should be
7953 the last previously processed stop_pos (or BEGV/0, if none were
7954 processed yet) whose position is less that IT's current
7958 handle_stop_backwards (struct it
*it
, ptrdiff_t charpos
)
7960 int bufp
= !STRINGP (it
->string
);
7961 ptrdiff_t where_we_are
= (bufp
? IT_CHARPOS (*it
) : IT_STRING_CHARPOS (*it
));
7962 struct display_pos save_current
= it
->current
;
7963 struct text_pos save_position
= it
->position
;
7964 struct text_pos pos1
;
7965 ptrdiff_t next_stop
;
7967 /* Scan in strict logical order. */
7968 eassert (it
->bidi_p
);
7972 it
->prev_stop
= charpos
;
7975 SET_TEXT_POS (pos1
, charpos
, CHAR_TO_BYTE (charpos
));
7976 reseat_1 (it
, pos1
, 0);
7979 it
->current
.string_pos
= string_pos (charpos
, it
->string
);
7980 compute_stop_pos (it
);
7981 /* We must advance forward, right? */
7982 if (it
->stop_charpos
<= it
->prev_stop
)
7984 charpos
= it
->stop_charpos
;
7986 while (charpos
<= where_we_are
);
7989 it
->current
= save_current
;
7990 it
->position
= save_position
;
7991 next_stop
= it
->stop_charpos
;
7992 it
->stop_charpos
= it
->prev_stop
;
7994 it
->stop_charpos
= next_stop
;
7997 /* Load IT with the next display element from current_buffer. Value
7998 is zero if end of buffer reached. IT->stop_charpos is the next
7999 position at which to stop and check for text properties or buffer
8003 next_element_from_buffer (struct it
*it
)
8007 eassert (IT_CHARPOS (*it
) >= BEGV
);
8008 eassert (NILP (it
->string
) && !it
->s
);
8009 eassert (!it
->bidi_p
8010 || (EQ (it
->bidi_it
.string
.lstring
, Qnil
)
8011 && it
->bidi_it
.string
.s
== NULL
));
8013 /* With bidi reordering, the character to display might not be the
8014 character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that
8015 we were reseat()ed to a new buffer position, which is potentially
8016 a different paragraph. */
8017 if (it
->bidi_p
&& it
->bidi_it
.first_elt
)
8019 get_visually_first_element (it
);
8020 SET_TEXT_POS (it
->position
, IT_CHARPOS (*it
), IT_BYTEPOS (*it
));
8023 if (IT_CHARPOS (*it
) >= it
->stop_charpos
)
8025 if (IT_CHARPOS (*it
) >= it
->end_charpos
)
8027 int overlay_strings_follow_p
;
8029 /* End of the game, except when overlay strings follow that
8030 haven't been returned yet. */
8031 if (it
->overlay_strings_at_end_processed_p
)
8032 overlay_strings_follow_p
= 0;
8035 it
->overlay_strings_at_end_processed_p
= 1;
8036 overlay_strings_follow_p
= get_overlay_strings (it
, 0);
8039 if (overlay_strings_follow_p
)
8040 success_p
= GET_NEXT_DISPLAY_ELEMENT (it
);
8044 it
->position
= it
->current
.pos
;
8048 else if (!(!it
->bidi_p
8049 || BIDI_AT_BASE_LEVEL (it
->bidi_it
)
8050 || IT_CHARPOS (*it
) == it
->stop_charpos
))
8052 /* With bidi non-linear iteration, we could find ourselves
8053 far beyond the last computed stop_charpos, with several
8054 other stop positions in between that we missed. Scan
8055 them all now, in buffer's logical order, until we find
8056 and handle the last stop_charpos that precedes our
8057 current position. */
8058 handle_stop_backwards (it
, it
->stop_charpos
);
8059 return GET_NEXT_DISPLAY_ELEMENT (it
);
8065 /* Take note of the stop position we just moved across,
8066 for when we will move back across it. */
8067 it
->prev_stop
= it
->stop_charpos
;
8068 /* If we are at base paragraph embedding level, take
8069 note of the last stop position seen at this
8071 if (BIDI_AT_BASE_LEVEL (it
->bidi_it
))
8072 it
->base_level_stop
= it
->stop_charpos
;
8075 return GET_NEXT_DISPLAY_ELEMENT (it
);
8079 /* If we are before prev_stop, we may have overstepped on
8080 our way backwards a stop_pos, and if so, we need to
8081 handle that stop_pos. */
8082 && IT_CHARPOS (*it
) < it
->prev_stop
8083 /* We can sometimes back up for reasons that have nothing
8084 to do with bidi reordering. E.g., compositions. The
8085 code below is only needed when we are above the base
8086 embedding level, so test for that explicitly. */
8087 && !BIDI_AT_BASE_LEVEL (it
->bidi_it
))
8089 if (it
->base_level_stop
<= 0
8090 || IT_CHARPOS (*it
) < it
->base_level_stop
)
8092 /* If we lost track of base_level_stop, we need to find
8093 prev_stop by looking backwards. This happens, e.g., when
8094 we were reseated to the previous screenful of text by
8096 it
->base_level_stop
= BEGV
;
8097 compute_stop_pos_backwards (it
);
8098 handle_stop_backwards (it
, it
->prev_stop
);
8101 handle_stop_backwards (it
, it
->base_level_stop
);
8102 return GET_NEXT_DISPLAY_ELEMENT (it
);
8106 /* No face changes, overlays etc. in sight, so just return a
8107 character from current_buffer. */
8111 /* Maybe run the redisplay end trigger hook. Performance note:
8112 This doesn't seem to cost measurable time. */
8113 if (it
->redisplay_end_trigger_charpos
8115 && IT_CHARPOS (*it
) >= it
->redisplay_end_trigger_charpos
)
8116 run_redisplay_end_trigger_hook (it
);
8118 stop
= it
->bidi_it
.scan_dir
< 0 ? -1 : it
->end_charpos
;
8119 if (CHAR_COMPOSED_P (it
, IT_CHARPOS (*it
), IT_BYTEPOS (*it
),
8121 && next_element_from_composition (it
))
8126 /* Get the next character, maybe multibyte. */
8127 p
= BYTE_POS_ADDR (IT_BYTEPOS (*it
));
8128 if (it
->multibyte_p
&& !ASCII_BYTE_P (*p
))
8129 it
->c
= STRING_CHAR_AND_LENGTH (p
, it
->len
);
8131 it
->c
= *p
, it
->len
= 1;
8133 /* Record what we have and where it came from. */
8134 it
->what
= IT_CHARACTER
;
8135 it
->object
= it
->w
->contents
;
8136 it
->position
= it
->current
.pos
;
8138 /* Normally we return the character found above, except when we
8139 really want to return an ellipsis for selective display. */
8144 /* A value of selective > 0 means hide lines indented more
8145 than that number of columns. */
8146 if (it
->selective
> 0
8147 && IT_CHARPOS (*it
) + 1 < ZV
8148 && indented_beyond_p (IT_CHARPOS (*it
) + 1,
8149 IT_BYTEPOS (*it
) + 1,
8152 success_p
= next_element_from_ellipsis (it
);
8153 it
->dpvec_char_len
= -1;
8156 else if (it
->c
== '\r' && it
->selective
== -1)
8158 /* A value of selective == -1 means that everything from the
8159 CR to the end of the line is invisible, with maybe an
8160 ellipsis displayed for it. */
8161 success_p
= next_element_from_ellipsis (it
);
8162 it
->dpvec_char_len
= -1;
8167 /* Value is zero if end of buffer reached. */
8168 eassert (!success_p
|| it
->what
!= IT_CHARACTER
|| it
->len
> 0);
8173 /* Run the redisplay end trigger hook for IT. */
8176 run_redisplay_end_trigger_hook (struct it
*it
)
8178 Lisp_Object args
[3];
8180 /* IT->glyph_row should be non-null, i.e. we should be actually
8181 displaying something, or otherwise we should not run the hook. */
8182 eassert (it
->glyph_row
);
8184 /* Set up hook arguments. */
8185 args
[0] = Qredisplay_end_trigger_functions
;
8186 args
[1] = it
->window
;
8187 XSETINT (args
[2], it
->redisplay_end_trigger_charpos
);
8188 it
->redisplay_end_trigger_charpos
= 0;
8190 /* Since we are *trying* to run these functions, don't try to run
8191 them again, even if they get an error. */
8192 wset_redisplay_end_trigger (it
->w
, Qnil
);
8193 Frun_hook_with_args (3, args
);
8195 /* Notice if it changed the face of the character we are on. */
8196 handle_face_prop (it
);
8200 /* Deliver a composition display element. Unlike the other
8201 next_element_from_XXX, this function is not registered in the array
8202 get_next_element[]. It is called from next_element_from_buffer and
8203 next_element_from_string when necessary. */
8206 next_element_from_composition (struct it
*it
)
8208 it
->what
= IT_COMPOSITION
;
8209 it
->len
= it
->cmp_it
.nbytes
;
8210 if (STRINGP (it
->string
))
8214 IT_STRING_CHARPOS (*it
) += it
->cmp_it
.nchars
;
8215 IT_STRING_BYTEPOS (*it
) += it
->cmp_it
.nbytes
;
8218 it
->position
= it
->current
.string_pos
;
8219 it
->object
= it
->string
;
8220 it
->c
= composition_update_it (&it
->cmp_it
, IT_STRING_CHARPOS (*it
),
8221 IT_STRING_BYTEPOS (*it
), it
->string
);
8227 IT_CHARPOS (*it
) += it
->cmp_it
.nchars
;
8228 IT_BYTEPOS (*it
) += it
->cmp_it
.nbytes
;
8231 if (it
->bidi_it
.new_paragraph
)
8232 bidi_paragraph_init (it
->paragraph_embedding
, &it
->bidi_it
, 0);
8233 /* Resync the bidi iterator with IT's new position.
8234 FIXME: this doesn't support bidirectional text. */
8235 while (it
->bidi_it
.charpos
< IT_CHARPOS (*it
))
8236 bidi_move_to_visually_next (&it
->bidi_it
);
8240 it
->position
= it
->current
.pos
;
8241 it
->object
= it
->w
->contents
;
8242 it
->c
= composition_update_it (&it
->cmp_it
, IT_CHARPOS (*it
),
8243 IT_BYTEPOS (*it
), Qnil
);
8250 /***********************************************************************
8251 Moving an iterator without producing glyphs
8252 ***********************************************************************/
8254 /* Check if iterator is at a position corresponding to a valid buffer
8255 position after some move_it_ call. */
8257 #define IT_POS_VALID_AFTER_MOVE_P(it) \
8258 ((it)->method == GET_FROM_STRING \
8259 ? IT_STRING_CHARPOS (*it) == 0 \
8263 /* Move iterator IT to a specified buffer or X position within one
8264 line on the display without producing glyphs.
8266 OP should be a bit mask including some or all of these bits:
8267 MOVE_TO_X: Stop upon reaching x-position TO_X.
8268 MOVE_TO_POS: Stop upon reaching buffer or string position TO_CHARPOS.
8269 Regardless of OP's value, stop upon reaching the end of the display line.
8271 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
8272 This means, in particular, that TO_X includes window's horizontal
8275 The return value has several possible values that
8276 say what condition caused the scan to stop:
8278 MOVE_POS_MATCH_OR_ZV
8279 - when TO_POS or ZV was reached.
8282 -when TO_X was reached before TO_POS or ZV were reached.
8285 - when we reached the end of the display area and the line must
8289 - when we reached the end of the display area and the line is
8293 - when we stopped at a line end, i.e. a newline or a CR and selective
8296 static enum move_it_result
8297 move_it_in_display_line_to (struct it
*it
,
8298 ptrdiff_t to_charpos
, int to_x
,
8299 enum move_operation_enum op
)
8301 enum move_it_result result
= MOVE_UNDEFINED
;
8302 struct glyph_row
*saved_glyph_row
;
8303 struct it wrap_it
, atpos_it
, atx_it
, ppos_it
;
8304 void *wrap_data
= NULL
, *atpos_data
= NULL
, *atx_data
= NULL
;
8305 void *ppos_data
= NULL
;
8307 enum it_method prev_method
= it
->method
;
8308 ptrdiff_t prev_pos
= IT_CHARPOS (*it
);
8309 int saw_smaller_pos
= prev_pos
< to_charpos
;
8311 /* Don't produce glyphs in produce_glyphs. */
8312 saved_glyph_row
= it
->glyph_row
;
8313 it
->glyph_row
= NULL
;
8315 /* Use wrap_it to save a copy of IT wherever a word wrap could
8316 occur. Use atpos_it to save a copy of IT at the desired buffer
8317 position, if found, so that we can scan ahead and check if the
8318 word later overshoots the window edge. Use atx_it similarly, for
8324 /* Use ppos_it under bidi reordering to save a copy of IT for the
8325 position > CHARPOS that is the closest to CHARPOS. We restore
8326 that position in IT when we have scanned the entire display line
8327 without finding a match for CHARPOS and all the character
8328 positions are greater than CHARPOS. */
8331 SAVE_IT (ppos_it
, *it
, ppos_data
);
8332 SET_TEXT_POS (ppos_it
.current
.pos
, ZV
, ZV_BYTE
);
8333 if ((op
& MOVE_TO_POS
) && IT_CHARPOS (*it
) >= to_charpos
)
8334 SAVE_IT (ppos_it
, *it
, ppos_data
);
8337 #define BUFFER_POS_REACHED_P() \
8338 ((op & MOVE_TO_POS) != 0 \
8339 && BUFFERP (it->object) \
8340 && (IT_CHARPOS (*it) == to_charpos \
8342 || BIDI_AT_BASE_LEVEL (it->bidi_it)) \
8343 && IT_CHARPOS (*it) > to_charpos) \
8344 || (it->what == IT_COMPOSITION \
8345 && ((IT_CHARPOS (*it) > to_charpos \
8346 && to_charpos >= it->cmp_it.charpos) \
8347 || (IT_CHARPOS (*it) < to_charpos \
8348 && to_charpos <= it->cmp_it.charpos)))) \
8349 && (it->method == GET_FROM_BUFFER \
8350 || (it->method == GET_FROM_DISPLAY_VECTOR \
8351 && it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
8353 /* If there's a line-/wrap-prefix, handle it. */
8354 if (it
->hpos
== 0 && it
->method
== GET_FROM_BUFFER
8355 && it
->current_y
< it
->last_visible_y
)
8356 handle_line_prefix (it
);
8358 if (IT_CHARPOS (*it
) < CHARPOS (this_line_min_pos
))
8359 SET_TEXT_POS (this_line_min_pos
, IT_CHARPOS (*it
), IT_BYTEPOS (*it
));
8363 int x
, i
, ascent
= 0, descent
= 0;
8365 /* Utility macro to reset an iterator with x, ascent, and descent. */
8366 #define IT_RESET_X_ASCENT_DESCENT(IT) \
8367 ((IT)->current_x = x, (IT)->max_ascent = ascent, \
8368 (IT)->max_descent = descent)
8370 /* Stop if we move beyond TO_CHARPOS (after an image or a
8371 display string or stretch glyph). */
8372 if ((op
& MOVE_TO_POS
) != 0
8373 && BUFFERP (it
->object
)
8374 && it
->method
== GET_FROM_BUFFER
8376 /* When the iterator is at base embedding level, we
8377 are guaranteed that characters are delivered for
8378 display in strictly increasing order of their
8379 buffer positions. */
8380 || BIDI_AT_BASE_LEVEL (it
->bidi_it
))
8381 && IT_CHARPOS (*it
) > to_charpos
)
8383 && (prev_method
== GET_FROM_IMAGE
8384 || prev_method
== GET_FROM_STRETCH
8385 || prev_method
== GET_FROM_STRING
)
8386 /* Passed TO_CHARPOS from left to right. */
8387 && ((prev_pos
< to_charpos
8388 && IT_CHARPOS (*it
) > to_charpos
)
8389 /* Passed TO_CHARPOS from right to left. */
8390 || (prev_pos
> to_charpos
8391 && IT_CHARPOS (*it
) < to_charpos
)))))
8393 if (it
->line_wrap
!= WORD_WRAP
|| wrap_it
.sp
< 0)
8395 result
= MOVE_POS_MATCH_OR_ZV
;
8398 else if (it
->line_wrap
== WORD_WRAP
&& atpos_it
.sp
< 0)
8399 /* If wrap_it is valid, the current position might be in a
8400 word that is wrapped. So, save the iterator in
8401 atpos_it and continue to see if wrapping happens. */
8402 SAVE_IT (atpos_it
, *it
, atpos_data
);
8405 /* Stop when ZV reached.
8406 We used to stop here when TO_CHARPOS reached as well, but that is
8407 too soon if this glyph does not fit on this line. So we handle it
8408 explicitly below. */
8409 if (!get_next_display_element (it
))
8411 result
= MOVE_POS_MATCH_OR_ZV
;
8415 if (it
->line_wrap
== TRUNCATE
)
8417 if (BUFFER_POS_REACHED_P ())
8419 result
= MOVE_POS_MATCH_OR_ZV
;
8425 if (it
->line_wrap
== WORD_WRAP
)
8427 if (IT_DISPLAYING_WHITESPACE (it
))
8431 /* We have reached a glyph that follows one or more
8432 whitespace characters. If the position is
8433 already found, we are done. */
8434 if (atpos_it
.sp
>= 0)
8436 RESTORE_IT (it
, &atpos_it
, atpos_data
);
8437 result
= MOVE_POS_MATCH_OR_ZV
;
8442 RESTORE_IT (it
, &atx_it
, atx_data
);
8443 result
= MOVE_X_REACHED
;
8446 /* Otherwise, we can wrap here. */
8447 SAVE_IT (wrap_it
, *it
, wrap_data
);
8453 /* Remember the line height for the current line, in case
8454 the next element doesn't fit on the line. */
8455 ascent
= it
->max_ascent
;
8456 descent
= it
->max_descent
;
8458 /* The call to produce_glyphs will get the metrics of the
8459 display element IT is loaded with. Record the x-position
8460 before this display element, in case it doesn't fit on the
8464 PRODUCE_GLYPHS (it
);
8466 if (it
->area
!= TEXT_AREA
)
8468 prev_method
= it
->method
;
8469 if (it
->method
== GET_FROM_BUFFER
)
8470 prev_pos
= IT_CHARPOS (*it
);
8471 set_iterator_to_next (it
, 1);
8472 if (IT_CHARPOS (*it
) < CHARPOS (this_line_min_pos
))
8473 SET_TEXT_POS (this_line_min_pos
,
8474 IT_CHARPOS (*it
), IT_BYTEPOS (*it
));
8476 && (op
& MOVE_TO_POS
)
8477 && IT_CHARPOS (*it
) > to_charpos
8478 && IT_CHARPOS (*it
) < IT_CHARPOS (ppos_it
))
8479 SAVE_IT (ppos_it
, *it
, ppos_data
);
8483 /* The number of glyphs we get back in IT->nglyphs will normally
8484 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
8485 character on a terminal frame, or (iii) a line end. For the
8486 second case, IT->nglyphs - 1 padding glyphs will be present.
8487 (On X frames, there is only one glyph produced for a
8488 composite character.)
8490 The behavior implemented below means, for continuation lines,
8491 that as many spaces of a TAB as fit on the current line are
8492 displayed there. For terminal frames, as many glyphs of a
8493 multi-glyph character are displayed in the current line, too.
8494 This is what the old redisplay code did, and we keep it that
8495 way. Under X, the whole shape of a complex character must
8496 fit on the line or it will be completely displayed in the
8499 Note that both for tabs and padding glyphs, all glyphs have
8503 /* More than one glyph or glyph doesn't fit on line. All
8504 glyphs have the same width. */
8505 int single_glyph_width
= it
->pixel_width
/ it
->nglyphs
;
8507 int x_before_this_char
= x
;
8508 int hpos_before_this_char
= it
->hpos
;
8510 for (i
= 0; i
< it
->nglyphs
; ++i
, x
= new_x
)
8512 new_x
= x
+ single_glyph_width
;
8514 /* We want to leave anything reaching TO_X to the caller. */
8515 if ((op
& MOVE_TO_X
) && new_x
> to_x
)
8517 if (BUFFER_POS_REACHED_P ())
8519 if (it
->line_wrap
!= WORD_WRAP
|| wrap_it
.sp
< 0)
8520 goto buffer_pos_reached
;
8521 if (atpos_it
.sp
< 0)
8523 SAVE_IT (atpos_it
, *it
, atpos_data
);
8524 IT_RESET_X_ASCENT_DESCENT (&atpos_it
);
8529 if (it
->line_wrap
!= WORD_WRAP
|| wrap_it
.sp
< 0)
8532 result
= MOVE_X_REACHED
;
8537 SAVE_IT (atx_it
, *it
, atx_data
);
8538 IT_RESET_X_ASCENT_DESCENT (&atx_it
);
8543 if (/* Lines are continued. */
8544 it
->line_wrap
!= TRUNCATE
8545 && (/* And glyph doesn't fit on the line. */
8546 new_x
> it
->last_visible_x
8547 /* Or it fits exactly and we're on a window
8549 || (new_x
== it
->last_visible_x
8550 && FRAME_WINDOW_P (it
->f
)
8551 && ((it
->bidi_p
&& it
->bidi_it
.paragraph_dir
== R2L
)
8552 ? WINDOW_LEFT_FRINGE_WIDTH (it
->w
)
8553 : WINDOW_RIGHT_FRINGE_WIDTH (it
->w
)))))
8555 if (/* IT->hpos == 0 means the very first glyph
8556 doesn't fit on the line, e.g. a wide image. */
8558 || (new_x
== it
->last_visible_x
8559 && FRAME_WINDOW_P (it
->f
)))
8562 it
->current_x
= new_x
;
8564 /* The character's last glyph just barely fits
8566 if (i
== it
->nglyphs
- 1)
8568 /* If this is the destination position,
8569 return a position *before* it in this row,
8570 now that we know it fits in this row. */
8571 if (BUFFER_POS_REACHED_P ())
8573 if (it
->line_wrap
!= WORD_WRAP
8576 it
->hpos
= hpos_before_this_char
;
8577 it
->current_x
= x_before_this_char
;
8578 result
= MOVE_POS_MATCH_OR_ZV
;
8581 if (it
->line_wrap
== WORD_WRAP
8584 SAVE_IT (atpos_it
, *it
, atpos_data
);
8585 atpos_it
.current_x
= x_before_this_char
;
8586 atpos_it
.hpos
= hpos_before_this_char
;
8590 prev_method
= it
->method
;
8591 if (it
->method
== GET_FROM_BUFFER
)
8592 prev_pos
= IT_CHARPOS (*it
);
8593 set_iterator_to_next (it
, 1);
8594 if (IT_CHARPOS (*it
) < CHARPOS (this_line_min_pos
))
8595 SET_TEXT_POS (this_line_min_pos
,
8596 IT_CHARPOS (*it
), IT_BYTEPOS (*it
));
8597 /* On graphical terminals, newlines may
8598 "overflow" into the fringe if
8599 overflow-newline-into-fringe is non-nil.
8600 On text terminals, and on graphical
8601 terminals with no right margin, newlines
8602 may overflow into the last glyph on the
8604 if (!FRAME_WINDOW_P (it
->f
)
8606 && it
->bidi_it
.paragraph_dir
== R2L
)
8607 ? WINDOW_LEFT_FRINGE_WIDTH (it
->w
)
8608 : WINDOW_RIGHT_FRINGE_WIDTH (it
->w
)) == 0
8609 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
8611 if (!get_next_display_element (it
))
8613 result
= MOVE_POS_MATCH_OR_ZV
;
8616 if (BUFFER_POS_REACHED_P ())
8618 if (ITERATOR_AT_END_OF_LINE_P (it
))
8619 result
= MOVE_POS_MATCH_OR_ZV
;
8621 result
= MOVE_LINE_CONTINUED
;
8624 if (ITERATOR_AT_END_OF_LINE_P (it
)
8625 && (it
->line_wrap
!= WORD_WRAP
8628 result
= MOVE_NEWLINE_OR_CR
;
8635 IT_RESET_X_ASCENT_DESCENT (it
);
8637 if (wrap_it
.sp
>= 0)
8639 RESTORE_IT (it
, &wrap_it
, wrap_data
);
8644 TRACE_MOVE ((stderr
, "move_it_in: continued at %d\n",
8646 result
= MOVE_LINE_CONTINUED
;
8650 if (BUFFER_POS_REACHED_P ())
8652 if (it
->line_wrap
!= WORD_WRAP
|| wrap_it
.sp
< 0)
8653 goto buffer_pos_reached
;
8654 if (it
->line_wrap
== WORD_WRAP
&& atpos_it
.sp
< 0)
8656 SAVE_IT (atpos_it
, *it
, atpos_data
);
8657 IT_RESET_X_ASCENT_DESCENT (&atpos_it
);
8661 if (new_x
> it
->first_visible_x
)
8663 /* Glyph is visible. Increment number of glyphs that
8664 would be displayed. */
8669 if (result
!= MOVE_UNDEFINED
)
8672 else if (BUFFER_POS_REACHED_P ())
8675 IT_RESET_X_ASCENT_DESCENT (it
);
8676 result
= MOVE_POS_MATCH_OR_ZV
;
8679 else if ((op
& MOVE_TO_X
) && it
->current_x
>= to_x
)
8681 /* Stop when TO_X specified and reached. This check is
8682 necessary here because of lines consisting of a line end,
8683 only. The line end will not produce any glyphs and we
8684 would never get MOVE_X_REACHED. */
8685 eassert (it
->nglyphs
== 0);
8686 result
= MOVE_X_REACHED
;
8690 /* Is this a line end? If yes, we're done. */
8691 if (ITERATOR_AT_END_OF_LINE_P (it
))
8693 /* If we are past TO_CHARPOS, but never saw any character
8694 positions smaller than TO_CHARPOS, return
8695 MOVE_POS_MATCH_OR_ZV, like the unidirectional display
8697 if (it
->bidi_p
&& (op
& MOVE_TO_POS
) != 0)
8699 if (!saw_smaller_pos
&& IT_CHARPOS (*it
) > to_charpos
)
8701 if (IT_CHARPOS (ppos_it
) < ZV
)
8703 RESTORE_IT (it
, &ppos_it
, ppos_data
);
8704 result
= MOVE_POS_MATCH_OR_ZV
;
8707 goto buffer_pos_reached
;
8709 else if (it
->line_wrap
== WORD_WRAP
&& atpos_it
.sp
>= 0
8710 && IT_CHARPOS (*it
) > to_charpos
)
8711 goto buffer_pos_reached
;
8713 result
= MOVE_NEWLINE_OR_CR
;
8716 result
= MOVE_NEWLINE_OR_CR
;
8720 prev_method
= it
->method
;
8721 if (it
->method
== GET_FROM_BUFFER
)
8722 prev_pos
= IT_CHARPOS (*it
);
8723 /* The current display element has been consumed. Advance
8725 set_iterator_to_next (it
, 1);
8726 if (IT_CHARPOS (*it
) < CHARPOS (this_line_min_pos
))
8727 SET_TEXT_POS (this_line_min_pos
, IT_CHARPOS (*it
), IT_BYTEPOS (*it
));
8728 if (IT_CHARPOS (*it
) < to_charpos
)
8729 saw_smaller_pos
= 1;
8731 && (op
& MOVE_TO_POS
)
8732 && IT_CHARPOS (*it
) >= to_charpos
8733 && IT_CHARPOS (*it
) < IT_CHARPOS (ppos_it
))
8734 SAVE_IT (ppos_it
, *it
, ppos_data
);
8736 /* Stop if lines are truncated and IT's current x-position is
8737 past the right edge of the window now. */
8738 if (it
->line_wrap
== TRUNCATE
8739 && it
->current_x
>= it
->last_visible_x
)
8741 if (!FRAME_WINDOW_P (it
->f
)
8742 || ((it
->bidi_p
&& it
->bidi_it
.paragraph_dir
== R2L
)
8743 ? WINDOW_LEFT_FRINGE_WIDTH (it
->w
)
8744 : WINDOW_RIGHT_FRINGE_WIDTH (it
->w
)) == 0
8745 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
8749 if ((at_eob_p
= !get_next_display_element (it
))
8750 || BUFFER_POS_REACHED_P ()
8751 /* If we are past TO_CHARPOS, but never saw any
8752 character positions smaller than TO_CHARPOS,
8753 return MOVE_POS_MATCH_OR_ZV, like the
8754 unidirectional display did. */
8755 || (it
->bidi_p
&& (op
& MOVE_TO_POS
) != 0
8757 && IT_CHARPOS (*it
) > to_charpos
))
8760 && !at_eob_p
&& IT_CHARPOS (ppos_it
) < ZV
)
8761 RESTORE_IT (it
, &ppos_it
, ppos_data
);
8762 result
= MOVE_POS_MATCH_OR_ZV
;
8765 if (ITERATOR_AT_END_OF_LINE_P (it
))
8767 result
= MOVE_NEWLINE_OR_CR
;
8771 else if (it
->bidi_p
&& (op
& MOVE_TO_POS
) != 0
8773 && IT_CHARPOS (*it
) > to_charpos
)
8775 if (IT_CHARPOS (ppos_it
) < ZV
)
8776 RESTORE_IT (it
, &ppos_it
, ppos_data
);
8777 result
= MOVE_POS_MATCH_OR_ZV
;
8780 result
= MOVE_LINE_TRUNCATED
;
8783 #undef IT_RESET_X_ASCENT_DESCENT
8786 #undef BUFFER_POS_REACHED_P
8788 /* If we scanned beyond to_pos and didn't find a point to wrap at,
8789 restore the saved iterator. */
8790 if (atpos_it
.sp
>= 0)
8791 RESTORE_IT (it
, &atpos_it
, atpos_data
);
8792 else if (atx_it
.sp
>= 0)
8793 RESTORE_IT (it
, &atx_it
, atx_data
);
8798 bidi_unshelve_cache (atpos_data
, 1);
8800 bidi_unshelve_cache (atx_data
, 1);
8802 bidi_unshelve_cache (wrap_data
, 1);
8804 bidi_unshelve_cache (ppos_data
, 1);
8806 /* Restore the iterator settings altered at the beginning of this
8808 it
->glyph_row
= saved_glyph_row
;
8812 /* For external use. */
8814 move_it_in_display_line (struct it
*it
,
8815 ptrdiff_t to_charpos
, int to_x
,
8816 enum move_operation_enum op
)
8818 if (it
->line_wrap
== WORD_WRAP
8819 && (op
& MOVE_TO_X
))
8822 void *save_data
= NULL
;
8825 SAVE_IT (save_it
, *it
, save_data
);
8826 skip
= move_it_in_display_line_to (it
, to_charpos
, to_x
, op
);
8827 /* When word-wrap is on, TO_X may lie past the end
8828 of a wrapped line. Then it->current is the
8829 character on the next line, so backtrack to the
8830 space before the wrap point. */
8831 if (skip
== MOVE_LINE_CONTINUED
)
8833 int prev_x
= max (it
->current_x
- 1, 0);
8834 RESTORE_IT (it
, &save_it
, save_data
);
8835 move_it_in_display_line_to
8836 (it
, -1, prev_x
, MOVE_TO_X
);
8839 bidi_unshelve_cache (save_data
, 1);
8842 move_it_in_display_line_to (it
, to_charpos
, to_x
, op
);
8846 /* Move IT forward until it satisfies one or more of the criteria in
8847 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
8849 OP is a bit-mask that specifies where to stop, and in particular,
8850 which of those four position arguments makes a difference. See the
8851 description of enum move_operation_enum.
8853 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
8854 screen line, this function will set IT to the next position that is
8855 displayed to the right of TO_CHARPOS on the screen. */
8858 move_it_to (struct it
*it
, ptrdiff_t to_charpos
, int to_x
, int to_y
, int to_vpos
, int op
)
8860 enum move_it_result skip
, skip2
= MOVE_X_REACHED
;
8861 int line_height
, line_start_x
= 0, reached
= 0;
8862 void *backup_data
= NULL
;
8866 if (op
& MOVE_TO_VPOS
)
8868 /* If no TO_CHARPOS and no TO_X specified, stop at the
8869 start of the line TO_VPOS. */
8870 if ((op
& (MOVE_TO_X
| MOVE_TO_POS
)) == 0)
8872 if (it
->vpos
== to_vpos
)
8878 skip
= move_it_in_display_line_to (it
, -1, -1, 0);
8882 /* TO_VPOS >= 0 means stop at TO_X in the line at
8883 TO_VPOS, or at TO_POS, whichever comes first. */
8884 if (it
->vpos
== to_vpos
)
8890 skip
= move_it_in_display_line_to (it
, to_charpos
, to_x
, op
);
8892 if (skip
== MOVE_POS_MATCH_OR_ZV
|| it
->vpos
== to_vpos
)
8897 else if (skip
== MOVE_X_REACHED
&& it
->vpos
!= to_vpos
)
8899 /* We have reached TO_X but not in the line we want. */
8900 skip
= move_it_in_display_line_to (it
, to_charpos
,
8902 if (skip
== MOVE_POS_MATCH_OR_ZV
)
8910 else if (op
& MOVE_TO_Y
)
8912 struct it it_backup
;
8914 if (it
->line_wrap
== WORD_WRAP
)
8915 SAVE_IT (it_backup
, *it
, backup_data
);
8917 /* TO_Y specified means stop at TO_X in the line containing
8918 TO_Y---or at TO_CHARPOS if this is reached first. The
8919 problem is that we can't really tell whether the line
8920 contains TO_Y before we have completely scanned it, and
8921 this may skip past TO_X. What we do is to first scan to
8924 If TO_X is not specified, use a TO_X of zero. The reason
8925 is to make the outcome of this function more predictable.
8926 If we didn't use TO_X == 0, we would stop at the end of
8927 the line which is probably not what a caller would expect
8929 skip
= move_it_in_display_line_to
8930 (it
, to_charpos
, ((op
& MOVE_TO_X
) ? to_x
: 0),
8931 (MOVE_TO_X
| (op
& MOVE_TO_POS
)));
8933 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
8934 if (skip
== MOVE_POS_MATCH_OR_ZV
)
8936 else if (skip
== MOVE_X_REACHED
)
8938 /* If TO_X was reached, we want to know whether TO_Y is
8939 in the line. We know this is the case if the already
8940 scanned glyphs make the line tall enough. Otherwise,
8941 we must check by scanning the rest of the line. */
8942 line_height
= it
->max_ascent
+ it
->max_descent
;
8943 if (to_y
>= it
->current_y
8944 && to_y
< it
->current_y
+ line_height
)
8949 SAVE_IT (it_backup
, *it
, backup_data
);
8950 TRACE_MOVE ((stderr
, "move_it: from %d\n", IT_CHARPOS (*it
)));
8951 skip2
= move_it_in_display_line_to (it
, to_charpos
, -1,
8953 TRACE_MOVE ((stderr
, "move_it: to %d\n", IT_CHARPOS (*it
)));
8954 line_height
= it
->max_ascent
+ it
->max_descent
;
8955 TRACE_MOVE ((stderr
, "move_it: line_height = %d\n", line_height
));
8957 if (to_y
>= it
->current_y
8958 && to_y
< it
->current_y
+ line_height
)
8960 /* If TO_Y is in this line and TO_X was reached
8961 above, we scanned too far. We have to restore
8962 IT's settings to the ones before skipping. But
8963 keep the more accurate values of max_ascent and
8964 max_descent we've found while skipping the rest
8965 of the line, for the sake of callers, such as
8966 pos_visible_p, that need to know the line
8968 int max_ascent
= it
->max_ascent
;
8969 int max_descent
= it
->max_descent
;
8971 RESTORE_IT (it
, &it_backup
, backup_data
);
8972 it
->max_ascent
= max_ascent
;
8973 it
->max_descent
= max_descent
;
8979 if (skip
== MOVE_POS_MATCH_OR_ZV
)
8985 /* Check whether TO_Y is in this line. */
8986 line_height
= it
->max_ascent
+ it
->max_descent
;
8987 TRACE_MOVE ((stderr
, "move_it: line_height = %d\n", line_height
));
8989 if (to_y
>= it
->current_y
8990 && to_y
< it
->current_y
+ line_height
)
8992 /* When word-wrap is on, TO_X may lie past the end
8993 of a wrapped line. Then it->current is the
8994 character on the next line, so backtrack to the
8995 space before the wrap point. */
8996 if (skip
== MOVE_LINE_CONTINUED
8997 && it
->line_wrap
== WORD_WRAP
)
8999 int prev_x
= max (it
->current_x
- 1, 0);
9000 RESTORE_IT (it
, &it_backup
, backup_data
);
9001 skip
= move_it_in_display_line_to
9002 (it
, -1, prev_x
, MOVE_TO_X
);
9011 else if (BUFFERP (it
->object
)
9012 && (it
->method
== GET_FROM_BUFFER
9013 || it
->method
== GET_FROM_STRETCH
)
9014 && IT_CHARPOS (*it
) >= to_charpos
9015 /* Under bidi iteration, a call to set_iterator_to_next
9016 can scan far beyond to_charpos if the initial
9017 portion of the next line needs to be reordered. In
9018 that case, give move_it_in_display_line_to another
9021 && it
->bidi_it
.scan_dir
== -1))
9022 skip
= MOVE_POS_MATCH_OR_ZV
;
9024 skip
= move_it_in_display_line_to (it
, to_charpos
, -1, MOVE_TO_POS
);
9028 case MOVE_POS_MATCH_OR_ZV
:
9032 case MOVE_NEWLINE_OR_CR
:
9033 set_iterator_to_next (it
, 1);
9034 it
->continuation_lines_width
= 0;
9037 case MOVE_LINE_TRUNCATED
:
9038 it
->continuation_lines_width
= 0;
9039 reseat_at_next_visible_line_start (it
, 0);
9040 if ((op
& MOVE_TO_POS
) != 0
9041 && IT_CHARPOS (*it
) > to_charpos
)
9048 case MOVE_LINE_CONTINUED
:
9049 /* For continued lines ending in a tab, some of the glyphs
9050 associated with the tab are displayed on the current
9051 line. Since it->current_x does not include these glyphs,
9052 we use it->last_visible_x instead. */
9055 it
->continuation_lines_width
+= it
->last_visible_x
;
9056 /* When moving by vpos, ensure that the iterator really
9057 advances to the next line (bug#847, bug#969). Fixme:
9058 do we need to do this in other circumstances? */
9059 if (it
->current_x
!= it
->last_visible_x
9060 && (op
& MOVE_TO_VPOS
)
9061 && !(op
& (MOVE_TO_X
| MOVE_TO_POS
)))
9063 line_start_x
= it
->current_x
+ it
->pixel_width
9064 - it
->last_visible_x
;
9065 set_iterator_to_next (it
, 0);
9069 it
->continuation_lines_width
+= it
->current_x
;
9076 /* Reset/increment for the next run. */
9077 recenter_overlay_lists (current_buffer
, IT_CHARPOS (*it
));
9078 it
->current_x
= line_start_x
;
9081 it
->current_y
+= it
->max_ascent
+ it
->max_descent
;
9083 last_height
= it
->max_ascent
+ it
->max_descent
;
9084 it
->max_ascent
= it
->max_descent
= 0;
9089 /* On text terminals, we may stop at the end of a line in the middle
9090 of a multi-character glyph. If the glyph itself is continued,
9091 i.e. it is actually displayed on the next line, don't treat this
9092 stopping point as valid; move to the next line instead (unless
9093 that brings us offscreen). */
9094 if (!FRAME_WINDOW_P (it
->f
)
9096 && IT_CHARPOS (*it
) == to_charpos
9097 && it
->what
== IT_CHARACTER
9099 && it
->line_wrap
== WINDOW_WRAP
9100 && it
->current_x
== it
->last_visible_x
- 1
9103 && it
->vpos
< it
->w
->window_end_vpos
)
9105 it
->continuation_lines_width
+= it
->current_x
;
9106 it
->current_x
= it
->hpos
= it
->max_ascent
= it
->max_descent
= 0;
9107 it
->current_y
+= it
->max_ascent
+ it
->max_descent
;
9109 last_height
= it
->max_ascent
+ it
->max_descent
;
9113 bidi_unshelve_cache (backup_data
, 1);
9115 TRACE_MOVE ((stderr
, "move_it_to: reached %d\n", reached
));
9119 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
9121 If DY > 0, move IT backward at least that many pixels. DY = 0
9122 means move IT backward to the preceding line start or BEGV. This
9123 function may move over more than DY pixels if IT->current_y - DY
9124 ends up in the middle of a line; in this case IT->current_y will be
9125 set to the top of the line moved to. */
9128 move_it_vertically_backward (struct it
*it
, int dy
)
9132 void *it2data
= NULL
, *it3data
= NULL
;
9133 ptrdiff_t start_pos
;
9135 = (it
->last_visible_x
- it
->first_visible_x
) / FRAME_COLUMN_WIDTH (it
->f
);
9136 ptrdiff_t pos_limit
;
9141 start_pos
= IT_CHARPOS (*it
);
9143 /* Estimate how many newlines we must move back. */
9144 nlines
= max (1, dy
/ default_line_pixel_height (it
->w
));
9145 if (it
->line_wrap
== TRUNCATE
)
9148 pos_limit
= max (start_pos
- nlines
* nchars_per_row
, BEGV
);
9150 /* Set the iterator's position that many lines back. But don't go
9151 back more than NLINES full screen lines -- this wins a day with
9152 buffers which have very long lines. */
9153 while (nlines
-- && IT_CHARPOS (*it
) > pos_limit
)
9154 back_to_previous_visible_line_start (it
);
9156 /* Reseat the iterator here. When moving backward, we don't want
9157 reseat to skip forward over invisible text, set up the iterator
9158 to deliver from overlay strings at the new position etc. So,
9159 use reseat_1 here. */
9160 reseat_1 (it
, it
->current
.pos
, 1);
9162 /* We are now surely at a line start. */
9163 it
->current_x
= it
->hpos
= 0; /* FIXME: this is incorrect when bidi
9164 reordering is in effect. */
9165 it
->continuation_lines_width
= 0;
9167 /* Move forward and see what y-distance we moved. First move to the
9168 start of the next line so that we get its height. We need this
9169 height to be able to tell whether we reached the specified
9171 SAVE_IT (it2
, *it
, it2data
);
9172 it2
.max_ascent
= it2
.max_descent
= 0;
9175 move_it_to (&it2
, start_pos
, -1, -1, it2
.vpos
+ 1,
9176 MOVE_TO_POS
| MOVE_TO_VPOS
);
9178 while (!(IT_POS_VALID_AFTER_MOVE_P (&it2
)
9179 /* If we are in a display string which starts at START_POS,
9180 and that display string includes a newline, and we are
9181 right after that newline (i.e. at the beginning of a
9182 display line), exit the loop, because otherwise we will
9183 infloop, since move_it_to will see that it is already at
9184 START_POS and will not move. */
9185 || (it2
.method
== GET_FROM_STRING
9186 && IT_CHARPOS (it2
) == start_pos
9187 && SREF (it2
.string
, IT_STRING_BYTEPOS (it2
) - 1) == '\n')));
9188 eassert (IT_CHARPOS (*it
) >= BEGV
);
9189 SAVE_IT (it3
, it2
, it3data
);
9191 move_it_to (&it2
, start_pos
, -1, -1, -1, MOVE_TO_POS
);
9192 eassert (IT_CHARPOS (*it
) >= BEGV
);
9193 /* H is the actual vertical distance from the position in *IT
9194 and the starting position. */
9195 h
= it2
.current_y
- it
->current_y
;
9196 /* NLINES is the distance in number of lines. */
9197 nlines
= it2
.vpos
- it
->vpos
;
9199 /* Correct IT's y and vpos position
9200 so that they are relative to the starting point. */
9206 /* DY == 0 means move to the start of the screen line. The
9207 value of nlines is > 0 if continuation lines were involved,
9208 or if the original IT position was at start of a line. */
9209 RESTORE_IT (it
, it
, it2data
);
9211 move_it_by_lines (it
, nlines
);
9212 /* The above code moves us to some position NLINES down,
9213 usually to its first glyph (leftmost in an L2R line), but
9214 that's not necessarily the start of the line, under bidi
9215 reordering. We want to get to the character position
9216 that is immediately after the newline of the previous
9219 && !it
->continuation_lines_width
9220 && !STRINGP (it
->string
)
9221 && IT_CHARPOS (*it
) > BEGV
9222 && FETCH_BYTE (IT_BYTEPOS (*it
) - 1) != '\n')
9224 ptrdiff_t cp
= IT_CHARPOS (*it
), bp
= IT_BYTEPOS (*it
);
9227 cp
= find_newline_no_quit (cp
, bp
, -1, NULL
);
9228 move_it_to (it
, cp
, -1, -1, -1, MOVE_TO_POS
);
9230 bidi_unshelve_cache (it3data
, 1);
9234 /* The y-position we try to reach, relative to *IT.
9235 Note that H has been subtracted in front of the if-statement. */
9236 int target_y
= it
->current_y
+ h
- dy
;
9237 int y0
= it3
.current_y
;
9241 RESTORE_IT (&it3
, &it3
, it3data
);
9242 y1
= line_bottom_y (&it3
);
9243 line_height
= y1
- y0
;
9244 RESTORE_IT (it
, it
, it2data
);
9245 /* If we did not reach target_y, try to move further backward if
9246 we can. If we moved too far backward, try to move forward. */
9247 if (target_y
< it
->current_y
9248 /* This is heuristic. In a window that's 3 lines high, with
9249 a line height of 13 pixels each, recentering with point
9250 on the bottom line will try to move -39/2 = 19 pixels
9251 backward. Try to avoid moving into the first line. */
9252 && (it
->current_y
- target_y
9253 > min (window_box_height (it
->w
), line_height
* 2 / 3))
9254 && IT_CHARPOS (*it
) > BEGV
)
9256 TRACE_MOVE ((stderr
, " not far enough -> move_vert %d\n",
9257 target_y
- it
->current_y
));
9258 dy
= it
->current_y
- target_y
;
9259 goto move_further_back
;
9261 else if (target_y
>= it
->current_y
+ line_height
9262 && IT_CHARPOS (*it
) < ZV
)
9264 /* Should move forward by at least one line, maybe more.
9266 Note: Calling move_it_by_lines can be expensive on
9267 terminal frames, where compute_motion is used (via
9268 vmotion) to do the job, when there are very long lines
9269 and truncate-lines is nil. That's the reason for
9270 treating terminal frames specially here. */
9272 if (!FRAME_WINDOW_P (it
->f
))
9273 move_it_vertically (it
, target_y
- (it
->current_y
+ line_height
));
9278 move_it_by_lines (it
, 1);
9280 while (target_y
>= line_bottom_y (it
) && IT_CHARPOS (*it
) < ZV
);
9287 /* Move IT by a specified amount of pixel lines DY. DY negative means
9288 move backwards. DY = 0 means move to start of screen line. At the
9289 end, IT will be on the start of a screen line. */
9292 move_it_vertically (struct it
*it
, int dy
)
9295 move_it_vertically_backward (it
, -dy
);
9298 TRACE_MOVE ((stderr
, "move_it_v: from %d, %d\n", IT_CHARPOS (*it
), dy
));
9299 move_it_to (it
, ZV
, -1, it
->current_y
+ dy
, -1,
9300 MOVE_TO_POS
| MOVE_TO_Y
);
9301 TRACE_MOVE ((stderr
, "move_it_v: to %d\n", IT_CHARPOS (*it
)));
9303 /* If buffer ends in ZV without a newline, move to the start of
9304 the line to satisfy the post-condition. */
9305 if (IT_CHARPOS (*it
) == ZV
9307 && FETCH_BYTE (IT_BYTEPOS (*it
) - 1) != '\n')
9308 move_it_by_lines (it
, 0);
9313 /* Move iterator IT past the end of the text line it is in. */
9316 move_it_past_eol (struct it
*it
)
9318 enum move_it_result rc
;
9320 rc
= move_it_in_display_line_to (it
, Z
, 0, MOVE_TO_POS
);
9321 if (rc
== MOVE_NEWLINE_OR_CR
)
9322 set_iterator_to_next (it
, 0);
9326 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
9327 negative means move up. DVPOS == 0 means move to the start of the
9330 Optimization idea: If we would know that IT->f doesn't use
9331 a face with proportional font, we could be faster for
9332 truncate-lines nil. */
9335 move_it_by_lines (struct it
*it
, ptrdiff_t dvpos
)
9338 /* The commented-out optimization uses vmotion on terminals. This
9339 gives bad results, because elements like it->what, on which
9340 callers such as pos_visible_p rely, aren't updated. */
9341 /* struct position pos;
9342 if (!FRAME_WINDOW_P (it->f))
9344 struct text_pos textpos;
9346 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
9347 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
9348 reseat (it, textpos, 1);
9349 it->vpos += pos.vpos;
9350 it->current_y += pos.vpos;
9356 /* DVPOS == 0 means move to the start of the screen line. */
9357 move_it_vertically_backward (it
, 0);
9358 /* Let next call to line_bottom_y calculate real line height */
9363 move_it_to (it
, -1, -1, -1, it
->vpos
+ dvpos
, MOVE_TO_VPOS
);
9364 if (!IT_POS_VALID_AFTER_MOVE_P (it
))
9366 /* Only move to the next buffer position if we ended up in a
9367 string from display property, not in an overlay string
9368 (before-string or after-string). That is because the
9369 latter don't conceal the underlying buffer position, so
9370 we can ask to move the iterator to the exact position we
9371 are interested in. Note that, even if we are already at
9372 IT_CHARPOS (*it), the call below is not a no-op, as it
9373 will detect that we are at the end of the string, pop the
9374 iterator, and compute it->current_x and it->hpos
9376 move_it_to (it
, IT_CHARPOS (*it
) + it
->string_from_display_prop_p
,
9377 -1, -1, -1, MOVE_TO_POS
);
9383 void *it2data
= NULL
;
9384 ptrdiff_t start_charpos
, i
;
9386 = (it
->last_visible_x
- it
->first_visible_x
) / FRAME_COLUMN_WIDTH (it
->f
);
9387 ptrdiff_t pos_limit
;
9389 /* Start at the beginning of the screen line containing IT's
9390 position. This may actually move vertically backwards,
9391 in case of overlays, so adjust dvpos accordingly. */
9393 move_it_vertically_backward (it
, 0);
9396 /* Go back -DVPOS buffer lines, but no farther than -DVPOS full
9397 screen lines, and reseat the iterator there. */
9398 start_charpos
= IT_CHARPOS (*it
);
9399 if (it
->line_wrap
== TRUNCATE
)
9402 pos_limit
= max (start_charpos
+ dvpos
* nchars_per_row
, BEGV
);
9403 for (i
= -dvpos
; i
> 0 && IT_CHARPOS (*it
) > pos_limit
; --i
)
9404 back_to_previous_visible_line_start (it
);
9405 reseat (it
, it
->current
.pos
, 1);
9407 /* Move further back if we end up in a string or an image. */
9408 while (!IT_POS_VALID_AFTER_MOVE_P (it
))
9410 /* First try to move to start of display line. */
9412 move_it_vertically_backward (it
, 0);
9414 if (IT_POS_VALID_AFTER_MOVE_P (it
))
9416 /* If start of line is still in string or image,
9417 move further back. */
9418 back_to_previous_visible_line_start (it
);
9419 reseat (it
, it
->current
.pos
, 1);
9423 it
->current_x
= it
->hpos
= 0;
9425 /* Above call may have moved too far if continuation lines
9426 are involved. Scan forward and see if it did. */
9427 SAVE_IT (it2
, *it
, it2data
);
9428 it2
.vpos
= it2
.current_y
= 0;
9429 move_it_to (&it2
, start_charpos
, -1, -1, -1, MOVE_TO_POS
);
9430 it
->vpos
-= it2
.vpos
;
9431 it
->current_y
-= it2
.current_y
;
9432 it
->current_x
= it
->hpos
= 0;
9434 /* If we moved too far back, move IT some lines forward. */
9435 if (it2
.vpos
> -dvpos
)
9437 int delta
= it2
.vpos
+ dvpos
;
9439 RESTORE_IT (&it2
, &it2
, it2data
);
9440 SAVE_IT (it2
, *it
, it2data
);
9441 move_it_to (it
, -1, -1, -1, it
->vpos
+ delta
, MOVE_TO_VPOS
);
9442 /* Move back again if we got too far ahead. */
9443 if (IT_CHARPOS (*it
) >= start_charpos
)
9444 RESTORE_IT (it
, &it2
, it2data
);
9446 bidi_unshelve_cache (it2data
, 1);
9449 RESTORE_IT (it
, it
, it2data
);
9453 /* Return 1 if IT points into the middle of a display vector. */
9456 in_display_vector_p (struct it
*it
)
9458 return (it
->method
== GET_FROM_DISPLAY_VECTOR
9459 && it
->current
.dpvec_index
> 0
9460 && it
->dpvec
+ it
->current
.dpvec_index
!= it
->dpend
);
9464 /***********************************************************************
9466 ***********************************************************************/
9469 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
9473 add_to_log (const char *format
, Lisp_Object arg1
, Lisp_Object arg2
)
9475 Lisp_Object args
[3];
9476 Lisp_Object msg
, fmt
;
9479 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
9483 GCPRO4 (fmt
, msg
, arg1
, arg2
);
9485 args
[0] = fmt
= build_string (format
);
9488 msg
= Fformat (3, args
);
9490 len
= SBYTES (msg
) + 1;
9491 buffer
= SAFE_ALLOCA (len
);
9492 memcpy (buffer
, SDATA (msg
), len
);
9494 message_dolog (buffer
, len
- 1, 1, 0);
9501 /* Output a newline in the *Messages* buffer if "needs" one. */
9504 message_log_maybe_newline (void)
9506 if (message_log_need_newline
)
9507 message_dolog ("", 0, 1, 0);
9511 /* Add a string M of length NBYTES to the message log, optionally
9512 terminated with a newline when NLFLAG is true. MULTIBYTE, if
9513 true, means interpret the contents of M as multibyte. This
9514 function calls low-level routines in order to bypass text property
9515 hooks, etc. which might not be safe to run.
9517 This may GC (insert may run before/after change hooks),
9518 so the buffer M must NOT point to a Lisp string. */
9521 message_dolog (const char *m
, ptrdiff_t nbytes
, bool nlflag
, bool multibyte
)
9523 const unsigned char *msg
= (const unsigned char *) m
;
9525 if (!NILP (Vmemory_full
))
9528 if (!NILP (Vmessage_log_max
))
9530 struct buffer
*oldbuf
;
9531 Lisp_Object oldpoint
, oldbegv
, oldzv
;
9532 int old_windows_or_buffers_changed
= windows_or_buffers_changed
;
9533 ptrdiff_t point_at_end
= 0;
9534 ptrdiff_t zv_at_end
= 0;
9535 Lisp_Object old_deactivate_mark
;
9537 struct gcpro gcpro1
;
9539 old_deactivate_mark
= Vdeactivate_mark
;
9540 oldbuf
= current_buffer
;
9541 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name
));
9542 bset_undo_list (current_buffer
, Qt
);
9544 oldpoint
= message_dolog_marker1
;
9545 set_marker_restricted_both (oldpoint
, Qnil
, PT
, PT_BYTE
);
9546 oldbegv
= message_dolog_marker2
;
9547 set_marker_restricted_both (oldbegv
, Qnil
, BEGV
, BEGV_BYTE
);
9548 oldzv
= message_dolog_marker3
;
9549 set_marker_restricted_both (oldzv
, Qnil
, ZV
, ZV_BYTE
);
9550 GCPRO1 (old_deactivate_mark
);
9558 BEGV_BYTE
= BEG_BYTE
;
9561 TEMP_SET_PT_BOTH (Z
, Z_BYTE
);
9563 /* Insert the string--maybe converting multibyte to single byte
9564 or vice versa, so that all the text fits the buffer. */
9566 && NILP (BVAR (current_buffer
, enable_multibyte_characters
)))
9572 /* Convert a multibyte string to single-byte
9573 for the *Message* buffer. */
9574 for (i
= 0; i
< nbytes
; i
+= char_bytes
)
9576 c
= string_char_and_length (msg
+ i
, &char_bytes
);
9577 work
[0] = (ASCII_CHAR_P (c
)
9579 : multibyte_char_to_unibyte (c
));
9580 insert_1_both (work
, 1, 1, 1, 0, 0);
9583 else if (! multibyte
9584 && ! NILP (BVAR (current_buffer
, enable_multibyte_characters
)))
9588 unsigned char str
[MAX_MULTIBYTE_LENGTH
];
9589 /* Convert a single-byte string to multibyte
9590 for the *Message* buffer. */
9591 for (i
= 0; i
< nbytes
; i
++)
9594 MAKE_CHAR_MULTIBYTE (c
);
9595 char_bytes
= CHAR_STRING (c
, str
);
9596 insert_1_both ((char *) str
, 1, char_bytes
, 1, 0, 0);
9600 insert_1_both (m
, chars_in_text (msg
, nbytes
), nbytes
, 1, 0, 0);
9604 ptrdiff_t this_bol
, this_bol_byte
, prev_bol
, prev_bol_byte
;
9607 insert_1_both ("\n", 1, 1, 1, 0, 0);
9609 scan_newline (Z
, Z_BYTE
, BEG
, BEG_BYTE
, -2, 0);
9611 this_bol_byte
= PT_BYTE
;
9613 /* See if this line duplicates the previous one.
9614 If so, combine duplicates. */
9617 scan_newline (PT
, PT_BYTE
, BEG
, BEG_BYTE
, -2, 0);
9619 prev_bol_byte
= PT_BYTE
;
9621 dups
= message_log_check_duplicate (prev_bol_byte
,
9625 del_range_both (prev_bol
, prev_bol_byte
,
9626 this_bol
, this_bol_byte
, 0);
9629 char dupstr
[sizeof " [ times]"
9630 + INT_STRLEN_BOUND (printmax_t
)];
9632 /* If you change this format, don't forget to also
9633 change message_log_check_duplicate. */
9634 int duplen
= sprintf (dupstr
, " [%"pMd
" times]", dups
);
9635 TEMP_SET_PT_BOTH (Z
- 1, Z_BYTE
- 1);
9636 insert_1_both (dupstr
, duplen
, duplen
, 1, 0, 1);
9641 /* If we have more than the desired maximum number of lines
9642 in the *Messages* buffer now, delete the oldest ones.
9643 This is safe because we don't have undo in this buffer. */
9645 if (NATNUMP (Vmessage_log_max
))
9647 scan_newline (Z
, Z_BYTE
, BEG
, BEG_BYTE
,
9648 -XFASTINT (Vmessage_log_max
) - 1, 0);
9649 del_range_both (BEG
, BEG_BYTE
, PT
, PT_BYTE
, 0);
9652 BEGV
= marker_position (oldbegv
);
9653 BEGV_BYTE
= marker_byte_position (oldbegv
);
9662 ZV
= marker_position (oldzv
);
9663 ZV_BYTE
= marker_byte_position (oldzv
);
9667 TEMP_SET_PT_BOTH (Z
, Z_BYTE
);
9669 /* We can't do Fgoto_char (oldpoint) because it will run some
9671 TEMP_SET_PT_BOTH (marker_position (oldpoint
),
9672 marker_byte_position (oldpoint
));
9675 unchain_marker (XMARKER (oldpoint
));
9676 unchain_marker (XMARKER (oldbegv
));
9677 unchain_marker (XMARKER (oldzv
));
9679 shown
= buffer_window_count (current_buffer
) > 0;
9680 set_buffer_internal (oldbuf
);
9681 /* We called insert_1_both above with its 5th argument (PREPARE)
9682 zero, which prevents insert_1_both from calling
9683 prepare_to_modify_buffer, which in turns prevents us from
9684 incrementing windows_or_buffers_changed even if *Messages* is
9685 shown in some window. So we must manually incrementing
9686 windows_or_buffers_changed here to make up for that. */
9688 windows_or_buffers_changed
++;
9690 windows_or_buffers_changed
= old_windows_or_buffers_changed
;
9691 message_log_need_newline
= !nlflag
;
9692 Vdeactivate_mark
= old_deactivate_mark
;
9697 /* We are at the end of the buffer after just having inserted a newline.
9698 (Note: We depend on the fact we won't be crossing the gap.)
9699 Check to see if the most recent message looks a lot like the previous one.
9700 Return 0 if different, 1 if the new one should just replace it, or a
9701 value N > 1 if we should also append " [N times]". */
9704 message_log_check_duplicate (ptrdiff_t prev_bol_byte
, ptrdiff_t this_bol_byte
)
9707 ptrdiff_t len
= Z_BYTE
- 1 - this_bol_byte
;
9709 unsigned char *p1
= BUF_BYTE_ADDRESS (current_buffer
, prev_bol_byte
);
9710 unsigned char *p2
= BUF_BYTE_ADDRESS (current_buffer
, this_bol_byte
);
9712 for (i
= 0; i
< len
; i
++)
9714 if (i
>= 3 && p1
[i
- 3] == '.' && p1
[i
- 2] == '.' && p1
[i
- 1] == '.')
9722 if (*p1
++ == ' ' && *p1
++ == '[')
9725 intmax_t n
= strtoimax ((char *) p1
, &pend
, 10);
9726 if (0 < n
&& n
< INTMAX_MAX
&& strncmp (pend
, " times]\n", 8) == 0)
9733 /* Display an echo area message M with a specified length of NBYTES
9734 bytes. The string may include null characters. If M is not a
9735 string, clear out any existing message, and let the mini-buffer
9738 This function cancels echoing. */
9741 message3 (Lisp_Object m
)
9743 struct gcpro gcpro1
;
9746 clear_message (1,1);
9749 /* First flush out any partial line written with print. */
9750 message_log_maybe_newline ();
9753 ptrdiff_t nbytes
= SBYTES (m
);
9754 bool multibyte
= STRING_MULTIBYTE (m
);
9756 char *buffer
= SAFE_ALLOCA (nbytes
);
9757 memcpy (buffer
, SDATA (m
), nbytes
);
9758 message_dolog (buffer
, nbytes
, 1, multibyte
);
9767 /* The non-logging version of message3.
9768 This does not cancel echoing, because it is used for echoing.
9769 Perhaps we need to make a separate function for echoing
9770 and make this cancel echoing. */
9773 message3_nolog (Lisp_Object m
)
9775 struct frame
*sf
= SELECTED_FRAME ();
9777 if (FRAME_INITIAL_P (sf
))
9779 if (noninteractive_need_newline
)
9780 putc ('\n', stderr
);
9781 noninteractive_need_newline
= 0;
9783 fwrite (SDATA (m
), SBYTES (m
), 1, stderr
);
9784 if (cursor_in_echo_area
== 0)
9785 fprintf (stderr
, "\n");
9788 /* Error messages get reported properly by cmd_error, so this must be just an
9789 informative message; if the frame hasn't really been initialized yet, just
9791 else if (INTERACTIVE
&& sf
->glyphs_initialized_p
)
9793 /* Get the frame containing the mini-buffer
9794 that the selected frame is using. */
9795 Lisp_Object mini_window
= FRAME_MINIBUF_WINDOW (sf
);
9796 Lisp_Object frame
= XWINDOW (mini_window
)->frame
;
9797 struct frame
*f
= XFRAME (frame
);
9799 if (FRAME_VISIBLE_P (sf
) && !FRAME_VISIBLE_P (f
))
9800 Fmake_frame_visible (frame
);
9802 if (STRINGP (m
) && SCHARS (m
) > 0)
9805 if (minibuffer_auto_raise
)
9806 Fraise_frame (frame
);
9807 /* Assume we are not echoing.
9808 (If we are, echo_now will override this.) */
9809 echo_message_buffer
= Qnil
;
9812 clear_message (1, 1);
9814 do_pending_window_change (0);
9815 echo_area_display (1);
9816 do_pending_window_change (0);
9817 if (FRAME_TERMINAL (f
)->frame_up_to_date_hook
)
9818 (*FRAME_TERMINAL (f
)->frame_up_to_date_hook
) (f
);
9823 /* Display a null-terminated echo area message M. If M is 0, clear
9824 out any existing message, and let the mini-buffer text show through.
9826 The buffer M must continue to exist until after the echo area gets
9827 cleared or some other message gets displayed there. Do not pass
9828 text that is stored in a Lisp string. Do not pass text in a buffer
9829 that was alloca'd. */
9832 message1 (const char *m
)
9834 message3 (m
? build_unibyte_string (m
) : Qnil
);
9838 /* The non-logging counterpart of message1. */
9841 message1_nolog (const char *m
)
9843 message3_nolog (m
? build_unibyte_string (m
) : Qnil
);
9846 /* Display a message M which contains a single %s
9847 which gets replaced with STRING. */
9850 message_with_string (const char *m
, Lisp_Object string
, int log
)
9852 CHECK_STRING (string
);
9858 if (noninteractive_need_newline
)
9859 putc ('\n', stderr
);
9860 noninteractive_need_newline
= 0;
9861 fprintf (stderr
, m
, SDATA (string
));
9862 if (!cursor_in_echo_area
)
9863 fprintf (stderr
, "\n");
9867 else if (INTERACTIVE
)
9869 /* The frame whose minibuffer we're going to display the message on.
9870 It may be larger than the selected frame, so we need
9871 to use its buffer, not the selected frame's buffer. */
9872 Lisp_Object mini_window
;
9873 struct frame
*f
, *sf
= SELECTED_FRAME ();
9875 /* Get the frame containing the minibuffer
9876 that the selected frame is using. */
9877 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
9878 f
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
9880 /* Error messages get reported properly by cmd_error, so this must be
9881 just an informative message; if the frame hasn't really been
9882 initialized yet, just toss it. */
9883 if (f
->glyphs_initialized_p
)
9885 Lisp_Object args
[2], msg
;
9886 struct gcpro gcpro1
, gcpro2
;
9888 args
[0] = build_string (m
);
9889 args
[1] = msg
= string
;
9890 GCPRO2 (args
[0], msg
);
9893 msg
= Fformat (2, args
);
9898 message3_nolog (msg
);
9902 /* Print should start at the beginning of the message
9903 buffer next time. */
9904 message_buf_print
= 0;
9910 /* Dump an informative message to the minibuf. If M is 0, clear out
9911 any existing message, and let the mini-buffer text show through. */
9914 vmessage (const char *m
, va_list ap
)
9920 if (noninteractive_need_newline
)
9921 putc ('\n', stderr
);
9922 noninteractive_need_newline
= 0;
9923 vfprintf (stderr
, m
, ap
);
9924 if (cursor_in_echo_area
== 0)
9925 fprintf (stderr
, "\n");
9929 else if (INTERACTIVE
)
9931 /* The frame whose mini-buffer we're going to display the message
9932 on. It may be larger than the selected frame, so we need to
9933 use its buffer, not the selected frame's buffer. */
9934 Lisp_Object mini_window
;
9935 struct frame
*f
, *sf
= SELECTED_FRAME ();
9937 /* Get the frame containing the mini-buffer
9938 that the selected frame is using. */
9939 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
9940 f
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
9942 /* Error messages get reported properly by cmd_error, so this must be
9943 just an informative message; if the frame hasn't really been
9944 initialized yet, just toss it. */
9945 if (f
->glyphs_initialized_p
)
9950 ptrdiff_t maxsize
= FRAME_MESSAGE_BUF_SIZE (f
);
9951 char *message_buf
= alloca (maxsize
+ 1);
9953 len
= doprnt (message_buf
, maxsize
, m
, 0, ap
);
9955 message3 (make_string (message_buf
, len
));
9960 /* Print should start at the beginning of the message
9961 buffer next time. */
9962 message_buf_print
= 0;
9968 message (const char *m
, ...)
9978 /* The non-logging version of message. */
9981 message_nolog (const char *m
, ...)
9983 Lisp_Object old_log_max
;
9986 old_log_max
= Vmessage_log_max
;
9987 Vmessage_log_max
= Qnil
;
9989 Vmessage_log_max
= old_log_max
;
9995 /* Display the current message in the current mini-buffer. This is
9996 only called from error handlers in process.c, and is not time
10000 update_echo_area (void)
10002 if (!NILP (echo_area_buffer
[0]))
10004 Lisp_Object string
;
10005 string
= Fcurrent_message ();
10011 /* Make sure echo area buffers in `echo_buffers' are live.
10012 If they aren't, make new ones. */
10015 ensure_echo_area_buffers (void)
10019 for (i
= 0; i
< 2; ++i
)
10020 if (!BUFFERP (echo_buffer
[i
])
10021 || !BUFFER_LIVE_P (XBUFFER (echo_buffer
[i
])))
10024 Lisp_Object old_buffer
;
10027 old_buffer
= echo_buffer
[i
];
10028 echo_buffer
[i
] = Fget_buffer_create
10029 (make_formatted_string (name
, " *Echo Area %d*", i
));
10030 bset_truncate_lines (XBUFFER (echo_buffer
[i
]), Qnil
);
10031 /* to force word wrap in echo area -
10032 it was decided to postpone this*/
10033 /* XBUFFER (echo_buffer[i])->word_wrap = Qt; */
10035 for (j
= 0; j
< 2; ++j
)
10036 if (EQ (old_buffer
, echo_area_buffer
[j
]))
10037 echo_area_buffer
[j
] = echo_buffer
[i
];
10042 /* Call FN with args A1..A2 with either the current or last displayed
10043 echo_area_buffer as current buffer.
10045 WHICH zero means use the current message buffer
10046 echo_area_buffer[0]. If that is nil, choose a suitable buffer
10047 from echo_buffer[] and clear it.
10049 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
10050 suitable buffer from echo_buffer[] and clear it.
10052 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
10053 that the current message becomes the last displayed one, make
10054 choose a suitable buffer for echo_area_buffer[0], and clear it.
10056 Value is what FN returns. */
10059 with_echo_area_buffer (struct window
*w
, int which
,
10060 int (*fn
) (ptrdiff_t, Lisp_Object
),
10061 ptrdiff_t a1
, Lisp_Object a2
)
10063 Lisp_Object buffer
;
10064 int this_one
, the_other
, clear_buffer_p
, rc
;
10065 ptrdiff_t count
= SPECPDL_INDEX ();
10067 /* If buffers aren't live, make new ones. */
10068 ensure_echo_area_buffers ();
10070 clear_buffer_p
= 0;
10073 this_one
= 0, the_other
= 1;
10074 else if (which
> 0)
10075 this_one
= 1, the_other
= 0;
10078 this_one
= 0, the_other
= 1;
10079 clear_buffer_p
= 1;
10081 /* We need a fresh one in case the current echo buffer equals
10082 the one containing the last displayed echo area message. */
10083 if (!NILP (echo_area_buffer
[this_one
])
10084 && EQ (echo_area_buffer
[this_one
], echo_area_buffer
[the_other
]))
10085 echo_area_buffer
[this_one
] = Qnil
;
10088 /* Choose a suitable buffer from echo_buffer[] is we don't
10090 if (NILP (echo_area_buffer
[this_one
]))
10092 echo_area_buffer
[this_one
]
10093 = (EQ (echo_area_buffer
[the_other
], echo_buffer
[this_one
])
10094 ? echo_buffer
[the_other
]
10095 : echo_buffer
[this_one
]);
10096 clear_buffer_p
= 1;
10099 buffer
= echo_area_buffer
[this_one
];
10101 /* Don't get confused by reusing the buffer used for echoing
10102 for a different purpose. */
10103 if (echo_kboard
== NULL
&& EQ (buffer
, echo_message_buffer
))
10106 record_unwind_protect (unwind_with_echo_area_buffer
,
10107 with_echo_area_buffer_unwind_data (w
));
10109 /* Make the echo area buffer current. Note that for display
10110 purposes, it is not necessary that the displayed window's buffer
10111 == current_buffer, except for text property lookup. So, let's
10112 only set that buffer temporarily here without doing a full
10113 Fset_window_buffer. We must also change w->pointm, though,
10114 because otherwise an assertions in unshow_buffer fails, and Emacs
10116 set_buffer_internal_1 (XBUFFER (buffer
));
10119 wset_buffer (w
, buffer
);
10120 set_marker_both (w
->pointm
, buffer
, BEG
, BEG_BYTE
);
10123 bset_undo_list (current_buffer
, Qt
);
10124 bset_read_only (current_buffer
, Qnil
);
10125 specbind (Qinhibit_read_only
, Qt
);
10126 specbind (Qinhibit_modification_hooks
, Qt
);
10128 if (clear_buffer_p
&& Z
> BEG
)
10129 del_range (BEG
, Z
);
10131 eassert (BEGV
>= BEG
);
10132 eassert (ZV
<= Z
&& ZV
>= BEGV
);
10136 eassert (BEGV
>= BEG
);
10137 eassert (ZV
<= Z
&& ZV
>= BEGV
);
10139 unbind_to (count
, Qnil
);
10144 /* Save state that should be preserved around the call to the function
10145 FN called in with_echo_area_buffer. */
10148 with_echo_area_buffer_unwind_data (struct window
*w
)
10151 Lisp_Object vector
, tmp
;
10153 /* Reduce consing by keeping one vector in
10154 Vwith_echo_area_save_vector. */
10155 vector
= Vwith_echo_area_save_vector
;
10156 Vwith_echo_area_save_vector
= Qnil
;
10159 vector
= Fmake_vector (make_number (9), Qnil
);
10161 XSETBUFFER (tmp
, current_buffer
); ASET (vector
, i
, tmp
); ++i
;
10162 ASET (vector
, i
, Vdeactivate_mark
); ++i
;
10163 ASET (vector
, i
, make_number (windows_or_buffers_changed
)); ++i
;
10167 XSETWINDOW (tmp
, w
); ASET (vector
, i
, tmp
); ++i
;
10168 ASET (vector
, i
, w
->contents
); ++i
;
10169 ASET (vector
, i
, make_number (marker_position (w
->pointm
))); ++i
;
10170 ASET (vector
, i
, make_number (marker_byte_position (w
->pointm
))); ++i
;
10171 ASET (vector
, i
, make_number (marker_position (w
->start
))); ++i
;
10172 ASET (vector
, i
, make_number (marker_byte_position (w
->start
))); ++i
;
10177 for (; i
< end
; ++i
)
10178 ASET (vector
, i
, Qnil
);
10181 eassert (i
== ASIZE (vector
));
10186 /* Restore global state from VECTOR which was created by
10187 with_echo_area_buffer_unwind_data. */
10190 unwind_with_echo_area_buffer (Lisp_Object vector
)
10192 set_buffer_internal_1 (XBUFFER (AREF (vector
, 0)));
10193 Vdeactivate_mark
= AREF (vector
, 1);
10194 windows_or_buffers_changed
= XFASTINT (AREF (vector
, 2));
10196 if (WINDOWP (AREF (vector
, 3)))
10199 Lisp_Object buffer
;
10201 w
= XWINDOW (AREF (vector
, 3));
10202 buffer
= AREF (vector
, 4);
10204 wset_buffer (w
, buffer
);
10205 set_marker_both (w
->pointm
, buffer
,
10206 XFASTINT (AREF (vector
, 5)),
10207 XFASTINT (AREF (vector
, 6)));
10208 set_marker_both (w
->start
, buffer
,
10209 XFASTINT (AREF (vector
, 7)),
10210 XFASTINT (AREF (vector
, 8)));
10213 Vwith_echo_area_save_vector
= vector
;
10217 /* Set up the echo area for use by print functions. MULTIBYTE_P
10218 non-zero means we will print multibyte. */
10221 setup_echo_area_for_printing (int multibyte_p
)
10223 /* If we can't find an echo area any more, exit. */
10224 if (! FRAME_LIVE_P (XFRAME (selected_frame
)))
10225 Fkill_emacs (Qnil
);
10227 ensure_echo_area_buffers ();
10229 if (!message_buf_print
)
10231 /* A message has been output since the last time we printed.
10232 Choose a fresh echo area buffer. */
10233 if (EQ (echo_area_buffer
[1], echo_buffer
[0]))
10234 echo_area_buffer
[0] = echo_buffer
[1];
10236 echo_area_buffer
[0] = echo_buffer
[0];
10238 /* Switch to that buffer and clear it. */
10239 set_buffer_internal (XBUFFER (echo_area_buffer
[0]));
10240 bset_truncate_lines (current_buffer
, Qnil
);
10244 ptrdiff_t count
= SPECPDL_INDEX ();
10245 specbind (Qinhibit_read_only
, Qt
);
10246 /* Note that undo recording is always disabled. */
10247 del_range (BEG
, Z
);
10248 unbind_to (count
, Qnil
);
10250 TEMP_SET_PT_BOTH (BEG
, BEG_BYTE
);
10252 /* Set up the buffer for the multibyteness we need. */
10254 != !NILP (BVAR (current_buffer
, enable_multibyte_characters
)))
10255 Fset_buffer_multibyte (multibyte_p
? Qt
: Qnil
);
10257 /* Raise the frame containing the echo area. */
10258 if (minibuffer_auto_raise
)
10260 struct frame
*sf
= SELECTED_FRAME ();
10261 Lisp_Object mini_window
;
10262 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
10263 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window
)));
10266 message_log_maybe_newline ();
10267 message_buf_print
= 1;
10271 if (NILP (echo_area_buffer
[0]))
10273 if (EQ (echo_area_buffer
[1], echo_buffer
[0]))
10274 echo_area_buffer
[0] = echo_buffer
[1];
10276 echo_area_buffer
[0] = echo_buffer
[0];
10279 if (current_buffer
!= XBUFFER (echo_area_buffer
[0]))
10281 /* Someone switched buffers between print requests. */
10282 set_buffer_internal (XBUFFER (echo_area_buffer
[0]));
10283 bset_truncate_lines (current_buffer
, Qnil
);
10289 /* Display an echo area message in window W. Value is non-zero if W's
10290 height is changed. If display_last_displayed_message_p is
10291 non-zero, display the message that was last displayed, otherwise
10292 display the current message. */
10295 display_echo_area (struct window
*w
)
10297 int i
, no_message_p
, window_height_changed_p
;
10299 /* Temporarily disable garbage collections while displaying the echo
10300 area. This is done because a GC can print a message itself.
10301 That message would modify the echo area buffer's contents while a
10302 redisplay of the buffer is going on, and seriously confuse
10304 ptrdiff_t count
= inhibit_garbage_collection ();
10306 /* If there is no message, we must call display_echo_area_1
10307 nevertheless because it resizes the window. But we will have to
10308 reset the echo_area_buffer in question to nil at the end because
10309 with_echo_area_buffer will sets it to an empty buffer. */
10310 i
= display_last_displayed_message_p
? 1 : 0;
10311 no_message_p
= NILP (echo_area_buffer
[i
]);
10313 window_height_changed_p
10314 = with_echo_area_buffer (w
, display_last_displayed_message_p
,
10315 display_echo_area_1
,
10316 (intptr_t) w
, Qnil
);
10319 echo_area_buffer
[i
] = Qnil
;
10321 unbind_to (count
, Qnil
);
10322 return window_height_changed_p
;
10326 /* Helper for display_echo_area. Display the current buffer which
10327 contains the current echo area message in window W, a mini-window,
10328 a pointer to which is passed in A1. A2..A4 are currently not used.
10329 Change the height of W so that all of the message is displayed.
10330 Value is non-zero if height of W was changed. */
10333 display_echo_area_1 (ptrdiff_t a1
, Lisp_Object a2
)
10336 struct window
*w
= (struct window
*) i1
;
10337 Lisp_Object window
;
10338 struct text_pos start
;
10339 int window_height_changed_p
= 0;
10341 /* Do this before displaying, so that we have a large enough glyph
10342 matrix for the display. If we can't get enough space for the
10343 whole text, display the last N lines. That works by setting w->start. */
10344 window_height_changed_p
= resize_mini_window (w
, 0);
10346 /* Use the starting position chosen by resize_mini_window. */
10347 SET_TEXT_POS_FROM_MARKER (start
, w
->start
);
10350 clear_glyph_matrix (w
->desired_matrix
);
10351 XSETWINDOW (window
, w
);
10352 try_window (window
, start
, 0);
10354 return window_height_changed_p
;
10358 /* Resize the echo area window to exactly the size needed for the
10359 currently displayed message, if there is one. If a mini-buffer
10360 is active, don't shrink it. */
10363 resize_echo_area_exactly (void)
10365 if (BUFFERP (echo_area_buffer
[0])
10366 && WINDOWP (echo_area_window
))
10368 struct window
*w
= XWINDOW (echo_area_window
);
10370 Lisp_Object resize_exactly
;
10372 if (minibuf_level
== 0)
10373 resize_exactly
= Qt
;
10375 resize_exactly
= Qnil
;
10377 resized_p
= with_echo_area_buffer (w
, 0, resize_mini_window_1
,
10378 (intptr_t) w
, resize_exactly
);
10381 ++windows_or_buffers_changed
;
10382 ++update_mode_lines
;
10383 redisplay_internal ();
10389 /* Callback function for with_echo_area_buffer, when used from
10390 resize_echo_area_exactly. A1 contains a pointer to the window to
10391 resize, EXACTLY non-nil means resize the mini-window exactly to the
10392 size of the text displayed. A3 and A4 are not used. Value is what
10393 resize_mini_window returns. */
10396 resize_mini_window_1 (ptrdiff_t a1
, Lisp_Object exactly
)
10399 return resize_mini_window ((struct window
*) i1
, !NILP (exactly
));
10403 /* Resize mini-window W to fit the size of its contents. EXACT_P
10404 means size the window exactly to the size needed. Otherwise, it's
10405 only enlarged until W's buffer is empty.
10407 Set W->start to the right place to begin display. If the whole
10408 contents fit, start at the beginning. Otherwise, start so as
10409 to make the end of the contents appear. This is particularly
10410 important for y-or-n-p, but seems desirable generally.
10412 Value is non-zero if the window height has been changed. */
10415 resize_mini_window (struct window
*w
, int exact_p
)
10417 struct frame
*f
= XFRAME (w
->frame
);
10418 int window_height_changed_p
= 0;
10420 eassert (MINI_WINDOW_P (w
));
10422 /* By default, start display at the beginning. */
10423 set_marker_both (w
->start
, w
->contents
,
10424 BUF_BEGV (XBUFFER (w
->contents
)),
10425 BUF_BEGV_BYTE (XBUFFER (w
->contents
)));
10427 /* Don't resize windows while redisplaying a window; it would
10428 confuse redisplay functions when the size of the window they are
10429 displaying changes from under them. Such a resizing can happen,
10430 for instance, when which-func prints a long message while
10431 we are running fontification-functions. We're running these
10432 functions with safe_call which binds inhibit-redisplay to t. */
10433 if (!NILP (Vinhibit_redisplay
))
10436 /* Nil means don't try to resize. */
10437 if (NILP (Vresize_mini_windows
)
10438 || (FRAME_X_P (f
) && FRAME_X_OUTPUT (f
) == NULL
))
10441 if (!FRAME_MINIBUF_ONLY_P (f
))
10444 struct window
*root
= XWINDOW (FRAME_ROOT_WINDOW (f
));
10445 int total_height
= WINDOW_TOTAL_LINES (root
) + WINDOW_TOTAL_LINES (w
);
10447 EMACS_INT max_height
;
10448 int unit
= FRAME_LINE_HEIGHT (f
);
10449 struct text_pos start
;
10450 struct buffer
*old_current_buffer
= NULL
;
10452 if (current_buffer
!= XBUFFER (w
->contents
))
10454 old_current_buffer
= current_buffer
;
10455 set_buffer_internal (XBUFFER (w
->contents
));
10458 init_iterator (&it
, w
, BEGV
, BEGV_BYTE
, NULL
, DEFAULT_FACE_ID
);
10460 /* Compute the max. number of lines specified by the user. */
10461 if (FLOATP (Vmax_mini_window_height
))
10462 max_height
= XFLOATINT (Vmax_mini_window_height
) * FRAME_LINES (f
);
10463 else if (INTEGERP (Vmax_mini_window_height
))
10464 max_height
= XINT (Vmax_mini_window_height
);
10466 max_height
= total_height
/ 4;
10468 /* Correct that max. height if it's bogus. */
10469 max_height
= clip_to_bounds (1, max_height
, total_height
);
10471 /* Find out the height of the text in the window. */
10472 if (it
.line_wrap
== TRUNCATE
)
10477 move_it_to (&it
, ZV
, -1, -1, -1, MOVE_TO_POS
);
10478 if (it
.max_ascent
== 0 && it
.max_descent
== 0)
10479 height
= it
.current_y
+ last_height
;
10481 height
= it
.current_y
+ it
.max_ascent
+ it
.max_descent
;
10482 height
-= min (it
.extra_line_spacing
, it
.max_extra_line_spacing
);
10483 height
= (height
+ unit
- 1) / unit
;
10486 /* Compute a suitable window start. */
10487 if (height
> max_height
)
10489 height
= max_height
;
10490 init_iterator (&it
, w
, ZV
, ZV_BYTE
, NULL
, DEFAULT_FACE_ID
);
10491 move_it_vertically_backward (&it
, (height
- 1) * unit
);
10492 start
= it
.current
.pos
;
10495 SET_TEXT_POS (start
, BEGV
, BEGV_BYTE
);
10496 SET_MARKER_FROM_TEXT_POS (w
->start
, start
);
10498 if (EQ (Vresize_mini_windows
, Qgrow_only
))
10500 /* Let it grow only, until we display an empty message, in which
10501 case the window shrinks again. */
10502 if (height
> WINDOW_TOTAL_LINES (w
))
10504 int old_height
= WINDOW_TOTAL_LINES (w
);
10506 FRAME_WINDOWS_FROZEN (f
) = 1;
10507 grow_mini_window (w
, height
- WINDOW_TOTAL_LINES (w
));
10508 window_height_changed_p
= WINDOW_TOTAL_LINES (w
) != old_height
;
10510 else if (height
< WINDOW_TOTAL_LINES (w
)
10511 && (exact_p
|| BEGV
== ZV
))
10513 int old_height
= WINDOW_TOTAL_LINES (w
);
10515 FRAME_WINDOWS_FROZEN (f
) = 0;
10516 shrink_mini_window (w
);
10517 window_height_changed_p
= WINDOW_TOTAL_LINES (w
) != old_height
;
10522 /* Always resize to exact size needed. */
10523 if (height
> WINDOW_TOTAL_LINES (w
))
10525 int old_height
= WINDOW_TOTAL_LINES (w
);
10527 FRAME_WINDOWS_FROZEN (f
) = 1;
10528 grow_mini_window (w
, height
- WINDOW_TOTAL_LINES (w
));
10529 window_height_changed_p
= WINDOW_TOTAL_LINES (w
) != old_height
;
10531 else if (height
< WINDOW_TOTAL_LINES (w
))
10533 int old_height
= WINDOW_TOTAL_LINES (w
);
10535 FRAME_WINDOWS_FROZEN (f
) = 0;
10536 shrink_mini_window (w
);
10540 FRAME_WINDOWS_FROZEN (f
) = 1;
10541 grow_mini_window (w
, height
- WINDOW_TOTAL_LINES (w
));
10544 window_height_changed_p
= WINDOW_TOTAL_LINES (w
) != old_height
;
10548 if (old_current_buffer
)
10549 set_buffer_internal (old_current_buffer
);
10552 return window_height_changed_p
;
10556 /* Value is the current message, a string, or nil if there is no
10557 current message. */
10560 current_message (void)
10564 if (!BUFFERP (echo_area_buffer
[0]))
10568 with_echo_area_buffer (0, 0, current_message_1
,
10569 (intptr_t) &msg
, Qnil
);
10571 echo_area_buffer
[0] = Qnil
;
10579 current_message_1 (ptrdiff_t a1
, Lisp_Object a2
)
10582 Lisp_Object
*msg
= (Lisp_Object
*) i1
;
10585 *msg
= make_buffer_string (BEG
, Z
, 1);
10592 /* Push the current message on Vmessage_stack for later restoration
10593 by restore_message. Value is non-zero if the current message isn't
10594 empty. This is a relatively infrequent operation, so it's not
10595 worth optimizing. */
10598 push_message (void)
10600 Lisp_Object msg
= current_message ();
10601 Vmessage_stack
= Fcons (msg
, Vmessage_stack
);
10602 return STRINGP (msg
);
10606 /* Restore message display from the top of Vmessage_stack. */
10609 restore_message (void)
10611 eassert (CONSP (Vmessage_stack
));
10612 message3_nolog (XCAR (Vmessage_stack
));
10616 /* Handler for unwind-protect calling pop_message. */
10619 pop_message_unwind (void)
10621 /* Pop the top-most entry off Vmessage_stack. */
10622 eassert (CONSP (Vmessage_stack
));
10623 Vmessage_stack
= XCDR (Vmessage_stack
);
10627 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
10628 exits. If the stack is not empty, we have a missing pop_message
10632 check_message_stack (void)
10634 if (!NILP (Vmessage_stack
))
10639 /* Truncate to NCHARS what will be displayed in the echo area the next
10640 time we display it---but don't redisplay it now. */
10643 truncate_echo_area (ptrdiff_t nchars
)
10646 echo_area_buffer
[0] = Qnil
;
10647 else if (!noninteractive
10649 && !NILP (echo_area_buffer
[0]))
10651 struct frame
*sf
= SELECTED_FRAME ();
10652 /* Error messages get reported properly by cmd_error, so this must be
10653 just an informative message; if the frame hasn't really been
10654 initialized yet, just toss it. */
10655 if (sf
->glyphs_initialized_p
)
10656 with_echo_area_buffer (0, 0, truncate_message_1
, nchars
, Qnil
);
10661 /* Helper function for truncate_echo_area. Truncate the current
10662 message to at most NCHARS characters. */
10665 truncate_message_1 (ptrdiff_t nchars
, Lisp_Object a2
)
10667 if (BEG
+ nchars
< Z
)
10668 del_range (BEG
+ nchars
, Z
);
10670 echo_area_buffer
[0] = Qnil
;
10674 /* Set the current message to STRING. */
10677 set_message (Lisp_Object string
)
10679 eassert (STRINGP (string
));
10681 message_enable_multibyte
= STRING_MULTIBYTE (string
);
10683 with_echo_area_buffer (0, -1, set_message_1
, 0, string
);
10684 message_buf_print
= 0;
10685 help_echo_showing_p
= 0;
10687 if (STRINGP (Vdebug_on_message
)
10688 && STRINGP (string
)
10689 && fast_string_match (Vdebug_on_message
, string
) >= 0)
10690 call_debugger (list2 (Qerror
, string
));
10694 /* Helper function for set_message. First argument is ignored and second
10695 argument has the same meaning as for set_message.
10696 This function is called with the echo area buffer being current. */
10699 set_message_1 (ptrdiff_t a1
, Lisp_Object string
)
10701 eassert (STRINGP (string
));
10703 /* Change multibyteness of the echo buffer appropriately. */
10704 if (message_enable_multibyte
10705 != !NILP (BVAR (current_buffer
, enable_multibyte_characters
)))
10706 Fset_buffer_multibyte (message_enable_multibyte
? Qt
: Qnil
);
10708 bset_truncate_lines (current_buffer
, message_truncate_lines
? Qt
: Qnil
);
10709 if (!NILP (BVAR (current_buffer
, bidi_display_reordering
)))
10710 bset_bidi_paragraph_direction (current_buffer
, Qleft_to_right
);
10712 /* Insert new message at BEG. */
10713 TEMP_SET_PT_BOTH (BEG
, BEG_BYTE
);
10715 /* This function takes care of single/multibyte conversion.
10716 We just have to ensure that the echo area buffer has the right
10717 setting of enable_multibyte_characters. */
10718 insert_from_string (string
, 0, 0, SCHARS (string
), SBYTES (string
), 1);
10724 /* Clear messages. CURRENT_P non-zero means clear the current
10725 message. LAST_DISPLAYED_P non-zero means clear the message
10729 clear_message (int current_p
, int last_displayed_p
)
10733 echo_area_buffer
[0] = Qnil
;
10734 message_cleared_p
= 1;
10737 if (last_displayed_p
)
10738 echo_area_buffer
[1] = Qnil
;
10740 message_buf_print
= 0;
10743 /* Clear garbaged frames.
10745 This function is used where the old redisplay called
10746 redraw_garbaged_frames which in turn called redraw_frame which in
10747 turn called clear_frame. The call to clear_frame was a source of
10748 flickering. I believe a clear_frame is not necessary. It should
10749 suffice in the new redisplay to invalidate all current matrices,
10750 and ensure a complete redisplay of all windows. */
10753 clear_garbaged_frames (void)
10755 if (frame_garbaged
)
10757 Lisp_Object tail
, frame
;
10758 int changed_count
= 0;
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
);
10776 frame_garbaged
= 0;
10778 ++windows_or_buffers_changed
;
10783 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
10784 is non-zero update selected_frame. Value is non-zero if the
10785 mini-windows height has been changed. */
10788 echo_area_display (int update_frame_p
)
10790 Lisp_Object mini_window
;
10793 int window_height_changed_p
= 0;
10794 struct frame
*sf
= SELECTED_FRAME ();
10796 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
10797 w
= XWINDOW (mini_window
);
10798 f
= XFRAME (WINDOW_FRAME (w
));
10800 /* Don't display if frame is invisible or not yet initialized. */
10801 if (!FRAME_VISIBLE_P (f
) || !f
->glyphs_initialized_p
)
10804 #ifdef HAVE_WINDOW_SYSTEM
10805 /* When Emacs starts, selected_frame may be the initial terminal
10806 frame. If we let this through, a message would be displayed on
10808 if (FRAME_INITIAL_P (XFRAME (selected_frame
)))
10810 #endif /* HAVE_WINDOW_SYSTEM */
10812 /* Redraw garbaged frames. */
10813 clear_garbaged_frames ();
10815 if (!NILP (echo_area_buffer
[0]) || minibuf_level
== 0)
10817 echo_area_window
= mini_window
;
10818 window_height_changed_p
= display_echo_area (w
);
10819 w
->must_be_updated_p
= 1;
10821 /* Update the display, unless called from redisplay_internal.
10822 Also don't update the screen during redisplay itself. The
10823 update will happen at the end of redisplay, and an update
10824 here could cause confusion. */
10825 if (update_frame_p
&& !redisplaying_p
)
10829 /* If the display update has been interrupted by pending
10830 input, update mode lines in the frame. Due to the
10831 pending input, it might have been that redisplay hasn't
10832 been called, so that mode lines above the echo area are
10833 garbaged. This looks odd, so we prevent it here. */
10834 if (!display_completed
)
10835 n
= redisplay_mode_lines (FRAME_ROOT_WINDOW (f
), 0);
10837 if (window_height_changed_p
10838 /* Don't do this if Emacs is shutting down. Redisplay
10839 needs to run hooks. */
10840 && !NILP (Vrun_hooks
))
10842 /* Must update other windows. Likewise as in other
10843 cases, don't let this update be interrupted by
10845 ptrdiff_t count
= SPECPDL_INDEX ();
10846 specbind (Qredisplay_dont_pause
, Qt
);
10847 windows_or_buffers_changed
= 1;
10848 redisplay_internal ();
10849 unbind_to (count
, Qnil
);
10851 else if (FRAME_WINDOW_P (f
) && n
== 0)
10853 /* Window configuration is the same as before.
10854 Can do with a display update of the echo area,
10855 unless we displayed some mode lines. */
10856 update_single_window (w
, 1);
10860 update_frame (f
, 1, 1);
10862 /* If cursor is in the echo area, make sure that the next
10863 redisplay displays the minibuffer, so that the cursor will
10864 be replaced with what the minibuffer wants. */
10865 if (cursor_in_echo_area
)
10866 ++windows_or_buffers_changed
;
10869 else if (!EQ (mini_window
, selected_window
))
10870 windows_or_buffers_changed
++;
10872 /* Last displayed message is now the current message. */
10873 echo_area_buffer
[1] = echo_area_buffer
[0];
10874 /* Inform read_char that we're not echoing. */
10875 echo_message_buffer
= Qnil
;
10877 /* Prevent redisplay optimization in redisplay_internal by resetting
10878 this_line_start_pos. This is done because the mini-buffer now
10879 displays the message instead of its buffer text. */
10880 if (EQ (mini_window
, selected_window
))
10881 CHARPOS (this_line_start_pos
) = 0;
10883 return window_height_changed_p
;
10886 /* Nonzero if the current window's buffer is shown in more than one
10887 window and was modified since last redisplay. */
10890 buffer_shared_and_changed (void)
10892 return (buffer_window_count (current_buffer
) > 1
10893 && UNCHANGED_MODIFIED
< MODIFF
);
10896 /* Nonzero if W's buffer was changed but not saved or Transient Mark mode
10897 is enabled and mark of W's buffer was changed since last W's update. */
10900 window_buffer_changed (struct window
*w
)
10902 struct buffer
*b
= XBUFFER (w
->contents
);
10904 eassert (BUFFER_LIVE_P (b
));
10906 return (((BUF_SAVE_MODIFF (b
) < BUF_MODIFF (b
)) != w
->last_had_star
)
10907 || ((!NILP (Vtransient_mark_mode
) && !NILP (BVAR (b
, mark_active
)))
10908 != (w
->region_showing
!= 0)));
10911 /* Nonzero if W has %c in its mode line and mode line should be updated. */
10914 mode_line_update_needed (struct window
*w
)
10916 return (w
->column_number_displayed
!= -1
10917 && !(PT
== w
->last_point
&& !window_outdated (w
))
10918 && (w
->column_number_displayed
!= current_column ()));
10921 /* Nonzero if window start of W is frozen and may not be changed during
10925 window_frozen_p (struct window
*w
)
10927 if (FRAME_WINDOWS_FROZEN (XFRAME (WINDOW_FRAME (w
))))
10929 Lisp_Object window
;
10931 XSETWINDOW (window
, w
);
10932 if (MINI_WINDOW_P (w
))
10934 else if (EQ (window
, selected_window
))
10936 else if (MINI_WINDOW_P (XWINDOW (selected_window
))
10937 && EQ (window
, Vminibuf_scroll_window
))
10938 /* This special window can't be frozen too. */
10946 /***********************************************************************
10947 Mode Lines and Frame Titles
10948 ***********************************************************************/
10950 /* A buffer for constructing non-propertized mode-line strings and
10951 frame titles in it; allocated from the heap in init_xdisp and
10952 resized as needed in store_mode_line_noprop_char. */
10954 static char *mode_line_noprop_buf
;
10956 /* The buffer's end, and a current output position in it. */
10958 static char *mode_line_noprop_buf_end
;
10959 static char *mode_line_noprop_ptr
;
10961 #define MODE_LINE_NOPROP_LEN(start) \
10962 ((mode_line_noprop_ptr - mode_line_noprop_buf) - start)
10965 MODE_LINE_DISPLAY
= 0,
10969 } mode_line_target
;
10971 /* Alist that caches the results of :propertize.
10972 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
10973 static Lisp_Object mode_line_proptrans_alist
;
10975 /* List of strings making up the mode-line. */
10976 static Lisp_Object mode_line_string_list
;
10978 /* Base face property when building propertized mode line string. */
10979 static Lisp_Object mode_line_string_face
;
10980 static Lisp_Object mode_line_string_face_prop
;
10983 /* Unwind data for mode line strings */
10985 static Lisp_Object Vmode_line_unwind_vector
;
10988 format_mode_line_unwind_data (struct frame
*target_frame
,
10989 struct buffer
*obuf
,
10991 int save_proptrans
)
10993 Lisp_Object vector
, tmp
;
10995 /* Reduce consing by keeping one vector in
10996 Vwith_echo_area_save_vector. */
10997 vector
= Vmode_line_unwind_vector
;
10998 Vmode_line_unwind_vector
= Qnil
;
11001 vector
= Fmake_vector (make_number (10), Qnil
);
11003 ASET (vector
, 0, make_number (mode_line_target
));
11004 ASET (vector
, 1, make_number (MODE_LINE_NOPROP_LEN (0)));
11005 ASET (vector
, 2, mode_line_string_list
);
11006 ASET (vector
, 3, save_proptrans
? mode_line_proptrans_alist
: Qt
);
11007 ASET (vector
, 4, mode_line_string_face
);
11008 ASET (vector
, 5, mode_line_string_face_prop
);
11011 XSETBUFFER (tmp
, obuf
);
11014 ASET (vector
, 6, tmp
);
11015 ASET (vector
, 7, owin
);
11018 /* Similarly to `with-selected-window', if the operation selects
11019 a window on another frame, we must restore that frame's
11020 selected window, and (for a tty) the top-frame. */
11021 ASET (vector
, 8, target_frame
->selected_window
);
11022 if (FRAME_TERMCAP_P (target_frame
))
11023 ASET (vector
, 9, FRAME_TTY (target_frame
)->top_frame
);
11030 unwind_format_mode_line (Lisp_Object vector
)
11032 Lisp_Object old_window
= AREF (vector
, 7);
11033 Lisp_Object target_frame_window
= AREF (vector
, 8);
11034 Lisp_Object old_top_frame
= AREF (vector
, 9);
11036 mode_line_target
= XINT (AREF (vector
, 0));
11037 mode_line_noprop_ptr
= mode_line_noprop_buf
+ XINT (AREF (vector
, 1));
11038 mode_line_string_list
= AREF (vector
, 2);
11039 if (! EQ (AREF (vector
, 3), Qt
))
11040 mode_line_proptrans_alist
= AREF (vector
, 3);
11041 mode_line_string_face
= AREF (vector
, 4);
11042 mode_line_string_face_prop
= AREF (vector
, 5);
11044 /* Select window before buffer, since it may change the buffer. */
11045 if (!NILP (old_window
))
11047 /* If the operation that we are unwinding had selected a window
11048 on a different frame, reset its frame-selected-window. For a
11049 text terminal, reset its top-frame if necessary. */
11050 if (!NILP (target_frame_window
))
11053 = WINDOW_FRAME (XWINDOW (target_frame_window
));
11055 if (!EQ (frame
, WINDOW_FRAME (XWINDOW (old_window
))))
11056 Fselect_window (target_frame_window
, Qt
);
11058 if (!NILP (old_top_frame
) && !EQ (old_top_frame
, frame
))
11059 Fselect_frame (old_top_frame
, Qt
);
11062 Fselect_window (old_window
, Qt
);
11065 if (!NILP (AREF (vector
, 6)))
11067 set_buffer_internal_1 (XBUFFER (AREF (vector
, 6)));
11068 ASET (vector
, 6, Qnil
);
11071 Vmode_line_unwind_vector
= vector
;
11075 /* Store a single character C for the frame title in mode_line_noprop_buf.
11076 Re-allocate mode_line_noprop_buf if necessary. */
11079 store_mode_line_noprop_char (char c
)
11081 /* If output position has reached the end of the allocated buffer,
11082 increase the buffer's size. */
11083 if (mode_line_noprop_ptr
== mode_line_noprop_buf_end
)
11085 ptrdiff_t len
= MODE_LINE_NOPROP_LEN (0);
11086 ptrdiff_t size
= len
;
11087 mode_line_noprop_buf
=
11088 xpalloc (mode_line_noprop_buf
, &size
, 1, STRING_BYTES_BOUND
, 1);
11089 mode_line_noprop_buf_end
= mode_line_noprop_buf
+ size
;
11090 mode_line_noprop_ptr
= mode_line_noprop_buf
+ len
;
11093 *mode_line_noprop_ptr
++ = c
;
11097 /* Store part of a frame title in mode_line_noprop_buf, beginning at
11098 mode_line_noprop_ptr. STRING is the string to store. Do not copy
11099 characters that yield more columns than PRECISION; PRECISION <= 0
11100 means copy the whole string. Pad with spaces until FIELD_WIDTH
11101 number of characters have been copied; FIELD_WIDTH <= 0 means don't
11102 pad. Called from display_mode_element when it is used to build a
11106 store_mode_line_noprop (const char *string
, int field_width
, int precision
)
11108 const unsigned char *str
= (const unsigned char *) string
;
11110 ptrdiff_t dummy
, nbytes
;
11112 /* Copy at most PRECISION chars from STR. */
11113 nbytes
= strlen (string
);
11114 n
+= c_string_width (str
, nbytes
, precision
, &dummy
, &nbytes
);
11116 store_mode_line_noprop_char (*str
++);
11118 /* Fill up with spaces until FIELD_WIDTH reached. */
11119 while (field_width
> 0
11120 && n
< field_width
)
11122 store_mode_line_noprop_char (' ');
11129 /***********************************************************************
11131 ***********************************************************************/
11133 #ifdef HAVE_WINDOW_SYSTEM
11135 /* Set the title of FRAME, if it has changed. The title format is
11136 Vicon_title_format if FRAME is iconified, otherwise it is
11137 frame_title_format. */
11140 x_consider_frame_title (Lisp_Object frame
)
11142 struct frame
*f
= XFRAME (frame
);
11144 if (FRAME_WINDOW_P (f
)
11145 || FRAME_MINIBUF_ONLY_P (f
)
11146 || f
->explicit_name
)
11148 /* Do we have more than one visible frame on this X display? */
11149 Lisp_Object tail
, other_frame
, fmt
;
11150 ptrdiff_t title_start
;
11154 ptrdiff_t count
= SPECPDL_INDEX ();
11156 FOR_EACH_FRAME (tail
, other_frame
)
11158 struct frame
*tf
= XFRAME (other_frame
);
11161 && FRAME_KBOARD (tf
) == FRAME_KBOARD (f
)
11162 && !FRAME_MINIBUF_ONLY_P (tf
)
11163 && !EQ (other_frame
, tip_frame
)
11164 && (FRAME_VISIBLE_P (tf
) || FRAME_ICONIFIED_P (tf
)))
11168 /* Set global variable indicating that multiple frames exist. */
11169 multiple_frames
= CONSP (tail
);
11171 /* Switch to the buffer of selected window of the frame. Set up
11172 mode_line_target so that display_mode_element will output into
11173 mode_line_noprop_buf; then display the title. */
11174 record_unwind_protect (unwind_format_mode_line
,
11175 format_mode_line_unwind_data
11176 (f
, current_buffer
, selected_window
, 0));
11178 Fselect_window (f
->selected_window
, Qt
);
11179 set_buffer_internal_1
11180 (XBUFFER (XWINDOW (f
->selected_window
)->contents
));
11181 fmt
= FRAME_ICONIFIED_P (f
) ? Vicon_title_format
: Vframe_title_format
;
11183 mode_line_target
= MODE_LINE_TITLE
;
11184 title_start
= MODE_LINE_NOPROP_LEN (0);
11185 init_iterator (&it
, XWINDOW (f
->selected_window
), -1, -1,
11186 NULL
, DEFAULT_FACE_ID
);
11187 display_mode_element (&it
, 0, -1, -1, fmt
, Qnil
, 0);
11188 len
= MODE_LINE_NOPROP_LEN (title_start
);
11189 title
= mode_line_noprop_buf
+ title_start
;
11190 unbind_to (count
, Qnil
);
11192 /* Set the title only if it's changed. This avoids consing in
11193 the common case where it hasn't. (If it turns out that we've
11194 already wasted too much time by walking through the list with
11195 display_mode_element, then we might need to optimize at a
11196 higher level than this.) */
11197 if (! STRINGP (f
->name
)
11198 || SBYTES (f
->name
) != len
11199 || memcmp (title
, SDATA (f
->name
), len
) != 0)
11200 x_implicitly_set_name (f
, make_string (title
, len
), Qnil
);
11204 #endif /* not HAVE_WINDOW_SYSTEM */
11207 /***********************************************************************
11209 ***********************************************************************/
11212 /* Prepare for redisplay by updating menu-bar item lists when
11213 appropriate. This can call eval. */
11216 prepare_menu_bars (void)
11219 struct gcpro gcpro1
, gcpro2
;
11221 Lisp_Object tooltip_frame
;
11223 #ifdef HAVE_WINDOW_SYSTEM
11224 tooltip_frame
= tip_frame
;
11226 tooltip_frame
= Qnil
;
11229 /* Update all frame titles based on their buffer names, etc. We do
11230 this before the menu bars so that the buffer-menu will show the
11231 up-to-date frame titles. */
11232 #ifdef HAVE_WINDOW_SYSTEM
11233 if (windows_or_buffers_changed
|| update_mode_lines
)
11235 Lisp_Object tail
, frame
;
11237 FOR_EACH_FRAME (tail
, frame
)
11239 f
= XFRAME (frame
);
11240 if (!EQ (frame
, tooltip_frame
)
11241 && (FRAME_ICONIFIED_P (f
)
11242 || FRAME_VISIBLE_P (f
) == 1
11243 /* Exclude TTY frames that are obscured because they
11244 are not the top frame on their console. This is
11245 because x_consider_frame_title actually switches
11246 to the frame, which for TTY frames means it is
11247 marked as garbaged, and will be completely
11248 redrawn on the next redisplay cycle. This causes
11249 TTY frames to be completely redrawn, when there
11250 are more than one of them, even though nothing
11251 should be changed on display. */
11252 || (FRAME_VISIBLE_P (f
) == 2 && FRAME_WINDOW_P (f
))))
11253 x_consider_frame_title (frame
);
11256 #endif /* HAVE_WINDOW_SYSTEM */
11258 /* Update the menu bar item lists, if appropriate. This has to be
11259 done before any actual redisplay or generation of display lines. */
11260 all_windows
= (update_mode_lines
11261 || buffer_shared_and_changed ()
11262 || windows_or_buffers_changed
);
11265 Lisp_Object tail
, frame
;
11266 ptrdiff_t count
= SPECPDL_INDEX ();
11267 /* 1 means that update_menu_bar has run its hooks
11268 so any further calls to update_menu_bar shouldn't do so again. */
11269 int menu_bar_hooks_run
= 0;
11271 record_unwind_save_match_data ();
11273 FOR_EACH_FRAME (tail
, frame
)
11275 f
= XFRAME (frame
);
11277 /* Ignore tooltip frame. */
11278 if (EQ (frame
, tooltip_frame
))
11281 /* If a window on this frame changed size, report that to
11282 the user and clear the size-change flag. */
11283 if (FRAME_WINDOW_SIZES_CHANGED (f
))
11285 Lisp_Object functions
;
11287 /* Clear flag first in case we get an error below. */
11288 FRAME_WINDOW_SIZES_CHANGED (f
) = 0;
11289 functions
= Vwindow_size_change_functions
;
11290 GCPRO2 (tail
, functions
);
11292 while (CONSP (functions
))
11294 if (!EQ (XCAR (functions
), Qt
))
11295 call1 (XCAR (functions
), frame
);
11296 functions
= XCDR (functions
);
11302 menu_bar_hooks_run
= update_menu_bar (f
, 0, menu_bar_hooks_run
);
11303 #ifdef HAVE_WINDOW_SYSTEM
11304 update_tool_bar (f
, 0);
11307 if (windows_or_buffers_changed
11310 (f
, Fbuffer_modified_p (XWINDOW (f
->selected_window
)->contents
));
11315 unbind_to (count
, Qnil
);
11319 struct frame
*sf
= SELECTED_FRAME ();
11320 update_menu_bar (sf
, 1, 0);
11321 #ifdef HAVE_WINDOW_SYSTEM
11322 update_tool_bar (sf
, 1);
11328 /* Update the menu bar item list for frame F. This has to be done
11329 before we start to fill in any display lines, because it can call
11332 If SAVE_MATCH_DATA is non-zero, we must save and restore it here.
11334 If HOOKS_RUN is 1, that means a previous call to update_menu_bar
11335 already ran the menu bar hooks for this redisplay, so there
11336 is no need to run them again. The return value is the
11337 updated value of this flag, to pass to the next call. */
11340 update_menu_bar (struct frame
*f
, int save_match_data
, int hooks_run
)
11342 Lisp_Object window
;
11343 register struct window
*w
;
11345 /* If called recursively during a menu update, do nothing. This can
11346 happen when, for instance, an activate-menubar-hook causes a
11348 if (inhibit_menubar_update
)
11351 window
= FRAME_SELECTED_WINDOW (f
);
11352 w
= XWINDOW (window
);
11354 if (FRAME_WINDOW_P (f
)
11356 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
11357 || defined (HAVE_NS) || defined (USE_GTK)
11358 FRAME_EXTERNAL_MENU_BAR (f
)
11360 FRAME_MENU_BAR_LINES (f
) > 0
11362 : FRAME_MENU_BAR_LINES (f
) > 0)
11364 /* If the user has switched buffers or windows, we need to
11365 recompute to reflect the new bindings. But we'll
11366 recompute when update_mode_lines is set too; that means
11367 that people can use force-mode-line-update to request
11368 that the menu bar be recomputed. The adverse effect on
11369 the rest of the redisplay algorithm is about the same as
11370 windows_or_buffers_changed anyway. */
11371 if (windows_or_buffers_changed
11372 /* This used to test w->update_mode_line, but we believe
11373 there is no need to recompute the menu in that case. */
11374 || update_mode_lines
11375 || window_buffer_changed (w
))
11377 struct buffer
*prev
= current_buffer
;
11378 ptrdiff_t count
= SPECPDL_INDEX ();
11380 specbind (Qinhibit_menubar_update
, Qt
);
11382 set_buffer_internal_1 (XBUFFER (w
->contents
));
11383 if (save_match_data
)
11384 record_unwind_save_match_data ();
11385 if (NILP (Voverriding_local_map_menu_flag
))
11387 specbind (Qoverriding_terminal_local_map
, Qnil
);
11388 specbind (Qoverriding_local_map
, Qnil
);
11393 /* Run the Lucid hook. */
11394 safe_run_hooks (Qactivate_menubar_hook
);
11396 /* If it has changed current-menubar from previous value,
11397 really recompute the menu-bar from the value. */
11398 if (! NILP (Vlucid_menu_bar_dirty_flag
))
11399 call0 (Qrecompute_lucid_menubar
);
11401 safe_run_hooks (Qmenu_bar_update_hook
);
11406 XSETFRAME (Vmenu_updating_frame
, f
);
11407 fset_menu_bar_items (f
, menu_bar_items (FRAME_MENU_BAR_ITEMS (f
)));
11409 /* Redisplay the menu bar in case we changed it. */
11410 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
11411 || defined (HAVE_NS) || defined (USE_GTK)
11412 if (FRAME_WINDOW_P (f
))
11414 #if defined (HAVE_NS)
11415 /* All frames on Mac OS share the same menubar. So only
11416 the selected frame should be allowed to set it. */
11417 if (f
== SELECTED_FRAME ())
11419 set_frame_menubar (f
, 0, 0);
11422 /* On a terminal screen, the menu bar is an ordinary screen
11423 line, and this makes it get updated. */
11424 w
->update_mode_line
= 1;
11425 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
11426 /* In the non-toolkit version, the menu bar is an ordinary screen
11427 line, and this makes it get updated. */
11428 w
->update_mode_line
= 1;
11429 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
11431 unbind_to (count
, Qnil
);
11432 set_buffer_internal_1 (prev
);
11439 /***********************************************************************
11441 ***********************************************************************/
11443 #ifdef HAVE_WINDOW_SYSTEM
11445 /* Where the mouse was last time we reported a mouse event. */
11447 struct frame
*last_mouse_frame
;
11449 /* Tool-bar item index of the item on which a mouse button was pressed
11452 int last_tool_bar_item
;
11454 /* Select `frame' temporarily without running all the code in
11456 FIXME: Maybe do_switch_frame should be trimmed down similarly
11457 when `norecord' is set. */
11459 fast_set_selected_frame (Lisp_Object frame
)
11461 if (!EQ (selected_frame
, frame
))
11463 selected_frame
= frame
;
11464 selected_window
= XFRAME (frame
)->selected_window
;
11468 /* Update the tool-bar item list for frame F. This has to be done
11469 before we start to fill in any display lines. Called from
11470 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
11471 and restore it here. */
11474 update_tool_bar (struct frame
*f
, int save_match_data
)
11476 #if defined (USE_GTK) || defined (HAVE_NS)
11477 int do_update
= FRAME_EXTERNAL_TOOL_BAR (f
);
11479 int do_update
= WINDOWP (f
->tool_bar_window
)
11480 && WINDOW_TOTAL_LINES (XWINDOW (f
->tool_bar_window
)) > 0;
11485 Lisp_Object window
;
11488 window
= FRAME_SELECTED_WINDOW (f
);
11489 w
= XWINDOW (window
);
11491 /* If the user has switched buffers or windows, we need to
11492 recompute to reflect the new bindings. But we'll
11493 recompute when update_mode_lines is set too; that means
11494 that people can use force-mode-line-update to request
11495 that the menu bar be recomputed. The adverse effect on
11496 the rest of the redisplay algorithm is about the same as
11497 windows_or_buffers_changed anyway. */
11498 if (windows_or_buffers_changed
11499 || w
->update_mode_line
11500 || update_mode_lines
11501 || window_buffer_changed (w
))
11503 struct buffer
*prev
= current_buffer
;
11504 ptrdiff_t count
= SPECPDL_INDEX ();
11505 Lisp_Object frame
, new_tool_bar
;
11506 int new_n_tool_bar
;
11507 struct gcpro gcpro1
;
11509 /* Set current_buffer to the buffer of the selected
11510 window of the frame, so that we get the right local
11512 set_buffer_internal_1 (XBUFFER (w
->contents
));
11514 /* Save match data, if we must. */
11515 if (save_match_data
)
11516 record_unwind_save_match_data ();
11518 /* Make sure that we don't accidentally use bogus keymaps. */
11519 if (NILP (Voverriding_local_map_menu_flag
))
11521 specbind (Qoverriding_terminal_local_map
, Qnil
);
11522 specbind (Qoverriding_local_map
, Qnil
);
11525 GCPRO1 (new_tool_bar
);
11527 /* We must temporarily set the selected frame to this frame
11528 before calling tool_bar_items, because the calculation of
11529 the tool-bar keymap uses the selected frame (see
11530 `tool-bar-make-keymap' in tool-bar.el). */
11531 eassert (EQ (selected_window
,
11532 /* Since we only explicitly preserve selected_frame,
11533 check that selected_window would be redundant. */
11534 XFRAME (selected_frame
)->selected_window
));
11535 record_unwind_protect (fast_set_selected_frame
, selected_frame
);
11536 XSETFRAME (frame
, f
);
11537 fast_set_selected_frame (frame
);
11539 /* Build desired tool-bar items from keymaps. */
11541 = tool_bar_items (Fcopy_sequence (f
->tool_bar_items
),
11544 /* Redisplay the tool-bar if we changed it. */
11545 if (new_n_tool_bar
!= f
->n_tool_bar_items
11546 || NILP (Fequal (new_tool_bar
, f
->tool_bar_items
)))
11548 /* Redisplay that happens asynchronously due to an expose event
11549 may access f->tool_bar_items. Make sure we update both
11550 variables within BLOCK_INPUT so no such event interrupts. */
11552 fset_tool_bar_items (f
, new_tool_bar
);
11553 f
->n_tool_bar_items
= new_n_tool_bar
;
11554 w
->update_mode_line
= 1;
11560 unbind_to (count
, Qnil
);
11561 set_buffer_internal_1 (prev
);
11566 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
11568 /* Set F->desired_tool_bar_string to a Lisp string representing frame
11569 F's desired tool-bar contents. F->tool_bar_items must have
11570 been set up previously by calling prepare_menu_bars. */
11573 build_desired_tool_bar_string (struct frame
*f
)
11575 int i
, size
, size_needed
;
11576 struct gcpro gcpro1
, gcpro2
, gcpro3
;
11577 Lisp_Object image
, plist
, props
;
11579 image
= plist
= props
= Qnil
;
11580 GCPRO3 (image
, plist
, props
);
11582 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
11583 Otherwise, make a new string. */
11585 /* The size of the string we might be able to reuse. */
11586 size
= (STRINGP (f
->desired_tool_bar_string
)
11587 ? SCHARS (f
->desired_tool_bar_string
)
11590 /* We need one space in the string for each image. */
11591 size_needed
= f
->n_tool_bar_items
;
11593 /* Reuse f->desired_tool_bar_string, if possible. */
11594 if (size
< size_needed
|| NILP (f
->desired_tool_bar_string
))
11595 fset_desired_tool_bar_string
11596 (f
, Fmake_string (make_number (size_needed
), make_number (' ')));
11599 props
= list4 (Qdisplay
, Qnil
, Qmenu_item
, Qnil
);
11600 Fremove_text_properties (make_number (0), make_number (size
),
11601 props
, f
->desired_tool_bar_string
);
11604 /* Put a `display' property on the string for the images to display,
11605 put a `menu_item' property on tool-bar items with a value that
11606 is the index of the item in F's tool-bar item vector. */
11607 for (i
= 0; i
< f
->n_tool_bar_items
; ++i
)
11609 #define PROP(IDX) \
11610 AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
11612 int enabled_p
= !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P
));
11613 int selected_p
= !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P
));
11614 int hmargin
, vmargin
, relief
, idx
, end
;
11616 /* If image is a vector, choose the image according to the
11618 image
= PROP (TOOL_BAR_ITEM_IMAGES
);
11619 if (VECTORP (image
))
11623 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
11624 : TOOL_BAR_IMAGE_ENABLED_DESELECTED
);
11627 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
11628 : TOOL_BAR_IMAGE_DISABLED_DESELECTED
);
11630 eassert (ASIZE (image
) >= idx
);
11631 image
= AREF (image
, idx
);
11636 /* Ignore invalid image specifications. */
11637 if (!valid_image_p (image
))
11640 /* Display the tool-bar button pressed, or depressed. */
11641 plist
= Fcopy_sequence (XCDR (image
));
11643 /* Compute margin and relief to draw. */
11644 relief
= (tool_bar_button_relief
>= 0
11645 ? tool_bar_button_relief
11646 : DEFAULT_TOOL_BAR_BUTTON_RELIEF
);
11647 hmargin
= vmargin
= relief
;
11649 if (RANGED_INTEGERP (1, Vtool_bar_button_margin
,
11650 INT_MAX
- max (hmargin
, vmargin
)))
11652 hmargin
+= XFASTINT (Vtool_bar_button_margin
);
11653 vmargin
+= XFASTINT (Vtool_bar_button_margin
);
11655 else if (CONSP (Vtool_bar_button_margin
))
11657 if (RANGED_INTEGERP (1, XCAR (Vtool_bar_button_margin
),
11658 INT_MAX
- hmargin
))
11659 hmargin
+= XFASTINT (XCAR (Vtool_bar_button_margin
));
11661 if (RANGED_INTEGERP (1, XCDR (Vtool_bar_button_margin
),
11662 INT_MAX
- vmargin
))
11663 vmargin
+= XFASTINT (XCDR (Vtool_bar_button_margin
));
11666 if (auto_raise_tool_bar_buttons_p
)
11668 /* Add a `:relief' property to the image spec if the item is
11672 plist
= Fplist_put (plist
, QCrelief
, make_number (-relief
));
11679 /* If image is selected, display it pressed, i.e. with a
11680 negative relief. If it's not selected, display it with a
11682 plist
= Fplist_put (plist
, QCrelief
,
11684 ? make_number (-relief
)
11685 : make_number (relief
)));
11690 /* Put a margin around the image. */
11691 if (hmargin
|| vmargin
)
11693 if (hmargin
== vmargin
)
11694 plist
= Fplist_put (plist
, QCmargin
, make_number (hmargin
));
11696 plist
= Fplist_put (plist
, QCmargin
,
11697 Fcons (make_number (hmargin
),
11698 make_number (vmargin
)));
11701 /* If button is not enabled, and we don't have special images
11702 for the disabled state, make the image appear disabled by
11703 applying an appropriate algorithm to it. */
11704 if (!enabled_p
&& idx
< 0)
11705 plist
= Fplist_put (plist
, QCconversion
, Qdisabled
);
11707 /* Put a `display' text property on the string for the image to
11708 display. Put a `menu-item' property on the string that gives
11709 the start of this item's properties in the tool-bar items
11711 image
= Fcons (Qimage
, plist
);
11712 props
= list4 (Qdisplay
, image
,
11713 Qmenu_item
, make_number (i
* TOOL_BAR_ITEM_NSLOTS
));
11715 /* Let the last image hide all remaining spaces in the tool bar
11716 string. The string can be longer than needed when we reuse a
11717 previous string. */
11718 if (i
+ 1 == f
->n_tool_bar_items
)
11719 end
= SCHARS (f
->desired_tool_bar_string
);
11722 Fadd_text_properties (make_number (i
), make_number (end
),
11723 props
, f
->desired_tool_bar_string
);
11731 /* Display one line of the tool-bar of frame IT->f.
11733 HEIGHT specifies the desired height of the tool-bar line.
11734 If the actual height of the glyph row is less than HEIGHT, the
11735 row's height is increased to HEIGHT, and the icons are centered
11736 vertically in the new height.
11738 If HEIGHT is -1, we are counting needed tool-bar lines, so don't
11739 count a final empty row in case the tool-bar width exactly matches
11744 display_tool_bar_line (struct it
*it
, int height
)
11746 struct glyph_row
*row
= it
->glyph_row
;
11747 int max_x
= it
->last_visible_x
;
11748 struct glyph
*last
;
11750 prepare_desired_row (row
);
11751 row
->y
= it
->current_y
;
11753 /* Note that this isn't made use of if the face hasn't a box,
11754 so there's no need to check the face here. */
11755 it
->start_of_box_run_p
= 1;
11757 while (it
->current_x
< max_x
)
11759 int x
, n_glyphs_before
, i
, nglyphs
;
11760 struct it it_before
;
11762 /* Get the next display element. */
11763 if (!get_next_display_element (it
))
11765 /* Don't count empty row if we are counting needed tool-bar lines. */
11766 if (height
< 0 && !it
->hpos
)
11771 /* Produce glyphs. */
11772 n_glyphs_before
= row
->used
[TEXT_AREA
];
11775 PRODUCE_GLYPHS (it
);
11777 nglyphs
= row
->used
[TEXT_AREA
] - n_glyphs_before
;
11779 x
= it_before
.current_x
;
11780 while (i
< nglyphs
)
11782 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
] + n_glyphs_before
+ i
;
11784 if (x
+ glyph
->pixel_width
> max_x
)
11786 /* Glyph doesn't fit on line. Backtrack. */
11787 row
->used
[TEXT_AREA
] = n_glyphs_before
;
11789 /* If this is the only glyph on this line, it will never fit on the
11790 tool-bar, so skip it. But ensure there is at least one glyph,
11791 so we don't accidentally disable the tool-bar. */
11792 if (n_glyphs_before
== 0
11793 && (it
->vpos
> 0 || IT_STRING_CHARPOS (*it
) < it
->end_charpos
-1))
11799 x
+= glyph
->pixel_width
;
11803 /* Stop at line end. */
11804 if (ITERATOR_AT_END_OF_LINE_P (it
))
11807 set_iterator_to_next (it
, 1);
11812 row
->displays_text_p
= row
->used
[TEXT_AREA
] != 0;
11814 /* Use default face for the border below the tool bar.
11816 FIXME: When auto-resize-tool-bars is grow-only, there is
11817 no additional border below the possibly empty tool-bar lines.
11818 So to make the extra empty lines look "normal", we have to
11819 use the tool-bar face for the border too. */
11820 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row
)
11821 && !EQ (Vauto_resize_tool_bars
, Qgrow_only
))
11822 it
->face_id
= DEFAULT_FACE_ID
;
11824 extend_face_to_end_of_line (it
);
11825 last
= row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
] - 1;
11826 last
->right_box_line_p
= 1;
11827 if (last
== row
->glyphs
[TEXT_AREA
])
11828 last
->left_box_line_p
= 1;
11830 /* Make line the desired height and center it vertically. */
11831 if ((height
-= it
->max_ascent
+ it
->max_descent
) > 0)
11833 /* Don't add more than one line height. */
11834 height
%= FRAME_LINE_HEIGHT (it
->f
);
11835 it
->max_ascent
+= height
/ 2;
11836 it
->max_descent
+= (height
+ 1) / 2;
11839 compute_line_metrics (it
);
11841 /* If line is empty, make it occupy the rest of the tool-bar. */
11842 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row
))
11844 row
->height
= row
->phys_height
= it
->last_visible_y
- row
->y
;
11845 row
->visible_height
= row
->height
;
11846 row
->ascent
= row
->phys_ascent
= 0;
11847 row
->extra_line_spacing
= 0;
11850 row
->full_width_p
= 1;
11851 row
->continued_p
= 0;
11852 row
->truncated_on_left_p
= 0;
11853 row
->truncated_on_right_p
= 0;
11855 it
->current_x
= it
->hpos
= 0;
11856 it
->current_y
+= row
->height
;
11862 /* Max tool-bar height. */
11864 #define MAX_FRAME_TOOL_BAR_HEIGHT(f) \
11865 ((FRAME_LINE_HEIGHT (f) * FRAME_LINES (f)))
11867 /* Value is the number of screen lines needed to make all tool-bar
11868 items of frame F visible. The number of actual rows needed is
11869 returned in *N_ROWS if non-NULL. */
11872 tool_bar_lines_needed (struct frame
*f
, int *n_rows
)
11874 struct window
*w
= XWINDOW (f
->tool_bar_window
);
11876 /* tool_bar_lines_needed is called from redisplay_tool_bar after building
11877 the desired matrix, so use (unused) mode-line row as temporary row to
11878 avoid destroying the first tool-bar row. */
11879 struct glyph_row
*temp_row
= MATRIX_MODE_LINE_ROW (w
->desired_matrix
);
11881 /* Initialize an iterator for iteration over
11882 F->desired_tool_bar_string in the tool-bar window of frame F. */
11883 init_iterator (&it
, w
, -1, -1, temp_row
, TOOL_BAR_FACE_ID
);
11884 it
.first_visible_x
= 0;
11885 it
.last_visible_x
= FRAME_TOTAL_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
11886 reseat_to_string (&it
, NULL
, f
->desired_tool_bar_string
, 0, 0, 0, -1);
11887 it
.paragraph_embedding
= L2R
;
11889 while (!ITERATOR_AT_END_P (&it
))
11891 clear_glyph_row (temp_row
);
11892 it
.glyph_row
= temp_row
;
11893 display_tool_bar_line (&it
, -1);
11895 clear_glyph_row (temp_row
);
11897 /* f->n_tool_bar_rows == 0 means "unknown"; -1 means no tool-bar. */
11899 *n_rows
= it
.vpos
> 0 ? it
.vpos
: -1;
11901 return (it
.current_y
+ FRAME_LINE_HEIGHT (f
) - 1) / FRAME_LINE_HEIGHT (f
);
11904 #endif /* !USE_GTK && !HAVE_NS */
11906 #if defined USE_GTK || defined HAVE_NS
11907 EXFUN (Ftool_bar_lines_needed
, 1) ATTRIBUTE_CONST
;
11910 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed
, Stool_bar_lines_needed
,
11912 doc
: /* Return the number of lines occupied by the tool bar of FRAME.
11913 If FRAME is nil or omitted, use the selected frame. */)
11914 (Lisp_Object frame
)
11917 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
11918 struct frame
*f
= decode_any_frame (frame
);
11921 if (WINDOWP (f
->tool_bar_window
)
11922 && (w
= XWINDOW (f
->tool_bar_window
),
11923 WINDOW_TOTAL_LINES (w
) > 0))
11925 update_tool_bar (f
, 1);
11926 if (f
->n_tool_bar_items
)
11928 build_desired_tool_bar_string (f
);
11929 nlines
= tool_bar_lines_needed (f
, NULL
);
11933 return make_number (nlines
);
11937 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
11938 height should be changed. */
11941 redisplay_tool_bar (struct frame
*f
)
11943 #if defined (USE_GTK) || defined (HAVE_NS)
11945 if (FRAME_EXTERNAL_TOOL_BAR (f
))
11946 update_frame_tool_bar (f
);
11949 #else /* !USE_GTK && !HAVE_NS */
11953 struct glyph_row
*row
;
11955 /* If frame hasn't a tool-bar window or if it is zero-height, don't
11956 do anything. This means you must start with tool-bar-lines
11957 non-zero to get the auto-sizing effect. Or in other words, you
11958 can turn off tool-bars by specifying tool-bar-lines zero. */
11959 if (!WINDOWP (f
->tool_bar_window
)
11960 || (w
= XWINDOW (f
->tool_bar_window
),
11961 WINDOW_TOTAL_LINES (w
) == 0))
11964 /* Set up an iterator for the tool-bar window. */
11965 init_iterator (&it
, w
, -1, -1, w
->desired_matrix
->rows
, TOOL_BAR_FACE_ID
);
11966 it
.first_visible_x
= 0;
11967 it
.last_visible_x
= FRAME_TOTAL_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
11968 row
= it
.glyph_row
;
11970 /* Build a string that represents the contents of the tool-bar. */
11971 build_desired_tool_bar_string (f
);
11972 reseat_to_string (&it
, NULL
, f
->desired_tool_bar_string
, 0, 0, 0, -1);
11973 /* FIXME: This should be controlled by a user option. But it
11974 doesn't make sense to have an R2L tool bar if the menu bar cannot
11975 be drawn also R2L, and making the menu bar R2L is tricky due
11976 toolkit-specific code that implements it. If an R2L tool bar is
11977 ever supported, display_tool_bar_line should also be augmented to
11978 call unproduce_glyphs like display_line and display_string
11980 it
.paragraph_embedding
= L2R
;
11982 if (f
->n_tool_bar_rows
== 0)
11986 if ((nlines
= tool_bar_lines_needed (f
, &f
->n_tool_bar_rows
),
11987 nlines
!= WINDOW_TOTAL_LINES (w
)))
11990 int old_height
= WINDOW_TOTAL_LINES (w
);
11992 XSETFRAME (frame
, f
);
11993 Fmodify_frame_parameters (frame
,
11994 list1 (Fcons (Qtool_bar_lines
,
11995 make_number (nlines
))));
11996 if (WINDOW_TOTAL_LINES (w
) != old_height
)
11998 clear_glyph_matrix (w
->desired_matrix
);
11999 f
->fonts_changed
= 1;
12005 /* Display as many lines as needed to display all tool-bar items. */
12007 if (f
->n_tool_bar_rows
> 0)
12009 int border
, rows
, height
, extra
;
12011 if (TYPE_RANGED_INTEGERP (int, Vtool_bar_border
))
12012 border
= XINT (Vtool_bar_border
);
12013 else if (EQ (Vtool_bar_border
, Qinternal_border_width
))
12014 border
= FRAME_INTERNAL_BORDER_WIDTH (f
);
12015 else if (EQ (Vtool_bar_border
, Qborder_width
))
12016 border
= f
->border_width
;
12022 rows
= f
->n_tool_bar_rows
;
12023 height
= max (1, (it
.last_visible_y
- border
) / rows
);
12024 extra
= it
.last_visible_y
- border
- height
* rows
;
12026 while (it
.current_y
< it
.last_visible_y
)
12029 if (extra
> 0 && rows
-- > 0)
12031 h
= (extra
+ rows
- 1) / rows
;
12034 display_tool_bar_line (&it
, height
+ h
);
12039 while (it
.current_y
< it
.last_visible_y
)
12040 display_tool_bar_line (&it
, 0);
12043 /* It doesn't make much sense to try scrolling in the tool-bar
12044 window, so don't do it. */
12045 w
->desired_matrix
->no_scrolling_p
= 1;
12046 w
->must_be_updated_p
= 1;
12048 if (!NILP (Vauto_resize_tool_bars
))
12050 int max_tool_bar_height
= MAX_FRAME_TOOL_BAR_HEIGHT (f
);
12051 int change_height_p
= 0;
12053 /* If we couldn't display everything, change the tool-bar's
12054 height if there is room for more. */
12055 if (IT_STRING_CHARPOS (it
) < it
.end_charpos
12056 && it
.current_y
< max_tool_bar_height
)
12057 change_height_p
= 1;
12059 row
= it
.glyph_row
- 1;
12061 /* If there are blank lines at the end, except for a partially
12062 visible blank line at the end that is smaller than
12063 FRAME_LINE_HEIGHT, change the tool-bar's height. */
12064 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row
)
12065 && row
->height
>= FRAME_LINE_HEIGHT (f
))
12066 change_height_p
= 1;
12068 /* If row displays tool-bar items, but is partially visible,
12069 change the tool-bar's height. */
12070 if (MATRIX_ROW_DISPLAYS_TEXT_P (row
)
12071 && MATRIX_ROW_BOTTOM_Y (row
) > it
.last_visible_y
12072 && MATRIX_ROW_BOTTOM_Y (row
) < max_tool_bar_height
)
12073 change_height_p
= 1;
12075 /* Resize windows as needed by changing the `tool-bar-lines'
12076 frame parameter. */
12077 if (change_height_p
)
12080 int old_height
= WINDOW_TOTAL_LINES (w
);
12082 int nlines
= tool_bar_lines_needed (f
, &nrows
);
12084 change_height_p
= ((EQ (Vauto_resize_tool_bars
, Qgrow_only
)
12085 && !f
->minimize_tool_bar_window_p
)
12086 ? (nlines
> old_height
)
12087 : (nlines
!= old_height
));
12088 f
->minimize_tool_bar_window_p
= 0;
12090 if (change_height_p
)
12092 XSETFRAME (frame
, f
);
12093 Fmodify_frame_parameters (frame
,
12094 list1 (Fcons (Qtool_bar_lines
,
12095 make_number (nlines
))));
12096 if (WINDOW_TOTAL_LINES (w
) != old_height
)
12098 clear_glyph_matrix (w
->desired_matrix
);
12099 f
->n_tool_bar_rows
= nrows
;
12100 f
->fonts_changed
= 1;
12107 f
->minimize_tool_bar_window_p
= 0;
12110 #endif /* USE_GTK || HAVE_NS */
12113 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
12115 /* Get information about the tool-bar item which is displayed in GLYPH
12116 on frame F. Return in *PROP_IDX the index where tool-bar item
12117 properties start in F->tool_bar_items. Value is zero if
12118 GLYPH doesn't display a tool-bar item. */
12121 tool_bar_item_info (struct frame
*f
, struct glyph
*glyph
, int *prop_idx
)
12127 /* This function can be called asynchronously, which means we must
12128 exclude any possibility that Fget_text_property signals an
12130 charpos
= min (SCHARS (f
->current_tool_bar_string
), glyph
->charpos
);
12131 charpos
= max (0, charpos
);
12133 /* Get the text property `menu-item' at pos. The value of that
12134 property is the start index of this item's properties in
12135 F->tool_bar_items. */
12136 prop
= Fget_text_property (make_number (charpos
),
12137 Qmenu_item
, f
->current_tool_bar_string
);
12138 if (INTEGERP (prop
))
12140 *prop_idx
= XINT (prop
);
12150 /* Get information about the tool-bar item at position X/Y on frame F.
12151 Return in *GLYPH a pointer to the glyph of the tool-bar item in
12152 the current matrix of the tool-bar window of F, or NULL if not
12153 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
12154 item in F->tool_bar_items. Value is
12156 -1 if X/Y is not on a tool-bar item
12157 0 if X/Y is on the same item that was highlighted before.
12161 get_tool_bar_item (struct frame
*f
, int x
, int y
, struct glyph
**glyph
,
12162 int *hpos
, int *vpos
, int *prop_idx
)
12164 Mouse_HLInfo
*hlinfo
= MOUSE_HL_INFO (f
);
12165 struct window
*w
= XWINDOW (f
->tool_bar_window
);
12168 /* Find the glyph under X/Y. */
12169 *glyph
= x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, 0, 0, &area
);
12170 if (*glyph
== NULL
)
12173 /* Get the start of this tool-bar item's properties in
12174 f->tool_bar_items. */
12175 if (!tool_bar_item_info (f
, *glyph
, prop_idx
))
12178 /* Is mouse on the highlighted item? */
12179 if (EQ (f
->tool_bar_window
, hlinfo
->mouse_face_window
)
12180 && *vpos
>= hlinfo
->mouse_face_beg_row
12181 && *vpos
<= hlinfo
->mouse_face_end_row
12182 && (*vpos
> hlinfo
->mouse_face_beg_row
12183 || *hpos
>= hlinfo
->mouse_face_beg_col
)
12184 && (*vpos
< hlinfo
->mouse_face_end_row
12185 || *hpos
< hlinfo
->mouse_face_end_col
12186 || hlinfo
->mouse_face_past_end
))
12194 Handle mouse button event on the tool-bar of frame F, at
12195 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
12196 0 for button release. MODIFIERS is event modifiers for button
12200 handle_tool_bar_click (struct frame
*f
, int x
, int y
, int down_p
,
12203 Mouse_HLInfo
*hlinfo
= MOUSE_HL_INFO (f
);
12204 struct window
*w
= XWINDOW (f
->tool_bar_window
);
12205 int hpos
, vpos
, prop_idx
;
12206 struct glyph
*glyph
;
12207 Lisp_Object enabled_p
;
12210 /* If not on the highlighted tool-bar item, and mouse-highlight is
12211 non-nil, return. This is so we generate the tool-bar button
12212 click only when the mouse button is released on the same item as
12213 where it was pressed. However, when mouse-highlight is disabled,
12214 generate the click when the button is released regardless of the
12215 highlight, since tool-bar items are not highlighted in that
12217 frame_to_window_pixel_xy (w
, &x
, &y
);
12218 ts
= get_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
);
12220 || (ts
!= 0 && !NILP (Vmouse_highlight
)))
12223 /* When mouse-highlight is off, generate the click for the item
12224 where the button was pressed, disregarding where it was
12226 if (NILP (Vmouse_highlight
) && !down_p
)
12227 prop_idx
= last_tool_bar_item
;
12229 /* If item is disabled, do nothing. */
12230 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
12231 if (NILP (enabled_p
))
12236 /* Show item in pressed state. */
12237 if (!NILP (Vmouse_highlight
))
12238 show_mouse_face (hlinfo
, DRAW_IMAGE_SUNKEN
);
12239 last_tool_bar_item
= prop_idx
;
12243 Lisp_Object key
, frame
;
12244 struct input_event event
;
12245 EVENT_INIT (event
);
12247 /* Show item in released state. */
12248 if (!NILP (Vmouse_highlight
))
12249 show_mouse_face (hlinfo
, DRAW_IMAGE_RAISED
);
12251 key
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_KEY
);
12253 XSETFRAME (frame
, f
);
12254 event
.kind
= TOOL_BAR_EVENT
;
12255 event
.frame_or_window
= frame
;
12257 kbd_buffer_store_event (&event
);
12259 event
.kind
= TOOL_BAR_EVENT
;
12260 event
.frame_or_window
= frame
;
12262 event
.modifiers
= modifiers
;
12263 kbd_buffer_store_event (&event
);
12264 last_tool_bar_item
= -1;
12269 /* Possibly highlight a tool-bar item on frame F when mouse moves to
12270 tool-bar window-relative coordinates X/Y. Called from
12271 note_mouse_highlight. */
12274 note_tool_bar_highlight (struct frame
*f
, int x
, int y
)
12276 Lisp_Object window
= f
->tool_bar_window
;
12277 struct window
*w
= XWINDOW (window
);
12278 Display_Info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
12279 Mouse_HLInfo
*hlinfo
= MOUSE_HL_INFO (f
);
12281 struct glyph
*glyph
;
12282 struct glyph_row
*row
;
12284 Lisp_Object enabled_p
;
12286 enum draw_glyphs_face draw
= DRAW_IMAGE_RAISED
;
12287 int mouse_down_p
, rc
;
12289 /* Function note_mouse_highlight is called with negative X/Y
12290 values when mouse moves outside of the frame. */
12291 if (x
<= 0 || y
<= 0)
12293 clear_mouse_face (hlinfo
);
12297 rc
= get_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
);
12300 /* Not on tool-bar item. */
12301 clear_mouse_face (hlinfo
);
12305 /* On same tool-bar item as before. */
12306 goto set_help_echo
;
12308 clear_mouse_face (hlinfo
);
12310 /* Mouse is down, but on different tool-bar item? */
12311 mouse_down_p
= (dpyinfo
->grabbed
12312 && f
== last_mouse_frame
12313 && FRAME_LIVE_P (f
));
12315 && last_tool_bar_item
!= prop_idx
)
12318 draw
= mouse_down_p
? DRAW_IMAGE_SUNKEN
: DRAW_IMAGE_RAISED
;
12320 /* If tool-bar item is not enabled, don't highlight it. */
12321 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
12322 if (!NILP (enabled_p
) && !NILP (Vmouse_highlight
))
12324 /* Compute the x-position of the glyph. In front and past the
12325 image is a space. We include this in the highlighted area. */
12326 row
= MATRIX_ROW (w
->current_matrix
, vpos
);
12327 for (i
= x
= 0; i
< hpos
; ++i
)
12328 x
+= row
->glyphs
[TEXT_AREA
][i
].pixel_width
;
12330 /* Record this as the current active region. */
12331 hlinfo
->mouse_face_beg_col
= hpos
;
12332 hlinfo
->mouse_face_beg_row
= vpos
;
12333 hlinfo
->mouse_face_beg_x
= x
;
12334 hlinfo
->mouse_face_past_end
= 0;
12336 hlinfo
->mouse_face_end_col
= hpos
+ 1;
12337 hlinfo
->mouse_face_end_row
= vpos
;
12338 hlinfo
->mouse_face_end_x
= x
+ glyph
->pixel_width
;
12339 hlinfo
->mouse_face_window
= window
;
12340 hlinfo
->mouse_face_face_id
= TOOL_BAR_FACE_ID
;
12342 /* Display it as active. */
12343 show_mouse_face (hlinfo
, draw
);
12348 /* Set help_echo_string to a help string to display for this tool-bar item.
12349 XTread_socket does the rest. */
12350 help_echo_object
= help_echo_window
= Qnil
;
12351 help_echo_pos
= -1;
12352 help_echo_string
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_HELP
);
12353 if (NILP (help_echo_string
))
12354 help_echo_string
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_CAPTION
);
12357 #endif /* !USE_GTK && !HAVE_NS */
12359 #endif /* HAVE_WINDOW_SYSTEM */
12363 /************************************************************************
12364 Horizontal scrolling
12365 ************************************************************************/
12367 static int hscroll_window_tree (Lisp_Object
);
12368 static int hscroll_windows (Lisp_Object
);
12370 /* For all leaf windows in the window tree rooted at WINDOW, set their
12371 hscroll value so that PT is (i) visible in the window, and (ii) so
12372 that it is not within a certain margin at the window's left and
12373 right border. Value is non-zero if any window's hscroll has been
12377 hscroll_window_tree (Lisp_Object window
)
12379 int hscrolled_p
= 0;
12380 int hscroll_relative_p
= FLOATP (Vhscroll_step
);
12381 int hscroll_step_abs
= 0;
12382 double hscroll_step_rel
= 0;
12384 if (hscroll_relative_p
)
12386 hscroll_step_rel
= XFLOAT_DATA (Vhscroll_step
);
12387 if (hscroll_step_rel
< 0)
12389 hscroll_relative_p
= 0;
12390 hscroll_step_abs
= 0;
12393 else if (TYPE_RANGED_INTEGERP (int, Vhscroll_step
))
12395 hscroll_step_abs
= XINT (Vhscroll_step
);
12396 if (hscroll_step_abs
< 0)
12397 hscroll_step_abs
= 0;
12400 hscroll_step_abs
= 0;
12402 while (WINDOWP (window
))
12404 struct window
*w
= XWINDOW (window
);
12406 if (WINDOWP (w
->contents
))
12407 hscrolled_p
|= hscroll_window_tree (w
->contents
);
12408 else if (w
->cursor
.vpos
>= 0)
12411 int text_area_width
;
12412 struct glyph_row
*current_cursor_row
12413 = MATRIX_ROW (w
->current_matrix
, w
->cursor
.vpos
);
12414 struct glyph_row
*desired_cursor_row
12415 = MATRIX_ROW (w
->desired_matrix
, w
->cursor
.vpos
);
12416 struct glyph_row
*cursor_row
12417 = (desired_cursor_row
->enabled_p
12418 ? desired_cursor_row
12419 : current_cursor_row
);
12420 int row_r2l_p
= cursor_row
->reversed_p
;
12422 text_area_width
= window_box_width (w
, TEXT_AREA
);
12424 /* Scroll when cursor is inside this scroll margin. */
12425 h_margin
= hscroll_margin
* WINDOW_FRAME_COLUMN_WIDTH (w
);
12427 if (!NILP (Fbuffer_local_value (Qauto_hscroll_mode
, w
->contents
))
12428 /* For left-to-right rows, hscroll when cursor is either
12429 (i) inside the right hscroll margin, or (ii) if it is
12430 inside the left margin and the window is already
12434 && w
->cursor
.x
<= h_margin
)
12435 || (cursor_row
->enabled_p
12436 && cursor_row
->truncated_on_right_p
12437 && (w
->cursor
.x
>= text_area_width
- h_margin
))))
12438 /* For right-to-left rows, the logic is similar,
12439 except that rules for scrolling to left and right
12440 are reversed. E.g., if cursor.x <= h_margin, we
12441 need to hscroll "to the right" unconditionally,
12442 and that will scroll the screen to the left so as
12443 to reveal the next portion of the row. */
12445 && ((cursor_row
->enabled_p
12446 /* FIXME: It is confusing to set the
12447 truncated_on_right_p flag when R2L rows
12448 are actually truncated on the left. */
12449 && cursor_row
->truncated_on_right_p
12450 && w
->cursor
.x
<= h_margin
)
12452 && (w
->cursor
.x
>= text_area_width
- h_margin
))))))
12456 struct buffer
*saved_current_buffer
;
12460 /* Find point in a display of infinite width. */
12461 saved_current_buffer
= current_buffer
;
12462 current_buffer
= XBUFFER (w
->contents
);
12464 if (w
== XWINDOW (selected_window
))
12467 pt
= clip_to_bounds (BEGV
, marker_position (w
->pointm
), ZV
);
12469 /* Move iterator to pt starting at cursor_row->start in
12470 a line with infinite width. */
12471 init_to_row_start (&it
, w
, cursor_row
);
12472 it
.last_visible_x
= INFINITY
;
12473 move_it_in_display_line_to (&it
, pt
, -1, MOVE_TO_POS
);
12474 current_buffer
= saved_current_buffer
;
12476 /* Position cursor in window. */
12477 if (!hscroll_relative_p
&& hscroll_step_abs
== 0)
12478 hscroll
= max (0, (it
.current_x
12479 - (ITERATOR_AT_END_OF_LINE_P (&it
)
12480 ? (text_area_width
- 4 * FRAME_COLUMN_WIDTH (it
.f
))
12481 : (text_area_width
/ 2))))
12482 / FRAME_COLUMN_WIDTH (it
.f
);
12483 else if ((!row_r2l_p
12484 && w
->cursor
.x
>= text_area_width
- h_margin
)
12485 || (row_r2l_p
&& w
->cursor
.x
<= h_margin
))
12487 if (hscroll_relative_p
)
12488 wanted_x
= text_area_width
* (1 - hscroll_step_rel
)
12491 wanted_x
= text_area_width
12492 - hscroll_step_abs
* FRAME_COLUMN_WIDTH (it
.f
)
12495 = max (0, it
.current_x
- wanted_x
) / FRAME_COLUMN_WIDTH (it
.f
);
12499 if (hscroll_relative_p
)
12500 wanted_x
= text_area_width
* hscroll_step_rel
12503 wanted_x
= hscroll_step_abs
* FRAME_COLUMN_WIDTH (it
.f
)
12506 = max (0, it
.current_x
- wanted_x
) / FRAME_COLUMN_WIDTH (it
.f
);
12508 hscroll
= max (hscroll
, w
->min_hscroll
);
12510 /* Don't prevent redisplay optimizations if hscroll
12511 hasn't changed, as it will unnecessarily slow down
12513 if (w
->hscroll
!= hscroll
)
12515 XBUFFER (w
->contents
)->prevent_redisplay_optimizations_p
= 1;
12516 w
->hscroll
= hscroll
;
12525 /* Value is non-zero if hscroll of any leaf window has been changed. */
12526 return hscrolled_p
;
12530 /* Set hscroll so that cursor is visible and not inside horizontal
12531 scroll margins for all windows in the tree rooted at WINDOW. See
12532 also hscroll_window_tree above. Value is non-zero if any window's
12533 hscroll has been changed. If it has, desired matrices on the frame
12534 of WINDOW are cleared. */
12537 hscroll_windows (Lisp_Object window
)
12539 int hscrolled_p
= hscroll_window_tree (window
);
12541 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window
))));
12542 return hscrolled_p
;
12547 /************************************************************************
12549 ************************************************************************/
12551 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
12552 to a non-zero value. This is sometimes handy to have in a debugger
12557 /* First and last unchanged row for try_window_id. */
12559 static int debug_first_unchanged_at_end_vpos
;
12560 static int debug_last_unchanged_at_beg_vpos
;
12562 /* Delta vpos and y. */
12564 static int debug_dvpos
, debug_dy
;
12566 /* Delta in characters and bytes for try_window_id. */
12568 static ptrdiff_t debug_delta
, debug_delta_bytes
;
12570 /* Values of window_end_pos and window_end_vpos at the end of
12573 static ptrdiff_t debug_end_vpos
;
12575 /* Append a string to W->desired_matrix->method. FMT is a printf
12576 format string. If trace_redisplay_p is non-zero also printf the
12577 resulting string to stderr. */
12579 static void debug_method_add (struct window
*, char const *, ...)
12580 ATTRIBUTE_FORMAT_PRINTF (2, 3);
12583 debug_method_add (struct window
*w
, char const *fmt
, ...)
12586 char *method
= w
->desired_matrix
->method
;
12587 int len
= strlen (method
);
12588 int size
= sizeof w
->desired_matrix
->method
;
12589 int remaining
= size
- len
- 1;
12592 if (len
&& remaining
)
12595 --remaining
, ++len
;
12598 va_start (ap
, fmt
);
12599 vsnprintf (method
+ len
, remaining
+ 1, fmt
, ap
);
12602 if (trace_redisplay_p
)
12603 fprintf (stderr
, "%p (%s): %s\n",
12605 ((BUFFERP (w
->contents
)
12606 && STRINGP (BVAR (XBUFFER (w
->contents
), name
)))
12607 ? SSDATA (BVAR (XBUFFER (w
->contents
), name
))
12612 #endif /* GLYPH_DEBUG */
12615 /* Value is non-zero if all changes in window W, which displays
12616 current_buffer, are in the text between START and END. START is a
12617 buffer position, END is given as a distance from Z. Used in
12618 redisplay_internal for display optimization. */
12621 text_outside_line_unchanged_p (struct window
*w
,
12622 ptrdiff_t start
, ptrdiff_t end
)
12624 int unchanged_p
= 1;
12626 /* If text or overlays have changed, see where. */
12627 if (window_outdated (w
))
12629 /* Gap in the line? */
12630 if (GPT
< start
|| Z
- GPT
< end
)
12633 /* Changes start in front of the line, or end after it? */
12635 && (BEG_UNCHANGED
< start
- 1
12636 || END_UNCHANGED
< end
))
12639 /* If selective display, can't optimize if changes start at the
12640 beginning of the line. */
12642 && INTEGERP (BVAR (current_buffer
, selective_display
))
12643 && XINT (BVAR (current_buffer
, selective_display
)) > 0
12644 && (BEG_UNCHANGED
< start
|| GPT
<= start
))
12647 /* If there are overlays at the start or end of the line, these
12648 may have overlay strings with newlines in them. A change at
12649 START, for instance, may actually concern the display of such
12650 overlay strings as well, and they are displayed on different
12651 lines. So, quickly rule out this case. (For the future, it
12652 might be desirable to implement something more telling than
12653 just BEG/END_UNCHANGED.) */
12656 if (BEG
+ BEG_UNCHANGED
== start
12657 && overlay_touches_p (start
))
12659 if (END_UNCHANGED
== end
12660 && overlay_touches_p (Z
- end
))
12664 /* Under bidi reordering, adding or deleting a character in the
12665 beginning of a paragraph, before the first strong directional
12666 character, can change the base direction of the paragraph (unless
12667 the buffer specifies a fixed paragraph direction), which will
12668 require to redisplay the whole paragraph. It might be worthwhile
12669 to find the paragraph limits and widen the range of redisplayed
12670 lines to that, but for now just give up this optimization. */
12671 if (!NILP (BVAR (XBUFFER (w
->contents
), bidi_display_reordering
))
12672 && NILP (BVAR (XBUFFER (w
->contents
), bidi_paragraph_direction
)))
12676 return unchanged_p
;
12680 /* Do a frame update, taking possible shortcuts into account. This is
12681 the main external entry point for redisplay.
12683 If the last redisplay displayed an echo area message and that message
12684 is no longer requested, we clear the echo area or bring back the
12685 mini-buffer if that is in use. */
12690 redisplay_internal ();
12695 overlay_arrow_string_or_property (Lisp_Object var
)
12699 if (val
= Fget (var
, Qoverlay_arrow_string
), STRINGP (val
))
12702 return Voverlay_arrow_string
;
12705 /* Return 1 if there are any overlay-arrows in current_buffer. */
12707 overlay_arrow_in_current_buffer_p (void)
12711 for (vlist
= Voverlay_arrow_variable_list
;
12713 vlist
= XCDR (vlist
))
12715 Lisp_Object var
= XCAR (vlist
);
12718 if (!SYMBOLP (var
))
12720 val
= find_symbol_value (var
);
12722 && current_buffer
== XMARKER (val
)->buffer
)
12729 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
12733 overlay_arrows_changed_p (void)
12737 for (vlist
= Voverlay_arrow_variable_list
;
12739 vlist
= XCDR (vlist
))
12741 Lisp_Object var
= XCAR (vlist
);
12742 Lisp_Object val
, pstr
;
12744 if (!SYMBOLP (var
))
12746 val
= find_symbol_value (var
);
12747 if (!MARKERP (val
))
12749 if (! EQ (COERCE_MARKER (val
),
12750 Fget (var
, Qlast_arrow_position
))
12751 || ! (pstr
= overlay_arrow_string_or_property (var
),
12752 EQ (pstr
, Fget (var
, Qlast_arrow_string
))))
12758 /* Mark overlay arrows to be updated on next redisplay. */
12761 update_overlay_arrows (int up_to_date
)
12765 for (vlist
= Voverlay_arrow_variable_list
;
12767 vlist
= XCDR (vlist
))
12769 Lisp_Object var
= XCAR (vlist
);
12771 if (!SYMBOLP (var
))
12774 if (up_to_date
> 0)
12776 Lisp_Object val
= find_symbol_value (var
);
12777 Fput (var
, Qlast_arrow_position
,
12778 COERCE_MARKER (val
));
12779 Fput (var
, Qlast_arrow_string
,
12780 overlay_arrow_string_or_property (var
));
12782 else if (up_to_date
< 0
12783 || !NILP (Fget (var
, Qlast_arrow_position
)))
12785 Fput (var
, Qlast_arrow_position
, Qt
);
12786 Fput (var
, Qlast_arrow_string
, Qt
);
12792 /* Return overlay arrow string to display at row.
12793 Return integer (bitmap number) for arrow bitmap in left fringe.
12794 Return nil if no overlay arrow. */
12797 overlay_arrow_at_row (struct it
*it
, struct glyph_row
*row
)
12801 for (vlist
= Voverlay_arrow_variable_list
;
12803 vlist
= XCDR (vlist
))
12805 Lisp_Object var
= XCAR (vlist
);
12808 if (!SYMBOLP (var
))
12811 val
= find_symbol_value (var
);
12814 && current_buffer
== XMARKER (val
)->buffer
12815 && (MATRIX_ROW_START_CHARPOS (row
) == marker_position (val
)))
12817 if (FRAME_WINDOW_P (it
->f
)
12818 /* FIXME: if ROW->reversed_p is set, this should test
12819 the right fringe, not the left one. */
12820 && WINDOW_LEFT_FRINGE_WIDTH (it
->w
) > 0)
12822 #ifdef HAVE_WINDOW_SYSTEM
12823 if (val
= Fget (var
, Qoverlay_arrow_bitmap
), SYMBOLP (val
))
12826 if ((fringe_bitmap
= lookup_fringe_bitmap (val
)) != 0)
12827 return make_number (fringe_bitmap
);
12830 return make_number (-1); /* Use default arrow bitmap. */
12832 return overlay_arrow_string_or_property (var
);
12839 /* Return 1 if point moved out of or into a composition. Otherwise
12840 return 0. PREV_BUF and PREV_PT are the last point buffer and
12841 position. BUF and PT are the current point buffer and position. */
12844 check_point_in_composition (struct buffer
*prev_buf
, ptrdiff_t prev_pt
,
12845 struct buffer
*buf
, ptrdiff_t pt
)
12847 ptrdiff_t start
, end
;
12849 Lisp_Object buffer
;
12851 XSETBUFFER (buffer
, buf
);
12852 /* Check a composition at the last point if point moved within the
12854 if (prev_buf
== buf
)
12857 /* Point didn't move. */
12860 if (prev_pt
> BUF_BEGV (buf
) && prev_pt
< BUF_ZV (buf
)
12861 && find_composition (prev_pt
, -1, &start
, &end
, &prop
, buffer
)
12862 && composition_valid_p (start
, end
, prop
)
12863 && start
< prev_pt
&& end
> prev_pt
)
12864 /* The last point was within the composition. Return 1 iff
12865 point moved out of the composition. */
12866 return (pt
<= start
|| pt
>= end
);
12869 /* Check a composition at the current point. */
12870 return (pt
> BUF_BEGV (buf
) && pt
< BUF_ZV (buf
)
12871 && find_composition (pt
, -1, &start
, &end
, &prop
, buffer
)
12872 && composition_valid_p (start
, end
, prop
)
12873 && start
< pt
&& end
> pt
);
12876 /* Reconsider the clip changes of buffer which is displayed in W. */
12879 reconsider_clip_changes (struct window
*w
)
12881 struct buffer
*b
= XBUFFER (w
->contents
);
12883 if (b
->clip_changed
12884 && w
->window_end_valid
12885 && w
->current_matrix
->buffer
== b
12886 && w
->current_matrix
->zv
== BUF_ZV (b
)
12887 && w
->current_matrix
->begv
== BUF_BEGV (b
))
12888 b
->clip_changed
= 0;
12890 /* If display wasn't paused, and W is not a tool bar window, see if
12891 point has been moved into or out of a composition. In that case,
12892 we set b->clip_changed to 1 to force updating the screen. If
12893 b->clip_changed has already been set to 1, we can skip this
12895 if (!b
->clip_changed
&& w
->window_end_valid
)
12897 ptrdiff_t pt
= (w
== XWINDOW (selected_window
)
12898 ? PT
: marker_position (w
->pointm
));
12900 if ((w
->current_matrix
->buffer
!= b
|| pt
!= w
->last_point
)
12901 && check_point_in_composition (w
->current_matrix
->buffer
,
12902 w
->last_point
, b
, pt
))
12903 b
->clip_changed
= 1;
12907 #define STOP_POLLING \
12908 do { if (! polling_stopped_here) stop_polling (); \
12909 polling_stopped_here = 1; } while (0)
12911 #define RESUME_POLLING \
12912 do { if (polling_stopped_here) start_polling (); \
12913 polling_stopped_here = 0; } while (0)
12916 /* Perhaps in the future avoid recentering windows if it
12917 is not necessary; currently that causes some problems. */
12920 redisplay_internal (void)
12922 struct window
*w
= XWINDOW (selected_window
);
12926 bool must_finish
= 0, match_p
;
12927 struct text_pos tlbufpos
, tlendpos
;
12928 int number_of_visible_frames
;
12931 int polling_stopped_here
= 0;
12932 Lisp_Object tail
, frame
;
12934 /* Non-zero means redisplay has to consider all windows on all
12935 frames. Zero means, only selected_window is considered. */
12936 int consider_all_windows_p
;
12938 /* Non-zero means redisplay has to redisplay the miniwindow. */
12939 int update_miniwindow_p
= 0;
12941 TRACE ((stderr
, "redisplay_internal %d\n", redisplaying_p
));
12943 /* No redisplay if running in batch mode or frame is not yet fully
12944 initialized, or redisplay is explicitly turned off by setting
12945 Vinhibit_redisplay. */
12946 if (FRAME_INITIAL_P (SELECTED_FRAME ())
12947 || !NILP (Vinhibit_redisplay
))
12950 /* Don't examine these until after testing Vinhibit_redisplay.
12951 When Emacs is shutting down, perhaps because its connection to
12952 X has dropped, we should not look at them at all. */
12953 fr
= XFRAME (w
->frame
);
12954 sf
= SELECTED_FRAME ();
12956 if (!fr
->glyphs_initialized_p
)
12959 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS)
12960 if (popup_activated ())
12964 /* I don't think this happens but let's be paranoid. */
12965 if (redisplaying_p
)
12968 /* Record a function that clears redisplaying_p
12969 when we leave this function. */
12970 count
= SPECPDL_INDEX ();
12971 record_unwind_protect_void (unwind_redisplay
);
12972 redisplaying_p
= 1;
12973 specbind (Qinhibit_free_realized_faces
, Qnil
);
12975 /* Record this function, so it appears on the profiler's backtraces. */
12976 record_in_backtrace (Qredisplay_internal
, &Qnil
, 0);
12978 FOR_EACH_FRAME (tail
, frame
)
12979 XFRAME (frame
)->already_hscrolled_p
= 0;
12982 /* Remember the currently selected window. */
12986 last_escape_glyph_frame
= NULL
;
12987 last_escape_glyph_face_id
= (1 << FACE_ID_BITS
);
12988 last_glyphless_glyph_frame
= NULL
;
12989 last_glyphless_glyph_face_id
= (1 << FACE_ID_BITS
);
12991 /* If face_change_count is non-zero, init_iterator will free all
12992 realized faces, which includes the faces referenced from current
12993 matrices. So, we can't reuse current matrices in this case. */
12994 if (face_change_count
)
12995 ++windows_or_buffers_changed
;
12997 if ((FRAME_TERMCAP_P (sf
) || FRAME_MSDOS_P (sf
))
12998 && FRAME_TTY (sf
)->previous_frame
!= sf
)
13000 /* Since frames on a single ASCII terminal share the same
13001 display area, displaying a different frame means redisplay
13002 the whole thing. */
13003 windows_or_buffers_changed
++;
13004 SET_FRAME_GARBAGED (sf
);
13006 set_tty_color_mode (FRAME_TTY (sf
), sf
);
13008 FRAME_TTY (sf
)->previous_frame
= sf
;
13011 /* Set the visible flags for all frames. Do this before checking for
13012 resized or garbaged frames; they want to know if their frames are
13013 visible. See the comment in frame.h for FRAME_SAMPLE_VISIBILITY. */
13014 number_of_visible_frames
= 0;
13016 FOR_EACH_FRAME (tail
, frame
)
13018 struct frame
*f
= XFRAME (frame
);
13020 if (FRAME_VISIBLE_P (f
))
13022 ++number_of_visible_frames
;
13023 /* Adjust matrices for visible frames only. */
13024 if (f
->fonts_changed
)
13026 adjust_frame_glyphs (f
);
13027 f
->fonts_changed
= 0;
13029 /* If cursor type has been changed on the frame
13030 other than selected, consider all frames. */
13031 if (f
!= sf
&& f
->cursor_type_changed
)
13032 update_mode_lines
++;
13034 clear_desired_matrices (f
);
13037 /* Notice any pending interrupt request to change frame size. */
13038 do_pending_window_change (1);
13040 /* do_pending_window_change could change the selected_window due to
13041 frame resizing which makes the selected window too small. */
13042 if (WINDOWP (selected_window
) && (w
= XWINDOW (selected_window
)) != sw
)
13045 /* Clear frames marked as garbaged. */
13046 clear_garbaged_frames ();
13048 /* Build menubar and tool-bar items. */
13049 if (NILP (Vmemory_full
))
13050 prepare_menu_bars ();
13052 if (windows_or_buffers_changed
)
13053 update_mode_lines
++;
13055 reconsider_clip_changes (w
);
13057 /* In most cases selected window displays current buffer. */
13058 match_p
= XBUFFER (w
->contents
) == current_buffer
;
13063 /* Detect case that we need to write or remove a star in the mode line. */
13064 if ((SAVE_MODIFF
< MODIFF
) != w
->last_had_star
)
13066 w
->update_mode_line
= 1;
13067 if (buffer_shared_and_changed ())
13068 update_mode_lines
++;
13071 /* Avoid invocation of point motion hooks by `current_column' below. */
13072 count1
= SPECPDL_INDEX ();
13073 specbind (Qinhibit_point_motion_hooks
, Qt
);
13075 if (mode_line_update_needed (w
))
13076 w
->update_mode_line
= 1;
13078 unbind_to (count1
, Qnil
);
13081 consider_all_windows_p
= (update_mode_lines
13082 || buffer_shared_and_changed ());
13084 /* If specs for an arrow have changed, do thorough redisplay
13085 to ensure we remove any arrow that should no longer exist. */
13086 if (overlay_arrows_changed_p ())
13087 consider_all_windows_p
= windows_or_buffers_changed
= 1;
13089 /* Normally the message* functions will have already displayed and
13090 updated the echo area, but the frame may have been trashed, or
13091 the update may have been preempted, so display the echo area
13092 again here. Checking message_cleared_p captures the case that
13093 the echo area should be cleared. */
13094 if ((!NILP (echo_area_buffer
[0]) && !display_last_displayed_message_p
)
13095 || (!NILP (echo_area_buffer
[1]) && display_last_displayed_message_p
)
13096 || (message_cleared_p
13097 && minibuf_level
== 0
13098 /* If the mini-window is currently selected, this means the
13099 echo-area doesn't show through. */
13100 && !MINI_WINDOW_P (XWINDOW (selected_window
))))
13102 int window_height_changed_p
= echo_area_display (0);
13104 if (message_cleared_p
)
13105 update_miniwindow_p
= 1;
13109 /* If we don't display the current message, don't clear the
13110 message_cleared_p flag, because, if we did, we wouldn't clear
13111 the echo area in the next redisplay which doesn't preserve
13113 if (!display_last_displayed_message_p
)
13114 message_cleared_p
= 0;
13116 if (window_height_changed_p
)
13118 consider_all_windows_p
= 1;
13119 ++update_mode_lines
;
13120 ++windows_or_buffers_changed
;
13122 /* If window configuration was changed, frames may have been
13123 marked garbaged. Clear them or we will experience
13124 surprises wrt scrolling. */
13125 clear_garbaged_frames ();
13128 else if (EQ (selected_window
, minibuf_window
)
13129 && (current_buffer
->clip_changed
|| window_outdated (w
))
13130 && resize_mini_window (w
, 0))
13132 /* Resized active mini-window to fit the size of what it is
13133 showing if its contents might have changed. */
13135 /* FIXME: this causes all frames to be updated, which seems unnecessary
13136 since only the current frame needs to be considered. This function
13137 needs to be rewritten with two variables, consider_all_windows and
13138 consider_all_frames. */
13139 consider_all_windows_p
= 1;
13140 ++windows_or_buffers_changed
;
13141 ++update_mode_lines
;
13143 /* If window configuration was changed, frames may have been
13144 marked garbaged. Clear them or we will experience
13145 surprises wrt scrolling. */
13146 clear_garbaged_frames ();
13149 /* If showing the region, and mark has changed, we must redisplay
13150 the whole window. The assignment to this_line_start_pos prevents
13151 the optimization directly below this if-statement. */
13152 if (((!NILP (Vtransient_mark_mode
)
13153 && !NILP (BVAR (XBUFFER (w
->contents
), mark_active
)))
13154 != (w
->region_showing
> 0))
13155 || (w
->region_showing
13156 && w
->region_showing
13157 != XINT (Fmarker_position (BVAR (XBUFFER (w
->contents
), mark
)))))
13158 CHARPOS (this_line_start_pos
) = 0;
13160 /* Optimize the case that only the line containing the cursor in the
13161 selected window has changed. Variables starting with this_ are
13162 set in display_line and record information about the line
13163 containing the cursor. */
13164 tlbufpos
= this_line_start_pos
;
13165 tlendpos
= this_line_end_pos
;
13166 if (!consider_all_windows_p
13167 && CHARPOS (tlbufpos
) > 0
13168 && !w
->update_mode_line
13169 && !current_buffer
->clip_changed
13170 && !current_buffer
->prevent_redisplay_optimizations_p
13171 && FRAME_VISIBLE_P (XFRAME (w
->frame
))
13172 && !FRAME_OBSCURED_P (XFRAME (w
->frame
))
13173 && !XFRAME (w
->frame
)->cursor_type_changed
13174 /* Make sure recorded data applies to current buffer, etc. */
13175 && this_line_buffer
== current_buffer
13178 && !w
->optional_new_start
13179 /* Point must be on the line that we have info recorded about. */
13180 && PT
>= CHARPOS (tlbufpos
)
13181 && PT
<= Z
- CHARPOS (tlendpos
)
13182 /* All text outside that line, including its final newline,
13183 must be unchanged. */
13184 && text_outside_line_unchanged_p (w
, CHARPOS (tlbufpos
),
13185 CHARPOS (tlendpos
)))
13187 if (CHARPOS (tlbufpos
) > BEGV
13188 && FETCH_BYTE (BYTEPOS (tlbufpos
) - 1) != '\n'
13189 && (CHARPOS (tlbufpos
) == ZV
13190 || FETCH_BYTE (BYTEPOS (tlbufpos
)) == '\n'))
13191 /* Former continuation line has disappeared by becoming empty. */
13193 else if (window_outdated (w
) || MINI_WINDOW_P (w
))
13195 /* We have to handle the case of continuation around a
13196 wide-column character (see the comment in indent.c around
13199 For instance, in the following case:
13201 -------- Insert --------
13202 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
13203 J_I_ ==> J_I_ `^^' are cursors.
13207 As we have to redraw the line above, we cannot use this
13211 int line_height_before
= this_line_pixel_height
;
13213 /* Note that start_display will handle the case that the
13214 line starting at tlbufpos is a continuation line. */
13215 start_display (&it
, w
, tlbufpos
);
13217 /* Implementation note: It this still necessary? */
13218 if (it
.current_x
!= this_line_start_x
)
13221 TRACE ((stderr
, "trying display optimization 1\n"));
13222 w
->cursor
.vpos
= -1;
13223 overlay_arrow_seen
= 0;
13224 it
.vpos
= this_line_vpos
;
13225 it
.current_y
= this_line_y
;
13226 it
.glyph_row
= MATRIX_ROW (w
->desired_matrix
, this_line_vpos
);
13227 display_line (&it
);
13229 /* If line contains point, is not continued,
13230 and ends at same distance from eob as before, we win. */
13231 if (w
->cursor
.vpos
>= 0
13232 /* Line is not continued, otherwise this_line_start_pos
13233 would have been set to 0 in display_line. */
13234 && CHARPOS (this_line_start_pos
)
13235 /* Line ends as before. */
13236 && CHARPOS (this_line_end_pos
) == CHARPOS (tlendpos
)
13237 /* Line has same height as before. Otherwise other lines
13238 would have to be shifted up or down. */
13239 && this_line_pixel_height
== line_height_before
)
13241 /* If this is not the window's last line, we must adjust
13242 the charstarts of the lines below. */
13243 if (it
.current_y
< it
.last_visible_y
)
13245 struct glyph_row
*row
13246 = MATRIX_ROW (w
->current_matrix
, this_line_vpos
+ 1);
13247 ptrdiff_t delta
, delta_bytes
;
13249 /* We used to distinguish between two cases here,
13250 conditioned by Z - CHARPOS (tlendpos) == ZV, for
13251 when the line ends in a newline or the end of the
13252 buffer's accessible portion. But both cases did
13253 the same, so they were collapsed. */
13255 - CHARPOS (tlendpos
)
13256 - MATRIX_ROW_START_CHARPOS (row
));
13257 delta_bytes
= (Z_BYTE
13258 - BYTEPOS (tlendpos
)
13259 - MATRIX_ROW_START_BYTEPOS (row
));
13261 increment_matrix_positions (w
->current_matrix
,
13262 this_line_vpos
+ 1,
13263 w
->current_matrix
->nrows
,
13264 delta
, delta_bytes
);
13267 /* If this row displays text now but previously didn't,
13268 or vice versa, w->window_end_vpos may have to be
13270 if (MATRIX_ROW_DISPLAYS_TEXT_P (it
.glyph_row
- 1))
13272 if (w
->window_end_vpos
< this_line_vpos
)
13273 w
->window_end_vpos
= this_line_vpos
;
13275 else if (w
->window_end_vpos
== this_line_vpos
13276 && this_line_vpos
> 0)
13277 w
->window_end_vpos
= this_line_vpos
- 1;
13278 w
->window_end_valid
= 0;
13280 /* Update hint: No need to try to scroll in update_window. */
13281 w
->desired_matrix
->no_scrolling_p
= 1;
13284 *w
->desired_matrix
->method
= 0;
13285 debug_method_add (w
, "optimization 1");
13287 #ifdef HAVE_WINDOW_SYSTEM
13288 update_window_fringes (w
, 0);
13295 else if (/* Cursor position hasn't changed. */
13296 PT
== w
->last_point
13297 /* Make sure the cursor was last displayed
13298 in this window. Otherwise we have to reposition it. */
13299 && 0 <= w
->cursor
.vpos
13300 && w
->cursor
.vpos
< WINDOW_TOTAL_LINES (w
))
13304 do_pending_window_change (1);
13305 /* If selected_window changed, redisplay again. */
13306 if (WINDOWP (selected_window
)
13307 && (w
= XWINDOW (selected_window
)) != sw
)
13310 /* We used to always goto end_of_redisplay here, but this
13311 isn't enough if we have a blinking cursor. */
13312 if (w
->cursor_off_p
== w
->last_cursor_off_p
)
13313 goto end_of_redisplay
;
13317 /* If highlighting the region, or if the cursor is in the echo area,
13318 then we can't just move the cursor. */
13319 else if (! (!NILP (Vtransient_mark_mode
)
13320 && !NILP (BVAR (current_buffer
, mark_active
)))
13321 && (EQ (selected_window
,
13322 BVAR (current_buffer
, last_selected_window
))
13323 || highlight_nonselected_windows
)
13324 && !w
->region_showing
13325 && NILP (Vshow_trailing_whitespace
)
13326 && !cursor_in_echo_area
)
13329 struct glyph_row
*row
;
13331 /* Skip from tlbufpos to PT and see where it is. Note that
13332 PT may be in invisible text. If so, we will end at the
13333 next visible position. */
13334 init_iterator (&it
, w
, CHARPOS (tlbufpos
), BYTEPOS (tlbufpos
),
13335 NULL
, DEFAULT_FACE_ID
);
13336 it
.current_x
= this_line_start_x
;
13337 it
.current_y
= this_line_y
;
13338 it
.vpos
= this_line_vpos
;
13340 /* The call to move_it_to stops in front of PT, but
13341 moves over before-strings. */
13342 move_it_to (&it
, PT
, -1, -1, -1, MOVE_TO_POS
);
13344 if (it
.vpos
== this_line_vpos
13345 && (row
= MATRIX_ROW (w
->current_matrix
, this_line_vpos
),
13348 eassert (this_line_vpos
== it
.vpos
);
13349 eassert (this_line_y
== it
.current_y
);
13350 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
13352 *w
->desired_matrix
->method
= 0;
13353 debug_method_add (w
, "optimization 3");
13362 /* Text changed drastically or point moved off of line. */
13363 SET_MATRIX_ROW_ENABLED_P (w
->desired_matrix
, this_line_vpos
, 0);
13366 CHARPOS (this_line_start_pos
) = 0;
13367 consider_all_windows_p
|= buffer_shared_and_changed ();
13368 ++clear_face_cache_count
;
13369 #ifdef HAVE_WINDOW_SYSTEM
13370 ++clear_image_cache_count
;
13373 /* Build desired matrices, and update the display. If
13374 consider_all_windows_p is non-zero, do it for all windows on all
13375 frames. Otherwise do it for selected_window, only. */
13377 if (consider_all_windows_p
)
13379 FOR_EACH_FRAME (tail
, frame
)
13380 XFRAME (frame
)->updated_p
= 0;
13382 FOR_EACH_FRAME (tail
, frame
)
13384 struct frame
*f
= XFRAME (frame
);
13386 /* We don't have to do anything for unselected terminal
13388 if ((FRAME_TERMCAP_P (f
) || FRAME_MSDOS_P (f
))
13389 && !EQ (FRAME_TTY (f
)->top_frame
, frame
))
13394 if (FRAME_WINDOW_P (f
) || FRAME_TERMCAP_P (f
) || f
== sf
)
13396 /* Mark all the scroll bars to be removed; we'll redeem
13397 the ones we want when we redisplay their windows. */
13398 if (FRAME_TERMINAL (f
)->condemn_scroll_bars_hook
)
13399 FRAME_TERMINAL (f
)->condemn_scroll_bars_hook (f
);
13401 if (FRAME_VISIBLE_P (f
) && !FRAME_OBSCURED_P (f
))
13402 redisplay_windows (FRAME_ROOT_WINDOW (f
));
13404 /* The X error handler may have deleted that frame. */
13405 if (!FRAME_LIVE_P (f
))
13408 /* Any scroll bars which redisplay_windows should have
13409 nuked should now go away. */
13410 if (FRAME_TERMINAL (f
)->judge_scroll_bars_hook
)
13411 FRAME_TERMINAL (f
)->judge_scroll_bars_hook (f
);
13413 if (FRAME_VISIBLE_P (f
) && !FRAME_OBSCURED_P (f
))
13415 /* If fonts changed on visible frame, display again. */
13416 if (f
->fonts_changed
)
13418 adjust_frame_glyphs (f
);
13419 f
->fonts_changed
= 0;
13423 /* See if we have to hscroll. */
13424 if (!f
->already_hscrolled_p
)
13426 f
->already_hscrolled_p
= 1;
13427 if (hscroll_windows (f
->root_window
))
13431 /* Prevent various kinds of signals during display
13432 update. stdio is not robust about handling
13433 signals, which can cause an apparent I/O
13435 if (interrupt_input
)
13436 unrequest_sigio ();
13439 /* Update the display. */
13440 set_window_update_flags (XWINDOW (f
->root_window
), 1);
13441 pending
|= update_frame (f
, 0, 0);
13442 f
->cursor_type_changed
= 0;
13448 eassert (EQ (XFRAME (selected_frame
)->selected_window
, selected_window
));
13452 /* Do the mark_window_display_accurate after all windows have
13453 been redisplayed because this call resets flags in buffers
13454 which are needed for proper redisplay. */
13455 FOR_EACH_FRAME (tail
, frame
)
13457 struct frame
*f
= XFRAME (frame
);
13460 mark_window_display_accurate (f
->root_window
, 1);
13461 if (FRAME_TERMINAL (f
)->frame_up_to_date_hook
)
13462 FRAME_TERMINAL (f
)->frame_up_to_date_hook (f
);
13467 else if (FRAME_VISIBLE_P (sf
) && !FRAME_OBSCURED_P (sf
))
13469 Lisp_Object mini_window
= FRAME_MINIBUF_WINDOW (sf
);
13470 struct frame
*mini_frame
;
13472 displayed_buffer
= XBUFFER (XWINDOW (selected_window
)->contents
);
13473 /* Use list_of_error, not Qerror, so that
13474 we catch only errors and don't run the debugger. */
13475 internal_condition_case_1 (redisplay_window_1
, selected_window
,
13477 redisplay_window_error
);
13478 if (update_miniwindow_p
)
13479 internal_condition_case_1 (redisplay_window_1
, mini_window
,
13481 redisplay_window_error
);
13483 /* Compare desired and current matrices, perform output. */
13486 /* If fonts changed, display again. */
13487 if (sf
->fonts_changed
)
13490 /* Prevent various kinds of signals during display update.
13491 stdio is not robust about handling signals,
13492 which can cause an apparent I/O error. */
13493 if (interrupt_input
)
13494 unrequest_sigio ();
13497 if (FRAME_VISIBLE_P (sf
) && !FRAME_OBSCURED_P (sf
))
13499 if (hscroll_windows (selected_window
))
13502 XWINDOW (selected_window
)->must_be_updated_p
= 1;
13503 pending
= update_frame (sf
, 0, 0);
13504 sf
->cursor_type_changed
= 0;
13507 /* We may have called echo_area_display at the top of this
13508 function. If the echo area is on another frame, that may
13509 have put text on a frame other than the selected one, so the
13510 above call to update_frame would not have caught it. Catch
13512 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
13513 mini_frame
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
13515 if (mini_frame
!= sf
&& FRAME_WINDOW_P (mini_frame
))
13517 XWINDOW (mini_window
)->must_be_updated_p
= 1;
13518 pending
|= update_frame (mini_frame
, 0, 0);
13519 mini_frame
->cursor_type_changed
= 0;
13520 if (!pending
&& hscroll_windows (mini_window
))
13525 /* If display was paused because of pending input, make sure we do a
13526 thorough update the next time. */
13529 /* Prevent the optimization at the beginning of
13530 redisplay_internal that tries a single-line update of the
13531 line containing the cursor in the selected window. */
13532 CHARPOS (this_line_start_pos
) = 0;
13534 /* Let the overlay arrow be updated the next time. */
13535 update_overlay_arrows (0);
13537 /* If we pause after scrolling, some rows in the current
13538 matrices of some windows are not valid. */
13539 if (!WINDOW_FULL_WIDTH_P (w
)
13540 && !FRAME_WINDOW_P (XFRAME (w
->frame
)))
13541 update_mode_lines
= 1;
13545 if (!consider_all_windows_p
)
13547 /* This has already been done above if
13548 consider_all_windows_p is set. */
13549 mark_window_display_accurate_1 (w
, 1);
13551 /* Say overlay arrows are up to date. */
13552 update_overlay_arrows (1);
13554 if (FRAME_TERMINAL (sf
)->frame_up_to_date_hook
!= 0)
13555 FRAME_TERMINAL (sf
)->frame_up_to_date_hook (sf
);
13558 update_mode_lines
= 0;
13559 windows_or_buffers_changed
= 0;
13562 /* Start SIGIO interrupts coming again. Having them off during the
13563 code above makes it less likely one will discard output, but not
13564 impossible, since there might be stuff in the system buffer here.
13565 But it is much hairier to try to do anything about that. */
13566 if (interrupt_input
)
13570 /* If a frame has become visible which was not before, redisplay
13571 again, so that we display it. Expose events for such a frame
13572 (which it gets when becoming visible) don't call the parts of
13573 redisplay constructing glyphs, so simply exposing a frame won't
13574 display anything in this case. So, we have to display these
13575 frames here explicitly. */
13580 FOR_EACH_FRAME (tail
, frame
)
13582 int this_is_visible
= 0;
13584 if (XFRAME (frame
)->visible
)
13585 this_is_visible
= 1;
13587 if (this_is_visible
)
13591 if (new_count
!= number_of_visible_frames
)
13592 windows_or_buffers_changed
++;
13595 /* Change frame size now if a change is pending. */
13596 do_pending_window_change (1);
13598 /* If we just did a pending size change, or have additional
13599 visible frames, or selected_window changed, redisplay again. */
13600 if ((windows_or_buffers_changed
&& !pending
)
13601 || (WINDOWP (selected_window
) && (w
= XWINDOW (selected_window
)) != sw
))
13604 /* Clear the face and image caches.
13606 We used to do this only if consider_all_windows_p. But the cache
13607 needs to be cleared if a timer creates images in the current
13608 buffer (e.g. the test case in Bug#6230). */
13610 if (clear_face_cache_count
> CLEAR_FACE_CACHE_COUNT
)
13612 clear_face_cache (0);
13613 clear_face_cache_count
= 0;
13616 #ifdef HAVE_WINDOW_SYSTEM
13617 if (clear_image_cache_count
> CLEAR_IMAGE_CACHE_COUNT
)
13619 clear_image_caches (Qnil
);
13620 clear_image_cache_count
= 0;
13622 #endif /* HAVE_WINDOW_SYSTEM */
13625 unbind_to (count
, Qnil
);
13630 /* Redisplay, but leave alone any recent echo area message unless
13631 another message has been requested in its place.
13633 This is useful in situations where you need to redisplay but no
13634 user action has occurred, making it inappropriate for the message
13635 area to be cleared. See tracking_off and
13636 wait_reading_process_output for examples of these situations.
13638 FROM_WHERE is an integer saying from where this function was
13639 called. This is useful for debugging. */
13642 redisplay_preserve_echo_area (int from_where
)
13644 TRACE ((stderr
, "redisplay_preserve_echo_area (%d)\n", from_where
));
13646 if (!NILP (echo_area_buffer
[1]))
13648 /* We have a previously displayed message, but no current
13649 message. Redisplay the previous message. */
13650 display_last_displayed_message_p
= 1;
13651 redisplay_internal ();
13652 display_last_displayed_message_p
= 0;
13655 redisplay_internal ();
13657 flush_frame (SELECTED_FRAME ());
13661 /* Function registered with record_unwind_protect in redisplay_internal. */
13664 unwind_redisplay (void)
13666 redisplaying_p
= 0;
13670 /* Mark the display of leaf window W as accurate or inaccurate.
13671 If ACCURATE_P is non-zero mark display of W as accurate. If
13672 ACCURATE_P is zero, arrange for W to be redisplayed the next
13673 time redisplay_internal is called. */
13676 mark_window_display_accurate_1 (struct window
*w
, int accurate_p
)
13678 struct buffer
*b
= XBUFFER (w
->contents
);
13680 w
->last_modified
= accurate_p
? BUF_MODIFF (b
) : 0;
13681 w
->last_overlay_modified
= accurate_p
? BUF_OVERLAY_MODIFF (b
) : 0;
13682 w
->last_had_star
= BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
);
13686 b
->clip_changed
= 0;
13687 b
->prevent_redisplay_optimizations_p
= 0;
13689 BUF_UNCHANGED_MODIFIED (b
) = BUF_MODIFF (b
);
13690 BUF_OVERLAY_UNCHANGED_MODIFIED (b
) = BUF_OVERLAY_MODIFF (b
);
13691 BUF_BEG_UNCHANGED (b
) = BUF_GPT (b
) - BUF_BEG (b
);
13692 BUF_END_UNCHANGED (b
) = BUF_Z (b
) - BUF_GPT (b
);
13694 w
->current_matrix
->buffer
= b
;
13695 w
->current_matrix
->begv
= BUF_BEGV (b
);
13696 w
->current_matrix
->zv
= BUF_ZV (b
);
13698 w
->last_cursor_vpos
= w
->cursor
.vpos
;
13699 w
->last_cursor_off_p
= w
->cursor_off_p
;
13701 if (w
== XWINDOW (selected_window
))
13702 w
->last_point
= BUF_PT (b
);
13704 w
->last_point
= marker_position (w
->pointm
);
13706 w
->window_end_valid
= 1;
13707 w
->update_mode_line
= 0;
13712 /* Mark the display of windows in the window tree rooted at WINDOW as
13713 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
13714 windows as accurate. If ACCURATE_P is zero, arrange for windows to
13715 be redisplayed the next time redisplay_internal is called. */
13718 mark_window_display_accurate (Lisp_Object window
, int accurate_p
)
13722 for (; !NILP (window
); window
= w
->next
)
13724 w
= XWINDOW (window
);
13725 if (WINDOWP (w
->contents
))
13726 mark_window_display_accurate (w
->contents
, accurate_p
);
13728 mark_window_display_accurate_1 (w
, accurate_p
);
13732 update_overlay_arrows (1);
13734 /* Force a thorough redisplay the next time by setting
13735 last_arrow_position and last_arrow_string to t, which is
13736 unequal to any useful value of Voverlay_arrow_... */
13737 update_overlay_arrows (-1);
13741 /* Return value in display table DP (Lisp_Char_Table *) for character
13742 C. Since a display table doesn't have any parent, we don't have to
13743 follow parent. Do not call this function directly but use the
13744 macro DISP_CHAR_VECTOR. */
13747 disp_char_vector (struct Lisp_Char_Table
*dp
, int c
)
13751 if (ASCII_CHAR_P (c
))
13754 if (SUB_CHAR_TABLE_P (val
))
13755 val
= XSUB_CHAR_TABLE (val
)->contents
[c
];
13761 XSETCHAR_TABLE (table
, dp
);
13762 val
= char_table_ref (table
, c
);
13771 /***********************************************************************
13773 ***********************************************************************/
13775 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
13778 redisplay_windows (Lisp_Object window
)
13780 while (!NILP (window
))
13782 struct window
*w
= XWINDOW (window
);
13784 if (WINDOWP (w
->contents
))
13785 redisplay_windows (w
->contents
);
13786 else if (BUFFERP (w
->contents
))
13788 displayed_buffer
= XBUFFER (w
->contents
);
13789 /* Use list_of_error, not Qerror, so that
13790 we catch only errors and don't run the debugger. */
13791 internal_condition_case_1 (redisplay_window_0
, window
,
13793 redisplay_window_error
);
13801 redisplay_window_error (Lisp_Object ignore
)
13803 displayed_buffer
->display_error_modiff
= BUF_MODIFF (displayed_buffer
);
13808 redisplay_window_0 (Lisp_Object window
)
13810 if (displayed_buffer
->display_error_modiff
< BUF_MODIFF (displayed_buffer
))
13811 redisplay_window (window
, 0);
13816 redisplay_window_1 (Lisp_Object window
)
13818 if (displayed_buffer
->display_error_modiff
< BUF_MODIFF (displayed_buffer
))
13819 redisplay_window (window
, 1);
13824 /* Set cursor position of W. PT is assumed to be displayed in ROW.
13825 DELTA and DELTA_BYTES are the numbers of characters and bytes by
13826 which positions recorded in ROW differ from current buffer
13829 Return 0 if cursor is not on this row, 1 otherwise. */
13832 set_cursor_from_row (struct window
*w
, struct glyph_row
*row
,
13833 struct glyph_matrix
*matrix
,
13834 ptrdiff_t delta
, ptrdiff_t delta_bytes
,
13837 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
];
13838 struct glyph
*end
= glyph
+ row
->used
[TEXT_AREA
];
13839 struct glyph
*cursor
= NULL
;
13840 /* The last known character position in row. */
13841 ptrdiff_t last_pos
= MATRIX_ROW_START_CHARPOS (row
) + delta
;
13843 ptrdiff_t pt_old
= PT
- delta
;
13844 ptrdiff_t pos_before
= MATRIX_ROW_START_CHARPOS (row
) + delta
;
13845 ptrdiff_t pos_after
= MATRIX_ROW_END_CHARPOS (row
) + delta
;
13846 struct glyph
*glyph_before
= glyph
- 1, *glyph_after
= end
;
13847 /* A glyph beyond the edge of TEXT_AREA which we should never
13849 struct glyph
*glyphs_end
= end
;
13850 /* Non-zero means we've found a match for cursor position, but that
13851 glyph has the avoid_cursor_p flag set. */
13852 int match_with_avoid_cursor
= 0;
13853 /* Non-zero means we've seen at least one glyph that came from a
13855 int string_seen
= 0;
13856 /* Largest and smallest buffer positions seen so far during scan of
13858 ptrdiff_t bpos_max
= pos_before
;
13859 ptrdiff_t bpos_min
= pos_after
;
13860 /* Last buffer position covered by an overlay string with an integer
13861 `cursor' property. */
13862 ptrdiff_t bpos_covered
= 0;
13863 /* Non-zero means the display string on which to display the cursor
13864 comes from a text property, not from an overlay. */
13865 int string_from_text_prop
= 0;
13867 /* Don't even try doing anything if called for a mode-line or
13868 header-line row, since the rest of the code isn't prepared to
13869 deal with such calamities. */
13870 eassert (!row
->mode_line_p
);
13871 if (row
->mode_line_p
)
13874 /* Skip over glyphs not having an object at the start and the end of
13875 the row. These are special glyphs like truncation marks on
13876 terminal frames. */
13877 if (MATRIX_ROW_DISPLAYS_TEXT_P (row
))
13879 if (!row
->reversed_p
)
13882 && INTEGERP (glyph
->object
)
13883 && glyph
->charpos
< 0)
13885 x
+= glyph
->pixel_width
;
13889 && INTEGERP ((end
- 1)->object
)
13890 /* CHARPOS is zero for blanks and stretch glyphs
13891 inserted by extend_face_to_end_of_line. */
13892 && (end
- 1)->charpos
<= 0)
13894 glyph_before
= glyph
- 1;
13901 /* If the glyph row is reversed, we need to process it from back
13902 to front, so swap the edge pointers. */
13903 glyphs_end
= end
= glyph
- 1;
13904 glyph
+= row
->used
[TEXT_AREA
] - 1;
13906 while (glyph
> end
+ 1
13907 && INTEGERP (glyph
->object
)
13908 && glyph
->charpos
< 0)
13911 x
-= glyph
->pixel_width
;
13913 if (INTEGERP (glyph
->object
) && glyph
->charpos
< 0)
13915 /* By default, in reversed rows we put the cursor on the
13916 rightmost (first in the reading order) glyph. */
13917 for (g
= end
+ 1; g
< glyph
; g
++)
13918 x
+= g
->pixel_width
;
13920 && INTEGERP ((end
+ 1)->object
)
13921 && (end
+ 1)->charpos
<= 0)
13923 glyph_before
= glyph
+ 1;
13927 else if (row
->reversed_p
)
13929 /* In R2L rows that don't display text, put the cursor on the
13930 rightmost glyph. Case in point: an empty last line that is
13931 part of an R2L paragraph. */
13933 /* Avoid placing the cursor on the last glyph of the row, where
13934 on terminal frames we hold the vertical border between
13935 adjacent windows. */
13936 if (!FRAME_WINDOW_P (WINDOW_XFRAME (w
))
13937 && !WINDOW_RIGHTMOST_P (w
)
13938 && cursor
== row
->glyphs
[LAST_AREA
] - 1)
13940 x
= -1; /* will be computed below, at label compute_x */
13943 /* Step 1: Try to find the glyph whose character position
13944 corresponds to point. If that's not possible, find 2 glyphs
13945 whose character positions are the closest to point, one before
13946 point, the other after it. */
13947 if (!row
->reversed_p
)
13948 while (/* not marched to end of glyph row */
13950 /* glyph was not inserted by redisplay for internal purposes */
13951 && !INTEGERP (glyph
->object
))
13953 if (BUFFERP (glyph
->object
))
13955 ptrdiff_t dpos
= glyph
->charpos
- pt_old
;
13957 if (glyph
->charpos
> bpos_max
)
13958 bpos_max
= glyph
->charpos
;
13959 if (glyph
->charpos
< bpos_min
)
13960 bpos_min
= glyph
->charpos
;
13961 if (!glyph
->avoid_cursor_p
)
13963 /* If we hit point, we've found the glyph on which to
13964 display the cursor. */
13967 match_with_avoid_cursor
= 0;
13970 /* See if we've found a better approximation to
13971 POS_BEFORE or to POS_AFTER. */
13972 if (0 > dpos
&& dpos
> pos_before
- pt_old
)
13974 pos_before
= glyph
->charpos
;
13975 glyph_before
= glyph
;
13977 else if (0 < dpos
&& dpos
< pos_after
- pt_old
)
13979 pos_after
= glyph
->charpos
;
13980 glyph_after
= glyph
;
13983 else if (dpos
== 0)
13984 match_with_avoid_cursor
= 1;
13986 else if (STRINGP (glyph
->object
))
13988 Lisp_Object chprop
;
13989 ptrdiff_t glyph_pos
= glyph
->charpos
;
13991 chprop
= Fget_char_property (make_number (glyph_pos
), Qcursor
,
13993 if (!NILP (chprop
))
13995 /* If the string came from a `display' text property,
13996 look up the buffer position of that property and
13997 use that position to update bpos_max, as if we
13998 actually saw such a position in one of the row's
13999 glyphs. This helps with supporting integer values
14000 of `cursor' property on the display string in
14001 situations where most or all of the row's buffer
14002 text is completely covered by display properties,
14003 so that no glyph with valid buffer positions is
14004 ever seen in the row. */
14005 ptrdiff_t prop_pos
=
14006 string_buffer_position_lim (glyph
->object
, pos_before
,
14009 if (prop_pos
>= pos_before
)
14010 bpos_max
= prop_pos
- 1;
14012 if (INTEGERP (chprop
))
14014 bpos_covered
= bpos_max
+ XINT (chprop
);
14015 /* If the `cursor' property covers buffer positions up
14016 to and including point, we should display cursor on
14017 this glyph. Note that, if a `cursor' property on one
14018 of the string's characters has an integer value, we
14019 will break out of the loop below _before_ we get to
14020 the position match above. IOW, integer values of
14021 the `cursor' property override the "exact match for
14022 point" strategy of positioning the cursor. */
14023 /* Implementation note: bpos_max == pt_old when, e.g.,
14024 we are in an empty line, where bpos_max is set to
14025 MATRIX_ROW_START_CHARPOS, see above. */
14026 if (bpos_max
<= pt_old
&& bpos_covered
>= pt_old
)
14035 x
+= glyph
->pixel_width
;
14038 else if (glyph
> end
) /* row is reversed */
14039 while (!INTEGERP (glyph
->object
))
14041 if (BUFFERP (glyph
->object
))
14043 ptrdiff_t dpos
= glyph
->charpos
- pt_old
;
14045 if (glyph
->charpos
> bpos_max
)
14046 bpos_max
= glyph
->charpos
;
14047 if (glyph
->charpos
< bpos_min
)
14048 bpos_min
= glyph
->charpos
;
14049 if (!glyph
->avoid_cursor_p
)
14053 match_with_avoid_cursor
= 0;
14056 if (0 > dpos
&& dpos
> pos_before
- pt_old
)
14058 pos_before
= glyph
->charpos
;
14059 glyph_before
= glyph
;
14061 else if (0 < dpos
&& dpos
< pos_after
- pt_old
)
14063 pos_after
= glyph
->charpos
;
14064 glyph_after
= glyph
;
14067 else if (dpos
== 0)
14068 match_with_avoid_cursor
= 1;
14070 else if (STRINGP (glyph
->object
))
14072 Lisp_Object chprop
;
14073 ptrdiff_t glyph_pos
= glyph
->charpos
;
14075 chprop
= Fget_char_property (make_number (glyph_pos
), Qcursor
,
14077 if (!NILP (chprop
))
14079 ptrdiff_t prop_pos
=
14080 string_buffer_position_lim (glyph
->object
, pos_before
,
14083 if (prop_pos
>= pos_before
)
14084 bpos_max
= prop_pos
- 1;
14086 if (INTEGERP (chprop
))
14088 bpos_covered
= bpos_max
+ XINT (chprop
);
14089 /* If the `cursor' property covers buffer positions up
14090 to and including point, we should display cursor on
14092 if (bpos_max
<= pt_old
&& bpos_covered
>= pt_old
)
14101 if (glyph
== glyphs_end
) /* don't dereference outside TEXT_AREA */
14103 x
--; /* can't use any pixel_width */
14106 x
-= glyph
->pixel_width
;
14109 /* Step 2: If we didn't find an exact match for point, we need to
14110 look for a proper place to put the cursor among glyphs between
14111 GLYPH_BEFORE and GLYPH_AFTER. */
14112 if (!((row
->reversed_p
? glyph
> glyphs_end
: glyph
< glyphs_end
)
14113 && BUFFERP (glyph
->object
) && glyph
->charpos
== pt_old
)
14114 && !(bpos_max
< pt_old
&& pt_old
<= bpos_covered
))
14116 /* An empty line has a single glyph whose OBJECT is zero and
14117 whose CHARPOS is the position of a newline on that line.
14118 Note that on a TTY, there are more glyphs after that, which
14119 were produced by extend_face_to_end_of_line, but their
14120 CHARPOS is zero or negative. */
14122 (row
->reversed_p
? glyph
> glyphs_end
: glyph
< glyphs_end
)
14123 && INTEGERP (glyph
->object
) && glyph
->charpos
> 0
14124 /* On a TTY, continued and truncated rows also have a glyph at
14125 their end whose OBJECT is zero and whose CHARPOS is
14126 positive (the continuation and truncation glyphs), but such
14127 rows are obviously not "empty". */
14128 && !(row
->continued_p
|| row
->truncated_on_right_p
);
14130 if (row
->ends_in_ellipsis_p
&& pos_after
== last_pos
)
14132 ptrdiff_t ellipsis_pos
;
14134 /* Scan back over the ellipsis glyphs. */
14135 if (!row
->reversed_p
)
14137 ellipsis_pos
= (glyph
- 1)->charpos
;
14138 while (glyph
> row
->glyphs
[TEXT_AREA
]
14139 && (glyph
- 1)->charpos
== ellipsis_pos
)
14140 glyph
--, x
-= glyph
->pixel_width
;
14141 /* That loop always goes one position too far, including
14142 the glyph before the ellipsis. So scan forward over
14144 x
+= glyph
->pixel_width
;
14147 else /* row is reversed */
14149 ellipsis_pos
= (glyph
+ 1)->charpos
;
14150 while (glyph
< row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
] - 1
14151 && (glyph
+ 1)->charpos
== ellipsis_pos
)
14152 glyph
++, x
+= glyph
->pixel_width
;
14153 x
-= glyph
->pixel_width
;
14157 else if (match_with_avoid_cursor
)
14159 cursor
= glyph_after
;
14162 else if (string_seen
)
14164 int incr
= row
->reversed_p
? -1 : +1;
14166 /* Need to find the glyph that came out of a string which is
14167 present at point. That glyph is somewhere between
14168 GLYPH_BEFORE and GLYPH_AFTER, and it came from a string
14169 positioned between POS_BEFORE and POS_AFTER in the
14171 struct glyph
*start
, *stop
;
14172 ptrdiff_t pos
= pos_before
;
14176 /* If the row ends in a newline from a display string,
14177 reordering could have moved the glyphs belonging to the
14178 string out of the [GLYPH_BEFORE..GLYPH_AFTER] range. So
14179 in this case we extend the search to the last glyph in
14180 the row that was not inserted by redisplay. */
14181 if (row
->ends_in_newline_from_string_p
)
14184 pos_after
= MATRIX_ROW_END_CHARPOS (row
) + delta
;
14187 /* GLYPH_BEFORE and GLYPH_AFTER are the glyphs that
14188 correspond to POS_BEFORE and POS_AFTER, respectively. We
14189 need START and STOP in the order that corresponds to the
14190 row's direction as given by its reversed_p flag. If the
14191 directionality of characters between POS_BEFORE and
14192 POS_AFTER is the opposite of the row's base direction,
14193 these characters will have been reordered for display,
14194 and we need to reverse START and STOP. */
14195 if (!row
->reversed_p
)
14197 start
= min (glyph_before
, glyph_after
);
14198 stop
= max (glyph_before
, glyph_after
);
14202 start
= max (glyph_before
, glyph_after
);
14203 stop
= min (glyph_before
, glyph_after
);
14205 for (glyph
= start
+ incr
;
14206 row
->reversed_p
? glyph
> stop
: glyph
< stop
; )
14209 /* Any glyphs that come from the buffer are here because
14210 of bidi reordering. Skip them, and only pay
14211 attention to glyphs that came from some string. */
14212 if (STRINGP (glyph
->object
))
14216 /* If the display property covers the newline, we
14217 need to search for it one position farther. */
14218 ptrdiff_t lim
= pos_after
14219 + (pos_after
== MATRIX_ROW_END_CHARPOS (row
) + delta
);
14221 string_from_text_prop
= 0;
14222 str
= glyph
->object
;
14223 tem
= string_buffer_position_lim (str
, pos
, lim
, 0);
14224 if (tem
== 0 /* from overlay */
14227 /* If the string from which this glyph came is
14228 found in the buffer at point, or at position
14229 that is closer to point than pos_after, then
14230 we've found the glyph we've been looking for.
14231 If it comes from an overlay (tem == 0), and
14232 it has the `cursor' property on one of its
14233 glyphs, record that glyph as a candidate for
14234 displaying the cursor. (As in the
14235 unidirectional version, we will display the
14236 cursor on the last candidate we find.) */
14239 || (tem
- pt_old
> 0 && tem
< pos_after
))
14241 /* The glyphs from this string could have
14242 been reordered. Find the one with the
14243 smallest string position. Or there could
14244 be a character in the string with the
14245 `cursor' property, which means display
14246 cursor on that character's glyph. */
14247 ptrdiff_t strpos
= glyph
->charpos
;
14252 string_from_text_prop
= 1;
14255 (row
->reversed_p
? glyph
> stop
: glyph
< stop
)
14256 && EQ (glyph
->object
, str
);
14260 ptrdiff_t gpos
= glyph
->charpos
;
14262 cprop
= Fget_char_property (make_number (gpos
),
14270 if (tem
&& glyph
->charpos
< strpos
)
14272 strpos
= glyph
->charpos
;
14278 || (tem
- pt_old
> 0 && tem
< pos_after
))
14282 pos
= tem
+ 1; /* don't find previous instances */
14284 /* This string is not what we want; skip all of the
14285 glyphs that came from it. */
14286 while ((row
->reversed_p
? glyph
> stop
: glyph
< stop
)
14287 && EQ (glyph
->object
, str
))
14294 /* If we reached the end of the line, and END was from a string,
14295 the cursor is not on this line. */
14297 && (row
->reversed_p
? glyph
<= end
: glyph
>= end
)
14298 && (row
->reversed_p
? end
> glyphs_end
: end
< glyphs_end
)
14299 && STRINGP (end
->object
)
14300 && row
->continued_p
)
14303 /* A truncated row may not include PT among its character positions.
14304 Setting the cursor inside the scroll margin will trigger
14305 recalculation of hscroll in hscroll_window_tree. But if a
14306 display string covers point, defer to the string-handling
14307 code below to figure this out. */
14308 else if (row
->truncated_on_left_p
&& pt_old
< bpos_min
)
14310 cursor
= glyph_before
;
14313 else if ((row
->truncated_on_right_p
&& pt_old
> bpos_max
)
14314 /* Zero-width characters produce no glyphs. */
14316 && (row
->reversed_p
14317 ? glyph_after
> glyphs_end
14318 : glyph_after
< glyphs_end
)))
14320 cursor
= glyph_after
;
14326 if (cursor
!= NULL
)
14328 else if (glyph
== glyphs_end
14329 && pos_before
== pos_after
14330 && STRINGP ((row
->reversed_p
14331 ? row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
] - 1
14332 : row
->glyphs
[TEXT_AREA
])->object
))
14334 /* If all the glyphs of this row came from strings, put the
14335 cursor on the first glyph of the row. This avoids having the
14336 cursor outside of the text area in this very rare and hard
14340 ? row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
] - 1
14341 : row
->glyphs
[TEXT_AREA
];
14347 /* Need to compute x that corresponds to GLYPH. */
14348 for (g
= row
->glyphs
[TEXT_AREA
], x
= row
->x
; g
< glyph
; g
++)
14350 if (g
>= row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
])
14352 x
+= g
->pixel_width
;
14356 /* ROW could be part of a continued line, which, under bidi
14357 reordering, might have other rows whose start and end charpos
14358 occlude point. Only set w->cursor if we found a better
14359 approximation to the cursor position than we have from previously
14360 examined candidate rows belonging to the same continued line. */
14361 if (/* we already have a candidate row */
14362 w
->cursor
.vpos
>= 0
14363 /* that candidate is not the row we are processing */
14364 && MATRIX_ROW (matrix
, w
->cursor
.vpos
) != row
14365 /* Make sure cursor.vpos specifies a row whose start and end
14366 charpos occlude point, and it is valid candidate for being a
14367 cursor-row. This is because some callers of this function
14368 leave cursor.vpos at the row where the cursor was displayed
14369 during the last redisplay cycle. */
14370 && MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix
, w
->cursor
.vpos
)) <= pt_old
14371 && pt_old
<= MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix
, w
->cursor
.vpos
))
14372 && cursor_row_p (MATRIX_ROW (matrix
, w
->cursor
.vpos
)))
14375 MATRIX_ROW_GLYPH_START (matrix
, w
->cursor
.vpos
) + w
->cursor
.hpos
;
14377 /* Don't consider glyphs that are outside TEXT_AREA. */
14378 if (!(row
->reversed_p
? glyph
> glyphs_end
: glyph
< glyphs_end
))
14380 /* Keep the candidate whose buffer position is the closest to
14381 point or has the `cursor' property. */
14382 if (/* previous candidate is a glyph in TEXT_AREA of that row */
14383 w
->cursor
.hpos
>= 0
14384 && w
->cursor
.hpos
< MATRIX_ROW_USED (matrix
, w
->cursor
.vpos
)
14385 && ((BUFFERP (g1
->object
)
14386 && (g1
->charpos
== pt_old
/* an exact match always wins */
14387 || (BUFFERP (glyph
->object
)
14388 && eabs (g1
->charpos
- pt_old
)
14389 < eabs (glyph
->charpos
- pt_old
))))
14390 /* previous candidate is a glyph from a string that has
14391 a non-nil `cursor' property */
14392 || (STRINGP (g1
->object
)
14393 && (!NILP (Fget_char_property (make_number (g1
->charpos
),
14394 Qcursor
, g1
->object
))
14395 /* previous candidate is from the same display
14396 string as this one, and the display string
14397 came from a text property */
14398 || (EQ (g1
->object
, glyph
->object
)
14399 && string_from_text_prop
)
14400 /* this candidate is from newline and its
14401 position is not an exact match */
14402 || (INTEGERP (glyph
->object
)
14403 && glyph
->charpos
!= pt_old
)))))
14405 /* If this candidate gives an exact match, use that. */
14406 if (!((BUFFERP (glyph
->object
) && glyph
->charpos
== pt_old
)
14407 /* If this candidate is a glyph created for the
14408 terminating newline of a line, and point is on that
14409 newline, it wins because it's an exact match. */
14410 || (!row
->continued_p
14411 && INTEGERP (glyph
->object
)
14412 && glyph
->charpos
== 0
14413 && pt_old
== MATRIX_ROW_END_CHARPOS (row
) - 1))
14414 /* Otherwise, keep the candidate that comes from a row
14415 spanning less buffer positions. This may win when one or
14416 both candidate positions are on glyphs that came from
14417 display strings, for which we cannot compare buffer
14419 && MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix
, w
->cursor
.vpos
))
14420 - MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix
, w
->cursor
.vpos
))
14421 < MATRIX_ROW_END_CHARPOS (row
) - MATRIX_ROW_START_CHARPOS (row
))
14424 w
->cursor
.hpos
= glyph
- row
->glyphs
[TEXT_AREA
];
14426 w
->cursor
.vpos
= MATRIX_ROW_VPOS (row
, matrix
) + dvpos
;
14427 w
->cursor
.y
= row
->y
+ dy
;
14429 if (w
== XWINDOW (selected_window
))
14431 if (!row
->continued_p
14432 && !MATRIX_ROW_CONTINUATION_LINE_P (row
)
14435 this_line_buffer
= XBUFFER (w
->contents
);
14437 CHARPOS (this_line_start_pos
)
14438 = MATRIX_ROW_START_CHARPOS (row
) + delta
;
14439 BYTEPOS (this_line_start_pos
)
14440 = MATRIX_ROW_START_BYTEPOS (row
) + delta_bytes
;
14442 CHARPOS (this_line_end_pos
)
14443 = Z
- (MATRIX_ROW_END_CHARPOS (row
) + delta
);
14444 BYTEPOS (this_line_end_pos
)
14445 = Z_BYTE
- (MATRIX_ROW_END_BYTEPOS (row
) + delta_bytes
);
14447 this_line_y
= w
->cursor
.y
;
14448 this_line_pixel_height
= row
->height
;
14449 this_line_vpos
= w
->cursor
.vpos
;
14450 this_line_start_x
= row
->x
;
14453 CHARPOS (this_line_start_pos
) = 0;
14460 /* Run window scroll functions, if any, for WINDOW with new window
14461 start STARTP. Sets the window start of WINDOW to that position.
14463 We assume that the window's buffer is really current. */
14465 static struct text_pos
14466 run_window_scroll_functions (Lisp_Object window
, struct text_pos startp
)
14468 struct window
*w
= XWINDOW (window
);
14469 SET_MARKER_FROM_TEXT_POS (w
->start
, startp
);
14471 eassert (current_buffer
== XBUFFER (w
->contents
));
14473 if (!NILP (Vwindow_scroll_functions
))
14475 run_hook_with_args_2 (Qwindow_scroll_functions
, window
,
14476 make_number (CHARPOS (startp
)));
14477 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
14478 /* In case the hook functions switch buffers. */
14479 set_buffer_internal (XBUFFER (w
->contents
));
14486 /* Make sure the line containing the cursor is fully visible.
14487 A value of 1 means there is nothing to be done.
14488 (Either the line is fully visible, or it cannot be made so,
14489 or we cannot tell.)
14491 If FORCE_P is non-zero, return 0 even if partial visible cursor row
14492 is higher than window.
14494 A value of 0 means the caller should do scrolling
14495 as if point had gone off the screen. */
14498 cursor_row_fully_visible_p (struct window
*w
, int force_p
, int current_matrix_p
)
14500 struct glyph_matrix
*matrix
;
14501 struct glyph_row
*row
;
14504 if (!make_cursor_line_fully_visible_p
)
14507 /* It's not always possible to find the cursor, e.g, when a window
14508 is full of overlay strings. Don't do anything in that case. */
14509 if (w
->cursor
.vpos
< 0)
14512 matrix
= current_matrix_p
? w
->current_matrix
: w
->desired_matrix
;
14513 row
= MATRIX_ROW (matrix
, w
->cursor
.vpos
);
14515 /* If the cursor row is not partially visible, there's nothing to do. */
14516 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w
, row
))
14519 /* If the row the cursor is in is taller than the window's height,
14520 it's not clear what to do, so do nothing. */
14521 window_height
= window_box_height (w
);
14522 if (row
->height
>= window_height
)
14524 if (!force_p
|| MINI_WINDOW_P (w
)
14525 || w
->vscroll
|| w
->cursor
.vpos
== 0)
14532 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
14533 non-zero means only WINDOW is redisplayed in redisplay_internal.
14534 TEMP_SCROLL_STEP has the same meaning as emacs_scroll_step, and is used
14535 in redisplay_window to bring a partially visible line into view in
14536 the case that only the cursor has moved.
14538 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
14539 last screen line's vertical height extends past the end of the screen.
14543 1 if scrolling succeeded
14545 0 if scrolling didn't find point.
14547 -1 if new fonts have been loaded so that we must interrupt
14548 redisplay, adjust glyph matrices, and try again. */
14554 SCROLLING_NEED_LARGER_MATRICES
14557 /* If scroll-conservatively is more than this, never recenter.
14559 If you change this, don't forget to update the doc string of
14560 `scroll-conservatively' and the Emacs manual. */
14561 #define SCROLL_LIMIT 100
14564 try_scrolling (Lisp_Object window
, int just_this_one_p
,
14565 ptrdiff_t arg_scroll_conservatively
, ptrdiff_t scroll_step
,
14566 int temp_scroll_step
, int last_line_misfit
)
14568 struct window
*w
= XWINDOW (window
);
14569 struct frame
*f
= XFRAME (w
->frame
);
14570 struct text_pos pos
, startp
;
14572 int this_scroll_margin
, scroll_max
, rc
, height
;
14573 int dy
= 0, amount_to_scroll
= 0, scroll_down_p
= 0;
14574 int extra_scroll_margin_lines
= last_line_misfit
? 1 : 0;
14575 Lisp_Object aggressive
;
14576 /* We will never try scrolling more than this number of lines. */
14577 int scroll_limit
= SCROLL_LIMIT
;
14578 int frame_line_height
= default_line_pixel_height (w
);
14579 int window_total_lines
14580 = WINDOW_TOTAL_LINES (w
) * FRAME_LINE_HEIGHT (f
) / frame_line_height
;
14583 debug_method_add (w
, "try_scrolling");
14586 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
14588 /* Compute scroll margin height in pixels. We scroll when point is
14589 within this distance from the top or bottom of the window. */
14590 if (scroll_margin
> 0)
14591 this_scroll_margin
= min (scroll_margin
, window_total_lines
/ 4)
14592 * frame_line_height
;
14594 this_scroll_margin
= 0;
14596 /* Force arg_scroll_conservatively to have a reasonable value, to
14597 avoid scrolling too far away with slow move_it_* functions. Note
14598 that the user can supply scroll-conservatively equal to
14599 `most-positive-fixnum', which can be larger than INT_MAX. */
14600 if (arg_scroll_conservatively
> scroll_limit
)
14602 arg_scroll_conservatively
= scroll_limit
+ 1;
14603 scroll_max
= scroll_limit
* frame_line_height
;
14605 else if (scroll_step
|| arg_scroll_conservatively
|| temp_scroll_step
)
14606 /* Compute how much we should try to scroll maximally to bring
14607 point into view. */
14608 scroll_max
= (max (scroll_step
,
14609 max (arg_scroll_conservatively
, temp_scroll_step
))
14610 * frame_line_height
);
14611 else if (NUMBERP (BVAR (current_buffer
, scroll_down_aggressively
))
14612 || NUMBERP (BVAR (current_buffer
, scroll_up_aggressively
)))
14613 /* We're trying to scroll because of aggressive scrolling but no
14614 scroll_step is set. Choose an arbitrary one. */
14615 scroll_max
= 10 * frame_line_height
;
14621 /* Decide whether to scroll down. */
14622 if (PT
> CHARPOS (startp
))
14624 int scroll_margin_y
;
14626 /* Compute the pixel ypos of the scroll margin, then move IT to
14627 either that ypos or PT, whichever comes first. */
14628 start_display (&it
, w
, startp
);
14629 scroll_margin_y
= it
.last_visible_y
- this_scroll_margin
14630 - frame_line_height
* extra_scroll_margin_lines
;
14631 move_it_to (&it
, PT
, -1, scroll_margin_y
- 1, -1,
14632 (MOVE_TO_POS
| MOVE_TO_Y
));
14634 if (PT
> CHARPOS (it
.current
.pos
))
14636 int y0
= line_bottom_y (&it
);
14637 /* Compute how many pixels below window bottom to stop searching
14638 for PT. This avoids costly search for PT that is far away if
14639 the user limited scrolling by a small number of lines, but
14640 always finds PT if scroll_conservatively is set to a large
14641 number, such as most-positive-fixnum. */
14642 int slack
= max (scroll_max
, 10 * frame_line_height
);
14643 int y_to_move
= it
.last_visible_y
+ slack
;
14645 /* Compute the distance from the scroll margin to PT or to
14646 the scroll limit, whichever comes first. This should
14647 include the height of the cursor line, to make that line
14649 move_it_to (&it
, PT
, -1, y_to_move
,
14650 -1, MOVE_TO_POS
| MOVE_TO_Y
);
14651 dy
= line_bottom_y (&it
) - y0
;
14653 if (dy
> scroll_max
)
14654 return SCROLLING_FAILED
;
14663 /* Point is in or below the bottom scroll margin, so move the
14664 window start down. If scrolling conservatively, move it just
14665 enough down to make point visible. If scroll_step is set,
14666 move it down by scroll_step. */
14667 if (arg_scroll_conservatively
)
14669 = min (max (dy
, frame_line_height
),
14670 frame_line_height
* arg_scroll_conservatively
);
14671 else if (scroll_step
|| temp_scroll_step
)
14672 amount_to_scroll
= scroll_max
;
14675 aggressive
= BVAR (current_buffer
, scroll_up_aggressively
);
14676 height
= WINDOW_BOX_TEXT_HEIGHT (w
);
14677 if (NUMBERP (aggressive
))
14679 double float_amount
= XFLOATINT (aggressive
) * height
;
14680 int aggressive_scroll
= float_amount
;
14681 if (aggressive_scroll
== 0 && float_amount
> 0)
14682 aggressive_scroll
= 1;
14683 /* Don't let point enter the scroll margin near top of
14684 the window. This could happen if the value of
14685 scroll_up_aggressively is too large and there are
14686 non-zero margins, because scroll_up_aggressively
14687 means put point that fraction of window height
14688 _from_the_bottom_margin_. */
14689 if (aggressive_scroll
+ 2*this_scroll_margin
> height
)
14690 aggressive_scroll
= height
- 2*this_scroll_margin
;
14691 amount_to_scroll
= dy
+ aggressive_scroll
;
14695 if (amount_to_scroll
<= 0)
14696 return SCROLLING_FAILED
;
14698 start_display (&it
, w
, startp
);
14699 if (arg_scroll_conservatively
<= scroll_limit
)
14700 move_it_vertically (&it
, amount_to_scroll
);
14703 /* Extra precision for users who set scroll-conservatively
14704 to a large number: make sure the amount we scroll
14705 the window start is never less than amount_to_scroll,
14706 which was computed as distance from window bottom to
14707 point. This matters when lines at window top and lines
14708 below window bottom have different height. */
14710 void *it1data
= NULL
;
14711 /* We use a temporary it1 because line_bottom_y can modify
14712 its argument, if it moves one line down; see there. */
14715 SAVE_IT (it1
, it
, it1data
);
14716 start_y
= line_bottom_y (&it1
);
14718 RESTORE_IT (&it
, &it
, it1data
);
14719 move_it_by_lines (&it
, 1);
14720 SAVE_IT (it1
, it
, it1data
);
14721 } while (line_bottom_y (&it1
) - start_y
< amount_to_scroll
);
14724 /* If STARTP is unchanged, move it down another screen line. */
14725 if (CHARPOS (it
.current
.pos
) == CHARPOS (startp
))
14726 move_it_by_lines (&it
, 1);
14727 startp
= it
.current
.pos
;
14731 struct text_pos scroll_margin_pos
= startp
;
14734 /* See if point is inside the scroll margin at the top of the
14736 if (this_scroll_margin
)
14740 start_display (&it
, w
, startp
);
14741 y_start
= it
.current_y
;
14742 move_it_vertically (&it
, this_scroll_margin
);
14743 scroll_margin_pos
= it
.current
.pos
;
14744 /* If we didn't move enough before hitting ZV, request
14745 additional amount of scroll, to move point out of the
14747 if (IT_CHARPOS (it
) == ZV
14748 && it
.current_y
- y_start
< this_scroll_margin
)
14749 y_offset
= this_scroll_margin
- (it
.current_y
- y_start
);
14752 if (PT
< CHARPOS (scroll_margin_pos
))
14754 /* Point is in the scroll margin at the top of the window or
14755 above what is displayed in the window. */
14758 /* Compute the vertical distance from PT to the scroll
14759 margin position. Move as far as scroll_max allows, or
14760 one screenful, or 10 screen lines, whichever is largest.
14761 Give up if distance is greater than scroll_max or if we
14762 didn't reach the scroll margin position. */
14763 SET_TEXT_POS (pos
, PT
, PT_BYTE
);
14764 start_display (&it
, w
, pos
);
14766 y_to_move
= max (it
.last_visible_y
,
14767 max (scroll_max
, 10 * frame_line_height
));
14768 move_it_to (&it
, CHARPOS (scroll_margin_pos
), 0,
14770 MOVE_TO_POS
| MOVE_TO_X
| MOVE_TO_Y
);
14771 dy
= it
.current_y
- y0
;
14772 if (dy
> scroll_max
14773 || IT_CHARPOS (it
) < CHARPOS (scroll_margin_pos
))
14774 return SCROLLING_FAILED
;
14776 /* Additional scroll for when ZV was too close to point. */
14779 /* Compute new window start. */
14780 start_display (&it
, w
, startp
);
14782 if (arg_scroll_conservatively
)
14783 amount_to_scroll
= max (dy
, frame_line_height
*
14784 max (scroll_step
, temp_scroll_step
));
14785 else if (scroll_step
|| temp_scroll_step
)
14786 amount_to_scroll
= scroll_max
;
14789 aggressive
= BVAR (current_buffer
, scroll_down_aggressively
);
14790 height
= WINDOW_BOX_TEXT_HEIGHT (w
);
14791 if (NUMBERP (aggressive
))
14793 double float_amount
= XFLOATINT (aggressive
) * height
;
14794 int aggressive_scroll
= float_amount
;
14795 if (aggressive_scroll
== 0 && float_amount
> 0)
14796 aggressive_scroll
= 1;
14797 /* Don't let point enter the scroll margin near
14798 bottom of the window, if the value of
14799 scroll_down_aggressively happens to be too
14801 if (aggressive_scroll
+ 2*this_scroll_margin
> height
)
14802 aggressive_scroll
= height
- 2*this_scroll_margin
;
14803 amount_to_scroll
= dy
+ aggressive_scroll
;
14807 if (amount_to_scroll
<= 0)
14808 return SCROLLING_FAILED
;
14810 move_it_vertically_backward (&it
, amount_to_scroll
);
14811 startp
= it
.current
.pos
;
14815 /* Run window scroll functions. */
14816 startp
= run_window_scroll_functions (window
, startp
);
14818 /* Display the window. Give up if new fonts are loaded, or if point
14820 if (!try_window (window
, startp
, 0))
14821 rc
= SCROLLING_NEED_LARGER_MATRICES
;
14822 else if (w
->cursor
.vpos
< 0)
14824 clear_glyph_matrix (w
->desired_matrix
);
14825 rc
= SCROLLING_FAILED
;
14829 /* Maybe forget recorded base line for line number display. */
14830 if (!just_this_one_p
14831 || current_buffer
->clip_changed
14832 || BEG_UNCHANGED
< CHARPOS (startp
))
14833 w
->base_line_number
= 0;
14835 /* If cursor ends up on a partially visible line,
14836 treat that as being off the bottom of the screen. */
14837 if (! cursor_row_fully_visible_p (w
, extra_scroll_margin_lines
<= 1, 0)
14838 /* It's possible that the cursor is on the first line of the
14839 buffer, which is partially obscured due to a vscroll
14840 (Bug#7537). In that case, avoid looping forever . */
14841 && extra_scroll_margin_lines
< w
->desired_matrix
->nrows
- 1)
14843 clear_glyph_matrix (w
->desired_matrix
);
14844 ++extra_scroll_margin_lines
;
14847 rc
= SCROLLING_SUCCESS
;
14854 /* Compute a suitable window start for window W if display of W starts
14855 on a continuation line. Value is non-zero if a new window start
14858 The new window start will be computed, based on W's width, starting
14859 from the start of the continued line. It is the start of the
14860 screen line with the minimum distance from the old start W->start. */
14863 compute_window_start_on_continuation_line (struct window
*w
)
14865 struct text_pos pos
, start_pos
;
14866 int window_start_changed_p
= 0;
14868 SET_TEXT_POS_FROM_MARKER (start_pos
, w
->start
);
14870 /* If window start is on a continuation line... Window start may be
14871 < BEGV in case there's invisible text at the start of the
14872 buffer (M-x rmail, for example). */
14873 if (CHARPOS (start_pos
) > BEGV
14874 && FETCH_BYTE (BYTEPOS (start_pos
) - 1) != '\n')
14877 struct glyph_row
*row
;
14879 /* Handle the case that the window start is out of range. */
14880 if (CHARPOS (start_pos
) < BEGV
)
14881 SET_TEXT_POS (start_pos
, BEGV
, BEGV_BYTE
);
14882 else if (CHARPOS (start_pos
) > ZV
)
14883 SET_TEXT_POS (start_pos
, ZV
, ZV_BYTE
);
14885 /* Find the start of the continued line. This should be fast
14886 because find_newline is fast (newline cache). */
14887 row
= w
->desired_matrix
->rows
+ (WINDOW_WANTS_HEADER_LINE_P (w
) ? 1 : 0);
14888 init_iterator (&it
, w
, CHARPOS (start_pos
), BYTEPOS (start_pos
),
14889 row
, DEFAULT_FACE_ID
);
14890 reseat_at_previous_visible_line_start (&it
);
14892 /* If the line start is "too far" away from the window start,
14893 say it takes too much time to compute a new window start. */
14894 if (CHARPOS (start_pos
) - IT_CHARPOS (it
)
14895 < WINDOW_TOTAL_LINES (w
) * WINDOW_TOTAL_COLS (w
))
14897 int min_distance
, distance
;
14899 /* Move forward by display lines to find the new window
14900 start. If window width was enlarged, the new start can
14901 be expected to be > the old start. If window width was
14902 decreased, the new window start will be < the old start.
14903 So, we're looking for the display line start with the
14904 minimum distance from the old window start. */
14905 pos
= it
.current
.pos
;
14906 min_distance
= INFINITY
;
14907 while ((distance
= eabs (CHARPOS (start_pos
) - IT_CHARPOS (it
))),
14908 distance
< min_distance
)
14910 min_distance
= distance
;
14911 pos
= it
.current
.pos
;
14912 if (it
.line_wrap
== WORD_WRAP
)
14914 /* Under WORD_WRAP, move_it_by_lines is likely to
14915 overshoot and stop not at the first, but the
14916 second character from the left margin. So in
14917 that case, we need a more tight control on the X
14918 coordinate of the iterator than move_it_by_lines
14919 promises in its contract. The method is to first
14920 go to the last (rightmost) visible character of a
14921 line, then move to the leftmost character on the
14922 next line in a separate call. */
14923 move_it_to (&it
, ZV
, it
.last_visible_x
, it
.current_y
, -1,
14924 MOVE_TO_POS
| MOVE_TO_X
| MOVE_TO_Y
);
14925 move_it_to (&it
, ZV
, 0,
14926 it
.current_y
+ it
.max_ascent
+ it
.max_descent
, -1,
14927 MOVE_TO_POS
| MOVE_TO_X
| MOVE_TO_Y
);
14930 move_it_by_lines (&it
, 1);
14933 /* Set the window start there. */
14934 SET_MARKER_FROM_TEXT_POS (w
->start
, pos
);
14935 window_start_changed_p
= 1;
14939 return window_start_changed_p
;
14943 /* Try cursor movement in case text has not changed in window WINDOW,
14944 with window start STARTP. Value is
14946 CURSOR_MOVEMENT_SUCCESS if successful
14948 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
14950 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
14951 display. *SCROLL_STEP is set to 1, under certain circumstances, if
14952 we want to scroll as if scroll-step were set to 1. See the code.
14954 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
14955 which case we have to abort this redisplay, and adjust matrices
14960 CURSOR_MOVEMENT_SUCCESS
,
14961 CURSOR_MOVEMENT_CANNOT_BE_USED
,
14962 CURSOR_MOVEMENT_MUST_SCROLL
,
14963 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
14967 try_cursor_movement (Lisp_Object window
, struct text_pos startp
, int *scroll_step
)
14969 struct window
*w
= XWINDOW (window
);
14970 struct frame
*f
= XFRAME (w
->frame
);
14971 int rc
= CURSOR_MOVEMENT_CANNOT_BE_USED
;
14974 if (inhibit_try_cursor_movement
)
14978 /* Previously, there was a check for Lisp integer in the
14979 if-statement below. Now, this field is converted to
14980 ptrdiff_t, thus zero means invalid position in a buffer. */
14981 eassert (w
->last_point
> 0);
14982 /* Likewise there was a check whether window_end_vpos is nil or larger
14983 than the window. Now window_end_vpos is int and so never nil, but
14984 let's leave eassert to check whether it fits in the window. */
14985 eassert (w
->window_end_vpos
< w
->current_matrix
->nrows
);
14987 /* Handle case where text has not changed, only point, and it has
14988 not moved off the frame. */
14989 if (/* Point may be in this window. */
14990 PT
>= CHARPOS (startp
)
14991 /* Selective display hasn't changed. */
14992 && !current_buffer
->clip_changed
14993 /* Function force-mode-line-update is used to force a thorough
14994 redisplay. It sets either windows_or_buffers_changed or
14995 update_mode_lines. So don't take a shortcut here for these
14997 && !update_mode_lines
14998 && !windows_or_buffers_changed
14999 && !f
->cursor_type_changed
15000 /* Can't use this case if highlighting a region. When a
15001 region exists, cursor movement has to do more than just
15003 && markpos_of_region () < 0
15004 && !w
->region_showing
15005 && NILP (Vshow_trailing_whitespace
)
15006 /* This code is not used for mini-buffer for the sake of the case
15007 of redisplaying to replace an echo area message; since in
15008 that case the mini-buffer contents per se are usually
15009 unchanged. This code is of no real use in the mini-buffer
15010 since the handling of this_line_start_pos, etc., in redisplay
15011 handles the same cases. */
15012 && !EQ (window
, minibuf_window
)
15013 && (FRAME_WINDOW_P (f
)
15014 || !overlay_arrow_in_current_buffer_p ()))
15016 int this_scroll_margin
, top_scroll_margin
;
15017 struct glyph_row
*row
= NULL
;
15018 int frame_line_height
= default_line_pixel_height (w
);
15019 int window_total_lines
15020 = WINDOW_TOTAL_LINES (w
) * FRAME_LINE_HEIGHT (f
) / frame_line_height
;
15023 debug_method_add (w
, "cursor movement");
15026 /* Scroll if point within this distance from the top or bottom
15027 of the window. This is a pixel value. */
15028 if (scroll_margin
> 0)
15030 this_scroll_margin
= min (scroll_margin
, window_total_lines
/ 4);
15031 this_scroll_margin
*= frame_line_height
;
15034 this_scroll_margin
= 0;
15036 top_scroll_margin
= this_scroll_margin
;
15037 if (WINDOW_WANTS_HEADER_LINE_P (w
))
15038 top_scroll_margin
+= CURRENT_HEADER_LINE_HEIGHT (w
);
15040 /* Start with the row the cursor was displayed during the last
15041 not paused redisplay. Give up if that row is not valid. */
15042 if (w
->last_cursor_vpos
< 0
15043 || w
->last_cursor_vpos
>= w
->current_matrix
->nrows
)
15044 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
15047 row
= MATRIX_ROW (w
->current_matrix
, w
->last_cursor_vpos
);
15048 if (row
->mode_line_p
)
15050 if (!row
->enabled_p
)
15051 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
15054 if (rc
== CURSOR_MOVEMENT_CANNOT_BE_USED
)
15056 int scroll_p
= 0, must_scroll
= 0;
15057 int last_y
= window_text_bottom_y (w
) - this_scroll_margin
;
15059 if (PT
> w
->last_point
)
15061 /* Point has moved forward. */
15062 while (MATRIX_ROW_END_CHARPOS (row
) < PT
15063 && MATRIX_ROW_BOTTOM_Y (row
) < last_y
)
15065 eassert (row
->enabled_p
);
15069 /* If the end position of a row equals the start
15070 position of the next row, and PT is at that position,
15071 we would rather display cursor in the next line. */
15072 while (MATRIX_ROW_BOTTOM_Y (row
) < last_y
15073 && MATRIX_ROW_END_CHARPOS (row
) == PT
15074 && row
< MATRIX_MODE_LINE_ROW (w
->current_matrix
)
15075 && MATRIX_ROW_START_CHARPOS (row
+1) == PT
15076 && !cursor_row_p (row
))
15079 /* If within the scroll margin, scroll. Note that
15080 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
15081 the next line would be drawn, and that
15082 this_scroll_margin can be zero. */
15083 if (MATRIX_ROW_BOTTOM_Y (row
) > last_y
15084 || PT
> MATRIX_ROW_END_CHARPOS (row
)
15085 /* Line is completely visible last line in window
15086 and PT is to be set in the next line. */
15087 || (MATRIX_ROW_BOTTOM_Y (row
) == last_y
15088 && PT
== MATRIX_ROW_END_CHARPOS (row
)
15089 && !row
->ends_at_zv_p
15090 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row
)))
15093 else if (PT
< w
->last_point
)
15095 /* Cursor has to be moved backward. Note that PT >=
15096 CHARPOS (startp) because of the outer if-statement. */
15097 while (!row
->mode_line_p
15098 && (MATRIX_ROW_START_CHARPOS (row
) > PT
15099 || (MATRIX_ROW_START_CHARPOS (row
) == PT
15100 && (MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row
)
15101 || (/* STARTS_IN_MIDDLE_OF_STRING_P (row) */
15102 row
> w
->current_matrix
->rows
15103 && (row
-1)->ends_in_newline_from_string_p
))))
15104 && (row
->y
> top_scroll_margin
15105 || CHARPOS (startp
) == BEGV
))
15107 eassert (row
->enabled_p
);
15111 /* Consider the following case: Window starts at BEGV,
15112 there is invisible, intangible text at BEGV, so that
15113 display starts at some point START > BEGV. It can
15114 happen that we are called with PT somewhere between
15115 BEGV and START. Try to handle that case. */
15116 if (row
< w
->current_matrix
->rows
15117 || row
->mode_line_p
)
15119 row
= w
->current_matrix
->rows
;
15120 if (row
->mode_line_p
)
15124 /* Due to newlines in overlay strings, we may have to
15125 skip forward over overlay strings. */
15126 while (MATRIX_ROW_BOTTOM_Y (row
) < last_y
15127 && MATRIX_ROW_END_CHARPOS (row
) == PT
15128 && !cursor_row_p (row
))
15131 /* If within the scroll margin, scroll. */
15132 if (row
->y
< top_scroll_margin
15133 && CHARPOS (startp
) != BEGV
)
15138 /* Cursor did not move. So don't scroll even if cursor line
15139 is partially visible, as it was so before. */
15140 rc
= CURSOR_MOVEMENT_SUCCESS
;
15143 if (PT
< MATRIX_ROW_START_CHARPOS (row
)
15144 || PT
> MATRIX_ROW_END_CHARPOS (row
))
15146 /* if PT is not in the glyph row, give up. */
15147 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
15150 else if (rc
!= CURSOR_MOVEMENT_SUCCESS
15151 && !NILP (BVAR (XBUFFER (w
->contents
), bidi_display_reordering
)))
15153 struct glyph_row
*row1
;
15155 /* If rows are bidi-reordered and point moved, back up
15156 until we find a row that does not belong to a
15157 continuation line. This is because we must consider
15158 all rows of a continued line as candidates for the
15159 new cursor positioning, since row start and end
15160 positions change non-linearly with vertical position
15162 /* FIXME: Revisit this when glyph ``spilling'' in
15163 continuation lines' rows is implemented for
15164 bidi-reordered rows. */
15165 for (row1
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
15166 MATRIX_ROW_CONTINUATION_LINE_P (row
);
15169 /* If we hit the beginning of the displayed portion
15170 without finding the first row of a continued
15174 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
15177 eassert (row
->enabled_p
);
15182 else if (rc
!= CURSOR_MOVEMENT_SUCCESS
15183 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w
, row
)
15184 /* Make sure this isn't a header line by any chance, since
15185 then MATRIX_ROW_PARTIALLY_VISIBLE_P might yield non-zero. */
15186 && !row
->mode_line_p
15187 && make_cursor_line_fully_visible_p
)
15189 if (PT
== MATRIX_ROW_END_CHARPOS (row
)
15190 && !row
->ends_at_zv_p
15191 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row
))
15192 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
15193 else if (row
->height
> window_box_height (w
))
15195 /* If we end up in a partially visible line, let's
15196 make it fully visible, except when it's taller
15197 than the window, in which case we can't do much
15200 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
15204 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
15205 if (!cursor_row_fully_visible_p (w
, 0, 1))
15206 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
15208 rc
= CURSOR_MOVEMENT_SUCCESS
;
15212 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
15213 else if (rc
!= CURSOR_MOVEMENT_SUCCESS
15214 && !NILP (BVAR (XBUFFER (w
->contents
), bidi_display_reordering
)))
15216 /* With bidi-reordered rows, there could be more than
15217 one candidate row whose start and end positions
15218 occlude point. We need to let set_cursor_from_row
15219 find the best candidate. */
15220 /* FIXME: Revisit this when glyph ``spilling'' in
15221 continuation lines' rows is implemented for
15222 bidi-reordered rows. */
15227 int at_zv_p
= 0, exact_match_p
= 0;
15229 if (MATRIX_ROW_START_CHARPOS (row
) <= PT
15230 && PT
<= MATRIX_ROW_END_CHARPOS (row
)
15231 && cursor_row_p (row
))
15232 rv
|= set_cursor_from_row (w
, row
, w
->current_matrix
,
15234 /* As soon as we've found the exact match for point,
15235 or the first suitable row whose ends_at_zv_p flag
15236 is set, we are done. */
15238 MATRIX_ROW (w
->current_matrix
, w
->cursor
.vpos
)->ends_at_zv_p
;
15240 && w
->cursor
.hpos
>= 0
15241 && w
->cursor
.hpos
< MATRIX_ROW_USED (w
->current_matrix
,
15244 struct glyph_row
*candidate
=
15245 MATRIX_ROW (w
->current_matrix
, w
->cursor
.vpos
);
15247 candidate
->glyphs
[TEXT_AREA
] + w
->cursor
.hpos
;
15248 ptrdiff_t endpos
= MATRIX_ROW_END_CHARPOS (candidate
);
15251 (BUFFERP (g
->object
) && g
->charpos
== PT
)
15252 || (INTEGERP (g
->object
)
15253 && (g
->charpos
== PT
15254 || (g
->charpos
== 0 && endpos
- 1 == PT
)));
15256 if (rv
&& (at_zv_p
|| exact_match_p
))
15258 rc
= CURSOR_MOVEMENT_SUCCESS
;
15261 if (MATRIX_ROW_BOTTOM_Y (row
) == last_y
)
15265 while (((MATRIX_ROW_CONTINUATION_LINE_P (row
)
15266 || row
->continued_p
)
15267 && MATRIX_ROW_BOTTOM_Y (row
) <= last_y
)
15268 || (MATRIX_ROW_START_CHARPOS (row
) == PT
15269 && MATRIX_ROW_BOTTOM_Y (row
) < last_y
));
15270 /* If we didn't find any candidate rows, or exited the
15271 loop before all the candidates were examined, signal
15272 to the caller that this method failed. */
15273 if (rc
!= CURSOR_MOVEMENT_SUCCESS
15275 && !MATRIX_ROW_CONTINUATION_LINE_P (row
)
15276 && !row
->continued_p
))
15277 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
15279 rc
= CURSOR_MOVEMENT_SUCCESS
;
15285 if (set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0))
15287 rc
= CURSOR_MOVEMENT_SUCCESS
;
15292 while (MATRIX_ROW_BOTTOM_Y (row
) < last_y
15293 && MATRIX_ROW_START_CHARPOS (row
) == PT
15294 && cursor_row_p (row
));
15302 #if !defined USE_TOOLKIT_SCROLL_BARS || defined USE_GTK
15306 set_vertical_scroll_bar (struct window
*w
)
15308 ptrdiff_t start
, end
, whole
;
15310 /* Calculate the start and end positions for the current window.
15311 At some point, it would be nice to choose between scrollbars
15312 which reflect the whole buffer size, with special markers
15313 indicating narrowing, and scrollbars which reflect only the
15316 Note that mini-buffers sometimes aren't displaying any text. */
15317 if (!MINI_WINDOW_P (w
)
15318 || (w
== XWINDOW (minibuf_window
)
15319 && NILP (echo_area_buffer
[0])))
15321 struct buffer
*buf
= XBUFFER (w
->contents
);
15322 whole
= BUF_ZV (buf
) - BUF_BEGV (buf
);
15323 start
= marker_position (w
->start
) - BUF_BEGV (buf
);
15324 /* I don't think this is guaranteed to be right. For the
15325 moment, we'll pretend it is. */
15326 end
= BUF_Z (buf
) - w
->window_end_pos
- BUF_BEGV (buf
);
15330 if (whole
< (end
- start
))
15331 whole
= end
- start
;
15334 start
= end
= whole
= 0;
15336 /* Indicate what this scroll bar ought to be displaying now. */
15337 if (FRAME_TERMINAL (XFRAME (w
->frame
))->set_vertical_scroll_bar_hook
)
15338 (*FRAME_TERMINAL (XFRAME (w
->frame
))->set_vertical_scroll_bar_hook
)
15339 (w
, end
- start
, whole
, start
);
15343 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
15344 selected_window is redisplayed.
15346 We can return without actually redisplaying the window if fonts has been
15347 changed on window's frame. In that case, redisplay_internal will retry. */
15350 redisplay_window (Lisp_Object window
, int just_this_one_p
)
15352 struct window
*w
= XWINDOW (window
);
15353 struct frame
*f
= XFRAME (w
->frame
);
15354 struct buffer
*buffer
= XBUFFER (w
->contents
);
15355 struct buffer
*old
= current_buffer
;
15356 struct text_pos lpoint
, opoint
, startp
;
15357 int update_mode_line
;
15360 /* Record it now because it's overwritten. */
15361 int current_matrix_up_to_date_p
= 0;
15362 int used_current_matrix_p
= 0;
15363 /* This is less strict than current_matrix_up_to_date_p.
15364 It indicates that the buffer contents and narrowing are unchanged. */
15365 int buffer_unchanged_p
= 0;
15366 int temp_scroll_step
= 0;
15367 ptrdiff_t count
= SPECPDL_INDEX ();
15369 int centering_position
= -1;
15370 int last_line_misfit
= 0;
15371 ptrdiff_t beg_unchanged
, end_unchanged
;
15372 int frame_line_height
;
15374 SET_TEXT_POS (lpoint
, PT
, PT_BYTE
);
15378 *w
->desired_matrix
->method
= 0;
15381 /* Make sure that both W's markers are valid. */
15382 eassert (XMARKER (w
->start
)->buffer
== buffer
);
15383 eassert (XMARKER (w
->pointm
)->buffer
== buffer
);
15386 reconsider_clip_changes (w
);
15387 frame_line_height
= default_line_pixel_height (w
);
15389 /* Has the mode line to be updated? */
15390 update_mode_line
= (w
->update_mode_line
15391 || update_mode_lines
15392 || buffer
->clip_changed
15393 || buffer
->prevent_redisplay_optimizations_p
);
15395 if (MINI_WINDOW_P (w
))
15397 if (w
== XWINDOW (echo_area_window
)
15398 && !NILP (echo_area_buffer
[0]))
15400 if (update_mode_line
)
15401 /* We may have to update a tty frame's menu bar or a
15402 tool-bar. Example `M-x C-h C-h C-g'. */
15403 goto finish_menu_bars
;
15405 /* We've already displayed the echo area glyphs in this window. */
15406 goto finish_scroll_bars
;
15408 else if ((w
!= XWINDOW (minibuf_window
)
15409 || minibuf_level
== 0)
15410 /* When buffer is nonempty, redisplay window normally. */
15411 && BUF_Z (XBUFFER (w
->contents
)) == BUF_BEG (XBUFFER (w
->contents
))
15412 /* Quail displays non-mini buffers in minibuffer window.
15413 In that case, redisplay the window normally. */
15414 && !NILP (Fmemq (w
->contents
, Vminibuffer_list
)))
15416 /* W is a mini-buffer window, but it's not active, so clear
15418 int yb
= window_text_bottom_y (w
);
15419 struct glyph_row
*row
;
15422 for (y
= 0, row
= w
->desired_matrix
->rows
;
15424 y
+= row
->height
, ++row
)
15425 blank_row (w
, row
, y
);
15426 goto finish_scroll_bars
;
15429 clear_glyph_matrix (w
->desired_matrix
);
15432 /* Otherwise set up data on this window; select its buffer and point
15434 /* Really select the buffer, for the sake of buffer-local
15436 set_buffer_internal_1 (XBUFFER (w
->contents
));
15438 current_matrix_up_to_date_p
15439 = (w
->window_end_valid
15440 && !current_buffer
->clip_changed
15441 && !current_buffer
->prevent_redisplay_optimizations_p
15442 && !window_outdated (w
));
15444 /* Run the window-bottom-change-functions
15445 if it is possible that the text on the screen has changed
15446 (either due to modification of the text, or any other reason). */
15447 if (!current_matrix_up_to_date_p
15448 && !NILP (Vwindow_text_change_functions
))
15450 safe_run_hooks (Qwindow_text_change_functions
);
15454 beg_unchanged
= BEG_UNCHANGED
;
15455 end_unchanged
= END_UNCHANGED
;
15457 SET_TEXT_POS (opoint
, PT
, PT_BYTE
);
15459 specbind (Qinhibit_point_motion_hooks
, Qt
);
15462 = (w
->window_end_valid
15463 && !current_buffer
->clip_changed
15464 && !window_outdated (w
));
15466 /* When windows_or_buffers_changed is non-zero, we can't rely
15467 on the window end being valid, so set it to zero there. */
15468 if (windows_or_buffers_changed
)
15470 /* If window starts on a continuation line, maybe adjust the
15471 window start in case the window's width changed. */
15472 if (XMARKER (w
->start
)->buffer
== current_buffer
)
15473 compute_window_start_on_continuation_line (w
);
15475 w
->window_end_valid
= 0;
15476 /* If so, we also can't rely on current matrix
15477 and should not fool try_cursor_movement below. */
15478 current_matrix_up_to_date_p
= 0;
15481 /* Some sanity checks. */
15482 CHECK_WINDOW_END (w
);
15483 if (Z
== Z_BYTE
&& CHARPOS (opoint
) != BYTEPOS (opoint
))
15485 if (BYTEPOS (opoint
) < CHARPOS (opoint
))
15488 if (mode_line_update_needed (w
))
15489 update_mode_line
= 1;
15491 /* Point refers normally to the selected window. For any other
15492 window, set up appropriate value. */
15493 if (!EQ (window
, selected_window
))
15495 ptrdiff_t new_pt
= marker_position (w
->pointm
);
15496 ptrdiff_t new_pt_byte
= marker_byte_position (w
->pointm
);
15500 new_pt_byte
= BEGV_BYTE
;
15501 set_marker_both (w
->pointm
, Qnil
, BEGV
, BEGV_BYTE
);
15503 else if (new_pt
> (ZV
- 1))
15506 new_pt_byte
= ZV_BYTE
;
15507 set_marker_both (w
->pointm
, Qnil
, ZV
, ZV_BYTE
);
15510 /* We don't use SET_PT so that the point-motion hooks don't run. */
15511 TEMP_SET_PT_BOTH (new_pt
, new_pt_byte
);
15514 /* If any of the character widths specified in the display table
15515 have changed, invalidate the width run cache. It's true that
15516 this may be a bit late to catch such changes, but the rest of
15517 redisplay goes (non-fatally) haywire when the display table is
15518 changed, so why should we worry about doing any better? */
15519 if (current_buffer
->width_run_cache
)
15521 struct Lisp_Char_Table
*disptab
= buffer_display_table ();
15523 if (! disptab_matches_widthtab
15524 (disptab
, XVECTOR (BVAR (current_buffer
, width_table
))))
15526 invalidate_region_cache (current_buffer
,
15527 current_buffer
->width_run_cache
,
15529 recompute_width_table (current_buffer
, disptab
);
15533 /* If window-start is screwed up, choose a new one. */
15534 if (XMARKER (w
->start
)->buffer
!= current_buffer
)
15537 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
15539 /* If someone specified a new starting point but did not insist,
15540 check whether it can be used. */
15541 if (w
->optional_new_start
15542 && CHARPOS (startp
) >= BEGV
15543 && CHARPOS (startp
) <= ZV
)
15545 w
->optional_new_start
= 0;
15546 start_display (&it
, w
, startp
);
15547 move_it_to (&it
, PT
, 0, it
.last_visible_y
, -1,
15548 MOVE_TO_POS
| MOVE_TO_X
| MOVE_TO_Y
);
15549 if (IT_CHARPOS (it
) == PT
)
15550 w
->force_start
= 1;
15551 /* IT may overshoot PT if text at PT is invisible. */
15552 else if (IT_CHARPOS (it
) > PT
&& CHARPOS (startp
) <= PT
)
15553 w
->force_start
= 1;
15558 /* Handle case where place to start displaying has been specified,
15559 unless the specified location is outside the accessible range. */
15560 if (w
->force_start
|| window_frozen_p (w
))
15562 /* We set this later on if we have to adjust point. */
15565 w
->force_start
= 0;
15567 w
->window_end_valid
= 0;
15569 /* Forget any recorded base line for line number display. */
15570 if (!buffer_unchanged_p
)
15571 w
->base_line_number
= 0;
15573 /* Redisplay the mode line. Select the buffer properly for that.
15574 Also, run the hook window-scroll-functions
15575 because we have scrolled. */
15576 /* Note, we do this after clearing force_start because
15577 if there's an error, it is better to forget about force_start
15578 than to get into an infinite loop calling the hook functions
15579 and having them get more errors. */
15580 if (!update_mode_line
15581 || ! NILP (Vwindow_scroll_functions
))
15583 update_mode_line
= 1;
15584 w
->update_mode_line
= 1;
15585 startp
= run_window_scroll_functions (window
, startp
);
15588 if (CHARPOS (startp
) < BEGV
)
15589 SET_TEXT_POS (startp
, BEGV
, BEGV_BYTE
);
15590 else if (CHARPOS (startp
) > ZV
)
15591 SET_TEXT_POS (startp
, ZV
, ZV_BYTE
);
15593 /* Redisplay, then check if cursor has been set during the
15594 redisplay. Give up if new fonts were loaded. */
15595 /* We used to issue a CHECK_MARGINS argument to try_window here,
15596 but this causes scrolling to fail when point begins inside
15597 the scroll margin (bug#148) -- cyd */
15598 if (!try_window (window
, startp
, 0))
15600 w
->force_start
= 1;
15601 clear_glyph_matrix (w
->desired_matrix
);
15602 goto need_larger_matrices
;
15605 if (w
->cursor
.vpos
< 0 && !window_frozen_p (w
))
15607 /* If point does not appear, try to move point so it does
15608 appear. The desired matrix has been built above, so we
15609 can use it here. */
15610 new_vpos
= window_box_height (w
) / 2;
15613 if (!cursor_row_fully_visible_p (w
, 0, 0))
15615 /* Point does appear, but on a line partly visible at end of window.
15616 Move it back to a fully-visible line. */
15617 new_vpos
= window_box_height (w
);
15619 else if (w
->cursor
.vpos
>=0)
15621 /* Some people insist on not letting point enter the scroll
15622 margin, even though this part handles windows that didn't
15624 int window_total_lines
15625 = WINDOW_TOTAL_LINES (w
) * FRAME_LINE_HEIGHT (f
) / frame_line_height
;
15626 int margin
= min (scroll_margin
, window_total_lines
/ 4);
15627 int pixel_margin
= margin
* frame_line_height
;
15628 bool header_line
= WINDOW_WANTS_HEADER_LINE_P (w
);
15630 /* Note: We add an extra FRAME_LINE_HEIGHT, because the loop
15631 below, which finds the row to move point to, advances by
15632 the Y coordinate of the _next_ row, see the definition of
15633 MATRIX_ROW_BOTTOM_Y. */
15634 if (w
->cursor
.vpos
< margin
+ header_line
)
15636 w
->cursor
.vpos
= -1;
15637 clear_glyph_matrix (w
->desired_matrix
);
15638 goto try_to_scroll
;
15642 int window_height
= window_box_height (w
);
15645 window_height
+= CURRENT_HEADER_LINE_HEIGHT (w
);
15646 if (w
->cursor
.y
>= window_height
- pixel_margin
)
15648 w
->cursor
.vpos
= -1;
15649 clear_glyph_matrix (w
->desired_matrix
);
15650 goto try_to_scroll
;
15655 /* If we need to move point for either of the above reasons,
15656 now actually do it. */
15659 struct glyph_row
*row
;
15661 row
= MATRIX_FIRST_TEXT_ROW (w
->desired_matrix
);
15662 while (MATRIX_ROW_BOTTOM_Y (row
) < new_vpos
)
15665 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row
),
15666 MATRIX_ROW_START_BYTEPOS (row
));
15668 if (w
!= XWINDOW (selected_window
))
15669 set_marker_both (w
->pointm
, Qnil
, PT
, PT_BYTE
);
15670 else if (current_buffer
== old
)
15671 SET_TEXT_POS (lpoint
, PT
, PT_BYTE
);
15673 set_cursor_from_row (w
, row
, w
->desired_matrix
, 0, 0, 0, 0);
15675 /* If we are highlighting the region, then we just changed
15676 the region, so redisplay to show it. */
15677 if (markpos_of_region () >= 0)
15679 clear_glyph_matrix (w
->desired_matrix
);
15680 if (!try_window (window
, startp
, 0))
15681 goto need_larger_matrices
;
15686 debug_method_add (w
, "forced window start");
15691 /* Handle case where text has not changed, only point, and it has
15692 not moved off the frame, and we are not retrying after hscroll.
15693 (current_matrix_up_to_date_p is nonzero when retrying.) */
15694 if (current_matrix_up_to_date_p
15695 && (rc
= try_cursor_movement (window
, startp
, &temp_scroll_step
),
15696 rc
!= CURSOR_MOVEMENT_CANNOT_BE_USED
))
15700 case CURSOR_MOVEMENT_SUCCESS
:
15701 used_current_matrix_p
= 1;
15704 case CURSOR_MOVEMENT_MUST_SCROLL
:
15705 goto try_to_scroll
;
15711 /* If current starting point was originally the beginning of a line
15712 but no longer is, find a new starting point. */
15713 else if (w
->start_at_line_beg
15714 && !(CHARPOS (startp
) <= BEGV
15715 || FETCH_BYTE (BYTEPOS (startp
) - 1) == '\n'))
15718 debug_method_add (w
, "recenter 1");
15723 /* Try scrolling with try_window_id. Value is > 0 if update has
15724 been done, it is -1 if we know that the same window start will
15725 not work. It is 0 if unsuccessful for some other reason. */
15726 else if ((tem
= try_window_id (w
)) != 0)
15729 debug_method_add (w
, "try_window_id %d", tem
);
15732 if (f
->fonts_changed
)
15733 goto need_larger_matrices
;
15737 /* Otherwise try_window_id has returned -1 which means that we
15738 don't want the alternative below this comment to execute. */
15740 else if (CHARPOS (startp
) >= BEGV
15741 && CHARPOS (startp
) <= ZV
15742 && PT
>= CHARPOS (startp
)
15743 && (CHARPOS (startp
) < ZV
15744 /* Avoid starting at end of buffer. */
15745 || CHARPOS (startp
) == BEGV
15746 || !window_outdated (w
)))
15748 int d1
, d2
, d3
, d4
, d5
, d6
;
15750 /* If first window line is a continuation line, and window start
15751 is inside the modified region, but the first change is before
15752 current window start, we must select a new window start.
15754 However, if this is the result of a down-mouse event (e.g. by
15755 extending the mouse-drag-overlay), we don't want to select a
15756 new window start, since that would change the position under
15757 the mouse, resulting in an unwanted mouse-movement rather
15758 than a simple mouse-click. */
15759 if (!w
->start_at_line_beg
15760 && NILP (do_mouse_tracking
)
15761 && CHARPOS (startp
) > BEGV
15762 && CHARPOS (startp
) > BEG
+ beg_unchanged
15763 && CHARPOS (startp
) <= Z
- end_unchanged
15764 /* Even if w->start_at_line_beg is nil, a new window may
15765 start at a line_beg, since that's how set_buffer_window
15766 sets it. So, we need to check the return value of
15767 compute_window_start_on_continuation_line. (See also
15769 && XMARKER (w
->start
)->buffer
== current_buffer
15770 && compute_window_start_on_continuation_line (w
)
15771 /* It doesn't make sense to force the window start like we
15772 do at label force_start if it is already known that point
15773 will not be visible in the resulting window, because
15774 doing so will move point from its correct position
15775 instead of scrolling the window to bring point into view.
15777 && pos_visible_p (w
, PT
, &d1
, &d2
, &d3
, &d4
, &d5
, &d6
))
15779 w
->force_start
= 1;
15780 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
15785 debug_method_add (w
, "same window start");
15788 /* Try to redisplay starting at same place as before.
15789 If point has not moved off frame, accept the results. */
15790 if (!current_matrix_up_to_date_p
15791 /* Don't use try_window_reusing_current_matrix in this case
15792 because a window scroll function can have changed the
15794 || !NILP (Vwindow_scroll_functions
)
15795 || MINI_WINDOW_P (w
)
15796 || !(used_current_matrix_p
15797 = try_window_reusing_current_matrix (w
)))
15799 IF_DEBUG (debug_method_add (w
, "1"));
15800 if (try_window (window
, startp
, TRY_WINDOW_CHECK_MARGINS
) < 0)
15801 /* -1 means we need to scroll.
15802 0 means we need new matrices, but fonts_changed
15803 is set in that case, so we will detect it below. */
15804 goto try_to_scroll
;
15807 if (f
->fonts_changed
)
15808 goto need_larger_matrices
;
15810 if (w
->cursor
.vpos
>= 0)
15812 if (!just_this_one_p
15813 || current_buffer
->clip_changed
15814 || BEG_UNCHANGED
< CHARPOS (startp
))
15815 /* Forget any recorded base line for line number display. */
15816 w
->base_line_number
= 0;
15818 if (!cursor_row_fully_visible_p (w
, 1, 0))
15820 clear_glyph_matrix (w
->desired_matrix
);
15821 last_line_misfit
= 1;
15823 /* Drop through and scroll. */
15828 clear_glyph_matrix (w
->desired_matrix
);
15833 /* Redisplay the mode line. Select the buffer properly for that. */
15834 if (!update_mode_line
)
15836 update_mode_line
= 1;
15837 w
->update_mode_line
= 1;
15840 /* Try to scroll by specified few lines. */
15841 if ((scroll_conservatively
15842 || emacs_scroll_step
15843 || temp_scroll_step
15844 || NUMBERP (BVAR (current_buffer
, scroll_up_aggressively
))
15845 || NUMBERP (BVAR (current_buffer
, scroll_down_aggressively
)))
15846 && CHARPOS (startp
) >= BEGV
15847 && CHARPOS (startp
) <= ZV
)
15849 /* The function returns -1 if new fonts were loaded, 1 if
15850 successful, 0 if not successful. */
15851 int ss
= try_scrolling (window
, just_this_one_p
,
15852 scroll_conservatively
,
15854 temp_scroll_step
, last_line_misfit
);
15857 case SCROLLING_SUCCESS
:
15860 case SCROLLING_NEED_LARGER_MATRICES
:
15861 goto need_larger_matrices
;
15863 case SCROLLING_FAILED
:
15871 /* Finally, just choose a place to start which positions point
15872 according to user preferences. */
15877 debug_method_add (w
, "recenter");
15880 /* Forget any previously recorded base line for line number display. */
15881 if (!buffer_unchanged_p
)
15882 w
->base_line_number
= 0;
15884 /* Determine the window start relative to point. */
15885 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
15886 it
.current_y
= it
.last_visible_y
;
15887 if (centering_position
< 0)
15889 int window_total_lines
15890 = WINDOW_TOTAL_LINES (w
) * FRAME_LINE_HEIGHT (f
) / frame_line_height
;
15893 ? min (scroll_margin
, window_total_lines
/ 4)
15895 ptrdiff_t margin_pos
= CHARPOS (startp
);
15896 Lisp_Object aggressive
;
15899 /* If there is a scroll margin at the top of the window, find
15900 its character position. */
15902 /* Cannot call start_display if startp is not in the
15903 accessible region of the buffer. This can happen when we
15904 have just switched to a different buffer and/or changed
15905 its restriction. In that case, startp is initialized to
15906 the character position 1 (BEGV) because we did not yet
15907 have chance to display the buffer even once. */
15908 && BEGV
<= CHARPOS (startp
) && CHARPOS (startp
) <= ZV
)
15911 void *it1data
= NULL
;
15913 SAVE_IT (it1
, it
, it1data
);
15914 start_display (&it1
, w
, startp
);
15915 move_it_vertically (&it1
, margin
* frame_line_height
);
15916 margin_pos
= IT_CHARPOS (it1
);
15917 RESTORE_IT (&it
, &it
, it1data
);
15919 scrolling_up
= PT
> margin_pos
;
15922 ? BVAR (current_buffer
, scroll_up_aggressively
)
15923 : BVAR (current_buffer
, scroll_down_aggressively
);
15925 if (!MINI_WINDOW_P (w
)
15926 && (scroll_conservatively
> SCROLL_LIMIT
|| NUMBERP (aggressive
)))
15930 /* Setting scroll-conservatively overrides
15931 scroll-*-aggressively. */
15932 if (!scroll_conservatively
&& NUMBERP (aggressive
))
15934 double float_amount
= XFLOATINT (aggressive
);
15936 pt_offset
= float_amount
* WINDOW_BOX_TEXT_HEIGHT (w
);
15937 if (pt_offset
== 0 && float_amount
> 0)
15939 if (pt_offset
&& margin
> 0)
15942 /* Compute how much to move the window start backward from
15943 point so that point will be displayed where the user
15947 centering_position
= it
.last_visible_y
;
15949 centering_position
-= pt_offset
;
15950 centering_position
-=
15951 frame_line_height
* (1 + margin
+ (last_line_misfit
!= 0))
15952 + WINDOW_HEADER_LINE_HEIGHT (w
);
15953 /* Don't let point enter the scroll margin near top of
15955 if (centering_position
< margin
* frame_line_height
)
15956 centering_position
= margin
* frame_line_height
;
15959 centering_position
= margin
* frame_line_height
+ pt_offset
;
15962 /* Set the window start half the height of the window backward
15964 centering_position
= window_box_height (w
) / 2;
15966 move_it_vertically_backward (&it
, centering_position
);
15968 eassert (IT_CHARPOS (it
) >= BEGV
);
15970 /* The function move_it_vertically_backward may move over more
15971 than the specified y-distance. If it->w is small, e.g. a
15972 mini-buffer window, we may end up in front of the window's
15973 display area. Start displaying at the start of the line
15974 containing PT in this case. */
15975 if (it
.current_y
<= 0)
15977 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
15978 move_it_vertically_backward (&it
, 0);
15982 it
.current_x
= it
.hpos
= 0;
15984 /* Set the window start position here explicitly, to avoid an
15985 infinite loop in case the functions in window-scroll-functions
15987 set_marker_both (w
->start
, Qnil
, IT_CHARPOS (it
), IT_BYTEPOS (it
));
15989 /* Run scroll hooks. */
15990 startp
= run_window_scroll_functions (window
, it
.current
.pos
);
15992 /* Redisplay the window. */
15993 if (!current_matrix_up_to_date_p
15994 || windows_or_buffers_changed
15995 || f
->cursor_type_changed
15996 /* Don't use try_window_reusing_current_matrix in this case
15997 because it can have changed the buffer. */
15998 || !NILP (Vwindow_scroll_functions
)
15999 || !just_this_one_p
16000 || MINI_WINDOW_P (w
)
16001 || !(used_current_matrix_p
16002 = try_window_reusing_current_matrix (w
)))
16003 try_window (window
, startp
, 0);
16005 /* If new fonts have been loaded (due to fontsets), give up. We
16006 have to start a new redisplay since we need to re-adjust glyph
16008 if (f
->fonts_changed
)
16009 goto need_larger_matrices
;
16011 /* If cursor did not appear assume that the middle of the window is
16012 in the first line of the window. Do it again with the next line.
16013 (Imagine a window of height 100, displaying two lines of height
16014 60. Moving back 50 from it->last_visible_y will end in the first
16016 if (w
->cursor
.vpos
< 0)
16018 if (w
->window_end_valid
&& PT
>= Z
- w
->window_end_pos
)
16020 clear_glyph_matrix (w
->desired_matrix
);
16021 move_it_by_lines (&it
, 1);
16022 try_window (window
, it
.current
.pos
, 0);
16024 else if (PT
< IT_CHARPOS (it
))
16026 clear_glyph_matrix (w
->desired_matrix
);
16027 move_it_by_lines (&it
, -1);
16028 try_window (window
, it
.current
.pos
, 0);
16032 /* Not much we can do about it. */
16036 /* Consider the following case: Window starts at BEGV, there is
16037 invisible, intangible text at BEGV, so that display starts at
16038 some point START > BEGV. It can happen that we are called with
16039 PT somewhere between BEGV and START. Try to handle that case. */
16040 if (w
->cursor
.vpos
< 0)
16042 struct glyph_row
*row
= w
->current_matrix
->rows
;
16043 if (row
->mode_line_p
)
16045 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
16048 if (!cursor_row_fully_visible_p (w
, 0, 0))
16050 /* If vscroll is enabled, disable it and try again. */
16054 clear_glyph_matrix (w
->desired_matrix
);
16058 /* Users who set scroll-conservatively to a large number want
16059 point just above/below the scroll margin. If we ended up
16060 with point's row partially visible, move the window start to
16061 make that row fully visible and out of the margin. */
16062 if (scroll_conservatively
> SCROLL_LIMIT
)
16064 int window_total_lines
16065 = WINDOW_TOTAL_LINES (w
) * FRAME_LINE_HEIGHT (f
) * frame_line_height
;
16068 ? min (scroll_margin
, window_total_lines
/ 4)
16070 int move_down
= w
->cursor
.vpos
>= window_total_lines
/ 2;
16072 move_it_by_lines (&it
, move_down
? margin
+ 1 : -(margin
+ 1));
16073 clear_glyph_matrix (w
->desired_matrix
);
16074 if (1 == try_window (window
, it
.current
.pos
,
16075 TRY_WINDOW_CHECK_MARGINS
))
16079 /* If centering point failed to make the whole line visible,
16080 put point at the top instead. That has to make the whole line
16081 visible, if it can be done. */
16082 if (centering_position
== 0)
16085 clear_glyph_matrix (w
->desired_matrix
);
16086 centering_position
= 0;
16092 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
16093 w
->start_at_line_beg
= (CHARPOS (startp
) == BEGV
16094 || FETCH_BYTE (BYTEPOS (startp
) - 1) == '\n');
16096 /* Display the mode line, if we must. */
16097 if ((update_mode_line
16098 /* If window not full width, must redo its mode line
16099 if (a) the window to its side is being redone and
16100 (b) we do a frame-based redisplay. This is a consequence
16101 of how inverted lines are drawn in frame-based redisplay. */
16102 || (!just_this_one_p
16103 && !FRAME_WINDOW_P (f
)
16104 && !WINDOW_FULL_WIDTH_P (w
))
16105 /* Line number to display. */
16106 || w
->base_line_pos
> 0
16107 /* Column number is displayed and different from the one displayed. */
16108 || (w
->column_number_displayed
!= -1
16109 && (w
->column_number_displayed
!= current_column ())))
16110 /* This means that the window has a mode line. */
16111 && (WINDOW_WANTS_MODELINE_P (w
)
16112 || WINDOW_WANTS_HEADER_LINE_P (w
)))
16114 display_mode_lines (w
);
16116 /* If mode line height has changed, arrange for a thorough
16117 immediate redisplay using the correct mode line height. */
16118 if (WINDOW_WANTS_MODELINE_P (w
)
16119 && CURRENT_MODE_LINE_HEIGHT (w
) != DESIRED_MODE_LINE_HEIGHT (w
))
16121 f
->fonts_changed
= 1;
16122 w
->mode_line_height
= -1;
16123 MATRIX_MODE_LINE_ROW (w
->current_matrix
)->height
16124 = DESIRED_MODE_LINE_HEIGHT (w
);
16127 /* If header line height has changed, arrange for a thorough
16128 immediate redisplay using the correct header line height. */
16129 if (WINDOW_WANTS_HEADER_LINE_P (w
)
16130 && CURRENT_HEADER_LINE_HEIGHT (w
) != DESIRED_HEADER_LINE_HEIGHT (w
))
16132 f
->fonts_changed
= 1;
16133 w
->header_line_height
= -1;
16134 MATRIX_HEADER_LINE_ROW (w
->current_matrix
)->height
16135 = DESIRED_HEADER_LINE_HEIGHT (w
);
16138 if (f
->fonts_changed
)
16139 goto need_larger_matrices
;
16142 if (!line_number_displayed
&& w
->base_line_pos
!= -1)
16144 w
->base_line_pos
= 0;
16145 w
->base_line_number
= 0;
16150 /* When we reach a frame's selected window, redo the frame's menu bar. */
16151 if (update_mode_line
16152 && EQ (FRAME_SELECTED_WINDOW (f
), window
))
16154 int redisplay_menu_p
= 0;
16156 if (FRAME_WINDOW_P (f
))
16158 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
16159 || defined (HAVE_NS) || defined (USE_GTK)
16160 redisplay_menu_p
= FRAME_EXTERNAL_MENU_BAR (f
);
16162 redisplay_menu_p
= FRAME_MENU_BAR_LINES (f
) > 0;
16166 redisplay_menu_p
= FRAME_MENU_BAR_LINES (f
) > 0;
16168 if (redisplay_menu_p
)
16169 display_menu_bar (w
);
16171 #ifdef HAVE_WINDOW_SYSTEM
16172 if (FRAME_WINDOW_P (f
))
16174 #if defined (USE_GTK) || defined (HAVE_NS)
16175 if (FRAME_EXTERNAL_TOOL_BAR (f
))
16176 redisplay_tool_bar (f
);
16178 if (WINDOWP (f
->tool_bar_window
)
16179 && (FRAME_TOOL_BAR_LINES (f
) > 0
16180 || !NILP (Vauto_resize_tool_bars
))
16181 && redisplay_tool_bar (f
))
16182 ignore_mouse_drag_p
= 1;
16188 #ifdef HAVE_WINDOW_SYSTEM
16189 if (FRAME_WINDOW_P (f
)
16190 && update_window_fringes (w
, (just_this_one_p
16191 || (!used_current_matrix_p
&& !overlay_arrow_seen
)
16192 || w
->pseudo_window_p
)))
16196 if (draw_window_fringes (w
, 1))
16197 x_draw_vertical_border (w
);
16201 #endif /* HAVE_WINDOW_SYSTEM */
16203 /* We go to this label, with fonts_changed set, if it is
16204 necessary to try again using larger glyph matrices.
16205 We have to redeem the scroll bar even in this case,
16206 because the loop in redisplay_internal expects that. */
16207 need_larger_matrices
:
16209 finish_scroll_bars
:
16211 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w
))
16213 /* Set the thumb's position and size. */
16214 set_vertical_scroll_bar (w
);
16216 /* Note that we actually used the scroll bar attached to this
16217 window, so it shouldn't be deleted at the end of redisplay. */
16218 if (FRAME_TERMINAL (f
)->redeem_scroll_bar_hook
)
16219 (*FRAME_TERMINAL (f
)->redeem_scroll_bar_hook
) (w
);
16222 /* Restore current_buffer and value of point in it. The window
16223 update may have changed the buffer, so first make sure `opoint'
16224 is still valid (Bug#6177). */
16225 if (CHARPOS (opoint
) < BEGV
)
16226 TEMP_SET_PT_BOTH (BEGV
, BEGV_BYTE
);
16227 else if (CHARPOS (opoint
) > ZV
)
16228 TEMP_SET_PT_BOTH (Z
, Z_BYTE
);
16230 TEMP_SET_PT_BOTH (CHARPOS (opoint
), BYTEPOS (opoint
));
16232 set_buffer_internal_1 (old
);
16233 /* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become
16234 shorter. This can be caused by log truncation in *Messages*. */
16235 if (CHARPOS (lpoint
) <= ZV
)
16236 TEMP_SET_PT_BOTH (CHARPOS (lpoint
), BYTEPOS (lpoint
));
16238 unbind_to (count
, Qnil
);
16242 /* Build the complete desired matrix of WINDOW with a window start
16243 buffer position POS.
16245 Value is 1 if successful. It is zero if fonts were loaded during
16246 redisplay which makes re-adjusting glyph matrices necessary, and -1
16247 if point would appear in the scroll margins.
16248 (We check the former only if TRY_WINDOW_IGNORE_FONTS_CHANGE is
16249 unset in FLAGS, and the latter only if TRY_WINDOW_CHECK_MARGINS is
16253 try_window (Lisp_Object window
, struct text_pos pos
, int flags
)
16255 struct window
*w
= XWINDOW (window
);
16257 struct glyph_row
*last_text_row
= NULL
;
16258 struct frame
*f
= XFRAME (w
->frame
);
16259 int frame_line_height
= default_line_pixel_height (w
);
16261 /* Make POS the new window start. */
16262 set_marker_both (w
->start
, Qnil
, CHARPOS (pos
), BYTEPOS (pos
));
16264 /* Mark cursor position as unknown. No overlay arrow seen. */
16265 w
->cursor
.vpos
= -1;
16266 overlay_arrow_seen
= 0;
16268 /* Initialize iterator and info to start at POS. */
16269 start_display (&it
, w
, pos
);
16271 /* Display all lines of W. */
16272 while (it
.current_y
< it
.last_visible_y
)
16274 if (display_line (&it
))
16275 last_text_row
= it
.glyph_row
- 1;
16276 if (f
->fonts_changed
&& !(flags
& TRY_WINDOW_IGNORE_FONTS_CHANGE
))
16280 /* Don't let the cursor end in the scroll margins. */
16281 if ((flags
& TRY_WINDOW_CHECK_MARGINS
)
16282 && !MINI_WINDOW_P (w
))
16284 int this_scroll_margin
;
16285 int window_total_lines
16286 = WINDOW_TOTAL_LINES (w
) * FRAME_LINE_HEIGHT (f
) / frame_line_height
;
16288 if (scroll_margin
> 0)
16290 this_scroll_margin
= min (scroll_margin
, window_total_lines
/ 4);
16291 this_scroll_margin
*= frame_line_height
;
16294 this_scroll_margin
= 0;
16296 if ((w
->cursor
.y
>= 0 /* not vscrolled */
16297 && w
->cursor
.y
< this_scroll_margin
16298 && CHARPOS (pos
) > BEGV
16299 && IT_CHARPOS (it
) < ZV
)
16300 /* rms: considering make_cursor_line_fully_visible_p here
16301 seems to give wrong results. We don't want to recenter
16302 when the last line is partly visible, we want to allow
16303 that case to be handled in the usual way. */
16304 || w
->cursor
.y
> it
.last_visible_y
- this_scroll_margin
- 1)
16306 w
->cursor
.vpos
= -1;
16307 clear_glyph_matrix (w
->desired_matrix
);
16312 /* If bottom moved off end of frame, change mode line percentage. */
16313 if (w
->window_end_pos
<= 0 && Z
!= IT_CHARPOS (it
))
16314 w
->update_mode_line
= 1;
16316 /* Set window_end_pos to the offset of the last character displayed
16317 on the window from the end of current_buffer. Set
16318 window_end_vpos to its row number. */
16321 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row
));
16322 adjust_window_ends (w
, last_text_row
, 0);
16324 (MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w
->desired_matrix
,
16325 w
->window_end_vpos
)));
16329 w
->window_end_bytepos
= Z_BYTE
- ZV_BYTE
;
16330 w
->window_end_pos
= Z
- ZV
;
16331 w
->window_end_vpos
= 0;
16334 /* But that is not valid info until redisplay finishes. */
16335 w
->window_end_valid
= 0;
16341 /************************************************************************
16342 Window redisplay reusing current matrix when buffer has not changed
16343 ************************************************************************/
16345 /* Try redisplay of window W showing an unchanged buffer with a
16346 different window start than the last time it was displayed by
16347 reusing its current matrix. Value is non-zero if successful.
16348 W->start is the new window start. */
16351 try_window_reusing_current_matrix (struct window
*w
)
16353 struct frame
*f
= XFRAME (w
->frame
);
16354 struct glyph_row
*bottom_row
;
16357 struct text_pos start
, new_start
;
16358 int nrows_scrolled
, i
;
16359 struct glyph_row
*last_text_row
;
16360 struct glyph_row
*last_reused_text_row
;
16361 struct glyph_row
*start_row
;
16362 int start_vpos
, min_y
, max_y
;
16365 if (inhibit_try_window_reusing
)
16369 if (/* This function doesn't handle terminal frames. */
16370 !FRAME_WINDOW_P (f
)
16371 /* Don't try to reuse the display if windows have been split
16373 || windows_or_buffers_changed
16374 || f
->cursor_type_changed
)
16377 /* Can't do this if region may have changed. */
16378 if (markpos_of_region () >= 0
16379 || w
->region_showing
16380 || !NILP (Vshow_trailing_whitespace
))
16383 /* If top-line visibility has changed, give up. */
16384 if (WINDOW_WANTS_HEADER_LINE_P (w
)
16385 != MATRIX_HEADER_LINE_ROW (w
->current_matrix
)->mode_line_p
)
16388 /* Give up if old or new display is scrolled vertically. We could
16389 make this function handle this, but right now it doesn't. */
16390 start_row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
16391 if (w
->vscroll
|| MATRIX_ROW_PARTIALLY_VISIBLE_P (w
, start_row
))
16394 /* The variable new_start now holds the new window start. The old
16395 start `start' can be determined from the current matrix. */
16396 SET_TEXT_POS_FROM_MARKER (new_start
, w
->start
);
16397 start
= start_row
->minpos
;
16398 start_vpos
= MATRIX_ROW_VPOS (start_row
, w
->current_matrix
);
16400 /* Clear the desired matrix for the display below. */
16401 clear_glyph_matrix (w
->desired_matrix
);
16403 if (CHARPOS (new_start
) <= CHARPOS (start
))
16405 /* Don't use this method if the display starts with an ellipsis
16406 displayed for invisible text. It's not easy to handle that case
16407 below, and it's certainly not worth the effort since this is
16408 not a frequent case. */
16409 if (in_ellipses_for_invisible_text_p (&start_row
->start
, w
))
16412 IF_DEBUG (debug_method_add (w
, "twu1"));
16414 /* Display up to a row that can be reused. The variable
16415 last_text_row is set to the last row displayed that displays
16416 text. Note that it.vpos == 0 if or if not there is a
16417 header-line; it's not the same as the MATRIX_ROW_VPOS! */
16418 start_display (&it
, w
, new_start
);
16419 w
->cursor
.vpos
= -1;
16420 last_text_row
= last_reused_text_row
= NULL
;
16422 while (it
.current_y
< it
.last_visible_y
&& !f
->fonts_changed
)
16424 /* If we have reached into the characters in the START row,
16425 that means the line boundaries have changed. So we
16426 can't start copying with the row START. Maybe it will
16427 work to start copying with the following row. */
16428 while (IT_CHARPOS (it
) > CHARPOS (start
))
16430 /* Advance to the next row as the "start". */
16432 start
= start_row
->minpos
;
16433 /* If there are no more rows to try, or just one, give up. */
16434 if (start_row
== MATRIX_MODE_LINE_ROW (w
->current_matrix
) - 1
16435 || w
->vscroll
|| MATRIX_ROW_PARTIALLY_VISIBLE_P (w
, start_row
)
16436 || CHARPOS (start
) == ZV
)
16438 clear_glyph_matrix (w
->desired_matrix
);
16442 start_vpos
= MATRIX_ROW_VPOS (start_row
, w
->current_matrix
);
16444 /* If we have reached alignment, we can copy the rest of the
16446 if (IT_CHARPOS (it
) == CHARPOS (start
)
16447 /* Don't accept "alignment" inside a display vector,
16448 since start_row could have started in the middle of
16449 that same display vector (thus their character
16450 positions match), and we have no way of telling if
16451 that is the case. */
16452 && it
.current
.dpvec_index
< 0)
16455 if (display_line (&it
))
16456 last_text_row
= it
.glyph_row
- 1;
16460 /* A value of current_y < last_visible_y means that we stopped
16461 at the previous window start, which in turn means that we
16462 have at least one reusable row. */
16463 if (it
.current_y
< it
.last_visible_y
)
16465 struct glyph_row
*row
;
16467 /* IT.vpos always starts from 0; it counts text lines. */
16468 nrows_scrolled
= it
.vpos
- (start_row
- MATRIX_FIRST_TEXT_ROW (w
->current_matrix
));
16470 /* Find PT if not already found in the lines displayed. */
16471 if (w
->cursor
.vpos
< 0)
16473 int dy
= it
.current_y
- start_row
->y
;
16475 row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
16476 row
= row_containing_pos (w
, PT
, row
, NULL
, dy
);
16478 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0,
16479 dy
, nrows_scrolled
);
16482 clear_glyph_matrix (w
->desired_matrix
);
16487 /* Scroll the display. Do it before the current matrix is
16488 changed. The problem here is that update has not yet
16489 run, i.e. part of the current matrix is not up to date.
16490 scroll_run_hook will clear the cursor, and use the
16491 current matrix to get the height of the row the cursor is
16493 run
.current_y
= start_row
->y
;
16494 run
.desired_y
= it
.current_y
;
16495 run
.height
= it
.last_visible_y
- it
.current_y
;
16497 if (run
.height
> 0 && run
.current_y
!= run
.desired_y
)
16500 FRAME_RIF (f
)->update_window_begin_hook (w
);
16501 FRAME_RIF (f
)->clear_window_mouse_face (w
);
16502 FRAME_RIF (f
)->scroll_run_hook (w
, &run
);
16503 FRAME_RIF (f
)->update_window_end_hook (w
, 0, 0);
16507 /* Shift current matrix down by nrows_scrolled lines. */
16508 bottom_row
= MATRIX_BOTTOM_TEXT_ROW (w
->current_matrix
, w
);
16509 rotate_matrix (w
->current_matrix
,
16511 MATRIX_ROW_VPOS (bottom_row
, w
->current_matrix
),
16514 /* Disable lines that must be updated. */
16515 for (i
= 0; i
< nrows_scrolled
; ++i
)
16516 (start_row
+ i
)->enabled_p
= 0;
16518 /* Re-compute Y positions. */
16519 min_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
16520 max_y
= it
.last_visible_y
;
16521 for (row
= start_row
+ nrows_scrolled
;
16525 row
->y
= it
.current_y
;
16526 row
->visible_height
= row
->height
;
16528 if (row
->y
< min_y
)
16529 row
->visible_height
-= min_y
- row
->y
;
16530 if (row
->y
+ row
->height
> max_y
)
16531 row
->visible_height
-= row
->y
+ row
->height
- max_y
;
16532 if (row
->fringe_bitmap_periodic_p
)
16533 row
->redraw_fringe_bitmaps_p
= 1;
16535 it
.current_y
+= row
->height
;
16537 if (MATRIX_ROW_DISPLAYS_TEXT_P (row
))
16538 last_reused_text_row
= row
;
16539 if (MATRIX_ROW_BOTTOM_Y (row
) >= it
.last_visible_y
)
16543 /* Disable lines in the current matrix which are now
16544 below the window. */
16545 for (++row
; row
< bottom_row
; ++row
)
16546 row
->enabled_p
= row
->mode_line_p
= 0;
16549 /* Update window_end_pos etc.; last_reused_text_row is the last
16550 reused row from the current matrix containing text, if any.
16551 The value of last_text_row is the last displayed line
16552 containing text. */
16553 if (last_reused_text_row
)
16554 adjust_window_ends (w
, last_reused_text_row
, 1);
16555 else if (last_text_row
)
16556 adjust_window_ends (w
, last_text_row
, 0);
16559 /* This window must be completely empty. */
16560 w
->window_end_bytepos
= Z_BYTE
- ZV_BYTE
;
16561 w
->window_end_pos
= Z
- ZV
;
16562 w
->window_end_vpos
= 0;
16564 w
->window_end_valid
= 0;
16566 /* Update hint: don't try scrolling again in update_window. */
16567 w
->desired_matrix
->no_scrolling_p
= 1;
16570 debug_method_add (w
, "try_window_reusing_current_matrix 1");
16574 else if (CHARPOS (new_start
) > CHARPOS (start
))
16576 struct glyph_row
*pt_row
, *row
;
16577 struct glyph_row
*first_reusable_row
;
16578 struct glyph_row
*first_row_to_display
;
16580 int yb
= window_text_bottom_y (w
);
16582 /* Find the row starting at new_start, if there is one. Don't
16583 reuse a partially visible line at the end. */
16584 first_reusable_row
= start_row
;
16585 while (first_reusable_row
->enabled_p
16586 && MATRIX_ROW_BOTTOM_Y (first_reusable_row
) < yb
16587 && (MATRIX_ROW_START_CHARPOS (first_reusable_row
)
16588 < CHARPOS (new_start
)))
16589 ++first_reusable_row
;
16591 /* Give up if there is no row to reuse. */
16592 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row
) >= yb
16593 || !first_reusable_row
->enabled_p
16594 || (MATRIX_ROW_START_CHARPOS (first_reusable_row
)
16595 != CHARPOS (new_start
)))
16598 /* We can reuse fully visible rows beginning with
16599 first_reusable_row to the end of the window. Set
16600 first_row_to_display to the first row that cannot be reused.
16601 Set pt_row to the row containing point, if there is any. */
16603 for (first_row_to_display
= first_reusable_row
;
16604 MATRIX_ROW_BOTTOM_Y (first_row_to_display
) < yb
;
16605 ++first_row_to_display
)
16607 if (PT
>= MATRIX_ROW_START_CHARPOS (first_row_to_display
)
16608 && (PT
< MATRIX_ROW_END_CHARPOS (first_row_to_display
)
16609 || (PT
== MATRIX_ROW_END_CHARPOS (first_row_to_display
)
16610 && first_row_to_display
->ends_at_zv_p
16611 && pt_row
== NULL
)))
16612 pt_row
= first_row_to_display
;
16615 /* Start displaying at the start of first_row_to_display. */
16616 eassert (first_row_to_display
->y
< yb
);
16617 init_to_row_start (&it
, w
, first_row_to_display
);
16619 nrows_scrolled
= (MATRIX_ROW_VPOS (first_reusable_row
, w
->current_matrix
)
16621 it
.vpos
= (MATRIX_ROW_VPOS (first_row_to_display
, w
->current_matrix
)
16623 it
.current_y
= (first_row_to_display
->y
- first_reusable_row
->y
16624 + WINDOW_HEADER_LINE_HEIGHT (w
));
16626 /* Display lines beginning with first_row_to_display in the
16627 desired matrix. Set last_text_row to the last row displayed
16628 that displays text. */
16629 it
.glyph_row
= MATRIX_ROW (w
->desired_matrix
, it
.vpos
);
16630 if (pt_row
== NULL
)
16631 w
->cursor
.vpos
= -1;
16632 last_text_row
= NULL
;
16633 while (it
.current_y
< it
.last_visible_y
&& !f
->fonts_changed
)
16634 if (display_line (&it
))
16635 last_text_row
= it
.glyph_row
- 1;
16637 /* If point is in a reused row, adjust y and vpos of the cursor
16641 w
->cursor
.vpos
-= nrows_scrolled
;
16642 w
->cursor
.y
-= first_reusable_row
->y
- start_row
->y
;
16645 /* Give up if point isn't in a row displayed or reused. (This
16646 also handles the case where w->cursor.vpos < nrows_scrolled
16647 after the calls to display_line, which can happen with scroll
16648 margins. See bug#1295.) */
16649 if (w
->cursor
.vpos
< 0)
16651 clear_glyph_matrix (w
->desired_matrix
);
16655 /* Scroll the display. */
16656 run
.current_y
= first_reusable_row
->y
;
16657 run
.desired_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
16658 run
.height
= it
.last_visible_y
- run
.current_y
;
16659 dy
= run
.current_y
- run
.desired_y
;
16664 FRAME_RIF (f
)->update_window_begin_hook (w
);
16665 FRAME_RIF (f
)->clear_window_mouse_face (w
);
16666 FRAME_RIF (f
)->scroll_run_hook (w
, &run
);
16667 FRAME_RIF (f
)->update_window_end_hook (w
, 0, 0);
16671 /* Adjust Y positions of reused rows. */
16672 bottom_row
= MATRIX_BOTTOM_TEXT_ROW (w
->current_matrix
, w
);
16673 min_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
16674 max_y
= it
.last_visible_y
;
16675 for (row
= first_reusable_row
; row
< first_row_to_display
; ++row
)
16678 row
->visible_height
= row
->height
;
16679 if (row
->y
< min_y
)
16680 row
->visible_height
-= min_y
- row
->y
;
16681 if (row
->y
+ row
->height
> max_y
)
16682 row
->visible_height
-= row
->y
+ row
->height
- max_y
;
16683 if (row
->fringe_bitmap_periodic_p
)
16684 row
->redraw_fringe_bitmaps_p
= 1;
16687 /* Scroll the current matrix. */
16688 eassert (nrows_scrolled
> 0);
16689 rotate_matrix (w
->current_matrix
,
16691 MATRIX_ROW_VPOS (bottom_row
, w
->current_matrix
),
16694 /* Disable rows not reused. */
16695 for (row
-= nrows_scrolled
; row
< bottom_row
; ++row
)
16696 row
->enabled_p
= 0;
16698 /* Point may have moved to a different line, so we cannot assume that
16699 the previous cursor position is valid; locate the correct row. */
16702 for (row
= MATRIX_ROW (w
->current_matrix
, w
->cursor
.vpos
);
16704 && PT
>= MATRIX_ROW_END_CHARPOS (row
)
16705 && !row
->ends_at_zv_p
;
16709 w
->cursor
.y
= row
->y
;
16711 if (row
< bottom_row
)
16713 /* Can't simply scan the row for point with
16714 bidi-reordered glyph rows. Let set_cursor_from_row
16715 figure out where to put the cursor, and if it fails,
16717 if (!NILP (BVAR (XBUFFER (w
->contents
), bidi_display_reordering
)))
16719 if (!set_cursor_from_row (w
, row
, w
->current_matrix
,
16722 clear_glyph_matrix (w
->desired_matrix
);
16728 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
] + w
->cursor
.hpos
;
16729 struct glyph
*end
= row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
];
16732 && (!BUFFERP (glyph
->object
)
16733 || glyph
->charpos
< PT
);
16737 w
->cursor
.x
+= glyph
->pixel_width
;
16743 /* Adjust window end. A null value of last_text_row means that
16744 the window end is in reused rows which in turn means that
16745 only its vpos can have changed. */
16747 adjust_window_ends (w
, last_text_row
, 0);
16749 w
->window_end_vpos
-= nrows_scrolled
;
16751 w
->window_end_valid
= 0;
16752 w
->desired_matrix
->no_scrolling_p
= 1;
16755 debug_method_add (w
, "try_window_reusing_current_matrix 2");
16765 /************************************************************************
16766 Window redisplay reusing current matrix when buffer has changed
16767 ************************************************************************/
16769 static struct glyph_row
*find_last_unchanged_at_beg_row (struct window
*);
16770 static struct glyph_row
*find_first_unchanged_at_end_row (struct window
*,
16771 ptrdiff_t *, ptrdiff_t *);
16772 static struct glyph_row
*
16773 find_last_row_displaying_text (struct glyph_matrix
*, struct it
*,
16774 struct glyph_row
*);
16777 /* Return the last row in MATRIX displaying text. If row START is
16778 non-null, start searching with that row. IT gives the dimensions
16779 of the display. Value is null if matrix is empty; otherwise it is
16780 a pointer to the row found. */
16782 static struct glyph_row
*
16783 find_last_row_displaying_text (struct glyph_matrix
*matrix
, struct it
*it
,
16784 struct glyph_row
*start
)
16786 struct glyph_row
*row
, *row_found
;
16788 /* Set row_found to the last row in IT->w's current matrix
16789 displaying text. The loop looks funny but think of partially
16792 row
= start
? start
: MATRIX_FIRST_TEXT_ROW (matrix
);
16793 while (MATRIX_ROW_DISPLAYS_TEXT_P (row
))
16795 eassert (row
->enabled_p
);
16797 if (MATRIX_ROW_BOTTOM_Y (row
) >= it
->last_visible_y
)
16806 /* Return the last row in the current matrix of W that is not affected
16807 by changes at the start of current_buffer that occurred since W's
16808 current matrix was built. Value is null if no such row exists.
16810 BEG_UNCHANGED us the number of characters unchanged at the start of
16811 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
16812 first changed character in current_buffer. Characters at positions <
16813 BEG + BEG_UNCHANGED are at the same buffer positions as they were
16814 when the current matrix was built. */
16816 static struct glyph_row
*
16817 find_last_unchanged_at_beg_row (struct window
*w
)
16819 ptrdiff_t first_changed_pos
= BEG
+ BEG_UNCHANGED
;
16820 struct glyph_row
*row
;
16821 struct glyph_row
*row_found
= NULL
;
16822 int yb
= window_text_bottom_y (w
);
16824 /* Find the last row displaying unchanged text. */
16825 for (row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
16826 MATRIX_ROW_DISPLAYS_TEXT_P (row
)
16827 && MATRIX_ROW_START_CHARPOS (row
) < first_changed_pos
;
16830 if (/* If row ends before first_changed_pos, it is unchanged,
16831 except in some case. */
16832 MATRIX_ROW_END_CHARPOS (row
) <= first_changed_pos
16833 /* When row ends in ZV and we write at ZV it is not
16835 && !row
->ends_at_zv_p
16836 /* When first_changed_pos is the end of a continued line,
16837 row is not unchanged because it may be no longer
16839 && !(MATRIX_ROW_END_CHARPOS (row
) == first_changed_pos
16840 && (row
->continued_p
16841 || row
->exact_window_width_line_p
))
16842 /* If ROW->end is beyond ZV, then ROW->end is outdated and
16843 needs to be recomputed, so don't consider this row as
16844 unchanged. This happens when the last line was
16845 bidi-reordered and was killed immediately before this
16846 redisplay cycle. In that case, ROW->end stores the
16847 buffer position of the first visual-order character of
16848 the killed text, which is now beyond ZV. */
16849 && CHARPOS (row
->end
.pos
) <= ZV
)
16852 /* Stop if last visible row. */
16853 if (MATRIX_ROW_BOTTOM_Y (row
) >= yb
)
16861 /* Find the first glyph row in the current matrix of W that is not
16862 affected by changes at the end of current_buffer since the
16863 time W's current matrix was built.
16865 Return in *DELTA the number of chars by which buffer positions in
16866 unchanged text at the end of current_buffer must be adjusted.
16868 Return in *DELTA_BYTES the corresponding number of bytes.
16870 Value is null if no such row exists, i.e. all rows are affected by
16873 static struct glyph_row
*
16874 find_first_unchanged_at_end_row (struct window
*w
,
16875 ptrdiff_t *delta
, ptrdiff_t *delta_bytes
)
16877 struct glyph_row
*row
;
16878 struct glyph_row
*row_found
= NULL
;
16880 *delta
= *delta_bytes
= 0;
16882 /* Display must not have been paused, otherwise the current matrix
16883 is not up to date. */
16884 eassert (w
->window_end_valid
);
16886 /* A value of window_end_pos >= END_UNCHANGED means that the window
16887 end is in the range of changed text. If so, there is no
16888 unchanged row at the end of W's current matrix. */
16889 if (w
->window_end_pos
>= END_UNCHANGED
)
16892 /* Set row to the last row in W's current matrix displaying text. */
16893 row
= MATRIX_ROW (w
->current_matrix
, w
->window_end_vpos
);
16895 /* If matrix is entirely empty, no unchanged row exists. */
16896 if (MATRIX_ROW_DISPLAYS_TEXT_P (row
))
16898 /* The value of row is the last glyph row in the matrix having a
16899 meaningful buffer position in it. The end position of row
16900 corresponds to window_end_pos. This allows us to translate
16901 buffer positions in the current matrix to current buffer
16902 positions for characters not in changed text. */
16904 MATRIX_ROW_END_CHARPOS (row
) + w
->window_end_pos
;
16905 ptrdiff_t Z_BYTE_old
=
16906 MATRIX_ROW_END_BYTEPOS (row
) + w
->window_end_bytepos
;
16907 ptrdiff_t last_unchanged_pos
, last_unchanged_pos_old
;
16908 struct glyph_row
*first_text_row
16909 = MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
16911 *delta
= Z
- Z_old
;
16912 *delta_bytes
= Z_BYTE
- Z_BYTE_old
;
16914 /* Set last_unchanged_pos to the buffer position of the last
16915 character in the buffer that has not been changed. Z is the
16916 index + 1 of the last character in current_buffer, i.e. by
16917 subtracting END_UNCHANGED we get the index of the last
16918 unchanged character, and we have to add BEG to get its buffer
16920 last_unchanged_pos
= Z
- END_UNCHANGED
+ BEG
;
16921 last_unchanged_pos_old
= last_unchanged_pos
- *delta
;
16923 /* Search backward from ROW for a row displaying a line that
16924 starts at a minimum position >= last_unchanged_pos_old. */
16925 for (; row
> first_text_row
; --row
)
16927 /* This used to abort, but it can happen.
16928 It is ok to just stop the search instead here. KFS. */
16929 if (!row
->enabled_p
|| !MATRIX_ROW_DISPLAYS_TEXT_P (row
))
16932 if (MATRIX_ROW_START_CHARPOS (row
) >= last_unchanged_pos_old
)
16937 eassert (!row_found
|| MATRIX_ROW_DISPLAYS_TEXT_P (row_found
));
16943 /* Make sure that glyph rows in the current matrix of window W
16944 reference the same glyph memory as corresponding rows in the
16945 frame's frame matrix. This function is called after scrolling W's
16946 current matrix on a terminal frame in try_window_id and
16947 try_window_reusing_current_matrix. */
16950 sync_frame_with_window_matrix_rows (struct window
*w
)
16952 struct frame
*f
= XFRAME (w
->frame
);
16953 struct glyph_row
*window_row
, *window_row_end
, *frame_row
;
16955 /* Preconditions: W must be a leaf window and full-width. Its frame
16956 must have a frame matrix. */
16957 eassert (BUFFERP (w
->contents
));
16958 eassert (WINDOW_FULL_WIDTH_P (w
));
16959 eassert (!FRAME_WINDOW_P (f
));
16961 /* If W is a full-width window, glyph pointers in W's current matrix
16962 have, by definition, to be the same as glyph pointers in the
16963 corresponding frame matrix. Note that frame matrices have no
16964 marginal areas (see build_frame_matrix). */
16965 window_row
= w
->current_matrix
->rows
;
16966 window_row_end
= window_row
+ w
->current_matrix
->nrows
;
16967 frame_row
= f
->current_matrix
->rows
+ WINDOW_TOP_EDGE_LINE (w
);
16968 while (window_row
< window_row_end
)
16970 struct glyph
*start
= window_row
->glyphs
[LEFT_MARGIN_AREA
];
16971 struct glyph
*end
= window_row
->glyphs
[LAST_AREA
];
16973 frame_row
->glyphs
[LEFT_MARGIN_AREA
] = start
;
16974 frame_row
->glyphs
[TEXT_AREA
] = start
;
16975 frame_row
->glyphs
[RIGHT_MARGIN_AREA
] = end
;
16976 frame_row
->glyphs
[LAST_AREA
] = end
;
16978 /* Disable frame rows whose corresponding window rows have
16979 been disabled in try_window_id. */
16980 if (!window_row
->enabled_p
)
16981 frame_row
->enabled_p
= 0;
16983 ++window_row
, ++frame_row
;
16988 /* Find the glyph row in window W containing CHARPOS. Consider all
16989 rows between START and END (not inclusive). END null means search
16990 all rows to the end of the display area of W. Value is the row
16991 containing CHARPOS or null. */
16994 row_containing_pos (struct window
*w
, ptrdiff_t charpos
,
16995 struct glyph_row
*start
, struct glyph_row
*end
, int dy
)
16997 struct glyph_row
*row
= start
;
16998 struct glyph_row
*best_row
= NULL
;
16999 ptrdiff_t mindif
= BUF_ZV (XBUFFER (w
->contents
)) + 1;
17002 /* If we happen to start on a header-line, skip that. */
17003 if (row
->mode_line_p
)
17006 if ((end
&& row
>= end
) || !row
->enabled_p
)
17009 last_y
= window_text_bottom_y (w
) - dy
;
17013 /* Give up if we have gone too far. */
17014 if (end
&& row
>= end
)
17016 /* This formerly returned if they were equal.
17017 I think that both quantities are of a "last plus one" type;
17018 if so, when they are equal, the row is within the screen. -- rms. */
17019 if (MATRIX_ROW_BOTTOM_Y (row
) > last_y
)
17022 /* If it is in this row, return this row. */
17023 if (! (MATRIX_ROW_END_CHARPOS (row
) < charpos
17024 || (MATRIX_ROW_END_CHARPOS (row
) == charpos
17025 /* The end position of a row equals the start
17026 position of the next row. If CHARPOS is there, we
17027 would rather consider it displayed in the next
17028 line, except when this line ends in ZV. */
17029 && !row_for_charpos_p (row
, charpos
)))
17030 && charpos
>= MATRIX_ROW_START_CHARPOS (row
))
17034 if (NILP (BVAR (XBUFFER (w
->contents
), bidi_display_reordering
))
17035 || (!best_row
&& !row
->continued_p
))
17037 /* In bidi-reordered rows, there could be several rows whose
17038 edges surround CHARPOS, all of these rows belonging to
17039 the same continued line. We need to find the row which
17040 fits CHARPOS the best. */
17041 for (g
= row
->glyphs
[TEXT_AREA
];
17042 g
< row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
];
17045 if (!STRINGP (g
->object
))
17047 if (g
->charpos
> 0 && eabs (g
->charpos
- charpos
) < mindif
)
17049 mindif
= eabs (g
->charpos
- charpos
);
17051 /* Exact match always wins. */
17058 else if (best_row
&& !row
->continued_p
)
17065 /* Try to redisplay window W by reusing its existing display. W's
17066 current matrix must be up to date when this function is called,
17067 i.e. window_end_valid must be nonzero.
17071 1 if display has been updated
17072 0 if otherwise unsuccessful
17073 -1 if redisplay with same window start is known not to succeed
17075 The following steps are performed:
17077 1. Find the last row in the current matrix of W that is not
17078 affected by changes at the start of current_buffer. If no such row
17081 2. Find the first row in W's current matrix that is not affected by
17082 changes at the end of current_buffer. Maybe there is no such row.
17084 3. Display lines beginning with the row + 1 found in step 1 to the
17085 row found in step 2 or, if step 2 didn't find a row, to the end of
17088 4. If cursor is not known to appear on the window, give up.
17090 5. If display stopped at the row found in step 2, scroll the
17091 display and current matrix as needed.
17093 6. Maybe display some lines at the end of W, if we must. This can
17094 happen under various circumstances, like a partially visible line
17095 becoming fully visible, or because newly displayed lines are displayed
17096 in smaller font sizes.
17098 7. Update W's window end information. */
17101 try_window_id (struct window
*w
)
17103 struct frame
*f
= XFRAME (w
->frame
);
17104 struct glyph_matrix
*current_matrix
= w
->current_matrix
;
17105 struct glyph_matrix
*desired_matrix
= w
->desired_matrix
;
17106 struct glyph_row
*last_unchanged_at_beg_row
;
17107 struct glyph_row
*first_unchanged_at_end_row
;
17108 struct glyph_row
*row
;
17109 struct glyph_row
*bottom_row
;
17112 ptrdiff_t delta
= 0, delta_bytes
= 0, stop_pos
;
17114 struct text_pos start_pos
;
17116 int first_unchanged_at_end_vpos
= 0;
17117 struct glyph_row
*last_text_row
, *last_text_row_at_end
;
17118 struct text_pos start
;
17119 ptrdiff_t first_changed_charpos
, last_changed_charpos
;
17122 if (inhibit_try_window_id
)
17126 /* This is handy for debugging. */
17128 #define GIVE_UP(X) \
17130 fprintf (stderr, "try_window_id give up %d\n", (X)); \
17134 #define GIVE_UP(X) return 0
17137 SET_TEXT_POS_FROM_MARKER (start
, w
->start
);
17139 /* Don't use this for mini-windows because these can show
17140 messages and mini-buffers, and we don't handle that here. */
17141 if (MINI_WINDOW_P (w
))
17144 /* This flag is used to prevent redisplay optimizations. */
17145 if (windows_or_buffers_changed
|| f
->cursor_type_changed
)
17148 /* Verify that narrowing has not changed.
17149 Also verify that we were not told to prevent redisplay optimizations.
17150 It would be nice to further
17151 reduce the number of cases where this prevents try_window_id. */
17152 if (current_buffer
->clip_changed
17153 || current_buffer
->prevent_redisplay_optimizations_p
)
17156 /* Window must either use window-based redisplay or be full width. */
17157 if (!FRAME_WINDOW_P (f
)
17158 && (!FRAME_LINE_INS_DEL_OK (f
)
17159 || !WINDOW_FULL_WIDTH_P (w
)))
17162 /* Give up if point is known NOT to appear in W. */
17163 if (PT
< CHARPOS (start
))
17166 /* Another way to prevent redisplay optimizations. */
17167 if (w
->last_modified
== 0)
17170 /* Verify that window is not hscrolled. */
17171 if (w
->hscroll
!= 0)
17174 /* Verify that display wasn't paused. */
17175 if (!w
->window_end_valid
)
17178 /* Can't use this if highlighting a region because a cursor movement
17179 will do more than just set the cursor. */
17180 if (markpos_of_region () >= 0)
17183 /* Likewise if highlighting trailing whitespace. */
17184 if (!NILP (Vshow_trailing_whitespace
))
17187 /* Likewise if showing a region. */
17188 if (w
->region_showing
)
17191 /* Can't use this if overlay arrow position and/or string have
17193 if (overlay_arrows_changed_p ())
17196 /* When word-wrap is on, adding a space to the first word of a
17197 wrapped line can change the wrap position, altering the line
17198 above it. It might be worthwhile to handle this more
17199 intelligently, but for now just redisplay from scratch. */
17200 if (!NILP (BVAR (XBUFFER (w
->contents
), word_wrap
)))
17203 /* Under bidi reordering, adding or deleting a character in the
17204 beginning of a paragraph, before the first strong directional
17205 character, can change the base direction of the paragraph (unless
17206 the buffer specifies a fixed paragraph direction), which will
17207 require to redisplay the whole paragraph. It might be worthwhile
17208 to find the paragraph limits and widen the range of redisplayed
17209 lines to that, but for now just give up this optimization and
17210 redisplay from scratch. */
17211 if (!NILP (BVAR (XBUFFER (w
->contents
), bidi_display_reordering
))
17212 && NILP (BVAR (XBUFFER (w
->contents
), bidi_paragraph_direction
)))
17215 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
17216 only if buffer has really changed. The reason is that the gap is
17217 initially at Z for freshly visited files. The code below would
17218 set end_unchanged to 0 in that case. */
17219 if (MODIFF
> SAVE_MODIFF
17220 /* This seems to happen sometimes after saving a buffer. */
17221 || BEG_UNCHANGED
+ END_UNCHANGED
> Z_BYTE
)
17223 if (GPT
- BEG
< BEG_UNCHANGED
)
17224 BEG_UNCHANGED
= GPT
- BEG
;
17225 if (Z
- GPT
< END_UNCHANGED
)
17226 END_UNCHANGED
= Z
- GPT
;
17229 /* The position of the first and last character that has been changed. */
17230 first_changed_charpos
= BEG
+ BEG_UNCHANGED
;
17231 last_changed_charpos
= Z
- END_UNCHANGED
;
17233 /* If window starts after a line end, and the last change is in
17234 front of that newline, then changes don't affect the display.
17235 This case happens with stealth-fontification. Note that although
17236 the display is unchanged, glyph positions in the matrix have to
17237 be adjusted, of course. */
17238 row
= MATRIX_ROW (w
->current_matrix
, w
->window_end_vpos
);
17239 if (MATRIX_ROW_DISPLAYS_TEXT_P (row
)
17240 && ((last_changed_charpos
< CHARPOS (start
)
17241 && CHARPOS (start
) == BEGV
)
17242 || (last_changed_charpos
< CHARPOS (start
) - 1
17243 && FETCH_BYTE (BYTEPOS (start
) - 1) == '\n')))
17245 ptrdiff_t Z_old
, Z_delta
, Z_BYTE_old
, Z_delta_bytes
;
17246 struct glyph_row
*r0
;
17248 /* Compute how many chars/bytes have been added to or removed
17249 from the buffer. */
17250 Z_old
= MATRIX_ROW_END_CHARPOS (row
) + w
->window_end_pos
;
17251 Z_BYTE_old
= MATRIX_ROW_END_BYTEPOS (row
) + w
->window_end_bytepos
;
17252 Z_delta
= Z
- Z_old
;
17253 Z_delta_bytes
= Z_BYTE
- Z_BYTE_old
;
17255 /* Give up if PT is not in the window. Note that it already has
17256 been checked at the start of try_window_id that PT is not in
17257 front of the window start. */
17258 if (PT
>= MATRIX_ROW_END_CHARPOS (row
) + Z_delta
)
17261 /* If window start is unchanged, we can reuse the whole matrix
17262 as is, after adjusting glyph positions. No need to compute
17263 the window end again, since its offset from Z hasn't changed. */
17264 r0
= MATRIX_FIRST_TEXT_ROW (current_matrix
);
17265 if (CHARPOS (start
) == MATRIX_ROW_START_CHARPOS (r0
) + Z_delta
17266 && BYTEPOS (start
) == MATRIX_ROW_START_BYTEPOS (r0
) + Z_delta_bytes
17267 /* PT must not be in a partially visible line. */
17268 && !(PT
>= MATRIX_ROW_START_CHARPOS (row
) + Z_delta
17269 && MATRIX_ROW_BOTTOM_Y (row
) > window_text_bottom_y (w
)))
17271 /* Adjust positions in the glyph matrix. */
17272 if (Z_delta
|| Z_delta_bytes
)
17274 struct glyph_row
*r1
17275 = MATRIX_BOTTOM_TEXT_ROW (current_matrix
, w
);
17276 increment_matrix_positions (w
->current_matrix
,
17277 MATRIX_ROW_VPOS (r0
, current_matrix
),
17278 MATRIX_ROW_VPOS (r1
, current_matrix
),
17279 Z_delta
, Z_delta_bytes
);
17282 /* Set the cursor. */
17283 row
= row_containing_pos (w
, PT
, r0
, NULL
, 0);
17285 set_cursor_from_row (w
, row
, current_matrix
, 0, 0, 0, 0);
17292 /* Handle the case that changes are all below what is displayed in
17293 the window, and that PT is in the window. This shortcut cannot
17294 be taken if ZV is visible in the window, and text has been added
17295 there that is visible in the window. */
17296 if (first_changed_charpos
>= MATRIX_ROW_END_CHARPOS (row
)
17297 /* ZV is not visible in the window, or there are no
17298 changes at ZV, actually. */
17299 && (current_matrix
->zv
> MATRIX_ROW_END_CHARPOS (row
)
17300 || first_changed_charpos
== last_changed_charpos
))
17302 struct glyph_row
*r0
;
17304 /* Give up if PT is not in the window. Note that it already has
17305 been checked at the start of try_window_id that PT is not in
17306 front of the window start. */
17307 if (PT
>= MATRIX_ROW_END_CHARPOS (row
))
17310 /* If window start is unchanged, we can reuse the whole matrix
17311 as is, without changing glyph positions since no text has
17312 been added/removed in front of the window end. */
17313 r0
= MATRIX_FIRST_TEXT_ROW (current_matrix
);
17314 if (TEXT_POS_EQUAL_P (start
, r0
->minpos
)
17315 /* PT must not be in a partially visible line. */
17316 && !(PT
>= MATRIX_ROW_START_CHARPOS (row
)
17317 && MATRIX_ROW_BOTTOM_Y (row
) > window_text_bottom_y (w
)))
17319 /* We have to compute the window end anew since text
17320 could have been added/removed after it. */
17321 w
->window_end_pos
= Z
- MATRIX_ROW_END_CHARPOS (row
);
17322 w
->window_end_bytepos
= Z_BYTE
- MATRIX_ROW_END_BYTEPOS (row
);
17324 /* Set the cursor. */
17325 row
= row_containing_pos (w
, PT
, r0
, NULL
, 0);
17327 set_cursor_from_row (w
, row
, current_matrix
, 0, 0, 0, 0);
17334 /* Give up if window start is in the changed area.
17336 The condition used to read
17338 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
17340 but why that was tested escapes me at the moment. */
17341 if (CHARPOS (start
) >= first_changed_charpos
17342 && CHARPOS (start
) <= last_changed_charpos
)
17345 /* Check that window start agrees with the start of the first glyph
17346 row in its current matrix. Check this after we know the window
17347 start is not in changed text, otherwise positions would not be
17349 row
= MATRIX_FIRST_TEXT_ROW (current_matrix
);
17350 if (!TEXT_POS_EQUAL_P (start
, row
->minpos
))
17353 /* Give up if the window ends in strings. Overlay strings
17354 at the end are difficult to handle, so don't try. */
17355 row
= MATRIX_ROW (current_matrix
, w
->window_end_vpos
);
17356 if (MATRIX_ROW_START_CHARPOS (row
) == MATRIX_ROW_END_CHARPOS (row
))
17359 /* Compute the position at which we have to start displaying new
17360 lines. Some of the lines at the top of the window might be
17361 reusable because they are not displaying changed text. Find the
17362 last row in W's current matrix not affected by changes at the
17363 start of current_buffer. Value is null if changes start in the
17364 first line of window. */
17365 last_unchanged_at_beg_row
= find_last_unchanged_at_beg_row (w
);
17366 if (last_unchanged_at_beg_row
)
17368 /* Avoid starting to display in the middle of a character, a TAB
17369 for instance. This is easier than to set up the iterator
17370 exactly, and it's not a frequent case, so the additional
17371 effort wouldn't really pay off. */
17372 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row
)
17373 || last_unchanged_at_beg_row
->ends_in_newline_from_string_p
)
17374 && last_unchanged_at_beg_row
> w
->current_matrix
->rows
)
17375 --last_unchanged_at_beg_row
;
17377 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row
))
17380 if (init_to_row_end (&it
, w
, last_unchanged_at_beg_row
) == 0)
17382 start_pos
= it
.current
.pos
;
17384 /* Start displaying new lines in the desired matrix at the same
17385 vpos we would use in the current matrix, i.e. below
17386 last_unchanged_at_beg_row. */
17387 it
.vpos
= 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row
,
17389 it
.glyph_row
= MATRIX_ROW (desired_matrix
, it
.vpos
);
17390 it
.current_y
= MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row
);
17392 eassert (it
.hpos
== 0 && it
.current_x
== 0);
17396 /* There are no reusable lines at the start of the window.
17397 Start displaying in the first text line. */
17398 start_display (&it
, w
, start
);
17399 it
.vpos
= it
.first_vpos
;
17400 start_pos
= it
.current
.pos
;
17403 /* Find the first row that is not affected by changes at the end of
17404 the buffer. Value will be null if there is no unchanged row, in
17405 which case we must redisplay to the end of the window. delta
17406 will be set to the value by which buffer positions beginning with
17407 first_unchanged_at_end_row have to be adjusted due to text
17409 first_unchanged_at_end_row
17410 = find_first_unchanged_at_end_row (w
, &delta
, &delta_bytes
);
17411 IF_DEBUG (debug_delta
= delta
);
17412 IF_DEBUG (debug_delta_bytes
= delta_bytes
);
17414 /* Set stop_pos to the buffer position up to which we will have to
17415 display new lines. If first_unchanged_at_end_row != NULL, this
17416 is the buffer position of the start of the line displayed in that
17417 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
17418 that we don't stop at a buffer position. */
17420 if (first_unchanged_at_end_row
)
17422 eassert (last_unchanged_at_beg_row
== NULL
17423 || first_unchanged_at_end_row
>= last_unchanged_at_beg_row
);
17425 /* If this is a continuation line, move forward to the next one
17426 that isn't. Changes in lines above affect this line.
17427 Caution: this may move first_unchanged_at_end_row to a row
17428 not displaying text. */
17429 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row
)
17430 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row
)
17431 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row
)
17432 < it
.last_visible_y
))
17433 ++first_unchanged_at_end_row
;
17435 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row
)
17436 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row
)
17437 >= it
.last_visible_y
))
17438 first_unchanged_at_end_row
= NULL
;
17441 stop_pos
= (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row
)
17443 first_unchanged_at_end_vpos
17444 = MATRIX_ROW_VPOS (first_unchanged_at_end_row
, current_matrix
);
17445 eassert (stop_pos
>= Z
- END_UNCHANGED
);
17448 else if (last_unchanged_at_beg_row
== NULL
)
17454 /* Either there is no unchanged row at the end, or the one we have
17455 now displays text. This is a necessary condition for the window
17456 end pos calculation at the end of this function. */
17457 eassert (first_unchanged_at_end_row
== NULL
17458 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row
));
17460 debug_last_unchanged_at_beg_vpos
17461 = (last_unchanged_at_beg_row
17462 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row
, current_matrix
)
17464 debug_first_unchanged_at_end_vpos
= first_unchanged_at_end_vpos
;
17466 #endif /* GLYPH_DEBUG */
17469 /* Display new lines. Set last_text_row to the last new line
17470 displayed which has text on it, i.e. might end up as being the
17471 line where the window_end_vpos is. */
17472 w
->cursor
.vpos
= -1;
17473 last_text_row
= NULL
;
17474 overlay_arrow_seen
= 0;
17475 while (it
.current_y
< it
.last_visible_y
17476 && !f
->fonts_changed
17477 && (first_unchanged_at_end_row
== NULL
17478 || IT_CHARPOS (it
) < stop_pos
))
17480 if (display_line (&it
))
17481 last_text_row
= it
.glyph_row
- 1;
17484 if (f
->fonts_changed
)
17488 /* Compute differences in buffer positions, y-positions etc. for
17489 lines reused at the bottom of the window. Compute what we can
17491 if (first_unchanged_at_end_row
17492 /* No lines reused because we displayed everything up to the
17493 bottom of the window. */
17494 && it
.current_y
< it
.last_visible_y
)
17497 - MATRIX_ROW_VPOS (first_unchanged_at_end_row
,
17499 dy
= it
.current_y
- first_unchanged_at_end_row
->y
;
17500 run
.current_y
= first_unchanged_at_end_row
->y
;
17501 run
.desired_y
= run
.current_y
+ dy
;
17502 run
.height
= it
.last_visible_y
- max (run
.current_y
, run
.desired_y
);
17506 delta
= delta_bytes
= dvpos
= dy
17507 = run
.current_y
= run
.desired_y
= run
.height
= 0;
17508 first_unchanged_at_end_row
= NULL
;
17510 IF_DEBUG (debug_dvpos
= dvpos
; debug_dy
= dy
);
17513 /* Find the cursor if not already found. We have to decide whether
17514 PT will appear on this window (it sometimes doesn't, but this is
17515 not a very frequent case.) This decision has to be made before
17516 the current matrix is altered. A value of cursor.vpos < 0 means
17517 that PT is either in one of the lines beginning at
17518 first_unchanged_at_end_row or below the window. Don't care for
17519 lines that might be displayed later at the window end; as
17520 mentioned, this is not a frequent case. */
17521 if (w
->cursor
.vpos
< 0)
17523 /* Cursor in unchanged rows at the top? */
17524 if (PT
< CHARPOS (start_pos
)
17525 && last_unchanged_at_beg_row
)
17527 row
= row_containing_pos (w
, PT
,
17528 MATRIX_FIRST_TEXT_ROW (w
->current_matrix
),
17529 last_unchanged_at_beg_row
+ 1, 0);
17531 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
17534 /* Start from first_unchanged_at_end_row looking for PT. */
17535 else if (first_unchanged_at_end_row
)
17537 row
= row_containing_pos (w
, PT
- delta
,
17538 first_unchanged_at_end_row
, NULL
, 0);
17540 set_cursor_from_row (w
, row
, w
->current_matrix
, delta
,
17541 delta_bytes
, dy
, dvpos
);
17544 /* Give up if cursor was not found. */
17545 if (w
->cursor
.vpos
< 0)
17547 clear_glyph_matrix (w
->desired_matrix
);
17552 /* Don't let the cursor end in the scroll margins. */
17554 int this_scroll_margin
, cursor_height
;
17555 int frame_line_height
= default_line_pixel_height (w
);
17556 int window_total_lines
17557 = WINDOW_TOTAL_LINES (w
) * FRAME_LINE_HEIGHT (it
.f
) / frame_line_height
;
17559 this_scroll_margin
=
17560 max (0, min (scroll_margin
, window_total_lines
/ 4));
17561 this_scroll_margin
*= frame_line_height
;
17562 cursor_height
= MATRIX_ROW (w
->desired_matrix
, w
->cursor
.vpos
)->height
;
17564 if ((w
->cursor
.y
< this_scroll_margin
17565 && CHARPOS (start
) > BEGV
)
17566 /* Old redisplay didn't take scroll margin into account at the bottom,
17567 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
17568 || (w
->cursor
.y
+ (make_cursor_line_fully_visible_p
17569 ? cursor_height
+ this_scroll_margin
17570 : 1)) > it
.last_visible_y
)
17572 w
->cursor
.vpos
= -1;
17573 clear_glyph_matrix (w
->desired_matrix
);
17578 /* Scroll the display. Do it before changing the current matrix so
17579 that xterm.c doesn't get confused about where the cursor glyph is
17581 if (dy
&& run
.height
)
17585 if (FRAME_WINDOW_P (f
))
17587 FRAME_RIF (f
)->update_window_begin_hook (w
);
17588 FRAME_RIF (f
)->clear_window_mouse_face (w
);
17589 FRAME_RIF (f
)->scroll_run_hook (w
, &run
);
17590 FRAME_RIF (f
)->update_window_end_hook (w
, 0, 0);
17594 /* Terminal frame. In this case, dvpos gives the number of
17595 lines to scroll by; dvpos < 0 means scroll up. */
17597 = MATRIX_ROW_VPOS (first_unchanged_at_end_row
, w
->current_matrix
);
17598 int from
= WINDOW_TOP_EDGE_LINE (w
) + from_vpos
;
17599 int end
= (WINDOW_TOP_EDGE_LINE (w
)
17600 + (WINDOW_WANTS_HEADER_LINE_P (w
) ? 1 : 0)
17601 + window_internal_height (w
));
17603 #if defined (HAVE_GPM) || defined (MSDOS)
17604 x_clear_window_mouse_face (w
);
17606 /* Perform the operation on the screen. */
17609 /* Scroll last_unchanged_at_beg_row to the end of the
17610 window down dvpos lines. */
17611 set_terminal_window (f
, end
);
17613 /* On dumb terminals delete dvpos lines at the end
17614 before inserting dvpos empty lines. */
17615 if (!FRAME_SCROLL_REGION_OK (f
))
17616 ins_del_lines (f
, end
- dvpos
, -dvpos
);
17618 /* Insert dvpos empty lines in front of
17619 last_unchanged_at_beg_row. */
17620 ins_del_lines (f
, from
, dvpos
);
17622 else if (dvpos
< 0)
17624 /* Scroll up last_unchanged_at_beg_vpos to the end of
17625 the window to last_unchanged_at_beg_vpos - |dvpos|. */
17626 set_terminal_window (f
, end
);
17628 /* Delete dvpos lines in front of
17629 last_unchanged_at_beg_vpos. ins_del_lines will set
17630 the cursor to the given vpos and emit |dvpos| delete
17632 ins_del_lines (f
, from
+ dvpos
, dvpos
);
17634 /* On a dumb terminal insert dvpos empty lines at the
17636 if (!FRAME_SCROLL_REGION_OK (f
))
17637 ins_del_lines (f
, end
+ dvpos
, -dvpos
);
17640 set_terminal_window (f
, 0);
17646 /* Shift reused rows of the current matrix to the right position.
17647 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
17649 bottom_row
= MATRIX_BOTTOM_TEXT_ROW (current_matrix
, w
);
17650 bottom_vpos
= MATRIX_ROW_VPOS (bottom_row
, current_matrix
);
17653 rotate_matrix (current_matrix
, first_unchanged_at_end_vpos
+ dvpos
,
17654 bottom_vpos
, dvpos
);
17655 clear_glyph_matrix_rows (current_matrix
, bottom_vpos
+ dvpos
,
17658 else if (dvpos
> 0)
17660 rotate_matrix (current_matrix
, first_unchanged_at_end_vpos
,
17661 bottom_vpos
, dvpos
);
17662 clear_glyph_matrix_rows (current_matrix
, first_unchanged_at_end_vpos
,
17663 first_unchanged_at_end_vpos
+ dvpos
);
17666 /* For frame-based redisplay, make sure that current frame and window
17667 matrix are in sync with respect to glyph memory. */
17668 if (!FRAME_WINDOW_P (f
))
17669 sync_frame_with_window_matrix_rows (w
);
17671 /* Adjust buffer positions in reused rows. */
17672 if (delta
|| delta_bytes
)
17673 increment_matrix_positions (current_matrix
,
17674 first_unchanged_at_end_vpos
+ dvpos
,
17675 bottom_vpos
, delta
, delta_bytes
);
17677 /* Adjust Y positions. */
17679 shift_glyph_matrix (w
, current_matrix
,
17680 first_unchanged_at_end_vpos
+ dvpos
,
17683 if (first_unchanged_at_end_row
)
17685 first_unchanged_at_end_row
+= dvpos
;
17686 if (first_unchanged_at_end_row
->y
>= it
.last_visible_y
17687 || !MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row
))
17688 first_unchanged_at_end_row
= NULL
;
17691 /* If scrolling up, there may be some lines to display at the end of
17693 last_text_row_at_end
= NULL
;
17696 /* Scrolling up can leave for example a partially visible line
17697 at the end of the window to be redisplayed. */
17698 /* Set last_row to the glyph row in the current matrix where the
17699 window end line is found. It has been moved up or down in
17700 the matrix by dvpos. */
17701 int last_vpos
= w
->window_end_vpos
+ dvpos
;
17702 struct glyph_row
*last_row
= MATRIX_ROW (current_matrix
, last_vpos
);
17704 /* If last_row is the window end line, it should display text. */
17705 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_row
));
17707 /* If window end line was partially visible before, begin
17708 displaying at that line. Otherwise begin displaying with the
17709 line following it. */
17710 if (MATRIX_ROW_BOTTOM_Y (last_row
) - dy
>= it
.last_visible_y
)
17712 init_to_row_start (&it
, w
, last_row
);
17713 it
.vpos
= last_vpos
;
17714 it
.current_y
= last_row
->y
;
17718 init_to_row_end (&it
, w
, last_row
);
17719 it
.vpos
= 1 + last_vpos
;
17720 it
.current_y
= MATRIX_ROW_BOTTOM_Y (last_row
);
17724 /* We may start in a continuation line. If so, we have to
17725 get the right continuation_lines_width and current_x. */
17726 it
.continuation_lines_width
= last_row
->continuation_lines_width
;
17727 it
.hpos
= it
.current_x
= 0;
17729 /* Display the rest of the lines at the window end. */
17730 it
.glyph_row
= MATRIX_ROW (desired_matrix
, it
.vpos
);
17731 while (it
.current_y
< it
.last_visible_y
&& !f
->fonts_changed
)
17733 /* Is it always sure that the display agrees with lines in
17734 the current matrix? I don't think so, so we mark rows
17735 displayed invalid in the current matrix by setting their
17736 enabled_p flag to zero. */
17737 MATRIX_ROW (w
->current_matrix
, it
.vpos
)->enabled_p
= 0;
17738 if (display_line (&it
))
17739 last_text_row_at_end
= it
.glyph_row
- 1;
17743 /* Update window_end_pos and window_end_vpos. */
17744 if (first_unchanged_at_end_row
&& !last_text_row_at_end
)
17746 /* Window end line if one of the preserved rows from the current
17747 matrix. Set row to the last row displaying text in current
17748 matrix starting at first_unchanged_at_end_row, after
17750 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row
));
17751 row
= find_last_row_displaying_text (w
->current_matrix
, &it
,
17752 first_unchanged_at_end_row
);
17753 eassert (row
&& MATRIX_ROW_DISPLAYS_TEXT_P (row
));
17754 adjust_window_ends (w
, row
, 1);
17755 eassert (w
->window_end_bytepos
>= 0);
17756 IF_DEBUG (debug_method_add (w
, "A"));
17758 else if (last_text_row_at_end
)
17760 adjust_window_ends (w
, last_text_row_at_end
, 0);
17761 eassert (w
->window_end_bytepos
>= 0);
17762 IF_DEBUG (debug_method_add (w
, "B"));
17764 else if (last_text_row
)
17766 /* We have displayed either to the end of the window or at the
17767 end of the window, i.e. the last row with text is to be found
17768 in the desired matrix. */
17769 adjust_window_ends (w
, last_text_row
, 0);
17770 eassert (w
->window_end_bytepos
>= 0);
17772 else if (first_unchanged_at_end_row
== NULL
17773 && last_text_row
== NULL
17774 && last_text_row_at_end
== NULL
)
17776 /* Displayed to end of window, but no line containing text was
17777 displayed. Lines were deleted at the end of the window. */
17778 int first_vpos
= WINDOW_WANTS_HEADER_LINE_P (w
) ? 1 : 0;
17779 int vpos
= w
->window_end_vpos
;
17780 struct glyph_row
*current_row
= current_matrix
->rows
+ vpos
;
17781 struct glyph_row
*desired_row
= desired_matrix
->rows
+ vpos
;
17784 row
== NULL
&& vpos
>= first_vpos
;
17785 --vpos
, --current_row
, --desired_row
)
17787 if (desired_row
->enabled_p
)
17789 if (MATRIX_ROW_DISPLAYS_TEXT_P (desired_row
))
17792 else if (MATRIX_ROW_DISPLAYS_TEXT_P (current_row
))
17796 eassert (row
!= NULL
);
17797 w
->window_end_vpos
= vpos
+ 1;
17798 w
->window_end_pos
= Z
- MATRIX_ROW_END_CHARPOS (row
);
17799 w
->window_end_bytepos
= Z_BYTE
- MATRIX_ROW_END_BYTEPOS (row
);
17800 eassert (w
->window_end_bytepos
>= 0);
17801 IF_DEBUG (debug_method_add (w
, "C"));
17806 IF_DEBUG (debug_end_pos
= w
->window_end_pos
;
17807 debug_end_vpos
= w
->window_end_vpos
);
17809 /* Record that display has not been completed. */
17810 w
->window_end_valid
= 0;
17811 w
->desired_matrix
->no_scrolling_p
= 1;
17819 /***********************************************************************
17820 More debugging support
17821 ***********************************************************************/
17825 void dump_glyph_row (struct glyph_row
*, int, int) EXTERNALLY_VISIBLE
;
17826 void dump_glyph_matrix (struct glyph_matrix
*, int) EXTERNALLY_VISIBLE
;
17827 void dump_glyph (struct glyph_row
*, struct glyph
*, int) EXTERNALLY_VISIBLE
;
17830 /* Dump the contents of glyph matrix MATRIX on stderr.
17832 GLYPHS 0 means don't show glyph contents.
17833 GLYPHS 1 means show glyphs in short form
17834 GLYPHS > 1 means show glyphs in long form. */
17837 dump_glyph_matrix (struct glyph_matrix
*matrix
, int glyphs
)
17840 for (i
= 0; i
< matrix
->nrows
; ++i
)
17841 dump_glyph_row (MATRIX_ROW (matrix
, i
), i
, glyphs
);
17845 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
17846 the glyph row and area where the glyph comes from. */
17849 dump_glyph (struct glyph_row
*row
, struct glyph
*glyph
, int area
)
17851 if (glyph
->type
== CHAR_GLYPH
17852 || glyph
->type
== GLYPHLESS_GLYPH
)
17855 " %5"pD
"d %c %9"pI
"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
17856 glyph
- row
->glyphs
[TEXT_AREA
],
17857 (glyph
->type
== CHAR_GLYPH
17861 (BUFFERP (glyph
->object
)
17863 : (STRINGP (glyph
->object
)
17865 : (INTEGERP (glyph
->object
)
17868 glyph
->pixel_width
,
17870 (glyph
->u
.ch
< 0x80 && glyph
->u
.ch
>= ' '
17874 glyph
->left_box_line_p
,
17875 glyph
->right_box_line_p
);
17877 else if (glyph
->type
== STRETCH_GLYPH
)
17880 " %5"pD
"d %c %9"pI
"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
17881 glyph
- row
->glyphs
[TEXT_AREA
],
17884 (BUFFERP (glyph
->object
)
17886 : (STRINGP (glyph
->object
)
17888 : (INTEGERP (glyph
->object
)
17891 glyph
->pixel_width
,
17895 glyph
->left_box_line_p
,
17896 glyph
->right_box_line_p
);
17898 else if (glyph
->type
== IMAGE_GLYPH
)
17901 " %5"pD
"d %c %9"pI
"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
17902 glyph
- row
->glyphs
[TEXT_AREA
],
17905 (BUFFERP (glyph
->object
)
17907 : (STRINGP (glyph
->object
)
17909 : (INTEGERP (glyph
->object
)
17912 glyph
->pixel_width
,
17916 glyph
->left_box_line_p
,
17917 glyph
->right_box_line_p
);
17919 else if (glyph
->type
== COMPOSITE_GLYPH
)
17922 " %5"pD
"d %c %9"pI
"d %c %3d 0x%06x",
17923 glyph
- row
->glyphs
[TEXT_AREA
],
17926 (BUFFERP (glyph
->object
)
17928 : (STRINGP (glyph
->object
)
17930 : (INTEGERP (glyph
->object
)
17933 glyph
->pixel_width
,
17935 if (glyph
->u
.cmp
.automatic
)
17938 glyph
->slice
.cmp
.from
, glyph
->slice
.cmp
.to
);
17939 fprintf (stderr
, " . %4d %1.1d%1.1d\n",
17941 glyph
->left_box_line_p
,
17942 glyph
->right_box_line_p
);
17947 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
17948 GLYPHS 0 means don't show glyph contents.
17949 GLYPHS 1 means show glyphs in short form
17950 GLYPHS > 1 means show glyphs in long form. */
17953 dump_glyph_row (struct glyph_row
*row
, int vpos
, int glyphs
)
17957 fprintf (stderr
, "Row Start End Used oE><\\CTZFesm X Y W H V A P\n");
17958 fprintf (stderr
, "==============================================================================\n");
17960 fprintf (stderr
, "%3d %9"pI
"d %9"pI
"d %4d %1.1d%1.1d%1.1d%1.1d\
17961 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
17963 MATRIX_ROW_START_CHARPOS (row
),
17964 MATRIX_ROW_END_CHARPOS (row
),
17965 row
->used
[TEXT_AREA
],
17966 row
->contains_overlapping_glyphs_p
,
17968 row
->truncated_on_left_p
,
17969 row
->truncated_on_right_p
,
17971 MATRIX_ROW_CONTINUATION_LINE_P (row
),
17972 MATRIX_ROW_DISPLAYS_TEXT_P (row
),
17975 row
->ends_in_middle_of_char_p
,
17976 row
->starts_in_middle_of_char_p
,
17982 row
->visible_height
,
17985 /* The next 3 lines should align to "Start" in the header. */
17986 fprintf (stderr
, " %9"pD
"d %9"pD
"d\t%5d\n", row
->start
.overlay_string_index
,
17987 row
->end
.overlay_string_index
,
17988 row
->continuation_lines_width
);
17989 fprintf (stderr
, " %9"pI
"d %9"pI
"d\n",
17990 CHARPOS (row
->start
.string_pos
),
17991 CHARPOS (row
->end
.string_pos
));
17992 fprintf (stderr
, " %9d %9d\n", row
->start
.dpvec_index
,
17993 row
->end
.dpvec_index
);
18000 for (area
= LEFT_MARGIN_AREA
; area
< LAST_AREA
; ++area
)
18002 struct glyph
*glyph
= row
->glyphs
[area
];
18003 struct glyph
*glyph_end
= glyph
+ row
->used
[area
];
18005 /* Glyph for a line end in text. */
18006 if (area
== TEXT_AREA
&& glyph
== glyph_end
&& glyph
->charpos
> 0)
18009 if (glyph
< glyph_end
)
18010 fprintf (stderr
, " Glyph# Type Pos O W Code C Face LR\n");
18012 for (; glyph
< glyph_end
; ++glyph
)
18013 dump_glyph (row
, glyph
, area
);
18016 else if (glyphs
== 1)
18020 for (area
= LEFT_MARGIN_AREA
; area
< LAST_AREA
; ++area
)
18022 char *s
= alloca (row
->used
[area
] + 4);
18025 for (i
= 0; i
< row
->used
[area
]; ++i
)
18027 struct glyph
*glyph
= row
->glyphs
[area
] + i
;
18028 if (i
== row
->used
[area
] - 1
18029 && area
== TEXT_AREA
18030 && INTEGERP (glyph
->object
)
18031 && glyph
->type
== CHAR_GLYPH
18032 && glyph
->u
.ch
== ' ')
18034 strcpy (&s
[i
], "[\\n]");
18037 else if (glyph
->type
== CHAR_GLYPH
18038 && glyph
->u
.ch
< 0x80
18039 && glyph
->u
.ch
>= ' ')
18040 s
[i
] = glyph
->u
.ch
;
18046 fprintf (stderr
, "%3d: (%d) '%s'\n", vpos
, row
->enabled_p
, s
);
18052 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix
,
18053 Sdump_glyph_matrix
, 0, 1, "p",
18054 doc
: /* Dump the current matrix of the selected window to stderr.
18055 Shows contents of glyph row structures. With non-nil
18056 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
18057 glyphs in short form, otherwise show glyphs in long form. */)
18058 (Lisp_Object glyphs
)
18060 struct window
*w
= XWINDOW (selected_window
);
18061 struct buffer
*buffer
= XBUFFER (w
->contents
);
18063 fprintf (stderr
, "PT = %"pI
"d, BEGV = %"pI
"d. ZV = %"pI
"d\n",
18064 BUF_PT (buffer
), BUF_BEGV (buffer
), BUF_ZV (buffer
));
18065 fprintf (stderr
, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
18066 w
->cursor
.x
, w
->cursor
.y
, w
->cursor
.hpos
, w
->cursor
.vpos
);
18067 fprintf (stderr
, "=============================================\n");
18068 dump_glyph_matrix (w
->current_matrix
,
18069 TYPE_RANGED_INTEGERP (int, glyphs
) ? XINT (glyphs
) : 0);
18074 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix
,
18075 Sdump_frame_glyph_matrix
, 0, 0, "", doc
: /* */)
18078 struct frame
*f
= XFRAME (selected_frame
);
18079 dump_glyph_matrix (f
->current_matrix
, 1);
18084 DEFUN ("dump-glyph-row", Fdump_glyph_row
, Sdump_glyph_row
, 1, 2, "",
18085 doc
: /* Dump glyph row ROW to stderr.
18086 GLYPH 0 means don't dump glyphs.
18087 GLYPH 1 means dump glyphs in short form.
18088 GLYPH > 1 or omitted means dump glyphs in long form. */)
18089 (Lisp_Object row
, Lisp_Object glyphs
)
18091 struct glyph_matrix
*matrix
;
18094 CHECK_NUMBER (row
);
18095 matrix
= XWINDOW (selected_window
)->current_matrix
;
18097 if (vpos
>= 0 && vpos
< matrix
->nrows
)
18098 dump_glyph_row (MATRIX_ROW (matrix
, vpos
),
18100 TYPE_RANGED_INTEGERP (int, glyphs
) ? XINT (glyphs
) : 2);
18105 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row
, Sdump_tool_bar_row
, 1, 2, "",
18106 doc
: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
18107 GLYPH 0 means don't dump glyphs.
18108 GLYPH 1 means dump glyphs in short form.
18109 GLYPH > 1 or omitted means dump glyphs in long form. */)
18110 (Lisp_Object row
, Lisp_Object glyphs
)
18112 struct frame
*sf
= SELECTED_FRAME ();
18113 struct glyph_matrix
*m
= XWINDOW (sf
->tool_bar_window
)->current_matrix
;
18116 CHECK_NUMBER (row
);
18118 if (vpos
>= 0 && vpos
< m
->nrows
)
18119 dump_glyph_row (MATRIX_ROW (m
, vpos
), vpos
,
18120 TYPE_RANGED_INTEGERP (int, glyphs
) ? XINT (glyphs
) : 2);
18125 DEFUN ("trace-redisplay", Ftrace_redisplay
, Strace_redisplay
, 0, 1, "P",
18126 doc
: /* Toggle tracing of redisplay.
18127 With ARG, turn tracing on if and only if ARG is positive. */)
18131 trace_redisplay_p
= !trace_redisplay_p
;
18134 arg
= Fprefix_numeric_value (arg
);
18135 trace_redisplay_p
= XINT (arg
) > 0;
18142 DEFUN ("trace-to-stderr", Ftrace_to_stderr
, Strace_to_stderr
, 1, MANY
, "",
18143 doc
: /* Like `format', but print result to stderr.
18144 usage: (trace-to-stderr STRING &rest OBJECTS) */)
18145 (ptrdiff_t nargs
, Lisp_Object
*args
)
18147 Lisp_Object s
= Fformat (nargs
, args
);
18148 fprintf (stderr
, "%s", SDATA (s
));
18152 #endif /* GLYPH_DEBUG */
18156 /***********************************************************************
18157 Building Desired Matrix Rows
18158 ***********************************************************************/
18160 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
18161 Used for non-window-redisplay windows, and for windows w/o left fringe. */
18163 static struct glyph_row
*
18164 get_overlay_arrow_glyph_row (struct window
*w
, Lisp_Object overlay_arrow_string
)
18166 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
18167 struct buffer
*buffer
= XBUFFER (w
->contents
);
18168 struct buffer
*old
= current_buffer
;
18169 const unsigned char *arrow_string
= SDATA (overlay_arrow_string
);
18170 int arrow_len
= SCHARS (overlay_arrow_string
);
18171 const unsigned char *arrow_end
= arrow_string
+ arrow_len
;
18172 const unsigned char *p
;
18175 int n_glyphs_before
;
18177 set_buffer_temp (buffer
);
18178 init_iterator (&it
, w
, -1, -1, &scratch_glyph_row
, DEFAULT_FACE_ID
);
18179 it
.glyph_row
->used
[TEXT_AREA
] = 0;
18180 SET_TEXT_POS (it
.position
, 0, 0);
18182 multibyte_p
= !NILP (BVAR (buffer
, enable_multibyte_characters
));
18184 while (p
< arrow_end
)
18186 Lisp_Object face
, ilisp
;
18188 /* Get the next character. */
18190 it
.c
= it
.char_to_display
= string_char_and_length (p
, &it
.len
);
18193 it
.c
= it
.char_to_display
= *p
, it
.len
= 1;
18194 if (! ASCII_CHAR_P (it
.c
))
18195 it
.char_to_display
= BYTE8_TO_CHAR (it
.c
);
18199 /* Get its face. */
18200 ilisp
= make_number (p
- arrow_string
);
18201 face
= Fget_text_property (ilisp
, Qface
, overlay_arrow_string
);
18202 it
.face_id
= compute_char_face (f
, it
.char_to_display
, face
);
18204 /* Compute its width, get its glyphs. */
18205 n_glyphs_before
= it
.glyph_row
->used
[TEXT_AREA
];
18206 SET_TEXT_POS (it
.position
, -1, -1);
18207 PRODUCE_GLYPHS (&it
);
18209 /* If this character doesn't fit any more in the line, we have
18210 to remove some glyphs. */
18211 if (it
.current_x
> it
.last_visible_x
)
18213 it
.glyph_row
->used
[TEXT_AREA
] = n_glyphs_before
;
18218 set_buffer_temp (old
);
18219 return it
.glyph_row
;
18223 /* Insert truncation glyphs at the start of IT->glyph_row. Which
18224 glyphs to insert is determined by produce_special_glyphs. */
18227 insert_left_trunc_glyphs (struct it
*it
)
18229 struct it truncate_it
;
18230 struct glyph
*from
, *end
, *to
, *toend
;
18232 eassert (!FRAME_WINDOW_P (it
->f
)
18233 || (!it
->glyph_row
->reversed_p
18234 && WINDOW_LEFT_FRINGE_WIDTH (it
->w
) == 0)
18235 || (it
->glyph_row
->reversed_p
18236 && WINDOW_RIGHT_FRINGE_WIDTH (it
->w
) == 0));
18238 /* Get the truncation glyphs. */
18240 truncate_it
.current_x
= 0;
18241 truncate_it
.face_id
= DEFAULT_FACE_ID
;
18242 truncate_it
.glyph_row
= &scratch_glyph_row
;
18243 truncate_it
.glyph_row
->used
[TEXT_AREA
] = 0;
18244 CHARPOS (truncate_it
.position
) = BYTEPOS (truncate_it
.position
) = -1;
18245 truncate_it
.object
= make_number (0);
18246 produce_special_glyphs (&truncate_it
, IT_TRUNCATION
);
18248 /* Overwrite glyphs from IT with truncation glyphs. */
18249 if (!it
->glyph_row
->reversed_p
)
18251 short tused
= truncate_it
.glyph_row
->used
[TEXT_AREA
];
18253 from
= truncate_it
.glyph_row
->glyphs
[TEXT_AREA
];
18254 end
= from
+ tused
;
18255 to
= it
->glyph_row
->glyphs
[TEXT_AREA
];
18256 toend
= to
+ it
->glyph_row
->used
[TEXT_AREA
];
18257 if (FRAME_WINDOW_P (it
->f
))
18259 /* On GUI frames, when variable-size fonts are displayed,
18260 the truncation glyphs may need more pixels than the row's
18261 glyphs they overwrite. We overwrite more glyphs to free
18262 enough screen real estate, and enlarge the stretch glyph
18263 on the right (see display_line), if there is one, to
18264 preserve the screen position of the truncation glyphs on
18267 struct glyph
*g
= to
;
18270 /* The first glyph could be partially visible, in which case
18271 it->glyph_row->x will be negative. But we want the left
18272 truncation glyphs to be aligned at the left margin of the
18273 window, so we override the x coordinate at which the row
18275 it
->glyph_row
->x
= 0;
18276 while (g
< toend
&& w
< it
->truncation_pixel_width
)
18278 w
+= g
->pixel_width
;
18281 if (g
- to
- tused
> 0)
18283 memmove (to
+ tused
, g
, (toend
- g
) * sizeof(*g
));
18284 it
->glyph_row
->used
[TEXT_AREA
] -= g
- to
- tused
;
18286 used
= it
->glyph_row
->used
[TEXT_AREA
];
18287 if (it
->glyph_row
->truncated_on_right_p
18288 && WINDOW_RIGHT_FRINGE_WIDTH (it
->w
) == 0
18289 && it
->glyph_row
->glyphs
[TEXT_AREA
][used
- 2].type
18292 int extra
= w
- it
->truncation_pixel_width
;
18294 it
->glyph_row
->glyphs
[TEXT_AREA
][used
- 2].pixel_width
+= extra
;
18301 /* There may be padding glyphs left over. Overwrite them too. */
18302 if (!FRAME_WINDOW_P (it
->f
))
18304 while (to
< toend
&& CHAR_GLYPH_PADDING_P (*to
))
18306 from
= truncate_it
.glyph_row
->glyphs
[TEXT_AREA
];
18313 it
->glyph_row
->used
[TEXT_AREA
] = to
- it
->glyph_row
->glyphs
[TEXT_AREA
];
18317 short tused
= truncate_it
.glyph_row
->used
[TEXT_AREA
];
18319 /* In R2L rows, overwrite the last (rightmost) glyphs, and do
18320 that back to front. */
18321 end
= truncate_it
.glyph_row
->glyphs
[TEXT_AREA
];
18322 from
= end
+ truncate_it
.glyph_row
->used
[TEXT_AREA
] - 1;
18323 toend
= it
->glyph_row
->glyphs
[TEXT_AREA
];
18324 to
= toend
+ it
->glyph_row
->used
[TEXT_AREA
] - 1;
18325 if (FRAME_WINDOW_P (it
->f
))
18328 struct glyph
*g
= to
;
18330 while (g
>= toend
&& w
< it
->truncation_pixel_width
)
18332 w
+= g
->pixel_width
;
18335 if (to
- g
- tused
> 0)
18337 if (it
->glyph_row
->truncated_on_right_p
18338 && WINDOW_LEFT_FRINGE_WIDTH (it
->w
) == 0
18339 && it
->glyph_row
->glyphs
[TEXT_AREA
][1].type
== STRETCH_GLYPH
)
18341 int extra
= w
- it
->truncation_pixel_width
;
18343 it
->glyph_row
->glyphs
[TEXT_AREA
][1].pixel_width
+= extra
;
18347 while (from
>= end
&& to
>= toend
)
18349 if (!FRAME_WINDOW_P (it
->f
))
18351 while (to
>= toend
&& CHAR_GLYPH_PADDING_P (*to
))
18354 truncate_it
.glyph_row
->glyphs
[TEXT_AREA
]
18355 + truncate_it
.glyph_row
->used
[TEXT_AREA
] - 1;
18356 while (from
>= end
&& to
>= toend
)
18362 /* Need to free some room before prepending additional
18364 int move_by
= from
- end
+ 1;
18365 struct glyph
*g0
= it
->glyph_row
->glyphs
[TEXT_AREA
];
18366 struct glyph
*g
= g0
+ it
->glyph_row
->used
[TEXT_AREA
] - 1;
18368 for ( ; g
>= g0
; g
--)
18370 while (from
>= end
)
18372 it
->glyph_row
->used
[TEXT_AREA
] += move_by
;
18377 /* Compute the hash code for ROW. */
18379 row_hash (struct glyph_row
*row
)
18382 unsigned hashval
= 0;
18384 for (area
= LEFT_MARGIN_AREA
; area
< LAST_AREA
; ++area
)
18385 for (k
= 0; k
< row
->used
[area
]; ++k
)
18386 hashval
= ((((hashval
<< 4) + (hashval
>> 24)) & 0x0fffffff)
18387 + row
->glyphs
[area
][k
].u
.val
18388 + row
->glyphs
[area
][k
].face_id
18389 + row
->glyphs
[area
][k
].padding_p
18390 + (row
->glyphs
[area
][k
].type
<< 2));
18395 /* Compute the pixel height and width of IT->glyph_row.
18397 Most of the time, ascent and height of a display line will be equal
18398 to the max_ascent and max_height values of the display iterator
18399 structure. This is not the case if
18401 1. We hit ZV without displaying anything. In this case, max_ascent
18402 and max_height will be zero.
18404 2. We have some glyphs that don't contribute to the line height.
18405 (The glyph row flag contributes_to_line_height_p is for future
18406 pixmap extensions).
18408 The first case is easily covered by using default values because in
18409 these cases, the line height does not really matter, except that it
18410 must not be zero. */
18413 compute_line_metrics (struct it
*it
)
18415 struct glyph_row
*row
= it
->glyph_row
;
18417 if (FRAME_WINDOW_P (it
->f
))
18419 int i
, min_y
, max_y
;
18421 /* The line may consist of one space only, that was added to
18422 place the cursor on it. If so, the row's height hasn't been
18424 if (row
->height
== 0)
18426 if (it
->max_ascent
+ it
->max_descent
== 0)
18427 it
->max_descent
= it
->max_phys_descent
= FRAME_LINE_HEIGHT (it
->f
);
18428 row
->ascent
= it
->max_ascent
;
18429 row
->height
= it
->max_ascent
+ it
->max_descent
;
18430 row
->phys_ascent
= it
->max_phys_ascent
;
18431 row
->phys_height
= it
->max_phys_ascent
+ it
->max_phys_descent
;
18432 row
->extra_line_spacing
= it
->max_extra_line_spacing
;
18435 /* Compute the width of this line. */
18436 row
->pixel_width
= row
->x
;
18437 for (i
= 0; i
< row
->used
[TEXT_AREA
]; ++i
)
18438 row
->pixel_width
+= row
->glyphs
[TEXT_AREA
][i
].pixel_width
;
18440 eassert (row
->pixel_width
>= 0);
18441 eassert (row
->ascent
>= 0 && row
->height
> 0);
18443 row
->overlapping_p
= (MATRIX_ROW_OVERLAPS_SUCC_P (row
)
18444 || MATRIX_ROW_OVERLAPS_PRED_P (row
));
18446 /* If first line's physical ascent is larger than its logical
18447 ascent, use the physical ascent, and make the row taller.
18448 This makes accented characters fully visible. */
18449 if (row
== MATRIX_FIRST_TEXT_ROW (it
->w
->desired_matrix
)
18450 && row
->phys_ascent
> row
->ascent
)
18452 row
->height
+= row
->phys_ascent
- row
->ascent
;
18453 row
->ascent
= row
->phys_ascent
;
18456 /* Compute how much of the line is visible. */
18457 row
->visible_height
= row
->height
;
18459 min_y
= WINDOW_HEADER_LINE_HEIGHT (it
->w
);
18460 max_y
= WINDOW_BOX_HEIGHT_NO_MODE_LINE (it
->w
);
18462 if (row
->y
< min_y
)
18463 row
->visible_height
-= min_y
- row
->y
;
18464 if (row
->y
+ row
->height
> max_y
)
18465 row
->visible_height
-= row
->y
+ row
->height
- max_y
;
18469 row
->pixel_width
= row
->used
[TEXT_AREA
];
18470 if (row
->continued_p
)
18471 row
->pixel_width
-= it
->continuation_pixel_width
;
18472 else if (row
->truncated_on_right_p
)
18473 row
->pixel_width
-= it
->truncation_pixel_width
;
18474 row
->ascent
= row
->phys_ascent
= 0;
18475 row
->height
= row
->phys_height
= row
->visible_height
= 1;
18476 row
->extra_line_spacing
= 0;
18479 /* Compute a hash code for this row. */
18480 row
->hash
= row_hash (row
);
18482 it
->max_ascent
= it
->max_descent
= 0;
18483 it
->max_phys_ascent
= it
->max_phys_descent
= 0;
18487 /* Append one space to the glyph row of iterator IT if doing a
18488 window-based redisplay. The space has the same face as
18489 IT->face_id. Value is non-zero if a space was added.
18491 This function is called to make sure that there is always one glyph
18492 at the end of a glyph row that the cursor can be set on under
18493 window-systems. (If there weren't such a glyph we would not know
18494 how wide and tall a box cursor should be displayed).
18496 At the same time this space let's a nicely handle clearing to the
18497 end of the line if the row ends in italic text. */
18500 append_space_for_newline (struct it
*it
, int default_face_p
)
18502 if (FRAME_WINDOW_P (it
->f
))
18504 int n
= it
->glyph_row
->used
[TEXT_AREA
];
18506 if (it
->glyph_row
->glyphs
[TEXT_AREA
] + n
18507 < it
->glyph_row
->glyphs
[1 + TEXT_AREA
])
18509 /* Save some values that must not be changed.
18510 Must save IT->c and IT->len because otherwise
18511 ITERATOR_AT_END_P wouldn't work anymore after
18512 append_space_for_newline has been called. */
18513 enum display_element_type saved_what
= it
->what
;
18514 int saved_c
= it
->c
, saved_len
= it
->len
;
18515 int saved_char_to_display
= it
->char_to_display
;
18516 int saved_x
= it
->current_x
;
18517 int saved_face_id
= it
->face_id
;
18518 int saved_box_end
= it
->end_of_box_run_p
;
18519 struct text_pos saved_pos
;
18520 Lisp_Object saved_object
;
18523 saved_object
= it
->object
;
18524 saved_pos
= it
->position
;
18526 it
->what
= IT_CHARACTER
;
18527 memset (&it
->position
, 0, sizeof it
->position
);
18528 it
->object
= make_number (0);
18529 it
->c
= it
->char_to_display
= ' ';
18532 /* If the default face was remapped, be sure to use the
18533 remapped face for the appended newline. */
18534 if (default_face_p
)
18535 it
->face_id
= lookup_basic_face (it
->f
, DEFAULT_FACE_ID
);
18536 else if (it
->face_before_selective_p
)
18537 it
->face_id
= it
->saved_face_id
;
18538 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
18539 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, 0, -1, Qnil
);
18540 /* In R2L rows, we will prepend a stretch glyph that will
18541 have the end_of_box_run_p flag set for it, so there's no
18542 need for the appended newline glyph to have that flag
18544 if (it
->glyph_row
->reversed_p
18545 /* But if the appended newline glyph goes all the way to
18546 the end of the row, there will be no stretch glyph,
18547 so leave the box flag set. */
18548 && saved_x
+ FRAME_COLUMN_WIDTH (it
->f
) < it
->last_visible_x
)
18549 it
->end_of_box_run_p
= 0;
18551 PRODUCE_GLYPHS (it
);
18553 it
->override_ascent
= -1;
18554 it
->constrain_row_ascent_descent_p
= 0;
18555 it
->current_x
= saved_x
;
18556 it
->object
= saved_object
;
18557 it
->position
= saved_pos
;
18558 it
->what
= saved_what
;
18559 it
->face_id
= saved_face_id
;
18560 it
->len
= saved_len
;
18562 it
->char_to_display
= saved_char_to_display
;
18563 it
->end_of_box_run_p
= saved_box_end
;
18572 /* Extend the face of the last glyph in the text area of IT->glyph_row
18573 to the end of the display line. Called from display_line. If the
18574 glyph row is empty, add a space glyph to it so that we know the
18575 face to draw. Set the glyph row flag fill_line_p. If the glyph
18576 row is R2L, prepend a stretch glyph to cover the empty space to the
18577 left of the leftmost glyph. */
18580 extend_face_to_end_of_line (struct it
*it
)
18582 struct face
*face
, *default_face
;
18583 struct frame
*f
= it
->f
;
18585 /* If line is already filled, do nothing. Non window-system frames
18586 get a grace of one more ``pixel'' because their characters are
18587 1-``pixel'' wide, so they hit the equality too early. This grace
18588 is needed only for R2L rows that are not continued, to produce
18589 one extra blank where we could display the cursor. */
18590 if (it
->current_x
>= it
->last_visible_x
18591 + (!FRAME_WINDOW_P (f
)
18592 && it
->glyph_row
->reversed_p
18593 && !it
->glyph_row
->continued_p
))
18596 /* The default face, possibly remapped. */
18597 default_face
= FACE_FROM_ID (f
, lookup_basic_face (f
, DEFAULT_FACE_ID
));
18599 /* Face extension extends the background and box of IT->face_id
18600 to the end of the line. If the background equals the background
18601 of the frame, we don't have to do anything. */
18602 if (it
->face_before_selective_p
)
18603 face
= FACE_FROM_ID (f
, it
->saved_face_id
);
18605 face
= FACE_FROM_ID (f
, it
->face_id
);
18607 if (FRAME_WINDOW_P (f
)
18608 && MATRIX_ROW_DISPLAYS_TEXT_P (it
->glyph_row
)
18609 && face
->box
== FACE_NO_BOX
18610 && face
->background
== FRAME_BACKGROUND_PIXEL (f
)
18612 && !it
->glyph_row
->reversed_p
)
18615 /* Set the glyph row flag indicating that the face of the last glyph
18616 in the text area has to be drawn to the end of the text area. */
18617 it
->glyph_row
->fill_line_p
= 1;
18619 /* If current character of IT is not ASCII, make sure we have the
18620 ASCII face. This will be automatically undone the next time
18621 get_next_display_element returns a multibyte character. Note
18622 that the character will always be single byte in unibyte
18624 if (!ASCII_CHAR_P (it
->c
))
18626 it
->face_id
= FACE_FOR_CHAR (f
, face
, 0, -1, Qnil
);
18629 if (FRAME_WINDOW_P (f
))
18631 /* If the row is empty, add a space with the current face of IT,
18632 so that we know which face to draw. */
18633 if (it
->glyph_row
->used
[TEXT_AREA
] == 0)
18635 it
->glyph_row
->glyphs
[TEXT_AREA
][0] = space_glyph
;
18636 it
->glyph_row
->glyphs
[TEXT_AREA
][0].face_id
= face
->id
;
18637 it
->glyph_row
->used
[TEXT_AREA
] = 1;
18639 #ifdef HAVE_WINDOW_SYSTEM
18640 if (it
->glyph_row
->reversed_p
)
18642 /* Prepend a stretch glyph to the row, such that the
18643 rightmost glyph will be drawn flushed all the way to the
18644 right margin of the window. The stretch glyph that will
18645 occupy the empty space, if any, to the left of the
18647 struct font
*font
= face
->font
? face
->font
: FRAME_FONT (f
);
18648 struct glyph
*row_start
= it
->glyph_row
->glyphs
[TEXT_AREA
];
18649 struct glyph
*row_end
= row_start
+ it
->glyph_row
->used
[TEXT_AREA
];
18651 int row_width
, stretch_ascent
, stretch_width
;
18652 struct text_pos saved_pos
;
18653 int saved_face_id
, saved_avoid_cursor
, saved_box_start
;
18655 for (row_width
= 0, g
= row_start
; g
< row_end
; g
++)
18656 row_width
+= g
->pixel_width
;
18657 stretch_width
= window_box_width (it
->w
, TEXT_AREA
) - row_width
;
18658 if (stretch_width
> 0)
18661 (((it
->ascent
+ it
->descent
)
18662 * FONT_BASE (font
)) / FONT_HEIGHT (font
));
18663 saved_pos
= it
->position
;
18664 memset (&it
->position
, 0, sizeof it
->position
);
18665 saved_avoid_cursor
= it
->avoid_cursor_p
;
18666 it
->avoid_cursor_p
= 1;
18667 saved_face_id
= it
->face_id
;
18668 saved_box_start
= it
->start_of_box_run_p
;
18669 /* The last row's stretch glyph should get the default
18670 face, to avoid painting the rest of the window with
18671 the region face, if the region ends at ZV. */
18672 if (it
->glyph_row
->ends_at_zv_p
)
18673 it
->face_id
= default_face
->id
;
18675 it
->face_id
= face
->id
;
18676 it
->start_of_box_run_p
= 0;
18677 append_stretch_glyph (it
, make_number (0), stretch_width
,
18678 it
->ascent
+ it
->descent
, stretch_ascent
);
18679 it
->position
= saved_pos
;
18680 it
->avoid_cursor_p
= saved_avoid_cursor
;
18681 it
->face_id
= saved_face_id
;
18682 it
->start_of_box_run_p
= saved_box_start
;
18685 #endif /* HAVE_WINDOW_SYSTEM */
18689 /* Save some values that must not be changed. */
18690 int saved_x
= it
->current_x
;
18691 struct text_pos saved_pos
;
18692 Lisp_Object saved_object
;
18693 enum display_element_type saved_what
= it
->what
;
18694 int saved_face_id
= it
->face_id
;
18696 saved_object
= it
->object
;
18697 saved_pos
= it
->position
;
18699 it
->what
= IT_CHARACTER
;
18700 memset (&it
->position
, 0, sizeof it
->position
);
18701 it
->object
= make_number (0);
18702 it
->c
= it
->char_to_display
= ' ';
18704 /* The last row's blank glyphs should get the default face, to
18705 avoid painting the rest of the window with the region face,
18706 if the region ends at ZV. */
18707 if (it
->glyph_row
->ends_at_zv_p
)
18708 it
->face_id
= default_face
->id
;
18710 it
->face_id
= face
->id
;
18712 PRODUCE_GLYPHS (it
);
18714 while (it
->current_x
<= it
->last_visible_x
)
18715 PRODUCE_GLYPHS (it
);
18717 /* Don't count these blanks really. It would let us insert a left
18718 truncation glyph below and make us set the cursor on them, maybe. */
18719 it
->current_x
= saved_x
;
18720 it
->object
= saved_object
;
18721 it
->position
= saved_pos
;
18722 it
->what
= saved_what
;
18723 it
->face_id
= saved_face_id
;
18728 /* Value is non-zero if text starting at CHARPOS in current_buffer is
18729 trailing whitespace. */
18732 trailing_whitespace_p (ptrdiff_t charpos
)
18734 ptrdiff_t bytepos
= CHAR_TO_BYTE (charpos
);
18737 while (bytepos
< ZV_BYTE
18738 && (c
= FETCH_CHAR (bytepos
),
18739 c
== ' ' || c
== '\t'))
18742 if (bytepos
>= ZV_BYTE
|| c
== '\n' || c
== '\r')
18744 if (bytepos
!= PT_BYTE
)
18751 /* Highlight trailing whitespace, if any, in ROW. */
18754 highlight_trailing_whitespace (struct frame
*f
, struct glyph_row
*row
)
18756 int used
= row
->used
[TEXT_AREA
];
18760 struct glyph
*start
= row
->glyphs
[TEXT_AREA
];
18761 struct glyph
*glyph
= start
+ used
- 1;
18763 if (row
->reversed_p
)
18765 /* Right-to-left rows need to be processed in the opposite
18766 direction, so swap the edge pointers. */
18768 start
= row
->glyphs
[TEXT_AREA
] + used
- 1;
18771 /* Skip over glyphs inserted to display the cursor at the
18772 end of a line, for extending the face of the last glyph
18773 to the end of the line on terminals, and for truncation
18774 and continuation glyphs. */
18775 if (!row
->reversed_p
)
18777 while (glyph
>= start
18778 && glyph
->type
== CHAR_GLYPH
18779 && INTEGERP (glyph
->object
))
18784 while (glyph
<= start
18785 && glyph
->type
== CHAR_GLYPH
18786 && INTEGERP (glyph
->object
))
18790 /* If last glyph is a space or stretch, and it's trailing
18791 whitespace, set the face of all trailing whitespace glyphs in
18792 IT->glyph_row to `trailing-whitespace'. */
18793 if ((row
->reversed_p
? glyph
<= start
: glyph
>= start
)
18794 && BUFFERP (glyph
->object
)
18795 && (glyph
->type
== STRETCH_GLYPH
18796 || (glyph
->type
== CHAR_GLYPH
18797 && glyph
->u
.ch
== ' '))
18798 && trailing_whitespace_p (glyph
->charpos
))
18800 int face_id
= lookup_named_face (f
, Qtrailing_whitespace
, 0);
18804 if (!row
->reversed_p
)
18806 while (glyph
>= start
18807 && BUFFERP (glyph
->object
)
18808 && (glyph
->type
== STRETCH_GLYPH
18809 || (glyph
->type
== CHAR_GLYPH
18810 && glyph
->u
.ch
== ' ')))
18811 (glyph
--)->face_id
= face_id
;
18815 while (glyph
<= start
18816 && BUFFERP (glyph
->object
)
18817 && (glyph
->type
== STRETCH_GLYPH
18818 || (glyph
->type
== CHAR_GLYPH
18819 && glyph
->u
.ch
== ' ')))
18820 (glyph
++)->face_id
= face_id
;
18827 /* Value is non-zero if glyph row ROW should be
18828 considered to hold the buffer position CHARPOS. */
18831 row_for_charpos_p (struct glyph_row
*row
, ptrdiff_t charpos
)
18835 if (charpos
== CHARPOS (row
->end
.pos
)
18836 || charpos
== MATRIX_ROW_END_CHARPOS (row
))
18838 /* Suppose the row ends on a string.
18839 Unless the row is continued, that means it ends on a newline
18840 in the string. If it's anything other than a display string
18841 (e.g., a before-string from an overlay), we don't want the
18842 cursor there. (This heuristic seems to give the optimal
18843 behavior for the various types of multi-line strings.)
18844 One exception: if the string has `cursor' property on one of
18845 its characters, we _do_ want the cursor there. */
18846 if (CHARPOS (row
->end
.string_pos
) >= 0)
18848 if (row
->continued_p
)
18852 /* Check for `display' property. */
18853 struct glyph
*beg
= row
->glyphs
[TEXT_AREA
];
18854 struct glyph
*end
= beg
+ row
->used
[TEXT_AREA
] - 1;
18855 struct glyph
*glyph
;
18858 for (glyph
= end
; glyph
>= beg
; --glyph
)
18859 if (STRINGP (glyph
->object
))
18862 = Fget_char_property (make_number (charpos
),
18866 && display_prop_string_p (prop
, glyph
->object
));
18867 /* If there's a `cursor' property on one of the
18868 string's characters, this row is a cursor row,
18869 even though this is not a display string. */
18872 Lisp_Object s
= glyph
->object
;
18874 for ( ; glyph
>= beg
&& EQ (glyph
->object
, s
); --glyph
)
18876 ptrdiff_t gpos
= glyph
->charpos
;
18878 if (!NILP (Fget_char_property (make_number (gpos
),
18890 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row
))
18892 /* If the row ends in middle of a real character,
18893 and the line is continued, we want the cursor here.
18894 That's because CHARPOS (ROW->end.pos) would equal
18895 PT if PT is before the character. */
18896 if (!row
->ends_in_ellipsis_p
)
18897 result
= row
->continued_p
;
18899 /* If the row ends in an ellipsis, then
18900 CHARPOS (ROW->end.pos) will equal point after the
18901 invisible text. We want that position to be displayed
18902 after the ellipsis. */
18905 /* If the row ends at ZV, display the cursor at the end of that
18906 row instead of at the start of the row below. */
18907 else if (row
->ends_at_zv_p
)
18916 /* Value is non-zero if glyph row ROW should be
18917 used to hold the cursor. */
18920 cursor_row_p (struct glyph_row
*row
)
18922 return row_for_charpos_p (row
, PT
);
18927 /* Push the property PROP so that it will be rendered at the current
18928 position in IT. Return 1 if PROP was successfully pushed, 0
18929 otherwise. Called from handle_line_prefix to handle the
18930 `line-prefix' and `wrap-prefix' properties. */
18933 push_prefix_prop (struct it
*it
, Lisp_Object prop
)
18935 struct text_pos pos
=
18936 STRINGP (it
->string
) ? it
->current
.string_pos
: it
->current
.pos
;
18938 eassert (it
->method
== GET_FROM_BUFFER
18939 || it
->method
== GET_FROM_DISPLAY_VECTOR
18940 || it
->method
== GET_FROM_STRING
);
18942 /* We need to save the current buffer/string position, so it will be
18943 restored by pop_it, because iterate_out_of_display_property
18944 depends on that being set correctly, but some situations leave
18945 it->position not yet set when this function is called. */
18946 push_it (it
, &pos
);
18948 if (STRINGP (prop
))
18950 if (SCHARS (prop
) == 0)
18957 it
->string_from_prefix_prop_p
= 1;
18958 it
->multibyte_p
= STRING_MULTIBYTE (it
->string
);
18959 it
->current
.overlay_string_index
= -1;
18960 IT_STRING_CHARPOS (*it
) = IT_STRING_BYTEPOS (*it
) = 0;
18961 it
->end_charpos
= it
->string_nchars
= SCHARS (it
->string
);
18962 it
->method
= GET_FROM_STRING
;
18963 it
->stop_charpos
= 0;
18965 it
->base_level_stop
= 0;
18967 /* Force paragraph direction to be that of the parent
18969 if (it
->bidi_p
&& it
->bidi_it
.paragraph_dir
== R2L
)
18970 it
->paragraph_embedding
= it
->bidi_it
.paragraph_dir
;
18972 it
->paragraph_embedding
= L2R
;
18974 /* Set up the bidi iterator for this display string. */
18977 it
->bidi_it
.string
.lstring
= it
->string
;
18978 it
->bidi_it
.string
.s
= NULL
;
18979 it
->bidi_it
.string
.schars
= it
->end_charpos
;
18980 it
->bidi_it
.string
.bufpos
= IT_CHARPOS (*it
);
18981 it
->bidi_it
.string
.from_disp_str
= it
->string_from_display_prop_p
;
18982 it
->bidi_it
.string
.unibyte
= !it
->multibyte_p
;
18983 it
->bidi_it
.w
= it
->w
;
18984 bidi_init_it (0, 0, FRAME_WINDOW_P (it
->f
), &it
->bidi_it
);
18987 else if (CONSP (prop
) && EQ (XCAR (prop
), Qspace
))
18989 it
->method
= GET_FROM_STRETCH
;
18992 #ifdef HAVE_WINDOW_SYSTEM
18993 else if (IMAGEP (prop
))
18995 it
->what
= IT_IMAGE
;
18996 it
->image_id
= lookup_image (it
->f
, prop
);
18997 it
->method
= GET_FROM_IMAGE
;
18999 #endif /* HAVE_WINDOW_SYSTEM */
19002 pop_it (it
); /* bogus display property, give up */
19009 /* Return the character-property PROP at the current position in IT. */
19012 get_it_property (struct it
*it
, Lisp_Object prop
)
19014 Lisp_Object position
, object
= it
->object
;
19016 if (STRINGP (object
))
19017 position
= make_number (IT_STRING_CHARPOS (*it
));
19018 else if (BUFFERP (object
))
19020 position
= make_number (IT_CHARPOS (*it
));
19021 object
= it
->window
;
19026 return Fget_char_property (position
, prop
, object
);
19029 /* See if there's a line- or wrap-prefix, and if so, push it on IT. */
19032 handle_line_prefix (struct it
*it
)
19034 Lisp_Object prefix
;
19036 if (it
->continuation_lines_width
> 0)
19038 prefix
= get_it_property (it
, Qwrap_prefix
);
19040 prefix
= Vwrap_prefix
;
19044 prefix
= get_it_property (it
, Qline_prefix
);
19046 prefix
= Vline_prefix
;
19048 if (! NILP (prefix
) && push_prefix_prop (it
, prefix
))
19050 /* If the prefix is wider than the window, and we try to wrap
19051 it, it would acquire its own wrap prefix, and so on till the
19052 iterator stack overflows. So, don't wrap the prefix. */
19053 it
->line_wrap
= TRUNCATE
;
19054 it
->avoid_cursor_p
= 1;
19060 /* Remove N glyphs at the start of a reversed IT->glyph_row. Called
19061 only for R2L lines from display_line and display_string, when they
19062 decide that too many glyphs were produced by PRODUCE_GLYPHS, and
19063 the line/string needs to be continued on the next glyph row. */
19065 unproduce_glyphs (struct it
*it
, int n
)
19067 struct glyph
*glyph
, *end
;
19069 eassert (it
->glyph_row
);
19070 eassert (it
->glyph_row
->reversed_p
);
19071 eassert (it
->area
== TEXT_AREA
);
19072 eassert (n
<= it
->glyph_row
->used
[TEXT_AREA
]);
19074 if (n
> it
->glyph_row
->used
[TEXT_AREA
])
19075 n
= it
->glyph_row
->used
[TEXT_AREA
];
19076 glyph
= it
->glyph_row
->glyphs
[TEXT_AREA
] + n
;
19077 end
= it
->glyph_row
->glyphs
[TEXT_AREA
] + it
->glyph_row
->used
[TEXT_AREA
];
19078 for ( ; glyph
< end
; glyph
++)
19079 glyph
[-n
] = *glyph
;
19082 /* Find the positions in a bidi-reordered ROW to serve as ROW->minpos
19083 and ROW->maxpos. */
19085 find_row_edges (struct it
*it
, struct glyph_row
*row
,
19086 ptrdiff_t min_pos
, ptrdiff_t min_bpos
,
19087 ptrdiff_t max_pos
, ptrdiff_t max_bpos
)
19089 /* FIXME: Revisit this when glyph ``spilling'' in continuation
19090 lines' rows is implemented for bidi-reordered rows. */
19092 /* ROW->minpos is the value of min_pos, the minimal buffer position
19093 we have in ROW, or ROW->start.pos if that is smaller. */
19094 if (min_pos
<= ZV
&& min_pos
< row
->start
.pos
.charpos
)
19095 SET_TEXT_POS (row
->minpos
, min_pos
, min_bpos
);
19097 /* We didn't find buffer positions smaller than ROW->start, or
19098 didn't find _any_ valid buffer positions in any of the glyphs,
19099 so we must trust the iterator's computed positions. */
19100 row
->minpos
= row
->start
.pos
;
19103 max_pos
= CHARPOS (it
->current
.pos
);
19104 max_bpos
= BYTEPOS (it
->current
.pos
);
19107 /* Here are the various use-cases for ending the row, and the
19108 corresponding values for ROW->maxpos:
19110 Line ends in a newline from buffer eol_pos + 1
19111 Line is continued from buffer max_pos + 1
19112 Line is truncated on right it->current.pos
19113 Line ends in a newline from string max_pos + 1(*)
19114 (*) + 1 only when line ends in a forward scan
19115 Line is continued from string max_pos
19116 Line is continued from display vector max_pos
19117 Line is entirely from a string min_pos == max_pos
19118 Line is entirely from a display vector min_pos == max_pos
19119 Line that ends at ZV ZV
19121 If you discover other use-cases, please add them here as
19123 if (row
->ends_at_zv_p
)
19124 row
->maxpos
= it
->current
.pos
;
19125 else if (row
->used
[TEXT_AREA
])
19127 int seen_this_string
= 0;
19128 struct glyph_row
*r1
= row
- 1;
19130 /* Did we see the same display string on the previous row? */
19131 if (STRINGP (it
->object
)
19132 /* this is not the first row */
19133 && row
> it
->w
->desired_matrix
->rows
19134 /* previous row is not the header line */
19135 && !r1
->mode_line_p
19136 /* previous row also ends in a newline from a string */
19137 && r1
->ends_in_newline_from_string_p
)
19139 struct glyph
*start
, *end
;
19141 /* Search for the last glyph of the previous row that came
19142 from buffer or string. Depending on whether the row is
19143 L2R or R2L, we need to process it front to back or the
19144 other way round. */
19145 if (!r1
->reversed_p
)
19147 start
= r1
->glyphs
[TEXT_AREA
];
19148 end
= start
+ r1
->used
[TEXT_AREA
];
19149 /* Glyphs inserted by redisplay have an integer (zero)
19150 as their object. */
19152 && INTEGERP ((end
- 1)->object
)
19153 && (end
- 1)->charpos
<= 0)
19157 if (EQ ((end
- 1)->object
, it
->object
))
19158 seen_this_string
= 1;
19161 /* If all the glyphs of the previous row were inserted
19162 by redisplay, it means the previous row was
19163 produced from a single newline, which is only
19164 possible if that newline came from the same string
19165 as the one which produced this ROW. */
19166 seen_this_string
= 1;
19170 end
= r1
->glyphs
[TEXT_AREA
] - 1;
19171 start
= end
+ r1
->used
[TEXT_AREA
];
19173 && INTEGERP ((end
+ 1)->object
)
19174 && (end
+ 1)->charpos
<= 0)
19178 if (EQ ((end
+ 1)->object
, it
->object
))
19179 seen_this_string
= 1;
19182 seen_this_string
= 1;
19185 /* Take note of each display string that covers a newline only
19186 once, the first time we see it. This is for when a display
19187 string includes more than one newline in it. */
19188 if (row
->ends_in_newline_from_string_p
&& !seen_this_string
)
19190 /* If we were scanning the buffer forward when we displayed
19191 the string, we want to account for at least one buffer
19192 position that belongs to this row (position covered by
19193 the display string), so that cursor positioning will
19194 consider this row as a candidate when point is at the end
19195 of the visual line represented by this row. This is not
19196 required when scanning back, because max_pos will already
19197 have a much larger value. */
19198 if (CHARPOS (row
->end
.pos
) > max_pos
)
19199 INC_BOTH (max_pos
, max_bpos
);
19200 SET_TEXT_POS (row
->maxpos
, max_pos
, max_bpos
);
19202 else if (CHARPOS (it
->eol_pos
) > 0)
19203 SET_TEXT_POS (row
->maxpos
,
19204 CHARPOS (it
->eol_pos
) + 1, BYTEPOS (it
->eol_pos
) + 1);
19205 else if (row
->continued_p
)
19207 /* If max_pos is different from IT's current position, it
19208 means IT->method does not belong to the display element
19209 at max_pos. However, it also means that the display
19210 element at max_pos was displayed in its entirety on this
19211 line, which is equivalent to saying that the next line
19212 starts at the next buffer position. */
19213 if (IT_CHARPOS (*it
) == max_pos
&& it
->method
!= GET_FROM_BUFFER
)
19214 SET_TEXT_POS (row
->maxpos
, max_pos
, max_bpos
);
19217 INC_BOTH (max_pos
, max_bpos
);
19218 SET_TEXT_POS (row
->maxpos
, max_pos
, max_bpos
);
19221 else if (row
->truncated_on_right_p
)
19222 /* display_line already called reseat_at_next_visible_line_start,
19223 which puts the iterator at the beginning of the next line, in
19224 the logical order. */
19225 row
->maxpos
= it
->current
.pos
;
19226 else if (max_pos
== min_pos
&& it
->method
!= GET_FROM_BUFFER
)
19227 /* A line that is entirely from a string/image/stretch... */
19228 row
->maxpos
= row
->minpos
;
19233 row
->maxpos
= it
->current
.pos
;
19236 /* Construct the glyph row IT->glyph_row in the desired matrix of
19237 IT->w from text at the current position of IT. See dispextern.h
19238 for an overview of struct it. Value is non-zero if
19239 IT->glyph_row displays text, as opposed to a line displaying ZV
19243 display_line (struct it
*it
)
19245 struct glyph_row
*row
= it
->glyph_row
;
19246 Lisp_Object overlay_arrow_string
;
19248 void *wrap_data
= NULL
;
19249 int may_wrap
= 0, wrap_x
IF_LINT (= 0);
19250 int wrap_row_used
= -1;
19251 int wrap_row_ascent
IF_LINT (= 0), wrap_row_height
IF_LINT (= 0);
19252 int wrap_row_phys_ascent
IF_LINT (= 0), wrap_row_phys_height
IF_LINT (= 0);
19253 int wrap_row_extra_line_spacing
IF_LINT (= 0);
19254 ptrdiff_t wrap_row_min_pos
IF_LINT (= 0), wrap_row_min_bpos
IF_LINT (= 0);
19255 ptrdiff_t wrap_row_max_pos
IF_LINT (= 0), wrap_row_max_bpos
IF_LINT (= 0);
19257 ptrdiff_t min_pos
= ZV
+ 1, max_pos
= 0;
19258 ptrdiff_t min_bpos
IF_LINT (= 0), max_bpos
IF_LINT (= 0);
19260 /* We always start displaying at hpos zero even if hscrolled. */
19261 eassert (it
->hpos
== 0 && it
->current_x
== 0);
19263 if (MATRIX_ROW_VPOS (row
, it
->w
->desired_matrix
)
19264 >= it
->w
->desired_matrix
->nrows
)
19266 it
->w
->nrows_scale_factor
++;
19267 it
->f
->fonts_changed
= 1;
19271 /* Is IT->w showing the region? */
19272 it
->w
->region_showing
= it
->region_beg_charpos
> 0 ? it
->region_beg_charpos
: 0;
19274 /* Clear the result glyph row and enable it. */
19275 prepare_desired_row (row
);
19277 row
->y
= it
->current_y
;
19278 row
->start
= it
->start
;
19279 row
->continuation_lines_width
= it
->continuation_lines_width
;
19280 row
->displays_text_p
= 1;
19281 row
->starts_in_middle_of_char_p
= it
->starts_in_middle_of_char_p
;
19282 it
->starts_in_middle_of_char_p
= 0;
19284 /* Arrange the overlays nicely for our purposes. Usually, we call
19285 display_line on only one line at a time, in which case this
19286 can't really hurt too much, or we call it on lines which appear
19287 one after another in the buffer, in which case all calls to
19288 recenter_overlay_lists but the first will be pretty cheap. */
19289 recenter_overlay_lists (current_buffer
, IT_CHARPOS (*it
));
19291 /* Move over display elements that are not visible because we are
19292 hscrolled. This may stop at an x-position < IT->first_visible_x
19293 if the first glyph is partially visible or if we hit a line end. */
19294 if (it
->current_x
< it
->first_visible_x
)
19296 enum move_it_result move_result
;
19298 this_line_min_pos
= row
->start
.pos
;
19299 move_result
= move_it_in_display_line_to (it
, ZV
, it
->first_visible_x
,
19300 MOVE_TO_POS
| MOVE_TO_X
);
19301 /* If we are under a large hscroll, move_it_in_display_line_to
19302 could hit the end of the line without reaching
19303 it->first_visible_x. Pretend that we did reach it. This is
19304 especially important on a TTY, where we will call
19305 extend_face_to_end_of_line, which needs to know how many
19306 blank glyphs to produce. */
19307 if (it
->current_x
< it
->first_visible_x
19308 && (move_result
== MOVE_NEWLINE_OR_CR
19309 || move_result
== MOVE_POS_MATCH_OR_ZV
))
19310 it
->current_x
= it
->first_visible_x
;
19312 /* Record the smallest positions seen while we moved over
19313 display elements that are not visible. This is needed by
19314 redisplay_internal for optimizing the case where the cursor
19315 stays inside the same line. The rest of this function only
19316 considers positions that are actually displayed, so
19317 RECORD_MAX_MIN_POS will not otherwise record positions that
19318 are hscrolled to the left of the left edge of the window. */
19319 min_pos
= CHARPOS (this_line_min_pos
);
19320 min_bpos
= BYTEPOS (this_line_min_pos
);
19324 /* We only do this when not calling `move_it_in_display_line_to'
19325 above, because move_it_in_display_line_to calls
19326 handle_line_prefix itself. */
19327 handle_line_prefix (it
);
19330 /* Get the initial row height. This is either the height of the
19331 text hscrolled, if there is any, or zero. */
19332 row
->ascent
= it
->max_ascent
;
19333 row
->height
= it
->max_ascent
+ it
->max_descent
;
19334 row
->phys_ascent
= it
->max_phys_ascent
;
19335 row
->phys_height
= it
->max_phys_ascent
+ it
->max_phys_descent
;
19336 row
->extra_line_spacing
= it
->max_extra_line_spacing
;
19338 /* Utility macro to record max and min buffer positions seen until now. */
19339 #define RECORD_MAX_MIN_POS(IT) \
19342 int composition_p = !STRINGP ((IT)->string) \
19343 && ((IT)->what == IT_COMPOSITION); \
19344 ptrdiff_t current_pos = \
19345 composition_p ? (IT)->cmp_it.charpos \
19346 : IT_CHARPOS (*(IT)); \
19347 ptrdiff_t current_bpos = \
19348 composition_p ? CHAR_TO_BYTE (current_pos) \
19349 : IT_BYTEPOS (*(IT)); \
19350 if (current_pos < min_pos) \
19352 min_pos = current_pos; \
19353 min_bpos = current_bpos; \
19355 if (IT_CHARPOS (*it) > max_pos) \
19357 max_pos = IT_CHARPOS (*it); \
19358 max_bpos = IT_BYTEPOS (*it); \
19363 /* Loop generating characters. The loop is left with IT on the next
19364 character to display. */
19367 int n_glyphs_before
, hpos_before
, x_before
;
19369 int ascent
= 0, descent
= 0, phys_ascent
= 0, phys_descent
= 0;
19371 /* Retrieve the next thing to display. Value is zero if end of
19373 if (!get_next_display_element (it
))
19375 /* Maybe add a space at the end of this line that is used to
19376 display the cursor there under X. Set the charpos of the
19377 first glyph of blank lines not corresponding to any text
19379 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
19380 row
->exact_window_width_line_p
= 1;
19381 else if ((append_space_for_newline (it
, 1) && row
->used
[TEXT_AREA
] == 1)
19382 || row
->used
[TEXT_AREA
] == 0)
19384 row
->glyphs
[TEXT_AREA
]->charpos
= -1;
19385 row
->displays_text_p
= 0;
19387 if (!NILP (BVAR (XBUFFER (it
->w
->contents
), indicate_empty_lines
))
19388 && (!MINI_WINDOW_P (it
->w
)
19389 || (minibuf_level
&& EQ (it
->window
, minibuf_window
))))
19390 row
->indicate_empty_line_p
= 1;
19393 it
->continuation_lines_width
= 0;
19394 row
->ends_at_zv_p
= 1;
19395 /* A row that displays right-to-left text must always have
19396 its last face extended all the way to the end of line,
19397 even if this row ends in ZV, because we still write to
19398 the screen left to right. We also need to extend the
19399 last face if the default face is remapped to some
19400 different face, otherwise the functions that clear
19401 portions of the screen will clear with the default face's
19402 background color. */
19403 if (row
->reversed_p
19404 || lookup_basic_face (it
->f
, DEFAULT_FACE_ID
) != DEFAULT_FACE_ID
)
19405 extend_face_to_end_of_line (it
);
19409 /* Now, get the metrics of what we want to display. This also
19410 generates glyphs in `row' (which is IT->glyph_row). */
19411 n_glyphs_before
= row
->used
[TEXT_AREA
];
19414 /* Remember the line height so far in case the next element doesn't
19415 fit on the line. */
19416 if (it
->line_wrap
!= TRUNCATE
)
19418 ascent
= it
->max_ascent
;
19419 descent
= it
->max_descent
;
19420 phys_ascent
= it
->max_phys_ascent
;
19421 phys_descent
= it
->max_phys_descent
;
19423 if (it
->line_wrap
== WORD_WRAP
&& it
->area
== TEXT_AREA
)
19425 if (IT_DISPLAYING_WHITESPACE (it
))
19429 SAVE_IT (wrap_it
, *it
, wrap_data
);
19431 wrap_row_used
= row
->used
[TEXT_AREA
];
19432 wrap_row_ascent
= row
->ascent
;
19433 wrap_row_height
= row
->height
;
19434 wrap_row_phys_ascent
= row
->phys_ascent
;
19435 wrap_row_phys_height
= row
->phys_height
;
19436 wrap_row_extra_line_spacing
= row
->extra_line_spacing
;
19437 wrap_row_min_pos
= min_pos
;
19438 wrap_row_min_bpos
= min_bpos
;
19439 wrap_row_max_pos
= max_pos
;
19440 wrap_row_max_bpos
= max_bpos
;
19446 PRODUCE_GLYPHS (it
);
19448 /* If this display element was in marginal areas, continue with
19450 if (it
->area
!= TEXT_AREA
)
19452 row
->ascent
= max (row
->ascent
, it
->max_ascent
);
19453 row
->height
= max (row
->height
, it
->max_ascent
+ it
->max_descent
);
19454 row
->phys_ascent
= max (row
->phys_ascent
, it
->max_phys_ascent
);
19455 row
->phys_height
= max (row
->phys_height
,
19456 it
->max_phys_ascent
+ it
->max_phys_descent
);
19457 row
->extra_line_spacing
= max (row
->extra_line_spacing
,
19458 it
->max_extra_line_spacing
);
19459 set_iterator_to_next (it
, 1);
19463 /* Does the display element fit on the line? If we truncate
19464 lines, we should draw past the right edge of the window. If
19465 we don't truncate, we want to stop so that we can display the
19466 continuation glyph before the right margin. If lines are
19467 continued, there are two possible strategies for characters
19468 resulting in more than 1 glyph (e.g. tabs): Display as many
19469 glyphs as possible in this line and leave the rest for the
19470 continuation line, or display the whole element in the next
19471 line. Original redisplay did the former, so we do it also. */
19472 nglyphs
= row
->used
[TEXT_AREA
] - n_glyphs_before
;
19473 hpos_before
= it
->hpos
;
19476 if (/* Not a newline. */
19478 /* Glyphs produced fit entirely in the line. */
19479 && it
->current_x
< it
->last_visible_x
)
19481 it
->hpos
+= nglyphs
;
19482 row
->ascent
= max (row
->ascent
, it
->max_ascent
);
19483 row
->height
= max (row
->height
, it
->max_ascent
+ it
->max_descent
);
19484 row
->phys_ascent
= max (row
->phys_ascent
, it
->max_phys_ascent
);
19485 row
->phys_height
= max (row
->phys_height
,
19486 it
->max_phys_ascent
+ it
->max_phys_descent
);
19487 row
->extra_line_spacing
= max (row
->extra_line_spacing
,
19488 it
->max_extra_line_spacing
);
19489 if (it
->current_x
- it
->pixel_width
< it
->first_visible_x
)
19490 row
->x
= x
- it
->first_visible_x
;
19491 /* Record the maximum and minimum buffer positions seen so
19492 far in glyphs that will be displayed by this row. */
19494 RECORD_MAX_MIN_POS (it
);
19499 struct glyph
*glyph
;
19501 for (i
= 0; i
< nglyphs
; ++i
, x
= new_x
)
19503 glyph
= row
->glyphs
[TEXT_AREA
] + n_glyphs_before
+ i
;
19504 new_x
= x
+ glyph
->pixel_width
;
19506 if (/* Lines are continued. */
19507 it
->line_wrap
!= TRUNCATE
19508 && (/* Glyph doesn't fit on the line. */
19509 new_x
> it
->last_visible_x
19510 /* Or it fits exactly on a window system frame. */
19511 || (new_x
== it
->last_visible_x
19512 && FRAME_WINDOW_P (it
->f
)
19513 && (row
->reversed_p
19514 ? WINDOW_LEFT_FRINGE_WIDTH (it
->w
)
19515 : WINDOW_RIGHT_FRINGE_WIDTH (it
->w
)))))
19517 /* End of a continued line. */
19520 || (new_x
== it
->last_visible_x
19521 && FRAME_WINDOW_P (it
->f
)
19522 && (row
->reversed_p
19523 ? WINDOW_LEFT_FRINGE_WIDTH (it
->w
)
19524 : WINDOW_RIGHT_FRINGE_WIDTH (it
->w
))))
19526 /* Current glyph is the only one on the line or
19527 fits exactly on the line. We must continue
19528 the line because we can't draw the cursor
19529 after the glyph. */
19530 row
->continued_p
= 1;
19531 it
->current_x
= new_x
;
19532 it
->continuation_lines_width
+= new_x
;
19534 if (i
== nglyphs
- 1)
19536 /* If line-wrap is on, check if a previous
19537 wrap point was found. */
19538 if (wrap_row_used
> 0
19539 /* Even if there is a previous wrap
19540 point, continue the line here as
19541 usual, if (i) the previous character
19542 was a space or tab AND (ii) the
19543 current character is not. */
19545 || IT_DISPLAYING_WHITESPACE (it
)))
19548 /* Record the maximum and minimum buffer
19549 positions seen so far in glyphs that will be
19550 displayed by this row. */
19552 RECORD_MAX_MIN_POS (it
);
19553 set_iterator_to_next (it
, 1);
19554 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
19556 if (!get_next_display_element (it
))
19558 row
->exact_window_width_line_p
= 1;
19559 it
->continuation_lines_width
= 0;
19560 row
->continued_p
= 0;
19561 row
->ends_at_zv_p
= 1;
19563 else if (ITERATOR_AT_END_OF_LINE_P (it
))
19565 row
->continued_p
= 0;
19566 row
->exact_window_width_line_p
= 1;
19570 else if (it
->bidi_p
)
19571 RECORD_MAX_MIN_POS (it
);
19573 else if (CHAR_GLYPH_PADDING_P (*glyph
)
19574 && !FRAME_WINDOW_P (it
->f
))
19576 /* A padding glyph that doesn't fit on this line.
19577 This means the whole character doesn't fit
19579 if (row
->reversed_p
)
19580 unproduce_glyphs (it
, row
->used
[TEXT_AREA
]
19581 - n_glyphs_before
);
19582 row
->used
[TEXT_AREA
] = n_glyphs_before
;
19584 /* Fill the rest of the row with continuation
19585 glyphs like in 20.x. */
19586 while (row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
]
19587 < row
->glyphs
[1 + TEXT_AREA
])
19588 produce_special_glyphs (it
, IT_CONTINUATION
);
19590 row
->continued_p
= 1;
19591 it
->current_x
= x_before
;
19592 it
->continuation_lines_width
+= x_before
;
19594 /* Restore the height to what it was before the
19595 element not fitting on the line. */
19596 it
->max_ascent
= ascent
;
19597 it
->max_descent
= descent
;
19598 it
->max_phys_ascent
= phys_ascent
;
19599 it
->max_phys_descent
= phys_descent
;
19601 else if (wrap_row_used
> 0)
19604 if (row
->reversed_p
)
19605 unproduce_glyphs (it
,
19606 row
->used
[TEXT_AREA
] - wrap_row_used
);
19607 RESTORE_IT (it
, &wrap_it
, wrap_data
);
19608 it
->continuation_lines_width
+= wrap_x
;
19609 row
->used
[TEXT_AREA
] = wrap_row_used
;
19610 row
->ascent
= wrap_row_ascent
;
19611 row
->height
= wrap_row_height
;
19612 row
->phys_ascent
= wrap_row_phys_ascent
;
19613 row
->phys_height
= wrap_row_phys_height
;
19614 row
->extra_line_spacing
= wrap_row_extra_line_spacing
;
19615 min_pos
= wrap_row_min_pos
;
19616 min_bpos
= wrap_row_min_bpos
;
19617 max_pos
= wrap_row_max_pos
;
19618 max_bpos
= wrap_row_max_bpos
;
19619 row
->continued_p
= 1;
19620 row
->ends_at_zv_p
= 0;
19621 row
->exact_window_width_line_p
= 0;
19622 it
->continuation_lines_width
+= x
;
19624 /* Make sure that a non-default face is extended
19625 up to the right margin of the window. */
19626 extend_face_to_end_of_line (it
);
19628 else if (it
->c
== '\t' && FRAME_WINDOW_P (it
->f
))
19630 /* A TAB that extends past the right edge of the
19631 window. This produces a single glyph on
19632 window system frames. We leave the glyph in
19633 this row and let it fill the row, but don't
19634 consume the TAB. */
19635 if ((row
->reversed_p
19636 ? WINDOW_LEFT_FRINGE_WIDTH (it
->w
)
19637 : WINDOW_RIGHT_FRINGE_WIDTH (it
->w
)) == 0)
19638 produce_special_glyphs (it
, IT_CONTINUATION
);
19639 it
->continuation_lines_width
+= it
->last_visible_x
;
19640 row
->ends_in_middle_of_char_p
= 1;
19641 row
->continued_p
= 1;
19642 glyph
->pixel_width
= it
->last_visible_x
- x
;
19643 it
->starts_in_middle_of_char_p
= 1;
19647 /* Something other than a TAB that draws past
19648 the right edge of the window. Restore
19649 positions to values before the element. */
19650 if (row
->reversed_p
)
19651 unproduce_glyphs (it
, row
->used
[TEXT_AREA
]
19652 - (n_glyphs_before
+ i
));
19653 row
->used
[TEXT_AREA
] = n_glyphs_before
+ i
;
19655 /* Display continuation glyphs. */
19656 it
->current_x
= x_before
;
19657 it
->continuation_lines_width
+= x
;
19658 if (!FRAME_WINDOW_P (it
->f
)
19659 || (row
->reversed_p
19660 ? WINDOW_LEFT_FRINGE_WIDTH (it
->w
)
19661 : WINDOW_RIGHT_FRINGE_WIDTH (it
->w
)) == 0)
19662 produce_special_glyphs (it
, IT_CONTINUATION
);
19663 row
->continued_p
= 1;
19665 extend_face_to_end_of_line (it
);
19667 if (nglyphs
> 1 && i
> 0)
19669 row
->ends_in_middle_of_char_p
= 1;
19670 it
->starts_in_middle_of_char_p
= 1;
19673 /* Restore the height to what it was before the
19674 element not fitting on the line. */
19675 it
->max_ascent
= ascent
;
19676 it
->max_descent
= descent
;
19677 it
->max_phys_ascent
= phys_ascent
;
19678 it
->max_phys_descent
= phys_descent
;
19683 else if (new_x
> it
->first_visible_x
)
19685 /* Increment number of glyphs actually displayed. */
19688 /* Record the maximum and minimum buffer positions
19689 seen so far in glyphs that will be displayed by
19692 RECORD_MAX_MIN_POS (it
);
19694 if (x
< it
->first_visible_x
)
19695 /* Glyph is partially visible, i.e. row starts at
19696 negative X position. */
19697 row
->x
= x
- it
->first_visible_x
;
19701 /* Glyph is completely off the left margin of the
19702 window. This should not happen because of the
19703 move_it_in_display_line at the start of this
19704 function, unless the text display area of the
19705 window is empty. */
19706 eassert (it
->first_visible_x
<= it
->last_visible_x
);
19709 /* Even if this display element produced no glyphs at all,
19710 we want to record its position. */
19711 if (it
->bidi_p
&& nglyphs
== 0)
19712 RECORD_MAX_MIN_POS (it
);
19714 row
->ascent
= max (row
->ascent
, it
->max_ascent
);
19715 row
->height
= max (row
->height
, it
->max_ascent
+ it
->max_descent
);
19716 row
->phys_ascent
= max (row
->phys_ascent
, it
->max_phys_ascent
);
19717 row
->phys_height
= max (row
->phys_height
,
19718 it
->max_phys_ascent
+ it
->max_phys_descent
);
19719 row
->extra_line_spacing
= max (row
->extra_line_spacing
,
19720 it
->max_extra_line_spacing
);
19722 /* End of this display line if row is continued. */
19723 if (row
->continued_p
|| row
->ends_at_zv_p
)
19728 /* Is this a line end? If yes, we're also done, after making
19729 sure that a non-default face is extended up to the right
19730 margin of the window. */
19731 if (ITERATOR_AT_END_OF_LINE_P (it
))
19733 int used_before
= row
->used
[TEXT_AREA
];
19735 row
->ends_in_newline_from_string_p
= STRINGP (it
->object
);
19737 /* Add a space at the end of the line that is used to
19738 display the cursor there. */
19739 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
19740 append_space_for_newline (it
, 0);
19742 /* Extend the face to the end of the line. */
19743 extend_face_to_end_of_line (it
);
19745 /* Make sure we have the position. */
19746 if (used_before
== 0)
19747 row
->glyphs
[TEXT_AREA
]->charpos
= CHARPOS (it
->position
);
19749 /* Record the position of the newline, for use in
19751 it
->eol_pos
= it
->current
.pos
;
19753 /* Consume the line end. This skips over invisible lines. */
19754 set_iterator_to_next (it
, 1);
19755 it
->continuation_lines_width
= 0;
19759 /* Proceed with next display element. Note that this skips
19760 over lines invisible because of selective display. */
19761 set_iterator_to_next (it
, 1);
19763 /* If we truncate lines, we are done when the last displayed
19764 glyphs reach past the right margin of the window. */
19765 if (it
->line_wrap
== TRUNCATE
19766 && (FRAME_WINDOW_P (it
->f
) && WINDOW_RIGHT_FRINGE_WIDTH (it
->w
)
19767 ? (it
->current_x
>= it
->last_visible_x
)
19768 : (it
->current_x
> it
->last_visible_x
)))
19770 /* Maybe add truncation glyphs. */
19771 if (!FRAME_WINDOW_P (it
->f
)
19772 || (row
->reversed_p
19773 ? WINDOW_LEFT_FRINGE_WIDTH (it
->w
)
19774 : WINDOW_RIGHT_FRINGE_WIDTH (it
->w
)) == 0)
19778 if (!row
->reversed_p
)
19780 for (i
= row
->used
[TEXT_AREA
] - 1; i
> 0; --i
)
19781 if (!CHAR_GLYPH_PADDING_P (row
->glyphs
[TEXT_AREA
][i
]))
19786 for (i
= 0; i
< row
->used
[TEXT_AREA
]; i
++)
19787 if (!CHAR_GLYPH_PADDING_P (row
->glyphs
[TEXT_AREA
][i
]))
19789 /* Remove any padding glyphs at the front of ROW, to
19790 make room for the truncation glyphs we will be
19791 adding below. The loop below always inserts at
19792 least one truncation glyph, so also remove the
19793 last glyph added to ROW. */
19794 unproduce_glyphs (it
, i
+ 1);
19795 /* Adjust i for the loop below. */
19796 i
= row
->used
[TEXT_AREA
] - (i
+ 1);
19799 it
->current_x
= x_before
;
19800 if (!FRAME_WINDOW_P (it
->f
))
19802 for (n
= row
->used
[TEXT_AREA
]; i
< n
; ++i
)
19804 row
->used
[TEXT_AREA
] = i
;
19805 produce_special_glyphs (it
, IT_TRUNCATION
);
19810 row
->used
[TEXT_AREA
] = i
;
19811 produce_special_glyphs (it
, IT_TRUNCATION
);
19814 else if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
19816 /* Don't truncate if we can overflow newline into fringe. */
19817 if (!get_next_display_element (it
))
19819 it
->continuation_lines_width
= 0;
19820 row
->ends_at_zv_p
= 1;
19821 row
->exact_window_width_line_p
= 1;
19824 if (ITERATOR_AT_END_OF_LINE_P (it
))
19826 row
->exact_window_width_line_p
= 1;
19827 goto at_end_of_line
;
19829 it
->current_x
= x_before
;
19832 row
->truncated_on_right_p
= 1;
19833 it
->continuation_lines_width
= 0;
19834 reseat_at_next_visible_line_start (it
, 0);
19835 row
->ends_at_zv_p
= FETCH_BYTE (IT_BYTEPOS (*it
) - 1) != '\n';
19836 it
->hpos
= hpos_before
;
19842 bidi_unshelve_cache (wrap_data
, 1);
19844 /* If line is not empty and hscrolled, maybe insert truncation glyphs
19845 at the left window margin. */
19846 if (it
->first_visible_x
19847 && IT_CHARPOS (*it
) != CHARPOS (row
->start
.pos
))
19849 if (!FRAME_WINDOW_P (it
->f
)
19850 || (row
->reversed_p
19851 ? WINDOW_RIGHT_FRINGE_WIDTH (it
->w
)
19852 : WINDOW_LEFT_FRINGE_WIDTH (it
->w
)) == 0)
19853 insert_left_trunc_glyphs (it
);
19854 row
->truncated_on_left_p
= 1;
19857 /* Remember the position at which this line ends.
19859 BIDI Note: any code that needs MATRIX_ROW_START/END_CHARPOS
19860 cannot be before the call to find_row_edges below, since that is
19861 where these positions are determined. */
19862 row
->end
= it
->current
;
19865 row
->minpos
= row
->start
.pos
;
19866 row
->maxpos
= row
->end
.pos
;
19870 /* ROW->minpos and ROW->maxpos must be the smallest and
19871 `1 + the largest' buffer positions in ROW. But if ROW was
19872 bidi-reordered, these two positions can be anywhere in the
19873 row, so we must determine them now. */
19874 find_row_edges (it
, row
, min_pos
, min_bpos
, max_pos
, max_bpos
);
19877 /* If the start of this line is the overlay arrow-position, then
19878 mark this glyph row as the one containing the overlay arrow.
19879 This is clearly a mess with variable size fonts. It would be
19880 better to let it be displayed like cursors under X. */
19881 if ((MATRIX_ROW_DISPLAYS_TEXT_P (row
) || !overlay_arrow_seen
)
19882 && (overlay_arrow_string
= overlay_arrow_at_row (it
, row
),
19883 !NILP (overlay_arrow_string
)))
19885 /* Overlay arrow in window redisplay is a fringe bitmap. */
19886 if (STRINGP (overlay_arrow_string
))
19888 struct glyph_row
*arrow_row
19889 = get_overlay_arrow_glyph_row (it
->w
, overlay_arrow_string
);
19890 struct glyph
*glyph
= arrow_row
->glyphs
[TEXT_AREA
];
19891 struct glyph
*arrow_end
= glyph
+ arrow_row
->used
[TEXT_AREA
];
19892 struct glyph
*p
= row
->glyphs
[TEXT_AREA
];
19893 struct glyph
*p2
, *end
;
19895 /* Copy the arrow glyphs. */
19896 while (glyph
< arrow_end
)
19899 /* Throw away padding glyphs. */
19901 end
= row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
];
19902 while (p2
< end
&& CHAR_GLYPH_PADDING_P (*p2
))
19908 row
->used
[TEXT_AREA
] = p2
- row
->glyphs
[TEXT_AREA
];
19913 eassert (INTEGERP (overlay_arrow_string
));
19914 row
->overlay_arrow_bitmap
= XINT (overlay_arrow_string
);
19916 overlay_arrow_seen
= 1;
19919 /* Highlight trailing whitespace. */
19920 if (!NILP (Vshow_trailing_whitespace
))
19921 highlight_trailing_whitespace (it
->f
, it
->glyph_row
);
19923 /* Compute pixel dimensions of this line. */
19924 compute_line_metrics (it
);
19926 /* Implementation note: No changes in the glyphs of ROW or in their
19927 faces can be done past this point, because compute_line_metrics
19928 computes ROW's hash value and stores it within the glyph_row
19931 /* Record whether this row ends inside an ellipsis. */
19932 row
->ends_in_ellipsis_p
19933 = (it
->method
== GET_FROM_DISPLAY_VECTOR
19934 && it
->ellipsis_p
);
19936 /* Save fringe bitmaps in this row. */
19937 row
->left_user_fringe_bitmap
= it
->left_user_fringe_bitmap
;
19938 row
->left_user_fringe_face_id
= it
->left_user_fringe_face_id
;
19939 row
->right_user_fringe_bitmap
= it
->right_user_fringe_bitmap
;
19940 row
->right_user_fringe_face_id
= it
->right_user_fringe_face_id
;
19942 it
->left_user_fringe_bitmap
= 0;
19943 it
->left_user_fringe_face_id
= 0;
19944 it
->right_user_fringe_bitmap
= 0;
19945 it
->right_user_fringe_face_id
= 0;
19947 /* Maybe set the cursor. */
19948 cvpos
= it
->w
->cursor
.vpos
;
19950 /* In bidi-reordered rows, keep checking for proper cursor
19951 position even if one has been found already, because buffer
19952 positions in such rows change non-linearly with ROW->VPOS,
19953 when a line is continued. One exception: when we are at ZV,
19954 display cursor on the first suitable glyph row, since all
19955 the empty rows after that also have their position set to ZV. */
19956 /* FIXME: Revisit this when glyph ``spilling'' in continuation
19957 lines' rows is implemented for bidi-reordered rows. */
19959 && !MATRIX_ROW (it
->w
->desired_matrix
, cvpos
)->ends_at_zv_p
))
19960 && PT
>= MATRIX_ROW_START_CHARPOS (row
)
19961 && PT
<= MATRIX_ROW_END_CHARPOS (row
)
19962 && cursor_row_p (row
))
19963 set_cursor_from_row (it
->w
, row
, it
->w
->desired_matrix
, 0, 0, 0, 0);
19965 /* Prepare for the next line. This line starts horizontally at (X
19966 HPOS) = (0 0). Vertical positions are incremented. As a
19967 convenience for the caller, IT->glyph_row is set to the next
19969 it
->current_x
= it
->hpos
= 0;
19970 it
->current_y
+= row
->height
;
19971 SET_TEXT_POS (it
->eol_pos
, 0, 0);
19974 /* The next row should by default use the same value of the
19975 reversed_p flag as this one. set_iterator_to_next decides when
19976 it's a new paragraph, and PRODUCE_GLYPHS recomputes the value of
19977 the flag accordingly. */
19978 if (it
->glyph_row
< MATRIX_BOTTOM_TEXT_ROW (it
->w
->desired_matrix
, it
->w
))
19979 it
->glyph_row
->reversed_p
= row
->reversed_p
;
19980 it
->start
= row
->end
;
19981 return MATRIX_ROW_DISPLAYS_TEXT_P (row
);
19983 #undef RECORD_MAX_MIN_POS
19986 DEFUN ("current-bidi-paragraph-direction", Fcurrent_bidi_paragraph_direction
,
19987 Scurrent_bidi_paragraph_direction
, 0, 1, 0,
19988 doc
: /* Return paragraph direction at point in BUFFER.
19989 Value is either `left-to-right' or `right-to-left'.
19990 If BUFFER is omitted or nil, it defaults to the current buffer.
19992 Paragraph direction determines how the text in the paragraph is displayed.
19993 In left-to-right paragraphs, text begins at the left margin of the window
19994 and the reading direction is generally left to right. In right-to-left
19995 paragraphs, text begins at the right margin and is read from right to left.
19997 See also `bidi-paragraph-direction'. */)
19998 (Lisp_Object buffer
)
20000 struct buffer
*buf
= current_buffer
;
20001 struct buffer
*old
= buf
;
20003 if (! NILP (buffer
))
20005 CHECK_BUFFER (buffer
);
20006 buf
= XBUFFER (buffer
);
20009 if (NILP (BVAR (buf
, bidi_display_reordering
))
20010 || NILP (BVAR (buf
, enable_multibyte_characters
))
20011 /* When we are loading loadup.el, the character property tables
20012 needed for bidi iteration are not yet available. */
20013 || !NILP (Vpurify_flag
))
20014 return Qleft_to_right
;
20015 else if (!NILP (BVAR (buf
, bidi_paragraph_direction
)))
20016 return BVAR (buf
, bidi_paragraph_direction
);
20019 /* Determine the direction from buffer text. We could try to
20020 use current_matrix if it is up to date, but this seems fast
20021 enough as it is. */
20022 struct bidi_it itb
;
20023 ptrdiff_t pos
= BUF_PT (buf
);
20024 ptrdiff_t bytepos
= BUF_PT_BYTE (buf
);
20026 void *itb_data
= bidi_shelve_cache ();
20028 set_buffer_temp (buf
);
20029 /* bidi_paragraph_init finds the base direction of the paragraph
20030 by searching forward from paragraph start. We need the base
20031 direction of the current or _previous_ paragraph, so we need
20032 to make sure we are within that paragraph. To that end, find
20033 the previous non-empty line. */
20034 if (pos
>= ZV
&& pos
> BEGV
)
20035 DEC_BOTH (pos
, bytepos
);
20036 if (fast_looking_at (build_string ("[\f\t ]*\n"),
20037 pos
, bytepos
, ZV
, ZV_BYTE
, Qnil
) > 0)
20039 while ((c
= FETCH_BYTE (bytepos
)) == '\n'
20040 || c
== ' ' || c
== '\t' || c
== '\f')
20042 if (bytepos
<= BEGV_BYTE
)
20047 while (!CHAR_HEAD_P (FETCH_BYTE (bytepos
)))
20050 bidi_init_it (pos
, bytepos
, FRAME_WINDOW_P (SELECTED_FRAME ()), &itb
);
20051 itb
.paragraph_dir
= NEUTRAL_DIR
;
20052 itb
.string
.s
= NULL
;
20053 itb
.string
.lstring
= Qnil
;
20054 itb
.string
.bufpos
= 0;
20055 itb
.string
.unibyte
= 0;
20056 /* We have no window to use here for ignoring window-specific
20057 overlays. Using NULL for window pointer will cause
20058 compute_display_string_pos to use the current buffer. */
20060 bidi_paragraph_init (NEUTRAL_DIR
, &itb
, 1);
20061 bidi_unshelve_cache (itb_data
, 0);
20062 set_buffer_temp (old
);
20063 switch (itb
.paragraph_dir
)
20066 return Qleft_to_right
;
20069 return Qright_to_left
;
20077 DEFUN ("move-point-visually", Fmove_point_visually
,
20078 Smove_point_visually
, 1, 1, 0,
20079 doc
: /* Move point in the visual order in the specified DIRECTION.
20080 DIRECTION can be 1, meaning move to the right, or -1, which moves to the
20083 Value is the new character position of point. */)
20084 (Lisp_Object direction
)
20086 struct window
*w
= XWINDOW (selected_window
);
20087 struct buffer
*b
= XBUFFER (w
->contents
);
20088 struct glyph_row
*row
;
20090 Lisp_Object paragraph_dir
;
20092 #define ROW_GLYPH_NEWLINE_P(ROW,GLYPH) \
20093 (!(ROW)->continued_p \
20094 && INTEGERP ((GLYPH)->object) \
20095 && (GLYPH)->type == CHAR_GLYPH \
20096 && (GLYPH)->u.ch == ' ' \
20097 && (GLYPH)->charpos >= 0 \
20098 && !(GLYPH)->avoid_cursor_p)
20100 CHECK_NUMBER (direction
);
20101 dir
= XINT (direction
);
20107 /* If current matrix is up-to-date, we can use the information
20108 recorded in the glyphs, at least as long as the goal is on the
20110 if (w
->window_end_valid
20111 && !windows_or_buffers_changed
20113 && !b
->clip_changed
20114 && !b
->prevent_redisplay_optimizations_p
20115 && !window_outdated (w
)
20116 && w
->cursor
.vpos
>= 0
20117 && w
->cursor
.vpos
< w
->current_matrix
->nrows
20118 && (row
= MATRIX_ROW (w
->current_matrix
, w
->cursor
.vpos
))->enabled_p
)
20120 struct glyph
*g
= row
->glyphs
[TEXT_AREA
];
20121 struct glyph
*e
= dir
> 0 ? g
+ row
->used
[TEXT_AREA
] : g
- 1;
20122 struct glyph
*gpt
= g
+ w
->cursor
.hpos
;
20124 for (g
= gpt
+ dir
; (dir
> 0 ? g
< e
: g
> e
); g
+= dir
)
20126 if (BUFFERP (g
->object
) && g
->charpos
!= PT
)
20128 SET_PT (g
->charpos
);
20129 w
->cursor
.vpos
= -1;
20130 return make_number (PT
);
20132 else if (!INTEGERP (g
->object
) && !EQ (g
->object
, gpt
->object
))
20136 if (BUFFERP (gpt
->object
))
20139 if ((gpt
->resolved_level
- row
->reversed_p
) % 2 == 0)
20140 new_pos
+= (row
->reversed_p
? -dir
: dir
);
20142 new_pos
-= (row
->reversed_p
? -dir
: dir
);;
20144 else if (BUFFERP (g
->object
))
20145 new_pos
= g
->charpos
;
20149 w
->cursor
.vpos
= -1;
20150 return make_number (PT
);
20152 else if (ROW_GLYPH_NEWLINE_P (row
, g
))
20154 /* Glyphs inserted at the end of a non-empty line for
20155 positioning the cursor have zero charpos, so we must
20156 deduce the value of point by other means. */
20157 if (g
->charpos
> 0)
20158 SET_PT (g
->charpos
);
20159 else if (row
->ends_at_zv_p
&& PT
!= ZV
)
20161 else if (PT
!= MATRIX_ROW_END_CHARPOS (row
) - 1)
20162 SET_PT (MATRIX_ROW_END_CHARPOS (row
) - 1);
20165 w
->cursor
.vpos
= -1;
20166 return make_number (PT
);
20169 if (g
== e
|| INTEGERP (g
->object
))
20171 if (row
->truncated_on_left_p
|| row
->truncated_on_right_p
)
20172 goto simulate_display
;
20173 if (!row
->reversed_p
)
20177 if (row
< MATRIX_FIRST_TEXT_ROW (w
->current_matrix
)
20178 || row
> MATRIX_BOTTOM_TEXT_ROW (w
->current_matrix
, w
))
20179 goto simulate_display
;
20183 if (row
->reversed_p
&& !row
->continued_p
)
20185 SET_PT (MATRIX_ROW_END_CHARPOS (row
) - 1);
20186 w
->cursor
.vpos
= -1;
20187 return make_number (PT
);
20189 g
= row
->glyphs
[TEXT_AREA
];
20190 e
= g
+ row
->used
[TEXT_AREA
];
20191 for ( ; g
< e
; g
++)
20193 if (BUFFERP (g
->object
)
20194 /* Empty lines have only one glyph, which stands
20195 for the newline, and whose charpos is the
20196 buffer position of the newline. */
20197 || ROW_GLYPH_NEWLINE_P (row
, g
)
20198 /* When the buffer ends in a newline, the line at
20199 EOB also has one glyph, but its charpos is -1. */
20200 || (row
->ends_at_zv_p
20201 && !row
->reversed_p
20202 && INTEGERP (g
->object
)
20203 && g
->type
== CHAR_GLYPH
20204 && g
->u
.ch
== ' '))
20206 if (g
->charpos
> 0)
20207 SET_PT (g
->charpos
);
20208 else if (!row
->reversed_p
20209 && row
->ends_at_zv_p
20214 w
->cursor
.vpos
= -1;
20215 return make_number (PT
);
20221 if (!row
->reversed_p
&& !row
->continued_p
)
20223 SET_PT (MATRIX_ROW_END_CHARPOS (row
) - 1);
20224 w
->cursor
.vpos
= -1;
20225 return make_number (PT
);
20227 e
= row
->glyphs
[TEXT_AREA
];
20228 g
= e
+ row
->used
[TEXT_AREA
] - 1;
20229 for ( ; g
>= e
; g
--)
20231 if (BUFFERP (g
->object
)
20232 || (ROW_GLYPH_NEWLINE_P (row
, g
)
20234 /* Empty R2L lines on GUI frames have the buffer
20235 position of the newline stored in the stretch
20237 || g
->type
== STRETCH_GLYPH
20238 || (row
->ends_at_zv_p
20240 && INTEGERP (g
->object
)
20241 && g
->type
== CHAR_GLYPH
20242 && g
->u
.ch
== ' '))
20244 if (g
->charpos
> 0)
20245 SET_PT (g
->charpos
);
20246 else if (row
->reversed_p
20247 && row
->ends_at_zv_p
20252 w
->cursor
.vpos
= -1;
20253 return make_number (PT
);
20262 /* If we wind up here, we failed to move by using the glyphs, so we
20263 need to simulate display instead. */
20266 paragraph_dir
= Fcurrent_bidi_paragraph_direction (w
->contents
);
20268 paragraph_dir
= Qleft_to_right
;
20269 if (EQ (paragraph_dir
, Qright_to_left
))
20271 if (PT
<= BEGV
&& dir
< 0)
20272 xsignal0 (Qbeginning_of_buffer
);
20273 else if (PT
>= ZV
&& dir
> 0)
20274 xsignal0 (Qend_of_buffer
);
20277 struct text_pos pt
;
20279 int pt_x
, target_x
, pixel_width
, pt_vpos
;
20281 bool overshoot_expected
= false;
20282 bool target_is_eol_p
= false;
20284 /* Setup the arena. */
20285 SET_TEXT_POS (pt
, PT
, PT_BYTE
);
20286 start_display (&it
, w
, pt
);
20288 if (it
.cmp_it
.id
< 0
20289 && it
.method
== GET_FROM_STRING
20290 && it
.area
== TEXT_AREA
20291 && it
.string_from_display_prop_p
20292 && (it
.sp
> 0 && it
.stack
[it
.sp
- 1].method
== GET_FROM_BUFFER
))
20293 overshoot_expected
= true;
20295 /* Find the X coordinate of point. We start from the beginning
20296 of this or previous line to make sure we are before point in
20297 the logical order (since the move_it_* functions can only
20299 reseat_at_previous_visible_line_start (&it
);
20300 it
.current_x
= it
.hpos
= it
.current_y
= it
.vpos
= 0;
20301 if (IT_CHARPOS (it
) != PT
)
20302 move_it_to (&it
, overshoot_expected
? PT
- 1 : PT
,
20303 -1, -1, -1, MOVE_TO_POS
);
20304 pt_x
= it
.current_x
;
20306 if (dir
> 0 || overshoot_expected
)
20308 struct glyph_row
*row
= it
.glyph_row
;
20310 /* When point is at beginning of line, we don't have
20311 information about the glyph there loaded into struct
20312 it. Calling get_next_display_element fixes that. */
20314 get_next_display_element (&it
);
20315 at_eol_p
= ITERATOR_AT_END_OF_LINE_P (&it
);
20316 it
.glyph_row
= NULL
;
20317 PRODUCE_GLYPHS (&it
); /* compute it.pixel_width */
20318 it
.glyph_row
= row
;
20319 /* PRODUCE_GLYPHS advances it.current_x, so we must restore
20320 it, lest it will become out of sync with it's buffer
20322 it
.current_x
= pt_x
;
20325 at_eol_p
= ITERATOR_AT_END_OF_LINE_P (&it
);
20326 pixel_width
= it
.pixel_width
;
20327 if (overshoot_expected
&& at_eol_p
)
20329 else if (pixel_width
<= 0)
20332 /* If there's a display string at point, we are actually at the
20333 glyph to the left of point, so we need to correct the X
20335 if (overshoot_expected
)
20336 pt_x
+= pixel_width
;
20338 /* Compute target X coordinate, either to the left or to the
20339 right of point. On TTY frames, all characters have the same
20340 pixel width of 1, so we can use that. On GUI frames we don't
20341 have an easy way of getting at the pixel width of the
20342 character to the left of point, so we use a different method
20343 of getting to that place. */
20345 target_x
= pt_x
+ pixel_width
;
20347 target_x
= pt_x
- (!FRAME_WINDOW_P (it
.f
)) * pixel_width
;
20349 /* Target X coordinate could be one line above or below the line
20350 of point, in which case we need to adjust the target X
20351 coordinate. Also, if moving to the left, we need to begin at
20352 the left edge of the point's screen line. */
20357 start_display (&it
, w
, pt
);
20358 reseat_at_previous_visible_line_start (&it
);
20359 it
.current_x
= it
.current_y
= it
.hpos
= 0;
20361 move_it_by_lines (&it
, pt_vpos
);
20365 move_it_by_lines (&it
, -1);
20366 target_x
= it
.last_visible_x
- !FRAME_WINDOW_P (it
.f
);
20367 target_is_eol_p
= true;
20373 || (target_x
>= it
.last_visible_x
20374 && it
.line_wrap
!= TRUNCATE
))
20377 move_it_by_lines (&it
, 0);
20378 move_it_by_lines (&it
, 1);
20383 /* Move to the target X coordinate. */
20384 #ifdef HAVE_WINDOW_SYSTEM
20385 /* On GUI frames, as we don't know the X coordinate of the
20386 character to the left of point, moving point to the left
20387 requires walking, one grapheme cluster at a time, until we
20388 find ourself at a place immediately to the left of the
20389 character at point. */
20390 if (FRAME_WINDOW_P (it
.f
) && dir
< 0)
20392 struct text_pos new_pos
= it
.current
.pos
;
20393 enum move_it_result rc
= MOVE_X_REACHED
;
20395 while (it
.current_x
+ it
.pixel_width
<= target_x
20396 && rc
== MOVE_X_REACHED
)
20398 int new_x
= it
.current_x
+ it
.pixel_width
;
20400 new_pos
= it
.current
.pos
;
20401 if (new_x
== it
.current_x
)
20403 rc
= move_it_in_display_line_to (&it
, ZV
, new_x
,
20404 MOVE_TO_POS
| MOVE_TO_X
);
20405 if (ITERATOR_AT_END_OF_LINE_P (&it
) && !target_is_eol_p
)
20408 /* If we ended up on a composed character inside
20409 bidi-reordered text (e.g., Hebrew text with diacritics),
20410 the iterator gives us the buffer position of the last (in
20411 logical order) character of the composed grapheme cluster,
20412 which is not what we want. So we cheat: we compute the
20413 character position of the character that follows (in the
20414 logical order) the one where the above loop stopped. That
20415 character will appear on display to the left of point. */
20417 && it
.bidi_it
.scan_dir
== -1
20418 && new_pos
.charpos
- IT_CHARPOS (it
) > 1)
20420 new_pos
.charpos
= IT_CHARPOS (it
) + 1;
20421 new_pos
.bytepos
= CHAR_TO_BYTE (new_pos
.charpos
);
20423 it
.current
.pos
= new_pos
;
20427 if (it
.current_x
!= target_x
)
20428 move_it_in_display_line_to (&it
, ZV
, target_x
, MOVE_TO_POS
| MOVE_TO_X
);
20430 /* When lines are truncated, the above loop will stop at the
20431 window edge. But we want to get to the end of line, even if
20432 it is beyond the window edge; automatic hscroll will then
20433 scroll the window to show point as appropriate. */
20434 if (target_is_eol_p
&& it
.line_wrap
== TRUNCATE
20435 && get_next_display_element (&it
))
20437 struct text_pos new_pos
= it
.current
.pos
;
20439 while (!ITERATOR_AT_END_OF_LINE_P (&it
))
20441 set_iterator_to_next (&it
, 0);
20442 if (it
.method
== GET_FROM_BUFFER
)
20443 new_pos
= it
.current
.pos
;
20444 if (!get_next_display_element (&it
))
20448 it
.current
.pos
= new_pos
;
20451 /* If we ended up in a display string that covers point, move to
20452 buffer position to the right in the visual order. */
20455 while (IT_CHARPOS (it
) == PT
)
20457 set_iterator_to_next (&it
, 0);
20458 if (!get_next_display_element (&it
))
20463 /* Move point to that position. */
20464 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
20467 return make_number (PT
);
20469 #undef ROW_GLYPH_NEWLINE_P
20473 /***********************************************************************
20475 ***********************************************************************/
20477 /* Redisplay the menu bar in the frame for window W.
20479 The menu bar of X frames that don't have X toolkit support is
20480 displayed in a special window W->frame->menu_bar_window.
20482 The menu bar of terminal frames is treated specially as far as
20483 glyph matrices are concerned. Menu bar lines are not part of
20484 windows, so the update is done directly on the frame matrix rows
20485 for the menu bar. */
20488 display_menu_bar (struct window
*w
)
20490 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
20495 /* Don't do all this for graphical frames. */
20497 if (FRAME_W32_P (f
))
20500 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
20506 if (FRAME_NS_P (f
))
20508 #endif /* HAVE_NS */
20510 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
20511 eassert (!FRAME_WINDOW_P (f
));
20512 init_iterator (&it
, w
, -1, -1, f
->desired_matrix
->rows
, MENU_FACE_ID
);
20513 it
.first_visible_x
= 0;
20514 it
.last_visible_x
= FRAME_TOTAL_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
20515 #elif defined (HAVE_X_WINDOWS) /* X without toolkit. */
20516 if (FRAME_WINDOW_P (f
))
20518 /* Menu bar lines are displayed in the desired matrix of the
20519 dummy window menu_bar_window. */
20520 struct window
*menu_w
;
20521 menu_w
= XWINDOW (f
->menu_bar_window
);
20522 init_iterator (&it
, menu_w
, -1, -1, menu_w
->desired_matrix
->rows
,
20524 it
.first_visible_x
= 0;
20525 it
.last_visible_x
= FRAME_TOTAL_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
20528 #endif /* not USE_X_TOOLKIT and not USE_GTK */
20530 /* This is a TTY frame, i.e. character hpos/vpos are used as
20532 init_iterator (&it
, w
, -1, -1, f
->desired_matrix
->rows
,
20534 it
.first_visible_x
= 0;
20535 it
.last_visible_x
= FRAME_COLS (f
);
20538 /* FIXME: This should be controlled by a user option. See the
20539 comments in redisplay_tool_bar and display_mode_line about
20541 it
.paragraph_embedding
= L2R
;
20543 /* Clear all rows of the menu bar. */
20544 for (i
= 0; i
< FRAME_MENU_BAR_LINES (f
); ++i
)
20546 struct glyph_row
*row
= it
.glyph_row
+ i
;
20547 clear_glyph_row (row
);
20548 row
->enabled_p
= 1;
20549 row
->full_width_p
= 1;
20552 /* Display all items of the menu bar. */
20553 items
= FRAME_MENU_BAR_ITEMS (it
.f
);
20554 for (i
= 0; i
< ASIZE (items
); i
+= 4)
20556 Lisp_Object string
;
20558 /* Stop at nil string. */
20559 string
= AREF (items
, i
+ 1);
20563 /* Remember where item was displayed. */
20564 ASET (items
, i
+ 3, make_number (it
.hpos
));
20566 /* Display the item, pad with one space. */
20567 if (it
.current_x
< it
.last_visible_x
)
20568 display_string (NULL
, string
, Qnil
, 0, 0, &it
,
20569 SCHARS (string
) + 1, 0, 0, -1);
20572 /* Fill out the line with spaces. */
20573 if (it
.current_x
< it
.last_visible_x
)
20574 display_string ("", Qnil
, Qnil
, 0, 0, &it
, -1, 0, 0, -1);
20576 /* Compute the total height of the lines. */
20577 compute_line_metrics (&it
);
20582 /***********************************************************************
20584 ***********************************************************************/
20586 /* Redisplay mode lines in the window tree whose root is WINDOW. If
20587 FORCE is non-zero, redisplay mode lines unconditionally.
20588 Otherwise, redisplay only mode lines that are garbaged. Value is
20589 the number of windows whose mode lines were redisplayed. */
20592 redisplay_mode_lines (Lisp_Object window
, int force
)
20596 while (!NILP (window
))
20598 struct window
*w
= XWINDOW (window
);
20600 if (WINDOWP (w
->contents
))
20601 nwindows
+= redisplay_mode_lines (w
->contents
, force
);
20603 || FRAME_GARBAGED_P (XFRAME (w
->frame
))
20604 || !MATRIX_MODE_LINE_ROW (w
->current_matrix
)->enabled_p
)
20606 struct text_pos lpoint
;
20607 struct buffer
*old
= current_buffer
;
20609 /* Set the window's buffer for the mode line display. */
20610 SET_TEXT_POS (lpoint
, PT
, PT_BYTE
);
20611 set_buffer_internal_1 (XBUFFER (w
->contents
));
20613 /* Point refers normally to the selected window. For any
20614 other window, set up appropriate value. */
20615 if (!EQ (window
, selected_window
))
20617 struct text_pos pt
;
20619 CLIP_TEXT_POS_FROM_MARKER (pt
, w
->pointm
);
20620 TEMP_SET_PT_BOTH (CHARPOS (pt
), BYTEPOS (pt
));
20623 /* Display mode lines. */
20624 clear_glyph_matrix (w
->desired_matrix
);
20625 if (display_mode_lines (w
))
20628 w
->must_be_updated_p
= 1;
20631 /* Restore old settings. */
20632 set_buffer_internal_1 (old
);
20633 TEMP_SET_PT_BOTH (CHARPOS (lpoint
), BYTEPOS (lpoint
));
20643 /* Display the mode and/or header line of window W. Value is the
20644 sum number of mode lines and header lines displayed. */
20647 display_mode_lines (struct window
*w
)
20649 Lisp_Object old_selected_window
= selected_window
;
20650 Lisp_Object old_selected_frame
= selected_frame
;
20651 Lisp_Object new_frame
= w
->frame
;
20652 Lisp_Object old_frame_selected_window
= XFRAME (new_frame
)->selected_window
;
20655 selected_frame
= new_frame
;
20656 /* FIXME: If we were to allow the mode-line's computation changing the buffer
20657 or window's point, then we'd need select_window_1 here as well. */
20658 XSETWINDOW (selected_window
, w
);
20659 XFRAME (new_frame
)->selected_window
= selected_window
;
20661 /* These will be set while the mode line specs are processed. */
20662 line_number_displayed
= 0;
20663 w
->column_number_displayed
= -1;
20665 if (WINDOW_WANTS_MODELINE_P (w
))
20667 struct window
*sel_w
= XWINDOW (old_selected_window
);
20669 /* Select mode line face based on the real selected window. */
20670 display_mode_line (w
, CURRENT_MODE_LINE_FACE_ID_3 (sel_w
, sel_w
, w
),
20671 BVAR (current_buffer
, mode_line_format
));
20675 if (WINDOW_WANTS_HEADER_LINE_P (w
))
20677 display_mode_line (w
, HEADER_LINE_FACE_ID
,
20678 BVAR (current_buffer
, header_line_format
));
20682 XFRAME (new_frame
)->selected_window
= old_frame_selected_window
;
20683 selected_frame
= old_selected_frame
;
20684 selected_window
= old_selected_window
;
20689 /* Display mode or header line of window W. FACE_ID specifies which
20690 line to display; it is either MODE_LINE_FACE_ID or
20691 HEADER_LINE_FACE_ID. FORMAT is the mode/header line format to
20692 display. Value is the pixel height of the mode/header line
20696 display_mode_line (struct window
*w
, enum face_id face_id
, Lisp_Object format
)
20700 ptrdiff_t count
= SPECPDL_INDEX ();
20702 init_iterator (&it
, w
, -1, -1, NULL
, face_id
);
20703 /* Don't extend on a previously drawn mode-line.
20704 This may happen if called from pos_visible_p. */
20705 it
.glyph_row
->enabled_p
= 0;
20706 prepare_desired_row (it
.glyph_row
);
20708 it
.glyph_row
->mode_line_p
= 1;
20710 /* FIXME: This should be controlled by a user option. But
20711 supporting such an option is not trivial, since the mode line is
20712 made up of many separate strings. */
20713 it
.paragraph_embedding
= L2R
;
20715 record_unwind_protect (unwind_format_mode_line
,
20716 format_mode_line_unwind_data (NULL
, NULL
, Qnil
, 0));
20718 mode_line_target
= MODE_LINE_DISPLAY
;
20720 /* Temporarily make frame's keyboard the current kboard so that
20721 kboard-local variables in the mode_line_format will get the right
20723 push_kboard (FRAME_KBOARD (it
.f
));
20724 record_unwind_save_match_data ();
20725 display_mode_element (&it
, 0, 0, 0, format
, Qnil
, 0);
20728 unbind_to (count
, Qnil
);
20730 /* Fill up with spaces. */
20731 display_string (" ", Qnil
, Qnil
, 0, 0, &it
, 10000, -1, -1, 0);
20733 compute_line_metrics (&it
);
20734 it
.glyph_row
->full_width_p
= 1;
20735 it
.glyph_row
->continued_p
= 0;
20736 it
.glyph_row
->truncated_on_left_p
= 0;
20737 it
.glyph_row
->truncated_on_right_p
= 0;
20739 /* Make a 3D mode-line have a shadow at its right end. */
20740 face
= FACE_FROM_ID (it
.f
, face_id
);
20741 extend_face_to_end_of_line (&it
);
20742 if (face
->box
!= FACE_NO_BOX
)
20744 struct glyph
*last
= (it
.glyph_row
->glyphs
[TEXT_AREA
]
20745 + it
.glyph_row
->used
[TEXT_AREA
] - 1);
20746 last
->right_box_line_p
= 1;
20749 return it
.glyph_row
->height
;
20752 /* Move element ELT in LIST to the front of LIST.
20753 Return the updated list. */
20756 move_elt_to_front (Lisp_Object elt
, Lisp_Object list
)
20758 register Lisp_Object tail
, prev
;
20759 register Lisp_Object tem
;
20763 while (CONSP (tail
))
20769 /* Splice out the link TAIL. */
20771 list
= XCDR (tail
);
20773 Fsetcdr (prev
, XCDR (tail
));
20775 /* Now make it the first. */
20776 Fsetcdr (tail
, list
);
20781 tail
= XCDR (tail
);
20785 /* Not found--return unchanged LIST. */
20789 /* Contribute ELT to the mode line for window IT->w. How it
20790 translates into text depends on its data type.
20792 IT describes the display environment in which we display, as usual.
20794 DEPTH is the depth in recursion. It is used to prevent
20795 infinite recursion here.
20797 FIELD_WIDTH is the number of characters the display of ELT should
20798 occupy in the mode line, and PRECISION is the maximum number of
20799 characters to display from ELT's representation. See
20800 display_string for details.
20802 Returns the hpos of the end of the text generated by ELT.
20804 PROPS is a property list to add to any string we encounter.
20806 If RISKY is nonzero, remove (disregard) any properties in any string
20807 we encounter, and ignore :eval and :propertize.
20809 The global variable `mode_line_target' determines whether the
20810 output is passed to `store_mode_line_noprop',
20811 `store_mode_line_string', or `display_string'. */
20814 display_mode_element (struct it
*it
, int depth
, int field_width
, int precision
,
20815 Lisp_Object elt
, Lisp_Object props
, int risky
)
20817 int n
= 0, field
, prec
;
20822 elt
= build_string ("*too-deep*");
20826 switch (XTYPE (elt
))
20830 /* A string: output it and check for %-constructs within it. */
20832 ptrdiff_t offset
= 0;
20834 if (SCHARS (elt
) > 0
20835 && (!NILP (props
) || risky
))
20837 Lisp_Object oprops
, aelt
;
20838 oprops
= Ftext_properties_at (make_number (0), elt
);
20840 /* If the starting string's properties are not what
20841 we want, translate the string. Also, if the string
20842 is risky, do that anyway. */
20844 if (NILP (Fequal (props
, oprops
)) || risky
)
20846 /* If the starting string has properties,
20847 merge the specified ones onto the existing ones. */
20848 if (! NILP (oprops
) && !risky
)
20852 oprops
= Fcopy_sequence (oprops
);
20854 while (CONSP (tem
))
20856 oprops
= Fplist_put (oprops
, XCAR (tem
),
20857 XCAR (XCDR (tem
)));
20858 tem
= XCDR (XCDR (tem
));
20863 aelt
= Fassoc (elt
, mode_line_proptrans_alist
);
20864 if (! NILP (aelt
) && !NILP (Fequal (props
, XCDR (aelt
))))
20866 /* AELT is what we want. Move it to the front
20867 without consing. */
20869 mode_line_proptrans_alist
20870 = move_elt_to_front (aelt
, mode_line_proptrans_alist
);
20876 /* If AELT has the wrong props, it is useless.
20877 so get rid of it. */
20879 mode_line_proptrans_alist
20880 = Fdelq (aelt
, mode_line_proptrans_alist
);
20882 elt
= Fcopy_sequence (elt
);
20883 Fset_text_properties (make_number (0), Flength (elt
),
20885 /* Add this item to mode_line_proptrans_alist. */
20886 mode_line_proptrans_alist
20887 = Fcons (Fcons (elt
, props
),
20888 mode_line_proptrans_alist
);
20889 /* Truncate mode_line_proptrans_alist
20890 to at most 50 elements. */
20891 tem
= Fnthcdr (make_number (50),
20892 mode_line_proptrans_alist
);
20894 XSETCDR (tem
, Qnil
);
20903 prec
= precision
- n
;
20904 switch (mode_line_target
)
20906 case MODE_LINE_NOPROP
:
20907 case MODE_LINE_TITLE
:
20908 n
+= store_mode_line_noprop (SSDATA (elt
), -1, prec
);
20910 case MODE_LINE_STRING
:
20911 n
+= store_mode_line_string (NULL
, elt
, 1, 0, prec
, Qnil
);
20913 case MODE_LINE_DISPLAY
:
20914 n
+= display_string (NULL
, elt
, Qnil
, 0, 0, it
,
20915 0, prec
, 0, STRING_MULTIBYTE (elt
));
20922 /* Handle the non-literal case. */
20924 while ((precision
<= 0 || n
< precision
)
20925 && SREF (elt
, offset
) != 0
20926 && (mode_line_target
!= MODE_LINE_DISPLAY
20927 || it
->current_x
< it
->last_visible_x
))
20929 ptrdiff_t last_offset
= offset
;
20931 /* Advance to end of string or next format specifier. */
20932 while ((c
= SREF (elt
, offset
++)) != '\0' && c
!= '%')
20935 if (offset
- 1 != last_offset
)
20937 ptrdiff_t nchars
, nbytes
;
20939 /* Output to end of string or up to '%'. Field width
20940 is length of string. Don't output more than
20941 PRECISION allows us. */
20944 prec
= c_string_width (SDATA (elt
) + last_offset
,
20945 offset
- last_offset
, precision
- n
,
20948 switch (mode_line_target
)
20950 case MODE_LINE_NOPROP
:
20951 case MODE_LINE_TITLE
:
20952 n
+= store_mode_line_noprop (SSDATA (elt
) + last_offset
, 0, prec
);
20954 case MODE_LINE_STRING
:
20956 ptrdiff_t bytepos
= last_offset
;
20957 ptrdiff_t charpos
= string_byte_to_char (elt
, bytepos
);
20958 ptrdiff_t endpos
= (precision
<= 0
20959 ? string_byte_to_char (elt
, offset
)
20960 : charpos
+ nchars
);
20962 n
+= store_mode_line_string (NULL
,
20963 Fsubstring (elt
, make_number (charpos
),
20964 make_number (endpos
)),
20968 case MODE_LINE_DISPLAY
:
20970 ptrdiff_t bytepos
= last_offset
;
20971 ptrdiff_t charpos
= string_byte_to_char (elt
, bytepos
);
20973 if (precision
<= 0)
20974 nchars
= string_byte_to_char (elt
, offset
) - charpos
;
20975 n
+= display_string (NULL
, elt
, Qnil
, 0, charpos
,
20977 STRING_MULTIBYTE (elt
));
20982 else /* c == '%' */
20984 ptrdiff_t percent_position
= offset
;
20986 /* Get the specified minimum width. Zero means
20989 while ((c
= SREF (elt
, offset
++)) >= '0' && c
<= '9')
20990 field
= field
* 10 + c
- '0';
20992 /* Don't pad beyond the total padding allowed. */
20993 if (field_width
- n
> 0 && field
> field_width
- n
)
20994 field
= field_width
- n
;
20996 /* Note that either PRECISION <= 0 or N < PRECISION. */
20997 prec
= precision
- n
;
21000 n
+= display_mode_element (it
, depth
, field
, prec
,
21001 Vglobal_mode_string
, props
,
21006 ptrdiff_t bytepos
, charpos
;
21008 Lisp_Object string
;
21010 bytepos
= percent_position
;
21011 charpos
= (STRING_MULTIBYTE (elt
)
21012 ? string_byte_to_char (elt
, bytepos
)
21014 spec
= decode_mode_spec (it
->w
, c
, field
, &string
);
21015 multibyte
= STRINGP (string
) && STRING_MULTIBYTE (string
);
21017 switch (mode_line_target
)
21019 case MODE_LINE_NOPROP
:
21020 case MODE_LINE_TITLE
:
21021 n
+= store_mode_line_noprop (spec
, field
, prec
);
21023 case MODE_LINE_STRING
:
21025 Lisp_Object tem
= build_string (spec
);
21026 props
= Ftext_properties_at (make_number (charpos
), elt
);
21027 /* Should only keep face property in props */
21028 n
+= store_mode_line_string (NULL
, tem
, 0, field
, prec
, props
);
21031 case MODE_LINE_DISPLAY
:
21033 int nglyphs_before
, nwritten
;
21035 nglyphs_before
= it
->glyph_row
->used
[TEXT_AREA
];
21036 nwritten
= display_string (spec
, string
, elt
,
21041 /* Assign to the glyphs written above the
21042 string where the `%x' came from, position
21046 struct glyph
*glyph
21047 = (it
->glyph_row
->glyphs
[TEXT_AREA
]
21051 for (i
= 0; i
< nwritten
; ++i
)
21053 glyph
[i
].object
= elt
;
21054 glyph
[i
].charpos
= charpos
;
21071 /* A symbol: process the value of the symbol recursively
21072 as if it appeared here directly. Avoid error if symbol void.
21073 Special case: if value of symbol is a string, output the string
21076 register Lisp_Object tem
;
21078 /* If the variable is not marked as risky to set
21079 then its contents are risky to use. */
21080 if (NILP (Fget (elt
, Qrisky_local_variable
)))
21083 tem
= Fboundp (elt
);
21086 tem
= Fsymbol_value (elt
);
21087 /* If value is a string, output that string literally:
21088 don't check for % within it. */
21092 if (!EQ (tem
, elt
))
21094 /* Give up right away for nil or t. */
21104 register Lisp_Object car
, tem
;
21106 /* A cons cell: five distinct cases.
21107 If first element is :eval or :propertize, do something special.
21108 If first element is a string or a cons, process all the elements
21109 and effectively concatenate them.
21110 If first element is a negative number, truncate displaying cdr to
21111 at most that many characters. If positive, pad (with spaces)
21112 to at least that many characters.
21113 If first element is a symbol, process the cadr or caddr recursively
21114 according to whether the symbol's value is non-nil or nil. */
21116 if (EQ (car
, QCeval
))
21118 /* An element of the form (:eval FORM) means evaluate FORM
21119 and use the result as mode line elements. */
21124 if (CONSP (XCDR (elt
)))
21127 spec
= safe_eval (XCAR (XCDR (elt
)));
21128 n
+= display_mode_element (it
, depth
, field_width
- n
,
21129 precision
- n
, spec
, props
,
21133 else if (EQ (car
, QCpropertize
))
21135 /* An element of the form (:propertize ELT PROPS...)
21136 means display ELT but applying properties PROPS. */
21141 if (CONSP (XCDR (elt
)))
21142 n
+= display_mode_element (it
, depth
, field_width
- n
,
21143 precision
- n
, XCAR (XCDR (elt
)),
21144 XCDR (XCDR (elt
)), risky
);
21146 else if (SYMBOLP (car
))
21148 tem
= Fboundp (car
);
21152 /* elt is now the cdr, and we know it is a cons cell.
21153 Use its car if CAR has a non-nil value. */
21156 tem
= Fsymbol_value (car
);
21163 /* Symbol's value is nil (or symbol is unbound)
21164 Get the cddr of the original list
21165 and if possible find the caddr and use that. */
21169 else if (!CONSP (elt
))
21174 else if (INTEGERP (car
))
21176 register int lim
= XINT (car
);
21180 /* Negative int means reduce maximum width. */
21181 if (precision
<= 0)
21184 precision
= min (precision
, -lim
);
21188 /* Padding specified. Don't let it be more than
21189 current maximum. */
21191 lim
= min (precision
, lim
);
21193 /* If that's more padding than already wanted, queue it.
21194 But don't reduce padding already specified even if
21195 that is beyond the current truncation point. */
21196 field_width
= max (lim
, field_width
);
21200 else if (STRINGP (car
) || CONSP (car
))
21202 Lisp_Object halftail
= elt
;
21206 && (precision
<= 0 || n
< precision
))
21208 n
+= display_mode_element (it
, depth
,
21209 /* Do padding only after the last
21210 element in the list. */
21211 (! CONSP (XCDR (elt
))
21214 precision
- n
, XCAR (elt
),
21218 if ((len
& 1) == 0)
21219 halftail
= XCDR (halftail
);
21220 /* Check for cycle. */
21221 if (EQ (halftail
, elt
))
21230 elt
= build_string ("*invalid*");
21234 /* Pad to FIELD_WIDTH. */
21235 if (field_width
> 0 && n
< field_width
)
21237 switch (mode_line_target
)
21239 case MODE_LINE_NOPROP
:
21240 case MODE_LINE_TITLE
:
21241 n
+= store_mode_line_noprop ("", field_width
- n
, 0);
21243 case MODE_LINE_STRING
:
21244 n
+= store_mode_line_string ("", Qnil
, 0, field_width
- n
, 0, Qnil
);
21246 case MODE_LINE_DISPLAY
:
21247 n
+= display_string ("", Qnil
, Qnil
, 0, 0, it
, field_width
- n
,
21256 /* Store a mode-line string element in mode_line_string_list.
21258 If STRING is non-null, display that C string. Otherwise, the Lisp
21259 string LISP_STRING is displayed.
21261 FIELD_WIDTH is the minimum number of output glyphs to produce.
21262 If STRING has fewer characters than FIELD_WIDTH, pad to the right
21263 with spaces. FIELD_WIDTH <= 0 means don't pad.
21265 PRECISION is the maximum number of characters to output from
21266 STRING. PRECISION <= 0 means don't truncate the string.
21268 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
21269 properties to the string.
21271 PROPS are the properties to add to the string.
21272 The mode_line_string_face face property is always added to the string.
21276 store_mode_line_string (const char *string
, Lisp_Object lisp_string
, int copy_string
,
21277 int field_width
, int precision
, Lisp_Object props
)
21282 if (string
!= NULL
)
21284 len
= strlen (string
);
21285 if (precision
> 0 && len
> precision
)
21287 lisp_string
= make_string (string
, len
);
21289 props
= mode_line_string_face_prop
;
21290 else if (!NILP (mode_line_string_face
))
21292 Lisp_Object face
= Fplist_get (props
, Qface
);
21293 props
= Fcopy_sequence (props
);
21295 face
= mode_line_string_face
;
21297 face
= list2 (face
, mode_line_string_face
);
21298 props
= Fplist_put (props
, Qface
, face
);
21300 Fadd_text_properties (make_number (0), make_number (len
),
21301 props
, lisp_string
);
21305 len
= XFASTINT (Flength (lisp_string
));
21306 if (precision
> 0 && len
> precision
)
21309 lisp_string
= Fsubstring (lisp_string
, make_number (0), make_number (len
));
21312 if (!NILP (mode_line_string_face
))
21316 props
= Ftext_properties_at (make_number (0), lisp_string
);
21317 face
= Fplist_get (props
, Qface
);
21319 face
= mode_line_string_face
;
21321 face
= list2 (face
, mode_line_string_face
);
21322 props
= list2 (Qface
, face
);
21324 lisp_string
= Fcopy_sequence (lisp_string
);
21327 Fadd_text_properties (make_number (0), make_number (len
),
21328 props
, lisp_string
);
21333 mode_line_string_list
= Fcons (lisp_string
, mode_line_string_list
);
21337 if (field_width
> len
)
21339 field_width
-= len
;
21340 lisp_string
= Fmake_string (make_number (field_width
), make_number (' '));
21342 Fadd_text_properties (make_number (0), make_number (field_width
),
21343 props
, lisp_string
);
21344 mode_line_string_list
= Fcons (lisp_string
, mode_line_string_list
);
21352 DEFUN ("format-mode-line", Fformat_mode_line
, Sformat_mode_line
,
21354 doc
: /* Format a string out of a mode line format specification.
21355 First arg FORMAT specifies the mode line format (see `mode-line-format'
21356 for details) to use.
21358 By default, the format is evaluated for the currently selected window.
21360 Optional second arg FACE specifies the face property to put on all
21361 characters for which no face is specified. The value nil means the
21362 default face. The value t means whatever face the window's mode line
21363 currently uses (either `mode-line' or `mode-line-inactive',
21364 depending on whether the window is the selected window or not).
21365 An integer value means the value string has no text
21368 Optional third and fourth args WINDOW and BUFFER specify the window
21369 and buffer to use as the context for the formatting (defaults
21370 are the selected window and the WINDOW's buffer). */)
21371 (Lisp_Object format
, Lisp_Object face
,
21372 Lisp_Object window
, Lisp_Object buffer
)
21377 struct buffer
*old_buffer
= NULL
;
21379 int no_props
= INTEGERP (face
);
21380 ptrdiff_t count
= SPECPDL_INDEX ();
21382 int string_start
= 0;
21384 w
= decode_any_window (window
);
21385 XSETWINDOW (window
, w
);
21388 buffer
= w
->contents
;
21389 CHECK_BUFFER (buffer
);
21391 /* Make formatting the modeline a non-op when noninteractive, otherwise
21392 there will be problems later caused by a partially initialized frame. */
21393 if (NILP (format
) || noninteractive
)
21394 return empty_unibyte_string
;
21399 face_id
= (NILP (face
) || EQ (face
, Qdefault
)) ? DEFAULT_FACE_ID
21400 : EQ (face
, Qt
) ? (EQ (window
, selected_window
)
21401 ? MODE_LINE_FACE_ID
: MODE_LINE_INACTIVE_FACE_ID
)
21402 : EQ (face
, Qmode_line
) ? MODE_LINE_FACE_ID
21403 : EQ (face
, Qmode_line_inactive
) ? MODE_LINE_INACTIVE_FACE_ID
21404 : EQ (face
, Qheader_line
) ? HEADER_LINE_FACE_ID
21405 : EQ (face
, Qtool_bar
) ? TOOL_BAR_FACE_ID
21408 old_buffer
= current_buffer
;
21410 /* Save things including mode_line_proptrans_alist,
21411 and set that to nil so that we don't alter the outer value. */
21412 record_unwind_protect (unwind_format_mode_line
,
21413 format_mode_line_unwind_data
21414 (XFRAME (WINDOW_FRAME (w
)),
21415 old_buffer
, selected_window
, 1));
21416 mode_line_proptrans_alist
= Qnil
;
21418 Fselect_window (window
, Qt
);
21419 set_buffer_internal_1 (XBUFFER (buffer
));
21421 init_iterator (&it
, w
, -1, -1, NULL
, face_id
);
21425 mode_line_target
= MODE_LINE_NOPROP
;
21426 mode_line_string_face_prop
= Qnil
;
21427 mode_line_string_list
= Qnil
;
21428 string_start
= MODE_LINE_NOPROP_LEN (0);
21432 mode_line_target
= MODE_LINE_STRING
;
21433 mode_line_string_list
= Qnil
;
21434 mode_line_string_face
= face
;
21435 mode_line_string_face_prop
21436 = NILP (face
) ? Qnil
: list2 (Qface
, face
);
21439 push_kboard (FRAME_KBOARD (it
.f
));
21440 display_mode_element (&it
, 0, 0, 0, format
, Qnil
, 0);
21445 len
= MODE_LINE_NOPROP_LEN (string_start
);
21446 str
= make_string (mode_line_noprop_buf
+ string_start
, len
);
21450 mode_line_string_list
= Fnreverse (mode_line_string_list
);
21451 str
= Fmapconcat (intern ("identity"), mode_line_string_list
,
21452 empty_unibyte_string
);
21455 unbind_to (count
, Qnil
);
21459 /* Write a null-terminated, right justified decimal representation of
21460 the positive integer D to BUF using a minimal field width WIDTH. */
21463 pint2str (register char *buf
, register int width
, register ptrdiff_t d
)
21465 register char *p
= buf
;
21473 *p
++ = d
% 10 + '0';
21478 for (width
-= (int) (p
- buf
); width
> 0; --width
)
21489 /* Write a null-terminated, right justified decimal and "human
21490 readable" representation of the nonnegative integer D to BUF using
21491 a minimal field width WIDTH. D should be smaller than 999.5e24. */
21493 static const char power_letter
[] =
21507 pint2hrstr (char *buf
, int width
, ptrdiff_t d
)
21509 /* We aim to represent the nonnegative integer D as
21510 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
21511 ptrdiff_t quotient
= d
;
21513 /* -1 means: do not use TENTHS. */
21517 /* Length of QUOTIENT.TENTHS as a string. */
21523 if (quotient
>= 1000)
21525 /* Scale to the appropriate EXPONENT. */
21528 remainder
= quotient
% 1000;
21532 while (quotient
>= 1000);
21534 /* Round to nearest and decide whether to use TENTHS or not. */
21537 tenths
= remainder
/ 100;
21538 if (remainder
% 100 >= 50)
21545 if (quotient
== 10)
21553 if (remainder
>= 500)
21555 if (quotient
< 999)
21566 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
21567 if (tenths
== -1 && quotient
<= 99)
21574 p
= psuffix
= buf
+ max (width
, length
);
21576 /* Print EXPONENT. */
21577 *psuffix
++ = power_letter
[exponent
];
21580 /* Print TENTHS. */
21583 *--p
= '0' + tenths
;
21587 /* Print QUOTIENT. */
21590 int digit
= quotient
% 10;
21591 *--p
= '0' + digit
;
21593 while ((quotient
/= 10) != 0);
21595 /* Print leading spaces. */
21600 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
21601 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
21602 type of CODING_SYSTEM. Return updated pointer into BUF. */
21604 static unsigned char invalid_eol_type
[] = "(*invalid*)";
21607 decode_mode_spec_coding (Lisp_Object coding_system
, register char *buf
, int eol_flag
)
21610 bool multibyte
= !NILP (BVAR (current_buffer
, enable_multibyte_characters
));
21611 const unsigned char *eol_str
;
21613 /* The EOL conversion we are using. */
21614 Lisp_Object eoltype
;
21616 val
= CODING_SYSTEM_SPEC (coding_system
);
21619 if (!VECTORP (val
)) /* Not yet decided. */
21621 *buf
++ = multibyte
? '-' : ' ';
21623 eoltype
= eol_mnemonic_undecided
;
21624 /* Don't mention EOL conversion if it isn't decided. */
21629 Lisp_Object eolvalue
;
21631 attrs
= AREF (val
, 0);
21632 eolvalue
= AREF (val
, 2);
21635 ? XFASTINT (CODING_ATTR_MNEMONIC (attrs
))
21640 /* The EOL conversion that is normal on this system. */
21642 if (NILP (eolvalue
)) /* Not yet decided. */
21643 eoltype
= eol_mnemonic_undecided
;
21644 else if (VECTORP (eolvalue
)) /* Not yet decided. */
21645 eoltype
= eol_mnemonic_undecided
;
21646 else /* eolvalue is Qunix, Qdos, or Qmac. */
21647 eoltype
= (EQ (eolvalue
, Qunix
)
21648 ? eol_mnemonic_unix
21649 : (EQ (eolvalue
, Qdos
) == 1
21650 ? eol_mnemonic_dos
: eol_mnemonic_mac
));
21656 /* Mention the EOL conversion if it is not the usual one. */
21657 if (STRINGP (eoltype
))
21659 eol_str
= SDATA (eoltype
);
21660 eol_str_len
= SBYTES (eoltype
);
21662 else if (CHARACTERP (eoltype
))
21664 unsigned char *tmp
= alloca (MAX_MULTIBYTE_LENGTH
);
21665 int c
= XFASTINT (eoltype
);
21666 eol_str_len
= CHAR_STRING (c
, tmp
);
21671 eol_str
= invalid_eol_type
;
21672 eol_str_len
= sizeof (invalid_eol_type
) - 1;
21674 memcpy (buf
, eol_str
, eol_str_len
);
21675 buf
+= eol_str_len
;
21681 /* Return a string for the output of a mode line %-spec for window W,
21682 generated by character C. FIELD_WIDTH > 0 means pad the string
21683 returned with spaces to that value. Return a Lisp string in
21684 *STRING if the resulting string is taken from that Lisp string.
21686 Note we operate on the current buffer for most purposes. */
21688 static char lots_of_dashes
[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
21690 static const char *
21691 decode_mode_spec (struct window
*w
, register int c
, int field_width
,
21692 Lisp_Object
*string
)
21695 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
21696 char *decode_mode_spec_buf
= f
->decode_mode_spec_buffer
;
21697 /* We are going to use f->decode_mode_spec_buffer as the buffer to
21698 produce strings from numerical values, so limit preposterously
21699 large values of FIELD_WIDTH to avoid overrunning the buffer's
21700 end. The size of the buffer is enough for FRAME_MESSAGE_BUF_SIZE
21701 bytes plus the terminating null. */
21702 int width
= min (field_width
, FRAME_MESSAGE_BUF_SIZE (f
));
21703 struct buffer
*b
= current_buffer
;
21711 if (!NILP (BVAR (b
, read_only
)))
21713 if (BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
))
21718 /* This differs from %* only for a modified read-only buffer. */
21719 if (BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
))
21721 if (!NILP (BVAR (b
, read_only
)))
21726 /* This differs from %* in ignoring read-only-ness. */
21727 if (BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
))
21739 if (command_loop_level
> 5)
21741 p
= decode_mode_spec_buf
;
21742 for (i
= 0; i
< command_loop_level
; i
++)
21745 return decode_mode_spec_buf
;
21753 if (command_loop_level
> 5)
21755 p
= decode_mode_spec_buf
;
21756 for (i
= 0; i
< command_loop_level
; i
++)
21759 return decode_mode_spec_buf
;
21766 /* Let lots_of_dashes be a string of infinite length. */
21767 if (mode_line_target
== MODE_LINE_NOPROP
21768 || mode_line_target
== MODE_LINE_STRING
)
21770 if (field_width
<= 0
21771 || field_width
> sizeof (lots_of_dashes
))
21773 for (i
= 0; i
< FRAME_MESSAGE_BUF_SIZE (f
) - 1; ++i
)
21774 decode_mode_spec_buf
[i
] = '-';
21775 decode_mode_spec_buf
[i
] = '\0';
21776 return decode_mode_spec_buf
;
21779 return lots_of_dashes
;
21783 obj
= BVAR (b
, name
);
21787 /* %c and %l are ignored in `frame-title-format'.
21788 (In redisplay_internal, the frame title is drawn _before_ the
21789 windows are updated, so the stuff which depends on actual
21790 window contents (such as %l) may fail to render properly, or
21791 even crash emacs.) */
21792 if (mode_line_target
== MODE_LINE_TITLE
)
21796 ptrdiff_t col
= current_column ();
21797 w
->column_number_displayed
= col
;
21798 pint2str (decode_mode_spec_buf
, width
, col
);
21799 return decode_mode_spec_buf
;
21803 #ifndef SYSTEM_MALLOC
21805 if (NILP (Vmemory_full
))
21808 return "!MEM FULL! ";
21815 /* %F displays the frame name. */
21816 if (!NILP (f
->title
))
21817 return SSDATA (f
->title
);
21818 if (f
->explicit_name
|| ! FRAME_WINDOW_P (f
))
21819 return SSDATA (f
->name
);
21823 obj
= BVAR (b
, filename
);
21828 ptrdiff_t size
= ZV
- BEGV
;
21829 pint2str (decode_mode_spec_buf
, width
, size
);
21830 return decode_mode_spec_buf
;
21835 ptrdiff_t size
= ZV
- BEGV
;
21836 pint2hrstr (decode_mode_spec_buf
, width
, size
);
21837 return decode_mode_spec_buf
;
21842 ptrdiff_t startpos
, startpos_byte
, line
, linepos
, linepos_byte
;
21843 ptrdiff_t topline
, nlines
, height
;
21846 /* %c and %l are ignored in `frame-title-format'. */
21847 if (mode_line_target
== MODE_LINE_TITLE
)
21850 startpos
= marker_position (w
->start
);
21851 startpos_byte
= marker_byte_position (w
->start
);
21852 height
= WINDOW_TOTAL_LINES (w
);
21854 /* If we decided that this buffer isn't suitable for line numbers,
21855 don't forget that too fast. */
21856 if (w
->base_line_pos
== -1)
21859 /* If the buffer is very big, don't waste time. */
21860 if (INTEGERP (Vline_number_display_limit
)
21861 && BUF_ZV (b
) - BUF_BEGV (b
) > XINT (Vline_number_display_limit
))
21863 w
->base_line_pos
= 0;
21864 w
->base_line_number
= 0;
21868 if (w
->base_line_number
> 0
21869 && w
->base_line_pos
> 0
21870 && w
->base_line_pos
<= startpos
)
21872 line
= w
->base_line_number
;
21873 linepos
= w
->base_line_pos
;
21874 linepos_byte
= buf_charpos_to_bytepos (b
, linepos
);
21879 linepos
= BUF_BEGV (b
);
21880 linepos_byte
= BUF_BEGV_BYTE (b
);
21883 /* Count lines from base line to window start position. */
21884 nlines
= display_count_lines (linepos_byte
,
21888 topline
= nlines
+ line
;
21890 /* Determine a new base line, if the old one is too close
21891 or too far away, or if we did not have one.
21892 "Too close" means it's plausible a scroll-down would
21893 go back past it. */
21894 if (startpos
== BUF_BEGV (b
))
21896 w
->base_line_number
= topline
;
21897 w
->base_line_pos
= BUF_BEGV (b
);
21899 else if (nlines
< height
+ 25 || nlines
> height
* 3 + 50
21900 || linepos
== BUF_BEGV (b
))
21902 ptrdiff_t limit
= BUF_BEGV (b
);
21903 ptrdiff_t limit_byte
= BUF_BEGV_BYTE (b
);
21904 ptrdiff_t position
;
21905 ptrdiff_t distance
=
21906 (height
* 2 + 30) * line_number_display_limit_width
;
21908 if (startpos
- distance
> limit
)
21910 limit
= startpos
- distance
;
21911 limit_byte
= CHAR_TO_BYTE (limit
);
21914 nlines
= display_count_lines (startpos_byte
,
21916 - (height
* 2 + 30),
21918 /* If we couldn't find the lines we wanted within
21919 line_number_display_limit_width chars per line,
21920 give up on line numbers for this window. */
21921 if (position
== limit_byte
&& limit
== startpos
- distance
)
21923 w
->base_line_pos
= -1;
21924 w
->base_line_number
= 0;
21928 w
->base_line_number
= topline
- nlines
;
21929 w
->base_line_pos
= BYTE_TO_CHAR (position
);
21932 /* Now count lines from the start pos to point. */
21933 nlines
= display_count_lines (startpos_byte
,
21934 PT_BYTE
, PT
, &junk
);
21936 /* Record that we did display the line number. */
21937 line_number_displayed
= 1;
21939 /* Make the string to show. */
21940 pint2str (decode_mode_spec_buf
, width
, topline
+ nlines
);
21941 return decode_mode_spec_buf
;
21944 char* p
= decode_mode_spec_buf
;
21945 int pad
= width
- 2;
21951 return decode_mode_spec_buf
;
21957 obj
= BVAR (b
, mode_name
);
21961 if (BUF_BEGV (b
) > BUF_BEG (b
) || BUF_ZV (b
) < BUF_Z (b
))
21967 ptrdiff_t pos
= marker_position (w
->start
);
21968 ptrdiff_t total
= BUF_ZV (b
) - BUF_BEGV (b
);
21970 if (w
->window_end_pos
<= BUF_Z (b
) - BUF_ZV (b
))
21972 if (pos
<= BUF_BEGV (b
))
21977 else if (pos
<= BUF_BEGV (b
))
21981 if (total
> 1000000)
21982 /* Do it differently for a large value, to avoid overflow. */
21983 total
= ((pos
- BUF_BEGV (b
)) + (total
/ 100) - 1) / (total
/ 100);
21985 total
= ((pos
- BUF_BEGV (b
)) * 100 + total
- 1) / total
;
21986 /* We can't normally display a 3-digit number,
21987 so get us a 2-digit number that is close. */
21990 sprintf (decode_mode_spec_buf
, "%2"pD
"d%%", total
);
21991 return decode_mode_spec_buf
;
21995 /* Display percentage of size above the bottom of the screen. */
21998 ptrdiff_t toppos
= marker_position (w
->start
);
21999 ptrdiff_t botpos
= BUF_Z (b
) - w
->window_end_pos
;
22000 ptrdiff_t total
= BUF_ZV (b
) - BUF_BEGV (b
);
22002 if (botpos
>= BUF_ZV (b
))
22004 if (toppos
<= BUF_BEGV (b
))
22011 if (total
> 1000000)
22012 /* Do it differently for a large value, to avoid overflow. */
22013 total
= ((botpos
- BUF_BEGV (b
)) + (total
/ 100) - 1) / (total
/ 100);
22015 total
= ((botpos
- BUF_BEGV (b
)) * 100 + total
- 1) / total
;
22016 /* We can't normally display a 3-digit number,
22017 so get us a 2-digit number that is close. */
22020 if (toppos
<= BUF_BEGV (b
))
22021 sprintf (decode_mode_spec_buf
, "Top%2"pD
"d%%", total
);
22023 sprintf (decode_mode_spec_buf
, "%2"pD
"d%%", total
);
22024 return decode_mode_spec_buf
;
22029 /* status of process */
22030 obj
= Fget_buffer_process (Fcurrent_buffer ());
22032 return "no process";
22034 obj
= Fsymbol_name (Fprocess_status (obj
));
22040 ptrdiff_t count
= inhibit_garbage_collection ();
22041 Lisp_Object val
= call1 (intern ("file-remote-p"),
22042 BVAR (current_buffer
, directory
));
22043 unbind_to (count
, Qnil
);
22052 /* coding-system (not including end-of-line format) */
22054 /* coding-system (including end-of-line type) */
22056 int eol_flag
= (c
== 'Z');
22057 char *p
= decode_mode_spec_buf
;
22059 if (! FRAME_WINDOW_P (f
))
22061 /* No need to mention EOL here--the terminal never needs
22062 to do EOL conversion. */
22063 p
= decode_mode_spec_coding (CODING_ID_NAME
22064 (FRAME_KEYBOARD_CODING (f
)->id
),
22066 p
= decode_mode_spec_coding (CODING_ID_NAME
22067 (FRAME_TERMINAL_CODING (f
)->id
),
22070 p
= decode_mode_spec_coding (BVAR (b
, buffer_file_coding_system
),
22073 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
22074 #ifdef subprocesses
22075 obj
= Fget_buffer_process (Fcurrent_buffer ());
22076 if (PROCESSP (obj
))
22078 p
= decode_mode_spec_coding
22079 (XPROCESS (obj
)->decode_coding_system
, p
, eol_flag
);
22080 p
= decode_mode_spec_coding
22081 (XPROCESS (obj
)->encode_coding_system
, p
, eol_flag
);
22083 #endif /* subprocesses */
22086 return decode_mode_spec_buf
;
22093 return SSDATA (obj
);
22100 /* Count up to COUNT lines starting from START_BYTE. COUNT negative
22101 means count lines back from START_BYTE. But don't go beyond
22102 LIMIT_BYTE. Return the number of lines thus found (always
22105 Set *BYTE_POS_PTR to the byte position where we stopped. This is
22106 either the position COUNT lines after/before START_BYTE, if we
22107 found COUNT lines, or LIMIT_BYTE if we hit the limit before finding
22111 display_count_lines (ptrdiff_t start_byte
,
22112 ptrdiff_t limit_byte
, ptrdiff_t count
,
22113 ptrdiff_t *byte_pos_ptr
)
22115 register unsigned char *cursor
;
22116 unsigned char *base
;
22118 register ptrdiff_t ceiling
;
22119 register unsigned char *ceiling_addr
;
22120 ptrdiff_t orig_count
= count
;
22122 /* If we are not in selective display mode,
22123 check only for newlines. */
22124 int selective_display
= (!NILP (BVAR (current_buffer
, selective_display
))
22125 && !INTEGERP (BVAR (current_buffer
, selective_display
)));
22129 while (start_byte
< limit_byte
)
22131 ceiling
= BUFFER_CEILING_OF (start_byte
);
22132 ceiling
= min (limit_byte
- 1, ceiling
);
22133 ceiling_addr
= BYTE_POS_ADDR (ceiling
) + 1;
22134 base
= (cursor
= BYTE_POS_ADDR (start_byte
));
22138 if (selective_display
)
22140 while (*cursor
!= '\n' && *cursor
!= 015
22141 && ++cursor
!= ceiling_addr
)
22143 if (cursor
== ceiling_addr
)
22148 cursor
= memchr (cursor
, '\n', ceiling_addr
- cursor
);
22157 start_byte
+= cursor
- base
;
22158 *byte_pos_ptr
= start_byte
;
22162 while (cursor
< ceiling_addr
);
22164 start_byte
+= ceiling_addr
- base
;
22169 while (start_byte
> limit_byte
)
22171 ceiling
= BUFFER_FLOOR_OF (start_byte
- 1);
22172 ceiling
= max (limit_byte
, ceiling
);
22173 ceiling_addr
= BYTE_POS_ADDR (ceiling
);
22174 base
= (cursor
= BYTE_POS_ADDR (start_byte
- 1) + 1);
22177 if (selective_display
)
22179 while (--cursor
>= ceiling_addr
22180 && *cursor
!= '\n' && *cursor
!= 015)
22182 if (cursor
< ceiling_addr
)
22187 cursor
= memrchr (ceiling_addr
, '\n', cursor
- ceiling_addr
);
22194 start_byte
+= cursor
- base
+ 1;
22195 *byte_pos_ptr
= start_byte
;
22196 /* When scanning backwards, we should
22197 not count the newline posterior to which we stop. */
22198 return - orig_count
- 1;
22201 start_byte
+= ceiling_addr
- base
;
22205 *byte_pos_ptr
= limit_byte
;
22208 return - orig_count
+ count
;
22209 return orig_count
- count
;
22215 /***********************************************************************
22217 ***********************************************************************/
22219 /* Display a NUL-terminated string, starting with index START.
22221 If STRING is non-null, display that C string. Otherwise, the Lisp
22222 string LISP_STRING is displayed. There's a case that STRING is
22223 non-null and LISP_STRING is not nil. It means STRING is a string
22224 data of LISP_STRING. In that case, we display LISP_STRING while
22225 ignoring its text properties.
22227 If FACE_STRING is not nil, FACE_STRING_POS is a position in
22228 FACE_STRING. Display STRING or LISP_STRING with the face at
22229 FACE_STRING_POS in FACE_STRING:
22231 Display the string in the environment given by IT, but use the
22232 standard display table, temporarily.
22234 FIELD_WIDTH is the minimum number of output glyphs to produce.
22235 If STRING has fewer characters than FIELD_WIDTH, pad to the right
22236 with spaces. If STRING has more characters, more than FIELD_WIDTH
22237 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
22239 PRECISION is the maximum number of characters to output from
22240 STRING. PRECISION < 0 means don't truncate the string.
22242 This is roughly equivalent to printf format specifiers:
22244 FIELD_WIDTH PRECISION PRINTF
22245 ----------------------------------------
22251 MULTIBYTE zero means do not display multibyte chars, > 0 means do
22252 display them, and < 0 means obey the current buffer's value of
22253 enable_multibyte_characters.
22255 Value is the number of columns displayed. */
22258 display_string (const char *string
, Lisp_Object lisp_string
, Lisp_Object face_string
,
22259 ptrdiff_t face_string_pos
, ptrdiff_t start
, struct it
*it
,
22260 int field_width
, int precision
, int max_x
, int multibyte
)
22262 int hpos_at_start
= it
->hpos
;
22263 int saved_face_id
= it
->face_id
;
22264 struct glyph_row
*row
= it
->glyph_row
;
22265 ptrdiff_t it_charpos
;
22267 /* Initialize the iterator IT for iteration over STRING beginning
22268 with index START. */
22269 reseat_to_string (it
, NILP (lisp_string
) ? string
: NULL
, lisp_string
, start
,
22270 precision
, field_width
, multibyte
);
22271 if (string
&& STRINGP (lisp_string
))
22272 /* LISP_STRING is the one returned by decode_mode_spec. We should
22273 ignore its text properties. */
22274 it
->stop_charpos
= it
->end_charpos
;
22276 /* If displaying STRING, set up the face of the iterator from
22277 FACE_STRING, if that's given. */
22278 if (STRINGP (face_string
))
22284 = face_at_string_position (it
->w
, face_string
, face_string_pos
,
22285 0, it
->region_beg_charpos
,
22286 it
->region_end_charpos
,
22287 &endptr
, it
->base_face_id
, 0);
22288 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
22289 it
->face_box_p
= face
->box
!= FACE_NO_BOX
;
22292 /* Set max_x to the maximum allowed X position. Don't let it go
22293 beyond the right edge of the window. */
22295 max_x
= it
->last_visible_x
;
22297 max_x
= min (max_x
, it
->last_visible_x
);
22299 /* Skip over display elements that are not visible. because IT->w is
22301 if (it
->current_x
< it
->first_visible_x
)
22302 move_it_in_display_line_to (it
, 100000, it
->first_visible_x
,
22303 MOVE_TO_POS
| MOVE_TO_X
);
22305 row
->ascent
= it
->max_ascent
;
22306 row
->height
= it
->max_ascent
+ it
->max_descent
;
22307 row
->phys_ascent
= it
->max_phys_ascent
;
22308 row
->phys_height
= it
->max_phys_ascent
+ it
->max_phys_descent
;
22309 row
->extra_line_spacing
= it
->max_extra_line_spacing
;
22311 if (STRINGP (it
->string
))
22312 it_charpos
= IT_STRING_CHARPOS (*it
);
22314 it_charpos
= IT_CHARPOS (*it
);
22316 /* This condition is for the case that we are called with current_x
22317 past last_visible_x. */
22318 while (it
->current_x
< max_x
)
22320 int x_before
, x
, n_glyphs_before
, i
, nglyphs
;
22322 /* Get the next display element. */
22323 if (!get_next_display_element (it
))
22326 /* Produce glyphs. */
22327 x_before
= it
->current_x
;
22328 n_glyphs_before
= row
->used
[TEXT_AREA
];
22329 PRODUCE_GLYPHS (it
);
22331 nglyphs
= row
->used
[TEXT_AREA
] - n_glyphs_before
;
22334 while (i
< nglyphs
)
22336 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
] + n_glyphs_before
+ i
;
22338 if (it
->line_wrap
!= TRUNCATE
22339 && x
+ glyph
->pixel_width
> max_x
)
22341 /* End of continued line or max_x reached. */
22342 if (CHAR_GLYPH_PADDING_P (*glyph
))
22344 /* A wide character is unbreakable. */
22345 if (row
->reversed_p
)
22346 unproduce_glyphs (it
, row
->used
[TEXT_AREA
]
22347 - n_glyphs_before
);
22348 row
->used
[TEXT_AREA
] = n_glyphs_before
;
22349 it
->current_x
= x_before
;
22353 if (row
->reversed_p
)
22354 unproduce_glyphs (it
, row
->used
[TEXT_AREA
]
22355 - (n_glyphs_before
+ i
));
22356 row
->used
[TEXT_AREA
] = n_glyphs_before
+ i
;
22361 else if (x
+ glyph
->pixel_width
>= it
->first_visible_x
)
22363 /* Glyph is at least partially visible. */
22365 if (x
< it
->first_visible_x
)
22366 row
->x
= x
- it
->first_visible_x
;
22370 /* Glyph is off the left margin of the display area.
22371 Should not happen. */
22375 row
->ascent
= max (row
->ascent
, it
->max_ascent
);
22376 row
->height
= max (row
->height
, it
->max_ascent
+ it
->max_descent
);
22377 row
->phys_ascent
= max (row
->phys_ascent
, it
->max_phys_ascent
);
22378 row
->phys_height
= max (row
->phys_height
,
22379 it
->max_phys_ascent
+ it
->max_phys_descent
);
22380 row
->extra_line_spacing
= max (row
->extra_line_spacing
,
22381 it
->max_extra_line_spacing
);
22382 x
+= glyph
->pixel_width
;
22386 /* Stop if max_x reached. */
22390 /* Stop at line ends. */
22391 if (ITERATOR_AT_END_OF_LINE_P (it
))
22393 it
->continuation_lines_width
= 0;
22397 set_iterator_to_next (it
, 1);
22398 if (STRINGP (it
->string
))
22399 it_charpos
= IT_STRING_CHARPOS (*it
);
22401 it_charpos
= IT_CHARPOS (*it
);
22403 /* Stop if truncating at the right edge. */
22404 if (it
->line_wrap
== TRUNCATE
22405 && it
->current_x
>= it
->last_visible_x
)
22407 /* Add truncation mark, but don't do it if the line is
22408 truncated at a padding space. */
22409 if (it_charpos
< it
->string_nchars
)
22411 if (!FRAME_WINDOW_P (it
->f
))
22415 if (it
->current_x
> it
->last_visible_x
)
22417 if (!row
->reversed_p
)
22419 for (ii
= row
->used
[TEXT_AREA
] - 1; ii
> 0; --ii
)
22420 if (!CHAR_GLYPH_PADDING_P (row
->glyphs
[TEXT_AREA
][ii
]))
22425 for (ii
= 0; ii
< row
->used
[TEXT_AREA
]; ii
++)
22426 if (!CHAR_GLYPH_PADDING_P (row
->glyphs
[TEXT_AREA
][ii
]))
22428 unproduce_glyphs (it
, ii
+ 1);
22429 ii
= row
->used
[TEXT_AREA
] - (ii
+ 1);
22431 for (n
= row
->used
[TEXT_AREA
]; ii
< n
; ++ii
)
22433 row
->used
[TEXT_AREA
] = ii
;
22434 produce_special_glyphs (it
, IT_TRUNCATION
);
22437 produce_special_glyphs (it
, IT_TRUNCATION
);
22439 row
->truncated_on_right_p
= 1;
22445 /* Maybe insert a truncation at the left. */
22446 if (it
->first_visible_x
22449 if (!FRAME_WINDOW_P (it
->f
)
22450 || (row
->reversed_p
22451 ? WINDOW_RIGHT_FRINGE_WIDTH (it
->w
)
22452 : WINDOW_LEFT_FRINGE_WIDTH (it
->w
)) == 0)
22453 insert_left_trunc_glyphs (it
);
22454 row
->truncated_on_left_p
= 1;
22457 it
->face_id
= saved_face_id
;
22459 /* Value is number of columns displayed. */
22460 return it
->hpos
- hpos_at_start
;
22465 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
22466 appears as an element of LIST or as the car of an element of LIST.
22467 If PROPVAL is a list, compare each element against LIST in that
22468 way, and return 1/2 if any element of PROPVAL is found in LIST.
22469 Otherwise return 0. This function cannot quit.
22470 The return value is 2 if the text is invisible but with an ellipsis
22471 and 1 if it's invisible and without an ellipsis. */
22474 invisible_p (register Lisp_Object propval
, Lisp_Object list
)
22476 register Lisp_Object tail
, proptail
;
22478 for (tail
= list
; CONSP (tail
); tail
= XCDR (tail
))
22480 register Lisp_Object tem
;
22482 if (EQ (propval
, tem
))
22484 if (CONSP (tem
) && EQ (propval
, XCAR (tem
)))
22485 return NILP (XCDR (tem
)) ? 1 : 2;
22488 if (CONSP (propval
))
22490 for (proptail
= propval
; CONSP (proptail
); proptail
= XCDR (proptail
))
22492 Lisp_Object propelt
;
22493 propelt
= XCAR (proptail
);
22494 for (tail
= list
; CONSP (tail
); tail
= XCDR (tail
))
22496 register Lisp_Object tem
;
22498 if (EQ (propelt
, tem
))
22500 if (CONSP (tem
) && EQ (propelt
, XCAR (tem
)))
22501 return NILP (XCDR (tem
)) ? 1 : 2;
22509 DEFUN ("invisible-p", Finvisible_p
, Sinvisible_p
, 1, 1, 0,
22510 doc
: /* Non-nil if the property makes the text invisible.
22511 POS-OR-PROP can be a marker or number, in which case it is taken to be
22512 a position in the current buffer and the value of the `invisible' property
22513 is checked; or it can be some other value, which is then presumed to be the
22514 value of the `invisible' property of the text of interest.
22515 The non-nil value returned can be t for truly invisible text or something
22516 else if the text is replaced by an ellipsis. */)
22517 (Lisp_Object pos_or_prop
)
22520 = (NATNUMP (pos_or_prop
) || MARKERP (pos_or_prop
)
22521 ? Fget_char_property (pos_or_prop
, Qinvisible
, Qnil
)
22523 int invis
= TEXT_PROP_MEANS_INVISIBLE (prop
);
22524 return (invis
== 0 ? Qnil
22526 : make_number (invis
));
22529 /* Calculate a width or height in pixels from a specification using
22530 the following elements:
22533 NUM - a (fractional) multiple of the default font width/height
22534 (NUM) - specifies exactly NUM pixels
22535 UNIT - a fixed number of pixels, see below.
22536 ELEMENT - size of a display element in pixels, see below.
22537 (NUM . SPEC) - equals NUM * SPEC
22538 (+ SPEC SPEC ...) - add pixel values
22539 (- SPEC SPEC ...) - subtract pixel values
22540 (- SPEC) - negate pixel value
22543 INT or FLOAT - a number constant
22544 SYMBOL - use symbol's (buffer local) variable binding.
22547 in - pixels per inch *)
22548 mm - pixels per 1/1000 meter *)
22549 cm - pixels per 1/100 meter *)
22550 width - width of current font in pixels.
22551 height - height of current font in pixels.
22553 *) using the ratio(s) defined in display-pixels-per-inch.
22557 left-fringe - left fringe width in pixels
22558 right-fringe - right fringe width in pixels
22560 left-margin - left margin width in pixels
22561 right-margin - right margin width in pixels
22563 scroll-bar - scroll-bar area width in pixels
22567 Pixels corresponding to 5 inches:
22570 Total width of non-text areas on left side of window (if scroll-bar is on left):
22571 '(space :width (+ left-fringe left-margin scroll-bar))
22573 Align to first text column (in header line):
22574 '(space :align-to 0)
22576 Align to middle of text area minus half the width of variable `my-image'
22577 containing a loaded image:
22578 '(space :align-to (0.5 . (- text my-image)))
22580 Width of left margin minus width of 1 character in the default font:
22581 '(space :width (- left-margin 1))
22583 Width of left margin minus width of 2 characters in the current font:
22584 '(space :width (- left-margin (2 . width)))
22586 Center 1 character over left-margin (in header line):
22587 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
22589 Different ways to express width of left fringe plus left margin minus one pixel:
22590 '(space :width (- (+ left-fringe left-margin) (1)))
22591 '(space :width (+ left-fringe left-margin (- (1))))
22592 '(space :width (+ left-fringe left-margin (-1)))
22597 calc_pixel_width_or_height (double *res
, struct it
*it
, Lisp_Object prop
,
22598 struct font
*font
, int width_p
, int *align_to
)
22602 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
22603 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
22606 return OK_PIXELS (0);
22608 eassert (FRAME_LIVE_P (it
->f
));
22610 if (SYMBOLP (prop
))
22612 if (SCHARS (SYMBOL_NAME (prop
)) == 2)
22614 char *unit
= SSDATA (SYMBOL_NAME (prop
));
22616 if (unit
[0] == 'i' && unit
[1] == 'n')
22618 else if (unit
[0] == 'm' && unit
[1] == 'm')
22620 else if (unit
[0] == 'c' && unit
[1] == 'm')
22626 double ppi
= (width_p
? FRAME_RES_X (it
->f
)
22627 : FRAME_RES_Y (it
->f
));
22630 return OK_PIXELS (ppi
/ pixels
);
22635 #ifdef HAVE_WINDOW_SYSTEM
22636 if (EQ (prop
, Qheight
))
22637 return OK_PIXELS (font
? FONT_HEIGHT (font
) : FRAME_LINE_HEIGHT (it
->f
));
22638 if (EQ (prop
, Qwidth
))
22639 return OK_PIXELS (font
? FONT_WIDTH (font
) : FRAME_COLUMN_WIDTH (it
->f
));
22641 if (EQ (prop
, Qheight
) || EQ (prop
, Qwidth
))
22642 return OK_PIXELS (1);
22645 if (EQ (prop
, Qtext
))
22646 return OK_PIXELS (width_p
22647 ? window_box_width (it
->w
, TEXT_AREA
)
22648 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it
->w
));
22650 if (align_to
&& *align_to
< 0)
22653 if (EQ (prop
, Qleft
))
22654 return OK_ALIGN_TO (window_box_left_offset (it
->w
, TEXT_AREA
));
22655 if (EQ (prop
, Qright
))
22656 return OK_ALIGN_TO (window_box_right_offset (it
->w
, TEXT_AREA
));
22657 if (EQ (prop
, Qcenter
))
22658 return OK_ALIGN_TO (window_box_left_offset (it
->w
, TEXT_AREA
)
22659 + window_box_width (it
->w
, TEXT_AREA
) / 2);
22660 if (EQ (prop
, Qleft_fringe
))
22661 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it
->w
)
22662 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it
->w
)
22663 : window_box_right_offset (it
->w
, LEFT_MARGIN_AREA
));
22664 if (EQ (prop
, Qright_fringe
))
22665 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it
->w
)
22666 ? window_box_right_offset (it
->w
, RIGHT_MARGIN_AREA
)
22667 : window_box_right_offset (it
->w
, TEXT_AREA
));
22668 if (EQ (prop
, Qleft_margin
))
22669 return OK_ALIGN_TO (window_box_left_offset (it
->w
, LEFT_MARGIN_AREA
));
22670 if (EQ (prop
, Qright_margin
))
22671 return OK_ALIGN_TO (window_box_left_offset (it
->w
, RIGHT_MARGIN_AREA
));
22672 if (EQ (prop
, Qscroll_bar
))
22673 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it
->w
)
22675 : (window_box_right_offset (it
->w
, RIGHT_MARGIN_AREA
)
22676 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it
->w
)
22677 ? WINDOW_RIGHT_FRINGE_WIDTH (it
->w
)
22682 if (EQ (prop
, Qleft_fringe
))
22683 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it
->w
));
22684 if (EQ (prop
, Qright_fringe
))
22685 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it
->w
));
22686 if (EQ (prop
, Qleft_margin
))
22687 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it
->w
));
22688 if (EQ (prop
, Qright_margin
))
22689 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it
->w
));
22690 if (EQ (prop
, Qscroll_bar
))
22691 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it
->w
));
22694 prop
= buffer_local_value_1 (prop
, it
->w
->contents
);
22695 if (EQ (prop
, Qunbound
))
22699 if (INTEGERP (prop
) || FLOATP (prop
))
22701 int base_unit
= (width_p
22702 ? FRAME_COLUMN_WIDTH (it
->f
)
22703 : FRAME_LINE_HEIGHT (it
->f
));
22704 return OK_PIXELS (XFLOATINT (prop
) * base_unit
);
22709 Lisp_Object car
= XCAR (prop
);
22710 Lisp_Object cdr
= XCDR (prop
);
22714 #ifdef HAVE_WINDOW_SYSTEM
22715 if (FRAME_WINDOW_P (it
->f
)
22716 && valid_image_p (prop
))
22718 ptrdiff_t id
= lookup_image (it
->f
, prop
);
22719 struct image
*img
= IMAGE_FROM_ID (it
->f
, id
);
22721 return OK_PIXELS (width_p
? img
->width
: img
->height
);
22724 if (EQ (car
, Qplus
) || EQ (car
, Qminus
))
22730 while (CONSP (cdr
))
22732 if (!calc_pixel_width_or_height (&px
, it
, XCAR (cdr
),
22733 font
, width_p
, align_to
))
22736 pixels
= (EQ (car
, Qplus
) ? px
: -px
), first
= 0;
22741 if (EQ (car
, Qminus
))
22743 return OK_PIXELS (pixels
);
22746 car
= buffer_local_value_1 (car
, it
->w
->contents
);
22747 if (EQ (car
, Qunbound
))
22751 if (INTEGERP (car
) || FLOATP (car
))
22754 pixels
= XFLOATINT (car
);
22756 return OK_PIXELS (pixels
);
22757 if (calc_pixel_width_or_height (&fact
, it
, cdr
,
22758 font
, width_p
, align_to
))
22759 return OK_PIXELS (pixels
* fact
);
22770 /***********************************************************************
22772 ***********************************************************************/
22774 #ifdef HAVE_WINDOW_SYSTEM
22779 dump_glyph_string (struct glyph_string
*s
)
22781 fprintf (stderr
, "glyph string\n");
22782 fprintf (stderr
, " x, y, w, h = %d, %d, %d, %d\n",
22783 s
->x
, s
->y
, s
->width
, s
->height
);
22784 fprintf (stderr
, " ybase = %d\n", s
->ybase
);
22785 fprintf (stderr
, " hl = %d\n", s
->hl
);
22786 fprintf (stderr
, " left overhang = %d, right = %d\n",
22787 s
->left_overhang
, s
->right_overhang
);
22788 fprintf (stderr
, " nchars = %d\n", s
->nchars
);
22789 fprintf (stderr
, " extends to end of line = %d\n",
22790 s
->extends_to_end_of_line_p
);
22791 fprintf (stderr
, " font height = %d\n", FONT_HEIGHT (s
->font
));
22792 fprintf (stderr
, " bg width = %d\n", s
->background_width
);
22795 #endif /* GLYPH_DEBUG */
22797 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
22798 of XChar2b structures for S; it can't be allocated in
22799 init_glyph_string because it must be allocated via `alloca'. W
22800 is the window on which S is drawn. ROW and AREA are the glyph row
22801 and area within the row from which S is constructed. START is the
22802 index of the first glyph structure covered by S. HL is a
22803 face-override for drawing S. */
22806 #define OPTIONAL_HDC(hdc) HDC hdc,
22807 #define DECLARE_HDC(hdc) HDC hdc;
22808 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
22809 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
22812 #ifndef OPTIONAL_HDC
22813 #define OPTIONAL_HDC(hdc)
22814 #define DECLARE_HDC(hdc)
22815 #define ALLOCATE_HDC(hdc, f)
22816 #define RELEASE_HDC(hdc, f)
22820 init_glyph_string (struct glyph_string
*s
,
22822 XChar2b
*char2b
, struct window
*w
, struct glyph_row
*row
,
22823 enum glyph_row_area area
, int start
, enum draw_glyphs_face hl
)
22825 memset (s
, 0, sizeof *s
);
22827 s
->f
= XFRAME (w
->frame
);
22831 s
->display
= FRAME_X_DISPLAY (s
->f
);
22832 s
->window
= FRAME_X_WINDOW (s
->f
);
22833 s
->char2b
= char2b
;
22837 s
->first_glyph
= row
->glyphs
[area
] + start
;
22838 s
->height
= row
->height
;
22839 s
->y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
22840 s
->ybase
= s
->y
+ row
->ascent
;
22844 /* Append the list of glyph strings with head H and tail T to the list
22845 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
22848 append_glyph_string_lists (struct glyph_string
**head
, struct glyph_string
**tail
,
22849 struct glyph_string
*h
, struct glyph_string
*t
)
22863 /* Prepend the list of glyph strings with head H and tail T to the
22864 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
22868 prepend_glyph_string_lists (struct glyph_string
**head
, struct glyph_string
**tail
,
22869 struct glyph_string
*h
, struct glyph_string
*t
)
22883 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
22884 Set *HEAD and *TAIL to the resulting list. */
22887 append_glyph_string (struct glyph_string
**head
, struct glyph_string
**tail
,
22888 struct glyph_string
*s
)
22890 s
->next
= s
->prev
= NULL
;
22891 append_glyph_string_lists (head
, tail
, s
, s
);
22895 /* Get face and two-byte form of character C in face FACE_ID on frame F.
22896 The encoding of C is returned in *CHAR2B. DISPLAY_P non-zero means
22897 make sure that X resources for the face returned are allocated.
22898 Value is a pointer to a realized face that is ready for display if
22899 DISPLAY_P is non-zero. */
22901 static struct face
*
22902 get_char_face_and_encoding (struct frame
*f
, int c
, int face_id
,
22903 XChar2b
*char2b
, int display_p
)
22905 struct face
*face
= FACE_FROM_ID (f
, face_id
);
22910 code
= face
->font
->driver
->encode_char (face
->font
, c
);
22912 if (code
== FONT_INVALID_CODE
)
22915 STORE_XCHAR2B (char2b
, (code
>> 8), (code
& 0xFF));
22917 /* Make sure X resources of the face are allocated. */
22918 #ifdef HAVE_X_WINDOWS
22922 eassert (face
!= NULL
);
22923 PREPARE_FACE_FOR_DISPLAY (f
, face
);
22930 /* Get face and two-byte form of character glyph GLYPH on frame F.
22931 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
22932 a pointer to a realized face that is ready for display. */
22934 static struct face
*
22935 get_glyph_face_and_encoding (struct frame
*f
, struct glyph
*glyph
,
22936 XChar2b
*char2b
, int *two_byte_p
)
22941 eassert (glyph
->type
== CHAR_GLYPH
);
22942 face
= FACE_FROM_ID (f
, glyph
->face_id
);
22944 /* Make sure X resources of the face are allocated. */
22945 eassert (face
!= NULL
);
22946 PREPARE_FACE_FOR_DISPLAY (f
, face
);
22953 if (CHAR_BYTE8_P (glyph
->u
.ch
))
22954 code
= CHAR_TO_BYTE8 (glyph
->u
.ch
);
22956 code
= face
->font
->driver
->encode_char (face
->font
, glyph
->u
.ch
);
22958 if (code
== FONT_INVALID_CODE
)
22962 STORE_XCHAR2B (char2b
, (code
>> 8), (code
& 0xFF));
22967 /* Get glyph code of character C in FONT in the two-byte form CHAR2B.
22968 Return 1 if FONT has a glyph for C, otherwise return 0. */
22971 get_char_glyph_code (int c
, struct font
*font
, XChar2b
*char2b
)
22975 if (CHAR_BYTE8_P (c
))
22976 code
= CHAR_TO_BYTE8 (c
);
22978 code
= font
->driver
->encode_char (font
, c
);
22980 if (code
== FONT_INVALID_CODE
)
22982 STORE_XCHAR2B (char2b
, (code
>> 8), (code
& 0xFF));
22987 /* Fill glyph string S with composition components specified by S->cmp.
22989 BASE_FACE is the base face of the composition.
22990 S->cmp_from is the index of the first component for S.
22992 OVERLAPS non-zero means S should draw the foreground only, and use
22993 its physical height for clipping. See also draw_glyphs.
22995 Value is the index of a component not in S. */
22998 fill_composite_glyph_string (struct glyph_string
*s
, struct face
*base_face
,
23002 /* For all glyphs of this composition, starting at the offset
23003 S->cmp_from, until we reach the end of the definition or encounter a
23004 glyph that requires the different face, add it to S. */
23009 s
->for_overlaps
= overlaps
;
23012 for (i
= s
->cmp_from
; i
< s
->cmp
->glyph_len
; i
++)
23014 int c
= COMPOSITION_GLYPH (s
->cmp
, i
);
23016 /* TAB in a composition means display glyphs with padding space
23017 on the left or right. */
23020 int face_id
= FACE_FOR_CHAR (s
->f
, base_face
->ascii_face
, c
,
23023 face
= get_char_face_and_encoding (s
->f
, c
, face_id
,
23030 s
->font
= s
->face
->font
;
23032 else if (s
->face
!= face
)
23040 if (s
->face
== NULL
)
23042 s
->face
= base_face
->ascii_face
;
23043 s
->font
= s
->face
->font
;
23046 /* All glyph strings for the same composition has the same width,
23047 i.e. the width set for the first component of the composition. */
23048 s
->width
= s
->first_glyph
->pixel_width
;
23050 /* If the specified font could not be loaded, use the frame's
23051 default font, but record the fact that we couldn't load it in
23052 the glyph string so that we can draw rectangles for the
23053 characters of the glyph string. */
23054 if (s
->font
== NULL
)
23056 s
->font_not_found_p
= 1;
23057 s
->font
= FRAME_FONT (s
->f
);
23060 /* Adjust base line for subscript/superscript text. */
23061 s
->ybase
+= s
->first_glyph
->voffset
;
23063 /* This glyph string must always be drawn with 16-bit functions. */
23070 fill_gstring_glyph_string (struct glyph_string
*s
, int face_id
,
23071 int start
, int end
, int overlaps
)
23073 struct glyph
*glyph
, *last
;
23074 Lisp_Object lgstring
;
23077 s
->for_overlaps
= overlaps
;
23078 glyph
= s
->row
->glyphs
[s
->area
] + start
;
23079 last
= s
->row
->glyphs
[s
->area
] + end
;
23080 s
->cmp_id
= glyph
->u
.cmp
.id
;
23081 s
->cmp_from
= glyph
->slice
.cmp
.from
;
23082 s
->cmp_to
= glyph
->slice
.cmp
.to
+ 1;
23083 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
23084 lgstring
= composition_gstring_from_id (s
->cmp_id
);
23085 s
->font
= XFONT_OBJECT (LGSTRING_FONT (lgstring
));
23087 while (glyph
< last
23088 && glyph
->u
.cmp
.automatic
23089 && glyph
->u
.cmp
.id
== s
->cmp_id
23090 && s
->cmp_to
== glyph
->slice
.cmp
.from
)
23091 s
->cmp_to
= (glyph
++)->slice
.cmp
.to
+ 1;
23093 for (i
= s
->cmp_from
; i
< s
->cmp_to
; i
++)
23095 Lisp_Object lglyph
= LGSTRING_GLYPH (lgstring
, i
);
23096 unsigned code
= LGLYPH_CODE (lglyph
);
23098 STORE_XCHAR2B ((s
->char2b
+ i
), code
>> 8, code
& 0xFF);
23100 s
->width
= composition_gstring_width (lgstring
, s
->cmp_from
, s
->cmp_to
, NULL
);
23101 return glyph
- s
->row
->glyphs
[s
->area
];
23105 /* Fill glyph string S from a sequence glyphs for glyphless characters.
23106 See the comment of fill_glyph_string for arguments.
23107 Value is the index of the first glyph not in S. */
23111 fill_glyphless_glyph_string (struct glyph_string
*s
, int face_id
,
23112 int start
, int end
, int overlaps
)
23114 struct glyph
*glyph
, *last
;
23117 eassert (s
->first_glyph
->type
== GLYPHLESS_GLYPH
);
23118 s
->for_overlaps
= overlaps
;
23119 glyph
= s
->row
->glyphs
[s
->area
] + start
;
23120 last
= s
->row
->glyphs
[s
->area
] + end
;
23121 voffset
= glyph
->voffset
;
23122 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
23123 s
->font
= s
->face
->font
? s
->face
->font
: FRAME_FONT (s
->f
);
23125 s
->width
= glyph
->pixel_width
;
23127 while (glyph
< last
23128 && glyph
->type
== GLYPHLESS_GLYPH
23129 && glyph
->voffset
== voffset
23130 && glyph
->face_id
== face_id
)
23133 s
->width
+= glyph
->pixel_width
;
23136 s
->ybase
+= voffset
;
23137 return glyph
- s
->row
->glyphs
[s
->area
];
23141 /* Fill glyph string S from a sequence of character glyphs.
23143 FACE_ID is the face id of the string. START is the index of the
23144 first glyph to consider, END is the index of the last + 1.
23145 OVERLAPS non-zero means S should draw the foreground only, and use
23146 its physical height for clipping. See also draw_glyphs.
23148 Value is the index of the first glyph not in S. */
23151 fill_glyph_string (struct glyph_string
*s
, int face_id
,
23152 int start
, int end
, int overlaps
)
23154 struct glyph
*glyph
, *last
;
23156 int glyph_not_available_p
;
23158 eassert (s
->f
== XFRAME (s
->w
->frame
));
23159 eassert (s
->nchars
== 0);
23160 eassert (start
>= 0 && end
> start
);
23162 s
->for_overlaps
= overlaps
;
23163 glyph
= s
->row
->glyphs
[s
->area
] + start
;
23164 last
= s
->row
->glyphs
[s
->area
] + end
;
23165 voffset
= glyph
->voffset
;
23166 s
->padding_p
= glyph
->padding_p
;
23167 glyph_not_available_p
= glyph
->glyph_not_available_p
;
23169 while (glyph
< last
23170 && glyph
->type
== CHAR_GLYPH
23171 && glyph
->voffset
== voffset
23172 /* Same face id implies same font, nowadays. */
23173 && glyph
->face_id
== face_id
23174 && glyph
->glyph_not_available_p
== glyph_not_available_p
)
23178 s
->face
= get_glyph_face_and_encoding (s
->f
, glyph
,
23179 s
->char2b
+ s
->nchars
,
23181 s
->two_byte_p
= two_byte_p
;
23183 eassert (s
->nchars
<= end
- start
);
23184 s
->width
+= glyph
->pixel_width
;
23185 if (glyph
++->padding_p
!= s
->padding_p
)
23189 s
->font
= s
->face
->font
;
23191 /* If the specified font could not be loaded, use the frame's font,
23192 but record the fact that we couldn't load it in
23193 S->font_not_found_p so that we can draw rectangles for the
23194 characters of the glyph string. */
23195 if (s
->font
== NULL
|| glyph_not_available_p
)
23197 s
->font_not_found_p
= 1;
23198 s
->font
= FRAME_FONT (s
->f
);
23201 /* Adjust base line for subscript/superscript text. */
23202 s
->ybase
+= voffset
;
23204 eassert (s
->face
&& s
->face
->gc
);
23205 return glyph
- s
->row
->glyphs
[s
->area
];
23209 /* Fill glyph string S from image glyph S->first_glyph. */
23212 fill_image_glyph_string (struct glyph_string
*s
)
23214 eassert (s
->first_glyph
->type
== IMAGE_GLYPH
);
23215 s
->img
= IMAGE_FROM_ID (s
->f
, s
->first_glyph
->u
.img_id
);
23217 s
->slice
= s
->first_glyph
->slice
.img
;
23218 s
->face
= FACE_FROM_ID (s
->f
, s
->first_glyph
->face_id
);
23219 s
->font
= s
->face
->font
;
23220 s
->width
= s
->first_glyph
->pixel_width
;
23222 /* Adjust base line for subscript/superscript text. */
23223 s
->ybase
+= s
->first_glyph
->voffset
;
23227 /* Fill glyph string S from a sequence of stretch glyphs.
23229 START is the index of the first glyph to consider,
23230 END is the index of the last + 1.
23232 Value is the index of the first glyph not in S. */
23235 fill_stretch_glyph_string (struct glyph_string
*s
, int start
, int end
)
23237 struct glyph
*glyph
, *last
;
23238 int voffset
, face_id
;
23240 eassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
23242 glyph
= s
->row
->glyphs
[s
->area
] + start
;
23243 last
= s
->row
->glyphs
[s
->area
] + end
;
23244 face_id
= glyph
->face_id
;
23245 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
23246 s
->font
= s
->face
->font
;
23247 s
->width
= glyph
->pixel_width
;
23249 voffset
= glyph
->voffset
;
23253 && glyph
->type
== STRETCH_GLYPH
23254 && glyph
->voffset
== voffset
23255 && glyph
->face_id
== face_id
);
23257 s
->width
+= glyph
->pixel_width
;
23259 /* Adjust base line for subscript/superscript text. */
23260 s
->ybase
+= voffset
;
23262 /* The case that face->gc == 0 is handled when drawing the glyph
23263 string by calling PREPARE_FACE_FOR_DISPLAY. */
23265 return glyph
- s
->row
->glyphs
[s
->area
];
23268 static struct font_metrics
*
23269 get_per_char_metric (struct font
*font
, XChar2b
*char2b
)
23271 static struct font_metrics metrics
;
23276 code
= (XCHAR2B_BYTE1 (char2b
) << 8) | XCHAR2B_BYTE2 (char2b
);
23277 if (code
== FONT_INVALID_CODE
)
23279 font
->driver
->text_extents (font
, &code
, 1, &metrics
);
23284 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
23285 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
23286 assumed to be zero. */
23289 x_get_glyph_overhangs (struct glyph
*glyph
, struct frame
*f
, int *left
, int *right
)
23291 *left
= *right
= 0;
23293 if (glyph
->type
== CHAR_GLYPH
)
23297 struct font_metrics
*pcm
;
23299 face
= get_glyph_face_and_encoding (f
, glyph
, &char2b
, NULL
);
23300 if (face
->font
&& (pcm
= get_per_char_metric (face
->font
, &char2b
)))
23302 if (pcm
->rbearing
> pcm
->width
)
23303 *right
= pcm
->rbearing
- pcm
->width
;
23304 if (pcm
->lbearing
< 0)
23305 *left
= -pcm
->lbearing
;
23308 else if (glyph
->type
== COMPOSITE_GLYPH
)
23310 if (! glyph
->u
.cmp
.automatic
)
23312 struct composition
*cmp
= composition_table
[glyph
->u
.cmp
.id
];
23314 if (cmp
->rbearing
> cmp
->pixel_width
)
23315 *right
= cmp
->rbearing
- cmp
->pixel_width
;
23316 if (cmp
->lbearing
< 0)
23317 *left
= - cmp
->lbearing
;
23321 Lisp_Object gstring
= composition_gstring_from_id (glyph
->u
.cmp
.id
);
23322 struct font_metrics metrics
;
23324 composition_gstring_width (gstring
, glyph
->slice
.cmp
.from
,
23325 glyph
->slice
.cmp
.to
+ 1, &metrics
);
23326 if (metrics
.rbearing
> metrics
.width
)
23327 *right
= metrics
.rbearing
- metrics
.width
;
23328 if (metrics
.lbearing
< 0)
23329 *left
= - metrics
.lbearing
;
23335 /* Return the index of the first glyph preceding glyph string S that
23336 is overwritten by S because of S's left overhang. Value is -1
23337 if no glyphs are overwritten. */
23340 left_overwritten (struct glyph_string
*s
)
23344 if (s
->left_overhang
)
23347 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
23348 int first
= s
->first_glyph
- glyphs
;
23350 for (i
= first
- 1; i
>= 0 && x
> -s
->left_overhang
; --i
)
23351 x
-= glyphs
[i
].pixel_width
;
23362 /* Return the index of the first glyph preceding glyph string S that
23363 is overwriting S because of its right overhang. Value is -1 if no
23364 glyph in front of S overwrites S. */
23367 left_overwriting (struct glyph_string
*s
)
23370 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
23371 int first
= s
->first_glyph
- glyphs
;
23375 for (i
= first
- 1; i
>= 0; --i
)
23378 x_get_glyph_overhangs (glyphs
+ i
, s
->f
, &left
, &right
);
23381 x
-= glyphs
[i
].pixel_width
;
23388 /* Return the index of the last glyph following glyph string S that is
23389 overwritten by S because of S's right overhang. Value is -1 if
23390 no such glyph is found. */
23393 right_overwritten (struct glyph_string
*s
)
23397 if (s
->right_overhang
)
23400 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
23401 int first
= (s
->first_glyph
- glyphs
23402 + (s
->first_glyph
->type
== COMPOSITE_GLYPH
? 1 : s
->nchars
));
23403 int end
= s
->row
->used
[s
->area
];
23405 for (i
= first
; i
< end
&& s
->right_overhang
> x
; ++i
)
23406 x
+= glyphs
[i
].pixel_width
;
23415 /* Return the index of the last glyph following glyph string S that
23416 overwrites S because of its left overhang. Value is negative
23417 if no such glyph is found. */
23420 right_overwriting (struct glyph_string
*s
)
23423 int end
= s
->row
->used
[s
->area
];
23424 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
23425 int first
= (s
->first_glyph
- glyphs
23426 + (s
->first_glyph
->type
== COMPOSITE_GLYPH
? 1 : s
->nchars
));
23430 for (i
= first
; i
< end
; ++i
)
23433 x_get_glyph_overhangs (glyphs
+ i
, s
->f
, &left
, &right
);
23436 x
+= glyphs
[i
].pixel_width
;
23443 /* Set background width of glyph string S. START is the index of the
23444 first glyph following S. LAST_X is the right-most x-position + 1
23445 in the drawing area. */
23448 set_glyph_string_background_width (struct glyph_string
*s
, int start
, int last_x
)
23450 /* If the face of this glyph string has to be drawn to the end of
23451 the drawing area, set S->extends_to_end_of_line_p. */
23453 if (start
== s
->row
->used
[s
->area
]
23454 && s
->area
== TEXT_AREA
23455 && ((s
->row
->fill_line_p
23456 && (s
->hl
== DRAW_NORMAL_TEXT
23457 || s
->hl
== DRAW_IMAGE_RAISED
23458 || s
->hl
== DRAW_IMAGE_SUNKEN
))
23459 || s
->hl
== DRAW_MOUSE_FACE
))
23460 s
->extends_to_end_of_line_p
= 1;
23462 /* If S extends its face to the end of the line, set its
23463 background_width to the distance to the right edge of the drawing
23465 if (s
->extends_to_end_of_line_p
)
23466 s
->background_width
= last_x
- s
->x
+ 1;
23468 s
->background_width
= s
->width
;
23472 /* Compute overhangs and x-positions for glyph string S and its
23473 predecessors, or successors. X is the starting x-position for S.
23474 BACKWARD_P non-zero means process predecessors. */
23477 compute_overhangs_and_x (struct glyph_string
*s
, int x
, int backward_p
)
23483 if (FRAME_RIF (s
->f
)->compute_glyph_string_overhangs
)
23484 FRAME_RIF (s
->f
)->compute_glyph_string_overhangs (s
);
23494 if (FRAME_RIF (s
->f
)->compute_glyph_string_overhangs
)
23495 FRAME_RIF (s
->f
)->compute_glyph_string_overhangs (s
);
23505 /* The following macros are only called from draw_glyphs below.
23506 They reference the following parameters of that function directly:
23507 `w', `row', `area', and `overlap_p'
23508 as well as the following local variables:
23509 `s', `f', and `hdc' (in W32) */
23512 /* On W32, silently add local `hdc' variable to argument list of
23513 init_glyph_string. */
23514 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
23515 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
23517 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
23518 init_glyph_string (s, char2b, w, row, area, start, hl)
23521 /* Add a glyph string for a stretch glyph to the list of strings
23522 between HEAD and TAIL. START is the index of the stretch glyph in
23523 row area AREA of glyph row ROW. END is the index of the last glyph
23524 in that glyph row area. X is the current output position assigned
23525 to the new glyph string constructed. HL overrides that face of the
23526 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
23527 is the right-most x-position of the drawing area. */
23529 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
23530 and below -- keep them on one line. */
23531 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23534 s = alloca (sizeof *s); \
23535 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
23536 START = fill_stretch_glyph_string (s, START, END); \
23537 append_glyph_string (&HEAD, &TAIL, s); \
23543 /* Add a glyph string for an image glyph to the list of strings
23544 between HEAD and TAIL. START is the index of the image glyph in
23545 row area AREA of glyph row ROW. END is the index of the last glyph
23546 in that glyph row area. X is the current output position assigned
23547 to the new glyph string constructed. HL overrides that face of the
23548 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
23549 is the right-most x-position of the drawing area. */
23551 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23554 s = alloca (sizeof *s); \
23555 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
23556 fill_image_glyph_string (s); \
23557 append_glyph_string (&HEAD, &TAIL, s); \
23564 /* Add a glyph string for a sequence of character glyphs to the list
23565 of strings between HEAD and TAIL. START is the index of the first
23566 glyph in row area AREA of glyph row ROW that is part of the new
23567 glyph string. END is the index of the last glyph in that glyph row
23568 area. X is the current output position assigned to the new glyph
23569 string constructed. HL overrides that face of the glyph; e.g. it
23570 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
23571 right-most x-position of the drawing area. */
23573 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
23579 face_id = (row)->glyphs[area][START].face_id; \
23581 s = alloca (sizeof *s); \
23582 char2b = alloca ((END - START) * sizeof *char2b); \
23583 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
23584 append_glyph_string (&HEAD, &TAIL, s); \
23586 START = fill_glyph_string (s, face_id, START, END, overlaps); \
23591 /* Add a glyph string for a composite sequence to the list of strings
23592 between HEAD and TAIL. START is the index of the first glyph in
23593 row area AREA of glyph row ROW that is part of the new glyph
23594 string. END is the index of the last glyph in that glyph row area.
23595 X is the current output position assigned to the new glyph string
23596 constructed. HL overrides that face of the glyph; e.g. it is
23597 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
23598 x-position of the drawing area. */
23600 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23602 int face_id = (row)->glyphs[area][START].face_id; \
23603 struct face *base_face = FACE_FROM_ID (f, face_id); \
23604 ptrdiff_t cmp_id = (row)->glyphs[area][START].u.cmp.id; \
23605 struct composition *cmp = composition_table[cmp_id]; \
23607 struct glyph_string *first_s = NULL; \
23610 char2b = alloca (cmp->glyph_len * sizeof *char2b); \
23612 /* Make glyph_strings for each glyph sequence that is drawable by \
23613 the same face, and append them to HEAD/TAIL. */ \
23614 for (n = 0; n < cmp->glyph_len;) \
23616 s = alloca (sizeof *s); \
23617 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
23618 append_glyph_string (&(HEAD), &(TAIL), s); \
23624 n = fill_composite_glyph_string (s, base_face, overlaps); \
23632 /* Add a glyph string for a glyph-string sequence to the list of strings
23633 between HEAD and TAIL. */
23635 #define BUILD_GSTRING_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23639 Lisp_Object gstring; \
23641 face_id = (row)->glyphs[area][START].face_id; \
23642 gstring = (composition_gstring_from_id \
23643 ((row)->glyphs[area][START].u.cmp.id)); \
23644 s = alloca (sizeof *s); \
23645 char2b = alloca (LGSTRING_GLYPH_LEN (gstring) * sizeof *char2b); \
23646 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
23647 append_glyph_string (&(HEAD), &(TAIL), s); \
23649 START = fill_gstring_glyph_string (s, face_id, START, END, overlaps); \
23653 /* Add a glyph string for a sequence of glyphless character's glyphs
23654 to the list of strings between HEAD and TAIL. The meanings of
23655 arguments are the same as those of BUILD_CHAR_GLYPH_STRINGS. */
23657 #define BUILD_GLYPHLESS_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23662 face_id = (row)->glyphs[area][START].face_id; \
23664 s = alloca (sizeof *s); \
23665 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
23666 append_glyph_string (&HEAD, &TAIL, s); \
23668 START = fill_glyphless_glyph_string (s, face_id, START, END, \
23674 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
23675 of AREA of glyph row ROW on window W between indices START and END.
23676 HL overrides the face for drawing glyph strings, e.g. it is
23677 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
23678 x-positions of the drawing area.
23680 This is an ugly monster macro construct because we must use alloca
23681 to allocate glyph strings (because draw_glyphs can be called
23682 asynchronously). */
23684 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
23687 HEAD = TAIL = NULL; \
23688 while (START < END) \
23690 struct glyph *first_glyph = (row)->glyphs[area] + START; \
23691 switch (first_glyph->type) \
23694 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
23698 case COMPOSITE_GLYPH: \
23699 if (first_glyph->u.cmp.automatic) \
23700 BUILD_GSTRING_GLYPH_STRING (START, END, HEAD, TAIL, \
23703 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
23707 case STRETCH_GLYPH: \
23708 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
23712 case IMAGE_GLYPH: \
23713 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
23717 case GLYPHLESS_GLYPH: \
23718 BUILD_GLYPHLESS_GLYPH_STRING (START, END, HEAD, TAIL, \
23728 set_glyph_string_background_width (s, START, LAST_X); \
23735 /* Draw glyphs between START and END in AREA of ROW on window W,
23736 starting at x-position X. X is relative to AREA in W. HL is a
23737 face-override with the following meaning:
23739 DRAW_NORMAL_TEXT draw normally
23740 DRAW_CURSOR draw in cursor face
23741 DRAW_MOUSE_FACE draw in mouse face.
23742 DRAW_INVERSE_VIDEO draw in mode line face
23743 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
23744 DRAW_IMAGE_RAISED draw an image with a raised relief around it
23746 If OVERLAPS is non-zero, draw only the foreground of characters and
23747 clip to the physical height of ROW. Non-zero value also defines
23748 the overlapping part to be drawn:
23750 OVERLAPS_PRED overlap with preceding rows
23751 OVERLAPS_SUCC overlap with succeeding rows
23752 OVERLAPS_BOTH overlap with both preceding/succeeding rows
23753 OVERLAPS_ERASED_CURSOR overlap with erased cursor area
23755 Value is the x-position reached, relative to AREA of W. */
23758 draw_glyphs (struct window
*w
, int x
, struct glyph_row
*row
,
23759 enum glyph_row_area area
, ptrdiff_t start
, ptrdiff_t end
,
23760 enum draw_glyphs_face hl
, int overlaps
)
23762 struct glyph_string
*head
, *tail
;
23763 struct glyph_string
*s
;
23764 struct glyph_string
*clip_head
= NULL
, *clip_tail
= NULL
;
23765 int i
, j
, x_reached
, last_x
, area_left
= 0;
23766 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
23769 ALLOCATE_HDC (hdc
, f
);
23771 /* Let's rather be paranoid than getting a SEGV. */
23772 end
= min (end
, row
->used
[area
]);
23773 start
= clip_to_bounds (0, start
, end
);
23775 /* Translate X to frame coordinates. Set last_x to the right
23776 end of the drawing area. */
23777 if (row
->full_width_p
)
23779 /* X is relative to the left edge of W, without scroll bars
23781 area_left
= WINDOW_LEFT_EDGE_X (w
);
23782 last_x
= WINDOW_LEFT_EDGE_X (w
) + WINDOW_TOTAL_WIDTH (w
);
23786 area_left
= window_box_left (w
, area
);
23787 last_x
= area_left
+ window_box_width (w
, area
);
23791 /* Build a doubly-linked list of glyph_string structures between
23792 head and tail from what we have to draw. Note that the macro
23793 BUILD_GLYPH_STRINGS will modify its start parameter. That's
23794 the reason we use a separate variable `i'. */
23796 BUILD_GLYPH_STRINGS (i
, end
, head
, tail
, hl
, x
, last_x
);
23798 x_reached
= tail
->x
+ tail
->background_width
;
23802 /* If there are any glyphs with lbearing < 0 or rbearing > width in
23803 the row, redraw some glyphs in front or following the glyph
23804 strings built above. */
23805 if (head
&& !overlaps
&& row
->contains_overlapping_glyphs_p
)
23807 struct glyph_string
*h
, *t
;
23808 Mouse_HLInfo
*hlinfo
= MOUSE_HL_INFO (f
);
23809 int mouse_beg_col
IF_LINT (= 0), mouse_end_col
IF_LINT (= 0);
23810 int check_mouse_face
= 0;
23813 /* If mouse highlighting is on, we may need to draw adjacent
23814 glyphs using mouse-face highlighting. */
23815 if (area
== TEXT_AREA
&& row
->mouse_face_p
23816 && hlinfo
->mouse_face_beg_row
>= 0
23817 && hlinfo
->mouse_face_end_row
>= 0)
23819 ptrdiff_t row_vpos
= MATRIX_ROW_VPOS (row
, w
->current_matrix
);
23821 if (row_vpos
>= hlinfo
->mouse_face_beg_row
23822 && row_vpos
<= hlinfo
->mouse_face_end_row
)
23824 check_mouse_face
= 1;
23825 mouse_beg_col
= (row_vpos
== hlinfo
->mouse_face_beg_row
)
23826 ? hlinfo
->mouse_face_beg_col
: 0;
23827 mouse_end_col
= (row_vpos
== hlinfo
->mouse_face_end_row
)
23828 ? hlinfo
->mouse_face_end_col
23829 : row
->used
[TEXT_AREA
];
23833 /* Compute overhangs for all glyph strings. */
23834 if (FRAME_RIF (f
)->compute_glyph_string_overhangs
)
23835 for (s
= head
; s
; s
= s
->next
)
23836 FRAME_RIF (f
)->compute_glyph_string_overhangs (s
);
23838 /* Prepend glyph strings for glyphs in front of the first glyph
23839 string that are overwritten because of the first glyph
23840 string's left overhang. The background of all strings
23841 prepended must be drawn because the first glyph string
23843 i
= left_overwritten (head
);
23846 enum draw_glyphs_face overlap_hl
;
23848 /* If this row contains mouse highlighting, attempt to draw
23849 the overlapped glyphs with the correct highlight. This
23850 code fails if the overlap encompasses more than one glyph
23851 and mouse-highlight spans only some of these glyphs.
23852 However, making it work perfectly involves a lot more
23853 code, and I don't know if the pathological case occurs in
23854 practice, so we'll stick to this for now. --- cyd */
23855 if (check_mouse_face
23856 && mouse_beg_col
< start
&& mouse_end_col
> i
)
23857 overlap_hl
= DRAW_MOUSE_FACE
;
23859 overlap_hl
= DRAW_NORMAL_TEXT
;
23862 BUILD_GLYPH_STRINGS (j
, start
, h
, t
,
23863 overlap_hl
, dummy_x
, last_x
);
23865 compute_overhangs_and_x (t
, head
->x
, 1);
23866 prepend_glyph_string_lists (&head
, &tail
, h
, t
);
23870 /* Prepend glyph strings for glyphs in front of the first glyph
23871 string that overwrite that glyph string because of their
23872 right overhang. For these strings, only the foreground must
23873 be drawn, because it draws over the glyph string at `head'.
23874 The background must not be drawn because this would overwrite
23875 right overhangs of preceding glyphs for which no glyph
23877 i
= left_overwriting (head
);
23880 enum draw_glyphs_face overlap_hl
;
23882 if (check_mouse_face
23883 && mouse_beg_col
< start
&& mouse_end_col
> i
)
23884 overlap_hl
= DRAW_MOUSE_FACE
;
23886 overlap_hl
= DRAW_NORMAL_TEXT
;
23889 BUILD_GLYPH_STRINGS (i
, start
, h
, t
,
23890 overlap_hl
, dummy_x
, last_x
);
23891 for (s
= h
; s
; s
= s
->next
)
23892 s
->background_filled_p
= 1;
23893 compute_overhangs_and_x (t
, head
->x
, 1);
23894 prepend_glyph_string_lists (&head
, &tail
, h
, t
);
23897 /* Append glyphs strings for glyphs following the last glyph
23898 string tail that are overwritten by tail. The background of
23899 these strings has to be drawn because tail's foreground draws
23901 i
= right_overwritten (tail
);
23904 enum draw_glyphs_face overlap_hl
;
23906 if (check_mouse_face
23907 && mouse_beg_col
< i
&& mouse_end_col
> end
)
23908 overlap_hl
= DRAW_MOUSE_FACE
;
23910 overlap_hl
= DRAW_NORMAL_TEXT
;
23912 BUILD_GLYPH_STRINGS (end
, i
, h
, t
,
23913 overlap_hl
, x
, last_x
);
23914 /* Because BUILD_GLYPH_STRINGS updates the first argument,
23915 we don't have `end = i;' here. */
23916 compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
23917 append_glyph_string_lists (&head
, &tail
, h
, t
);
23921 /* Append glyph strings for glyphs following the last glyph
23922 string tail that overwrite tail. The foreground of such
23923 glyphs has to be drawn because it writes into the background
23924 of tail. The background must not be drawn because it could
23925 paint over the foreground of following glyphs. */
23926 i
= right_overwriting (tail
);
23929 enum draw_glyphs_face overlap_hl
;
23930 if (check_mouse_face
23931 && mouse_beg_col
< i
&& mouse_end_col
> end
)
23932 overlap_hl
= DRAW_MOUSE_FACE
;
23934 overlap_hl
= DRAW_NORMAL_TEXT
;
23937 i
++; /* We must include the Ith glyph. */
23938 BUILD_GLYPH_STRINGS (end
, i
, h
, t
,
23939 overlap_hl
, x
, last_x
);
23940 for (s
= h
; s
; s
= s
->next
)
23941 s
->background_filled_p
= 1;
23942 compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
23943 append_glyph_string_lists (&head
, &tail
, h
, t
);
23945 if (clip_head
|| clip_tail
)
23946 for (s
= head
; s
; s
= s
->next
)
23948 s
->clip_head
= clip_head
;
23949 s
->clip_tail
= clip_tail
;
23953 /* Draw all strings. */
23954 for (s
= head
; s
; s
= s
->next
)
23955 FRAME_RIF (f
)->draw_glyph_string (s
);
23958 /* When focus a sole frame and move horizontally, this sets on_p to 0
23959 causing a failure to erase prev cursor position. */
23960 if (area
== TEXT_AREA
23961 && !row
->full_width_p
23962 /* When drawing overlapping rows, only the glyph strings'
23963 foreground is drawn, which doesn't erase a cursor
23967 int x0
= clip_head
? clip_head
->x
: (head
? head
->x
: x
);
23968 int x1
= (clip_tail
? clip_tail
->x
+ clip_tail
->background_width
23969 : (tail
? tail
->x
+ tail
->background_width
: x
));
23973 notice_overwritten_cursor (w
, TEXT_AREA
, x0
, x1
,
23974 row
->y
, MATRIX_ROW_BOTTOM_Y (row
));
23978 /* Value is the x-position up to which drawn, relative to AREA of W.
23979 This doesn't include parts drawn because of overhangs. */
23980 if (row
->full_width_p
)
23981 x_reached
= FRAME_TO_WINDOW_PIXEL_X (w
, x_reached
);
23983 x_reached
-= area_left
;
23985 RELEASE_HDC (hdc
, f
);
23990 /* Expand row matrix if too narrow. Don't expand if area
23993 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
23995 if (!it->f->fonts_changed \
23996 && (it->glyph_row->glyphs[area] \
23997 < it->glyph_row->glyphs[area + 1])) \
23999 it->w->ncols_scale_factor++; \
24000 it->f->fonts_changed = 1; \
24004 /* Store one glyph for IT->char_to_display in IT->glyph_row.
24005 Called from x_produce_glyphs when IT->glyph_row is non-null. */
24008 append_glyph (struct it
*it
)
24010 struct glyph
*glyph
;
24011 enum glyph_row_area area
= it
->area
;
24013 eassert (it
->glyph_row
);
24014 eassert (it
->char_to_display
!= '\n' && it
->char_to_display
!= '\t');
24016 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
24017 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
24019 /* If the glyph row is reversed, we need to prepend the glyph
24020 rather than append it. */
24021 if (it
->glyph_row
->reversed_p
&& area
== TEXT_AREA
)
24025 /* Make room for the additional glyph. */
24026 for (g
= glyph
- 1; g
>= it
->glyph_row
->glyphs
[area
]; g
--)
24028 glyph
= it
->glyph_row
->glyphs
[area
];
24030 glyph
->charpos
= CHARPOS (it
->position
);
24031 glyph
->object
= it
->object
;
24032 if (it
->pixel_width
> 0)
24034 glyph
->pixel_width
= it
->pixel_width
;
24035 glyph
->padding_p
= 0;
24039 /* Assure at least 1-pixel width. Otherwise, cursor can't
24040 be displayed correctly. */
24041 glyph
->pixel_width
= 1;
24042 glyph
->padding_p
= 1;
24044 glyph
->ascent
= it
->ascent
;
24045 glyph
->descent
= it
->descent
;
24046 glyph
->voffset
= it
->voffset
;
24047 glyph
->type
= CHAR_GLYPH
;
24048 glyph
->avoid_cursor_p
= it
->avoid_cursor_p
;
24049 glyph
->multibyte_p
= it
->multibyte_p
;
24050 if (it
->glyph_row
->reversed_p
&& area
== TEXT_AREA
)
24052 /* In R2L rows, the left and the right box edges need to be
24053 drawn in reverse direction. */
24054 glyph
->right_box_line_p
= it
->start_of_box_run_p
;
24055 glyph
->left_box_line_p
= it
->end_of_box_run_p
;
24059 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
24060 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
24062 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
24063 || it
->phys_descent
> it
->descent
);
24064 glyph
->glyph_not_available_p
= it
->glyph_not_available_p
;
24065 glyph
->face_id
= it
->face_id
;
24066 glyph
->u
.ch
= it
->char_to_display
;
24067 glyph
->slice
.img
= null_glyph_slice
;
24068 glyph
->font_type
= FONT_TYPE_UNKNOWN
;
24071 glyph
->resolved_level
= it
->bidi_it
.resolved_level
;
24072 if ((it
->bidi_it
.type
& 7) != it
->bidi_it
.type
)
24074 glyph
->bidi_type
= it
->bidi_it
.type
;
24078 glyph
->resolved_level
= 0;
24079 glyph
->bidi_type
= UNKNOWN_BT
;
24081 ++it
->glyph_row
->used
[area
];
24084 IT_EXPAND_MATRIX_WIDTH (it
, area
);
24087 /* Store one glyph for the composition IT->cmp_it.id in
24088 IT->glyph_row. Called from x_produce_glyphs when IT->glyph_row is
24092 append_composite_glyph (struct it
*it
)
24094 struct glyph
*glyph
;
24095 enum glyph_row_area area
= it
->area
;
24097 eassert (it
->glyph_row
);
24099 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
24100 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
24102 /* If the glyph row is reversed, we need to prepend the glyph
24103 rather than append it. */
24104 if (it
->glyph_row
->reversed_p
&& it
->area
== TEXT_AREA
)
24108 /* Make room for the new glyph. */
24109 for (g
= glyph
- 1; g
>= it
->glyph_row
->glyphs
[it
->area
]; g
--)
24111 glyph
= it
->glyph_row
->glyphs
[it
->area
];
24113 glyph
->charpos
= it
->cmp_it
.charpos
;
24114 glyph
->object
= it
->object
;
24115 glyph
->pixel_width
= it
->pixel_width
;
24116 glyph
->ascent
= it
->ascent
;
24117 glyph
->descent
= it
->descent
;
24118 glyph
->voffset
= it
->voffset
;
24119 glyph
->type
= COMPOSITE_GLYPH
;
24120 if (it
->cmp_it
.ch
< 0)
24122 glyph
->u
.cmp
.automatic
= 0;
24123 glyph
->u
.cmp
.id
= it
->cmp_it
.id
;
24124 glyph
->slice
.cmp
.from
= glyph
->slice
.cmp
.to
= 0;
24128 glyph
->u
.cmp
.automatic
= 1;
24129 glyph
->u
.cmp
.id
= it
->cmp_it
.id
;
24130 glyph
->slice
.cmp
.from
= it
->cmp_it
.from
;
24131 glyph
->slice
.cmp
.to
= it
->cmp_it
.to
- 1;
24133 glyph
->avoid_cursor_p
= it
->avoid_cursor_p
;
24134 glyph
->multibyte_p
= it
->multibyte_p
;
24135 if (it
->glyph_row
->reversed_p
&& area
== TEXT_AREA
)
24137 /* In R2L rows, the left and the right box edges need to be
24138 drawn in reverse direction. */
24139 glyph
->right_box_line_p
= it
->start_of_box_run_p
;
24140 glyph
->left_box_line_p
= it
->end_of_box_run_p
;
24144 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
24145 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
24147 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
24148 || it
->phys_descent
> it
->descent
);
24149 glyph
->padding_p
= 0;
24150 glyph
->glyph_not_available_p
= 0;
24151 glyph
->face_id
= it
->face_id
;
24152 glyph
->font_type
= FONT_TYPE_UNKNOWN
;
24155 glyph
->resolved_level
= it
->bidi_it
.resolved_level
;
24156 if ((it
->bidi_it
.type
& 7) != it
->bidi_it
.type
)
24158 glyph
->bidi_type
= it
->bidi_it
.type
;
24160 ++it
->glyph_row
->used
[area
];
24163 IT_EXPAND_MATRIX_WIDTH (it
, area
);
24167 /* Change IT->ascent and IT->height according to the setting of
24171 take_vertical_position_into_account (struct it
*it
)
24175 if (it
->voffset
< 0)
24176 /* Increase the ascent so that we can display the text higher
24178 it
->ascent
-= it
->voffset
;
24180 /* Increase the descent so that we can display the text lower
24182 it
->descent
+= it
->voffset
;
24187 /* Produce glyphs/get display metrics for the image IT is loaded with.
24188 See the description of struct display_iterator in dispextern.h for
24189 an overview of struct display_iterator. */
24192 produce_image_glyph (struct it
*it
)
24196 int glyph_ascent
, crop
;
24197 struct glyph_slice slice
;
24199 eassert (it
->what
== IT_IMAGE
);
24201 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
24203 /* Make sure X resources of the face is loaded. */
24204 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
24206 if (it
->image_id
< 0)
24208 /* Fringe bitmap. */
24209 it
->ascent
= it
->phys_ascent
= 0;
24210 it
->descent
= it
->phys_descent
= 0;
24211 it
->pixel_width
= 0;
24216 img
= IMAGE_FROM_ID (it
->f
, it
->image_id
);
24218 /* Make sure X resources of the image is loaded. */
24219 prepare_image_for_display (it
->f
, img
);
24221 slice
.x
= slice
.y
= 0;
24222 slice
.width
= img
->width
;
24223 slice
.height
= img
->height
;
24225 if (INTEGERP (it
->slice
.x
))
24226 slice
.x
= XINT (it
->slice
.x
);
24227 else if (FLOATP (it
->slice
.x
))
24228 slice
.x
= XFLOAT_DATA (it
->slice
.x
) * img
->width
;
24230 if (INTEGERP (it
->slice
.y
))
24231 slice
.y
= XINT (it
->slice
.y
);
24232 else if (FLOATP (it
->slice
.y
))
24233 slice
.y
= XFLOAT_DATA (it
->slice
.y
) * img
->height
;
24235 if (INTEGERP (it
->slice
.width
))
24236 slice
.width
= XINT (it
->slice
.width
);
24237 else if (FLOATP (it
->slice
.width
))
24238 slice
.width
= XFLOAT_DATA (it
->slice
.width
) * img
->width
;
24240 if (INTEGERP (it
->slice
.height
))
24241 slice
.height
= XINT (it
->slice
.height
);
24242 else if (FLOATP (it
->slice
.height
))
24243 slice
.height
= XFLOAT_DATA (it
->slice
.height
) * img
->height
;
24245 if (slice
.x
>= img
->width
)
24246 slice
.x
= img
->width
;
24247 if (slice
.y
>= img
->height
)
24248 slice
.y
= img
->height
;
24249 if (slice
.x
+ slice
.width
>= img
->width
)
24250 slice
.width
= img
->width
- slice
.x
;
24251 if (slice
.y
+ slice
.height
> img
->height
)
24252 slice
.height
= img
->height
- slice
.y
;
24254 if (slice
.width
== 0 || slice
.height
== 0)
24257 it
->ascent
= it
->phys_ascent
= glyph_ascent
= image_ascent (img
, face
, &slice
);
24259 it
->descent
= slice
.height
- glyph_ascent
;
24261 it
->descent
+= img
->vmargin
;
24262 if (slice
.y
+ slice
.height
== img
->height
)
24263 it
->descent
+= img
->vmargin
;
24264 it
->phys_descent
= it
->descent
;
24266 it
->pixel_width
= slice
.width
;
24268 it
->pixel_width
+= img
->hmargin
;
24269 if (slice
.x
+ slice
.width
== img
->width
)
24270 it
->pixel_width
+= img
->hmargin
;
24272 /* It's quite possible for images to have an ascent greater than
24273 their height, so don't get confused in that case. */
24274 if (it
->descent
< 0)
24279 if (face
->box
!= FACE_NO_BOX
)
24281 if (face
->box_line_width
> 0)
24284 it
->ascent
+= face
->box_line_width
;
24285 if (slice
.y
+ slice
.height
== img
->height
)
24286 it
->descent
+= face
->box_line_width
;
24289 if (it
->start_of_box_run_p
&& slice
.x
== 0)
24290 it
->pixel_width
+= eabs (face
->box_line_width
);
24291 if (it
->end_of_box_run_p
&& slice
.x
+ slice
.width
== img
->width
)
24292 it
->pixel_width
+= eabs (face
->box_line_width
);
24295 take_vertical_position_into_account (it
);
24297 /* Automatically crop wide image glyphs at right edge so we can
24298 draw the cursor on same display row. */
24299 if ((crop
= it
->pixel_width
- (it
->last_visible_x
- it
->current_x
), crop
> 0)
24300 && (it
->hpos
== 0 || it
->pixel_width
> it
->last_visible_x
/ 4))
24302 it
->pixel_width
-= crop
;
24303 slice
.width
-= crop
;
24308 struct glyph
*glyph
;
24309 enum glyph_row_area area
= it
->area
;
24311 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
24312 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
24314 glyph
->charpos
= CHARPOS (it
->position
);
24315 glyph
->object
= it
->object
;
24316 glyph
->pixel_width
= it
->pixel_width
;
24317 glyph
->ascent
= glyph_ascent
;
24318 glyph
->descent
= it
->descent
;
24319 glyph
->voffset
= it
->voffset
;
24320 glyph
->type
= IMAGE_GLYPH
;
24321 glyph
->avoid_cursor_p
= it
->avoid_cursor_p
;
24322 glyph
->multibyte_p
= it
->multibyte_p
;
24323 if (it
->glyph_row
->reversed_p
&& area
== TEXT_AREA
)
24325 /* In R2L rows, the left and the right box edges need to be
24326 drawn in reverse direction. */
24327 glyph
->right_box_line_p
= it
->start_of_box_run_p
;
24328 glyph
->left_box_line_p
= it
->end_of_box_run_p
;
24332 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
24333 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
24335 glyph
->overlaps_vertically_p
= 0;
24336 glyph
->padding_p
= 0;
24337 glyph
->glyph_not_available_p
= 0;
24338 glyph
->face_id
= it
->face_id
;
24339 glyph
->u
.img_id
= img
->id
;
24340 glyph
->slice
.img
= slice
;
24341 glyph
->font_type
= FONT_TYPE_UNKNOWN
;
24344 glyph
->resolved_level
= it
->bidi_it
.resolved_level
;
24345 if ((it
->bidi_it
.type
& 7) != it
->bidi_it
.type
)
24347 glyph
->bidi_type
= it
->bidi_it
.type
;
24349 ++it
->glyph_row
->used
[area
];
24352 IT_EXPAND_MATRIX_WIDTH (it
, area
);
24357 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
24358 of the glyph, WIDTH and HEIGHT are the width and height of the
24359 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
24362 append_stretch_glyph (struct it
*it
, Lisp_Object object
,
24363 int width
, int height
, int ascent
)
24365 struct glyph
*glyph
;
24366 enum glyph_row_area area
= it
->area
;
24368 eassert (ascent
>= 0 && ascent
<= height
);
24370 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
24371 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
24373 /* If the glyph row is reversed, we need to prepend the glyph
24374 rather than append it. */
24375 if (it
->glyph_row
->reversed_p
&& area
== TEXT_AREA
)
24379 /* Make room for the additional glyph. */
24380 for (g
= glyph
- 1; g
>= it
->glyph_row
->glyphs
[area
]; g
--)
24382 glyph
= it
->glyph_row
->glyphs
[area
];
24384 glyph
->charpos
= CHARPOS (it
->position
);
24385 glyph
->object
= object
;
24386 glyph
->pixel_width
= width
;
24387 glyph
->ascent
= ascent
;
24388 glyph
->descent
= height
- ascent
;
24389 glyph
->voffset
= it
->voffset
;
24390 glyph
->type
= STRETCH_GLYPH
;
24391 glyph
->avoid_cursor_p
= it
->avoid_cursor_p
;
24392 glyph
->multibyte_p
= it
->multibyte_p
;
24393 if (it
->glyph_row
->reversed_p
&& area
== TEXT_AREA
)
24395 /* In R2L rows, the left and the right box edges need to be
24396 drawn in reverse direction. */
24397 glyph
->right_box_line_p
= it
->start_of_box_run_p
;
24398 glyph
->left_box_line_p
= it
->end_of_box_run_p
;
24402 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
24403 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
24405 glyph
->overlaps_vertically_p
= 0;
24406 glyph
->padding_p
= 0;
24407 glyph
->glyph_not_available_p
= 0;
24408 glyph
->face_id
= it
->face_id
;
24409 glyph
->u
.stretch
.ascent
= ascent
;
24410 glyph
->u
.stretch
.height
= height
;
24411 glyph
->slice
.img
= null_glyph_slice
;
24412 glyph
->font_type
= FONT_TYPE_UNKNOWN
;
24415 glyph
->resolved_level
= it
->bidi_it
.resolved_level
;
24416 if ((it
->bidi_it
.type
& 7) != it
->bidi_it
.type
)
24418 glyph
->bidi_type
= it
->bidi_it
.type
;
24422 glyph
->resolved_level
= 0;
24423 glyph
->bidi_type
= UNKNOWN_BT
;
24425 ++it
->glyph_row
->used
[area
];
24428 IT_EXPAND_MATRIX_WIDTH (it
, area
);
24431 #endif /* HAVE_WINDOW_SYSTEM */
24433 /* Produce a stretch glyph for iterator IT. IT->object is the value
24434 of the glyph property displayed. The value must be a list
24435 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
24438 1. `:width WIDTH' specifies that the space should be WIDTH *
24439 canonical char width wide. WIDTH may be an integer or floating
24442 2. `:relative-width FACTOR' specifies that the width of the stretch
24443 should be computed from the width of the first character having the
24444 `glyph' property, and should be FACTOR times that width.
24446 3. `:align-to HPOS' specifies that the space should be wide enough
24447 to reach HPOS, a value in canonical character units.
24449 Exactly one of the above pairs must be present.
24451 4. `:height HEIGHT' specifies that the height of the stretch produced
24452 should be HEIGHT, measured in canonical character units.
24454 5. `:relative-height FACTOR' specifies that the height of the
24455 stretch should be FACTOR times the height of the characters having
24456 the glyph property.
24458 Either none or exactly one of 4 or 5 must be present.
24460 6. `:ascent ASCENT' specifies that ASCENT percent of the height
24461 of the stretch should be used for the ascent of the stretch.
24462 ASCENT must be in the range 0 <= ASCENT <= 100. */
24465 produce_stretch_glyph (struct it
*it
)
24467 /* (space :width WIDTH :height HEIGHT ...) */
24468 Lisp_Object prop
, plist
;
24469 int width
= 0, height
= 0, align_to
= -1;
24470 int zero_width_ok_p
= 0;
24472 struct font
*font
= NULL
;
24474 #ifdef HAVE_WINDOW_SYSTEM
24476 int zero_height_ok_p
= 0;
24478 if (FRAME_WINDOW_P (it
->f
))
24480 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
24481 font
= face
->font
? face
->font
: FRAME_FONT (it
->f
);
24482 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
24486 /* List should start with `space'. */
24487 eassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
24488 plist
= XCDR (it
->object
);
24490 /* Compute the width of the stretch. */
24491 if ((prop
= Fplist_get (plist
, QCwidth
), !NILP (prop
))
24492 && calc_pixel_width_or_height (&tem
, it
, prop
, font
, 1, 0))
24494 /* Absolute width `:width WIDTH' specified and valid. */
24495 zero_width_ok_p
= 1;
24498 #ifdef HAVE_WINDOW_SYSTEM
24499 else if (FRAME_WINDOW_P (it
->f
)
24500 && (prop
= Fplist_get (plist
, QCrelative_width
), NUMVAL (prop
) > 0))
24502 /* Relative width `:relative-width FACTOR' specified and valid.
24503 Compute the width of the characters having the `glyph'
24506 unsigned char *p
= BYTE_POS_ADDR (IT_BYTEPOS (*it
));
24509 if (it
->multibyte_p
)
24510 it2
.c
= it2
.char_to_display
= STRING_CHAR_AND_LENGTH (p
, it2
.len
);
24513 it2
.c
= it2
.char_to_display
= *p
, it2
.len
= 1;
24514 if (! ASCII_CHAR_P (it2
.c
))
24515 it2
.char_to_display
= BYTE8_TO_CHAR (it2
.c
);
24518 it2
.glyph_row
= NULL
;
24519 it2
.what
= IT_CHARACTER
;
24520 x_produce_glyphs (&it2
);
24521 width
= NUMVAL (prop
) * it2
.pixel_width
;
24523 #endif /* HAVE_WINDOW_SYSTEM */
24524 else if ((prop
= Fplist_get (plist
, QCalign_to
), !NILP (prop
))
24525 && calc_pixel_width_or_height (&tem
, it
, prop
, font
, 1, &align_to
))
24527 if (it
->glyph_row
== NULL
|| !it
->glyph_row
->mode_line_p
)
24528 align_to
= (align_to
< 0
24530 : align_to
- window_box_left_offset (it
->w
, TEXT_AREA
));
24531 else if (align_to
< 0)
24532 align_to
= window_box_left_offset (it
->w
, TEXT_AREA
);
24533 width
= max (0, (int)tem
+ align_to
- it
->current_x
);
24534 zero_width_ok_p
= 1;
24537 /* Nothing specified -> width defaults to canonical char width. */
24538 width
= FRAME_COLUMN_WIDTH (it
->f
);
24540 if (width
<= 0 && (width
< 0 || !zero_width_ok_p
))
24543 #ifdef HAVE_WINDOW_SYSTEM
24544 /* Compute height. */
24545 if (FRAME_WINDOW_P (it
->f
))
24547 if ((prop
= Fplist_get (plist
, QCheight
), !NILP (prop
))
24548 && calc_pixel_width_or_height (&tem
, it
, prop
, font
, 0, 0))
24551 zero_height_ok_p
= 1;
24553 else if (prop
= Fplist_get (plist
, QCrelative_height
),
24555 height
= FONT_HEIGHT (font
) * NUMVAL (prop
);
24557 height
= FONT_HEIGHT (font
);
24559 if (height
<= 0 && (height
< 0 || !zero_height_ok_p
))
24562 /* Compute percentage of height used for ascent. If
24563 `:ascent ASCENT' is present and valid, use that. Otherwise,
24564 derive the ascent from the font in use. */
24565 if (prop
= Fplist_get (plist
, QCascent
),
24566 NUMVAL (prop
) > 0 && NUMVAL (prop
) <= 100)
24567 ascent
= height
* NUMVAL (prop
) / 100.0;
24568 else if (!NILP (prop
)
24569 && calc_pixel_width_or_height (&tem
, it
, prop
, font
, 0, 0))
24570 ascent
= min (max (0, (int)tem
), height
);
24572 ascent
= (height
* FONT_BASE (font
)) / FONT_HEIGHT (font
);
24575 #endif /* HAVE_WINDOW_SYSTEM */
24578 if (width
> 0 && it
->line_wrap
!= TRUNCATE
24579 && it
->current_x
+ width
> it
->last_visible_x
)
24581 width
= it
->last_visible_x
- it
->current_x
;
24582 #ifdef HAVE_WINDOW_SYSTEM
24583 /* Subtract one more pixel from the stretch width, but only on
24584 GUI frames, since on a TTY each glyph is one "pixel" wide. */
24585 width
-= FRAME_WINDOW_P (it
->f
);
24589 if (width
> 0 && height
> 0 && it
->glyph_row
)
24591 Lisp_Object o_object
= it
->object
;
24592 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
24595 if (!STRINGP (object
))
24596 object
= it
->w
->contents
;
24597 #ifdef HAVE_WINDOW_SYSTEM
24598 if (FRAME_WINDOW_P (it
->f
))
24599 append_stretch_glyph (it
, object
, width
, height
, ascent
);
24603 it
->object
= object
;
24604 it
->char_to_display
= ' ';
24605 it
->pixel_width
= it
->len
= 1;
24607 tty_append_glyph (it
);
24608 it
->object
= o_object
;
24612 it
->pixel_width
= width
;
24613 #ifdef HAVE_WINDOW_SYSTEM
24614 if (FRAME_WINDOW_P (it
->f
))
24616 it
->ascent
= it
->phys_ascent
= ascent
;
24617 it
->descent
= it
->phys_descent
= height
- it
->ascent
;
24618 it
->nglyphs
= width
> 0 && height
> 0 ? 1 : 0;
24619 take_vertical_position_into_account (it
);
24623 it
->nglyphs
= width
;
24626 /* Get information about special display element WHAT in an
24627 environment described by IT. WHAT is one of IT_TRUNCATION or
24628 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
24629 non-null glyph_row member. This function ensures that fields like
24630 face_id, c, len of IT are left untouched. */
24633 produce_special_glyphs (struct it
*it
, enum display_element_type what
)
24640 temp_it
.object
= make_number (0);
24641 memset (&temp_it
.current
, 0, sizeof temp_it
.current
);
24643 if (what
== IT_CONTINUATION
)
24645 /* Continuation glyph. For R2L lines, we mirror it by hand. */
24646 if (it
->bidi_it
.paragraph_dir
== R2L
)
24647 SET_GLYPH_FROM_CHAR (glyph
, '/');
24649 SET_GLYPH_FROM_CHAR (glyph
, '\\');
24651 && (gc
= DISP_CONTINUE_GLYPH (it
->dp
), GLYPH_CODE_P (gc
)))
24653 /* FIXME: Should we mirror GC for R2L lines? */
24654 SET_GLYPH_FROM_GLYPH_CODE (glyph
, gc
);
24655 spec_glyph_lookup_face (XWINDOW (it
->window
), &glyph
);
24658 else if (what
== IT_TRUNCATION
)
24660 /* Truncation glyph. */
24661 SET_GLYPH_FROM_CHAR (glyph
, '$');
24663 && (gc
= DISP_TRUNC_GLYPH (it
->dp
), GLYPH_CODE_P (gc
)))
24665 /* FIXME: Should we mirror GC for R2L lines? */
24666 SET_GLYPH_FROM_GLYPH_CODE (glyph
, gc
);
24667 spec_glyph_lookup_face (XWINDOW (it
->window
), &glyph
);
24673 #ifdef HAVE_WINDOW_SYSTEM
24674 /* On a GUI frame, when the right fringe (left fringe for R2L rows)
24675 is turned off, we precede the truncation/continuation glyphs by a
24676 stretch glyph whose width is computed such that these special
24677 glyphs are aligned at the window margin, even when very different
24678 fonts are used in different glyph rows. */
24679 if (FRAME_WINDOW_P (temp_it
.f
)
24680 /* init_iterator calls this with it->glyph_row == NULL, and it
24681 wants only the pixel width of the truncation/continuation
24683 && temp_it
.glyph_row
24684 /* insert_left_trunc_glyphs calls us at the beginning of the
24685 row, and it has its own calculation of the stretch glyph
24687 && temp_it
.glyph_row
->used
[TEXT_AREA
] > 0
24688 && (temp_it
.glyph_row
->reversed_p
24689 ? WINDOW_LEFT_FRINGE_WIDTH (temp_it
.w
)
24690 : WINDOW_RIGHT_FRINGE_WIDTH (temp_it
.w
)) == 0)
24692 int stretch_width
= temp_it
.last_visible_x
- temp_it
.current_x
;
24694 if (stretch_width
> 0)
24696 struct face
*face
= FACE_FROM_ID (temp_it
.f
, temp_it
.face_id
);
24697 struct font
*font
=
24698 face
->font
? face
->font
: FRAME_FONT (temp_it
.f
);
24699 int stretch_ascent
=
24700 (((temp_it
.ascent
+ temp_it
.descent
)
24701 * FONT_BASE (font
)) / FONT_HEIGHT (font
));
24703 append_stretch_glyph (&temp_it
, make_number (0), stretch_width
,
24704 temp_it
.ascent
+ temp_it
.descent
,
24711 temp_it
.what
= IT_CHARACTER
;
24713 temp_it
.c
= temp_it
.char_to_display
= GLYPH_CHAR (glyph
);
24714 temp_it
.face_id
= GLYPH_FACE (glyph
);
24715 temp_it
.len
= CHAR_BYTES (temp_it
.c
);
24717 PRODUCE_GLYPHS (&temp_it
);
24718 it
->pixel_width
= temp_it
.pixel_width
;
24719 it
->nglyphs
= temp_it
.pixel_width
;
24722 #ifdef HAVE_WINDOW_SYSTEM
24724 /* Calculate line-height and line-spacing properties.
24725 An integer value specifies explicit pixel value.
24726 A float value specifies relative value to current face height.
24727 A cons (float . face-name) specifies relative value to
24728 height of specified face font.
24730 Returns height in pixels, or nil. */
24734 calc_line_height_property (struct it
*it
, Lisp_Object val
, struct font
*font
,
24735 int boff
, int override
)
24737 Lisp_Object face_name
= Qnil
;
24738 int ascent
, descent
, height
;
24740 if (NILP (val
) || INTEGERP (val
) || (override
&& EQ (val
, Qt
)))
24745 face_name
= XCAR (val
);
24747 if (!NUMBERP (val
))
24748 val
= make_number (1);
24749 if (NILP (face_name
))
24751 height
= it
->ascent
+ it
->descent
;
24756 if (NILP (face_name
))
24758 font
= FRAME_FONT (it
->f
);
24759 boff
= FRAME_BASELINE_OFFSET (it
->f
);
24761 else if (EQ (face_name
, Qt
))
24770 face_id
= lookup_named_face (it
->f
, face_name
, 0);
24772 return make_number (-1);
24774 face
= FACE_FROM_ID (it
->f
, face_id
);
24777 return make_number (-1);
24778 boff
= font
->baseline_offset
;
24779 if (font
->vertical_centering
)
24780 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
24783 ascent
= FONT_BASE (font
) + boff
;
24784 descent
= FONT_DESCENT (font
) - boff
;
24788 it
->override_ascent
= ascent
;
24789 it
->override_descent
= descent
;
24790 it
->override_boff
= boff
;
24793 height
= ascent
+ descent
;
24797 height
= (int)(XFLOAT_DATA (val
) * height
);
24798 else if (INTEGERP (val
))
24799 height
*= XINT (val
);
24801 return make_number (height
);
24805 /* Append a glyph for a glyphless character to IT->glyph_row. FACE_ID
24806 is a face ID to be used for the glyph. FOR_NO_FONT is nonzero if
24807 and only if this is for a character for which no font was found.
24809 If the display method (it->glyphless_method) is
24810 GLYPHLESS_DISPLAY_ACRONYM or GLYPHLESS_DISPLAY_HEX_CODE, LEN is a
24811 length of the acronym or the hexadecimal string, UPPER_XOFF and
24812 UPPER_YOFF are pixel offsets for the upper part of the string,
24813 LOWER_XOFF and LOWER_YOFF are for the lower part.
24815 For the other display methods, LEN through LOWER_YOFF are zero. */
24818 append_glyphless_glyph (struct it
*it
, int face_id
, int for_no_font
, int len
,
24819 short upper_xoff
, short upper_yoff
,
24820 short lower_xoff
, short lower_yoff
)
24822 struct glyph
*glyph
;
24823 enum glyph_row_area area
= it
->area
;
24825 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
24826 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
24828 /* If the glyph row is reversed, we need to prepend the glyph
24829 rather than append it. */
24830 if (it
->glyph_row
->reversed_p
&& area
== TEXT_AREA
)
24834 /* Make room for the additional glyph. */
24835 for (g
= glyph
- 1; g
>= it
->glyph_row
->glyphs
[area
]; g
--)
24837 glyph
= it
->glyph_row
->glyphs
[area
];
24839 glyph
->charpos
= CHARPOS (it
->position
);
24840 glyph
->object
= it
->object
;
24841 glyph
->pixel_width
= it
->pixel_width
;
24842 glyph
->ascent
= it
->ascent
;
24843 glyph
->descent
= it
->descent
;
24844 glyph
->voffset
= it
->voffset
;
24845 glyph
->type
= GLYPHLESS_GLYPH
;
24846 glyph
->u
.glyphless
.method
= it
->glyphless_method
;
24847 glyph
->u
.glyphless
.for_no_font
= for_no_font
;
24848 glyph
->u
.glyphless
.len
= len
;
24849 glyph
->u
.glyphless
.ch
= it
->c
;
24850 glyph
->slice
.glyphless
.upper_xoff
= upper_xoff
;
24851 glyph
->slice
.glyphless
.upper_yoff
= upper_yoff
;
24852 glyph
->slice
.glyphless
.lower_xoff
= lower_xoff
;
24853 glyph
->slice
.glyphless
.lower_yoff
= lower_yoff
;
24854 glyph
->avoid_cursor_p
= it
->avoid_cursor_p
;
24855 glyph
->multibyte_p
= it
->multibyte_p
;
24856 if (it
->glyph_row
->reversed_p
&& area
== TEXT_AREA
)
24858 /* In R2L rows, the left and the right box edges need to be
24859 drawn in reverse direction. */
24860 glyph
->right_box_line_p
= it
->start_of_box_run_p
;
24861 glyph
->left_box_line_p
= it
->end_of_box_run_p
;
24865 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
24866 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
24868 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
24869 || it
->phys_descent
> it
->descent
);
24870 glyph
->padding_p
= 0;
24871 glyph
->glyph_not_available_p
= 0;
24872 glyph
->face_id
= face_id
;
24873 glyph
->font_type
= FONT_TYPE_UNKNOWN
;
24876 glyph
->resolved_level
= it
->bidi_it
.resolved_level
;
24877 if ((it
->bidi_it
.type
& 7) != it
->bidi_it
.type
)
24879 glyph
->bidi_type
= it
->bidi_it
.type
;
24881 ++it
->glyph_row
->used
[area
];
24884 IT_EXPAND_MATRIX_WIDTH (it
, area
);
24888 /* Produce a glyph for a glyphless character for iterator IT.
24889 IT->glyphless_method specifies which method to use for displaying
24890 the character. See the description of enum
24891 glyphless_display_method in dispextern.h for the detail.
24893 FOR_NO_FONT is nonzero if and only if this is for a character for
24894 which no font was found. ACRONYM, if non-nil, is an acronym string
24895 for the character. */
24898 produce_glyphless_glyph (struct it
*it
, int for_no_font
, Lisp_Object acronym
)
24903 int base_width
, base_height
, width
, height
;
24904 short upper_xoff
, upper_yoff
, lower_xoff
, lower_yoff
;
24907 /* Get the metrics of the base font. We always refer to the current
24909 face
= FACE_FROM_ID (it
->f
, it
->face_id
)->ascii_face
;
24910 font
= face
->font
? face
->font
: FRAME_FONT (it
->f
);
24911 it
->ascent
= FONT_BASE (font
) + font
->baseline_offset
;
24912 it
->descent
= FONT_DESCENT (font
) - font
->baseline_offset
;
24913 base_height
= it
->ascent
+ it
->descent
;
24914 base_width
= font
->average_width
;
24916 face_id
= merge_glyphless_glyph_face (it
);
24918 if (it
->glyphless_method
== GLYPHLESS_DISPLAY_THIN_SPACE
)
24920 it
->pixel_width
= THIN_SPACE_WIDTH
;
24922 upper_xoff
= upper_yoff
= lower_xoff
= lower_yoff
= 0;
24924 else if (it
->glyphless_method
== GLYPHLESS_DISPLAY_EMPTY_BOX
)
24926 width
= CHAR_WIDTH (it
->c
);
24929 else if (width
> 4)
24931 it
->pixel_width
= base_width
* width
;
24933 upper_xoff
= upper_yoff
= lower_xoff
= lower_yoff
= 0;
24939 unsigned int code
[6];
24941 int ascent
, descent
;
24942 struct font_metrics metrics_upper
, metrics_lower
;
24944 face
= FACE_FROM_ID (it
->f
, face_id
);
24945 font
= face
->font
? face
->font
: FRAME_FONT (it
->f
);
24946 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
24948 if (it
->glyphless_method
== GLYPHLESS_DISPLAY_ACRONYM
)
24950 if (! STRINGP (acronym
) && CHAR_TABLE_P (Vglyphless_char_display
))
24951 acronym
= CHAR_TABLE_REF (Vglyphless_char_display
, it
->c
);
24952 if (CONSP (acronym
))
24953 acronym
= XCAR (acronym
);
24954 str
= STRINGP (acronym
) ? SSDATA (acronym
) : "";
24958 eassert (it
->glyphless_method
== GLYPHLESS_DISPLAY_HEX_CODE
);
24959 sprintf (buf
, "%0*X", it
->c
< 0x10000 ? 4 : 6, it
->c
);
24962 for (len
= 0; str
[len
] && ASCII_BYTE_P (str
[len
]) && len
< 6; len
++)
24963 code
[len
] = font
->driver
->encode_char (font
, str
[len
]);
24964 upper_len
= (len
+ 1) / 2;
24965 font
->driver
->text_extents (font
, code
, upper_len
,
24967 font
->driver
->text_extents (font
, code
+ upper_len
, len
- upper_len
,
24972 /* +4 is for vertical bars of a box plus 1-pixel spaces at both side. */
24973 width
= max (metrics_upper
.width
, metrics_lower
.width
) + 4;
24974 upper_xoff
= upper_yoff
= 2; /* the typical case */
24975 if (base_width
>= width
)
24977 /* Align the upper to the left, the lower to the right. */
24978 it
->pixel_width
= base_width
;
24979 lower_xoff
= base_width
- 2 - metrics_lower
.width
;
24983 /* Center the shorter one. */
24984 it
->pixel_width
= width
;
24985 if (metrics_upper
.width
>= metrics_lower
.width
)
24986 lower_xoff
= (width
- metrics_lower
.width
) / 2;
24989 /* FIXME: This code doesn't look right. It formerly was
24990 missing the "lower_xoff = 0;", which couldn't have
24991 been right since it left lower_xoff uninitialized. */
24993 upper_xoff
= (width
- metrics_upper
.width
) / 2;
24997 /* +5 is for horizontal bars of a box plus 1-pixel spaces at
24998 top, bottom, and between upper and lower strings. */
24999 height
= (metrics_upper
.ascent
+ metrics_upper
.descent
25000 + metrics_lower
.ascent
+ metrics_lower
.descent
) + 5;
25001 /* Center vertically.
25002 H:base_height, D:base_descent
25003 h:height, ld:lower_descent, la:lower_ascent, ud:upper_descent
25005 ascent = - (D - H/2 - h/2 + 1); "+ 1" for rounding up
25006 descent = D - H/2 + h/2;
25007 lower_yoff = descent - 2 - ld;
25008 upper_yoff = lower_yoff - la - 1 - ud; */
25009 ascent
= - (it
->descent
- (base_height
+ height
+ 1) / 2);
25010 descent
= it
->descent
- (base_height
- height
) / 2;
25011 lower_yoff
= descent
- 2 - metrics_lower
.descent
;
25012 upper_yoff
= (lower_yoff
- metrics_lower
.ascent
- 1
25013 - metrics_upper
.descent
);
25014 /* Don't make the height shorter than the base height. */
25015 if (height
> base_height
)
25017 it
->ascent
= ascent
;
25018 it
->descent
= descent
;
25022 it
->phys_ascent
= it
->ascent
;
25023 it
->phys_descent
= it
->descent
;
25025 append_glyphless_glyph (it
, face_id
, for_no_font
, len
,
25026 upper_xoff
, upper_yoff
,
25027 lower_xoff
, lower_yoff
);
25029 take_vertical_position_into_account (it
);
25034 Produce glyphs/get display metrics for the display element IT is
25035 loaded with. See the description of struct it in dispextern.h
25036 for an overview of struct it. */
25039 x_produce_glyphs (struct it
*it
)
25041 int extra_line_spacing
= it
->extra_line_spacing
;
25043 it
->glyph_not_available_p
= 0;
25045 if (it
->what
== IT_CHARACTER
)
25048 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
25049 struct font
*font
= face
->font
;
25050 struct font_metrics
*pcm
= NULL
;
25051 int boff
; /* baseline offset */
25055 /* When no suitable font is found, display this character by
25056 the method specified in the first extra slot of
25057 Vglyphless_char_display. */
25058 Lisp_Object acronym
= lookup_glyphless_char_display (-1, it
);
25060 eassert (it
->what
== IT_GLYPHLESS
);
25061 produce_glyphless_glyph (it
, 1, STRINGP (acronym
) ? acronym
: Qnil
);
25065 boff
= font
->baseline_offset
;
25066 if (font
->vertical_centering
)
25067 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
25069 if (it
->char_to_display
!= '\n' && it
->char_to_display
!= '\t')
25075 if (it
->override_ascent
>= 0)
25077 it
->ascent
= it
->override_ascent
;
25078 it
->descent
= it
->override_descent
;
25079 boff
= it
->override_boff
;
25083 it
->ascent
= FONT_BASE (font
) + boff
;
25084 it
->descent
= FONT_DESCENT (font
) - boff
;
25087 if (get_char_glyph_code (it
->char_to_display
, font
, &char2b
))
25089 pcm
= get_per_char_metric (font
, &char2b
);
25090 if (pcm
->width
== 0
25091 && pcm
->rbearing
== 0 && pcm
->lbearing
== 0)
25097 it
->phys_ascent
= pcm
->ascent
+ boff
;
25098 it
->phys_descent
= pcm
->descent
- boff
;
25099 it
->pixel_width
= pcm
->width
;
25103 it
->glyph_not_available_p
= 1;
25104 it
->phys_ascent
= it
->ascent
;
25105 it
->phys_descent
= it
->descent
;
25106 it
->pixel_width
= font
->space_width
;
25109 if (it
->constrain_row_ascent_descent_p
)
25111 if (it
->descent
> it
->max_descent
)
25113 it
->ascent
+= it
->descent
- it
->max_descent
;
25114 it
->descent
= it
->max_descent
;
25116 if (it
->ascent
> it
->max_ascent
)
25118 it
->descent
= min (it
->max_descent
, it
->descent
+ it
->ascent
- it
->max_ascent
);
25119 it
->ascent
= it
->max_ascent
;
25121 it
->phys_ascent
= min (it
->phys_ascent
, it
->ascent
);
25122 it
->phys_descent
= min (it
->phys_descent
, it
->descent
);
25123 extra_line_spacing
= 0;
25126 /* If this is a space inside a region of text with
25127 `space-width' property, change its width. */
25128 stretched_p
= it
->char_to_display
== ' ' && !NILP (it
->space_width
);
25130 it
->pixel_width
*= XFLOATINT (it
->space_width
);
25132 /* If face has a box, add the box thickness to the character
25133 height. If character has a box line to the left and/or
25134 right, add the box line width to the character's width. */
25135 if (face
->box
!= FACE_NO_BOX
)
25137 int thick
= face
->box_line_width
;
25141 it
->ascent
+= thick
;
25142 it
->descent
+= thick
;
25147 if (it
->start_of_box_run_p
)
25148 it
->pixel_width
+= thick
;
25149 if (it
->end_of_box_run_p
)
25150 it
->pixel_width
+= thick
;
25153 /* If face has an overline, add the height of the overline
25154 (1 pixel) and a 1 pixel margin to the character height. */
25155 if (face
->overline_p
)
25156 it
->ascent
+= overline_margin
;
25158 if (it
->constrain_row_ascent_descent_p
)
25160 if (it
->ascent
> it
->max_ascent
)
25161 it
->ascent
= it
->max_ascent
;
25162 if (it
->descent
> it
->max_descent
)
25163 it
->descent
= it
->max_descent
;
25166 take_vertical_position_into_account (it
);
25168 /* If we have to actually produce glyphs, do it. */
25173 /* Translate a space with a `space-width' property
25174 into a stretch glyph. */
25175 int ascent
= (((it
->ascent
+ it
->descent
) * FONT_BASE (font
))
25176 / FONT_HEIGHT (font
));
25177 append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
25178 it
->ascent
+ it
->descent
, ascent
);
25183 /* If characters with lbearing or rbearing are displayed
25184 in this line, record that fact in a flag of the
25185 glyph row. This is used to optimize X output code. */
25186 if (pcm
&& (pcm
->lbearing
< 0 || pcm
->rbearing
> pcm
->width
))
25187 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
25189 if (! stretched_p
&& it
->pixel_width
== 0)
25190 /* We assure that all visible glyphs have at least 1-pixel
25192 it
->pixel_width
= 1;
25194 else if (it
->char_to_display
== '\n')
25196 /* A newline has no width, but we need the height of the
25197 line. But if previous part of the line sets a height,
25198 don't increase that height */
25200 Lisp_Object height
;
25201 Lisp_Object total_height
= Qnil
;
25203 it
->override_ascent
= -1;
25204 it
->pixel_width
= 0;
25207 height
= get_it_property (it
, Qline_height
);
25208 /* Split (line-height total-height) list */
25210 && CONSP (XCDR (height
))
25211 && NILP (XCDR (XCDR (height
))))
25213 total_height
= XCAR (XCDR (height
));
25214 height
= XCAR (height
);
25216 height
= calc_line_height_property (it
, height
, font
, boff
, 1);
25218 if (it
->override_ascent
>= 0)
25220 it
->ascent
= it
->override_ascent
;
25221 it
->descent
= it
->override_descent
;
25222 boff
= it
->override_boff
;
25226 it
->ascent
= FONT_BASE (font
) + boff
;
25227 it
->descent
= FONT_DESCENT (font
) - boff
;
25230 if (EQ (height
, Qt
))
25232 if (it
->descent
> it
->max_descent
)
25234 it
->ascent
+= it
->descent
- it
->max_descent
;
25235 it
->descent
= it
->max_descent
;
25237 if (it
->ascent
> it
->max_ascent
)
25239 it
->descent
= min (it
->max_descent
, it
->descent
+ it
->ascent
- it
->max_ascent
);
25240 it
->ascent
= it
->max_ascent
;
25242 it
->phys_ascent
= min (it
->phys_ascent
, it
->ascent
);
25243 it
->phys_descent
= min (it
->phys_descent
, it
->descent
);
25244 it
->constrain_row_ascent_descent_p
= 1;
25245 extra_line_spacing
= 0;
25249 Lisp_Object spacing
;
25251 it
->phys_ascent
= it
->ascent
;
25252 it
->phys_descent
= it
->descent
;
25254 if ((it
->max_ascent
> 0 || it
->max_descent
> 0)
25255 && face
->box
!= FACE_NO_BOX
25256 && face
->box_line_width
> 0)
25258 it
->ascent
+= face
->box_line_width
;
25259 it
->descent
+= face
->box_line_width
;
25262 && XINT (height
) > it
->ascent
+ it
->descent
)
25263 it
->ascent
= XINT (height
) - it
->descent
;
25265 if (!NILP (total_height
))
25266 spacing
= calc_line_height_property (it
, total_height
, font
, boff
, 0);
25269 spacing
= get_it_property (it
, Qline_spacing
);
25270 spacing
= calc_line_height_property (it
, spacing
, font
, boff
, 0);
25272 if (INTEGERP (spacing
))
25274 extra_line_spacing
= XINT (spacing
);
25275 if (!NILP (total_height
))
25276 extra_line_spacing
-= (it
->phys_ascent
+ it
->phys_descent
);
25280 else /* i.e. (it->char_to_display == '\t') */
25282 if (font
->space_width
> 0)
25284 int tab_width
= it
->tab_width
* font
->space_width
;
25285 int x
= it
->current_x
+ it
->continuation_lines_width
;
25286 int next_tab_x
= ((1 + x
+ tab_width
- 1) / tab_width
) * tab_width
;
25288 /* If the distance from the current position to the next tab
25289 stop is less than a space character width, use the
25290 tab stop after that. */
25291 if (next_tab_x
- x
< font
->space_width
)
25292 next_tab_x
+= tab_width
;
25294 it
->pixel_width
= next_tab_x
- x
;
25296 it
->ascent
= it
->phys_ascent
= FONT_BASE (font
) + boff
;
25297 it
->descent
= it
->phys_descent
= FONT_DESCENT (font
) - boff
;
25301 append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
25302 it
->ascent
+ it
->descent
, it
->ascent
);
25307 it
->pixel_width
= 0;
25312 else if (it
->what
== IT_COMPOSITION
&& it
->cmp_it
.ch
< 0)
25314 /* A static composition.
25316 Note: A composition is represented as one glyph in the
25317 glyph matrix. There are no padding glyphs.
25319 Important note: pixel_width, ascent, and descent are the
25320 values of what is drawn by draw_glyphs (i.e. the values of
25321 the overall glyphs composed). */
25322 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
25323 int boff
; /* baseline offset */
25324 struct composition
*cmp
= composition_table
[it
->cmp_it
.id
];
25325 int glyph_len
= cmp
->glyph_len
;
25326 struct font
*font
= face
->font
;
25330 /* If we have not yet calculated pixel size data of glyphs of
25331 the composition for the current face font, calculate them
25332 now. Theoretically, we have to check all fonts for the
25333 glyphs, but that requires much time and memory space. So,
25334 here we check only the font of the first glyph. This may
25335 lead to incorrect display, but it's very rare, and C-l
25336 (recenter-top-bottom) can correct the display anyway. */
25337 if (! cmp
->font
|| cmp
->font
!= font
)
25339 /* Ascent and descent of the font of the first character
25340 of this composition (adjusted by baseline offset).
25341 Ascent and descent of overall glyphs should not be less
25342 than these, respectively. */
25343 int font_ascent
, font_descent
, font_height
;
25344 /* Bounding box of the overall glyphs. */
25345 int leftmost
, rightmost
, lowest
, highest
;
25346 int lbearing
, rbearing
;
25347 int i
, width
, ascent
, descent
;
25348 int left_padded
= 0, right_padded
= 0;
25349 int c
IF_LINT (= 0); /* cmp->glyph_len can't be zero; see Bug#8512 */
25351 struct font_metrics
*pcm
;
25352 int font_not_found_p
;
25355 for (glyph_len
= cmp
->glyph_len
; glyph_len
> 0; glyph_len
--)
25356 if ((c
= COMPOSITION_GLYPH (cmp
, glyph_len
- 1)) != '\t')
25358 if (glyph_len
< cmp
->glyph_len
)
25360 for (i
= 0; i
< glyph_len
; i
++)
25362 if ((c
= COMPOSITION_GLYPH (cmp
, i
)) != '\t')
25364 cmp
->offsets
[i
* 2] = cmp
->offsets
[i
* 2 + 1] = 0;
25369 pos
= (STRINGP (it
->string
) ? IT_STRING_CHARPOS (*it
)
25370 : IT_CHARPOS (*it
));
25371 /* If no suitable font is found, use the default font. */
25372 font_not_found_p
= font
== NULL
;
25373 if (font_not_found_p
)
25375 face
= face
->ascii_face
;
25378 boff
= font
->baseline_offset
;
25379 if (font
->vertical_centering
)
25380 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
25381 font_ascent
= FONT_BASE (font
) + boff
;
25382 font_descent
= FONT_DESCENT (font
) - boff
;
25383 font_height
= FONT_HEIGHT (font
);
25388 if (! font_not_found_p
)
25390 get_char_face_and_encoding (it
->f
, c
, it
->face_id
,
25392 pcm
= get_per_char_metric (font
, &char2b
);
25395 /* Initialize the bounding box. */
25398 width
= cmp
->glyph_len
> 0 ? pcm
->width
: 0;
25399 ascent
= pcm
->ascent
;
25400 descent
= pcm
->descent
;
25401 lbearing
= pcm
->lbearing
;
25402 rbearing
= pcm
->rbearing
;
25406 width
= cmp
->glyph_len
> 0 ? font
->space_width
: 0;
25407 ascent
= FONT_BASE (font
);
25408 descent
= FONT_DESCENT (font
);
25415 lowest
= - descent
+ boff
;
25416 highest
= ascent
+ boff
;
25418 if (! font_not_found_p
25419 && font
->default_ascent
25420 && CHAR_TABLE_P (Vuse_default_ascent
)
25421 && !NILP (Faref (Vuse_default_ascent
,
25422 make_number (it
->char_to_display
))))
25423 highest
= font
->default_ascent
+ boff
;
25425 /* Draw the first glyph at the normal position. It may be
25426 shifted to right later if some other glyphs are drawn
25428 cmp
->offsets
[i
* 2] = 0;
25429 cmp
->offsets
[i
* 2 + 1] = boff
;
25430 cmp
->lbearing
= lbearing
;
25431 cmp
->rbearing
= rbearing
;
25433 /* Set cmp->offsets for the remaining glyphs. */
25434 for (i
++; i
< glyph_len
; i
++)
25436 int left
, right
, btm
, top
;
25437 int ch
= COMPOSITION_GLYPH (cmp
, i
);
25439 struct face
*this_face
;
25443 face_id
= FACE_FOR_CHAR (it
->f
, face
, ch
, pos
, it
->string
);
25444 this_face
= FACE_FROM_ID (it
->f
, face_id
);
25445 font
= this_face
->font
;
25451 get_char_face_and_encoding (it
->f
, ch
, face_id
,
25453 pcm
= get_per_char_metric (font
, &char2b
);
25456 cmp
->offsets
[i
* 2] = cmp
->offsets
[i
* 2 + 1] = 0;
25459 width
= pcm
->width
;
25460 ascent
= pcm
->ascent
;
25461 descent
= pcm
->descent
;
25462 lbearing
= pcm
->lbearing
;
25463 rbearing
= pcm
->rbearing
;
25464 if (cmp
->method
!= COMPOSITION_WITH_RULE_ALTCHARS
)
25466 /* Relative composition with or without
25467 alternate chars. */
25468 left
= (leftmost
+ rightmost
- width
) / 2;
25469 btm
= - descent
+ boff
;
25470 if (font
->relative_compose
25471 && (! CHAR_TABLE_P (Vignore_relative_composition
)
25472 || NILP (Faref (Vignore_relative_composition
,
25473 make_number (ch
)))))
25476 if (- descent
>= font
->relative_compose
)
25477 /* One extra pixel between two glyphs. */
25479 else if (ascent
<= 0)
25480 /* One extra pixel between two glyphs. */
25481 btm
= lowest
- 1 - ascent
- descent
;
25486 /* A composition rule is specified by an integer
25487 value that encodes global and new reference
25488 points (GREF and NREF). GREF and NREF are
25489 specified by numbers as below:
25491 0---1---2 -- ascent
25495 9--10--11 -- center
25497 ---3---4---5--- baseline
25499 6---7---8 -- descent
25501 int rule
= COMPOSITION_RULE (cmp
, i
);
25502 int gref
, nref
, grefx
, grefy
, nrefx
, nrefy
, xoff
, yoff
;
25504 COMPOSITION_DECODE_RULE (rule
, gref
, nref
, xoff
, yoff
);
25505 grefx
= gref
% 3, nrefx
= nref
% 3;
25506 grefy
= gref
/ 3, nrefy
= nref
/ 3;
25508 xoff
= font_height
* (xoff
- 128) / 256;
25510 yoff
= font_height
* (yoff
- 128) / 256;
25513 + grefx
* (rightmost
- leftmost
) / 2
25514 - nrefx
* width
/ 2
25517 btm
= ((grefy
== 0 ? highest
25519 : grefy
== 2 ? lowest
25520 : (highest
+ lowest
) / 2)
25521 - (nrefy
== 0 ? ascent
+ descent
25522 : nrefy
== 1 ? descent
- boff
25524 : (ascent
+ descent
) / 2)
25528 cmp
->offsets
[i
* 2] = left
;
25529 cmp
->offsets
[i
* 2 + 1] = btm
+ descent
;
25531 /* Update the bounding box of the overall glyphs. */
25534 right
= left
+ width
;
25535 if (left
< leftmost
)
25537 if (right
> rightmost
)
25540 top
= btm
+ descent
+ ascent
;
25546 if (cmp
->lbearing
> left
+ lbearing
)
25547 cmp
->lbearing
= left
+ lbearing
;
25548 if (cmp
->rbearing
< left
+ rbearing
)
25549 cmp
->rbearing
= left
+ rbearing
;
25553 /* If there are glyphs whose x-offsets are negative,
25554 shift all glyphs to the right and make all x-offsets
25558 for (i
= 0; i
< cmp
->glyph_len
; i
++)
25559 cmp
->offsets
[i
* 2] -= leftmost
;
25560 rightmost
-= leftmost
;
25561 cmp
->lbearing
-= leftmost
;
25562 cmp
->rbearing
-= leftmost
;
25565 if (left_padded
&& cmp
->lbearing
< 0)
25567 for (i
= 0; i
< cmp
->glyph_len
; i
++)
25568 cmp
->offsets
[i
* 2] -= cmp
->lbearing
;
25569 rightmost
-= cmp
->lbearing
;
25570 cmp
->rbearing
-= cmp
->lbearing
;
25573 if (right_padded
&& rightmost
< cmp
->rbearing
)
25575 rightmost
= cmp
->rbearing
;
25578 cmp
->pixel_width
= rightmost
;
25579 cmp
->ascent
= highest
;
25580 cmp
->descent
= - lowest
;
25581 if (cmp
->ascent
< font_ascent
)
25582 cmp
->ascent
= font_ascent
;
25583 if (cmp
->descent
< font_descent
)
25584 cmp
->descent
= font_descent
;
25588 && (cmp
->lbearing
< 0
25589 || cmp
->rbearing
> cmp
->pixel_width
))
25590 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
25592 it
->pixel_width
= cmp
->pixel_width
;
25593 it
->ascent
= it
->phys_ascent
= cmp
->ascent
;
25594 it
->descent
= it
->phys_descent
= cmp
->descent
;
25595 if (face
->box
!= FACE_NO_BOX
)
25597 int thick
= face
->box_line_width
;
25601 it
->ascent
+= thick
;
25602 it
->descent
+= thick
;
25607 if (it
->start_of_box_run_p
)
25608 it
->pixel_width
+= thick
;
25609 if (it
->end_of_box_run_p
)
25610 it
->pixel_width
+= thick
;
25613 /* If face has an overline, add the height of the overline
25614 (1 pixel) and a 1 pixel margin to the character height. */
25615 if (face
->overline_p
)
25616 it
->ascent
+= overline_margin
;
25618 take_vertical_position_into_account (it
);
25619 if (it
->ascent
< 0)
25621 if (it
->descent
< 0)
25624 if (it
->glyph_row
&& cmp
->glyph_len
> 0)
25625 append_composite_glyph (it
);
25627 else if (it
->what
== IT_COMPOSITION
)
25629 /* A dynamic (automatic) composition. */
25630 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
25631 Lisp_Object gstring
;
25632 struct font_metrics metrics
;
25636 gstring
= composition_gstring_from_id (it
->cmp_it
.id
);
25638 = composition_gstring_width (gstring
, it
->cmp_it
.from
, it
->cmp_it
.to
,
25641 && (metrics
.lbearing
< 0 || metrics
.rbearing
> metrics
.width
))
25642 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
25643 it
->ascent
= it
->phys_ascent
= metrics
.ascent
;
25644 it
->descent
= it
->phys_descent
= metrics
.descent
;
25645 if (face
->box
!= FACE_NO_BOX
)
25647 int thick
= face
->box_line_width
;
25651 it
->ascent
+= thick
;
25652 it
->descent
+= thick
;
25657 if (it
->start_of_box_run_p
)
25658 it
->pixel_width
+= thick
;
25659 if (it
->end_of_box_run_p
)
25660 it
->pixel_width
+= thick
;
25662 /* If face has an overline, add the height of the overline
25663 (1 pixel) and a 1 pixel margin to the character height. */
25664 if (face
->overline_p
)
25665 it
->ascent
+= overline_margin
;
25666 take_vertical_position_into_account (it
);
25667 if (it
->ascent
< 0)
25669 if (it
->descent
< 0)
25673 append_composite_glyph (it
);
25675 else if (it
->what
== IT_GLYPHLESS
)
25676 produce_glyphless_glyph (it
, 0, Qnil
);
25677 else if (it
->what
== IT_IMAGE
)
25678 produce_image_glyph (it
);
25679 else if (it
->what
== IT_STRETCH
)
25680 produce_stretch_glyph (it
);
25683 /* Accumulate dimensions. Note: can't assume that it->descent > 0
25684 because this isn't true for images with `:ascent 100'. */
25685 eassert (it
->ascent
>= 0 && it
->descent
>= 0);
25686 if (it
->area
== TEXT_AREA
)
25687 it
->current_x
+= it
->pixel_width
;
25689 if (extra_line_spacing
> 0)
25691 it
->descent
+= extra_line_spacing
;
25692 if (extra_line_spacing
> it
->max_extra_line_spacing
)
25693 it
->max_extra_line_spacing
= extra_line_spacing
;
25696 it
->max_ascent
= max (it
->max_ascent
, it
->ascent
);
25697 it
->max_descent
= max (it
->max_descent
, it
->descent
);
25698 it
->max_phys_ascent
= max (it
->max_phys_ascent
, it
->phys_ascent
);
25699 it
->max_phys_descent
= max (it
->max_phys_descent
, it
->phys_descent
);
25703 Output LEN glyphs starting at START at the nominal cursor position.
25704 Advance the nominal cursor over the text. UPDATED_ROW is the glyph row
25705 being updated, and UPDATED_AREA is the area of that row being updated. */
25708 x_write_glyphs (struct window
*w
, struct glyph_row
*updated_row
,
25709 struct glyph
*start
, enum glyph_row_area updated_area
, int len
)
25711 int x
, hpos
, chpos
= w
->phys_cursor
.hpos
;
25713 eassert (updated_row
);
25714 /* When the window is hscrolled, cursor hpos can legitimately be out
25715 of bounds, but we draw the cursor at the corresponding window
25716 margin in that case. */
25717 if (!updated_row
->reversed_p
&& chpos
< 0)
25719 if (updated_row
->reversed_p
&& chpos
>= updated_row
->used
[TEXT_AREA
])
25720 chpos
= updated_row
->used
[TEXT_AREA
] - 1;
25724 /* Write glyphs. */
25726 hpos
= start
- updated_row
->glyphs
[updated_area
];
25727 x
= draw_glyphs (w
, w
->output_cursor
.x
,
25728 updated_row
, updated_area
,
25730 DRAW_NORMAL_TEXT
, 0);
25732 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
25733 if (updated_area
== TEXT_AREA
25734 && w
->phys_cursor_on_p
25735 && w
->phys_cursor
.vpos
== w
->output_cursor
.vpos
25737 && chpos
< hpos
+ len
)
25738 w
->phys_cursor_on_p
= 0;
25742 /* Advance the output cursor. */
25743 w
->output_cursor
.hpos
+= len
;
25744 w
->output_cursor
.x
= x
;
25749 Insert LEN glyphs from START at the nominal cursor position. */
25752 x_insert_glyphs (struct window
*w
, struct glyph_row
*updated_row
,
25753 struct glyph
*start
, enum glyph_row_area updated_area
, int len
)
25756 int line_height
, shift_by_width
, shifted_region_width
;
25757 struct glyph_row
*row
;
25758 struct glyph
*glyph
;
25759 int frame_x
, frame_y
;
25762 eassert (updated_row
);
25764 f
= XFRAME (WINDOW_FRAME (w
));
25766 /* Get the height of the line we are in. */
25768 line_height
= row
->height
;
25770 /* Get the width of the glyphs to insert. */
25771 shift_by_width
= 0;
25772 for (glyph
= start
; glyph
< start
+ len
; ++glyph
)
25773 shift_by_width
+= glyph
->pixel_width
;
25775 /* Get the width of the region to shift right. */
25776 shifted_region_width
= (window_box_width (w
, updated_area
)
25777 - w
->output_cursor
.x
25781 frame_x
= window_box_left (w
, updated_area
) + w
->output_cursor
.x
;
25782 frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, w
->output_cursor
.y
);
25784 FRAME_RIF (f
)->shift_glyphs_for_insert (f
, frame_x
, frame_y
, shifted_region_width
,
25785 line_height
, shift_by_width
);
25787 /* Write the glyphs. */
25788 hpos
= start
- row
->glyphs
[updated_area
];
25789 draw_glyphs (w
, w
->output_cursor
.x
, row
, updated_area
,
25791 DRAW_NORMAL_TEXT
, 0);
25793 /* Advance the output cursor. */
25794 w
->output_cursor
.hpos
+= len
;
25795 w
->output_cursor
.x
+= shift_by_width
;
25801 Erase the current text line from the nominal cursor position
25802 (inclusive) to pixel column TO_X (exclusive). The idea is that
25803 everything from TO_X onward is already erased.
25805 TO_X is a pixel position relative to UPDATED_AREA of currently
25806 updated window W. TO_X == -1 means clear to the end of this area. */
25809 x_clear_end_of_line (struct window
*w
, struct glyph_row
*updated_row
,
25810 enum glyph_row_area updated_area
, int to_x
)
25813 int max_x
, min_y
, max_y
;
25814 int from_x
, from_y
, to_y
;
25816 eassert (updated_row
);
25817 f
= XFRAME (w
->frame
);
25819 if (updated_row
->full_width_p
)
25820 max_x
= WINDOW_TOTAL_WIDTH (w
);
25822 max_x
= window_box_width (w
, updated_area
);
25823 max_y
= window_text_bottom_y (w
);
25825 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
25826 of window. For TO_X > 0, truncate to end of drawing area. */
25832 to_x
= min (to_x
, max_x
);
25834 to_y
= min (max_y
, w
->output_cursor
.y
+ updated_row
->height
);
25836 /* Notice if the cursor will be cleared by this operation. */
25837 if (!updated_row
->full_width_p
)
25838 notice_overwritten_cursor (w
, updated_area
,
25839 w
->output_cursor
.x
, -1,
25841 MATRIX_ROW_BOTTOM_Y (updated_row
));
25843 from_x
= w
->output_cursor
.x
;
25845 /* Translate to frame coordinates. */
25846 if (updated_row
->full_width_p
)
25848 from_x
= WINDOW_TO_FRAME_PIXEL_X (w
, from_x
);
25849 to_x
= WINDOW_TO_FRAME_PIXEL_X (w
, to_x
);
25853 int area_left
= window_box_left (w
, updated_area
);
25854 from_x
+= area_left
;
25858 min_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
25859 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (min_y
, w
->output_cursor
.y
));
25860 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, to_y
);
25862 /* Prevent inadvertently clearing to end of the X window. */
25863 if (to_x
> from_x
&& to_y
> from_y
)
25866 FRAME_RIF (f
)->clear_frame_area (f
, from_x
, from_y
,
25867 to_x
- from_x
, to_y
- from_y
);
25872 #endif /* HAVE_WINDOW_SYSTEM */
25876 /***********************************************************************
25878 ***********************************************************************/
25880 /* Value is the internal representation of the specified cursor type
25881 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
25882 of the bar cursor. */
25884 static enum text_cursor_kinds
25885 get_specified_cursor_type (Lisp_Object arg
, int *width
)
25887 enum text_cursor_kinds type
;
25892 if (EQ (arg
, Qbox
))
25893 return FILLED_BOX_CURSOR
;
25895 if (EQ (arg
, Qhollow
))
25896 return HOLLOW_BOX_CURSOR
;
25898 if (EQ (arg
, Qbar
))
25905 && EQ (XCAR (arg
), Qbar
)
25906 && RANGED_INTEGERP (0, XCDR (arg
), INT_MAX
))
25908 *width
= XINT (XCDR (arg
));
25912 if (EQ (arg
, Qhbar
))
25915 return HBAR_CURSOR
;
25919 && EQ (XCAR (arg
), Qhbar
)
25920 && RANGED_INTEGERP (0, XCDR (arg
), INT_MAX
))
25922 *width
= XINT (XCDR (arg
));
25923 return HBAR_CURSOR
;
25926 /* Treat anything unknown as "hollow box cursor".
25927 It was bad to signal an error; people have trouble fixing
25928 .Xdefaults with Emacs, when it has something bad in it. */
25929 type
= HOLLOW_BOX_CURSOR
;
25934 /* Set the default cursor types for specified frame. */
25936 set_frame_cursor_types (struct frame
*f
, Lisp_Object arg
)
25941 FRAME_DESIRED_CURSOR (f
) = get_specified_cursor_type (arg
, &width
);
25942 FRAME_CURSOR_WIDTH (f
) = width
;
25944 /* By default, set up the blink-off state depending on the on-state. */
25946 tem
= Fassoc (arg
, Vblink_cursor_alist
);
25949 FRAME_BLINK_OFF_CURSOR (f
)
25950 = get_specified_cursor_type (XCDR (tem
), &width
);
25951 FRAME_BLINK_OFF_CURSOR_WIDTH (f
) = width
;
25954 FRAME_BLINK_OFF_CURSOR (f
) = DEFAULT_CURSOR
;
25956 /* Make sure the cursor gets redrawn. */
25957 f
->cursor_type_changed
= 1;
25961 #ifdef HAVE_WINDOW_SYSTEM
25963 /* Return the cursor we want to be displayed in window W. Return
25964 width of bar/hbar cursor through WIDTH arg. Return with
25965 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
25966 (i.e. if the `system caret' should track this cursor).
25968 In a mini-buffer window, we want the cursor only to appear if we
25969 are reading input from this window. For the selected window, we
25970 want the cursor type given by the frame parameter or buffer local
25971 setting of cursor-type. If explicitly marked off, draw no cursor.
25972 In all other cases, we want a hollow box cursor. */
25974 static enum text_cursor_kinds
25975 get_window_cursor_type (struct window
*w
, struct glyph
*glyph
, int *width
,
25976 int *active_cursor
)
25978 struct frame
*f
= XFRAME (w
->frame
);
25979 struct buffer
*b
= XBUFFER (w
->contents
);
25980 int cursor_type
= DEFAULT_CURSOR
;
25981 Lisp_Object alt_cursor
;
25982 int non_selected
= 0;
25984 *active_cursor
= 1;
25987 if (cursor_in_echo_area
25988 && FRAME_HAS_MINIBUF_P (f
)
25989 && EQ (FRAME_MINIBUF_WINDOW (f
), echo_area_window
))
25991 if (w
== XWINDOW (echo_area_window
))
25993 if (EQ (BVAR (b
, cursor_type
), Qt
) || NILP (BVAR (b
, cursor_type
)))
25995 *width
= FRAME_CURSOR_WIDTH (f
);
25996 return FRAME_DESIRED_CURSOR (f
);
25999 return get_specified_cursor_type (BVAR (b
, cursor_type
), width
);
26002 *active_cursor
= 0;
26006 /* Detect a nonselected window or nonselected frame. */
26007 else if (w
!= XWINDOW (f
->selected_window
)
26008 || f
!= FRAME_DISPLAY_INFO (f
)->x_highlight_frame
)
26010 *active_cursor
= 0;
26012 if (MINI_WINDOW_P (w
) && minibuf_level
== 0)
26018 /* Never display a cursor in a window in which cursor-type is nil. */
26019 if (NILP (BVAR (b
, cursor_type
)))
26022 /* Get the normal cursor type for this window. */
26023 if (EQ (BVAR (b
, cursor_type
), Qt
))
26025 cursor_type
= FRAME_DESIRED_CURSOR (f
);
26026 *width
= FRAME_CURSOR_WIDTH (f
);
26029 cursor_type
= get_specified_cursor_type (BVAR (b
, cursor_type
), width
);
26031 /* Use cursor-in-non-selected-windows instead
26032 for non-selected window or frame. */
26035 alt_cursor
= BVAR (b
, cursor_in_non_selected_windows
);
26036 if (!EQ (Qt
, alt_cursor
))
26037 return get_specified_cursor_type (alt_cursor
, width
);
26038 /* t means modify the normal cursor type. */
26039 if (cursor_type
== FILLED_BOX_CURSOR
)
26040 cursor_type
= HOLLOW_BOX_CURSOR
;
26041 else if (cursor_type
== BAR_CURSOR
&& *width
> 1)
26043 return cursor_type
;
26046 /* Use normal cursor if not blinked off. */
26047 if (!w
->cursor_off_p
)
26049 if (glyph
!= NULL
&& glyph
->type
== IMAGE_GLYPH
)
26051 if (cursor_type
== FILLED_BOX_CURSOR
)
26053 /* Using a block cursor on large images can be very annoying.
26054 So use a hollow cursor for "large" images.
26055 If image is not transparent (no mask), also use hollow cursor. */
26056 struct image
*img
= IMAGE_FROM_ID (f
, glyph
->u
.img_id
);
26057 if (img
!= NULL
&& IMAGEP (img
->spec
))
26059 /* Arbitrarily, interpret "Large" as >32x32 and >NxN
26060 where N = size of default frame font size.
26061 This should cover most of the "tiny" icons people may use. */
26063 || img
->width
> max (32, WINDOW_FRAME_COLUMN_WIDTH (w
))
26064 || img
->height
> max (32, WINDOW_FRAME_LINE_HEIGHT (w
)))
26065 cursor_type
= HOLLOW_BOX_CURSOR
;
26068 else if (cursor_type
!= NO_CURSOR
)
26070 /* Display current only supports BOX and HOLLOW cursors for images.
26071 So for now, unconditionally use a HOLLOW cursor when cursor is
26072 not a solid box cursor. */
26073 cursor_type
= HOLLOW_BOX_CURSOR
;
26076 return cursor_type
;
26079 /* Cursor is blinked off, so determine how to "toggle" it. */
26081 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
26082 if ((alt_cursor
= Fassoc (BVAR (b
, cursor_type
), Vblink_cursor_alist
), !NILP (alt_cursor
)))
26083 return get_specified_cursor_type (XCDR (alt_cursor
), width
);
26085 /* Then see if frame has specified a specific blink off cursor type. */
26086 if (FRAME_BLINK_OFF_CURSOR (f
) != DEFAULT_CURSOR
)
26088 *width
= FRAME_BLINK_OFF_CURSOR_WIDTH (f
);
26089 return FRAME_BLINK_OFF_CURSOR (f
);
26093 /* Some people liked having a permanently visible blinking cursor,
26094 while others had very strong opinions against it. So it was
26095 decided to remove it. KFS 2003-09-03 */
26097 /* Finally perform built-in cursor blinking:
26098 filled box <-> hollow box
26099 wide [h]bar <-> narrow [h]bar
26100 narrow [h]bar <-> no cursor
26101 other type <-> no cursor */
26103 if (cursor_type
== FILLED_BOX_CURSOR
)
26104 return HOLLOW_BOX_CURSOR
;
26106 if ((cursor_type
== BAR_CURSOR
|| cursor_type
== HBAR_CURSOR
) && *width
> 1)
26109 return cursor_type
;
26117 /* Notice when the text cursor of window W has been completely
26118 overwritten by a drawing operation that outputs glyphs in AREA
26119 starting at X0 and ending at X1 in the line starting at Y0 and
26120 ending at Y1. X coordinates are area-relative. X1 < 0 means all
26121 the rest of the line after X0 has been written. Y coordinates
26122 are window-relative. */
26125 notice_overwritten_cursor (struct window
*w
, enum glyph_row_area area
,
26126 int x0
, int x1
, int y0
, int y1
)
26128 int cx0
, cx1
, cy0
, cy1
;
26129 struct glyph_row
*row
;
26131 if (!w
->phys_cursor_on_p
)
26133 if (area
!= TEXT_AREA
)
26136 if (w
->phys_cursor
.vpos
< 0
26137 || w
->phys_cursor
.vpos
>= w
->current_matrix
->nrows
26138 || (row
= w
->current_matrix
->rows
+ w
->phys_cursor
.vpos
,
26139 !(row
->enabled_p
&& MATRIX_ROW_DISPLAYS_TEXT_P (row
))))
26142 if (row
->cursor_in_fringe_p
)
26144 row
->cursor_in_fringe_p
= 0;
26145 draw_fringe_bitmap (w
, row
, row
->reversed_p
);
26146 w
->phys_cursor_on_p
= 0;
26150 cx0
= w
->phys_cursor
.x
;
26151 cx1
= cx0
+ w
->phys_cursor_width
;
26152 if (x0
> cx0
|| (x1
>= 0 && x1
< cx1
))
26155 /* The cursor image will be completely removed from the
26156 screen if the output area intersects the cursor area in
26157 y-direction. When we draw in [y0 y1[, and some part of
26158 the cursor is at y < y0, that part must have been drawn
26159 before. When scrolling, the cursor is erased before
26160 actually scrolling, so we don't come here. When not
26161 scrolling, the rows above the old cursor row must have
26162 changed, and in this case these rows must have written
26163 over the cursor image.
26165 Likewise if part of the cursor is below y1, with the
26166 exception of the cursor being in the first blank row at
26167 the buffer and window end because update_text_area
26168 doesn't draw that row. (Except when it does, but
26169 that's handled in update_text_area.) */
26171 cy0
= w
->phys_cursor
.y
;
26172 cy1
= cy0
+ w
->phys_cursor_height
;
26173 if ((y0
< cy0
|| y0
>= cy1
) && (y1
<= cy0
|| y1
>= cy1
))
26176 w
->phys_cursor_on_p
= 0;
26179 #endif /* HAVE_WINDOW_SYSTEM */
26182 /************************************************************************
26184 ************************************************************************/
26186 #ifdef HAVE_WINDOW_SYSTEM
26189 Fix the display of area AREA of overlapping row ROW in window W
26190 with respect to the overlapping part OVERLAPS. */
26193 x_fix_overlapping_area (struct window
*w
, struct glyph_row
*row
,
26194 enum glyph_row_area area
, int overlaps
)
26201 for (i
= 0; i
< row
->used
[area
];)
26203 if (row
->glyphs
[area
][i
].overlaps_vertically_p
)
26205 int start
= i
, start_x
= x
;
26209 x
+= row
->glyphs
[area
][i
].pixel_width
;
26212 while (i
< row
->used
[area
]
26213 && row
->glyphs
[area
][i
].overlaps_vertically_p
);
26215 draw_glyphs (w
, start_x
, row
, area
,
26217 DRAW_NORMAL_TEXT
, overlaps
);
26221 x
+= row
->glyphs
[area
][i
].pixel_width
;
26231 Draw the cursor glyph of window W in glyph row ROW. See the
26232 comment of draw_glyphs for the meaning of HL. */
26235 draw_phys_cursor_glyph (struct window
*w
, struct glyph_row
*row
,
26236 enum draw_glyphs_face hl
)
26238 /* If cursor hpos is out of bounds, don't draw garbage. This can
26239 happen in mini-buffer windows when switching between echo area
26240 glyphs and mini-buffer. */
26241 if ((row
->reversed_p
26242 ? (w
->phys_cursor
.hpos
>= 0)
26243 : (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])))
26245 int on_p
= w
->phys_cursor_on_p
;
26247 int hpos
= w
->phys_cursor
.hpos
;
26249 /* When the window is hscrolled, cursor hpos can legitimately be
26250 out of bounds, but we draw the cursor at the corresponding
26251 window margin in that case. */
26252 if (!row
->reversed_p
&& hpos
< 0)
26254 if (row
->reversed_p
&& hpos
>= row
->used
[TEXT_AREA
])
26255 hpos
= row
->used
[TEXT_AREA
] - 1;
26257 x1
= draw_glyphs (w
, w
->phys_cursor
.x
, row
, TEXT_AREA
, hpos
, hpos
+ 1,
26259 w
->phys_cursor_on_p
= on_p
;
26261 if (hl
== DRAW_CURSOR
)
26262 w
->phys_cursor_width
= x1
- w
->phys_cursor
.x
;
26263 /* When we erase the cursor, and ROW is overlapped by other
26264 rows, make sure that these overlapping parts of other rows
26266 else if (hl
== DRAW_NORMAL_TEXT
&& row
->overlapped_p
)
26268 w
->phys_cursor_width
= x1
- w
->phys_cursor
.x
;
26270 if (row
> w
->current_matrix
->rows
26271 && MATRIX_ROW_OVERLAPS_SUCC_P (row
- 1))
26272 x_fix_overlapping_area (w
, row
- 1, TEXT_AREA
,
26273 OVERLAPS_ERASED_CURSOR
);
26275 if (MATRIX_ROW_BOTTOM_Y (row
) < window_text_bottom_y (w
)
26276 && MATRIX_ROW_OVERLAPS_PRED_P (row
+ 1))
26277 x_fix_overlapping_area (w
, row
+ 1, TEXT_AREA
,
26278 OVERLAPS_ERASED_CURSOR
);
26285 Erase the image of a cursor of window W from the screen. */
26288 erase_phys_cursor (struct window
*w
)
26290 struct frame
*f
= XFRAME (w
->frame
);
26291 Mouse_HLInfo
*hlinfo
= MOUSE_HL_INFO (f
);
26292 int hpos
= w
->phys_cursor
.hpos
;
26293 int vpos
= w
->phys_cursor
.vpos
;
26294 int mouse_face_here_p
= 0;
26295 struct glyph_matrix
*active_glyphs
= w
->current_matrix
;
26296 struct glyph_row
*cursor_row
;
26297 struct glyph
*cursor_glyph
;
26298 enum draw_glyphs_face hl
;
26300 /* No cursor displayed or row invalidated => nothing to do on the
26302 if (w
->phys_cursor_type
== NO_CURSOR
)
26303 goto mark_cursor_off
;
26305 /* VPOS >= active_glyphs->nrows means that window has been resized.
26306 Don't bother to erase the cursor. */
26307 if (vpos
>= active_glyphs
->nrows
)
26308 goto mark_cursor_off
;
26310 /* If row containing cursor is marked invalid, there is nothing we
26312 cursor_row
= MATRIX_ROW (active_glyphs
, vpos
);
26313 if (!cursor_row
->enabled_p
)
26314 goto mark_cursor_off
;
26316 /* If line spacing is > 0, old cursor may only be partially visible in
26317 window after split-window. So adjust visible height. */
26318 cursor_row
->visible_height
= min (cursor_row
->visible_height
,
26319 window_text_bottom_y (w
) - cursor_row
->y
);
26321 /* If row is completely invisible, don't attempt to delete a cursor which
26322 isn't there. This can happen if cursor is at top of a window, and
26323 we switch to a buffer with a header line in that window. */
26324 if (cursor_row
->visible_height
<= 0)
26325 goto mark_cursor_off
;
26327 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
26328 if (cursor_row
->cursor_in_fringe_p
)
26330 cursor_row
->cursor_in_fringe_p
= 0;
26331 draw_fringe_bitmap (w
, cursor_row
, cursor_row
->reversed_p
);
26332 goto mark_cursor_off
;
26335 /* This can happen when the new row is shorter than the old one.
26336 In this case, either draw_glyphs or clear_end_of_line
26337 should have cleared the cursor. Note that we wouldn't be
26338 able to erase the cursor in this case because we don't have a
26339 cursor glyph at hand. */
26340 if ((cursor_row
->reversed_p
26341 ? (w
->phys_cursor
.hpos
< 0)
26342 : (w
->phys_cursor
.hpos
>= cursor_row
->used
[TEXT_AREA
])))
26343 goto mark_cursor_off
;
26345 /* When the window is hscrolled, cursor hpos can legitimately be out
26346 of bounds, but we draw the cursor at the corresponding window
26347 margin in that case. */
26348 if (!cursor_row
->reversed_p
&& hpos
< 0)
26350 if (cursor_row
->reversed_p
&& hpos
>= cursor_row
->used
[TEXT_AREA
])
26351 hpos
= cursor_row
->used
[TEXT_AREA
] - 1;
26353 /* If the cursor is in the mouse face area, redisplay that when
26354 we clear the cursor. */
26355 if (! NILP (hlinfo
->mouse_face_window
)
26356 && coords_in_mouse_face_p (w
, hpos
, vpos
)
26357 /* Don't redraw the cursor's spot in mouse face if it is at the
26358 end of a line (on a newline). The cursor appears there, but
26359 mouse highlighting does not. */
26360 && cursor_row
->used
[TEXT_AREA
] > hpos
&& hpos
>= 0)
26361 mouse_face_here_p
= 1;
26363 /* Maybe clear the display under the cursor. */
26364 if (w
->phys_cursor_type
== HOLLOW_BOX_CURSOR
)
26367 int header_line_height
= WINDOW_HEADER_LINE_HEIGHT (w
);
26370 cursor_glyph
= get_phys_cursor_glyph (w
);
26371 if (cursor_glyph
== NULL
)
26372 goto mark_cursor_off
;
26374 width
= cursor_glyph
->pixel_width
;
26375 left_x
= window_box_left_offset (w
, TEXT_AREA
);
26376 x
= w
->phys_cursor
.x
;
26378 width
-= left_x
- x
;
26379 width
= min (width
, window_box_width (w
, TEXT_AREA
) - x
);
26380 y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
, cursor_row
->y
));
26381 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, max (x
, left_x
));
26384 FRAME_RIF (f
)->clear_frame_area (f
, x
, y
, width
, cursor_row
->visible_height
);
26387 /* Erase the cursor by redrawing the character underneath it. */
26388 if (mouse_face_here_p
)
26389 hl
= DRAW_MOUSE_FACE
;
26391 hl
= DRAW_NORMAL_TEXT
;
26392 draw_phys_cursor_glyph (w
, cursor_row
, hl
);
26395 w
->phys_cursor_on_p
= 0;
26396 w
->phys_cursor_type
= NO_CURSOR
;
26401 Display or clear cursor of window W. If ON is zero, clear the
26402 cursor. If it is non-zero, display the cursor. If ON is nonzero,
26403 where to put the cursor is specified by HPOS, VPOS, X and Y. */
26406 display_and_set_cursor (struct window
*w
, bool on
,
26407 int hpos
, int vpos
, int x
, int y
)
26409 struct frame
*f
= XFRAME (w
->frame
);
26410 int new_cursor_type
;
26411 int new_cursor_width
;
26413 struct glyph_row
*glyph_row
;
26414 struct glyph
*glyph
;
26416 /* This is pointless on invisible frames, and dangerous on garbaged
26417 windows and frames; in the latter case, the frame or window may
26418 be in the midst of changing its size, and x and y may be off the
26420 if (! FRAME_VISIBLE_P (f
)
26421 || FRAME_GARBAGED_P (f
)
26422 || vpos
>= w
->current_matrix
->nrows
26423 || hpos
>= w
->current_matrix
->matrix_w
)
26426 /* If cursor is off and we want it off, return quickly. */
26427 if (!on
&& !w
->phys_cursor_on_p
)
26430 glyph_row
= MATRIX_ROW (w
->current_matrix
, vpos
);
26431 /* If cursor row is not enabled, we don't really know where to
26432 display the cursor. */
26433 if (!glyph_row
->enabled_p
)
26435 w
->phys_cursor_on_p
= 0;
26440 if (!glyph_row
->exact_window_width_line_p
26441 || (0 <= hpos
&& hpos
< glyph_row
->used
[TEXT_AREA
]))
26442 glyph
= glyph_row
->glyphs
[TEXT_AREA
] + hpos
;
26444 eassert (input_blocked_p ());
26446 /* Set new_cursor_type to the cursor we want to be displayed. */
26447 new_cursor_type
= get_window_cursor_type (w
, glyph
,
26448 &new_cursor_width
, &active_cursor
);
26450 /* If cursor is currently being shown and we don't want it to be or
26451 it is in the wrong place, or the cursor type is not what we want,
26453 if (w
->phys_cursor_on_p
26455 || w
->phys_cursor
.x
!= x
26456 || w
->phys_cursor
.y
!= y
26457 || new_cursor_type
!= w
->phys_cursor_type
26458 || ((new_cursor_type
== BAR_CURSOR
|| new_cursor_type
== HBAR_CURSOR
)
26459 && new_cursor_width
!= w
->phys_cursor_width
)))
26460 erase_phys_cursor (w
);
26462 /* Don't check phys_cursor_on_p here because that flag is only set
26463 to zero in some cases where we know that the cursor has been
26464 completely erased, to avoid the extra work of erasing the cursor
26465 twice. In other words, phys_cursor_on_p can be 1 and the cursor
26466 still not be visible, or it has only been partly erased. */
26469 w
->phys_cursor_ascent
= glyph_row
->ascent
;
26470 w
->phys_cursor_height
= glyph_row
->height
;
26472 /* Set phys_cursor_.* before x_draw_.* is called because some
26473 of them may need the information. */
26474 w
->phys_cursor
.x
= x
;
26475 w
->phys_cursor
.y
= glyph_row
->y
;
26476 w
->phys_cursor
.hpos
= hpos
;
26477 w
->phys_cursor
.vpos
= vpos
;
26480 FRAME_RIF (f
)->draw_window_cursor (w
, glyph_row
, x
, y
,
26481 new_cursor_type
, new_cursor_width
,
26482 on
, active_cursor
);
26486 /* Switch the display of W's cursor on or off, according to the value
26490 update_window_cursor (struct window
*w
, bool on
)
26492 /* Don't update cursor in windows whose frame is in the process
26493 of being deleted. */
26494 if (w
->current_matrix
)
26496 int hpos
= w
->phys_cursor
.hpos
;
26497 int vpos
= w
->phys_cursor
.vpos
;
26498 struct glyph_row
*row
;
26500 if (vpos
>= w
->current_matrix
->nrows
26501 || hpos
>= w
->current_matrix
->matrix_w
)
26504 row
= MATRIX_ROW (w
->current_matrix
, vpos
);
26506 /* When the window is hscrolled, cursor hpos can legitimately be
26507 out of bounds, but we draw the cursor at the corresponding
26508 window margin in that case. */
26509 if (!row
->reversed_p
&& hpos
< 0)
26511 if (row
->reversed_p
&& hpos
>= row
->used
[TEXT_AREA
])
26512 hpos
= row
->used
[TEXT_AREA
] - 1;
26515 display_and_set_cursor (w
, on
, hpos
, vpos
,
26516 w
->phys_cursor
.x
, w
->phys_cursor
.y
);
26522 /* Call update_window_cursor with parameter ON_P on all leaf windows
26523 in the window tree rooted at W. */
26526 update_cursor_in_window_tree (struct window
*w
, bool on_p
)
26530 if (WINDOWP (w
->contents
))
26531 update_cursor_in_window_tree (XWINDOW (w
->contents
), on_p
);
26533 update_window_cursor (w
, on_p
);
26535 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
26541 Display the cursor on window W, or clear it, according to ON_P.
26542 Don't change the cursor's position. */
26545 x_update_cursor (struct frame
*f
, bool on_p
)
26547 update_cursor_in_window_tree (XWINDOW (f
->root_window
), on_p
);
26552 Clear the cursor of window W to background color, and mark the
26553 cursor as not shown. This is used when the text where the cursor
26554 is about to be rewritten. */
26557 x_clear_cursor (struct window
*w
)
26559 if (FRAME_VISIBLE_P (XFRAME (w
->frame
)) && w
->phys_cursor_on_p
)
26560 update_window_cursor (w
, 0);
26563 #endif /* HAVE_WINDOW_SYSTEM */
26565 /* Implementation of draw_row_with_mouse_face for GUI sessions, GPM,
26568 draw_row_with_mouse_face (struct window
*w
, int start_x
, struct glyph_row
*row
,
26569 int start_hpos
, int end_hpos
,
26570 enum draw_glyphs_face draw
)
26572 #ifdef HAVE_WINDOW_SYSTEM
26573 if (FRAME_WINDOW_P (XFRAME (w
->frame
)))
26575 draw_glyphs (w
, start_x
, row
, TEXT_AREA
, start_hpos
, end_hpos
, draw
, 0);
26579 #if defined (HAVE_GPM) || defined (MSDOS) || defined (WINDOWSNT)
26580 tty_draw_row_with_mouse_face (w
, row
, start_hpos
, end_hpos
, draw
);
26584 /* Display the active region described by mouse_face_* according to DRAW. */
26587 show_mouse_face (Mouse_HLInfo
*hlinfo
, enum draw_glyphs_face draw
)
26589 struct window
*w
= XWINDOW (hlinfo
->mouse_face_window
);
26590 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
26592 if (/* If window is in the process of being destroyed, don't bother
26594 w
->current_matrix
!= NULL
26595 /* Don't update mouse highlight if hidden */
26596 && (draw
!= DRAW_MOUSE_FACE
|| !hlinfo
->mouse_face_hidden
)
26597 /* Recognize when we are called to operate on rows that don't exist
26598 anymore. This can happen when a window is split. */
26599 && hlinfo
->mouse_face_end_row
< w
->current_matrix
->nrows
)
26601 int phys_cursor_on_p
= w
->phys_cursor_on_p
;
26602 struct glyph_row
*row
, *first
, *last
;
26604 first
= MATRIX_ROW (w
->current_matrix
, hlinfo
->mouse_face_beg_row
);
26605 last
= MATRIX_ROW (w
->current_matrix
, hlinfo
->mouse_face_end_row
);
26607 for (row
= first
; row
<= last
&& row
->enabled_p
; ++row
)
26609 int start_hpos
, end_hpos
, start_x
;
26611 /* For all but the first row, the highlight starts at column 0. */
26614 /* R2L rows have BEG and END in reversed order, but the
26615 screen drawing geometry is always left to right. So
26616 we need to mirror the beginning and end of the
26617 highlighted area in R2L rows. */
26618 if (!row
->reversed_p
)
26620 start_hpos
= hlinfo
->mouse_face_beg_col
;
26621 start_x
= hlinfo
->mouse_face_beg_x
;
26623 else if (row
== last
)
26625 start_hpos
= hlinfo
->mouse_face_end_col
;
26626 start_x
= hlinfo
->mouse_face_end_x
;
26634 else if (row
->reversed_p
&& row
== last
)
26636 start_hpos
= hlinfo
->mouse_face_end_col
;
26637 start_x
= hlinfo
->mouse_face_end_x
;
26647 if (!row
->reversed_p
)
26648 end_hpos
= hlinfo
->mouse_face_end_col
;
26649 else if (row
== first
)
26650 end_hpos
= hlinfo
->mouse_face_beg_col
;
26653 end_hpos
= row
->used
[TEXT_AREA
];
26654 if (draw
== DRAW_NORMAL_TEXT
)
26655 row
->fill_line_p
= 1; /* Clear to end of line */
26658 else if (row
->reversed_p
&& row
== first
)
26659 end_hpos
= hlinfo
->mouse_face_beg_col
;
26662 end_hpos
= row
->used
[TEXT_AREA
];
26663 if (draw
== DRAW_NORMAL_TEXT
)
26664 row
->fill_line_p
= 1; /* Clear to end of line */
26667 if (end_hpos
> start_hpos
)
26669 draw_row_with_mouse_face (w
, start_x
, row
,
26670 start_hpos
, end_hpos
, draw
);
26673 = draw
== DRAW_MOUSE_FACE
|| draw
== DRAW_IMAGE_RAISED
;
26677 #ifdef HAVE_WINDOW_SYSTEM
26678 /* When we've written over the cursor, arrange for it to
26679 be displayed again. */
26680 if (FRAME_WINDOW_P (f
)
26681 && phys_cursor_on_p
&& !w
->phys_cursor_on_p
)
26683 int hpos
= w
->phys_cursor
.hpos
;
26685 /* When the window is hscrolled, cursor hpos can legitimately be
26686 out of bounds, but we draw the cursor at the corresponding
26687 window margin in that case. */
26688 if (!row
->reversed_p
&& hpos
< 0)
26690 if (row
->reversed_p
&& hpos
>= row
->used
[TEXT_AREA
])
26691 hpos
= row
->used
[TEXT_AREA
] - 1;
26694 display_and_set_cursor (w
, 1, hpos
, w
->phys_cursor
.vpos
,
26695 w
->phys_cursor
.x
, w
->phys_cursor
.y
);
26698 #endif /* HAVE_WINDOW_SYSTEM */
26701 #ifdef HAVE_WINDOW_SYSTEM
26702 /* Change the mouse cursor. */
26703 if (FRAME_WINDOW_P (f
))
26705 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
26706 if (draw
== DRAW_NORMAL_TEXT
26707 && !EQ (hlinfo
->mouse_face_window
, f
->tool_bar_window
))
26708 FRAME_RIF (f
)->define_frame_cursor (f
, FRAME_X_OUTPUT (f
)->text_cursor
);
26711 if (draw
== DRAW_MOUSE_FACE
)
26712 FRAME_RIF (f
)->define_frame_cursor (f
, FRAME_X_OUTPUT (f
)->hand_cursor
);
26714 FRAME_RIF (f
)->define_frame_cursor (f
, FRAME_X_OUTPUT (f
)->nontext_cursor
);
26716 #endif /* HAVE_WINDOW_SYSTEM */
26720 Clear out the mouse-highlighted active region.
26721 Redraw it un-highlighted first. Value is non-zero if mouse
26722 face was actually drawn unhighlighted. */
26725 clear_mouse_face (Mouse_HLInfo
*hlinfo
)
26729 if (!hlinfo
->mouse_face_hidden
&& !NILP (hlinfo
->mouse_face_window
))
26731 show_mouse_face (hlinfo
, DRAW_NORMAL_TEXT
);
26735 reset_mouse_highlight (hlinfo
);
26739 /* Return non-zero if the coordinates HPOS and VPOS on windows W are
26740 within the mouse face on that window. */
26742 coords_in_mouse_face_p (struct window
*w
, int hpos
, int vpos
)
26744 Mouse_HLInfo
*hlinfo
= MOUSE_HL_INFO (XFRAME (w
->frame
));
26746 /* Quickly resolve the easy cases. */
26747 if (!(WINDOWP (hlinfo
->mouse_face_window
)
26748 && XWINDOW (hlinfo
->mouse_face_window
) == w
))
26750 if (vpos
< hlinfo
->mouse_face_beg_row
26751 || vpos
> hlinfo
->mouse_face_end_row
)
26753 if (vpos
> hlinfo
->mouse_face_beg_row
26754 && vpos
< hlinfo
->mouse_face_end_row
)
26757 if (!MATRIX_ROW (w
->current_matrix
, vpos
)->reversed_p
)
26759 if (hlinfo
->mouse_face_beg_row
== hlinfo
->mouse_face_end_row
)
26761 if (hlinfo
->mouse_face_beg_col
<= hpos
&& hpos
< hlinfo
->mouse_face_end_col
)
26764 else if ((vpos
== hlinfo
->mouse_face_beg_row
26765 && hpos
>= hlinfo
->mouse_face_beg_col
)
26766 || (vpos
== hlinfo
->mouse_face_end_row
26767 && hpos
< hlinfo
->mouse_face_end_col
))
26772 if (hlinfo
->mouse_face_beg_row
== hlinfo
->mouse_face_end_row
)
26774 if (hlinfo
->mouse_face_end_col
< hpos
&& hpos
<= hlinfo
->mouse_face_beg_col
)
26777 else if ((vpos
== hlinfo
->mouse_face_beg_row
26778 && hpos
<= hlinfo
->mouse_face_beg_col
)
26779 || (vpos
== hlinfo
->mouse_face_end_row
26780 && hpos
> hlinfo
->mouse_face_end_col
))
26788 Non-zero if physical cursor of window W is within mouse face. */
26791 cursor_in_mouse_face_p (struct window
*w
)
26793 int hpos
= w
->phys_cursor
.hpos
;
26794 int vpos
= w
->phys_cursor
.vpos
;
26795 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, vpos
);
26797 /* When the window is hscrolled, cursor hpos can legitimately be out
26798 of bounds, but we draw the cursor at the corresponding window
26799 margin in that case. */
26800 if (!row
->reversed_p
&& hpos
< 0)
26802 if (row
->reversed_p
&& hpos
>= row
->used
[TEXT_AREA
])
26803 hpos
= row
->used
[TEXT_AREA
] - 1;
26805 return coords_in_mouse_face_p (w
, hpos
, vpos
);
26810 /* Find the glyph rows START_ROW and END_ROW of window W that display
26811 characters between buffer positions START_CHARPOS and END_CHARPOS
26812 (excluding END_CHARPOS). DISP_STRING is a display string that
26813 covers these buffer positions. This is similar to
26814 row_containing_pos, but is more accurate when bidi reordering makes
26815 buffer positions change non-linearly with glyph rows. */
26817 rows_from_pos_range (struct window
*w
,
26818 ptrdiff_t start_charpos
, ptrdiff_t end_charpos
,
26819 Lisp_Object disp_string
,
26820 struct glyph_row
**start
, struct glyph_row
**end
)
26822 struct glyph_row
*first
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
26823 int last_y
= window_text_bottom_y (w
);
26824 struct glyph_row
*row
;
26829 while (!first
->enabled_p
26830 && first
< MATRIX_BOTTOM_TEXT_ROW (w
->current_matrix
, w
))
26833 /* Find the START row. */
26835 row
->enabled_p
&& MATRIX_ROW_BOTTOM_Y (row
) <= last_y
;
26838 /* A row can potentially be the START row if the range of the
26839 characters it displays intersects the range
26840 [START_CHARPOS..END_CHARPOS). */
26841 if (! ((start_charpos
< MATRIX_ROW_START_CHARPOS (row
)
26842 && end_charpos
< MATRIX_ROW_START_CHARPOS (row
))
26843 /* See the commentary in row_containing_pos, for the
26844 explanation of the complicated way to check whether
26845 some position is beyond the end of the characters
26846 displayed by a row. */
26847 || ((start_charpos
> MATRIX_ROW_END_CHARPOS (row
)
26848 || (start_charpos
== MATRIX_ROW_END_CHARPOS (row
)
26849 && !row
->ends_at_zv_p
26850 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row
)))
26851 && (end_charpos
> MATRIX_ROW_END_CHARPOS (row
)
26852 || (end_charpos
== MATRIX_ROW_END_CHARPOS (row
)
26853 && !row
->ends_at_zv_p
26854 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row
))))))
26856 /* Found a candidate row. Now make sure at least one of the
26857 glyphs it displays has a charpos from the range
26858 [START_CHARPOS..END_CHARPOS).
26860 This is not obvious because bidi reordering could make
26861 buffer positions of a row be 1,2,3,102,101,100, and if we
26862 want to highlight characters in [50..60), we don't want
26863 this row, even though [50..60) does intersect [1..103),
26864 the range of character positions given by the row's start
26865 and end positions. */
26866 struct glyph
*g
= row
->glyphs
[TEXT_AREA
];
26867 struct glyph
*e
= g
+ row
->used
[TEXT_AREA
];
26871 if (((BUFFERP (g
->object
) || INTEGERP (g
->object
))
26872 && start_charpos
<= g
->charpos
&& g
->charpos
< end_charpos
)
26873 /* A glyph that comes from DISP_STRING is by
26874 definition to be highlighted. */
26875 || EQ (g
->object
, disp_string
))
26884 /* Find the END row. */
26886 /* If the last row is partially visible, start looking for END
26887 from that row, instead of starting from FIRST. */
26888 && !(row
->enabled_p
26889 && row
->y
< last_y
&& MATRIX_ROW_BOTTOM_Y (row
) > last_y
))
26891 for ( ; row
->enabled_p
&& MATRIX_ROW_BOTTOM_Y (row
) <= last_y
; row
++)
26893 struct glyph_row
*next
= row
+ 1;
26894 ptrdiff_t next_start
= MATRIX_ROW_START_CHARPOS (next
);
26896 if (!next
->enabled_p
26897 || next
>= MATRIX_BOTTOM_TEXT_ROW (w
->current_matrix
, w
)
26898 /* The first row >= START whose range of displayed characters
26899 does NOT intersect the range [START_CHARPOS..END_CHARPOS]
26900 is the row END + 1. */
26901 || (start_charpos
< next_start
26902 && end_charpos
< next_start
)
26903 || ((start_charpos
> MATRIX_ROW_END_CHARPOS (next
)
26904 || (start_charpos
== MATRIX_ROW_END_CHARPOS (next
)
26905 && !next
->ends_at_zv_p
26906 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next
)))
26907 && (end_charpos
> MATRIX_ROW_END_CHARPOS (next
)
26908 || (end_charpos
== MATRIX_ROW_END_CHARPOS (next
)
26909 && !next
->ends_at_zv_p
26910 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next
)))))
26917 /* If the next row's edges intersect [START_CHARPOS..END_CHARPOS],
26918 but none of the characters it displays are in the range, it is
26920 struct glyph
*g
= next
->glyphs
[TEXT_AREA
];
26921 struct glyph
*s
= g
;
26922 struct glyph
*e
= g
+ next
->used
[TEXT_AREA
];
26926 if (((BUFFERP (g
->object
) || INTEGERP (g
->object
))
26927 && ((start_charpos
<= g
->charpos
&& g
->charpos
< end_charpos
)
26928 /* If the buffer position of the first glyph in
26929 the row is equal to END_CHARPOS, it means
26930 the last character to be highlighted is the
26931 newline of ROW, and we must consider NEXT as
26933 || (((!next
->reversed_p
&& g
== s
)
26934 || (next
->reversed_p
&& g
== e
- 1))
26935 && (g
->charpos
== end_charpos
26936 /* Special case for when NEXT is an
26937 empty line at ZV. */
26938 || (g
->charpos
== -1
26939 && !row
->ends_at_zv_p
26940 && next_start
== end_charpos
)))))
26941 /* A glyph that comes from DISP_STRING is by
26942 definition to be highlighted. */
26943 || EQ (g
->object
, disp_string
))
26952 /* The first row that ends at ZV must be the last to be
26954 else if (next
->ends_at_zv_p
)
26963 /* This function sets the mouse_face_* elements of HLINFO, assuming
26964 the mouse cursor is on a glyph with buffer charpos MOUSE_CHARPOS in
26965 window WINDOW. START_CHARPOS and END_CHARPOS are buffer positions
26966 for the overlay or run of text properties specifying the mouse
26967 face. BEFORE_STRING and AFTER_STRING, if non-nil, are a
26968 before-string and after-string that must also be highlighted.
26969 DISP_STRING, if non-nil, is a display string that may cover some
26970 or all of the highlighted text. */
26973 mouse_face_from_buffer_pos (Lisp_Object window
,
26974 Mouse_HLInfo
*hlinfo
,
26975 ptrdiff_t mouse_charpos
,
26976 ptrdiff_t start_charpos
,
26977 ptrdiff_t end_charpos
,
26978 Lisp_Object before_string
,
26979 Lisp_Object after_string
,
26980 Lisp_Object disp_string
)
26982 struct window
*w
= XWINDOW (window
);
26983 struct glyph_row
*first
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
26984 struct glyph_row
*r1
, *r2
;
26985 struct glyph
*glyph
, *end
;
26986 ptrdiff_t ignore
, pos
;
26989 eassert (NILP (disp_string
) || STRINGP (disp_string
));
26990 eassert (NILP (before_string
) || STRINGP (before_string
));
26991 eassert (NILP (after_string
) || STRINGP (after_string
));
26993 /* Find the rows corresponding to START_CHARPOS and END_CHARPOS. */
26994 rows_from_pos_range (w
, start_charpos
, end_charpos
, disp_string
, &r1
, &r2
);
26996 r1
= MATRIX_ROW (w
->current_matrix
, w
->window_end_vpos
);
26997 /* If the before-string or display-string contains newlines,
26998 rows_from_pos_range skips to its last row. Move back. */
26999 if (!NILP (before_string
) || !NILP (disp_string
))
27001 struct glyph_row
*prev
;
27002 while ((prev
= r1
- 1, prev
>= first
)
27003 && MATRIX_ROW_END_CHARPOS (prev
) == start_charpos
27004 && prev
->used
[TEXT_AREA
] > 0)
27006 struct glyph
*beg
= prev
->glyphs
[TEXT_AREA
];
27007 glyph
= beg
+ prev
->used
[TEXT_AREA
];
27008 while (--glyph
>= beg
&& INTEGERP (glyph
->object
));
27010 || !(EQ (glyph
->object
, before_string
)
27011 || EQ (glyph
->object
, disp_string
)))
27018 r2
= MATRIX_ROW (w
->current_matrix
, w
->window_end_vpos
);
27019 hlinfo
->mouse_face_past_end
= 1;
27021 else if (!NILP (after_string
))
27023 /* If the after-string has newlines, advance to its last row. */
27024 struct glyph_row
*next
;
27025 struct glyph_row
*last
27026 = MATRIX_ROW (w
->current_matrix
, w
->window_end_vpos
);
27028 for (next
= r2
+ 1;
27030 && next
->used
[TEXT_AREA
] > 0
27031 && EQ (next
->glyphs
[TEXT_AREA
]->object
, after_string
);
27035 /* The rest of the display engine assumes that mouse_face_beg_row is
27036 either above mouse_face_end_row or identical to it. But with
27037 bidi-reordered continued lines, the row for START_CHARPOS could
27038 be below the row for END_CHARPOS. If so, swap the rows and store
27039 them in correct order. */
27042 struct glyph_row
*tem
= r2
;
27048 hlinfo
->mouse_face_beg_row
= MATRIX_ROW_VPOS (r1
, w
->current_matrix
);
27049 hlinfo
->mouse_face_end_row
= MATRIX_ROW_VPOS (r2
, w
->current_matrix
);
27051 /* For a bidi-reordered row, the positions of BEFORE_STRING,
27052 AFTER_STRING, DISP_STRING, START_CHARPOS, and END_CHARPOS
27053 could be anywhere in the row and in any order. The strategy
27054 below is to find the leftmost and the rightmost glyph that
27055 belongs to either of these 3 strings, or whose position is
27056 between START_CHARPOS and END_CHARPOS, and highlight all the
27057 glyphs between those two. This may cover more than just the text
27058 between START_CHARPOS and END_CHARPOS if the range of characters
27059 strides the bidi level boundary, e.g. if the beginning is in R2L
27060 text while the end is in L2R text or vice versa. */
27061 if (!r1
->reversed_p
)
27063 /* This row is in a left to right paragraph. Scan it left to
27065 glyph
= r1
->glyphs
[TEXT_AREA
];
27066 end
= glyph
+ r1
->used
[TEXT_AREA
];
27069 /* Skip truncation glyphs at the start of the glyph row. */
27070 if (MATRIX_ROW_DISPLAYS_TEXT_P (r1
))
27072 && INTEGERP (glyph
->object
)
27073 && glyph
->charpos
< 0;
27075 x
+= glyph
->pixel_width
;
27077 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
27078 or DISP_STRING, and the first glyph from buffer whose
27079 position is between START_CHARPOS and END_CHARPOS. */
27081 && !INTEGERP (glyph
->object
)
27082 && !EQ (glyph
->object
, disp_string
)
27083 && !(BUFFERP (glyph
->object
)
27084 && (glyph
->charpos
>= start_charpos
27085 && glyph
->charpos
< end_charpos
));
27088 /* BEFORE_STRING or AFTER_STRING are only relevant if they
27089 are present at buffer positions between START_CHARPOS and
27090 END_CHARPOS, or if they come from an overlay. */
27091 if (EQ (glyph
->object
, before_string
))
27093 pos
= string_buffer_position (before_string
,
27095 /* If pos == 0, it means before_string came from an
27096 overlay, not from a buffer position. */
27097 if (!pos
|| (pos
>= start_charpos
&& pos
< end_charpos
))
27100 else if (EQ (glyph
->object
, after_string
))
27102 pos
= string_buffer_position (after_string
, end_charpos
);
27103 if (!pos
|| (pos
>= start_charpos
&& pos
< end_charpos
))
27106 x
+= glyph
->pixel_width
;
27108 hlinfo
->mouse_face_beg_x
= x
;
27109 hlinfo
->mouse_face_beg_col
= glyph
- r1
->glyphs
[TEXT_AREA
];
27113 /* This row is in a right to left paragraph. Scan it right to
27117 end
= r1
->glyphs
[TEXT_AREA
] - 1;
27118 glyph
= end
+ r1
->used
[TEXT_AREA
];
27120 /* Skip truncation glyphs at the start of the glyph row. */
27121 if (MATRIX_ROW_DISPLAYS_TEXT_P (r1
))
27123 && INTEGERP (glyph
->object
)
27124 && glyph
->charpos
< 0;
27128 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
27129 or DISP_STRING, and the first glyph from buffer whose
27130 position is between START_CHARPOS and END_CHARPOS. */
27132 && !INTEGERP (glyph
->object
)
27133 && !EQ (glyph
->object
, disp_string
)
27134 && !(BUFFERP (glyph
->object
)
27135 && (glyph
->charpos
>= start_charpos
27136 && glyph
->charpos
< end_charpos
));
27139 /* BEFORE_STRING or AFTER_STRING are only relevant if they
27140 are present at buffer positions between START_CHARPOS and
27141 END_CHARPOS, or if they come from an overlay. */
27142 if (EQ (glyph
->object
, before_string
))
27144 pos
= string_buffer_position (before_string
, start_charpos
);
27145 /* If pos == 0, it means before_string came from an
27146 overlay, not from a buffer position. */
27147 if (!pos
|| (pos
>= start_charpos
&& pos
< end_charpos
))
27150 else if (EQ (glyph
->object
, after_string
))
27152 pos
= string_buffer_position (after_string
, end_charpos
);
27153 if (!pos
|| (pos
>= start_charpos
&& pos
< end_charpos
))
27158 glyph
++; /* first glyph to the right of the highlighted area */
27159 for (g
= r1
->glyphs
[TEXT_AREA
], x
= r1
->x
; g
< glyph
; g
++)
27160 x
+= g
->pixel_width
;
27161 hlinfo
->mouse_face_beg_x
= x
;
27162 hlinfo
->mouse_face_beg_col
= glyph
- r1
->glyphs
[TEXT_AREA
];
27165 /* If the highlight ends in a different row, compute GLYPH and END
27166 for the end row. Otherwise, reuse the values computed above for
27167 the row where the highlight begins. */
27170 if (!r2
->reversed_p
)
27172 glyph
= r2
->glyphs
[TEXT_AREA
];
27173 end
= glyph
+ r2
->used
[TEXT_AREA
];
27178 end
= r2
->glyphs
[TEXT_AREA
] - 1;
27179 glyph
= end
+ r2
->used
[TEXT_AREA
];
27183 if (!r2
->reversed_p
)
27185 /* Skip truncation and continuation glyphs near the end of the
27186 row, and also blanks and stretch glyphs inserted by
27187 extend_face_to_end_of_line. */
27189 && INTEGERP ((end
- 1)->object
))
27191 /* Scan the rest of the glyph row from the end, looking for the
27192 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
27193 DISP_STRING, or whose position is between START_CHARPOS
27197 && !INTEGERP (end
->object
)
27198 && !EQ (end
->object
, disp_string
)
27199 && !(BUFFERP (end
->object
)
27200 && (end
->charpos
>= start_charpos
27201 && end
->charpos
< end_charpos
));
27204 /* BEFORE_STRING or AFTER_STRING are only relevant if they
27205 are present at buffer positions between START_CHARPOS and
27206 END_CHARPOS, or if they come from an overlay. */
27207 if (EQ (end
->object
, before_string
))
27209 pos
= string_buffer_position (before_string
, start_charpos
);
27210 if (!pos
|| (pos
>= start_charpos
&& pos
< end_charpos
))
27213 else if (EQ (end
->object
, after_string
))
27215 pos
= string_buffer_position (after_string
, end_charpos
);
27216 if (!pos
|| (pos
>= start_charpos
&& pos
< end_charpos
))
27220 /* Find the X coordinate of the last glyph to be highlighted. */
27221 for (; glyph
<= end
; ++glyph
)
27222 x
+= glyph
->pixel_width
;
27224 hlinfo
->mouse_face_end_x
= x
;
27225 hlinfo
->mouse_face_end_col
= glyph
- r2
->glyphs
[TEXT_AREA
];
27229 /* Skip truncation and continuation glyphs near the end of the
27230 row, and also blanks and stretch glyphs inserted by
27231 extend_face_to_end_of_line. */
27235 && INTEGERP (end
->object
))
27237 x
+= end
->pixel_width
;
27240 /* Scan the rest of the glyph row from the end, looking for the
27241 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
27242 DISP_STRING, or whose position is between START_CHARPOS
27246 && !INTEGERP (end
->object
)
27247 && !EQ (end
->object
, disp_string
)
27248 && !(BUFFERP (end
->object
)
27249 && (end
->charpos
>= start_charpos
27250 && end
->charpos
< end_charpos
));
27253 /* BEFORE_STRING or AFTER_STRING are only relevant if they
27254 are present at buffer positions between START_CHARPOS and
27255 END_CHARPOS, or if they come from an overlay. */
27256 if (EQ (end
->object
, before_string
))
27258 pos
= string_buffer_position (before_string
, start_charpos
);
27259 if (!pos
|| (pos
>= start_charpos
&& pos
< end_charpos
))
27262 else if (EQ (end
->object
, after_string
))
27264 pos
= string_buffer_position (after_string
, end_charpos
);
27265 if (!pos
|| (pos
>= start_charpos
&& pos
< end_charpos
))
27268 x
+= end
->pixel_width
;
27270 /* If we exited the above loop because we arrived at the last
27271 glyph of the row, and its buffer position is still not in
27272 range, it means the last character in range is the preceding
27273 newline. Bump the end column and x values to get past the
27276 && BUFFERP (end
->object
)
27277 && (end
->charpos
< start_charpos
27278 || end
->charpos
>= end_charpos
))
27280 x
+= end
->pixel_width
;
27283 hlinfo
->mouse_face_end_x
= x
;
27284 hlinfo
->mouse_face_end_col
= end
- r2
->glyphs
[TEXT_AREA
];
27287 hlinfo
->mouse_face_window
= window
;
27288 hlinfo
->mouse_face_face_id
27289 = face_at_buffer_position (w
, mouse_charpos
, 0, 0, &ignore
,
27291 !hlinfo
->mouse_face_hidden
, -1);
27292 show_mouse_face (hlinfo
, DRAW_MOUSE_FACE
);
27295 /* The following function is not used anymore (replaced with
27296 mouse_face_from_string_pos), but I leave it here for the time
27297 being, in case someone would. */
27299 #if 0 /* not used */
27301 /* Find the position of the glyph for position POS in OBJECT in
27302 window W's current matrix, and return in *X, *Y the pixel
27303 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
27305 RIGHT_P non-zero means return the position of the right edge of the
27306 glyph, RIGHT_P zero means return the left edge position.
27308 If no glyph for POS exists in the matrix, return the position of
27309 the glyph with the next smaller position that is in the matrix, if
27310 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
27311 exists in the matrix, return the position of the glyph with the
27312 next larger position in OBJECT.
27314 Value is non-zero if a glyph was found. */
27317 fast_find_string_pos (struct window
*w
, ptrdiff_t pos
, Lisp_Object object
,
27318 int *hpos
, int *vpos
, int *x
, int *y
, int right_p
)
27320 int yb
= window_text_bottom_y (w
);
27321 struct glyph_row
*r
;
27322 struct glyph
*best_glyph
= NULL
;
27323 struct glyph_row
*best_row
= NULL
;
27326 for (r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
27327 r
->enabled_p
&& r
->y
< yb
;
27330 struct glyph
*g
= r
->glyphs
[TEXT_AREA
];
27331 struct glyph
*e
= g
+ r
->used
[TEXT_AREA
];
27334 for (gx
= r
->x
; g
< e
; gx
+= g
->pixel_width
, ++g
)
27335 if (EQ (g
->object
, object
))
27337 if (g
->charpos
== pos
)
27344 else if (best_glyph
== NULL
27345 || ((eabs (g
->charpos
- pos
)
27346 < eabs (best_glyph
->charpos
- pos
))
27349 : g
->charpos
> pos
)))
27363 *hpos
= best_glyph
- best_row
->glyphs
[TEXT_AREA
];
27367 *x
+= best_glyph
->pixel_width
;
27372 *vpos
= MATRIX_ROW_VPOS (best_row
, w
->current_matrix
);
27375 return best_glyph
!= NULL
;
27377 #endif /* not used */
27379 /* Find the positions of the first and the last glyphs in window W's
27380 current matrix that occlude positions [STARTPOS..ENDPOS] in OBJECT
27381 (assumed to be a string), and return in HLINFO's mouse_face_*
27382 members the pixel and column/row coordinates of those glyphs. */
27385 mouse_face_from_string_pos (struct window
*w
, Mouse_HLInfo
*hlinfo
,
27386 Lisp_Object object
,
27387 ptrdiff_t startpos
, ptrdiff_t endpos
)
27389 int yb
= window_text_bottom_y (w
);
27390 struct glyph_row
*r
;
27391 struct glyph
*g
, *e
;
27395 /* Find the glyph row with at least one position in the range
27396 [STARTPOS..ENDPOS], and the first glyph in that row whose
27397 position belongs to that range. */
27398 for (r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
27399 r
->enabled_p
&& r
->y
< yb
;
27402 if (!r
->reversed_p
)
27404 g
= r
->glyphs
[TEXT_AREA
];
27405 e
= g
+ r
->used
[TEXT_AREA
];
27406 for (gx
= r
->x
; g
< e
; gx
+= g
->pixel_width
, ++g
)
27407 if (EQ (g
->object
, object
)
27408 && startpos
<= g
->charpos
&& g
->charpos
<= endpos
)
27410 hlinfo
->mouse_face_beg_row
27411 = MATRIX_ROW_VPOS (r
, w
->current_matrix
);
27412 hlinfo
->mouse_face_beg_col
= g
- r
->glyphs
[TEXT_AREA
];
27413 hlinfo
->mouse_face_beg_x
= gx
;
27422 e
= r
->glyphs
[TEXT_AREA
];
27423 g
= e
+ r
->used
[TEXT_AREA
];
27424 for ( ; g
> e
; --g
)
27425 if (EQ ((g
-1)->object
, object
)
27426 && startpos
<= (g
-1)->charpos
&& (g
-1)->charpos
<= endpos
)
27428 hlinfo
->mouse_face_beg_row
27429 = MATRIX_ROW_VPOS (r
, w
->current_matrix
);
27430 hlinfo
->mouse_face_beg_col
= g
- r
->glyphs
[TEXT_AREA
];
27431 for (gx
= r
->x
, g1
= r
->glyphs
[TEXT_AREA
]; g1
< g
; ++g1
)
27432 gx
+= g1
->pixel_width
;
27433 hlinfo
->mouse_face_beg_x
= gx
;
27445 /* Starting with the next row, look for the first row which does NOT
27446 include any glyphs whose positions are in the range. */
27447 for (++r
; r
->enabled_p
&& r
->y
< yb
; ++r
)
27449 g
= r
->glyphs
[TEXT_AREA
];
27450 e
= g
+ r
->used
[TEXT_AREA
];
27452 for ( ; g
< e
; ++g
)
27453 if (EQ (g
->object
, object
)
27454 && startpos
<= g
->charpos
&& g
->charpos
<= endpos
)
27463 /* The highlighted region ends on the previous row. */
27466 /* Set the end row. */
27467 hlinfo
->mouse_face_end_row
= MATRIX_ROW_VPOS (r
, w
->current_matrix
);
27469 /* Compute and set the end column and the end column's horizontal
27470 pixel coordinate. */
27471 if (!r
->reversed_p
)
27473 g
= r
->glyphs
[TEXT_AREA
];
27474 e
= g
+ r
->used
[TEXT_AREA
];
27475 for ( ; e
> g
; --e
)
27476 if (EQ ((e
-1)->object
, object
)
27477 && startpos
<= (e
-1)->charpos
&& (e
-1)->charpos
<= endpos
)
27479 hlinfo
->mouse_face_end_col
= e
- g
;
27481 for (gx
= r
->x
; g
< e
; ++g
)
27482 gx
+= g
->pixel_width
;
27483 hlinfo
->mouse_face_end_x
= gx
;
27487 e
= r
->glyphs
[TEXT_AREA
];
27488 g
= e
+ r
->used
[TEXT_AREA
];
27489 for (gx
= r
->x
; e
< g
; ++e
)
27491 if (EQ (e
->object
, object
)
27492 && startpos
<= e
->charpos
&& e
->charpos
<= endpos
)
27494 gx
+= e
->pixel_width
;
27496 hlinfo
->mouse_face_end_col
= e
- r
->glyphs
[TEXT_AREA
];
27497 hlinfo
->mouse_face_end_x
= gx
;
27501 #ifdef HAVE_WINDOW_SYSTEM
27503 /* See if position X, Y is within a hot-spot of an image. */
27506 on_hot_spot_p (Lisp_Object hot_spot
, int x
, int y
)
27508 if (!CONSP (hot_spot
))
27511 if (EQ (XCAR (hot_spot
), Qrect
))
27513 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
27514 Lisp_Object rect
= XCDR (hot_spot
);
27518 if (!CONSP (XCAR (rect
)))
27520 if (!CONSP (XCDR (rect
)))
27522 if (!(tem
= XCAR (XCAR (rect
)), INTEGERP (tem
) && x
>= XINT (tem
)))
27524 if (!(tem
= XCDR (XCAR (rect
)), INTEGERP (tem
) && y
>= XINT (tem
)))
27526 if (!(tem
= XCAR (XCDR (rect
)), INTEGERP (tem
) && x
<= XINT (tem
)))
27528 if (!(tem
= XCDR (XCDR (rect
)), INTEGERP (tem
) && y
<= XINT (tem
)))
27532 else if (EQ (XCAR (hot_spot
), Qcircle
))
27534 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
27535 Lisp_Object circ
= XCDR (hot_spot
);
27536 Lisp_Object lr
, lx0
, ly0
;
27538 && CONSP (XCAR (circ
))
27539 && (lr
= XCDR (circ
), INTEGERP (lr
) || FLOATP (lr
))
27540 && (lx0
= XCAR (XCAR (circ
)), INTEGERP (lx0
))
27541 && (ly0
= XCDR (XCAR (circ
)), INTEGERP (ly0
)))
27543 double r
= XFLOATINT (lr
);
27544 double dx
= XINT (lx0
) - x
;
27545 double dy
= XINT (ly0
) - y
;
27546 return (dx
* dx
+ dy
* dy
<= r
* r
);
27549 else if (EQ (XCAR (hot_spot
), Qpoly
))
27551 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
27552 if (VECTORP (XCDR (hot_spot
)))
27554 struct Lisp_Vector
*v
= XVECTOR (XCDR (hot_spot
));
27555 Lisp_Object
*poly
= v
->contents
;
27556 ptrdiff_t n
= v
->header
.size
;
27559 Lisp_Object lx
, ly
;
27562 /* Need an even number of coordinates, and at least 3 edges. */
27563 if (n
< 6 || n
& 1)
27566 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
27567 If count is odd, we are inside polygon. Pixels on edges
27568 may or may not be included depending on actual geometry of the
27570 if ((lx
= poly
[n
-2], !INTEGERP (lx
))
27571 || (ly
= poly
[n
-1], !INTEGERP (lx
)))
27573 x0
= XINT (lx
), y0
= XINT (ly
);
27574 for (i
= 0; i
< n
; i
+= 2)
27576 int x1
= x0
, y1
= y0
;
27577 if ((lx
= poly
[i
], !INTEGERP (lx
))
27578 || (ly
= poly
[i
+1], !INTEGERP (ly
)))
27580 x0
= XINT (lx
), y0
= XINT (ly
);
27582 /* Does this segment cross the X line? */
27590 if (y
> y0
&& y
> y1
)
27592 if (y
< y0
+ ((y1
- y0
) * (x
- x0
)) / (x1
- x0
))
27602 find_hot_spot (Lisp_Object map
, int x
, int y
)
27604 while (CONSP (map
))
27606 if (CONSP (XCAR (map
))
27607 && on_hot_spot_p (XCAR (XCAR (map
)), x
, y
))
27615 DEFUN ("lookup-image-map", Flookup_image_map
, Slookup_image_map
,
27617 doc
: /* Lookup in image map MAP coordinates X and Y.
27618 An image map is an alist where each element has the format (AREA ID PLIST).
27619 An AREA is specified as either a rectangle, a circle, or a polygon:
27620 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
27621 pixel coordinates of the upper left and bottom right corners.
27622 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
27623 and the radius of the circle; r may be a float or integer.
27624 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
27625 vector describes one corner in the polygon.
27626 Returns the alist element for the first matching AREA in MAP. */)
27627 (Lisp_Object map
, Lisp_Object x
, Lisp_Object y
)
27635 return find_hot_spot (map
,
27636 clip_to_bounds (INT_MIN
, XINT (x
), INT_MAX
),
27637 clip_to_bounds (INT_MIN
, XINT (y
), INT_MAX
));
27641 /* Display frame CURSOR, optionally using shape defined by POINTER. */
27643 define_frame_cursor1 (struct frame
*f
, Cursor cursor
, Lisp_Object pointer
)
27645 /* Do not change cursor shape while dragging mouse. */
27646 if (!NILP (do_mouse_tracking
))
27649 if (!NILP (pointer
))
27651 if (EQ (pointer
, Qarrow
))
27652 cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
27653 else if (EQ (pointer
, Qhand
))
27654 cursor
= FRAME_X_OUTPUT (f
)->hand_cursor
;
27655 else if (EQ (pointer
, Qtext
))
27656 cursor
= FRAME_X_OUTPUT (f
)->text_cursor
;
27657 else if (EQ (pointer
, intern ("hdrag")))
27658 cursor
= FRAME_X_OUTPUT (f
)->horizontal_drag_cursor
;
27659 #ifdef HAVE_X_WINDOWS
27660 else if (EQ (pointer
, intern ("vdrag")))
27661 cursor
= FRAME_DISPLAY_INFO (f
)->vertical_scroll_bar_cursor
;
27663 else if (EQ (pointer
, intern ("hourglass")))
27664 cursor
= FRAME_X_OUTPUT (f
)->hourglass_cursor
;
27665 else if (EQ (pointer
, Qmodeline
))
27666 cursor
= FRAME_X_OUTPUT (f
)->modeline_cursor
;
27668 cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
27671 if (cursor
!= No_Cursor
)
27672 FRAME_RIF (f
)->define_frame_cursor (f
, cursor
);
27675 #endif /* HAVE_WINDOW_SYSTEM */
27677 /* Take proper action when mouse has moved to the mode or header line
27678 or marginal area AREA of window W, x-position X and y-position Y.
27679 X is relative to the start of the text display area of W, so the
27680 width of bitmap areas and scroll bars must be subtracted to get a
27681 position relative to the start of the mode line. */
27684 note_mode_line_or_margin_highlight (Lisp_Object window
, int x
, int y
,
27685 enum window_part area
)
27687 struct window
*w
= XWINDOW (window
);
27688 struct frame
*f
= XFRAME (w
->frame
);
27689 Mouse_HLInfo
*hlinfo
= MOUSE_HL_INFO (f
);
27690 #ifdef HAVE_WINDOW_SYSTEM
27691 Display_Info
*dpyinfo
;
27693 Cursor cursor
= No_Cursor
;
27694 Lisp_Object pointer
= Qnil
;
27695 int dx
, dy
, width
, height
;
27697 Lisp_Object string
, object
= Qnil
;
27698 Lisp_Object pos
IF_LINT (= Qnil
), help
;
27700 Lisp_Object mouse_face
;
27701 int original_x_pixel
= x
;
27702 struct glyph
* glyph
= NULL
, * row_start_glyph
= NULL
;
27703 struct glyph_row
*row
IF_LINT (= 0);
27705 if (area
== ON_MODE_LINE
|| area
== ON_HEADER_LINE
)
27710 /* Kludge alert: mode_line_string takes X/Y in pixels, but
27711 returns them in row/column units! */
27712 string
= mode_line_string (w
, area
, &x
, &y
, &charpos
,
27713 &object
, &dx
, &dy
, &width
, &height
);
27715 row
= (area
== ON_MODE_LINE
27716 ? MATRIX_MODE_LINE_ROW (w
->current_matrix
)
27717 : MATRIX_HEADER_LINE_ROW (w
->current_matrix
));
27719 /* Find the glyph under the mouse pointer. */
27720 if (row
->mode_line_p
&& row
->enabled_p
)
27722 glyph
= row_start_glyph
= row
->glyphs
[TEXT_AREA
];
27723 end
= glyph
+ row
->used
[TEXT_AREA
];
27725 for (x0
= original_x_pixel
;
27726 glyph
< end
&& x0
>= glyph
->pixel_width
;
27728 x0
-= glyph
->pixel_width
;
27736 x
-= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w
);
27737 /* Kludge alert: marginal_area_string takes X/Y in pixels, but
27738 returns them in row/column units! */
27739 string
= marginal_area_string (w
, area
, &x
, &y
, &charpos
,
27740 &object
, &dx
, &dy
, &width
, &height
);
27745 #ifdef HAVE_WINDOW_SYSTEM
27746 if (IMAGEP (object
))
27748 Lisp_Object image_map
, hotspot
;
27749 if ((image_map
= Fplist_get (XCDR (object
), QCmap
),
27751 && (hotspot
= find_hot_spot (image_map
, dx
, dy
),
27753 && (hotspot
= XCDR (hotspot
), CONSP (hotspot
)))
27757 /* Could check XCAR (hotspot) to see if we enter/leave this hot-spot.
27758 If so, we could look for mouse-enter, mouse-leave
27759 properties in PLIST (and do something...). */
27760 hotspot
= XCDR (hotspot
);
27761 if (CONSP (hotspot
)
27762 && (plist
= XCAR (hotspot
), CONSP (plist
)))
27764 pointer
= Fplist_get (plist
, Qpointer
);
27765 if (NILP (pointer
))
27767 help
= Fplist_get (plist
, Qhelp_echo
);
27770 help_echo_string
= help
;
27771 XSETWINDOW (help_echo_window
, w
);
27772 help_echo_object
= w
->contents
;
27773 help_echo_pos
= charpos
;
27777 if (NILP (pointer
))
27778 pointer
= Fplist_get (XCDR (object
), QCpointer
);
27780 #endif /* HAVE_WINDOW_SYSTEM */
27782 if (STRINGP (string
))
27783 pos
= make_number (charpos
);
27785 /* Set the help text and mouse pointer. If the mouse is on a part
27786 of the mode line without any text (e.g. past the right edge of
27787 the mode line text), use the default help text and pointer. */
27788 if (STRINGP (string
) || area
== ON_MODE_LINE
)
27790 /* Arrange to display the help by setting the global variables
27791 help_echo_string, help_echo_object, and help_echo_pos. */
27794 if (STRINGP (string
))
27795 help
= Fget_text_property (pos
, Qhelp_echo
, string
);
27799 help_echo_string
= help
;
27800 XSETWINDOW (help_echo_window
, w
);
27801 help_echo_object
= string
;
27802 help_echo_pos
= charpos
;
27804 else if (area
== ON_MODE_LINE
)
27806 Lisp_Object default_help
27807 = buffer_local_value_1 (Qmode_line_default_help_echo
,
27810 if (STRINGP (default_help
))
27812 help_echo_string
= default_help
;
27813 XSETWINDOW (help_echo_window
, w
);
27814 help_echo_object
= Qnil
;
27815 help_echo_pos
= -1;
27820 #ifdef HAVE_WINDOW_SYSTEM
27821 /* Change the mouse pointer according to what is under it. */
27822 if (FRAME_WINDOW_P (f
))
27824 dpyinfo
= FRAME_DISPLAY_INFO (f
);
27825 if (STRINGP (string
))
27827 cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
27829 if (NILP (pointer
))
27830 pointer
= Fget_text_property (pos
, Qpointer
, string
);
27832 /* Change the mouse pointer according to what is under X/Y. */
27834 && ((area
== ON_MODE_LINE
) || (area
== ON_HEADER_LINE
)))
27837 map
= Fget_text_property (pos
, Qlocal_map
, string
);
27838 if (!KEYMAPP (map
))
27839 map
= Fget_text_property (pos
, Qkeymap
, string
);
27840 if (!KEYMAPP (map
))
27841 cursor
= dpyinfo
->vertical_scroll_bar_cursor
;
27845 /* Default mode-line pointer. */
27846 cursor
= FRAME_DISPLAY_INFO (f
)->vertical_scroll_bar_cursor
;
27851 /* Change the mouse face according to what is under X/Y. */
27852 if (STRINGP (string
))
27854 mouse_face
= Fget_text_property (pos
, Qmouse_face
, string
);
27855 if (!NILP (Vmouse_highlight
) && !NILP (mouse_face
)
27856 && ((area
== ON_MODE_LINE
) || (area
== ON_HEADER_LINE
))
27861 struct glyph
* tmp_glyph
;
27865 int total_pixel_width
;
27866 ptrdiff_t begpos
, endpos
, ignore
;
27870 b
= Fprevious_single_property_change (make_number (charpos
+ 1),
27871 Qmouse_face
, string
, Qnil
);
27877 e
= Fnext_single_property_change (pos
, Qmouse_face
, string
, Qnil
);
27879 endpos
= SCHARS (string
);
27883 /* Calculate the glyph position GPOS of GLYPH in the
27884 displayed string, relative to the beginning of the
27885 highlighted part of the string.
27887 Note: GPOS is different from CHARPOS. CHARPOS is the
27888 position of GLYPH in the internal string object. A mode
27889 line string format has structures which are converted to
27890 a flattened string by the Emacs Lisp interpreter. The
27891 internal string is an element of those structures. The
27892 displayed string is the flattened string. */
27893 tmp_glyph
= row_start_glyph
;
27894 while (tmp_glyph
< glyph
27895 && (!(EQ (tmp_glyph
->object
, glyph
->object
)
27896 && begpos
<= tmp_glyph
->charpos
27897 && tmp_glyph
->charpos
< endpos
)))
27899 gpos
= glyph
- tmp_glyph
;
27901 /* Calculate the length GSEQ_LENGTH of the glyph sequence of
27902 the highlighted part of the displayed string to which
27903 GLYPH belongs. Note: GSEQ_LENGTH is different from
27904 SCHARS (STRING), because the latter returns the length of
27905 the internal string. */
27906 for (tmp_glyph
= row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
] - 1;
27908 && (!(EQ (tmp_glyph
->object
, glyph
->object
)
27909 && begpos
<= tmp_glyph
->charpos
27910 && tmp_glyph
->charpos
< endpos
));
27913 gseq_length
= gpos
+ (tmp_glyph
- glyph
) + 1;
27915 /* Calculate the total pixel width of all the glyphs between
27916 the beginning of the highlighted area and GLYPH. */
27917 total_pixel_width
= 0;
27918 for (tmp_glyph
= glyph
- gpos
; tmp_glyph
!= glyph
; tmp_glyph
++)
27919 total_pixel_width
+= tmp_glyph
->pixel_width
;
27921 /* Pre calculation of re-rendering position. Note: X is in
27922 column units here, after the call to mode_line_string or
27923 marginal_area_string. */
27925 vpos
= (area
== ON_MODE_LINE
27926 ? (w
->current_matrix
)->nrows
- 1
27929 /* If GLYPH's position is included in the region that is
27930 already drawn in mouse face, we have nothing to do. */
27931 if ( EQ (window
, hlinfo
->mouse_face_window
)
27932 && (!row
->reversed_p
27933 ? (hlinfo
->mouse_face_beg_col
<= hpos
27934 && hpos
< hlinfo
->mouse_face_end_col
)
27935 /* In R2L rows we swap BEG and END, see below. */
27936 : (hlinfo
->mouse_face_end_col
<= hpos
27937 && hpos
< hlinfo
->mouse_face_beg_col
))
27938 && hlinfo
->mouse_face_beg_row
== vpos
)
27941 if (clear_mouse_face (hlinfo
))
27942 cursor
= No_Cursor
;
27944 if (!row
->reversed_p
)
27946 hlinfo
->mouse_face_beg_col
= hpos
;
27947 hlinfo
->mouse_face_beg_x
= original_x_pixel
27948 - (total_pixel_width
+ dx
);
27949 hlinfo
->mouse_face_end_col
= hpos
+ gseq_length
;
27950 hlinfo
->mouse_face_end_x
= 0;
27954 /* In R2L rows, show_mouse_face expects BEG and END
27955 coordinates to be swapped. */
27956 hlinfo
->mouse_face_end_col
= hpos
;
27957 hlinfo
->mouse_face_end_x
= original_x_pixel
27958 - (total_pixel_width
+ dx
);
27959 hlinfo
->mouse_face_beg_col
= hpos
+ gseq_length
;
27960 hlinfo
->mouse_face_beg_x
= 0;
27963 hlinfo
->mouse_face_beg_row
= vpos
;
27964 hlinfo
->mouse_face_end_row
= hlinfo
->mouse_face_beg_row
;
27965 hlinfo
->mouse_face_past_end
= 0;
27966 hlinfo
->mouse_face_window
= window
;
27968 hlinfo
->mouse_face_face_id
= face_at_string_position (w
, string
,
27974 show_mouse_face (hlinfo
, DRAW_MOUSE_FACE
);
27976 if (NILP (pointer
))
27979 else if ((area
== ON_MODE_LINE
) || (area
== ON_HEADER_LINE
))
27980 clear_mouse_face (hlinfo
);
27982 #ifdef HAVE_WINDOW_SYSTEM
27983 if (FRAME_WINDOW_P (f
))
27984 define_frame_cursor1 (f
, cursor
, pointer
);
27990 Take proper action when the mouse has moved to position X, Y on
27991 frame F with regards to highlighting portions of display that have
27992 mouse-face properties. Also de-highlight portions of display where
27993 the mouse was before, set the mouse pointer shape as appropriate
27994 for the mouse coordinates, and activate help echo (tooltips).
27995 X and Y can be negative or out of range. */
27998 note_mouse_highlight (struct frame
*f
, int x
, int y
)
28000 Mouse_HLInfo
*hlinfo
= MOUSE_HL_INFO (f
);
28001 enum window_part part
= ON_NOTHING
;
28002 Lisp_Object window
;
28004 Cursor cursor
= No_Cursor
;
28005 Lisp_Object pointer
= Qnil
; /* Takes precedence over cursor! */
28008 /* When a menu is active, don't highlight because this looks odd. */
28009 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) || defined (MSDOS)
28010 if (popup_activated ())
28014 if (!f
->glyphs_initialized_p
28015 || f
->pointer_invisible
)
28018 hlinfo
->mouse_face_mouse_x
= x
;
28019 hlinfo
->mouse_face_mouse_y
= y
;
28020 hlinfo
->mouse_face_mouse_frame
= f
;
28022 if (hlinfo
->mouse_face_defer
)
28025 /* Which window is that in? */
28026 window
= window_from_coordinates (f
, x
, y
, &part
, 1);
28028 /* If displaying active text in another window, clear that. */
28029 if (! EQ (window
, hlinfo
->mouse_face_window
)
28030 /* Also clear if we move out of text area in same window. */
28031 || (!NILP (hlinfo
->mouse_face_window
)
28034 && part
!= ON_MODE_LINE
28035 && part
!= ON_HEADER_LINE
))
28036 clear_mouse_face (hlinfo
);
28038 /* Not on a window -> return. */
28039 if (!WINDOWP (window
))
28042 /* Reset help_echo_string. It will get recomputed below. */
28043 help_echo_string
= Qnil
;
28045 /* Convert to window-relative pixel coordinates. */
28046 w
= XWINDOW (window
);
28047 frame_to_window_pixel_xy (w
, &x
, &y
);
28049 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
28050 /* Handle tool-bar window differently since it doesn't display a
28052 if (EQ (window
, f
->tool_bar_window
))
28054 note_tool_bar_highlight (f
, x
, y
);
28059 /* Mouse is on the mode, header line or margin? */
28060 if (part
== ON_MODE_LINE
|| part
== ON_HEADER_LINE
28061 || part
== ON_LEFT_MARGIN
|| part
== ON_RIGHT_MARGIN
)
28063 note_mode_line_or_margin_highlight (window
, x
, y
, part
);
28067 #ifdef HAVE_WINDOW_SYSTEM
28068 if (part
== ON_VERTICAL_BORDER
)
28070 cursor
= FRAME_X_OUTPUT (f
)->horizontal_drag_cursor
;
28071 help_echo_string
= build_string ("drag-mouse-1: resize");
28073 else if (part
== ON_LEFT_FRINGE
|| part
== ON_RIGHT_FRINGE
28074 || part
== ON_SCROLL_BAR
)
28075 cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
28077 cursor
= FRAME_X_OUTPUT (f
)->text_cursor
;
28080 /* Are we in a window whose display is up to date?
28081 And verify the buffer's text has not changed. */
28082 b
= XBUFFER (w
->contents
);
28083 if (part
== ON_TEXT
&& w
->window_end_valid
&& !window_outdated (w
))
28085 int hpos
, vpos
, dx
, dy
, area
= LAST_AREA
;
28087 struct glyph
*glyph
;
28088 Lisp_Object object
;
28089 Lisp_Object mouse_face
= Qnil
, position
;
28090 Lisp_Object
*overlay_vec
= NULL
;
28091 ptrdiff_t i
, noverlays
;
28092 struct buffer
*obuf
;
28093 ptrdiff_t obegv
, ozv
;
28096 /* Find the glyph under X/Y. */
28097 glyph
= x_y_to_hpos_vpos (w
, x
, y
, &hpos
, &vpos
, &dx
, &dy
, &area
);
28099 #ifdef HAVE_WINDOW_SYSTEM
28100 /* Look for :pointer property on image. */
28101 if (glyph
!= NULL
&& glyph
->type
== IMAGE_GLYPH
)
28103 struct image
*img
= IMAGE_FROM_ID (f
, glyph
->u
.img_id
);
28104 if (img
!= NULL
&& IMAGEP (img
->spec
))
28106 Lisp_Object image_map
, hotspot
;
28107 if ((image_map
= Fplist_get (XCDR (img
->spec
), QCmap
),
28109 && (hotspot
= find_hot_spot (image_map
,
28110 glyph
->slice
.img
.x
+ dx
,
28111 glyph
->slice
.img
.y
+ dy
),
28113 && (hotspot
= XCDR (hotspot
), CONSP (hotspot
)))
28117 /* Could check XCAR (hotspot) to see if we enter/leave
28119 If so, we could look for mouse-enter, mouse-leave
28120 properties in PLIST (and do something...). */
28121 hotspot
= XCDR (hotspot
);
28122 if (CONSP (hotspot
)
28123 && (plist
= XCAR (hotspot
), CONSP (plist
)))
28125 pointer
= Fplist_get (plist
, Qpointer
);
28126 if (NILP (pointer
))
28128 help_echo_string
= Fplist_get (plist
, Qhelp_echo
);
28129 if (!NILP (help_echo_string
))
28131 help_echo_window
= window
;
28132 help_echo_object
= glyph
->object
;
28133 help_echo_pos
= glyph
->charpos
;
28137 if (NILP (pointer
))
28138 pointer
= Fplist_get (XCDR (img
->spec
), QCpointer
);
28141 #endif /* HAVE_WINDOW_SYSTEM */
28143 /* Clear mouse face if X/Y not over text. */
28145 || area
!= TEXT_AREA
28146 || !MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w
->current_matrix
, vpos
))
28147 /* Glyph's OBJECT is an integer for glyphs inserted by the
28148 display engine for its internal purposes, like truncation
28149 and continuation glyphs and blanks beyond the end of
28150 line's text on text terminals. If we are over such a
28151 glyph, we are not over any text. */
28152 || INTEGERP (glyph
->object
)
28153 /* R2L rows have a stretch glyph at their front, which
28154 stands for no text, whereas L2R rows have no glyphs at
28155 all beyond the end of text. Treat such stretch glyphs
28156 like we do with NULL glyphs in L2R rows. */
28157 || (MATRIX_ROW (w
->current_matrix
, vpos
)->reversed_p
28158 && glyph
== MATRIX_ROW_GLYPH_START (w
->current_matrix
, vpos
)
28159 && glyph
->type
== STRETCH_GLYPH
28160 && glyph
->avoid_cursor_p
))
28162 if (clear_mouse_face (hlinfo
))
28163 cursor
= No_Cursor
;
28164 #ifdef HAVE_WINDOW_SYSTEM
28165 if (FRAME_WINDOW_P (f
) && NILP (pointer
))
28167 if (area
!= TEXT_AREA
)
28168 cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
28170 pointer
= Vvoid_text_area_pointer
;
28176 pos
= glyph
->charpos
;
28177 object
= glyph
->object
;
28178 if (!STRINGP (object
) && !BUFFERP (object
))
28181 /* If we get an out-of-range value, return now; avoid an error. */
28182 if (BUFFERP (object
) && pos
> BUF_Z (b
))
28185 /* Make the window's buffer temporarily current for
28186 overlays_at and compute_char_face. */
28187 obuf
= current_buffer
;
28188 current_buffer
= b
;
28194 /* Is this char mouse-active or does it have help-echo? */
28195 position
= make_number (pos
);
28197 if (BUFFERP (object
))
28199 /* Put all the overlays we want in a vector in overlay_vec. */
28200 GET_OVERLAYS_AT (pos
, overlay_vec
, noverlays
, NULL
, 0);
28201 /* Sort overlays into increasing priority order. */
28202 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
28207 if (NILP (Vmouse_highlight
))
28209 clear_mouse_face (hlinfo
);
28210 goto check_help_echo
;
28213 same_region
= coords_in_mouse_face_p (w
, hpos
, vpos
);
28216 cursor
= No_Cursor
;
28218 /* Check mouse-face highlighting. */
28220 /* If there exists an overlay with mouse-face overlapping
28221 the one we are currently highlighting, we have to
28222 check if we enter the overlapping overlay, and then
28223 highlight only that. */
28224 || (OVERLAYP (hlinfo
->mouse_face_overlay
)
28225 && mouse_face_overlay_overlaps (hlinfo
->mouse_face_overlay
)))
28227 /* Find the highest priority overlay with a mouse-face. */
28228 Lisp_Object overlay
= Qnil
;
28229 for (i
= noverlays
- 1; i
>= 0 && NILP (overlay
); --i
)
28231 mouse_face
= Foverlay_get (overlay_vec
[i
], Qmouse_face
);
28232 if (!NILP (mouse_face
))
28233 overlay
= overlay_vec
[i
];
28236 /* If we're highlighting the same overlay as before, there's
28237 no need to do that again. */
28238 if (!NILP (overlay
) && EQ (overlay
, hlinfo
->mouse_face_overlay
))
28239 goto check_help_echo
;
28240 hlinfo
->mouse_face_overlay
= overlay
;
28242 /* Clear the display of the old active region, if any. */
28243 if (clear_mouse_face (hlinfo
))
28244 cursor
= No_Cursor
;
28246 /* If no overlay applies, get a text property. */
28247 if (NILP (overlay
))
28248 mouse_face
= Fget_text_property (position
, Qmouse_face
, object
);
28250 /* Next, compute the bounds of the mouse highlighting and
28252 if (!NILP (mouse_face
) && STRINGP (object
))
28254 /* The mouse-highlighting comes from a display string
28255 with a mouse-face. */
28259 s
= Fprevious_single_property_change
28260 (make_number (pos
+ 1), Qmouse_face
, object
, Qnil
);
28261 e
= Fnext_single_property_change
28262 (position
, Qmouse_face
, object
, Qnil
);
28264 s
= make_number (0);
28266 e
= make_number (SCHARS (object
) - 1);
28267 mouse_face_from_string_pos (w
, hlinfo
, object
,
28268 XINT (s
), XINT (e
));
28269 hlinfo
->mouse_face_past_end
= 0;
28270 hlinfo
->mouse_face_window
= window
;
28271 hlinfo
->mouse_face_face_id
28272 = face_at_string_position (w
, object
, pos
, 0, 0, 0, &ignore
,
28273 glyph
->face_id
, 1);
28274 show_mouse_face (hlinfo
, DRAW_MOUSE_FACE
);
28275 cursor
= No_Cursor
;
28279 /* The mouse-highlighting, if any, comes from an overlay
28280 or text property in the buffer. */
28281 Lisp_Object buffer
IF_LINT (= Qnil
);
28282 Lisp_Object disp_string
IF_LINT (= Qnil
);
28284 if (STRINGP (object
))
28286 /* If we are on a display string with no mouse-face,
28287 check if the text under it has one. */
28288 struct glyph_row
*r
= MATRIX_ROW (w
->current_matrix
, vpos
);
28289 ptrdiff_t start
= MATRIX_ROW_START_CHARPOS (r
);
28290 pos
= string_buffer_position (object
, start
);
28293 mouse_face
= get_char_property_and_overlay
28294 (make_number (pos
), Qmouse_face
, w
->contents
, &overlay
);
28295 buffer
= w
->contents
;
28296 disp_string
= object
;
28302 disp_string
= Qnil
;
28305 if (!NILP (mouse_face
))
28307 Lisp_Object before
, after
;
28308 Lisp_Object before_string
, after_string
;
28309 /* To correctly find the limits of mouse highlight
28310 in a bidi-reordered buffer, we must not use the
28311 optimization of limiting the search in
28312 previous-single-property-change and
28313 next-single-property-change, because
28314 rows_from_pos_range needs the real start and end
28315 positions to DTRT in this case. That's because
28316 the first row visible in a window does not
28317 necessarily display the character whose position
28318 is the smallest. */
28320 NILP (BVAR (XBUFFER (buffer
), bidi_display_reordering
))
28321 ? Fmarker_position (w
->start
)
28324 NILP (BVAR (XBUFFER (buffer
), bidi_display_reordering
))
28325 ? make_number (BUF_Z (XBUFFER (buffer
)) - w
->window_end_pos
)
28328 if (NILP (overlay
))
28330 /* Handle the text property case. */
28331 before
= Fprevious_single_property_change
28332 (make_number (pos
+ 1), Qmouse_face
, buffer
, lim1
);
28333 after
= Fnext_single_property_change
28334 (make_number (pos
), Qmouse_face
, buffer
, lim2
);
28335 before_string
= after_string
= Qnil
;
28339 /* Handle the overlay case. */
28340 before
= Foverlay_start (overlay
);
28341 after
= Foverlay_end (overlay
);
28342 before_string
= Foverlay_get (overlay
, Qbefore_string
);
28343 after_string
= Foverlay_get (overlay
, Qafter_string
);
28345 if (!STRINGP (before_string
)) before_string
= Qnil
;
28346 if (!STRINGP (after_string
)) after_string
= Qnil
;
28349 mouse_face_from_buffer_pos (window
, hlinfo
, pos
,
28352 : XFASTINT (before
),
28354 ? BUF_Z (XBUFFER (buffer
))
28355 : XFASTINT (after
),
28356 before_string
, after_string
,
28358 cursor
= No_Cursor
;
28365 /* Look for a `help-echo' property. */
28366 if (NILP (help_echo_string
)) {
28367 Lisp_Object help
, overlay
;
28369 /* Check overlays first. */
28370 help
= overlay
= Qnil
;
28371 for (i
= noverlays
- 1; i
>= 0 && NILP (help
); --i
)
28373 overlay
= overlay_vec
[i
];
28374 help
= Foverlay_get (overlay
, Qhelp_echo
);
28379 help_echo_string
= help
;
28380 help_echo_window
= window
;
28381 help_echo_object
= overlay
;
28382 help_echo_pos
= pos
;
28386 Lisp_Object obj
= glyph
->object
;
28387 ptrdiff_t charpos
= glyph
->charpos
;
28389 /* Try text properties. */
28392 && charpos
< SCHARS (obj
))
28394 help
= Fget_text_property (make_number (charpos
),
28398 /* If the string itself doesn't specify a help-echo,
28399 see if the buffer text ``under'' it does. */
28400 struct glyph_row
*r
28401 = MATRIX_ROW (w
->current_matrix
, vpos
);
28402 ptrdiff_t start
= MATRIX_ROW_START_CHARPOS (r
);
28403 ptrdiff_t p
= string_buffer_position (obj
, start
);
28406 help
= Fget_char_property (make_number (p
),
28407 Qhelp_echo
, w
->contents
);
28416 else if (BUFFERP (obj
)
28419 help
= Fget_text_property (make_number (charpos
), Qhelp_echo
,
28424 help_echo_string
= help
;
28425 help_echo_window
= window
;
28426 help_echo_object
= obj
;
28427 help_echo_pos
= charpos
;
28432 #ifdef HAVE_WINDOW_SYSTEM
28433 /* Look for a `pointer' property. */
28434 if (FRAME_WINDOW_P (f
) && NILP (pointer
))
28436 /* Check overlays first. */
28437 for (i
= noverlays
- 1; i
>= 0 && NILP (pointer
); --i
)
28438 pointer
= Foverlay_get (overlay_vec
[i
], Qpointer
);
28440 if (NILP (pointer
))
28442 Lisp_Object obj
= glyph
->object
;
28443 ptrdiff_t charpos
= glyph
->charpos
;
28445 /* Try text properties. */
28448 && charpos
< SCHARS (obj
))
28450 pointer
= Fget_text_property (make_number (charpos
),
28452 if (NILP (pointer
))
28454 /* If the string itself doesn't specify a pointer,
28455 see if the buffer text ``under'' it does. */
28456 struct glyph_row
*r
28457 = MATRIX_ROW (w
->current_matrix
, vpos
);
28458 ptrdiff_t start
= MATRIX_ROW_START_CHARPOS (r
);
28459 ptrdiff_t p
= string_buffer_position (obj
, start
);
28461 pointer
= Fget_char_property (make_number (p
),
28462 Qpointer
, w
->contents
);
28465 else if (BUFFERP (obj
)
28468 pointer
= Fget_text_property (make_number (charpos
),
28472 #endif /* HAVE_WINDOW_SYSTEM */
28476 current_buffer
= obuf
;
28481 #ifdef HAVE_WINDOW_SYSTEM
28482 if (FRAME_WINDOW_P (f
))
28483 define_frame_cursor1 (f
, cursor
, pointer
);
28485 /* This is here to prevent a compiler error, about "label at end of
28486 compound statement". */
28493 Clear any mouse-face on window W. This function is part of the
28494 redisplay interface, and is called from try_window_id and similar
28495 functions to ensure the mouse-highlight is off. */
28498 x_clear_window_mouse_face (struct window
*w
)
28500 Mouse_HLInfo
*hlinfo
= MOUSE_HL_INFO (XFRAME (w
->frame
));
28501 Lisp_Object window
;
28504 XSETWINDOW (window
, w
);
28505 if (EQ (window
, hlinfo
->mouse_face_window
))
28506 clear_mouse_face (hlinfo
);
28512 Just discard the mouse face information for frame F, if any.
28513 This is used when the size of F is changed. */
28516 cancel_mouse_face (struct frame
*f
)
28518 Lisp_Object window
;
28519 Mouse_HLInfo
*hlinfo
= MOUSE_HL_INFO (f
);
28521 window
= hlinfo
->mouse_face_window
;
28522 if (! NILP (window
) && XFRAME (XWINDOW (window
)->frame
) == f
)
28523 reset_mouse_highlight (hlinfo
);
28528 /***********************************************************************
28530 ***********************************************************************/
28532 #ifdef HAVE_WINDOW_SYSTEM
28534 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
28535 which intersects rectangle R. R is in window-relative coordinates. */
28538 expose_area (struct window
*w
, struct glyph_row
*row
, XRectangle
*r
,
28539 enum glyph_row_area area
)
28541 struct glyph
*first
= row
->glyphs
[area
];
28542 struct glyph
*end
= row
->glyphs
[area
] + row
->used
[area
];
28543 struct glyph
*last
;
28544 int first_x
, start_x
, x
;
28546 if (area
== TEXT_AREA
&& row
->fill_line_p
)
28547 /* If row extends face to end of line write the whole line. */
28548 draw_glyphs (w
, 0, row
, area
,
28549 0, row
->used
[area
],
28550 DRAW_NORMAL_TEXT
, 0);
28553 /* Set START_X to the window-relative start position for drawing glyphs of
28554 AREA. The first glyph of the text area can be partially visible.
28555 The first glyphs of other areas cannot. */
28556 start_x
= window_box_left_offset (w
, area
);
28558 if (area
== TEXT_AREA
)
28561 /* Find the first glyph that must be redrawn. */
28563 && x
+ first
->pixel_width
< r
->x
)
28565 x
+= first
->pixel_width
;
28569 /* Find the last one. */
28573 && x
< r
->x
+ r
->width
)
28575 x
+= last
->pixel_width
;
28581 draw_glyphs (w
, first_x
- start_x
, row
, area
,
28582 first
- row
->glyphs
[area
], last
- row
->glyphs
[area
],
28583 DRAW_NORMAL_TEXT
, 0);
28588 /* Redraw the parts of the glyph row ROW on window W intersecting
28589 rectangle R. R is in window-relative coordinates. Value is
28590 non-zero if mouse-face was overwritten. */
28593 expose_line (struct window
*w
, struct glyph_row
*row
, XRectangle
*r
)
28595 eassert (row
->enabled_p
);
28597 if (row
->mode_line_p
|| w
->pseudo_window_p
)
28598 draw_glyphs (w
, 0, row
, TEXT_AREA
,
28599 0, row
->used
[TEXT_AREA
],
28600 DRAW_NORMAL_TEXT
, 0);
28603 if (row
->used
[LEFT_MARGIN_AREA
])
28604 expose_area (w
, row
, r
, LEFT_MARGIN_AREA
);
28605 if (row
->used
[TEXT_AREA
])
28606 expose_area (w
, row
, r
, TEXT_AREA
);
28607 if (row
->used
[RIGHT_MARGIN_AREA
])
28608 expose_area (w
, row
, r
, RIGHT_MARGIN_AREA
);
28609 draw_row_fringe_bitmaps (w
, row
);
28612 return row
->mouse_face_p
;
28616 /* Redraw those parts of glyphs rows during expose event handling that
28617 overlap other rows. Redrawing of an exposed line writes over parts
28618 of lines overlapping that exposed line; this function fixes that.
28620 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
28621 row in W's current matrix that is exposed and overlaps other rows.
28622 LAST_OVERLAPPING_ROW is the last such row. */
28625 expose_overlaps (struct window
*w
,
28626 struct glyph_row
*first_overlapping_row
,
28627 struct glyph_row
*last_overlapping_row
,
28630 struct glyph_row
*row
;
28632 for (row
= first_overlapping_row
; row
<= last_overlapping_row
; ++row
)
28633 if (row
->overlapping_p
)
28635 eassert (row
->enabled_p
&& !row
->mode_line_p
);
28638 if (row
->used
[LEFT_MARGIN_AREA
])
28639 x_fix_overlapping_area (w
, row
, LEFT_MARGIN_AREA
, OVERLAPS_BOTH
);
28641 if (row
->used
[TEXT_AREA
])
28642 x_fix_overlapping_area (w
, row
, TEXT_AREA
, OVERLAPS_BOTH
);
28644 if (row
->used
[RIGHT_MARGIN_AREA
])
28645 x_fix_overlapping_area (w
, row
, RIGHT_MARGIN_AREA
, OVERLAPS_BOTH
);
28651 /* Return non-zero if W's cursor intersects rectangle R. */
28654 phys_cursor_in_rect_p (struct window
*w
, XRectangle
*r
)
28656 XRectangle cr
, result
;
28657 struct glyph
*cursor_glyph
;
28658 struct glyph_row
*row
;
28660 if (w
->phys_cursor
.vpos
>= 0
28661 && w
->phys_cursor
.vpos
< w
->current_matrix
->nrows
28662 && (row
= MATRIX_ROW (w
->current_matrix
, w
->phys_cursor
.vpos
),
28664 && row
->cursor_in_fringe_p
)
28666 /* Cursor is in the fringe. */
28667 cr
.x
= window_box_right_offset (w
,
28668 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
28669 ? RIGHT_MARGIN_AREA
28672 cr
.width
= WINDOW_RIGHT_FRINGE_WIDTH (w
);
28673 cr
.height
= row
->height
;
28674 return x_intersect_rectangles (&cr
, r
, &result
);
28677 cursor_glyph
= get_phys_cursor_glyph (w
);
28680 /* r is relative to W's box, but w->phys_cursor.x is relative
28681 to left edge of W's TEXT area. Adjust it. */
28682 cr
.x
= window_box_left_offset (w
, TEXT_AREA
) + w
->phys_cursor
.x
;
28683 cr
.y
= w
->phys_cursor
.y
;
28684 cr
.width
= cursor_glyph
->pixel_width
;
28685 cr
.height
= w
->phys_cursor_height
;
28686 /* ++KFS: W32 version used W32-specific IntersectRect here, but
28687 I assume the effect is the same -- and this is portable. */
28688 return x_intersect_rectangles (&cr
, r
, &result
);
28690 /* If we don't understand the format, pretend we're not in the hot-spot. */
28696 Draw a vertical window border to the right of window W if W doesn't
28697 have vertical scroll bars. */
28700 x_draw_vertical_border (struct window
*w
)
28702 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
28704 /* We could do better, if we knew what type of scroll-bar the adjacent
28705 windows (on either side) have... But we don't :-(
28706 However, I think this works ok. ++KFS 2003-04-25 */
28708 /* Redraw borders between horizontally adjacent windows. Don't
28709 do it for frames with vertical scroll bars because either the
28710 right scroll bar of a window, or the left scroll bar of its
28711 neighbor will suffice as a border. */
28712 if (FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (w
->frame
)))
28715 /* Note: It is necessary to redraw both the left and the right
28716 borders, for when only this single window W is being
28718 if (!WINDOW_RIGHTMOST_P (w
)
28719 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w
))
28721 int x0
, x1
, y0
, y1
;
28723 window_box_edges (w
, &x0
, &y0
, &x1
, &y1
);
28726 if (WINDOW_LEFT_FRINGE_WIDTH (w
) == 0)
28729 FRAME_RIF (f
)->draw_vertical_window_border (w
, x1
, y0
, y1
);
28731 if (!WINDOW_LEFTMOST_P (w
)
28732 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w
))
28734 int x0
, x1
, y0
, y1
;
28736 window_box_edges (w
, &x0
, &y0
, &x1
, &y1
);
28739 if (WINDOW_LEFT_FRINGE_WIDTH (w
) == 0)
28742 FRAME_RIF (f
)->draw_vertical_window_border (w
, x0
, y0
, y1
);
28747 /* Redraw the part of window W intersection rectangle FR. Pixel
28748 coordinates in FR are frame-relative. Call this function with
28749 input blocked. Value is non-zero if the exposure overwrites
28753 expose_window (struct window
*w
, XRectangle
*fr
)
28755 struct frame
*f
= XFRAME (w
->frame
);
28757 int mouse_face_overwritten_p
= 0;
28759 /* If window is not yet fully initialized, do nothing. This can
28760 happen when toolkit scroll bars are used and a window is split.
28761 Reconfiguring the scroll bar will generate an expose for a newly
28763 if (w
->current_matrix
== NULL
)
28766 /* When we're currently updating the window, display and current
28767 matrix usually don't agree. Arrange for a thorough display
28769 if (w
->must_be_updated_p
)
28771 SET_FRAME_GARBAGED (f
);
28775 /* Frame-relative pixel rectangle of W. */
28776 wr
.x
= WINDOW_LEFT_EDGE_X (w
);
28777 wr
.y
= WINDOW_TOP_EDGE_Y (w
);
28778 wr
.width
= WINDOW_TOTAL_WIDTH (w
);
28779 wr
.height
= WINDOW_TOTAL_HEIGHT (w
);
28781 if (x_intersect_rectangles (fr
, &wr
, &r
))
28783 int yb
= window_text_bottom_y (w
);
28784 struct glyph_row
*row
;
28785 int cursor_cleared_p
, phys_cursor_on_p
;
28786 struct glyph_row
*first_overlapping_row
, *last_overlapping_row
;
28788 TRACE ((stderr
, "expose_window (%d, %d, %d, %d)\n",
28789 r
.x
, r
.y
, r
.width
, r
.height
));
28791 /* Convert to window coordinates. */
28792 r
.x
-= WINDOW_LEFT_EDGE_X (w
);
28793 r
.y
-= WINDOW_TOP_EDGE_Y (w
);
28795 /* Turn off the cursor. */
28796 if (!w
->pseudo_window_p
28797 && phys_cursor_in_rect_p (w
, &r
))
28799 x_clear_cursor (w
);
28800 cursor_cleared_p
= 1;
28803 cursor_cleared_p
= 0;
28805 /* If the row containing the cursor extends face to end of line,
28806 then expose_area might overwrite the cursor outside the
28807 rectangle and thus notice_overwritten_cursor might clear
28808 w->phys_cursor_on_p. We remember the original value and
28809 check later if it is changed. */
28810 phys_cursor_on_p
= w
->phys_cursor_on_p
;
28812 /* Update lines intersecting rectangle R. */
28813 first_overlapping_row
= last_overlapping_row
= NULL
;
28814 for (row
= w
->current_matrix
->rows
;
28819 int y1
= MATRIX_ROW_BOTTOM_Y (row
);
28821 if ((y0
>= r
.y
&& y0
< r
.y
+ r
.height
)
28822 || (y1
> r
.y
&& y1
< r
.y
+ r
.height
)
28823 || (r
.y
>= y0
&& r
.y
< y1
)
28824 || (r
.y
+ r
.height
> y0
&& r
.y
+ r
.height
< y1
))
28826 /* A header line may be overlapping, but there is no need
28827 to fix overlapping areas for them. KFS 2005-02-12 */
28828 if (row
->overlapping_p
&& !row
->mode_line_p
)
28830 if (first_overlapping_row
== NULL
)
28831 first_overlapping_row
= row
;
28832 last_overlapping_row
= row
;
28836 if (expose_line (w
, row
, &r
))
28837 mouse_face_overwritten_p
= 1;
28840 else if (row
->overlapping_p
)
28842 /* We must redraw a row overlapping the exposed area. */
28844 ? y0
+ row
->phys_height
> r
.y
28845 : y0
+ row
->ascent
- row
->phys_ascent
< r
.y
+r
.height
)
28847 if (first_overlapping_row
== NULL
)
28848 first_overlapping_row
= row
;
28849 last_overlapping_row
= row
;
28857 /* Display the mode line if there is one. */
28858 if (WINDOW_WANTS_MODELINE_P (w
)
28859 && (row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
),
28861 && row
->y
< r
.y
+ r
.height
)
28863 if (expose_line (w
, row
, &r
))
28864 mouse_face_overwritten_p
= 1;
28867 if (!w
->pseudo_window_p
)
28869 /* Fix the display of overlapping rows. */
28870 if (first_overlapping_row
)
28871 expose_overlaps (w
, first_overlapping_row
, last_overlapping_row
,
28874 /* Draw border between windows. */
28875 x_draw_vertical_border (w
);
28877 /* Turn the cursor on again. */
28878 if (cursor_cleared_p
28879 || (phys_cursor_on_p
&& !w
->phys_cursor_on_p
))
28880 update_window_cursor (w
, 1);
28884 return mouse_face_overwritten_p
;
28889 /* Redraw (parts) of all windows in the window tree rooted at W that
28890 intersect R. R contains frame pixel coordinates. Value is
28891 non-zero if the exposure overwrites mouse-face. */
28894 expose_window_tree (struct window
*w
, XRectangle
*r
)
28896 struct frame
*f
= XFRAME (w
->frame
);
28897 int mouse_face_overwritten_p
= 0;
28899 while (w
&& !FRAME_GARBAGED_P (f
))
28901 if (WINDOWP (w
->contents
))
28902 mouse_face_overwritten_p
28903 |= expose_window_tree (XWINDOW (w
->contents
), r
);
28905 mouse_face_overwritten_p
|= expose_window (w
, r
);
28907 w
= NILP (w
->next
) ? NULL
: XWINDOW (w
->next
);
28910 return mouse_face_overwritten_p
;
28915 Redisplay an exposed area of frame F. X and Y are the upper-left
28916 corner of the exposed rectangle. W and H are width and height of
28917 the exposed area. All are pixel values. W or H zero means redraw
28918 the entire frame. */
28921 expose_frame (struct frame
*f
, int x
, int y
, int w
, int h
)
28924 int mouse_face_overwritten_p
= 0;
28926 TRACE ((stderr
, "expose_frame "));
28928 /* No need to redraw if frame will be redrawn soon. */
28929 if (FRAME_GARBAGED_P (f
))
28931 TRACE ((stderr
, " garbaged\n"));
28935 /* If basic faces haven't been realized yet, there is no point in
28936 trying to redraw anything. This can happen when we get an expose
28937 event while Emacs is starting, e.g. by moving another window. */
28938 if (FRAME_FACE_CACHE (f
) == NULL
28939 || FRAME_FACE_CACHE (f
)->used
< BASIC_FACE_ID_SENTINEL
)
28941 TRACE ((stderr
, " no faces\n"));
28945 if (w
== 0 || h
== 0)
28948 r
.width
= FRAME_COLUMN_WIDTH (f
) * FRAME_COLS (f
);
28949 r
.height
= FRAME_LINE_HEIGHT (f
) * FRAME_LINES (f
);
28959 TRACE ((stderr
, "(%d, %d, %d, %d)\n", r
.x
, r
.y
, r
.width
, r
.height
));
28960 mouse_face_overwritten_p
= expose_window_tree (XWINDOW (f
->root_window
), &r
);
28962 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
28963 if (WINDOWP (f
->tool_bar_window
))
28964 mouse_face_overwritten_p
28965 |= expose_window (XWINDOW (f
->tool_bar_window
), &r
);
28968 #ifdef HAVE_X_WINDOWS
28970 #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
28971 if (WINDOWP (f
->menu_bar_window
))
28972 mouse_face_overwritten_p
28973 |= expose_window (XWINDOW (f
->menu_bar_window
), &r
);
28974 #endif /* not USE_X_TOOLKIT and not USE_GTK */
28978 /* Some window managers support a focus-follows-mouse style with
28979 delayed raising of frames. Imagine a partially obscured frame,
28980 and moving the mouse into partially obscured mouse-face on that
28981 frame. The visible part of the mouse-face will be highlighted,
28982 then the WM raises the obscured frame. With at least one WM, KDE
28983 2.1, Emacs is not getting any event for the raising of the frame
28984 (even tried with SubstructureRedirectMask), only Expose events.
28985 These expose events will draw text normally, i.e. not
28986 highlighted. Which means we must redo the highlight here.
28987 Subsume it under ``we love X''. --gerd 2001-08-15 */
28988 /* Included in Windows version because Windows most likely does not
28989 do the right thing if any third party tool offers
28990 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
28991 if (mouse_face_overwritten_p
&& !FRAME_GARBAGED_P (f
))
28993 Mouse_HLInfo
*hlinfo
= MOUSE_HL_INFO (f
);
28994 if (f
== hlinfo
->mouse_face_mouse_frame
)
28996 int mouse_x
= hlinfo
->mouse_face_mouse_x
;
28997 int mouse_y
= hlinfo
->mouse_face_mouse_y
;
28998 clear_mouse_face (hlinfo
);
28999 note_mouse_highlight (f
, mouse_x
, mouse_y
);
29006 Determine the intersection of two rectangles R1 and R2. Return
29007 the intersection in *RESULT. Value is non-zero if RESULT is not
29011 x_intersect_rectangles (XRectangle
*r1
, XRectangle
*r2
, XRectangle
*result
)
29013 XRectangle
*left
, *right
;
29014 XRectangle
*upper
, *lower
;
29015 int intersection_p
= 0;
29017 /* Rearrange so that R1 is the left-most rectangle. */
29019 left
= r1
, right
= r2
;
29021 left
= r2
, right
= r1
;
29023 /* X0 of the intersection is right.x0, if this is inside R1,
29024 otherwise there is no intersection. */
29025 if (right
->x
<= left
->x
+ left
->width
)
29027 result
->x
= right
->x
;
29029 /* The right end of the intersection is the minimum of
29030 the right ends of left and right. */
29031 result
->width
= (min (left
->x
+ left
->width
, right
->x
+ right
->width
)
29034 /* Same game for Y. */
29036 upper
= r1
, lower
= r2
;
29038 upper
= r2
, lower
= r1
;
29040 /* The upper end of the intersection is lower.y0, if this is inside
29041 of upper. Otherwise, there is no intersection. */
29042 if (lower
->y
<= upper
->y
+ upper
->height
)
29044 result
->y
= lower
->y
;
29046 /* The lower end of the intersection is the minimum of the lower
29047 ends of upper and lower. */
29048 result
->height
= (min (lower
->y
+ lower
->height
,
29049 upper
->y
+ upper
->height
)
29051 intersection_p
= 1;
29055 return intersection_p
;
29058 #endif /* HAVE_WINDOW_SYSTEM */
29061 /***********************************************************************
29063 ***********************************************************************/
29066 syms_of_xdisp (void)
29068 Vwith_echo_area_save_vector
= Qnil
;
29069 staticpro (&Vwith_echo_area_save_vector
);
29071 Vmessage_stack
= Qnil
;
29072 staticpro (&Vmessage_stack
);
29074 DEFSYM (Qinhibit_redisplay
, "inhibit-redisplay");
29075 DEFSYM (Qredisplay_internal
, "redisplay_internal (C function)");
29077 message_dolog_marker1
= Fmake_marker ();
29078 staticpro (&message_dolog_marker1
);
29079 message_dolog_marker2
= Fmake_marker ();
29080 staticpro (&message_dolog_marker2
);
29081 message_dolog_marker3
= Fmake_marker ();
29082 staticpro (&message_dolog_marker3
);
29085 defsubr (&Sdump_frame_glyph_matrix
);
29086 defsubr (&Sdump_glyph_matrix
);
29087 defsubr (&Sdump_glyph_row
);
29088 defsubr (&Sdump_tool_bar_row
);
29089 defsubr (&Strace_redisplay
);
29090 defsubr (&Strace_to_stderr
);
29092 #ifdef HAVE_WINDOW_SYSTEM
29093 defsubr (&Stool_bar_lines_needed
);
29094 defsubr (&Slookup_image_map
);
29096 defsubr (&Sline_pixel_height
);
29097 defsubr (&Sformat_mode_line
);
29098 defsubr (&Sinvisible_p
);
29099 defsubr (&Scurrent_bidi_paragraph_direction
);
29100 defsubr (&Smove_point_visually
);
29102 DEFSYM (Qmenu_bar_update_hook
, "menu-bar-update-hook");
29103 DEFSYM (Qoverriding_terminal_local_map
, "overriding-terminal-local-map");
29104 DEFSYM (Qoverriding_local_map
, "overriding-local-map");
29105 DEFSYM (Qwindow_scroll_functions
, "window-scroll-functions");
29106 DEFSYM (Qwindow_text_change_functions
, "window-text-change-functions");
29107 DEFSYM (Qredisplay_end_trigger_functions
, "redisplay-end-trigger-functions");
29108 DEFSYM (Qinhibit_point_motion_hooks
, "inhibit-point-motion-hooks");
29109 DEFSYM (Qeval
, "eval");
29110 DEFSYM (QCdata
, ":data");
29111 DEFSYM (Qdisplay
, "display");
29112 DEFSYM (Qspace_width
, "space-width");
29113 DEFSYM (Qraise
, "raise");
29114 DEFSYM (Qslice
, "slice");
29115 DEFSYM (Qspace
, "space");
29116 DEFSYM (Qmargin
, "margin");
29117 DEFSYM (Qpointer
, "pointer");
29118 DEFSYM (Qleft_margin
, "left-margin");
29119 DEFSYM (Qright_margin
, "right-margin");
29120 DEFSYM (Qcenter
, "center");
29121 DEFSYM (Qline_height
, "line-height");
29122 DEFSYM (QCalign_to
, ":align-to");
29123 DEFSYM (QCrelative_width
, ":relative-width");
29124 DEFSYM (QCrelative_height
, ":relative-height");
29125 DEFSYM (QCeval
, ":eval");
29126 DEFSYM (QCpropertize
, ":propertize");
29127 DEFSYM (QCfile
, ":file");
29128 DEFSYM (Qfontified
, "fontified");
29129 DEFSYM (Qfontification_functions
, "fontification-functions");
29130 DEFSYM (Qtrailing_whitespace
, "trailing-whitespace");
29131 DEFSYM (Qescape_glyph
, "escape-glyph");
29132 DEFSYM (Qnobreak_space
, "nobreak-space");
29133 DEFSYM (Qimage
, "image");
29134 DEFSYM (Qtext
, "text");
29135 DEFSYM (Qboth
, "both");
29136 DEFSYM (Qboth_horiz
, "both-horiz");
29137 DEFSYM (Qtext_image_horiz
, "text-image-horiz");
29138 DEFSYM (QCmap
, ":map");
29139 DEFSYM (QCpointer
, ":pointer");
29140 DEFSYM (Qrect
, "rect");
29141 DEFSYM (Qcircle
, "circle");
29142 DEFSYM (Qpoly
, "poly");
29143 DEFSYM (Qmessage_truncate_lines
, "message-truncate-lines");
29144 DEFSYM (Qgrow_only
, "grow-only");
29145 DEFSYM (Qinhibit_menubar_update
, "inhibit-menubar-update");
29146 DEFSYM (Qinhibit_eval_during_redisplay
, "inhibit-eval-during-redisplay");
29147 DEFSYM (Qposition
, "position");
29148 DEFSYM (Qbuffer_position
, "buffer-position");
29149 DEFSYM (Qobject
, "object");
29150 DEFSYM (Qbar
, "bar");
29151 DEFSYM (Qhbar
, "hbar");
29152 DEFSYM (Qbox
, "box");
29153 DEFSYM (Qhollow
, "hollow");
29154 DEFSYM (Qhand
, "hand");
29155 DEFSYM (Qarrow
, "arrow");
29156 DEFSYM (Qinhibit_free_realized_faces
, "inhibit-free-realized-faces");
29158 list_of_error
= list1 (list2 (intern_c_string ("error"),
29159 intern_c_string ("void-variable")));
29160 staticpro (&list_of_error
);
29162 DEFSYM (Qlast_arrow_position
, "last-arrow-position");
29163 DEFSYM (Qlast_arrow_string
, "last-arrow-string");
29164 DEFSYM (Qoverlay_arrow_string
, "overlay-arrow-string");
29165 DEFSYM (Qoverlay_arrow_bitmap
, "overlay-arrow-bitmap");
29167 echo_buffer
[0] = echo_buffer
[1] = Qnil
;
29168 staticpro (&echo_buffer
[0]);
29169 staticpro (&echo_buffer
[1]);
29171 echo_area_buffer
[0] = echo_area_buffer
[1] = Qnil
;
29172 staticpro (&echo_area_buffer
[0]);
29173 staticpro (&echo_area_buffer
[1]);
29175 Vmessages_buffer_name
= build_pure_c_string ("*Messages*");
29176 staticpro (&Vmessages_buffer_name
);
29178 mode_line_proptrans_alist
= Qnil
;
29179 staticpro (&mode_line_proptrans_alist
);
29180 mode_line_string_list
= Qnil
;
29181 staticpro (&mode_line_string_list
);
29182 mode_line_string_face
= Qnil
;
29183 staticpro (&mode_line_string_face
);
29184 mode_line_string_face_prop
= Qnil
;
29185 staticpro (&mode_line_string_face_prop
);
29186 Vmode_line_unwind_vector
= Qnil
;
29187 staticpro (&Vmode_line_unwind_vector
);
29189 DEFSYM (Qmode_line_default_help_echo
, "mode-line-default-help-echo");
29191 help_echo_string
= Qnil
;
29192 staticpro (&help_echo_string
);
29193 help_echo_object
= Qnil
;
29194 staticpro (&help_echo_object
);
29195 help_echo_window
= Qnil
;
29196 staticpro (&help_echo_window
);
29197 previous_help_echo_string
= Qnil
;
29198 staticpro (&previous_help_echo_string
);
29199 help_echo_pos
= -1;
29201 DEFSYM (Qright_to_left
, "right-to-left");
29202 DEFSYM (Qleft_to_right
, "left-to-right");
29204 #ifdef HAVE_WINDOW_SYSTEM
29205 DEFVAR_BOOL ("x-stretch-cursor", x_stretch_cursor_p
,
29206 doc
: /* Non-nil means draw block cursor as wide as the glyph under it.
29207 For example, if a block cursor is over a tab, it will be drawn as
29208 wide as that tab on the display. */);
29209 x_stretch_cursor_p
= 0;
29212 DEFVAR_LISP ("show-trailing-whitespace", Vshow_trailing_whitespace
,
29213 doc
: /* Non-nil means highlight trailing whitespace.
29214 The face used for trailing whitespace is `trailing-whitespace'. */);
29215 Vshow_trailing_whitespace
= Qnil
;
29217 DEFVAR_LISP ("nobreak-char-display", Vnobreak_char_display
,
29218 doc
: /* Control highlighting of non-ASCII space and hyphen chars.
29219 If the value is t, Emacs highlights non-ASCII chars which have the
29220 same appearance as an ASCII space or hyphen, using the `nobreak-space'
29221 or `escape-glyph' face respectively.
29223 U+00A0 (no-break space), U+00AD (soft hyphen), U+2010 (hyphen), and
29224 U+2011 (non-breaking hyphen) are affected.
29226 Any other non-nil value means to display these characters as a escape
29227 glyph followed by an ordinary space or hyphen.
29229 A value of nil means no special handling of these characters. */);
29230 Vnobreak_char_display
= Qt
;
29232 DEFVAR_LISP ("void-text-area-pointer", Vvoid_text_area_pointer
,
29233 doc
: /* The pointer shape to show in void text areas.
29234 A value of nil means to show the text pointer. Other options are `arrow',
29235 `text', `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
29236 Vvoid_text_area_pointer
= Qarrow
;
29238 DEFVAR_LISP ("inhibit-redisplay", Vinhibit_redisplay
,
29239 doc
: /* Non-nil means don't actually do any redisplay.
29240 This is used for internal purposes. */);
29241 Vinhibit_redisplay
= Qnil
;
29243 DEFVAR_LISP ("global-mode-string", Vglobal_mode_string
,
29244 doc
: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
29245 Vglobal_mode_string
= Qnil
;
29247 DEFVAR_LISP ("overlay-arrow-position", Voverlay_arrow_position
,
29248 doc
: /* Marker for where to display an arrow on top of the buffer text.
29249 This must be the beginning of a line in order to work.
29250 See also `overlay-arrow-string'. */);
29251 Voverlay_arrow_position
= Qnil
;
29253 DEFVAR_LISP ("overlay-arrow-string", Voverlay_arrow_string
,
29254 doc
: /* String to display as an arrow in non-window frames.
29255 See also `overlay-arrow-position'. */);
29256 Voverlay_arrow_string
= build_pure_c_string ("=>");
29258 DEFVAR_LISP ("overlay-arrow-variable-list", Voverlay_arrow_variable_list
,
29259 doc
: /* List of variables (symbols) which hold markers for overlay arrows.
29260 The symbols on this list are examined during redisplay to determine
29261 where to display overlay arrows. */);
29262 Voverlay_arrow_variable_list
29263 = list1 (intern_c_string ("overlay-arrow-position"));
29265 DEFVAR_INT ("scroll-step", emacs_scroll_step
,
29266 doc
: /* The number of lines to try scrolling a window by when point moves out.
29267 If that fails to bring point back on frame, point is centered instead.
29268 If this is zero, point is always centered after it moves off frame.
29269 If you want scrolling to always be a line at a time, you should set
29270 `scroll-conservatively' to a large value rather than set this to 1. */);
29272 DEFVAR_INT ("scroll-conservatively", scroll_conservatively
,
29273 doc
: /* Scroll up to this many lines, to bring point back on screen.
29274 If point moves off-screen, redisplay will scroll by up to
29275 `scroll-conservatively' lines in order to bring point just barely
29276 onto the screen again. If that cannot be done, then redisplay
29277 recenters point as usual.
29279 If the value is greater than 100, redisplay will never recenter point,
29280 but will always scroll just enough text to bring point into view, even
29281 if you move far away.
29283 A value of zero means always recenter point if it moves off screen. */);
29284 scroll_conservatively
= 0;
29286 DEFVAR_INT ("scroll-margin", scroll_margin
,
29287 doc
: /* Number of lines of margin at the top and bottom of a window.
29288 Recenter the window whenever point gets within this many lines
29289 of the top or bottom of the window. */);
29292 DEFVAR_LISP ("display-pixels-per-inch", Vdisplay_pixels_per_inch
,
29293 doc
: /* Pixels per inch value for non-window system displays.
29294 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
29295 Vdisplay_pixels_per_inch
= make_float (72.0);
29298 DEFVAR_INT ("debug-end-pos", debug_end_pos
, doc
: /* Don't ask. */);
29301 DEFVAR_LISP ("truncate-partial-width-windows",
29302 Vtruncate_partial_width_windows
,
29303 doc
: /* Non-nil means truncate lines in windows narrower than the frame.
29304 For an integer value, truncate lines in each window narrower than the
29305 full frame width, provided the window width is less than that integer;
29306 otherwise, respect the value of `truncate-lines'.
29308 For any other non-nil value, truncate lines in all windows that do
29309 not span the full frame width.
29311 A value of nil means to respect the value of `truncate-lines'.
29313 If `word-wrap' is enabled, you might want to reduce this. */);
29314 Vtruncate_partial_width_windows
= make_number (50);
29316 DEFVAR_LISP ("line-number-display-limit", Vline_number_display_limit
,
29317 doc
: /* Maximum buffer size for which line number should be displayed.
29318 If the buffer is bigger than this, the line number does not appear
29319 in the mode line. A value of nil means no limit. */);
29320 Vline_number_display_limit
= Qnil
;
29322 DEFVAR_INT ("line-number-display-limit-width",
29323 line_number_display_limit_width
,
29324 doc
: /* Maximum line width (in characters) for line number display.
29325 If the average length of the lines near point is bigger than this, then the
29326 line number may be omitted from the mode line. */);
29327 line_number_display_limit_width
= 200;
29329 DEFVAR_BOOL ("highlight-nonselected-windows", highlight_nonselected_windows
,
29330 doc
: /* Non-nil means highlight region even in nonselected windows. */);
29331 highlight_nonselected_windows
= 0;
29333 DEFVAR_BOOL ("multiple-frames", multiple_frames
,
29334 doc
: /* Non-nil if more than one frame is visible on this display.
29335 Minibuffer-only frames don't count, but iconified frames do.
29336 This variable is not guaranteed to be accurate except while processing
29337 `frame-title-format' and `icon-title-format'. */);
29339 DEFVAR_LISP ("frame-title-format", Vframe_title_format
,
29340 doc
: /* Template for displaying the title bar of visible frames.
29341 \(Assuming the window manager supports this feature.)
29343 This variable has the same structure as `mode-line-format', except that
29344 the %c and %l constructs are ignored. It is used only on frames for
29345 which no explicit name has been set \(see `modify-frame-parameters'). */);
29347 DEFVAR_LISP ("icon-title-format", Vicon_title_format
,
29348 doc
: /* Template for displaying the title bar of an iconified frame.
29349 \(Assuming the window manager supports this feature.)
29350 This variable has the same structure as `mode-line-format' (which see),
29351 and is used only on frames for which no explicit name has been set
29352 \(see `modify-frame-parameters'). */);
29354 = Vframe_title_format
29355 = listn (CONSTYPE_PURE
, 3,
29356 intern_c_string ("multiple-frames"),
29357 build_pure_c_string ("%b"),
29358 listn (CONSTYPE_PURE
, 4,
29359 empty_unibyte_string
,
29360 intern_c_string ("invocation-name"),
29361 build_pure_c_string ("@"),
29362 intern_c_string ("system-name")));
29364 DEFVAR_LISP ("message-log-max", Vmessage_log_max
,
29365 doc
: /* Maximum number of lines to keep in the message log buffer.
29366 If nil, disable message logging. If t, log messages but don't truncate
29367 the buffer when it becomes large. */);
29368 Vmessage_log_max
= make_number (1000);
29370 DEFVAR_LISP ("window-size-change-functions", Vwindow_size_change_functions
,
29371 doc
: /* Functions called before redisplay, if window sizes have changed.
29372 The value should be a list of functions that take one argument.
29373 Just before redisplay, for each frame, if any of its windows have changed
29374 size since the last redisplay, or have been split or deleted,
29375 all the functions in the list are called, with the frame as argument. */);
29376 Vwindow_size_change_functions
= Qnil
;
29378 DEFVAR_LISP ("window-scroll-functions", Vwindow_scroll_functions
,
29379 doc
: /* List of functions to call before redisplaying a window with scrolling.
29380 Each function is called with two arguments, the window and its new
29381 display-start position. Note that these functions are also called by
29382 `set-window-buffer'. Also note that the value of `window-end' is not
29383 valid when these functions are called.
29385 Warning: Do not use this feature to alter the way the window
29386 is scrolled. It is not designed for that, and such use probably won't
29388 Vwindow_scroll_functions
= Qnil
;
29390 DEFVAR_LISP ("window-text-change-functions",
29391 Vwindow_text_change_functions
,
29392 doc
: /* Functions to call in redisplay when text in the window might change. */);
29393 Vwindow_text_change_functions
= Qnil
;
29395 DEFVAR_LISP ("redisplay-end-trigger-functions", Vredisplay_end_trigger_functions
,
29396 doc
: /* Functions called when redisplay of a window reaches the end trigger.
29397 Each function is called with two arguments, the window and the end trigger value.
29398 See `set-window-redisplay-end-trigger'. */);
29399 Vredisplay_end_trigger_functions
= Qnil
;
29401 DEFVAR_LISP ("mouse-autoselect-window", Vmouse_autoselect_window
,
29402 doc
: /* Non-nil means autoselect window with mouse pointer.
29403 If nil, do not autoselect windows.
29404 A positive number means delay autoselection by that many seconds: a
29405 window is autoselected only after the mouse has remained in that
29406 window for the duration of the delay.
29407 A negative number has a similar effect, but causes windows to be
29408 autoselected only after the mouse has stopped moving. \(Because of
29409 the way Emacs compares mouse events, you will occasionally wait twice
29410 that time before the window gets selected.\)
29411 Any other value means to autoselect window instantaneously when the
29412 mouse pointer enters it.
29414 Autoselection selects the minibuffer only if it is active, and never
29415 unselects the minibuffer if it is active.
29417 When customizing this variable make sure that the actual value of
29418 `focus-follows-mouse' matches the behavior of your window manager. */);
29419 Vmouse_autoselect_window
= Qnil
;
29421 DEFVAR_LISP ("auto-resize-tool-bars", Vauto_resize_tool_bars
,
29422 doc
: /* Non-nil means automatically resize tool-bars.
29423 This dynamically changes the tool-bar's height to the minimum height
29424 that is needed to make all tool-bar items visible.
29425 If value is `grow-only', the tool-bar's height is only increased
29426 automatically; to decrease the tool-bar height, use \\[recenter]. */);
29427 Vauto_resize_tool_bars
= Qt
;
29429 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", auto_raise_tool_bar_buttons_p
,
29430 doc
: /* Non-nil means raise tool-bar buttons when the mouse moves over them. */);
29431 auto_raise_tool_bar_buttons_p
= 1;
29433 DEFVAR_BOOL ("make-cursor-line-fully-visible", make_cursor_line_fully_visible_p
,
29434 doc
: /* Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
29435 make_cursor_line_fully_visible_p
= 1;
29437 DEFVAR_LISP ("tool-bar-border", Vtool_bar_border
,
29438 doc
: /* Border below tool-bar in pixels.
29439 If an integer, use it as the height of the border.
29440 If it is one of `internal-border-width' or `border-width', use the
29441 value of the corresponding frame parameter.
29442 Otherwise, no border is added below the tool-bar. */);
29443 Vtool_bar_border
= Qinternal_border_width
;
29445 DEFVAR_LISP ("tool-bar-button-margin", Vtool_bar_button_margin
,
29446 doc
: /* Margin around tool-bar buttons in pixels.
29447 If an integer, use that for both horizontal and vertical margins.
29448 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
29449 HORZ specifying the horizontal margin, and VERT specifying the
29450 vertical margin. */);
29451 Vtool_bar_button_margin
= make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN
);
29453 DEFVAR_INT ("tool-bar-button-relief", tool_bar_button_relief
,
29454 doc
: /* Relief thickness of tool-bar buttons. */);
29455 tool_bar_button_relief
= DEFAULT_TOOL_BAR_BUTTON_RELIEF
;
29457 DEFVAR_LISP ("tool-bar-style", Vtool_bar_style
,
29458 doc
: /* Tool bar style to use.
29460 image - show images only
29461 text - show text only
29462 both - show both, text below image
29463 both-horiz - show text to the right of the image
29464 text-image-horiz - show text to the left of the image
29465 any other - use system default or image if no system default.
29467 This variable only affects the GTK+ toolkit version of Emacs. */);
29468 Vtool_bar_style
= Qnil
;
29470 DEFVAR_INT ("tool-bar-max-label-size", tool_bar_max_label_size
,
29471 doc
: /* Maximum number of characters a label can have to be shown.
29472 The tool bar style must also show labels for this to have any effect, see
29473 `tool-bar-style'. */);
29474 tool_bar_max_label_size
= DEFAULT_TOOL_BAR_LABEL_SIZE
;
29476 DEFVAR_LISP ("fontification-functions", Vfontification_functions
,
29477 doc
: /* List of functions to call to fontify regions of text.
29478 Each function is called with one argument POS. Functions must
29479 fontify a region starting at POS in the current buffer, and give
29480 fontified regions the property `fontified'. */);
29481 Vfontification_functions
= Qnil
;
29482 Fmake_variable_buffer_local (Qfontification_functions
);
29484 DEFVAR_BOOL ("unibyte-display-via-language-environment",
29485 unibyte_display_via_language_environment
,
29486 doc
: /* Non-nil means display unibyte text according to language environment.
29487 Specifically, this means that raw bytes in the range 160-255 decimal
29488 are displayed by converting them to the equivalent multibyte characters
29489 according to the current language environment. As a result, they are
29490 displayed according to the current fontset.
29492 Note that this variable affects only how these bytes are displayed,
29493 but does not change the fact they are interpreted as raw bytes. */);
29494 unibyte_display_via_language_environment
= 0;
29496 DEFVAR_LISP ("max-mini-window-height", Vmax_mini_window_height
,
29497 doc
: /* Maximum height for resizing mini-windows (the minibuffer and the echo area).
29498 If a float, it specifies a fraction of the mini-window frame's height.
29499 If an integer, it specifies a number of lines. */);
29500 Vmax_mini_window_height
= make_float (0.25);
29502 DEFVAR_LISP ("resize-mini-windows", Vresize_mini_windows
,
29503 doc
: /* How to resize mini-windows (the minibuffer and the echo area).
29504 A value of nil means don't automatically resize mini-windows.
29505 A value of t means resize them to fit the text displayed in them.
29506 A value of `grow-only', the default, means let mini-windows grow only;
29507 they return to their normal size when the minibuffer is closed, or the
29508 echo area becomes empty. */);
29509 Vresize_mini_windows
= Qgrow_only
;
29511 DEFVAR_LISP ("blink-cursor-alist", Vblink_cursor_alist
,
29512 doc
: /* Alist specifying how to blink the cursor off.
29513 Each element has the form (ON-STATE . OFF-STATE). Whenever the
29514 `cursor-type' frame-parameter or variable equals ON-STATE,
29515 comparing using `equal', Emacs uses OFF-STATE to specify
29516 how to blink it off. ON-STATE and OFF-STATE are values for
29517 the `cursor-type' frame parameter.
29519 If a frame's ON-STATE has no entry in this list,
29520 the frame's other specifications determine how to blink the cursor off. */);
29521 Vblink_cursor_alist
= Qnil
;
29523 DEFVAR_BOOL ("auto-hscroll-mode", automatic_hscrolling_p
,
29524 doc
: /* Allow or disallow automatic horizontal scrolling of windows.
29525 If non-nil, windows are automatically scrolled horizontally to make
29526 point visible. */);
29527 automatic_hscrolling_p
= 1;
29528 DEFSYM (Qauto_hscroll_mode
, "auto-hscroll-mode");
29530 DEFVAR_INT ("hscroll-margin", hscroll_margin
,
29531 doc
: /* How many columns away from the window edge point is allowed to get
29532 before automatic hscrolling will horizontally scroll the window. */);
29533 hscroll_margin
= 5;
29535 DEFVAR_LISP ("hscroll-step", Vhscroll_step
,
29536 doc
: /* How many columns to scroll the window when point gets too close to the edge.
29537 When point is less than `hscroll-margin' columns from the window
29538 edge, automatic hscrolling will scroll the window by the amount of columns
29539 determined by this variable. If its value is a positive integer, scroll that
29540 many columns. If it's a positive floating-point number, it specifies the
29541 fraction of the window's width to scroll. If it's nil or zero, point will be
29542 centered horizontally after the scroll. Any other value, including negative
29543 numbers, are treated as if the value were zero.
29545 Automatic hscrolling always moves point outside the scroll margin, so if
29546 point was more than scroll step columns inside the margin, the window will
29547 scroll more than the value given by the scroll step.
29549 Note that the lower bound for automatic hscrolling specified by `scroll-left'
29550 and `scroll-right' overrides this variable's effect. */);
29551 Vhscroll_step
= make_number (0);
29553 DEFVAR_BOOL ("message-truncate-lines", message_truncate_lines
,
29554 doc
: /* If non-nil, messages are truncated instead of resizing the echo area.
29555 Bind this around calls to `message' to let it take effect. */);
29556 message_truncate_lines
= 0;
29558 DEFVAR_LISP ("menu-bar-update-hook", Vmenu_bar_update_hook
,
29559 doc
: /* Normal hook run to update the menu bar definitions.
29560 Redisplay runs this hook before it redisplays the menu bar.
29561 This is used to update submenus such as Buffers,
29562 whose contents depend on various data. */);
29563 Vmenu_bar_update_hook
= Qnil
;
29565 DEFVAR_LISP ("menu-updating-frame", Vmenu_updating_frame
,
29566 doc
: /* Frame for which we are updating a menu.
29567 The enable predicate for a menu binding should check this variable. */);
29568 Vmenu_updating_frame
= Qnil
;
29570 DEFVAR_BOOL ("inhibit-menubar-update", inhibit_menubar_update
,
29571 doc
: /* Non-nil means don't update menu bars. Internal use only. */);
29572 inhibit_menubar_update
= 0;
29574 DEFVAR_LISP ("wrap-prefix", Vwrap_prefix
,
29575 doc
: /* Prefix prepended to all continuation lines at display time.
29576 The value may be a string, an image, or a stretch-glyph; it is
29577 interpreted in the same way as the value of a `display' text property.
29579 This variable is overridden by any `wrap-prefix' text or overlay
29582 To add a prefix to non-continuation lines, use `line-prefix'. */);
29583 Vwrap_prefix
= Qnil
;
29584 DEFSYM (Qwrap_prefix
, "wrap-prefix");
29585 Fmake_variable_buffer_local (Qwrap_prefix
);
29587 DEFVAR_LISP ("line-prefix", Vline_prefix
,
29588 doc
: /* Prefix prepended to all non-continuation lines at display time.
29589 The value may be a string, an image, or a stretch-glyph; it is
29590 interpreted in the same way as the value of a `display' text property.
29592 This variable is overridden by any `line-prefix' text or overlay
29595 To add a prefix to continuation lines, use `wrap-prefix'. */);
29596 Vline_prefix
= Qnil
;
29597 DEFSYM (Qline_prefix
, "line-prefix");
29598 Fmake_variable_buffer_local (Qline_prefix
);
29600 DEFVAR_BOOL ("inhibit-eval-during-redisplay", inhibit_eval_during_redisplay
,
29601 doc
: /* Non-nil means don't eval Lisp during redisplay. */);
29602 inhibit_eval_during_redisplay
= 0;
29604 DEFVAR_BOOL ("inhibit-free-realized-faces", inhibit_free_realized_faces
,
29605 doc
: /* Non-nil means don't free realized faces. Internal use only. */);
29606 inhibit_free_realized_faces
= 0;
29609 DEFVAR_BOOL ("inhibit-try-window-id", inhibit_try_window_id
,
29610 doc
: /* Inhibit try_window_id display optimization. */);
29611 inhibit_try_window_id
= 0;
29613 DEFVAR_BOOL ("inhibit-try-window-reusing", inhibit_try_window_reusing
,
29614 doc
: /* Inhibit try_window_reusing display optimization. */);
29615 inhibit_try_window_reusing
= 0;
29617 DEFVAR_BOOL ("inhibit-try-cursor-movement", inhibit_try_cursor_movement
,
29618 doc
: /* Inhibit try_cursor_movement display optimization. */);
29619 inhibit_try_cursor_movement
= 0;
29620 #endif /* GLYPH_DEBUG */
29622 DEFVAR_INT ("overline-margin", overline_margin
,
29623 doc
: /* Space between overline and text, in pixels.
29624 The default value is 2: the height of the overline (1 pixel) plus 1 pixel
29625 margin to the character height. */);
29626 overline_margin
= 2;
29628 DEFVAR_INT ("underline-minimum-offset",
29629 underline_minimum_offset
,
29630 doc
: /* Minimum distance between baseline and underline.
29631 This can improve legibility of underlined text at small font sizes,
29632 particularly when using variable `x-use-underline-position-properties'
29633 with fonts that specify an UNDERLINE_POSITION relatively close to the
29634 baseline. The default value is 1. */);
29635 underline_minimum_offset
= 1;
29637 DEFVAR_BOOL ("display-hourglass", display_hourglass_p
,
29638 doc
: /* Non-nil means show an hourglass pointer, when Emacs is busy.
29639 This feature only works when on a window system that can change
29640 cursor shapes. */);
29641 display_hourglass_p
= 1;
29643 DEFVAR_LISP ("hourglass-delay", Vhourglass_delay
,
29644 doc
: /* Seconds to wait before displaying an hourglass pointer when Emacs is busy. */);
29645 Vhourglass_delay
= make_number (DEFAULT_HOURGLASS_DELAY
);
29647 #ifdef HAVE_WINDOW_SYSTEM
29648 hourglass_atimer
= NULL
;
29649 hourglass_shown_p
= 0;
29650 #endif /* HAVE_WINDOW_SYSTEM */
29652 DEFSYM (Qglyphless_char
, "glyphless-char");
29653 DEFSYM (Qhex_code
, "hex-code");
29654 DEFSYM (Qempty_box
, "empty-box");
29655 DEFSYM (Qthin_space
, "thin-space");
29656 DEFSYM (Qzero_width
, "zero-width");
29658 DEFSYM (Qglyphless_char_display
, "glyphless-char-display");
29659 Fput (Qglyphless_char_display
, Qchar_table_extra_slots
, make_number (1));
29661 DEFVAR_LISP ("glyphless-char-display", Vglyphless_char_display
,
29662 doc
: /* Char-table defining glyphless characters.
29663 Each element, if non-nil, should be one of the following:
29664 an ASCII acronym string: display this string in a box
29665 `hex-code': display the hexadecimal code of a character in a box
29666 `empty-box': display as an empty box
29667 `thin-space': display as 1-pixel width space
29668 `zero-width': don't display
29669 An element may also be a cons cell (GRAPHICAL . TEXT), which specifies the
29670 display method for graphical terminals and text terminals respectively.
29671 GRAPHICAL and TEXT should each have one of the values listed above.
29673 The char-table has one extra slot to control the display of a character for
29674 which no font is found. This slot only takes effect on graphical terminals.
29675 Its value should be an ASCII acronym string, `hex-code', `empty-box', or
29676 `thin-space'. The default is `empty-box'. */);
29677 Vglyphless_char_display
= Fmake_char_table (Qglyphless_char_display
, Qnil
);
29678 Fset_char_table_extra_slot (Vglyphless_char_display
, make_number (0),
29681 DEFVAR_LISP ("debug-on-message", Vdebug_on_message
,
29682 doc
: /* If non-nil, debug if a message matching this regexp is displayed. */);
29683 Vdebug_on_message
= Qnil
;
29687 /* Initialize this module when Emacs starts. */
29692 CHARPOS (this_line_start_pos
) = 0;
29694 if (!noninteractive
)
29696 struct window
*m
= XWINDOW (minibuf_window
);
29697 Lisp_Object frame
= m
->frame
;
29698 struct frame
*f
= XFRAME (frame
);
29699 Lisp_Object root
= FRAME_ROOT_WINDOW (f
);
29700 struct window
*r
= XWINDOW (root
);
29703 echo_area_window
= minibuf_window
;
29705 r
->top_line
= FRAME_TOP_MARGIN (f
);
29706 r
->total_lines
= FRAME_LINES (f
) - 1 - FRAME_TOP_MARGIN (f
);
29707 r
->total_cols
= FRAME_COLS (f
);
29709 m
->top_line
= FRAME_LINES (f
) - 1;
29710 m
->total_lines
= 1;
29711 m
->total_cols
= FRAME_COLS (f
);
29713 scratch_glyph_row
.glyphs
[TEXT_AREA
] = scratch_glyphs
;
29714 scratch_glyph_row
.glyphs
[TEXT_AREA
+ 1]
29715 = scratch_glyphs
+ MAX_SCRATCH_GLYPHS
;
29717 /* The default ellipsis glyphs `...'. */
29718 for (i
= 0; i
< 3; ++i
)
29719 default_invis_vector
[i
] = make_number ('.');
29723 /* Allocate the buffer for frame titles.
29724 Also used for `format-mode-line'. */
29726 mode_line_noprop_buf
= xmalloc (size
);
29727 mode_line_noprop_buf_end
= mode_line_noprop_buf
+ size
;
29728 mode_line_noprop_ptr
= mode_line_noprop_buf
;
29729 mode_line_target
= MODE_LINE_DISPLAY
;
29732 help_echo_showing_p
= 0;
29735 #ifdef HAVE_WINDOW_SYSTEM
29737 /* Platform-independent portion of hourglass implementation. */
29739 /* Cancel a currently active hourglass timer, and start a new one. */
29741 start_hourglass (void)
29743 struct timespec delay
;
29745 cancel_hourglass ();
29747 if (INTEGERP (Vhourglass_delay
)
29748 && XINT (Vhourglass_delay
) > 0)
29749 delay
= make_timespec (min (XINT (Vhourglass_delay
),
29750 TYPE_MAXIMUM (time_t)),
29752 else if (FLOATP (Vhourglass_delay
)
29753 && XFLOAT_DATA (Vhourglass_delay
) > 0)
29754 delay
= dtotimespec (XFLOAT_DATA (Vhourglass_delay
));
29756 delay
= make_timespec (DEFAULT_HOURGLASS_DELAY
, 0);
29760 extern void w32_note_current_window (void);
29761 w32_note_current_window ();
29763 #endif /* HAVE_NTGUI */
29765 hourglass_atimer
= start_atimer (ATIMER_RELATIVE
, delay
,
29766 show_hourglass
, NULL
);
29770 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
29773 cancel_hourglass (void)
29775 if (hourglass_atimer
)
29777 cancel_atimer (hourglass_atimer
);
29778 hourglass_atimer
= NULL
;
29781 if (hourglass_shown_p
)
29785 #endif /* HAVE_WINDOW_SYSTEM */