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"
303 #ifdef HAVE_X_WINDOWS
318 #ifndef FRAME_X_OUTPUT
319 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
322 #define INFINITY 10000000
324 Lisp_Object Qoverriding_local_map
, Qoverriding_terminal_local_map
;
325 Lisp_Object Qwindow_scroll_functions
;
326 static Lisp_Object Qwindow_text_change_functions
;
327 static Lisp_Object Qredisplay_end_trigger_functions
;
328 Lisp_Object Qinhibit_point_motion_hooks
;
329 static Lisp_Object QCeval
, QCpropertize
;
330 Lisp_Object QCfile
, QCdata
;
331 static Lisp_Object Qfontified
;
332 static Lisp_Object Qgrow_only
;
333 static Lisp_Object Qinhibit_eval_during_redisplay
;
334 static Lisp_Object Qbuffer_position
, Qposition
, Qobject
;
335 static Lisp_Object Qright_to_left
, Qleft_to_right
;
338 Lisp_Object Qbar
, Qhbar
, Qbox
, Qhollow
;
340 /* Pointer shapes. */
341 static Lisp_Object Qarrow
, Qhand
;
344 /* Holds the list (error). */
345 static Lisp_Object list_of_error
;
347 static Lisp_Object Qfontification_functions
;
349 static Lisp_Object Qwrap_prefix
;
350 static Lisp_Object Qline_prefix
;
351 static Lisp_Object Qredisplay_internal
;
353 /* Non-nil means don't actually do any redisplay. */
355 Lisp_Object Qinhibit_redisplay
;
357 /* Names of text properties relevant for redisplay. */
359 Lisp_Object Qdisplay
;
361 Lisp_Object Qspace
, QCalign_to
;
362 static Lisp_Object QCrelative_width
, QCrelative_height
;
363 Lisp_Object Qleft_margin
, Qright_margin
;
364 static Lisp_Object Qspace_width
, Qraise
;
365 static Lisp_Object Qslice
;
367 static Lisp_Object Qmargin
, Qpointer
;
368 static Lisp_Object Qline_height
;
370 #ifdef HAVE_WINDOW_SYSTEM
372 /* Test if overflow newline into fringe. Called with iterator IT
373 at or past right window margin, and with IT->current_x set. */
375 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(IT) \
376 (!NILP (Voverflow_newline_into_fringe) \
377 && FRAME_WINDOW_P ((IT)->f) \
378 && ((IT)->bidi_it.paragraph_dir == R2L \
379 ? (WINDOW_LEFT_FRINGE_WIDTH ((IT)->w) > 0) \
380 : (WINDOW_RIGHT_FRINGE_WIDTH ((IT)->w) > 0)) \
381 && (IT)->current_x == (IT)->last_visible_x \
382 && (IT)->line_wrap != WORD_WRAP)
384 #else /* !HAVE_WINDOW_SYSTEM */
385 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) 0
386 #endif /* HAVE_WINDOW_SYSTEM */
388 /* Test if the display element loaded in IT, or the underlying buffer
389 or string character, is a space or a TAB character. This is used
390 to determine where word wrapping can occur. */
392 #define IT_DISPLAYING_WHITESPACE(it) \
393 ((it->what == IT_CHARACTER && (it->c == ' ' || it->c == '\t')) \
394 || ((STRINGP (it->string) \
395 && (SREF (it->string, IT_STRING_BYTEPOS (*it)) == ' ' \
396 || SREF (it->string, IT_STRING_BYTEPOS (*it)) == '\t')) \
398 && (it->s[IT_BYTEPOS (*it)] == ' ' \
399 || it->s[IT_BYTEPOS (*it)] == '\t')) \
400 || (IT_BYTEPOS (*it) < ZV_BYTE \
401 && (*BYTE_POS_ADDR (IT_BYTEPOS (*it)) == ' ' \
402 || *BYTE_POS_ADDR (IT_BYTEPOS (*it)) == '\t')))) \
404 /* Name of the face used to highlight trailing whitespace. */
406 static Lisp_Object Qtrailing_whitespace
;
408 /* Name and number of the face used to highlight escape glyphs. */
410 static Lisp_Object Qescape_glyph
;
412 /* Name and number of the face used to highlight non-breaking spaces. */
414 static Lisp_Object Qnobreak_space
;
416 /* The symbol `image' which is the car of the lists used to represent
417 images in Lisp. Also a tool bar style. */
421 /* The image map types. */
423 static Lisp_Object QCpointer
;
424 static Lisp_Object Qrect
, Qcircle
, Qpoly
;
426 /* Tool bar styles */
427 Lisp_Object Qboth
, Qboth_horiz
, Qtext_image_horiz
;
429 /* Non-zero means print newline to stdout before next mini-buffer
432 int noninteractive_need_newline
;
434 /* Non-zero means print newline to message log before next message. */
436 static int message_log_need_newline
;
438 /* Three markers that message_dolog uses.
439 It could allocate them itself, but that causes trouble
440 in handling memory-full errors. */
441 static Lisp_Object message_dolog_marker1
;
442 static Lisp_Object message_dolog_marker2
;
443 static Lisp_Object message_dolog_marker3
;
445 /* The buffer position of the first character appearing entirely or
446 partially on the line of the selected window which contains the
447 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
448 redisplay optimization in redisplay_internal. */
450 static struct text_pos this_line_start_pos
;
452 /* Number of characters past the end of the line above, including the
453 terminating newline. */
455 static struct text_pos this_line_end_pos
;
457 /* The vertical positions and the height of this line. */
459 static int this_line_vpos
;
460 static int this_line_y
;
461 static int this_line_pixel_height
;
463 /* X position at which this display line starts. Usually zero;
464 negative if first character is partially visible. */
466 static int this_line_start_x
;
468 /* The smallest character position seen by move_it_* functions as they
469 move across display lines. Used to set MATRIX_ROW_START_CHARPOS of
470 hscrolled lines, see display_line. */
472 static struct text_pos this_line_min_pos
;
474 /* Buffer that this_line_.* variables are referring to. */
476 static struct buffer
*this_line_buffer
;
479 /* Values of those variables at last redisplay are stored as
480 properties on `overlay-arrow-position' symbol. However, if
481 Voverlay_arrow_position is a marker, last-arrow-position is its
482 numerical position. */
484 static Lisp_Object Qlast_arrow_position
, Qlast_arrow_string
;
486 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
487 properties on a symbol in overlay-arrow-variable-list. */
489 static Lisp_Object Qoverlay_arrow_string
, Qoverlay_arrow_bitmap
;
491 Lisp_Object Qmenu_bar_update_hook
;
493 /* Nonzero if an overlay arrow has been displayed in this window. */
495 static int overlay_arrow_seen
;
497 /* Vector containing glyphs for an ellipsis `...'. */
499 static Lisp_Object default_invis_vector
[3];
501 /* This is the window where the echo area message was displayed. It
502 is always a mini-buffer window, but it may not be the same window
503 currently active as a mini-buffer. */
505 Lisp_Object echo_area_window
;
507 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
508 pushes the current message and the value of
509 message_enable_multibyte on the stack, the function restore_message
510 pops the stack and displays MESSAGE again. */
512 static Lisp_Object Vmessage_stack
;
514 /* Nonzero means multibyte characters were enabled when the echo area
515 message was specified. */
517 static int message_enable_multibyte
;
519 /* Nonzero if we should redraw the mode lines on the next redisplay. */
521 int update_mode_lines
;
523 /* Nonzero if window sizes or contents have changed since last
524 redisplay that finished. */
526 int windows_or_buffers_changed
;
528 /* Nonzero means a frame's cursor type has been changed. */
530 int cursor_type_changed
;
532 /* Nonzero after display_mode_line if %l was used and it displayed a
535 static int line_number_displayed
;
537 /* The name of the *Messages* buffer, a string. */
539 static Lisp_Object Vmessages_buffer_name
;
541 /* Current, index 0, and last displayed echo area message. Either
542 buffers from echo_buffers, or nil to indicate no message. */
544 Lisp_Object echo_area_buffer
[2];
546 /* The buffers referenced from echo_area_buffer. */
548 static Lisp_Object echo_buffer
[2];
550 /* A vector saved used in with_area_buffer to reduce consing. */
552 static Lisp_Object Vwith_echo_area_save_vector
;
554 /* Non-zero means display_echo_area should display the last echo area
555 message again. Set by redisplay_preserve_echo_area. */
557 static int display_last_displayed_message_p
;
559 /* Nonzero if echo area is being used by print; zero if being used by
562 static int message_buf_print
;
564 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
566 static Lisp_Object Qinhibit_menubar_update
;
567 static Lisp_Object Qmessage_truncate_lines
;
569 /* Set to 1 in clear_message to make redisplay_internal aware
570 of an emptied echo area. */
572 static int message_cleared_p
;
574 /* A scratch glyph row with contents used for generating truncation
575 glyphs. Also used in direct_output_for_insert. */
577 #define MAX_SCRATCH_GLYPHS 100
578 static struct glyph_row scratch_glyph_row
;
579 static struct glyph scratch_glyphs
[MAX_SCRATCH_GLYPHS
];
581 /* Ascent and height of the last line processed by move_it_to. */
583 static int last_height
;
585 /* Non-zero if there's a help-echo in the echo area. */
587 int help_echo_showing_p
;
589 /* If >= 0, computed, exact values of mode-line and header-line height
590 to use in the macros CURRENT_MODE_LINE_HEIGHT and
591 CURRENT_HEADER_LINE_HEIGHT. */
593 int current_mode_line_height
, current_header_line_height
;
595 /* The maximum distance to look ahead for text properties. Values
596 that are too small let us call compute_char_face and similar
597 functions too often which is expensive. Values that are too large
598 let us call compute_char_face and alike too often because we
599 might not be interested in text properties that far away. */
601 #define TEXT_PROP_DISTANCE_LIMIT 100
603 /* SAVE_IT and RESTORE_IT are called when we save a snapshot of the
604 iterator state and later restore it. This is needed because the
605 bidi iterator on bidi.c keeps a stacked cache of its states, which
606 is really a singleton. When we use scratch iterator objects to
607 move around the buffer, we can cause the bidi cache to be pushed or
608 popped, and therefore we need to restore the cache state when we
609 return to the original iterator. */
610 #define SAVE_IT(ITCOPY,ITORIG,CACHE) \
613 bidi_unshelve_cache (CACHE, 1); \
615 CACHE = bidi_shelve_cache (); \
618 #define RESTORE_IT(pITORIG,pITCOPY,CACHE) \
620 if (pITORIG != pITCOPY) \
621 *(pITORIG) = *(pITCOPY); \
622 bidi_unshelve_cache (CACHE, 0); \
628 /* Non-zero means print traces of redisplay if compiled with
629 GLYPH_DEBUG defined. */
631 int trace_redisplay_p
;
633 #endif /* GLYPH_DEBUG */
635 #ifdef DEBUG_TRACE_MOVE
636 /* Non-zero means trace with TRACE_MOVE to stderr. */
639 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
641 #define TRACE_MOVE(x) (void) 0
644 static Lisp_Object Qauto_hscroll_mode
;
646 /* Buffer being redisplayed -- for redisplay_window_error. */
648 static struct buffer
*displayed_buffer
;
650 /* Value returned from text property handlers (see below). */
655 HANDLED_RECOMPUTE_PROPS
,
656 HANDLED_OVERLAY_STRING_CONSUMED
,
660 /* A description of text properties that redisplay is interested
665 /* The name of the property. */
668 /* A unique index for the property. */
671 /* A handler function called to set up iterator IT from the property
672 at IT's current position. Value is used to steer handle_stop. */
673 enum prop_handled (*handler
) (struct it
*it
);
676 static enum prop_handled
handle_face_prop (struct it
*);
677 static enum prop_handled
handle_invisible_prop (struct it
*);
678 static enum prop_handled
handle_display_prop (struct it
*);
679 static enum prop_handled
handle_composition_prop (struct it
*);
680 static enum prop_handled
handle_overlay_change (struct it
*);
681 static enum prop_handled
handle_fontified_prop (struct it
*);
683 /* Properties handled by iterators. */
685 static struct props it_props
[] =
687 {&Qfontified
, FONTIFIED_PROP_IDX
, handle_fontified_prop
},
688 /* Handle `face' before `display' because some sub-properties of
689 `display' need to know the face. */
690 {&Qface
, FACE_PROP_IDX
, handle_face_prop
},
691 {&Qdisplay
, DISPLAY_PROP_IDX
, handle_display_prop
},
692 {&Qinvisible
, INVISIBLE_PROP_IDX
, handle_invisible_prop
},
693 {&Qcomposition
, COMPOSITION_PROP_IDX
, handle_composition_prop
},
697 /* Value is the position described by X. If X is a marker, value is
698 the marker_position of X. Otherwise, value is X. */
700 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
702 /* Enumeration returned by some move_it_.* functions internally. */
706 /* Not used. Undefined value. */
709 /* Move ended at the requested buffer position or ZV. */
710 MOVE_POS_MATCH_OR_ZV
,
712 /* Move ended at the requested X pixel position. */
715 /* Move within a line ended at the end of a line that must be
719 /* Move within a line ended at the end of a line that would
720 be displayed truncated. */
723 /* Move within a line ended at a line end. */
727 /* This counter is used to clear the face cache every once in a while
728 in redisplay_internal. It is incremented for each redisplay.
729 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
732 #define CLEAR_FACE_CACHE_COUNT 500
733 static int clear_face_cache_count
;
735 /* Similarly for the image cache. */
737 #ifdef HAVE_WINDOW_SYSTEM
738 #define CLEAR_IMAGE_CACHE_COUNT 101
739 static int clear_image_cache_count
;
741 /* Null glyph slice */
742 static struct glyph_slice null_glyph_slice
= { 0, 0, 0, 0 };
745 /* True while redisplay_internal is in progress. */
749 static Lisp_Object Qinhibit_free_realized_faces
;
750 static Lisp_Object Qmode_line_default_help_echo
;
752 /* If a string, XTread_socket generates an event to display that string.
753 (The display is done in read_char.) */
755 Lisp_Object help_echo_string
;
756 Lisp_Object help_echo_window
;
757 Lisp_Object help_echo_object
;
758 ptrdiff_t help_echo_pos
;
760 /* Temporary variable for XTread_socket. */
762 Lisp_Object previous_help_echo_string
;
764 /* Platform-independent portion of hourglass implementation. */
766 /* Non-zero means an hourglass cursor is currently shown. */
767 int hourglass_shown_p
;
769 /* If non-null, an asynchronous timer that, when it expires, displays
770 an hourglass cursor on all frames. */
771 struct atimer
*hourglass_atimer
;
773 /* Name of the face used to display glyphless characters. */
774 Lisp_Object Qglyphless_char
;
776 /* Symbol for the purpose of Vglyphless_char_display. */
777 static Lisp_Object Qglyphless_char_display
;
779 /* Method symbols for Vglyphless_char_display. */
780 static Lisp_Object Qhex_code
, Qempty_box
, Qthin_space
, Qzero_width
;
782 /* Default pixel width of `thin-space' display method. */
783 #define THIN_SPACE_WIDTH 1
785 /* Default number of seconds to wait before displaying an hourglass
787 #define DEFAULT_HOURGLASS_DELAY 1
790 /* Function prototypes. */
792 static void setup_for_ellipsis (struct it
*, int);
793 static void set_iterator_to_next (struct it
*, int);
794 static void mark_window_display_accurate_1 (struct window
*, int);
795 static int single_display_spec_string_p (Lisp_Object
, Lisp_Object
);
796 static int display_prop_string_p (Lisp_Object
, Lisp_Object
);
797 static int row_for_charpos_p (struct glyph_row
*, ptrdiff_t);
798 static int cursor_row_p (struct glyph_row
*);
799 static int redisplay_mode_lines (Lisp_Object
, int);
800 static char *decode_mode_spec_coding (Lisp_Object
, char *, int);
802 static Lisp_Object
get_it_property (struct it
*it
, Lisp_Object prop
);
804 static void handle_line_prefix (struct it
*);
806 static void pint2str (char *, int, ptrdiff_t);
807 static void pint2hrstr (char *, int, ptrdiff_t);
808 static struct text_pos
run_window_scroll_functions (Lisp_Object
,
810 static void reconsider_clip_changes (struct window
*, struct buffer
*);
811 static int text_outside_line_unchanged_p (struct window
*,
812 ptrdiff_t, ptrdiff_t);
813 static void store_mode_line_noprop_char (char);
814 static int store_mode_line_noprop (const char *, int, int);
815 static void handle_stop (struct it
*);
816 static void handle_stop_backwards (struct it
*, ptrdiff_t);
817 static void vmessage (const char *, va_list) ATTRIBUTE_FORMAT_PRINTF (1, 0);
818 static void ensure_echo_area_buffers (void);
819 static Lisp_Object
unwind_with_echo_area_buffer (Lisp_Object
);
820 static Lisp_Object
with_echo_area_buffer_unwind_data (struct window
*);
821 static int with_echo_area_buffer (struct window
*, int,
822 int (*) (ptrdiff_t, Lisp_Object
),
823 ptrdiff_t, Lisp_Object
);
824 static void clear_garbaged_frames (void);
825 static int current_message_1 (ptrdiff_t, Lisp_Object
);
826 static void pop_message (void);
827 static int truncate_message_1 (ptrdiff_t, Lisp_Object
);
828 static void set_message (Lisp_Object
);
829 static int set_message_1 (ptrdiff_t, Lisp_Object
);
830 static int display_echo_area (struct window
*);
831 static int display_echo_area_1 (ptrdiff_t, Lisp_Object
);
832 static int resize_mini_window_1 (ptrdiff_t, Lisp_Object
);
833 static Lisp_Object
unwind_redisplay (Lisp_Object
);
834 static int string_char_and_length (const unsigned char *, int *);
835 static struct text_pos
display_prop_end (struct it
*, Lisp_Object
,
837 static int compute_window_start_on_continuation_line (struct window
*);
838 static void insert_left_trunc_glyphs (struct it
*);
839 static struct glyph_row
*get_overlay_arrow_glyph_row (struct window
*,
841 static void extend_face_to_end_of_line (struct it
*);
842 static int append_space_for_newline (struct it
*, int);
843 static int cursor_row_fully_visible_p (struct window
*, int, int);
844 static int try_scrolling (Lisp_Object
, int, ptrdiff_t, ptrdiff_t, int, int);
845 static int try_cursor_movement (Lisp_Object
, struct text_pos
, int *);
846 static int trailing_whitespace_p (ptrdiff_t);
847 static intmax_t message_log_check_duplicate (ptrdiff_t, ptrdiff_t);
848 static void push_it (struct it
*, struct text_pos
*);
849 static void iterate_out_of_display_property (struct it
*);
850 static void pop_it (struct it
*);
851 static void sync_frame_with_window_matrix_rows (struct window
*);
852 static void redisplay_internal (void);
853 static int echo_area_display (int);
854 static void redisplay_windows (Lisp_Object
);
855 static void redisplay_window (Lisp_Object
, int);
856 static Lisp_Object
redisplay_window_error (Lisp_Object
);
857 static Lisp_Object
redisplay_window_0 (Lisp_Object
);
858 static Lisp_Object
redisplay_window_1 (Lisp_Object
);
859 static int set_cursor_from_row (struct window
*, struct glyph_row
*,
860 struct glyph_matrix
*, ptrdiff_t, ptrdiff_t,
862 static int update_menu_bar (struct frame
*, int, int);
863 static int try_window_reusing_current_matrix (struct window
*);
864 static int try_window_id (struct window
*);
865 static int display_line (struct it
*);
866 static int display_mode_lines (struct window
*);
867 static int display_mode_line (struct window
*, enum face_id
, Lisp_Object
);
868 static int display_mode_element (struct it
*, int, int, int, Lisp_Object
, Lisp_Object
, int);
869 static int store_mode_line_string (const char *, Lisp_Object
, int, int, int, Lisp_Object
);
870 static const char *decode_mode_spec (struct window
*, int, int, Lisp_Object
*);
871 static void display_menu_bar (struct window
*);
872 static ptrdiff_t display_count_lines (ptrdiff_t, ptrdiff_t, ptrdiff_t,
874 static int display_string (const char *, Lisp_Object
, Lisp_Object
,
875 ptrdiff_t, ptrdiff_t, struct it
*, int, int, int, int);
876 static void compute_line_metrics (struct it
*);
877 static void run_redisplay_end_trigger_hook (struct it
*);
878 static int get_overlay_strings (struct it
*, ptrdiff_t);
879 static int get_overlay_strings_1 (struct it
*, ptrdiff_t, int);
880 static void next_overlay_string (struct it
*);
881 static void reseat (struct it
*, struct text_pos
, int);
882 static void reseat_1 (struct it
*, struct text_pos
, int);
883 static void back_to_previous_visible_line_start (struct it
*);
884 static void reseat_at_next_visible_line_start (struct it
*, int);
885 static int next_element_from_ellipsis (struct it
*);
886 static int next_element_from_display_vector (struct it
*);
887 static int next_element_from_string (struct it
*);
888 static int next_element_from_c_string (struct it
*);
889 static int next_element_from_buffer (struct it
*);
890 static int next_element_from_composition (struct it
*);
891 static int next_element_from_image (struct it
*);
892 static int next_element_from_stretch (struct it
*);
893 static void load_overlay_strings (struct it
*, ptrdiff_t);
894 static int init_from_display_pos (struct it
*, struct window
*,
895 struct display_pos
*);
896 static void reseat_to_string (struct it
*, const char *,
897 Lisp_Object
, ptrdiff_t, ptrdiff_t, int, int);
898 static int get_next_display_element (struct it
*);
899 static enum move_it_result
900 move_it_in_display_line_to (struct it
*, ptrdiff_t, int,
901 enum move_operation_enum
);
902 static void get_visually_first_element (struct it
*);
903 static void init_to_row_start (struct it
*, struct window
*,
905 static int init_to_row_end (struct it
*, struct window
*,
907 static void back_to_previous_line_start (struct it
*);
908 static int forward_to_next_line_start (struct it
*, int *, struct bidi_it
*);
909 static struct text_pos
string_pos_nchars_ahead (struct text_pos
,
910 Lisp_Object
, ptrdiff_t);
911 static struct text_pos
string_pos (ptrdiff_t, Lisp_Object
);
912 static struct text_pos
c_string_pos (ptrdiff_t, const char *, bool);
913 static ptrdiff_t number_of_chars (const char *, bool);
914 static void compute_stop_pos (struct it
*);
915 static void compute_string_pos (struct text_pos
*, struct text_pos
,
917 static int face_before_or_after_it_pos (struct it
*, int);
918 static ptrdiff_t next_overlay_change (ptrdiff_t);
919 static int handle_display_spec (struct it
*, Lisp_Object
, Lisp_Object
,
920 Lisp_Object
, struct text_pos
*, ptrdiff_t, int);
921 static int handle_single_display_spec (struct it
*, Lisp_Object
,
922 Lisp_Object
, Lisp_Object
,
923 struct text_pos
*, ptrdiff_t, int, int);
924 static int underlying_face_id (struct it
*);
925 static int in_ellipses_for_invisible_text_p (struct display_pos
*,
928 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
929 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
931 #ifdef HAVE_WINDOW_SYSTEM
933 static void x_consider_frame_title (Lisp_Object
);
934 static int tool_bar_lines_needed (struct frame
*, int *);
935 static void update_tool_bar (struct frame
*, int);
936 static void build_desired_tool_bar_string (struct frame
*f
);
937 static int redisplay_tool_bar (struct frame
*);
938 static void display_tool_bar_line (struct it
*, int);
939 static void notice_overwritten_cursor (struct window
*,
942 static void append_stretch_glyph (struct it
*, Lisp_Object
,
946 #endif /* HAVE_WINDOW_SYSTEM */
948 static void produce_special_glyphs (struct it
*, enum display_element_type
);
949 static void show_mouse_face (Mouse_HLInfo
*, enum draw_glyphs_face
);
950 static int coords_in_mouse_face_p (struct window
*, int, int);
954 /***********************************************************************
955 Window display dimensions
956 ***********************************************************************/
958 /* Return the bottom boundary y-position for text lines in window W.
959 This is the first y position at which a line cannot start.
960 It is relative to the top of the window.
962 This is the height of W minus the height of a mode line, if any. */
965 window_text_bottom_y (struct window
*w
)
967 int height
= WINDOW_TOTAL_HEIGHT (w
);
969 if (WINDOW_WANTS_MODELINE_P (w
))
970 height
-= CURRENT_MODE_LINE_HEIGHT (w
);
974 /* Return the pixel width of display area AREA of window W. AREA < 0
975 means return the total width of W, not including fringes to
976 the left and right of the window. */
979 window_box_width (struct window
*w
, int area
)
981 int cols
= w
->total_cols
;
984 if (!w
->pseudo_window_p
)
986 cols
-= WINDOW_SCROLL_BAR_COLS (w
);
988 if (area
== TEXT_AREA
)
990 if (INTEGERP (w
->left_margin_cols
))
991 cols
-= XFASTINT (w
->left_margin_cols
);
992 if (INTEGERP (w
->right_margin_cols
))
993 cols
-= XFASTINT (w
->right_margin_cols
);
994 pixels
= -WINDOW_TOTAL_FRINGE_WIDTH (w
);
996 else if (area
== LEFT_MARGIN_AREA
)
998 cols
= (INTEGERP (w
->left_margin_cols
)
999 ? XFASTINT (w
->left_margin_cols
) : 0);
1002 else if (area
== RIGHT_MARGIN_AREA
)
1004 cols
= (INTEGERP (w
->right_margin_cols
)
1005 ? XFASTINT (w
->right_margin_cols
) : 0);
1010 return cols
* WINDOW_FRAME_COLUMN_WIDTH (w
) + pixels
;
1014 /* Return the pixel height of the display area of window W, not
1015 including mode lines of W, if any. */
1018 window_box_height (struct window
*w
)
1020 struct frame
*f
= XFRAME (w
->frame
);
1021 int height
= WINDOW_TOTAL_HEIGHT (w
);
1023 eassert (height
>= 0);
1025 /* Note: the code below that determines the mode-line/header-line
1026 height is essentially the same as that contained in the macro
1027 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1028 the appropriate glyph row has its `mode_line_p' flag set,
1029 and if it doesn't, uses estimate_mode_line_height instead. */
1031 if (WINDOW_WANTS_MODELINE_P (w
))
1033 struct glyph_row
*ml_row
1034 = (w
->current_matrix
&& w
->current_matrix
->rows
1035 ? MATRIX_MODE_LINE_ROW (w
->current_matrix
)
1037 if (ml_row
&& ml_row
->mode_line_p
)
1038 height
-= ml_row
->height
;
1040 height
-= estimate_mode_line_height (f
, CURRENT_MODE_LINE_FACE_ID (w
));
1043 if (WINDOW_WANTS_HEADER_LINE_P (w
))
1045 struct glyph_row
*hl_row
1046 = (w
->current_matrix
&& w
->current_matrix
->rows
1047 ? MATRIX_HEADER_LINE_ROW (w
->current_matrix
)
1049 if (hl_row
&& hl_row
->mode_line_p
)
1050 height
-= hl_row
->height
;
1052 height
-= estimate_mode_line_height (f
, HEADER_LINE_FACE_ID
);
1055 /* With a very small font and a mode-line that's taller than
1056 default, we might end up with a negative height. */
1057 return max (0, height
);
1060 /* Return the window-relative coordinate of the left edge of display
1061 area AREA of window W. AREA < 0 means return the left edge of the
1062 whole window, to the right of the left fringe of W. */
1065 window_box_left_offset (struct window
*w
, int area
)
1069 if (w
->pseudo_window_p
)
1072 x
= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w
);
1074 if (area
== TEXT_AREA
)
1075 x
+= (WINDOW_LEFT_FRINGE_WIDTH (w
)
1076 + window_box_width (w
, LEFT_MARGIN_AREA
));
1077 else if (area
== RIGHT_MARGIN_AREA
)
1078 x
+= (WINDOW_LEFT_FRINGE_WIDTH (w
)
1079 + window_box_width (w
, LEFT_MARGIN_AREA
)
1080 + window_box_width (w
, TEXT_AREA
)
1081 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
1083 : WINDOW_RIGHT_FRINGE_WIDTH (w
)));
1084 else if (area
== LEFT_MARGIN_AREA
1085 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
))
1086 x
+= WINDOW_LEFT_FRINGE_WIDTH (w
);
1092 /* Return the window-relative coordinate of the right edge of display
1093 area AREA of window W. AREA < 0 means return the right edge of the
1094 whole window, to the left of the right fringe of W. */
1097 window_box_right_offset (struct window
*w
, int area
)
1099 return window_box_left_offset (w
, area
) + window_box_width (w
, area
);
1102 /* Return the frame-relative coordinate of the left edge of display
1103 area AREA of window W. AREA < 0 means return the left edge of the
1104 whole window, to the right of the left fringe of W. */
1107 window_box_left (struct window
*w
, int area
)
1109 struct frame
*f
= XFRAME (w
->frame
);
1112 if (w
->pseudo_window_p
)
1113 return FRAME_INTERNAL_BORDER_WIDTH (f
);
1115 x
= (WINDOW_LEFT_EDGE_X (w
)
1116 + window_box_left_offset (w
, area
));
1122 /* Return the frame-relative coordinate of the right edge of display
1123 area AREA of window W. AREA < 0 means return the right edge of the
1124 whole window, to the left of the right fringe of W. */
1127 window_box_right (struct window
*w
, int area
)
1129 return window_box_left (w
, area
) + window_box_width (w
, area
);
1132 /* Get the bounding box of the display area AREA of window W, without
1133 mode lines, in frame-relative coordinates. AREA < 0 means the
1134 whole window, not including the left and right fringes of
1135 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1136 coordinates of the upper-left corner of the box. Return in
1137 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1140 window_box (struct window
*w
, int area
, int *box_x
, int *box_y
,
1141 int *box_width
, int *box_height
)
1144 *box_width
= window_box_width (w
, area
);
1146 *box_height
= window_box_height (w
);
1148 *box_x
= window_box_left (w
, area
);
1151 *box_y
= WINDOW_TOP_EDGE_Y (w
);
1152 if (WINDOW_WANTS_HEADER_LINE_P (w
))
1153 *box_y
+= CURRENT_HEADER_LINE_HEIGHT (w
);
1158 /* Get the bounding box of the display area AREA of window W, without
1159 mode lines. AREA < 0 means the whole window, not including the
1160 left and right fringe of the window. Return in *TOP_LEFT_X
1161 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1162 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1163 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1167 window_box_edges (struct window
*w
, int area
, int *top_left_x
, int *top_left_y
,
1168 int *bottom_right_x
, int *bottom_right_y
)
1170 window_box (w
, area
, top_left_x
, top_left_y
, bottom_right_x
,
1172 *bottom_right_x
+= *top_left_x
;
1173 *bottom_right_y
+= *top_left_y
;
1178 /***********************************************************************
1180 ***********************************************************************/
1182 /* Return the bottom y-position of the line the iterator IT is in.
1183 This can modify IT's settings. */
1186 line_bottom_y (struct it
*it
)
1188 int line_height
= it
->max_ascent
+ it
->max_descent
;
1189 int line_top_y
= it
->current_y
;
1191 if (line_height
== 0)
1194 line_height
= last_height
;
1195 else if (IT_CHARPOS (*it
) < ZV
)
1197 move_it_by_lines (it
, 1);
1198 line_height
= (it
->max_ascent
|| it
->max_descent
1199 ? it
->max_ascent
+ it
->max_descent
1204 struct glyph_row
*row
= it
->glyph_row
;
1206 /* Use the default character height. */
1207 it
->glyph_row
= NULL
;
1208 it
->what
= IT_CHARACTER
;
1211 PRODUCE_GLYPHS (it
);
1212 line_height
= it
->ascent
+ it
->descent
;
1213 it
->glyph_row
= row
;
1217 return line_top_y
+ line_height
;
1220 /* Subroutine of pos_visible_p below. Extracts a display string, if
1221 any, from the display spec given as its argument. */
1223 string_from_display_spec (Lisp_Object spec
)
1227 while (CONSP (spec
))
1229 if (STRINGP (XCAR (spec
)))
1234 else if (VECTORP (spec
))
1238 for (i
= 0; i
< ASIZE (spec
); i
++)
1240 if (STRINGP (AREF (spec
, i
)))
1241 return AREF (spec
, i
);
1250 /* Limit insanely large values of W->hscroll on frame F to the largest
1251 value that will still prevent first_visible_x and last_visible_x of
1252 'struct it' from overflowing an int. */
1254 window_hscroll_limited (struct window
*w
, struct frame
*f
)
1256 ptrdiff_t window_hscroll
= w
->hscroll
;
1257 int window_text_width
= window_box_width (w
, TEXT_AREA
);
1258 int colwidth
= FRAME_COLUMN_WIDTH (f
);
1260 if (window_hscroll
> (INT_MAX
- window_text_width
) / colwidth
- 1)
1261 window_hscroll
= (INT_MAX
- window_text_width
) / colwidth
- 1;
1263 return window_hscroll
;
1266 /* Return 1 if position CHARPOS is visible in window W.
1267 CHARPOS < 0 means return info about WINDOW_END position.
1268 If visible, set *X and *Y to pixel coordinates of top left corner.
1269 Set *RTOP and *RBOT to pixel height of an invisible area of glyph at POS.
1270 Set *ROWH and *VPOS to row's visible height and VPOS (row number). */
1273 pos_visible_p (struct window
*w
, ptrdiff_t charpos
, int *x
, int *y
,
1274 int *rtop
, int *rbot
, int *rowh
, int *vpos
)
1277 void *itdata
= bidi_shelve_cache ();
1278 struct text_pos top
;
1280 struct buffer
*old_buffer
= NULL
;
1282 if (FRAME_INITIAL_P (XFRAME (WINDOW_FRAME (w
))))
1285 if (XBUFFER (w
->contents
) != current_buffer
)
1287 old_buffer
= current_buffer
;
1288 set_buffer_internal_1 (XBUFFER (w
->contents
));
1291 SET_TEXT_POS_FROM_MARKER (top
, w
->start
);
1292 /* Scrolling a minibuffer window via scroll bar when the echo area
1293 shows long text sometimes resets the minibuffer contents behind
1295 if (CHARPOS (top
) > ZV
)
1296 SET_TEXT_POS (top
, BEGV
, BEGV_BYTE
);
1298 /* Compute exact mode line heights. */
1299 if (WINDOW_WANTS_MODELINE_P (w
))
1300 current_mode_line_height
1301 = display_mode_line (w
, CURRENT_MODE_LINE_FACE_ID (w
),
1302 BVAR (current_buffer
, mode_line_format
));
1304 if (WINDOW_WANTS_HEADER_LINE_P (w
))
1305 current_header_line_height
1306 = display_mode_line (w
, HEADER_LINE_FACE_ID
,
1307 BVAR (current_buffer
, header_line_format
));
1309 start_display (&it
, w
, top
);
1310 move_it_to (&it
, charpos
, -1, it
.last_visible_y
- 1, -1,
1311 (charpos
>= 0 ? MOVE_TO_POS
: 0) | MOVE_TO_Y
);
1314 && (((!it
.bidi_p
|| it
.bidi_it
.scan_dir
== 1)
1315 && IT_CHARPOS (it
) >= charpos
)
1316 /* When scanning backwards under bidi iteration, move_it_to
1317 stops at or _before_ CHARPOS, because it stops at or to
1318 the _right_ of the character at CHARPOS. */
1319 || (it
.bidi_p
&& it
.bidi_it
.scan_dir
== -1
1320 && IT_CHARPOS (it
) <= charpos
)))
1322 /* We have reached CHARPOS, or passed it. How the call to
1323 move_it_to can overshoot: (i) If CHARPOS is on invisible text
1324 or covered by a display property, move_it_to stops at the end
1325 of the invisible text, to the right of CHARPOS. (ii) If
1326 CHARPOS is in a display vector, move_it_to stops on its last
1328 int top_x
= it
.current_x
;
1329 int top_y
= it
.current_y
;
1330 /* Calling line_bottom_y may change it.method, it.position, etc. */
1331 enum it_method it_method
= it
.method
;
1332 int bottom_y
= (last_height
= 0, line_bottom_y (&it
));
1333 int window_top_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
1335 if (top_y
< window_top_y
)
1336 visible_p
= bottom_y
> window_top_y
;
1337 else if (top_y
< it
.last_visible_y
)
1339 if (bottom_y
>= it
.last_visible_y
1340 && it
.bidi_p
&& it
.bidi_it
.scan_dir
== -1
1341 && IT_CHARPOS (it
) < charpos
)
1343 /* When the last line of the window is scanned backwards
1344 under bidi iteration, we could be duped into thinking
1345 that we have passed CHARPOS, when in fact move_it_to
1346 simply stopped short of CHARPOS because it reached
1347 last_visible_y. To see if that's what happened, we call
1348 move_it_to again with a slightly larger vertical limit,
1349 and see if it actually moved vertically; if it did, we
1350 didn't really reach CHARPOS, which is beyond window end. */
1351 struct it save_it
= it
;
1352 /* Why 10? because we don't know how many canonical lines
1353 will the height of the next line(s) be. So we guess. */
1354 int ten_more_lines
=
1355 10 * FRAME_LINE_HEIGHT (XFRAME (WINDOW_FRAME (w
)));
1357 move_it_to (&it
, charpos
, -1, bottom_y
+ ten_more_lines
, -1,
1358 MOVE_TO_POS
| MOVE_TO_Y
);
1359 if (it
.current_y
> top_y
)
1366 if (it_method
== GET_FROM_DISPLAY_VECTOR
)
1368 /* We stopped on the last glyph of a display vector.
1369 Try and recompute. Hack alert! */
1370 if (charpos
< 2 || top
.charpos
>= charpos
)
1371 top_x
= it
.glyph_row
->x
;
1374 struct it it2
, it2_prev
;
1375 /* The idea is to get to the previous buffer
1376 position, consume the character there, and use
1377 the pixel coordinates we get after that. But if
1378 the previous buffer position is also displayed
1379 from a display vector, we need to consume all of
1380 the glyphs from that display vector. */
1381 start_display (&it2
, w
, top
);
1382 move_it_to (&it2
, charpos
- 1, -1, -1, -1, MOVE_TO_POS
);
1383 /* If we didn't get to CHARPOS - 1, there's some
1384 replacing display property at that position, and
1385 we stopped after it. That is exactly the place
1386 whose coordinates we want. */
1387 if (IT_CHARPOS (it2
) != charpos
- 1)
1391 /* Iterate until we get out of the display
1392 vector that displays the character at
1395 get_next_display_element (&it2
);
1396 PRODUCE_GLYPHS (&it2
);
1398 set_iterator_to_next (&it2
, 1);
1399 } while (it2
.method
== GET_FROM_DISPLAY_VECTOR
1400 && IT_CHARPOS (it2
) < charpos
);
1402 if (ITERATOR_AT_END_OF_LINE_P (&it2_prev
)
1403 || it2_prev
.current_x
> it2_prev
.last_visible_x
)
1404 top_x
= it
.glyph_row
->x
;
1407 top_x
= it2_prev
.current_x
;
1408 top_y
= it2_prev
.current_y
;
1412 else if (IT_CHARPOS (it
) != charpos
)
1414 Lisp_Object cpos
= make_number (charpos
);
1415 Lisp_Object spec
= Fget_char_property (cpos
, Qdisplay
, Qnil
);
1416 Lisp_Object string
= string_from_display_spec (spec
);
1417 struct text_pos tpos
;
1418 int replacing_spec_p
;
1419 bool newline_in_string
1421 && memchr (SDATA (string
), '\n', SBYTES (string
)));
1423 SET_TEXT_POS (tpos
, charpos
, CHAR_TO_BYTE (charpos
));
1426 && handle_display_spec (NULL
, spec
, Qnil
, Qnil
, &tpos
,
1427 charpos
, FRAME_WINDOW_P (it
.f
)));
1428 /* The tricky code below is needed because there's a
1429 discrepancy between move_it_to and how we set cursor
1430 when PT is at the beginning of a portion of text
1431 covered by a display property or an overlay with a
1432 display property, or the display line ends in a
1433 newline from a display string. move_it_to will stop
1434 _after_ such display strings, whereas
1435 set_cursor_from_row conspires with cursor_row_p to
1436 place the cursor on the first glyph produced from the
1439 /* We have overshoot PT because it is covered by a
1440 display property that replaces the text it covers.
1441 If the string includes embedded newlines, we are also
1442 in the wrong display line. Backtrack to the correct
1443 line, where the display property begins. */
1444 if (replacing_spec_p
)
1446 Lisp_Object startpos
, endpos
;
1447 EMACS_INT start
, end
;
1451 /* Find the first and the last buffer positions
1452 covered by the display string. */
1454 Fnext_single_char_property_change (cpos
, Qdisplay
,
1457 Fprevious_single_char_property_change (endpos
, Qdisplay
,
1459 start
= XFASTINT (startpos
);
1460 end
= XFASTINT (endpos
);
1461 /* Move to the last buffer position before the
1462 display property. */
1463 start_display (&it3
, w
, top
);
1464 move_it_to (&it3
, start
- 1, -1, -1, -1, MOVE_TO_POS
);
1465 /* Move forward one more line if the position before
1466 the display string is a newline or if it is the
1467 rightmost character on a line that is
1468 continued or word-wrapped. */
1469 if (it3
.method
== GET_FROM_BUFFER
1471 || FETCH_BYTE (IT_BYTEPOS (it3
)) == '\n'))
1472 move_it_by_lines (&it3
, 1);
1473 else if (move_it_in_display_line_to (&it3
, -1,
1477 == MOVE_LINE_CONTINUED
)
1479 move_it_by_lines (&it3
, 1);
1480 /* When we are under word-wrap, the #$@%!
1481 move_it_by_lines moves 2 lines, so we need to
1483 if (it3
.line_wrap
== WORD_WRAP
)
1484 move_it_by_lines (&it3
, -1);
1487 /* Record the vertical coordinate of the display
1488 line where we wound up. */
1489 top_y
= it3
.current_y
;
1492 /* When characters are reordered for display,
1493 the character displayed to the left of the
1494 display string could be _after_ the display
1495 property in the logical order. Use the
1496 smallest vertical position of these two. */
1497 start_display (&it3
, w
, top
);
1498 move_it_to (&it3
, end
+ 1, -1, -1, -1, MOVE_TO_POS
);
1499 if (it3
.current_y
< top_y
)
1500 top_y
= it3
.current_y
;
1502 /* Move from the top of the window to the beginning
1503 of the display line where the display string
1505 start_display (&it3
, w
, top
);
1506 move_it_to (&it3
, -1, 0, top_y
, -1, MOVE_TO_X
| MOVE_TO_Y
);
1507 /* If it3_moved stays zero after the 'while' loop
1508 below, that means we already were at a newline
1509 before the loop (e.g., the display string begins
1510 with a newline), so we don't need to (and cannot)
1511 inspect the glyphs of it3.glyph_row, because
1512 PRODUCE_GLYPHS will not produce anything for a
1513 newline, and thus it3.glyph_row stays at its
1514 stale content it got at top of the window. */
1516 /* Finally, advance the iterator until we hit the
1517 first display element whose character position is
1518 CHARPOS, or until the first newline from the
1519 display string, which signals the end of the
1521 while (get_next_display_element (&it3
))
1523 PRODUCE_GLYPHS (&it3
);
1524 if (IT_CHARPOS (it3
) == charpos
1525 || ITERATOR_AT_END_OF_LINE_P (&it3
))
1528 set_iterator_to_next (&it3
, 0);
1530 top_x
= it3
.current_x
- it3
.pixel_width
;
1531 /* Normally, we would exit the above loop because we
1532 found the display element whose character
1533 position is CHARPOS. For the contingency that we
1534 didn't, and stopped at the first newline from the
1535 display string, move back over the glyphs
1536 produced from the string, until we find the
1537 rightmost glyph not from the string. */
1539 && newline_in_string
1540 && IT_CHARPOS (it3
) != charpos
&& EQ (it3
.object
, string
))
1542 struct glyph
*g
= it3
.glyph_row
->glyphs
[TEXT_AREA
]
1543 + it3
.glyph_row
->used
[TEXT_AREA
];
1545 while (EQ ((g
- 1)->object
, string
))
1548 top_x
-= g
->pixel_width
;
1550 eassert (g
< it3
.glyph_row
->glyphs
[TEXT_AREA
]
1551 + it3
.glyph_row
->used
[TEXT_AREA
]);
1557 *y
= max (top_y
+ max (0, it
.max_ascent
- it
.ascent
), window_top_y
);
1558 *rtop
= max (0, window_top_y
- top_y
);
1559 *rbot
= max (0, bottom_y
- it
.last_visible_y
);
1560 *rowh
= max (0, (min (bottom_y
, it
.last_visible_y
)
1561 - max (top_y
, window_top_y
)));
1567 /* We were asked to provide info about WINDOW_END. */
1569 void *it2data
= NULL
;
1571 SAVE_IT (it2
, it
, it2data
);
1572 if (IT_CHARPOS (it
) < ZV
&& FETCH_BYTE (IT_BYTEPOS (it
)) != '\n')
1573 move_it_by_lines (&it
, 1);
1574 if (charpos
< IT_CHARPOS (it
)
1575 || (it
.what
== IT_EOB
&& charpos
== IT_CHARPOS (it
)))
1578 RESTORE_IT (&it2
, &it2
, it2data
);
1579 move_it_to (&it2
, charpos
, -1, -1, -1, MOVE_TO_POS
);
1581 *y
= it2
.current_y
+ it2
.max_ascent
- it2
.ascent
;
1582 *rtop
= max (0, -it2
.current_y
);
1583 *rbot
= max (0, ((it2
.current_y
+ it2
.max_ascent
+ it2
.max_descent
)
1584 - it
.last_visible_y
));
1585 *rowh
= max (0, (min (it2
.current_y
+ it2
.max_ascent
+ it2
.max_descent
,
1587 - max (it2
.current_y
,
1588 WINDOW_HEADER_LINE_HEIGHT (w
))));
1592 bidi_unshelve_cache (it2data
, 1);
1594 bidi_unshelve_cache (itdata
, 0);
1597 set_buffer_internal_1 (old_buffer
);
1599 current_header_line_height
= current_mode_line_height
= -1;
1601 if (visible_p
&& w
->hscroll
> 0)
1603 window_hscroll_limited (w
, WINDOW_XFRAME (w
))
1604 * WINDOW_FRAME_COLUMN_WIDTH (w
);
1607 /* Debugging code. */
1609 fprintf (stderr
, "+pv pt=%d vs=%d --> x=%d y=%d rt=%d rb=%d rh=%d vp=%d\n",
1610 charpos
, w
->vscroll
, *x
, *y
, *rtop
, *rbot
, *rowh
, *vpos
);
1612 fprintf (stderr
, "-pv pt=%d vs=%d\n", charpos
, w
->vscroll
);
1619 /* Return the next character from STR. Return in *LEN the length of
1620 the character. This is like STRING_CHAR_AND_LENGTH but never
1621 returns an invalid character. If we find one, we return a `?', but
1622 with the length of the invalid character. */
1625 string_char_and_length (const unsigned char *str
, int *len
)
1629 c
= STRING_CHAR_AND_LENGTH (str
, *len
);
1630 if (!CHAR_VALID_P (c
))
1631 /* We may not change the length here because other places in Emacs
1632 don't use this function, i.e. they silently accept invalid
1641 /* Given a position POS containing a valid character and byte position
1642 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1644 static struct text_pos
1645 string_pos_nchars_ahead (struct text_pos pos
, Lisp_Object string
, ptrdiff_t nchars
)
1647 eassert (STRINGP (string
) && nchars
>= 0);
1649 if (STRING_MULTIBYTE (string
))
1651 const unsigned char *p
= SDATA (string
) + BYTEPOS (pos
);
1656 string_char_and_length (p
, &len
);
1659 BYTEPOS (pos
) += len
;
1663 SET_TEXT_POS (pos
, CHARPOS (pos
) + nchars
, BYTEPOS (pos
) + nchars
);
1669 /* Value is the text position, i.e. character and byte position,
1670 for character position CHARPOS in STRING. */
1672 static struct text_pos
1673 string_pos (ptrdiff_t charpos
, Lisp_Object string
)
1675 struct text_pos pos
;
1676 eassert (STRINGP (string
));
1677 eassert (charpos
>= 0);
1678 SET_TEXT_POS (pos
, charpos
, string_char_to_byte (string
, charpos
));
1683 /* Value is a text position, i.e. character and byte position, for
1684 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1685 means recognize multibyte characters. */
1687 static struct text_pos
1688 c_string_pos (ptrdiff_t charpos
, const char *s
, bool multibyte_p
)
1690 struct text_pos pos
;
1692 eassert (s
!= NULL
);
1693 eassert (charpos
>= 0);
1699 SET_TEXT_POS (pos
, 0, 0);
1702 string_char_and_length ((const unsigned char *) s
, &len
);
1705 BYTEPOS (pos
) += len
;
1709 SET_TEXT_POS (pos
, charpos
, charpos
);
1715 /* Value is the number of characters in C string S. MULTIBYTE_P
1716 non-zero means recognize multibyte characters. */
1719 number_of_chars (const char *s
, bool multibyte_p
)
1725 ptrdiff_t rest
= strlen (s
);
1727 const unsigned char *p
= (const unsigned char *) s
;
1729 for (nchars
= 0; rest
> 0; ++nchars
)
1731 string_char_and_length (p
, &len
);
1732 rest
-= len
, p
+= len
;
1736 nchars
= strlen (s
);
1742 /* Compute byte position NEWPOS->bytepos corresponding to
1743 NEWPOS->charpos. POS is a known position in string STRING.
1744 NEWPOS->charpos must be >= POS.charpos. */
1747 compute_string_pos (struct text_pos
*newpos
, struct text_pos pos
, Lisp_Object string
)
1749 eassert (STRINGP (string
));
1750 eassert (CHARPOS (*newpos
) >= CHARPOS (pos
));
1752 if (STRING_MULTIBYTE (string
))
1753 *newpos
= string_pos_nchars_ahead (pos
, string
,
1754 CHARPOS (*newpos
) - CHARPOS (pos
));
1756 BYTEPOS (*newpos
) = CHARPOS (*newpos
);
1760 Return an estimation of the pixel height of mode or header lines on
1761 frame F. FACE_ID specifies what line's height to estimate. */
1764 estimate_mode_line_height (struct frame
*f
, enum face_id face_id
)
1766 #ifdef HAVE_WINDOW_SYSTEM
1767 if (FRAME_WINDOW_P (f
))
1769 int height
= FONT_HEIGHT (FRAME_FONT (f
));
1771 /* This function is called so early when Emacs starts that the face
1772 cache and mode line face are not yet initialized. */
1773 if (FRAME_FACE_CACHE (f
))
1775 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1779 height
= FONT_HEIGHT (face
->font
);
1780 if (face
->box_line_width
> 0)
1781 height
+= 2 * face
->box_line_width
;
1792 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1793 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1794 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1795 not force the value into range. */
1798 pixel_to_glyph_coords (FRAME_PTR f
, register int pix_x
, register int pix_y
,
1799 int *x
, int *y
, NativeRectangle
*bounds
, int noclip
)
1802 #ifdef HAVE_WINDOW_SYSTEM
1803 if (FRAME_WINDOW_P (f
))
1805 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1806 even for negative values. */
1808 pix_x
-= FRAME_COLUMN_WIDTH (f
) - 1;
1810 pix_y
-= FRAME_LINE_HEIGHT (f
) - 1;
1812 pix_x
= FRAME_PIXEL_X_TO_COL (f
, pix_x
);
1813 pix_y
= FRAME_PIXEL_Y_TO_LINE (f
, pix_y
);
1816 STORE_NATIVE_RECT (*bounds
,
1817 FRAME_COL_TO_PIXEL_X (f
, pix_x
),
1818 FRAME_LINE_TO_PIXEL_Y (f
, pix_y
),
1819 FRAME_COLUMN_WIDTH (f
) - 1,
1820 FRAME_LINE_HEIGHT (f
) - 1);
1826 else if (pix_x
> FRAME_TOTAL_COLS (f
))
1827 pix_x
= FRAME_TOTAL_COLS (f
);
1831 else if (pix_y
> FRAME_LINES (f
))
1832 pix_y
= FRAME_LINES (f
);
1842 /* Find the glyph under window-relative coordinates X/Y in window W.
1843 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1844 strings. Return in *HPOS and *VPOS the row and column number of
1845 the glyph found. Return in *AREA the glyph area containing X.
1846 Value is a pointer to the glyph found or null if X/Y is not on
1847 text, or we can't tell because W's current matrix is not up to
1852 x_y_to_hpos_vpos (struct window
*w
, int x
, int y
, int *hpos
, int *vpos
,
1853 int *dx
, int *dy
, int *area
)
1855 struct glyph
*glyph
, *end
;
1856 struct glyph_row
*row
= NULL
;
1859 /* Find row containing Y. Give up if some row is not enabled. */
1860 for (i
= 0; i
< w
->current_matrix
->nrows
; ++i
)
1862 row
= MATRIX_ROW (w
->current_matrix
, i
);
1863 if (!row
->enabled_p
)
1865 if (y
>= row
->y
&& y
< MATRIX_ROW_BOTTOM_Y (row
))
1872 /* Give up if Y is not in the window. */
1873 if (i
== w
->current_matrix
->nrows
)
1876 /* Get the glyph area containing X. */
1877 if (w
->pseudo_window_p
)
1884 if (x
< window_box_left_offset (w
, TEXT_AREA
))
1886 *area
= LEFT_MARGIN_AREA
;
1887 x0
= window_box_left_offset (w
, LEFT_MARGIN_AREA
);
1889 else if (x
< window_box_right_offset (w
, TEXT_AREA
))
1892 x0
= window_box_left_offset (w
, TEXT_AREA
) + min (row
->x
, 0);
1896 *area
= RIGHT_MARGIN_AREA
;
1897 x0
= window_box_left_offset (w
, RIGHT_MARGIN_AREA
);
1901 /* Find glyph containing X. */
1902 glyph
= row
->glyphs
[*area
];
1903 end
= glyph
+ row
->used
[*area
];
1905 while (glyph
< end
&& x
>= glyph
->pixel_width
)
1907 x
-= glyph
->pixel_width
;
1917 *dy
= y
- (row
->y
+ row
->ascent
- glyph
->ascent
);
1920 *hpos
= glyph
- row
->glyphs
[*area
];
1924 /* Convert frame-relative x/y to coordinates relative to window W.
1925 Takes pseudo-windows into account. */
1928 frame_to_window_pixel_xy (struct window
*w
, int *x
, int *y
)
1930 if (w
->pseudo_window_p
)
1932 /* A pseudo-window is always full-width, and starts at the
1933 left edge of the frame, plus a frame border. */
1934 struct frame
*f
= XFRAME (w
->frame
);
1935 *x
-= FRAME_INTERNAL_BORDER_WIDTH (f
);
1936 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
1940 *x
-= WINDOW_LEFT_EDGE_X (w
);
1941 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
1945 #ifdef HAVE_WINDOW_SYSTEM
1948 Return in RECTS[] at most N clipping rectangles for glyph string S.
1949 Return the number of stored rectangles. */
1952 get_glyph_string_clip_rects (struct glyph_string
*s
, NativeRectangle
*rects
, int n
)
1959 if (s
->row
->full_width_p
)
1961 /* Draw full-width. X coordinates are relative to S->w->left_col. */
1962 r
.x
= WINDOW_LEFT_EDGE_X (s
->w
);
1963 r
.width
= WINDOW_TOTAL_WIDTH (s
->w
);
1965 /* Unless displaying a mode or menu bar line, which are always
1966 fully visible, clip to the visible part of the row. */
1967 if (s
->w
->pseudo_window_p
)
1968 r
.height
= s
->row
->visible_height
;
1970 r
.height
= s
->height
;
1974 /* This is a text line that may be partially visible. */
1975 r
.x
= window_box_left (s
->w
, s
->area
);
1976 r
.width
= window_box_width (s
->w
, s
->area
);
1977 r
.height
= s
->row
->visible_height
;
1981 if (r
.x
< s
->clip_head
->x
)
1983 if (r
.width
>= s
->clip_head
->x
- r
.x
)
1984 r
.width
-= s
->clip_head
->x
- r
.x
;
1987 r
.x
= s
->clip_head
->x
;
1990 if (r
.x
+ r
.width
> s
->clip_tail
->x
+ s
->clip_tail
->background_width
)
1992 if (s
->clip_tail
->x
+ s
->clip_tail
->background_width
>= r
.x
)
1993 r
.width
= s
->clip_tail
->x
+ s
->clip_tail
->background_width
- r
.x
;
1998 /* If S draws overlapping rows, it's sufficient to use the top and
1999 bottom of the window for clipping because this glyph string
2000 intentionally draws over other lines. */
2001 if (s
->for_overlaps
)
2003 r
.y
= WINDOW_HEADER_LINE_HEIGHT (s
->w
);
2004 r
.height
= window_text_bottom_y (s
->w
) - r
.y
;
2006 /* Alas, the above simple strategy does not work for the
2007 environments with anti-aliased text: if the same text is
2008 drawn onto the same place multiple times, it gets thicker.
2009 If the overlap we are processing is for the erased cursor, we
2010 take the intersection with the rectangle of the cursor. */
2011 if (s
->for_overlaps
& OVERLAPS_ERASED_CURSOR
)
2013 XRectangle rc
, r_save
= r
;
2015 rc
.x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (s
->w
, s
->w
->phys_cursor
.x
);
2016 rc
.y
= s
->w
->phys_cursor
.y
;
2017 rc
.width
= s
->w
->phys_cursor_width
;
2018 rc
.height
= s
->w
->phys_cursor_height
;
2020 x_intersect_rectangles (&r_save
, &rc
, &r
);
2025 /* Don't use S->y for clipping because it doesn't take partially
2026 visible lines into account. For example, it can be negative for
2027 partially visible lines at the top of a window. */
2028 if (!s
->row
->full_width_p
2029 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s
->w
, s
->row
))
2030 r
.y
= WINDOW_HEADER_LINE_HEIGHT (s
->w
);
2032 r
.y
= max (0, s
->row
->y
);
2035 r
.y
= WINDOW_TO_FRAME_PIXEL_Y (s
->w
, r
.y
);
2037 /* If drawing the cursor, don't let glyph draw outside its
2038 advertised boundaries. Cleartype does this under some circumstances. */
2039 if (s
->hl
== DRAW_CURSOR
)
2041 struct glyph
*glyph
= s
->first_glyph
;
2046 r
.width
-= s
->x
- r
.x
;
2049 r
.width
= min (r
.width
, glyph
->pixel_width
);
2051 /* If r.y is below window bottom, ensure that we still see a cursor. */
2052 height
= min (glyph
->ascent
+ glyph
->descent
,
2053 min (FRAME_LINE_HEIGHT (s
->f
), s
->row
->visible_height
));
2054 max_y
= window_text_bottom_y (s
->w
) - height
;
2055 max_y
= WINDOW_TO_FRAME_PIXEL_Y (s
->w
, max_y
);
2056 if (s
->ybase
- glyph
->ascent
> max_y
)
2063 /* Don't draw cursor glyph taller than our actual glyph. */
2064 height
= max (FRAME_LINE_HEIGHT (s
->f
), glyph
->ascent
+ glyph
->descent
);
2065 if (height
< r
.height
)
2067 max_y
= r
.y
+ r
.height
;
2068 r
.y
= min (max_y
, max (r
.y
, s
->ybase
+ glyph
->descent
- height
));
2069 r
.height
= min (max_y
- r
.y
, height
);
2076 XRectangle r_save
= r
;
2078 if (! x_intersect_rectangles (&r_save
, s
->row
->clip
, &r
))
2082 if ((s
->for_overlaps
& OVERLAPS_BOTH
) == 0
2083 || ((s
->for_overlaps
& OVERLAPS_BOTH
) == OVERLAPS_BOTH
&& n
== 1))
2085 #ifdef CONVERT_FROM_XRECT
2086 CONVERT_FROM_XRECT (r
, *rects
);
2094 /* If we are processing overlapping and allowed to return
2095 multiple clipping rectangles, we exclude the row of the glyph
2096 string from the clipping rectangle. This is to avoid drawing
2097 the same text on the environment with anti-aliasing. */
2098 #ifdef CONVERT_FROM_XRECT
2101 XRectangle
*rs
= rects
;
2103 int i
= 0, row_y
= WINDOW_TO_FRAME_PIXEL_Y (s
->w
, s
->row
->y
);
2105 if (s
->for_overlaps
& OVERLAPS_PRED
)
2108 if (r
.y
+ r
.height
> row_y
)
2111 rs
[i
].height
= row_y
- r
.y
;
2117 if (s
->for_overlaps
& OVERLAPS_SUCC
)
2120 if (r
.y
< row_y
+ s
->row
->visible_height
)
2122 if (r
.y
+ r
.height
> row_y
+ s
->row
->visible_height
)
2124 rs
[i
].y
= row_y
+ s
->row
->visible_height
;
2125 rs
[i
].height
= r
.y
+ r
.height
- rs
[i
].y
;
2134 #ifdef CONVERT_FROM_XRECT
2135 for (i
= 0; i
< n
; i
++)
2136 CONVERT_FROM_XRECT (rs
[i
], rects
[i
]);
2143 Return in *NR the clipping rectangle for glyph string S. */
2146 get_glyph_string_clip_rect (struct glyph_string
*s
, NativeRectangle
*nr
)
2148 get_glyph_string_clip_rects (s
, nr
, 1);
2153 Return the position and height of the phys cursor in window W.
2154 Set w->phys_cursor_width to width of phys cursor.
2158 get_phys_cursor_geometry (struct window
*w
, struct glyph_row
*row
,
2159 struct glyph
*glyph
, int *xp
, int *yp
, int *heightp
)
2161 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
2162 int x
, y
, wd
, h
, h0
, y0
;
2164 /* Compute the width of the rectangle to draw. If on a stretch
2165 glyph, and `x-stretch-block-cursor' is nil, don't draw a
2166 rectangle as wide as the glyph, but use a canonical character
2168 wd
= glyph
->pixel_width
- 1;
2169 #if defined (HAVE_NTGUI) || defined (HAVE_NS)
2173 x
= w
->phys_cursor
.x
;
2180 if (glyph
->type
== STRETCH_GLYPH
2181 && !x_stretch_cursor_p
)
2182 wd
= min (FRAME_COLUMN_WIDTH (f
), wd
);
2183 w
->phys_cursor_width
= wd
;
2185 y
= w
->phys_cursor
.y
+ row
->ascent
- glyph
->ascent
;
2187 /* If y is below window bottom, ensure that we still see a cursor. */
2188 h0
= min (FRAME_LINE_HEIGHT (f
), row
->visible_height
);
2190 h
= max (h0
, glyph
->ascent
+ glyph
->descent
);
2191 h0
= min (h0
, glyph
->ascent
+ glyph
->descent
);
2193 y0
= WINDOW_HEADER_LINE_HEIGHT (w
);
2196 h
= max (h
- (y0
- y
) + 1, h0
);
2201 y0
= window_text_bottom_y (w
) - h0
;
2209 *xp
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, x
);
2210 *yp
= WINDOW_TO_FRAME_PIXEL_Y (w
, y
);
2215 * Remember which glyph the mouse is over.
2219 remember_mouse_glyph (struct frame
*f
, int gx
, int gy
, NativeRectangle
*rect
)
2223 struct glyph_row
*r
, *gr
, *end_row
;
2224 enum window_part part
;
2225 enum glyph_row_area area
;
2226 int x
, y
, width
, height
;
2228 /* Try to determine frame pixel position and size of the glyph under
2229 frame pixel coordinates X/Y on frame F. */
2231 if (!f
->glyphs_initialized_p
2232 || (window
= window_from_coordinates (f
, gx
, gy
, &part
, 0),
2235 width
= FRAME_SMALLEST_CHAR_WIDTH (f
);
2236 height
= FRAME_SMALLEST_FONT_HEIGHT (f
);
2240 w
= XWINDOW (window
);
2241 width
= WINDOW_FRAME_COLUMN_WIDTH (w
);
2242 height
= WINDOW_FRAME_LINE_HEIGHT (w
);
2244 x
= window_relative_x_coord (w
, part
, gx
);
2245 y
= gy
- WINDOW_TOP_EDGE_Y (w
);
2247 r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
2248 end_row
= MATRIX_BOTTOM_TEXT_ROW (w
->current_matrix
, w
);
2250 if (w
->pseudo_window_p
)
2253 part
= ON_MODE_LINE
; /* Don't adjust margin. */
2259 case ON_LEFT_MARGIN
:
2260 area
= LEFT_MARGIN_AREA
;
2263 case ON_RIGHT_MARGIN
:
2264 area
= RIGHT_MARGIN_AREA
;
2267 case ON_HEADER_LINE
:
2269 gr
= (part
== ON_HEADER_LINE
2270 ? MATRIX_HEADER_LINE_ROW (w
->current_matrix
)
2271 : MATRIX_MODE_LINE_ROW (w
->current_matrix
));
2274 goto text_glyph_row_found
;
2281 for (; r
<= end_row
&& r
->enabled_p
; ++r
)
2282 if (r
->y
+ r
->height
> y
)
2288 text_glyph_row_found
:
2291 struct glyph
*g
= gr
->glyphs
[area
];
2292 struct glyph
*end
= g
+ gr
->used
[area
];
2294 height
= gr
->height
;
2295 for (gx
= gr
->x
; g
< end
; gx
+= g
->pixel_width
, ++g
)
2296 if (gx
+ g
->pixel_width
> x
)
2301 if (g
->type
== IMAGE_GLYPH
)
2303 /* Don't remember when mouse is over image, as
2304 image may have hot-spots. */
2305 STORE_NATIVE_RECT (*rect
, 0, 0, 0, 0);
2308 width
= g
->pixel_width
;
2312 /* Use nominal char spacing at end of line. */
2314 gx
+= (x
/ width
) * width
;
2317 if (part
!= ON_MODE_LINE
&& part
!= ON_HEADER_LINE
)
2318 gx
+= window_box_left_offset (w
, area
);
2322 /* Use nominal line height at end of window. */
2323 gx
= (x
/ width
) * width
;
2325 gy
+= (y
/ height
) * height
;
2329 case ON_LEFT_FRINGE
:
2330 gx
= (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
2331 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w
)
2332 : window_box_right_offset (w
, LEFT_MARGIN_AREA
));
2333 width
= WINDOW_LEFT_FRINGE_WIDTH (w
);
2336 case ON_RIGHT_FRINGE
:
2337 gx
= (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
2338 ? window_box_right_offset (w
, RIGHT_MARGIN_AREA
)
2339 : window_box_right_offset (w
, TEXT_AREA
));
2340 width
= WINDOW_RIGHT_FRINGE_WIDTH (w
);
2344 gx
= (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w
)
2346 : (window_box_right_offset (w
, RIGHT_MARGIN_AREA
)
2347 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
2348 ? WINDOW_RIGHT_FRINGE_WIDTH (w
)
2350 width
= WINDOW_SCROLL_BAR_AREA_WIDTH (w
);
2354 for (; r
<= end_row
&& r
->enabled_p
; ++r
)
2355 if (r
->y
+ r
->height
> y
)
2362 height
= gr
->height
;
2365 /* Use nominal line height at end of window. */
2367 gy
+= (y
/ height
) * height
;
2374 /* If there is no glyph under the mouse, then we divide the screen
2375 into a grid of the smallest glyph in the frame, and use that
2378 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to
2379 round down even for negative values. */
2385 gx
= (gx
/ width
) * width
;
2386 gy
= (gy
/ height
) * height
;
2391 gx
+= WINDOW_LEFT_EDGE_X (w
);
2392 gy
+= WINDOW_TOP_EDGE_Y (w
);
2395 STORE_NATIVE_RECT (*rect
, gx
, gy
, width
, height
);
2397 /* Visible feedback for debugging. */
2400 XDrawRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
2401 f
->output_data
.x
->normal_gc
,
2402 gx
, gy
, width
, height
);
2408 #endif /* HAVE_WINDOW_SYSTEM */
2411 /***********************************************************************
2412 Lisp form evaluation
2413 ***********************************************************************/
2415 /* Error handler for safe_eval and safe_call. */
2418 safe_eval_handler (Lisp_Object arg
, ptrdiff_t nargs
, Lisp_Object
*args
)
2420 add_to_log ("Error during redisplay: %S signaled %S",
2421 Flist (nargs
, args
), arg
);
2425 /* Call function FUNC with the rest of NARGS - 1 arguments
2426 following. Return the result, or nil if something went
2427 wrong. Prevent redisplay during the evaluation. */
2430 safe_call (ptrdiff_t nargs
, Lisp_Object func
, ...)
2434 if (inhibit_eval_during_redisplay
)
2440 ptrdiff_t count
= SPECPDL_INDEX ();
2441 struct gcpro gcpro1
;
2442 Lisp_Object
*args
= alloca (nargs
* word_size
);
2445 va_start (ap
, func
);
2446 for (i
= 1; i
< nargs
; i
++)
2447 args
[i
] = va_arg (ap
, Lisp_Object
);
2451 gcpro1
.nvars
= nargs
;
2452 specbind (Qinhibit_redisplay
, Qt
);
2453 /* Use Qt to ensure debugger does not run,
2454 so there is no possibility of wanting to redisplay. */
2455 val
= internal_condition_case_n (Ffuncall
, nargs
, args
, Qt
,
2458 val
= unbind_to (count
, val
);
2465 /* Call function FN with one argument ARG.
2466 Return the result, or nil if something went wrong. */
2469 safe_call1 (Lisp_Object fn
, Lisp_Object arg
)
2471 return safe_call (2, fn
, arg
);
2474 static Lisp_Object Qeval
;
2477 safe_eval (Lisp_Object sexpr
)
2479 return safe_call1 (Qeval
, sexpr
);
2482 /* Call function FN with two arguments ARG1 and ARG2.
2483 Return the result, or nil if something went wrong. */
2486 safe_call2 (Lisp_Object fn
, Lisp_Object arg1
, Lisp_Object arg2
)
2488 return safe_call (3, fn
, arg1
, arg2
);
2493 /***********************************************************************
2495 ***********************************************************************/
2499 /* Define CHECK_IT to perform sanity checks on iterators.
2500 This is for debugging. It is too slow to do unconditionally. */
2503 check_it (struct it
*it
)
2505 if (it
->method
== GET_FROM_STRING
)
2507 eassert (STRINGP (it
->string
));
2508 eassert (IT_STRING_CHARPOS (*it
) >= 0);
2512 eassert (IT_STRING_CHARPOS (*it
) < 0);
2513 if (it
->method
== GET_FROM_BUFFER
)
2515 /* Check that character and byte positions agree. */
2516 eassert (IT_CHARPOS (*it
) == BYTE_TO_CHAR (IT_BYTEPOS (*it
)));
2521 eassert (it
->current
.dpvec_index
>= 0);
2523 eassert (it
->current
.dpvec_index
< 0);
2526 #define CHECK_IT(IT) check_it ((IT))
2530 #define CHECK_IT(IT) (void) 0
2535 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
2537 /* Check that the window end of window W is what we expect it
2538 to be---the last row in the current matrix displaying text. */
2541 check_window_end (struct window
*w
)
2543 if (!MINI_WINDOW_P (w
) && w
->window_end_valid
)
2545 struct glyph_row
*row
;
2546 eassert ((row
= MATRIX_ROW (w
->current_matrix
,
2547 XFASTINT (w
->window_end_vpos
)),
2549 || MATRIX_ROW_DISPLAYS_TEXT_P (row
)
2550 || MATRIX_ROW_VPOS (row
, w
->current_matrix
) == 0));
2554 #define CHECK_WINDOW_END(W) check_window_end ((W))
2558 #define CHECK_WINDOW_END(W) (void) 0
2560 #endif /* GLYPH_DEBUG and ENABLE_CHECKING */
2562 /* Return mark position if current buffer has the region of non-zero length,
2566 markpos_of_region (void)
2568 if (!NILP (Vtransient_mark_mode
)
2569 && !NILP (BVAR (current_buffer
, mark_active
))
2570 && XMARKER (BVAR (current_buffer
, mark
))->buffer
!= NULL
)
2572 ptrdiff_t markpos
= XMARKER (BVAR (current_buffer
, mark
))->charpos
;
2580 /***********************************************************************
2581 Iterator initialization
2582 ***********************************************************************/
2584 /* Initialize IT for displaying current_buffer in window W, starting
2585 at character position CHARPOS. CHARPOS < 0 means that no buffer
2586 position is specified which is useful when the iterator is assigned
2587 a position later. BYTEPOS is the byte position corresponding to
2590 If ROW is not null, calls to produce_glyphs with IT as parameter
2591 will produce glyphs in that row.
2593 BASE_FACE_ID is the id of a base face to use. It must be one of
2594 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2595 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2596 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2598 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2599 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2600 will be initialized to use the corresponding mode line glyph row of
2601 the desired matrix of W. */
2604 init_iterator (struct it
*it
, struct window
*w
,
2605 ptrdiff_t charpos
, ptrdiff_t bytepos
,
2606 struct glyph_row
*row
, enum face_id base_face_id
)
2609 enum face_id remapped_base_face_id
= base_face_id
;
2611 /* Some precondition checks. */
2612 eassert (w
!= NULL
&& it
!= NULL
);
2613 eassert (charpos
< 0 || (charpos
>= BUF_BEG (current_buffer
)
2616 /* If face attributes have been changed since the last redisplay,
2617 free realized faces now because they depend on face definitions
2618 that might have changed. Don't free faces while there might be
2619 desired matrices pending which reference these faces. */
2620 if (face_change_count
&& !inhibit_free_realized_faces
)
2622 face_change_count
= 0;
2623 free_all_realized_faces (Qnil
);
2626 /* Perhaps remap BASE_FACE_ID to a user-specified alternative. */
2627 if (! NILP (Vface_remapping_alist
))
2628 remapped_base_face_id
2629 = lookup_basic_face (XFRAME (w
->frame
), base_face_id
);
2631 /* Use one of the mode line rows of W's desired matrix if
2635 if (base_face_id
== MODE_LINE_FACE_ID
2636 || base_face_id
== MODE_LINE_INACTIVE_FACE_ID
)
2637 row
= MATRIX_MODE_LINE_ROW (w
->desired_matrix
);
2638 else if (base_face_id
== HEADER_LINE_FACE_ID
)
2639 row
= MATRIX_HEADER_LINE_ROW (w
->desired_matrix
);
2643 memset (it
, 0, sizeof *it
);
2644 it
->current
.overlay_string_index
= -1;
2645 it
->current
.dpvec_index
= -1;
2646 it
->base_face_id
= remapped_base_face_id
;
2648 IT_STRING_CHARPOS (*it
) = IT_STRING_BYTEPOS (*it
) = -1;
2649 it
->paragraph_embedding
= L2R
;
2650 it
->bidi_it
.string
.lstring
= Qnil
;
2651 it
->bidi_it
.string
.s
= NULL
;
2652 it
->bidi_it
.string
.bufpos
= 0;
2655 /* The window in which we iterate over current_buffer: */
2656 XSETWINDOW (it
->window
, w
);
2658 it
->f
= XFRAME (w
->frame
);
2662 /* Extra space between lines (on window systems only). */
2663 if (base_face_id
== DEFAULT_FACE_ID
2664 && FRAME_WINDOW_P (it
->f
))
2666 if (NATNUMP (BVAR (current_buffer
, extra_line_spacing
)))
2667 it
->extra_line_spacing
= XFASTINT (BVAR (current_buffer
, extra_line_spacing
));
2668 else if (FLOATP (BVAR (current_buffer
, extra_line_spacing
)))
2669 it
->extra_line_spacing
= (XFLOAT_DATA (BVAR (current_buffer
, extra_line_spacing
))
2670 * FRAME_LINE_HEIGHT (it
->f
));
2671 else if (it
->f
->extra_line_spacing
> 0)
2672 it
->extra_line_spacing
= it
->f
->extra_line_spacing
;
2673 it
->max_extra_line_spacing
= 0;
2676 /* If realized faces have been removed, e.g. because of face
2677 attribute changes of named faces, recompute them. When running
2678 in batch mode, the face cache of the initial frame is null. If
2679 we happen to get called, make a dummy face cache. */
2680 if (FRAME_FACE_CACHE (it
->f
) == NULL
)
2681 init_frame_faces (it
->f
);
2682 if (FRAME_FACE_CACHE (it
->f
)->used
== 0)
2683 recompute_basic_faces (it
->f
);
2685 /* Current value of the `slice', `space-width', and 'height' properties. */
2686 it
->slice
.x
= it
->slice
.y
= it
->slice
.width
= it
->slice
.height
= Qnil
;
2687 it
->space_width
= Qnil
;
2688 it
->font_height
= Qnil
;
2689 it
->override_ascent
= -1;
2691 /* Are control characters displayed as `^C'? */
2692 it
->ctl_arrow_p
= !NILP (BVAR (current_buffer
, ctl_arrow
));
2694 /* -1 means everything between a CR and the following line end
2695 is invisible. >0 means lines indented more than this value are
2697 it
->selective
= (INTEGERP (BVAR (current_buffer
, selective_display
))
2699 (-1, XINT (BVAR (current_buffer
, selective_display
)),
2701 : (!NILP (BVAR (current_buffer
, selective_display
))
2703 it
->selective_display_ellipsis_p
2704 = !NILP (BVAR (current_buffer
, selective_display_ellipses
));
2706 /* Display table to use. */
2707 it
->dp
= window_display_table (w
);
2709 /* Are multibyte characters enabled in current_buffer? */
2710 it
->multibyte_p
= !NILP (BVAR (current_buffer
, enable_multibyte_characters
));
2712 /* If visible region is of non-zero length, set IT->region_beg_charpos
2713 and IT->region_end_charpos to the start and end of a visible region
2714 in window IT->w. Set both to -1 to indicate no region. */
2715 markpos
= markpos_of_region ();
2717 /* Maybe highlight only in selected window. */
2718 && (/* Either show region everywhere. */
2719 highlight_nonselected_windows
2720 /* Or show region in the selected window. */
2721 || w
== XWINDOW (selected_window
)
2722 /* Or show the region if we are in the mini-buffer and W is
2723 the window the mini-buffer refers to. */
2724 || (MINI_WINDOW_P (XWINDOW (selected_window
))
2725 && WINDOWP (minibuf_selected_window
)
2726 && w
== XWINDOW (minibuf_selected_window
))))
2728 it
->region_beg_charpos
= min (PT
, markpos
);
2729 it
->region_end_charpos
= max (PT
, markpos
);
2732 it
->region_beg_charpos
= it
->region_end_charpos
= -1;
2734 /* Get the position at which the redisplay_end_trigger hook should
2735 be run, if it is to be run at all. */
2736 if (MARKERP (w
->redisplay_end_trigger
)
2737 && XMARKER (w
->redisplay_end_trigger
)->buffer
!= 0)
2738 it
->redisplay_end_trigger_charpos
2739 = marker_position (w
->redisplay_end_trigger
);
2740 else if (INTEGERP (w
->redisplay_end_trigger
))
2741 it
->redisplay_end_trigger_charpos
=
2742 clip_to_bounds (PTRDIFF_MIN
, XINT (w
->redisplay_end_trigger
), PTRDIFF_MAX
);
2744 it
->tab_width
= SANE_TAB_WIDTH (current_buffer
);
2746 /* Are lines in the display truncated? */
2747 if (base_face_id
!= DEFAULT_FACE_ID
2749 || (! WINDOW_FULL_WIDTH_P (it
->w
)
2750 && ((!NILP (Vtruncate_partial_width_windows
)
2751 && !INTEGERP (Vtruncate_partial_width_windows
))
2752 || (INTEGERP (Vtruncate_partial_width_windows
)
2753 && (WINDOW_TOTAL_COLS (it
->w
)
2754 < XINT (Vtruncate_partial_width_windows
))))))
2755 it
->line_wrap
= TRUNCATE
;
2756 else if (NILP (BVAR (current_buffer
, truncate_lines
)))
2757 it
->line_wrap
= NILP (BVAR (current_buffer
, word_wrap
))
2758 ? WINDOW_WRAP
: WORD_WRAP
;
2760 it
->line_wrap
= TRUNCATE
;
2762 /* Get dimensions of truncation and continuation glyphs. These are
2763 displayed as fringe bitmaps under X, but we need them for such
2764 frames when the fringes are turned off. But leave the dimensions
2765 zero for tooltip frames, as these glyphs look ugly there and also
2766 sabotage calculations of tooltip dimensions in x-show-tip. */
2767 #ifdef HAVE_WINDOW_SYSTEM
2768 if (!(FRAME_WINDOW_P (it
->f
)
2769 && FRAMEP (tip_frame
)
2770 && it
->f
== XFRAME (tip_frame
)))
2773 if (it
->line_wrap
== TRUNCATE
)
2775 /* We will need the truncation glyph. */
2776 eassert (it
->glyph_row
== NULL
);
2777 produce_special_glyphs (it
, IT_TRUNCATION
);
2778 it
->truncation_pixel_width
= it
->pixel_width
;
2782 /* We will need the continuation glyph. */
2783 eassert (it
->glyph_row
== NULL
);
2784 produce_special_glyphs (it
, IT_CONTINUATION
);
2785 it
->continuation_pixel_width
= it
->pixel_width
;
2789 /* Reset these values to zero because the produce_special_glyphs
2790 above has changed them. */
2791 it
->pixel_width
= it
->ascent
= it
->descent
= 0;
2792 it
->phys_ascent
= it
->phys_descent
= 0;
2794 /* Set this after getting the dimensions of truncation and
2795 continuation glyphs, so that we don't produce glyphs when calling
2796 produce_special_glyphs, above. */
2797 it
->glyph_row
= row
;
2798 it
->area
= TEXT_AREA
;
2800 /* Forget any previous info about this row being reversed. */
2802 it
->glyph_row
->reversed_p
= 0;
2804 /* Get the dimensions of the display area. The display area
2805 consists of the visible window area plus a horizontally scrolled
2806 part to the left of the window. All x-values are relative to the
2807 start of this total display area. */
2808 if (base_face_id
!= DEFAULT_FACE_ID
)
2810 /* Mode lines, menu bar in terminal frames. */
2811 it
->first_visible_x
= 0;
2812 it
->last_visible_x
= WINDOW_TOTAL_WIDTH (w
);
2816 it
->first_visible_x
=
2817 window_hscroll_limited (it
->w
, it
->f
) * FRAME_COLUMN_WIDTH (it
->f
);
2818 it
->last_visible_x
= (it
->first_visible_x
2819 + window_box_width (w
, TEXT_AREA
));
2821 /* If we truncate lines, leave room for the truncation glyph(s) at
2822 the right margin. Otherwise, leave room for the continuation
2823 glyph(s). Done only if the window has no fringes. Since we
2824 don't know at this point whether there will be any R2L lines in
2825 the window, we reserve space for truncation/continuation glyphs
2826 even if only one of the fringes is absent. */
2827 if (WINDOW_RIGHT_FRINGE_WIDTH (it
->w
) == 0
2828 || (it
->bidi_p
&& WINDOW_LEFT_FRINGE_WIDTH (it
->w
) == 0))
2830 if (it
->line_wrap
== TRUNCATE
)
2831 it
->last_visible_x
-= it
->truncation_pixel_width
;
2833 it
->last_visible_x
-= it
->continuation_pixel_width
;
2836 it
->header_line_p
= WINDOW_WANTS_HEADER_LINE_P (w
);
2837 it
->current_y
= WINDOW_HEADER_LINE_HEIGHT (w
) + w
->vscroll
;
2840 /* Leave room for a border glyph. */
2841 if (!FRAME_WINDOW_P (it
->f
)
2842 && !WINDOW_RIGHTMOST_P (it
->w
))
2843 it
->last_visible_x
-= 1;
2845 it
->last_visible_y
= window_text_bottom_y (w
);
2847 /* For mode lines and alike, arrange for the first glyph having a
2848 left box line if the face specifies a box. */
2849 if (base_face_id
!= DEFAULT_FACE_ID
)
2853 it
->face_id
= remapped_base_face_id
;
2855 /* If we have a boxed mode line, make the first character appear
2856 with a left box line. */
2857 face
= FACE_FROM_ID (it
->f
, remapped_base_face_id
);
2858 if (face
->box
!= FACE_NO_BOX
)
2859 it
->start_of_box_run_p
= 1;
2862 /* If a buffer position was specified, set the iterator there,
2863 getting overlays and face properties from that position. */
2864 if (charpos
>= BUF_BEG (current_buffer
))
2866 it
->end_charpos
= ZV
;
2867 eassert (charpos
== BYTE_TO_CHAR (bytepos
));
2868 IT_CHARPOS (*it
) = charpos
;
2869 IT_BYTEPOS (*it
) = bytepos
;
2871 /* We will rely on `reseat' to set this up properly, via
2872 handle_face_prop. */
2873 it
->face_id
= it
->base_face_id
;
2875 it
->start
= it
->current
;
2876 /* Do we need to reorder bidirectional text? Not if this is a
2877 unibyte buffer: by definition, none of the single-byte
2878 characters are strong R2L, so no reordering is needed. And
2879 bidi.c doesn't support unibyte buffers anyway. Also, don't
2880 reorder while we are loading loadup.el, since the tables of
2881 character properties needed for reordering are not yet
2885 && !NILP (BVAR (current_buffer
, bidi_display_reordering
))
2888 /* If we are to reorder bidirectional text, init the bidi
2892 /* Note the paragraph direction that this buffer wants to
2894 if (EQ (BVAR (current_buffer
, bidi_paragraph_direction
),
2896 it
->paragraph_embedding
= L2R
;
2897 else if (EQ (BVAR (current_buffer
, bidi_paragraph_direction
),
2899 it
->paragraph_embedding
= R2L
;
2901 it
->paragraph_embedding
= NEUTRAL_DIR
;
2902 bidi_unshelve_cache (NULL
, 0);
2903 bidi_init_it (charpos
, IT_BYTEPOS (*it
), FRAME_WINDOW_P (it
->f
),
2907 /* Compute faces etc. */
2908 reseat (it
, it
->current
.pos
, 1);
2915 /* Initialize IT for the display of window W with window start POS. */
2918 start_display (struct it
*it
, struct window
*w
, struct text_pos pos
)
2920 struct glyph_row
*row
;
2921 int first_vpos
= WINDOW_WANTS_HEADER_LINE_P (w
) ? 1 : 0;
2923 row
= w
->desired_matrix
->rows
+ first_vpos
;
2924 init_iterator (it
, w
, CHARPOS (pos
), BYTEPOS (pos
), row
, DEFAULT_FACE_ID
);
2925 it
->first_vpos
= first_vpos
;
2927 /* Don't reseat to previous visible line start if current start
2928 position is in a string or image. */
2929 if (it
->method
== GET_FROM_BUFFER
&& it
->line_wrap
!= TRUNCATE
)
2931 int start_at_line_beg_p
;
2932 int first_y
= it
->current_y
;
2934 /* If window start is not at a line start, skip forward to POS to
2935 get the correct continuation lines width. */
2936 start_at_line_beg_p
= (CHARPOS (pos
) == BEGV
2937 || FETCH_BYTE (BYTEPOS (pos
) - 1) == '\n');
2938 if (!start_at_line_beg_p
)
2942 reseat_at_previous_visible_line_start (it
);
2943 move_it_to (it
, CHARPOS (pos
), -1, -1, -1, MOVE_TO_POS
);
2945 new_x
= it
->current_x
+ it
->pixel_width
;
2947 /* If lines are continued, this line may end in the middle
2948 of a multi-glyph character (e.g. a control character
2949 displayed as \003, or in the middle of an overlay
2950 string). In this case move_it_to above will not have
2951 taken us to the start of the continuation line but to the
2952 end of the continued line. */
2953 if (it
->current_x
> 0
2954 && it
->line_wrap
!= TRUNCATE
/* Lines are continued. */
2955 && (/* And glyph doesn't fit on the line. */
2956 new_x
> it
->last_visible_x
2957 /* Or it fits exactly and we're on a window
2959 || (new_x
== it
->last_visible_x
2960 && FRAME_WINDOW_P (it
->f
)
2961 && ((it
->bidi_p
&& it
->bidi_it
.paragraph_dir
== R2L
)
2962 ? WINDOW_LEFT_FRINGE_WIDTH (it
->w
)
2963 : WINDOW_RIGHT_FRINGE_WIDTH (it
->w
)))))
2965 if ((it
->current
.dpvec_index
>= 0
2966 || it
->current
.overlay_string_index
>= 0)
2967 /* If we are on a newline from a display vector or
2968 overlay string, then we are already at the end of
2969 a screen line; no need to go to the next line in
2970 that case, as this line is not really continued.
2971 (If we do go to the next line, C-e will not DTRT.) */
2974 set_iterator_to_next (it
, 1);
2975 move_it_in_display_line_to (it
, -1, -1, 0);
2978 it
->continuation_lines_width
+= it
->current_x
;
2980 /* If the character at POS is displayed via a display
2981 vector, move_it_to above stops at the final glyph of
2982 IT->dpvec. To make the caller redisplay that character
2983 again (a.k.a. start at POS), we need to reset the
2984 dpvec_index to the beginning of IT->dpvec. */
2985 else if (it
->current
.dpvec_index
>= 0)
2986 it
->current
.dpvec_index
= 0;
2988 /* We're starting a new display line, not affected by the
2989 height of the continued line, so clear the appropriate
2990 fields in the iterator structure. */
2991 it
->max_ascent
= it
->max_descent
= 0;
2992 it
->max_phys_ascent
= it
->max_phys_descent
= 0;
2994 it
->current_y
= first_y
;
2996 it
->current_x
= it
->hpos
= 0;
3002 /* Return 1 if POS is a position in ellipses displayed for invisible
3003 text. W is the window we display, for text property lookup. */
3006 in_ellipses_for_invisible_text_p (struct display_pos
*pos
, struct window
*w
)
3008 Lisp_Object prop
, window
;
3010 ptrdiff_t charpos
= CHARPOS (pos
->pos
);
3012 /* If POS specifies a position in a display vector, this might
3013 be for an ellipsis displayed for invisible text. We won't
3014 get the iterator set up for delivering that ellipsis unless
3015 we make sure that it gets aware of the invisible text. */
3016 if (pos
->dpvec_index
>= 0
3017 && pos
->overlay_string_index
< 0
3018 && CHARPOS (pos
->string_pos
) < 0
3020 && (XSETWINDOW (window
, w
),
3021 prop
= Fget_char_property (make_number (charpos
),
3022 Qinvisible
, window
),
3023 !TEXT_PROP_MEANS_INVISIBLE (prop
)))
3025 prop
= Fget_char_property (make_number (charpos
- 1), Qinvisible
,
3027 ellipses_p
= 2 == TEXT_PROP_MEANS_INVISIBLE (prop
);
3034 /* Initialize IT for stepping through current_buffer in window W,
3035 starting at position POS that includes overlay string and display
3036 vector/ control character translation position information. Value
3037 is zero if there are overlay strings with newlines at POS. */
3040 init_from_display_pos (struct it
*it
, struct window
*w
, struct display_pos
*pos
)
3042 ptrdiff_t charpos
= CHARPOS (pos
->pos
), bytepos
= BYTEPOS (pos
->pos
);
3043 int i
, overlay_strings_with_newlines
= 0;
3045 /* If POS specifies a position in a display vector, this might
3046 be for an ellipsis displayed for invisible text. We won't
3047 get the iterator set up for delivering that ellipsis unless
3048 we make sure that it gets aware of the invisible text. */
3049 if (in_ellipses_for_invisible_text_p (pos
, w
))
3055 /* Keep in mind: the call to reseat in init_iterator skips invisible
3056 text, so we might end up at a position different from POS. This
3057 is only a problem when POS is a row start after a newline and an
3058 overlay starts there with an after-string, and the overlay has an
3059 invisible property. Since we don't skip invisible text in
3060 display_line and elsewhere immediately after consuming the
3061 newline before the row start, such a POS will not be in a string,
3062 but the call to init_iterator below will move us to the
3064 init_iterator (it
, w
, charpos
, bytepos
, NULL
, DEFAULT_FACE_ID
);
3066 /* This only scans the current chunk -- it should scan all chunks.
3067 However, OVERLAY_STRING_CHUNK_SIZE has been increased from 3 in 21.1
3068 to 16 in 22.1 to make this a lesser problem. */
3069 for (i
= 0; i
< it
->n_overlay_strings
&& i
< OVERLAY_STRING_CHUNK_SIZE
; ++i
)
3071 const char *s
= SSDATA (it
->overlay_strings
[i
]);
3072 const char *e
= s
+ SBYTES (it
->overlay_strings
[i
]);
3074 while (s
< e
&& *s
!= '\n')
3079 overlay_strings_with_newlines
= 1;
3084 /* If position is within an overlay string, set up IT to the right
3086 if (pos
->overlay_string_index
>= 0)
3090 /* If the first overlay string happens to have a `display'
3091 property for an image, the iterator will be set up for that
3092 image, and we have to undo that setup first before we can
3093 correct the overlay string index. */
3094 if (it
->method
== GET_FROM_IMAGE
)
3097 /* We already have the first chunk of overlay strings in
3098 IT->overlay_strings. Load more until the one for
3099 pos->overlay_string_index is in IT->overlay_strings. */
3100 if (pos
->overlay_string_index
>= OVERLAY_STRING_CHUNK_SIZE
)
3102 ptrdiff_t n
= pos
->overlay_string_index
/ OVERLAY_STRING_CHUNK_SIZE
;
3103 it
->current
.overlay_string_index
= 0;
3106 load_overlay_strings (it
, 0);
3107 it
->current
.overlay_string_index
+= OVERLAY_STRING_CHUNK_SIZE
;
3111 it
->current
.overlay_string_index
= pos
->overlay_string_index
;
3112 relative_index
= (it
->current
.overlay_string_index
3113 % OVERLAY_STRING_CHUNK_SIZE
);
3114 it
->string
= it
->overlay_strings
[relative_index
];
3115 eassert (STRINGP (it
->string
));
3116 it
->current
.string_pos
= pos
->string_pos
;
3117 it
->method
= GET_FROM_STRING
;
3118 it
->end_charpos
= SCHARS (it
->string
);
3119 /* Set up the bidi iterator for this overlay string. */
3122 it
->bidi_it
.string
.lstring
= it
->string
;
3123 it
->bidi_it
.string
.s
= NULL
;
3124 it
->bidi_it
.string
.schars
= SCHARS (it
->string
);
3125 it
->bidi_it
.string
.bufpos
= it
->overlay_strings_charpos
;
3126 it
->bidi_it
.string
.from_disp_str
= it
->string_from_display_prop_p
;
3127 it
->bidi_it
.string
.unibyte
= !it
->multibyte_p
;
3128 it
->bidi_it
.w
= it
->w
;
3129 bidi_init_it (IT_STRING_CHARPOS (*it
), IT_STRING_BYTEPOS (*it
),
3130 FRAME_WINDOW_P (it
->f
), &it
->bidi_it
);
3132 /* Synchronize the state of the bidi iterator with
3133 pos->string_pos. For any string position other than
3134 zero, this will be done automagically when we resume
3135 iteration over the string and get_visually_first_element
3136 is called. But if string_pos is zero, and the string is
3137 to be reordered for display, we need to resync manually,
3138 since it could be that the iteration state recorded in
3139 pos ended at string_pos of 0 moving backwards in string. */
3140 if (CHARPOS (pos
->string_pos
) == 0)
3142 get_visually_first_element (it
);
3143 if (IT_STRING_CHARPOS (*it
) != 0)
3146 eassert (it
->bidi_it
.charpos
< it
->bidi_it
.string
.schars
);
3147 bidi_move_to_visually_next (&it
->bidi_it
);
3148 } while (it
->bidi_it
.charpos
!= 0);
3150 eassert (IT_STRING_CHARPOS (*it
) == it
->bidi_it
.charpos
3151 && IT_STRING_BYTEPOS (*it
) == it
->bidi_it
.bytepos
);
3155 if (CHARPOS (pos
->string_pos
) >= 0)
3157 /* Recorded position is not in an overlay string, but in another
3158 string. This can only be a string from a `display' property.
3159 IT should already be filled with that string. */
3160 it
->current
.string_pos
= pos
->string_pos
;
3161 eassert (STRINGP (it
->string
));
3163 bidi_init_it (IT_STRING_CHARPOS (*it
), IT_STRING_BYTEPOS (*it
),
3164 FRAME_WINDOW_P (it
->f
), &it
->bidi_it
);
3167 /* Restore position in display vector translations, control
3168 character translations or ellipses. */
3169 if (pos
->dpvec_index
>= 0)
3171 if (it
->dpvec
== NULL
)
3172 get_next_display_element (it
);
3173 eassert (it
->dpvec
&& it
->current
.dpvec_index
== 0);
3174 it
->current
.dpvec_index
= pos
->dpvec_index
;
3178 return !overlay_strings_with_newlines
;
3182 /* Initialize IT for stepping through current_buffer in window W
3183 starting at ROW->start. */
3186 init_to_row_start (struct it
*it
, struct window
*w
, struct glyph_row
*row
)
3188 init_from_display_pos (it
, w
, &row
->start
);
3189 it
->start
= row
->start
;
3190 it
->continuation_lines_width
= row
->continuation_lines_width
;
3195 /* Initialize IT for stepping through current_buffer in window W
3196 starting in the line following ROW, i.e. starting at ROW->end.
3197 Value is zero if there are overlay strings with newlines at ROW's
3201 init_to_row_end (struct it
*it
, struct window
*w
, struct glyph_row
*row
)
3205 if (init_from_display_pos (it
, w
, &row
->end
))
3207 if (row
->continued_p
)
3208 it
->continuation_lines_width
3209 = row
->continuation_lines_width
+ row
->pixel_width
;
3220 /***********************************************************************
3222 ***********************************************************************/
3224 /* Called when IT reaches IT->stop_charpos. Handle text property and
3225 overlay changes. Set IT->stop_charpos to the next position where
3229 handle_stop (struct it
*it
)
3231 enum prop_handled handled
;
3232 int handle_overlay_change_p
;
3236 it
->current
.dpvec_index
= -1;
3237 handle_overlay_change_p
= !it
->ignore_overlay_strings_at_pos_p
;
3238 it
->ignore_overlay_strings_at_pos_p
= 0;
3241 /* Use face of preceding text for ellipsis (if invisible) */
3242 if (it
->selective_display_ellipsis_p
)
3243 it
->saved_face_id
= it
->face_id
;
3247 handled
= HANDLED_NORMALLY
;
3249 /* Call text property handlers. */
3250 for (p
= it_props
; p
->handler
; ++p
)
3252 handled
= p
->handler (it
);
3254 if (handled
== HANDLED_RECOMPUTE_PROPS
)
3256 else if (handled
== HANDLED_RETURN
)
3258 /* We still want to show before and after strings from
3259 overlays even if the actual buffer text is replaced. */
3260 if (!handle_overlay_change_p
3262 /* Don't call get_overlay_strings_1 if we already
3263 have overlay strings loaded, because doing so
3264 will load them again and push the iterator state
3265 onto the stack one more time, which is not
3266 expected by the rest of the code that processes
3268 || (it
->current
.overlay_string_index
< 0
3269 ? !get_overlay_strings_1 (it
, 0, 0)
3273 setup_for_ellipsis (it
, 0);
3274 /* When handling a display spec, we might load an
3275 empty string. In that case, discard it here. We
3276 used to discard it in handle_single_display_spec,
3277 but that causes get_overlay_strings_1, above, to
3278 ignore overlay strings that we must check. */
3279 if (STRINGP (it
->string
) && !SCHARS (it
->string
))
3283 else if (STRINGP (it
->string
) && !SCHARS (it
->string
))
3287 it
->ignore_overlay_strings_at_pos_p
= 1;
3288 it
->string_from_display_prop_p
= 0;
3289 it
->from_disp_prop_p
= 0;
3290 handle_overlay_change_p
= 0;
3292 handled
= HANDLED_RECOMPUTE_PROPS
;
3295 else if (handled
== HANDLED_OVERLAY_STRING_CONSUMED
)
3296 handle_overlay_change_p
= 0;
3299 if (handled
!= HANDLED_RECOMPUTE_PROPS
)
3301 /* Don't check for overlay strings below when set to deliver
3302 characters from a display vector. */
3303 if (it
->method
== GET_FROM_DISPLAY_VECTOR
)
3304 handle_overlay_change_p
= 0;
3306 /* Handle overlay changes.
3307 This sets HANDLED to HANDLED_RECOMPUTE_PROPS
3308 if it finds overlays. */
3309 if (handle_overlay_change_p
)
3310 handled
= handle_overlay_change (it
);
3315 setup_for_ellipsis (it
, 0);
3319 while (handled
== HANDLED_RECOMPUTE_PROPS
);
3321 /* Determine where to stop next. */
3322 if (handled
== HANDLED_NORMALLY
)
3323 compute_stop_pos (it
);
3327 /* Compute IT->stop_charpos from text property and overlay change
3328 information for IT's current position. */
3331 compute_stop_pos (struct it
*it
)
3333 register INTERVAL iv
, next_iv
;
3334 Lisp_Object object
, limit
, position
;
3335 ptrdiff_t charpos
, bytepos
;
3337 if (STRINGP (it
->string
))
3339 /* Strings are usually short, so don't limit the search for
3341 it
->stop_charpos
= it
->end_charpos
;
3342 object
= it
->string
;
3344 charpos
= IT_STRING_CHARPOS (*it
);
3345 bytepos
= IT_STRING_BYTEPOS (*it
);
3351 /* If end_charpos is out of range for some reason, such as a
3352 misbehaving display function, rationalize it (Bug#5984). */
3353 if (it
->end_charpos
> ZV
)
3354 it
->end_charpos
= ZV
;
3355 it
->stop_charpos
= it
->end_charpos
;
3357 /* If next overlay change is in front of the current stop pos
3358 (which is IT->end_charpos), stop there. Note: value of
3359 next_overlay_change is point-max if no overlay change
3361 charpos
= IT_CHARPOS (*it
);
3362 bytepos
= IT_BYTEPOS (*it
);
3363 pos
= next_overlay_change (charpos
);
3364 if (pos
< it
->stop_charpos
)
3365 it
->stop_charpos
= pos
;
3367 /* If showing the region, we have to stop at the region
3368 start or end because the face might change there. */
3369 if (it
->region_beg_charpos
> 0)
3371 if (IT_CHARPOS (*it
) < it
->region_beg_charpos
)
3372 it
->stop_charpos
= min (it
->stop_charpos
, it
->region_beg_charpos
);
3373 else if (IT_CHARPOS (*it
) < it
->region_end_charpos
)
3374 it
->stop_charpos
= min (it
->stop_charpos
, it
->region_end_charpos
);
3377 /* Set up variables for computing the stop position from text
3378 property changes. */
3379 XSETBUFFER (object
, current_buffer
);
3380 limit
= make_number (IT_CHARPOS (*it
) + TEXT_PROP_DISTANCE_LIMIT
);
3383 /* Get the interval containing IT's position. Value is a null
3384 interval if there isn't such an interval. */
3385 position
= make_number (charpos
);
3386 iv
= validate_interval_range (object
, &position
, &position
, 0);
3389 Lisp_Object values_here
[LAST_PROP_IDX
];
3392 /* Get properties here. */
3393 for (p
= it_props
; p
->handler
; ++p
)
3394 values_here
[p
->idx
] = textget (iv
->plist
, *p
->name
);
3396 /* Look for an interval following iv that has different
3398 for (next_iv
= next_interval (iv
);
3401 || XFASTINT (limit
) > next_iv
->position
));
3402 next_iv
= next_interval (next_iv
))
3404 for (p
= it_props
; p
->handler
; ++p
)
3406 Lisp_Object new_value
;
3408 new_value
= textget (next_iv
->plist
, *p
->name
);
3409 if (!EQ (values_here
[p
->idx
], new_value
))
3419 if (INTEGERP (limit
)
3420 && next_iv
->position
>= XFASTINT (limit
))
3421 /* No text property change up to limit. */
3422 it
->stop_charpos
= min (XFASTINT (limit
), it
->stop_charpos
);
3424 /* Text properties change in next_iv. */
3425 it
->stop_charpos
= min (it
->stop_charpos
, next_iv
->position
);
3429 if (it
->cmp_it
.id
< 0)
3431 ptrdiff_t stoppos
= it
->end_charpos
;
3433 if (it
->bidi_p
&& it
->bidi_it
.scan_dir
< 0)
3435 composition_compute_stop_pos (&it
->cmp_it
, charpos
, bytepos
,
3436 stoppos
, it
->string
);
3439 eassert (STRINGP (it
->string
)
3440 || (it
->stop_charpos
>= BEGV
3441 && it
->stop_charpos
>= IT_CHARPOS (*it
)));
3445 /* Return the position of the next overlay change after POS in
3446 current_buffer. Value is point-max if no overlay change
3447 follows. This is like `next-overlay-change' but doesn't use
3451 next_overlay_change (ptrdiff_t pos
)
3453 ptrdiff_t i
, noverlays
;
3455 Lisp_Object
*overlays
;
3457 /* Get all overlays at the given position. */
3458 GET_OVERLAYS_AT (pos
, overlays
, noverlays
, &endpos
, 1);
3460 /* If any of these overlays ends before endpos,
3461 use its ending point instead. */
3462 for (i
= 0; i
< noverlays
; ++i
)
3467 oend
= OVERLAY_END (overlays
[i
]);
3468 oendpos
= OVERLAY_POSITION (oend
);
3469 endpos
= min (endpos
, oendpos
);
3475 /* How many characters forward to search for a display property or
3476 display string. Searching too far forward makes the bidi display
3477 sluggish, especially in small windows. */
3478 #define MAX_DISP_SCAN 250
3480 /* Return the character position of a display string at or after
3481 position specified by POSITION. If no display string exists at or
3482 after POSITION, return ZV. A display string is either an overlay
3483 with `display' property whose value is a string, or a `display'
3484 text property whose value is a string. STRING is data about the
3485 string to iterate; if STRING->lstring is nil, we are iterating a
3486 buffer. FRAME_WINDOW_P is non-zero when we are displaying a window
3487 on a GUI frame. DISP_PROP is set to zero if we searched
3488 MAX_DISP_SCAN characters forward without finding any display
3489 strings, non-zero otherwise. It is set to 2 if the display string
3490 uses any kind of `(space ...)' spec that will produce a stretch of
3491 white space in the text area. */
3493 compute_display_string_pos (struct text_pos
*position
,
3494 struct bidi_string_data
*string
,
3496 int frame_window_p
, int *disp_prop
)
3498 /* OBJECT = nil means current buffer. */
3499 Lisp_Object object
, object1
;
3500 Lisp_Object pos
, spec
, limpos
;
3501 int string_p
= (string
&& (STRINGP (string
->lstring
) || string
->s
));
3502 ptrdiff_t eob
= string_p
? string
->schars
: ZV
;
3503 ptrdiff_t begb
= string_p
? 0 : BEGV
;
3504 ptrdiff_t bufpos
, charpos
= CHARPOS (*position
);
3506 (charpos
< eob
- MAX_DISP_SCAN
) ? charpos
+ MAX_DISP_SCAN
: eob
;
3507 struct text_pos tpos
;
3510 if (string
&& STRINGP (string
->lstring
))
3511 object1
= object
= string
->lstring
;
3514 eassert (w
!= NULL
);
3515 XSETWINDOW (object
, w
);
3519 object1
= object
= Qnil
;
3524 /* We don't support display properties whose values are strings
3525 that have display string properties. */
3526 || string
->from_disp_str
3527 /* C strings cannot have display properties. */
3528 || (string
->s
&& !STRINGP (object
)))
3534 /* If the character at CHARPOS is where the display string begins,
3536 pos
= make_number (charpos
);
3537 if (STRINGP (object
))
3538 bufpos
= string
->bufpos
;
3542 if (!NILP (spec
= Fget_char_property (pos
, Qdisplay
, object
))
3544 || !EQ (Fget_char_property (make_number (charpos
- 1), Qdisplay
,
3547 && (rv
= handle_display_spec (NULL
, spec
, object
, Qnil
, &tpos
, bufpos
,
3555 /* Look forward for the first character with a `display' property
3556 that will replace the underlying text when displayed. */
3557 limpos
= make_number (lim
);
3559 pos
= Fnext_single_char_property_change (pos
, Qdisplay
, object1
, limpos
);
3560 CHARPOS (tpos
) = XFASTINT (pos
);
3561 if (CHARPOS (tpos
) >= lim
)
3566 if (STRINGP (object
))
3567 BYTEPOS (tpos
) = string_char_to_byte (object
, CHARPOS (tpos
));
3569 BYTEPOS (tpos
) = CHAR_TO_BYTE (CHARPOS (tpos
));
3570 spec
= Fget_char_property (pos
, Qdisplay
, object
);
3571 if (!STRINGP (object
))
3572 bufpos
= CHARPOS (tpos
);
3573 } while (NILP (spec
)
3574 || !(rv
= handle_display_spec (NULL
, spec
, object
, Qnil
, &tpos
,
3575 bufpos
, frame_window_p
)));
3579 return CHARPOS (tpos
);
3582 /* Return the character position of the end of the display string that
3583 started at CHARPOS. If there's no display string at CHARPOS,
3584 return -1. A display string is either an overlay with `display'
3585 property whose value is a string or a `display' text property whose
3586 value is a string. */
3588 compute_display_string_end (ptrdiff_t charpos
, struct bidi_string_data
*string
)
3590 /* OBJECT = nil means current buffer. */
3591 Lisp_Object object
=
3592 (string
&& STRINGP (string
->lstring
)) ? string
->lstring
: Qnil
;
3593 Lisp_Object pos
= make_number (charpos
);
3595 (STRINGP (object
) || (string
&& string
->s
)) ? string
->schars
: ZV
;
3597 if (charpos
>= eob
|| (string
->s
&& !STRINGP (object
)))
3600 /* It could happen that the display property or overlay was removed
3601 since we found it in compute_display_string_pos above. One way
3602 this can happen is if JIT font-lock was called (through
3603 handle_fontified_prop), and jit-lock-functions remove text
3604 properties or overlays from the portion of buffer that includes
3605 CHARPOS. Muse mode is known to do that, for example. In this
3606 case, we return -1 to the caller, to signal that no display
3607 string is actually present at CHARPOS. See bidi_fetch_char for
3608 how this is handled.
3610 An alternative would be to never look for display properties past
3611 it->stop_charpos. But neither compute_display_string_pos nor
3612 bidi_fetch_char that calls it know or care where the next
3614 if (NILP (Fget_char_property (pos
, Qdisplay
, object
)))
3617 /* Look forward for the first character where the `display' property
3619 pos
= Fnext_single_char_property_change (pos
, Qdisplay
, object
, Qnil
);
3621 return XFASTINT (pos
);
3626 /***********************************************************************
3628 ***********************************************************************/
3630 /* Handle changes in the `fontified' property of the current buffer by
3631 calling hook functions from Qfontification_functions to fontify
3634 static enum prop_handled
3635 handle_fontified_prop (struct it
*it
)
3637 Lisp_Object prop
, pos
;
3638 enum prop_handled handled
= HANDLED_NORMALLY
;
3640 if (!NILP (Vmemory_full
))
3643 /* Get the value of the `fontified' property at IT's current buffer
3644 position. (The `fontified' property doesn't have a special
3645 meaning in strings.) If the value is nil, call functions from
3646 Qfontification_functions. */
3647 if (!STRINGP (it
->string
)
3649 && !NILP (Vfontification_functions
)
3650 && !NILP (Vrun_hooks
)
3651 && (pos
= make_number (IT_CHARPOS (*it
)),
3652 prop
= Fget_char_property (pos
, Qfontified
, Qnil
),
3653 /* Ignore the special cased nil value always present at EOB since
3654 no amount of fontifying will be able to change it. */
3655 NILP (prop
) && IT_CHARPOS (*it
) < Z
))
3657 ptrdiff_t count
= SPECPDL_INDEX ();
3659 struct buffer
*obuf
= current_buffer
;
3660 int begv
= BEGV
, zv
= ZV
;
3661 int old_clip_changed
= current_buffer
->clip_changed
;
3663 val
= Vfontification_functions
;
3664 specbind (Qfontification_functions
, Qnil
);
3666 eassert (it
->end_charpos
== ZV
);
3668 if (!CONSP (val
) || EQ (XCAR (val
), Qlambda
))
3669 safe_call1 (val
, pos
);
3672 Lisp_Object fns
, fn
;
3673 struct gcpro gcpro1
, gcpro2
;
3678 for (; CONSP (val
); val
= XCDR (val
))
3684 /* A value of t indicates this hook has a local
3685 binding; it means to run the global binding too.
3686 In a global value, t should not occur. If it
3687 does, we must ignore it to avoid an endless
3689 for (fns
= Fdefault_value (Qfontification_functions
);
3695 safe_call1 (fn
, pos
);
3699 safe_call1 (fn
, pos
);
3705 unbind_to (count
, Qnil
);
3707 /* Fontification functions routinely call `save-restriction'.
3708 Normally, this tags clip_changed, which can confuse redisplay
3709 (see discussion in Bug#6671). Since we don't perform any
3710 special handling of fontification changes in the case where
3711 `save-restriction' isn't called, there's no point doing so in
3712 this case either. So, if the buffer's restrictions are
3713 actually left unchanged, reset clip_changed. */
3714 if (obuf
== current_buffer
)
3716 if (begv
== BEGV
&& zv
== ZV
)
3717 current_buffer
->clip_changed
= old_clip_changed
;
3719 /* There isn't much we can reasonably do to protect against
3720 misbehaving fontification, but here's a fig leaf. */
3721 else if (BUFFER_LIVE_P (obuf
))
3722 set_buffer_internal_1 (obuf
);
3724 /* The fontification code may have added/removed text.
3725 It could do even a lot worse, but let's at least protect against
3726 the most obvious case where only the text past `pos' gets changed',
3727 as is/was done in grep.el where some escapes sequences are turned
3728 into face properties (bug#7876). */
3729 it
->end_charpos
= ZV
;
3731 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
3732 something. This avoids an endless loop if they failed to
3733 fontify the text for which reason ever. */
3734 if (!NILP (Fget_char_property (pos
, Qfontified
, Qnil
)))
3735 handled
= HANDLED_RECOMPUTE_PROPS
;
3743 /***********************************************************************
3745 ***********************************************************************/
3747 /* Set up iterator IT from face properties at its current position.
3748 Called from handle_stop. */
3750 static enum prop_handled
3751 handle_face_prop (struct it
*it
)
3754 ptrdiff_t next_stop
;
3756 if (!STRINGP (it
->string
))
3759 = face_at_buffer_position (it
->w
,
3761 it
->region_beg_charpos
,
3762 it
->region_end_charpos
,
3765 + TEXT_PROP_DISTANCE_LIMIT
),
3766 0, it
->base_face_id
);
3768 /* Is this a start of a run of characters with box face?
3769 Caveat: this can be called for a freshly initialized
3770 iterator; face_id is -1 in this case. We know that the new
3771 face will not change until limit, i.e. if the new face has a
3772 box, all characters up to limit will have one. But, as
3773 usual, we don't know whether limit is really the end. */
3774 if (new_face_id
!= it
->face_id
)
3776 struct face
*new_face
= FACE_FROM_ID (it
->f
, new_face_id
);
3777 /* If it->face_id is -1, old_face below will be NULL, see
3778 the definition of FACE_FROM_ID. This will happen if this
3779 is the initial call that gets the face. */
3780 struct face
*old_face
= FACE_FROM_ID (it
->f
, it
->face_id
);
3782 /* If the value of face_id of the iterator is -1, we have to
3783 look in front of IT's position and see whether there is a
3784 face there that's different from new_face_id. */
3785 if (!old_face
&& IT_CHARPOS (*it
) > BEG
)
3787 int prev_face_id
= face_before_it_pos (it
);
3789 old_face
= FACE_FROM_ID (it
->f
, prev_face_id
);
3792 /* If the new face has a box, but the old face does not,
3793 this is the start of a run of characters with box face,
3794 i.e. this character has a shadow on the left side. */
3795 it
->start_of_box_run_p
= (new_face
->box
!= FACE_NO_BOX
3796 && (old_face
== NULL
|| !old_face
->box
));
3797 it
->face_box_p
= new_face
->box
!= FACE_NO_BOX
;
3805 Lisp_Object from_overlay
3806 = (it
->current
.overlay_string_index
>= 0
3807 ? it
->string_overlays
[it
->current
.overlay_string_index
3808 % OVERLAY_STRING_CHUNK_SIZE
]
3811 /* See if we got to this string directly or indirectly from
3812 an overlay property. That includes the before-string or
3813 after-string of an overlay, strings in display properties
3814 provided by an overlay, their text properties, etc.
3816 FROM_OVERLAY is the overlay that brought us here, or nil if none. */
3817 if (! NILP (from_overlay
))
3818 for (i
= it
->sp
- 1; i
>= 0; i
--)
3820 if (it
->stack
[i
].current
.overlay_string_index
>= 0)
3822 = it
->string_overlays
[it
->stack
[i
].current
.overlay_string_index
3823 % OVERLAY_STRING_CHUNK_SIZE
];
3824 else if (! NILP (it
->stack
[i
].from_overlay
))
3825 from_overlay
= it
->stack
[i
].from_overlay
;
3827 if (!NILP (from_overlay
))
3831 if (! NILP (from_overlay
))
3833 bufpos
= IT_CHARPOS (*it
);
3834 /* For a string from an overlay, the base face depends
3835 only on text properties and ignores overlays. */
3837 = face_for_overlay_string (it
->w
,
3839 it
->region_beg_charpos
,
3840 it
->region_end_charpos
,
3843 + TEXT_PROP_DISTANCE_LIMIT
),
3851 /* For strings from a `display' property, use the face at
3852 IT's current buffer position as the base face to merge
3853 with, so that overlay strings appear in the same face as
3854 surrounding text, unless they specify their own
3856 base_face_id
= it
->string_from_prefix_prop_p
3858 : underlying_face_id (it
);
3861 new_face_id
= face_at_string_position (it
->w
,
3863 IT_STRING_CHARPOS (*it
),
3865 it
->region_beg_charpos
,
3866 it
->region_end_charpos
,
3870 /* Is this a start of a run of characters with box? Caveat:
3871 this can be called for a freshly allocated iterator; face_id
3872 is -1 is this case. We know that the new face will not
3873 change until the next check pos, i.e. if the new face has a
3874 box, all characters up to that position will have a
3875 box. But, as usual, we don't know whether that position
3876 is really the end. */
3877 if (new_face_id
!= it
->face_id
)
3879 struct face
*new_face
= FACE_FROM_ID (it
->f
, new_face_id
);
3880 struct face
*old_face
= FACE_FROM_ID (it
->f
, it
->face_id
);
3882 /* If new face has a box but old face hasn't, this is the
3883 start of a run of characters with box, i.e. it has a
3884 shadow on the left side. */
3885 it
->start_of_box_run_p
3886 = new_face
->box
&& (old_face
== NULL
|| !old_face
->box
);
3887 it
->face_box_p
= new_face
->box
!= FACE_NO_BOX
;
3891 it
->face_id
= new_face_id
;
3892 return HANDLED_NORMALLY
;
3896 /* Return the ID of the face ``underlying'' IT's current position,
3897 which is in a string. If the iterator is associated with a
3898 buffer, return the face at IT's current buffer position.
3899 Otherwise, use the iterator's base_face_id. */
3902 underlying_face_id (struct it
*it
)
3904 int face_id
= it
->base_face_id
, i
;
3906 eassert (STRINGP (it
->string
));
3908 for (i
= it
->sp
- 1; i
>= 0; --i
)
3909 if (NILP (it
->stack
[i
].string
))
3910 face_id
= it
->stack
[i
].face_id
;
3916 /* Compute the face one character before or after the current position
3917 of IT, in the visual order. BEFORE_P non-zero means get the face
3918 in front (to the left in L2R paragraphs, to the right in R2L
3919 paragraphs) of IT's screen position. Value is the ID of the face. */
3922 face_before_or_after_it_pos (struct it
*it
, int before_p
)
3925 ptrdiff_t next_check_charpos
;
3927 void *it_copy_data
= NULL
;
3929 eassert (it
->s
== NULL
);
3931 if (STRINGP (it
->string
))
3933 ptrdiff_t bufpos
, charpos
;
3936 /* No face change past the end of the string (for the case
3937 we are padding with spaces). No face change before the
3939 if (IT_STRING_CHARPOS (*it
) >= SCHARS (it
->string
)
3940 || (IT_STRING_CHARPOS (*it
) == 0 && before_p
))
3945 /* Set charpos to the position before or after IT's current
3946 position, in the logical order, which in the non-bidi
3947 case is the same as the visual order. */
3949 charpos
= IT_STRING_CHARPOS (*it
) - 1;
3950 else if (it
->what
== IT_COMPOSITION
)
3951 /* For composition, we must check the character after the
3953 charpos
= IT_STRING_CHARPOS (*it
) + it
->cmp_it
.nchars
;
3955 charpos
= IT_STRING_CHARPOS (*it
) + 1;
3961 /* With bidi iteration, the character before the current
3962 in the visual order cannot be found by simple
3963 iteration, because "reverse" reordering is not
3964 supported. Instead, we need to use the move_it_*
3965 family of functions. */
3966 /* Ignore face changes before the first visible
3967 character on this display line. */
3968 if (it
->current_x
<= it
->first_visible_x
)
3970 SAVE_IT (it_copy
, *it
, it_copy_data
);
3971 /* Implementation note: Since move_it_in_display_line
3972 works in the iterator geometry, and thinks the first
3973 character is always the leftmost, even in R2L lines,
3974 we don't need to distinguish between the R2L and L2R
3976 move_it_in_display_line (&it_copy
, SCHARS (it_copy
.string
),
3977 it_copy
.current_x
- 1, MOVE_TO_X
);
3978 charpos
= IT_STRING_CHARPOS (it_copy
);
3979 RESTORE_IT (it
, it
, it_copy_data
);
3983 /* Set charpos to the string position of the character
3984 that comes after IT's current position in the visual
3986 int n
= (it
->what
== IT_COMPOSITION
? it
->cmp_it
.nchars
: 1);
3990 bidi_move_to_visually_next (&it_copy
.bidi_it
);
3992 charpos
= it_copy
.bidi_it
.charpos
;
3995 eassert (0 <= charpos
&& charpos
<= SCHARS (it
->string
));
3997 if (it
->current
.overlay_string_index
>= 0)
3998 bufpos
= IT_CHARPOS (*it
);
4002 base_face_id
= underlying_face_id (it
);
4004 /* Get the face for ASCII, or unibyte. */
4005 face_id
= face_at_string_position (it
->w
,
4009 it
->region_beg_charpos
,
4010 it
->region_end_charpos
,
4011 &next_check_charpos
,
4014 /* Correct the face for charsets different from ASCII. Do it
4015 for the multibyte case only. The face returned above is
4016 suitable for unibyte text if IT->string is unibyte. */
4017 if (STRING_MULTIBYTE (it
->string
))
4019 struct text_pos pos1
= string_pos (charpos
, it
->string
);
4020 const unsigned char *p
= SDATA (it
->string
) + BYTEPOS (pos1
);
4022 struct face
*face
= FACE_FROM_ID (it
->f
, face_id
);
4024 c
= string_char_and_length (p
, &len
);
4025 face_id
= FACE_FOR_CHAR (it
->f
, face
, c
, charpos
, it
->string
);
4030 struct text_pos pos
;
4032 if ((IT_CHARPOS (*it
) >= ZV
&& !before_p
)
4033 || (IT_CHARPOS (*it
) <= BEGV
&& before_p
))
4036 limit
= IT_CHARPOS (*it
) + TEXT_PROP_DISTANCE_LIMIT
;
4037 pos
= it
->current
.pos
;
4042 DEC_TEXT_POS (pos
, it
->multibyte_p
);
4045 if (it
->what
== IT_COMPOSITION
)
4047 /* For composition, we must check the position after
4049 pos
.charpos
+= it
->cmp_it
.nchars
;
4050 pos
.bytepos
+= it
->len
;
4053 INC_TEXT_POS (pos
, it
->multibyte_p
);
4060 /* With bidi iteration, the character before the current
4061 in the visual order cannot be found by simple
4062 iteration, because "reverse" reordering is not
4063 supported. Instead, we need to use the move_it_*
4064 family of functions. */
4065 /* Ignore face changes before the first visible
4066 character on this display line. */
4067 if (it
->current_x
<= it
->first_visible_x
)
4069 SAVE_IT (it_copy
, *it
, it_copy_data
);
4070 /* Implementation note: Since move_it_in_display_line
4071 works in the iterator geometry, and thinks the first
4072 character is always the leftmost, even in R2L lines,
4073 we don't need to distinguish between the R2L and L2R
4075 move_it_in_display_line (&it_copy
, ZV
,
4076 it_copy
.current_x
- 1, MOVE_TO_X
);
4077 pos
= it_copy
.current
.pos
;
4078 RESTORE_IT (it
, it
, it_copy_data
);
4082 /* Set charpos to the buffer position of the character
4083 that comes after IT's current position in the visual
4085 int n
= (it
->what
== IT_COMPOSITION
? it
->cmp_it
.nchars
: 1);
4089 bidi_move_to_visually_next (&it_copy
.bidi_it
);
4092 it_copy
.bidi_it
.charpos
, it_copy
.bidi_it
.bytepos
);
4095 eassert (BEGV
<= CHARPOS (pos
) && CHARPOS (pos
) <= ZV
);
4097 /* Determine face for CHARSET_ASCII, or unibyte. */
4098 face_id
= face_at_buffer_position (it
->w
,
4100 it
->region_beg_charpos
,
4101 it
->region_end_charpos
,
4102 &next_check_charpos
,
4105 /* Correct the face for charsets different from ASCII. Do it
4106 for the multibyte case only. The face returned above is
4107 suitable for unibyte text if current_buffer is unibyte. */
4108 if (it
->multibyte_p
)
4110 int c
= FETCH_MULTIBYTE_CHAR (BYTEPOS (pos
));
4111 struct face
*face
= FACE_FROM_ID (it
->f
, face_id
);
4112 face_id
= FACE_FOR_CHAR (it
->f
, face
, c
, CHARPOS (pos
), Qnil
);
4121 /***********************************************************************
4123 ***********************************************************************/
4125 /* Set up iterator IT from invisible properties at its current
4126 position. Called from handle_stop. */
4128 static enum prop_handled
4129 handle_invisible_prop (struct it
*it
)
4131 enum prop_handled handled
= HANDLED_NORMALLY
;
4135 if (STRINGP (it
->string
))
4137 Lisp_Object end_charpos
, limit
, charpos
;
4139 /* Get the value of the invisible text property at the
4140 current position. Value will be nil if there is no such
4142 charpos
= make_number (IT_STRING_CHARPOS (*it
));
4143 prop
= Fget_text_property (charpos
, Qinvisible
, it
->string
);
4144 invis_p
= TEXT_PROP_MEANS_INVISIBLE (prop
);
4146 if (invis_p
&& IT_STRING_CHARPOS (*it
) < it
->end_charpos
)
4148 /* Record whether we have to display an ellipsis for the
4150 int display_ellipsis_p
= (invis_p
== 2);
4151 ptrdiff_t len
, endpos
;
4153 handled
= HANDLED_RECOMPUTE_PROPS
;
4155 /* Get the position at which the next visible text can be
4156 found in IT->string, if any. */
4157 endpos
= len
= SCHARS (it
->string
);
4158 XSETINT (limit
, len
);
4161 end_charpos
= Fnext_single_property_change (charpos
, Qinvisible
,
4163 if (INTEGERP (end_charpos
))
4165 endpos
= XFASTINT (end_charpos
);
4166 prop
= Fget_text_property (end_charpos
, Qinvisible
, it
->string
);
4167 invis_p
= TEXT_PROP_MEANS_INVISIBLE (prop
);
4169 display_ellipsis_p
= 1;
4172 while (invis_p
&& endpos
< len
);
4174 if (display_ellipsis_p
)
4179 /* Text at END_CHARPOS is visible. Move IT there. */
4180 struct text_pos old
;
4183 old
= it
->current
.string_pos
;
4184 oldpos
= CHARPOS (old
);
4187 if (it
->bidi_it
.first_elt
4188 && it
->bidi_it
.charpos
< SCHARS (it
->string
))
4189 bidi_paragraph_init (it
->paragraph_embedding
,
4191 /* Bidi-iterate out of the invisible text. */
4194 bidi_move_to_visually_next (&it
->bidi_it
);
4196 while (oldpos
<= it
->bidi_it
.charpos
4197 && it
->bidi_it
.charpos
< endpos
);
4199 IT_STRING_CHARPOS (*it
) = it
->bidi_it
.charpos
;
4200 IT_STRING_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
4201 if (IT_CHARPOS (*it
) >= endpos
)
4202 it
->prev_stop
= endpos
;
4206 IT_STRING_CHARPOS (*it
) = XFASTINT (end_charpos
);
4207 compute_string_pos (&it
->current
.string_pos
, old
, it
->string
);
4212 /* The rest of the string is invisible. If this is an
4213 overlay string, proceed with the next overlay string
4214 or whatever comes and return a character from there. */
4215 if (it
->current
.overlay_string_index
>= 0
4216 && !display_ellipsis_p
)
4218 next_overlay_string (it
);
4219 /* Don't check for overlay strings when we just
4220 finished processing them. */
4221 handled
= HANDLED_OVERLAY_STRING_CONSUMED
;
4225 IT_STRING_CHARPOS (*it
) = SCHARS (it
->string
);
4226 IT_STRING_BYTEPOS (*it
) = SBYTES (it
->string
);
4233 ptrdiff_t newpos
, next_stop
, start_charpos
, tem
;
4234 Lisp_Object pos
, overlay
;
4236 /* First of all, is there invisible text at this position? */
4237 tem
= start_charpos
= IT_CHARPOS (*it
);
4238 pos
= make_number (tem
);
4239 prop
= get_char_property_and_overlay (pos
, Qinvisible
, it
->window
,
4241 invis_p
= TEXT_PROP_MEANS_INVISIBLE (prop
);
4243 /* If we are on invisible text, skip over it. */
4244 if (invis_p
&& start_charpos
< it
->end_charpos
)
4246 /* Record whether we have to display an ellipsis for the
4248 int display_ellipsis_p
= invis_p
== 2;
4250 handled
= HANDLED_RECOMPUTE_PROPS
;
4252 /* Loop skipping over invisible text. The loop is left at
4253 ZV or with IT on the first char being visible again. */
4256 /* Try to skip some invisible text. Return value is the
4257 position reached which can be equal to where we start
4258 if there is nothing invisible there. This skips both
4259 over invisible text properties and overlays with
4260 invisible property. */
4261 newpos
= skip_invisible (tem
, &next_stop
, ZV
, it
->window
);
4263 /* If we skipped nothing at all we weren't at invisible
4264 text in the first place. If everything to the end of
4265 the buffer was skipped, end the loop. */
4266 if (newpos
== tem
|| newpos
>= ZV
)
4270 /* We skipped some characters but not necessarily
4271 all there are. Check if we ended up on visible
4272 text. Fget_char_property returns the property of
4273 the char before the given position, i.e. if we
4274 get invis_p = 0, this means that the char at
4275 newpos is visible. */
4276 pos
= make_number (newpos
);
4277 prop
= Fget_char_property (pos
, Qinvisible
, it
->window
);
4278 invis_p
= TEXT_PROP_MEANS_INVISIBLE (prop
);
4281 /* If we ended up on invisible text, proceed to
4282 skip starting with next_stop. */
4286 /* If there are adjacent invisible texts, don't lose the
4287 second one's ellipsis. */
4289 display_ellipsis_p
= 1;
4293 /* The position newpos is now either ZV or on visible text. */
4296 ptrdiff_t bpos
= CHAR_TO_BYTE (newpos
);
4298 bpos
== ZV_BYTE
|| FETCH_BYTE (bpos
) == '\n';
4300 newpos
<= BEGV
|| FETCH_BYTE (bpos
- 1) == '\n';
4302 /* If the invisible text ends on a newline or on a
4303 character after a newline, we can avoid the costly,
4304 character by character, bidi iteration to NEWPOS, and
4305 instead simply reseat the iterator there. That's
4306 because all bidi reordering information is tossed at
4307 the newline. This is a big win for modes that hide
4308 complete lines, like Outline, Org, etc. */
4309 if (on_newline
|| after_newline
)
4311 struct text_pos tpos
;
4312 bidi_dir_t pdir
= it
->bidi_it
.paragraph_dir
;
4314 SET_TEXT_POS (tpos
, newpos
, bpos
);
4315 reseat_1 (it
, tpos
, 0);
4316 /* If we reseat on a newline/ZV, we need to prep the
4317 bidi iterator for advancing to the next character
4318 after the newline/EOB, keeping the current paragraph
4319 direction (so that PRODUCE_GLYPHS does TRT wrt
4320 prepending/appending glyphs to a glyph row). */
4323 it
->bidi_it
.first_elt
= 0;
4324 it
->bidi_it
.paragraph_dir
= pdir
;
4325 it
->bidi_it
.ch
= (bpos
== ZV_BYTE
) ? -1 : '\n';
4326 it
->bidi_it
.nchars
= 1;
4327 it
->bidi_it
.ch_len
= 1;
4330 else /* Must use the slow method. */
4332 /* With bidi iteration, the region of invisible text
4333 could start and/or end in the middle of a
4334 non-base embedding level. Therefore, we need to
4335 skip invisible text using the bidi iterator,
4336 starting at IT's current position, until we find
4337 ourselves outside of the invisible text.
4338 Skipping invisible text _after_ bidi iteration
4339 avoids affecting the visual order of the
4340 displayed text when invisible properties are
4341 added or removed. */
4342 if (it
->bidi_it
.first_elt
&& it
->bidi_it
.charpos
< ZV
)
4344 /* If we were `reseat'ed to a new paragraph,
4345 determine the paragraph base direction. We
4346 need to do it now because
4347 next_element_from_buffer may not have a
4348 chance to do it, if we are going to skip any
4349 text at the beginning, which resets the
4351 bidi_paragraph_init (it
->paragraph_embedding
,
4356 bidi_move_to_visually_next (&it
->bidi_it
);
4358 while (it
->stop_charpos
<= it
->bidi_it
.charpos
4359 && it
->bidi_it
.charpos
< newpos
);
4360 IT_CHARPOS (*it
) = it
->bidi_it
.charpos
;
4361 IT_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
4362 /* If we overstepped NEWPOS, record its position in
4363 the iterator, so that we skip invisible text if
4364 later the bidi iteration lands us in the
4365 invisible region again. */
4366 if (IT_CHARPOS (*it
) >= newpos
)
4367 it
->prev_stop
= newpos
;
4372 IT_CHARPOS (*it
) = newpos
;
4373 IT_BYTEPOS (*it
) = CHAR_TO_BYTE (newpos
);
4376 /* If there are before-strings at the start of invisible
4377 text, and the text is invisible because of a text
4378 property, arrange to show before-strings because 20.x did
4379 it that way. (If the text is invisible because of an
4380 overlay property instead of a text property, this is
4381 already handled in the overlay code.) */
4383 && get_overlay_strings (it
, it
->stop_charpos
))
4385 handled
= HANDLED_RECOMPUTE_PROPS
;
4386 it
->stack
[it
->sp
- 1].display_ellipsis_p
= display_ellipsis_p
;
4388 else if (display_ellipsis_p
)
4390 /* Make sure that the glyphs of the ellipsis will get
4391 correct `charpos' values. If we would not update
4392 it->position here, the glyphs would belong to the
4393 last visible character _before_ the invisible
4394 text, which confuses `set_cursor_from_row'.
4396 We use the last invisible position instead of the
4397 first because this way the cursor is always drawn on
4398 the first "." of the ellipsis, whenever PT is inside
4399 the invisible text. Otherwise the cursor would be
4400 placed _after_ the ellipsis when the point is after the
4401 first invisible character. */
4402 if (!STRINGP (it
->object
))
4404 it
->position
.charpos
= newpos
- 1;
4405 it
->position
.bytepos
= CHAR_TO_BYTE (it
->position
.charpos
);
4408 /* Let the ellipsis display before
4409 considering any properties of the following char.
4410 Fixes jasonr@gnu.org 01 Oct 07 bug. */
4411 handled
= HANDLED_RETURN
;
4420 /* Make iterator IT return `...' next.
4421 Replaces LEN characters from buffer. */
4424 setup_for_ellipsis (struct it
*it
, int len
)
4426 /* Use the display table definition for `...'. Invalid glyphs
4427 will be handled by the method returning elements from dpvec. */
4428 if (it
->dp
&& VECTORP (DISP_INVIS_VECTOR (it
->dp
)))
4430 struct Lisp_Vector
*v
= XVECTOR (DISP_INVIS_VECTOR (it
->dp
));
4431 it
->dpvec
= v
->contents
;
4432 it
->dpend
= v
->contents
+ v
->header
.size
;
4436 /* Default `...'. */
4437 it
->dpvec
= default_invis_vector
;
4438 it
->dpend
= default_invis_vector
+ 3;
4441 it
->dpvec_char_len
= len
;
4442 it
->current
.dpvec_index
= 0;
4443 it
->dpvec_face_id
= -1;
4445 /* Remember the current face id in case glyphs specify faces.
4446 IT's face is restored in set_iterator_to_next.
4447 saved_face_id was set to preceding char's face in handle_stop. */
4448 if (it
->saved_face_id
< 0 || it
->saved_face_id
!= it
->face_id
)
4449 it
->saved_face_id
= it
->face_id
= DEFAULT_FACE_ID
;
4451 it
->method
= GET_FROM_DISPLAY_VECTOR
;
4457 /***********************************************************************
4459 ***********************************************************************/
4461 /* Set up iterator IT from `display' property at its current position.
4462 Called from handle_stop.
4463 We return HANDLED_RETURN if some part of the display property
4464 overrides the display of the buffer text itself.
4465 Otherwise we return HANDLED_NORMALLY. */
4467 static enum prop_handled
4468 handle_display_prop (struct it
*it
)
4470 Lisp_Object propval
, object
, overlay
;
4471 struct text_pos
*position
;
4473 /* Nonzero if some property replaces the display of the text itself. */
4474 int display_replaced_p
= 0;
4476 if (STRINGP (it
->string
))
4478 object
= it
->string
;
4479 position
= &it
->current
.string_pos
;
4480 bufpos
= CHARPOS (it
->current
.pos
);
4484 XSETWINDOW (object
, it
->w
);
4485 position
= &it
->current
.pos
;
4486 bufpos
= CHARPOS (*position
);
4489 /* Reset those iterator values set from display property values. */
4490 it
->slice
.x
= it
->slice
.y
= it
->slice
.width
= it
->slice
.height
= Qnil
;
4491 it
->space_width
= Qnil
;
4492 it
->font_height
= Qnil
;
4495 /* We don't support recursive `display' properties, i.e. string
4496 values that have a string `display' property, that have a string
4497 `display' property etc. */
4498 if (!it
->string_from_display_prop_p
)
4499 it
->area
= TEXT_AREA
;
4501 propval
= get_char_property_and_overlay (make_number (position
->charpos
),
4502 Qdisplay
, object
, &overlay
);
4504 return HANDLED_NORMALLY
;
4505 /* Now OVERLAY is the overlay that gave us this property, or nil
4506 if it was a text property. */
4508 if (!STRINGP (it
->string
))
4509 object
= it
->w
->contents
;
4511 display_replaced_p
= handle_display_spec (it
, propval
, object
, overlay
,
4513 FRAME_WINDOW_P (it
->f
));
4515 return display_replaced_p
? HANDLED_RETURN
: HANDLED_NORMALLY
;
4518 /* Subroutine of handle_display_prop. Returns non-zero if the display
4519 specification in SPEC is a replacing specification, i.e. it would
4520 replace the text covered by `display' property with something else,
4521 such as an image or a display string. If SPEC includes any kind or
4522 `(space ...) specification, the value is 2; this is used by
4523 compute_display_string_pos, which see.
4525 See handle_single_display_spec for documentation of arguments.
4526 frame_window_p is non-zero if the window being redisplayed is on a
4527 GUI frame; this argument is used only if IT is NULL, see below.
4529 IT can be NULL, if this is called by the bidi reordering code
4530 through compute_display_string_pos, which see. In that case, this
4531 function only examines SPEC, but does not otherwise "handle" it, in
4532 the sense that it doesn't set up members of IT from the display
4535 handle_display_spec (struct it
*it
, Lisp_Object spec
, Lisp_Object object
,
4536 Lisp_Object overlay
, struct text_pos
*position
,
4537 ptrdiff_t bufpos
, int frame_window_p
)
4539 int replacing_p
= 0;
4543 /* Simple specifications. */
4544 && !EQ (XCAR (spec
), Qimage
)
4545 && !EQ (XCAR (spec
), Qspace
)
4546 && !EQ (XCAR (spec
), Qwhen
)
4547 && !EQ (XCAR (spec
), Qslice
)
4548 && !EQ (XCAR (spec
), Qspace_width
)
4549 && !EQ (XCAR (spec
), Qheight
)
4550 && !EQ (XCAR (spec
), Qraise
)
4551 /* Marginal area specifications. */
4552 && !(CONSP (XCAR (spec
)) && EQ (XCAR (XCAR (spec
)), Qmargin
))
4553 && !EQ (XCAR (spec
), Qleft_fringe
)
4554 && !EQ (XCAR (spec
), Qright_fringe
)
4555 && !NILP (XCAR (spec
)))
4557 for (; CONSP (spec
); spec
= XCDR (spec
))
4559 if ((rv
= handle_single_display_spec (it
, XCAR (spec
), object
,
4560 overlay
, position
, bufpos
,
4561 replacing_p
, frame_window_p
)))
4564 /* If some text in a string is replaced, `position' no
4565 longer points to the position of `object'. */
4566 if (!it
|| STRINGP (object
))
4571 else if (VECTORP (spec
))
4574 for (i
= 0; i
< ASIZE (spec
); ++i
)
4575 if ((rv
= handle_single_display_spec (it
, AREF (spec
, i
), object
,
4576 overlay
, position
, bufpos
,
4577 replacing_p
, frame_window_p
)))
4580 /* If some text in a string is replaced, `position' no
4581 longer points to the position of `object'. */
4582 if (!it
|| STRINGP (object
))
4588 if ((rv
= handle_single_display_spec (it
, spec
, object
, overlay
,
4589 position
, bufpos
, 0,
4597 /* Value is the position of the end of the `display' property starting
4598 at START_POS in OBJECT. */
4600 static struct text_pos
4601 display_prop_end (struct it
*it
, Lisp_Object object
, struct text_pos start_pos
)
4604 struct text_pos end_pos
;
4606 end
= Fnext_single_char_property_change (make_number (CHARPOS (start_pos
)),
4607 Qdisplay
, object
, Qnil
);
4608 CHARPOS (end_pos
) = XFASTINT (end
);
4609 if (STRINGP (object
))
4610 compute_string_pos (&end_pos
, start_pos
, it
->string
);
4612 BYTEPOS (end_pos
) = CHAR_TO_BYTE (XFASTINT (end
));
4618 /* Set up IT from a single `display' property specification SPEC. OBJECT
4619 is the object in which the `display' property was found. *POSITION
4620 is the position in OBJECT at which the `display' property was found.
4621 BUFPOS is the buffer position of OBJECT (different from POSITION if
4622 OBJECT is not a buffer). DISPLAY_REPLACED_P non-zero means that we
4623 previously saw a display specification which already replaced text
4624 display with something else, for example an image; we ignore such
4625 properties after the first one has been processed.
4627 OVERLAY is the overlay this `display' property came from,
4628 or nil if it was a text property.
4630 If SPEC is a `space' or `image' specification, and in some other
4631 cases too, set *POSITION to the position where the `display'
4634 If IT is NULL, only examine the property specification in SPEC, but
4635 don't set up IT. In that case, FRAME_WINDOW_P non-zero means SPEC
4636 is intended to be displayed in a window on a GUI frame.
4638 Value is non-zero if something was found which replaces the display
4639 of buffer or string text. */
4642 handle_single_display_spec (struct it
*it
, Lisp_Object spec
, Lisp_Object object
,
4643 Lisp_Object overlay
, struct text_pos
*position
,
4644 ptrdiff_t bufpos
, int display_replaced_p
,
4648 Lisp_Object location
, value
;
4649 struct text_pos start_pos
= *position
;
4652 /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
4653 If the result is non-nil, use VALUE instead of SPEC. */
4655 if (CONSP (spec
) && EQ (XCAR (spec
), Qwhen
))
4664 if (!NILP (form
) && !EQ (form
, Qt
))
4666 ptrdiff_t count
= SPECPDL_INDEX ();
4667 struct gcpro gcpro1
;
4669 /* Bind `object' to the object having the `display' property, a
4670 buffer or string. Bind `position' to the position in the
4671 object where the property was found, and `buffer-position'
4672 to the current position in the buffer. */
4675 XSETBUFFER (object
, current_buffer
);
4676 specbind (Qobject
, object
);
4677 specbind (Qposition
, make_number (CHARPOS (*position
)));
4678 specbind (Qbuffer_position
, make_number (bufpos
));
4680 form
= safe_eval (form
);
4682 unbind_to (count
, Qnil
);
4688 /* Handle `(height HEIGHT)' specifications. */
4690 && EQ (XCAR (spec
), Qheight
)
4691 && CONSP (XCDR (spec
)))
4695 if (!FRAME_WINDOW_P (it
->f
))
4698 it
->font_height
= XCAR (XCDR (spec
));
4699 if (!NILP (it
->font_height
))
4701 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
4702 int new_height
= -1;
4704 if (CONSP (it
->font_height
)
4705 && (EQ (XCAR (it
->font_height
), Qplus
)
4706 || EQ (XCAR (it
->font_height
), Qminus
))
4707 && CONSP (XCDR (it
->font_height
))
4708 && RANGED_INTEGERP (0, XCAR (XCDR (it
->font_height
)), INT_MAX
))
4710 /* `(+ N)' or `(- N)' where N is an integer. */
4711 int steps
= XINT (XCAR (XCDR (it
->font_height
)));
4712 if (EQ (XCAR (it
->font_height
), Qplus
))
4714 it
->face_id
= smaller_face (it
->f
, it
->face_id
, steps
);
4716 else if (FUNCTIONP (it
->font_height
))
4718 /* Call function with current height as argument.
4719 Value is the new height. */
4721 height
= safe_call1 (it
->font_height
,
4722 face
->lface
[LFACE_HEIGHT_INDEX
]);
4723 if (NUMBERP (height
))
4724 new_height
= XFLOATINT (height
);
4726 else if (NUMBERP (it
->font_height
))
4728 /* Value is a multiple of the canonical char height. */
4731 f
= FACE_FROM_ID (it
->f
,
4732 lookup_basic_face (it
->f
, DEFAULT_FACE_ID
));
4733 new_height
= (XFLOATINT (it
->font_height
)
4734 * XINT (f
->lface
[LFACE_HEIGHT_INDEX
]));
4738 /* Evaluate IT->font_height with `height' bound to the
4739 current specified height to get the new height. */
4740 ptrdiff_t count
= SPECPDL_INDEX ();
4742 specbind (Qheight
, face
->lface
[LFACE_HEIGHT_INDEX
]);
4743 value
= safe_eval (it
->font_height
);
4744 unbind_to (count
, Qnil
);
4746 if (NUMBERP (value
))
4747 new_height
= XFLOATINT (value
);
4751 it
->face_id
= face_with_height (it
->f
, it
->face_id
, new_height
);
4758 /* Handle `(space-width WIDTH)'. */
4760 && EQ (XCAR (spec
), Qspace_width
)
4761 && CONSP (XCDR (spec
)))
4765 if (!FRAME_WINDOW_P (it
->f
))
4768 value
= XCAR (XCDR (spec
));
4769 if (NUMBERP (value
) && XFLOATINT (value
) > 0)
4770 it
->space_width
= value
;
4776 /* Handle `(slice X Y WIDTH HEIGHT)'. */
4778 && EQ (XCAR (spec
), Qslice
))
4784 if (!FRAME_WINDOW_P (it
->f
))
4787 if (tem
= XCDR (spec
), CONSP (tem
))
4789 it
->slice
.x
= XCAR (tem
);
4790 if (tem
= XCDR (tem
), CONSP (tem
))
4792 it
->slice
.y
= XCAR (tem
);
4793 if (tem
= XCDR (tem
), CONSP (tem
))
4795 it
->slice
.width
= XCAR (tem
);
4796 if (tem
= XCDR (tem
), CONSP (tem
))
4797 it
->slice
.height
= XCAR (tem
);
4806 /* Handle `(raise FACTOR)'. */
4808 && EQ (XCAR (spec
), Qraise
)
4809 && CONSP (XCDR (spec
)))
4813 if (!FRAME_WINDOW_P (it
->f
))
4816 #ifdef HAVE_WINDOW_SYSTEM
4817 value
= XCAR (XCDR (spec
));
4818 if (NUMBERP (value
))
4820 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
4821 it
->voffset
= - (XFLOATINT (value
)
4822 * (FONT_HEIGHT (face
->font
)));
4824 #endif /* HAVE_WINDOW_SYSTEM */
4830 /* Don't handle the other kinds of display specifications
4831 inside a string that we got from a `display' property. */
4832 if (it
&& it
->string_from_display_prop_p
)
4835 /* Characters having this form of property are not displayed, so
4836 we have to find the end of the property. */
4839 start_pos
= *position
;
4840 *position
= display_prop_end (it
, object
, start_pos
);
4844 /* Stop the scan at that end position--we assume that all
4845 text properties change there. */
4847 it
->stop_charpos
= position
->charpos
;
4849 /* Handle `(left-fringe BITMAP [FACE])'
4850 and `(right-fringe BITMAP [FACE])'. */
4852 && (EQ (XCAR (spec
), Qleft_fringe
)
4853 || EQ (XCAR (spec
), Qright_fringe
))
4854 && CONSP (XCDR (spec
)))
4860 if (!FRAME_WINDOW_P (it
->f
))
4861 /* If we return here, POSITION has been advanced
4862 across the text with this property. */
4864 /* Synchronize the bidi iterator with POSITION. This is
4865 needed because we are not going to push the iterator
4866 on behalf of this display property, so there will be
4867 no pop_it call to do this synchronization for us. */
4870 it
->position
= *position
;
4871 iterate_out_of_display_property (it
);
4872 *position
= it
->position
;
4877 else if (!frame_window_p
)
4880 #ifdef HAVE_WINDOW_SYSTEM
4881 value
= XCAR (XCDR (spec
));
4882 if (!SYMBOLP (value
)
4883 || !(fringe_bitmap
= lookup_fringe_bitmap (value
)))
4884 /* If we return here, POSITION has been advanced
4885 across the text with this property. */
4887 if (it
&& it
->bidi_p
)
4889 it
->position
= *position
;
4890 iterate_out_of_display_property (it
);
4891 *position
= it
->position
;
4898 int face_id
= lookup_basic_face (it
->f
, DEFAULT_FACE_ID
);;
4900 if (CONSP (XCDR (XCDR (spec
))))
4902 Lisp_Object face_name
= XCAR (XCDR (XCDR (spec
)));
4903 int face_id2
= lookup_derived_face (it
->f
, face_name
,
4909 /* Save current settings of IT so that we can restore them
4910 when we are finished with the glyph property value. */
4911 push_it (it
, position
);
4913 it
->area
= TEXT_AREA
;
4914 it
->what
= IT_IMAGE
;
4915 it
->image_id
= -1; /* no image */
4916 it
->position
= start_pos
;
4917 it
->object
= NILP (object
) ? it
->w
->contents
: object
;
4918 it
->method
= GET_FROM_IMAGE
;
4919 it
->from_overlay
= Qnil
;
4920 it
->face_id
= face_id
;
4921 it
->from_disp_prop_p
= 1;
4923 /* Say that we haven't consumed the characters with
4924 `display' property yet. The call to pop_it in
4925 set_iterator_to_next will clean this up. */
4926 *position
= start_pos
;
4928 if (EQ (XCAR (spec
), Qleft_fringe
))
4930 it
->left_user_fringe_bitmap
= fringe_bitmap
;
4931 it
->left_user_fringe_face_id
= face_id
;
4935 it
->right_user_fringe_bitmap
= fringe_bitmap
;
4936 it
->right_user_fringe_face_id
= face_id
;
4939 #endif /* HAVE_WINDOW_SYSTEM */
4943 /* Prepare to handle `((margin left-margin) ...)',
4944 `((margin right-margin) ...)' and `((margin nil) ...)'
4945 prefixes for display specifications. */
4946 location
= Qunbound
;
4947 if (CONSP (spec
) && CONSP (XCAR (spec
)))
4951 value
= XCDR (spec
);
4953 value
= XCAR (value
);
4956 if (EQ (XCAR (tem
), Qmargin
)
4957 && (tem
= XCDR (tem
),
4958 tem
= CONSP (tem
) ? XCAR (tem
) : Qnil
,
4960 || EQ (tem
, Qleft_margin
)
4961 || EQ (tem
, Qright_margin
))))
4965 if (EQ (location
, Qunbound
))
4971 /* After this point, VALUE is the property after any
4972 margin prefix has been stripped. It must be a string,
4973 an image specification, or `(space ...)'.
4975 LOCATION specifies where to display: `left-margin',
4976 `right-margin' or nil. */
4978 valid_p
= (STRINGP (value
)
4979 #ifdef HAVE_WINDOW_SYSTEM
4980 || ((it
? FRAME_WINDOW_P (it
->f
) : frame_window_p
)
4981 && valid_image_p (value
))
4982 #endif /* not HAVE_WINDOW_SYSTEM */
4983 || (CONSP (value
) && EQ (XCAR (value
), Qspace
)));
4985 if (valid_p
&& !display_replaced_p
)
4991 /* Callers need to know whether the display spec is any kind
4992 of `(space ...)' spec that is about to affect text-area
4994 if (CONSP (value
) && EQ (XCAR (value
), Qspace
) && NILP (location
))
4999 /* Save current settings of IT so that we can restore them
5000 when we are finished with the glyph property value. */
5001 push_it (it
, position
);
5002 it
->from_overlay
= overlay
;
5003 it
->from_disp_prop_p
= 1;
5005 if (NILP (location
))
5006 it
->area
= TEXT_AREA
;
5007 else if (EQ (location
, Qleft_margin
))
5008 it
->area
= LEFT_MARGIN_AREA
;
5010 it
->area
= RIGHT_MARGIN_AREA
;
5012 if (STRINGP (value
))
5015 it
->multibyte_p
= STRING_MULTIBYTE (it
->string
);
5016 it
->current
.overlay_string_index
= -1;
5017 IT_STRING_CHARPOS (*it
) = IT_STRING_BYTEPOS (*it
) = 0;
5018 it
->end_charpos
= it
->string_nchars
= SCHARS (it
->string
);
5019 it
->method
= GET_FROM_STRING
;
5020 it
->stop_charpos
= 0;
5022 it
->base_level_stop
= 0;
5023 it
->string_from_display_prop_p
= 1;
5024 /* Say that we haven't consumed the characters with
5025 `display' property yet. The call to pop_it in
5026 set_iterator_to_next will clean this up. */
5027 if (BUFFERP (object
))
5028 *position
= start_pos
;
5030 /* Force paragraph direction to be that of the parent
5031 object. If the parent object's paragraph direction is
5032 not yet determined, default to L2R. */
5033 if (it
->bidi_p
&& it
->bidi_it
.paragraph_dir
== R2L
)
5034 it
->paragraph_embedding
= it
->bidi_it
.paragraph_dir
;
5036 it
->paragraph_embedding
= L2R
;
5038 /* Set up the bidi iterator for this display string. */
5041 it
->bidi_it
.string
.lstring
= it
->string
;
5042 it
->bidi_it
.string
.s
= NULL
;
5043 it
->bidi_it
.string
.schars
= it
->end_charpos
;
5044 it
->bidi_it
.string
.bufpos
= bufpos
;
5045 it
->bidi_it
.string
.from_disp_str
= 1;
5046 it
->bidi_it
.string
.unibyte
= !it
->multibyte_p
;
5047 it
->bidi_it
.w
= it
->w
;
5048 bidi_init_it (0, 0, FRAME_WINDOW_P (it
->f
), &it
->bidi_it
);
5051 else if (CONSP (value
) && EQ (XCAR (value
), Qspace
))
5053 it
->method
= GET_FROM_STRETCH
;
5055 *position
= it
->position
= start_pos
;
5056 retval
= 1 + (it
->area
== TEXT_AREA
);
5058 #ifdef HAVE_WINDOW_SYSTEM
5061 it
->what
= IT_IMAGE
;
5062 it
->image_id
= lookup_image (it
->f
, value
);
5063 it
->position
= start_pos
;
5064 it
->object
= NILP (object
) ? it
->w
->contents
: object
;
5065 it
->method
= GET_FROM_IMAGE
;
5067 /* Say that we haven't consumed the characters with
5068 `display' property yet. The call to pop_it in
5069 set_iterator_to_next will clean this up. */
5070 *position
= start_pos
;
5072 #endif /* HAVE_WINDOW_SYSTEM */
5077 /* Invalid property or property not supported. Restore
5078 POSITION to what it was before. */
5079 *position
= start_pos
;
5083 /* Check if PROP is a display property value whose text should be
5084 treated as intangible. OVERLAY is the overlay from which PROP
5085 came, or nil if it came from a text property. CHARPOS and BYTEPOS
5086 specify the buffer position covered by PROP. */
5089 display_prop_intangible_p (Lisp_Object prop
, Lisp_Object overlay
,
5090 ptrdiff_t charpos
, ptrdiff_t bytepos
)
5092 int frame_window_p
= FRAME_WINDOW_P (XFRAME (selected_frame
));
5093 struct text_pos position
;
5095 SET_TEXT_POS (position
, charpos
, bytepos
);
5096 return handle_display_spec (NULL
, prop
, Qnil
, overlay
,
5097 &position
, charpos
, frame_window_p
);
5101 /* Return 1 if PROP is a display sub-property value containing STRING.
5103 Implementation note: this and the following function are really
5104 special cases of handle_display_spec and
5105 handle_single_display_spec, and should ideally use the same code.
5106 Until they do, these two pairs must be consistent and must be
5107 modified in sync. */
5110 single_display_spec_string_p (Lisp_Object prop
, Lisp_Object string
)
5112 if (EQ (string
, prop
))
5115 /* Skip over `when FORM'. */
5116 if (CONSP (prop
) && EQ (XCAR (prop
), Qwhen
))
5121 /* Actually, the condition following `when' should be eval'ed,
5122 like handle_single_display_spec does, and we should return
5123 zero if it evaluates to nil. However, this function is
5124 called only when the buffer was already displayed and some
5125 glyph in the glyph matrix was found to come from a display
5126 string. Therefore, the condition was already evaluated, and
5127 the result was non-nil, otherwise the display string wouldn't
5128 have been displayed and we would have never been called for
5129 this property. Thus, we can skip the evaluation and assume
5130 its result is non-nil. */
5135 /* Skip over `margin LOCATION'. */
5136 if (EQ (XCAR (prop
), Qmargin
))
5147 return EQ (prop
, string
) || (CONSP (prop
) && EQ (XCAR (prop
), string
));
5151 /* Return 1 if STRING appears in the `display' property PROP. */
5154 display_prop_string_p (Lisp_Object prop
, Lisp_Object string
)
5157 && !EQ (XCAR (prop
), Qwhen
)
5158 && !(CONSP (XCAR (prop
)) && EQ (Qmargin
, XCAR (XCAR (prop
)))))
5160 /* A list of sub-properties. */
5161 while (CONSP (prop
))
5163 if (single_display_spec_string_p (XCAR (prop
), string
))
5168 else if (VECTORP (prop
))
5170 /* A vector of sub-properties. */
5172 for (i
= 0; i
< ASIZE (prop
); ++i
)
5173 if (single_display_spec_string_p (AREF (prop
, i
), string
))
5177 return single_display_spec_string_p (prop
, string
);
5182 /* Look for STRING in overlays and text properties in the current
5183 buffer, between character positions FROM and TO (excluding TO).
5184 BACK_P non-zero means look back (in this case, TO is supposed to be
5186 Value is the first character position where STRING was found, or
5187 zero if it wasn't found before hitting TO.
5189 This function may only use code that doesn't eval because it is
5190 called asynchronously from note_mouse_highlight. */
5193 string_buffer_position_lim (Lisp_Object string
,
5194 ptrdiff_t from
, ptrdiff_t to
, int back_p
)
5196 Lisp_Object limit
, prop
, pos
;
5199 pos
= make_number (max (from
, BEGV
));
5201 if (!back_p
) /* looking forward */
5203 limit
= make_number (min (to
, ZV
));
5204 while (!found
&& !EQ (pos
, limit
))
5206 prop
= Fget_char_property (pos
, Qdisplay
, Qnil
);
5207 if (!NILP (prop
) && display_prop_string_p (prop
, string
))
5210 pos
= Fnext_single_char_property_change (pos
, Qdisplay
, Qnil
,
5214 else /* looking back */
5216 limit
= make_number (max (to
, BEGV
));
5217 while (!found
&& !EQ (pos
, limit
))
5219 prop
= Fget_char_property (pos
, Qdisplay
, Qnil
);
5220 if (!NILP (prop
) && display_prop_string_p (prop
, string
))
5223 pos
= Fprevious_single_char_property_change (pos
, Qdisplay
, Qnil
,
5228 return found
? XINT (pos
) : 0;
5231 /* Determine which buffer position in current buffer STRING comes from.
5232 AROUND_CHARPOS is an approximate position where it could come from.
5233 Value is the buffer position or 0 if it couldn't be determined.
5235 This function is necessary because we don't record buffer positions
5236 in glyphs generated from strings (to keep struct glyph small).
5237 This function may only use code that doesn't eval because it is
5238 called asynchronously from note_mouse_highlight. */
5241 string_buffer_position (Lisp_Object string
, ptrdiff_t around_charpos
)
5243 const int MAX_DISTANCE
= 1000;
5244 ptrdiff_t found
= string_buffer_position_lim (string
, around_charpos
,
5245 around_charpos
+ MAX_DISTANCE
,
5249 found
= string_buffer_position_lim (string
, around_charpos
,
5250 around_charpos
- MAX_DISTANCE
, 1);
5256 /***********************************************************************
5257 `composition' property
5258 ***********************************************************************/
5260 /* Set up iterator IT from `composition' property at its current
5261 position. Called from handle_stop. */
5263 static enum prop_handled
5264 handle_composition_prop (struct it
*it
)
5266 Lisp_Object prop
, string
;
5267 ptrdiff_t pos
, pos_byte
, start
, end
;
5269 if (STRINGP (it
->string
))
5273 pos
= IT_STRING_CHARPOS (*it
);
5274 pos_byte
= IT_STRING_BYTEPOS (*it
);
5275 string
= it
->string
;
5276 s
= SDATA (string
) + pos_byte
;
5277 it
->c
= STRING_CHAR (s
);
5281 pos
= IT_CHARPOS (*it
);
5282 pos_byte
= IT_BYTEPOS (*it
);
5284 it
->c
= FETCH_CHAR (pos_byte
);
5287 /* If there's a valid composition and point is not inside of the
5288 composition (in the case that the composition is from the current
5289 buffer), draw a glyph composed from the composition components. */
5290 if (find_composition (pos
, -1, &start
, &end
, &prop
, string
)
5291 && COMPOSITION_VALID_P (start
, end
, prop
)
5292 && (STRINGP (it
->string
) || (PT
<= start
|| PT
>= end
)))
5295 /* As we can't handle this situation (perhaps font-lock added
5296 a new composition), we just return here hoping that next
5297 redisplay will detect this composition much earlier. */
5298 return HANDLED_NORMALLY
;
5301 if (STRINGP (it
->string
))
5302 pos_byte
= string_char_to_byte (it
->string
, start
);
5304 pos_byte
= CHAR_TO_BYTE (start
);
5306 it
->cmp_it
.id
= get_composition_id (start
, pos_byte
, end
- start
,
5309 if (it
->cmp_it
.id
>= 0)
5312 it
->cmp_it
.nchars
= COMPOSITION_LENGTH (prop
);
5313 it
->cmp_it
.nglyphs
= -1;
5317 return HANDLED_NORMALLY
;
5322 /***********************************************************************
5324 ***********************************************************************/
5326 /* The following structure is used to record overlay strings for
5327 later sorting in load_overlay_strings. */
5329 struct overlay_entry
5331 Lisp_Object overlay
;
5338 /* Set up iterator IT from overlay strings at its current position.
5339 Called from handle_stop. */
5341 static enum prop_handled
5342 handle_overlay_change (struct it
*it
)
5344 if (!STRINGP (it
->string
) && get_overlay_strings (it
, 0))
5345 return HANDLED_RECOMPUTE_PROPS
;
5347 return HANDLED_NORMALLY
;
5351 /* Set up the next overlay string for delivery by IT, if there is an
5352 overlay string to deliver. Called by set_iterator_to_next when the
5353 end of the current overlay string is reached. If there are more
5354 overlay strings to display, IT->string and
5355 IT->current.overlay_string_index are set appropriately here.
5356 Otherwise IT->string is set to nil. */
5359 next_overlay_string (struct it
*it
)
5361 ++it
->current
.overlay_string_index
;
5362 if (it
->current
.overlay_string_index
== it
->n_overlay_strings
)
5364 /* No more overlay strings. Restore IT's settings to what
5365 they were before overlay strings were processed, and
5366 continue to deliver from current_buffer. */
5368 it
->ellipsis_p
= (it
->stack
[it
->sp
- 1].display_ellipsis_p
!= 0);
5371 || (NILP (it
->string
)
5372 && it
->method
== GET_FROM_BUFFER
5373 && it
->stop_charpos
>= BEGV
5374 && it
->stop_charpos
<= it
->end_charpos
));
5375 it
->current
.overlay_string_index
= -1;
5376 it
->n_overlay_strings
= 0;
5377 it
->overlay_strings_charpos
= -1;
5378 /* If there's an empty display string on the stack, pop the
5379 stack, to resync the bidi iterator with IT's position. Such
5380 empty strings are pushed onto the stack in
5381 get_overlay_strings_1. */
5382 if (it
->sp
> 0 && STRINGP (it
->string
) && !SCHARS (it
->string
))
5385 /* If we're at the end of the buffer, record that we have
5386 processed the overlay strings there already, so that
5387 next_element_from_buffer doesn't try it again. */
5388 if (NILP (it
->string
) && IT_CHARPOS (*it
) >= it
->end_charpos
)
5389 it
->overlay_strings_at_end_processed_p
= 1;
5393 /* There are more overlay strings to process. If
5394 IT->current.overlay_string_index has advanced to a position
5395 where we must load IT->overlay_strings with more strings, do
5396 it. We must load at the IT->overlay_strings_charpos where
5397 IT->n_overlay_strings was originally computed; when invisible
5398 text is present, this might not be IT_CHARPOS (Bug#7016). */
5399 int i
= it
->current
.overlay_string_index
% OVERLAY_STRING_CHUNK_SIZE
;
5401 if (it
->current
.overlay_string_index
&& i
== 0)
5402 load_overlay_strings (it
, it
->overlay_strings_charpos
);
5404 /* Initialize IT to deliver display elements from the overlay
5406 it
->string
= it
->overlay_strings
[i
];
5407 it
->multibyte_p
= STRING_MULTIBYTE (it
->string
);
5408 SET_TEXT_POS (it
->current
.string_pos
, 0, 0);
5409 it
->method
= GET_FROM_STRING
;
5410 it
->stop_charpos
= 0;
5411 it
->end_charpos
= SCHARS (it
->string
);
5412 if (it
->cmp_it
.stop_pos
>= 0)
5413 it
->cmp_it
.stop_pos
= 0;
5415 it
->base_level_stop
= 0;
5417 /* Set up the bidi iterator for this overlay string. */
5420 it
->bidi_it
.string
.lstring
= it
->string
;
5421 it
->bidi_it
.string
.s
= NULL
;
5422 it
->bidi_it
.string
.schars
= SCHARS (it
->string
);
5423 it
->bidi_it
.string
.bufpos
= it
->overlay_strings_charpos
;
5424 it
->bidi_it
.string
.from_disp_str
= it
->string_from_display_prop_p
;
5425 it
->bidi_it
.string
.unibyte
= !it
->multibyte_p
;
5426 it
->bidi_it
.w
= it
->w
;
5427 bidi_init_it (0, 0, FRAME_WINDOW_P (it
->f
), &it
->bidi_it
);
5435 /* Compare two overlay_entry structures E1 and E2. Used as a
5436 comparison function for qsort in load_overlay_strings. Overlay
5437 strings for the same position are sorted so that
5439 1. All after-strings come in front of before-strings, except
5440 when they come from the same overlay.
5442 2. Within after-strings, strings are sorted so that overlay strings
5443 from overlays with higher priorities come first.
5445 2. Within before-strings, strings are sorted so that overlay
5446 strings from overlays with higher priorities come last.
5448 Value is analogous to strcmp. */
5452 compare_overlay_entries (const void *e1
, const void *e2
)
5454 struct overlay_entry
*entry1
= (struct overlay_entry
*) e1
;
5455 struct overlay_entry
*entry2
= (struct overlay_entry
*) e2
;
5458 if (entry1
->after_string_p
!= entry2
->after_string_p
)
5460 /* Let after-strings appear in front of before-strings if
5461 they come from different overlays. */
5462 if (EQ (entry1
->overlay
, entry2
->overlay
))
5463 result
= entry1
->after_string_p
? 1 : -1;
5465 result
= entry1
->after_string_p
? -1 : 1;
5467 else if (entry1
->priority
!= entry2
->priority
)
5469 if (entry1
->after_string_p
)
5470 /* After-strings sorted in order of decreasing priority. */
5471 result
= entry2
->priority
< entry1
->priority
? -1 : 1;
5473 /* Before-strings sorted in order of increasing priority. */
5474 result
= entry1
->priority
< entry2
->priority
? -1 : 1;
5483 /* Load the vector IT->overlay_strings with overlay strings from IT's
5484 current buffer position, or from CHARPOS if that is > 0. Set
5485 IT->n_overlays to the total number of overlay strings found.
5487 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
5488 a time. On entry into load_overlay_strings,
5489 IT->current.overlay_string_index gives the number of overlay
5490 strings that have already been loaded by previous calls to this
5493 IT->add_overlay_start contains an additional overlay start
5494 position to consider for taking overlay strings from, if non-zero.
5495 This position comes into play when the overlay has an `invisible'
5496 property, and both before and after-strings. When we've skipped to
5497 the end of the overlay, because of its `invisible' property, we
5498 nevertheless want its before-string to appear.
5499 IT->add_overlay_start will contain the overlay start position
5502 Overlay strings are sorted so that after-string strings come in
5503 front of before-string strings. Within before and after-strings,
5504 strings are sorted by overlay priority. See also function
5505 compare_overlay_entries. */
5508 load_overlay_strings (struct it
*it
, ptrdiff_t charpos
)
5510 Lisp_Object overlay
, window
, str
, invisible
;
5511 struct Lisp_Overlay
*ov
;
5512 ptrdiff_t start
, end
;
5513 ptrdiff_t size
= 20;
5514 ptrdiff_t n
= 0, i
, j
;
5516 struct overlay_entry
*entries
= alloca (size
* sizeof *entries
);
5520 charpos
= IT_CHARPOS (*it
);
5522 /* Append the overlay string STRING of overlay OVERLAY to vector
5523 `entries' which has size `size' and currently contains `n'
5524 elements. AFTER_P non-zero means STRING is an after-string of
5526 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
5529 Lisp_Object priority; \
5533 struct overlay_entry *old = entries; \
5534 SAFE_NALLOCA (entries, 2, size); \
5535 memcpy (entries, old, size * sizeof *entries); \
5539 entries[n].string = (STRING); \
5540 entries[n].overlay = (OVERLAY); \
5541 priority = Foverlay_get ((OVERLAY), Qpriority); \
5542 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
5543 entries[n].after_string_p = (AFTER_P); \
5548 /* Process overlay before the overlay center. */
5549 for (ov
= current_buffer
->overlays_before
; ov
; ov
= ov
->next
)
5551 XSETMISC (overlay
, ov
);
5552 eassert (OVERLAYP (overlay
));
5553 start
= OVERLAY_POSITION (OVERLAY_START (overlay
));
5554 end
= OVERLAY_POSITION (OVERLAY_END (overlay
));
5559 /* Skip this overlay if it doesn't start or end at IT's current
5561 if (end
!= charpos
&& start
!= charpos
)
5564 /* Skip this overlay if it doesn't apply to IT->w. */
5565 window
= Foverlay_get (overlay
, Qwindow
);
5566 if (WINDOWP (window
) && XWINDOW (window
) != it
->w
)
5569 /* If the text ``under'' the overlay is invisible, both before-
5570 and after-strings from this overlay are visible; start and
5571 end position are indistinguishable. */
5572 invisible
= Foverlay_get (overlay
, Qinvisible
);
5573 invis_p
= TEXT_PROP_MEANS_INVISIBLE (invisible
);
5575 /* If overlay has a non-empty before-string, record it. */
5576 if ((start
== charpos
|| (end
== charpos
&& invis_p
))
5577 && (str
= Foverlay_get (overlay
, Qbefore_string
), STRINGP (str
))
5579 RECORD_OVERLAY_STRING (overlay
, str
, 0);
5581 /* If overlay has a non-empty after-string, record it. */
5582 if ((end
== charpos
|| (start
== charpos
&& invis_p
))
5583 && (str
= Foverlay_get (overlay
, Qafter_string
), STRINGP (str
))
5585 RECORD_OVERLAY_STRING (overlay
, str
, 1);
5588 /* Process overlays after the overlay center. */
5589 for (ov
= current_buffer
->overlays_after
; ov
; ov
= ov
->next
)
5591 XSETMISC (overlay
, ov
);
5592 eassert (OVERLAYP (overlay
));
5593 start
= OVERLAY_POSITION (OVERLAY_START (overlay
));
5594 end
= OVERLAY_POSITION (OVERLAY_END (overlay
));
5596 if (start
> charpos
)
5599 /* Skip this overlay if it doesn't start or end at IT's current
5601 if (end
!= charpos
&& start
!= charpos
)
5604 /* Skip this overlay if it doesn't apply to IT->w. */
5605 window
= Foverlay_get (overlay
, Qwindow
);
5606 if (WINDOWP (window
) && XWINDOW (window
) != it
->w
)
5609 /* If the text ``under'' the overlay is invisible, it has a zero
5610 dimension, and both before- and after-strings apply. */
5611 invisible
= Foverlay_get (overlay
, Qinvisible
);
5612 invis_p
= TEXT_PROP_MEANS_INVISIBLE (invisible
);
5614 /* If overlay has a non-empty before-string, record it. */
5615 if ((start
== charpos
|| (end
== charpos
&& invis_p
))
5616 && (str
= Foverlay_get (overlay
, Qbefore_string
), STRINGP (str
))
5618 RECORD_OVERLAY_STRING (overlay
, str
, 0);
5620 /* If overlay has a non-empty after-string, record it. */
5621 if ((end
== charpos
|| (start
== charpos
&& invis_p
))
5622 && (str
= Foverlay_get (overlay
, Qafter_string
), STRINGP (str
))
5624 RECORD_OVERLAY_STRING (overlay
, str
, 1);
5627 #undef RECORD_OVERLAY_STRING
5631 qsort (entries
, n
, sizeof *entries
, compare_overlay_entries
);
5633 /* Record number of overlay strings, and where we computed it. */
5634 it
->n_overlay_strings
= n
;
5635 it
->overlay_strings_charpos
= charpos
;
5637 /* IT->current.overlay_string_index is the number of overlay strings
5638 that have already been consumed by IT. Copy some of the
5639 remaining overlay strings to IT->overlay_strings. */
5641 j
= it
->current
.overlay_string_index
;
5642 while (i
< OVERLAY_STRING_CHUNK_SIZE
&& j
< n
)
5644 it
->overlay_strings
[i
] = entries
[j
].string
;
5645 it
->string_overlays
[i
++] = entries
[j
++].overlay
;
5653 /* Get the first chunk of overlay strings at IT's current buffer
5654 position, or at CHARPOS if that is > 0. Value is non-zero if at
5655 least one overlay string was found. */
5658 get_overlay_strings_1 (struct it
*it
, ptrdiff_t charpos
, int compute_stop_p
)
5660 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
5661 process. This fills IT->overlay_strings with strings, and sets
5662 IT->n_overlay_strings to the total number of strings to process.
5663 IT->pos.overlay_string_index has to be set temporarily to zero
5664 because load_overlay_strings needs this; it must be set to -1
5665 when no overlay strings are found because a zero value would
5666 indicate a position in the first overlay string. */
5667 it
->current
.overlay_string_index
= 0;
5668 load_overlay_strings (it
, charpos
);
5670 /* If we found overlay strings, set up IT to deliver display
5671 elements from the first one. Otherwise set up IT to deliver
5672 from current_buffer. */
5673 if (it
->n_overlay_strings
)
5675 /* Make sure we know settings in current_buffer, so that we can
5676 restore meaningful values when we're done with the overlay
5679 compute_stop_pos (it
);
5680 eassert (it
->face_id
>= 0);
5682 /* Save IT's settings. They are restored after all overlay
5683 strings have been processed. */
5684 eassert (!compute_stop_p
|| it
->sp
== 0);
5686 /* When called from handle_stop, there might be an empty display
5687 string loaded. In that case, don't bother saving it. But
5688 don't use this optimization with the bidi iterator, since we
5689 need the corresponding pop_it call to resync the bidi
5690 iterator's position with IT's position, after we are done
5691 with the overlay strings. (The corresponding call to pop_it
5692 in case of an empty display string is in
5693 next_overlay_string.) */
5695 && STRINGP (it
->string
) && !SCHARS (it
->string
)))
5698 /* Set up IT to deliver display elements from the first overlay
5700 IT_STRING_CHARPOS (*it
) = IT_STRING_BYTEPOS (*it
) = 0;
5701 it
->string
= it
->overlay_strings
[0];
5702 it
->from_overlay
= Qnil
;
5703 it
->stop_charpos
= 0;
5704 eassert (STRINGP (it
->string
));
5705 it
->end_charpos
= SCHARS (it
->string
);
5707 it
->base_level_stop
= 0;
5708 it
->multibyte_p
= STRING_MULTIBYTE (it
->string
);
5709 it
->method
= GET_FROM_STRING
;
5710 it
->from_disp_prop_p
= 0;
5712 /* Force paragraph direction to be that of the parent
5714 if (it
->bidi_p
&& it
->bidi_it
.paragraph_dir
== R2L
)
5715 it
->paragraph_embedding
= it
->bidi_it
.paragraph_dir
;
5717 it
->paragraph_embedding
= L2R
;
5719 /* Set up the bidi iterator for this overlay string. */
5722 ptrdiff_t pos
= (charpos
> 0 ? charpos
: IT_CHARPOS (*it
));
5724 it
->bidi_it
.string
.lstring
= it
->string
;
5725 it
->bidi_it
.string
.s
= NULL
;
5726 it
->bidi_it
.string
.schars
= SCHARS (it
->string
);
5727 it
->bidi_it
.string
.bufpos
= pos
;
5728 it
->bidi_it
.string
.from_disp_str
= it
->string_from_display_prop_p
;
5729 it
->bidi_it
.string
.unibyte
= !it
->multibyte_p
;
5730 it
->bidi_it
.w
= it
->w
;
5731 bidi_init_it (0, 0, FRAME_WINDOW_P (it
->f
), &it
->bidi_it
);
5736 it
->current
.overlay_string_index
= -1;
5741 get_overlay_strings (struct it
*it
, ptrdiff_t charpos
)
5744 it
->method
= GET_FROM_BUFFER
;
5746 (void) get_overlay_strings_1 (it
, charpos
, 1);
5750 /* Value is non-zero if we found at least one overlay string. */
5751 return STRINGP (it
->string
);
5756 /***********************************************************************
5757 Saving and restoring state
5758 ***********************************************************************/
5760 /* Save current settings of IT on IT->stack. Called, for example,
5761 before setting up IT for an overlay string, to be able to restore
5762 IT's settings to what they were after the overlay string has been
5763 processed. If POSITION is non-NULL, it is the position to save on
5764 the stack instead of IT->position. */
5767 push_it (struct it
*it
, struct text_pos
*position
)
5769 struct iterator_stack_entry
*p
;
5771 eassert (it
->sp
< IT_STACK_SIZE
);
5772 p
= it
->stack
+ it
->sp
;
5774 p
->stop_charpos
= it
->stop_charpos
;
5775 p
->prev_stop
= it
->prev_stop
;
5776 p
->base_level_stop
= it
->base_level_stop
;
5777 p
->cmp_it
= it
->cmp_it
;
5778 eassert (it
->face_id
>= 0);
5779 p
->face_id
= it
->face_id
;
5780 p
->string
= it
->string
;
5781 p
->method
= it
->method
;
5782 p
->from_overlay
= it
->from_overlay
;
5785 case GET_FROM_IMAGE
:
5786 p
->u
.image
.object
= it
->object
;
5787 p
->u
.image
.image_id
= it
->image_id
;
5788 p
->u
.image
.slice
= it
->slice
;
5790 case GET_FROM_STRETCH
:
5791 p
->u
.stretch
.object
= it
->object
;
5794 p
->position
= position
? *position
: it
->position
;
5795 p
->current
= it
->current
;
5796 p
->end_charpos
= it
->end_charpos
;
5797 p
->string_nchars
= it
->string_nchars
;
5799 p
->multibyte_p
= it
->multibyte_p
;
5800 p
->avoid_cursor_p
= it
->avoid_cursor_p
;
5801 p
->space_width
= it
->space_width
;
5802 p
->font_height
= it
->font_height
;
5803 p
->voffset
= it
->voffset
;
5804 p
->string_from_display_prop_p
= it
->string_from_display_prop_p
;
5805 p
->string_from_prefix_prop_p
= it
->string_from_prefix_prop_p
;
5806 p
->display_ellipsis_p
= 0;
5807 p
->line_wrap
= it
->line_wrap
;
5808 p
->bidi_p
= it
->bidi_p
;
5809 p
->paragraph_embedding
= it
->paragraph_embedding
;
5810 p
->from_disp_prop_p
= it
->from_disp_prop_p
;
5813 /* Save the state of the bidi iterator as well. */
5815 bidi_push_it (&it
->bidi_it
);
5819 iterate_out_of_display_property (struct it
*it
)
5821 int buffer_p
= !STRINGP (it
->string
);
5822 ptrdiff_t eob
= (buffer_p
? ZV
: it
->end_charpos
);
5823 ptrdiff_t bob
= (buffer_p
? BEGV
: 0);
5825 eassert (eob
>= CHARPOS (it
->position
) && CHARPOS (it
->position
) >= bob
);
5827 /* Maybe initialize paragraph direction. If we are at the beginning
5828 of a new paragraph, next_element_from_buffer may not have a
5829 chance to do that. */
5830 if (it
->bidi_it
.first_elt
&& it
->bidi_it
.charpos
< eob
)
5831 bidi_paragraph_init (it
->paragraph_embedding
, &it
->bidi_it
, 1);
5832 /* prev_stop can be zero, so check against BEGV as well. */
5833 while (it
->bidi_it
.charpos
>= bob
5834 && it
->prev_stop
<= it
->bidi_it
.charpos
5835 && it
->bidi_it
.charpos
< CHARPOS (it
->position
)
5836 && it
->bidi_it
.charpos
< eob
)
5837 bidi_move_to_visually_next (&it
->bidi_it
);
5838 /* Record the stop_pos we just crossed, for when we cross it
5840 if (it
->bidi_it
.charpos
> CHARPOS (it
->position
))
5841 it
->prev_stop
= CHARPOS (it
->position
);
5842 /* If we ended up not where pop_it put us, resync IT's
5843 positional members with the bidi iterator. */
5844 if (it
->bidi_it
.charpos
!= CHARPOS (it
->position
))
5845 SET_TEXT_POS (it
->position
, it
->bidi_it
.charpos
, it
->bidi_it
.bytepos
);
5847 it
->current
.pos
= it
->position
;
5849 it
->current
.string_pos
= it
->position
;
5852 /* Restore IT's settings from IT->stack. Called, for example, when no
5853 more overlay strings must be processed, and we return to delivering
5854 display elements from a buffer, or when the end of a string from a
5855 `display' property is reached and we return to delivering display
5856 elements from an overlay string, or from a buffer. */
5859 pop_it (struct it
*it
)
5861 struct iterator_stack_entry
*p
;
5862 int from_display_prop
= it
->from_disp_prop_p
;
5864 eassert (it
->sp
> 0);
5866 p
= it
->stack
+ it
->sp
;
5867 it
->stop_charpos
= p
->stop_charpos
;
5868 it
->prev_stop
= p
->prev_stop
;
5869 it
->base_level_stop
= p
->base_level_stop
;
5870 it
->cmp_it
= p
->cmp_it
;
5871 it
->face_id
= p
->face_id
;
5872 it
->current
= p
->current
;
5873 it
->position
= p
->position
;
5874 it
->string
= p
->string
;
5875 it
->from_overlay
= p
->from_overlay
;
5876 if (NILP (it
->string
))
5877 SET_TEXT_POS (it
->current
.string_pos
, -1, -1);
5878 it
->method
= p
->method
;
5881 case GET_FROM_IMAGE
:
5882 it
->image_id
= p
->u
.image
.image_id
;
5883 it
->object
= p
->u
.image
.object
;
5884 it
->slice
= p
->u
.image
.slice
;
5886 case GET_FROM_STRETCH
:
5887 it
->object
= p
->u
.stretch
.object
;
5889 case GET_FROM_BUFFER
:
5890 it
->object
= it
->w
->contents
;
5892 case GET_FROM_STRING
:
5893 it
->object
= it
->string
;
5895 case GET_FROM_DISPLAY_VECTOR
:
5897 it
->method
= GET_FROM_C_STRING
;
5898 else if (STRINGP (it
->string
))
5899 it
->method
= GET_FROM_STRING
;
5902 it
->method
= GET_FROM_BUFFER
;
5903 it
->object
= it
->w
->contents
;
5906 it
->end_charpos
= p
->end_charpos
;
5907 it
->string_nchars
= p
->string_nchars
;
5909 it
->multibyte_p
= p
->multibyte_p
;
5910 it
->avoid_cursor_p
= p
->avoid_cursor_p
;
5911 it
->space_width
= p
->space_width
;
5912 it
->font_height
= p
->font_height
;
5913 it
->voffset
= p
->voffset
;
5914 it
->string_from_display_prop_p
= p
->string_from_display_prop_p
;
5915 it
->string_from_prefix_prop_p
= p
->string_from_prefix_prop_p
;
5916 it
->line_wrap
= p
->line_wrap
;
5917 it
->bidi_p
= p
->bidi_p
;
5918 it
->paragraph_embedding
= p
->paragraph_embedding
;
5919 it
->from_disp_prop_p
= p
->from_disp_prop_p
;
5922 bidi_pop_it (&it
->bidi_it
);
5923 /* Bidi-iterate until we get out of the portion of text, if any,
5924 covered by a `display' text property or by an overlay with
5925 `display' property. (We cannot just jump there, because the
5926 internal coherency of the bidi iterator state can not be
5927 preserved across such jumps.) We also must determine the
5928 paragraph base direction if the overlay we just processed is
5929 at the beginning of a new paragraph. */
5930 if (from_display_prop
5931 && (it
->method
== GET_FROM_BUFFER
|| it
->method
== GET_FROM_STRING
))
5932 iterate_out_of_display_property (it
);
5934 eassert ((BUFFERP (it
->object
)
5935 && IT_CHARPOS (*it
) == it
->bidi_it
.charpos
5936 && IT_BYTEPOS (*it
) == it
->bidi_it
.bytepos
)
5937 || (STRINGP (it
->object
)
5938 && IT_STRING_CHARPOS (*it
) == it
->bidi_it
.charpos
5939 && IT_STRING_BYTEPOS (*it
) == it
->bidi_it
.bytepos
)
5940 || (CONSP (it
->object
) && it
->method
== GET_FROM_STRETCH
));
5946 /***********************************************************************
5948 ***********************************************************************/
5950 /* Set IT's current position to the previous line start. */
5953 back_to_previous_line_start (struct it
*it
)
5955 ptrdiff_t cp
= IT_CHARPOS (*it
), bp
= IT_BYTEPOS (*it
);
5958 IT_CHARPOS (*it
) = find_newline_no_quit (cp
, bp
, -1, &IT_BYTEPOS (*it
));
5962 /* Move IT to the next line start.
5964 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
5965 we skipped over part of the text (as opposed to moving the iterator
5966 continuously over the text). Otherwise, don't change the value
5969 If BIDI_IT_PREV is non-NULL, store into it the state of the bidi
5970 iterator on the newline, if it was found.
5972 Newlines may come from buffer text, overlay strings, or strings
5973 displayed via the `display' property. That's the reason we can't
5974 simply use find_newline_no_quit.
5976 Note that this function may not skip over invisible text that is so
5977 because of text properties and immediately follows a newline. If
5978 it would, function reseat_at_next_visible_line_start, when called
5979 from set_iterator_to_next, would effectively make invisible
5980 characters following a newline part of the wrong glyph row, which
5981 leads to wrong cursor motion. */
5984 forward_to_next_line_start (struct it
*it
, int *skipped_p
,
5985 struct bidi_it
*bidi_it_prev
)
5987 ptrdiff_t old_selective
;
5988 int newline_found_p
, n
;
5989 const int MAX_NEWLINE_DISTANCE
= 500;
5991 /* If already on a newline, just consume it to avoid unintended
5992 skipping over invisible text below. */
5993 if (it
->what
== IT_CHARACTER
5995 && CHARPOS (it
->position
) == IT_CHARPOS (*it
))
5997 if (it
->bidi_p
&& bidi_it_prev
)
5998 *bidi_it_prev
= it
->bidi_it
;
5999 set_iterator_to_next (it
, 0);
6004 /* Don't handle selective display in the following. It's (a)
6005 unnecessary because it's done by the caller, and (b) leads to an
6006 infinite recursion because next_element_from_ellipsis indirectly
6007 calls this function. */
6008 old_selective
= it
->selective
;
6011 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
6012 from buffer text. */
6013 for (n
= newline_found_p
= 0;
6014 !newline_found_p
&& n
< MAX_NEWLINE_DISTANCE
;
6015 n
+= STRINGP (it
->string
) ? 0 : 1)
6017 if (!get_next_display_element (it
))
6019 newline_found_p
= it
->what
== IT_CHARACTER
&& it
->c
== '\n';
6020 if (newline_found_p
&& it
->bidi_p
&& bidi_it_prev
)
6021 *bidi_it_prev
= it
->bidi_it
;
6022 set_iterator_to_next (it
, 0);
6025 /* If we didn't find a newline near enough, see if we can use a
6027 if (!newline_found_p
)
6029 ptrdiff_t bytepos
, start
= IT_CHARPOS (*it
);
6030 ptrdiff_t limit
= find_newline_no_quit (start
, IT_BYTEPOS (*it
),
6034 eassert (!STRINGP (it
->string
));
6036 /* If there isn't any `display' property in sight, and no
6037 overlays, we can just use the position of the newline in
6039 if (it
->stop_charpos
>= limit
6040 || ((pos
= Fnext_single_property_change (make_number (start
),
6042 make_number (limit
)),
6044 && next_overlay_change (start
) == ZV
))
6048 IT_CHARPOS (*it
) = limit
;
6049 IT_BYTEPOS (*it
) = bytepos
;
6053 struct bidi_it bprev
;
6055 /* Help bidi.c avoid expensive searches for display
6056 properties and overlays, by telling it that there are
6057 none up to `limit'. */
6058 if (it
->bidi_it
.disp_pos
< limit
)
6060 it
->bidi_it
.disp_pos
= limit
;
6061 it
->bidi_it
.disp_prop
= 0;
6064 bprev
= it
->bidi_it
;
6065 bidi_move_to_visually_next (&it
->bidi_it
);
6066 } while (it
->bidi_it
.charpos
!= limit
);
6067 IT_CHARPOS (*it
) = limit
;
6068 IT_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
6070 *bidi_it_prev
= bprev
;
6072 *skipped_p
= newline_found_p
= 1;
6076 while (get_next_display_element (it
)
6077 && !newline_found_p
)
6079 newline_found_p
= ITERATOR_AT_END_OF_LINE_P (it
);
6080 if (newline_found_p
&& it
->bidi_p
&& bidi_it_prev
)
6081 *bidi_it_prev
= it
->bidi_it
;
6082 set_iterator_to_next (it
, 0);
6087 it
->selective
= old_selective
;
6088 return newline_found_p
;
6092 /* Set IT's current position to the previous visible line start. Skip
6093 invisible text that is so either due to text properties or due to
6094 selective display. Caution: this does not change IT->current_x and
6098 back_to_previous_visible_line_start (struct it
*it
)
6100 while (IT_CHARPOS (*it
) > BEGV
)
6102 back_to_previous_line_start (it
);
6104 if (IT_CHARPOS (*it
) <= BEGV
)
6107 /* If selective > 0, then lines indented more than its value are
6109 if (it
->selective
> 0
6110 && indented_beyond_p (IT_CHARPOS (*it
), IT_BYTEPOS (*it
),
6114 /* Check the newline before point for invisibility. */
6117 prop
= Fget_char_property (make_number (IT_CHARPOS (*it
) - 1),
6118 Qinvisible
, it
->window
);
6119 if (TEXT_PROP_MEANS_INVISIBLE (prop
))
6123 if (IT_CHARPOS (*it
) <= BEGV
)
6128 void *it2data
= NULL
;
6131 Lisp_Object val
, overlay
;
6133 SAVE_IT (it2
, *it
, it2data
);
6135 /* If newline is part of a composition, continue from start of composition */
6136 if (find_composition (IT_CHARPOS (*it
), -1, &beg
, &end
, &val
, Qnil
)
6137 && beg
< IT_CHARPOS (*it
))
6140 /* If newline is replaced by a display property, find start of overlay
6141 or interval and continue search from that point. */
6142 pos
= --IT_CHARPOS (it2
);
6145 bidi_unshelve_cache (NULL
, 0);
6146 it2
.string_from_display_prop_p
= 0;
6147 it2
.from_disp_prop_p
= 0;
6148 if (handle_display_prop (&it2
) == HANDLED_RETURN
6149 && !NILP (val
= get_char_property_and_overlay
6150 (make_number (pos
), Qdisplay
, Qnil
, &overlay
))
6151 && (OVERLAYP (overlay
)
6152 ? (beg
= OVERLAY_POSITION (OVERLAY_START (overlay
)))
6153 : get_property_and_range (pos
, Qdisplay
, &val
, &beg
, &end
, Qnil
)))
6155 RESTORE_IT (it
, it
, it2data
);
6159 /* Newline is not replaced by anything -- so we are done. */
6160 RESTORE_IT (it
, it
, it2data
);
6166 IT_CHARPOS (*it
) = beg
;
6167 IT_BYTEPOS (*it
) = buf_charpos_to_bytepos (current_buffer
, beg
);
6171 it
->continuation_lines_width
= 0;
6173 eassert (IT_CHARPOS (*it
) >= BEGV
);
6174 eassert (IT_CHARPOS (*it
) == BEGV
6175 || FETCH_BYTE (IT_BYTEPOS (*it
) - 1) == '\n');
6180 /* Reseat iterator IT at the previous visible line start. Skip
6181 invisible text that is so either due to text properties or due to
6182 selective display. At the end, update IT's overlay information,
6183 face information etc. */
6186 reseat_at_previous_visible_line_start (struct it
*it
)
6188 back_to_previous_visible_line_start (it
);
6189 reseat (it
, it
->current
.pos
, 1);
6194 /* Reseat iterator IT on the next visible line start in the current
6195 buffer. ON_NEWLINE_P non-zero means position IT on the newline
6196 preceding the line start. Skip over invisible text that is so
6197 because of selective display. Compute faces, overlays etc at the
6198 new position. Note that this function does not skip over text that
6199 is invisible because of text properties. */
6202 reseat_at_next_visible_line_start (struct it
*it
, int on_newline_p
)
6204 int newline_found_p
, skipped_p
= 0;
6205 struct bidi_it bidi_it_prev
;
6207 newline_found_p
= forward_to_next_line_start (it
, &skipped_p
, &bidi_it_prev
);
6209 /* Skip over lines that are invisible because they are indented
6210 more than the value of IT->selective. */
6211 if (it
->selective
> 0)
6212 while (IT_CHARPOS (*it
) < ZV
6213 && indented_beyond_p (IT_CHARPOS (*it
), IT_BYTEPOS (*it
),
6216 eassert (IT_BYTEPOS (*it
) == BEGV
6217 || FETCH_BYTE (IT_BYTEPOS (*it
) - 1) == '\n');
6219 forward_to_next_line_start (it
, &skipped_p
, &bidi_it_prev
);
6222 /* Position on the newline if that's what's requested. */
6223 if (on_newline_p
&& newline_found_p
)
6225 if (STRINGP (it
->string
))
6227 if (IT_STRING_CHARPOS (*it
) > 0)
6231 --IT_STRING_CHARPOS (*it
);
6232 --IT_STRING_BYTEPOS (*it
);
6236 /* We need to restore the bidi iterator to the state
6237 it had on the newline, and resync the IT's
6238 position with that. */
6239 it
->bidi_it
= bidi_it_prev
;
6240 IT_STRING_CHARPOS (*it
) = it
->bidi_it
.charpos
;
6241 IT_STRING_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
6245 else if (IT_CHARPOS (*it
) > BEGV
)
6254 /* We need to restore the bidi iterator to the state it
6255 had on the newline and resync IT with that. */
6256 it
->bidi_it
= bidi_it_prev
;
6257 IT_CHARPOS (*it
) = it
->bidi_it
.charpos
;
6258 IT_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
6260 reseat (it
, it
->current
.pos
, 0);
6264 reseat (it
, it
->current
.pos
, 0);
6271 /***********************************************************************
6272 Changing an iterator's position
6273 ***********************************************************************/
6275 /* Change IT's current position to POS in current_buffer. If FORCE_P
6276 is non-zero, always check for text properties at the new position.
6277 Otherwise, text properties are only looked up if POS >=
6278 IT->check_charpos of a property. */
6281 reseat (struct it
*it
, struct text_pos pos
, int force_p
)
6283 ptrdiff_t original_pos
= IT_CHARPOS (*it
);
6285 reseat_1 (it
, pos
, 0);
6287 /* Determine where to check text properties. Avoid doing it
6288 where possible because text property lookup is very expensive. */
6290 || CHARPOS (pos
) > it
->stop_charpos
6291 || CHARPOS (pos
) < original_pos
)
6295 /* For bidi iteration, we need to prime prev_stop and
6296 base_level_stop with our best estimations. */
6297 /* Implementation note: Of course, POS is not necessarily a
6298 stop position, so assigning prev_pos to it is a lie; we
6299 should have called compute_stop_backwards. However, if
6300 the current buffer does not include any R2L characters,
6301 that call would be a waste of cycles, because the
6302 iterator will never move back, and thus never cross this
6303 "fake" stop position. So we delay that backward search
6304 until the time we really need it, in next_element_from_buffer. */
6305 if (CHARPOS (pos
) != it
->prev_stop
)
6306 it
->prev_stop
= CHARPOS (pos
);
6307 if (CHARPOS (pos
) < it
->base_level_stop
)
6308 it
->base_level_stop
= 0; /* meaning it's unknown */
6314 it
->prev_stop
= it
->base_level_stop
= 0;
6323 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
6324 IT->stop_pos to POS, also. */
6327 reseat_1 (struct it
*it
, struct text_pos pos
, int set_stop_p
)
6329 /* Don't call this function when scanning a C string. */
6330 eassert (it
->s
== NULL
);
6332 /* POS must be a reasonable value. */
6333 eassert (CHARPOS (pos
) >= BEGV
&& CHARPOS (pos
) <= ZV
);
6335 it
->current
.pos
= it
->position
= pos
;
6336 it
->end_charpos
= ZV
;
6338 it
->current
.dpvec_index
= -1;
6339 it
->current
.overlay_string_index
= -1;
6340 IT_STRING_CHARPOS (*it
) = -1;
6341 IT_STRING_BYTEPOS (*it
) = -1;
6343 it
->method
= GET_FROM_BUFFER
;
6344 it
->object
= it
->w
->contents
;
6345 it
->area
= TEXT_AREA
;
6346 it
->multibyte_p
= !NILP (BVAR (current_buffer
, enable_multibyte_characters
));
6348 it
->string_from_display_prop_p
= 0;
6349 it
->string_from_prefix_prop_p
= 0;
6351 it
->from_disp_prop_p
= 0;
6352 it
->face_before_selective_p
= 0;
6355 bidi_init_it (IT_CHARPOS (*it
), IT_BYTEPOS (*it
), FRAME_WINDOW_P (it
->f
),
6357 bidi_unshelve_cache (NULL
, 0);
6358 it
->bidi_it
.paragraph_dir
= NEUTRAL_DIR
;
6359 it
->bidi_it
.string
.s
= NULL
;
6360 it
->bidi_it
.string
.lstring
= Qnil
;
6361 it
->bidi_it
.string
.bufpos
= 0;
6362 it
->bidi_it
.string
.unibyte
= 0;
6363 it
->bidi_it
.w
= it
->w
;
6368 it
->stop_charpos
= CHARPOS (pos
);
6369 it
->base_level_stop
= CHARPOS (pos
);
6371 /* This make the information stored in it->cmp_it invalidate. */
6376 /* Set up IT for displaying a string, starting at CHARPOS in window W.
6377 If S is non-null, it is a C string to iterate over. Otherwise,
6378 STRING gives a Lisp string to iterate over.
6380 If PRECISION > 0, don't return more then PRECISION number of
6381 characters from the string.
6383 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
6384 characters have been returned. FIELD_WIDTH < 0 means an infinite
6387 MULTIBYTE = 0 means disable processing of multibyte characters,
6388 MULTIBYTE > 0 means enable it,
6389 MULTIBYTE < 0 means use IT->multibyte_p.
6391 IT must be initialized via a prior call to init_iterator before
6392 calling this function. */
6395 reseat_to_string (struct it
*it
, const char *s
, Lisp_Object string
,
6396 ptrdiff_t charpos
, ptrdiff_t precision
, int field_width
,
6399 /* No region in strings. */
6400 it
->region_beg_charpos
= it
->region_end_charpos
= -1;
6402 /* No text property checks performed by default, but see below. */
6403 it
->stop_charpos
= -1;
6405 /* Set iterator position and end position. */
6406 memset (&it
->current
, 0, sizeof it
->current
);
6407 it
->current
.overlay_string_index
= -1;
6408 it
->current
.dpvec_index
= -1;
6409 eassert (charpos
>= 0);
6411 /* If STRING is specified, use its multibyteness, otherwise use the
6412 setting of MULTIBYTE, if specified. */
6414 it
->multibyte_p
= multibyte
> 0;
6416 /* Bidirectional reordering of strings is controlled by the default
6417 value of bidi-display-reordering. Don't try to reorder while
6418 loading loadup.el, as the necessary character property tables are
6419 not yet available. */
6422 && !NILP (BVAR (&buffer_defaults
, bidi_display_reordering
));
6426 eassert (STRINGP (string
));
6427 it
->string
= string
;
6429 it
->end_charpos
= it
->string_nchars
= SCHARS (string
);
6430 it
->method
= GET_FROM_STRING
;
6431 it
->current
.string_pos
= string_pos (charpos
, string
);
6435 it
->bidi_it
.string
.lstring
= string
;
6436 it
->bidi_it
.string
.s
= NULL
;
6437 it
->bidi_it
.string
.schars
= it
->end_charpos
;
6438 it
->bidi_it
.string
.bufpos
= 0;
6439 it
->bidi_it
.string
.from_disp_str
= 0;
6440 it
->bidi_it
.string
.unibyte
= !it
->multibyte_p
;
6441 it
->bidi_it
.w
= it
->w
;
6442 bidi_init_it (charpos
, IT_STRING_BYTEPOS (*it
),
6443 FRAME_WINDOW_P (it
->f
), &it
->bidi_it
);
6448 it
->s
= (const unsigned char *) s
;
6451 /* Note that we use IT->current.pos, not it->current.string_pos,
6452 for displaying C strings. */
6453 IT_STRING_CHARPOS (*it
) = IT_STRING_BYTEPOS (*it
) = -1;
6454 if (it
->multibyte_p
)
6456 it
->current
.pos
= c_string_pos (charpos
, s
, 1);
6457 it
->end_charpos
= it
->string_nchars
= number_of_chars (s
, 1);
6461 IT_CHARPOS (*it
) = IT_BYTEPOS (*it
) = charpos
;
6462 it
->end_charpos
= it
->string_nchars
= strlen (s
);
6467 it
->bidi_it
.string
.lstring
= Qnil
;
6468 it
->bidi_it
.string
.s
= (const unsigned char *) s
;
6469 it
->bidi_it
.string
.schars
= it
->end_charpos
;
6470 it
->bidi_it
.string
.bufpos
= 0;
6471 it
->bidi_it
.string
.from_disp_str
= 0;
6472 it
->bidi_it
.string
.unibyte
= !it
->multibyte_p
;
6473 it
->bidi_it
.w
= it
->w
;
6474 bidi_init_it (charpos
, IT_BYTEPOS (*it
), FRAME_WINDOW_P (it
->f
),
6477 it
->method
= GET_FROM_C_STRING
;
6480 /* PRECISION > 0 means don't return more than PRECISION characters
6482 if (precision
> 0 && it
->end_charpos
- charpos
> precision
)
6484 it
->end_charpos
= it
->string_nchars
= charpos
+ precision
;
6486 it
->bidi_it
.string
.schars
= it
->end_charpos
;
6489 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
6490 characters have been returned. FIELD_WIDTH == 0 means don't pad,
6491 FIELD_WIDTH < 0 means infinite field width. This is useful for
6492 padding with `-' at the end of a mode line. */
6493 if (field_width
< 0)
6494 field_width
= INFINITY
;
6495 /* Implementation note: We deliberately don't enlarge
6496 it->bidi_it.string.schars here to fit it->end_charpos, because
6497 the bidi iterator cannot produce characters out of thin air. */
6498 if (field_width
> it
->end_charpos
- charpos
)
6499 it
->end_charpos
= charpos
+ field_width
;
6501 /* Use the standard display table for displaying strings. */
6502 if (DISP_TABLE_P (Vstandard_display_table
))
6503 it
->dp
= XCHAR_TABLE (Vstandard_display_table
);
6505 it
->stop_charpos
= charpos
;
6506 it
->prev_stop
= charpos
;
6507 it
->base_level_stop
= 0;
6510 it
->bidi_it
.first_elt
= 1;
6511 it
->bidi_it
.paragraph_dir
= NEUTRAL_DIR
;
6512 it
->bidi_it
.disp_pos
= -1;
6514 if (s
== NULL
&& it
->multibyte_p
)
6516 ptrdiff_t endpos
= SCHARS (it
->string
);
6517 if (endpos
> it
->end_charpos
)
6518 endpos
= it
->end_charpos
;
6519 composition_compute_stop_pos (&it
->cmp_it
, charpos
, -1, endpos
,
6527 /***********************************************************************
6529 ***********************************************************************/
6531 /* Map enum it_method value to corresponding next_element_from_* function. */
6533 static int (* get_next_element
[NUM_IT_METHODS
]) (struct it
*it
) =
6535 next_element_from_buffer
,
6536 next_element_from_display_vector
,
6537 next_element_from_string
,
6538 next_element_from_c_string
,
6539 next_element_from_image
,
6540 next_element_from_stretch
6543 #define GET_NEXT_DISPLAY_ELEMENT(it) (*get_next_element[(it)->method]) (it)
6546 /* Return 1 iff a character at CHARPOS (and BYTEPOS) is composed
6547 (possibly with the following characters). */
6549 #define CHAR_COMPOSED_P(IT,CHARPOS,BYTEPOS,END_CHARPOS) \
6550 ((IT)->cmp_it.id >= 0 \
6551 || ((IT)->cmp_it.stop_pos == (CHARPOS) \
6552 && composition_reseat_it (&(IT)->cmp_it, CHARPOS, BYTEPOS, \
6553 END_CHARPOS, (IT)->w, \
6554 FACE_FROM_ID ((IT)->f, (IT)->face_id), \
6558 /* Lookup the char-table Vglyphless_char_display for character C (-1
6559 if we want information for no-font case), and return the display
6560 method symbol. By side-effect, update it->what and
6561 it->glyphless_method. This function is called from
6562 get_next_display_element for each character element, and from
6563 x_produce_glyphs when no suitable font was found. */
6566 lookup_glyphless_char_display (int c
, struct it
*it
)
6568 Lisp_Object glyphless_method
= Qnil
;
6570 if (CHAR_TABLE_P (Vglyphless_char_display
)
6571 && CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display
)) >= 1)
6575 glyphless_method
= CHAR_TABLE_REF (Vglyphless_char_display
, c
);
6576 if (CONSP (glyphless_method
))
6577 glyphless_method
= FRAME_WINDOW_P (it
->f
)
6578 ? XCAR (glyphless_method
)
6579 : XCDR (glyphless_method
);
6582 glyphless_method
= XCHAR_TABLE (Vglyphless_char_display
)->extras
[0];
6586 if (NILP (glyphless_method
))
6589 /* The default is to display the character by a proper font. */
6591 /* The default for the no-font case is to display an empty box. */
6592 glyphless_method
= Qempty_box
;
6594 if (EQ (glyphless_method
, Qzero_width
))
6597 return glyphless_method
;
6598 /* This method can't be used for the no-font case. */
6599 glyphless_method
= Qempty_box
;
6601 if (EQ (glyphless_method
, Qthin_space
))
6602 it
->glyphless_method
= GLYPHLESS_DISPLAY_THIN_SPACE
;
6603 else if (EQ (glyphless_method
, Qempty_box
))
6604 it
->glyphless_method
= GLYPHLESS_DISPLAY_EMPTY_BOX
;
6605 else if (EQ (glyphless_method
, Qhex_code
))
6606 it
->glyphless_method
= GLYPHLESS_DISPLAY_HEX_CODE
;
6607 else if (STRINGP (glyphless_method
))
6608 it
->glyphless_method
= GLYPHLESS_DISPLAY_ACRONYM
;
6611 /* Invalid value. We use the default method. */
6612 glyphless_method
= Qnil
;
6615 it
->what
= IT_GLYPHLESS
;
6616 return glyphless_method
;
6619 /* Load IT's display element fields with information about the next
6620 display element from the current position of IT. Value is zero if
6621 end of buffer (or C string) is reached. */
6623 static struct frame
*last_escape_glyph_frame
= NULL
;
6624 static int last_escape_glyph_face_id
= (1 << FACE_ID_BITS
);
6625 static int last_escape_glyph_merged_face_id
= 0;
6627 struct frame
*last_glyphless_glyph_frame
= NULL
;
6628 int last_glyphless_glyph_face_id
= (1 << FACE_ID_BITS
);
6629 int last_glyphless_glyph_merged_face_id
= 0;
6632 get_next_display_element (struct it
*it
)
6634 /* Non-zero means that we found a display element. Zero means that
6635 we hit the end of what we iterate over. Performance note: the
6636 function pointer `method' used here turns out to be faster than
6637 using a sequence of if-statements. */
6641 success_p
= GET_NEXT_DISPLAY_ELEMENT (it
);
6643 if (it
->what
== IT_CHARACTER
)
6645 /* UAX#9, L4: "A character is depicted by a mirrored glyph if
6646 and only if (a) the resolved directionality of that character
6648 /* FIXME: Do we need an exception for characters from display
6650 if (it
->bidi_p
&& it
->bidi_it
.type
== STRONG_R
)
6651 it
->c
= bidi_mirror_char (it
->c
);
6652 /* Map via display table or translate control characters.
6653 IT->c, IT->len etc. have been set to the next character by
6654 the function call above. If we have a display table, and it
6655 contains an entry for IT->c, translate it. Don't do this if
6656 IT->c itself comes from a display table, otherwise we could
6657 end up in an infinite recursion. (An alternative could be to
6658 count the recursion depth of this function and signal an
6659 error when a certain maximum depth is reached.) Is it worth
6661 if (success_p
&& it
->dpvec
== NULL
)
6664 struct charset
*unibyte
= CHARSET_FROM_ID (charset_unibyte
);
6665 int nonascii_space_p
= 0;
6666 int nonascii_hyphen_p
= 0;
6667 int c
= it
->c
; /* This is the character to display. */
6669 if (! it
->multibyte_p
&& ! ASCII_CHAR_P (c
))
6671 eassert (SINGLE_BYTE_CHAR_P (c
));
6672 if (unibyte_display_via_language_environment
)
6674 c
= DECODE_CHAR (unibyte
, c
);
6676 c
= BYTE8_TO_CHAR (it
->c
);
6679 c
= BYTE8_TO_CHAR (it
->c
);
6683 && (dv
= DISP_CHAR_VECTOR (it
->dp
, c
),
6686 struct Lisp_Vector
*v
= XVECTOR (dv
);
6688 /* Return the first character from the display table
6689 entry, if not empty. If empty, don't display the
6690 current character. */
6693 it
->dpvec_char_len
= it
->len
;
6694 it
->dpvec
= v
->contents
;
6695 it
->dpend
= v
->contents
+ v
->header
.size
;
6696 it
->current
.dpvec_index
= 0;
6697 it
->dpvec_face_id
= -1;
6698 it
->saved_face_id
= it
->face_id
;
6699 it
->method
= GET_FROM_DISPLAY_VECTOR
;
6704 set_iterator_to_next (it
, 0);
6709 if (! NILP (lookup_glyphless_char_display (c
, it
)))
6711 if (it
->what
== IT_GLYPHLESS
)
6713 /* Don't display this character. */
6714 set_iterator_to_next (it
, 0);
6718 /* If `nobreak-char-display' is non-nil, we display
6719 non-ASCII spaces and hyphens specially. */
6720 if (! ASCII_CHAR_P (c
) && ! NILP (Vnobreak_char_display
))
6723 nonascii_space_p
= 1;
6724 else if (c
== 0xAD || c
== 0x2010 || c
== 0x2011)
6725 nonascii_hyphen_p
= 1;
6728 /* Translate control characters into `\003' or `^C' form.
6729 Control characters coming from a display table entry are
6730 currently not translated because we use IT->dpvec to hold
6731 the translation. This could easily be changed but I
6732 don't believe that it is worth doing.
6734 The characters handled by `nobreak-char-display' must be
6737 Non-printable characters and raw-byte characters are also
6738 translated to octal form. */
6739 if (((c
< ' ' || c
== 127) /* ASCII control chars */
6740 ? (it
->area
!= TEXT_AREA
6741 /* In mode line, treat \n, \t like other crl chars. */
6744 && (it
->glyph_row
->mode_line_p
|| it
->avoid_cursor_p
))
6745 || (c
!= '\n' && c
!= '\t'))
6747 || nonascii_hyphen_p
6749 || ! CHAR_PRINTABLE_P (c
))))
6751 /* C is a control character, non-ASCII space/hyphen,
6752 raw-byte, or a non-printable character which must be
6753 displayed either as '\003' or as `^C' where the '\\'
6754 and '^' can be defined in the display table. Fill
6755 IT->ctl_chars with glyphs for what we have to
6756 display. Then, set IT->dpvec to these glyphs. */
6763 /* Handle control characters with ^. */
6765 if (ASCII_CHAR_P (c
) && it
->ctl_arrow_p
)
6769 g
= '^'; /* default glyph for Control */
6770 /* Set IT->ctl_chars[0] to the glyph for `^'. */
6772 && (gc
= DISP_CTRL_GLYPH (it
->dp
), GLYPH_CODE_P (gc
)))
6774 g
= GLYPH_CODE_CHAR (gc
);
6775 lface_id
= GLYPH_CODE_FACE (gc
);
6779 face_id
= merge_faces (it
->f
, Qt
, lface_id
, it
->face_id
);
6781 else if (it
->f
== last_escape_glyph_frame
6782 && it
->face_id
== last_escape_glyph_face_id
)
6784 face_id
= last_escape_glyph_merged_face_id
;
6788 /* Merge the escape-glyph face into the current face. */
6789 face_id
= merge_faces (it
->f
, Qescape_glyph
, 0,
6791 last_escape_glyph_frame
= it
->f
;
6792 last_escape_glyph_face_id
= it
->face_id
;
6793 last_escape_glyph_merged_face_id
= face_id
;
6796 XSETINT (it
->ctl_chars
[0], g
);
6797 XSETINT (it
->ctl_chars
[1], c
^ 0100);
6799 goto display_control
;
6802 /* Handle non-ascii space in the mode where it only gets
6805 if (nonascii_space_p
&& EQ (Vnobreak_char_display
, Qt
))
6807 /* Merge `nobreak-space' into the current face. */
6808 face_id
= merge_faces (it
->f
, Qnobreak_space
, 0,
6810 XSETINT (it
->ctl_chars
[0], ' ');
6812 goto display_control
;
6815 /* Handle sequences that start with the "escape glyph". */
6817 /* the default escape glyph is \. */
6818 escape_glyph
= '\\';
6821 && (gc
= DISP_ESCAPE_GLYPH (it
->dp
), GLYPH_CODE_P (gc
)))
6823 escape_glyph
= GLYPH_CODE_CHAR (gc
);
6824 lface_id
= GLYPH_CODE_FACE (gc
);
6828 /* The display table specified a face.
6829 Merge it into face_id and also into escape_glyph. */
6830 face_id
= merge_faces (it
->f
, Qt
, lface_id
,
6833 else if (it
->f
== last_escape_glyph_frame
6834 && it
->face_id
== last_escape_glyph_face_id
)
6836 face_id
= last_escape_glyph_merged_face_id
;
6840 /* Merge the escape-glyph face into the current face. */
6841 face_id
= merge_faces (it
->f
, Qescape_glyph
, 0,
6843 last_escape_glyph_frame
= it
->f
;
6844 last_escape_glyph_face_id
= it
->face_id
;
6845 last_escape_glyph_merged_face_id
= face_id
;
6848 /* Draw non-ASCII hyphen with just highlighting: */
6850 if (nonascii_hyphen_p
&& EQ (Vnobreak_char_display
, Qt
))
6852 XSETINT (it
->ctl_chars
[0], '-');
6854 goto display_control
;
6857 /* Draw non-ASCII space/hyphen with escape glyph: */
6859 if (nonascii_space_p
|| nonascii_hyphen_p
)
6861 XSETINT (it
->ctl_chars
[0], escape_glyph
);
6862 XSETINT (it
->ctl_chars
[1], nonascii_space_p
? ' ' : '-');
6864 goto display_control
;
6871 if (CHAR_BYTE8_P (c
))
6872 /* Display \200 instead of \17777600. */
6873 c
= CHAR_TO_BYTE8 (c
);
6874 len
= sprintf (str
, "%03o", c
);
6876 XSETINT (it
->ctl_chars
[0], escape_glyph
);
6877 for (i
= 0; i
< len
; i
++)
6878 XSETINT (it
->ctl_chars
[i
+ 1], str
[i
]);
6883 /* Set up IT->dpvec and return first character from it. */
6884 it
->dpvec_char_len
= it
->len
;
6885 it
->dpvec
= it
->ctl_chars
;
6886 it
->dpend
= it
->dpvec
+ ctl_len
;
6887 it
->current
.dpvec_index
= 0;
6888 it
->dpvec_face_id
= face_id
;
6889 it
->saved_face_id
= it
->face_id
;
6890 it
->method
= GET_FROM_DISPLAY_VECTOR
;
6894 it
->char_to_display
= c
;
6898 it
->char_to_display
= it
->c
;
6902 /* Adjust face id for a multibyte character. There are no multibyte
6903 character in unibyte text. */
6904 if ((it
->what
== IT_CHARACTER
|| it
->what
== IT_COMPOSITION
)
6907 && FRAME_WINDOW_P (it
->f
))
6909 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
6911 if (it
->what
== IT_COMPOSITION
&& it
->cmp_it
.ch
>= 0)
6913 /* Automatic composition with glyph-string. */
6914 Lisp_Object gstring
= composition_gstring_from_id (it
->cmp_it
.id
);
6916 it
->face_id
= face_for_font (it
->f
, LGSTRING_FONT (gstring
), face
);
6920 ptrdiff_t pos
= (it
->s
? -1
6921 : STRINGP (it
->string
) ? IT_STRING_CHARPOS (*it
)
6922 : IT_CHARPOS (*it
));
6925 if (it
->what
== IT_CHARACTER
)
6926 c
= it
->char_to_display
;
6929 struct composition
*cmp
= composition_table
[it
->cmp_it
.id
];
6933 for (i
= 0; i
< cmp
->glyph_len
; i
++)
6934 /* TAB in a composition means display glyphs with
6935 padding space on the left or right. */
6936 if ((c
= COMPOSITION_GLYPH (cmp
, i
)) != '\t')
6939 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, c
, pos
, it
->string
);
6944 /* Is this character the last one of a run of characters with
6945 box? If yes, set IT->end_of_box_run_p to 1. */
6949 if (it
->method
== GET_FROM_STRING
&& it
->sp
)
6951 int face_id
= underlying_face_id (it
);
6952 struct face
*face
= FACE_FROM_ID (it
->f
, face_id
);
6956 if (face
->box
== FACE_NO_BOX
)
6958 /* If the box comes from face properties in a
6959 display string, check faces in that string. */
6960 int string_face_id
= face_after_it_pos (it
);
6961 it
->end_of_box_run_p
6962 = (FACE_FROM_ID (it
->f
, string_face_id
)->box
6965 /* Otherwise, the box comes from the underlying face.
6966 If this is the last string character displayed, check
6967 the next buffer location. */
6968 else if ((IT_STRING_CHARPOS (*it
) >= SCHARS (it
->string
) - 1)
6969 && (it
->current
.overlay_string_index
6970 == it
->n_overlay_strings
- 1))
6974 struct text_pos pos
= it
->current
.pos
;
6975 INC_TEXT_POS (pos
, it
->multibyte_p
);
6977 next_face_id
= face_at_buffer_position
6978 (it
->w
, CHARPOS (pos
), it
->region_beg_charpos
,
6979 it
->region_end_charpos
, &ignore
,
6980 (IT_CHARPOS (*it
) + TEXT_PROP_DISTANCE_LIMIT
), 0,
6982 it
->end_of_box_run_p
6983 = (FACE_FROM_ID (it
->f
, next_face_id
)->box
6990 int face_id
= face_after_it_pos (it
);
6991 it
->end_of_box_run_p
6992 = (face_id
!= it
->face_id
6993 && FACE_FROM_ID (it
->f
, face_id
)->box
== FACE_NO_BOX
);
6996 /* If we reached the end of the object we've been iterating (e.g., a
6997 display string or an overlay string), and there's something on
6998 IT->stack, proceed with what's on the stack. It doesn't make
6999 sense to return zero if there's unprocessed stuff on the stack,
7000 because otherwise that stuff will never be displayed. */
7001 if (!success_p
&& it
->sp
> 0)
7003 set_iterator_to_next (it
, 0);
7004 success_p
= get_next_display_element (it
);
7007 /* Value is 0 if end of buffer or string reached. */
7012 /* Move IT to the next display element.
7014 RESEAT_P non-zero means if called on a newline in buffer text,
7015 skip to the next visible line start.
7017 Functions get_next_display_element and set_iterator_to_next are
7018 separate because I find this arrangement easier to handle than a
7019 get_next_display_element function that also increments IT's
7020 position. The way it is we can first look at an iterator's current
7021 display element, decide whether it fits on a line, and if it does,
7022 increment the iterator position. The other way around we probably
7023 would either need a flag indicating whether the iterator has to be
7024 incremented the next time, or we would have to implement a
7025 decrement position function which would not be easy to write. */
7028 set_iterator_to_next (struct it
*it
, int reseat_p
)
7030 /* Reset flags indicating start and end of a sequence of characters
7031 with box. Reset them at the start of this function because
7032 moving the iterator to a new position might set them. */
7033 it
->start_of_box_run_p
= it
->end_of_box_run_p
= 0;
7037 case GET_FROM_BUFFER
:
7038 /* The current display element of IT is a character from
7039 current_buffer. Advance in the buffer, and maybe skip over
7040 invisible lines that are so because of selective display. */
7041 if (ITERATOR_AT_END_OF_LINE_P (it
) && reseat_p
)
7042 reseat_at_next_visible_line_start (it
, 0);
7043 else if (it
->cmp_it
.id
>= 0)
7045 /* We are currently getting glyphs from a composition. */
7050 IT_CHARPOS (*it
) += it
->cmp_it
.nchars
;
7051 IT_BYTEPOS (*it
) += it
->cmp_it
.nbytes
;
7052 if (it
->cmp_it
.to
< it
->cmp_it
.nglyphs
)
7054 it
->cmp_it
.from
= it
->cmp_it
.to
;
7059 composition_compute_stop_pos (&it
->cmp_it
, IT_CHARPOS (*it
),
7061 it
->end_charpos
, Qnil
);
7064 else if (! it
->cmp_it
.reversed_p
)
7066 /* Composition created while scanning forward. */
7067 /* Update IT's char/byte positions to point to the first
7068 character of the next grapheme cluster, or to the
7069 character visually after the current composition. */
7070 for (i
= 0; i
< it
->cmp_it
.nchars
; i
++)
7071 bidi_move_to_visually_next (&it
->bidi_it
);
7072 IT_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
7073 IT_CHARPOS (*it
) = it
->bidi_it
.charpos
;
7075 if (it
->cmp_it
.to
< it
->cmp_it
.nglyphs
)
7077 /* Proceed to the next grapheme cluster. */
7078 it
->cmp_it
.from
= it
->cmp_it
.to
;
7082 /* No more grapheme clusters in this composition.
7083 Find the next stop position. */
7084 ptrdiff_t stop
= it
->end_charpos
;
7085 if (it
->bidi_it
.scan_dir
< 0)
7086 /* Now we are scanning backward and don't know
7089 composition_compute_stop_pos (&it
->cmp_it
, IT_CHARPOS (*it
),
7090 IT_BYTEPOS (*it
), stop
, Qnil
);
7095 /* Composition created while scanning backward. */
7096 /* Update IT's char/byte positions to point to the last
7097 character of the previous grapheme cluster, or the
7098 character visually after the current composition. */
7099 for (i
= 0; i
< it
->cmp_it
.nchars
; i
++)
7100 bidi_move_to_visually_next (&it
->bidi_it
);
7101 IT_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
7102 IT_CHARPOS (*it
) = it
->bidi_it
.charpos
;
7103 if (it
->cmp_it
.from
> 0)
7105 /* Proceed to the previous grapheme cluster. */
7106 it
->cmp_it
.to
= it
->cmp_it
.from
;
7110 /* No more grapheme clusters in this composition.
7111 Find the next stop position. */
7112 ptrdiff_t stop
= it
->end_charpos
;
7113 if (it
->bidi_it
.scan_dir
< 0)
7114 /* Now we are scanning backward and don't know
7117 composition_compute_stop_pos (&it
->cmp_it
, IT_CHARPOS (*it
),
7118 IT_BYTEPOS (*it
), stop
, Qnil
);
7124 eassert (it
->len
!= 0);
7128 IT_BYTEPOS (*it
) += it
->len
;
7129 IT_CHARPOS (*it
) += 1;
7133 int prev_scan_dir
= it
->bidi_it
.scan_dir
;
7134 /* If this is a new paragraph, determine its base
7135 direction (a.k.a. its base embedding level). */
7136 if (it
->bidi_it
.new_paragraph
)
7137 bidi_paragraph_init (it
->paragraph_embedding
, &it
->bidi_it
, 0);
7138 bidi_move_to_visually_next (&it
->bidi_it
);
7139 IT_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
7140 IT_CHARPOS (*it
) = it
->bidi_it
.charpos
;
7141 if (prev_scan_dir
!= it
->bidi_it
.scan_dir
)
7143 /* As the scan direction was changed, we must
7144 re-compute the stop position for composition. */
7145 ptrdiff_t stop
= it
->end_charpos
;
7146 if (it
->bidi_it
.scan_dir
< 0)
7148 composition_compute_stop_pos (&it
->cmp_it
, IT_CHARPOS (*it
),
7149 IT_BYTEPOS (*it
), stop
, Qnil
);
7152 eassert (IT_BYTEPOS (*it
) == CHAR_TO_BYTE (IT_CHARPOS (*it
)));
7156 case GET_FROM_C_STRING
:
7157 /* Current display element of IT is from a C string. */
7159 /* If the string position is beyond string's end, it means
7160 next_element_from_c_string is padding the string with
7161 blanks, in which case we bypass the bidi iterator,
7162 because it cannot deal with such virtual characters. */
7163 || IT_CHARPOS (*it
) >= it
->bidi_it
.string
.schars
)
7165 IT_BYTEPOS (*it
) += it
->len
;
7166 IT_CHARPOS (*it
) += 1;
7170 bidi_move_to_visually_next (&it
->bidi_it
);
7171 IT_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
7172 IT_CHARPOS (*it
) = it
->bidi_it
.charpos
;
7176 case GET_FROM_DISPLAY_VECTOR
:
7177 /* Current display element of IT is from a display table entry.
7178 Advance in the display table definition. Reset it to null if
7179 end reached, and continue with characters from buffers/
7181 ++it
->current
.dpvec_index
;
7183 /* Restore face of the iterator to what they were before the
7184 display vector entry (these entries may contain faces). */
7185 it
->face_id
= it
->saved_face_id
;
7187 if (it
->dpvec
+ it
->current
.dpvec_index
>= it
->dpend
)
7189 int recheck_faces
= it
->ellipsis_p
;
7192 it
->method
= GET_FROM_C_STRING
;
7193 else if (STRINGP (it
->string
))
7194 it
->method
= GET_FROM_STRING
;
7197 it
->method
= GET_FROM_BUFFER
;
7198 it
->object
= it
->w
->contents
;
7202 it
->current
.dpvec_index
= -1;
7204 /* Skip over characters which were displayed via IT->dpvec. */
7205 if (it
->dpvec_char_len
< 0)
7206 reseat_at_next_visible_line_start (it
, 1);
7207 else if (it
->dpvec_char_len
> 0)
7209 if (it
->method
== GET_FROM_STRING
7210 && it
->current
.overlay_string_index
>= 0
7211 && it
->n_overlay_strings
> 0)
7212 it
->ignore_overlay_strings_at_pos_p
= 1;
7213 it
->len
= it
->dpvec_char_len
;
7214 set_iterator_to_next (it
, reseat_p
);
7217 /* Maybe recheck faces after display vector */
7219 it
->stop_charpos
= IT_CHARPOS (*it
);
7223 case GET_FROM_STRING
:
7224 /* Current display element is a character from a Lisp string. */
7225 eassert (it
->s
== NULL
&& STRINGP (it
->string
));
7226 /* Don't advance past string end. These conditions are true
7227 when set_iterator_to_next is called at the end of
7228 get_next_display_element, in which case the Lisp string is
7229 already exhausted, and all we want is pop the iterator
7231 if (it
->current
.overlay_string_index
>= 0)
7233 /* This is an overlay string, so there's no padding with
7234 spaces, and the number of characters in the string is
7235 where the string ends. */
7236 if (IT_STRING_CHARPOS (*it
) >= SCHARS (it
->string
))
7237 goto consider_string_end
;
7241 /* Not an overlay string. There could be padding, so test
7242 against it->end_charpos . */
7243 if (IT_STRING_CHARPOS (*it
) >= it
->end_charpos
)
7244 goto consider_string_end
;
7246 if (it
->cmp_it
.id
>= 0)
7252 IT_STRING_CHARPOS (*it
) += it
->cmp_it
.nchars
;
7253 IT_STRING_BYTEPOS (*it
) += it
->cmp_it
.nbytes
;
7254 if (it
->cmp_it
.to
< it
->cmp_it
.nglyphs
)
7255 it
->cmp_it
.from
= it
->cmp_it
.to
;
7259 composition_compute_stop_pos (&it
->cmp_it
,
7260 IT_STRING_CHARPOS (*it
),
7261 IT_STRING_BYTEPOS (*it
),
7262 it
->end_charpos
, it
->string
);
7265 else if (! it
->cmp_it
.reversed_p
)
7267 for (i
= 0; i
< it
->cmp_it
.nchars
; i
++)
7268 bidi_move_to_visually_next (&it
->bidi_it
);
7269 IT_STRING_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
7270 IT_STRING_CHARPOS (*it
) = it
->bidi_it
.charpos
;
7272 if (it
->cmp_it
.to
< it
->cmp_it
.nglyphs
)
7273 it
->cmp_it
.from
= it
->cmp_it
.to
;
7276 ptrdiff_t stop
= it
->end_charpos
;
7277 if (it
->bidi_it
.scan_dir
< 0)
7279 composition_compute_stop_pos (&it
->cmp_it
,
7280 IT_STRING_CHARPOS (*it
),
7281 IT_STRING_BYTEPOS (*it
), stop
,
7287 for (i
= 0; i
< it
->cmp_it
.nchars
; i
++)
7288 bidi_move_to_visually_next (&it
->bidi_it
);
7289 IT_STRING_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
7290 IT_STRING_CHARPOS (*it
) = it
->bidi_it
.charpos
;
7291 if (it
->cmp_it
.from
> 0)
7292 it
->cmp_it
.to
= it
->cmp_it
.from
;
7295 ptrdiff_t stop
= it
->end_charpos
;
7296 if (it
->bidi_it
.scan_dir
< 0)
7298 composition_compute_stop_pos (&it
->cmp_it
,
7299 IT_STRING_CHARPOS (*it
),
7300 IT_STRING_BYTEPOS (*it
), stop
,
7308 /* If the string position is beyond string's end, it
7309 means next_element_from_string is padding the string
7310 with blanks, in which case we bypass the bidi
7311 iterator, because it cannot deal with such virtual
7313 || IT_STRING_CHARPOS (*it
) >= it
->bidi_it
.string
.schars
)
7315 IT_STRING_BYTEPOS (*it
) += it
->len
;
7316 IT_STRING_CHARPOS (*it
) += 1;
7320 int prev_scan_dir
= it
->bidi_it
.scan_dir
;
7322 bidi_move_to_visually_next (&it
->bidi_it
);
7323 IT_STRING_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
7324 IT_STRING_CHARPOS (*it
) = it
->bidi_it
.charpos
;
7325 if (prev_scan_dir
!= it
->bidi_it
.scan_dir
)
7327 ptrdiff_t stop
= it
->end_charpos
;
7329 if (it
->bidi_it
.scan_dir
< 0)
7331 composition_compute_stop_pos (&it
->cmp_it
,
7332 IT_STRING_CHARPOS (*it
),
7333 IT_STRING_BYTEPOS (*it
), stop
,
7339 consider_string_end
:
7341 if (it
->current
.overlay_string_index
>= 0)
7343 /* IT->string is an overlay string. Advance to the
7344 next, if there is one. */
7345 if (IT_STRING_CHARPOS (*it
) >= SCHARS (it
->string
))
7348 next_overlay_string (it
);
7350 setup_for_ellipsis (it
, 0);
7355 /* IT->string is not an overlay string. If we reached
7356 its end, and there is something on IT->stack, proceed
7357 with what is on the stack. This can be either another
7358 string, this time an overlay string, or a buffer. */
7359 if (IT_STRING_CHARPOS (*it
) == SCHARS (it
->string
)
7363 if (it
->method
== GET_FROM_STRING
)
7364 goto consider_string_end
;
7369 case GET_FROM_IMAGE
:
7370 case GET_FROM_STRETCH
:
7371 /* The position etc with which we have to proceed are on
7372 the stack. The position may be at the end of a string,
7373 if the `display' property takes up the whole string. */
7374 eassert (it
->sp
> 0);
7376 if (it
->method
== GET_FROM_STRING
)
7377 goto consider_string_end
;
7381 /* There are no other methods defined, so this should be a bug. */
7385 eassert (it
->method
!= GET_FROM_STRING
7386 || (STRINGP (it
->string
)
7387 && IT_STRING_CHARPOS (*it
) >= 0));
7390 /* Load IT's display element fields with information about the next
7391 display element which comes from a display table entry or from the
7392 result of translating a control character to one of the forms `^C'
7395 IT->dpvec holds the glyphs to return as characters.
7396 IT->saved_face_id holds the face id before the display vector--it
7397 is restored into IT->face_id in set_iterator_to_next. */
7400 next_element_from_display_vector (struct it
*it
)
7405 eassert (it
->dpvec
&& it
->current
.dpvec_index
>= 0);
7407 it
->face_id
= it
->saved_face_id
;
7409 /* KFS: This code used to check ip->dpvec[0] instead of the current element.
7410 That seemed totally bogus - so I changed it... */
7411 gc
= it
->dpvec
[it
->current
.dpvec_index
];
7413 if (GLYPH_CODE_P (gc
))
7415 it
->c
= GLYPH_CODE_CHAR (gc
);
7416 it
->len
= CHAR_BYTES (it
->c
);
7418 /* The entry may contain a face id to use. Such a face id is
7419 the id of a Lisp face, not a realized face. A face id of
7420 zero means no face is specified. */
7421 if (it
->dpvec_face_id
>= 0)
7422 it
->face_id
= it
->dpvec_face_id
;
7425 int lface_id
= GLYPH_CODE_FACE (gc
);
7427 it
->face_id
= merge_faces (it
->f
, Qt
, lface_id
,
7432 /* Display table entry is invalid. Return a space. */
7433 it
->c
= ' ', it
->len
= 1;
7435 /* Don't change position and object of the iterator here. They are
7436 still the values of the character that had this display table
7437 entry or was translated, and that's what we want. */
7438 it
->what
= IT_CHARACTER
;
7442 /* Get the first element of string/buffer in the visual order, after
7443 being reseated to a new position in a string or a buffer. */
7445 get_visually_first_element (struct it
*it
)
7447 int string_p
= STRINGP (it
->string
) || it
->s
;
7448 ptrdiff_t eob
= (string_p
? it
->bidi_it
.string
.schars
: ZV
);
7449 ptrdiff_t bob
= (string_p
? 0 : BEGV
);
7451 if (STRINGP (it
->string
))
7453 it
->bidi_it
.charpos
= IT_STRING_CHARPOS (*it
);
7454 it
->bidi_it
.bytepos
= IT_STRING_BYTEPOS (*it
);
7458 it
->bidi_it
.charpos
= IT_CHARPOS (*it
);
7459 it
->bidi_it
.bytepos
= IT_BYTEPOS (*it
);
7462 if (it
->bidi_it
.charpos
== eob
)
7464 /* Nothing to do, but reset the FIRST_ELT flag, like
7465 bidi_paragraph_init does, because we are not going to
7467 it
->bidi_it
.first_elt
= 0;
7469 else if (it
->bidi_it
.charpos
== bob
7471 && (FETCH_CHAR (it
->bidi_it
.bytepos
- 1) == '\n'
7472 || FETCH_CHAR (it
->bidi_it
.bytepos
) == '\n')))
7474 /* If we are at the beginning of a line/string, we can produce
7475 the next element right away. */
7476 bidi_paragraph_init (it
->paragraph_embedding
, &it
->bidi_it
, 1);
7477 bidi_move_to_visually_next (&it
->bidi_it
);
7481 ptrdiff_t orig_bytepos
= it
->bidi_it
.bytepos
;
7483 /* We need to prime the bidi iterator starting at the line's or
7484 string's beginning, before we will be able to produce the
7487 it
->bidi_it
.charpos
= it
->bidi_it
.bytepos
= 0;
7489 it
->bidi_it
.charpos
= find_newline_no_quit (IT_CHARPOS (*it
),
7490 IT_BYTEPOS (*it
), -1,
7491 &it
->bidi_it
.bytepos
);
7492 bidi_paragraph_init (it
->paragraph_embedding
, &it
->bidi_it
, 1);
7495 /* Now return to buffer/string position where we were asked
7496 to get the next display element, and produce that. */
7497 bidi_move_to_visually_next (&it
->bidi_it
);
7499 while (it
->bidi_it
.bytepos
!= orig_bytepos
7500 && it
->bidi_it
.charpos
< eob
);
7503 /* Adjust IT's position information to where we ended up. */
7504 if (STRINGP (it
->string
))
7506 IT_STRING_CHARPOS (*it
) = it
->bidi_it
.charpos
;
7507 IT_STRING_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
7511 IT_CHARPOS (*it
) = it
->bidi_it
.charpos
;
7512 IT_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
7515 if (STRINGP (it
->string
) || !it
->s
)
7517 ptrdiff_t stop
, charpos
, bytepos
;
7519 if (STRINGP (it
->string
))
7522 stop
= SCHARS (it
->string
);
7523 if (stop
> it
->end_charpos
)
7524 stop
= it
->end_charpos
;
7525 charpos
= IT_STRING_CHARPOS (*it
);
7526 bytepos
= IT_STRING_BYTEPOS (*it
);
7530 stop
= it
->end_charpos
;
7531 charpos
= IT_CHARPOS (*it
);
7532 bytepos
= IT_BYTEPOS (*it
);
7534 if (it
->bidi_it
.scan_dir
< 0)
7536 composition_compute_stop_pos (&it
->cmp_it
, charpos
, bytepos
, stop
,
7541 /* Load IT with the next display element from Lisp string IT->string.
7542 IT->current.string_pos is the current position within the string.
7543 If IT->current.overlay_string_index >= 0, the Lisp string is an
7547 next_element_from_string (struct it
*it
)
7549 struct text_pos position
;
7551 eassert (STRINGP (it
->string
));
7552 eassert (!it
->bidi_p
|| EQ (it
->string
, it
->bidi_it
.string
.lstring
));
7553 eassert (IT_STRING_CHARPOS (*it
) >= 0);
7554 position
= it
->current
.string_pos
;
7556 /* With bidi reordering, the character to display might not be the
7557 character at IT_STRING_CHARPOS. BIDI_IT.FIRST_ELT non-zero means
7558 that we were reseat()ed to a new string, whose paragraph
7559 direction is not known. */
7560 if (it
->bidi_p
&& it
->bidi_it
.first_elt
)
7562 get_visually_first_element (it
);
7563 SET_TEXT_POS (position
, IT_STRING_CHARPOS (*it
), IT_STRING_BYTEPOS (*it
));
7566 /* Time to check for invisible text? */
7567 if (IT_STRING_CHARPOS (*it
) < it
->end_charpos
)
7569 if (IT_STRING_CHARPOS (*it
) >= it
->stop_charpos
)
7572 || BIDI_AT_BASE_LEVEL (it
->bidi_it
)
7573 || IT_STRING_CHARPOS (*it
) == it
->stop_charpos
))
7575 /* With bidi non-linear iteration, we could find
7576 ourselves far beyond the last computed stop_charpos,
7577 with several other stop positions in between that we
7578 missed. Scan them all now, in buffer's logical
7579 order, until we find and handle the last stop_charpos
7580 that precedes our current position. */
7581 handle_stop_backwards (it
, it
->stop_charpos
);
7582 return GET_NEXT_DISPLAY_ELEMENT (it
);
7588 /* Take note of the stop position we just moved
7589 across, for when we will move back across it. */
7590 it
->prev_stop
= it
->stop_charpos
;
7591 /* If we are at base paragraph embedding level, take
7592 note of the last stop position seen at this
7594 if (BIDI_AT_BASE_LEVEL (it
->bidi_it
))
7595 it
->base_level_stop
= it
->stop_charpos
;
7599 /* Since a handler may have changed IT->method, we must
7601 return GET_NEXT_DISPLAY_ELEMENT (it
);
7605 /* If we are before prev_stop, we may have overstepped
7606 on our way backwards a stop_pos, and if so, we need
7607 to handle that stop_pos. */
7608 && IT_STRING_CHARPOS (*it
) < it
->prev_stop
7609 /* We can sometimes back up for reasons that have nothing
7610 to do with bidi reordering. E.g., compositions. The
7611 code below is only needed when we are above the base
7612 embedding level, so test for that explicitly. */
7613 && !BIDI_AT_BASE_LEVEL (it
->bidi_it
))
7615 /* If we lost track of base_level_stop, we have no better
7616 place for handle_stop_backwards to start from than string
7617 beginning. This happens, e.g., when we were reseated to
7618 the previous screenful of text by vertical-motion. */
7619 if (it
->base_level_stop
<= 0
7620 || IT_STRING_CHARPOS (*it
) < it
->base_level_stop
)
7621 it
->base_level_stop
= 0;
7622 handle_stop_backwards (it
, it
->base_level_stop
);
7623 return GET_NEXT_DISPLAY_ELEMENT (it
);
7627 if (it
->current
.overlay_string_index
>= 0)
7629 /* Get the next character from an overlay string. In overlay
7630 strings, there is no field width or padding with spaces to
7632 if (IT_STRING_CHARPOS (*it
) >= SCHARS (it
->string
))
7637 else if (CHAR_COMPOSED_P (it
, IT_STRING_CHARPOS (*it
),
7638 IT_STRING_BYTEPOS (*it
),
7639 it
->bidi_it
.scan_dir
< 0
7641 : SCHARS (it
->string
))
7642 && next_element_from_composition (it
))
7646 else if (STRING_MULTIBYTE (it
->string
))
7648 const unsigned char *s
= (SDATA (it
->string
)
7649 + IT_STRING_BYTEPOS (*it
));
7650 it
->c
= string_char_and_length (s
, &it
->len
);
7654 it
->c
= SREF (it
->string
, IT_STRING_BYTEPOS (*it
));
7660 /* Get the next character from a Lisp string that is not an
7661 overlay string. Such strings come from the mode line, for
7662 example. We may have to pad with spaces, or truncate the
7663 string. See also next_element_from_c_string. */
7664 if (IT_STRING_CHARPOS (*it
) >= it
->end_charpos
)
7669 else if (IT_STRING_CHARPOS (*it
) >= it
->string_nchars
)
7671 /* Pad with spaces. */
7672 it
->c
= ' ', it
->len
= 1;
7673 CHARPOS (position
) = BYTEPOS (position
) = -1;
7675 else if (CHAR_COMPOSED_P (it
, IT_STRING_CHARPOS (*it
),
7676 IT_STRING_BYTEPOS (*it
),
7677 it
->bidi_it
.scan_dir
< 0
7679 : it
->string_nchars
)
7680 && next_element_from_composition (it
))
7684 else if (STRING_MULTIBYTE (it
->string
))
7686 const unsigned char *s
= (SDATA (it
->string
)
7687 + IT_STRING_BYTEPOS (*it
));
7688 it
->c
= string_char_and_length (s
, &it
->len
);
7692 it
->c
= SREF (it
->string
, IT_STRING_BYTEPOS (*it
));
7697 /* Record what we have and where it came from. */
7698 it
->what
= IT_CHARACTER
;
7699 it
->object
= it
->string
;
7700 it
->position
= position
;
7705 /* Load IT with next display element from C string IT->s.
7706 IT->string_nchars is the maximum number of characters to return
7707 from the string. IT->end_charpos may be greater than
7708 IT->string_nchars when this function is called, in which case we
7709 may have to return padding spaces. Value is zero if end of string
7710 reached, including padding spaces. */
7713 next_element_from_c_string (struct it
*it
)
7718 eassert (!it
->bidi_p
|| it
->s
== it
->bidi_it
.string
.s
);
7719 it
->what
= IT_CHARACTER
;
7720 BYTEPOS (it
->position
) = CHARPOS (it
->position
) = 0;
7723 /* With bidi reordering, the character to display might not be the
7724 character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that
7725 we were reseated to a new string, whose paragraph direction is
7727 if (it
->bidi_p
&& it
->bidi_it
.first_elt
)
7728 get_visually_first_element (it
);
7730 /* IT's position can be greater than IT->string_nchars in case a
7731 field width or precision has been specified when the iterator was
7733 if (IT_CHARPOS (*it
) >= it
->end_charpos
)
7735 /* End of the game. */
7739 else if (IT_CHARPOS (*it
) >= it
->string_nchars
)
7741 /* Pad with spaces. */
7742 it
->c
= ' ', it
->len
= 1;
7743 BYTEPOS (it
->position
) = CHARPOS (it
->position
) = -1;
7745 else if (it
->multibyte_p
)
7746 it
->c
= string_char_and_length (it
->s
+ IT_BYTEPOS (*it
), &it
->len
);
7748 it
->c
= it
->s
[IT_BYTEPOS (*it
)], it
->len
= 1;
7754 /* Set up IT to return characters from an ellipsis, if appropriate.
7755 The definition of the ellipsis glyphs may come from a display table
7756 entry. This function fills IT with the first glyph from the
7757 ellipsis if an ellipsis is to be displayed. */
7760 next_element_from_ellipsis (struct it
*it
)
7762 if (it
->selective_display_ellipsis_p
)
7763 setup_for_ellipsis (it
, it
->len
);
7766 /* The face at the current position may be different from the
7767 face we find after the invisible text. Remember what it
7768 was in IT->saved_face_id, and signal that it's there by
7769 setting face_before_selective_p. */
7770 it
->saved_face_id
= it
->face_id
;
7771 it
->method
= GET_FROM_BUFFER
;
7772 it
->object
= it
->w
->contents
;
7773 reseat_at_next_visible_line_start (it
, 1);
7774 it
->face_before_selective_p
= 1;
7777 return GET_NEXT_DISPLAY_ELEMENT (it
);
7781 /* Deliver an image display element. The iterator IT is already
7782 filled with image information (done in handle_display_prop). Value
7787 next_element_from_image (struct it
*it
)
7789 it
->what
= IT_IMAGE
;
7790 it
->ignore_overlay_strings_at_pos_p
= 0;
7795 /* Fill iterator IT with next display element from a stretch glyph
7796 property. IT->object is the value of the text property. Value is
7800 next_element_from_stretch (struct it
*it
)
7802 it
->what
= IT_STRETCH
;
7806 /* Scan backwards from IT's current position until we find a stop
7807 position, or until BEGV. This is called when we find ourself
7808 before both the last known prev_stop and base_level_stop while
7809 reordering bidirectional text. */
7812 compute_stop_pos_backwards (struct it
*it
)
7814 const int SCAN_BACK_LIMIT
= 1000;
7815 struct text_pos pos
;
7816 struct display_pos save_current
= it
->current
;
7817 struct text_pos save_position
= it
->position
;
7818 ptrdiff_t charpos
= IT_CHARPOS (*it
);
7819 ptrdiff_t where_we_are
= charpos
;
7820 ptrdiff_t save_stop_pos
= it
->stop_charpos
;
7821 ptrdiff_t save_end_pos
= it
->end_charpos
;
7823 eassert (NILP (it
->string
) && !it
->s
);
7824 eassert (it
->bidi_p
);
7828 it
->end_charpos
= min (charpos
+ 1, ZV
);
7829 charpos
= max (charpos
- SCAN_BACK_LIMIT
, BEGV
);
7830 SET_TEXT_POS (pos
, charpos
, CHAR_TO_BYTE (charpos
));
7831 reseat_1 (it
, pos
, 0);
7832 compute_stop_pos (it
);
7833 /* We must advance forward, right? */
7834 if (it
->stop_charpos
<= charpos
)
7837 while (charpos
> BEGV
&& it
->stop_charpos
>= it
->end_charpos
);
7839 if (it
->stop_charpos
<= where_we_are
)
7840 it
->prev_stop
= it
->stop_charpos
;
7842 it
->prev_stop
= BEGV
;
7844 it
->current
= save_current
;
7845 it
->position
= save_position
;
7846 it
->stop_charpos
= save_stop_pos
;
7847 it
->end_charpos
= save_end_pos
;
7850 /* Scan forward from CHARPOS in the current buffer/string, until we
7851 find a stop position > current IT's position. Then handle the stop
7852 position before that. This is called when we bump into a stop
7853 position while reordering bidirectional text. CHARPOS should be
7854 the last previously processed stop_pos (or BEGV/0, if none were
7855 processed yet) whose position is less that IT's current
7859 handle_stop_backwards (struct it
*it
, ptrdiff_t charpos
)
7861 int bufp
= !STRINGP (it
->string
);
7862 ptrdiff_t where_we_are
= (bufp
? IT_CHARPOS (*it
) : IT_STRING_CHARPOS (*it
));
7863 struct display_pos save_current
= it
->current
;
7864 struct text_pos save_position
= it
->position
;
7865 struct text_pos pos1
;
7866 ptrdiff_t next_stop
;
7868 /* Scan in strict logical order. */
7869 eassert (it
->bidi_p
);
7873 it
->prev_stop
= charpos
;
7876 SET_TEXT_POS (pos1
, charpos
, CHAR_TO_BYTE (charpos
));
7877 reseat_1 (it
, pos1
, 0);
7880 it
->current
.string_pos
= string_pos (charpos
, it
->string
);
7881 compute_stop_pos (it
);
7882 /* We must advance forward, right? */
7883 if (it
->stop_charpos
<= it
->prev_stop
)
7885 charpos
= it
->stop_charpos
;
7887 while (charpos
<= where_we_are
);
7890 it
->current
= save_current
;
7891 it
->position
= save_position
;
7892 next_stop
= it
->stop_charpos
;
7893 it
->stop_charpos
= it
->prev_stop
;
7895 it
->stop_charpos
= next_stop
;
7898 /* Load IT with the next display element from current_buffer. Value
7899 is zero if end of buffer reached. IT->stop_charpos is the next
7900 position at which to stop and check for text properties or buffer
7904 next_element_from_buffer (struct it
*it
)
7908 eassert (IT_CHARPOS (*it
) >= BEGV
);
7909 eassert (NILP (it
->string
) && !it
->s
);
7910 eassert (!it
->bidi_p
7911 || (EQ (it
->bidi_it
.string
.lstring
, Qnil
)
7912 && it
->bidi_it
.string
.s
== NULL
));
7914 /* With bidi reordering, the character to display might not be the
7915 character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that
7916 we were reseat()ed to a new buffer position, which is potentially
7917 a different paragraph. */
7918 if (it
->bidi_p
&& it
->bidi_it
.first_elt
)
7920 get_visually_first_element (it
);
7921 SET_TEXT_POS (it
->position
, IT_CHARPOS (*it
), IT_BYTEPOS (*it
));
7924 if (IT_CHARPOS (*it
) >= it
->stop_charpos
)
7926 if (IT_CHARPOS (*it
) >= it
->end_charpos
)
7928 int overlay_strings_follow_p
;
7930 /* End of the game, except when overlay strings follow that
7931 haven't been returned yet. */
7932 if (it
->overlay_strings_at_end_processed_p
)
7933 overlay_strings_follow_p
= 0;
7936 it
->overlay_strings_at_end_processed_p
= 1;
7937 overlay_strings_follow_p
= get_overlay_strings (it
, 0);
7940 if (overlay_strings_follow_p
)
7941 success_p
= GET_NEXT_DISPLAY_ELEMENT (it
);
7945 it
->position
= it
->current
.pos
;
7949 else if (!(!it
->bidi_p
7950 || BIDI_AT_BASE_LEVEL (it
->bidi_it
)
7951 || IT_CHARPOS (*it
) == it
->stop_charpos
))
7953 /* With bidi non-linear iteration, we could find ourselves
7954 far beyond the last computed stop_charpos, with several
7955 other stop positions in between that we missed. Scan
7956 them all now, in buffer's logical order, until we find
7957 and handle the last stop_charpos that precedes our
7958 current position. */
7959 handle_stop_backwards (it
, it
->stop_charpos
);
7960 return GET_NEXT_DISPLAY_ELEMENT (it
);
7966 /* Take note of the stop position we just moved across,
7967 for when we will move back across it. */
7968 it
->prev_stop
= it
->stop_charpos
;
7969 /* If we are at base paragraph embedding level, take
7970 note of the last stop position seen at this
7972 if (BIDI_AT_BASE_LEVEL (it
->bidi_it
))
7973 it
->base_level_stop
= it
->stop_charpos
;
7976 return GET_NEXT_DISPLAY_ELEMENT (it
);
7980 /* If we are before prev_stop, we may have overstepped on
7981 our way backwards a stop_pos, and if so, we need to
7982 handle that stop_pos. */
7983 && IT_CHARPOS (*it
) < it
->prev_stop
7984 /* We can sometimes back up for reasons that have nothing
7985 to do with bidi reordering. E.g., compositions. The
7986 code below is only needed when we are above the base
7987 embedding level, so test for that explicitly. */
7988 && !BIDI_AT_BASE_LEVEL (it
->bidi_it
))
7990 if (it
->base_level_stop
<= 0
7991 || IT_CHARPOS (*it
) < it
->base_level_stop
)
7993 /* If we lost track of base_level_stop, we need to find
7994 prev_stop by looking backwards. This happens, e.g., when
7995 we were reseated to the previous screenful of text by
7997 it
->base_level_stop
= BEGV
;
7998 compute_stop_pos_backwards (it
);
7999 handle_stop_backwards (it
, it
->prev_stop
);
8002 handle_stop_backwards (it
, it
->base_level_stop
);
8003 return GET_NEXT_DISPLAY_ELEMENT (it
);
8007 /* No face changes, overlays etc. in sight, so just return a
8008 character from current_buffer. */
8012 /* Maybe run the redisplay end trigger hook. Performance note:
8013 This doesn't seem to cost measurable time. */
8014 if (it
->redisplay_end_trigger_charpos
8016 && IT_CHARPOS (*it
) >= it
->redisplay_end_trigger_charpos
)
8017 run_redisplay_end_trigger_hook (it
);
8019 stop
= it
->bidi_it
.scan_dir
< 0 ? -1 : it
->end_charpos
;
8020 if (CHAR_COMPOSED_P (it
, IT_CHARPOS (*it
), IT_BYTEPOS (*it
),
8022 && next_element_from_composition (it
))
8027 /* Get the next character, maybe multibyte. */
8028 p
= BYTE_POS_ADDR (IT_BYTEPOS (*it
));
8029 if (it
->multibyte_p
&& !ASCII_BYTE_P (*p
))
8030 it
->c
= STRING_CHAR_AND_LENGTH (p
, it
->len
);
8032 it
->c
= *p
, it
->len
= 1;
8034 /* Record what we have and where it came from. */
8035 it
->what
= IT_CHARACTER
;
8036 it
->object
= it
->w
->contents
;
8037 it
->position
= it
->current
.pos
;
8039 /* Normally we return the character found above, except when we
8040 really want to return an ellipsis for selective display. */
8045 /* A value of selective > 0 means hide lines indented more
8046 than that number of columns. */
8047 if (it
->selective
> 0
8048 && IT_CHARPOS (*it
) + 1 < ZV
8049 && indented_beyond_p (IT_CHARPOS (*it
) + 1,
8050 IT_BYTEPOS (*it
) + 1,
8053 success_p
= next_element_from_ellipsis (it
);
8054 it
->dpvec_char_len
= -1;
8057 else if (it
->c
== '\r' && it
->selective
== -1)
8059 /* A value of selective == -1 means that everything from the
8060 CR to the end of the line is invisible, with maybe an
8061 ellipsis displayed for it. */
8062 success_p
= next_element_from_ellipsis (it
);
8063 it
->dpvec_char_len
= -1;
8068 /* Value is zero if end of buffer reached. */
8069 eassert (!success_p
|| it
->what
!= IT_CHARACTER
|| it
->len
> 0);
8074 /* Run the redisplay end trigger hook for IT. */
8077 run_redisplay_end_trigger_hook (struct it
*it
)
8079 Lisp_Object args
[3];
8081 /* IT->glyph_row should be non-null, i.e. we should be actually
8082 displaying something, or otherwise we should not run the hook. */
8083 eassert (it
->glyph_row
);
8085 /* Set up hook arguments. */
8086 args
[0] = Qredisplay_end_trigger_functions
;
8087 args
[1] = it
->window
;
8088 XSETINT (args
[2], it
->redisplay_end_trigger_charpos
);
8089 it
->redisplay_end_trigger_charpos
= 0;
8091 /* Since we are *trying* to run these functions, don't try to run
8092 them again, even if they get an error. */
8093 wset_redisplay_end_trigger (it
->w
, Qnil
);
8094 Frun_hook_with_args (3, args
);
8096 /* Notice if it changed the face of the character we are on. */
8097 handle_face_prop (it
);
8101 /* Deliver a composition display element. Unlike the other
8102 next_element_from_XXX, this function is not registered in the array
8103 get_next_element[]. It is called from next_element_from_buffer and
8104 next_element_from_string when necessary. */
8107 next_element_from_composition (struct it
*it
)
8109 it
->what
= IT_COMPOSITION
;
8110 it
->len
= it
->cmp_it
.nbytes
;
8111 if (STRINGP (it
->string
))
8115 IT_STRING_CHARPOS (*it
) += it
->cmp_it
.nchars
;
8116 IT_STRING_BYTEPOS (*it
) += it
->cmp_it
.nbytes
;
8119 it
->position
= it
->current
.string_pos
;
8120 it
->object
= it
->string
;
8121 it
->c
= composition_update_it (&it
->cmp_it
, IT_STRING_CHARPOS (*it
),
8122 IT_STRING_BYTEPOS (*it
), it
->string
);
8128 IT_CHARPOS (*it
) += it
->cmp_it
.nchars
;
8129 IT_BYTEPOS (*it
) += it
->cmp_it
.nbytes
;
8132 if (it
->bidi_it
.new_paragraph
)
8133 bidi_paragraph_init (it
->paragraph_embedding
, &it
->bidi_it
, 0);
8134 /* Resync the bidi iterator with IT's new position.
8135 FIXME: this doesn't support bidirectional text. */
8136 while (it
->bidi_it
.charpos
< IT_CHARPOS (*it
))
8137 bidi_move_to_visually_next (&it
->bidi_it
);
8141 it
->position
= it
->current
.pos
;
8142 it
->object
= it
->w
->contents
;
8143 it
->c
= composition_update_it (&it
->cmp_it
, IT_CHARPOS (*it
),
8144 IT_BYTEPOS (*it
), Qnil
);
8151 /***********************************************************************
8152 Moving an iterator without producing glyphs
8153 ***********************************************************************/
8155 /* Check if iterator is at a position corresponding to a valid buffer
8156 position after some move_it_ call. */
8158 #define IT_POS_VALID_AFTER_MOVE_P(it) \
8159 ((it)->method == GET_FROM_STRING \
8160 ? IT_STRING_CHARPOS (*it) == 0 \
8164 /* Move iterator IT to a specified buffer or X position within one
8165 line on the display without producing glyphs.
8167 OP should be a bit mask including some or all of these bits:
8168 MOVE_TO_X: Stop upon reaching x-position TO_X.
8169 MOVE_TO_POS: Stop upon reaching buffer or string position TO_CHARPOS.
8170 Regardless of OP's value, stop upon reaching the end of the display line.
8172 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
8173 This means, in particular, that TO_X includes window's horizontal
8176 The return value has several possible values that
8177 say what condition caused the scan to stop:
8179 MOVE_POS_MATCH_OR_ZV
8180 - when TO_POS or ZV was reached.
8183 -when TO_X was reached before TO_POS or ZV were reached.
8186 - when we reached the end of the display area and the line must
8190 - when we reached the end of the display area and the line is
8194 - when we stopped at a line end, i.e. a newline or a CR and selective
8197 static enum move_it_result
8198 move_it_in_display_line_to (struct it
*it
,
8199 ptrdiff_t to_charpos
, int to_x
,
8200 enum move_operation_enum op
)
8202 enum move_it_result result
= MOVE_UNDEFINED
;
8203 struct glyph_row
*saved_glyph_row
;
8204 struct it wrap_it
, atpos_it
, atx_it
, ppos_it
;
8205 void *wrap_data
= NULL
, *atpos_data
= NULL
, *atx_data
= NULL
;
8206 void *ppos_data
= NULL
;
8208 enum it_method prev_method
= it
->method
;
8209 ptrdiff_t prev_pos
= IT_CHARPOS (*it
);
8210 int saw_smaller_pos
= prev_pos
< to_charpos
;
8212 /* Don't produce glyphs in produce_glyphs. */
8213 saved_glyph_row
= it
->glyph_row
;
8214 it
->glyph_row
= NULL
;
8216 /* Use wrap_it to save a copy of IT wherever a word wrap could
8217 occur. Use atpos_it to save a copy of IT at the desired buffer
8218 position, if found, so that we can scan ahead and check if the
8219 word later overshoots the window edge. Use atx_it similarly, for
8225 /* Use ppos_it under bidi reordering to save a copy of IT for the
8226 position > CHARPOS that is the closest to CHARPOS. We restore
8227 that position in IT when we have scanned the entire display line
8228 without finding a match for CHARPOS and all the character
8229 positions are greater than CHARPOS. */
8232 SAVE_IT (ppos_it
, *it
, ppos_data
);
8233 SET_TEXT_POS (ppos_it
.current
.pos
, ZV
, ZV_BYTE
);
8234 if ((op
& MOVE_TO_POS
) && IT_CHARPOS (*it
) >= to_charpos
)
8235 SAVE_IT (ppos_it
, *it
, ppos_data
);
8238 #define BUFFER_POS_REACHED_P() \
8239 ((op & MOVE_TO_POS) != 0 \
8240 && BUFFERP (it->object) \
8241 && (IT_CHARPOS (*it) == to_charpos \
8243 || BIDI_AT_BASE_LEVEL (it->bidi_it)) \
8244 && IT_CHARPOS (*it) > to_charpos) \
8245 || (it->what == IT_COMPOSITION \
8246 && ((IT_CHARPOS (*it) > to_charpos \
8247 && to_charpos >= it->cmp_it.charpos) \
8248 || (IT_CHARPOS (*it) < to_charpos \
8249 && to_charpos <= it->cmp_it.charpos)))) \
8250 && (it->method == GET_FROM_BUFFER \
8251 || (it->method == GET_FROM_DISPLAY_VECTOR \
8252 && it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
8254 /* If there's a line-/wrap-prefix, handle it. */
8255 if (it
->hpos
== 0 && it
->method
== GET_FROM_BUFFER
8256 && it
->current_y
< it
->last_visible_y
)
8257 handle_line_prefix (it
);
8259 if (IT_CHARPOS (*it
) < CHARPOS (this_line_min_pos
))
8260 SET_TEXT_POS (this_line_min_pos
, IT_CHARPOS (*it
), IT_BYTEPOS (*it
));
8264 int x
, i
, ascent
= 0, descent
= 0;
8266 /* Utility macro to reset an iterator with x, ascent, and descent. */
8267 #define IT_RESET_X_ASCENT_DESCENT(IT) \
8268 ((IT)->current_x = x, (IT)->max_ascent = ascent, \
8269 (IT)->max_descent = descent)
8271 /* Stop if we move beyond TO_CHARPOS (after an image or a
8272 display string or stretch glyph). */
8273 if ((op
& MOVE_TO_POS
) != 0
8274 && BUFFERP (it
->object
)
8275 && it
->method
== GET_FROM_BUFFER
8277 /* When the iterator is at base embedding level, we
8278 are guaranteed that characters are delivered for
8279 display in strictly increasing order of their
8280 buffer positions. */
8281 || BIDI_AT_BASE_LEVEL (it
->bidi_it
))
8282 && IT_CHARPOS (*it
) > to_charpos
)
8284 && (prev_method
== GET_FROM_IMAGE
8285 || prev_method
== GET_FROM_STRETCH
8286 || prev_method
== GET_FROM_STRING
)
8287 /* Passed TO_CHARPOS from left to right. */
8288 && ((prev_pos
< to_charpos
8289 && IT_CHARPOS (*it
) > to_charpos
)
8290 /* Passed TO_CHARPOS from right to left. */
8291 || (prev_pos
> to_charpos
8292 && IT_CHARPOS (*it
) < to_charpos
)))))
8294 if (it
->line_wrap
!= WORD_WRAP
|| wrap_it
.sp
< 0)
8296 result
= MOVE_POS_MATCH_OR_ZV
;
8299 else if (it
->line_wrap
== WORD_WRAP
&& atpos_it
.sp
< 0)
8300 /* If wrap_it is valid, the current position might be in a
8301 word that is wrapped. So, save the iterator in
8302 atpos_it and continue to see if wrapping happens. */
8303 SAVE_IT (atpos_it
, *it
, atpos_data
);
8306 /* Stop when ZV reached.
8307 We used to stop here when TO_CHARPOS reached as well, but that is
8308 too soon if this glyph does not fit on this line. So we handle it
8309 explicitly below. */
8310 if (!get_next_display_element (it
))
8312 result
= MOVE_POS_MATCH_OR_ZV
;
8316 if (it
->line_wrap
== TRUNCATE
)
8318 if (BUFFER_POS_REACHED_P ())
8320 result
= MOVE_POS_MATCH_OR_ZV
;
8326 if (it
->line_wrap
== WORD_WRAP
)
8328 if (IT_DISPLAYING_WHITESPACE (it
))
8332 /* We have reached a glyph that follows one or more
8333 whitespace characters. If the position is
8334 already found, we are done. */
8335 if (atpos_it
.sp
>= 0)
8337 RESTORE_IT (it
, &atpos_it
, atpos_data
);
8338 result
= MOVE_POS_MATCH_OR_ZV
;
8343 RESTORE_IT (it
, &atx_it
, atx_data
);
8344 result
= MOVE_X_REACHED
;
8347 /* Otherwise, we can wrap here. */
8348 SAVE_IT (wrap_it
, *it
, wrap_data
);
8354 /* Remember the line height for the current line, in case
8355 the next element doesn't fit on the line. */
8356 ascent
= it
->max_ascent
;
8357 descent
= it
->max_descent
;
8359 /* The call to produce_glyphs will get the metrics of the
8360 display element IT is loaded with. Record the x-position
8361 before this display element, in case it doesn't fit on the
8365 PRODUCE_GLYPHS (it
);
8367 if (it
->area
!= TEXT_AREA
)
8369 prev_method
= it
->method
;
8370 if (it
->method
== GET_FROM_BUFFER
)
8371 prev_pos
= IT_CHARPOS (*it
);
8372 set_iterator_to_next (it
, 1);
8373 if (IT_CHARPOS (*it
) < CHARPOS (this_line_min_pos
))
8374 SET_TEXT_POS (this_line_min_pos
,
8375 IT_CHARPOS (*it
), IT_BYTEPOS (*it
));
8377 && (op
& MOVE_TO_POS
)
8378 && IT_CHARPOS (*it
) > to_charpos
8379 && IT_CHARPOS (*it
) < IT_CHARPOS (ppos_it
))
8380 SAVE_IT (ppos_it
, *it
, ppos_data
);
8384 /* The number of glyphs we get back in IT->nglyphs will normally
8385 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
8386 character on a terminal frame, or (iii) a line end. For the
8387 second case, IT->nglyphs - 1 padding glyphs will be present.
8388 (On X frames, there is only one glyph produced for a
8389 composite character.)
8391 The behavior implemented below means, for continuation lines,
8392 that as many spaces of a TAB as fit on the current line are
8393 displayed there. For terminal frames, as many glyphs of a
8394 multi-glyph character are displayed in the current line, too.
8395 This is what the old redisplay code did, and we keep it that
8396 way. Under X, the whole shape of a complex character must
8397 fit on the line or it will be completely displayed in the
8400 Note that both for tabs and padding glyphs, all glyphs have
8404 /* More than one glyph or glyph doesn't fit on line. All
8405 glyphs have the same width. */
8406 int single_glyph_width
= it
->pixel_width
/ it
->nglyphs
;
8408 int x_before_this_char
= x
;
8409 int hpos_before_this_char
= it
->hpos
;
8411 for (i
= 0; i
< it
->nglyphs
; ++i
, x
= new_x
)
8413 new_x
= x
+ single_glyph_width
;
8415 /* We want to leave anything reaching TO_X to the caller. */
8416 if ((op
& MOVE_TO_X
) && new_x
> to_x
)
8418 if (BUFFER_POS_REACHED_P ())
8420 if (it
->line_wrap
!= WORD_WRAP
|| wrap_it
.sp
< 0)
8421 goto buffer_pos_reached
;
8422 if (atpos_it
.sp
< 0)
8424 SAVE_IT (atpos_it
, *it
, atpos_data
);
8425 IT_RESET_X_ASCENT_DESCENT (&atpos_it
);
8430 if (it
->line_wrap
!= WORD_WRAP
|| wrap_it
.sp
< 0)
8433 result
= MOVE_X_REACHED
;
8438 SAVE_IT (atx_it
, *it
, atx_data
);
8439 IT_RESET_X_ASCENT_DESCENT (&atx_it
);
8444 if (/* Lines are continued. */
8445 it
->line_wrap
!= TRUNCATE
8446 && (/* And glyph doesn't fit on the line. */
8447 new_x
> it
->last_visible_x
8448 /* Or it fits exactly and we're on a window
8450 || (new_x
== it
->last_visible_x
8451 && FRAME_WINDOW_P (it
->f
)
8452 && ((it
->bidi_p
&& it
->bidi_it
.paragraph_dir
== R2L
)
8453 ? WINDOW_LEFT_FRINGE_WIDTH (it
->w
)
8454 : WINDOW_RIGHT_FRINGE_WIDTH (it
->w
)))))
8456 if (/* IT->hpos == 0 means the very first glyph
8457 doesn't fit on the line, e.g. a wide image. */
8459 || (new_x
== it
->last_visible_x
8460 && FRAME_WINDOW_P (it
->f
)))
8463 it
->current_x
= new_x
;
8465 /* The character's last glyph just barely fits
8467 if (i
== it
->nglyphs
- 1)
8469 /* If this is the destination position,
8470 return a position *before* it in this row,
8471 now that we know it fits in this row. */
8472 if (BUFFER_POS_REACHED_P ())
8474 if (it
->line_wrap
!= WORD_WRAP
8477 it
->hpos
= hpos_before_this_char
;
8478 it
->current_x
= x_before_this_char
;
8479 result
= MOVE_POS_MATCH_OR_ZV
;
8482 if (it
->line_wrap
== WORD_WRAP
8485 SAVE_IT (atpos_it
, *it
, atpos_data
);
8486 atpos_it
.current_x
= x_before_this_char
;
8487 atpos_it
.hpos
= hpos_before_this_char
;
8491 prev_method
= it
->method
;
8492 if (it
->method
== GET_FROM_BUFFER
)
8493 prev_pos
= IT_CHARPOS (*it
);
8494 set_iterator_to_next (it
, 1);
8495 if (IT_CHARPOS (*it
) < CHARPOS (this_line_min_pos
))
8496 SET_TEXT_POS (this_line_min_pos
,
8497 IT_CHARPOS (*it
), IT_BYTEPOS (*it
));
8498 /* On graphical terminals, newlines may
8499 "overflow" into the fringe if
8500 overflow-newline-into-fringe is non-nil.
8501 On text terminals, and on graphical
8502 terminals with no right margin, newlines
8503 may overflow into the last glyph on the
8505 if (!FRAME_WINDOW_P (it
->f
)
8507 && it
->bidi_it
.paragraph_dir
== R2L
)
8508 ? WINDOW_LEFT_FRINGE_WIDTH (it
->w
)
8509 : WINDOW_RIGHT_FRINGE_WIDTH (it
->w
)) == 0
8510 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
8512 if (!get_next_display_element (it
))
8514 result
= MOVE_POS_MATCH_OR_ZV
;
8517 if (BUFFER_POS_REACHED_P ())
8519 if (ITERATOR_AT_END_OF_LINE_P (it
))
8520 result
= MOVE_POS_MATCH_OR_ZV
;
8522 result
= MOVE_LINE_CONTINUED
;
8525 if (ITERATOR_AT_END_OF_LINE_P (it
))
8527 result
= MOVE_NEWLINE_OR_CR
;
8534 IT_RESET_X_ASCENT_DESCENT (it
);
8536 if (wrap_it
.sp
>= 0)
8538 RESTORE_IT (it
, &wrap_it
, wrap_data
);
8543 TRACE_MOVE ((stderr
, "move_it_in: continued at %d\n",
8545 result
= MOVE_LINE_CONTINUED
;
8549 if (BUFFER_POS_REACHED_P ())
8551 if (it
->line_wrap
!= WORD_WRAP
|| wrap_it
.sp
< 0)
8552 goto buffer_pos_reached
;
8553 if (it
->line_wrap
== WORD_WRAP
&& atpos_it
.sp
< 0)
8555 SAVE_IT (atpos_it
, *it
, atpos_data
);
8556 IT_RESET_X_ASCENT_DESCENT (&atpos_it
);
8560 if (new_x
> it
->first_visible_x
)
8562 /* Glyph is visible. Increment number of glyphs that
8563 would be displayed. */
8568 if (result
!= MOVE_UNDEFINED
)
8571 else if (BUFFER_POS_REACHED_P ())
8574 IT_RESET_X_ASCENT_DESCENT (it
);
8575 result
= MOVE_POS_MATCH_OR_ZV
;
8578 else if ((op
& MOVE_TO_X
) && it
->current_x
>= to_x
)
8580 /* Stop when TO_X specified and reached. This check is
8581 necessary here because of lines consisting of a line end,
8582 only. The line end will not produce any glyphs and we
8583 would never get MOVE_X_REACHED. */
8584 eassert (it
->nglyphs
== 0);
8585 result
= MOVE_X_REACHED
;
8589 /* Is this a line end? If yes, we're done. */
8590 if (ITERATOR_AT_END_OF_LINE_P (it
))
8592 /* If we are past TO_CHARPOS, but never saw any character
8593 positions smaller than TO_CHARPOS, return
8594 MOVE_POS_MATCH_OR_ZV, like the unidirectional display
8596 if (it
->bidi_p
&& (op
& MOVE_TO_POS
) != 0)
8598 if (!saw_smaller_pos
&& IT_CHARPOS (*it
) > to_charpos
)
8600 if (IT_CHARPOS (ppos_it
) < ZV
)
8602 RESTORE_IT (it
, &ppos_it
, ppos_data
);
8603 result
= MOVE_POS_MATCH_OR_ZV
;
8606 goto buffer_pos_reached
;
8608 else if (it
->line_wrap
== WORD_WRAP
&& atpos_it
.sp
>= 0
8609 && IT_CHARPOS (*it
) > to_charpos
)
8610 goto buffer_pos_reached
;
8612 result
= MOVE_NEWLINE_OR_CR
;
8615 result
= MOVE_NEWLINE_OR_CR
;
8619 prev_method
= it
->method
;
8620 if (it
->method
== GET_FROM_BUFFER
)
8621 prev_pos
= IT_CHARPOS (*it
);
8622 /* The current display element has been consumed. Advance
8624 set_iterator_to_next (it
, 1);
8625 if (IT_CHARPOS (*it
) < CHARPOS (this_line_min_pos
))
8626 SET_TEXT_POS (this_line_min_pos
, IT_CHARPOS (*it
), IT_BYTEPOS (*it
));
8627 if (IT_CHARPOS (*it
) < to_charpos
)
8628 saw_smaller_pos
= 1;
8630 && (op
& MOVE_TO_POS
)
8631 && IT_CHARPOS (*it
) >= to_charpos
8632 && IT_CHARPOS (*it
) < IT_CHARPOS (ppos_it
))
8633 SAVE_IT (ppos_it
, *it
, ppos_data
);
8635 /* Stop if lines are truncated and IT's current x-position is
8636 past the right edge of the window now. */
8637 if (it
->line_wrap
== TRUNCATE
8638 && it
->current_x
>= it
->last_visible_x
)
8640 if (!FRAME_WINDOW_P (it
->f
)
8641 || ((it
->bidi_p
&& it
->bidi_it
.paragraph_dir
== R2L
)
8642 ? WINDOW_LEFT_FRINGE_WIDTH (it
->w
)
8643 : WINDOW_RIGHT_FRINGE_WIDTH (it
->w
)) == 0
8644 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
8648 if ((at_eob_p
= !get_next_display_element (it
))
8649 || BUFFER_POS_REACHED_P ()
8650 /* If we are past TO_CHARPOS, but never saw any
8651 character positions smaller than TO_CHARPOS,
8652 return MOVE_POS_MATCH_OR_ZV, like the
8653 unidirectional display did. */
8654 || (it
->bidi_p
&& (op
& MOVE_TO_POS
) != 0
8656 && IT_CHARPOS (*it
) > to_charpos
))
8659 && !at_eob_p
&& IT_CHARPOS (ppos_it
) < ZV
)
8660 RESTORE_IT (it
, &ppos_it
, ppos_data
);
8661 result
= MOVE_POS_MATCH_OR_ZV
;
8664 if (ITERATOR_AT_END_OF_LINE_P (it
))
8666 result
= MOVE_NEWLINE_OR_CR
;
8670 else if (it
->bidi_p
&& (op
& MOVE_TO_POS
) != 0
8672 && IT_CHARPOS (*it
) > to_charpos
)
8674 if (IT_CHARPOS (ppos_it
) < ZV
)
8675 RESTORE_IT (it
, &ppos_it
, ppos_data
);
8676 result
= MOVE_POS_MATCH_OR_ZV
;
8679 result
= MOVE_LINE_TRUNCATED
;
8682 #undef IT_RESET_X_ASCENT_DESCENT
8685 #undef BUFFER_POS_REACHED_P
8687 /* If we scanned beyond to_pos and didn't find a point to wrap at,
8688 restore the saved iterator. */
8689 if (atpos_it
.sp
>= 0)
8690 RESTORE_IT (it
, &atpos_it
, atpos_data
);
8691 else if (atx_it
.sp
>= 0)
8692 RESTORE_IT (it
, &atx_it
, atx_data
);
8697 bidi_unshelve_cache (atpos_data
, 1);
8699 bidi_unshelve_cache (atx_data
, 1);
8701 bidi_unshelve_cache (wrap_data
, 1);
8703 bidi_unshelve_cache (ppos_data
, 1);
8705 /* Restore the iterator settings altered at the beginning of this
8707 it
->glyph_row
= saved_glyph_row
;
8711 /* For external use. */
8713 move_it_in_display_line (struct it
*it
,
8714 ptrdiff_t to_charpos
, int to_x
,
8715 enum move_operation_enum op
)
8717 if (it
->line_wrap
== WORD_WRAP
8718 && (op
& MOVE_TO_X
))
8721 void *save_data
= NULL
;
8724 SAVE_IT (save_it
, *it
, save_data
);
8725 skip
= move_it_in_display_line_to (it
, to_charpos
, to_x
, op
);
8726 /* When word-wrap is on, TO_X may lie past the end
8727 of a wrapped line. Then it->current is the
8728 character on the next line, so backtrack to the
8729 space before the wrap point. */
8730 if (skip
== MOVE_LINE_CONTINUED
)
8732 int prev_x
= max (it
->current_x
- 1, 0);
8733 RESTORE_IT (it
, &save_it
, save_data
);
8734 move_it_in_display_line_to
8735 (it
, -1, prev_x
, MOVE_TO_X
);
8738 bidi_unshelve_cache (save_data
, 1);
8741 move_it_in_display_line_to (it
, to_charpos
, to_x
, op
);
8745 /* Move IT forward until it satisfies one or more of the criteria in
8746 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
8748 OP is a bit-mask that specifies where to stop, and in particular,
8749 which of those four position arguments makes a difference. See the
8750 description of enum move_operation_enum.
8752 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
8753 screen line, this function will set IT to the next position that is
8754 displayed to the right of TO_CHARPOS on the screen. */
8757 move_it_to (struct it
*it
, ptrdiff_t to_charpos
, int to_x
, int to_y
, int to_vpos
, int op
)
8759 enum move_it_result skip
, skip2
= MOVE_X_REACHED
;
8760 int line_height
, line_start_x
= 0, reached
= 0;
8761 void *backup_data
= NULL
;
8765 if (op
& MOVE_TO_VPOS
)
8767 /* If no TO_CHARPOS and no TO_X specified, stop at the
8768 start of the line TO_VPOS. */
8769 if ((op
& (MOVE_TO_X
| MOVE_TO_POS
)) == 0)
8771 if (it
->vpos
== to_vpos
)
8777 skip
= move_it_in_display_line_to (it
, -1, -1, 0);
8781 /* TO_VPOS >= 0 means stop at TO_X in the line at
8782 TO_VPOS, or at TO_POS, whichever comes first. */
8783 if (it
->vpos
== to_vpos
)
8789 skip
= move_it_in_display_line_to (it
, to_charpos
, to_x
, op
);
8791 if (skip
== MOVE_POS_MATCH_OR_ZV
|| it
->vpos
== to_vpos
)
8796 else if (skip
== MOVE_X_REACHED
&& it
->vpos
!= to_vpos
)
8798 /* We have reached TO_X but not in the line we want. */
8799 skip
= move_it_in_display_line_to (it
, to_charpos
,
8801 if (skip
== MOVE_POS_MATCH_OR_ZV
)
8809 else if (op
& MOVE_TO_Y
)
8811 struct it it_backup
;
8813 if (it
->line_wrap
== WORD_WRAP
)
8814 SAVE_IT (it_backup
, *it
, backup_data
);
8816 /* TO_Y specified means stop at TO_X in the line containing
8817 TO_Y---or at TO_CHARPOS if this is reached first. The
8818 problem is that we can't really tell whether the line
8819 contains TO_Y before we have completely scanned it, and
8820 this may skip past TO_X. What we do is to first scan to
8823 If TO_X is not specified, use a TO_X of zero. The reason
8824 is to make the outcome of this function more predictable.
8825 If we didn't use TO_X == 0, we would stop at the end of
8826 the line which is probably not what a caller would expect
8828 skip
= move_it_in_display_line_to
8829 (it
, to_charpos
, ((op
& MOVE_TO_X
) ? to_x
: 0),
8830 (MOVE_TO_X
| (op
& MOVE_TO_POS
)));
8832 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
8833 if (skip
== MOVE_POS_MATCH_OR_ZV
)
8835 else if (skip
== MOVE_X_REACHED
)
8837 /* If TO_X was reached, we want to know whether TO_Y is
8838 in the line. We know this is the case if the already
8839 scanned glyphs make the line tall enough. Otherwise,
8840 we must check by scanning the rest of the line. */
8841 line_height
= it
->max_ascent
+ it
->max_descent
;
8842 if (to_y
>= it
->current_y
8843 && to_y
< it
->current_y
+ line_height
)
8848 SAVE_IT (it_backup
, *it
, backup_data
);
8849 TRACE_MOVE ((stderr
, "move_it: from %d\n", IT_CHARPOS (*it
)));
8850 skip2
= move_it_in_display_line_to (it
, to_charpos
, -1,
8852 TRACE_MOVE ((stderr
, "move_it: to %d\n", IT_CHARPOS (*it
)));
8853 line_height
= it
->max_ascent
+ it
->max_descent
;
8854 TRACE_MOVE ((stderr
, "move_it: line_height = %d\n", line_height
));
8856 if (to_y
>= it
->current_y
8857 && to_y
< it
->current_y
+ line_height
)
8859 /* If TO_Y is in this line and TO_X was reached
8860 above, we scanned too far. We have to restore
8861 IT's settings to the ones before skipping. But
8862 keep the more accurate values of max_ascent and
8863 max_descent we've found while skipping the rest
8864 of the line, for the sake of callers, such as
8865 pos_visible_p, that need to know the line
8867 int max_ascent
= it
->max_ascent
;
8868 int max_descent
= it
->max_descent
;
8870 RESTORE_IT (it
, &it_backup
, backup_data
);
8871 it
->max_ascent
= max_ascent
;
8872 it
->max_descent
= max_descent
;
8878 if (skip
== MOVE_POS_MATCH_OR_ZV
)
8884 /* Check whether TO_Y is in this line. */
8885 line_height
= it
->max_ascent
+ it
->max_descent
;
8886 TRACE_MOVE ((stderr
, "move_it: line_height = %d\n", line_height
));
8888 if (to_y
>= it
->current_y
8889 && to_y
< it
->current_y
+ line_height
)
8891 /* When word-wrap is on, TO_X may lie past the end
8892 of a wrapped line. Then it->current is the
8893 character on the next line, so backtrack to the
8894 space before the wrap point. */
8895 if (skip
== MOVE_LINE_CONTINUED
8896 && it
->line_wrap
== WORD_WRAP
)
8898 int prev_x
= max (it
->current_x
- 1, 0);
8899 RESTORE_IT (it
, &it_backup
, backup_data
);
8900 skip
= move_it_in_display_line_to
8901 (it
, -1, prev_x
, MOVE_TO_X
);
8910 else if (BUFFERP (it
->object
)
8911 && (it
->method
== GET_FROM_BUFFER
8912 || it
->method
== GET_FROM_STRETCH
)
8913 && IT_CHARPOS (*it
) >= to_charpos
8914 /* Under bidi iteration, a call to set_iterator_to_next
8915 can scan far beyond to_charpos if the initial
8916 portion of the next line needs to be reordered. In
8917 that case, give move_it_in_display_line_to another
8920 && it
->bidi_it
.scan_dir
== -1))
8921 skip
= MOVE_POS_MATCH_OR_ZV
;
8923 skip
= move_it_in_display_line_to (it
, to_charpos
, -1, MOVE_TO_POS
);
8927 case MOVE_POS_MATCH_OR_ZV
:
8931 case MOVE_NEWLINE_OR_CR
:
8932 set_iterator_to_next (it
, 1);
8933 it
->continuation_lines_width
= 0;
8936 case MOVE_LINE_TRUNCATED
:
8937 it
->continuation_lines_width
= 0;
8938 reseat_at_next_visible_line_start (it
, 0);
8939 if ((op
& MOVE_TO_POS
) != 0
8940 && IT_CHARPOS (*it
) > to_charpos
)
8947 case MOVE_LINE_CONTINUED
:
8948 /* For continued lines ending in a tab, some of the glyphs
8949 associated with the tab are displayed on the current
8950 line. Since it->current_x does not include these glyphs,
8951 we use it->last_visible_x instead. */
8954 it
->continuation_lines_width
+= it
->last_visible_x
;
8955 /* When moving by vpos, ensure that the iterator really
8956 advances to the next line (bug#847, bug#969). Fixme:
8957 do we need to do this in other circumstances? */
8958 if (it
->current_x
!= it
->last_visible_x
8959 && (op
& MOVE_TO_VPOS
)
8960 && !(op
& (MOVE_TO_X
| MOVE_TO_POS
)))
8962 line_start_x
= it
->current_x
+ it
->pixel_width
8963 - it
->last_visible_x
;
8964 set_iterator_to_next (it
, 0);
8968 it
->continuation_lines_width
+= it
->current_x
;
8975 /* Reset/increment for the next run. */
8976 recenter_overlay_lists (current_buffer
, IT_CHARPOS (*it
));
8977 it
->current_x
= line_start_x
;
8980 it
->current_y
+= it
->max_ascent
+ it
->max_descent
;
8982 last_height
= it
->max_ascent
+ it
->max_descent
;
8983 it
->max_ascent
= it
->max_descent
= 0;
8988 /* On text terminals, we may stop at the end of a line in the middle
8989 of a multi-character glyph. If the glyph itself is continued,
8990 i.e. it is actually displayed on the next line, don't treat this
8991 stopping point as valid; move to the next line instead (unless
8992 that brings us offscreen). */
8993 if (!FRAME_WINDOW_P (it
->f
)
8995 && IT_CHARPOS (*it
) == to_charpos
8996 && it
->what
== IT_CHARACTER
8998 && it
->line_wrap
== WINDOW_WRAP
8999 && it
->current_x
== it
->last_visible_x
- 1
9002 && it
->vpos
< XFASTINT (it
->w
->window_end_vpos
))
9004 it
->continuation_lines_width
+= it
->current_x
;
9005 it
->current_x
= it
->hpos
= it
->max_ascent
= it
->max_descent
= 0;
9006 it
->current_y
+= it
->max_ascent
+ it
->max_descent
;
9008 last_height
= it
->max_ascent
+ it
->max_descent
;
9012 bidi_unshelve_cache (backup_data
, 1);
9014 TRACE_MOVE ((stderr
, "move_it_to: reached %d\n", reached
));
9018 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
9020 If DY > 0, move IT backward at least that many pixels. DY = 0
9021 means move IT backward to the preceding line start or BEGV. This
9022 function may move over more than DY pixels if IT->current_y - DY
9023 ends up in the middle of a line; in this case IT->current_y will be
9024 set to the top of the line moved to. */
9027 move_it_vertically_backward (struct it
*it
, int dy
)
9031 void *it2data
= NULL
, *it3data
= NULL
;
9032 ptrdiff_t start_pos
;
9034 = (it
->last_visible_x
- it
->first_visible_x
) / FRAME_COLUMN_WIDTH (it
->f
);
9035 ptrdiff_t pos_limit
;
9040 start_pos
= IT_CHARPOS (*it
);
9042 /* Estimate how many newlines we must move back. */
9043 nlines
= max (1, dy
/ FRAME_LINE_HEIGHT (it
->f
));
9044 if (it
->line_wrap
== TRUNCATE
)
9047 pos_limit
= max (start_pos
- nlines
* nchars_per_row
, BEGV
);
9049 /* Set the iterator's position that many lines back. But don't go
9050 back more than NLINES full screen lines -- this wins a day with
9051 buffers which have very long lines. */
9052 while (nlines
-- && IT_CHARPOS (*it
) > pos_limit
)
9053 back_to_previous_visible_line_start (it
);
9055 /* Reseat the iterator here. When moving backward, we don't want
9056 reseat to skip forward over invisible text, set up the iterator
9057 to deliver from overlay strings at the new position etc. So,
9058 use reseat_1 here. */
9059 reseat_1 (it
, it
->current
.pos
, 1);
9061 /* We are now surely at a line start. */
9062 it
->current_x
= it
->hpos
= 0; /* FIXME: this is incorrect when bidi
9063 reordering is in effect. */
9064 it
->continuation_lines_width
= 0;
9066 /* Move forward and see what y-distance we moved. First move to the
9067 start of the next line so that we get its height. We need this
9068 height to be able to tell whether we reached the specified
9070 SAVE_IT (it2
, *it
, it2data
);
9071 it2
.max_ascent
= it2
.max_descent
= 0;
9074 move_it_to (&it2
, start_pos
, -1, -1, it2
.vpos
+ 1,
9075 MOVE_TO_POS
| MOVE_TO_VPOS
);
9077 while (!(IT_POS_VALID_AFTER_MOVE_P (&it2
)
9078 /* If we are in a display string which starts at START_POS,
9079 and that display string includes a newline, and we are
9080 right after that newline (i.e. at the beginning of a
9081 display line), exit the loop, because otherwise we will
9082 infloop, since move_it_to will see that it is already at
9083 START_POS and will not move. */
9084 || (it2
.method
== GET_FROM_STRING
9085 && IT_CHARPOS (it2
) == start_pos
9086 && SREF (it2
.string
, IT_STRING_BYTEPOS (it2
) - 1) == '\n')));
9087 eassert (IT_CHARPOS (*it
) >= BEGV
);
9088 SAVE_IT (it3
, it2
, it3data
);
9090 move_it_to (&it2
, start_pos
, -1, -1, -1, MOVE_TO_POS
);
9091 eassert (IT_CHARPOS (*it
) >= BEGV
);
9092 /* H is the actual vertical distance from the position in *IT
9093 and the starting position. */
9094 h
= it2
.current_y
- it
->current_y
;
9095 /* NLINES is the distance in number of lines. */
9096 nlines
= it2
.vpos
- it
->vpos
;
9098 /* Correct IT's y and vpos position
9099 so that they are relative to the starting point. */
9105 /* DY == 0 means move to the start of the screen line. The
9106 value of nlines is > 0 if continuation lines were involved,
9107 or if the original IT position was at start of a line. */
9108 RESTORE_IT (it
, it
, it2data
);
9110 move_it_by_lines (it
, nlines
);
9111 /* The above code moves us to some position NLINES down,
9112 usually to its first glyph (leftmost in an L2R line), but
9113 that's not necessarily the start of the line, under bidi
9114 reordering. We want to get to the character position
9115 that is immediately after the newline of the previous
9118 && !it
->continuation_lines_width
9119 && !STRINGP (it
->string
)
9120 && IT_CHARPOS (*it
) > BEGV
9121 && FETCH_BYTE (IT_BYTEPOS (*it
) - 1) != '\n')
9123 ptrdiff_t cp
= IT_CHARPOS (*it
), bp
= IT_BYTEPOS (*it
);
9126 cp
= find_newline_no_quit (cp
, bp
, -1, NULL
);
9127 move_it_to (it
, cp
, -1, -1, -1, MOVE_TO_POS
);
9129 bidi_unshelve_cache (it3data
, 1);
9133 /* The y-position we try to reach, relative to *IT.
9134 Note that H has been subtracted in front of the if-statement. */
9135 int target_y
= it
->current_y
+ h
- dy
;
9136 int y0
= it3
.current_y
;
9140 RESTORE_IT (&it3
, &it3
, it3data
);
9141 y1
= line_bottom_y (&it3
);
9142 line_height
= y1
- y0
;
9143 RESTORE_IT (it
, it
, it2data
);
9144 /* If we did not reach target_y, try to move further backward if
9145 we can. If we moved too far backward, try to move forward. */
9146 if (target_y
< it
->current_y
9147 /* This is heuristic. In a window that's 3 lines high, with
9148 a line height of 13 pixels each, recentering with point
9149 on the bottom line will try to move -39/2 = 19 pixels
9150 backward. Try to avoid moving into the first line. */
9151 && (it
->current_y
- target_y
9152 > min (window_box_height (it
->w
), line_height
* 2 / 3))
9153 && IT_CHARPOS (*it
) > BEGV
)
9155 TRACE_MOVE ((stderr
, " not far enough -> move_vert %d\n",
9156 target_y
- it
->current_y
));
9157 dy
= it
->current_y
- target_y
;
9158 goto move_further_back
;
9160 else if (target_y
>= it
->current_y
+ line_height
9161 && IT_CHARPOS (*it
) < ZV
)
9163 /* Should move forward by at least one line, maybe more.
9165 Note: Calling move_it_by_lines can be expensive on
9166 terminal frames, where compute_motion is used (via
9167 vmotion) to do the job, when there are very long lines
9168 and truncate-lines is nil. That's the reason for
9169 treating terminal frames specially here. */
9171 if (!FRAME_WINDOW_P (it
->f
))
9172 move_it_vertically (it
, target_y
- (it
->current_y
+ line_height
));
9177 move_it_by_lines (it
, 1);
9179 while (target_y
>= line_bottom_y (it
) && IT_CHARPOS (*it
) < ZV
);
9186 /* Move IT by a specified amount of pixel lines DY. DY negative means
9187 move backwards. DY = 0 means move to start of screen line. At the
9188 end, IT will be on the start of a screen line. */
9191 move_it_vertically (struct it
*it
, int dy
)
9194 move_it_vertically_backward (it
, -dy
);
9197 TRACE_MOVE ((stderr
, "move_it_v: from %d, %d\n", IT_CHARPOS (*it
), dy
));
9198 move_it_to (it
, ZV
, -1, it
->current_y
+ dy
, -1,
9199 MOVE_TO_POS
| MOVE_TO_Y
);
9200 TRACE_MOVE ((stderr
, "move_it_v: to %d\n", IT_CHARPOS (*it
)));
9202 /* If buffer ends in ZV without a newline, move to the start of
9203 the line to satisfy the post-condition. */
9204 if (IT_CHARPOS (*it
) == ZV
9206 && FETCH_BYTE (IT_BYTEPOS (*it
) - 1) != '\n')
9207 move_it_by_lines (it
, 0);
9212 /* Move iterator IT past the end of the text line it is in. */
9215 move_it_past_eol (struct it
*it
)
9217 enum move_it_result rc
;
9219 rc
= move_it_in_display_line_to (it
, Z
, 0, MOVE_TO_POS
);
9220 if (rc
== MOVE_NEWLINE_OR_CR
)
9221 set_iterator_to_next (it
, 0);
9225 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
9226 negative means move up. DVPOS == 0 means move to the start of the
9229 Optimization idea: If we would know that IT->f doesn't use
9230 a face with proportional font, we could be faster for
9231 truncate-lines nil. */
9234 move_it_by_lines (struct it
*it
, ptrdiff_t dvpos
)
9237 /* The commented-out optimization uses vmotion on terminals. This
9238 gives bad results, because elements like it->what, on which
9239 callers such as pos_visible_p rely, aren't updated. */
9240 /* struct position pos;
9241 if (!FRAME_WINDOW_P (it->f))
9243 struct text_pos textpos;
9245 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
9246 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
9247 reseat (it, textpos, 1);
9248 it->vpos += pos.vpos;
9249 it->current_y += pos.vpos;
9255 /* DVPOS == 0 means move to the start of the screen line. */
9256 move_it_vertically_backward (it
, 0);
9257 /* Let next call to line_bottom_y calculate real line height */
9262 move_it_to (it
, -1, -1, -1, it
->vpos
+ dvpos
, MOVE_TO_VPOS
);
9263 if (!IT_POS_VALID_AFTER_MOVE_P (it
))
9265 /* Only move to the next buffer position if we ended up in a
9266 string from display property, not in an overlay string
9267 (before-string or after-string). That is because the
9268 latter don't conceal the underlying buffer position, so
9269 we can ask to move the iterator to the exact position we
9270 are interested in. Note that, even if we are already at
9271 IT_CHARPOS (*it), the call below is not a no-op, as it
9272 will detect that we are at the end of the string, pop the
9273 iterator, and compute it->current_x and it->hpos
9275 move_it_to (it
, IT_CHARPOS (*it
) + it
->string_from_display_prop_p
,
9276 -1, -1, -1, MOVE_TO_POS
);
9282 void *it2data
= NULL
;
9283 ptrdiff_t start_charpos
, i
;
9285 = (it
->last_visible_x
- it
->first_visible_x
) / FRAME_COLUMN_WIDTH (it
->f
);
9286 ptrdiff_t pos_limit
;
9288 /* Start at the beginning of the screen line containing IT's
9289 position. This may actually move vertically backwards,
9290 in case of overlays, so adjust dvpos accordingly. */
9292 move_it_vertically_backward (it
, 0);
9295 /* Go back -DVPOS buffer lines, but no farther than -DVPOS full
9296 screen lines, and reseat the iterator there. */
9297 start_charpos
= IT_CHARPOS (*it
);
9298 if (it
->line_wrap
== TRUNCATE
)
9301 pos_limit
= max (start_charpos
+ dvpos
* nchars_per_row
, BEGV
);
9302 for (i
= -dvpos
; i
> 0 && IT_CHARPOS (*it
) > pos_limit
; --i
)
9303 back_to_previous_visible_line_start (it
);
9304 reseat (it
, it
->current
.pos
, 1);
9306 /* Move further back if we end up in a string or an image. */
9307 while (!IT_POS_VALID_AFTER_MOVE_P (it
))
9309 /* First try to move to start of display line. */
9311 move_it_vertically_backward (it
, 0);
9313 if (IT_POS_VALID_AFTER_MOVE_P (it
))
9315 /* If start of line is still in string or image,
9316 move further back. */
9317 back_to_previous_visible_line_start (it
);
9318 reseat (it
, it
->current
.pos
, 1);
9322 it
->current_x
= it
->hpos
= 0;
9324 /* Above call may have moved too far if continuation lines
9325 are involved. Scan forward and see if it did. */
9326 SAVE_IT (it2
, *it
, it2data
);
9327 it2
.vpos
= it2
.current_y
= 0;
9328 move_it_to (&it2
, start_charpos
, -1, -1, -1, MOVE_TO_POS
);
9329 it
->vpos
-= it2
.vpos
;
9330 it
->current_y
-= it2
.current_y
;
9331 it
->current_x
= it
->hpos
= 0;
9333 /* If we moved too far back, move IT some lines forward. */
9334 if (it2
.vpos
> -dvpos
)
9336 int delta
= it2
.vpos
+ dvpos
;
9338 RESTORE_IT (&it2
, &it2
, it2data
);
9339 SAVE_IT (it2
, *it
, it2data
);
9340 move_it_to (it
, -1, -1, -1, it
->vpos
+ delta
, MOVE_TO_VPOS
);
9341 /* Move back again if we got too far ahead. */
9342 if (IT_CHARPOS (*it
) >= start_charpos
)
9343 RESTORE_IT (it
, &it2
, it2data
);
9345 bidi_unshelve_cache (it2data
, 1);
9348 RESTORE_IT (it
, it
, it2data
);
9352 /* Return 1 if IT points into the middle of a display vector. */
9355 in_display_vector_p (struct it
*it
)
9357 return (it
->method
== GET_FROM_DISPLAY_VECTOR
9358 && it
->current
.dpvec_index
> 0
9359 && it
->dpvec
+ it
->current
.dpvec_index
!= it
->dpend
);
9363 /***********************************************************************
9365 ***********************************************************************/
9368 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
9372 add_to_log (const char *format
, Lisp_Object arg1
, Lisp_Object arg2
)
9374 Lisp_Object args
[3];
9375 Lisp_Object msg
, fmt
;
9378 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
9382 GCPRO4 (fmt
, msg
, arg1
, arg2
);
9384 args
[0] = fmt
= build_string (format
);
9387 msg
= Fformat (3, args
);
9389 len
= SBYTES (msg
) + 1;
9390 buffer
= SAFE_ALLOCA (len
);
9391 memcpy (buffer
, SDATA (msg
), len
);
9393 message_dolog (buffer
, len
- 1, 1, 0);
9400 /* Output a newline in the *Messages* buffer if "needs" one. */
9403 message_log_maybe_newline (void)
9405 if (message_log_need_newline
)
9406 message_dolog ("", 0, 1, 0);
9410 /* Add a string M of length NBYTES to the message log, optionally
9411 terminated with a newline when NLFLAG is true. MULTIBYTE, if
9412 true, means interpret the contents of M as multibyte. This
9413 function calls low-level routines in order to bypass text property
9414 hooks, etc. which might not be safe to run.
9416 This may GC (insert may run before/after change hooks),
9417 so the buffer M must NOT point to a Lisp string. */
9420 message_dolog (const char *m
, ptrdiff_t nbytes
, bool nlflag
, bool multibyte
)
9422 const unsigned char *msg
= (const unsigned char *) m
;
9424 if (!NILP (Vmemory_full
))
9427 if (!NILP (Vmessage_log_max
))
9429 struct buffer
*oldbuf
;
9430 Lisp_Object oldpoint
, oldbegv
, oldzv
;
9431 int old_windows_or_buffers_changed
= windows_or_buffers_changed
;
9432 ptrdiff_t point_at_end
= 0;
9433 ptrdiff_t zv_at_end
= 0;
9434 Lisp_Object old_deactivate_mark
;
9436 struct gcpro gcpro1
;
9438 old_deactivate_mark
= Vdeactivate_mark
;
9439 oldbuf
= current_buffer
;
9440 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name
));
9441 bset_undo_list (current_buffer
, Qt
);
9443 oldpoint
= message_dolog_marker1
;
9444 set_marker_restricted_both (oldpoint
, Qnil
, PT
, PT_BYTE
);
9445 oldbegv
= message_dolog_marker2
;
9446 set_marker_restricted_both (oldbegv
, Qnil
, BEGV
, BEGV_BYTE
);
9447 oldzv
= message_dolog_marker3
;
9448 set_marker_restricted_both (oldzv
, Qnil
, ZV
, ZV_BYTE
);
9449 GCPRO1 (old_deactivate_mark
);
9457 BEGV_BYTE
= BEG_BYTE
;
9460 TEMP_SET_PT_BOTH (Z
, Z_BYTE
);
9462 /* Insert the string--maybe converting multibyte to single byte
9463 or vice versa, so that all the text fits the buffer. */
9465 && NILP (BVAR (current_buffer
, enable_multibyte_characters
)))
9471 /* Convert a multibyte string to single-byte
9472 for the *Message* buffer. */
9473 for (i
= 0; i
< nbytes
; i
+= char_bytes
)
9475 c
= string_char_and_length (msg
+ i
, &char_bytes
);
9476 work
[0] = (ASCII_CHAR_P (c
)
9478 : multibyte_char_to_unibyte (c
));
9479 insert_1_both (work
, 1, 1, 1, 0, 0);
9482 else if (! multibyte
9483 && ! NILP (BVAR (current_buffer
, enable_multibyte_characters
)))
9487 unsigned char str
[MAX_MULTIBYTE_LENGTH
];
9488 /* Convert a single-byte string to multibyte
9489 for the *Message* buffer. */
9490 for (i
= 0; i
< nbytes
; i
++)
9493 MAKE_CHAR_MULTIBYTE (c
);
9494 char_bytes
= CHAR_STRING (c
, str
);
9495 insert_1_both ((char *) str
, 1, char_bytes
, 1, 0, 0);
9499 insert_1_both (m
, chars_in_text (msg
, nbytes
), nbytes
, 1, 0, 0);
9503 ptrdiff_t this_bol
, this_bol_byte
, prev_bol
, prev_bol_byte
;
9506 insert_1_both ("\n", 1, 1, 1, 0, 0);
9508 scan_newline (Z
, Z_BYTE
, BEG
, BEG_BYTE
, -2, 0);
9510 this_bol_byte
= PT_BYTE
;
9512 /* See if this line duplicates the previous one.
9513 If so, combine duplicates. */
9516 scan_newline (PT
, PT_BYTE
, BEG
, BEG_BYTE
, -2, 0);
9518 prev_bol_byte
= PT_BYTE
;
9520 dups
= message_log_check_duplicate (prev_bol_byte
,
9524 del_range_both (prev_bol
, prev_bol_byte
,
9525 this_bol
, this_bol_byte
, 0);
9528 char dupstr
[sizeof " [ times]"
9529 + INT_STRLEN_BOUND (printmax_t
)];
9531 /* If you change this format, don't forget to also
9532 change message_log_check_duplicate. */
9533 int duplen
= sprintf (dupstr
, " [%"pMd
" times]", dups
);
9534 TEMP_SET_PT_BOTH (Z
- 1, Z_BYTE
- 1);
9535 insert_1_both (dupstr
, duplen
, duplen
, 1, 0, 1);
9540 /* If we have more than the desired maximum number of lines
9541 in the *Messages* buffer now, delete the oldest ones.
9542 This is safe because we don't have undo in this buffer. */
9544 if (NATNUMP (Vmessage_log_max
))
9546 scan_newline (Z
, Z_BYTE
, BEG
, BEG_BYTE
,
9547 -XFASTINT (Vmessage_log_max
) - 1, 0);
9548 del_range_both (BEG
, BEG_BYTE
, PT
, PT_BYTE
, 0);
9551 BEGV
= marker_position (oldbegv
);
9552 BEGV_BYTE
= marker_byte_position (oldbegv
);
9561 ZV
= marker_position (oldzv
);
9562 ZV_BYTE
= marker_byte_position (oldzv
);
9566 TEMP_SET_PT_BOTH (Z
, Z_BYTE
);
9568 /* We can't do Fgoto_char (oldpoint) because it will run some
9570 TEMP_SET_PT_BOTH (marker_position (oldpoint
),
9571 marker_byte_position (oldpoint
));
9574 unchain_marker (XMARKER (oldpoint
));
9575 unchain_marker (XMARKER (oldbegv
));
9576 unchain_marker (XMARKER (oldzv
));
9578 shown
= buffer_window_count (current_buffer
) > 0;
9579 set_buffer_internal (oldbuf
);
9580 /* We called insert_1_both above with its 5th argument (PREPARE)
9581 zero, which prevents insert_1_both from calling
9582 prepare_to_modify_buffer, which in turns prevents us from
9583 incrementing windows_or_buffers_changed even if *Messages* is
9584 shown in some window. So we must manually incrementing
9585 windows_or_buffers_changed here to make up for that. */
9587 windows_or_buffers_changed
++;
9589 windows_or_buffers_changed
= old_windows_or_buffers_changed
;
9590 message_log_need_newline
= !nlflag
;
9591 Vdeactivate_mark
= old_deactivate_mark
;
9596 /* We are at the end of the buffer after just having inserted a newline.
9597 (Note: We depend on the fact we won't be crossing the gap.)
9598 Check to see if the most recent message looks a lot like the previous one.
9599 Return 0 if different, 1 if the new one should just replace it, or a
9600 value N > 1 if we should also append " [N times]". */
9603 message_log_check_duplicate (ptrdiff_t prev_bol_byte
, ptrdiff_t this_bol_byte
)
9606 ptrdiff_t len
= Z_BYTE
- 1 - this_bol_byte
;
9608 unsigned char *p1
= BUF_BYTE_ADDRESS (current_buffer
, prev_bol_byte
);
9609 unsigned char *p2
= BUF_BYTE_ADDRESS (current_buffer
, this_bol_byte
);
9611 for (i
= 0; i
< len
; i
++)
9613 if (i
>= 3 && p1
[i
- 3] == '.' && p1
[i
- 2] == '.' && p1
[i
- 1] == '.')
9621 if (*p1
++ == ' ' && *p1
++ == '[')
9624 intmax_t n
= strtoimax ((char *) p1
, &pend
, 10);
9625 if (0 < n
&& n
< INTMAX_MAX
&& strncmp (pend
, " times]\n", 8) == 0)
9632 /* Display an echo area message M with a specified length of NBYTES
9633 bytes. The string may include null characters. If M is not a
9634 string, clear out any existing message, and let the mini-buffer
9637 This function cancels echoing. */
9640 message3 (Lisp_Object m
)
9642 struct gcpro gcpro1
;
9645 clear_message (1,1);
9648 /* First flush out any partial line written with print. */
9649 message_log_maybe_newline ();
9652 ptrdiff_t nbytes
= SBYTES (m
);
9653 bool multibyte
= STRING_MULTIBYTE (m
);
9655 char *buffer
= SAFE_ALLOCA (nbytes
);
9656 memcpy (buffer
, SDATA (m
), nbytes
);
9657 message_dolog (buffer
, nbytes
, 1, multibyte
);
9666 /* The non-logging version of message3.
9667 This does not cancel echoing, because it is used for echoing.
9668 Perhaps we need to make a separate function for echoing
9669 and make this cancel echoing. */
9672 message3_nolog (Lisp_Object m
)
9674 struct frame
*sf
= SELECTED_FRAME ();
9676 if (FRAME_INITIAL_P (sf
))
9678 if (noninteractive_need_newline
)
9679 putc ('\n', stderr
);
9680 noninteractive_need_newline
= 0;
9682 fwrite (SDATA (m
), SBYTES (m
), 1, stderr
);
9683 if (cursor_in_echo_area
== 0)
9684 fprintf (stderr
, "\n");
9687 /* Error messages get reported properly by cmd_error, so this must be just an
9688 informative message; if the frame hasn't really been initialized yet, just
9690 else if (INTERACTIVE
&& sf
->glyphs_initialized_p
)
9692 /* Get the frame containing the mini-buffer
9693 that the selected frame is using. */
9694 Lisp_Object mini_window
= FRAME_MINIBUF_WINDOW (sf
);
9695 Lisp_Object frame
= XWINDOW (mini_window
)->frame
;
9696 struct frame
*f
= XFRAME (frame
);
9698 if (FRAME_VISIBLE_P (sf
) && !FRAME_VISIBLE_P (f
))
9699 Fmake_frame_visible (frame
);
9701 if (STRINGP (m
) && SCHARS (m
) > 0)
9704 if (minibuffer_auto_raise
)
9705 Fraise_frame (frame
);
9706 /* Assume we are not echoing.
9707 (If we are, echo_now will override this.) */
9708 echo_message_buffer
= Qnil
;
9711 clear_message (1, 1);
9713 do_pending_window_change (0);
9714 echo_area_display (1);
9715 do_pending_window_change (0);
9716 if (FRAME_TERMINAL (f
)->frame_up_to_date_hook
)
9717 (*FRAME_TERMINAL (f
)->frame_up_to_date_hook
) (f
);
9722 /* Display a null-terminated echo area message M. If M is 0, clear
9723 out any existing message, and let the mini-buffer text show through.
9725 The buffer M must continue to exist until after the echo area gets
9726 cleared or some other message gets displayed there. Do not pass
9727 text that is stored in a Lisp string. Do not pass text in a buffer
9728 that was alloca'd. */
9731 message1 (const char *m
)
9733 message3 (m
? make_unibyte_string (m
, strlen (m
)) : Qnil
);
9737 /* The non-logging counterpart of message1. */
9740 message1_nolog (const char *m
)
9742 message3_nolog (m
? make_unibyte_string (m
, strlen (m
)) : Qnil
);
9745 /* Display a message M which contains a single %s
9746 which gets replaced with STRING. */
9749 message_with_string (const char *m
, Lisp_Object string
, int log
)
9751 CHECK_STRING (string
);
9757 if (noninteractive_need_newline
)
9758 putc ('\n', stderr
);
9759 noninteractive_need_newline
= 0;
9760 fprintf (stderr
, m
, SDATA (string
));
9761 if (!cursor_in_echo_area
)
9762 fprintf (stderr
, "\n");
9766 else if (INTERACTIVE
)
9768 /* The frame whose minibuffer we're going to display the message on.
9769 It may be larger than the selected frame, so we need
9770 to use its buffer, not the selected frame's buffer. */
9771 Lisp_Object mini_window
;
9772 struct frame
*f
, *sf
= SELECTED_FRAME ();
9774 /* Get the frame containing the minibuffer
9775 that the selected frame is using. */
9776 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
9777 f
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
9779 /* Error messages get reported properly by cmd_error, so this must be
9780 just an informative message; if the frame hasn't really been
9781 initialized yet, just toss it. */
9782 if (f
->glyphs_initialized_p
)
9784 Lisp_Object args
[2], msg
;
9785 struct gcpro gcpro1
, gcpro2
;
9787 args
[0] = build_string (m
);
9788 args
[1] = msg
= string
;
9789 GCPRO2 (args
[0], msg
);
9792 msg
= Fformat (2, args
);
9797 message3_nolog (msg
);
9801 /* Print should start at the beginning of the message
9802 buffer next time. */
9803 message_buf_print
= 0;
9809 /* Dump an informative message to the minibuf. If M is 0, clear out
9810 any existing message, and let the mini-buffer text show through. */
9813 vmessage (const char *m
, va_list ap
)
9819 if (noninteractive_need_newline
)
9820 putc ('\n', stderr
);
9821 noninteractive_need_newline
= 0;
9822 vfprintf (stderr
, m
, ap
);
9823 if (cursor_in_echo_area
== 0)
9824 fprintf (stderr
, "\n");
9828 else if (INTERACTIVE
)
9830 /* The frame whose mini-buffer we're going to display the message
9831 on. It may be larger than the selected frame, so we need to
9832 use its buffer, not the selected frame's buffer. */
9833 Lisp_Object mini_window
;
9834 struct frame
*f
, *sf
= SELECTED_FRAME ();
9836 /* Get the frame containing the mini-buffer
9837 that the selected frame is using. */
9838 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
9839 f
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
9841 /* Error messages get reported properly by cmd_error, so this must be
9842 just an informative message; if the frame hasn't really been
9843 initialized yet, just toss it. */
9844 if (f
->glyphs_initialized_p
)
9849 ptrdiff_t maxsize
= FRAME_MESSAGE_BUF_SIZE (f
);
9850 char *message_buf
= alloca (maxsize
+ 1);
9852 len
= doprnt (message_buf
, maxsize
, m
, (char *)0, ap
);
9854 message3 (make_string (message_buf
, len
));
9859 /* Print should start at the beginning of the message
9860 buffer next time. */
9861 message_buf_print
= 0;
9867 message (const char *m
, ...)
9877 /* The non-logging version of message. */
9880 message_nolog (const char *m
, ...)
9882 Lisp_Object old_log_max
;
9885 old_log_max
= Vmessage_log_max
;
9886 Vmessage_log_max
= Qnil
;
9888 Vmessage_log_max
= old_log_max
;
9894 /* Display the current message in the current mini-buffer. This is
9895 only called from error handlers in process.c, and is not time
9899 update_echo_area (void)
9901 if (!NILP (echo_area_buffer
[0]))
9904 string
= Fcurrent_message ();
9910 /* Make sure echo area buffers in `echo_buffers' are live.
9911 If they aren't, make new ones. */
9914 ensure_echo_area_buffers (void)
9918 for (i
= 0; i
< 2; ++i
)
9919 if (!BUFFERP (echo_buffer
[i
])
9920 || !BUFFER_LIVE_P (XBUFFER (echo_buffer
[i
])))
9923 Lisp_Object old_buffer
;
9926 old_buffer
= echo_buffer
[i
];
9927 echo_buffer
[i
] = Fget_buffer_create
9928 (make_formatted_string (name
, " *Echo Area %d*", i
));
9929 bset_truncate_lines (XBUFFER (echo_buffer
[i
]), Qnil
);
9930 /* to force word wrap in echo area -
9931 it was decided to postpone this*/
9932 /* XBUFFER (echo_buffer[i])->word_wrap = Qt; */
9934 for (j
= 0; j
< 2; ++j
)
9935 if (EQ (old_buffer
, echo_area_buffer
[j
]))
9936 echo_area_buffer
[j
] = echo_buffer
[i
];
9941 /* Call FN with args A1..A2 with either the current or last displayed
9942 echo_area_buffer as current buffer.
9944 WHICH zero means use the current message buffer
9945 echo_area_buffer[0]. If that is nil, choose a suitable buffer
9946 from echo_buffer[] and clear it.
9948 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
9949 suitable buffer from echo_buffer[] and clear it.
9951 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
9952 that the current message becomes the last displayed one, make
9953 choose a suitable buffer for echo_area_buffer[0], and clear it.
9955 Value is what FN returns. */
9958 with_echo_area_buffer (struct window
*w
, int which
,
9959 int (*fn
) (ptrdiff_t, Lisp_Object
),
9960 ptrdiff_t a1
, Lisp_Object a2
)
9963 int this_one
, the_other
, clear_buffer_p
, rc
;
9964 ptrdiff_t count
= SPECPDL_INDEX ();
9966 /* If buffers aren't live, make new ones. */
9967 ensure_echo_area_buffers ();
9972 this_one
= 0, the_other
= 1;
9974 this_one
= 1, the_other
= 0;
9977 this_one
= 0, the_other
= 1;
9980 /* We need a fresh one in case the current echo buffer equals
9981 the one containing the last displayed echo area message. */
9982 if (!NILP (echo_area_buffer
[this_one
])
9983 && EQ (echo_area_buffer
[this_one
], echo_area_buffer
[the_other
]))
9984 echo_area_buffer
[this_one
] = Qnil
;
9987 /* Choose a suitable buffer from echo_buffer[] is we don't
9989 if (NILP (echo_area_buffer
[this_one
]))
9991 echo_area_buffer
[this_one
]
9992 = (EQ (echo_area_buffer
[the_other
], echo_buffer
[this_one
])
9993 ? echo_buffer
[the_other
]
9994 : echo_buffer
[this_one
]);
9998 buffer
= echo_area_buffer
[this_one
];
10000 /* Don't get confused by reusing the buffer used for echoing
10001 for a different purpose. */
10002 if (echo_kboard
== NULL
&& EQ (buffer
, echo_message_buffer
))
10005 record_unwind_protect (unwind_with_echo_area_buffer
,
10006 with_echo_area_buffer_unwind_data (w
));
10008 /* Make the echo area buffer current. Note that for display
10009 purposes, it is not necessary that the displayed window's buffer
10010 == current_buffer, except for text property lookup. So, let's
10011 only set that buffer temporarily here without doing a full
10012 Fset_window_buffer. We must also change w->pointm, though,
10013 because otherwise an assertions in unshow_buffer fails, and Emacs
10015 set_buffer_internal_1 (XBUFFER (buffer
));
10018 wset_buffer (w
, buffer
);
10019 set_marker_both (w
->pointm
, buffer
, BEG
, BEG_BYTE
);
10022 bset_undo_list (current_buffer
, Qt
);
10023 bset_read_only (current_buffer
, Qnil
);
10024 specbind (Qinhibit_read_only
, Qt
);
10025 specbind (Qinhibit_modification_hooks
, Qt
);
10027 if (clear_buffer_p
&& Z
> BEG
)
10028 del_range (BEG
, Z
);
10030 eassert (BEGV
>= BEG
);
10031 eassert (ZV
<= Z
&& ZV
>= BEGV
);
10035 eassert (BEGV
>= BEG
);
10036 eassert (ZV
<= Z
&& ZV
>= BEGV
);
10038 unbind_to (count
, Qnil
);
10043 /* Save state that should be preserved around the call to the function
10044 FN called in with_echo_area_buffer. */
10047 with_echo_area_buffer_unwind_data (struct window
*w
)
10050 Lisp_Object vector
, tmp
;
10052 /* Reduce consing by keeping one vector in
10053 Vwith_echo_area_save_vector. */
10054 vector
= Vwith_echo_area_save_vector
;
10055 Vwith_echo_area_save_vector
= Qnil
;
10058 vector
= Fmake_vector (make_number (9), Qnil
);
10060 XSETBUFFER (tmp
, current_buffer
); ASET (vector
, i
, tmp
); ++i
;
10061 ASET (vector
, i
, Vdeactivate_mark
); ++i
;
10062 ASET (vector
, i
, make_number (windows_or_buffers_changed
)); ++i
;
10066 XSETWINDOW (tmp
, w
); ASET (vector
, i
, tmp
); ++i
;
10067 ASET (vector
, i
, w
->contents
); ++i
;
10068 ASET (vector
, i
, make_number (marker_position (w
->pointm
))); ++i
;
10069 ASET (vector
, i
, make_number (marker_byte_position (w
->pointm
))); ++i
;
10070 ASET (vector
, i
, make_number (marker_position (w
->start
))); ++i
;
10071 ASET (vector
, i
, make_number (marker_byte_position (w
->start
))); ++i
;
10076 for (; i
< end
; ++i
)
10077 ASET (vector
, i
, Qnil
);
10080 eassert (i
== ASIZE (vector
));
10085 /* Restore global state from VECTOR which was created by
10086 with_echo_area_buffer_unwind_data. */
10089 unwind_with_echo_area_buffer (Lisp_Object vector
)
10091 set_buffer_internal_1 (XBUFFER (AREF (vector
, 0)));
10092 Vdeactivate_mark
= AREF (vector
, 1);
10093 windows_or_buffers_changed
= XFASTINT (AREF (vector
, 2));
10095 if (WINDOWP (AREF (vector
, 3)))
10098 Lisp_Object buffer
;
10100 w
= XWINDOW (AREF (vector
, 3));
10101 buffer
= AREF (vector
, 4);
10103 wset_buffer (w
, buffer
);
10104 set_marker_both (w
->pointm
, buffer
,
10105 XFASTINT (AREF (vector
, 5)),
10106 XFASTINT (AREF (vector
, 6)));
10107 set_marker_both (w
->start
, buffer
,
10108 XFASTINT (AREF (vector
, 7)),
10109 XFASTINT (AREF (vector
, 8)));
10112 Vwith_echo_area_save_vector
= vector
;
10117 /* Set up the echo area for use by print functions. MULTIBYTE_P
10118 non-zero means we will print multibyte. */
10121 setup_echo_area_for_printing (int multibyte_p
)
10123 /* If we can't find an echo area any more, exit. */
10124 if (! FRAME_LIVE_P (XFRAME (selected_frame
)))
10125 Fkill_emacs (Qnil
);
10127 ensure_echo_area_buffers ();
10129 if (!message_buf_print
)
10131 /* A message has been output since the last time we printed.
10132 Choose a fresh echo area buffer. */
10133 if (EQ (echo_area_buffer
[1], echo_buffer
[0]))
10134 echo_area_buffer
[0] = echo_buffer
[1];
10136 echo_area_buffer
[0] = echo_buffer
[0];
10138 /* Switch to that buffer and clear it. */
10139 set_buffer_internal (XBUFFER (echo_area_buffer
[0]));
10140 bset_truncate_lines (current_buffer
, Qnil
);
10144 ptrdiff_t count
= SPECPDL_INDEX ();
10145 specbind (Qinhibit_read_only
, Qt
);
10146 /* Note that undo recording is always disabled. */
10147 del_range (BEG
, Z
);
10148 unbind_to (count
, Qnil
);
10150 TEMP_SET_PT_BOTH (BEG
, BEG_BYTE
);
10152 /* Set up the buffer for the multibyteness we need. */
10154 != !NILP (BVAR (current_buffer
, enable_multibyte_characters
)))
10155 Fset_buffer_multibyte (multibyte_p
? Qt
: Qnil
);
10157 /* Raise the frame containing the echo area. */
10158 if (minibuffer_auto_raise
)
10160 struct frame
*sf
= SELECTED_FRAME ();
10161 Lisp_Object mini_window
;
10162 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
10163 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window
)));
10166 message_log_maybe_newline ();
10167 message_buf_print
= 1;
10171 if (NILP (echo_area_buffer
[0]))
10173 if (EQ (echo_area_buffer
[1], echo_buffer
[0]))
10174 echo_area_buffer
[0] = echo_buffer
[1];
10176 echo_area_buffer
[0] = echo_buffer
[0];
10179 if (current_buffer
!= XBUFFER (echo_area_buffer
[0]))
10181 /* Someone switched buffers between print requests. */
10182 set_buffer_internal (XBUFFER (echo_area_buffer
[0]));
10183 bset_truncate_lines (current_buffer
, Qnil
);
10189 /* Display an echo area message in window W. Value is non-zero if W's
10190 height is changed. If display_last_displayed_message_p is
10191 non-zero, display the message that was last displayed, otherwise
10192 display the current message. */
10195 display_echo_area (struct window
*w
)
10197 int i
, no_message_p
, window_height_changed_p
;
10199 /* Temporarily disable garbage collections while displaying the echo
10200 area. This is done because a GC can print a message itself.
10201 That message would modify the echo area buffer's contents while a
10202 redisplay of the buffer is going on, and seriously confuse
10204 ptrdiff_t count
= inhibit_garbage_collection ();
10206 /* If there is no message, we must call display_echo_area_1
10207 nevertheless because it resizes the window. But we will have to
10208 reset the echo_area_buffer in question to nil at the end because
10209 with_echo_area_buffer will sets it to an empty buffer. */
10210 i
= display_last_displayed_message_p
? 1 : 0;
10211 no_message_p
= NILP (echo_area_buffer
[i
]);
10213 window_height_changed_p
10214 = with_echo_area_buffer (w
, display_last_displayed_message_p
,
10215 display_echo_area_1
,
10216 (intptr_t) w
, Qnil
);
10219 echo_area_buffer
[i
] = Qnil
;
10221 unbind_to (count
, Qnil
);
10222 return window_height_changed_p
;
10226 /* Helper for display_echo_area. Display the current buffer which
10227 contains the current echo area message in window W, a mini-window,
10228 a pointer to which is passed in A1. A2..A4 are currently not used.
10229 Change the height of W so that all of the message is displayed.
10230 Value is non-zero if height of W was changed. */
10233 display_echo_area_1 (ptrdiff_t a1
, Lisp_Object a2
)
10236 struct window
*w
= (struct window
*) i1
;
10237 Lisp_Object window
;
10238 struct text_pos start
;
10239 int window_height_changed_p
= 0;
10241 /* Do this before displaying, so that we have a large enough glyph
10242 matrix for the display. If we can't get enough space for the
10243 whole text, display the last N lines. That works by setting w->start. */
10244 window_height_changed_p
= resize_mini_window (w
, 0);
10246 /* Use the starting position chosen by resize_mini_window. */
10247 SET_TEXT_POS_FROM_MARKER (start
, w
->start
);
10250 clear_glyph_matrix (w
->desired_matrix
);
10251 XSETWINDOW (window
, w
);
10252 try_window (window
, start
, 0);
10254 return window_height_changed_p
;
10258 /* Resize the echo area window to exactly the size needed for the
10259 currently displayed message, if there is one. If a mini-buffer
10260 is active, don't shrink it. */
10263 resize_echo_area_exactly (void)
10265 if (BUFFERP (echo_area_buffer
[0])
10266 && WINDOWP (echo_area_window
))
10268 struct window
*w
= XWINDOW (echo_area_window
);
10270 Lisp_Object resize_exactly
;
10272 if (minibuf_level
== 0)
10273 resize_exactly
= Qt
;
10275 resize_exactly
= Qnil
;
10277 resized_p
= with_echo_area_buffer (w
, 0, resize_mini_window_1
,
10278 (intptr_t) w
, resize_exactly
);
10281 ++windows_or_buffers_changed
;
10282 ++update_mode_lines
;
10283 redisplay_internal ();
10289 /* Callback function for with_echo_area_buffer, when used from
10290 resize_echo_area_exactly. A1 contains a pointer to the window to
10291 resize, EXACTLY non-nil means resize the mini-window exactly to the
10292 size of the text displayed. A3 and A4 are not used. Value is what
10293 resize_mini_window returns. */
10296 resize_mini_window_1 (ptrdiff_t a1
, Lisp_Object exactly
)
10299 return resize_mini_window ((struct window
*) i1
, !NILP (exactly
));
10303 /* Resize mini-window W to fit the size of its contents. EXACT_P
10304 means size the window exactly to the size needed. Otherwise, it's
10305 only enlarged until W's buffer is empty.
10307 Set W->start to the right place to begin display. If the whole
10308 contents fit, start at the beginning. Otherwise, start so as
10309 to make the end of the contents appear. This is particularly
10310 important for y-or-n-p, but seems desirable generally.
10312 Value is non-zero if the window height has been changed. */
10315 resize_mini_window (struct window
*w
, int exact_p
)
10317 struct frame
*f
= XFRAME (w
->frame
);
10318 int window_height_changed_p
= 0;
10320 eassert (MINI_WINDOW_P (w
));
10322 /* By default, start display at the beginning. */
10323 set_marker_both (w
->start
, w
->contents
,
10324 BUF_BEGV (XBUFFER (w
->contents
)),
10325 BUF_BEGV_BYTE (XBUFFER (w
->contents
)));
10327 /* Don't resize windows while redisplaying a window; it would
10328 confuse redisplay functions when the size of the window they are
10329 displaying changes from under them. Such a resizing can happen,
10330 for instance, when which-func prints a long message while
10331 we are running fontification-functions. We're running these
10332 functions with safe_call which binds inhibit-redisplay to t. */
10333 if (!NILP (Vinhibit_redisplay
))
10336 /* Nil means don't try to resize. */
10337 if (NILP (Vresize_mini_windows
)
10338 || (FRAME_X_P (f
) && FRAME_X_OUTPUT (f
) == NULL
))
10341 if (!FRAME_MINIBUF_ONLY_P (f
))
10344 struct window
*root
= XWINDOW (FRAME_ROOT_WINDOW (f
));
10345 int total_height
= WINDOW_TOTAL_LINES (root
) + WINDOW_TOTAL_LINES (w
);
10347 EMACS_INT max_height
;
10348 int unit
= FRAME_LINE_HEIGHT (f
);
10349 struct text_pos start
;
10350 struct buffer
*old_current_buffer
= NULL
;
10352 if (current_buffer
!= XBUFFER (w
->contents
))
10354 old_current_buffer
= current_buffer
;
10355 set_buffer_internal (XBUFFER (w
->contents
));
10358 init_iterator (&it
, w
, BEGV
, BEGV_BYTE
, NULL
, DEFAULT_FACE_ID
);
10360 /* Compute the max. number of lines specified by the user. */
10361 if (FLOATP (Vmax_mini_window_height
))
10362 max_height
= XFLOATINT (Vmax_mini_window_height
) * FRAME_LINES (f
);
10363 else if (INTEGERP (Vmax_mini_window_height
))
10364 max_height
= XINT (Vmax_mini_window_height
);
10366 max_height
= total_height
/ 4;
10368 /* Correct that max. height if it's bogus. */
10369 max_height
= clip_to_bounds (1, max_height
, total_height
);
10371 /* Find out the height of the text in the window. */
10372 if (it
.line_wrap
== TRUNCATE
)
10377 move_it_to (&it
, ZV
, -1, -1, -1, MOVE_TO_POS
);
10378 if (it
.max_ascent
== 0 && it
.max_descent
== 0)
10379 height
= it
.current_y
+ last_height
;
10381 height
= it
.current_y
+ it
.max_ascent
+ it
.max_descent
;
10382 height
-= min (it
.extra_line_spacing
, it
.max_extra_line_spacing
);
10383 height
= (height
+ unit
- 1) / unit
;
10386 /* Compute a suitable window start. */
10387 if (height
> max_height
)
10389 height
= max_height
;
10390 init_iterator (&it
, w
, ZV
, ZV_BYTE
, NULL
, DEFAULT_FACE_ID
);
10391 move_it_vertically_backward (&it
, (height
- 1) * unit
);
10392 start
= it
.current
.pos
;
10395 SET_TEXT_POS (start
, BEGV
, BEGV_BYTE
);
10396 SET_MARKER_FROM_TEXT_POS (w
->start
, start
);
10398 if (EQ (Vresize_mini_windows
, Qgrow_only
))
10400 /* Let it grow only, until we display an empty message, in which
10401 case the window shrinks again. */
10402 if (height
> WINDOW_TOTAL_LINES (w
))
10404 int old_height
= WINDOW_TOTAL_LINES (w
);
10405 freeze_window_starts (f
, 1);
10406 grow_mini_window (w
, height
- WINDOW_TOTAL_LINES (w
));
10407 window_height_changed_p
= WINDOW_TOTAL_LINES (w
) != old_height
;
10409 else if (height
< WINDOW_TOTAL_LINES (w
)
10410 && (exact_p
|| BEGV
== ZV
))
10412 int old_height
= WINDOW_TOTAL_LINES (w
);
10413 freeze_window_starts (f
, 0);
10414 shrink_mini_window (w
);
10415 window_height_changed_p
= WINDOW_TOTAL_LINES (w
) != old_height
;
10420 /* Always resize to exact size needed. */
10421 if (height
> WINDOW_TOTAL_LINES (w
))
10423 int old_height
= WINDOW_TOTAL_LINES (w
);
10424 freeze_window_starts (f
, 1);
10425 grow_mini_window (w
, height
- WINDOW_TOTAL_LINES (w
));
10426 window_height_changed_p
= WINDOW_TOTAL_LINES (w
) != old_height
;
10428 else if (height
< WINDOW_TOTAL_LINES (w
))
10430 int old_height
= WINDOW_TOTAL_LINES (w
);
10431 freeze_window_starts (f
, 0);
10432 shrink_mini_window (w
);
10436 freeze_window_starts (f
, 1);
10437 grow_mini_window (w
, height
- WINDOW_TOTAL_LINES (w
));
10440 window_height_changed_p
= WINDOW_TOTAL_LINES (w
) != old_height
;
10444 if (old_current_buffer
)
10445 set_buffer_internal (old_current_buffer
);
10448 return window_height_changed_p
;
10452 /* Value is the current message, a string, or nil if there is no
10453 current message. */
10456 current_message (void)
10460 if (!BUFFERP (echo_area_buffer
[0]))
10464 with_echo_area_buffer (0, 0, current_message_1
,
10465 (intptr_t) &msg
, Qnil
);
10467 echo_area_buffer
[0] = Qnil
;
10475 current_message_1 (ptrdiff_t a1
, Lisp_Object a2
)
10478 Lisp_Object
*msg
= (Lisp_Object
*) i1
;
10481 *msg
= make_buffer_string (BEG
, Z
, 1);
10488 /* Push the current message on Vmessage_stack for later restoration
10489 by restore_message. Value is non-zero if the current message isn't
10490 empty. This is a relatively infrequent operation, so it's not
10491 worth optimizing. */
10494 push_message (void)
10496 Lisp_Object msg
= current_message ();
10497 Vmessage_stack
= Fcons (msg
, Vmessage_stack
);
10498 return STRINGP (msg
);
10502 /* Restore message display from the top of Vmessage_stack. */
10505 restore_message (void)
10507 eassert (CONSP (Vmessage_stack
));
10508 message3_nolog (XCAR (Vmessage_stack
));
10512 /* Handler for record_unwind_protect calling pop_message. */
10515 pop_message_unwind (Lisp_Object dummy
)
10521 /* Pop the top-most entry off Vmessage_stack. */
10526 eassert (CONSP (Vmessage_stack
));
10527 Vmessage_stack
= XCDR (Vmessage_stack
);
10531 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
10532 exits. If the stack is not empty, we have a missing pop_message
10536 check_message_stack (void)
10538 if (!NILP (Vmessage_stack
))
10543 /* Truncate to NCHARS what will be displayed in the echo area the next
10544 time we display it---but don't redisplay it now. */
10547 truncate_echo_area (ptrdiff_t nchars
)
10550 echo_area_buffer
[0] = Qnil
;
10551 else if (!noninteractive
10553 && !NILP (echo_area_buffer
[0]))
10555 struct frame
*sf
= SELECTED_FRAME ();
10556 /* Error messages get reported properly by cmd_error, so this must be
10557 just an informative message; if the frame hasn't really been
10558 initialized yet, just toss it. */
10559 if (sf
->glyphs_initialized_p
)
10560 with_echo_area_buffer (0, 0, truncate_message_1
, nchars
, Qnil
);
10565 /* Helper function for truncate_echo_area. Truncate the current
10566 message to at most NCHARS characters. */
10569 truncate_message_1 (ptrdiff_t nchars
, Lisp_Object a2
)
10571 if (BEG
+ nchars
< Z
)
10572 del_range (BEG
+ nchars
, Z
);
10574 echo_area_buffer
[0] = Qnil
;
10578 /* Set the current message to STRING. */
10581 set_message (Lisp_Object string
)
10583 eassert (STRINGP (string
));
10585 message_enable_multibyte
= STRING_MULTIBYTE (string
);
10587 with_echo_area_buffer (0, -1, set_message_1
, 0, string
);
10588 message_buf_print
= 0;
10589 help_echo_showing_p
= 0;
10591 if (STRINGP (Vdebug_on_message
)
10592 && STRINGP (string
)
10593 && fast_string_match (Vdebug_on_message
, string
) >= 0)
10594 call_debugger (list2 (Qerror
, string
));
10598 /* Helper function for set_message. First argument is ignored and second
10599 argument has the same meaning as for set_message.
10600 This function is called with the echo area buffer being current. */
10603 set_message_1 (ptrdiff_t a1
, Lisp_Object string
)
10605 eassert (STRINGP (string
));
10607 /* Change multibyteness of the echo buffer appropriately. */
10608 if (message_enable_multibyte
10609 != !NILP (BVAR (current_buffer
, enable_multibyte_characters
)))
10610 Fset_buffer_multibyte (message_enable_multibyte
? Qt
: Qnil
);
10612 bset_truncate_lines (current_buffer
, message_truncate_lines
? Qt
: Qnil
);
10613 if (!NILP (BVAR (current_buffer
, bidi_display_reordering
)))
10614 bset_bidi_paragraph_direction (current_buffer
, Qleft_to_right
);
10616 /* Insert new message at BEG. */
10617 TEMP_SET_PT_BOTH (BEG
, BEG_BYTE
);
10619 /* This function takes care of single/multibyte conversion.
10620 We just have to ensure that the echo area buffer has the right
10621 setting of enable_multibyte_characters. */
10622 insert_from_string (string
, 0, 0, SCHARS (string
), SBYTES (string
), 1);
10628 /* Clear messages. CURRENT_P non-zero means clear the current
10629 message. LAST_DISPLAYED_P non-zero means clear the message
10633 clear_message (int current_p
, int last_displayed_p
)
10637 echo_area_buffer
[0] = Qnil
;
10638 message_cleared_p
= 1;
10641 if (last_displayed_p
)
10642 echo_area_buffer
[1] = Qnil
;
10644 message_buf_print
= 0;
10647 /* Clear garbaged frames.
10649 This function is used where the old redisplay called
10650 redraw_garbaged_frames which in turn called redraw_frame which in
10651 turn called clear_frame. The call to clear_frame was a source of
10652 flickering. I believe a clear_frame is not necessary. It should
10653 suffice in the new redisplay to invalidate all current matrices,
10654 and ensure a complete redisplay of all windows. */
10657 clear_garbaged_frames (void)
10659 if (frame_garbaged
)
10661 Lisp_Object tail
, frame
;
10662 int changed_count
= 0;
10664 FOR_EACH_FRAME (tail
, frame
)
10666 struct frame
*f
= XFRAME (frame
);
10668 if (FRAME_VISIBLE_P (f
) && FRAME_GARBAGED_P (f
))
10673 f
->force_flush_display_p
= 1;
10675 clear_current_matrices (f
);
10682 frame_garbaged
= 0;
10684 ++windows_or_buffers_changed
;
10689 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
10690 is non-zero update selected_frame. Value is non-zero if the
10691 mini-windows height has been changed. */
10694 echo_area_display (int update_frame_p
)
10696 Lisp_Object mini_window
;
10699 int window_height_changed_p
= 0;
10700 struct frame
*sf
= SELECTED_FRAME ();
10702 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
10703 w
= XWINDOW (mini_window
);
10704 f
= XFRAME (WINDOW_FRAME (w
));
10706 /* Don't display if frame is invisible or not yet initialized. */
10707 if (!FRAME_VISIBLE_P (f
) || !f
->glyphs_initialized_p
)
10710 #ifdef HAVE_WINDOW_SYSTEM
10711 /* When Emacs starts, selected_frame may be the initial terminal
10712 frame. If we let this through, a message would be displayed on
10714 if (FRAME_INITIAL_P (XFRAME (selected_frame
)))
10716 #endif /* HAVE_WINDOW_SYSTEM */
10718 /* Redraw garbaged frames. */
10719 clear_garbaged_frames ();
10721 if (!NILP (echo_area_buffer
[0]) || minibuf_level
== 0)
10723 echo_area_window
= mini_window
;
10724 window_height_changed_p
= display_echo_area (w
);
10725 w
->must_be_updated_p
= 1;
10727 /* Update the display, unless called from redisplay_internal.
10728 Also don't update the screen during redisplay itself. The
10729 update will happen at the end of redisplay, and an update
10730 here could cause confusion. */
10731 if (update_frame_p
&& !redisplaying_p
)
10735 /* If the display update has been interrupted by pending
10736 input, update mode lines in the frame. Due to the
10737 pending input, it might have been that redisplay hasn't
10738 been called, so that mode lines above the echo area are
10739 garbaged. This looks odd, so we prevent it here. */
10740 if (!display_completed
)
10741 n
= redisplay_mode_lines (FRAME_ROOT_WINDOW (f
), 0);
10743 if (window_height_changed_p
10744 /* Don't do this if Emacs is shutting down. Redisplay
10745 needs to run hooks. */
10746 && !NILP (Vrun_hooks
))
10748 /* Must update other windows. Likewise as in other
10749 cases, don't let this update be interrupted by
10751 ptrdiff_t count
= SPECPDL_INDEX ();
10752 specbind (Qredisplay_dont_pause
, Qt
);
10753 windows_or_buffers_changed
= 1;
10754 redisplay_internal ();
10755 unbind_to (count
, Qnil
);
10757 else if (FRAME_WINDOW_P (f
) && n
== 0)
10759 /* Window configuration is the same as before.
10760 Can do with a display update of the echo area,
10761 unless we displayed some mode lines. */
10762 update_single_window (w
, 1);
10763 FRAME_RIF (f
)->flush_display (f
);
10766 update_frame (f
, 1, 1);
10768 /* If cursor is in the echo area, make sure that the next
10769 redisplay displays the minibuffer, so that the cursor will
10770 be replaced with what the minibuffer wants. */
10771 if (cursor_in_echo_area
)
10772 ++windows_or_buffers_changed
;
10775 else if (!EQ (mini_window
, selected_window
))
10776 windows_or_buffers_changed
++;
10778 /* Last displayed message is now the current message. */
10779 echo_area_buffer
[1] = echo_area_buffer
[0];
10780 /* Inform read_char that we're not echoing. */
10781 echo_message_buffer
= Qnil
;
10783 /* Prevent redisplay optimization in redisplay_internal by resetting
10784 this_line_start_pos. This is done because the mini-buffer now
10785 displays the message instead of its buffer text. */
10786 if (EQ (mini_window
, selected_window
))
10787 CHARPOS (this_line_start_pos
) = 0;
10789 return window_height_changed_p
;
10792 /* Nonzero if the current window's buffer is shown in more than one
10793 window and was modified since last redisplay. */
10796 buffer_shared_and_changed (void)
10798 return (buffer_window_count (current_buffer
) > 1
10799 && UNCHANGED_MODIFIED
< MODIFF
);
10802 /* Nonzero if W doesn't reflect the actual state of current buffer due
10803 to its text or overlays change. FIXME: this may be called when
10804 XBUFFER (w->contents) != current_buffer, which looks suspicious. */
10807 window_outdated (struct window
*w
)
10809 return (w
->last_modified
< MODIFF
10810 || w
->last_overlay_modified
< OVERLAY_MODIFF
);
10813 /* Nonzero if W's buffer was changed but not saved or Transient Mark mode
10814 is enabled and mark of W's buffer was changed since last W's update. */
10817 window_buffer_changed (struct window
*w
)
10819 struct buffer
*b
= XBUFFER (w
->contents
);
10821 eassert (BUFFER_LIVE_P (b
));
10823 return (((BUF_SAVE_MODIFF (b
) < BUF_MODIFF (b
)) != w
->last_had_star
)
10824 || ((!NILP (Vtransient_mark_mode
) && !NILP (BVAR (b
, mark_active
)))
10825 != (w
->region_showing
!= 0)));
10828 /* Nonzero if W has %c in its mode line and mode line should be updated. */
10831 mode_line_update_needed (struct window
*w
)
10833 return (w
->column_number_displayed
!= -1
10834 && !(PT
== w
->last_point
&& !window_outdated (w
))
10835 && (w
->column_number_displayed
!= current_column ()));
10838 /***********************************************************************
10839 Mode Lines and Frame Titles
10840 ***********************************************************************/
10842 /* A buffer for constructing non-propertized mode-line strings and
10843 frame titles in it; allocated from the heap in init_xdisp and
10844 resized as needed in store_mode_line_noprop_char. */
10846 static char *mode_line_noprop_buf
;
10848 /* The buffer's end, and a current output position in it. */
10850 static char *mode_line_noprop_buf_end
;
10851 static char *mode_line_noprop_ptr
;
10853 #define MODE_LINE_NOPROP_LEN(start) \
10854 ((mode_line_noprop_ptr - mode_line_noprop_buf) - start)
10857 MODE_LINE_DISPLAY
= 0,
10861 } mode_line_target
;
10863 /* Alist that caches the results of :propertize.
10864 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
10865 static Lisp_Object mode_line_proptrans_alist
;
10867 /* List of strings making up the mode-line. */
10868 static Lisp_Object mode_line_string_list
;
10870 /* Base face property when building propertized mode line string. */
10871 static Lisp_Object mode_line_string_face
;
10872 static Lisp_Object mode_line_string_face_prop
;
10875 /* Unwind data for mode line strings */
10877 static Lisp_Object Vmode_line_unwind_vector
;
10880 format_mode_line_unwind_data (struct frame
*target_frame
,
10881 struct buffer
*obuf
,
10883 int save_proptrans
)
10885 Lisp_Object vector
, tmp
;
10887 /* Reduce consing by keeping one vector in
10888 Vwith_echo_area_save_vector. */
10889 vector
= Vmode_line_unwind_vector
;
10890 Vmode_line_unwind_vector
= Qnil
;
10893 vector
= Fmake_vector (make_number (10), Qnil
);
10895 ASET (vector
, 0, make_number (mode_line_target
));
10896 ASET (vector
, 1, make_number (MODE_LINE_NOPROP_LEN (0)));
10897 ASET (vector
, 2, mode_line_string_list
);
10898 ASET (vector
, 3, save_proptrans
? mode_line_proptrans_alist
: Qt
);
10899 ASET (vector
, 4, mode_line_string_face
);
10900 ASET (vector
, 5, mode_line_string_face_prop
);
10903 XSETBUFFER (tmp
, obuf
);
10906 ASET (vector
, 6, tmp
);
10907 ASET (vector
, 7, owin
);
10910 /* Similarly to `with-selected-window', if the operation selects
10911 a window on another frame, we must restore that frame's
10912 selected window, and (for a tty) the top-frame. */
10913 ASET (vector
, 8, target_frame
->selected_window
);
10914 if (FRAME_TERMCAP_P (target_frame
))
10915 ASET (vector
, 9, FRAME_TTY (target_frame
)->top_frame
);
10922 unwind_format_mode_line (Lisp_Object vector
)
10924 Lisp_Object old_window
= AREF (vector
, 7);
10925 Lisp_Object target_frame_window
= AREF (vector
, 8);
10926 Lisp_Object old_top_frame
= AREF (vector
, 9);
10928 mode_line_target
= XINT (AREF (vector
, 0));
10929 mode_line_noprop_ptr
= mode_line_noprop_buf
+ XINT (AREF (vector
, 1));
10930 mode_line_string_list
= AREF (vector
, 2);
10931 if (! EQ (AREF (vector
, 3), Qt
))
10932 mode_line_proptrans_alist
= AREF (vector
, 3);
10933 mode_line_string_face
= AREF (vector
, 4);
10934 mode_line_string_face_prop
= AREF (vector
, 5);
10936 /* Select window before buffer, since it may change the buffer. */
10937 if (!NILP (old_window
))
10939 /* If the operation that we are unwinding had selected a window
10940 on a different frame, reset its frame-selected-window. For a
10941 text terminal, reset its top-frame if necessary. */
10942 if (!NILP (target_frame_window
))
10945 = WINDOW_FRAME (XWINDOW (target_frame_window
));
10947 if (!EQ (frame
, WINDOW_FRAME (XWINDOW (old_window
))))
10948 Fselect_window (target_frame_window
, Qt
);
10950 if (!NILP (old_top_frame
) && !EQ (old_top_frame
, frame
))
10951 Fselect_frame (old_top_frame
, Qt
);
10954 Fselect_window (old_window
, Qt
);
10957 if (!NILP (AREF (vector
, 6)))
10959 set_buffer_internal_1 (XBUFFER (AREF (vector
, 6)));
10960 ASET (vector
, 6, Qnil
);
10963 Vmode_line_unwind_vector
= vector
;
10968 /* Store a single character C for the frame title in mode_line_noprop_buf.
10969 Re-allocate mode_line_noprop_buf if necessary. */
10972 store_mode_line_noprop_char (char c
)
10974 /* If output position has reached the end of the allocated buffer,
10975 increase the buffer's size. */
10976 if (mode_line_noprop_ptr
== mode_line_noprop_buf_end
)
10978 ptrdiff_t len
= MODE_LINE_NOPROP_LEN (0);
10979 ptrdiff_t size
= len
;
10980 mode_line_noprop_buf
=
10981 xpalloc (mode_line_noprop_buf
, &size
, 1, STRING_BYTES_BOUND
, 1);
10982 mode_line_noprop_buf_end
= mode_line_noprop_buf
+ size
;
10983 mode_line_noprop_ptr
= mode_line_noprop_buf
+ len
;
10986 *mode_line_noprop_ptr
++ = c
;
10990 /* Store part of a frame title in mode_line_noprop_buf, beginning at
10991 mode_line_noprop_ptr. STRING is the string to store. Do not copy
10992 characters that yield more columns than PRECISION; PRECISION <= 0
10993 means copy the whole string. Pad with spaces until FIELD_WIDTH
10994 number of characters have been copied; FIELD_WIDTH <= 0 means don't
10995 pad. Called from display_mode_element when it is used to build a
10999 store_mode_line_noprop (const char *string
, int field_width
, int precision
)
11001 const unsigned char *str
= (const unsigned char *) string
;
11003 ptrdiff_t dummy
, nbytes
;
11005 /* Copy at most PRECISION chars from STR. */
11006 nbytes
= strlen (string
);
11007 n
+= c_string_width (str
, nbytes
, precision
, &dummy
, &nbytes
);
11009 store_mode_line_noprop_char (*str
++);
11011 /* Fill up with spaces until FIELD_WIDTH reached. */
11012 while (field_width
> 0
11013 && n
< field_width
)
11015 store_mode_line_noprop_char (' ');
11022 /***********************************************************************
11024 ***********************************************************************/
11026 #ifdef HAVE_WINDOW_SYSTEM
11028 /* Set the title of FRAME, if it has changed. The title format is
11029 Vicon_title_format if FRAME is iconified, otherwise it is
11030 frame_title_format. */
11033 x_consider_frame_title (Lisp_Object frame
)
11035 struct frame
*f
= XFRAME (frame
);
11037 if (FRAME_WINDOW_P (f
)
11038 || FRAME_MINIBUF_ONLY_P (f
)
11039 || f
->explicit_name
)
11041 /* Do we have more than one visible frame on this X display? */
11042 Lisp_Object tail
, other_frame
, fmt
;
11043 ptrdiff_t title_start
;
11047 ptrdiff_t count
= SPECPDL_INDEX ();
11049 FOR_EACH_FRAME (tail
, other_frame
)
11051 struct frame
*tf
= XFRAME (other_frame
);
11054 && FRAME_KBOARD (tf
) == FRAME_KBOARD (f
)
11055 && !FRAME_MINIBUF_ONLY_P (tf
)
11056 && !EQ (other_frame
, tip_frame
)
11057 && (FRAME_VISIBLE_P (tf
) || FRAME_ICONIFIED_P (tf
)))
11061 /* Set global variable indicating that multiple frames exist. */
11062 multiple_frames
= CONSP (tail
);
11064 /* Switch to the buffer of selected window of the frame. Set up
11065 mode_line_target so that display_mode_element will output into
11066 mode_line_noprop_buf; then display the title. */
11067 record_unwind_protect (unwind_format_mode_line
,
11068 format_mode_line_unwind_data
11069 (f
, current_buffer
, selected_window
, 0));
11071 Fselect_window (f
->selected_window
, Qt
);
11072 set_buffer_internal_1
11073 (XBUFFER (XWINDOW (f
->selected_window
)->contents
));
11074 fmt
= FRAME_ICONIFIED_P (f
) ? Vicon_title_format
: Vframe_title_format
;
11076 mode_line_target
= MODE_LINE_TITLE
;
11077 title_start
= MODE_LINE_NOPROP_LEN (0);
11078 init_iterator (&it
, XWINDOW (f
->selected_window
), -1, -1,
11079 NULL
, DEFAULT_FACE_ID
);
11080 display_mode_element (&it
, 0, -1, -1, fmt
, Qnil
, 0);
11081 len
= MODE_LINE_NOPROP_LEN (title_start
);
11082 title
= mode_line_noprop_buf
+ title_start
;
11083 unbind_to (count
, Qnil
);
11085 /* Set the title only if it's changed. This avoids consing in
11086 the common case where it hasn't. (If it turns out that we've
11087 already wasted too much time by walking through the list with
11088 display_mode_element, then we might need to optimize at a
11089 higher level than this.) */
11090 if (! STRINGP (f
->name
)
11091 || SBYTES (f
->name
) != len
11092 || memcmp (title
, SDATA (f
->name
), len
) != 0)
11093 x_implicitly_set_name (f
, make_string (title
, len
), Qnil
);
11097 #endif /* not HAVE_WINDOW_SYSTEM */
11100 /***********************************************************************
11102 ***********************************************************************/
11105 /* Prepare for redisplay by updating menu-bar item lists when
11106 appropriate. This can call eval. */
11109 prepare_menu_bars (void)
11112 struct gcpro gcpro1
, gcpro2
;
11114 Lisp_Object tooltip_frame
;
11116 #ifdef HAVE_WINDOW_SYSTEM
11117 tooltip_frame
= tip_frame
;
11119 tooltip_frame
= Qnil
;
11122 /* Update all frame titles based on their buffer names, etc. We do
11123 this before the menu bars so that the buffer-menu will show the
11124 up-to-date frame titles. */
11125 #ifdef HAVE_WINDOW_SYSTEM
11126 if (windows_or_buffers_changed
|| update_mode_lines
)
11128 Lisp_Object tail
, frame
;
11130 FOR_EACH_FRAME (tail
, frame
)
11132 f
= XFRAME (frame
);
11133 if (!EQ (frame
, tooltip_frame
)
11134 && (FRAME_VISIBLE_P (f
) || FRAME_ICONIFIED_P (f
)))
11135 x_consider_frame_title (frame
);
11138 #endif /* HAVE_WINDOW_SYSTEM */
11140 /* Update the menu bar item lists, if appropriate. This has to be
11141 done before any actual redisplay or generation of display lines. */
11142 all_windows
= (update_mode_lines
11143 || buffer_shared_and_changed ()
11144 || windows_or_buffers_changed
);
11147 Lisp_Object tail
, frame
;
11148 ptrdiff_t count
= SPECPDL_INDEX ();
11149 /* 1 means that update_menu_bar has run its hooks
11150 so any further calls to update_menu_bar shouldn't do so again. */
11151 int menu_bar_hooks_run
= 0;
11153 record_unwind_save_match_data ();
11155 FOR_EACH_FRAME (tail
, frame
)
11157 f
= XFRAME (frame
);
11159 /* Ignore tooltip frame. */
11160 if (EQ (frame
, tooltip_frame
))
11163 /* If a window on this frame changed size, report that to
11164 the user and clear the size-change flag. */
11165 if (FRAME_WINDOW_SIZES_CHANGED (f
))
11167 Lisp_Object functions
;
11169 /* Clear flag first in case we get an error below. */
11170 FRAME_WINDOW_SIZES_CHANGED (f
) = 0;
11171 functions
= Vwindow_size_change_functions
;
11172 GCPRO2 (tail
, functions
);
11174 while (CONSP (functions
))
11176 if (!EQ (XCAR (functions
), Qt
))
11177 call1 (XCAR (functions
), frame
);
11178 functions
= XCDR (functions
);
11184 menu_bar_hooks_run
= update_menu_bar (f
, 0, menu_bar_hooks_run
);
11185 #ifdef HAVE_WINDOW_SYSTEM
11186 update_tool_bar (f
, 0);
11189 if (windows_or_buffers_changed
11192 (f
, Fbuffer_modified_p (XWINDOW (f
->selected_window
)->contents
));
11197 unbind_to (count
, Qnil
);
11201 struct frame
*sf
= SELECTED_FRAME ();
11202 update_menu_bar (sf
, 1, 0);
11203 #ifdef HAVE_WINDOW_SYSTEM
11204 update_tool_bar (sf
, 1);
11210 /* Update the menu bar item list for frame F. This has to be done
11211 before we start to fill in any display lines, because it can call
11214 If SAVE_MATCH_DATA is non-zero, we must save and restore it here.
11216 If HOOKS_RUN is 1, that means a previous call to update_menu_bar
11217 already ran the menu bar hooks for this redisplay, so there
11218 is no need to run them again. The return value is the
11219 updated value of this flag, to pass to the next call. */
11222 update_menu_bar (struct frame
*f
, int save_match_data
, int hooks_run
)
11224 Lisp_Object window
;
11225 register struct window
*w
;
11227 /* If called recursively during a menu update, do nothing. This can
11228 happen when, for instance, an activate-menubar-hook causes a
11230 if (inhibit_menubar_update
)
11233 window
= FRAME_SELECTED_WINDOW (f
);
11234 w
= XWINDOW (window
);
11236 if (FRAME_WINDOW_P (f
)
11238 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
11239 || defined (HAVE_NS) || defined (USE_GTK)
11240 FRAME_EXTERNAL_MENU_BAR (f
)
11242 FRAME_MENU_BAR_LINES (f
) > 0
11244 : FRAME_MENU_BAR_LINES (f
) > 0)
11246 /* If the user has switched buffers or windows, we need to
11247 recompute to reflect the new bindings. But we'll
11248 recompute when update_mode_lines is set too; that means
11249 that people can use force-mode-line-update to request
11250 that the menu bar be recomputed. The adverse effect on
11251 the rest of the redisplay algorithm is about the same as
11252 windows_or_buffers_changed anyway. */
11253 if (windows_or_buffers_changed
11254 /* This used to test w->update_mode_line, but we believe
11255 there is no need to recompute the menu in that case. */
11256 || update_mode_lines
11257 || window_buffer_changed (w
))
11259 struct buffer
*prev
= current_buffer
;
11260 ptrdiff_t count
= SPECPDL_INDEX ();
11262 specbind (Qinhibit_menubar_update
, Qt
);
11264 set_buffer_internal_1 (XBUFFER (w
->contents
));
11265 if (save_match_data
)
11266 record_unwind_save_match_data ();
11267 if (NILP (Voverriding_local_map_menu_flag
))
11269 specbind (Qoverriding_terminal_local_map
, Qnil
);
11270 specbind (Qoverriding_local_map
, Qnil
);
11275 /* Run the Lucid hook. */
11276 safe_run_hooks (Qactivate_menubar_hook
);
11278 /* If it has changed current-menubar from previous value,
11279 really recompute the menu-bar from the value. */
11280 if (! NILP (Vlucid_menu_bar_dirty_flag
))
11281 call0 (Qrecompute_lucid_menubar
);
11283 safe_run_hooks (Qmenu_bar_update_hook
);
11288 XSETFRAME (Vmenu_updating_frame
, f
);
11289 fset_menu_bar_items (f
, menu_bar_items (FRAME_MENU_BAR_ITEMS (f
)));
11291 /* Redisplay the menu bar in case we changed it. */
11292 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
11293 || defined (HAVE_NS) || defined (USE_GTK)
11294 if (FRAME_WINDOW_P (f
))
11296 #if defined (HAVE_NS)
11297 /* All frames on Mac OS share the same menubar. So only
11298 the selected frame should be allowed to set it. */
11299 if (f
== SELECTED_FRAME ())
11301 set_frame_menubar (f
, 0, 0);
11304 /* On a terminal screen, the menu bar is an ordinary screen
11305 line, and this makes it get updated. */
11306 w
->update_mode_line
= 1;
11307 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
11308 /* In the non-toolkit version, the menu bar is an ordinary screen
11309 line, and this makes it get updated. */
11310 w
->update_mode_line
= 1;
11311 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
11313 unbind_to (count
, Qnil
);
11314 set_buffer_internal_1 (prev
);
11323 /***********************************************************************
11325 ***********************************************************************/
11327 #ifdef HAVE_WINDOW_SYSTEM
11330 Nominal cursor position -- where to draw output.
11331 HPOS and VPOS are window relative glyph matrix coordinates.
11332 X and Y are window relative pixel coordinates. */
11334 struct cursor_pos output_cursor
;
11338 Set the global variable output_cursor to CURSOR. All cursor
11339 positions are relative to updated_window. */
11342 set_output_cursor (struct cursor_pos
*cursor
)
11344 output_cursor
.hpos
= cursor
->hpos
;
11345 output_cursor
.vpos
= cursor
->vpos
;
11346 output_cursor
.x
= cursor
->x
;
11347 output_cursor
.y
= cursor
->y
;
11352 Set a nominal cursor position.
11354 HPOS and VPOS are column/row positions in a window glyph matrix. X
11355 and Y are window text area relative pixel positions.
11357 If this is done during an update, updated_window will contain the
11358 window that is being updated and the position is the future output
11359 cursor position for that window. If updated_window is null, use
11360 selected_window and display the cursor at the given position. */
11363 x_cursor_to (int vpos
, int hpos
, int y
, int x
)
11367 /* If updated_window is not set, work on selected_window. */
11368 if (updated_window
)
11369 w
= updated_window
;
11371 w
= XWINDOW (selected_window
);
11373 /* Set the output cursor. */
11374 output_cursor
.hpos
= hpos
;
11375 output_cursor
.vpos
= vpos
;
11376 output_cursor
.x
= x
;
11377 output_cursor
.y
= y
;
11379 /* If not called as part of an update, really display the cursor.
11380 This will also set the cursor position of W. */
11381 if (updated_window
== NULL
)
11384 display_and_set_cursor (w
, 1, hpos
, vpos
, x
, y
);
11385 if (FRAME_RIF (SELECTED_FRAME ())->flush_display_optional
)
11386 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (SELECTED_FRAME ());
11391 #endif /* HAVE_WINDOW_SYSTEM */
11394 /***********************************************************************
11396 ***********************************************************************/
11398 #ifdef HAVE_WINDOW_SYSTEM
11400 /* Where the mouse was last time we reported a mouse event. */
11402 FRAME_PTR last_mouse_frame
;
11404 /* Tool-bar item index of the item on which a mouse button was pressed
11407 int last_tool_bar_item
;
11409 /* Select `frame' temporarily without running all the code in
11411 FIXME: Maybe do_switch_frame should be trimmed down similarly
11412 when `norecord' is set. */
11414 fast_set_selected_frame (Lisp_Object frame
)
11416 if (!EQ (selected_frame
, frame
))
11418 selected_frame
= frame
;
11419 selected_window
= XFRAME (frame
)->selected_window
;
11424 /* Update the tool-bar item list for frame F. This has to be done
11425 before we start to fill in any display lines. Called from
11426 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
11427 and restore it here. */
11430 update_tool_bar (struct frame
*f
, int save_match_data
)
11432 #if defined (USE_GTK) || defined (HAVE_NS)
11433 int do_update
= FRAME_EXTERNAL_TOOL_BAR (f
);
11435 int do_update
= WINDOWP (f
->tool_bar_window
)
11436 && WINDOW_TOTAL_LINES (XWINDOW (f
->tool_bar_window
)) > 0;
11441 Lisp_Object window
;
11444 window
= FRAME_SELECTED_WINDOW (f
);
11445 w
= XWINDOW (window
);
11447 /* If the user has switched buffers or windows, we need to
11448 recompute to reflect the new bindings. But we'll
11449 recompute when update_mode_lines is set too; that means
11450 that people can use force-mode-line-update to request
11451 that the menu bar be recomputed. The adverse effect on
11452 the rest of the redisplay algorithm is about the same as
11453 windows_or_buffers_changed anyway. */
11454 if (windows_or_buffers_changed
11455 || w
->update_mode_line
11456 || update_mode_lines
11457 || window_buffer_changed (w
))
11459 struct buffer
*prev
= current_buffer
;
11460 ptrdiff_t count
= SPECPDL_INDEX ();
11461 Lisp_Object frame
, new_tool_bar
;
11462 int new_n_tool_bar
;
11463 struct gcpro gcpro1
;
11465 /* Set current_buffer to the buffer of the selected
11466 window of the frame, so that we get the right local
11468 set_buffer_internal_1 (XBUFFER (w
->contents
));
11470 /* Save match data, if we must. */
11471 if (save_match_data
)
11472 record_unwind_save_match_data ();
11474 /* Make sure that we don't accidentally use bogus keymaps. */
11475 if (NILP (Voverriding_local_map_menu_flag
))
11477 specbind (Qoverriding_terminal_local_map
, Qnil
);
11478 specbind (Qoverriding_local_map
, Qnil
);
11481 GCPRO1 (new_tool_bar
);
11483 /* We must temporarily set the selected frame to this frame
11484 before calling tool_bar_items, because the calculation of
11485 the tool-bar keymap uses the selected frame (see
11486 `tool-bar-make-keymap' in tool-bar.el). */
11487 eassert (EQ (selected_window
,
11488 /* Since we only explicitly preserve selected_frame,
11489 check that selected_window would be redundant. */
11490 XFRAME (selected_frame
)->selected_window
));
11491 record_unwind_protect (fast_set_selected_frame
, selected_frame
);
11492 XSETFRAME (frame
, f
);
11493 fast_set_selected_frame (frame
);
11495 /* Build desired tool-bar items from keymaps. */
11497 = tool_bar_items (Fcopy_sequence (f
->tool_bar_items
),
11500 /* Redisplay the tool-bar if we changed it. */
11501 if (new_n_tool_bar
!= f
->n_tool_bar_items
11502 || NILP (Fequal (new_tool_bar
, f
->tool_bar_items
)))
11504 /* Redisplay that happens asynchronously due to an expose event
11505 may access f->tool_bar_items. Make sure we update both
11506 variables within BLOCK_INPUT so no such event interrupts. */
11508 fset_tool_bar_items (f
, new_tool_bar
);
11509 f
->n_tool_bar_items
= new_n_tool_bar
;
11510 w
->update_mode_line
= 1;
11516 unbind_to (count
, Qnil
);
11517 set_buffer_internal_1 (prev
);
11523 /* Set F->desired_tool_bar_string to a Lisp string representing frame
11524 F's desired tool-bar contents. F->tool_bar_items must have
11525 been set up previously by calling prepare_menu_bars. */
11528 build_desired_tool_bar_string (struct frame
*f
)
11530 int i
, size
, size_needed
;
11531 struct gcpro gcpro1
, gcpro2
, gcpro3
;
11532 Lisp_Object image
, plist
, props
;
11534 image
= plist
= props
= Qnil
;
11535 GCPRO3 (image
, plist
, props
);
11537 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
11538 Otherwise, make a new string. */
11540 /* The size of the string we might be able to reuse. */
11541 size
= (STRINGP (f
->desired_tool_bar_string
)
11542 ? SCHARS (f
->desired_tool_bar_string
)
11545 /* We need one space in the string for each image. */
11546 size_needed
= f
->n_tool_bar_items
;
11548 /* Reuse f->desired_tool_bar_string, if possible. */
11549 if (size
< size_needed
|| NILP (f
->desired_tool_bar_string
))
11550 fset_desired_tool_bar_string
11551 (f
, Fmake_string (make_number (size_needed
), make_number (' ')));
11554 props
= list4 (Qdisplay
, Qnil
, Qmenu_item
, Qnil
);
11555 Fremove_text_properties (make_number (0), make_number (size
),
11556 props
, f
->desired_tool_bar_string
);
11559 /* Put a `display' property on the string for the images to display,
11560 put a `menu_item' property on tool-bar items with a value that
11561 is the index of the item in F's tool-bar item vector. */
11562 for (i
= 0; i
< f
->n_tool_bar_items
; ++i
)
11564 #define PROP(IDX) \
11565 AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
11567 int enabled_p
= !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P
));
11568 int selected_p
= !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P
));
11569 int hmargin
, vmargin
, relief
, idx
, end
;
11571 /* If image is a vector, choose the image according to the
11573 image
= PROP (TOOL_BAR_ITEM_IMAGES
);
11574 if (VECTORP (image
))
11578 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
11579 : TOOL_BAR_IMAGE_ENABLED_DESELECTED
);
11582 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
11583 : TOOL_BAR_IMAGE_DISABLED_DESELECTED
);
11585 eassert (ASIZE (image
) >= idx
);
11586 image
= AREF (image
, idx
);
11591 /* Ignore invalid image specifications. */
11592 if (!valid_image_p (image
))
11595 /* Display the tool-bar button pressed, or depressed. */
11596 plist
= Fcopy_sequence (XCDR (image
));
11598 /* Compute margin and relief to draw. */
11599 relief
= (tool_bar_button_relief
>= 0
11600 ? tool_bar_button_relief
11601 : DEFAULT_TOOL_BAR_BUTTON_RELIEF
);
11602 hmargin
= vmargin
= relief
;
11604 if (RANGED_INTEGERP (1, Vtool_bar_button_margin
,
11605 INT_MAX
- max (hmargin
, vmargin
)))
11607 hmargin
+= XFASTINT (Vtool_bar_button_margin
);
11608 vmargin
+= XFASTINT (Vtool_bar_button_margin
);
11610 else if (CONSP (Vtool_bar_button_margin
))
11612 if (RANGED_INTEGERP (1, XCAR (Vtool_bar_button_margin
),
11613 INT_MAX
- hmargin
))
11614 hmargin
+= XFASTINT (XCAR (Vtool_bar_button_margin
));
11616 if (RANGED_INTEGERP (1, XCDR (Vtool_bar_button_margin
),
11617 INT_MAX
- vmargin
))
11618 vmargin
+= XFASTINT (XCDR (Vtool_bar_button_margin
));
11621 if (auto_raise_tool_bar_buttons_p
)
11623 /* Add a `:relief' property to the image spec if the item is
11627 plist
= Fplist_put (plist
, QCrelief
, make_number (-relief
));
11634 /* If image is selected, display it pressed, i.e. with a
11635 negative relief. If it's not selected, display it with a
11637 plist
= Fplist_put (plist
, QCrelief
,
11639 ? make_number (-relief
)
11640 : make_number (relief
)));
11645 /* Put a margin around the image. */
11646 if (hmargin
|| vmargin
)
11648 if (hmargin
== vmargin
)
11649 plist
= Fplist_put (plist
, QCmargin
, make_number (hmargin
));
11651 plist
= Fplist_put (plist
, QCmargin
,
11652 Fcons (make_number (hmargin
),
11653 make_number (vmargin
)));
11656 /* If button is not enabled, and we don't have special images
11657 for the disabled state, make the image appear disabled by
11658 applying an appropriate algorithm to it. */
11659 if (!enabled_p
&& idx
< 0)
11660 plist
= Fplist_put (plist
, QCconversion
, Qdisabled
);
11662 /* Put a `display' text property on the string for the image to
11663 display. Put a `menu-item' property on the string that gives
11664 the start of this item's properties in the tool-bar items
11666 image
= Fcons (Qimage
, plist
);
11667 props
= list4 (Qdisplay
, image
,
11668 Qmenu_item
, make_number (i
* TOOL_BAR_ITEM_NSLOTS
));
11670 /* Let the last image hide all remaining spaces in the tool bar
11671 string. The string can be longer than needed when we reuse a
11672 previous string. */
11673 if (i
+ 1 == f
->n_tool_bar_items
)
11674 end
= SCHARS (f
->desired_tool_bar_string
);
11677 Fadd_text_properties (make_number (i
), make_number (end
),
11678 props
, f
->desired_tool_bar_string
);
11686 /* Display one line of the tool-bar of frame IT->f.
11688 HEIGHT specifies the desired height of the tool-bar line.
11689 If the actual height of the glyph row is less than HEIGHT, the
11690 row's height is increased to HEIGHT, and the icons are centered
11691 vertically in the new height.
11693 If HEIGHT is -1, we are counting needed tool-bar lines, so don't
11694 count a final empty row in case the tool-bar width exactly matches
11699 display_tool_bar_line (struct it
*it
, int height
)
11701 struct glyph_row
*row
= it
->glyph_row
;
11702 int max_x
= it
->last_visible_x
;
11703 struct glyph
*last
;
11705 prepare_desired_row (row
);
11706 row
->y
= it
->current_y
;
11708 /* Note that this isn't made use of if the face hasn't a box,
11709 so there's no need to check the face here. */
11710 it
->start_of_box_run_p
= 1;
11712 while (it
->current_x
< max_x
)
11714 int x
, n_glyphs_before
, i
, nglyphs
;
11715 struct it it_before
;
11717 /* Get the next display element. */
11718 if (!get_next_display_element (it
))
11720 /* Don't count empty row if we are counting needed tool-bar lines. */
11721 if (height
< 0 && !it
->hpos
)
11726 /* Produce glyphs. */
11727 n_glyphs_before
= row
->used
[TEXT_AREA
];
11730 PRODUCE_GLYPHS (it
);
11732 nglyphs
= row
->used
[TEXT_AREA
] - n_glyphs_before
;
11734 x
= it_before
.current_x
;
11735 while (i
< nglyphs
)
11737 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
] + n_glyphs_before
+ i
;
11739 if (x
+ glyph
->pixel_width
> max_x
)
11741 /* Glyph doesn't fit on line. Backtrack. */
11742 row
->used
[TEXT_AREA
] = n_glyphs_before
;
11744 /* If this is the only glyph on this line, it will never fit on the
11745 tool-bar, so skip it. But ensure there is at least one glyph,
11746 so we don't accidentally disable the tool-bar. */
11747 if (n_glyphs_before
== 0
11748 && (it
->vpos
> 0 || IT_STRING_CHARPOS (*it
) < it
->end_charpos
-1))
11754 x
+= glyph
->pixel_width
;
11758 /* Stop at line end. */
11759 if (ITERATOR_AT_END_OF_LINE_P (it
))
11762 set_iterator_to_next (it
, 1);
11767 row
->displays_text_p
= row
->used
[TEXT_AREA
] != 0;
11769 /* Use default face for the border below the tool bar.
11771 FIXME: When auto-resize-tool-bars is grow-only, there is
11772 no additional border below the possibly empty tool-bar lines.
11773 So to make the extra empty lines look "normal", we have to
11774 use the tool-bar face for the border too. */
11775 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row
)
11776 && !EQ (Vauto_resize_tool_bars
, Qgrow_only
))
11777 it
->face_id
= DEFAULT_FACE_ID
;
11779 extend_face_to_end_of_line (it
);
11780 last
= row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
] - 1;
11781 last
->right_box_line_p
= 1;
11782 if (last
== row
->glyphs
[TEXT_AREA
])
11783 last
->left_box_line_p
= 1;
11785 /* Make line the desired height and center it vertically. */
11786 if ((height
-= it
->max_ascent
+ it
->max_descent
) > 0)
11788 /* Don't add more than one line height. */
11789 height
%= FRAME_LINE_HEIGHT (it
->f
);
11790 it
->max_ascent
+= height
/ 2;
11791 it
->max_descent
+= (height
+ 1) / 2;
11794 compute_line_metrics (it
);
11796 /* If line is empty, make it occupy the rest of the tool-bar. */
11797 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row
))
11799 row
->height
= row
->phys_height
= it
->last_visible_y
- row
->y
;
11800 row
->visible_height
= row
->height
;
11801 row
->ascent
= row
->phys_ascent
= 0;
11802 row
->extra_line_spacing
= 0;
11805 row
->full_width_p
= 1;
11806 row
->continued_p
= 0;
11807 row
->truncated_on_left_p
= 0;
11808 row
->truncated_on_right_p
= 0;
11810 it
->current_x
= it
->hpos
= 0;
11811 it
->current_y
+= row
->height
;
11817 /* Max tool-bar height. */
11819 #define MAX_FRAME_TOOL_BAR_HEIGHT(f) \
11820 ((FRAME_LINE_HEIGHT (f) * FRAME_LINES (f)))
11822 /* Value is the number of screen lines needed to make all tool-bar
11823 items of frame F visible. The number of actual rows needed is
11824 returned in *N_ROWS if non-NULL. */
11827 tool_bar_lines_needed (struct frame
*f
, int *n_rows
)
11829 struct window
*w
= XWINDOW (f
->tool_bar_window
);
11831 /* tool_bar_lines_needed is called from redisplay_tool_bar after building
11832 the desired matrix, so use (unused) mode-line row as temporary row to
11833 avoid destroying the first tool-bar row. */
11834 struct glyph_row
*temp_row
= MATRIX_MODE_LINE_ROW (w
->desired_matrix
);
11836 /* Initialize an iterator for iteration over
11837 F->desired_tool_bar_string in the tool-bar window of frame F. */
11838 init_iterator (&it
, w
, -1, -1, temp_row
, TOOL_BAR_FACE_ID
);
11839 it
.first_visible_x
= 0;
11840 it
.last_visible_x
= FRAME_TOTAL_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
11841 reseat_to_string (&it
, NULL
, f
->desired_tool_bar_string
, 0, 0, 0, -1);
11842 it
.paragraph_embedding
= L2R
;
11844 while (!ITERATOR_AT_END_P (&it
))
11846 clear_glyph_row (temp_row
);
11847 it
.glyph_row
= temp_row
;
11848 display_tool_bar_line (&it
, -1);
11850 clear_glyph_row (temp_row
);
11852 /* f->n_tool_bar_rows == 0 means "unknown"; -1 means no tool-bar. */
11854 *n_rows
= it
.vpos
> 0 ? it
.vpos
: -1;
11856 return (it
.current_y
+ FRAME_LINE_HEIGHT (f
) - 1) / FRAME_LINE_HEIGHT (f
);
11860 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed
, Stool_bar_lines_needed
,
11862 doc
: /* Return the number of lines occupied by the tool bar of FRAME.
11863 If FRAME is nil or omitted, use the selected frame. */)
11864 (Lisp_Object frame
)
11866 struct frame
*f
= decode_any_frame (frame
);
11870 if (WINDOWP (f
->tool_bar_window
)
11871 && (w
= XWINDOW (f
->tool_bar_window
),
11872 WINDOW_TOTAL_LINES (w
) > 0))
11874 update_tool_bar (f
, 1);
11875 if (f
->n_tool_bar_items
)
11877 build_desired_tool_bar_string (f
);
11878 nlines
= tool_bar_lines_needed (f
, NULL
);
11882 return make_number (nlines
);
11886 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
11887 height should be changed. */
11890 redisplay_tool_bar (struct frame
*f
)
11894 struct glyph_row
*row
;
11896 #if defined (USE_GTK) || defined (HAVE_NS)
11897 if (FRAME_EXTERNAL_TOOL_BAR (f
))
11898 update_frame_tool_bar (f
);
11902 /* If frame hasn't a tool-bar window or if it is zero-height, don't
11903 do anything. This means you must start with tool-bar-lines
11904 non-zero to get the auto-sizing effect. Or in other words, you
11905 can turn off tool-bars by specifying tool-bar-lines zero. */
11906 if (!WINDOWP (f
->tool_bar_window
)
11907 || (w
= XWINDOW (f
->tool_bar_window
),
11908 WINDOW_TOTAL_LINES (w
) == 0))
11911 /* Set up an iterator for the tool-bar window. */
11912 init_iterator (&it
, w
, -1, -1, w
->desired_matrix
->rows
, TOOL_BAR_FACE_ID
);
11913 it
.first_visible_x
= 0;
11914 it
.last_visible_x
= FRAME_TOTAL_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
11915 row
= it
.glyph_row
;
11917 /* Build a string that represents the contents of the tool-bar. */
11918 build_desired_tool_bar_string (f
);
11919 reseat_to_string (&it
, NULL
, f
->desired_tool_bar_string
, 0, 0, 0, -1);
11920 /* FIXME: This should be controlled by a user option. But it
11921 doesn't make sense to have an R2L tool bar if the menu bar cannot
11922 be drawn also R2L, and making the menu bar R2L is tricky due
11923 toolkit-specific code that implements it. If an R2L tool bar is
11924 ever supported, display_tool_bar_line should also be augmented to
11925 call unproduce_glyphs like display_line and display_string
11927 it
.paragraph_embedding
= L2R
;
11929 if (f
->n_tool_bar_rows
== 0)
11933 if ((nlines
= tool_bar_lines_needed (f
, &f
->n_tool_bar_rows
),
11934 nlines
!= WINDOW_TOTAL_LINES (w
)))
11937 int old_height
= WINDOW_TOTAL_LINES (w
);
11939 XSETFRAME (frame
, f
);
11940 Fmodify_frame_parameters (frame
,
11941 Fcons (Fcons (Qtool_bar_lines
,
11942 make_number (nlines
)),
11944 if (WINDOW_TOTAL_LINES (w
) != old_height
)
11946 clear_glyph_matrix (w
->desired_matrix
);
11947 fonts_changed_p
= 1;
11953 /* Display as many lines as needed to display all tool-bar items. */
11955 if (f
->n_tool_bar_rows
> 0)
11957 int border
, rows
, height
, extra
;
11959 if (TYPE_RANGED_INTEGERP (int, Vtool_bar_border
))
11960 border
= XINT (Vtool_bar_border
);
11961 else if (EQ (Vtool_bar_border
, Qinternal_border_width
))
11962 border
= FRAME_INTERNAL_BORDER_WIDTH (f
);
11963 else if (EQ (Vtool_bar_border
, Qborder_width
))
11964 border
= f
->border_width
;
11970 rows
= f
->n_tool_bar_rows
;
11971 height
= max (1, (it
.last_visible_y
- border
) / rows
);
11972 extra
= it
.last_visible_y
- border
- height
* rows
;
11974 while (it
.current_y
< it
.last_visible_y
)
11977 if (extra
> 0 && rows
-- > 0)
11979 h
= (extra
+ rows
- 1) / rows
;
11982 display_tool_bar_line (&it
, height
+ h
);
11987 while (it
.current_y
< it
.last_visible_y
)
11988 display_tool_bar_line (&it
, 0);
11991 /* It doesn't make much sense to try scrolling in the tool-bar
11992 window, so don't do it. */
11993 w
->desired_matrix
->no_scrolling_p
= 1;
11994 w
->must_be_updated_p
= 1;
11996 if (!NILP (Vauto_resize_tool_bars
))
11998 int max_tool_bar_height
= MAX_FRAME_TOOL_BAR_HEIGHT (f
);
11999 int change_height_p
= 0;
12001 /* If we couldn't display everything, change the tool-bar's
12002 height if there is room for more. */
12003 if (IT_STRING_CHARPOS (it
) < it
.end_charpos
12004 && it
.current_y
< max_tool_bar_height
)
12005 change_height_p
= 1;
12007 row
= it
.glyph_row
- 1;
12009 /* If there are blank lines at the end, except for a partially
12010 visible blank line at the end that is smaller than
12011 FRAME_LINE_HEIGHT, change the tool-bar's height. */
12012 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row
)
12013 && row
->height
>= FRAME_LINE_HEIGHT (f
))
12014 change_height_p
= 1;
12016 /* If row displays tool-bar items, but is partially visible,
12017 change the tool-bar's height. */
12018 if (MATRIX_ROW_DISPLAYS_TEXT_P (row
)
12019 && MATRIX_ROW_BOTTOM_Y (row
) > it
.last_visible_y
12020 && MATRIX_ROW_BOTTOM_Y (row
) < max_tool_bar_height
)
12021 change_height_p
= 1;
12023 /* Resize windows as needed by changing the `tool-bar-lines'
12024 frame parameter. */
12025 if (change_height_p
)
12028 int old_height
= WINDOW_TOTAL_LINES (w
);
12030 int nlines
= tool_bar_lines_needed (f
, &nrows
);
12032 change_height_p
= ((EQ (Vauto_resize_tool_bars
, Qgrow_only
)
12033 && !f
->minimize_tool_bar_window_p
)
12034 ? (nlines
> old_height
)
12035 : (nlines
!= old_height
));
12036 f
->minimize_tool_bar_window_p
= 0;
12038 if (change_height_p
)
12040 XSETFRAME (frame
, f
);
12041 Fmodify_frame_parameters (frame
,
12042 Fcons (Fcons (Qtool_bar_lines
,
12043 make_number (nlines
)),
12045 if (WINDOW_TOTAL_LINES (w
) != old_height
)
12047 clear_glyph_matrix (w
->desired_matrix
);
12048 f
->n_tool_bar_rows
= nrows
;
12049 fonts_changed_p
= 1;
12056 f
->minimize_tool_bar_window_p
= 0;
12061 /* Get information about the tool-bar item which is displayed in GLYPH
12062 on frame F. Return in *PROP_IDX the index where tool-bar item
12063 properties start in F->tool_bar_items. Value is zero if
12064 GLYPH doesn't display a tool-bar item. */
12067 tool_bar_item_info (struct frame
*f
, struct glyph
*glyph
, int *prop_idx
)
12073 /* This function can be called asynchronously, which means we must
12074 exclude any possibility that Fget_text_property signals an
12076 charpos
= min (SCHARS (f
->current_tool_bar_string
), glyph
->charpos
);
12077 charpos
= max (0, charpos
);
12079 /* Get the text property `menu-item' at pos. The value of that
12080 property is the start index of this item's properties in
12081 F->tool_bar_items. */
12082 prop
= Fget_text_property (make_number (charpos
),
12083 Qmenu_item
, f
->current_tool_bar_string
);
12084 if (INTEGERP (prop
))
12086 *prop_idx
= XINT (prop
);
12096 /* Get information about the tool-bar item at position X/Y on frame F.
12097 Return in *GLYPH a pointer to the glyph of the tool-bar item in
12098 the current matrix of the tool-bar window of F, or NULL if not
12099 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
12100 item in F->tool_bar_items. Value is
12102 -1 if X/Y is not on a tool-bar item
12103 0 if X/Y is on the same item that was highlighted before.
12107 get_tool_bar_item (struct frame
*f
, int x
, int y
, struct glyph
**glyph
,
12108 int *hpos
, int *vpos
, int *prop_idx
)
12110 Mouse_HLInfo
*hlinfo
= MOUSE_HL_INFO (f
);
12111 struct window
*w
= XWINDOW (f
->tool_bar_window
);
12114 /* Find the glyph under X/Y. */
12115 *glyph
= x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, 0, 0, &area
);
12116 if (*glyph
== NULL
)
12119 /* Get the start of this tool-bar item's properties in
12120 f->tool_bar_items. */
12121 if (!tool_bar_item_info (f
, *glyph
, prop_idx
))
12124 /* Is mouse on the highlighted item? */
12125 if (EQ (f
->tool_bar_window
, hlinfo
->mouse_face_window
)
12126 && *vpos
>= hlinfo
->mouse_face_beg_row
12127 && *vpos
<= hlinfo
->mouse_face_end_row
12128 && (*vpos
> hlinfo
->mouse_face_beg_row
12129 || *hpos
>= hlinfo
->mouse_face_beg_col
)
12130 && (*vpos
< hlinfo
->mouse_face_end_row
12131 || *hpos
< hlinfo
->mouse_face_end_col
12132 || hlinfo
->mouse_face_past_end
))
12140 Handle mouse button event on the tool-bar of frame F, at
12141 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
12142 0 for button release. MODIFIERS is event modifiers for button
12146 handle_tool_bar_click (struct frame
*f
, int x
, int y
, int down_p
,
12149 Mouse_HLInfo
*hlinfo
= MOUSE_HL_INFO (f
);
12150 struct window
*w
= XWINDOW (f
->tool_bar_window
);
12151 int hpos
, vpos
, prop_idx
;
12152 struct glyph
*glyph
;
12153 Lisp_Object enabled_p
;
12156 /* If not on the highlighted tool-bar item, and mouse-highlight is
12157 non-nil, return. This is so we generate the tool-bar button
12158 click only when the mouse button is released on the same item as
12159 where it was pressed. However, when mouse-highlight is disabled,
12160 generate the click when the button is released regardless of the
12161 highlight, since tool-bar items are not highlighted in that
12163 frame_to_window_pixel_xy (w
, &x
, &y
);
12164 ts
= get_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
);
12166 || (ts
!= 0 && !NILP (Vmouse_highlight
)))
12169 /* When mouse-highlight is off, generate the click for the item
12170 where the button was pressed, disregarding where it was
12172 if (NILP (Vmouse_highlight
) && !down_p
)
12173 prop_idx
= last_tool_bar_item
;
12175 /* If item is disabled, do nothing. */
12176 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
12177 if (NILP (enabled_p
))
12182 /* Show item in pressed state. */
12183 if (!NILP (Vmouse_highlight
))
12184 show_mouse_face (hlinfo
, DRAW_IMAGE_SUNKEN
);
12185 last_tool_bar_item
= prop_idx
;
12189 Lisp_Object key
, frame
;
12190 struct input_event event
;
12191 EVENT_INIT (event
);
12193 /* Show item in released state. */
12194 if (!NILP (Vmouse_highlight
))
12195 show_mouse_face (hlinfo
, DRAW_IMAGE_RAISED
);
12197 key
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_KEY
);
12199 XSETFRAME (frame
, f
);
12200 event
.kind
= TOOL_BAR_EVENT
;
12201 event
.frame_or_window
= frame
;
12203 kbd_buffer_store_event (&event
);
12205 event
.kind
= TOOL_BAR_EVENT
;
12206 event
.frame_or_window
= frame
;
12208 event
.modifiers
= modifiers
;
12209 kbd_buffer_store_event (&event
);
12210 last_tool_bar_item
= -1;
12215 /* Possibly highlight a tool-bar item on frame F when mouse moves to
12216 tool-bar window-relative coordinates X/Y. Called from
12217 note_mouse_highlight. */
12220 note_tool_bar_highlight (struct frame
*f
, int x
, int y
)
12222 Lisp_Object window
= f
->tool_bar_window
;
12223 struct window
*w
= XWINDOW (window
);
12224 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
12225 Mouse_HLInfo
*hlinfo
= MOUSE_HL_INFO (f
);
12227 struct glyph
*glyph
;
12228 struct glyph_row
*row
;
12230 Lisp_Object enabled_p
;
12232 enum draw_glyphs_face draw
= DRAW_IMAGE_RAISED
;
12233 int mouse_down_p
, rc
;
12235 /* Function note_mouse_highlight is called with negative X/Y
12236 values when mouse moves outside of the frame. */
12237 if (x
<= 0 || y
<= 0)
12239 clear_mouse_face (hlinfo
);
12243 rc
= get_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
);
12246 /* Not on tool-bar item. */
12247 clear_mouse_face (hlinfo
);
12251 /* On same tool-bar item as before. */
12252 goto set_help_echo
;
12254 clear_mouse_face (hlinfo
);
12256 /* Mouse is down, but on different tool-bar item? */
12257 mouse_down_p
= (dpyinfo
->grabbed
12258 && f
== last_mouse_frame
12259 && FRAME_LIVE_P (f
));
12261 && last_tool_bar_item
!= prop_idx
)
12264 draw
= mouse_down_p
? DRAW_IMAGE_SUNKEN
: DRAW_IMAGE_RAISED
;
12266 /* If tool-bar item is not enabled, don't highlight it. */
12267 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
12268 if (!NILP (enabled_p
) && !NILP (Vmouse_highlight
))
12270 /* Compute the x-position of the glyph. In front and past the
12271 image is a space. We include this in the highlighted area. */
12272 row
= MATRIX_ROW (w
->current_matrix
, vpos
);
12273 for (i
= x
= 0; i
< hpos
; ++i
)
12274 x
+= row
->glyphs
[TEXT_AREA
][i
].pixel_width
;
12276 /* Record this as the current active region. */
12277 hlinfo
->mouse_face_beg_col
= hpos
;
12278 hlinfo
->mouse_face_beg_row
= vpos
;
12279 hlinfo
->mouse_face_beg_x
= x
;
12280 hlinfo
->mouse_face_beg_y
= row
->y
;
12281 hlinfo
->mouse_face_past_end
= 0;
12283 hlinfo
->mouse_face_end_col
= hpos
+ 1;
12284 hlinfo
->mouse_face_end_row
= vpos
;
12285 hlinfo
->mouse_face_end_x
= x
+ glyph
->pixel_width
;
12286 hlinfo
->mouse_face_end_y
= row
->y
;
12287 hlinfo
->mouse_face_window
= window
;
12288 hlinfo
->mouse_face_face_id
= TOOL_BAR_FACE_ID
;
12290 /* Display it as active. */
12291 show_mouse_face (hlinfo
, draw
);
12296 /* Set help_echo_string to a help string to display for this tool-bar item.
12297 XTread_socket does the rest. */
12298 help_echo_object
= help_echo_window
= Qnil
;
12299 help_echo_pos
= -1;
12300 help_echo_string
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_HELP
);
12301 if (NILP (help_echo_string
))
12302 help_echo_string
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_CAPTION
);
12305 #endif /* HAVE_WINDOW_SYSTEM */
12309 /************************************************************************
12310 Horizontal scrolling
12311 ************************************************************************/
12313 static int hscroll_window_tree (Lisp_Object
);
12314 static int hscroll_windows (Lisp_Object
);
12316 /* For all leaf windows in the window tree rooted at WINDOW, set their
12317 hscroll value so that PT is (i) visible in the window, and (ii) so
12318 that it is not within a certain margin at the window's left and
12319 right border. Value is non-zero if any window's hscroll has been
12323 hscroll_window_tree (Lisp_Object window
)
12325 int hscrolled_p
= 0;
12326 int hscroll_relative_p
= FLOATP (Vhscroll_step
);
12327 int hscroll_step_abs
= 0;
12328 double hscroll_step_rel
= 0;
12330 if (hscroll_relative_p
)
12332 hscroll_step_rel
= XFLOAT_DATA (Vhscroll_step
);
12333 if (hscroll_step_rel
< 0)
12335 hscroll_relative_p
= 0;
12336 hscroll_step_abs
= 0;
12339 else if (TYPE_RANGED_INTEGERP (int, Vhscroll_step
))
12341 hscroll_step_abs
= XINT (Vhscroll_step
);
12342 if (hscroll_step_abs
< 0)
12343 hscroll_step_abs
= 0;
12346 hscroll_step_abs
= 0;
12348 while (WINDOWP (window
))
12350 struct window
*w
= XWINDOW (window
);
12352 if (WINDOWP (w
->contents
))
12353 hscrolled_p
|= hscroll_window_tree (w
->contents
);
12354 else if (w
->cursor
.vpos
>= 0)
12357 int text_area_width
;
12358 struct glyph_row
*current_cursor_row
12359 = MATRIX_ROW (w
->current_matrix
, w
->cursor
.vpos
);
12360 struct glyph_row
*desired_cursor_row
12361 = MATRIX_ROW (w
->desired_matrix
, w
->cursor
.vpos
);
12362 struct glyph_row
*cursor_row
12363 = (desired_cursor_row
->enabled_p
12364 ? desired_cursor_row
12365 : current_cursor_row
);
12366 int row_r2l_p
= cursor_row
->reversed_p
;
12368 text_area_width
= window_box_width (w
, TEXT_AREA
);
12370 /* Scroll when cursor is inside this scroll margin. */
12371 h_margin
= hscroll_margin
* WINDOW_FRAME_COLUMN_WIDTH (w
);
12373 if (!NILP (Fbuffer_local_value (Qauto_hscroll_mode
, w
->contents
))
12374 /* For left-to-right rows, hscroll when cursor is either
12375 (i) inside the right hscroll margin, or (ii) if it is
12376 inside the left margin and the window is already
12380 && w
->cursor
.x
<= h_margin
)
12381 || (cursor_row
->enabled_p
12382 && cursor_row
->truncated_on_right_p
12383 && (w
->cursor
.x
>= text_area_width
- h_margin
))))
12384 /* For right-to-left rows, the logic is similar,
12385 except that rules for scrolling to left and right
12386 are reversed. E.g., if cursor.x <= h_margin, we
12387 need to hscroll "to the right" unconditionally,
12388 and that will scroll the screen to the left so as
12389 to reveal the next portion of the row. */
12391 && ((cursor_row
->enabled_p
12392 /* FIXME: It is confusing to set the
12393 truncated_on_right_p flag when R2L rows
12394 are actually truncated on the left. */
12395 && cursor_row
->truncated_on_right_p
12396 && w
->cursor
.x
<= h_margin
)
12398 && (w
->cursor
.x
>= text_area_width
- h_margin
))))))
12402 struct buffer
*saved_current_buffer
;
12406 /* Find point in a display of infinite width. */
12407 saved_current_buffer
= current_buffer
;
12408 current_buffer
= XBUFFER (w
->contents
);
12410 if (w
== XWINDOW (selected_window
))
12413 pt
= clip_to_bounds (BEGV
, marker_position (w
->pointm
), ZV
);
12415 /* Move iterator to pt starting at cursor_row->start in
12416 a line with infinite width. */
12417 init_to_row_start (&it
, w
, cursor_row
);
12418 it
.last_visible_x
= INFINITY
;
12419 move_it_in_display_line_to (&it
, pt
, -1, MOVE_TO_POS
);
12420 current_buffer
= saved_current_buffer
;
12422 /* Position cursor in window. */
12423 if (!hscroll_relative_p
&& hscroll_step_abs
== 0)
12424 hscroll
= max (0, (it
.current_x
12425 - (ITERATOR_AT_END_OF_LINE_P (&it
)
12426 ? (text_area_width
- 4 * FRAME_COLUMN_WIDTH (it
.f
))
12427 : (text_area_width
/ 2))))
12428 / FRAME_COLUMN_WIDTH (it
.f
);
12429 else if ((!row_r2l_p
12430 && w
->cursor
.x
>= text_area_width
- h_margin
)
12431 || (row_r2l_p
&& w
->cursor
.x
<= h_margin
))
12433 if (hscroll_relative_p
)
12434 wanted_x
= text_area_width
* (1 - hscroll_step_rel
)
12437 wanted_x
= text_area_width
12438 - hscroll_step_abs
* FRAME_COLUMN_WIDTH (it
.f
)
12441 = max (0, it
.current_x
- wanted_x
) / FRAME_COLUMN_WIDTH (it
.f
);
12445 if (hscroll_relative_p
)
12446 wanted_x
= text_area_width
* hscroll_step_rel
12449 wanted_x
= hscroll_step_abs
* FRAME_COLUMN_WIDTH (it
.f
)
12452 = max (0, it
.current_x
- wanted_x
) / FRAME_COLUMN_WIDTH (it
.f
);
12454 hscroll
= max (hscroll
, w
->min_hscroll
);
12456 /* Don't prevent redisplay optimizations if hscroll
12457 hasn't changed, as it will unnecessarily slow down
12459 if (w
->hscroll
!= hscroll
)
12461 XBUFFER (w
->contents
)->prevent_redisplay_optimizations_p
= 1;
12462 w
->hscroll
= hscroll
;
12471 /* Value is non-zero if hscroll of any leaf window has been changed. */
12472 return hscrolled_p
;
12476 /* Set hscroll so that cursor is visible and not inside horizontal
12477 scroll margins for all windows in the tree rooted at WINDOW. See
12478 also hscroll_window_tree above. Value is non-zero if any window's
12479 hscroll has been changed. If it has, desired matrices on the frame
12480 of WINDOW are cleared. */
12483 hscroll_windows (Lisp_Object window
)
12485 int hscrolled_p
= hscroll_window_tree (window
);
12487 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window
))));
12488 return hscrolled_p
;
12493 /************************************************************************
12495 ************************************************************************/
12497 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
12498 to a non-zero value. This is sometimes handy to have in a debugger
12503 /* First and last unchanged row for try_window_id. */
12505 static int debug_first_unchanged_at_end_vpos
;
12506 static int debug_last_unchanged_at_beg_vpos
;
12508 /* Delta vpos and y. */
12510 static int debug_dvpos
, debug_dy
;
12512 /* Delta in characters and bytes for try_window_id. */
12514 static ptrdiff_t debug_delta
, debug_delta_bytes
;
12516 /* Values of window_end_pos and window_end_vpos at the end of
12519 static ptrdiff_t debug_end_vpos
;
12521 /* Append a string to W->desired_matrix->method. FMT is a printf
12522 format string. If trace_redisplay_p is non-zero also printf the
12523 resulting string to stderr. */
12525 static void debug_method_add (struct window
*, char const *, ...)
12526 ATTRIBUTE_FORMAT_PRINTF (2, 3);
12529 debug_method_add (struct window
*w
, char const *fmt
, ...)
12531 char *method
= w
->desired_matrix
->method
;
12532 int len
= strlen (method
);
12533 int size
= sizeof w
->desired_matrix
->method
;
12534 int remaining
= size
- len
- 1;
12537 if (len
&& remaining
)
12540 --remaining
, ++len
;
12543 va_start (ap
, fmt
);
12544 vsnprintf (method
+ len
, remaining
+ 1, fmt
, ap
);
12547 if (trace_redisplay_p
)
12548 fprintf (stderr
, "%p (%s): %s\n",
12550 ((BUFFERP (w
->contents
)
12551 && STRINGP (BVAR (XBUFFER (w
->contents
), name
)))
12552 ? SSDATA (BVAR (XBUFFER (w
->contents
), name
))
12557 #endif /* GLYPH_DEBUG */
12560 /* Value is non-zero if all changes in window W, which displays
12561 current_buffer, are in the text between START and END. START is a
12562 buffer position, END is given as a distance from Z. Used in
12563 redisplay_internal for display optimization. */
12566 text_outside_line_unchanged_p (struct window
*w
,
12567 ptrdiff_t start
, ptrdiff_t end
)
12569 int unchanged_p
= 1;
12571 /* If text or overlays have changed, see where. */
12572 if (window_outdated (w
))
12574 /* Gap in the line? */
12575 if (GPT
< start
|| Z
- GPT
< end
)
12578 /* Changes start in front of the line, or end after it? */
12580 && (BEG_UNCHANGED
< start
- 1
12581 || END_UNCHANGED
< end
))
12584 /* If selective display, can't optimize if changes start at the
12585 beginning of the line. */
12587 && INTEGERP (BVAR (current_buffer
, selective_display
))
12588 && XINT (BVAR (current_buffer
, selective_display
)) > 0
12589 && (BEG_UNCHANGED
< start
|| GPT
<= start
))
12592 /* If there are overlays at the start or end of the line, these
12593 may have overlay strings with newlines in them. A change at
12594 START, for instance, may actually concern the display of such
12595 overlay strings as well, and they are displayed on different
12596 lines. So, quickly rule out this case. (For the future, it
12597 might be desirable to implement something more telling than
12598 just BEG/END_UNCHANGED.) */
12601 if (BEG
+ BEG_UNCHANGED
== start
12602 && overlay_touches_p (start
))
12604 if (END_UNCHANGED
== end
12605 && overlay_touches_p (Z
- end
))
12609 /* Under bidi reordering, adding or deleting a character in the
12610 beginning of a paragraph, before the first strong directional
12611 character, can change the base direction of the paragraph (unless
12612 the buffer specifies a fixed paragraph direction), which will
12613 require to redisplay the whole paragraph. It might be worthwhile
12614 to find the paragraph limits and widen the range of redisplayed
12615 lines to that, but for now just give up this optimization. */
12616 if (!NILP (BVAR (XBUFFER (w
->contents
), bidi_display_reordering
))
12617 && NILP (BVAR (XBUFFER (w
->contents
), bidi_paragraph_direction
)))
12621 return unchanged_p
;
12625 /* Do a frame update, taking possible shortcuts into account. This is
12626 the main external entry point for redisplay.
12628 If the last redisplay displayed an echo area message and that message
12629 is no longer requested, we clear the echo area or bring back the
12630 mini-buffer if that is in use. */
12635 redisplay_internal ();
12640 overlay_arrow_string_or_property (Lisp_Object var
)
12644 if (val
= Fget (var
, Qoverlay_arrow_string
), STRINGP (val
))
12647 return Voverlay_arrow_string
;
12650 /* Return 1 if there are any overlay-arrows in current_buffer. */
12652 overlay_arrow_in_current_buffer_p (void)
12656 for (vlist
= Voverlay_arrow_variable_list
;
12658 vlist
= XCDR (vlist
))
12660 Lisp_Object var
= XCAR (vlist
);
12663 if (!SYMBOLP (var
))
12665 val
= find_symbol_value (var
);
12667 && current_buffer
== XMARKER (val
)->buffer
)
12674 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
12678 overlay_arrows_changed_p (void)
12682 for (vlist
= Voverlay_arrow_variable_list
;
12684 vlist
= XCDR (vlist
))
12686 Lisp_Object var
= XCAR (vlist
);
12687 Lisp_Object val
, pstr
;
12689 if (!SYMBOLP (var
))
12691 val
= find_symbol_value (var
);
12692 if (!MARKERP (val
))
12694 if (! EQ (COERCE_MARKER (val
),
12695 Fget (var
, Qlast_arrow_position
))
12696 || ! (pstr
= overlay_arrow_string_or_property (var
),
12697 EQ (pstr
, Fget (var
, Qlast_arrow_string
))))
12703 /* Mark overlay arrows to be updated on next redisplay. */
12706 update_overlay_arrows (int up_to_date
)
12710 for (vlist
= Voverlay_arrow_variable_list
;
12712 vlist
= XCDR (vlist
))
12714 Lisp_Object var
= XCAR (vlist
);
12716 if (!SYMBOLP (var
))
12719 if (up_to_date
> 0)
12721 Lisp_Object val
= find_symbol_value (var
);
12722 Fput (var
, Qlast_arrow_position
,
12723 COERCE_MARKER (val
));
12724 Fput (var
, Qlast_arrow_string
,
12725 overlay_arrow_string_or_property (var
));
12727 else if (up_to_date
< 0
12728 || !NILP (Fget (var
, Qlast_arrow_position
)))
12730 Fput (var
, Qlast_arrow_position
, Qt
);
12731 Fput (var
, Qlast_arrow_string
, Qt
);
12737 /* Return overlay arrow string to display at row.
12738 Return integer (bitmap number) for arrow bitmap in left fringe.
12739 Return nil if no overlay arrow. */
12742 overlay_arrow_at_row (struct it
*it
, struct glyph_row
*row
)
12746 for (vlist
= Voverlay_arrow_variable_list
;
12748 vlist
= XCDR (vlist
))
12750 Lisp_Object var
= XCAR (vlist
);
12753 if (!SYMBOLP (var
))
12756 val
= find_symbol_value (var
);
12759 && current_buffer
== XMARKER (val
)->buffer
12760 && (MATRIX_ROW_START_CHARPOS (row
) == marker_position (val
)))
12762 if (FRAME_WINDOW_P (it
->f
)
12763 /* FIXME: if ROW->reversed_p is set, this should test
12764 the right fringe, not the left one. */
12765 && WINDOW_LEFT_FRINGE_WIDTH (it
->w
) > 0)
12767 #ifdef HAVE_WINDOW_SYSTEM
12768 if (val
= Fget (var
, Qoverlay_arrow_bitmap
), SYMBOLP (val
))
12771 if ((fringe_bitmap
= lookup_fringe_bitmap (val
)) != 0)
12772 return make_number (fringe_bitmap
);
12775 return make_number (-1); /* Use default arrow bitmap. */
12777 return overlay_arrow_string_or_property (var
);
12784 /* Return 1 if point moved out of or into a composition. Otherwise
12785 return 0. PREV_BUF and PREV_PT are the last point buffer and
12786 position. BUF and PT are the current point buffer and position. */
12789 check_point_in_composition (struct buffer
*prev_buf
, ptrdiff_t prev_pt
,
12790 struct buffer
*buf
, ptrdiff_t pt
)
12792 ptrdiff_t start
, end
;
12794 Lisp_Object buffer
;
12796 XSETBUFFER (buffer
, buf
);
12797 /* Check a composition at the last point if point moved within the
12799 if (prev_buf
== buf
)
12802 /* Point didn't move. */
12805 if (prev_pt
> BUF_BEGV (buf
) && prev_pt
< BUF_ZV (buf
)
12806 && find_composition (prev_pt
, -1, &start
, &end
, &prop
, buffer
)
12807 && COMPOSITION_VALID_P (start
, end
, prop
)
12808 && start
< prev_pt
&& end
> prev_pt
)
12809 /* The last point was within the composition. Return 1 iff
12810 point moved out of the composition. */
12811 return (pt
<= start
|| pt
>= end
);
12814 /* Check a composition at the current point. */
12815 return (pt
> BUF_BEGV (buf
) && pt
< BUF_ZV (buf
)
12816 && find_composition (pt
, -1, &start
, &end
, &prop
, buffer
)
12817 && COMPOSITION_VALID_P (start
, end
, prop
)
12818 && start
< pt
&& end
> pt
);
12822 /* Reconsider the setting of B->clip_changed which is displayed
12826 reconsider_clip_changes (struct window
*w
, struct buffer
*b
)
12828 if (b
->clip_changed
12829 && w
->window_end_valid
12830 && w
->current_matrix
->buffer
== b
12831 && w
->current_matrix
->zv
== BUF_ZV (b
)
12832 && w
->current_matrix
->begv
== BUF_BEGV (b
))
12833 b
->clip_changed
= 0;
12835 /* If display wasn't paused, and W is not a tool bar window, see if
12836 point has been moved into or out of a composition. In that case,
12837 we set b->clip_changed to 1 to force updating the screen. If
12838 b->clip_changed has already been set to 1, we can skip this
12840 if (!b
->clip_changed
&& BUFFERP (w
->contents
) && w
->window_end_valid
)
12844 if (w
== XWINDOW (selected_window
))
12847 pt
= marker_position (w
->pointm
);
12849 if ((w
->current_matrix
->buffer
!= XBUFFER (w
->contents
)
12850 || pt
!= w
->last_point
)
12851 && check_point_in_composition (w
->current_matrix
->buffer
,
12853 XBUFFER (w
->contents
), pt
))
12854 b
->clip_changed
= 1;
12859 #define STOP_POLLING \
12860 do { if (! polling_stopped_here) stop_polling (); \
12861 polling_stopped_here = 1; } while (0)
12863 #define RESUME_POLLING \
12864 do { if (polling_stopped_here) start_polling (); \
12865 polling_stopped_here = 0; } while (0)
12868 /* Perhaps in the future avoid recentering windows if it
12869 is not necessary; currently that causes some problems. */
12872 redisplay_internal (void)
12874 struct window
*w
= XWINDOW (selected_window
);
12878 int must_finish
= 0;
12879 struct text_pos tlbufpos
, tlendpos
;
12880 int number_of_visible_frames
;
12881 ptrdiff_t count
, count1
;
12883 int polling_stopped_here
= 0;
12884 Lisp_Object tail
, frame
;
12886 /* Non-zero means redisplay has to consider all windows on all
12887 frames. Zero means, only selected_window is considered. */
12888 int consider_all_windows_p
;
12890 /* Non-zero means redisplay has to redisplay the miniwindow. */
12891 int update_miniwindow_p
= 0;
12893 TRACE ((stderr
, "redisplay_internal %d\n", redisplaying_p
));
12895 /* No redisplay if running in batch mode or frame is not yet fully
12896 initialized, or redisplay is explicitly turned off by setting
12897 Vinhibit_redisplay. */
12898 if (FRAME_INITIAL_P (SELECTED_FRAME ())
12899 || !NILP (Vinhibit_redisplay
))
12902 /* Don't examine these until after testing Vinhibit_redisplay.
12903 When Emacs is shutting down, perhaps because its connection to
12904 X has dropped, we should not look at them at all. */
12905 fr
= XFRAME (w
->frame
);
12906 sf
= SELECTED_FRAME ();
12908 if (!fr
->glyphs_initialized_p
)
12911 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS)
12912 if (popup_activated ())
12916 /* I don't think this happens but let's be paranoid. */
12917 if (redisplaying_p
)
12920 /* Record a function that clears redisplaying_p
12921 when we leave this function. */
12922 count
= SPECPDL_INDEX ();
12923 record_unwind_protect (unwind_redisplay
, selected_frame
);
12924 redisplaying_p
= 1;
12925 specbind (Qinhibit_free_realized_faces
, Qnil
);
12927 /* Record this function, so it appears on the profiler's backtraces. */
12928 record_in_backtrace (Qredisplay_internal
, &Qnil
, 0);
12930 FOR_EACH_FRAME (tail
, frame
)
12931 XFRAME (frame
)->already_hscrolled_p
= 0;
12934 /* Remember the currently selected window. */
12938 reconsider_clip_changes (w
, current_buffer
);
12939 last_escape_glyph_frame
= NULL
;
12940 last_escape_glyph_face_id
= (1 << FACE_ID_BITS
);
12941 last_glyphless_glyph_frame
= NULL
;
12942 last_glyphless_glyph_face_id
= (1 << FACE_ID_BITS
);
12944 /* If new fonts have been loaded that make a glyph matrix adjustment
12945 necessary, do it. */
12946 if (fonts_changed_p
)
12948 adjust_glyphs (NULL
);
12949 ++windows_or_buffers_changed
;
12950 fonts_changed_p
= 0;
12953 /* If face_change_count is non-zero, init_iterator will free all
12954 realized faces, which includes the faces referenced from current
12955 matrices. So, we can't reuse current matrices in this case. */
12956 if (face_change_count
)
12957 ++windows_or_buffers_changed
;
12959 if ((FRAME_TERMCAP_P (sf
) || FRAME_MSDOS_P (sf
))
12960 && FRAME_TTY (sf
)->previous_frame
!= sf
)
12962 /* Since frames on a single ASCII terminal share the same
12963 display area, displaying a different frame means redisplay
12964 the whole thing. */
12965 windows_or_buffers_changed
++;
12966 SET_FRAME_GARBAGED (sf
);
12968 set_tty_color_mode (FRAME_TTY (sf
), sf
);
12970 FRAME_TTY (sf
)->previous_frame
= sf
;
12973 /* Set the visible flags for all frames. Do this before checking for
12974 resized or garbaged frames; they want to know if their frames are
12975 visible. See the comment in frame.h for FRAME_SAMPLE_VISIBILITY. */
12976 number_of_visible_frames
= 0;
12978 FOR_EACH_FRAME (tail
, frame
)
12980 struct frame
*f
= XFRAME (frame
);
12982 if (FRAME_VISIBLE_P (f
))
12983 ++number_of_visible_frames
;
12984 clear_desired_matrices (f
);
12987 /* Notice any pending interrupt request to change frame size. */
12988 do_pending_window_change (1);
12990 /* do_pending_window_change could change the selected_window due to
12991 frame resizing which makes the selected window too small. */
12992 if (WINDOWP (selected_window
) && (w
= XWINDOW (selected_window
)) != sw
)
12995 reconsider_clip_changes (w
, current_buffer
);
12998 /* Clear frames marked as garbaged. */
12999 clear_garbaged_frames ();
13001 /* Build menubar and tool-bar items. */
13002 if (NILP (Vmemory_full
))
13003 prepare_menu_bars ();
13005 if (windows_or_buffers_changed
)
13006 update_mode_lines
++;
13008 /* Detect case that we need to write or remove a star in the mode line. */
13009 if ((SAVE_MODIFF
< MODIFF
) != w
->last_had_star
)
13011 w
->update_mode_line
= 1;
13012 if (buffer_shared_and_changed ())
13013 update_mode_lines
++;
13016 /* Avoid invocation of point motion hooks by `current_column' below. */
13017 count1
= SPECPDL_INDEX ();
13018 specbind (Qinhibit_point_motion_hooks
, Qt
);
13020 if (mode_line_update_needed (w
))
13021 w
->update_mode_line
= 1;
13023 unbind_to (count1
, Qnil
);
13025 consider_all_windows_p
= (update_mode_lines
13026 || buffer_shared_and_changed ()
13027 || cursor_type_changed
);
13029 /* If specs for an arrow have changed, do thorough redisplay
13030 to ensure we remove any arrow that should no longer exist. */
13031 if (overlay_arrows_changed_p ())
13032 consider_all_windows_p
= windows_or_buffers_changed
= 1;
13034 /* Normally the message* functions will have already displayed and
13035 updated the echo area, but the frame may have been trashed, or
13036 the update may have been preempted, so display the echo area
13037 again here. Checking message_cleared_p captures the case that
13038 the echo area should be cleared. */
13039 if ((!NILP (echo_area_buffer
[0]) && !display_last_displayed_message_p
)
13040 || (!NILP (echo_area_buffer
[1]) && display_last_displayed_message_p
)
13041 || (message_cleared_p
13042 && minibuf_level
== 0
13043 /* If the mini-window is currently selected, this means the
13044 echo-area doesn't show through. */
13045 && !MINI_WINDOW_P (XWINDOW (selected_window
))))
13047 int window_height_changed_p
= echo_area_display (0);
13049 if (message_cleared_p
)
13050 update_miniwindow_p
= 1;
13054 /* If we don't display the current message, don't clear the
13055 message_cleared_p flag, because, if we did, we wouldn't clear
13056 the echo area in the next redisplay which doesn't preserve
13058 if (!display_last_displayed_message_p
)
13059 message_cleared_p
= 0;
13061 if (fonts_changed_p
)
13063 else if (window_height_changed_p
)
13065 consider_all_windows_p
= 1;
13066 ++update_mode_lines
;
13067 ++windows_or_buffers_changed
;
13069 /* If window configuration was changed, frames may have been
13070 marked garbaged. Clear them or we will experience
13071 surprises wrt scrolling. */
13072 clear_garbaged_frames ();
13075 else if (EQ (selected_window
, minibuf_window
)
13076 && (current_buffer
->clip_changed
|| window_outdated (w
))
13077 && resize_mini_window (w
, 0))
13079 /* Resized active mini-window to fit the size of what it is
13080 showing if its contents might have changed. */
13082 /* FIXME: this causes all frames to be updated, which seems unnecessary
13083 since only the current frame needs to be considered. This function
13084 needs to be rewritten with two variables, consider_all_windows and
13085 consider_all_frames. */
13086 consider_all_windows_p
= 1;
13087 ++windows_or_buffers_changed
;
13088 ++update_mode_lines
;
13090 /* If window configuration was changed, frames may have been
13091 marked garbaged. Clear them or we will experience
13092 surprises wrt scrolling. */
13093 clear_garbaged_frames ();
13096 /* If showing the region, and mark has changed, we must redisplay
13097 the whole window. The assignment to this_line_start_pos prevents
13098 the optimization directly below this if-statement. */
13099 if (((!NILP (Vtransient_mark_mode
)
13100 && !NILP (BVAR (XBUFFER (w
->contents
), mark_active
)))
13101 != (w
->region_showing
> 0))
13102 || (w
->region_showing
13103 && w
->region_showing
13104 != XINT (Fmarker_position (BVAR (XBUFFER (w
->contents
), mark
)))))
13105 CHARPOS (this_line_start_pos
) = 0;
13107 /* Optimize the case that only the line containing the cursor in the
13108 selected window has changed. Variables starting with this_ are
13109 set in display_line and record information about the line
13110 containing the cursor. */
13111 tlbufpos
= this_line_start_pos
;
13112 tlendpos
= this_line_end_pos
;
13113 if (!consider_all_windows_p
13114 && CHARPOS (tlbufpos
) > 0
13115 && !w
->update_mode_line
13116 && !current_buffer
->clip_changed
13117 && !current_buffer
->prevent_redisplay_optimizations_p
13118 && FRAME_VISIBLE_P (XFRAME (w
->frame
))
13119 && !FRAME_OBSCURED_P (XFRAME (w
->frame
))
13120 /* Make sure recorded data applies to current buffer, etc. */
13121 && this_line_buffer
== current_buffer
13122 && current_buffer
== XBUFFER (w
->contents
)
13124 && !w
->optional_new_start
13125 /* Point must be on the line that we have info recorded about. */
13126 && PT
>= CHARPOS (tlbufpos
)
13127 && PT
<= Z
- CHARPOS (tlendpos
)
13128 /* All text outside that line, including its final newline,
13129 must be unchanged. */
13130 && text_outside_line_unchanged_p (w
, CHARPOS (tlbufpos
),
13131 CHARPOS (tlendpos
)))
13133 if (CHARPOS (tlbufpos
) > BEGV
13134 && FETCH_BYTE (BYTEPOS (tlbufpos
) - 1) != '\n'
13135 && (CHARPOS (tlbufpos
) == ZV
13136 || FETCH_BYTE (BYTEPOS (tlbufpos
)) == '\n'))
13137 /* Former continuation line has disappeared by becoming empty. */
13139 else if (window_outdated (w
) || MINI_WINDOW_P (w
))
13141 /* We have to handle the case of continuation around a
13142 wide-column character (see the comment in indent.c around
13145 For instance, in the following case:
13147 -------- Insert --------
13148 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
13149 J_I_ ==> J_I_ `^^' are cursors.
13153 As we have to redraw the line above, we cannot use this
13157 int line_height_before
= this_line_pixel_height
;
13159 /* Note that start_display will handle the case that the
13160 line starting at tlbufpos is a continuation line. */
13161 start_display (&it
, w
, tlbufpos
);
13163 /* Implementation note: It this still necessary? */
13164 if (it
.current_x
!= this_line_start_x
)
13167 TRACE ((stderr
, "trying display optimization 1\n"));
13168 w
->cursor
.vpos
= -1;
13169 overlay_arrow_seen
= 0;
13170 it
.vpos
= this_line_vpos
;
13171 it
.current_y
= this_line_y
;
13172 it
.glyph_row
= MATRIX_ROW (w
->desired_matrix
, this_line_vpos
);
13173 display_line (&it
);
13175 /* If line contains point, is not continued,
13176 and ends at same distance from eob as before, we win. */
13177 if (w
->cursor
.vpos
>= 0
13178 /* Line is not continued, otherwise this_line_start_pos
13179 would have been set to 0 in display_line. */
13180 && CHARPOS (this_line_start_pos
)
13181 /* Line ends as before. */
13182 && CHARPOS (this_line_end_pos
) == CHARPOS (tlendpos
)
13183 /* Line has same height as before. Otherwise other lines
13184 would have to be shifted up or down. */
13185 && this_line_pixel_height
== line_height_before
)
13187 /* If this is not the window's last line, we must adjust
13188 the charstarts of the lines below. */
13189 if (it
.current_y
< it
.last_visible_y
)
13191 struct glyph_row
*row
13192 = MATRIX_ROW (w
->current_matrix
, this_line_vpos
+ 1);
13193 ptrdiff_t delta
, delta_bytes
;
13195 /* We used to distinguish between two cases here,
13196 conditioned by Z - CHARPOS (tlendpos) == ZV, for
13197 when the line ends in a newline or the end of the
13198 buffer's accessible portion. But both cases did
13199 the same, so they were collapsed. */
13201 - CHARPOS (tlendpos
)
13202 - MATRIX_ROW_START_CHARPOS (row
));
13203 delta_bytes
= (Z_BYTE
13204 - BYTEPOS (tlendpos
)
13205 - MATRIX_ROW_START_BYTEPOS (row
));
13207 increment_matrix_positions (w
->current_matrix
,
13208 this_line_vpos
+ 1,
13209 w
->current_matrix
->nrows
,
13210 delta
, delta_bytes
);
13213 /* If this row displays text now but previously didn't,
13214 or vice versa, w->window_end_vpos may have to be
13216 if (MATRIX_ROW_DISPLAYS_TEXT_P (it
.glyph_row
- 1))
13218 if (XFASTINT (w
->window_end_vpos
) < this_line_vpos
)
13219 wset_window_end_vpos (w
, make_number (this_line_vpos
));
13221 else if (XFASTINT (w
->window_end_vpos
) == this_line_vpos
13222 && this_line_vpos
> 0)
13223 wset_window_end_vpos (w
, make_number (this_line_vpos
- 1));
13224 w
->window_end_valid
= 0;
13226 /* Update hint: No need to try to scroll in update_window. */
13227 w
->desired_matrix
->no_scrolling_p
= 1;
13230 *w
->desired_matrix
->method
= 0;
13231 debug_method_add (w
, "optimization 1");
13233 #ifdef HAVE_WINDOW_SYSTEM
13234 update_window_fringes (w
, 0);
13241 else if (/* Cursor position hasn't changed. */
13242 PT
== w
->last_point
13243 /* Make sure the cursor was last displayed
13244 in this window. Otherwise we have to reposition it. */
13245 && 0 <= w
->cursor
.vpos
13246 && w
->cursor
.vpos
< WINDOW_TOTAL_LINES (w
))
13250 do_pending_window_change (1);
13251 /* If selected_window changed, redisplay again. */
13252 if (WINDOWP (selected_window
)
13253 && (w
= XWINDOW (selected_window
)) != sw
)
13256 /* We used to always goto end_of_redisplay here, but this
13257 isn't enough if we have a blinking cursor. */
13258 if (w
->cursor_off_p
== w
->last_cursor_off_p
)
13259 goto end_of_redisplay
;
13263 /* If highlighting the region, or if the cursor is in the echo area,
13264 then we can't just move the cursor. */
13265 else if (! (!NILP (Vtransient_mark_mode
)
13266 && !NILP (BVAR (current_buffer
, mark_active
)))
13267 && (EQ (selected_window
,
13268 BVAR (current_buffer
, last_selected_window
))
13269 || highlight_nonselected_windows
)
13270 && !w
->region_showing
13271 && NILP (Vshow_trailing_whitespace
)
13272 && !cursor_in_echo_area
)
13275 struct glyph_row
*row
;
13277 /* Skip from tlbufpos to PT and see where it is. Note that
13278 PT may be in invisible text. If so, we will end at the
13279 next visible position. */
13280 init_iterator (&it
, w
, CHARPOS (tlbufpos
), BYTEPOS (tlbufpos
),
13281 NULL
, DEFAULT_FACE_ID
);
13282 it
.current_x
= this_line_start_x
;
13283 it
.current_y
= this_line_y
;
13284 it
.vpos
= this_line_vpos
;
13286 /* The call to move_it_to stops in front of PT, but
13287 moves over before-strings. */
13288 move_it_to (&it
, PT
, -1, -1, -1, MOVE_TO_POS
);
13290 if (it
.vpos
== this_line_vpos
13291 && (row
= MATRIX_ROW (w
->current_matrix
, this_line_vpos
),
13294 eassert (this_line_vpos
== it
.vpos
);
13295 eassert (this_line_y
== it
.current_y
);
13296 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
13298 *w
->desired_matrix
->method
= 0;
13299 debug_method_add (w
, "optimization 3");
13308 /* Text changed drastically or point moved off of line. */
13309 SET_MATRIX_ROW_ENABLED_P (w
->desired_matrix
, this_line_vpos
, 0);
13312 CHARPOS (this_line_start_pos
) = 0;
13313 consider_all_windows_p
|= buffer_shared_and_changed ();
13314 ++clear_face_cache_count
;
13315 #ifdef HAVE_WINDOW_SYSTEM
13316 ++clear_image_cache_count
;
13319 /* Build desired matrices, and update the display. If
13320 consider_all_windows_p is non-zero, do it for all windows on all
13321 frames. Otherwise do it for selected_window, only. */
13323 if (consider_all_windows_p
)
13325 FOR_EACH_FRAME (tail
, frame
)
13326 XFRAME (frame
)->updated_p
= 0;
13328 FOR_EACH_FRAME (tail
, frame
)
13330 struct frame
*f
= XFRAME (frame
);
13332 /* We don't have to do anything for unselected terminal
13334 if ((FRAME_TERMCAP_P (f
) || FRAME_MSDOS_P (f
))
13335 && !EQ (FRAME_TTY (f
)->top_frame
, frame
))
13338 if (FRAME_WINDOW_P (f
) || FRAME_TERMCAP_P (f
) || f
== sf
)
13340 /* Mark all the scroll bars to be removed; we'll redeem
13341 the ones we want when we redisplay their windows. */
13342 if (FRAME_TERMINAL (f
)->condemn_scroll_bars_hook
)
13343 FRAME_TERMINAL (f
)->condemn_scroll_bars_hook (f
);
13345 if (FRAME_VISIBLE_P (f
) && !FRAME_OBSCURED_P (f
))
13346 redisplay_windows (FRAME_ROOT_WINDOW (f
));
13348 /* The X error handler may have deleted that frame. */
13349 if (!FRAME_LIVE_P (f
))
13352 /* Any scroll bars which redisplay_windows should have
13353 nuked should now go away. */
13354 if (FRAME_TERMINAL (f
)->judge_scroll_bars_hook
)
13355 FRAME_TERMINAL (f
)->judge_scroll_bars_hook (f
);
13357 /* If fonts changed, display again. */
13358 /* ??? rms: I suspect it is a mistake to jump all the way
13359 back to retry here. It should just retry this frame. */
13360 if (fonts_changed_p
)
13363 if (FRAME_VISIBLE_P (f
) && !FRAME_OBSCURED_P (f
))
13365 /* See if we have to hscroll. */
13366 if (!f
->already_hscrolled_p
)
13368 f
->already_hscrolled_p
= 1;
13369 if (hscroll_windows (f
->root_window
))
13373 /* Prevent various kinds of signals during display
13374 update. stdio is not robust about handling
13375 signals, which can cause an apparent I/O
13377 if (interrupt_input
)
13378 unrequest_sigio ();
13381 /* Update the display. */
13382 set_window_update_flags (XWINDOW (f
->root_window
), 1);
13383 pending
|= update_frame (f
, 0, 0);
13389 eassert (EQ (XFRAME (selected_frame
)->selected_window
, selected_window
));
13393 /* Do the mark_window_display_accurate after all windows have
13394 been redisplayed because this call resets flags in buffers
13395 which are needed for proper redisplay. */
13396 FOR_EACH_FRAME (tail
, frame
)
13398 struct frame
*f
= XFRAME (frame
);
13401 mark_window_display_accurate (f
->root_window
, 1);
13402 if (FRAME_TERMINAL (f
)->frame_up_to_date_hook
)
13403 FRAME_TERMINAL (f
)->frame_up_to_date_hook (f
);
13408 else if (FRAME_VISIBLE_P (sf
) && !FRAME_OBSCURED_P (sf
))
13410 Lisp_Object mini_window
= FRAME_MINIBUF_WINDOW (sf
);
13411 struct frame
*mini_frame
;
13413 displayed_buffer
= XBUFFER (XWINDOW (selected_window
)->contents
);
13414 /* Use list_of_error, not Qerror, so that
13415 we catch only errors and don't run the debugger. */
13416 internal_condition_case_1 (redisplay_window_1
, selected_window
,
13418 redisplay_window_error
);
13419 if (update_miniwindow_p
)
13420 internal_condition_case_1 (redisplay_window_1
, mini_window
,
13422 redisplay_window_error
);
13424 /* Compare desired and current matrices, perform output. */
13427 /* If fonts changed, display again. */
13428 if (fonts_changed_p
)
13431 /* Prevent various kinds of signals during display update.
13432 stdio is not robust about handling signals,
13433 which can cause an apparent I/O error. */
13434 if (interrupt_input
)
13435 unrequest_sigio ();
13438 if (FRAME_VISIBLE_P (sf
) && !FRAME_OBSCURED_P (sf
))
13440 if (hscroll_windows (selected_window
))
13443 XWINDOW (selected_window
)->must_be_updated_p
= 1;
13444 pending
= update_frame (sf
, 0, 0);
13447 /* We may have called echo_area_display at the top of this
13448 function. If the echo area is on another frame, that may
13449 have put text on a frame other than the selected one, so the
13450 above call to update_frame would not have caught it. Catch
13452 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
13453 mini_frame
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
13455 if (mini_frame
!= sf
&& FRAME_WINDOW_P (mini_frame
))
13457 XWINDOW (mini_window
)->must_be_updated_p
= 1;
13458 pending
|= update_frame (mini_frame
, 0, 0);
13459 if (!pending
&& hscroll_windows (mini_window
))
13464 /* If display was paused because of pending input, make sure we do a
13465 thorough update the next time. */
13468 /* Prevent the optimization at the beginning of
13469 redisplay_internal that tries a single-line update of the
13470 line containing the cursor in the selected window. */
13471 CHARPOS (this_line_start_pos
) = 0;
13473 /* Let the overlay arrow be updated the next time. */
13474 update_overlay_arrows (0);
13476 /* If we pause after scrolling, some rows in the current
13477 matrices of some windows are not valid. */
13478 if (!WINDOW_FULL_WIDTH_P (w
)
13479 && !FRAME_WINDOW_P (XFRAME (w
->frame
)))
13480 update_mode_lines
= 1;
13484 if (!consider_all_windows_p
)
13486 /* This has already been done above if
13487 consider_all_windows_p is set. */
13488 mark_window_display_accurate_1 (w
, 1);
13490 /* Say overlay arrows are up to date. */
13491 update_overlay_arrows (1);
13493 if (FRAME_TERMINAL (sf
)->frame_up_to_date_hook
!= 0)
13494 FRAME_TERMINAL (sf
)->frame_up_to_date_hook (sf
);
13497 update_mode_lines
= 0;
13498 windows_or_buffers_changed
= 0;
13499 cursor_type_changed
= 0;
13502 /* Start SIGIO interrupts coming again. Having them off during the
13503 code above makes it less likely one will discard output, but not
13504 impossible, since there might be stuff in the system buffer here.
13505 But it is much hairier to try to do anything about that. */
13506 if (interrupt_input
)
13510 /* If a frame has become visible which was not before, redisplay
13511 again, so that we display it. Expose events for such a frame
13512 (which it gets when becoming visible) don't call the parts of
13513 redisplay constructing glyphs, so simply exposing a frame won't
13514 display anything in this case. So, we have to display these
13515 frames here explicitly. */
13520 FOR_EACH_FRAME (tail
, frame
)
13522 int this_is_visible
= 0;
13524 if (XFRAME (frame
)->visible
)
13525 this_is_visible
= 1;
13527 if (this_is_visible
)
13531 if (new_count
!= number_of_visible_frames
)
13532 windows_or_buffers_changed
++;
13535 /* Change frame size now if a change is pending. */
13536 do_pending_window_change (1);
13538 /* If we just did a pending size change, or have additional
13539 visible frames, or selected_window changed, redisplay again. */
13540 if ((windows_or_buffers_changed
&& !pending
)
13541 || (WINDOWP (selected_window
) && (w
= XWINDOW (selected_window
)) != sw
))
13544 /* Clear the face and image caches.
13546 We used to do this only if consider_all_windows_p. But the cache
13547 needs to be cleared if a timer creates images in the current
13548 buffer (e.g. the test case in Bug#6230). */
13550 if (clear_face_cache_count
> CLEAR_FACE_CACHE_COUNT
)
13552 clear_face_cache (0);
13553 clear_face_cache_count
= 0;
13556 #ifdef HAVE_WINDOW_SYSTEM
13557 if (clear_image_cache_count
> CLEAR_IMAGE_CACHE_COUNT
)
13559 clear_image_caches (Qnil
);
13560 clear_image_cache_count
= 0;
13562 #endif /* HAVE_WINDOW_SYSTEM */
13565 unbind_to (count
, Qnil
);
13570 /* Redisplay, but leave alone any recent echo area message unless
13571 another message has been requested in its place.
13573 This is useful in situations where you need to redisplay but no
13574 user action has occurred, making it inappropriate for the message
13575 area to be cleared. See tracking_off and
13576 wait_reading_process_output for examples of these situations.
13578 FROM_WHERE is an integer saying from where this function was
13579 called. This is useful for debugging. */
13582 redisplay_preserve_echo_area (int from_where
)
13584 TRACE ((stderr
, "redisplay_preserve_echo_area (%d)\n", from_where
));
13586 if (!NILP (echo_area_buffer
[1]))
13588 /* We have a previously displayed message, but no current
13589 message. Redisplay the previous message. */
13590 display_last_displayed_message_p
= 1;
13591 redisplay_internal ();
13592 display_last_displayed_message_p
= 0;
13595 redisplay_internal ();
13597 if (FRAME_RIF (SELECTED_FRAME ()) != NULL
13598 && FRAME_RIF (SELECTED_FRAME ())->flush_display_optional
)
13599 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (NULL
);
13603 /* Function registered with record_unwind_protect in redisplay_internal.
13604 Clear redisplaying_p. Also select the previously selected frame. */
13607 unwind_redisplay (Lisp_Object old_frame
)
13609 redisplaying_p
= 0;
13614 /* Mark the display of leaf window W as accurate or inaccurate.
13615 If ACCURATE_P is non-zero mark display of W as accurate. If
13616 ACCURATE_P is zero, arrange for W to be redisplayed the next
13617 time redisplay_internal is called. */
13620 mark_window_display_accurate_1 (struct window
*w
, int accurate_p
)
13622 struct buffer
*b
= XBUFFER (w
->contents
);
13624 w
->last_modified
= accurate_p
? BUF_MODIFF (b
) : 0;
13625 w
->last_overlay_modified
= accurate_p
? BUF_OVERLAY_MODIFF (b
) : 0;
13626 w
->last_had_star
= BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
);
13630 b
->clip_changed
= 0;
13631 b
->prevent_redisplay_optimizations_p
= 0;
13633 BUF_UNCHANGED_MODIFIED (b
) = BUF_MODIFF (b
);
13634 BUF_OVERLAY_UNCHANGED_MODIFIED (b
) = BUF_OVERLAY_MODIFF (b
);
13635 BUF_BEG_UNCHANGED (b
) = BUF_GPT (b
) - BUF_BEG (b
);
13636 BUF_END_UNCHANGED (b
) = BUF_Z (b
) - BUF_GPT (b
);
13638 w
->current_matrix
->buffer
= b
;
13639 w
->current_matrix
->begv
= BUF_BEGV (b
);
13640 w
->current_matrix
->zv
= BUF_ZV (b
);
13642 w
->last_cursor
= w
->cursor
;
13643 w
->last_cursor_off_p
= w
->cursor_off_p
;
13645 if (w
== XWINDOW (selected_window
))
13646 w
->last_point
= BUF_PT (b
);
13648 w
->last_point
= marker_position (w
->pointm
);
13650 w
->window_end_valid
= 1;
13651 w
->update_mode_line
= 0;
13656 /* Mark the display of windows in the window tree rooted at WINDOW as
13657 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
13658 windows as accurate. If ACCURATE_P is zero, arrange for windows to
13659 be redisplayed the next time redisplay_internal is called. */
13662 mark_window_display_accurate (Lisp_Object window
, int accurate_p
)
13666 for (; !NILP (window
); window
= w
->next
)
13668 w
= XWINDOW (window
);
13669 if (WINDOWP (w
->contents
))
13670 mark_window_display_accurate (w
->contents
, accurate_p
);
13672 mark_window_display_accurate_1 (w
, accurate_p
);
13676 update_overlay_arrows (1);
13678 /* Force a thorough redisplay the next time by setting
13679 last_arrow_position and last_arrow_string to t, which is
13680 unequal to any useful value of Voverlay_arrow_... */
13681 update_overlay_arrows (-1);
13685 /* Return value in display table DP (Lisp_Char_Table *) for character
13686 C. Since a display table doesn't have any parent, we don't have to
13687 follow parent. Do not call this function directly but use the
13688 macro DISP_CHAR_VECTOR. */
13691 disp_char_vector (struct Lisp_Char_Table
*dp
, int c
)
13695 if (ASCII_CHAR_P (c
))
13698 if (SUB_CHAR_TABLE_P (val
))
13699 val
= XSUB_CHAR_TABLE (val
)->contents
[c
];
13705 XSETCHAR_TABLE (table
, dp
);
13706 val
= char_table_ref (table
, c
);
13715 /***********************************************************************
13717 ***********************************************************************/
13719 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
13722 redisplay_windows (Lisp_Object window
)
13724 while (!NILP (window
))
13726 struct window
*w
= XWINDOW (window
);
13728 if (WINDOWP (w
->contents
))
13729 redisplay_windows (w
->contents
);
13730 else if (BUFFERP (w
->contents
))
13732 displayed_buffer
= XBUFFER (w
->contents
);
13733 /* Use list_of_error, not Qerror, so that
13734 we catch only errors and don't run the debugger. */
13735 internal_condition_case_1 (redisplay_window_0
, window
,
13737 redisplay_window_error
);
13745 redisplay_window_error (Lisp_Object ignore
)
13747 displayed_buffer
->display_error_modiff
= BUF_MODIFF (displayed_buffer
);
13752 redisplay_window_0 (Lisp_Object window
)
13754 if (displayed_buffer
->display_error_modiff
< BUF_MODIFF (displayed_buffer
))
13755 redisplay_window (window
, 0);
13760 redisplay_window_1 (Lisp_Object window
)
13762 if (displayed_buffer
->display_error_modiff
< BUF_MODIFF (displayed_buffer
))
13763 redisplay_window (window
, 1);
13768 /* Set cursor position of W. PT is assumed to be displayed in ROW.
13769 DELTA and DELTA_BYTES are the numbers of characters and bytes by
13770 which positions recorded in ROW differ from current buffer
13773 Return 0 if cursor is not on this row, 1 otherwise. */
13776 set_cursor_from_row (struct window
*w
, struct glyph_row
*row
,
13777 struct glyph_matrix
*matrix
,
13778 ptrdiff_t delta
, ptrdiff_t delta_bytes
,
13781 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
];
13782 struct glyph
*end
= glyph
+ row
->used
[TEXT_AREA
];
13783 struct glyph
*cursor
= NULL
;
13784 /* The last known character position in row. */
13785 ptrdiff_t last_pos
= MATRIX_ROW_START_CHARPOS (row
) + delta
;
13787 ptrdiff_t pt_old
= PT
- delta
;
13788 ptrdiff_t pos_before
= MATRIX_ROW_START_CHARPOS (row
) + delta
;
13789 ptrdiff_t pos_after
= MATRIX_ROW_END_CHARPOS (row
) + delta
;
13790 struct glyph
*glyph_before
= glyph
- 1, *glyph_after
= end
;
13791 /* A glyph beyond the edge of TEXT_AREA which we should never
13793 struct glyph
*glyphs_end
= end
;
13794 /* Non-zero means we've found a match for cursor position, but that
13795 glyph has the avoid_cursor_p flag set. */
13796 int match_with_avoid_cursor
= 0;
13797 /* Non-zero means we've seen at least one glyph that came from a
13799 int string_seen
= 0;
13800 /* Largest and smallest buffer positions seen so far during scan of
13802 ptrdiff_t bpos_max
= pos_before
;
13803 ptrdiff_t bpos_min
= pos_after
;
13804 /* Last buffer position covered by an overlay string with an integer
13805 `cursor' property. */
13806 ptrdiff_t bpos_covered
= 0;
13807 /* Non-zero means the display string on which to display the cursor
13808 comes from a text property, not from an overlay. */
13809 int string_from_text_prop
= 0;
13811 /* Don't even try doing anything if called for a mode-line or
13812 header-line row, since the rest of the code isn't prepared to
13813 deal with such calamities. */
13814 eassert (!row
->mode_line_p
);
13815 if (row
->mode_line_p
)
13818 /* Skip over glyphs not having an object at the start and the end of
13819 the row. These are special glyphs like truncation marks on
13820 terminal frames. */
13821 if (MATRIX_ROW_DISPLAYS_TEXT_P (row
))
13823 if (!row
->reversed_p
)
13826 && INTEGERP (glyph
->object
)
13827 && glyph
->charpos
< 0)
13829 x
+= glyph
->pixel_width
;
13833 && INTEGERP ((end
- 1)->object
)
13834 /* CHARPOS is zero for blanks and stretch glyphs
13835 inserted by extend_face_to_end_of_line. */
13836 && (end
- 1)->charpos
<= 0)
13838 glyph_before
= glyph
- 1;
13845 /* If the glyph row is reversed, we need to process it from back
13846 to front, so swap the edge pointers. */
13847 glyphs_end
= end
= glyph
- 1;
13848 glyph
+= row
->used
[TEXT_AREA
] - 1;
13850 while (glyph
> end
+ 1
13851 && INTEGERP (glyph
->object
)
13852 && glyph
->charpos
< 0)
13855 x
-= glyph
->pixel_width
;
13857 if (INTEGERP (glyph
->object
) && glyph
->charpos
< 0)
13859 /* By default, in reversed rows we put the cursor on the
13860 rightmost (first in the reading order) glyph. */
13861 for (g
= end
+ 1; g
< glyph
; g
++)
13862 x
+= g
->pixel_width
;
13864 && INTEGERP ((end
+ 1)->object
)
13865 && (end
+ 1)->charpos
<= 0)
13867 glyph_before
= glyph
+ 1;
13871 else if (row
->reversed_p
)
13873 /* In R2L rows that don't display text, put the cursor on the
13874 rightmost glyph. Case in point: an empty last line that is
13875 part of an R2L paragraph. */
13877 /* Avoid placing the cursor on the last glyph of the row, where
13878 on terminal frames we hold the vertical border between
13879 adjacent windows. */
13880 if (!FRAME_WINDOW_P (WINDOW_XFRAME (w
))
13881 && !WINDOW_RIGHTMOST_P (w
)
13882 && cursor
== row
->glyphs
[LAST_AREA
] - 1)
13884 x
= -1; /* will be computed below, at label compute_x */
13887 /* Step 1: Try to find the glyph whose character position
13888 corresponds to point. If that's not possible, find 2 glyphs
13889 whose character positions are the closest to point, one before
13890 point, the other after it. */
13891 if (!row
->reversed_p
)
13892 while (/* not marched to end of glyph row */
13894 /* glyph was not inserted by redisplay for internal purposes */
13895 && !INTEGERP (glyph
->object
))
13897 if (BUFFERP (glyph
->object
))
13899 ptrdiff_t dpos
= glyph
->charpos
- pt_old
;
13901 if (glyph
->charpos
> bpos_max
)
13902 bpos_max
= glyph
->charpos
;
13903 if (glyph
->charpos
< bpos_min
)
13904 bpos_min
= glyph
->charpos
;
13905 if (!glyph
->avoid_cursor_p
)
13907 /* If we hit point, we've found the glyph on which to
13908 display the cursor. */
13911 match_with_avoid_cursor
= 0;
13914 /* See if we've found a better approximation to
13915 POS_BEFORE or to POS_AFTER. */
13916 if (0 > dpos
&& dpos
> pos_before
- pt_old
)
13918 pos_before
= glyph
->charpos
;
13919 glyph_before
= glyph
;
13921 else if (0 < dpos
&& dpos
< pos_after
- pt_old
)
13923 pos_after
= glyph
->charpos
;
13924 glyph_after
= glyph
;
13927 else if (dpos
== 0)
13928 match_with_avoid_cursor
= 1;
13930 else if (STRINGP (glyph
->object
))
13932 Lisp_Object chprop
;
13933 ptrdiff_t glyph_pos
= glyph
->charpos
;
13935 chprop
= Fget_char_property (make_number (glyph_pos
), Qcursor
,
13937 if (!NILP (chprop
))
13939 /* If the string came from a `display' text property,
13940 look up the buffer position of that property and
13941 use that position to update bpos_max, as if we
13942 actually saw such a position in one of the row's
13943 glyphs. This helps with supporting integer values
13944 of `cursor' property on the display string in
13945 situations where most or all of the row's buffer
13946 text is completely covered by display properties,
13947 so that no glyph with valid buffer positions is
13948 ever seen in the row. */
13949 ptrdiff_t prop_pos
=
13950 string_buffer_position_lim (glyph
->object
, pos_before
,
13953 if (prop_pos
>= pos_before
)
13954 bpos_max
= prop_pos
- 1;
13956 if (INTEGERP (chprop
))
13958 bpos_covered
= bpos_max
+ XINT (chprop
);
13959 /* If the `cursor' property covers buffer positions up
13960 to and including point, we should display cursor on
13961 this glyph. Note that, if a `cursor' property on one
13962 of the string's characters has an integer value, we
13963 will break out of the loop below _before_ we get to
13964 the position match above. IOW, integer values of
13965 the `cursor' property override the "exact match for
13966 point" strategy of positioning the cursor. */
13967 /* Implementation note: bpos_max == pt_old when, e.g.,
13968 we are in an empty line, where bpos_max is set to
13969 MATRIX_ROW_START_CHARPOS, see above. */
13970 if (bpos_max
<= pt_old
&& bpos_covered
>= pt_old
)
13979 x
+= glyph
->pixel_width
;
13982 else if (glyph
> end
) /* row is reversed */
13983 while (!INTEGERP (glyph
->object
))
13985 if (BUFFERP (glyph
->object
))
13987 ptrdiff_t dpos
= glyph
->charpos
- pt_old
;
13989 if (glyph
->charpos
> bpos_max
)
13990 bpos_max
= glyph
->charpos
;
13991 if (glyph
->charpos
< bpos_min
)
13992 bpos_min
= glyph
->charpos
;
13993 if (!glyph
->avoid_cursor_p
)
13997 match_with_avoid_cursor
= 0;
14000 if (0 > dpos
&& dpos
> pos_before
- pt_old
)
14002 pos_before
= glyph
->charpos
;
14003 glyph_before
= glyph
;
14005 else if (0 < dpos
&& dpos
< pos_after
- pt_old
)
14007 pos_after
= glyph
->charpos
;
14008 glyph_after
= glyph
;
14011 else if (dpos
== 0)
14012 match_with_avoid_cursor
= 1;
14014 else if (STRINGP (glyph
->object
))
14016 Lisp_Object chprop
;
14017 ptrdiff_t glyph_pos
= glyph
->charpos
;
14019 chprop
= Fget_char_property (make_number (glyph_pos
), Qcursor
,
14021 if (!NILP (chprop
))
14023 ptrdiff_t prop_pos
=
14024 string_buffer_position_lim (glyph
->object
, pos_before
,
14027 if (prop_pos
>= pos_before
)
14028 bpos_max
= prop_pos
- 1;
14030 if (INTEGERP (chprop
))
14032 bpos_covered
= bpos_max
+ XINT (chprop
);
14033 /* If the `cursor' property covers buffer positions up
14034 to and including point, we should display cursor on
14036 if (bpos_max
<= pt_old
&& bpos_covered
>= pt_old
)
14045 if (glyph
== glyphs_end
) /* don't dereference outside TEXT_AREA */
14047 x
--; /* can't use any pixel_width */
14050 x
-= glyph
->pixel_width
;
14053 /* Step 2: If we didn't find an exact match for point, we need to
14054 look for a proper place to put the cursor among glyphs between
14055 GLYPH_BEFORE and GLYPH_AFTER. */
14056 if (!((row
->reversed_p
? glyph
> glyphs_end
: glyph
< glyphs_end
)
14057 && BUFFERP (glyph
->object
) && glyph
->charpos
== pt_old
)
14058 && !(bpos_max
< pt_old
&& pt_old
<= bpos_covered
))
14060 /* An empty line has a single glyph whose OBJECT is zero and
14061 whose CHARPOS is the position of a newline on that line.
14062 Note that on a TTY, there are more glyphs after that, which
14063 were produced by extend_face_to_end_of_line, but their
14064 CHARPOS is zero or negative. */
14066 (row
->reversed_p
? glyph
> glyphs_end
: glyph
< glyphs_end
)
14067 && INTEGERP (glyph
->object
) && glyph
->charpos
> 0
14068 /* On a TTY, continued and truncated rows also have a glyph at
14069 their end whose OBJECT is zero and whose CHARPOS is
14070 positive (the continuation and truncation glyphs), but such
14071 rows are obviously not "empty". */
14072 && !(row
->continued_p
|| row
->truncated_on_right_p
);
14074 if (row
->ends_in_ellipsis_p
&& pos_after
== last_pos
)
14076 ptrdiff_t ellipsis_pos
;
14078 /* Scan back over the ellipsis glyphs. */
14079 if (!row
->reversed_p
)
14081 ellipsis_pos
= (glyph
- 1)->charpos
;
14082 while (glyph
> row
->glyphs
[TEXT_AREA
]
14083 && (glyph
- 1)->charpos
== ellipsis_pos
)
14084 glyph
--, x
-= glyph
->pixel_width
;
14085 /* That loop always goes one position too far, including
14086 the glyph before the ellipsis. So scan forward over
14088 x
+= glyph
->pixel_width
;
14091 else /* row is reversed */
14093 ellipsis_pos
= (glyph
+ 1)->charpos
;
14094 while (glyph
< row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
] - 1
14095 && (glyph
+ 1)->charpos
== ellipsis_pos
)
14096 glyph
++, x
+= glyph
->pixel_width
;
14097 x
-= glyph
->pixel_width
;
14101 else if (match_with_avoid_cursor
)
14103 cursor
= glyph_after
;
14106 else if (string_seen
)
14108 int incr
= row
->reversed_p
? -1 : +1;
14110 /* Need to find the glyph that came out of a string which is
14111 present at point. That glyph is somewhere between
14112 GLYPH_BEFORE and GLYPH_AFTER, and it came from a string
14113 positioned between POS_BEFORE and POS_AFTER in the
14115 struct glyph
*start
, *stop
;
14116 ptrdiff_t pos
= pos_before
;
14120 /* If the row ends in a newline from a display string,
14121 reordering could have moved the glyphs belonging to the
14122 string out of the [GLYPH_BEFORE..GLYPH_AFTER] range. So
14123 in this case we extend the search to the last glyph in
14124 the row that was not inserted by redisplay. */
14125 if (row
->ends_in_newline_from_string_p
)
14128 pos_after
= MATRIX_ROW_END_CHARPOS (row
) + delta
;
14131 /* GLYPH_BEFORE and GLYPH_AFTER are the glyphs that
14132 correspond to POS_BEFORE and POS_AFTER, respectively. We
14133 need START and STOP in the order that corresponds to the
14134 row's direction as given by its reversed_p flag. If the
14135 directionality of characters between POS_BEFORE and
14136 POS_AFTER is the opposite of the row's base direction,
14137 these characters will have been reordered for display,
14138 and we need to reverse START and STOP. */
14139 if (!row
->reversed_p
)
14141 start
= min (glyph_before
, glyph_after
);
14142 stop
= max (glyph_before
, glyph_after
);
14146 start
= max (glyph_before
, glyph_after
);
14147 stop
= min (glyph_before
, glyph_after
);
14149 for (glyph
= start
+ incr
;
14150 row
->reversed_p
? glyph
> stop
: glyph
< stop
; )
14153 /* Any glyphs that come from the buffer are here because
14154 of bidi reordering. Skip them, and only pay
14155 attention to glyphs that came from some string. */
14156 if (STRINGP (glyph
->object
))
14160 /* If the display property covers the newline, we
14161 need to search for it one position farther. */
14162 ptrdiff_t lim
= pos_after
14163 + (pos_after
== MATRIX_ROW_END_CHARPOS (row
) + delta
);
14165 string_from_text_prop
= 0;
14166 str
= glyph
->object
;
14167 tem
= string_buffer_position_lim (str
, pos
, lim
, 0);
14168 if (tem
== 0 /* from overlay */
14171 /* If the string from which this glyph came is
14172 found in the buffer at point, or at position
14173 that is closer to point than pos_after, then
14174 we've found the glyph we've been looking for.
14175 If it comes from an overlay (tem == 0), and
14176 it has the `cursor' property on one of its
14177 glyphs, record that glyph as a candidate for
14178 displaying the cursor. (As in the
14179 unidirectional version, we will display the
14180 cursor on the last candidate we find.) */
14183 || (tem
- pt_old
> 0 && tem
< pos_after
))
14185 /* The glyphs from this string could have
14186 been reordered. Find the one with the
14187 smallest string position. Or there could
14188 be a character in the string with the
14189 `cursor' property, which means display
14190 cursor on that character's glyph. */
14191 ptrdiff_t strpos
= glyph
->charpos
;
14196 string_from_text_prop
= 1;
14199 (row
->reversed_p
? glyph
> stop
: glyph
< stop
)
14200 && EQ (glyph
->object
, str
);
14204 ptrdiff_t gpos
= glyph
->charpos
;
14206 cprop
= Fget_char_property (make_number (gpos
),
14214 if (tem
&& glyph
->charpos
< strpos
)
14216 strpos
= glyph
->charpos
;
14222 || (tem
- pt_old
> 0 && tem
< pos_after
))
14226 pos
= tem
+ 1; /* don't find previous instances */
14228 /* This string is not what we want; skip all of the
14229 glyphs that came from it. */
14230 while ((row
->reversed_p
? glyph
> stop
: glyph
< stop
)
14231 && EQ (glyph
->object
, str
))
14238 /* If we reached the end of the line, and END was from a string,
14239 the cursor is not on this line. */
14241 && (row
->reversed_p
? glyph
<= end
: glyph
>= end
)
14242 && (row
->reversed_p
? end
> glyphs_end
: end
< glyphs_end
)
14243 && STRINGP (end
->object
)
14244 && row
->continued_p
)
14247 /* A truncated row may not include PT among its character positions.
14248 Setting the cursor inside the scroll margin will trigger
14249 recalculation of hscroll in hscroll_window_tree. But if a
14250 display string covers point, defer to the string-handling
14251 code below to figure this out. */
14252 else if (row
->truncated_on_left_p
&& pt_old
< bpos_min
)
14254 cursor
= glyph_before
;
14257 else if ((row
->truncated_on_right_p
&& pt_old
> bpos_max
)
14258 /* Zero-width characters produce no glyphs. */
14260 && (row
->reversed_p
14261 ? glyph_after
> glyphs_end
14262 : glyph_after
< glyphs_end
)))
14264 cursor
= glyph_after
;
14270 if (cursor
!= NULL
)
14272 else if (glyph
== glyphs_end
14273 && pos_before
== pos_after
14274 && STRINGP ((row
->reversed_p
14275 ? row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
] - 1
14276 : row
->glyphs
[TEXT_AREA
])->object
))
14278 /* If all the glyphs of this row came from strings, put the
14279 cursor on the first glyph of the row. This avoids having the
14280 cursor outside of the text area in this very rare and hard
14284 ? row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
] - 1
14285 : row
->glyphs
[TEXT_AREA
];
14291 /* Need to compute x that corresponds to GLYPH. */
14292 for (g
= row
->glyphs
[TEXT_AREA
], x
= row
->x
; g
< glyph
; g
++)
14294 if (g
>= row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
])
14296 x
+= g
->pixel_width
;
14300 /* ROW could be part of a continued line, which, under bidi
14301 reordering, might have other rows whose start and end charpos
14302 occlude point. Only set w->cursor if we found a better
14303 approximation to the cursor position than we have from previously
14304 examined candidate rows belonging to the same continued line. */
14305 if (/* we already have a candidate row */
14306 w
->cursor
.vpos
>= 0
14307 /* that candidate is not the row we are processing */
14308 && MATRIX_ROW (matrix
, w
->cursor
.vpos
) != row
14309 /* Make sure cursor.vpos specifies a row whose start and end
14310 charpos occlude point, and it is valid candidate for being a
14311 cursor-row. This is because some callers of this function
14312 leave cursor.vpos at the row where the cursor was displayed
14313 during the last redisplay cycle. */
14314 && MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix
, w
->cursor
.vpos
)) <= pt_old
14315 && pt_old
<= MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix
, w
->cursor
.vpos
))
14316 && cursor_row_p (MATRIX_ROW (matrix
, w
->cursor
.vpos
)))
14319 MATRIX_ROW_GLYPH_START (matrix
, w
->cursor
.vpos
) + w
->cursor
.hpos
;
14321 /* Don't consider glyphs that are outside TEXT_AREA. */
14322 if (!(row
->reversed_p
? glyph
> glyphs_end
: glyph
< glyphs_end
))
14324 /* Keep the candidate whose buffer position is the closest to
14325 point or has the `cursor' property. */
14326 if (/* previous candidate is a glyph in TEXT_AREA of that row */
14327 w
->cursor
.hpos
>= 0
14328 && w
->cursor
.hpos
< MATRIX_ROW_USED (matrix
, w
->cursor
.vpos
)
14329 && ((BUFFERP (g1
->object
)
14330 && (g1
->charpos
== pt_old
/* an exact match always wins */
14331 || (BUFFERP (glyph
->object
)
14332 && eabs (g1
->charpos
- pt_old
)
14333 < eabs (glyph
->charpos
- pt_old
))))
14334 /* previous candidate is a glyph from a string that has
14335 a non-nil `cursor' property */
14336 || (STRINGP (g1
->object
)
14337 && (!NILP (Fget_char_property (make_number (g1
->charpos
),
14338 Qcursor
, g1
->object
))
14339 /* previous candidate is from the same display
14340 string as this one, and the display string
14341 came from a text property */
14342 || (EQ (g1
->object
, glyph
->object
)
14343 && string_from_text_prop
)
14344 /* this candidate is from newline and its
14345 position is not an exact match */
14346 || (INTEGERP (glyph
->object
)
14347 && glyph
->charpos
!= pt_old
)))))
14349 /* If this candidate gives an exact match, use that. */
14350 if (!((BUFFERP (glyph
->object
) && glyph
->charpos
== pt_old
)
14351 /* If this candidate is a glyph created for the
14352 terminating newline of a line, and point is on that
14353 newline, it wins because it's an exact match. */
14354 || (!row
->continued_p
14355 && INTEGERP (glyph
->object
)
14356 && glyph
->charpos
== 0
14357 && pt_old
== MATRIX_ROW_END_CHARPOS (row
) - 1))
14358 /* Otherwise, keep the candidate that comes from a row
14359 spanning less buffer positions. This may win when one or
14360 both candidate positions are on glyphs that came from
14361 display strings, for which we cannot compare buffer
14363 && MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix
, w
->cursor
.vpos
))
14364 - MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix
, w
->cursor
.vpos
))
14365 < MATRIX_ROW_END_CHARPOS (row
) - MATRIX_ROW_START_CHARPOS (row
))
14368 w
->cursor
.hpos
= glyph
- row
->glyphs
[TEXT_AREA
];
14370 w
->cursor
.vpos
= MATRIX_ROW_VPOS (row
, matrix
) + dvpos
;
14371 w
->cursor
.y
= row
->y
+ dy
;
14373 if (w
== XWINDOW (selected_window
))
14375 if (!row
->continued_p
14376 && !MATRIX_ROW_CONTINUATION_LINE_P (row
)
14379 this_line_buffer
= XBUFFER (w
->contents
);
14381 CHARPOS (this_line_start_pos
)
14382 = MATRIX_ROW_START_CHARPOS (row
) + delta
;
14383 BYTEPOS (this_line_start_pos
)
14384 = MATRIX_ROW_START_BYTEPOS (row
) + delta_bytes
;
14386 CHARPOS (this_line_end_pos
)
14387 = Z
- (MATRIX_ROW_END_CHARPOS (row
) + delta
);
14388 BYTEPOS (this_line_end_pos
)
14389 = Z_BYTE
- (MATRIX_ROW_END_BYTEPOS (row
) + delta_bytes
);
14391 this_line_y
= w
->cursor
.y
;
14392 this_line_pixel_height
= row
->height
;
14393 this_line_vpos
= w
->cursor
.vpos
;
14394 this_line_start_x
= row
->x
;
14397 CHARPOS (this_line_start_pos
) = 0;
14404 /* Run window scroll functions, if any, for WINDOW with new window
14405 start STARTP. Sets the window start of WINDOW to that position.
14407 We assume that the window's buffer is really current. */
14409 static struct text_pos
14410 run_window_scroll_functions (Lisp_Object window
, struct text_pos startp
)
14412 struct window
*w
= XWINDOW (window
);
14413 SET_MARKER_FROM_TEXT_POS (w
->start
, startp
);
14415 if (current_buffer
!= XBUFFER (w
->contents
))
14418 if (!NILP (Vwindow_scroll_functions
))
14420 run_hook_with_args_2 (Qwindow_scroll_functions
, window
,
14421 make_number (CHARPOS (startp
)));
14422 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
14423 /* In case the hook functions switch buffers. */
14424 set_buffer_internal (XBUFFER (w
->contents
));
14431 /* Make sure the line containing the cursor is fully visible.
14432 A value of 1 means there is nothing to be done.
14433 (Either the line is fully visible, or it cannot be made so,
14434 or we cannot tell.)
14436 If FORCE_P is non-zero, return 0 even if partial visible cursor row
14437 is higher than window.
14439 A value of 0 means the caller should do scrolling
14440 as if point had gone off the screen. */
14443 cursor_row_fully_visible_p (struct window
*w
, int force_p
, int current_matrix_p
)
14445 struct glyph_matrix
*matrix
;
14446 struct glyph_row
*row
;
14449 if (!make_cursor_line_fully_visible_p
)
14452 /* It's not always possible to find the cursor, e.g, when a window
14453 is full of overlay strings. Don't do anything in that case. */
14454 if (w
->cursor
.vpos
< 0)
14457 matrix
= current_matrix_p
? w
->current_matrix
: w
->desired_matrix
;
14458 row
= MATRIX_ROW (matrix
, w
->cursor
.vpos
);
14460 /* If the cursor row is not partially visible, there's nothing to do. */
14461 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w
, row
))
14464 /* If the row the cursor is in is taller than the window's height,
14465 it's not clear what to do, so do nothing. */
14466 window_height
= window_box_height (w
);
14467 if (row
->height
>= window_height
)
14469 if (!force_p
|| MINI_WINDOW_P (w
)
14470 || w
->vscroll
|| w
->cursor
.vpos
== 0)
14477 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
14478 non-zero means only WINDOW is redisplayed in redisplay_internal.
14479 TEMP_SCROLL_STEP has the same meaning as emacs_scroll_step, and is used
14480 in redisplay_window to bring a partially visible line into view in
14481 the case that only the cursor has moved.
14483 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
14484 last screen line's vertical height extends past the end of the screen.
14488 1 if scrolling succeeded
14490 0 if scrolling didn't find point.
14492 -1 if new fonts have been loaded so that we must interrupt
14493 redisplay, adjust glyph matrices, and try again. */
14499 SCROLLING_NEED_LARGER_MATRICES
14502 /* If scroll-conservatively is more than this, never recenter.
14504 If you change this, don't forget to update the doc string of
14505 `scroll-conservatively' and the Emacs manual. */
14506 #define SCROLL_LIMIT 100
14509 try_scrolling (Lisp_Object window
, int just_this_one_p
,
14510 ptrdiff_t arg_scroll_conservatively
, ptrdiff_t scroll_step
,
14511 int temp_scroll_step
, int last_line_misfit
)
14513 struct window
*w
= XWINDOW (window
);
14514 struct frame
*f
= XFRAME (w
->frame
);
14515 struct text_pos pos
, startp
;
14517 int this_scroll_margin
, scroll_max
, rc
, height
;
14518 int dy
= 0, amount_to_scroll
= 0, scroll_down_p
= 0;
14519 int extra_scroll_margin_lines
= last_line_misfit
? 1 : 0;
14520 Lisp_Object aggressive
;
14521 /* We will never try scrolling more than this number of lines. */
14522 int scroll_limit
= SCROLL_LIMIT
;
14525 debug_method_add (w
, "try_scrolling");
14528 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
14530 /* Compute scroll margin height in pixels. We scroll when point is
14531 within this distance from the top or bottom of the window. */
14532 if (scroll_margin
> 0)
14533 this_scroll_margin
= min (scroll_margin
, WINDOW_TOTAL_LINES (w
) / 4)
14534 * FRAME_LINE_HEIGHT (f
);
14536 this_scroll_margin
= 0;
14538 /* Force arg_scroll_conservatively to have a reasonable value, to
14539 avoid scrolling too far away with slow move_it_* functions. Note
14540 that the user can supply scroll-conservatively equal to
14541 `most-positive-fixnum', which can be larger than INT_MAX. */
14542 if (arg_scroll_conservatively
> scroll_limit
)
14544 arg_scroll_conservatively
= scroll_limit
+ 1;
14545 scroll_max
= scroll_limit
* FRAME_LINE_HEIGHT (f
);
14547 else if (scroll_step
|| arg_scroll_conservatively
|| temp_scroll_step
)
14548 /* Compute how much we should try to scroll maximally to bring
14549 point into view. */
14550 scroll_max
= (max (scroll_step
,
14551 max (arg_scroll_conservatively
, temp_scroll_step
))
14552 * FRAME_LINE_HEIGHT (f
));
14553 else if (NUMBERP (BVAR (current_buffer
, scroll_down_aggressively
))
14554 || NUMBERP (BVAR (current_buffer
, scroll_up_aggressively
)))
14555 /* We're trying to scroll because of aggressive scrolling but no
14556 scroll_step is set. Choose an arbitrary one. */
14557 scroll_max
= 10 * FRAME_LINE_HEIGHT (f
);
14563 /* Decide whether to scroll down. */
14564 if (PT
> CHARPOS (startp
))
14566 int scroll_margin_y
;
14568 /* Compute the pixel ypos of the scroll margin, then move IT to
14569 either that ypos or PT, whichever comes first. */
14570 start_display (&it
, w
, startp
);
14571 scroll_margin_y
= it
.last_visible_y
- this_scroll_margin
14572 - FRAME_LINE_HEIGHT (f
) * extra_scroll_margin_lines
;
14573 move_it_to (&it
, PT
, -1, scroll_margin_y
- 1, -1,
14574 (MOVE_TO_POS
| MOVE_TO_Y
));
14576 if (PT
> CHARPOS (it
.current
.pos
))
14578 int y0
= line_bottom_y (&it
);
14579 /* Compute how many pixels below window bottom to stop searching
14580 for PT. This avoids costly search for PT that is far away if
14581 the user limited scrolling by a small number of lines, but
14582 always finds PT if scroll_conservatively is set to a large
14583 number, such as most-positive-fixnum. */
14584 int slack
= max (scroll_max
, 10 * FRAME_LINE_HEIGHT (f
));
14585 int y_to_move
= it
.last_visible_y
+ slack
;
14587 /* Compute the distance from the scroll margin to PT or to
14588 the scroll limit, whichever comes first. This should
14589 include the height of the cursor line, to make that line
14591 move_it_to (&it
, PT
, -1, y_to_move
,
14592 -1, MOVE_TO_POS
| MOVE_TO_Y
);
14593 dy
= line_bottom_y (&it
) - y0
;
14595 if (dy
> scroll_max
)
14596 return SCROLLING_FAILED
;
14605 /* Point is in or below the bottom scroll margin, so move the
14606 window start down. If scrolling conservatively, move it just
14607 enough down to make point visible. If scroll_step is set,
14608 move it down by scroll_step. */
14609 if (arg_scroll_conservatively
)
14611 = min (max (dy
, FRAME_LINE_HEIGHT (f
)),
14612 FRAME_LINE_HEIGHT (f
) * arg_scroll_conservatively
);
14613 else if (scroll_step
|| temp_scroll_step
)
14614 amount_to_scroll
= scroll_max
;
14617 aggressive
= BVAR (current_buffer
, scroll_up_aggressively
);
14618 height
= WINDOW_BOX_TEXT_HEIGHT (w
);
14619 if (NUMBERP (aggressive
))
14621 double float_amount
= XFLOATINT (aggressive
) * height
;
14622 int aggressive_scroll
= float_amount
;
14623 if (aggressive_scroll
== 0 && float_amount
> 0)
14624 aggressive_scroll
= 1;
14625 /* Don't let point enter the scroll margin near top of
14626 the window. This could happen if the value of
14627 scroll_up_aggressively is too large and there are
14628 non-zero margins, because scroll_up_aggressively
14629 means put point that fraction of window height
14630 _from_the_bottom_margin_. */
14631 if (aggressive_scroll
+ 2*this_scroll_margin
> height
)
14632 aggressive_scroll
= height
- 2*this_scroll_margin
;
14633 amount_to_scroll
= dy
+ aggressive_scroll
;
14637 if (amount_to_scroll
<= 0)
14638 return SCROLLING_FAILED
;
14640 start_display (&it
, w
, startp
);
14641 if (arg_scroll_conservatively
<= scroll_limit
)
14642 move_it_vertically (&it
, amount_to_scroll
);
14645 /* Extra precision for users who set scroll-conservatively
14646 to a large number: make sure the amount we scroll
14647 the window start is never less than amount_to_scroll,
14648 which was computed as distance from window bottom to
14649 point. This matters when lines at window top and lines
14650 below window bottom have different height. */
14652 void *it1data
= NULL
;
14653 /* We use a temporary it1 because line_bottom_y can modify
14654 its argument, if it moves one line down; see there. */
14657 SAVE_IT (it1
, it
, it1data
);
14658 start_y
= line_bottom_y (&it1
);
14660 RESTORE_IT (&it
, &it
, it1data
);
14661 move_it_by_lines (&it
, 1);
14662 SAVE_IT (it1
, it
, it1data
);
14663 } while (line_bottom_y (&it1
) - start_y
< amount_to_scroll
);
14666 /* If STARTP is unchanged, move it down another screen line. */
14667 if (CHARPOS (it
.current
.pos
) == CHARPOS (startp
))
14668 move_it_by_lines (&it
, 1);
14669 startp
= it
.current
.pos
;
14673 struct text_pos scroll_margin_pos
= startp
;
14676 /* See if point is inside the scroll margin at the top of the
14678 if (this_scroll_margin
)
14682 start_display (&it
, w
, startp
);
14683 y_start
= it
.current_y
;
14684 move_it_vertically (&it
, this_scroll_margin
);
14685 scroll_margin_pos
= it
.current
.pos
;
14686 /* If we didn't move enough before hitting ZV, request
14687 additional amount of scroll, to move point out of the
14689 if (IT_CHARPOS (it
) == ZV
14690 && it
.current_y
- y_start
< this_scroll_margin
)
14691 y_offset
= this_scroll_margin
- (it
.current_y
- y_start
);
14694 if (PT
< CHARPOS (scroll_margin_pos
))
14696 /* Point is in the scroll margin at the top of the window or
14697 above what is displayed in the window. */
14700 /* Compute the vertical distance from PT to the scroll
14701 margin position. Move as far as scroll_max allows, or
14702 one screenful, or 10 screen lines, whichever is largest.
14703 Give up if distance is greater than scroll_max or if we
14704 didn't reach the scroll margin position. */
14705 SET_TEXT_POS (pos
, PT
, PT_BYTE
);
14706 start_display (&it
, w
, pos
);
14708 y_to_move
= max (it
.last_visible_y
,
14709 max (scroll_max
, 10 * FRAME_LINE_HEIGHT (f
)));
14710 move_it_to (&it
, CHARPOS (scroll_margin_pos
), 0,
14712 MOVE_TO_POS
| MOVE_TO_X
| MOVE_TO_Y
);
14713 dy
= it
.current_y
- y0
;
14714 if (dy
> scroll_max
14715 || IT_CHARPOS (it
) < CHARPOS (scroll_margin_pos
))
14716 return SCROLLING_FAILED
;
14718 /* Additional scroll for when ZV was too close to point. */
14721 /* Compute new window start. */
14722 start_display (&it
, w
, startp
);
14724 if (arg_scroll_conservatively
)
14725 amount_to_scroll
= max (dy
, FRAME_LINE_HEIGHT (f
) *
14726 max (scroll_step
, temp_scroll_step
));
14727 else if (scroll_step
|| temp_scroll_step
)
14728 amount_to_scroll
= scroll_max
;
14731 aggressive
= BVAR (current_buffer
, scroll_down_aggressively
);
14732 height
= WINDOW_BOX_TEXT_HEIGHT (w
);
14733 if (NUMBERP (aggressive
))
14735 double float_amount
= XFLOATINT (aggressive
) * height
;
14736 int aggressive_scroll
= float_amount
;
14737 if (aggressive_scroll
== 0 && float_amount
> 0)
14738 aggressive_scroll
= 1;
14739 /* Don't let point enter the scroll margin near
14740 bottom of the window, if the value of
14741 scroll_down_aggressively happens to be too
14743 if (aggressive_scroll
+ 2*this_scroll_margin
> height
)
14744 aggressive_scroll
= height
- 2*this_scroll_margin
;
14745 amount_to_scroll
= dy
+ aggressive_scroll
;
14749 if (amount_to_scroll
<= 0)
14750 return SCROLLING_FAILED
;
14752 move_it_vertically_backward (&it
, amount_to_scroll
);
14753 startp
= it
.current
.pos
;
14757 /* Run window scroll functions. */
14758 startp
= run_window_scroll_functions (window
, startp
);
14760 /* Display the window. Give up if new fonts are loaded, or if point
14762 if (!try_window (window
, startp
, 0))
14763 rc
= SCROLLING_NEED_LARGER_MATRICES
;
14764 else if (w
->cursor
.vpos
< 0)
14766 clear_glyph_matrix (w
->desired_matrix
);
14767 rc
= SCROLLING_FAILED
;
14771 /* Maybe forget recorded base line for line number display. */
14772 if (!just_this_one_p
14773 || current_buffer
->clip_changed
14774 || BEG_UNCHANGED
< CHARPOS (startp
))
14775 w
->base_line_number
= 0;
14777 /* If cursor ends up on a partially visible line,
14778 treat that as being off the bottom of the screen. */
14779 if (! cursor_row_fully_visible_p (w
, extra_scroll_margin_lines
<= 1, 0)
14780 /* It's possible that the cursor is on the first line of the
14781 buffer, which is partially obscured due to a vscroll
14782 (Bug#7537). In that case, avoid looping forever . */
14783 && extra_scroll_margin_lines
< w
->desired_matrix
->nrows
- 1)
14785 clear_glyph_matrix (w
->desired_matrix
);
14786 ++extra_scroll_margin_lines
;
14789 rc
= SCROLLING_SUCCESS
;
14796 /* Compute a suitable window start for window W if display of W starts
14797 on a continuation line. Value is non-zero if a new window start
14800 The new window start will be computed, based on W's width, starting
14801 from the start of the continued line. It is the start of the
14802 screen line with the minimum distance from the old start W->start. */
14805 compute_window_start_on_continuation_line (struct window
*w
)
14807 struct text_pos pos
, start_pos
;
14808 int window_start_changed_p
= 0;
14810 SET_TEXT_POS_FROM_MARKER (start_pos
, w
->start
);
14812 /* If window start is on a continuation line... Window start may be
14813 < BEGV in case there's invisible text at the start of the
14814 buffer (M-x rmail, for example). */
14815 if (CHARPOS (start_pos
) > BEGV
14816 && FETCH_BYTE (BYTEPOS (start_pos
) - 1) != '\n')
14819 struct glyph_row
*row
;
14821 /* Handle the case that the window start is out of range. */
14822 if (CHARPOS (start_pos
) < BEGV
)
14823 SET_TEXT_POS (start_pos
, BEGV
, BEGV_BYTE
);
14824 else if (CHARPOS (start_pos
) > ZV
)
14825 SET_TEXT_POS (start_pos
, ZV
, ZV_BYTE
);
14827 /* Find the start of the continued line. This should be fast
14828 because find_newline is fast (newline cache). */
14829 row
= w
->desired_matrix
->rows
+ (WINDOW_WANTS_HEADER_LINE_P (w
) ? 1 : 0);
14830 init_iterator (&it
, w
, CHARPOS (start_pos
), BYTEPOS (start_pos
),
14831 row
, DEFAULT_FACE_ID
);
14832 reseat_at_previous_visible_line_start (&it
);
14834 /* If the line start is "too far" away from the window start,
14835 say it takes too much time to compute a new window start. */
14836 if (CHARPOS (start_pos
) - IT_CHARPOS (it
)
14837 < WINDOW_TOTAL_LINES (w
) * WINDOW_TOTAL_COLS (w
))
14839 int min_distance
, distance
;
14841 /* Move forward by display lines to find the new window
14842 start. If window width was enlarged, the new start can
14843 be expected to be > the old start. If window width was
14844 decreased, the new window start will be < the old start.
14845 So, we're looking for the display line start with the
14846 minimum distance from the old window start. */
14847 pos
= it
.current
.pos
;
14848 min_distance
= INFINITY
;
14849 while ((distance
= eabs (CHARPOS (start_pos
) - IT_CHARPOS (it
))),
14850 distance
< min_distance
)
14852 min_distance
= distance
;
14853 pos
= it
.current
.pos
;
14854 move_it_by_lines (&it
, 1);
14857 /* Set the window start there. */
14858 SET_MARKER_FROM_TEXT_POS (w
->start
, pos
);
14859 window_start_changed_p
= 1;
14863 return window_start_changed_p
;
14867 /* Try cursor movement in case text has not changed in window WINDOW,
14868 with window start STARTP. Value is
14870 CURSOR_MOVEMENT_SUCCESS if successful
14872 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
14874 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
14875 display. *SCROLL_STEP is set to 1, under certain circumstances, if
14876 we want to scroll as if scroll-step were set to 1. See the code.
14878 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
14879 which case we have to abort this redisplay, and adjust matrices
14884 CURSOR_MOVEMENT_SUCCESS
,
14885 CURSOR_MOVEMENT_CANNOT_BE_USED
,
14886 CURSOR_MOVEMENT_MUST_SCROLL
,
14887 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
14891 try_cursor_movement (Lisp_Object window
, struct text_pos startp
, int *scroll_step
)
14893 struct window
*w
= XWINDOW (window
);
14894 struct frame
*f
= XFRAME (w
->frame
);
14895 int rc
= CURSOR_MOVEMENT_CANNOT_BE_USED
;
14898 if (inhibit_try_cursor_movement
)
14902 /* Previously, there was a check for Lisp integer in the
14903 if-statement below. Now, this field is converted to
14904 ptrdiff_t, thus zero means invalid position in a buffer. */
14905 eassert (w
->last_point
> 0);
14907 /* Handle case where text has not changed, only point, and it has
14908 not moved off the frame. */
14909 if (/* Point may be in this window. */
14910 PT
>= CHARPOS (startp
)
14911 /* Selective display hasn't changed. */
14912 && !current_buffer
->clip_changed
14913 /* Function force-mode-line-update is used to force a thorough
14914 redisplay. It sets either windows_or_buffers_changed or
14915 update_mode_lines. So don't take a shortcut here for these
14917 && !update_mode_lines
14918 && !windows_or_buffers_changed
14919 && !cursor_type_changed
14920 /* Can't use this case if highlighting a region. When a
14921 region exists, cursor movement has to do more than just
14923 && markpos_of_region () < 0
14924 && !w
->region_showing
14925 && NILP (Vshow_trailing_whitespace
)
14926 /* This code is not used for mini-buffer for the sake of the case
14927 of redisplaying to replace an echo area message; since in
14928 that case the mini-buffer contents per se are usually
14929 unchanged. This code is of no real use in the mini-buffer
14930 since the handling of this_line_start_pos, etc., in redisplay
14931 handles the same cases. */
14932 && !EQ (window
, minibuf_window
)
14933 /* When splitting windows or for new windows, it happens that
14934 redisplay is called with a nil window_end_vpos or one being
14935 larger than the window. This should really be fixed in
14936 window.c. I don't have this on my list, now, so we do
14937 approximately the same as the old redisplay code. --gerd. */
14938 && INTEGERP (w
->window_end_vpos
)
14939 && XFASTINT (w
->window_end_vpos
) < w
->current_matrix
->nrows
14940 && (FRAME_WINDOW_P (f
)
14941 || !overlay_arrow_in_current_buffer_p ()))
14943 int this_scroll_margin
, top_scroll_margin
;
14944 struct glyph_row
*row
= NULL
;
14947 debug_method_add (w
, "cursor movement");
14950 /* Scroll if point within this distance from the top or bottom
14951 of the window. This is a pixel value. */
14952 if (scroll_margin
> 0)
14954 this_scroll_margin
= min (scroll_margin
, WINDOW_TOTAL_LINES (w
) / 4);
14955 this_scroll_margin
*= FRAME_LINE_HEIGHT (f
);
14958 this_scroll_margin
= 0;
14960 top_scroll_margin
= this_scroll_margin
;
14961 if (WINDOW_WANTS_HEADER_LINE_P (w
))
14962 top_scroll_margin
+= CURRENT_HEADER_LINE_HEIGHT (w
);
14964 /* Start with the row the cursor was displayed during the last
14965 not paused redisplay. Give up if that row is not valid. */
14966 if (w
->last_cursor
.vpos
< 0
14967 || w
->last_cursor
.vpos
>= w
->current_matrix
->nrows
)
14968 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
14971 row
= MATRIX_ROW (w
->current_matrix
, w
->last_cursor
.vpos
);
14972 if (row
->mode_line_p
)
14974 if (!row
->enabled_p
)
14975 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
14978 if (rc
== CURSOR_MOVEMENT_CANNOT_BE_USED
)
14980 int scroll_p
= 0, must_scroll
= 0;
14981 int last_y
= window_text_bottom_y (w
) - this_scroll_margin
;
14983 if (PT
> w
->last_point
)
14985 /* Point has moved forward. */
14986 while (MATRIX_ROW_END_CHARPOS (row
) < PT
14987 && MATRIX_ROW_BOTTOM_Y (row
) < last_y
)
14989 eassert (row
->enabled_p
);
14993 /* If the end position of a row equals the start
14994 position of the next row, and PT is at that position,
14995 we would rather display cursor in the next line. */
14996 while (MATRIX_ROW_BOTTOM_Y (row
) < last_y
14997 && MATRIX_ROW_END_CHARPOS (row
) == PT
14998 && row
< MATRIX_MODE_LINE_ROW (w
->current_matrix
)
14999 && MATRIX_ROW_START_CHARPOS (row
+1) == PT
15000 && !cursor_row_p (row
))
15003 /* If within the scroll margin, scroll. Note that
15004 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
15005 the next line would be drawn, and that
15006 this_scroll_margin can be zero. */
15007 if (MATRIX_ROW_BOTTOM_Y (row
) > last_y
15008 || PT
> MATRIX_ROW_END_CHARPOS (row
)
15009 /* Line is completely visible last line in window
15010 and PT is to be set in the next line. */
15011 || (MATRIX_ROW_BOTTOM_Y (row
) == last_y
15012 && PT
== MATRIX_ROW_END_CHARPOS (row
)
15013 && !row
->ends_at_zv_p
15014 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row
)))
15017 else if (PT
< w
->last_point
)
15019 /* Cursor has to be moved backward. Note that PT >=
15020 CHARPOS (startp) because of the outer if-statement. */
15021 while (!row
->mode_line_p
15022 && (MATRIX_ROW_START_CHARPOS (row
) > PT
15023 || (MATRIX_ROW_START_CHARPOS (row
) == PT
15024 && (MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row
)
15025 || (/* STARTS_IN_MIDDLE_OF_STRING_P (row) */
15026 row
> w
->current_matrix
->rows
15027 && (row
-1)->ends_in_newline_from_string_p
))))
15028 && (row
->y
> top_scroll_margin
15029 || CHARPOS (startp
) == BEGV
))
15031 eassert (row
->enabled_p
);
15035 /* Consider the following case: Window starts at BEGV,
15036 there is invisible, intangible text at BEGV, so that
15037 display starts at some point START > BEGV. It can
15038 happen that we are called with PT somewhere between
15039 BEGV and START. Try to handle that case. */
15040 if (row
< w
->current_matrix
->rows
15041 || row
->mode_line_p
)
15043 row
= w
->current_matrix
->rows
;
15044 if (row
->mode_line_p
)
15048 /* Due to newlines in overlay strings, we may have to
15049 skip forward over overlay strings. */
15050 while (MATRIX_ROW_BOTTOM_Y (row
) < last_y
15051 && MATRIX_ROW_END_CHARPOS (row
) == PT
15052 && !cursor_row_p (row
))
15055 /* If within the scroll margin, scroll. */
15056 if (row
->y
< top_scroll_margin
15057 && CHARPOS (startp
) != BEGV
)
15062 /* Cursor did not move. So don't scroll even if cursor line
15063 is partially visible, as it was so before. */
15064 rc
= CURSOR_MOVEMENT_SUCCESS
;
15067 if (PT
< MATRIX_ROW_START_CHARPOS (row
)
15068 || PT
> MATRIX_ROW_END_CHARPOS (row
))
15070 /* if PT is not in the glyph row, give up. */
15071 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
15074 else if (rc
!= CURSOR_MOVEMENT_SUCCESS
15075 && !NILP (BVAR (XBUFFER (w
->contents
), bidi_display_reordering
)))
15077 struct glyph_row
*row1
;
15079 /* If rows are bidi-reordered and point moved, back up
15080 until we find a row that does not belong to a
15081 continuation line. This is because we must consider
15082 all rows of a continued line as candidates for the
15083 new cursor positioning, since row start and end
15084 positions change non-linearly with vertical position
15086 /* FIXME: Revisit this when glyph ``spilling'' in
15087 continuation lines' rows is implemented for
15088 bidi-reordered rows. */
15089 for (row1
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
15090 MATRIX_ROW_CONTINUATION_LINE_P (row
);
15093 /* If we hit the beginning of the displayed portion
15094 without finding the first row of a continued
15098 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
15101 eassert (row
->enabled_p
);
15106 else if (rc
!= CURSOR_MOVEMENT_SUCCESS
15107 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w
, row
)
15108 /* Make sure this isn't a header line by any chance, since
15109 then MATRIX_ROW_PARTIALLY_VISIBLE_P might yield non-zero. */
15110 && !row
->mode_line_p
15111 && make_cursor_line_fully_visible_p
)
15113 if (PT
== MATRIX_ROW_END_CHARPOS (row
)
15114 && !row
->ends_at_zv_p
15115 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row
))
15116 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
15117 else if (row
->height
> window_box_height (w
))
15119 /* If we end up in a partially visible line, let's
15120 make it fully visible, except when it's taller
15121 than the window, in which case we can't do much
15124 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
15128 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
15129 if (!cursor_row_fully_visible_p (w
, 0, 1))
15130 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
15132 rc
= CURSOR_MOVEMENT_SUCCESS
;
15136 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
15137 else if (rc
!= CURSOR_MOVEMENT_SUCCESS
15138 && !NILP (BVAR (XBUFFER (w
->contents
), bidi_display_reordering
)))
15140 /* With bidi-reordered rows, there could be more than
15141 one candidate row whose start and end positions
15142 occlude point. We need to let set_cursor_from_row
15143 find the best candidate. */
15144 /* FIXME: Revisit this when glyph ``spilling'' in
15145 continuation lines' rows is implemented for
15146 bidi-reordered rows. */
15151 int at_zv_p
= 0, exact_match_p
= 0;
15153 if (MATRIX_ROW_START_CHARPOS (row
) <= PT
15154 && PT
<= MATRIX_ROW_END_CHARPOS (row
)
15155 && cursor_row_p (row
))
15156 rv
|= set_cursor_from_row (w
, row
, w
->current_matrix
,
15158 /* As soon as we've found the exact match for point,
15159 or the first suitable row whose ends_at_zv_p flag
15160 is set, we are done. */
15162 MATRIX_ROW (w
->current_matrix
, w
->cursor
.vpos
)->ends_at_zv_p
;
15164 && w
->cursor
.hpos
>= 0
15165 && w
->cursor
.hpos
< MATRIX_ROW_USED (w
->current_matrix
,
15168 struct glyph_row
*candidate
=
15169 MATRIX_ROW (w
->current_matrix
, w
->cursor
.vpos
);
15171 candidate
->glyphs
[TEXT_AREA
] + w
->cursor
.hpos
;
15172 ptrdiff_t endpos
= MATRIX_ROW_END_CHARPOS (candidate
);
15175 (BUFFERP (g
->object
) && g
->charpos
== PT
)
15176 || (INTEGERP (g
->object
)
15177 && (g
->charpos
== PT
15178 || (g
->charpos
== 0 && endpos
- 1 == PT
)));
15180 if (rv
&& (at_zv_p
|| exact_match_p
))
15182 rc
= CURSOR_MOVEMENT_SUCCESS
;
15185 if (MATRIX_ROW_BOTTOM_Y (row
) == last_y
)
15189 while (((MATRIX_ROW_CONTINUATION_LINE_P (row
)
15190 || row
->continued_p
)
15191 && MATRIX_ROW_BOTTOM_Y (row
) <= last_y
)
15192 || (MATRIX_ROW_START_CHARPOS (row
) == PT
15193 && MATRIX_ROW_BOTTOM_Y (row
) < last_y
));
15194 /* If we didn't find any candidate rows, or exited the
15195 loop before all the candidates were examined, signal
15196 to the caller that this method failed. */
15197 if (rc
!= CURSOR_MOVEMENT_SUCCESS
15199 && !MATRIX_ROW_CONTINUATION_LINE_P (row
)
15200 && !row
->continued_p
))
15201 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
15203 rc
= CURSOR_MOVEMENT_SUCCESS
;
15209 if (set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0))
15211 rc
= CURSOR_MOVEMENT_SUCCESS
;
15216 while (MATRIX_ROW_BOTTOM_Y (row
) < last_y
15217 && MATRIX_ROW_START_CHARPOS (row
) == PT
15218 && cursor_row_p (row
));
15226 #if !defined USE_TOOLKIT_SCROLL_BARS || defined USE_GTK
15230 set_vertical_scroll_bar (struct window
*w
)
15232 ptrdiff_t start
, end
, whole
;
15234 /* Calculate the start and end positions for the current window.
15235 At some point, it would be nice to choose between scrollbars
15236 which reflect the whole buffer size, with special markers
15237 indicating narrowing, and scrollbars which reflect only the
15240 Note that mini-buffers sometimes aren't displaying any text. */
15241 if (!MINI_WINDOW_P (w
)
15242 || (w
== XWINDOW (minibuf_window
)
15243 && NILP (echo_area_buffer
[0])))
15245 struct buffer
*buf
= XBUFFER (w
->contents
);
15246 whole
= BUF_ZV (buf
) - BUF_BEGV (buf
);
15247 start
= marker_position (w
->start
) - BUF_BEGV (buf
);
15248 /* I don't think this is guaranteed to be right. For the
15249 moment, we'll pretend it is. */
15250 end
= BUF_Z (buf
) - XFASTINT (w
->window_end_pos
) - BUF_BEGV (buf
);
15254 if (whole
< (end
- start
))
15255 whole
= end
- start
;
15258 start
= end
= whole
= 0;
15260 /* Indicate what this scroll bar ought to be displaying now. */
15261 if (FRAME_TERMINAL (XFRAME (w
->frame
))->set_vertical_scroll_bar_hook
)
15262 (*FRAME_TERMINAL (XFRAME (w
->frame
))->set_vertical_scroll_bar_hook
)
15263 (w
, end
- start
, whole
, start
);
15267 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
15268 selected_window is redisplayed.
15270 We can return without actually redisplaying the window if
15271 fonts_changed_p. In that case, redisplay_internal will
15275 redisplay_window (Lisp_Object window
, int just_this_one_p
)
15277 struct window
*w
= XWINDOW (window
);
15278 struct frame
*f
= XFRAME (w
->frame
);
15279 struct buffer
*buffer
= XBUFFER (w
->contents
);
15280 struct buffer
*old
= current_buffer
;
15281 struct text_pos lpoint
, opoint
, startp
;
15282 int update_mode_line
;
15285 /* Record it now because it's overwritten. */
15286 int current_matrix_up_to_date_p
= 0;
15287 int used_current_matrix_p
= 0;
15288 /* This is less strict than current_matrix_up_to_date_p.
15289 It indicates that the buffer contents and narrowing are unchanged. */
15290 int buffer_unchanged_p
= 0;
15291 int temp_scroll_step
= 0;
15292 ptrdiff_t count
= SPECPDL_INDEX ();
15294 int centering_position
= -1;
15295 int last_line_misfit
= 0;
15296 ptrdiff_t beg_unchanged
, end_unchanged
;
15298 SET_TEXT_POS (lpoint
, PT
, PT_BYTE
);
15302 *w
->desired_matrix
->method
= 0;
15305 /* Make sure that both W's markers are valid. */
15306 eassert (XMARKER (w
->start
)->buffer
== buffer
);
15307 eassert (XMARKER (w
->pointm
)->buffer
== buffer
);
15310 reconsider_clip_changes (w
, buffer
);
15312 /* Has the mode line to be updated? */
15313 update_mode_line
= (w
->update_mode_line
15314 || update_mode_lines
15315 || buffer
->clip_changed
15316 || buffer
->prevent_redisplay_optimizations_p
);
15318 if (MINI_WINDOW_P (w
))
15320 if (w
== XWINDOW (echo_area_window
)
15321 && !NILP (echo_area_buffer
[0]))
15323 if (update_mode_line
)
15324 /* We may have to update a tty frame's menu bar or a
15325 tool-bar. Example `M-x C-h C-h C-g'. */
15326 goto finish_menu_bars
;
15328 /* We've already displayed the echo area glyphs in this window. */
15329 goto finish_scroll_bars
;
15331 else if ((w
!= XWINDOW (minibuf_window
)
15332 || minibuf_level
== 0)
15333 /* When buffer is nonempty, redisplay window normally. */
15334 && BUF_Z (XBUFFER (w
->contents
)) == BUF_BEG (XBUFFER (w
->contents
))
15335 /* Quail displays non-mini buffers in minibuffer window.
15336 In that case, redisplay the window normally. */
15337 && !NILP (Fmemq (w
->contents
, Vminibuffer_list
)))
15339 /* W is a mini-buffer window, but it's not active, so clear
15341 int yb
= window_text_bottom_y (w
);
15342 struct glyph_row
*row
;
15345 for (y
= 0, row
= w
->desired_matrix
->rows
;
15347 y
+= row
->height
, ++row
)
15348 blank_row (w
, row
, y
);
15349 goto finish_scroll_bars
;
15352 clear_glyph_matrix (w
->desired_matrix
);
15355 /* Otherwise set up data on this window; select its buffer and point
15357 /* Really select the buffer, for the sake of buffer-local
15359 set_buffer_internal_1 (XBUFFER (w
->contents
));
15361 current_matrix_up_to_date_p
15362 = (w
->window_end_valid
15363 && !current_buffer
->clip_changed
15364 && !current_buffer
->prevent_redisplay_optimizations_p
15365 && !window_outdated (w
));
15367 /* Run the window-bottom-change-functions
15368 if it is possible that the text on the screen has changed
15369 (either due to modification of the text, or any other reason). */
15370 if (!current_matrix_up_to_date_p
15371 && !NILP (Vwindow_text_change_functions
))
15373 safe_run_hooks (Qwindow_text_change_functions
);
15377 beg_unchanged
= BEG_UNCHANGED
;
15378 end_unchanged
= END_UNCHANGED
;
15380 SET_TEXT_POS (opoint
, PT
, PT_BYTE
);
15382 specbind (Qinhibit_point_motion_hooks
, Qt
);
15385 = (w
->window_end_valid
15386 && !current_buffer
->clip_changed
15387 && !window_outdated (w
));
15389 /* When windows_or_buffers_changed is non-zero, we can't rely on
15390 the window end being valid, so set it to nil there. */
15391 if (windows_or_buffers_changed
)
15393 /* If window starts on a continuation line, maybe adjust the
15394 window start in case the window's width changed. */
15395 if (XMARKER (w
->start
)->buffer
== current_buffer
)
15396 compute_window_start_on_continuation_line (w
);
15398 w
->window_end_valid
= 0;
15401 /* Some sanity checks. */
15402 CHECK_WINDOW_END (w
);
15403 if (Z
== Z_BYTE
&& CHARPOS (opoint
) != BYTEPOS (opoint
))
15405 if (BYTEPOS (opoint
) < CHARPOS (opoint
))
15408 if (mode_line_update_needed (w
))
15409 update_mode_line
= 1;
15411 /* Point refers normally to the selected window. For any other
15412 window, set up appropriate value. */
15413 if (!EQ (window
, selected_window
))
15415 ptrdiff_t new_pt
= marker_position (w
->pointm
);
15416 ptrdiff_t new_pt_byte
= marker_byte_position (w
->pointm
);
15420 new_pt_byte
= BEGV_BYTE
;
15421 set_marker_both (w
->pointm
, Qnil
, BEGV
, BEGV_BYTE
);
15423 else if (new_pt
> (ZV
- 1))
15426 new_pt_byte
= ZV_BYTE
;
15427 set_marker_both (w
->pointm
, Qnil
, ZV
, ZV_BYTE
);
15430 /* We don't use SET_PT so that the point-motion hooks don't run. */
15431 TEMP_SET_PT_BOTH (new_pt
, new_pt_byte
);
15434 /* If any of the character widths specified in the display table
15435 have changed, invalidate the width run cache. It's true that
15436 this may be a bit late to catch such changes, but the rest of
15437 redisplay goes (non-fatally) haywire when the display table is
15438 changed, so why should we worry about doing any better? */
15439 if (current_buffer
->width_run_cache
)
15441 struct Lisp_Char_Table
*disptab
= buffer_display_table ();
15443 if (! disptab_matches_widthtab
15444 (disptab
, XVECTOR (BVAR (current_buffer
, width_table
))))
15446 invalidate_region_cache (current_buffer
,
15447 current_buffer
->width_run_cache
,
15449 recompute_width_table (current_buffer
, disptab
);
15453 /* If window-start is screwed up, choose a new one. */
15454 if (XMARKER (w
->start
)->buffer
!= current_buffer
)
15457 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
15459 /* If someone specified a new starting point but did not insist,
15460 check whether it can be used. */
15461 if (w
->optional_new_start
15462 && CHARPOS (startp
) >= BEGV
15463 && CHARPOS (startp
) <= ZV
)
15465 w
->optional_new_start
= 0;
15466 start_display (&it
, w
, startp
);
15467 move_it_to (&it
, PT
, 0, it
.last_visible_y
, -1,
15468 MOVE_TO_POS
| MOVE_TO_X
| MOVE_TO_Y
);
15469 if (IT_CHARPOS (it
) == PT
)
15470 w
->force_start
= 1;
15471 /* IT may overshoot PT if text at PT is invisible. */
15472 else if (IT_CHARPOS (it
) > PT
&& CHARPOS (startp
) <= PT
)
15473 w
->force_start
= 1;
15478 /* Handle case where place to start displaying has been specified,
15479 unless the specified location is outside the accessible range. */
15480 if (w
->force_start
|| w
->frozen_window_start_p
)
15482 /* We set this later on if we have to adjust point. */
15485 w
->force_start
= 0;
15487 w
->window_end_valid
= 0;
15489 /* Forget any recorded base line for line number display. */
15490 if (!buffer_unchanged_p
)
15491 w
->base_line_number
= 0;
15493 /* Redisplay the mode line. Select the buffer properly for that.
15494 Also, run the hook window-scroll-functions
15495 because we have scrolled. */
15496 /* Note, we do this after clearing force_start because
15497 if there's an error, it is better to forget about force_start
15498 than to get into an infinite loop calling the hook functions
15499 and having them get more errors. */
15500 if (!update_mode_line
15501 || ! NILP (Vwindow_scroll_functions
))
15503 update_mode_line
= 1;
15504 w
->update_mode_line
= 1;
15505 startp
= run_window_scroll_functions (window
, startp
);
15508 w
->last_modified
= 0;
15509 w
->last_overlay_modified
= 0;
15510 if (CHARPOS (startp
) < BEGV
)
15511 SET_TEXT_POS (startp
, BEGV
, BEGV_BYTE
);
15512 else if (CHARPOS (startp
) > ZV
)
15513 SET_TEXT_POS (startp
, ZV
, ZV_BYTE
);
15515 /* Redisplay, then check if cursor has been set during the
15516 redisplay. Give up if new fonts were loaded. */
15517 /* We used to issue a CHECK_MARGINS argument to try_window here,
15518 but this causes scrolling to fail when point begins inside
15519 the scroll margin (bug#148) -- cyd */
15520 if (!try_window (window
, startp
, 0))
15522 w
->force_start
= 1;
15523 clear_glyph_matrix (w
->desired_matrix
);
15524 goto need_larger_matrices
;
15527 if (w
->cursor
.vpos
< 0 && !w
->frozen_window_start_p
)
15529 /* If point does not appear, try to move point so it does
15530 appear. The desired matrix has been built above, so we
15531 can use it here. */
15532 new_vpos
= window_box_height (w
) / 2;
15535 if (!cursor_row_fully_visible_p (w
, 0, 0))
15537 /* Point does appear, but on a line partly visible at end of window.
15538 Move it back to a fully-visible line. */
15539 new_vpos
= window_box_height (w
);
15541 else if (w
->cursor
.vpos
>=0)
15543 /* Some people insist on not letting point enter the scroll
15544 margin, even though this part handles windows that didn't
15546 int margin
= min (scroll_margin
, WINDOW_TOTAL_LINES (w
) / 4);
15547 int pixel_margin
= margin
* FRAME_LINE_HEIGHT (f
);
15548 bool header_line
= WINDOW_WANTS_HEADER_LINE_P (w
);
15550 /* Note: We add an extra FRAME_LINE_HEIGHT, because the loop
15551 below, which finds the row to move point to, advances by
15552 the Y coordinate of the _next_ row, see the definition of
15553 MATRIX_ROW_BOTTOM_Y. */
15554 if (w
->cursor
.vpos
< margin
+ header_line
)
15556 = pixel_margin
+ (header_line
15557 ? CURRENT_HEADER_LINE_HEIGHT (w
)
15558 : 0) + FRAME_LINE_HEIGHT (f
);
15561 int window_height
= window_box_height (w
);
15564 window_height
+= CURRENT_HEADER_LINE_HEIGHT (w
);
15565 if (w
->cursor
.y
>= window_height
- pixel_margin
)
15566 new_vpos
= window_height
- pixel_margin
;
15570 /* If we need to move point for either of the above reasons,
15571 now actually do it. */
15574 struct glyph_row
*row
;
15576 row
= MATRIX_FIRST_TEXT_ROW (w
->desired_matrix
);
15577 while (MATRIX_ROW_BOTTOM_Y (row
) < new_vpos
)
15580 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row
),
15581 MATRIX_ROW_START_BYTEPOS (row
));
15583 if (w
!= XWINDOW (selected_window
))
15584 set_marker_both (w
->pointm
, Qnil
, PT
, PT_BYTE
);
15585 else if (current_buffer
== old
)
15586 SET_TEXT_POS (lpoint
, PT
, PT_BYTE
);
15588 set_cursor_from_row (w
, row
, w
->desired_matrix
, 0, 0, 0, 0);
15590 /* If we are highlighting the region, then we just changed
15591 the region, so redisplay to show it. */
15592 if (markpos_of_region () >= 0)
15594 clear_glyph_matrix (w
->desired_matrix
);
15595 if (!try_window (window
, startp
, 0))
15596 goto need_larger_matrices
;
15601 debug_method_add (w
, "forced window start");
15606 /* Handle case where text has not changed, only point, and it has
15607 not moved off the frame, and we are not retrying after hscroll.
15608 (current_matrix_up_to_date_p is nonzero when retrying.) */
15609 if (current_matrix_up_to_date_p
15610 && (rc
= try_cursor_movement (window
, startp
, &temp_scroll_step
),
15611 rc
!= CURSOR_MOVEMENT_CANNOT_BE_USED
))
15615 case CURSOR_MOVEMENT_SUCCESS
:
15616 used_current_matrix_p
= 1;
15619 case CURSOR_MOVEMENT_MUST_SCROLL
:
15620 goto try_to_scroll
;
15626 /* If current starting point was originally the beginning of a line
15627 but no longer is, find a new starting point. */
15628 else if (w
->start_at_line_beg
15629 && !(CHARPOS (startp
) <= BEGV
15630 || FETCH_BYTE (BYTEPOS (startp
) - 1) == '\n'))
15633 debug_method_add (w
, "recenter 1");
15638 /* Try scrolling with try_window_id. Value is > 0 if update has
15639 been done, it is -1 if we know that the same window start will
15640 not work. It is 0 if unsuccessful for some other reason. */
15641 else if ((tem
= try_window_id (w
)) != 0)
15644 debug_method_add (w
, "try_window_id %d", tem
);
15647 if (fonts_changed_p
)
15648 goto need_larger_matrices
;
15652 /* Otherwise try_window_id has returned -1 which means that we
15653 don't want the alternative below this comment to execute. */
15655 else if (CHARPOS (startp
) >= BEGV
15656 && CHARPOS (startp
) <= ZV
15657 && PT
>= CHARPOS (startp
)
15658 && (CHARPOS (startp
) < ZV
15659 /* Avoid starting at end of buffer. */
15660 || CHARPOS (startp
) == BEGV
15661 || !window_outdated (w
)))
15663 int d1
, d2
, d3
, d4
, d5
, d6
;
15665 /* If first window line is a continuation line, and window start
15666 is inside the modified region, but the first change is before
15667 current window start, we must select a new window start.
15669 However, if this is the result of a down-mouse event (e.g. by
15670 extending the mouse-drag-overlay), we don't want to select a
15671 new window start, since that would change the position under
15672 the mouse, resulting in an unwanted mouse-movement rather
15673 than a simple mouse-click. */
15674 if (!w
->start_at_line_beg
15675 && NILP (do_mouse_tracking
)
15676 && CHARPOS (startp
) > BEGV
15677 && CHARPOS (startp
) > BEG
+ beg_unchanged
15678 && CHARPOS (startp
) <= Z
- end_unchanged
15679 /* Even if w->start_at_line_beg is nil, a new window may
15680 start at a line_beg, since that's how set_buffer_window
15681 sets it. So, we need to check the return value of
15682 compute_window_start_on_continuation_line. (See also
15684 && XMARKER (w
->start
)->buffer
== current_buffer
15685 && compute_window_start_on_continuation_line (w
)
15686 /* It doesn't make sense to force the window start like we
15687 do at label force_start if it is already known that point
15688 will not be visible in the resulting window, because
15689 doing so will move point from its correct position
15690 instead of scrolling the window to bring point into view.
15692 && pos_visible_p (w
, PT
, &d1
, &d2
, &d3
, &d4
, &d5
, &d6
))
15694 w
->force_start
= 1;
15695 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
15700 debug_method_add (w
, "same window start");
15703 /* Try to redisplay starting at same place as before.
15704 If point has not moved off frame, accept the results. */
15705 if (!current_matrix_up_to_date_p
15706 /* Don't use try_window_reusing_current_matrix in this case
15707 because a window scroll function can have changed the
15709 || !NILP (Vwindow_scroll_functions
)
15710 || MINI_WINDOW_P (w
)
15711 || !(used_current_matrix_p
15712 = try_window_reusing_current_matrix (w
)))
15714 IF_DEBUG (debug_method_add (w
, "1"));
15715 if (try_window (window
, startp
, TRY_WINDOW_CHECK_MARGINS
) < 0)
15716 /* -1 means we need to scroll.
15717 0 means we need new matrices, but fonts_changed_p
15718 is set in that case, so we will detect it below. */
15719 goto try_to_scroll
;
15722 if (fonts_changed_p
)
15723 goto need_larger_matrices
;
15725 if (w
->cursor
.vpos
>= 0)
15727 if (!just_this_one_p
15728 || current_buffer
->clip_changed
15729 || BEG_UNCHANGED
< CHARPOS (startp
))
15730 /* Forget any recorded base line for line number display. */
15731 w
->base_line_number
= 0;
15733 if (!cursor_row_fully_visible_p (w
, 1, 0))
15735 clear_glyph_matrix (w
->desired_matrix
);
15736 last_line_misfit
= 1;
15738 /* Drop through and scroll. */
15743 clear_glyph_matrix (w
->desired_matrix
);
15748 w
->last_modified
= 0;
15749 w
->last_overlay_modified
= 0;
15751 /* Redisplay the mode line. Select the buffer properly for that. */
15752 if (!update_mode_line
)
15754 update_mode_line
= 1;
15755 w
->update_mode_line
= 1;
15758 /* Try to scroll by specified few lines. */
15759 if ((scroll_conservatively
15760 || emacs_scroll_step
15761 || temp_scroll_step
15762 || NUMBERP (BVAR (current_buffer
, scroll_up_aggressively
))
15763 || NUMBERP (BVAR (current_buffer
, scroll_down_aggressively
)))
15764 && CHARPOS (startp
) >= BEGV
15765 && CHARPOS (startp
) <= ZV
)
15767 /* The function returns -1 if new fonts were loaded, 1 if
15768 successful, 0 if not successful. */
15769 int ss
= try_scrolling (window
, just_this_one_p
,
15770 scroll_conservatively
,
15772 temp_scroll_step
, last_line_misfit
);
15775 case SCROLLING_SUCCESS
:
15778 case SCROLLING_NEED_LARGER_MATRICES
:
15779 goto need_larger_matrices
;
15781 case SCROLLING_FAILED
:
15789 /* Finally, just choose a place to start which positions point
15790 according to user preferences. */
15795 debug_method_add (w
, "recenter");
15798 /* Forget any previously recorded base line for line number display. */
15799 if (!buffer_unchanged_p
)
15800 w
->base_line_number
= 0;
15802 /* Determine the window start relative to point. */
15803 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
15804 it
.current_y
= it
.last_visible_y
;
15805 if (centering_position
< 0)
15809 ? min (scroll_margin
, WINDOW_TOTAL_LINES (w
) / 4)
15811 ptrdiff_t margin_pos
= CHARPOS (startp
);
15812 Lisp_Object aggressive
;
15815 /* If there is a scroll margin at the top of the window, find
15816 its character position. */
15818 /* Cannot call start_display if startp is not in the
15819 accessible region of the buffer. This can happen when we
15820 have just switched to a different buffer and/or changed
15821 its restriction. In that case, startp is initialized to
15822 the character position 1 (BEGV) because we did not yet
15823 have chance to display the buffer even once. */
15824 && BEGV
<= CHARPOS (startp
) && CHARPOS (startp
) <= ZV
)
15827 void *it1data
= NULL
;
15829 SAVE_IT (it1
, it
, it1data
);
15830 start_display (&it1
, w
, startp
);
15831 move_it_vertically (&it1
, margin
* FRAME_LINE_HEIGHT (f
));
15832 margin_pos
= IT_CHARPOS (it1
);
15833 RESTORE_IT (&it
, &it
, it1data
);
15835 scrolling_up
= PT
> margin_pos
;
15838 ? BVAR (current_buffer
, scroll_up_aggressively
)
15839 : BVAR (current_buffer
, scroll_down_aggressively
);
15841 if (!MINI_WINDOW_P (w
)
15842 && (scroll_conservatively
> SCROLL_LIMIT
|| NUMBERP (aggressive
)))
15846 /* Setting scroll-conservatively overrides
15847 scroll-*-aggressively. */
15848 if (!scroll_conservatively
&& NUMBERP (aggressive
))
15850 double float_amount
= XFLOATINT (aggressive
);
15852 pt_offset
= float_amount
* WINDOW_BOX_TEXT_HEIGHT (w
);
15853 if (pt_offset
== 0 && float_amount
> 0)
15855 if (pt_offset
&& margin
> 0)
15858 /* Compute how much to move the window start backward from
15859 point so that point will be displayed where the user
15863 centering_position
= it
.last_visible_y
;
15865 centering_position
-= pt_offset
;
15866 centering_position
-=
15867 FRAME_LINE_HEIGHT (f
) * (1 + margin
+ (last_line_misfit
!= 0))
15868 + WINDOW_HEADER_LINE_HEIGHT (w
);
15869 /* Don't let point enter the scroll margin near top of
15871 if (centering_position
< margin
* FRAME_LINE_HEIGHT (f
))
15872 centering_position
= margin
* FRAME_LINE_HEIGHT (f
);
15875 centering_position
= margin
* FRAME_LINE_HEIGHT (f
) + pt_offset
;
15878 /* Set the window start half the height of the window backward
15880 centering_position
= window_box_height (w
) / 2;
15882 move_it_vertically_backward (&it
, centering_position
);
15884 eassert (IT_CHARPOS (it
) >= BEGV
);
15886 /* The function move_it_vertically_backward may move over more
15887 than the specified y-distance. If it->w is small, e.g. a
15888 mini-buffer window, we may end up in front of the window's
15889 display area. Start displaying at the start of the line
15890 containing PT in this case. */
15891 if (it
.current_y
<= 0)
15893 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
15894 move_it_vertically_backward (&it
, 0);
15898 it
.current_x
= it
.hpos
= 0;
15900 /* Set the window start position here explicitly, to avoid an
15901 infinite loop in case the functions in window-scroll-functions
15903 set_marker_both (w
->start
, Qnil
, IT_CHARPOS (it
), IT_BYTEPOS (it
));
15905 /* Run scroll hooks. */
15906 startp
= run_window_scroll_functions (window
, it
.current
.pos
);
15908 /* Redisplay the window. */
15909 if (!current_matrix_up_to_date_p
15910 || windows_or_buffers_changed
15911 || cursor_type_changed
15912 /* Don't use try_window_reusing_current_matrix in this case
15913 because it can have changed the buffer. */
15914 || !NILP (Vwindow_scroll_functions
)
15915 || !just_this_one_p
15916 || MINI_WINDOW_P (w
)
15917 || !(used_current_matrix_p
15918 = try_window_reusing_current_matrix (w
)))
15919 try_window (window
, startp
, 0);
15921 /* If new fonts have been loaded (due to fontsets), give up. We
15922 have to start a new redisplay since we need to re-adjust glyph
15924 if (fonts_changed_p
)
15925 goto need_larger_matrices
;
15927 /* If cursor did not appear assume that the middle of the window is
15928 in the first line of the window. Do it again with the next line.
15929 (Imagine a window of height 100, displaying two lines of height
15930 60. Moving back 50 from it->last_visible_y will end in the first
15932 if (w
->cursor
.vpos
< 0)
15934 if (w
->window_end_valid
&& PT
>= Z
- XFASTINT (w
->window_end_pos
))
15936 clear_glyph_matrix (w
->desired_matrix
);
15937 move_it_by_lines (&it
, 1);
15938 try_window (window
, it
.current
.pos
, 0);
15940 else if (PT
< IT_CHARPOS (it
))
15942 clear_glyph_matrix (w
->desired_matrix
);
15943 move_it_by_lines (&it
, -1);
15944 try_window (window
, it
.current
.pos
, 0);
15948 /* Not much we can do about it. */
15952 /* Consider the following case: Window starts at BEGV, there is
15953 invisible, intangible text at BEGV, so that display starts at
15954 some point START > BEGV. It can happen that we are called with
15955 PT somewhere between BEGV and START. Try to handle that case. */
15956 if (w
->cursor
.vpos
< 0)
15958 struct glyph_row
*row
= w
->current_matrix
->rows
;
15959 if (row
->mode_line_p
)
15961 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
15964 if (!cursor_row_fully_visible_p (w
, 0, 0))
15966 /* If vscroll is enabled, disable it and try again. */
15970 clear_glyph_matrix (w
->desired_matrix
);
15974 /* Users who set scroll-conservatively to a large number want
15975 point just above/below the scroll margin. If we ended up
15976 with point's row partially visible, move the window start to
15977 make that row fully visible and out of the margin. */
15978 if (scroll_conservatively
> SCROLL_LIMIT
)
15982 ? min (scroll_margin
, WINDOW_TOTAL_LINES (w
) / 4)
15984 int move_down
= w
->cursor
.vpos
>= WINDOW_TOTAL_LINES (w
) / 2;
15986 move_it_by_lines (&it
, move_down
? margin
+ 1 : -(margin
+ 1));
15987 clear_glyph_matrix (w
->desired_matrix
);
15988 if (1 == try_window (window
, it
.current
.pos
,
15989 TRY_WINDOW_CHECK_MARGINS
))
15993 /* If centering point failed to make the whole line visible,
15994 put point at the top instead. That has to make the whole line
15995 visible, if it can be done. */
15996 if (centering_position
== 0)
15999 clear_glyph_matrix (w
->desired_matrix
);
16000 centering_position
= 0;
16006 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
16007 w
->start_at_line_beg
= (CHARPOS (startp
) == BEGV
16008 || FETCH_BYTE (BYTEPOS (startp
) - 1) == '\n');
16010 /* Display the mode line, if we must. */
16011 if ((update_mode_line
16012 /* If window not full width, must redo its mode line
16013 if (a) the window to its side is being redone and
16014 (b) we do a frame-based redisplay. This is a consequence
16015 of how inverted lines are drawn in frame-based redisplay. */
16016 || (!just_this_one_p
16017 && !FRAME_WINDOW_P (f
)
16018 && !WINDOW_FULL_WIDTH_P (w
))
16019 /* Line number to display. */
16020 || w
->base_line_pos
> 0
16021 /* Column number is displayed and different from the one displayed. */
16022 || (w
->column_number_displayed
!= -1
16023 && (w
->column_number_displayed
!= current_column ())))
16024 /* This means that the window has a mode line. */
16025 && (WINDOW_WANTS_MODELINE_P (w
)
16026 || WINDOW_WANTS_HEADER_LINE_P (w
)))
16028 display_mode_lines (w
);
16030 /* If mode line height has changed, arrange for a thorough
16031 immediate redisplay using the correct mode line height. */
16032 if (WINDOW_WANTS_MODELINE_P (w
)
16033 && CURRENT_MODE_LINE_HEIGHT (w
) != DESIRED_MODE_LINE_HEIGHT (w
))
16035 fonts_changed_p
= 1;
16036 MATRIX_MODE_LINE_ROW (w
->current_matrix
)->height
16037 = DESIRED_MODE_LINE_HEIGHT (w
);
16040 /* If header line height has changed, arrange for a thorough
16041 immediate redisplay using the correct header line height. */
16042 if (WINDOW_WANTS_HEADER_LINE_P (w
)
16043 && CURRENT_HEADER_LINE_HEIGHT (w
) != DESIRED_HEADER_LINE_HEIGHT (w
))
16045 fonts_changed_p
= 1;
16046 MATRIX_HEADER_LINE_ROW (w
->current_matrix
)->height
16047 = DESIRED_HEADER_LINE_HEIGHT (w
);
16050 if (fonts_changed_p
)
16051 goto need_larger_matrices
;
16054 if (!line_number_displayed
&& w
->base_line_pos
!= -1)
16056 w
->base_line_pos
= 0;
16057 w
->base_line_number
= 0;
16062 /* When we reach a frame's selected window, redo the frame's menu bar. */
16063 if (update_mode_line
16064 && EQ (FRAME_SELECTED_WINDOW (f
), window
))
16066 int redisplay_menu_p
= 0;
16068 if (FRAME_WINDOW_P (f
))
16070 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
16071 || defined (HAVE_NS) || defined (USE_GTK)
16072 redisplay_menu_p
= FRAME_EXTERNAL_MENU_BAR (f
);
16074 redisplay_menu_p
= FRAME_MENU_BAR_LINES (f
) > 0;
16078 redisplay_menu_p
= FRAME_MENU_BAR_LINES (f
) > 0;
16080 if (redisplay_menu_p
)
16081 display_menu_bar (w
);
16083 #ifdef HAVE_WINDOW_SYSTEM
16084 if (FRAME_WINDOW_P (f
))
16086 #if defined (USE_GTK) || defined (HAVE_NS)
16087 if (FRAME_EXTERNAL_TOOL_BAR (f
))
16088 redisplay_tool_bar (f
);
16090 if (WINDOWP (f
->tool_bar_window
)
16091 && (FRAME_TOOL_BAR_LINES (f
) > 0
16092 || !NILP (Vauto_resize_tool_bars
))
16093 && redisplay_tool_bar (f
))
16094 ignore_mouse_drag_p
= 1;
16100 #ifdef HAVE_WINDOW_SYSTEM
16101 if (FRAME_WINDOW_P (f
)
16102 && update_window_fringes (w
, (just_this_one_p
16103 || (!used_current_matrix_p
&& !overlay_arrow_seen
)
16104 || w
->pseudo_window_p
)))
16108 if (draw_window_fringes (w
, 1))
16109 x_draw_vertical_border (w
);
16113 #endif /* HAVE_WINDOW_SYSTEM */
16115 /* We go to this label, with fonts_changed_p set,
16116 if it is necessary to try again using larger glyph matrices.
16117 We have to redeem the scroll bar even in this case,
16118 because the loop in redisplay_internal expects that. */
16119 need_larger_matrices
:
16121 finish_scroll_bars
:
16123 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w
))
16125 /* Set the thumb's position and size. */
16126 set_vertical_scroll_bar (w
);
16128 /* Note that we actually used the scroll bar attached to this
16129 window, so it shouldn't be deleted at the end of redisplay. */
16130 if (FRAME_TERMINAL (f
)->redeem_scroll_bar_hook
)
16131 (*FRAME_TERMINAL (f
)->redeem_scroll_bar_hook
) (w
);
16134 /* Restore current_buffer and value of point in it. The window
16135 update may have changed the buffer, so first make sure `opoint'
16136 is still valid (Bug#6177). */
16137 if (CHARPOS (opoint
) < BEGV
)
16138 TEMP_SET_PT_BOTH (BEGV
, BEGV_BYTE
);
16139 else if (CHARPOS (opoint
) > ZV
)
16140 TEMP_SET_PT_BOTH (Z
, Z_BYTE
);
16142 TEMP_SET_PT_BOTH (CHARPOS (opoint
), BYTEPOS (opoint
));
16144 set_buffer_internal_1 (old
);
16145 /* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become
16146 shorter. This can be caused by log truncation in *Messages*. */
16147 if (CHARPOS (lpoint
) <= ZV
)
16148 TEMP_SET_PT_BOTH (CHARPOS (lpoint
), BYTEPOS (lpoint
));
16150 unbind_to (count
, Qnil
);
16154 /* Build the complete desired matrix of WINDOW with a window start
16155 buffer position POS.
16157 Value is 1 if successful. It is zero if fonts were loaded during
16158 redisplay which makes re-adjusting glyph matrices necessary, and -1
16159 if point would appear in the scroll margins.
16160 (We check the former only if TRY_WINDOW_IGNORE_FONTS_CHANGE is
16161 unset in FLAGS, and the latter only if TRY_WINDOW_CHECK_MARGINS is
16165 try_window (Lisp_Object window
, struct text_pos pos
, int flags
)
16167 struct window
*w
= XWINDOW (window
);
16169 struct glyph_row
*last_text_row
= NULL
;
16170 struct frame
*f
= XFRAME (w
->frame
);
16172 /* Make POS the new window start. */
16173 set_marker_both (w
->start
, Qnil
, CHARPOS (pos
), BYTEPOS (pos
));
16175 /* Mark cursor position as unknown. No overlay arrow seen. */
16176 w
->cursor
.vpos
= -1;
16177 overlay_arrow_seen
= 0;
16179 /* Initialize iterator and info to start at POS. */
16180 start_display (&it
, w
, pos
);
16182 /* Display all lines of W. */
16183 while (it
.current_y
< it
.last_visible_y
)
16185 if (display_line (&it
))
16186 last_text_row
= it
.glyph_row
- 1;
16187 if (fonts_changed_p
&& !(flags
& TRY_WINDOW_IGNORE_FONTS_CHANGE
))
16191 /* Don't let the cursor end in the scroll margins. */
16192 if ((flags
& TRY_WINDOW_CHECK_MARGINS
)
16193 && !MINI_WINDOW_P (w
))
16195 int this_scroll_margin
;
16197 if (scroll_margin
> 0)
16199 this_scroll_margin
= min (scroll_margin
, WINDOW_TOTAL_LINES (w
) / 4);
16200 this_scroll_margin
*= FRAME_LINE_HEIGHT (f
);
16203 this_scroll_margin
= 0;
16205 if ((w
->cursor
.y
>= 0 /* not vscrolled */
16206 && w
->cursor
.y
< this_scroll_margin
16207 && CHARPOS (pos
) > BEGV
16208 && IT_CHARPOS (it
) < ZV
)
16209 /* rms: considering make_cursor_line_fully_visible_p here
16210 seems to give wrong results. We don't want to recenter
16211 when the last line is partly visible, we want to allow
16212 that case to be handled in the usual way. */
16213 || w
->cursor
.y
> it
.last_visible_y
- this_scroll_margin
- 1)
16215 w
->cursor
.vpos
= -1;
16216 clear_glyph_matrix (w
->desired_matrix
);
16221 /* If bottom moved off end of frame, change mode line percentage. */
16222 if (XFASTINT (w
->window_end_pos
) <= 0
16223 && Z
!= IT_CHARPOS (it
))
16224 w
->update_mode_line
= 1;
16226 /* Set window_end_pos to the offset of the last character displayed
16227 on the window from the end of current_buffer. Set
16228 window_end_vpos to its row number. */
16231 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row
));
16232 w
->window_end_bytepos
16233 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_text_row
);
16234 wset_window_end_pos
16235 (w
, make_number (Z
- MATRIX_ROW_END_CHARPOS (last_text_row
)));
16236 wset_window_end_vpos
16237 (w
, make_number (MATRIX_ROW_VPOS (last_text_row
, w
->desired_matrix
)));
16239 (MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w
->desired_matrix
,
16240 XFASTINT (w
->window_end_vpos
))));
16244 w
->window_end_bytepos
= Z_BYTE
- ZV_BYTE
;
16245 wset_window_end_pos (w
, make_number (Z
- ZV
));
16246 wset_window_end_vpos (w
, make_number (0));
16249 /* But that is not valid info until redisplay finishes. */
16250 w
->window_end_valid
= 0;
16256 /************************************************************************
16257 Window redisplay reusing current matrix when buffer has not changed
16258 ************************************************************************/
16260 /* Try redisplay of window W showing an unchanged buffer with a
16261 different window start than the last time it was displayed by
16262 reusing its current matrix. Value is non-zero if successful.
16263 W->start is the new window start. */
16266 try_window_reusing_current_matrix (struct window
*w
)
16268 struct frame
*f
= XFRAME (w
->frame
);
16269 struct glyph_row
*bottom_row
;
16272 struct text_pos start
, new_start
;
16273 int nrows_scrolled
, i
;
16274 struct glyph_row
*last_text_row
;
16275 struct glyph_row
*last_reused_text_row
;
16276 struct glyph_row
*start_row
;
16277 int start_vpos
, min_y
, max_y
;
16280 if (inhibit_try_window_reusing
)
16284 if (/* This function doesn't handle terminal frames. */
16285 !FRAME_WINDOW_P (f
)
16286 /* Don't try to reuse the display if windows have been split
16288 || windows_or_buffers_changed
16289 || cursor_type_changed
)
16292 /* Can't do this if region may have changed. */
16293 if (markpos_of_region () >= 0
16294 || w
->region_showing
16295 || !NILP (Vshow_trailing_whitespace
))
16298 /* If top-line visibility has changed, give up. */
16299 if (WINDOW_WANTS_HEADER_LINE_P (w
)
16300 != MATRIX_HEADER_LINE_ROW (w
->current_matrix
)->mode_line_p
)
16303 /* Give up if old or new display is scrolled vertically. We could
16304 make this function handle this, but right now it doesn't. */
16305 start_row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
16306 if (w
->vscroll
|| MATRIX_ROW_PARTIALLY_VISIBLE_P (w
, start_row
))
16309 /* The variable new_start now holds the new window start. The old
16310 start `start' can be determined from the current matrix. */
16311 SET_TEXT_POS_FROM_MARKER (new_start
, w
->start
);
16312 start
= start_row
->minpos
;
16313 start_vpos
= MATRIX_ROW_VPOS (start_row
, w
->current_matrix
);
16315 /* Clear the desired matrix for the display below. */
16316 clear_glyph_matrix (w
->desired_matrix
);
16318 if (CHARPOS (new_start
) <= CHARPOS (start
))
16320 /* Don't use this method if the display starts with an ellipsis
16321 displayed for invisible text. It's not easy to handle that case
16322 below, and it's certainly not worth the effort since this is
16323 not a frequent case. */
16324 if (in_ellipses_for_invisible_text_p (&start_row
->start
, w
))
16327 IF_DEBUG (debug_method_add (w
, "twu1"));
16329 /* Display up to a row that can be reused. The variable
16330 last_text_row is set to the last row displayed that displays
16331 text. Note that it.vpos == 0 if or if not there is a
16332 header-line; it's not the same as the MATRIX_ROW_VPOS! */
16333 start_display (&it
, w
, new_start
);
16334 w
->cursor
.vpos
= -1;
16335 last_text_row
= last_reused_text_row
= NULL
;
16337 while (it
.current_y
< it
.last_visible_y
16338 && !fonts_changed_p
)
16340 /* If we have reached into the characters in the START row,
16341 that means the line boundaries have changed. So we
16342 can't start copying with the row START. Maybe it will
16343 work to start copying with the following row. */
16344 while (IT_CHARPOS (it
) > CHARPOS (start
))
16346 /* Advance to the next row as the "start". */
16348 start
= start_row
->minpos
;
16349 /* If there are no more rows to try, or just one, give up. */
16350 if (start_row
== MATRIX_MODE_LINE_ROW (w
->current_matrix
) - 1
16351 || w
->vscroll
|| MATRIX_ROW_PARTIALLY_VISIBLE_P (w
, start_row
)
16352 || CHARPOS (start
) == ZV
)
16354 clear_glyph_matrix (w
->desired_matrix
);
16358 start_vpos
= MATRIX_ROW_VPOS (start_row
, w
->current_matrix
);
16360 /* If we have reached alignment, we can copy the rest of the
16362 if (IT_CHARPOS (it
) == CHARPOS (start
)
16363 /* Don't accept "alignment" inside a display vector,
16364 since start_row could have started in the middle of
16365 that same display vector (thus their character
16366 positions match), and we have no way of telling if
16367 that is the case. */
16368 && it
.current
.dpvec_index
< 0)
16371 if (display_line (&it
))
16372 last_text_row
= it
.glyph_row
- 1;
16376 /* A value of current_y < last_visible_y means that we stopped
16377 at the previous window start, which in turn means that we
16378 have at least one reusable row. */
16379 if (it
.current_y
< it
.last_visible_y
)
16381 struct glyph_row
*row
;
16383 /* IT.vpos always starts from 0; it counts text lines. */
16384 nrows_scrolled
= it
.vpos
- (start_row
- MATRIX_FIRST_TEXT_ROW (w
->current_matrix
));
16386 /* Find PT if not already found in the lines displayed. */
16387 if (w
->cursor
.vpos
< 0)
16389 int dy
= it
.current_y
- start_row
->y
;
16391 row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
16392 row
= row_containing_pos (w
, PT
, row
, NULL
, dy
);
16394 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0,
16395 dy
, nrows_scrolled
);
16398 clear_glyph_matrix (w
->desired_matrix
);
16403 /* Scroll the display. Do it before the current matrix is
16404 changed. The problem here is that update has not yet
16405 run, i.e. part of the current matrix is not up to date.
16406 scroll_run_hook will clear the cursor, and use the
16407 current matrix to get the height of the row the cursor is
16409 run
.current_y
= start_row
->y
;
16410 run
.desired_y
= it
.current_y
;
16411 run
.height
= it
.last_visible_y
- it
.current_y
;
16413 if (run
.height
> 0 && run
.current_y
!= run
.desired_y
)
16416 FRAME_RIF (f
)->update_window_begin_hook (w
);
16417 FRAME_RIF (f
)->clear_window_mouse_face (w
);
16418 FRAME_RIF (f
)->scroll_run_hook (w
, &run
);
16419 FRAME_RIF (f
)->update_window_end_hook (w
, 0, 0);
16423 /* Shift current matrix down by nrows_scrolled lines. */
16424 bottom_row
= MATRIX_BOTTOM_TEXT_ROW (w
->current_matrix
, w
);
16425 rotate_matrix (w
->current_matrix
,
16427 MATRIX_ROW_VPOS (bottom_row
, w
->current_matrix
),
16430 /* Disable lines that must be updated. */
16431 for (i
= 0; i
< nrows_scrolled
; ++i
)
16432 (start_row
+ i
)->enabled_p
= 0;
16434 /* Re-compute Y positions. */
16435 min_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
16436 max_y
= it
.last_visible_y
;
16437 for (row
= start_row
+ nrows_scrolled
;
16441 row
->y
= it
.current_y
;
16442 row
->visible_height
= row
->height
;
16444 if (row
->y
< min_y
)
16445 row
->visible_height
-= min_y
- row
->y
;
16446 if (row
->y
+ row
->height
> max_y
)
16447 row
->visible_height
-= row
->y
+ row
->height
- max_y
;
16448 if (row
->fringe_bitmap_periodic_p
)
16449 row
->redraw_fringe_bitmaps_p
= 1;
16451 it
.current_y
+= row
->height
;
16453 if (MATRIX_ROW_DISPLAYS_TEXT_P (row
))
16454 last_reused_text_row
= row
;
16455 if (MATRIX_ROW_BOTTOM_Y (row
) >= it
.last_visible_y
)
16459 /* Disable lines in the current matrix which are now
16460 below the window. */
16461 for (++row
; row
< bottom_row
; ++row
)
16462 row
->enabled_p
= row
->mode_line_p
= 0;
16465 /* Update window_end_pos etc.; last_reused_text_row is the last
16466 reused row from the current matrix containing text, if any.
16467 The value of last_text_row is the last displayed line
16468 containing text. */
16469 if (last_reused_text_row
)
16471 w
->window_end_bytepos
16472 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_reused_text_row
);
16473 wset_window_end_pos
16475 - MATRIX_ROW_END_CHARPOS (last_reused_text_row
)));
16476 wset_window_end_vpos
16477 (w
, make_number (MATRIX_ROW_VPOS (last_reused_text_row
,
16478 w
->current_matrix
)));
16480 else if (last_text_row
)
16482 w
->window_end_bytepos
16483 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_text_row
);
16484 wset_window_end_pos
16485 (w
, make_number (Z
- MATRIX_ROW_END_CHARPOS (last_text_row
)));
16486 wset_window_end_vpos
16487 (w
, make_number (MATRIX_ROW_VPOS (last_text_row
,
16488 w
->desired_matrix
)));
16492 /* This window must be completely empty. */
16493 w
->window_end_bytepos
= Z_BYTE
- ZV_BYTE
;
16494 wset_window_end_pos (w
, make_number (Z
- ZV
));
16495 wset_window_end_vpos (w
, make_number (0));
16497 w
->window_end_valid
= 0;
16499 /* Update hint: don't try scrolling again in update_window. */
16500 w
->desired_matrix
->no_scrolling_p
= 1;
16503 debug_method_add (w
, "try_window_reusing_current_matrix 1");
16507 else if (CHARPOS (new_start
) > CHARPOS (start
))
16509 struct glyph_row
*pt_row
, *row
;
16510 struct glyph_row
*first_reusable_row
;
16511 struct glyph_row
*first_row_to_display
;
16513 int yb
= window_text_bottom_y (w
);
16515 /* Find the row starting at new_start, if there is one. Don't
16516 reuse a partially visible line at the end. */
16517 first_reusable_row
= start_row
;
16518 while (first_reusable_row
->enabled_p
16519 && MATRIX_ROW_BOTTOM_Y (first_reusable_row
) < yb
16520 && (MATRIX_ROW_START_CHARPOS (first_reusable_row
)
16521 < CHARPOS (new_start
)))
16522 ++first_reusable_row
;
16524 /* Give up if there is no row to reuse. */
16525 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row
) >= yb
16526 || !first_reusable_row
->enabled_p
16527 || (MATRIX_ROW_START_CHARPOS (first_reusable_row
)
16528 != CHARPOS (new_start
)))
16531 /* We can reuse fully visible rows beginning with
16532 first_reusable_row to the end of the window. Set
16533 first_row_to_display to the first row that cannot be reused.
16534 Set pt_row to the row containing point, if there is any. */
16536 for (first_row_to_display
= first_reusable_row
;
16537 MATRIX_ROW_BOTTOM_Y (first_row_to_display
) < yb
;
16538 ++first_row_to_display
)
16540 if (PT
>= MATRIX_ROW_START_CHARPOS (first_row_to_display
)
16541 && (PT
< MATRIX_ROW_END_CHARPOS (first_row_to_display
)
16542 || (PT
== MATRIX_ROW_END_CHARPOS (first_row_to_display
)
16543 && first_row_to_display
->ends_at_zv_p
16544 && pt_row
== NULL
)))
16545 pt_row
= first_row_to_display
;
16548 /* Start displaying at the start of first_row_to_display. */
16549 eassert (first_row_to_display
->y
< yb
);
16550 init_to_row_start (&it
, w
, first_row_to_display
);
16552 nrows_scrolled
= (MATRIX_ROW_VPOS (first_reusable_row
, w
->current_matrix
)
16554 it
.vpos
= (MATRIX_ROW_VPOS (first_row_to_display
, w
->current_matrix
)
16556 it
.current_y
= (first_row_to_display
->y
- first_reusable_row
->y
16557 + WINDOW_HEADER_LINE_HEIGHT (w
));
16559 /* Display lines beginning with first_row_to_display in the
16560 desired matrix. Set last_text_row to the last row displayed
16561 that displays text. */
16562 it
.glyph_row
= MATRIX_ROW (w
->desired_matrix
, it
.vpos
);
16563 if (pt_row
== NULL
)
16564 w
->cursor
.vpos
= -1;
16565 last_text_row
= NULL
;
16566 while (it
.current_y
< it
.last_visible_y
&& !fonts_changed_p
)
16567 if (display_line (&it
))
16568 last_text_row
= it
.glyph_row
- 1;
16570 /* If point is in a reused row, adjust y and vpos of the cursor
16574 w
->cursor
.vpos
-= nrows_scrolled
;
16575 w
->cursor
.y
-= first_reusable_row
->y
- start_row
->y
;
16578 /* Give up if point isn't in a row displayed or reused. (This
16579 also handles the case where w->cursor.vpos < nrows_scrolled
16580 after the calls to display_line, which can happen with scroll
16581 margins. See bug#1295.) */
16582 if (w
->cursor
.vpos
< 0)
16584 clear_glyph_matrix (w
->desired_matrix
);
16588 /* Scroll the display. */
16589 run
.current_y
= first_reusable_row
->y
;
16590 run
.desired_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
16591 run
.height
= it
.last_visible_y
- run
.current_y
;
16592 dy
= run
.current_y
- run
.desired_y
;
16597 FRAME_RIF (f
)->update_window_begin_hook (w
);
16598 FRAME_RIF (f
)->clear_window_mouse_face (w
);
16599 FRAME_RIF (f
)->scroll_run_hook (w
, &run
);
16600 FRAME_RIF (f
)->update_window_end_hook (w
, 0, 0);
16604 /* Adjust Y positions of reused rows. */
16605 bottom_row
= MATRIX_BOTTOM_TEXT_ROW (w
->current_matrix
, w
);
16606 min_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
16607 max_y
= it
.last_visible_y
;
16608 for (row
= first_reusable_row
; row
< first_row_to_display
; ++row
)
16611 row
->visible_height
= row
->height
;
16612 if (row
->y
< min_y
)
16613 row
->visible_height
-= min_y
- row
->y
;
16614 if (row
->y
+ row
->height
> max_y
)
16615 row
->visible_height
-= row
->y
+ row
->height
- max_y
;
16616 if (row
->fringe_bitmap_periodic_p
)
16617 row
->redraw_fringe_bitmaps_p
= 1;
16620 /* Scroll the current matrix. */
16621 eassert (nrows_scrolled
> 0);
16622 rotate_matrix (w
->current_matrix
,
16624 MATRIX_ROW_VPOS (bottom_row
, w
->current_matrix
),
16627 /* Disable rows not reused. */
16628 for (row
-= nrows_scrolled
; row
< bottom_row
; ++row
)
16629 row
->enabled_p
= 0;
16631 /* Point may have moved to a different line, so we cannot assume that
16632 the previous cursor position is valid; locate the correct row. */
16635 for (row
= MATRIX_ROW (w
->current_matrix
, w
->cursor
.vpos
);
16637 && PT
>= MATRIX_ROW_END_CHARPOS (row
)
16638 && !row
->ends_at_zv_p
;
16642 w
->cursor
.y
= row
->y
;
16644 if (row
< bottom_row
)
16646 /* Can't simply scan the row for point with
16647 bidi-reordered glyph rows. Let set_cursor_from_row
16648 figure out where to put the cursor, and if it fails,
16650 if (!NILP (BVAR (XBUFFER (w
->contents
), bidi_display_reordering
)))
16652 if (!set_cursor_from_row (w
, row
, w
->current_matrix
,
16655 clear_glyph_matrix (w
->desired_matrix
);
16661 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
] + w
->cursor
.hpos
;
16662 struct glyph
*end
= row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
];
16665 && (!BUFFERP (glyph
->object
)
16666 || glyph
->charpos
< PT
);
16670 w
->cursor
.x
+= glyph
->pixel_width
;
16676 /* Adjust window end. A null value of last_text_row means that
16677 the window end is in reused rows which in turn means that
16678 only its vpos can have changed. */
16681 w
->window_end_bytepos
16682 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_text_row
);
16683 wset_window_end_pos
16684 (w
, make_number (Z
- MATRIX_ROW_END_CHARPOS (last_text_row
)));
16685 wset_window_end_vpos
16686 (w
, make_number (MATRIX_ROW_VPOS (last_text_row
,
16687 w
->desired_matrix
)));
16691 wset_window_end_vpos
16692 (w
, make_number (XFASTINT (w
->window_end_vpos
) - nrows_scrolled
));
16695 w
->window_end_valid
= 0;
16696 w
->desired_matrix
->no_scrolling_p
= 1;
16699 debug_method_add (w
, "try_window_reusing_current_matrix 2");
16709 /************************************************************************
16710 Window redisplay reusing current matrix when buffer has changed
16711 ************************************************************************/
16713 static struct glyph_row
*find_last_unchanged_at_beg_row (struct window
*);
16714 static struct glyph_row
*find_first_unchanged_at_end_row (struct window
*,
16715 ptrdiff_t *, ptrdiff_t *);
16716 static struct glyph_row
*
16717 find_last_row_displaying_text (struct glyph_matrix
*, struct it
*,
16718 struct glyph_row
*);
16721 /* Return the last row in MATRIX displaying text. If row START is
16722 non-null, start searching with that row. IT gives the dimensions
16723 of the display. Value is null if matrix is empty; otherwise it is
16724 a pointer to the row found. */
16726 static struct glyph_row
*
16727 find_last_row_displaying_text (struct glyph_matrix
*matrix
, struct it
*it
,
16728 struct glyph_row
*start
)
16730 struct glyph_row
*row
, *row_found
;
16732 /* Set row_found to the last row in IT->w's current matrix
16733 displaying text. The loop looks funny but think of partially
16736 row
= start
? start
: MATRIX_FIRST_TEXT_ROW (matrix
);
16737 while (MATRIX_ROW_DISPLAYS_TEXT_P (row
))
16739 eassert (row
->enabled_p
);
16741 if (MATRIX_ROW_BOTTOM_Y (row
) >= it
->last_visible_y
)
16750 /* Return the last row in the current matrix of W that is not affected
16751 by changes at the start of current_buffer that occurred since W's
16752 current matrix was built. Value is null if no such row exists.
16754 BEG_UNCHANGED us the number of characters unchanged at the start of
16755 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
16756 first changed character in current_buffer. Characters at positions <
16757 BEG + BEG_UNCHANGED are at the same buffer positions as they were
16758 when the current matrix was built. */
16760 static struct glyph_row
*
16761 find_last_unchanged_at_beg_row (struct window
*w
)
16763 ptrdiff_t first_changed_pos
= BEG
+ BEG_UNCHANGED
;
16764 struct glyph_row
*row
;
16765 struct glyph_row
*row_found
= NULL
;
16766 int yb
= window_text_bottom_y (w
);
16768 /* Find the last row displaying unchanged text. */
16769 for (row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
16770 MATRIX_ROW_DISPLAYS_TEXT_P (row
)
16771 && MATRIX_ROW_START_CHARPOS (row
) < first_changed_pos
;
16774 if (/* If row ends before first_changed_pos, it is unchanged,
16775 except in some case. */
16776 MATRIX_ROW_END_CHARPOS (row
) <= first_changed_pos
16777 /* When row ends in ZV and we write at ZV it is not
16779 && !row
->ends_at_zv_p
16780 /* When first_changed_pos is the end of a continued line,
16781 row is not unchanged because it may be no longer
16783 && !(MATRIX_ROW_END_CHARPOS (row
) == first_changed_pos
16784 && (row
->continued_p
16785 || row
->exact_window_width_line_p
))
16786 /* If ROW->end is beyond ZV, then ROW->end is outdated and
16787 needs to be recomputed, so don't consider this row as
16788 unchanged. This happens when the last line was
16789 bidi-reordered and was killed immediately before this
16790 redisplay cycle. In that case, ROW->end stores the
16791 buffer position of the first visual-order character of
16792 the killed text, which is now beyond ZV. */
16793 && CHARPOS (row
->end
.pos
) <= ZV
)
16796 /* Stop if last visible row. */
16797 if (MATRIX_ROW_BOTTOM_Y (row
) >= yb
)
16805 /* Find the first glyph row in the current matrix of W that is not
16806 affected by changes at the end of current_buffer since the
16807 time W's current matrix was built.
16809 Return in *DELTA the number of chars by which buffer positions in
16810 unchanged text at the end of current_buffer must be adjusted.
16812 Return in *DELTA_BYTES the corresponding number of bytes.
16814 Value is null if no such row exists, i.e. all rows are affected by
16817 static struct glyph_row
*
16818 find_first_unchanged_at_end_row (struct window
*w
,
16819 ptrdiff_t *delta
, ptrdiff_t *delta_bytes
)
16821 struct glyph_row
*row
;
16822 struct glyph_row
*row_found
= NULL
;
16824 *delta
= *delta_bytes
= 0;
16826 /* Display must not have been paused, otherwise the current matrix
16827 is not up to date. */
16828 eassert (w
->window_end_valid
);
16830 /* A value of window_end_pos >= END_UNCHANGED means that the window
16831 end is in the range of changed text. If so, there is no
16832 unchanged row at the end of W's current matrix. */
16833 if (XFASTINT (w
->window_end_pos
) >= END_UNCHANGED
)
16836 /* Set row to the last row in W's current matrix displaying text. */
16837 row
= MATRIX_ROW (w
->current_matrix
, XFASTINT (w
->window_end_vpos
));
16839 /* If matrix is entirely empty, no unchanged row exists. */
16840 if (MATRIX_ROW_DISPLAYS_TEXT_P (row
))
16842 /* The value of row is the last glyph row in the matrix having a
16843 meaningful buffer position in it. The end position of row
16844 corresponds to window_end_pos. This allows us to translate
16845 buffer positions in the current matrix to current buffer
16846 positions for characters not in changed text. */
16848 MATRIX_ROW_END_CHARPOS (row
) + XFASTINT (w
->window_end_pos
);
16849 ptrdiff_t Z_BYTE_old
=
16850 MATRIX_ROW_END_BYTEPOS (row
) + w
->window_end_bytepos
;
16851 ptrdiff_t last_unchanged_pos
, last_unchanged_pos_old
;
16852 struct glyph_row
*first_text_row
16853 = MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
16855 *delta
= Z
- Z_old
;
16856 *delta_bytes
= Z_BYTE
- Z_BYTE_old
;
16858 /* Set last_unchanged_pos to the buffer position of the last
16859 character in the buffer that has not been changed. Z is the
16860 index + 1 of the last character in current_buffer, i.e. by
16861 subtracting END_UNCHANGED we get the index of the last
16862 unchanged character, and we have to add BEG to get its buffer
16864 last_unchanged_pos
= Z
- END_UNCHANGED
+ BEG
;
16865 last_unchanged_pos_old
= last_unchanged_pos
- *delta
;
16867 /* Search backward from ROW for a row displaying a line that
16868 starts at a minimum position >= last_unchanged_pos_old. */
16869 for (; row
> first_text_row
; --row
)
16871 /* This used to abort, but it can happen.
16872 It is ok to just stop the search instead here. KFS. */
16873 if (!row
->enabled_p
|| !MATRIX_ROW_DISPLAYS_TEXT_P (row
))
16876 if (MATRIX_ROW_START_CHARPOS (row
) >= last_unchanged_pos_old
)
16881 eassert (!row_found
|| MATRIX_ROW_DISPLAYS_TEXT_P (row_found
));
16887 /* Make sure that glyph rows in the current matrix of window W
16888 reference the same glyph memory as corresponding rows in the
16889 frame's frame matrix. This function is called after scrolling W's
16890 current matrix on a terminal frame in try_window_id and
16891 try_window_reusing_current_matrix. */
16894 sync_frame_with_window_matrix_rows (struct window
*w
)
16896 struct frame
*f
= XFRAME (w
->frame
);
16897 struct glyph_row
*window_row
, *window_row_end
, *frame_row
;
16899 /* Preconditions: W must be a leaf window and full-width. Its frame
16900 must have a frame matrix. */
16901 eassert (BUFFERP (w
->contents
));
16902 eassert (WINDOW_FULL_WIDTH_P (w
));
16903 eassert (!FRAME_WINDOW_P (f
));
16905 /* If W is a full-width window, glyph pointers in W's current matrix
16906 have, by definition, to be the same as glyph pointers in the
16907 corresponding frame matrix. Note that frame matrices have no
16908 marginal areas (see build_frame_matrix). */
16909 window_row
= w
->current_matrix
->rows
;
16910 window_row_end
= window_row
+ w
->current_matrix
->nrows
;
16911 frame_row
= f
->current_matrix
->rows
+ WINDOW_TOP_EDGE_LINE (w
);
16912 while (window_row
< window_row_end
)
16914 struct glyph
*start
= window_row
->glyphs
[LEFT_MARGIN_AREA
];
16915 struct glyph
*end
= window_row
->glyphs
[LAST_AREA
];
16917 frame_row
->glyphs
[LEFT_MARGIN_AREA
] = start
;
16918 frame_row
->glyphs
[TEXT_AREA
] = start
;
16919 frame_row
->glyphs
[RIGHT_MARGIN_AREA
] = end
;
16920 frame_row
->glyphs
[LAST_AREA
] = end
;
16922 /* Disable frame rows whose corresponding window rows have
16923 been disabled in try_window_id. */
16924 if (!window_row
->enabled_p
)
16925 frame_row
->enabled_p
= 0;
16927 ++window_row
, ++frame_row
;
16932 /* Find the glyph row in window W containing CHARPOS. Consider all
16933 rows between START and END (not inclusive). END null means search
16934 all rows to the end of the display area of W. Value is the row
16935 containing CHARPOS or null. */
16938 row_containing_pos (struct window
*w
, ptrdiff_t charpos
,
16939 struct glyph_row
*start
, struct glyph_row
*end
, int dy
)
16941 struct glyph_row
*row
= start
;
16942 struct glyph_row
*best_row
= NULL
;
16943 ptrdiff_t mindif
= BUF_ZV (XBUFFER (w
->contents
)) + 1;
16946 /* If we happen to start on a header-line, skip that. */
16947 if (row
->mode_line_p
)
16950 if ((end
&& row
>= end
) || !row
->enabled_p
)
16953 last_y
= window_text_bottom_y (w
) - dy
;
16957 /* Give up if we have gone too far. */
16958 if (end
&& row
>= end
)
16960 /* This formerly returned if they were equal.
16961 I think that both quantities are of a "last plus one" type;
16962 if so, when they are equal, the row is within the screen. -- rms. */
16963 if (MATRIX_ROW_BOTTOM_Y (row
) > last_y
)
16966 /* If it is in this row, return this row. */
16967 if (! (MATRIX_ROW_END_CHARPOS (row
) < charpos
16968 || (MATRIX_ROW_END_CHARPOS (row
) == charpos
16969 /* The end position of a row equals the start
16970 position of the next row. If CHARPOS is there, we
16971 would rather consider it displayed in the next
16972 line, except when this line ends in ZV. */
16973 && !row_for_charpos_p (row
, charpos
)))
16974 && charpos
>= MATRIX_ROW_START_CHARPOS (row
))
16978 if (NILP (BVAR (XBUFFER (w
->contents
), bidi_display_reordering
))
16979 || (!best_row
&& !row
->continued_p
))
16981 /* In bidi-reordered rows, there could be several rows whose
16982 edges surround CHARPOS, all of these rows belonging to
16983 the same continued line. We need to find the row which
16984 fits CHARPOS the best. */
16985 for (g
= row
->glyphs
[TEXT_AREA
];
16986 g
< row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
];
16989 if (!STRINGP (g
->object
))
16991 if (g
->charpos
> 0 && eabs (g
->charpos
- charpos
) < mindif
)
16993 mindif
= eabs (g
->charpos
- charpos
);
16995 /* Exact match always wins. */
17002 else if (best_row
&& !row
->continued_p
)
17009 /* Try to redisplay window W by reusing its existing display. W's
17010 current matrix must be up to date when this function is called,
17011 i.e. window_end_valid must be nonzero.
17015 1 if display has been updated
17016 0 if otherwise unsuccessful
17017 -1 if redisplay with same window start is known not to succeed
17019 The following steps are performed:
17021 1. Find the last row in the current matrix of W that is not
17022 affected by changes at the start of current_buffer. If no such row
17025 2. Find the first row in W's current matrix that is not affected by
17026 changes at the end of current_buffer. Maybe there is no such row.
17028 3. Display lines beginning with the row + 1 found in step 1 to the
17029 row found in step 2 or, if step 2 didn't find a row, to the end of
17032 4. If cursor is not known to appear on the window, give up.
17034 5. If display stopped at the row found in step 2, scroll the
17035 display and current matrix as needed.
17037 6. Maybe display some lines at the end of W, if we must. This can
17038 happen under various circumstances, like a partially visible line
17039 becoming fully visible, or because newly displayed lines are displayed
17040 in smaller font sizes.
17042 7. Update W's window end information. */
17045 try_window_id (struct window
*w
)
17047 struct frame
*f
= XFRAME (w
->frame
);
17048 struct glyph_matrix
*current_matrix
= w
->current_matrix
;
17049 struct glyph_matrix
*desired_matrix
= w
->desired_matrix
;
17050 struct glyph_row
*last_unchanged_at_beg_row
;
17051 struct glyph_row
*first_unchanged_at_end_row
;
17052 struct glyph_row
*row
;
17053 struct glyph_row
*bottom_row
;
17056 ptrdiff_t delta
= 0, delta_bytes
= 0, stop_pos
;
17058 struct text_pos start_pos
;
17060 int first_unchanged_at_end_vpos
= 0;
17061 struct glyph_row
*last_text_row
, *last_text_row_at_end
;
17062 struct text_pos start
;
17063 ptrdiff_t first_changed_charpos
, last_changed_charpos
;
17066 if (inhibit_try_window_id
)
17070 /* This is handy for debugging. */
17072 #define GIVE_UP(X) \
17074 fprintf (stderr, "try_window_id give up %d\n", (X)); \
17078 #define GIVE_UP(X) return 0
17081 SET_TEXT_POS_FROM_MARKER (start
, w
->start
);
17083 /* Don't use this for mini-windows because these can show
17084 messages and mini-buffers, and we don't handle that here. */
17085 if (MINI_WINDOW_P (w
))
17088 /* This flag is used to prevent redisplay optimizations. */
17089 if (windows_or_buffers_changed
|| cursor_type_changed
)
17092 /* Verify that narrowing has not changed.
17093 Also verify that we were not told to prevent redisplay optimizations.
17094 It would be nice to further
17095 reduce the number of cases where this prevents try_window_id. */
17096 if (current_buffer
->clip_changed
17097 || current_buffer
->prevent_redisplay_optimizations_p
)
17100 /* Window must either use window-based redisplay or be full width. */
17101 if (!FRAME_WINDOW_P (f
)
17102 && (!FRAME_LINE_INS_DEL_OK (f
)
17103 || !WINDOW_FULL_WIDTH_P (w
)))
17106 /* Give up if point is known NOT to appear in W. */
17107 if (PT
< CHARPOS (start
))
17110 /* Another way to prevent redisplay optimizations. */
17111 if (w
->last_modified
== 0)
17114 /* Verify that window is not hscrolled. */
17115 if (w
->hscroll
!= 0)
17118 /* Verify that display wasn't paused. */
17119 if (!w
->window_end_valid
)
17122 /* Can't use this if highlighting a region because a cursor movement
17123 will do more than just set the cursor. */
17124 if (markpos_of_region () >= 0)
17127 /* Likewise if highlighting trailing whitespace. */
17128 if (!NILP (Vshow_trailing_whitespace
))
17131 /* Likewise if showing a region. */
17132 if (w
->region_showing
)
17135 /* Can't use this if overlay arrow position and/or string have
17137 if (overlay_arrows_changed_p ())
17140 /* When word-wrap is on, adding a space to the first word of a
17141 wrapped line can change the wrap position, altering the line
17142 above it. It might be worthwhile to handle this more
17143 intelligently, but for now just redisplay from scratch. */
17144 if (!NILP (BVAR (XBUFFER (w
->contents
), word_wrap
)))
17147 /* Under bidi reordering, adding or deleting a character in the
17148 beginning of a paragraph, before the first strong directional
17149 character, can change the base direction of the paragraph (unless
17150 the buffer specifies a fixed paragraph direction), which will
17151 require to redisplay the whole paragraph. It might be worthwhile
17152 to find the paragraph limits and widen the range of redisplayed
17153 lines to that, but for now just give up this optimization and
17154 redisplay from scratch. */
17155 if (!NILP (BVAR (XBUFFER (w
->contents
), bidi_display_reordering
))
17156 && NILP (BVAR (XBUFFER (w
->contents
), bidi_paragraph_direction
)))
17159 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
17160 only if buffer has really changed. The reason is that the gap is
17161 initially at Z for freshly visited files. The code below would
17162 set end_unchanged to 0 in that case. */
17163 if (MODIFF
> SAVE_MODIFF
17164 /* This seems to happen sometimes after saving a buffer. */
17165 || BEG_UNCHANGED
+ END_UNCHANGED
> Z_BYTE
)
17167 if (GPT
- BEG
< BEG_UNCHANGED
)
17168 BEG_UNCHANGED
= GPT
- BEG
;
17169 if (Z
- GPT
< END_UNCHANGED
)
17170 END_UNCHANGED
= Z
- GPT
;
17173 /* The position of the first and last character that has been changed. */
17174 first_changed_charpos
= BEG
+ BEG_UNCHANGED
;
17175 last_changed_charpos
= Z
- END_UNCHANGED
;
17177 /* If window starts after a line end, and the last change is in
17178 front of that newline, then changes don't affect the display.
17179 This case happens with stealth-fontification. Note that although
17180 the display is unchanged, glyph positions in the matrix have to
17181 be adjusted, of course. */
17182 row
= MATRIX_ROW (w
->current_matrix
, XFASTINT (w
->window_end_vpos
));
17183 if (MATRIX_ROW_DISPLAYS_TEXT_P (row
)
17184 && ((last_changed_charpos
< CHARPOS (start
)
17185 && CHARPOS (start
) == BEGV
)
17186 || (last_changed_charpos
< CHARPOS (start
) - 1
17187 && FETCH_BYTE (BYTEPOS (start
) - 1) == '\n')))
17189 ptrdiff_t Z_old
, Z_delta
, Z_BYTE_old
, Z_delta_bytes
;
17190 struct glyph_row
*r0
;
17192 /* Compute how many chars/bytes have been added to or removed
17193 from the buffer. */
17194 Z_old
= MATRIX_ROW_END_CHARPOS (row
) + XFASTINT (w
->window_end_pos
);
17195 Z_BYTE_old
= MATRIX_ROW_END_BYTEPOS (row
) + w
->window_end_bytepos
;
17196 Z_delta
= Z
- Z_old
;
17197 Z_delta_bytes
= Z_BYTE
- Z_BYTE_old
;
17199 /* Give up if PT is not in the window. Note that it already has
17200 been checked at the start of try_window_id that PT is not in
17201 front of the window start. */
17202 if (PT
>= MATRIX_ROW_END_CHARPOS (row
) + Z_delta
)
17205 /* If window start is unchanged, we can reuse the whole matrix
17206 as is, after adjusting glyph positions. No need to compute
17207 the window end again, since its offset from Z hasn't changed. */
17208 r0
= MATRIX_FIRST_TEXT_ROW (current_matrix
);
17209 if (CHARPOS (start
) == MATRIX_ROW_START_CHARPOS (r0
) + Z_delta
17210 && BYTEPOS (start
) == MATRIX_ROW_START_BYTEPOS (r0
) + Z_delta_bytes
17211 /* PT must not be in a partially visible line. */
17212 && !(PT
>= MATRIX_ROW_START_CHARPOS (row
) + Z_delta
17213 && MATRIX_ROW_BOTTOM_Y (row
) > window_text_bottom_y (w
)))
17215 /* Adjust positions in the glyph matrix. */
17216 if (Z_delta
|| Z_delta_bytes
)
17218 struct glyph_row
*r1
17219 = MATRIX_BOTTOM_TEXT_ROW (current_matrix
, w
);
17220 increment_matrix_positions (w
->current_matrix
,
17221 MATRIX_ROW_VPOS (r0
, current_matrix
),
17222 MATRIX_ROW_VPOS (r1
, current_matrix
),
17223 Z_delta
, Z_delta_bytes
);
17226 /* Set the cursor. */
17227 row
= row_containing_pos (w
, PT
, r0
, NULL
, 0);
17229 set_cursor_from_row (w
, row
, current_matrix
, 0, 0, 0, 0);
17236 /* Handle the case that changes are all below what is displayed in
17237 the window, and that PT is in the window. This shortcut cannot
17238 be taken if ZV is visible in the window, and text has been added
17239 there that is visible in the window. */
17240 if (first_changed_charpos
>= MATRIX_ROW_END_CHARPOS (row
)
17241 /* ZV is not visible in the window, or there are no
17242 changes at ZV, actually. */
17243 && (current_matrix
->zv
> MATRIX_ROW_END_CHARPOS (row
)
17244 || first_changed_charpos
== last_changed_charpos
))
17246 struct glyph_row
*r0
;
17248 /* Give up if PT is not in the window. Note that it already has
17249 been checked at the start of try_window_id that PT is not in
17250 front of the window start. */
17251 if (PT
>= MATRIX_ROW_END_CHARPOS (row
))
17254 /* If window start is unchanged, we can reuse the whole matrix
17255 as is, without changing glyph positions since no text has
17256 been added/removed in front of the window end. */
17257 r0
= MATRIX_FIRST_TEXT_ROW (current_matrix
);
17258 if (TEXT_POS_EQUAL_P (start
, r0
->minpos
)
17259 /* PT must not be in a partially visible line. */
17260 && !(PT
>= MATRIX_ROW_START_CHARPOS (row
)
17261 && MATRIX_ROW_BOTTOM_Y (row
) > window_text_bottom_y (w
)))
17263 /* We have to compute the window end anew since text
17264 could have been added/removed after it. */
17265 wset_window_end_pos
17266 (w
, make_number (Z
- MATRIX_ROW_END_CHARPOS (row
)));
17267 w
->window_end_bytepos
17268 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (row
);
17270 /* Set the cursor. */
17271 row
= row_containing_pos (w
, PT
, r0
, NULL
, 0);
17273 set_cursor_from_row (w
, row
, current_matrix
, 0, 0, 0, 0);
17280 /* Give up if window start is in the changed area.
17282 The condition used to read
17284 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
17286 but why that was tested escapes me at the moment. */
17287 if (CHARPOS (start
) >= first_changed_charpos
17288 && CHARPOS (start
) <= last_changed_charpos
)
17291 /* Check that window start agrees with the start of the first glyph
17292 row in its current matrix. Check this after we know the window
17293 start is not in changed text, otherwise positions would not be
17295 row
= MATRIX_FIRST_TEXT_ROW (current_matrix
);
17296 if (!TEXT_POS_EQUAL_P (start
, row
->minpos
))
17299 /* Give up if the window ends in strings. Overlay strings
17300 at the end are difficult to handle, so don't try. */
17301 row
= MATRIX_ROW (current_matrix
, XFASTINT (w
->window_end_vpos
));
17302 if (MATRIX_ROW_START_CHARPOS (row
) == MATRIX_ROW_END_CHARPOS (row
))
17305 /* Compute the position at which we have to start displaying new
17306 lines. Some of the lines at the top of the window might be
17307 reusable because they are not displaying changed text. Find the
17308 last row in W's current matrix not affected by changes at the
17309 start of current_buffer. Value is null if changes start in the
17310 first line of window. */
17311 last_unchanged_at_beg_row
= find_last_unchanged_at_beg_row (w
);
17312 if (last_unchanged_at_beg_row
)
17314 /* Avoid starting to display in the middle of a character, a TAB
17315 for instance. This is easier than to set up the iterator
17316 exactly, and it's not a frequent case, so the additional
17317 effort wouldn't really pay off. */
17318 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row
)
17319 || last_unchanged_at_beg_row
->ends_in_newline_from_string_p
)
17320 && last_unchanged_at_beg_row
> w
->current_matrix
->rows
)
17321 --last_unchanged_at_beg_row
;
17323 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row
))
17326 if (init_to_row_end (&it
, w
, last_unchanged_at_beg_row
) == 0)
17328 start_pos
= it
.current
.pos
;
17330 /* Start displaying new lines in the desired matrix at the same
17331 vpos we would use in the current matrix, i.e. below
17332 last_unchanged_at_beg_row. */
17333 it
.vpos
= 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row
,
17335 it
.glyph_row
= MATRIX_ROW (desired_matrix
, it
.vpos
);
17336 it
.current_y
= MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row
);
17338 eassert (it
.hpos
== 0 && it
.current_x
== 0);
17342 /* There are no reusable lines at the start of the window.
17343 Start displaying in the first text line. */
17344 start_display (&it
, w
, start
);
17345 it
.vpos
= it
.first_vpos
;
17346 start_pos
= it
.current
.pos
;
17349 /* Find the first row that is not affected by changes at the end of
17350 the buffer. Value will be null if there is no unchanged row, in
17351 which case we must redisplay to the end of the window. delta
17352 will be set to the value by which buffer positions beginning with
17353 first_unchanged_at_end_row have to be adjusted due to text
17355 first_unchanged_at_end_row
17356 = find_first_unchanged_at_end_row (w
, &delta
, &delta_bytes
);
17357 IF_DEBUG (debug_delta
= delta
);
17358 IF_DEBUG (debug_delta_bytes
= delta_bytes
);
17360 /* Set stop_pos to the buffer position up to which we will have to
17361 display new lines. If first_unchanged_at_end_row != NULL, this
17362 is the buffer position of the start of the line displayed in that
17363 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
17364 that we don't stop at a buffer position. */
17366 if (first_unchanged_at_end_row
)
17368 eassert (last_unchanged_at_beg_row
== NULL
17369 || first_unchanged_at_end_row
>= last_unchanged_at_beg_row
);
17371 /* If this is a continuation line, move forward to the next one
17372 that isn't. Changes in lines above affect this line.
17373 Caution: this may move first_unchanged_at_end_row to a row
17374 not displaying text. */
17375 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row
)
17376 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row
)
17377 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row
)
17378 < it
.last_visible_y
))
17379 ++first_unchanged_at_end_row
;
17381 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row
)
17382 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row
)
17383 >= it
.last_visible_y
))
17384 first_unchanged_at_end_row
= NULL
;
17387 stop_pos
= (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row
)
17389 first_unchanged_at_end_vpos
17390 = MATRIX_ROW_VPOS (first_unchanged_at_end_row
, current_matrix
);
17391 eassert (stop_pos
>= Z
- END_UNCHANGED
);
17394 else if (last_unchanged_at_beg_row
== NULL
)
17400 /* Either there is no unchanged row at the end, or the one we have
17401 now displays text. This is a necessary condition for the window
17402 end pos calculation at the end of this function. */
17403 eassert (first_unchanged_at_end_row
== NULL
17404 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row
));
17406 debug_last_unchanged_at_beg_vpos
17407 = (last_unchanged_at_beg_row
17408 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row
, current_matrix
)
17410 debug_first_unchanged_at_end_vpos
= first_unchanged_at_end_vpos
;
17412 #endif /* GLYPH_DEBUG */
17415 /* Display new lines. Set last_text_row to the last new line
17416 displayed which has text on it, i.e. might end up as being the
17417 line where the window_end_vpos is. */
17418 w
->cursor
.vpos
= -1;
17419 last_text_row
= NULL
;
17420 overlay_arrow_seen
= 0;
17421 while (it
.current_y
< it
.last_visible_y
17422 && !fonts_changed_p
17423 && (first_unchanged_at_end_row
== NULL
17424 || IT_CHARPOS (it
) < stop_pos
))
17426 if (display_line (&it
))
17427 last_text_row
= it
.glyph_row
- 1;
17430 if (fonts_changed_p
)
17434 /* Compute differences in buffer positions, y-positions etc. for
17435 lines reused at the bottom of the window. Compute what we can
17437 if (first_unchanged_at_end_row
17438 /* No lines reused because we displayed everything up to the
17439 bottom of the window. */
17440 && it
.current_y
< it
.last_visible_y
)
17443 - MATRIX_ROW_VPOS (first_unchanged_at_end_row
,
17445 dy
= it
.current_y
- first_unchanged_at_end_row
->y
;
17446 run
.current_y
= first_unchanged_at_end_row
->y
;
17447 run
.desired_y
= run
.current_y
+ dy
;
17448 run
.height
= it
.last_visible_y
- max (run
.current_y
, run
.desired_y
);
17452 delta
= delta_bytes
= dvpos
= dy
17453 = run
.current_y
= run
.desired_y
= run
.height
= 0;
17454 first_unchanged_at_end_row
= NULL
;
17456 IF_DEBUG (debug_dvpos
= dvpos
; debug_dy
= dy
);
17459 /* Find the cursor if not already found. We have to decide whether
17460 PT will appear on this window (it sometimes doesn't, but this is
17461 not a very frequent case.) This decision has to be made before
17462 the current matrix is altered. A value of cursor.vpos < 0 means
17463 that PT is either in one of the lines beginning at
17464 first_unchanged_at_end_row or below the window. Don't care for
17465 lines that might be displayed later at the window end; as
17466 mentioned, this is not a frequent case. */
17467 if (w
->cursor
.vpos
< 0)
17469 /* Cursor in unchanged rows at the top? */
17470 if (PT
< CHARPOS (start_pos
)
17471 && last_unchanged_at_beg_row
)
17473 row
= row_containing_pos (w
, PT
,
17474 MATRIX_FIRST_TEXT_ROW (w
->current_matrix
),
17475 last_unchanged_at_beg_row
+ 1, 0);
17477 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
17480 /* Start from first_unchanged_at_end_row looking for PT. */
17481 else if (first_unchanged_at_end_row
)
17483 row
= row_containing_pos (w
, PT
- delta
,
17484 first_unchanged_at_end_row
, NULL
, 0);
17486 set_cursor_from_row (w
, row
, w
->current_matrix
, delta
,
17487 delta_bytes
, dy
, dvpos
);
17490 /* Give up if cursor was not found. */
17491 if (w
->cursor
.vpos
< 0)
17493 clear_glyph_matrix (w
->desired_matrix
);
17498 /* Don't let the cursor end in the scroll margins. */
17500 int this_scroll_margin
, cursor_height
;
17502 this_scroll_margin
=
17503 max (0, min (scroll_margin
, WINDOW_TOTAL_LINES (w
) / 4));
17504 this_scroll_margin
*= FRAME_LINE_HEIGHT (it
.f
);
17505 cursor_height
= MATRIX_ROW (w
->desired_matrix
, w
->cursor
.vpos
)->height
;
17507 if ((w
->cursor
.y
< this_scroll_margin
17508 && CHARPOS (start
) > BEGV
)
17509 /* Old redisplay didn't take scroll margin into account at the bottom,
17510 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
17511 || (w
->cursor
.y
+ (make_cursor_line_fully_visible_p
17512 ? cursor_height
+ this_scroll_margin
17513 : 1)) > it
.last_visible_y
)
17515 w
->cursor
.vpos
= -1;
17516 clear_glyph_matrix (w
->desired_matrix
);
17521 /* Scroll the display. Do it before changing the current matrix so
17522 that xterm.c doesn't get confused about where the cursor glyph is
17524 if (dy
&& run
.height
)
17528 if (FRAME_WINDOW_P (f
))
17530 FRAME_RIF (f
)->update_window_begin_hook (w
);
17531 FRAME_RIF (f
)->clear_window_mouse_face (w
);
17532 FRAME_RIF (f
)->scroll_run_hook (w
, &run
);
17533 FRAME_RIF (f
)->update_window_end_hook (w
, 0, 0);
17537 /* Terminal frame. In this case, dvpos gives the number of
17538 lines to scroll by; dvpos < 0 means scroll up. */
17540 = MATRIX_ROW_VPOS (first_unchanged_at_end_row
, w
->current_matrix
);
17541 int from
= WINDOW_TOP_EDGE_LINE (w
) + from_vpos
;
17542 int end
= (WINDOW_TOP_EDGE_LINE (w
)
17543 + (WINDOW_WANTS_HEADER_LINE_P (w
) ? 1 : 0)
17544 + window_internal_height (w
));
17546 #if defined (HAVE_GPM) || defined (MSDOS)
17547 x_clear_window_mouse_face (w
);
17549 /* Perform the operation on the screen. */
17552 /* Scroll last_unchanged_at_beg_row to the end of the
17553 window down dvpos lines. */
17554 set_terminal_window (f
, end
);
17556 /* On dumb terminals delete dvpos lines at the end
17557 before inserting dvpos empty lines. */
17558 if (!FRAME_SCROLL_REGION_OK (f
))
17559 ins_del_lines (f
, end
- dvpos
, -dvpos
);
17561 /* Insert dvpos empty lines in front of
17562 last_unchanged_at_beg_row. */
17563 ins_del_lines (f
, from
, dvpos
);
17565 else if (dvpos
< 0)
17567 /* Scroll up last_unchanged_at_beg_vpos to the end of
17568 the window to last_unchanged_at_beg_vpos - |dvpos|. */
17569 set_terminal_window (f
, end
);
17571 /* Delete dvpos lines in front of
17572 last_unchanged_at_beg_vpos. ins_del_lines will set
17573 the cursor to the given vpos and emit |dvpos| delete
17575 ins_del_lines (f
, from
+ dvpos
, dvpos
);
17577 /* On a dumb terminal insert dvpos empty lines at the
17579 if (!FRAME_SCROLL_REGION_OK (f
))
17580 ins_del_lines (f
, end
+ dvpos
, -dvpos
);
17583 set_terminal_window (f
, 0);
17589 /* Shift reused rows of the current matrix to the right position.
17590 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
17592 bottom_row
= MATRIX_BOTTOM_TEXT_ROW (current_matrix
, w
);
17593 bottom_vpos
= MATRIX_ROW_VPOS (bottom_row
, current_matrix
);
17596 rotate_matrix (current_matrix
, first_unchanged_at_end_vpos
+ dvpos
,
17597 bottom_vpos
, dvpos
);
17598 clear_glyph_matrix_rows (current_matrix
, bottom_vpos
+ dvpos
,
17601 else if (dvpos
> 0)
17603 rotate_matrix (current_matrix
, first_unchanged_at_end_vpos
,
17604 bottom_vpos
, dvpos
);
17605 clear_glyph_matrix_rows (current_matrix
, first_unchanged_at_end_vpos
,
17606 first_unchanged_at_end_vpos
+ dvpos
);
17609 /* For frame-based redisplay, make sure that current frame and window
17610 matrix are in sync with respect to glyph memory. */
17611 if (!FRAME_WINDOW_P (f
))
17612 sync_frame_with_window_matrix_rows (w
);
17614 /* Adjust buffer positions in reused rows. */
17615 if (delta
|| delta_bytes
)
17616 increment_matrix_positions (current_matrix
,
17617 first_unchanged_at_end_vpos
+ dvpos
,
17618 bottom_vpos
, delta
, delta_bytes
);
17620 /* Adjust Y positions. */
17622 shift_glyph_matrix (w
, current_matrix
,
17623 first_unchanged_at_end_vpos
+ dvpos
,
17626 if (first_unchanged_at_end_row
)
17628 first_unchanged_at_end_row
+= dvpos
;
17629 if (first_unchanged_at_end_row
->y
>= it
.last_visible_y
17630 || !MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row
))
17631 first_unchanged_at_end_row
= NULL
;
17634 /* If scrolling up, there may be some lines to display at the end of
17636 last_text_row_at_end
= NULL
;
17639 /* Scrolling up can leave for example a partially visible line
17640 at the end of the window to be redisplayed. */
17641 /* Set last_row to the glyph row in the current matrix where the
17642 window end line is found. It has been moved up or down in
17643 the matrix by dvpos. */
17644 int last_vpos
= XFASTINT (w
->window_end_vpos
) + dvpos
;
17645 struct glyph_row
*last_row
= MATRIX_ROW (current_matrix
, last_vpos
);
17647 /* If last_row is the window end line, it should display text. */
17648 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_row
));
17650 /* If window end line was partially visible before, begin
17651 displaying at that line. Otherwise begin displaying with the
17652 line following it. */
17653 if (MATRIX_ROW_BOTTOM_Y (last_row
) - dy
>= it
.last_visible_y
)
17655 init_to_row_start (&it
, w
, last_row
);
17656 it
.vpos
= last_vpos
;
17657 it
.current_y
= last_row
->y
;
17661 init_to_row_end (&it
, w
, last_row
);
17662 it
.vpos
= 1 + last_vpos
;
17663 it
.current_y
= MATRIX_ROW_BOTTOM_Y (last_row
);
17667 /* We may start in a continuation line. If so, we have to
17668 get the right continuation_lines_width and current_x. */
17669 it
.continuation_lines_width
= last_row
->continuation_lines_width
;
17670 it
.hpos
= it
.current_x
= 0;
17672 /* Display the rest of the lines at the window end. */
17673 it
.glyph_row
= MATRIX_ROW (desired_matrix
, it
.vpos
);
17674 while (it
.current_y
< it
.last_visible_y
17675 && !fonts_changed_p
)
17677 /* Is it always sure that the display agrees with lines in
17678 the current matrix? I don't think so, so we mark rows
17679 displayed invalid in the current matrix by setting their
17680 enabled_p flag to zero. */
17681 MATRIX_ROW (w
->current_matrix
, it
.vpos
)->enabled_p
= 0;
17682 if (display_line (&it
))
17683 last_text_row_at_end
= it
.glyph_row
- 1;
17687 /* Update window_end_pos and window_end_vpos. */
17688 if (first_unchanged_at_end_row
17689 && !last_text_row_at_end
)
17691 /* Window end line if one of the preserved rows from the current
17692 matrix. Set row to the last row displaying text in current
17693 matrix starting at first_unchanged_at_end_row, after
17695 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row
));
17696 row
= find_last_row_displaying_text (w
->current_matrix
, &it
,
17697 first_unchanged_at_end_row
);
17698 eassert (row
&& MATRIX_ROW_DISPLAYS_TEXT_P (row
));
17700 wset_window_end_pos (w
, make_number (Z
- MATRIX_ROW_END_CHARPOS (row
)));
17701 w
->window_end_bytepos
= Z_BYTE
- MATRIX_ROW_END_BYTEPOS (row
);
17702 wset_window_end_vpos
17703 (w
, make_number (MATRIX_ROW_VPOS (row
, w
->current_matrix
)));
17704 eassert (w
->window_end_bytepos
>= 0);
17705 IF_DEBUG (debug_method_add (w
, "A"));
17707 else if (last_text_row_at_end
)
17709 wset_window_end_pos
17710 (w
, make_number (Z
- MATRIX_ROW_END_CHARPOS (last_text_row_at_end
)));
17711 w
->window_end_bytepos
17712 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_text_row_at_end
);
17713 wset_window_end_vpos
17714 (w
, make_number (MATRIX_ROW_VPOS (last_text_row_at_end
,
17716 eassert (w
->window_end_bytepos
>= 0);
17717 IF_DEBUG (debug_method_add (w
, "B"));
17719 else if (last_text_row
)
17721 /* We have displayed either to the end of the window or at the
17722 end of the window, i.e. the last row with text is to be found
17723 in the desired matrix. */
17724 wset_window_end_pos
17725 (w
, make_number (Z
- MATRIX_ROW_END_CHARPOS (last_text_row
)));
17726 w
->window_end_bytepos
17727 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_text_row
);
17728 wset_window_end_vpos
17729 (w
, make_number (MATRIX_ROW_VPOS (last_text_row
, desired_matrix
)));
17730 eassert (w
->window_end_bytepos
>= 0);
17732 else if (first_unchanged_at_end_row
== NULL
17733 && last_text_row
== NULL
17734 && last_text_row_at_end
== NULL
)
17736 /* Displayed to end of window, but no line containing text was
17737 displayed. Lines were deleted at the end of the window. */
17738 int first_vpos
= WINDOW_WANTS_HEADER_LINE_P (w
) ? 1 : 0;
17739 int vpos
= XFASTINT (w
->window_end_vpos
);
17740 struct glyph_row
*current_row
= current_matrix
->rows
+ vpos
;
17741 struct glyph_row
*desired_row
= desired_matrix
->rows
+ vpos
;
17744 row
== NULL
&& vpos
>= first_vpos
;
17745 --vpos
, --current_row
, --desired_row
)
17747 if (desired_row
->enabled_p
)
17749 if (MATRIX_ROW_DISPLAYS_TEXT_P (desired_row
))
17752 else if (MATRIX_ROW_DISPLAYS_TEXT_P (current_row
))
17756 eassert (row
!= NULL
);
17757 wset_window_end_vpos (w
, make_number (vpos
+ 1));
17758 wset_window_end_pos (w
, make_number (Z
- MATRIX_ROW_END_CHARPOS (row
)));
17759 w
->window_end_bytepos
= Z_BYTE
- MATRIX_ROW_END_BYTEPOS (row
);
17760 eassert (w
->window_end_bytepos
>= 0);
17761 IF_DEBUG (debug_method_add (w
, "C"));
17766 IF_DEBUG (debug_end_pos
= XFASTINT (w
->window_end_pos
);
17767 debug_end_vpos
= XFASTINT (w
->window_end_vpos
));
17769 /* Record that display has not been completed. */
17770 w
->window_end_valid
= 0;
17771 w
->desired_matrix
->no_scrolling_p
= 1;
17779 /***********************************************************************
17780 More debugging support
17781 ***********************************************************************/
17785 void dump_glyph_row (struct glyph_row
*, int, int) EXTERNALLY_VISIBLE
;
17786 void dump_glyph_matrix (struct glyph_matrix
*, int) EXTERNALLY_VISIBLE
;
17787 void dump_glyph (struct glyph_row
*, struct glyph
*, int) EXTERNALLY_VISIBLE
;
17790 /* Dump the contents of glyph matrix MATRIX on stderr.
17792 GLYPHS 0 means don't show glyph contents.
17793 GLYPHS 1 means show glyphs in short form
17794 GLYPHS > 1 means show glyphs in long form. */
17797 dump_glyph_matrix (struct glyph_matrix
*matrix
, int glyphs
)
17800 for (i
= 0; i
< matrix
->nrows
; ++i
)
17801 dump_glyph_row (MATRIX_ROW (matrix
, i
), i
, glyphs
);
17805 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
17806 the glyph row and area where the glyph comes from. */
17809 dump_glyph (struct glyph_row
*row
, struct glyph
*glyph
, int area
)
17811 if (glyph
->type
== CHAR_GLYPH
17812 || glyph
->type
== GLYPHLESS_GLYPH
)
17815 " %5"pD
"d %c %9"pI
"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
17816 glyph
- row
->glyphs
[TEXT_AREA
],
17817 (glyph
->type
== CHAR_GLYPH
17821 (BUFFERP (glyph
->object
)
17823 : (STRINGP (glyph
->object
)
17825 : (INTEGERP (glyph
->object
)
17828 glyph
->pixel_width
,
17830 (glyph
->u
.ch
< 0x80 && glyph
->u
.ch
>= ' '
17834 glyph
->left_box_line_p
,
17835 glyph
->right_box_line_p
);
17837 else if (glyph
->type
== STRETCH_GLYPH
)
17840 " %5"pD
"d %c %9"pI
"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
17841 glyph
- row
->glyphs
[TEXT_AREA
],
17844 (BUFFERP (glyph
->object
)
17846 : (STRINGP (glyph
->object
)
17848 : (INTEGERP (glyph
->object
)
17851 glyph
->pixel_width
,
17855 glyph
->left_box_line_p
,
17856 glyph
->right_box_line_p
);
17858 else if (glyph
->type
== IMAGE_GLYPH
)
17861 " %5"pD
"d %c %9"pI
"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
17862 glyph
- row
->glyphs
[TEXT_AREA
],
17865 (BUFFERP (glyph
->object
)
17867 : (STRINGP (glyph
->object
)
17869 : (INTEGERP (glyph
->object
)
17872 glyph
->pixel_width
,
17876 glyph
->left_box_line_p
,
17877 glyph
->right_box_line_p
);
17879 else if (glyph
->type
== COMPOSITE_GLYPH
)
17882 " %5"pD
"d %c %9"pI
"d %c %3d 0x%06x",
17883 glyph
- row
->glyphs
[TEXT_AREA
],
17886 (BUFFERP (glyph
->object
)
17888 : (STRINGP (glyph
->object
)
17890 : (INTEGERP (glyph
->object
)
17893 glyph
->pixel_width
,
17895 if (glyph
->u
.cmp
.automatic
)
17898 glyph
->slice
.cmp
.from
, glyph
->slice
.cmp
.to
);
17899 fprintf (stderr
, " . %4d %1.1d%1.1d\n",
17901 glyph
->left_box_line_p
,
17902 glyph
->right_box_line_p
);
17907 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
17908 GLYPHS 0 means don't show glyph contents.
17909 GLYPHS 1 means show glyphs in short form
17910 GLYPHS > 1 means show glyphs in long form. */
17913 dump_glyph_row (struct glyph_row
*row
, int vpos
, int glyphs
)
17917 fprintf (stderr
, "Row Start End Used oE><\\CTZFesm X Y W H V A P\n");
17918 fprintf (stderr
, "==============================================================================\n");
17920 fprintf (stderr
, "%3d %9"pI
"d %9"pI
"d %4d %1.1d%1.1d%1.1d%1.1d\
17921 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
17923 MATRIX_ROW_START_CHARPOS (row
),
17924 MATRIX_ROW_END_CHARPOS (row
),
17925 row
->used
[TEXT_AREA
],
17926 row
->contains_overlapping_glyphs_p
,
17928 row
->truncated_on_left_p
,
17929 row
->truncated_on_right_p
,
17931 MATRIX_ROW_CONTINUATION_LINE_P (row
),
17932 MATRIX_ROW_DISPLAYS_TEXT_P (row
),
17935 row
->ends_in_middle_of_char_p
,
17936 row
->starts_in_middle_of_char_p
,
17942 row
->visible_height
,
17945 /* The next 3 lines should align to "Start" in the header. */
17946 fprintf (stderr
, " %9"pD
"d %9"pD
"d\t%5d\n", row
->start
.overlay_string_index
,
17947 row
->end
.overlay_string_index
,
17948 row
->continuation_lines_width
);
17949 fprintf (stderr
, " %9"pI
"d %9"pI
"d\n",
17950 CHARPOS (row
->start
.string_pos
),
17951 CHARPOS (row
->end
.string_pos
));
17952 fprintf (stderr
, " %9d %9d\n", row
->start
.dpvec_index
,
17953 row
->end
.dpvec_index
);
17960 for (area
= LEFT_MARGIN_AREA
; area
< LAST_AREA
; ++area
)
17962 struct glyph
*glyph
= row
->glyphs
[area
];
17963 struct glyph
*glyph_end
= glyph
+ row
->used
[area
];
17965 /* Glyph for a line end in text. */
17966 if (area
== TEXT_AREA
&& glyph
== glyph_end
&& glyph
->charpos
> 0)
17969 if (glyph
< glyph_end
)
17970 fprintf (stderr
, " Glyph# Type Pos O W Code C Face LR\n");
17972 for (; glyph
< glyph_end
; ++glyph
)
17973 dump_glyph (row
, glyph
, area
);
17976 else if (glyphs
== 1)
17980 for (area
= LEFT_MARGIN_AREA
; area
< LAST_AREA
; ++area
)
17982 char *s
= alloca (row
->used
[area
] + 4);
17985 for (i
= 0; i
< row
->used
[area
]; ++i
)
17987 struct glyph
*glyph
= row
->glyphs
[area
] + i
;
17988 if (i
== row
->used
[area
] - 1
17989 && area
== TEXT_AREA
17990 && INTEGERP (glyph
->object
)
17991 && glyph
->type
== CHAR_GLYPH
17992 && glyph
->u
.ch
== ' ')
17994 strcpy (&s
[i
], "[\\n]");
17997 else if (glyph
->type
== CHAR_GLYPH
17998 && glyph
->u
.ch
< 0x80
17999 && glyph
->u
.ch
>= ' ')
18000 s
[i
] = glyph
->u
.ch
;
18006 fprintf (stderr
, "%3d: (%d) '%s'\n", vpos
, row
->enabled_p
, s
);
18012 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix
,
18013 Sdump_glyph_matrix
, 0, 1, "p",
18014 doc
: /* Dump the current matrix of the selected window to stderr.
18015 Shows contents of glyph row structures. With non-nil
18016 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
18017 glyphs in short form, otherwise show glyphs in long form. */)
18018 (Lisp_Object glyphs
)
18020 struct window
*w
= XWINDOW (selected_window
);
18021 struct buffer
*buffer
= XBUFFER (w
->contents
);
18023 fprintf (stderr
, "PT = %"pI
"d, BEGV = %"pI
"d. ZV = %"pI
"d\n",
18024 BUF_PT (buffer
), BUF_BEGV (buffer
), BUF_ZV (buffer
));
18025 fprintf (stderr
, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
18026 w
->cursor
.x
, w
->cursor
.y
, w
->cursor
.hpos
, w
->cursor
.vpos
);
18027 fprintf (stderr
, "=============================================\n");
18028 dump_glyph_matrix (w
->current_matrix
,
18029 TYPE_RANGED_INTEGERP (int, glyphs
) ? XINT (glyphs
) : 0);
18034 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix
,
18035 Sdump_frame_glyph_matrix
, 0, 0, "", doc
: /* */)
18038 struct frame
*f
= XFRAME (selected_frame
);
18039 dump_glyph_matrix (f
->current_matrix
, 1);
18044 DEFUN ("dump-glyph-row", Fdump_glyph_row
, Sdump_glyph_row
, 1, 2, "",
18045 doc
: /* Dump glyph row ROW to stderr.
18046 GLYPH 0 means don't dump glyphs.
18047 GLYPH 1 means dump glyphs in short form.
18048 GLYPH > 1 or omitted means dump glyphs in long form. */)
18049 (Lisp_Object row
, Lisp_Object glyphs
)
18051 struct glyph_matrix
*matrix
;
18054 CHECK_NUMBER (row
);
18055 matrix
= XWINDOW (selected_window
)->current_matrix
;
18057 if (vpos
>= 0 && vpos
< matrix
->nrows
)
18058 dump_glyph_row (MATRIX_ROW (matrix
, vpos
),
18060 TYPE_RANGED_INTEGERP (int, glyphs
) ? XINT (glyphs
) : 2);
18065 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row
, Sdump_tool_bar_row
, 1, 2, "",
18066 doc
: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
18067 GLYPH 0 means don't dump glyphs.
18068 GLYPH 1 means dump glyphs in short form.
18069 GLYPH > 1 or omitted means dump glyphs in long form. */)
18070 (Lisp_Object row
, Lisp_Object glyphs
)
18072 struct frame
*sf
= SELECTED_FRAME ();
18073 struct glyph_matrix
*m
= XWINDOW (sf
->tool_bar_window
)->current_matrix
;
18076 CHECK_NUMBER (row
);
18078 if (vpos
>= 0 && vpos
< m
->nrows
)
18079 dump_glyph_row (MATRIX_ROW (m
, vpos
), vpos
,
18080 TYPE_RANGED_INTEGERP (int, glyphs
) ? XINT (glyphs
) : 2);
18085 DEFUN ("trace-redisplay", Ftrace_redisplay
, Strace_redisplay
, 0, 1, "P",
18086 doc
: /* Toggle tracing of redisplay.
18087 With ARG, turn tracing on if and only if ARG is positive. */)
18091 trace_redisplay_p
= !trace_redisplay_p
;
18094 arg
= Fprefix_numeric_value (arg
);
18095 trace_redisplay_p
= XINT (arg
) > 0;
18102 DEFUN ("trace-to-stderr", Ftrace_to_stderr
, Strace_to_stderr
, 1, MANY
, "",
18103 doc
: /* Like `format', but print result to stderr.
18104 usage: (trace-to-stderr STRING &rest OBJECTS) */)
18105 (ptrdiff_t nargs
, Lisp_Object
*args
)
18107 Lisp_Object s
= Fformat (nargs
, args
);
18108 fprintf (stderr
, "%s", SDATA (s
));
18112 #endif /* GLYPH_DEBUG */
18116 /***********************************************************************
18117 Building Desired Matrix Rows
18118 ***********************************************************************/
18120 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
18121 Used for non-window-redisplay windows, and for windows w/o left fringe. */
18123 static struct glyph_row
*
18124 get_overlay_arrow_glyph_row (struct window
*w
, Lisp_Object overlay_arrow_string
)
18126 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
18127 struct buffer
*buffer
= XBUFFER (w
->contents
);
18128 struct buffer
*old
= current_buffer
;
18129 const unsigned char *arrow_string
= SDATA (overlay_arrow_string
);
18130 int arrow_len
= SCHARS (overlay_arrow_string
);
18131 const unsigned char *arrow_end
= arrow_string
+ arrow_len
;
18132 const unsigned char *p
;
18135 int n_glyphs_before
;
18137 set_buffer_temp (buffer
);
18138 init_iterator (&it
, w
, -1, -1, &scratch_glyph_row
, DEFAULT_FACE_ID
);
18139 it
.glyph_row
->used
[TEXT_AREA
] = 0;
18140 SET_TEXT_POS (it
.position
, 0, 0);
18142 multibyte_p
= !NILP (BVAR (buffer
, enable_multibyte_characters
));
18144 while (p
< arrow_end
)
18146 Lisp_Object face
, ilisp
;
18148 /* Get the next character. */
18150 it
.c
= it
.char_to_display
= string_char_and_length (p
, &it
.len
);
18153 it
.c
= it
.char_to_display
= *p
, it
.len
= 1;
18154 if (! ASCII_CHAR_P (it
.c
))
18155 it
.char_to_display
= BYTE8_TO_CHAR (it
.c
);
18159 /* Get its face. */
18160 ilisp
= make_number (p
- arrow_string
);
18161 face
= Fget_text_property (ilisp
, Qface
, overlay_arrow_string
);
18162 it
.face_id
= compute_char_face (f
, it
.char_to_display
, face
);
18164 /* Compute its width, get its glyphs. */
18165 n_glyphs_before
= it
.glyph_row
->used
[TEXT_AREA
];
18166 SET_TEXT_POS (it
.position
, -1, -1);
18167 PRODUCE_GLYPHS (&it
);
18169 /* If this character doesn't fit any more in the line, we have
18170 to remove some glyphs. */
18171 if (it
.current_x
> it
.last_visible_x
)
18173 it
.glyph_row
->used
[TEXT_AREA
] = n_glyphs_before
;
18178 set_buffer_temp (old
);
18179 return it
.glyph_row
;
18183 /* Insert truncation glyphs at the start of IT->glyph_row. Which
18184 glyphs to insert is determined by produce_special_glyphs. */
18187 insert_left_trunc_glyphs (struct it
*it
)
18189 struct it truncate_it
;
18190 struct glyph
*from
, *end
, *to
, *toend
;
18192 eassert (!FRAME_WINDOW_P (it
->f
)
18193 || (!it
->glyph_row
->reversed_p
18194 && WINDOW_LEFT_FRINGE_WIDTH (it
->w
) == 0)
18195 || (it
->glyph_row
->reversed_p
18196 && WINDOW_RIGHT_FRINGE_WIDTH (it
->w
) == 0));
18198 /* Get the truncation glyphs. */
18200 truncate_it
.current_x
= 0;
18201 truncate_it
.face_id
= DEFAULT_FACE_ID
;
18202 truncate_it
.glyph_row
= &scratch_glyph_row
;
18203 truncate_it
.glyph_row
->used
[TEXT_AREA
] = 0;
18204 CHARPOS (truncate_it
.position
) = BYTEPOS (truncate_it
.position
) = -1;
18205 truncate_it
.object
= make_number (0);
18206 produce_special_glyphs (&truncate_it
, IT_TRUNCATION
);
18208 /* Overwrite glyphs from IT with truncation glyphs. */
18209 if (!it
->glyph_row
->reversed_p
)
18211 short tused
= truncate_it
.glyph_row
->used
[TEXT_AREA
];
18213 from
= truncate_it
.glyph_row
->glyphs
[TEXT_AREA
];
18214 end
= from
+ tused
;
18215 to
= it
->glyph_row
->glyphs
[TEXT_AREA
];
18216 toend
= to
+ it
->glyph_row
->used
[TEXT_AREA
];
18217 if (FRAME_WINDOW_P (it
->f
))
18219 /* On GUI frames, when variable-size fonts are displayed,
18220 the truncation glyphs may need more pixels than the row's
18221 glyphs they overwrite. We overwrite more glyphs to free
18222 enough screen real estate, and enlarge the stretch glyph
18223 on the right (see display_line), if there is one, to
18224 preserve the screen position of the truncation glyphs on
18227 struct glyph
*g
= to
;
18230 /* The first glyph could be partially visible, in which case
18231 it->glyph_row->x will be negative. But we want the left
18232 truncation glyphs to be aligned at the left margin of the
18233 window, so we override the x coordinate at which the row
18235 it
->glyph_row
->x
= 0;
18236 while (g
< toend
&& w
< it
->truncation_pixel_width
)
18238 w
+= g
->pixel_width
;
18241 if (g
- to
- tused
> 0)
18243 memmove (to
+ tused
, g
, (toend
- g
) * sizeof(*g
));
18244 it
->glyph_row
->used
[TEXT_AREA
] -= g
- to
- tused
;
18246 used
= it
->glyph_row
->used
[TEXT_AREA
];
18247 if (it
->glyph_row
->truncated_on_right_p
18248 && WINDOW_RIGHT_FRINGE_WIDTH (it
->w
) == 0
18249 && it
->glyph_row
->glyphs
[TEXT_AREA
][used
- 2].type
18252 int extra
= w
- it
->truncation_pixel_width
;
18254 it
->glyph_row
->glyphs
[TEXT_AREA
][used
- 2].pixel_width
+= extra
;
18261 /* There may be padding glyphs left over. Overwrite them too. */
18262 if (!FRAME_WINDOW_P (it
->f
))
18264 while (to
< toend
&& CHAR_GLYPH_PADDING_P (*to
))
18266 from
= truncate_it
.glyph_row
->glyphs
[TEXT_AREA
];
18273 it
->glyph_row
->used
[TEXT_AREA
] = to
- it
->glyph_row
->glyphs
[TEXT_AREA
];
18277 short tused
= truncate_it
.glyph_row
->used
[TEXT_AREA
];
18279 /* In R2L rows, overwrite the last (rightmost) glyphs, and do
18280 that back to front. */
18281 end
= truncate_it
.glyph_row
->glyphs
[TEXT_AREA
];
18282 from
= end
+ truncate_it
.glyph_row
->used
[TEXT_AREA
] - 1;
18283 toend
= it
->glyph_row
->glyphs
[TEXT_AREA
];
18284 to
= toend
+ it
->glyph_row
->used
[TEXT_AREA
] - 1;
18285 if (FRAME_WINDOW_P (it
->f
))
18288 struct glyph
*g
= to
;
18290 while (g
>= toend
&& w
< it
->truncation_pixel_width
)
18292 w
+= g
->pixel_width
;
18295 if (to
- g
- tused
> 0)
18297 if (it
->glyph_row
->truncated_on_right_p
18298 && WINDOW_LEFT_FRINGE_WIDTH (it
->w
) == 0
18299 && it
->glyph_row
->glyphs
[TEXT_AREA
][1].type
== STRETCH_GLYPH
)
18301 int extra
= w
- it
->truncation_pixel_width
;
18303 it
->glyph_row
->glyphs
[TEXT_AREA
][1].pixel_width
+= extra
;
18307 while (from
>= end
&& to
>= toend
)
18309 if (!FRAME_WINDOW_P (it
->f
))
18311 while (to
>= toend
&& CHAR_GLYPH_PADDING_P (*to
))
18314 truncate_it
.glyph_row
->glyphs
[TEXT_AREA
]
18315 + truncate_it
.glyph_row
->used
[TEXT_AREA
] - 1;
18316 while (from
>= end
&& to
>= toend
)
18322 /* Need to free some room before prepending additional
18324 int move_by
= from
- end
+ 1;
18325 struct glyph
*g0
= it
->glyph_row
->glyphs
[TEXT_AREA
];
18326 struct glyph
*g
= g0
+ it
->glyph_row
->used
[TEXT_AREA
] - 1;
18328 for ( ; g
>= g0
; g
--)
18330 while (from
>= end
)
18332 it
->glyph_row
->used
[TEXT_AREA
] += move_by
;
18337 /* Compute the hash code for ROW. */
18339 row_hash (struct glyph_row
*row
)
18342 unsigned hashval
= 0;
18344 for (area
= LEFT_MARGIN_AREA
; area
< LAST_AREA
; ++area
)
18345 for (k
= 0; k
< row
->used
[area
]; ++k
)
18346 hashval
= ((((hashval
<< 4) + (hashval
>> 24)) & 0x0fffffff)
18347 + row
->glyphs
[area
][k
].u
.val
18348 + row
->glyphs
[area
][k
].face_id
18349 + row
->glyphs
[area
][k
].padding_p
18350 + (row
->glyphs
[area
][k
].type
<< 2));
18355 /* Compute the pixel height and width of IT->glyph_row.
18357 Most of the time, ascent and height of a display line will be equal
18358 to the max_ascent and max_height values of the display iterator
18359 structure. This is not the case if
18361 1. We hit ZV without displaying anything. In this case, max_ascent
18362 and max_height will be zero.
18364 2. We have some glyphs that don't contribute to the line height.
18365 (The glyph row flag contributes_to_line_height_p is for future
18366 pixmap extensions).
18368 The first case is easily covered by using default values because in
18369 these cases, the line height does not really matter, except that it
18370 must not be zero. */
18373 compute_line_metrics (struct it
*it
)
18375 struct glyph_row
*row
= it
->glyph_row
;
18377 if (FRAME_WINDOW_P (it
->f
))
18379 int i
, min_y
, max_y
;
18381 /* The line may consist of one space only, that was added to
18382 place the cursor on it. If so, the row's height hasn't been
18384 if (row
->height
== 0)
18386 if (it
->max_ascent
+ it
->max_descent
== 0)
18387 it
->max_descent
= it
->max_phys_descent
= FRAME_LINE_HEIGHT (it
->f
);
18388 row
->ascent
= it
->max_ascent
;
18389 row
->height
= it
->max_ascent
+ it
->max_descent
;
18390 row
->phys_ascent
= it
->max_phys_ascent
;
18391 row
->phys_height
= it
->max_phys_ascent
+ it
->max_phys_descent
;
18392 row
->extra_line_spacing
= it
->max_extra_line_spacing
;
18395 /* Compute the width of this line. */
18396 row
->pixel_width
= row
->x
;
18397 for (i
= 0; i
< row
->used
[TEXT_AREA
]; ++i
)
18398 row
->pixel_width
+= row
->glyphs
[TEXT_AREA
][i
].pixel_width
;
18400 eassert (row
->pixel_width
>= 0);
18401 eassert (row
->ascent
>= 0 && row
->height
> 0);
18403 row
->overlapping_p
= (MATRIX_ROW_OVERLAPS_SUCC_P (row
)
18404 || MATRIX_ROW_OVERLAPS_PRED_P (row
));
18406 /* If first line's physical ascent is larger than its logical
18407 ascent, use the physical ascent, and make the row taller.
18408 This makes accented characters fully visible. */
18409 if (row
== MATRIX_FIRST_TEXT_ROW (it
->w
->desired_matrix
)
18410 && row
->phys_ascent
> row
->ascent
)
18412 row
->height
+= row
->phys_ascent
- row
->ascent
;
18413 row
->ascent
= row
->phys_ascent
;
18416 /* Compute how much of the line is visible. */
18417 row
->visible_height
= row
->height
;
18419 min_y
= WINDOW_HEADER_LINE_HEIGHT (it
->w
);
18420 max_y
= WINDOW_BOX_HEIGHT_NO_MODE_LINE (it
->w
);
18422 if (row
->y
< min_y
)
18423 row
->visible_height
-= min_y
- row
->y
;
18424 if (row
->y
+ row
->height
> max_y
)
18425 row
->visible_height
-= row
->y
+ row
->height
- max_y
;
18429 row
->pixel_width
= row
->used
[TEXT_AREA
];
18430 if (row
->continued_p
)
18431 row
->pixel_width
-= it
->continuation_pixel_width
;
18432 else if (row
->truncated_on_right_p
)
18433 row
->pixel_width
-= it
->truncation_pixel_width
;
18434 row
->ascent
= row
->phys_ascent
= 0;
18435 row
->height
= row
->phys_height
= row
->visible_height
= 1;
18436 row
->extra_line_spacing
= 0;
18439 /* Compute a hash code for this row. */
18440 row
->hash
= row_hash (row
);
18442 it
->max_ascent
= it
->max_descent
= 0;
18443 it
->max_phys_ascent
= it
->max_phys_descent
= 0;
18447 /* Append one space to the glyph row of iterator IT if doing a
18448 window-based redisplay. The space has the same face as
18449 IT->face_id. Value is non-zero if a space was added.
18451 This function is called to make sure that there is always one glyph
18452 at the end of a glyph row that the cursor can be set on under
18453 window-systems. (If there weren't such a glyph we would not know
18454 how wide and tall a box cursor should be displayed).
18456 At the same time this space let's a nicely handle clearing to the
18457 end of the line if the row ends in italic text. */
18460 append_space_for_newline (struct it
*it
, int default_face_p
)
18462 if (FRAME_WINDOW_P (it
->f
))
18464 int n
= it
->glyph_row
->used
[TEXT_AREA
];
18466 if (it
->glyph_row
->glyphs
[TEXT_AREA
] + n
18467 < it
->glyph_row
->glyphs
[1 + TEXT_AREA
])
18469 /* Save some values that must not be changed.
18470 Must save IT->c and IT->len because otherwise
18471 ITERATOR_AT_END_P wouldn't work anymore after
18472 append_space_for_newline has been called. */
18473 enum display_element_type saved_what
= it
->what
;
18474 int saved_c
= it
->c
, saved_len
= it
->len
;
18475 int saved_char_to_display
= it
->char_to_display
;
18476 int saved_x
= it
->current_x
;
18477 int saved_face_id
= it
->face_id
;
18478 int saved_box_end
= it
->end_of_box_run_p
;
18479 struct text_pos saved_pos
;
18480 Lisp_Object saved_object
;
18483 saved_object
= it
->object
;
18484 saved_pos
= it
->position
;
18486 it
->what
= IT_CHARACTER
;
18487 memset (&it
->position
, 0, sizeof it
->position
);
18488 it
->object
= make_number (0);
18489 it
->c
= it
->char_to_display
= ' ';
18492 /* If the default face was remapped, be sure to use the
18493 remapped face for the appended newline. */
18494 if (default_face_p
)
18495 it
->face_id
= lookup_basic_face (it
->f
, DEFAULT_FACE_ID
);
18496 else if (it
->face_before_selective_p
)
18497 it
->face_id
= it
->saved_face_id
;
18498 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
18499 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, 0, -1, Qnil
);
18500 /* In R2L rows, we will prepend a stretch glyph that will
18501 have the end_of_box_run_p flag set for it, so there's no
18502 need for the appended newline glyph to have that flag
18504 if (it
->glyph_row
->reversed_p
18505 /* But if the appended newline glyph goes all the way to
18506 the end of the row, there will be no stretch glyph,
18507 so leave the box flag set. */
18508 && saved_x
+ FRAME_COLUMN_WIDTH (it
->f
) < it
->last_visible_x
)
18509 it
->end_of_box_run_p
= 0;
18511 PRODUCE_GLYPHS (it
);
18513 it
->override_ascent
= -1;
18514 it
->constrain_row_ascent_descent_p
= 0;
18515 it
->current_x
= saved_x
;
18516 it
->object
= saved_object
;
18517 it
->position
= saved_pos
;
18518 it
->what
= saved_what
;
18519 it
->face_id
= saved_face_id
;
18520 it
->len
= saved_len
;
18522 it
->char_to_display
= saved_char_to_display
;
18523 it
->end_of_box_run_p
= saved_box_end
;
18532 /* Extend the face of the last glyph in the text area of IT->glyph_row
18533 to the end of the display line. Called from display_line. If the
18534 glyph row is empty, add a space glyph to it so that we know the
18535 face to draw. Set the glyph row flag fill_line_p. If the glyph
18536 row is R2L, prepend a stretch glyph to cover the empty space to the
18537 left of the leftmost glyph. */
18540 extend_face_to_end_of_line (struct it
*it
)
18542 struct face
*face
, *default_face
;
18543 struct frame
*f
= it
->f
;
18545 /* If line is already filled, do nothing. Non window-system frames
18546 get a grace of one more ``pixel'' because their characters are
18547 1-``pixel'' wide, so they hit the equality too early. This grace
18548 is needed only for R2L rows that are not continued, to produce
18549 one extra blank where we could display the cursor. */
18550 if (it
->current_x
>= it
->last_visible_x
18551 + (!FRAME_WINDOW_P (f
)
18552 && it
->glyph_row
->reversed_p
18553 && !it
->glyph_row
->continued_p
))
18556 /* The default face, possibly remapped. */
18557 default_face
= FACE_FROM_ID (f
, lookup_basic_face (f
, DEFAULT_FACE_ID
));
18559 /* Face extension extends the background and box of IT->face_id
18560 to the end of the line. If the background equals the background
18561 of the frame, we don't have to do anything. */
18562 if (it
->face_before_selective_p
)
18563 face
= FACE_FROM_ID (f
, it
->saved_face_id
);
18565 face
= FACE_FROM_ID (f
, it
->face_id
);
18567 if (FRAME_WINDOW_P (f
)
18568 && MATRIX_ROW_DISPLAYS_TEXT_P (it
->glyph_row
)
18569 && face
->box
== FACE_NO_BOX
18570 && face
->background
== FRAME_BACKGROUND_PIXEL (f
)
18572 && !it
->glyph_row
->reversed_p
)
18575 /* Set the glyph row flag indicating that the face of the last glyph
18576 in the text area has to be drawn to the end of the text area. */
18577 it
->glyph_row
->fill_line_p
= 1;
18579 /* If current character of IT is not ASCII, make sure we have the
18580 ASCII face. This will be automatically undone the next time
18581 get_next_display_element returns a multibyte character. Note
18582 that the character will always be single byte in unibyte
18584 if (!ASCII_CHAR_P (it
->c
))
18586 it
->face_id
= FACE_FOR_CHAR (f
, face
, 0, -1, Qnil
);
18589 if (FRAME_WINDOW_P (f
))
18591 /* If the row is empty, add a space with the current face of IT,
18592 so that we know which face to draw. */
18593 if (it
->glyph_row
->used
[TEXT_AREA
] == 0)
18595 it
->glyph_row
->glyphs
[TEXT_AREA
][0] = space_glyph
;
18596 it
->glyph_row
->glyphs
[TEXT_AREA
][0].face_id
= face
->id
;
18597 it
->glyph_row
->used
[TEXT_AREA
] = 1;
18599 #ifdef HAVE_WINDOW_SYSTEM
18600 if (it
->glyph_row
->reversed_p
)
18602 /* Prepend a stretch glyph to the row, such that the
18603 rightmost glyph will be drawn flushed all the way to the
18604 right margin of the window. The stretch glyph that will
18605 occupy the empty space, if any, to the left of the
18607 struct font
*font
= face
->font
? face
->font
: FRAME_FONT (f
);
18608 struct glyph
*row_start
= it
->glyph_row
->glyphs
[TEXT_AREA
];
18609 struct glyph
*row_end
= row_start
+ it
->glyph_row
->used
[TEXT_AREA
];
18611 int row_width
, stretch_ascent
, stretch_width
;
18612 struct text_pos saved_pos
;
18613 int saved_face_id
, saved_avoid_cursor
, saved_box_start
;
18615 for (row_width
= 0, g
= row_start
; g
< row_end
; g
++)
18616 row_width
+= g
->pixel_width
;
18617 stretch_width
= window_box_width (it
->w
, TEXT_AREA
) - row_width
;
18618 if (stretch_width
> 0)
18621 (((it
->ascent
+ it
->descent
)
18622 * FONT_BASE (font
)) / FONT_HEIGHT (font
));
18623 saved_pos
= it
->position
;
18624 memset (&it
->position
, 0, sizeof it
->position
);
18625 saved_avoid_cursor
= it
->avoid_cursor_p
;
18626 it
->avoid_cursor_p
= 1;
18627 saved_face_id
= it
->face_id
;
18628 saved_box_start
= it
->start_of_box_run_p
;
18629 /* The last row's stretch glyph should get the default
18630 face, to avoid painting the rest of the window with
18631 the region face, if the region ends at ZV. */
18632 if (it
->glyph_row
->ends_at_zv_p
)
18633 it
->face_id
= default_face
->id
;
18635 it
->face_id
= face
->id
;
18636 it
->start_of_box_run_p
= 0;
18637 append_stretch_glyph (it
, make_number (0), stretch_width
,
18638 it
->ascent
+ it
->descent
, stretch_ascent
);
18639 it
->position
= saved_pos
;
18640 it
->avoid_cursor_p
= saved_avoid_cursor
;
18641 it
->face_id
= saved_face_id
;
18642 it
->start_of_box_run_p
= saved_box_start
;
18645 #endif /* HAVE_WINDOW_SYSTEM */
18649 /* Save some values that must not be changed. */
18650 int saved_x
= it
->current_x
;
18651 struct text_pos saved_pos
;
18652 Lisp_Object saved_object
;
18653 enum display_element_type saved_what
= it
->what
;
18654 int saved_face_id
= it
->face_id
;
18656 saved_object
= it
->object
;
18657 saved_pos
= it
->position
;
18659 it
->what
= IT_CHARACTER
;
18660 memset (&it
->position
, 0, sizeof it
->position
);
18661 it
->object
= make_number (0);
18662 it
->c
= it
->char_to_display
= ' ';
18664 /* The last row's blank glyphs should get the default face, to
18665 avoid painting the rest of the window with the region face,
18666 if the region ends at ZV. */
18667 if (it
->glyph_row
->ends_at_zv_p
)
18668 it
->face_id
= default_face
->id
;
18670 it
->face_id
= face
->id
;
18672 PRODUCE_GLYPHS (it
);
18674 while (it
->current_x
<= it
->last_visible_x
)
18675 PRODUCE_GLYPHS (it
);
18677 /* Don't count these blanks really. It would let us insert a left
18678 truncation glyph below and make us set the cursor on them, maybe. */
18679 it
->current_x
= saved_x
;
18680 it
->object
= saved_object
;
18681 it
->position
= saved_pos
;
18682 it
->what
= saved_what
;
18683 it
->face_id
= saved_face_id
;
18688 /* Value is non-zero if text starting at CHARPOS in current_buffer is
18689 trailing whitespace. */
18692 trailing_whitespace_p (ptrdiff_t charpos
)
18694 ptrdiff_t bytepos
= CHAR_TO_BYTE (charpos
);
18697 while (bytepos
< ZV_BYTE
18698 && (c
= FETCH_CHAR (bytepos
),
18699 c
== ' ' || c
== '\t'))
18702 if (bytepos
>= ZV_BYTE
|| c
== '\n' || c
== '\r')
18704 if (bytepos
!= PT_BYTE
)
18711 /* Highlight trailing whitespace, if any, in ROW. */
18714 highlight_trailing_whitespace (struct frame
*f
, struct glyph_row
*row
)
18716 int used
= row
->used
[TEXT_AREA
];
18720 struct glyph
*start
= row
->glyphs
[TEXT_AREA
];
18721 struct glyph
*glyph
= start
+ used
- 1;
18723 if (row
->reversed_p
)
18725 /* Right-to-left rows need to be processed in the opposite
18726 direction, so swap the edge pointers. */
18728 start
= row
->glyphs
[TEXT_AREA
] + used
- 1;
18731 /* Skip over glyphs inserted to display the cursor at the
18732 end of a line, for extending the face of the last glyph
18733 to the end of the line on terminals, and for truncation
18734 and continuation glyphs. */
18735 if (!row
->reversed_p
)
18737 while (glyph
>= start
18738 && glyph
->type
== CHAR_GLYPH
18739 && INTEGERP (glyph
->object
))
18744 while (glyph
<= start
18745 && glyph
->type
== CHAR_GLYPH
18746 && INTEGERP (glyph
->object
))
18750 /* If last glyph is a space or stretch, and it's trailing
18751 whitespace, set the face of all trailing whitespace glyphs in
18752 IT->glyph_row to `trailing-whitespace'. */
18753 if ((row
->reversed_p
? glyph
<= start
: glyph
>= start
)
18754 && BUFFERP (glyph
->object
)
18755 && (glyph
->type
== STRETCH_GLYPH
18756 || (glyph
->type
== CHAR_GLYPH
18757 && glyph
->u
.ch
== ' '))
18758 && trailing_whitespace_p (glyph
->charpos
))
18760 int face_id
= lookup_named_face (f
, Qtrailing_whitespace
, 0);
18764 if (!row
->reversed_p
)
18766 while (glyph
>= start
18767 && BUFFERP (glyph
->object
)
18768 && (glyph
->type
== STRETCH_GLYPH
18769 || (glyph
->type
== CHAR_GLYPH
18770 && glyph
->u
.ch
== ' ')))
18771 (glyph
--)->face_id
= face_id
;
18775 while (glyph
<= start
18776 && BUFFERP (glyph
->object
)
18777 && (glyph
->type
== STRETCH_GLYPH
18778 || (glyph
->type
== CHAR_GLYPH
18779 && glyph
->u
.ch
== ' ')))
18780 (glyph
++)->face_id
= face_id
;
18787 /* Value is non-zero if glyph row ROW should be
18788 considered to hold the buffer position CHARPOS. */
18791 row_for_charpos_p (struct glyph_row
*row
, ptrdiff_t charpos
)
18795 if (charpos
== CHARPOS (row
->end
.pos
)
18796 || charpos
== MATRIX_ROW_END_CHARPOS (row
))
18798 /* Suppose the row ends on a string.
18799 Unless the row is continued, that means it ends on a newline
18800 in the string. If it's anything other than a display string
18801 (e.g., a before-string from an overlay), we don't want the
18802 cursor there. (This heuristic seems to give the optimal
18803 behavior for the various types of multi-line strings.)
18804 One exception: if the string has `cursor' property on one of
18805 its characters, we _do_ want the cursor there. */
18806 if (CHARPOS (row
->end
.string_pos
) >= 0)
18808 if (row
->continued_p
)
18812 /* Check for `display' property. */
18813 struct glyph
*beg
= row
->glyphs
[TEXT_AREA
];
18814 struct glyph
*end
= beg
+ row
->used
[TEXT_AREA
] - 1;
18815 struct glyph
*glyph
;
18818 for (glyph
= end
; glyph
>= beg
; --glyph
)
18819 if (STRINGP (glyph
->object
))
18822 = Fget_char_property (make_number (charpos
),
18826 && display_prop_string_p (prop
, glyph
->object
));
18827 /* If there's a `cursor' property on one of the
18828 string's characters, this row is a cursor row,
18829 even though this is not a display string. */
18832 Lisp_Object s
= glyph
->object
;
18834 for ( ; glyph
>= beg
&& EQ (glyph
->object
, s
); --glyph
)
18836 ptrdiff_t gpos
= glyph
->charpos
;
18838 if (!NILP (Fget_char_property (make_number (gpos
),
18850 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row
))
18852 /* If the row ends in middle of a real character,
18853 and the line is continued, we want the cursor here.
18854 That's because CHARPOS (ROW->end.pos) would equal
18855 PT if PT is before the character. */
18856 if (!row
->ends_in_ellipsis_p
)
18857 result
= row
->continued_p
;
18859 /* If the row ends in an ellipsis, then
18860 CHARPOS (ROW->end.pos) will equal point after the
18861 invisible text. We want that position to be displayed
18862 after the ellipsis. */
18865 /* If the row ends at ZV, display the cursor at the end of that
18866 row instead of at the start of the row below. */
18867 else if (row
->ends_at_zv_p
)
18876 /* Value is non-zero if glyph row ROW should be
18877 used to hold the cursor. */
18880 cursor_row_p (struct glyph_row
*row
)
18882 return row_for_charpos_p (row
, PT
);
18887 /* Push the property PROP so that it will be rendered at the current
18888 position in IT. Return 1 if PROP was successfully pushed, 0
18889 otherwise. Called from handle_line_prefix to handle the
18890 `line-prefix' and `wrap-prefix' properties. */
18893 push_prefix_prop (struct it
*it
, Lisp_Object prop
)
18895 struct text_pos pos
=
18896 STRINGP (it
->string
) ? it
->current
.string_pos
: it
->current
.pos
;
18898 eassert (it
->method
== GET_FROM_BUFFER
18899 || it
->method
== GET_FROM_DISPLAY_VECTOR
18900 || it
->method
== GET_FROM_STRING
);
18902 /* We need to save the current buffer/string position, so it will be
18903 restored by pop_it, because iterate_out_of_display_property
18904 depends on that being set correctly, but some situations leave
18905 it->position not yet set when this function is called. */
18906 push_it (it
, &pos
);
18908 if (STRINGP (prop
))
18910 if (SCHARS (prop
) == 0)
18917 it
->string_from_prefix_prop_p
= 1;
18918 it
->multibyte_p
= STRING_MULTIBYTE (it
->string
);
18919 it
->current
.overlay_string_index
= -1;
18920 IT_STRING_CHARPOS (*it
) = IT_STRING_BYTEPOS (*it
) = 0;
18921 it
->end_charpos
= it
->string_nchars
= SCHARS (it
->string
);
18922 it
->method
= GET_FROM_STRING
;
18923 it
->stop_charpos
= 0;
18925 it
->base_level_stop
= 0;
18927 /* Force paragraph direction to be that of the parent
18929 if (it
->bidi_p
&& it
->bidi_it
.paragraph_dir
== R2L
)
18930 it
->paragraph_embedding
= it
->bidi_it
.paragraph_dir
;
18932 it
->paragraph_embedding
= L2R
;
18934 /* Set up the bidi iterator for this display string. */
18937 it
->bidi_it
.string
.lstring
= it
->string
;
18938 it
->bidi_it
.string
.s
= NULL
;
18939 it
->bidi_it
.string
.schars
= it
->end_charpos
;
18940 it
->bidi_it
.string
.bufpos
= IT_CHARPOS (*it
);
18941 it
->bidi_it
.string
.from_disp_str
= it
->string_from_display_prop_p
;
18942 it
->bidi_it
.string
.unibyte
= !it
->multibyte_p
;
18943 it
->bidi_it
.w
= it
->w
;
18944 bidi_init_it (0, 0, FRAME_WINDOW_P (it
->f
), &it
->bidi_it
);
18947 else if (CONSP (prop
) && EQ (XCAR (prop
), Qspace
))
18949 it
->method
= GET_FROM_STRETCH
;
18952 #ifdef HAVE_WINDOW_SYSTEM
18953 else if (IMAGEP (prop
))
18955 it
->what
= IT_IMAGE
;
18956 it
->image_id
= lookup_image (it
->f
, prop
);
18957 it
->method
= GET_FROM_IMAGE
;
18959 #endif /* HAVE_WINDOW_SYSTEM */
18962 pop_it (it
); /* bogus display property, give up */
18969 /* Return the character-property PROP at the current position in IT. */
18972 get_it_property (struct it
*it
, Lisp_Object prop
)
18974 Lisp_Object position
;
18976 if (STRINGP (it
->object
))
18977 position
= make_number (IT_STRING_CHARPOS (*it
));
18978 else if (BUFFERP (it
->object
))
18979 position
= make_number (IT_CHARPOS (*it
));
18983 return Fget_char_property (position
, prop
, it
->object
);
18986 /* See if there's a line- or wrap-prefix, and if so, push it on IT. */
18989 handle_line_prefix (struct it
*it
)
18991 Lisp_Object prefix
;
18993 if (it
->continuation_lines_width
> 0)
18995 prefix
= get_it_property (it
, Qwrap_prefix
);
18997 prefix
= Vwrap_prefix
;
19001 prefix
= get_it_property (it
, Qline_prefix
);
19003 prefix
= Vline_prefix
;
19005 if (! NILP (prefix
) && push_prefix_prop (it
, prefix
))
19007 /* If the prefix is wider than the window, and we try to wrap
19008 it, it would acquire its own wrap prefix, and so on till the
19009 iterator stack overflows. So, don't wrap the prefix. */
19010 it
->line_wrap
= TRUNCATE
;
19011 it
->avoid_cursor_p
= 1;
19017 /* Remove N glyphs at the start of a reversed IT->glyph_row. Called
19018 only for R2L lines from display_line and display_string, when they
19019 decide that too many glyphs were produced by PRODUCE_GLYPHS, and
19020 the line/string needs to be continued on the next glyph row. */
19022 unproduce_glyphs (struct it
*it
, int n
)
19024 struct glyph
*glyph
, *end
;
19026 eassert (it
->glyph_row
);
19027 eassert (it
->glyph_row
->reversed_p
);
19028 eassert (it
->area
== TEXT_AREA
);
19029 eassert (n
<= it
->glyph_row
->used
[TEXT_AREA
]);
19031 if (n
> it
->glyph_row
->used
[TEXT_AREA
])
19032 n
= it
->glyph_row
->used
[TEXT_AREA
];
19033 glyph
= it
->glyph_row
->glyphs
[TEXT_AREA
] + n
;
19034 end
= it
->glyph_row
->glyphs
[TEXT_AREA
] + it
->glyph_row
->used
[TEXT_AREA
];
19035 for ( ; glyph
< end
; glyph
++)
19036 glyph
[-n
] = *glyph
;
19039 /* Find the positions in a bidi-reordered ROW to serve as ROW->minpos
19040 and ROW->maxpos. */
19042 find_row_edges (struct it
*it
, struct glyph_row
*row
,
19043 ptrdiff_t min_pos
, ptrdiff_t min_bpos
,
19044 ptrdiff_t max_pos
, ptrdiff_t max_bpos
)
19046 /* FIXME: Revisit this when glyph ``spilling'' in continuation
19047 lines' rows is implemented for bidi-reordered rows. */
19049 /* ROW->minpos is the value of min_pos, the minimal buffer position
19050 we have in ROW, or ROW->start.pos if that is smaller. */
19051 if (min_pos
<= ZV
&& min_pos
< row
->start
.pos
.charpos
)
19052 SET_TEXT_POS (row
->minpos
, min_pos
, min_bpos
);
19054 /* We didn't find buffer positions smaller than ROW->start, or
19055 didn't find _any_ valid buffer positions in any of the glyphs,
19056 so we must trust the iterator's computed positions. */
19057 row
->minpos
= row
->start
.pos
;
19060 max_pos
= CHARPOS (it
->current
.pos
);
19061 max_bpos
= BYTEPOS (it
->current
.pos
);
19064 /* Here are the various use-cases for ending the row, and the
19065 corresponding values for ROW->maxpos:
19067 Line ends in a newline from buffer eol_pos + 1
19068 Line is continued from buffer max_pos + 1
19069 Line is truncated on right it->current.pos
19070 Line ends in a newline from string max_pos + 1(*)
19071 (*) + 1 only when line ends in a forward scan
19072 Line is continued from string max_pos
19073 Line is continued from display vector max_pos
19074 Line is entirely from a string min_pos == max_pos
19075 Line is entirely from a display vector min_pos == max_pos
19076 Line that ends at ZV ZV
19078 If you discover other use-cases, please add them here as
19080 if (row
->ends_at_zv_p
)
19081 row
->maxpos
= it
->current
.pos
;
19082 else if (row
->used
[TEXT_AREA
])
19084 int seen_this_string
= 0;
19085 struct glyph_row
*r1
= row
- 1;
19087 /* Did we see the same display string on the previous row? */
19088 if (STRINGP (it
->object
)
19089 /* this is not the first row */
19090 && row
> it
->w
->desired_matrix
->rows
19091 /* previous row is not the header line */
19092 && !r1
->mode_line_p
19093 /* previous row also ends in a newline from a string */
19094 && r1
->ends_in_newline_from_string_p
)
19096 struct glyph
*start
, *end
;
19098 /* Search for the last glyph of the previous row that came
19099 from buffer or string. Depending on whether the row is
19100 L2R or R2L, we need to process it front to back or the
19101 other way round. */
19102 if (!r1
->reversed_p
)
19104 start
= r1
->glyphs
[TEXT_AREA
];
19105 end
= start
+ r1
->used
[TEXT_AREA
];
19106 /* Glyphs inserted by redisplay have an integer (zero)
19107 as their object. */
19109 && INTEGERP ((end
- 1)->object
)
19110 && (end
- 1)->charpos
<= 0)
19114 if (EQ ((end
- 1)->object
, it
->object
))
19115 seen_this_string
= 1;
19118 /* If all the glyphs of the previous row were inserted
19119 by redisplay, it means the previous row was
19120 produced from a single newline, which is only
19121 possible if that newline came from the same string
19122 as the one which produced this ROW. */
19123 seen_this_string
= 1;
19127 end
= r1
->glyphs
[TEXT_AREA
] - 1;
19128 start
= end
+ r1
->used
[TEXT_AREA
];
19130 && INTEGERP ((end
+ 1)->object
)
19131 && (end
+ 1)->charpos
<= 0)
19135 if (EQ ((end
+ 1)->object
, it
->object
))
19136 seen_this_string
= 1;
19139 seen_this_string
= 1;
19142 /* Take note of each display string that covers a newline only
19143 once, the first time we see it. This is for when a display
19144 string includes more than one newline in it. */
19145 if (row
->ends_in_newline_from_string_p
&& !seen_this_string
)
19147 /* If we were scanning the buffer forward when we displayed
19148 the string, we want to account for at least one buffer
19149 position that belongs to this row (position covered by
19150 the display string), so that cursor positioning will
19151 consider this row as a candidate when point is at the end
19152 of the visual line represented by this row. This is not
19153 required when scanning back, because max_pos will already
19154 have a much larger value. */
19155 if (CHARPOS (row
->end
.pos
) > max_pos
)
19156 INC_BOTH (max_pos
, max_bpos
);
19157 SET_TEXT_POS (row
->maxpos
, max_pos
, max_bpos
);
19159 else if (CHARPOS (it
->eol_pos
) > 0)
19160 SET_TEXT_POS (row
->maxpos
,
19161 CHARPOS (it
->eol_pos
) + 1, BYTEPOS (it
->eol_pos
) + 1);
19162 else if (row
->continued_p
)
19164 /* If max_pos is different from IT's current position, it
19165 means IT->method does not belong to the display element
19166 at max_pos. However, it also means that the display
19167 element at max_pos was displayed in its entirety on this
19168 line, which is equivalent to saying that the next line
19169 starts at the next buffer position. */
19170 if (IT_CHARPOS (*it
) == max_pos
&& it
->method
!= GET_FROM_BUFFER
)
19171 SET_TEXT_POS (row
->maxpos
, max_pos
, max_bpos
);
19174 INC_BOTH (max_pos
, max_bpos
);
19175 SET_TEXT_POS (row
->maxpos
, max_pos
, max_bpos
);
19178 else if (row
->truncated_on_right_p
)
19179 /* display_line already called reseat_at_next_visible_line_start,
19180 which puts the iterator at the beginning of the next line, in
19181 the logical order. */
19182 row
->maxpos
= it
->current
.pos
;
19183 else if (max_pos
== min_pos
&& it
->method
!= GET_FROM_BUFFER
)
19184 /* A line that is entirely from a string/image/stretch... */
19185 row
->maxpos
= row
->minpos
;
19190 row
->maxpos
= it
->current
.pos
;
19193 /* Construct the glyph row IT->glyph_row in the desired matrix of
19194 IT->w from text at the current position of IT. See dispextern.h
19195 for an overview of struct it. Value is non-zero if
19196 IT->glyph_row displays text, as opposed to a line displaying ZV
19200 display_line (struct it
*it
)
19202 struct glyph_row
*row
= it
->glyph_row
;
19203 Lisp_Object overlay_arrow_string
;
19205 void *wrap_data
= NULL
;
19206 int may_wrap
= 0, wrap_x
IF_LINT (= 0);
19207 int wrap_row_used
= -1;
19208 int wrap_row_ascent
IF_LINT (= 0), wrap_row_height
IF_LINT (= 0);
19209 int wrap_row_phys_ascent
IF_LINT (= 0), wrap_row_phys_height
IF_LINT (= 0);
19210 int wrap_row_extra_line_spacing
IF_LINT (= 0);
19211 ptrdiff_t wrap_row_min_pos
IF_LINT (= 0), wrap_row_min_bpos
IF_LINT (= 0);
19212 ptrdiff_t wrap_row_max_pos
IF_LINT (= 0), wrap_row_max_bpos
IF_LINT (= 0);
19214 ptrdiff_t min_pos
= ZV
+ 1, max_pos
= 0;
19215 ptrdiff_t min_bpos
IF_LINT (= 0), max_bpos
IF_LINT (= 0);
19217 /* We always start displaying at hpos zero even if hscrolled. */
19218 eassert (it
->hpos
== 0 && it
->current_x
== 0);
19220 if (MATRIX_ROW_VPOS (row
, it
->w
->desired_matrix
)
19221 >= it
->w
->desired_matrix
->nrows
)
19223 it
->w
->nrows_scale_factor
++;
19224 fonts_changed_p
= 1;
19228 /* Is IT->w showing the region? */
19229 it
->w
->region_showing
= it
->region_beg_charpos
> 0 ? it
->region_beg_charpos
: 0;
19231 /* Clear the result glyph row and enable it. */
19232 prepare_desired_row (row
);
19234 row
->y
= it
->current_y
;
19235 row
->start
= it
->start
;
19236 row
->continuation_lines_width
= it
->continuation_lines_width
;
19237 row
->displays_text_p
= 1;
19238 row
->starts_in_middle_of_char_p
= it
->starts_in_middle_of_char_p
;
19239 it
->starts_in_middle_of_char_p
= 0;
19241 /* Arrange the overlays nicely for our purposes. Usually, we call
19242 display_line on only one line at a time, in which case this
19243 can't really hurt too much, or we call it on lines which appear
19244 one after another in the buffer, in which case all calls to
19245 recenter_overlay_lists but the first will be pretty cheap. */
19246 recenter_overlay_lists (current_buffer
, IT_CHARPOS (*it
));
19248 /* Move over display elements that are not visible because we are
19249 hscrolled. This may stop at an x-position < IT->first_visible_x
19250 if the first glyph is partially visible or if we hit a line end. */
19251 if (it
->current_x
< it
->first_visible_x
)
19253 enum move_it_result move_result
;
19255 this_line_min_pos
= row
->start
.pos
;
19256 move_result
= move_it_in_display_line_to (it
, ZV
, it
->first_visible_x
,
19257 MOVE_TO_POS
| MOVE_TO_X
);
19258 /* If we are under a large hscroll, move_it_in_display_line_to
19259 could hit the end of the line without reaching
19260 it->first_visible_x. Pretend that we did reach it. This is
19261 especially important on a TTY, where we will call
19262 extend_face_to_end_of_line, which needs to know how many
19263 blank glyphs to produce. */
19264 if (it
->current_x
< it
->first_visible_x
19265 && (move_result
== MOVE_NEWLINE_OR_CR
19266 || move_result
== MOVE_POS_MATCH_OR_ZV
))
19267 it
->current_x
= it
->first_visible_x
;
19269 /* Record the smallest positions seen while we moved over
19270 display elements that are not visible. This is needed by
19271 redisplay_internal for optimizing the case where the cursor
19272 stays inside the same line. The rest of this function only
19273 considers positions that are actually displayed, so
19274 RECORD_MAX_MIN_POS will not otherwise record positions that
19275 are hscrolled to the left of the left edge of the window. */
19276 min_pos
= CHARPOS (this_line_min_pos
);
19277 min_bpos
= BYTEPOS (this_line_min_pos
);
19281 /* We only do this when not calling `move_it_in_display_line_to'
19282 above, because move_it_in_display_line_to calls
19283 handle_line_prefix itself. */
19284 handle_line_prefix (it
);
19287 /* Get the initial row height. This is either the height of the
19288 text hscrolled, if there is any, or zero. */
19289 row
->ascent
= it
->max_ascent
;
19290 row
->height
= it
->max_ascent
+ it
->max_descent
;
19291 row
->phys_ascent
= it
->max_phys_ascent
;
19292 row
->phys_height
= it
->max_phys_ascent
+ it
->max_phys_descent
;
19293 row
->extra_line_spacing
= it
->max_extra_line_spacing
;
19295 /* Utility macro to record max and min buffer positions seen until now. */
19296 #define RECORD_MAX_MIN_POS(IT) \
19299 int composition_p = !STRINGP ((IT)->string) \
19300 && ((IT)->what == IT_COMPOSITION); \
19301 ptrdiff_t current_pos = \
19302 composition_p ? (IT)->cmp_it.charpos \
19303 : IT_CHARPOS (*(IT)); \
19304 ptrdiff_t current_bpos = \
19305 composition_p ? CHAR_TO_BYTE (current_pos) \
19306 : IT_BYTEPOS (*(IT)); \
19307 if (current_pos < min_pos) \
19309 min_pos = current_pos; \
19310 min_bpos = current_bpos; \
19312 if (IT_CHARPOS (*it) > max_pos) \
19314 max_pos = IT_CHARPOS (*it); \
19315 max_bpos = IT_BYTEPOS (*it); \
19320 /* Loop generating characters. The loop is left with IT on the next
19321 character to display. */
19324 int n_glyphs_before
, hpos_before
, x_before
;
19326 int ascent
= 0, descent
= 0, phys_ascent
= 0, phys_descent
= 0;
19328 /* Retrieve the next thing to display. Value is zero if end of
19330 if (!get_next_display_element (it
))
19332 /* Maybe add a space at the end of this line that is used to
19333 display the cursor there under X. Set the charpos of the
19334 first glyph of blank lines not corresponding to any text
19336 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
19337 row
->exact_window_width_line_p
= 1;
19338 else if ((append_space_for_newline (it
, 1) && row
->used
[TEXT_AREA
] == 1)
19339 || row
->used
[TEXT_AREA
] == 0)
19341 row
->glyphs
[TEXT_AREA
]->charpos
= -1;
19342 row
->displays_text_p
= 0;
19344 if (!NILP (BVAR (XBUFFER (it
->w
->contents
), indicate_empty_lines
))
19345 && (!MINI_WINDOW_P (it
->w
)
19346 || (minibuf_level
&& EQ (it
->window
, minibuf_window
))))
19347 row
->indicate_empty_line_p
= 1;
19350 it
->continuation_lines_width
= 0;
19351 row
->ends_at_zv_p
= 1;
19352 /* A row that displays right-to-left text must always have
19353 its last face extended all the way to the end of line,
19354 even if this row ends in ZV, because we still write to
19355 the screen left to right. We also need to extend the
19356 last face if the default face is remapped to some
19357 different face, otherwise the functions that clear
19358 portions of the screen will clear with the default face's
19359 background color. */
19360 if (row
->reversed_p
19361 || lookup_basic_face (it
->f
, DEFAULT_FACE_ID
) != DEFAULT_FACE_ID
)
19362 extend_face_to_end_of_line (it
);
19366 /* Now, get the metrics of what we want to display. This also
19367 generates glyphs in `row' (which is IT->glyph_row). */
19368 n_glyphs_before
= row
->used
[TEXT_AREA
];
19371 /* Remember the line height so far in case the next element doesn't
19372 fit on the line. */
19373 if (it
->line_wrap
!= TRUNCATE
)
19375 ascent
= it
->max_ascent
;
19376 descent
= it
->max_descent
;
19377 phys_ascent
= it
->max_phys_ascent
;
19378 phys_descent
= it
->max_phys_descent
;
19380 if (it
->line_wrap
== WORD_WRAP
&& it
->area
== TEXT_AREA
)
19382 if (IT_DISPLAYING_WHITESPACE (it
))
19386 SAVE_IT (wrap_it
, *it
, wrap_data
);
19388 wrap_row_used
= row
->used
[TEXT_AREA
];
19389 wrap_row_ascent
= row
->ascent
;
19390 wrap_row_height
= row
->height
;
19391 wrap_row_phys_ascent
= row
->phys_ascent
;
19392 wrap_row_phys_height
= row
->phys_height
;
19393 wrap_row_extra_line_spacing
= row
->extra_line_spacing
;
19394 wrap_row_min_pos
= min_pos
;
19395 wrap_row_min_bpos
= min_bpos
;
19396 wrap_row_max_pos
= max_pos
;
19397 wrap_row_max_bpos
= max_bpos
;
19403 PRODUCE_GLYPHS (it
);
19405 /* If this display element was in marginal areas, continue with
19407 if (it
->area
!= TEXT_AREA
)
19409 row
->ascent
= max (row
->ascent
, it
->max_ascent
);
19410 row
->height
= max (row
->height
, it
->max_ascent
+ it
->max_descent
);
19411 row
->phys_ascent
= max (row
->phys_ascent
, it
->max_phys_ascent
);
19412 row
->phys_height
= max (row
->phys_height
,
19413 it
->max_phys_ascent
+ it
->max_phys_descent
);
19414 row
->extra_line_spacing
= max (row
->extra_line_spacing
,
19415 it
->max_extra_line_spacing
);
19416 set_iterator_to_next (it
, 1);
19420 /* Does the display element fit on the line? If we truncate
19421 lines, we should draw past the right edge of the window. If
19422 we don't truncate, we want to stop so that we can display the
19423 continuation glyph before the right margin. If lines are
19424 continued, there are two possible strategies for characters
19425 resulting in more than 1 glyph (e.g. tabs): Display as many
19426 glyphs as possible in this line and leave the rest for the
19427 continuation line, or display the whole element in the next
19428 line. Original redisplay did the former, so we do it also. */
19429 nglyphs
= row
->used
[TEXT_AREA
] - n_glyphs_before
;
19430 hpos_before
= it
->hpos
;
19433 if (/* Not a newline. */
19435 /* Glyphs produced fit entirely in the line. */
19436 && it
->current_x
< it
->last_visible_x
)
19438 it
->hpos
+= nglyphs
;
19439 row
->ascent
= max (row
->ascent
, it
->max_ascent
);
19440 row
->height
= max (row
->height
, it
->max_ascent
+ it
->max_descent
);
19441 row
->phys_ascent
= max (row
->phys_ascent
, it
->max_phys_ascent
);
19442 row
->phys_height
= max (row
->phys_height
,
19443 it
->max_phys_ascent
+ it
->max_phys_descent
);
19444 row
->extra_line_spacing
= max (row
->extra_line_spacing
,
19445 it
->max_extra_line_spacing
);
19446 if (it
->current_x
- it
->pixel_width
< it
->first_visible_x
)
19447 row
->x
= x
- it
->first_visible_x
;
19448 /* Record the maximum and minimum buffer positions seen so
19449 far in glyphs that will be displayed by this row. */
19451 RECORD_MAX_MIN_POS (it
);
19456 struct glyph
*glyph
;
19458 for (i
= 0; i
< nglyphs
; ++i
, x
= new_x
)
19460 glyph
= row
->glyphs
[TEXT_AREA
] + n_glyphs_before
+ i
;
19461 new_x
= x
+ glyph
->pixel_width
;
19463 if (/* Lines are continued. */
19464 it
->line_wrap
!= TRUNCATE
19465 && (/* Glyph doesn't fit on the line. */
19466 new_x
> it
->last_visible_x
19467 /* Or it fits exactly on a window system frame. */
19468 || (new_x
== it
->last_visible_x
19469 && FRAME_WINDOW_P (it
->f
)
19470 && (row
->reversed_p
19471 ? WINDOW_LEFT_FRINGE_WIDTH (it
->w
)
19472 : WINDOW_RIGHT_FRINGE_WIDTH (it
->w
)))))
19474 /* End of a continued line. */
19477 || (new_x
== it
->last_visible_x
19478 && FRAME_WINDOW_P (it
->f
)
19479 && (row
->reversed_p
19480 ? WINDOW_LEFT_FRINGE_WIDTH (it
->w
)
19481 : WINDOW_RIGHT_FRINGE_WIDTH (it
->w
))))
19483 /* Current glyph is the only one on the line or
19484 fits exactly on the line. We must continue
19485 the line because we can't draw the cursor
19486 after the glyph. */
19487 row
->continued_p
= 1;
19488 it
->current_x
= new_x
;
19489 it
->continuation_lines_width
+= new_x
;
19491 if (i
== nglyphs
- 1)
19493 /* If line-wrap is on, check if a previous
19494 wrap point was found. */
19495 if (wrap_row_used
> 0
19496 /* Even if there is a previous wrap
19497 point, continue the line here as
19498 usual, if (i) the previous character
19499 was a space or tab AND (ii) the
19500 current character is not. */
19502 || IT_DISPLAYING_WHITESPACE (it
)))
19505 /* Record the maximum and minimum buffer
19506 positions seen so far in glyphs that will be
19507 displayed by this row. */
19509 RECORD_MAX_MIN_POS (it
);
19510 set_iterator_to_next (it
, 1);
19511 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
19513 if (!get_next_display_element (it
))
19515 row
->exact_window_width_line_p
= 1;
19516 it
->continuation_lines_width
= 0;
19517 row
->continued_p
= 0;
19518 row
->ends_at_zv_p
= 1;
19520 else if (ITERATOR_AT_END_OF_LINE_P (it
))
19522 row
->continued_p
= 0;
19523 row
->exact_window_width_line_p
= 1;
19527 else if (it
->bidi_p
)
19528 RECORD_MAX_MIN_POS (it
);
19530 else if (CHAR_GLYPH_PADDING_P (*glyph
)
19531 && !FRAME_WINDOW_P (it
->f
))
19533 /* A padding glyph that doesn't fit on this line.
19534 This means the whole character doesn't fit
19536 if (row
->reversed_p
)
19537 unproduce_glyphs (it
, row
->used
[TEXT_AREA
]
19538 - n_glyphs_before
);
19539 row
->used
[TEXT_AREA
] = n_glyphs_before
;
19541 /* Fill the rest of the row with continuation
19542 glyphs like in 20.x. */
19543 while (row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
]
19544 < row
->glyphs
[1 + TEXT_AREA
])
19545 produce_special_glyphs (it
, IT_CONTINUATION
);
19547 row
->continued_p
= 1;
19548 it
->current_x
= x_before
;
19549 it
->continuation_lines_width
+= x_before
;
19551 /* Restore the height to what it was before the
19552 element not fitting on the line. */
19553 it
->max_ascent
= ascent
;
19554 it
->max_descent
= descent
;
19555 it
->max_phys_ascent
= phys_ascent
;
19556 it
->max_phys_descent
= phys_descent
;
19558 else if (wrap_row_used
> 0)
19561 if (row
->reversed_p
)
19562 unproduce_glyphs (it
,
19563 row
->used
[TEXT_AREA
] - wrap_row_used
);
19564 RESTORE_IT (it
, &wrap_it
, wrap_data
);
19565 it
->continuation_lines_width
+= wrap_x
;
19566 row
->used
[TEXT_AREA
] = wrap_row_used
;
19567 row
->ascent
= wrap_row_ascent
;
19568 row
->height
= wrap_row_height
;
19569 row
->phys_ascent
= wrap_row_phys_ascent
;
19570 row
->phys_height
= wrap_row_phys_height
;
19571 row
->extra_line_spacing
= wrap_row_extra_line_spacing
;
19572 min_pos
= wrap_row_min_pos
;
19573 min_bpos
= wrap_row_min_bpos
;
19574 max_pos
= wrap_row_max_pos
;
19575 max_bpos
= wrap_row_max_bpos
;
19576 row
->continued_p
= 1;
19577 row
->ends_at_zv_p
= 0;
19578 row
->exact_window_width_line_p
= 0;
19579 it
->continuation_lines_width
+= x
;
19581 /* Make sure that a non-default face is extended
19582 up to the right margin of the window. */
19583 extend_face_to_end_of_line (it
);
19585 else if (it
->c
== '\t' && FRAME_WINDOW_P (it
->f
))
19587 /* A TAB that extends past the right edge of the
19588 window. This produces a single glyph on
19589 window system frames. We leave the glyph in
19590 this row and let it fill the row, but don't
19591 consume the TAB. */
19592 if ((row
->reversed_p
19593 ? WINDOW_LEFT_FRINGE_WIDTH (it
->w
)
19594 : WINDOW_RIGHT_FRINGE_WIDTH (it
->w
)) == 0)
19595 produce_special_glyphs (it
, IT_CONTINUATION
);
19596 it
->continuation_lines_width
+= it
->last_visible_x
;
19597 row
->ends_in_middle_of_char_p
= 1;
19598 row
->continued_p
= 1;
19599 glyph
->pixel_width
= it
->last_visible_x
- x
;
19600 it
->starts_in_middle_of_char_p
= 1;
19604 /* Something other than a TAB that draws past
19605 the right edge of the window. Restore
19606 positions to values before the element. */
19607 if (row
->reversed_p
)
19608 unproduce_glyphs (it
, row
->used
[TEXT_AREA
]
19609 - (n_glyphs_before
+ i
));
19610 row
->used
[TEXT_AREA
] = n_glyphs_before
+ i
;
19612 /* Display continuation glyphs. */
19613 it
->current_x
= x_before
;
19614 it
->continuation_lines_width
+= x
;
19615 if (!FRAME_WINDOW_P (it
->f
)
19616 || (row
->reversed_p
19617 ? WINDOW_LEFT_FRINGE_WIDTH (it
->w
)
19618 : WINDOW_RIGHT_FRINGE_WIDTH (it
->w
)) == 0)
19619 produce_special_glyphs (it
, IT_CONTINUATION
);
19620 row
->continued_p
= 1;
19622 extend_face_to_end_of_line (it
);
19624 if (nglyphs
> 1 && i
> 0)
19626 row
->ends_in_middle_of_char_p
= 1;
19627 it
->starts_in_middle_of_char_p
= 1;
19630 /* Restore the height to what it was before the
19631 element not fitting on the line. */
19632 it
->max_ascent
= ascent
;
19633 it
->max_descent
= descent
;
19634 it
->max_phys_ascent
= phys_ascent
;
19635 it
->max_phys_descent
= phys_descent
;
19640 else if (new_x
> it
->first_visible_x
)
19642 /* Increment number of glyphs actually displayed. */
19645 /* Record the maximum and minimum buffer positions
19646 seen so far in glyphs that will be displayed by
19649 RECORD_MAX_MIN_POS (it
);
19651 if (x
< it
->first_visible_x
)
19652 /* Glyph is partially visible, i.e. row starts at
19653 negative X position. */
19654 row
->x
= x
- it
->first_visible_x
;
19658 /* Glyph is completely off the left margin of the
19659 window. This should not happen because of the
19660 move_it_in_display_line at the start of this
19661 function, unless the text display area of the
19662 window is empty. */
19663 eassert (it
->first_visible_x
<= it
->last_visible_x
);
19666 /* Even if this display element produced no glyphs at all,
19667 we want to record its position. */
19668 if (it
->bidi_p
&& nglyphs
== 0)
19669 RECORD_MAX_MIN_POS (it
);
19671 row
->ascent
= max (row
->ascent
, it
->max_ascent
);
19672 row
->height
= max (row
->height
, it
->max_ascent
+ it
->max_descent
);
19673 row
->phys_ascent
= max (row
->phys_ascent
, it
->max_phys_ascent
);
19674 row
->phys_height
= max (row
->phys_height
,
19675 it
->max_phys_ascent
+ it
->max_phys_descent
);
19676 row
->extra_line_spacing
= max (row
->extra_line_spacing
,
19677 it
->max_extra_line_spacing
);
19679 /* End of this display line if row is continued. */
19680 if (row
->continued_p
|| row
->ends_at_zv_p
)
19685 /* Is this a line end? If yes, we're also done, after making
19686 sure that a non-default face is extended up to the right
19687 margin of the window. */
19688 if (ITERATOR_AT_END_OF_LINE_P (it
))
19690 int used_before
= row
->used
[TEXT_AREA
];
19692 row
->ends_in_newline_from_string_p
= STRINGP (it
->object
);
19694 /* Add a space at the end of the line that is used to
19695 display the cursor there. */
19696 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
19697 append_space_for_newline (it
, 0);
19699 /* Extend the face to the end of the line. */
19700 extend_face_to_end_of_line (it
);
19702 /* Make sure we have the position. */
19703 if (used_before
== 0)
19704 row
->glyphs
[TEXT_AREA
]->charpos
= CHARPOS (it
->position
);
19706 /* Record the position of the newline, for use in
19708 it
->eol_pos
= it
->current
.pos
;
19710 /* Consume the line end. This skips over invisible lines. */
19711 set_iterator_to_next (it
, 1);
19712 it
->continuation_lines_width
= 0;
19716 /* Proceed with next display element. Note that this skips
19717 over lines invisible because of selective display. */
19718 set_iterator_to_next (it
, 1);
19720 /* If we truncate lines, we are done when the last displayed
19721 glyphs reach past the right margin of the window. */
19722 if (it
->line_wrap
== TRUNCATE
19723 && (FRAME_WINDOW_P (it
->f
) && WINDOW_RIGHT_FRINGE_WIDTH (it
->w
)
19724 ? (it
->current_x
>= it
->last_visible_x
)
19725 : (it
->current_x
> it
->last_visible_x
)))
19727 /* Maybe add truncation glyphs. */
19728 if (!FRAME_WINDOW_P (it
->f
)
19729 || (row
->reversed_p
19730 ? WINDOW_LEFT_FRINGE_WIDTH (it
->w
)
19731 : WINDOW_RIGHT_FRINGE_WIDTH (it
->w
)) == 0)
19735 if (!row
->reversed_p
)
19737 for (i
= row
->used
[TEXT_AREA
] - 1; i
> 0; --i
)
19738 if (!CHAR_GLYPH_PADDING_P (row
->glyphs
[TEXT_AREA
][i
]))
19743 for (i
= 0; i
< row
->used
[TEXT_AREA
]; i
++)
19744 if (!CHAR_GLYPH_PADDING_P (row
->glyphs
[TEXT_AREA
][i
]))
19746 /* Remove any padding glyphs at the front of ROW, to
19747 make room for the truncation glyphs we will be
19748 adding below. The loop below always inserts at
19749 least one truncation glyph, so also remove the
19750 last glyph added to ROW. */
19751 unproduce_glyphs (it
, i
+ 1);
19752 /* Adjust i for the loop below. */
19753 i
= row
->used
[TEXT_AREA
] - (i
+ 1);
19756 it
->current_x
= x_before
;
19757 if (!FRAME_WINDOW_P (it
->f
))
19759 for (n
= row
->used
[TEXT_AREA
]; i
< n
; ++i
)
19761 row
->used
[TEXT_AREA
] = i
;
19762 produce_special_glyphs (it
, IT_TRUNCATION
);
19767 row
->used
[TEXT_AREA
] = i
;
19768 produce_special_glyphs (it
, IT_TRUNCATION
);
19771 else if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
19773 /* Don't truncate if we can overflow newline into fringe. */
19774 if (!get_next_display_element (it
))
19776 it
->continuation_lines_width
= 0;
19777 row
->ends_at_zv_p
= 1;
19778 row
->exact_window_width_line_p
= 1;
19781 if (ITERATOR_AT_END_OF_LINE_P (it
))
19783 row
->exact_window_width_line_p
= 1;
19784 goto at_end_of_line
;
19786 it
->current_x
= x_before
;
19789 row
->truncated_on_right_p
= 1;
19790 it
->continuation_lines_width
= 0;
19791 reseat_at_next_visible_line_start (it
, 0);
19792 row
->ends_at_zv_p
= FETCH_BYTE (IT_BYTEPOS (*it
) - 1) != '\n';
19793 it
->hpos
= hpos_before
;
19799 bidi_unshelve_cache (wrap_data
, 1);
19801 /* If line is not empty and hscrolled, maybe insert truncation glyphs
19802 at the left window margin. */
19803 if (it
->first_visible_x
19804 && IT_CHARPOS (*it
) != CHARPOS (row
->start
.pos
))
19806 if (!FRAME_WINDOW_P (it
->f
)
19807 || (row
->reversed_p
19808 ? WINDOW_RIGHT_FRINGE_WIDTH (it
->w
)
19809 : WINDOW_LEFT_FRINGE_WIDTH (it
->w
)) == 0)
19810 insert_left_trunc_glyphs (it
);
19811 row
->truncated_on_left_p
= 1;
19814 /* Remember the position at which this line ends.
19816 BIDI Note: any code that needs MATRIX_ROW_START/END_CHARPOS
19817 cannot be before the call to find_row_edges below, since that is
19818 where these positions are determined. */
19819 row
->end
= it
->current
;
19822 row
->minpos
= row
->start
.pos
;
19823 row
->maxpos
= row
->end
.pos
;
19827 /* ROW->minpos and ROW->maxpos must be the smallest and
19828 `1 + the largest' buffer positions in ROW. But if ROW was
19829 bidi-reordered, these two positions can be anywhere in the
19830 row, so we must determine them now. */
19831 find_row_edges (it
, row
, min_pos
, min_bpos
, max_pos
, max_bpos
);
19834 /* If the start of this line is the overlay arrow-position, then
19835 mark this glyph row as the one containing the overlay arrow.
19836 This is clearly a mess with variable size fonts. It would be
19837 better to let it be displayed like cursors under X. */
19838 if ((MATRIX_ROW_DISPLAYS_TEXT_P (row
) || !overlay_arrow_seen
)
19839 && (overlay_arrow_string
= overlay_arrow_at_row (it
, row
),
19840 !NILP (overlay_arrow_string
)))
19842 /* Overlay arrow in window redisplay is a fringe bitmap. */
19843 if (STRINGP (overlay_arrow_string
))
19845 struct glyph_row
*arrow_row
19846 = get_overlay_arrow_glyph_row (it
->w
, overlay_arrow_string
);
19847 struct glyph
*glyph
= arrow_row
->glyphs
[TEXT_AREA
];
19848 struct glyph
*arrow_end
= glyph
+ arrow_row
->used
[TEXT_AREA
];
19849 struct glyph
*p
= row
->glyphs
[TEXT_AREA
];
19850 struct glyph
*p2
, *end
;
19852 /* Copy the arrow glyphs. */
19853 while (glyph
< arrow_end
)
19856 /* Throw away padding glyphs. */
19858 end
= row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
];
19859 while (p2
< end
&& CHAR_GLYPH_PADDING_P (*p2
))
19865 row
->used
[TEXT_AREA
] = p2
- row
->glyphs
[TEXT_AREA
];
19870 eassert (INTEGERP (overlay_arrow_string
));
19871 row
->overlay_arrow_bitmap
= XINT (overlay_arrow_string
);
19873 overlay_arrow_seen
= 1;
19876 /* Highlight trailing whitespace. */
19877 if (!NILP (Vshow_trailing_whitespace
))
19878 highlight_trailing_whitespace (it
->f
, it
->glyph_row
);
19880 /* Compute pixel dimensions of this line. */
19881 compute_line_metrics (it
);
19883 /* Implementation note: No changes in the glyphs of ROW or in their
19884 faces can be done past this point, because compute_line_metrics
19885 computes ROW's hash value and stores it within the glyph_row
19888 /* Record whether this row ends inside an ellipsis. */
19889 row
->ends_in_ellipsis_p
19890 = (it
->method
== GET_FROM_DISPLAY_VECTOR
19891 && it
->ellipsis_p
);
19893 /* Save fringe bitmaps in this row. */
19894 row
->left_user_fringe_bitmap
= it
->left_user_fringe_bitmap
;
19895 row
->left_user_fringe_face_id
= it
->left_user_fringe_face_id
;
19896 row
->right_user_fringe_bitmap
= it
->right_user_fringe_bitmap
;
19897 row
->right_user_fringe_face_id
= it
->right_user_fringe_face_id
;
19899 it
->left_user_fringe_bitmap
= 0;
19900 it
->left_user_fringe_face_id
= 0;
19901 it
->right_user_fringe_bitmap
= 0;
19902 it
->right_user_fringe_face_id
= 0;
19904 /* Maybe set the cursor. */
19905 cvpos
= it
->w
->cursor
.vpos
;
19907 /* In bidi-reordered rows, keep checking for proper cursor
19908 position even if one has been found already, because buffer
19909 positions in such rows change non-linearly with ROW->VPOS,
19910 when a line is continued. One exception: when we are at ZV,
19911 display cursor on the first suitable glyph row, since all
19912 the empty rows after that also have their position set to ZV. */
19913 /* FIXME: Revisit this when glyph ``spilling'' in continuation
19914 lines' rows is implemented for bidi-reordered rows. */
19916 && !MATRIX_ROW (it
->w
->desired_matrix
, cvpos
)->ends_at_zv_p
))
19917 && PT
>= MATRIX_ROW_START_CHARPOS (row
)
19918 && PT
<= MATRIX_ROW_END_CHARPOS (row
)
19919 && cursor_row_p (row
))
19920 set_cursor_from_row (it
->w
, row
, it
->w
->desired_matrix
, 0, 0, 0, 0);
19922 /* Prepare for the next line. This line starts horizontally at (X
19923 HPOS) = (0 0). Vertical positions are incremented. As a
19924 convenience for the caller, IT->glyph_row is set to the next
19926 it
->current_x
= it
->hpos
= 0;
19927 it
->current_y
+= row
->height
;
19928 SET_TEXT_POS (it
->eol_pos
, 0, 0);
19931 /* The next row should by default use the same value of the
19932 reversed_p flag as this one. set_iterator_to_next decides when
19933 it's a new paragraph, and PRODUCE_GLYPHS recomputes the value of
19934 the flag accordingly. */
19935 if (it
->glyph_row
< MATRIX_BOTTOM_TEXT_ROW (it
->w
->desired_matrix
, it
->w
))
19936 it
->glyph_row
->reversed_p
= row
->reversed_p
;
19937 it
->start
= row
->end
;
19938 return MATRIX_ROW_DISPLAYS_TEXT_P (row
);
19940 #undef RECORD_MAX_MIN_POS
19943 DEFUN ("current-bidi-paragraph-direction", Fcurrent_bidi_paragraph_direction
,
19944 Scurrent_bidi_paragraph_direction
, 0, 1, 0,
19945 doc
: /* Return paragraph direction at point in BUFFER.
19946 Value is either `left-to-right' or `right-to-left'.
19947 If BUFFER is omitted or nil, it defaults to the current buffer.
19949 Paragraph direction determines how the text in the paragraph is displayed.
19950 In left-to-right paragraphs, text begins at the left margin of the window
19951 and the reading direction is generally left to right. In right-to-left
19952 paragraphs, text begins at the right margin and is read from right to left.
19954 See also `bidi-paragraph-direction'. */)
19955 (Lisp_Object buffer
)
19957 struct buffer
*buf
= current_buffer
;
19958 struct buffer
*old
= buf
;
19960 if (! NILP (buffer
))
19962 CHECK_BUFFER (buffer
);
19963 buf
= XBUFFER (buffer
);
19966 if (NILP (BVAR (buf
, bidi_display_reordering
))
19967 || NILP (BVAR (buf
, enable_multibyte_characters
))
19968 /* When we are loading loadup.el, the character property tables
19969 needed for bidi iteration are not yet available. */
19970 || !NILP (Vpurify_flag
))
19971 return Qleft_to_right
;
19972 else if (!NILP (BVAR (buf
, bidi_paragraph_direction
)))
19973 return BVAR (buf
, bidi_paragraph_direction
);
19976 /* Determine the direction from buffer text. We could try to
19977 use current_matrix if it is up to date, but this seems fast
19978 enough as it is. */
19979 struct bidi_it itb
;
19980 ptrdiff_t pos
= BUF_PT (buf
);
19981 ptrdiff_t bytepos
= BUF_PT_BYTE (buf
);
19983 void *itb_data
= bidi_shelve_cache ();
19985 set_buffer_temp (buf
);
19986 /* bidi_paragraph_init finds the base direction of the paragraph
19987 by searching forward from paragraph start. We need the base
19988 direction of the current or _previous_ paragraph, so we need
19989 to make sure we are within that paragraph. To that end, find
19990 the previous non-empty line. */
19991 if (pos
>= ZV
&& pos
> BEGV
)
19992 DEC_BOTH (pos
, bytepos
);
19993 if (fast_looking_at (build_string ("[\f\t ]*\n"),
19994 pos
, bytepos
, ZV
, ZV_BYTE
, Qnil
) > 0)
19996 while ((c
= FETCH_BYTE (bytepos
)) == '\n'
19997 || c
== ' ' || c
== '\t' || c
== '\f')
19999 if (bytepos
<= BEGV_BYTE
)
20004 while (!CHAR_HEAD_P (FETCH_BYTE (bytepos
)))
20007 bidi_init_it (pos
, bytepos
, FRAME_WINDOW_P (SELECTED_FRAME ()), &itb
);
20008 itb
.paragraph_dir
= NEUTRAL_DIR
;
20009 itb
.string
.s
= NULL
;
20010 itb
.string
.lstring
= Qnil
;
20011 itb
.string
.bufpos
= 0;
20012 itb
.string
.unibyte
= 0;
20013 itb
.w
= XWINDOW (selected_window
);
20014 bidi_paragraph_init (NEUTRAL_DIR
, &itb
, 1);
20015 bidi_unshelve_cache (itb_data
, 0);
20016 set_buffer_temp (old
);
20017 switch (itb
.paragraph_dir
)
20020 return Qleft_to_right
;
20023 return Qright_to_left
;
20033 /***********************************************************************
20035 ***********************************************************************/
20037 /* Redisplay the menu bar in the frame for window W.
20039 The menu bar of X frames that don't have X toolkit support is
20040 displayed in a special window W->frame->menu_bar_window.
20042 The menu bar of terminal frames is treated specially as far as
20043 glyph matrices are concerned. Menu bar lines are not part of
20044 windows, so the update is done directly on the frame matrix rows
20045 for the menu bar. */
20048 display_menu_bar (struct window
*w
)
20050 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
20055 /* Don't do all this for graphical frames. */
20057 if (FRAME_W32_P (f
))
20060 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
20066 if (FRAME_NS_P (f
))
20068 #endif /* HAVE_NS */
20070 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
20071 eassert (!FRAME_WINDOW_P (f
));
20072 init_iterator (&it
, w
, -1, -1, f
->desired_matrix
->rows
, MENU_FACE_ID
);
20073 it
.first_visible_x
= 0;
20074 it
.last_visible_x
= FRAME_TOTAL_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
20075 #elif defined (HAVE_X_WINDOWS) /* X without toolkit. */
20076 if (FRAME_WINDOW_P (f
))
20078 /* Menu bar lines are displayed in the desired matrix of the
20079 dummy window menu_bar_window. */
20080 struct window
*menu_w
;
20081 menu_w
= XWINDOW (f
->menu_bar_window
);
20082 init_iterator (&it
, menu_w
, -1, -1, menu_w
->desired_matrix
->rows
,
20084 it
.first_visible_x
= 0;
20085 it
.last_visible_x
= FRAME_TOTAL_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
20088 #endif /* not USE_X_TOOLKIT and not USE_GTK */
20090 /* This is a TTY frame, i.e. character hpos/vpos are used as
20092 init_iterator (&it
, w
, -1, -1, f
->desired_matrix
->rows
,
20094 it
.first_visible_x
= 0;
20095 it
.last_visible_x
= FRAME_COLS (f
);
20098 /* FIXME: This should be controlled by a user option. See the
20099 comments in redisplay_tool_bar and display_mode_line about
20101 it
.paragraph_embedding
= L2R
;
20103 /* Clear all rows of the menu bar. */
20104 for (i
= 0; i
< FRAME_MENU_BAR_LINES (f
); ++i
)
20106 struct glyph_row
*row
= it
.glyph_row
+ i
;
20107 clear_glyph_row (row
);
20108 row
->enabled_p
= 1;
20109 row
->full_width_p
= 1;
20112 /* Display all items of the menu bar. */
20113 items
= FRAME_MENU_BAR_ITEMS (it
.f
);
20114 for (i
= 0; i
< ASIZE (items
); i
+= 4)
20116 Lisp_Object string
;
20118 /* Stop at nil string. */
20119 string
= AREF (items
, i
+ 1);
20123 /* Remember where item was displayed. */
20124 ASET (items
, i
+ 3, make_number (it
.hpos
));
20126 /* Display the item, pad with one space. */
20127 if (it
.current_x
< it
.last_visible_x
)
20128 display_string (NULL
, string
, Qnil
, 0, 0, &it
,
20129 SCHARS (string
) + 1, 0, 0, -1);
20132 /* Fill out the line with spaces. */
20133 if (it
.current_x
< it
.last_visible_x
)
20134 display_string ("", Qnil
, Qnil
, 0, 0, &it
, -1, 0, 0, -1);
20136 /* Compute the total height of the lines. */
20137 compute_line_metrics (&it
);
20142 /***********************************************************************
20144 ***********************************************************************/
20146 /* Redisplay mode lines in the window tree whose root is WINDOW. If
20147 FORCE is non-zero, redisplay mode lines unconditionally.
20148 Otherwise, redisplay only mode lines that are garbaged. Value is
20149 the number of windows whose mode lines were redisplayed. */
20152 redisplay_mode_lines (Lisp_Object window
, int force
)
20156 while (!NILP (window
))
20158 struct window
*w
= XWINDOW (window
);
20160 if (WINDOWP (w
->contents
))
20161 nwindows
+= redisplay_mode_lines (w
->contents
, force
);
20163 || FRAME_GARBAGED_P (XFRAME (w
->frame
))
20164 || !MATRIX_MODE_LINE_ROW (w
->current_matrix
)->enabled_p
)
20166 struct text_pos lpoint
;
20167 struct buffer
*old
= current_buffer
;
20169 /* Set the window's buffer for the mode line display. */
20170 SET_TEXT_POS (lpoint
, PT
, PT_BYTE
);
20171 set_buffer_internal_1 (XBUFFER (w
->contents
));
20173 /* Point refers normally to the selected window. For any
20174 other window, set up appropriate value. */
20175 if (!EQ (window
, selected_window
))
20177 struct text_pos pt
;
20179 SET_TEXT_POS_FROM_MARKER (pt
, w
->pointm
);
20180 if (CHARPOS (pt
) < BEGV
)
20181 TEMP_SET_PT_BOTH (BEGV
, BEGV_BYTE
);
20182 else if (CHARPOS (pt
) > (ZV
- 1))
20183 TEMP_SET_PT_BOTH (ZV
, ZV_BYTE
);
20185 TEMP_SET_PT_BOTH (CHARPOS (pt
), BYTEPOS (pt
));
20188 /* Display mode lines. */
20189 clear_glyph_matrix (w
->desired_matrix
);
20190 if (display_mode_lines (w
))
20193 w
->must_be_updated_p
= 1;
20196 /* Restore old settings. */
20197 set_buffer_internal_1 (old
);
20198 TEMP_SET_PT_BOTH (CHARPOS (lpoint
), BYTEPOS (lpoint
));
20208 /* Display the mode and/or header line of window W. Value is the
20209 sum number of mode lines and header lines displayed. */
20212 display_mode_lines (struct window
*w
)
20214 Lisp_Object old_selected_window
= selected_window
;
20215 Lisp_Object old_selected_frame
= selected_frame
;
20216 Lisp_Object new_frame
= w
->frame
;
20217 Lisp_Object old_frame_selected_window
= XFRAME (new_frame
)->selected_window
;
20220 selected_frame
= new_frame
;
20221 /* FIXME: If we were to allow the mode-line's computation changing the buffer
20222 or window's point, then we'd need select_window_1 here as well. */
20223 XSETWINDOW (selected_window
, w
);
20224 XFRAME (new_frame
)->selected_window
= selected_window
;
20226 /* These will be set while the mode line specs are processed. */
20227 line_number_displayed
= 0;
20228 w
->column_number_displayed
= -1;
20230 if (WINDOW_WANTS_MODELINE_P (w
))
20232 struct window
*sel_w
= XWINDOW (old_selected_window
);
20234 /* Select mode line face based on the real selected window. */
20235 display_mode_line (w
, CURRENT_MODE_LINE_FACE_ID_3 (sel_w
, sel_w
, w
),
20236 BVAR (current_buffer
, mode_line_format
));
20240 if (WINDOW_WANTS_HEADER_LINE_P (w
))
20242 display_mode_line (w
, HEADER_LINE_FACE_ID
,
20243 BVAR (current_buffer
, header_line_format
));
20247 XFRAME (new_frame
)->selected_window
= old_frame_selected_window
;
20248 selected_frame
= old_selected_frame
;
20249 selected_window
= old_selected_window
;
20254 /* Display mode or header line of window W. FACE_ID specifies which
20255 line to display; it is either MODE_LINE_FACE_ID or
20256 HEADER_LINE_FACE_ID. FORMAT is the mode/header line format to
20257 display. Value is the pixel height of the mode/header line
20261 display_mode_line (struct window
*w
, enum face_id face_id
, Lisp_Object format
)
20265 ptrdiff_t count
= SPECPDL_INDEX ();
20267 init_iterator (&it
, w
, -1, -1, NULL
, face_id
);
20268 /* Don't extend on a previously drawn mode-line.
20269 This may happen if called from pos_visible_p. */
20270 it
.glyph_row
->enabled_p
= 0;
20271 prepare_desired_row (it
.glyph_row
);
20273 it
.glyph_row
->mode_line_p
= 1;
20275 /* FIXME: This should be controlled by a user option. But
20276 supporting such an option is not trivial, since the mode line is
20277 made up of many separate strings. */
20278 it
.paragraph_embedding
= L2R
;
20280 record_unwind_protect (unwind_format_mode_line
,
20281 format_mode_line_unwind_data (NULL
, NULL
, Qnil
, 0));
20283 mode_line_target
= MODE_LINE_DISPLAY
;
20285 /* Temporarily make frame's keyboard the current kboard so that
20286 kboard-local variables in the mode_line_format will get the right
20288 push_kboard (FRAME_KBOARD (it
.f
));
20289 record_unwind_save_match_data ();
20290 display_mode_element (&it
, 0, 0, 0, format
, Qnil
, 0);
20293 unbind_to (count
, Qnil
);
20295 /* Fill up with spaces. */
20296 display_string (" ", Qnil
, Qnil
, 0, 0, &it
, 10000, -1, -1, 0);
20298 compute_line_metrics (&it
);
20299 it
.glyph_row
->full_width_p
= 1;
20300 it
.glyph_row
->continued_p
= 0;
20301 it
.glyph_row
->truncated_on_left_p
= 0;
20302 it
.glyph_row
->truncated_on_right_p
= 0;
20304 /* Make a 3D mode-line have a shadow at its right end. */
20305 face
= FACE_FROM_ID (it
.f
, face_id
);
20306 extend_face_to_end_of_line (&it
);
20307 if (face
->box
!= FACE_NO_BOX
)
20309 struct glyph
*last
= (it
.glyph_row
->glyphs
[TEXT_AREA
]
20310 + it
.glyph_row
->used
[TEXT_AREA
] - 1);
20311 last
->right_box_line_p
= 1;
20314 return it
.glyph_row
->height
;
20317 /* Move element ELT in LIST to the front of LIST.
20318 Return the updated list. */
20321 move_elt_to_front (Lisp_Object elt
, Lisp_Object list
)
20323 register Lisp_Object tail
, prev
;
20324 register Lisp_Object tem
;
20328 while (CONSP (tail
))
20334 /* Splice out the link TAIL. */
20336 list
= XCDR (tail
);
20338 Fsetcdr (prev
, XCDR (tail
));
20340 /* Now make it the first. */
20341 Fsetcdr (tail
, list
);
20346 tail
= XCDR (tail
);
20350 /* Not found--return unchanged LIST. */
20354 /* Contribute ELT to the mode line for window IT->w. How it
20355 translates into text depends on its data type.
20357 IT describes the display environment in which we display, as usual.
20359 DEPTH is the depth in recursion. It is used to prevent
20360 infinite recursion here.
20362 FIELD_WIDTH is the number of characters the display of ELT should
20363 occupy in the mode line, and PRECISION is the maximum number of
20364 characters to display from ELT's representation. See
20365 display_string for details.
20367 Returns the hpos of the end of the text generated by ELT.
20369 PROPS is a property list to add to any string we encounter.
20371 If RISKY is nonzero, remove (disregard) any properties in any string
20372 we encounter, and ignore :eval and :propertize.
20374 The global variable `mode_line_target' determines whether the
20375 output is passed to `store_mode_line_noprop',
20376 `store_mode_line_string', or `display_string'. */
20379 display_mode_element (struct it
*it
, int depth
, int field_width
, int precision
,
20380 Lisp_Object elt
, Lisp_Object props
, int risky
)
20382 int n
= 0, field
, prec
;
20387 elt
= build_string ("*too-deep*");
20391 switch (XTYPE (elt
))
20395 /* A string: output it and check for %-constructs within it. */
20397 ptrdiff_t offset
= 0;
20399 if (SCHARS (elt
) > 0
20400 && (!NILP (props
) || risky
))
20402 Lisp_Object oprops
, aelt
;
20403 oprops
= Ftext_properties_at (make_number (0), elt
);
20405 /* If the starting string's properties are not what
20406 we want, translate the string. Also, if the string
20407 is risky, do that anyway. */
20409 if (NILP (Fequal (props
, oprops
)) || risky
)
20411 /* If the starting string has properties,
20412 merge the specified ones onto the existing ones. */
20413 if (! NILP (oprops
) && !risky
)
20417 oprops
= Fcopy_sequence (oprops
);
20419 while (CONSP (tem
))
20421 oprops
= Fplist_put (oprops
, XCAR (tem
),
20422 XCAR (XCDR (tem
)));
20423 tem
= XCDR (XCDR (tem
));
20428 aelt
= Fassoc (elt
, mode_line_proptrans_alist
);
20429 if (! NILP (aelt
) && !NILP (Fequal (props
, XCDR (aelt
))))
20431 /* AELT is what we want. Move it to the front
20432 without consing. */
20434 mode_line_proptrans_alist
20435 = move_elt_to_front (aelt
, mode_line_proptrans_alist
);
20441 /* If AELT has the wrong props, it is useless.
20442 so get rid of it. */
20444 mode_line_proptrans_alist
20445 = Fdelq (aelt
, mode_line_proptrans_alist
);
20447 elt
= Fcopy_sequence (elt
);
20448 Fset_text_properties (make_number (0), Flength (elt
),
20450 /* Add this item to mode_line_proptrans_alist. */
20451 mode_line_proptrans_alist
20452 = Fcons (Fcons (elt
, props
),
20453 mode_line_proptrans_alist
);
20454 /* Truncate mode_line_proptrans_alist
20455 to at most 50 elements. */
20456 tem
= Fnthcdr (make_number (50),
20457 mode_line_proptrans_alist
);
20459 XSETCDR (tem
, Qnil
);
20468 prec
= precision
- n
;
20469 switch (mode_line_target
)
20471 case MODE_LINE_NOPROP
:
20472 case MODE_LINE_TITLE
:
20473 n
+= store_mode_line_noprop (SSDATA (elt
), -1, prec
);
20475 case MODE_LINE_STRING
:
20476 n
+= store_mode_line_string (NULL
, elt
, 1, 0, prec
, Qnil
);
20478 case MODE_LINE_DISPLAY
:
20479 n
+= display_string (NULL
, elt
, Qnil
, 0, 0, it
,
20480 0, prec
, 0, STRING_MULTIBYTE (elt
));
20487 /* Handle the non-literal case. */
20489 while ((precision
<= 0 || n
< precision
)
20490 && SREF (elt
, offset
) != 0
20491 && (mode_line_target
!= MODE_LINE_DISPLAY
20492 || it
->current_x
< it
->last_visible_x
))
20494 ptrdiff_t last_offset
= offset
;
20496 /* Advance to end of string or next format specifier. */
20497 while ((c
= SREF (elt
, offset
++)) != '\0' && c
!= '%')
20500 if (offset
- 1 != last_offset
)
20502 ptrdiff_t nchars
, nbytes
;
20504 /* Output to end of string or up to '%'. Field width
20505 is length of string. Don't output more than
20506 PRECISION allows us. */
20509 prec
= c_string_width (SDATA (elt
) + last_offset
,
20510 offset
- last_offset
, precision
- n
,
20513 switch (mode_line_target
)
20515 case MODE_LINE_NOPROP
:
20516 case MODE_LINE_TITLE
:
20517 n
+= store_mode_line_noprop (SSDATA (elt
) + last_offset
, 0, prec
);
20519 case MODE_LINE_STRING
:
20521 ptrdiff_t bytepos
= last_offset
;
20522 ptrdiff_t charpos
= string_byte_to_char (elt
, bytepos
);
20523 ptrdiff_t endpos
= (precision
<= 0
20524 ? string_byte_to_char (elt
, offset
)
20525 : charpos
+ nchars
);
20527 n
+= store_mode_line_string (NULL
,
20528 Fsubstring (elt
, make_number (charpos
),
20529 make_number (endpos
)),
20533 case MODE_LINE_DISPLAY
:
20535 ptrdiff_t bytepos
= last_offset
;
20536 ptrdiff_t charpos
= string_byte_to_char (elt
, bytepos
);
20538 if (precision
<= 0)
20539 nchars
= string_byte_to_char (elt
, offset
) - charpos
;
20540 n
+= display_string (NULL
, elt
, Qnil
, 0, charpos
,
20542 STRING_MULTIBYTE (elt
));
20547 else /* c == '%' */
20549 ptrdiff_t percent_position
= offset
;
20551 /* Get the specified minimum width. Zero means
20554 while ((c
= SREF (elt
, offset
++)) >= '0' && c
<= '9')
20555 field
= field
* 10 + c
- '0';
20557 /* Don't pad beyond the total padding allowed. */
20558 if (field_width
- n
> 0 && field
> field_width
- n
)
20559 field
= field_width
- n
;
20561 /* Note that either PRECISION <= 0 or N < PRECISION. */
20562 prec
= precision
- n
;
20565 n
+= display_mode_element (it
, depth
, field
, prec
,
20566 Vglobal_mode_string
, props
,
20571 ptrdiff_t bytepos
, charpos
;
20573 Lisp_Object string
;
20575 bytepos
= percent_position
;
20576 charpos
= (STRING_MULTIBYTE (elt
)
20577 ? string_byte_to_char (elt
, bytepos
)
20579 spec
= decode_mode_spec (it
->w
, c
, field
, &string
);
20580 multibyte
= STRINGP (string
) && STRING_MULTIBYTE (string
);
20582 switch (mode_line_target
)
20584 case MODE_LINE_NOPROP
:
20585 case MODE_LINE_TITLE
:
20586 n
+= store_mode_line_noprop (spec
, field
, prec
);
20588 case MODE_LINE_STRING
:
20590 Lisp_Object tem
= build_string (spec
);
20591 props
= Ftext_properties_at (make_number (charpos
), elt
);
20592 /* Should only keep face property in props */
20593 n
+= store_mode_line_string (NULL
, tem
, 0, field
, prec
, props
);
20596 case MODE_LINE_DISPLAY
:
20598 int nglyphs_before
, nwritten
;
20600 nglyphs_before
= it
->glyph_row
->used
[TEXT_AREA
];
20601 nwritten
= display_string (spec
, string
, elt
,
20606 /* Assign to the glyphs written above the
20607 string where the `%x' came from, position
20611 struct glyph
*glyph
20612 = (it
->glyph_row
->glyphs
[TEXT_AREA
]
20616 for (i
= 0; i
< nwritten
; ++i
)
20618 glyph
[i
].object
= elt
;
20619 glyph
[i
].charpos
= charpos
;
20636 /* A symbol: process the value of the symbol recursively
20637 as if it appeared here directly. Avoid error if symbol void.
20638 Special case: if value of symbol is a string, output the string
20641 register Lisp_Object tem
;
20643 /* If the variable is not marked as risky to set
20644 then its contents are risky to use. */
20645 if (NILP (Fget (elt
, Qrisky_local_variable
)))
20648 tem
= Fboundp (elt
);
20651 tem
= Fsymbol_value (elt
);
20652 /* If value is a string, output that string literally:
20653 don't check for % within it. */
20657 if (!EQ (tem
, elt
))
20659 /* Give up right away for nil or t. */
20669 register Lisp_Object car
, tem
;
20671 /* A cons cell: five distinct cases.
20672 If first element is :eval or :propertize, do something special.
20673 If first element is a string or a cons, process all the elements
20674 and effectively concatenate them.
20675 If first element is a negative number, truncate displaying cdr to
20676 at most that many characters. If positive, pad (with spaces)
20677 to at least that many characters.
20678 If first element is a symbol, process the cadr or caddr recursively
20679 according to whether the symbol's value is non-nil or nil. */
20681 if (EQ (car
, QCeval
))
20683 /* An element of the form (:eval FORM) means evaluate FORM
20684 and use the result as mode line elements. */
20689 if (CONSP (XCDR (elt
)))
20692 spec
= safe_eval (XCAR (XCDR (elt
)));
20693 n
+= display_mode_element (it
, depth
, field_width
- n
,
20694 precision
- n
, spec
, props
,
20698 else if (EQ (car
, QCpropertize
))
20700 /* An element of the form (:propertize ELT PROPS...)
20701 means display ELT but applying properties PROPS. */
20706 if (CONSP (XCDR (elt
)))
20707 n
+= display_mode_element (it
, depth
, field_width
- n
,
20708 precision
- n
, XCAR (XCDR (elt
)),
20709 XCDR (XCDR (elt
)), risky
);
20711 else if (SYMBOLP (car
))
20713 tem
= Fboundp (car
);
20717 /* elt is now the cdr, and we know it is a cons cell.
20718 Use its car if CAR has a non-nil value. */
20721 tem
= Fsymbol_value (car
);
20728 /* Symbol's value is nil (or symbol is unbound)
20729 Get the cddr of the original list
20730 and if possible find the caddr and use that. */
20734 else if (!CONSP (elt
))
20739 else if (INTEGERP (car
))
20741 register int lim
= XINT (car
);
20745 /* Negative int means reduce maximum width. */
20746 if (precision
<= 0)
20749 precision
= min (precision
, -lim
);
20753 /* Padding specified. Don't let it be more than
20754 current maximum. */
20756 lim
= min (precision
, lim
);
20758 /* If that's more padding than already wanted, queue it.
20759 But don't reduce padding already specified even if
20760 that is beyond the current truncation point. */
20761 field_width
= max (lim
, field_width
);
20765 else if (STRINGP (car
) || CONSP (car
))
20767 Lisp_Object halftail
= elt
;
20771 && (precision
<= 0 || n
< precision
))
20773 n
+= display_mode_element (it
, depth
,
20774 /* Do padding only after the last
20775 element in the list. */
20776 (! CONSP (XCDR (elt
))
20779 precision
- n
, XCAR (elt
),
20783 if ((len
& 1) == 0)
20784 halftail
= XCDR (halftail
);
20785 /* Check for cycle. */
20786 if (EQ (halftail
, elt
))
20795 elt
= build_string ("*invalid*");
20799 /* Pad to FIELD_WIDTH. */
20800 if (field_width
> 0 && n
< field_width
)
20802 switch (mode_line_target
)
20804 case MODE_LINE_NOPROP
:
20805 case MODE_LINE_TITLE
:
20806 n
+= store_mode_line_noprop ("", field_width
- n
, 0);
20808 case MODE_LINE_STRING
:
20809 n
+= store_mode_line_string ("", Qnil
, 0, field_width
- n
, 0, Qnil
);
20811 case MODE_LINE_DISPLAY
:
20812 n
+= display_string ("", Qnil
, Qnil
, 0, 0, it
, field_width
- n
,
20821 /* Store a mode-line string element in mode_line_string_list.
20823 If STRING is non-null, display that C string. Otherwise, the Lisp
20824 string LISP_STRING is displayed.
20826 FIELD_WIDTH is the minimum number of output glyphs to produce.
20827 If STRING has fewer characters than FIELD_WIDTH, pad to the right
20828 with spaces. FIELD_WIDTH <= 0 means don't pad.
20830 PRECISION is the maximum number of characters to output from
20831 STRING. PRECISION <= 0 means don't truncate the string.
20833 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
20834 properties to the string.
20836 PROPS are the properties to add to the string.
20837 The mode_line_string_face face property is always added to the string.
20841 store_mode_line_string (const char *string
, Lisp_Object lisp_string
, int copy_string
,
20842 int field_width
, int precision
, Lisp_Object props
)
20847 if (string
!= NULL
)
20849 len
= strlen (string
);
20850 if (precision
> 0 && len
> precision
)
20852 lisp_string
= make_string (string
, len
);
20854 props
= mode_line_string_face_prop
;
20855 else if (!NILP (mode_line_string_face
))
20857 Lisp_Object face
= Fplist_get (props
, Qface
);
20858 props
= Fcopy_sequence (props
);
20860 face
= mode_line_string_face
;
20862 face
= Fcons (face
, Fcons (mode_line_string_face
, Qnil
));
20863 props
= Fplist_put (props
, Qface
, face
);
20865 Fadd_text_properties (make_number (0), make_number (len
),
20866 props
, lisp_string
);
20870 len
= XFASTINT (Flength (lisp_string
));
20871 if (precision
> 0 && len
> precision
)
20874 lisp_string
= Fsubstring (lisp_string
, make_number (0), make_number (len
));
20877 if (!NILP (mode_line_string_face
))
20881 props
= Ftext_properties_at (make_number (0), lisp_string
);
20882 face
= Fplist_get (props
, Qface
);
20884 face
= mode_line_string_face
;
20886 face
= Fcons (face
, Fcons (mode_line_string_face
, Qnil
));
20887 props
= Fcons (Qface
, Fcons (face
, Qnil
));
20889 lisp_string
= Fcopy_sequence (lisp_string
);
20892 Fadd_text_properties (make_number (0), make_number (len
),
20893 props
, lisp_string
);
20898 mode_line_string_list
= Fcons (lisp_string
, mode_line_string_list
);
20902 if (field_width
> len
)
20904 field_width
-= len
;
20905 lisp_string
= Fmake_string (make_number (field_width
), make_number (' '));
20907 Fadd_text_properties (make_number (0), make_number (field_width
),
20908 props
, lisp_string
);
20909 mode_line_string_list
= Fcons (lisp_string
, mode_line_string_list
);
20917 DEFUN ("format-mode-line", Fformat_mode_line
, Sformat_mode_line
,
20919 doc
: /* Format a string out of a mode line format specification.
20920 First arg FORMAT specifies the mode line format (see `mode-line-format'
20921 for details) to use.
20923 By default, the format is evaluated for the currently selected window.
20925 Optional second arg FACE specifies the face property to put on all
20926 characters for which no face is specified. The value nil means the
20927 default face. The value t means whatever face the window's mode line
20928 currently uses (either `mode-line' or `mode-line-inactive',
20929 depending on whether the window is the selected window or not).
20930 An integer value means the value string has no text
20933 Optional third and fourth args WINDOW and BUFFER specify the window
20934 and buffer to use as the context for the formatting (defaults
20935 are the selected window and the WINDOW's buffer). */)
20936 (Lisp_Object format
, Lisp_Object face
,
20937 Lisp_Object window
, Lisp_Object buffer
)
20942 struct buffer
*old_buffer
= NULL
;
20944 int no_props
= INTEGERP (face
);
20945 ptrdiff_t count
= SPECPDL_INDEX ();
20947 int string_start
= 0;
20949 w
= decode_any_window (window
);
20950 XSETWINDOW (window
, w
);
20953 buffer
= w
->contents
;
20954 CHECK_BUFFER (buffer
);
20956 /* Make formatting the modeline a non-op when noninteractive, otherwise
20957 there will be problems later caused by a partially initialized frame. */
20958 if (NILP (format
) || noninteractive
)
20959 return empty_unibyte_string
;
20964 face_id
= (NILP (face
) || EQ (face
, Qdefault
)) ? DEFAULT_FACE_ID
20965 : EQ (face
, Qt
) ? (EQ (window
, selected_window
)
20966 ? MODE_LINE_FACE_ID
: MODE_LINE_INACTIVE_FACE_ID
)
20967 : EQ (face
, Qmode_line
) ? MODE_LINE_FACE_ID
20968 : EQ (face
, Qmode_line_inactive
) ? MODE_LINE_INACTIVE_FACE_ID
20969 : EQ (face
, Qheader_line
) ? HEADER_LINE_FACE_ID
20970 : EQ (face
, Qtool_bar
) ? TOOL_BAR_FACE_ID
20973 old_buffer
= current_buffer
;
20975 /* Save things including mode_line_proptrans_alist,
20976 and set that to nil so that we don't alter the outer value. */
20977 record_unwind_protect (unwind_format_mode_line
,
20978 format_mode_line_unwind_data
20979 (XFRAME (WINDOW_FRAME (w
)),
20980 old_buffer
, selected_window
, 1));
20981 mode_line_proptrans_alist
= Qnil
;
20983 Fselect_window (window
, Qt
);
20984 set_buffer_internal_1 (XBUFFER (buffer
));
20986 init_iterator (&it
, w
, -1, -1, NULL
, face_id
);
20990 mode_line_target
= MODE_LINE_NOPROP
;
20991 mode_line_string_face_prop
= Qnil
;
20992 mode_line_string_list
= Qnil
;
20993 string_start
= MODE_LINE_NOPROP_LEN (0);
20997 mode_line_target
= MODE_LINE_STRING
;
20998 mode_line_string_list
= Qnil
;
20999 mode_line_string_face
= face
;
21000 mode_line_string_face_prop
21001 = (NILP (face
) ? Qnil
: Fcons (Qface
, Fcons (face
, Qnil
)));
21004 push_kboard (FRAME_KBOARD (it
.f
));
21005 display_mode_element (&it
, 0, 0, 0, format
, Qnil
, 0);
21010 len
= MODE_LINE_NOPROP_LEN (string_start
);
21011 str
= make_string (mode_line_noprop_buf
+ string_start
, len
);
21015 mode_line_string_list
= Fnreverse (mode_line_string_list
);
21016 str
= Fmapconcat (intern ("identity"), mode_line_string_list
,
21017 empty_unibyte_string
);
21020 unbind_to (count
, Qnil
);
21024 /* Write a null-terminated, right justified decimal representation of
21025 the positive integer D to BUF using a minimal field width WIDTH. */
21028 pint2str (register char *buf
, register int width
, register ptrdiff_t d
)
21030 register char *p
= buf
;
21038 *p
++ = d
% 10 + '0';
21043 for (width
-= (int) (p
- buf
); width
> 0; --width
)
21054 /* Write a null-terminated, right justified decimal and "human
21055 readable" representation of the nonnegative integer D to BUF using
21056 a minimal field width WIDTH. D should be smaller than 999.5e24. */
21058 static const char power_letter
[] =
21072 pint2hrstr (char *buf
, int width
, ptrdiff_t d
)
21074 /* We aim to represent the nonnegative integer D as
21075 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
21076 ptrdiff_t quotient
= d
;
21078 /* -1 means: do not use TENTHS. */
21082 /* Length of QUOTIENT.TENTHS as a string. */
21088 if (quotient
>= 1000)
21090 /* Scale to the appropriate EXPONENT. */
21093 remainder
= quotient
% 1000;
21097 while (quotient
>= 1000);
21099 /* Round to nearest and decide whether to use TENTHS or not. */
21102 tenths
= remainder
/ 100;
21103 if (remainder
% 100 >= 50)
21110 if (quotient
== 10)
21118 if (remainder
>= 500)
21120 if (quotient
< 999)
21131 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
21132 if (tenths
== -1 && quotient
<= 99)
21139 p
= psuffix
= buf
+ max (width
, length
);
21141 /* Print EXPONENT. */
21142 *psuffix
++ = power_letter
[exponent
];
21145 /* Print TENTHS. */
21148 *--p
= '0' + tenths
;
21152 /* Print QUOTIENT. */
21155 int digit
= quotient
% 10;
21156 *--p
= '0' + digit
;
21158 while ((quotient
/= 10) != 0);
21160 /* Print leading spaces. */
21165 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
21166 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
21167 type of CODING_SYSTEM. Return updated pointer into BUF. */
21169 static unsigned char invalid_eol_type
[] = "(*invalid*)";
21172 decode_mode_spec_coding (Lisp_Object coding_system
, register char *buf
, int eol_flag
)
21175 bool multibyte
= !NILP (BVAR (current_buffer
, enable_multibyte_characters
));
21176 const unsigned char *eol_str
;
21178 /* The EOL conversion we are using. */
21179 Lisp_Object eoltype
;
21181 val
= CODING_SYSTEM_SPEC (coding_system
);
21184 if (!VECTORP (val
)) /* Not yet decided. */
21186 *buf
++ = multibyte
? '-' : ' ';
21188 eoltype
= eol_mnemonic_undecided
;
21189 /* Don't mention EOL conversion if it isn't decided. */
21194 Lisp_Object eolvalue
;
21196 attrs
= AREF (val
, 0);
21197 eolvalue
= AREF (val
, 2);
21200 ? XFASTINT (CODING_ATTR_MNEMONIC (attrs
))
21205 /* The EOL conversion that is normal on this system. */
21207 if (NILP (eolvalue
)) /* Not yet decided. */
21208 eoltype
= eol_mnemonic_undecided
;
21209 else if (VECTORP (eolvalue
)) /* Not yet decided. */
21210 eoltype
= eol_mnemonic_undecided
;
21211 else /* eolvalue is Qunix, Qdos, or Qmac. */
21212 eoltype
= (EQ (eolvalue
, Qunix
)
21213 ? eol_mnemonic_unix
21214 : (EQ (eolvalue
, Qdos
) == 1
21215 ? eol_mnemonic_dos
: eol_mnemonic_mac
));
21221 /* Mention the EOL conversion if it is not the usual one. */
21222 if (STRINGP (eoltype
))
21224 eol_str
= SDATA (eoltype
);
21225 eol_str_len
= SBYTES (eoltype
);
21227 else if (CHARACTERP (eoltype
))
21229 unsigned char *tmp
= alloca (MAX_MULTIBYTE_LENGTH
);
21230 int c
= XFASTINT (eoltype
);
21231 eol_str_len
= CHAR_STRING (c
, tmp
);
21236 eol_str
= invalid_eol_type
;
21237 eol_str_len
= sizeof (invalid_eol_type
) - 1;
21239 memcpy (buf
, eol_str
, eol_str_len
);
21240 buf
+= eol_str_len
;
21246 /* Return a string for the output of a mode line %-spec for window W,
21247 generated by character C. FIELD_WIDTH > 0 means pad the string
21248 returned with spaces to that value. Return a Lisp string in
21249 *STRING if the resulting string is taken from that Lisp string.
21251 Note we operate on the current buffer for most purposes. */
21253 static char lots_of_dashes
[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
21255 static const char *
21256 decode_mode_spec (struct window
*w
, register int c
, int field_width
,
21257 Lisp_Object
*string
)
21260 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
21261 char *decode_mode_spec_buf
= f
->decode_mode_spec_buffer
;
21262 /* We are going to use f->decode_mode_spec_buffer as the buffer to
21263 produce strings from numerical values, so limit preposterously
21264 large values of FIELD_WIDTH to avoid overrunning the buffer's
21265 end. The size of the buffer is enough for FRAME_MESSAGE_BUF_SIZE
21266 bytes plus the terminating null. */
21267 int width
= min (field_width
, FRAME_MESSAGE_BUF_SIZE (f
));
21268 struct buffer
*b
= current_buffer
;
21276 if (!NILP (BVAR (b
, read_only
)))
21278 if (BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
))
21283 /* This differs from %* only for a modified read-only buffer. */
21284 if (BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
))
21286 if (!NILP (BVAR (b
, read_only
)))
21291 /* This differs from %* in ignoring read-only-ness. */
21292 if (BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
))
21304 if (command_loop_level
> 5)
21306 p
= decode_mode_spec_buf
;
21307 for (i
= 0; i
< command_loop_level
; i
++)
21310 return decode_mode_spec_buf
;
21318 if (command_loop_level
> 5)
21320 p
= decode_mode_spec_buf
;
21321 for (i
= 0; i
< command_loop_level
; i
++)
21324 return decode_mode_spec_buf
;
21331 /* Let lots_of_dashes be a string of infinite length. */
21332 if (mode_line_target
== MODE_LINE_NOPROP
21333 || mode_line_target
== MODE_LINE_STRING
)
21335 if (field_width
<= 0
21336 || field_width
> sizeof (lots_of_dashes
))
21338 for (i
= 0; i
< FRAME_MESSAGE_BUF_SIZE (f
) - 1; ++i
)
21339 decode_mode_spec_buf
[i
] = '-';
21340 decode_mode_spec_buf
[i
] = '\0';
21341 return decode_mode_spec_buf
;
21344 return lots_of_dashes
;
21348 obj
= BVAR (b
, name
);
21352 /* %c and %l are ignored in `frame-title-format'.
21353 (In redisplay_internal, the frame title is drawn _before_ the
21354 windows are updated, so the stuff which depends on actual
21355 window contents (such as %l) may fail to render properly, or
21356 even crash emacs.) */
21357 if (mode_line_target
== MODE_LINE_TITLE
)
21361 ptrdiff_t col
= current_column ();
21362 w
->column_number_displayed
= col
;
21363 pint2str (decode_mode_spec_buf
, width
, col
);
21364 return decode_mode_spec_buf
;
21368 #ifndef SYSTEM_MALLOC
21370 if (NILP (Vmemory_full
))
21373 return "!MEM FULL! ";
21380 /* %F displays the frame name. */
21381 if (!NILP (f
->title
))
21382 return SSDATA (f
->title
);
21383 if (f
->explicit_name
|| ! FRAME_WINDOW_P (f
))
21384 return SSDATA (f
->name
);
21388 obj
= BVAR (b
, filename
);
21393 ptrdiff_t size
= ZV
- BEGV
;
21394 pint2str (decode_mode_spec_buf
, width
, size
);
21395 return decode_mode_spec_buf
;
21400 ptrdiff_t size
= ZV
- BEGV
;
21401 pint2hrstr (decode_mode_spec_buf
, width
, size
);
21402 return decode_mode_spec_buf
;
21407 ptrdiff_t startpos
, startpos_byte
, line
, linepos
, linepos_byte
;
21408 ptrdiff_t topline
, nlines
, height
;
21411 /* %c and %l are ignored in `frame-title-format'. */
21412 if (mode_line_target
== MODE_LINE_TITLE
)
21415 startpos
= marker_position (w
->start
);
21416 startpos_byte
= marker_byte_position (w
->start
);
21417 height
= WINDOW_TOTAL_LINES (w
);
21419 /* If we decided that this buffer isn't suitable for line numbers,
21420 don't forget that too fast. */
21421 if (w
->base_line_pos
== -1)
21424 /* If the buffer is very big, don't waste time. */
21425 if (INTEGERP (Vline_number_display_limit
)
21426 && BUF_ZV (b
) - BUF_BEGV (b
) > XINT (Vline_number_display_limit
))
21428 w
->base_line_pos
= 0;
21429 w
->base_line_number
= 0;
21433 if (w
->base_line_number
> 0
21434 && w
->base_line_pos
> 0
21435 && w
->base_line_pos
<= startpos
)
21437 line
= w
->base_line_number
;
21438 linepos
= w
->base_line_pos
;
21439 linepos_byte
= buf_charpos_to_bytepos (b
, linepos
);
21444 linepos
= BUF_BEGV (b
);
21445 linepos_byte
= BUF_BEGV_BYTE (b
);
21448 /* Count lines from base line to window start position. */
21449 nlines
= display_count_lines (linepos_byte
,
21453 topline
= nlines
+ line
;
21455 /* Determine a new base line, if the old one is too close
21456 or too far away, or if we did not have one.
21457 "Too close" means it's plausible a scroll-down would
21458 go back past it. */
21459 if (startpos
== BUF_BEGV (b
))
21461 w
->base_line_number
= topline
;
21462 w
->base_line_pos
= BUF_BEGV (b
);
21464 else if (nlines
< height
+ 25 || nlines
> height
* 3 + 50
21465 || linepos
== BUF_BEGV (b
))
21467 ptrdiff_t limit
= BUF_BEGV (b
);
21468 ptrdiff_t limit_byte
= BUF_BEGV_BYTE (b
);
21469 ptrdiff_t position
;
21470 ptrdiff_t distance
=
21471 (height
* 2 + 30) * line_number_display_limit_width
;
21473 if (startpos
- distance
> limit
)
21475 limit
= startpos
- distance
;
21476 limit_byte
= CHAR_TO_BYTE (limit
);
21479 nlines
= display_count_lines (startpos_byte
,
21481 - (height
* 2 + 30),
21483 /* If we couldn't find the lines we wanted within
21484 line_number_display_limit_width chars per line,
21485 give up on line numbers for this window. */
21486 if (position
== limit_byte
&& limit
== startpos
- distance
)
21488 w
->base_line_pos
= -1;
21489 w
->base_line_number
= 0;
21493 w
->base_line_number
= topline
- nlines
;
21494 w
->base_line_pos
= BYTE_TO_CHAR (position
);
21497 /* Now count lines from the start pos to point. */
21498 nlines
= display_count_lines (startpos_byte
,
21499 PT_BYTE
, PT
, &junk
);
21501 /* Record that we did display the line number. */
21502 line_number_displayed
= 1;
21504 /* Make the string to show. */
21505 pint2str (decode_mode_spec_buf
, width
, topline
+ nlines
);
21506 return decode_mode_spec_buf
;
21509 char* p
= decode_mode_spec_buf
;
21510 int pad
= width
- 2;
21516 return decode_mode_spec_buf
;
21522 obj
= BVAR (b
, mode_name
);
21526 if (BUF_BEGV (b
) > BUF_BEG (b
) || BUF_ZV (b
) < BUF_Z (b
))
21532 ptrdiff_t pos
= marker_position (w
->start
);
21533 ptrdiff_t total
= BUF_ZV (b
) - BUF_BEGV (b
);
21535 if (XFASTINT (w
->window_end_pos
) <= BUF_Z (b
) - BUF_ZV (b
))
21537 if (pos
<= BUF_BEGV (b
))
21542 else if (pos
<= BUF_BEGV (b
))
21546 if (total
> 1000000)
21547 /* Do it differently for a large value, to avoid overflow. */
21548 total
= ((pos
- BUF_BEGV (b
)) + (total
/ 100) - 1) / (total
/ 100);
21550 total
= ((pos
- BUF_BEGV (b
)) * 100 + total
- 1) / total
;
21551 /* We can't normally display a 3-digit number,
21552 so get us a 2-digit number that is close. */
21555 sprintf (decode_mode_spec_buf
, "%2"pD
"d%%", total
);
21556 return decode_mode_spec_buf
;
21560 /* Display percentage of size above the bottom of the screen. */
21563 ptrdiff_t toppos
= marker_position (w
->start
);
21564 ptrdiff_t botpos
= BUF_Z (b
) - XFASTINT (w
->window_end_pos
);
21565 ptrdiff_t total
= BUF_ZV (b
) - BUF_BEGV (b
);
21567 if (botpos
>= BUF_ZV (b
))
21569 if (toppos
<= BUF_BEGV (b
))
21576 if (total
> 1000000)
21577 /* Do it differently for a large value, to avoid overflow. */
21578 total
= ((botpos
- BUF_BEGV (b
)) + (total
/ 100) - 1) / (total
/ 100);
21580 total
= ((botpos
- BUF_BEGV (b
)) * 100 + total
- 1) / total
;
21581 /* We can't normally display a 3-digit number,
21582 so get us a 2-digit number that is close. */
21585 if (toppos
<= BUF_BEGV (b
))
21586 sprintf (decode_mode_spec_buf
, "Top%2"pD
"d%%", total
);
21588 sprintf (decode_mode_spec_buf
, "%2"pD
"d%%", total
);
21589 return decode_mode_spec_buf
;
21594 /* status of process */
21595 obj
= Fget_buffer_process (Fcurrent_buffer ());
21597 return "no process";
21599 obj
= Fsymbol_name (Fprocess_status (obj
));
21605 ptrdiff_t count
= inhibit_garbage_collection ();
21606 Lisp_Object val
= call1 (intern ("file-remote-p"),
21607 BVAR (current_buffer
, directory
));
21608 unbind_to (count
, Qnil
);
21617 /* coding-system (not including end-of-line format) */
21619 /* coding-system (including end-of-line type) */
21621 int eol_flag
= (c
== 'Z');
21622 char *p
= decode_mode_spec_buf
;
21624 if (! FRAME_WINDOW_P (f
))
21626 /* No need to mention EOL here--the terminal never needs
21627 to do EOL conversion. */
21628 p
= decode_mode_spec_coding (CODING_ID_NAME
21629 (FRAME_KEYBOARD_CODING (f
)->id
),
21631 p
= decode_mode_spec_coding (CODING_ID_NAME
21632 (FRAME_TERMINAL_CODING (f
)->id
),
21635 p
= decode_mode_spec_coding (BVAR (b
, buffer_file_coding_system
),
21638 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
21639 #ifdef subprocesses
21640 obj
= Fget_buffer_process (Fcurrent_buffer ());
21641 if (PROCESSP (obj
))
21643 p
= decode_mode_spec_coding
21644 (XPROCESS (obj
)->decode_coding_system
, p
, eol_flag
);
21645 p
= decode_mode_spec_coding
21646 (XPROCESS (obj
)->encode_coding_system
, p
, eol_flag
);
21648 #endif /* subprocesses */
21651 return decode_mode_spec_buf
;
21658 return SSDATA (obj
);
21665 /* Count up to COUNT lines starting from START_BYTE. COUNT negative
21666 means count lines back from START_BYTE. But don't go beyond
21667 LIMIT_BYTE. Return the number of lines thus found (always
21670 Set *BYTE_POS_PTR to the byte position where we stopped. This is
21671 either the position COUNT lines after/before START_BYTE, if we
21672 found COUNT lines, or LIMIT_BYTE if we hit the limit before finding
21676 display_count_lines (ptrdiff_t start_byte
,
21677 ptrdiff_t limit_byte
, ptrdiff_t count
,
21678 ptrdiff_t *byte_pos_ptr
)
21680 register unsigned char *cursor
;
21681 unsigned char *base
;
21683 register ptrdiff_t ceiling
;
21684 register unsigned char *ceiling_addr
;
21685 ptrdiff_t orig_count
= count
;
21687 /* If we are not in selective display mode,
21688 check only for newlines. */
21689 int selective_display
= (!NILP (BVAR (current_buffer
, selective_display
))
21690 && !INTEGERP (BVAR (current_buffer
, selective_display
)));
21694 while (start_byte
< limit_byte
)
21696 ceiling
= BUFFER_CEILING_OF (start_byte
);
21697 ceiling
= min (limit_byte
- 1, ceiling
);
21698 ceiling_addr
= BYTE_POS_ADDR (ceiling
) + 1;
21699 base
= (cursor
= BYTE_POS_ADDR (start_byte
));
21703 if (selective_display
)
21705 while (*cursor
!= '\n' && *cursor
!= 015
21706 && ++cursor
!= ceiling_addr
)
21708 if (cursor
== ceiling_addr
)
21713 cursor
= memchr (cursor
, '\n', ceiling_addr
- cursor
);
21722 start_byte
+= cursor
- base
;
21723 *byte_pos_ptr
= start_byte
;
21727 while (cursor
< ceiling_addr
);
21729 start_byte
+= ceiling_addr
- base
;
21734 while (start_byte
> limit_byte
)
21736 ceiling
= BUFFER_FLOOR_OF (start_byte
- 1);
21737 ceiling
= max (limit_byte
, ceiling
);
21738 ceiling_addr
= BYTE_POS_ADDR (ceiling
);
21739 base
= (cursor
= BYTE_POS_ADDR (start_byte
- 1) + 1);
21742 if (selective_display
)
21744 while (--cursor
>= ceiling_addr
21745 && *cursor
!= '\n' && *cursor
!= 015)
21747 if (cursor
< ceiling_addr
)
21752 cursor
= memrchr (ceiling_addr
, '\n', cursor
- ceiling_addr
);
21759 start_byte
+= cursor
- base
+ 1;
21760 *byte_pos_ptr
= start_byte
;
21761 /* When scanning backwards, we should
21762 not count the newline posterior to which we stop. */
21763 return - orig_count
- 1;
21766 start_byte
+= ceiling_addr
- base
;
21770 *byte_pos_ptr
= limit_byte
;
21773 return - orig_count
+ count
;
21774 return orig_count
- count
;
21780 /***********************************************************************
21782 ***********************************************************************/
21784 /* Display a NUL-terminated string, starting with index START.
21786 If STRING is non-null, display that C string. Otherwise, the Lisp
21787 string LISP_STRING is displayed. There's a case that STRING is
21788 non-null and LISP_STRING is not nil. It means STRING is a string
21789 data of LISP_STRING. In that case, we display LISP_STRING while
21790 ignoring its text properties.
21792 If FACE_STRING is not nil, FACE_STRING_POS is a position in
21793 FACE_STRING. Display STRING or LISP_STRING with the face at
21794 FACE_STRING_POS in FACE_STRING:
21796 Display the string in the environment given by IT, but use the
21797 standard display table, temporarily.
21799 FIELD_WIDTH is the minimum number of output glyphs to produce.
21800 If STRING has fewer characters than FIELD_WIDTH, pad to the right
21801 with spaces. If STRING has more characters, more than FIELD_WIDTH
21802 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
21804 PRECISION is the maximum number of characters to output from
21805 STRING. PRECISION < 0 means don't truncate the string.
21807 This is roughly equivalent to printf format specifiers:
21809 FIELD_WIDTH PRECISION PRINTF
21810 ----------------------------------------
21816 MULTIBYTE zero means do not display multibyte chars, > 0 means do
21817 display them, and < 0 means obey the current buffer's value of
21818 enable_multibyte_characters.
21820 Value is the number of columns displayed. */
21823 display_string (const char *string
, Lisp_Object lisp_string
, Lisp_Object face_string
,
21824 ptrdiff_t face_string_pos
, ptrdiff_t start
, struct it
*it
,
21825 int field_width
, int precision
, int max_x
, int multibyte
)
21827 int hpos_at_start
= it
->hpos
;
21828 int saved_face_id
= it
->face_id
;
21829 struct glyph_row
*row
= it
->glyph_row
;
21830 ptrdiff_t it_charpos
;
21832 /* Initialize the iterator IT for iteration over STRING beginning
21833 with index START. */
21834 reseat_to_string (it
, NILP (lisp_string
) ? string
: NULL
, lisp_string
, start
,
21835 precision
, field_width
, multibyte
);
21836 if (string
&& STRINGP (lisp_string
))
21837 /* LISP_STRING is the one returned by decode_mode_spec. We should
21838 ignore its text properties. */
21839 it
->stop_charpos
= it
->end_charpos
;
21841 /* If displaying STRING, set up the face of the iterator from
21842 FACE_STRING, if that's given. */
21843 if (STRINGP (face_string
))
21849 = face_at_string_position (it
->w
, face_string
, face_string_pos
,
21850 0, it
->region_beg_charpos
,
21851 it
->region_end_charpos
,
21852 &endptr
, it
->base_face_id
, 0);
21853 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
21854 it
->face_box_p
= face
->box
!= FACE_NO_BOX
;
21857 /* Set max_x to the maximum allowed X position. Don't let it go
21858 beyond the right edge of the window. */
21860 max_x
= it
->last_visible_x
;
21862 max_x
= min (max_x
, it
->last_visible_x
);
21864 /* Skip over display elements that are not visible. because IT->w is
21866 if (it
->current_x
< it
->first_visible_x
)
21867 move_it_in_display_line_to (it
, 100000, it
->first_visible_x
,
21868 MOVE_TO_POS
| MOVE_TO_X
);
21870 row
->ascent
= it
->max_ascent
;
21871 row
->height
= it
->max_ascent
+ it
->max_descent
;
21872 row
->phys_ascent
= it
->max_phys_ascent
;
21873 row
->phys_height
= it
->max_phys_ascent
+ it
->max_phys_descent
;
21874 row
->extra_line_spacing
= it
->max_extra_line_spacing
;
21876 if (STRINGP (it
->string
))
21877 it_charpos
= IT_STRING_CHARPOS (*it
);
21879 it_charpos
= IT_CHARPOS (*it
);
21881 /* This condition is for the case that we are called with current_x
21882 past last_visible_x. */
21883 while (it
->current_x
< max_x
)
21885 int x_before
, x
, n_glyphs_before
, i
, nglyphs
;
21887 /* Get the next display element. */
21888 if (!get_next_display_element (it
))
21891 /* Produce glyphs. */
21892 x_before
= it
->current_x
;
21893 n_glyphs_before
= row
->used
[TEXT_AREA
];
21894 PRODUCE_GLYPHS (it
);
21896 nglyphs
= row
->used
[TEXT_AREA
] - n_glyphs_before
;
21899 while (i
< nglyphs
)
21901 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
] + n_glyphs_before
+ i
;
21903 if (it
->line_wrap
!= TRUNCATE
21904 && x
+ glyph
->pixel_width
> max_x
)
21906 /* End of continued line or max_x reached. */
21907 if (CHAR_GLYPH_PADDING_P (*glyph
))
21909 /* A wide character is unbreakable. */
21910 if (row
->reversed_p
)
21911 unproduce_glyphs (it
, row
->used
[TEXT_AREA
]
21912 - n_glyphs_before
);
21913 row
->used
[TEXT_AREA
] = n_glyphs_before
;
21914 it
->current_x
= x_before
;
21918 if (row
->reversed_p
)
21919 unproduce_glyphs (it
, row
->used
[TEXT_AREA
]
21920 - (n_glyphs_before
+ i
));
21921 row
->used
[TEXT_AREA
] = n_glyphs_before
+ i
;
21926 else if (x
+ glyph
->pixel_width
>= it
->first_visible_x
)
21928 /* Glyph is at least partially visible. */
21930 if (x
< it
->first_visible_x
)
21931 row
->x
= x
- it
->first_visible_x
;
21935 /* Glyph is off the left margin of the display area.
21936 Should not happen. */
21940 row
->ascent
= max (row
->ascent
, it
->max_ascent
);
21941 row
->height
= max (row
->height
, it
->max_ascent
+ it
->max_descent
);
21942 row
->phys_ascent
= max (row
->phys_ascent
, it
->max_phys_ascent
);
21943 row
->phys_height
= max (row
->phys_height
,
21944 it
->max_phys_ascent
+ it
->max_phys_descent
);
21945 row
->extra_line_spacing
= max (row
->extra_line_spacing
,
21946 it
->max_extra_line_spacing
);
21947 x
+= glyph
->pixel_width
;
21951 /* Stop if max_x reached. */
21955 /* Stop at line ends. */
21956 if (ITERATOR_AT_END_OF_LINE_P (it
))
21958 it
->continuation_lines_width
= 0;
21962 set_iterator_to_next (it
, 1);
21963 if (STRINGP (it
->string
))
21964 it_charpos
= IT_STRING_CHARPOS (*it
);
21966 it_charpos
= IT_CHARPOS (*it
);
21968 /* Stop if truncating at the right edge. */
21969 if (it
->line_wrap
== TRUNCATE
21970 && it
->current_x
>= it
->last_visible_x
)
21972 /* Add truncation mark, but don't do it if the line is
21973 truncated at a padding space. */
21974 if (it_charpos
< it
->string_nchars
)
21976 if (!FRAME_WINDOW_P (it
->f
))
21980 if (it
->current_x
> it
->last_visible_x
)
21982 if (!row
->reversed_p
)
21984 for (ii
= row
->used
[TEXT_AREA
] - 1; ii
> 0; --ii
)
21985 if (!CHAR_GLYPH_PADDING_P (row
->glyphs
[TEXT_AREA
][ii
]))
21990 for (ii
= 0; ii
< row
->used
[TEXT_AREA
]; ii
++)
21991 if (!CHAR_GLYPH_PADDING_P (row
->glyphs
[TEXT_AREA
][ii
]))
21993 unproduce_glyphs (it
, ii
+ 1);
21994 ii
= row
->used
[TEXT_AREA
] - (ii
+ 1);
21996 for (n
= row
->used
[TEXT_AREA
]; ii
< n
; ++ii
)
21998 row
->used
[TEXT_AREA
] = ii
;
21999 produce_special_glyphs (it
, IT_TRUNCATION
);
22002 produce_special_glyphs (it
, IT_TRUNCATION
);
22004 row
->truncated_on_right_p
= 1;
22010 /* Maybe insert a truncation at the left. */
22011 if (it
->first_visible_x
22014 if (!FRAME_WINDOW_P (it
->f
)
22015 || (row
->reversed_p
22016 ? WINDOW_RIGHT_FRINGE_WIDTH (it
->w
)
22017 : WINDOW_LEFT_FRINGE_WIDTH (it
->w
)) == 0)
22018 insert_left_trunc_glyphs (it
);
22019 row
->truncated_on_left_p
= 1;
22022 it
->face_id
= saved_face_id
;
22024 /* Value is number of columns displayed. */
22025 return it
->hpos
- hpos_at_start
;
22030 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
22031 appears as an element of LIST or as the car of an element of LIST.
22032 If PROPVAL is a list, compare each element against LIST in that
22033 way, and return 1/2 if any element of PROPVAL is found in LIST.
22034 Otherwise return 0. This function cannot quit.
22035 The return value is 2 if the text is invisible but with an ellipsis
22036 and 1 if it's invisible and without an ellipsis. */
22039 invisible_p (register Lisp_Object propval
, Lisp_Object list
)
22041 register Lisp_Object tail
, proptail
;
22043 for (tail
= list
; CONSP (tail
); tail
= XCDR (tail
))
22045 register Lisp_Object tem
;
22047 if (EQ (propval
, tem
))
22049 if (CONSP (tem
) && EQ (propval
, XCAR (tem
)))
22050 return NILP (XCDR (tem
)) ? 1 : 2;
22053 if (CONSP (propval
))
22055 for (proptail
= propval
; CONSP (proptail
); proptail
= XCDR (proptail
))
22057 Lisp_Object propelt
;
22058 propelt
= XCAR (proptail
);
22059 for (tail
= list
; CONSP (tail
); tail
= XCDR (tail
))
22061 register Lisp_Object tem
;
22063 if (EQ (propelt
, tem
))
22065 if (CONSP (tem
) && EQ (propelt
, XCAR (tem
)))
22066 return NILP (XCDR (tem
)) ? 1 : 2;
22074 DEFUN ("invisible-p", Finvisible_p
, Sinvisible_p
, 1, 1, 0,
22075 doc
: /* Non-nil if the property makes the text invisible.
22076 POS-OR-PROP can be a marker or number, in which case it is taken to be
22077 a position in the current buffer and the value of the `invisible' property
22078 is checked; or it can be some other value, which is then presumed to be the
22079 value of the `invisible' property of the text of interest.
22080 The non-nil value returned can be t for truly invisible text or something
22081 else if the text is replaced by an ellipsis. */)
22082 (Lisp_Object pos_or_prop
)
22085 = (NATNUMP (pos_or_prop
) || MARKERP (pos_or_prop
)
22086 ? Fget_char_property (pos_or_prop
, Qinvisible
, Qnil
)
22088 int invis
= TEXT_PROP_MEANS_INVISIBLE (prop
);
22089 return (invis
== 0 ? Qnil
22091 : make_number (invis
));
22094 /* Calculate a width or height in pixels from a specification using
22095 the following elements:
22098 NUM - a (fractional) multiple of the default font width/height
22099 (NUM) - specifies exactly NUM pixels
22100 UNIT - a fixed number of pixels, see below.
22101 ELEMENT - size of a display element in pixels, see below.
22102 (NUM . SPEC) - equals NUM * SPEC
22103 (+ SPEC SPEC ...) - add pixel values
22104 (- SPEC SPEC ...) - subtract pixel values
22105 (- SPEC) - negate pixel value
22108 INT or FLOAT - a number constant
22109 SYMBOL - use symbol's (buffer local) variable binding.
22112 in - pixels per inch *)
22113 mm - pixels per 1/1000 meter *)
22114 cm - pixels per 1/100 meter *)
22115 width - width of current font in pixels.
22116 height - height of current font in pixels.
22118 *) using the ratio(s) defined in display-pixels-per-inch.
22122 left-fringe - left fringe width in pixels
22123 right-fringe - right fringe width in pixels
22125 left-margin - left margin width in pixels
22126 right-margin - right margin width in pixels
22128 scroll-bar - scroll-bar area width in pixels
22132 Pixels corresponding to 5 inches:
22135 Total width of non-text areas on left side of window (if scroll-bar is on left):
22136 '(space :width (+ left-fringe left-margin scroll-bar))
22138 Align to first text column (in header line):
22139 '(space :align-to 0)
22141 Align to middle of text area minus half the width of variable `my-image'
22142 containing a loaded image:
22143 '(space :align-to (0.5 . (- text my-image)))
22145 Width of left margin minus width of 1 character in the default font:
22146 '(space :width (- left-margin 1))
22148 Width of left margin minus width of 2 characters in the current font:
22149 '(space :width (- left-margin (2 . width)))
22151 Center 1 character over left-margin (in header line):
22152 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
22154 Different ways to express width of left fringe plus left margin minus one pixel:
22155 '(space :width (- (+ left-fringe left-margin) (1)))
22156 '(space :width (+ left-fringe left-margin (- (1))))
22157 '(space :width (+ left-fringe left-margin (-1)))
22162 calc_pixel_width_or_height (double *res
, struct it
*it
, Lisp_Object prop
,
22163 struct font
*font
, int width_p
, int *align_to
)
22167 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
22168 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
22171 return OK_PIXELS (0);
22173 eassert (FRAME_LIVE_P (it
->f
));
22175 if (SYMBOLP (prop
))
22177 if (SCHARS (SYMBOL_NAME (prop
)) == 2)
22179 char *unit
= SSDATA (SYMBOL_NAME (prop
));
22181 if (unit
[0] == 'i' && unit
[1] == 'n')
22183 else if (unit
[0] == 'm' && unit
[1] == 'm')
22185 else if (unit
[0] == 'c' && unit
[1] == 'm')
22191 double ppi
= (width_p
? FRAME_RES_X (it
->f
)
22192 : FRAME_RES_Y (it
->f
));
22195 return OK_PIXELS (ppi
/ pixels
);
22200 #ifdef HAVE_WINDOW_SYSTEM
22201 if (EQ (prop
, Qheight
))
22202 return OK_PIXELS (font
? FONT_HEIGHT (font
) : FRAME_LINE_HEIGHT (it
->f
));
22203 if (EQ (prop
, Qwidth
))
22204 return OK_PIXELS (font
? FONT_WIDTH (font
) : FRAME_COLUMN_WIDTH (it
->f
));
22206 if (EQ (prop
, Qheight
) || EQ (prop
, Qwidth
))
22207 return OK_PIXELS (1);
22210 if (EQ (prop
, Qtext
))
22211 return OK_PIXELS (width_p
22212 ? window_box_width (it
->w
, TEXT_AREA
)
22213 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it
->w
));
22215 if (align_to
&& *align_to
< 0)
22218 if (EQ (prop
, Qleft
))
22219 return OK_ALIGN_TO (window_box_left_offset (it
->w
, TEXT_AREA
));
22220 if (EQ (prop
, Qright
))
22221 return OK_ALIGN_TO (window_box_right_offset (it
->w
, TEXT_AREA
));
22222 if (EQ (prop
, Qcenter
))
22223 return OK_ALIGN_TO (window_box_left_offset (it
->w
, TEXT_AREA
)
22224 + window_box_width (it
->w
, TEXT_AREA
) / 2);
22225 if (EQ (prop
, Qleft_fringe
))
22226 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it
->w
)
22227 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it
->w
)
22228 : window_box_right_offset (it
->w
, LEFT_MARGIN_AREA
));
22229 if (EQ (prop
, Qright_fringe
))
22230 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it
->w
)
22231 ? window_box_right_offset (it
->w
, RIGHT_MARGIN_AREA
)
22232 : window_box_right_offset (it
->w
, TEXT_AREA
));
22233 if (EQ (prop
, Qleft_margin
))
22234 return OK_ALIGN_TO (window_box_left_offset (it
->w
, LEFT_MARGIN_AREA
));
22235 if (EQ (prop
, Qright_margin
))
22236 return OK_ALIGN_TO (window_box_left_offset (it
->w
, RIGHT_MARGIN_AREA
));
22237 if (EQ (prop
, Qscroll_bar
))
22238 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it
->w
)
22240 : (window_box_right_offset (it
->w
, RIGHT_MARGIN_AREA
)
22241 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it
->w
)
22242 ? WINDOW_RIGHT_FRINGE_WIDTH (it
->w
)
22247 if (EQ (prop
, Qleft_fringe
))
22248 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it
->w
));
22249 if (EQ (prop
, Qright_fringe
))
22250 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it
->w
));
22251 if (EQ (prop
, Qleft_margin
))
22252 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it
->w
));
22253 if (EQ (prop
, Qright_margin
))
22254 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it
->w
));
22255 if (EQ (prop
, Qscroll_bar
))
22256 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it
->w
));
22259 prop
= buffer_local_value_1 (prop
, it
->w
->contents
);
22260 if (EQ (prop
, Qunbound
))
22264 if (INTEGERP (prop
) || FLOATP (prop
))
22266 int base_unit
= (width_p
22267 ? FRAME_COLUMN_WIDTH (it
->f
)
22268 : FRAME_LINE_HEIGHT (it
->f
));
22269 return OK_PIXELS (XFLOATINT (prop
) * base_unit
);
22274 Lisp_Object car
= XCAR (prop
);
22275 Lisp_Object cdr
= XCDR (prop
);
22279 #ifdef HAVE_WINDOW_SYSTEM
22280 if (FRAME_WINDOW_P (it
->f
)
22281 && valid_image_p (prop
))
22283 ptrdiff_t id
= lookup_image (it
->f
, prop
);
22284 struct image
*img
= IMAGE_FROM_ID (it
->f
, id
);
22286 return OK_PIXELS (width_p
? img
->width
: img
->height
);
22289 if (EQ (car
, Qplus
) || EQ (car
, Qminus
))
22295 while (CONSP (cdr
))
22297 if (!calc_pixel_width_or_height (&px
, it
, XCAR (cdr
),
22298 font
, width_p
, align_to
))
22301 pixels
= (EQ (car
, Qplus
) ? px
: -px
), first
= 0;
22306 if (EQ (car
, Qminus
))
22308 return OK_PIXELS (pixels
);
22311 car
= buffer_local_value_1 (car
, it
->w
->contents
);
22312 if (EQ (car
, Qunbound
))
22316 if (INTEGERP (car
) || FLOATP (car
))
22319 pixels
= XFLOATINT (car
);
22321 return OK_PIXELS (pixels
);
22322 if (calc_pixel_width_or_height (&fact
, it
, cdr
,
22323 font
, width_p
, align_to
))
22324 return OK_PIXELS (pixels
* fact
);
22335 /***********************************************************************
22337 ***********************************************************************/
22339 #ifdef HAVE_WINDOW_SYSTEM
22344 dump_glyph_string (struct glyph_string
*s
)
22346 fprintf (stderr
, "glyph string\n");
22347 fprintf (stderr
, " x, y, w, h = %d, %d, %d, %d\n",
22348 s
->x
, s
->y
, s
->width
, s
->height
);
22349 fprintf (stderr
, " ybase = %d\n", s
->ybase
);
22350 fprintf (stderr
, " hl = %d\n", s
->hl
);
22351 fprintf (stderr
, " left overhang = %d, right = %d\n",
22352 s
->left_overhang
, s
->right_overhang
);
22353 fprintf (stderr
, " nchars = %d\n", s
->nchars
);
22354 fprintf (stderr
, " extends to end of line = %d\n",
22355 s
->extends_to_end_of_line_p
);
22356 fprintf (stderr
, " font height = %d\n", FONT_HEIGHT (s
->font
));
22357 fprintf (stderr
, " bg width = %d\n", s
->background_width
);
22360 #endif /* GLYPH_DEBUG */
22362 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
22363 of XChar2b structures for S; it can't be allocated in
22364 init_glyph_string because it must be allocated via `alloca'. W
22365 is the window on which S is drawn. ROW and AREA are the glyph row
22366 and area within the row from which S is constructed. START is the
22367 index of the first glyph structure covered by S. HL is a
22368 face-override for drawing S. */
22371 #define OPTIONAL_HDC(hdc) HDC hdc,
22372 #define DECLARE_HDC(hdc) HDC hdc;
22373 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
22374 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
22377 #ifndef OPTIONAL_HDC
22378 #define OPTIONAL_HDC(hdc)
22379 #define DECLARE_HDC(hdc)
22380 #define ALLOCATE_HDC(hdc, f)
22381 #define RELEASE_HDC(hdc, f)
22385 init_glyph_string (struct glyph_string
*s
,
22387 XChar2b
*char2b
, struct window
*w
, struct glyph_row
*row
,
22388 enum glyph_row_area area
, int start
, enum draw_glyphs_face hl
)
22390 memset (s
, 0, sizeof *s
);
22392 s
->f
= XFRAME (w
->frame
);
22396 s
->display
= FRAME_X_DISPLAY (s
->f
);
22397 s
->window
= FRAME_X_WINDOW (s
->f
);
22398 s
->char2b
= char2b
;
22402 s
->first_glyph
= row
->glyphs
[area
] + start
;
22403 s
->height
= row
->height
;
22404 s
->y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
22405 s
->ybase
= s
->y
+ row
->ascent
;
22409 /* Append the list of glyph strings with head H and tail T to the list
22410 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
22413 append_glyph_string_lists (struct glyph_string
**head
, struct glyph_string
**tail
,
22414 struct glyph_string
*h
, struct glyph_string
*t
)
22428 /* Prepend the list of glyph strings with head H and tail T to the
22429 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
22433 prepend_glyph_string_lists (struct glyph_string
**head
, struct glyph_string
**tail
,
22434 struct glyph_string
*h
, struct glyph_string
*t
)
22448 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
22449 Set *HEAD and *TAIL to the resulting list. */
22452 append_glyph_string (struct glyph_string
**head
, struct glyph_string
**tail
,
22453 struct glyph_string
*s
)
22455 s
->next
= s
->prev
= NULL
;
22456 append_glyph_string_lists (head
, tail
, s
, s
);
22460 /* Get face and two-byte form of character C in face FACE_ID on frame F.
22461 The encoding of C is returned in *CHAR2B. DISPLAY_P non-zero means
22462 make sure that X resources for the face returned are allocated.
22463 Value is a pointer to a realized face that is ready for display if
22464 DISPLAY_P is non-zero. */
22466 static struct face
*
22467 get_char_face_and_encoding (struct frame
*f
, int c
, int face_id
,
22468 XChar2b
*char2b
, int display_p
)
22470 struct face
*face
= FACE_FROM_ID (f
, face_id
);
22475 code
= face
->font
->driver
->encode_char (face
->font
, c
);
22477 if (code
== FONT_INVALID_CODE
)
22480 STORE_XCHAR2B (char2b
, (code
>> 8), (code
& 0xFF));
22482 /* Make sure X resources of the face are allocated. */
22483 #ifdef HAVE_X_WINDOWS
22487 eassert (face
!= NULL
);
22488 PREPARE_FACE_FOR_DISPLAY (f
, face
);
22495 /* Get face and two-byte form of character glyph GLYPH on frame F.
22496 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
22497 a pointer to a realized face that is ready for display. */
22499 static struct face
*
22500 get_glyph_face_and_encoding (struct frame
*f
, struct glyph
*glyph
,
22501 XChar2b
*char2b
, int *two_byte_p
)
22506 eassert (glyph
->type
== CHAR_GLYPH
);
22507 face
= FACE_FROM_ID (f
, glyph
->face_id
);
22509 /* Make sure X resources of the face are allocated. */
22510 eassert (face
!= NULL
);
22511 PREPARE_FACE_FOR_DISPLAY (f
, face
);
22518 if (CHAR_BYTE8_P (glyph
->u
.ch
))
22519 code
= CHAR_TO_BYTE8 (glyph
->u
.ch
);
22521 code
= face
->font
->driver
->encode_char (face
->font
, glyph
->u
.ch
);
22523 if (code
== FONT_INVALID_CODE
)
22527 STORE_XCHAR2B (char2b
, (code
>> 8), (code
& 0xFF));
22532 /* Get glyph code of character C in FONT in the two-byte form CHAR2B.
22533 Return 1 if FONT has a glyph for C, otherwise return 0. */
22536 get_char_glyph_code (int c
, struct font
*font
, XChar2b
*char2b
)
22540 if (CHAR_BYTE8_P (c
))
22541 code
= CHAR_TO_BYTE8 (c
);
22543 code
= font
->driver
->encode_char (font
, c
);
22545 if (code
== FONT_INVALID_CODE
)
22547 STORE_XCHAR2B (char2b
, (code
>> 8), (code
& 0xFF));
22552 /* Fill glyph string S with composition components specified by S->cmp.
22554 BASE_FACE is the base face of the composition.
22555 S->cmp_from is the index of the first component for S.
22557 OVERLAPS non-zero means S should draw the foreground only, and use
22558 its physical height for clipping. See also draw_glyphs.
22560 Value is the index of a component not in S. */
22563 fill_composite_glyph_string (struct glyph_string
*s
, struct face
*base_face
,
22567 /* For all glyphs of this composition, starting at the offset
22568 S->cmp_from, until we reach the end of the definition or encounter a
22569 glyph that requires the different face, add it to S. */
22574 s
->for_overlaps
= overlaps
;
22577 for (i
= s
->cmp_from
; i
< s
->cmp
->glyph_len
; i
++)
22579 int c
= COMPOSITION_GLYPH (s
->cmp
, i
);
22581 /* TAB in a composition means display glyphs with padding space
22582 on the left or right. */
22585 int face_id
= FACE_FOR_CHAR (s
->f
, base_face
->ascii_face
, c
,
22588 face
= get_char_face_and_encoding (s
->f
, c
, face_id
,
22595 s
->font
= s
->face
->font
;
22597 else if (s
->face
!= face
)
22605 if (s
->face
== NULL
)
22607 s
->face
= base_face
->ascii_face
;
22608 s
->font
= s
->face
->font
;
22611 /* All glyph strings for the same composition has the same width,
22612 i.e. the width set for the first component of the composition. */
22613 s
->width
= s
->first_glyph
->pixel_width
;
22615 /* If the specified font could not be loaded, use the frame's
22616 default font, but record the fact that we couldn't load it in
22617 the glyph string so that we can draw rectangles for the
22618 characters of the glyph string. */
22619 if (s
->font
== NULL
)
22621 s
->font_not_found_p
= 1;
22622 s
->font
= FRAME_FONT (s
->f
);
22625 /* Adjust base line for subscript/superscript text. */
22626 s
->ybase
+= s
->first_glyph
->voffset
;
22628 /* This glyph string must always be drawn with 16-bit functions. */
22635 fill_gstring_glyph_string (struct glyph_string
*s
, int face_id
,
22636 int start
, int end
, int overlaps
)
22638 struct glyph
*glyph
, *last
;
22639 Lisp_Object lgstring
;
22642 s
->for_overlaps
= overlaps
;
22643 glyph
= s
->row
->glyphs
[s
->area
] + start
;
22644 last
= s
->row
->glyphs
[s
->area
] + end
;
22645 s
->cmp_id
= glyph
->u
.cmp
.id
;
22646 s
->cmp_from
= glyph
->slice
.cmp
.from
;
22647 s
->cmp_to
= glyph
->slice
.cmp
.to
+ 1;
22648 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
22649 lgstring
= composition_gstring_from_id (s
->cmp_id
);
22650 s
->font
= XFONT_OBJECT (LGSTRING_FONT (lgstring
));
22652 while (glyph
< last
22653 && glyph
->u
.cmp
.automatic
22654 && glyph
->u
.cmp
.id
== s
->cmp_id
22655 && s
->cmp_to
== glyph
->slice
.cmp
.from
)
22656 s
->cmp_to
= (glyph
++)->slice
.cmp
.to
+ 1;
22658 for (i
= s
->cmp_from
; i
< s
->cmp_to
; i
++)
22660 Lisp_Object lglyph
= LGSTRING_GLYPH (lgstring
, i
);
22661 unsigned code
= LGLYPH_CODE (lglyph
);
22663 STORE_XCHAR2B ((s
->char2b
+ i
), code
>> 8, code
& 0xFF);
22665 s
->width
= composition_gstring_width (lgstring
, s
->cmp_from
, s
->cmp_to
, NULL
);
22666 return glyph
- s
->row
->glyphs
[s
->area
];
22670 /* Fill glyph string S from a sequence glyphs for glyphless characters.
22671 See the comment of fill_glyph_string for arguments.
22672 Value is the index of the first glyph not in S. */
22676 fill_glyphless_glyph_string (struct glyph_string
*s
, int face_id
,
22677 int start
, int end
, int overlaps
)
22679 struct glyph
*glyph
, *last
;
22682 eassert (s
->first_glyph
->type
== GLYPHLESS_GLYPH
);
22683 s
->for_overlaps
= overlaps
;
22684 glyph
= s
->row
->glyphs
[s
->area
] + start
;
22685 last
= s
->row
->glyphs
[s
->area
] + end
;
22686 voffset
= glyph
->voffset
;
22687 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
22688 s
->font
= s
->face
->font
? s
->face
->font
: FRAME_FONT (s
->f
);
22690 s
->width
= glyph
->pixel_width
;
22692 while (glyph
< last
22693 && glyph
->type
== GLYPHLESS_GLYPH
22694 && glyph
->voffset
== voffset
22695 && glyph
->face_id
== face_id
)
22698 s
->width
+= glyph
->pixel_width
;
22701 s
->ybase
+= voffset
;
22702 return glyph
- s
->row
->glyphs
[s
->area
];
22706 /* Fill glyph string S from a sequence of character glyphs.
22708 FACE_ID is the face id of the string. START is the index of the
22709 first glyph to consider, END is the index of the last + 1.
22710 OVERLAPS non-zero means S should draw the foreground only, and use
22711 its physical height for clipping. See also draw_glyphs.
22713 Value is the index of the first glyph not in S. */
22716 fill_glyph_string (struct glyph_string
*s
, int face_id
,
22717 int start
, int end
, int overlaps
)
22719 struct glyph
*glyph
, *last
;
22721 int glyph_not_available_p
;
22723 eassert (s
->f
== XFRAME (s
->w
->frame
));
22724 eassert (s
->nchars
== 0);
22725 eassert (start
>= 0 && end
> start
);
22727 s
->for_overlaps
= overlaps
;
22728 glyph
= s
->row
->glyphs
[s
->area
] + start
;
22729 last
= s
->row
->glyphs
[s
->area
] + end
;
22730 voffset
= glyph
->voffset
;
22731 s
->padding_p
= glyph
->padding_p
;
22732 glyph_not_available_p
= glyph
->glyph_not_available_p
;
22734 while (glyph
< last
22735 && glyph
->type
== CHAR_GLYPH
22736 && glyph
->voffset
== voffset
22737 /* Same face id implies same font, nowadays. */
22738 && glyph
->face_id
== face_id
22739 && glyph
->glyph_not_available_p
== glyph_not_available_p
)
22743 s
->face
= get_glyph_face_and_encoding (s
->f
, glyph
,
22744 s
->char2b
+ s
->nchars
,
22746 s
->two_byte_p
= two_byte_p
;
22748 eassert (s
->nchars
<= end
- start
);
22749 s
->width
+= glyph
->pixel_width
;
22750 if (glyph
++->padding_p
!= s
->padding_p
)
22754 s
->font
= s
->face
->font
;
22756 /* If the specified font could not be loaded, use the frame's font,
22757 but record the fact that we couldn't load it in
22758 S->font_not_found_p so that we can draw rectangles for the
22759 characters of the glyph string. */
22760 if (s
->font
== NULL
|| glyph_not_available_p
)
22762 s
->font_not_found_p
= 1;
22763 s
->font
= FRAME_FONT (s
->f
);
22766 /* Adjust base line for subscript/superscript text. */
22767 s
->ybase
+= voffset
;
22769 eassert (s
->face
&& s
->face
->gc
);
22770 return glyph
- s
->row
->glyphs
[s
->area
];
22774 /* Fill glyph string S from image glyph S->first_glyph. */
22777 fill_image_glyph_string (struct glyph_string
*s
)
22779 eassert (s
->first_glyph
->type
== IMAGE_GLYPH
);
22780 s
->img
= IMAGE_FROM_ID (s
->f
, s
->first_glyph
->u
.img_id
);
22782 s
->slice
= s
->first_glyph
->slice
.img
;
22783 s
->face
= FACE_FROM_ID (s
->f
, s
->first_glyph
->face_id
);
22784 s
->font
= s
->face
->font
;
22785 s
->width
= s
->first_glyph
->pixel_width
;
22787 /* Adjust base line for subscript/superscript text. */
22788 s
->ybase
+= s
->first_glyph
->voffset
;
22792 /* Fill glyph string S from a sequence of stretch glyphs.
22794 START is the index of the first glyph to consider,
22795 END is the index of the last + 1.
22797 Value is the index of the first glyph not in S. */
22800 fill_stretch_glyph_string (struct glyph_string
*s
, int start
, int end
)
22802 struct glyph
*glyph
, *last
;
22803 int voffset
, face_id
;
22805 eassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
22807 glyph
= s
->row
->glyphs
[s
->area
] + start
;
22808 last
= s
->row
->glyphs
[s
->area
] + end
;
22809 face_id
= glyph
->face_id
;
22810 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
22811 s
->font
= s
->face
->font
;
22812 s
->width
= glyph
->pixel_width
;
22814 voffset
= glyph
->voffset
;
22818 && glyph
->type
== STRETCH_GLYPH
22819 && glyph
->voffset
== voffset
22820 && glyph
->face_id
== face_id
);
22822 s
->width
+= glyph
->pixel_width
;
22824 /* Adjust base line for subscript/superscript text. */
22825 s
->ybase
+= voffset
;
22827 /* The case that face->gc == 0 is handled when drawing the glyph
22828 string by calling PREPARE_FACE_FOR_DISPLAY. */
22830 return glyph
- s
->row
->glyphs
[s
->area
];
22833 static struct font_metrics
*
22834 get_per_char_metric (struct font
*font
, XChar2b
*char2b
)
22836 static struct font_metrics metrics
;
22841 code
= (XCHAR2B_BYTE1 (char2b
) << 8) | XCHAR2B_BYTE2 (char2b
);
22842 if (code
== FONT_INVALID_CODE
)
22844 font
->driver
->text_extents (font
, &code
, 1, &metrics
);
22849 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
22850 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
22851 assumed to be zero. */
22854 x_get_glyph_overhangs (struct glyph
*glyph
, struct frame
*f
, int *left
, int *right
)
22856 *left
= *right
= 0;
22858 if (glyph
->type
== CHAR_GLYPH
)
22862 struct font_metrics
*pcm
;
22864 face
= get_glyph_face_and_encoding (f
, glyph
, &char2b
, NULL
);
22865 if (face
->font
&& (pcm
= get_per_char_metric (face
->font
, &char2b
)))
22867 if (pcm
->rbearing
> pcm
->width
)
22868 *right
= pcm
->rbearing
- pcm
->width
;
22869 if (pcm
->lbearing
< 0)
22870 *left
= -pcm
->lbearing
;
22873 else if (glyph
->type
== COMPOSITE_GLYPH
)
22875 if (! glyph
->u
.cmp
.automatic
)
22877 struct composition
*cmp
= composition_table
[glyph
->u
.cmp
.id
];
22879 if (cmp
->rbearing
> cmp
->pixel_width
)
22880 *right
= cmp
->rbearing
- cmp
->pixel_width
;
22881 if (cmp
->lbearing
< 0)
22882 *left
= - cmp
->lbearing
;
22886 Lisp_Object gstring
= composition_gstring_from_id (glyph
->u
.cmp
.id
);
22887 struct font_metrics metrics
;
22889 composition_gstring_width (gstring
, glyph
->slice
.cmp
.from
,
22890 glyph
->slice
.cmp
.to
+ 1, &metrics
);
22891 if (metrics
.rbearing
> metrics
.width
)
22892 *right
= metrics
.rbearing
- metrics
.width
;
22893 if (metrics
.lbearing
< 0)
22894 *left
= - metrics
.lbearing
;
22900 /* Return the index of the first glyph preceding glyph string S that
22901 is overwritten by S because of S's left overhang. Value is -1
22902 if no glyphs are overwritten. */
22905 left_overwritten (struct glyph_string
*s
)
22909 if (s
->left_overhang
)
22912 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
22913 int first
= s
->first_glyph
- glyphs
;
22915 for (i
= first
- 1; i
>= 0 && x
> -s
->left_overhang
; --i
)
22916 x
-= glyphs
[i
].pixel_width
;
22927 /* Return the index of the first glyph preceding glyph string S that
22928 is overwriting S because of its right overhang. Value is -1 if no
22929 glyph in front of S overwrites S. */
22932 left_overwriting (struct glyph_string
*s
)
22935 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
22936 int first
= s
->first_glyph
- glyphs
;
22940 for (i
= first
- 1; i
>= 0; --i
)
22943 x_get_glyph_overhangs (glyphs
+ i
, s
->f
, &left
, &right
);
22946 x
-= glyphs
[i
].pixel_width
;
22953 /* Return the index of the last glyph following glyph string S that is
22954 overwritten by S because of S's right overhang. Value is -1 if
22955 no such glyph is found. */
22958 right_overwritten (struct glyph_string
*s
)
22962 if (s
->right_overhang
)
22965 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
22966 int first
= (s
->first_glyph
- glyphs
22967 + (s
->first_glyph
->type
== COMPOSITE_GLYPH
? 1 : s
->nchars
));
22968 int end
= s
->row
->used
[s
->area
];
22970 for (i
= first
; i
< end
&& s
->right_overhang
> x
; ++i
)
22971 x
+= glyphs
[i
].pixel_width
;
22980 /* Return the index of the last glyph following glyph string S that
22981 overwrites S because of its left overhang. Value is negative
22982 if no such glyph is found. */
22985 right_overwriting (struct glyph_string
*s
)
22988 int end
= s
->row
->used
[s
->area
];
22989 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
22990 int first
= (s
->first_glyph
- glyphs
22991 + (s
->first_glyph
->type
== COMPOSITE_GLYPH
? 1 : s
->nchars
));
22995 for (i
= first
; i
< end
; ++i
)
22998 x_get_glyph_overhangs (glyphs
+ i
, s
->f
, &left
, &right
);
23001 x
+= glyphs
[i
].pixel_width
;
23008 /* Set background width of glyph string S. START is the index of the
23009 first glyph following S. LAST_X is the right-most x-position + 1
23010 in the drawing area. */
23013 set_glyph_string_background_width (struct glyph_string
*s
, int start
, int last_x
)
23015 /* If the face of this glyph string has to be drawn to the end of
23016 the drawing area, set S->extends_to_end_of_line_p. */
23018 if (start
== s
->row
->used
[s
->area
]
23019 && s
->area
== TEXT_AREA
23020 && ((s
->row
->fill_line_p
23021 && (s
->hl
== DRAW_NORMAL_TEXT
23022 || s
->hl
== DRAW_IMAGE_RAISED
23023 || s
->hl
== DRAW_IMAGE_SUNKEN
))
23024 || s
->hl
== DRAW_MOUSE_FACE
))
23025 s
->extends_to_end_of_line_p
= 1;
23027 /* If S extends its face to the end of the line, set its
23028 background_width to the distance to the right edge of the drawing
23030 if (s
->extends_to_end_of_line_p
)
23031 s
->background_width
= last_x
- s
->x
+ 1;
23033 s
->background_width
= s
->width
;
23037 /* Compute overhangs and x-positions for glyph string S and its
23038 predecessors, or successors. X is the starting x-position for S.
23039 BACKWARD_P non-zero means process predecessors. */
23042 compute_overhangs_and_x (struct glyph_string
*s
, int x
, int backward_p
)
23048 if (FRAME_RIF (s
->f
)->compute_glyph_string_overhangs
)
23049 FRAME_RIF (s
->f
)->compute_glyph_string_overhangs (s
);
23059 if (FRAME_RIF (s
->f
)->compute_glyph_string_overhangs
)
23060 FRAME_RIF (s
->f
)->compute_glyph_string_overhangs (s
);
23070 /* The following macros are only called from draw_glyphs below.
23071 They reference the following parameters of that function directly:
23072 `w', `row', `area', and `overlap_p'
23073 as well as the following local variables:
23074 `s', `f', and `hdc' (in W32) */
23077 /* On W32, silently add local `hdc' variable to argument list of
23078 init_glyph_string. */
23079 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
23080 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
23082 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
23083 init_glyph_string (s, char2b, w, row, area, start, hl)
23086 /* Add a glyph string for a stretch glyph to the list of strings
23087 between HEAD and TAIL. START is the index of the stretch glyph in
23088 row area AREA of glyph row ROW. END is the index of the last glyph
23089 in that glyph row area. X is the current output position assigned
23090 to the new glyph string constructed. HL overrides that face of the
23091 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
23092 is the right-most x-position of the drawing area. */
23094 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
23095 and below -- keep them on one line. */
23096 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23099 s = alloca (sizeof *s); \
23100 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
23101 START = fill_stretch_glyph_string (s, START, END); \
23102 append_glyph_string (&HEAD, &TAIL, s); \
23108 /* Add a glyph string for an image glyph to the list of strings
23109 between HEAD and TAIL. START is the index of the image glyph in
23110 row area AREA of glyph row ROW. END is the index of the last glyph
23111 in that glyph row area. X is the current output position assigned
23112 to the new glyph string constructed. HL overrides that face of the
23113 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
23114 is the right-most x-position of the drawing area. */
23116 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23119 s = alloca (sizeof *s); \
23120 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
23121 fill_image_glyph_string (s); \
23122 append_glyph_string (&HEAD, &TAIL, s); \
23129 /* Add a glyph string for a sequence of character glyphs to the list
23130 of strings between HEAD and TAIL. START is the index of the first
23131 glyph in row area AREA of glyph row ROW that is part of the new
23132 glyph string. END is the index of the last glyph in that glyph row
23133 area. X is the current output position assigned to the new glyph
23134 string constructed. HL overrides that face of the glyph; e.g. it
23135 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
23136 right-most x-position of the drawing area. */
23138 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
23144 face_id = (row)->glyphs[area][START].face_id; \
23146 s = alloca (sizeof *s); \
23147 char2b = alloca ((END - START) * sizeof *char2b); \
23148 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
23149 append_glyph_string (&HEAD, &TAIL, s); \
23151 START = fill_glyph_string (s, face_id, START, END, overlaps); \
23156 /* Add a glyph string for a composite sequence to the list of strings
23157 between HEAD and TAIL. START is the index of the first glyph in
23158 row area AREA of glyph row ROW that is part of the new glyph
23159 string. END is the index of the last glyph in that glyph row area.
23160 X is the current output position assigned to the new glyph string
23161 constructed. HL overrides that face of the glyph; e.g. it is
23162 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
23163 x-position of the drawing area. */
23165 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23167 int face_id = (row)->glyphs[area][START].face_id; \
23168 struct face *base_face = FACE_FROM_ID (f, face_id); \
23169 ptrdiff_t cmp_id = (row)->glyphs[area][START].u.cmp.id; \
23170 struct composition *cmp = composition_table[cmp_id]; \
23172 struct glyph_string *first_s = NULL; \
23175 char2b = alloca (cmp->glyph_len * sizeof *char2b); \
23177 /* Make glyph_strings for each glyph sequence that is drawable by \
23178 the same face, and append them to HEAD/TAIL. */ \
23179 for (n = 0; n < cmp->glyph_len;) \
23181 s = alloca (sizeof *s); \
23182 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
23183 append_glyph_string (&(HEAD), &(TAIL), s); \
23189 n = fill_composite_glyph_string (s, base_face, overlaps); \
23197 /* Add a glyph string for a glyph-string sequence to the list of strings
23198 between HEAD and TAIL. */
23200 #define BUILD_GSTRING_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23204 Lisp_Object gstring; \
23206 face_id = (row)->glyphs[area][START].face_id; \
23207 gstring = (composition_gstring_from_id \
23208 ((row)->glyphs[area][START].u.cmp.id)); \
23209 s = alloca (sizeof *s); \
23210 char2b = alloca (LGSTRING_GLYPH_LEN (gstring) * sizeof *char2b); \
23211 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
23212 append_glyph_string (&(HEAD), &(TAIL), s); \
23214 START = fill_gstring_glyph_string (s, face_id, START, END, overlaps); \
23218 /* Add a glyph string for a sequence of glyphless character's glyphs
23219 to the list of strings between HEAD and TAIL. The meanings of
23220 arguments are the same as those of BUILD_CHAR_GLYPH_STRINGS. */
23222 #define BUILD_GLYPHLESS_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23227 face_id = (row)->glyphs[area][START].face_id; \
23229 s = alloca (sizeof *s); \
23230 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
23231 append_glyph_string (&HEAD, &TAIL, s); \
23233 START = fill_glyphless_glyph_string (s, face_id, START, END, \
23239 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
23240 of AREA of glyph row ROW on window W between indices START and END.
23241 HL overrides the face for drawing glyph strings, e.g. it is
23242 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
23243 x-positions of the drawing area.
23245 This is an ugly monster macro construct because we must use alloca
23246 to allocate glyph strings (because draw_glyphs can be called
23247 asynchronously). */
23249 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
23252 HEAD = TAIL = NULL; \
23253 while (START < END) \
23255 struct glyph *first_glyph = (row)->glyphs[area] + START; \
23256 switch (first_glyph->type) \
23259 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
23263 case COMPOSITE_GLYPH: \
23264 if (first_glyph->u.cmp.automatic) \
23265 BUILD_GSTRING_GLYPH_STRING (START, END, HEAD, TAIL, \
23268 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
23272 case STRETCH_GLYPH: \
23273 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
23277 case IMAGE_GLYPH: \
23278 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
23282 case GLYPHLESS_GLYPH: \
23283 BUILD_GLYPHLESS_GLYPH_STRING (START, END, HEAD, TAIL, \
23293 set_glyph_string_background_width (s, START, LAST_X); \
23300 /* Draw glyphs between START and END in AREA of ROW on window W,
23301 starting at x-position X. X is relative to AREA in W. HL is a
23302 face-override with the following meaning:
23304 DRAW_NORMAL_TEXT draw normally
23305 DRAW_CURSOR draw in cursor face
23306 DRAW_MOUSE_FACE draw in mouse face.
23307 DRAW_INVERSE_VIDEO draw in mode line face
23308 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
23309 DRAW_IMAGE_RAISED draw an image with a raised relief around it
23311 If OVERLAPS is non-zero, draw only the foreground of characters and
23312 clip to the physical height of ROW. Non-zero value also defines
23313 the overlapping part to be drawn:
23315 OVERLAPS_PRED overlap with preceding rows
23316 OVERLAPS_SUCC overlap with succeeding rows
23317 OVERLAPS_BOTH overlap with both preceding/succeeding rows
23318 OVERLAPS_ERASED_CURSOR overlap with erased cursor area
23320 Value is the x-position reached, relative to AREA of W. */
23323 draw_glyphs (struct window
*w
, int x
, struct glyph_row
*row
,
23324 enum glyph_row_area area
, ptrdiff_t start
, ptrdiff_t end
,
23325 enum draw_glyphs_face hl
, int overlaps
)
23327 struct glyph_string
*head
, *tail
;
23328 struct glyph_string
*s
;
23329 struct glyph_string
*clip_head
= NULL
, *clip_tail
= NULL
;
23330 int i
, j
, x_reached
, last_x
, area_left
= 0;
23331 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
23334 ALLOCATE_HDC (hdc
, f
);
23336 /* Let's rather be paranoid than getting a SEGV. */
23337 end
= min (end
, row
->used
[area
]);
23338 start
= clip_to_bounds (0, start
, end
);
23340 /* Translate X to frame coordinates. Set last_x to the right
23341 end of the drawing area. */
23342 if (row
->full_width_p
)
23344 /* X is relative to the left edge of W, without scroll bars
23346 area_left
= WINDOW_LEFT_EDGE_X (w
);
23347 last_x
= WINDOW_LEFT_EDGE_X (w
) + WINDOW_TOTAL_WIDTH (w
);
23351 area_left
= window_box_left (w
, area
);
23352 last_x
= area_left
+ window_box_width (w
, area
);
23356 /* Build a doubly-linked list of glyph_string structures between
23357 head and tail from what we have to draw. Note that the macro
23358 BUILD_GLYPH_STRINGS will modify its start parameter. That's
23359 the reason we use a separate variable `i'. */
23361 BUILD_GLYPH_STRINGS (i
, end
, head
, tail
, hl
, x
, last_x
);
23363 x_reached
= tail
->x
+ tail
->background_width
;
23367 /* If there are any glyphs with lbearing < 0 or rbearing > width in
23368 the row, redraw some glyphs in front or following the glyph
23369 strings built above. */
23370 if (head
&& !overlaps
&& row
->contains_overlapping_glyphs_p
)
23372 struct glyph_string
*h
, *t
;
23373 Mouse_HLInfo
*hlinfo
= MOUSE_HL_INFO (f
);
23374 int mouse_beg_col
IF_LINT (= 0), mouse_end_col
IF_LINT (= 0);
23375 int check_mouse_face
= 0;
23378 /* If mouse highlighting is on, we may need to draw adjacent
23379 glyphs using mouse-face highlighting. */
23380 if (area
== TEXT_AREA
&& row
->mouse_face_p
23381 && hlinfo
->mouse_face_beg_row
>= 0
23382 && hlinfo
->mouse_face_end_row
>= 0)
23384 struct glyph_row
*mouse_beg_row
, *mouse_end_row
;
23386 mouse_beg_row
= MATRIX_ROW (w
->current_matrix
, hlinfo
->mouse_face_beg_row
);
23387 mouse_end_row
= MATRIX_ROW (w
->current_matrix
, hlinfo
->mouse_face_end_row
);
23389 if (row
>= mouse_beg_row
&& row
<= mouse_end_row
)
23391 check_mouse_face
= 1;
23392 mouse_beg_col
= (row
== mouse_beg_row
)
23393 ? hlinfo
->mouse_face_beg_col
: 0;
23394 mouse_end_col
= (row
== mouse_end_row
)
23395 ? hlinfo
->mouse_face_end_col
23396 : row
->used
[TEXT_AREA
];
23400 /* Compute overhangs for all glyph strings. */
23401 if (FRAME_RIF (f
)->compute_glyph_string_overhangs
)
23402 for (s
= head
; s
; s
= s
->next
)
23403 FRAME_RIF (f
)->compute_glyph_string_overhangs (s
);
23405 /* Prepend glyph strings for glyphs in front of the first glyph
23406 string that are overwritten because of the first glyph
23407 string's left overhang. The background of all strings
23408 prepended must be drawn because the first glyph string
23410 i
= left_overwritten (head
);
23413 enum draw_glyphs_face overlap_hl
;
23415 /* If this row contains mouse highlighting, attempt to draw
23416 the overlapped glyphs with the correct highlight. This
23417 code fails if the overlap encompasses more than one glyph
23418 and mouse-highlight spans only some of these glyphs.
23419 However, making it work perfectly involves a lot more
23420 code, and I don't know if the pathological case occurs in
23421 practice, so we'll stick to this for now. --- cyd */
23422 if (check_mouse_face
23423 && mouse_beg_col
< start
&& mouse_end_col
> i
)
23424 overlap_hl
= DRAW_MOUSE_FACE
;
23426 overlap_hl
= DRAW_NORMAL_TEXT
;
23429 BUILD_GLYPH_STRINGS (j
, start
, h
, t
,
23430 overlap_hl
, dummy_x
, last_x
);
23432 compute_overhangs_and_x (t
, head
->x
, 1);
23433 prepend_glyph_string_lists (&head
, &tail
, h
, t
);
23437 /* Prepend glyph strings for glyphs in front of the first glyph
23438 string that overwrite that glyph string because of their
23439 right overhang. For these strings, only the foreground must
23440 be drawn, because it draws over the glyph string at `head'.
23441 The background must not be drawn because this would overwrite
23442 right overhangs of preceding glyphs for which no glyph
23444 i
= left_overwriting (head
);
23447 enum draw_glyphs_face overlap_hl
;
23449 if (check_mouse_face
23450 && mouse_beg_col
< start
&& mouse_end_col
> i
)
23451 overlap_hl
= DRAW_MOUSE_FACE
;
23453 overlap_hl
= DRAW_NORMAL_TEXT
;
23456 BUILD_GLYPH_STRINGS (i
, start
, h
, t
,
23457 overlap_hl
, dummy_x
, last_x
);
23458 for (s
= h
; s
; s
= s
->next
)
23459 s
->background_filled_p
= 1;
23460 compute_overhangs_and_x (t
, head
->x
, 1);
23461 prepend_glyph_string_lists (&head
, &tail
, h
, t
);
23464 /* Append glyphs strings for glyphs following the last glyph
23465 string tail that are overwritten by tail. The background of
23466 these strings has to be drawn because tail's foreground draws
23468 i
= right_overwritten (tail
);
23471 enum draw_glyphs_face overlap_hl
;
23473 if (check_mouse_face
23474 && mouse_beg_col
< i
&& mouse_end_col
> end
)
23475 overlap_hl
= DRAW_MOUSE_FACE
;
23477 overlap_hl
= DRAW_NORMAL_TEXT
;
23479 BUILD_GLYPH_STRINGS (end
, i
, h
, t
,
23480 overlap_hl
, x
, last_x
);
23481 /* Because BUILD_GLYPH_STRINGS updates the first argument,
23482 we don't have `end = i;' here. */
23483 compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
23484 append_glyph_string_lists (&head
, &tail
, h
, t
);
23488 /* Append glyph strings for glyphs following the last glyph
23489 string tail that overwrite tail. The foreground of such
23490 glyphs has to be drawn because it writes into the background
23491 of tail. The background must not be drawn because it could
23492 paint over the foreground of following glyphs. */
23493 i
= right_overwriting (tail
);
23496 enum draw_glyphs_face overlap_hl
;
23497 if (check_mouse_face
23498 && mouse_beg_col
< i
&& mouse_end_col
> end
)
23499 overlap_hl
= DRAW_MOUSE_FACE
;
23501 overlap_hl
= DRAW_NORMAL_TEXT
;
23504 i
++; /* We must include the Ith glyph. */
23505 BUILD_GLYPH_STRINGS (end
, i
, h
, t
,
23506 overlap_hl
, x
, last_x
);
23507 for (s
= h
; s
; s
= s
->next
)
23508 s
->background_filled_p
= 1;
23509 compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
23510 append_glyph_string_lists (&head
, &tail
, h
, t
);
23512 if (clip_head
|| clip_tail
)
23513 for (s
= head
; s
; s
= s
->next
)
23515 s
->clip_head
= clip_head
;
23516 s
->clip_tail
= clip_tail
;
23520 /* Draw all strings. */
23521 for (s
= head
; s
; s
= s
->next
)
23522 FRAME_RIF (f
)->draw_glyph_string (s
);
23525 /* When focus a sole frame and move horizontally, this sets on_p to 0
23526 causing a failure to erase prev cursor position. */
23527 if (area
== TEXT_AREA
23528 && !row
->full_width_p
23529 /* When drawing overlapping rows, only the glyph strings'
23530 foreground is drawn, which doesn't erase a cursor
23534 int x0
= clip_head
? clip_head
->x
: (head
? head
->x
: x
);
23535 int x1
= (clip_tail
? clip_tail
->x
+ clip_tail
->background_width
23536 : (tail
? tail
->x
+ tail
->background_width
: x
));
23540 notice_overwritten_cursor (w
, TEXT_AREA
, x0
, x1
,
23541 row
->y
, MATRIX_ROW_BOTTOM_Y (row
));
23545 /* Value is the x-position up to which drawn, relative to AREA of W.
23546 This doesn't include parts drawn because of overhangs. */
23547 if (row
->full_width_p
)
23548 x_reached
= FRAME_TO_WINDOW_PIXEL_X (w
, x_reached
);
23550 x_reached
-= area_left
;
23552 RELEASE_HDC (hdc
, f
);
23557 /* Expand row matrix if too narrow. Don't expand if area
23560 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
23562 if (!fonts_changed_p \
23563 && (it->glyph_row->glyphs[area] \
23564 < it->glyph_row->glyphs[area + 1])) \
23566 it->w->ncols_scale_factor++; \
23567 fonts_changed_p = 1; \
23571 /* Store one glyph for IT->char_to_display in IT->glyph_row.
23572 Called from x_produce_glyphs when IT->glyph_row is non-null. */
23575 append_glyph (struct it
*it
)
23577 struct glyph
*glyph
;
23578 enum glyph_row_area area
= it
->area
;
23580 eassert (it
->glyph_row
);
23581 eassert (it
->char_to_display
!= '\n' && it
->char_to_display
!= '\t');
23583 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
23584 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
23586 /* If the glyph row is reversed, we need to prepend the glyph
23587 rather than append it. */
23588 if (it
->glyph_row
->reversed_p
&& area
== TEXT_AREA
)
23592 /* Make room for the additional glyph. */
23593 for (g
= glyph
- 1; g
>= it
->glyph_row
->glyphs
[area
]; g
--)
23595 glyph
= it
->glyph_row
->glyphs
[area
];
23597 glyph
->charpos
= CHARPOS (it
->position
);
23598 glyph
->object
= it
->object
;
23599 if (it
->pixel_width
> 0)
23601 glyph
->pixel_width
= it
->pixel_width
;
23602 glyph
->padding_p
= 0;
23606 /* Assure at least 1-pixel width. Otherwise, cursor can't
23607 be displayed correctly. */
23608 glyph
->pixel_width
= 1;
23609 glyph
->padding_p
= 1;
23611 glyph
->ascent
= it
->ascent
;
23612 glyph
->descent
= it
->descent
;
23613 glyph
->voffset
= it
->voffset
;
23614 glyph
->type
= CHAR_GLYPH
;
23615 glyph
->avoid_cursor_p
= it
->avoid_cursor_p
;
23616 glyph
->multibyte_p
= it
->multibyte_p
;
23617 if (it
->glyph_row
->reversed_p
&& area
== TEXT_AREA
)
23619 /* In R2L rows, the left and the right box edges need to be
23620 drawn in reverse direction. */
23621 glyph
->right_box_line_p
= it
->start_of_box_run_p
;
23622 glyph
->left_box_line_p
= it
->end_of_box_run_p
;
23626 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
23627 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
23629 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
23630 || it
->phys_descent
> it
->descent
);
23631 glyph
->glyph_not_available_p
= it
->glyph_not_available_p
;
23632 glyph
->face_id
= it
->face_id
;
23633 glyph
->u
.ch
= it
->char_to_display
;
23634 glyph
->slice
.img
= null_glyph_slice
;
23635 glyph
->font_type
= FONT_TYPE_UNKNOWN
;
23638 glyph
->resolved_level
= it
->bidi_it
.resolved_level
;
23639 if ((it
->bidi_it
.type
& 7) != it
->bidi_it
.type
)
23641 glyph
->bidi_type
= it
->bidi_it
.type
;
23645 glyph
->resolved_level
= 0;
23646 glyph
->bidi_type
= UNKNOWN_BT
;
23648 ++it
->glyph_row
->used
[area
];
23651 IT_EXPAND_MATRIX_WIDTH (it
, area
);
23654 /* Store one glyph for the composition IT->cmp_it.id in
23655 IT->glyph_row. Called from x_produce_glyphs when IT->glyph_row is
23659 append_composite_glyph (struct it
*it
)
23661 struct glyph
*glyph
;
23662 enum glyph_row_area area
= it
->area
;
23664 eassert (it
->glyph_row
);
23666 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
23667 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
23669 /* If the glyph row is reversed, we need to prepend the glyph
23670 rather than append it. */
23671 if (it
->glyph_row
->reversed_p
&& it
->area
== TEXT_AREA
)
23675 /* Make room for the new glyph. */
23676 for (g
= glyph
- 1; g
>= it
->glyph_row
->glyphs
[it
->area
]; g
--)
23678 glyph
= it
->glyph_row
->glyphs
[it
->area
];
23680 glyph
->charpos
= it
->cmp_it
.charpos
;
23681 glyph
->object
= it
->object
;
23682 glyph
->pixel_width
= it
->pixel_width
;
23683 glyph
->ascent
= it
->ascent
;
23684 glyph
->descent
= it
->descent
;
23685 glyph
->voffset
= it
->voffset
;
23686 glyph
->type
= COMPOSITE_GLYPH
;
23687 if (it
->cmp_it
.ch
< 0)
23689 glyph
->u
.cmp
.automatic
= 0;
23690 glyph
->u
.cmp
.id
= it
->cmp_it
.id
;
23691 glyph
->slice
.cmp
.from
= glyph
->slice
.cmp
.to
= 0;
23695 glyph
->u
.cmp
.automatic
= 1;
23696 glyph
->u
.cmp
.id
= it
->cmp_it
.id
;
23697 glyph
->slice
.cmp
.from
= it
->cmp_it
.from
;
23698 glyph
->slice
.cmp
.to
= it
->cmp_it
.to
- 1;
23700 glyph
->avoid_cursor_p
= it
->avoid_cursor_p
;
23701 glyph
->multibyte_p
= it
->multibyte_p
;
23702 if (it
->glyph_row
->reversed_p
&& area
== TEXT_AREA
)
23704 /* In R2L rows, the left and the right box edges need to be
23705 drawn in reverse direction. */
23706 glyph
->right_box_line_p
= it
->start_of_box_run_p
;
23707 glyph
->left_box_line_p
= it
->end_of_box_run_p
;
23711 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
23712 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
23714 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
23715 || it
->phys_descent
> it
->descent
);
23716 glyph
->padding_p
= 0;
23717 glyph
->glyph_not_available_p
= 0;
23718 glyph
->face_id
= it
->face_id
;
23719 glyph
->font_type
= FONT_TYPE_UNKNOWN
;
23722 glyph
->resolved_level
= it
->bidi_it
.resolved_level
;
23723 if ((it
->bidi_it
.type
& 7) != it
->bidi_it
.type
)
23725 glyph
->bidi_type
= it
->bidi_it
.type
;
23727 ++it
->glyph_row
->used
[area
];
23730 IT_EXPAND_MATRIX_WIDTH (it
, area
);
23734 /* Change IT->ascent and IT->height according to the setting of
23738 take_vertical_position_into_account (struct it
*it
)
23742 if (it
->voffset
< 0)
23743 /* Increase the ascent so that we can display the text higher
23745 it
->ascent
-= it
->voffset
;
23747 /* Increase the descent so that we can display the text lower
23749 it
->descent
+= it
->voffset
;
23754 /* Produce glyphs/get display metrics for the image IT is loaded with.
23755 See the description of struct display_iterator in dispextern.h for
23756 an overview of struct display_iterator. */
23759 produce_image_glyph (struct it
*it
)
23763 int glyph_ascent
, crop
;
23764 struct glyph_slice slice
;
23766 eassert (it
->what
== IT_IMAGE
);
23768 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
23770 /* Make sure X resources of the face is loaded. */
23771 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
23773 if (it
->image_id
< 0)
23775 /* Fringe bitmap. */
23776 it
->ascent
= it
->phys_ascent
= 0;
23777 it
->descent
= it
->phys_descent
= 0;
23778 it
->pixel_width
= 0;
23783 img
= IMAGE_FROM_ID (it
->f
, it
->image_id
);
23785 /* Make sure X resources of the image is loaded. */
23786 prepare_image_for_display (it
->f
, img
);
23788 slice
.x
= slice
.y
= 0;
23789 slice
.width
= img
->width
;
23790 slice
.height
= img
->height
;
23792 if (INTEGERP (it
->slice
.x
))
23793 slice
.x
= XINT (it
->slice
.x
);
23794 else if (FLOATP (it
->slice
.x
))
23795 slice
.x
= XFLOAT_DATA (it
->slice
.x
) * img
->width
;
23797 if (INTEGERP (it
->slice
.y
))
23798 slice
.y
= XINT (it
->slice
.y
);
23799 else if (FLOATP (it
->slice
.y
))
23800 slice
.y
= XFLOAT_DATA (it
->slice
.y
) * img
->height
;
23802 if (INTEGERP (it
->slice
.width
))
23803 slice
.width
= XINT (it
->slice
.width
);
23804 else if (FLOATP (it
->slice
.width
))
23805 slice
.width
= XFLOAT_DATA (it
->slice
.width
) * img
->width
;
23807 if (INTEGERP (it
->slice
.height
))
23808 slice
.height
= XINT (it
->slice
.height
);
23809 else if (FLOATP (it
->slice
.height
))
23810 slice
.height
= XFLOAT_DATA (it
->slice
.height
) * img
->height
;
23812 if (slice
.x
>= img
->width
)
23813 slice
.x
= img
->width
;
23814 if (slice
.y
>= img
->height
)
23815 slice
.y
= img
->height
;
23816 if (slice
.x
+ slice
.width
>= img
->width
)
23817 slice
.width
= img
->width
- slice
.x
;
23818 if (slice
.y
+ slice
.height
> img
->height
)
23819 slice
.height
= img
->height
- slice
.y
;
23821 if (slice
.width
== 0 || slice
.height
== 0)
23824 it
->ascent
= it
->phys_ascent
= glyph_ascent
= image_ascent (img
, face
, &slice
);
23826 it
->descent
= slice
.height
- glyph_ascent
;
23828 it
->descent
+= img
->vmargin
;
23829 if (slice
.y
+ slice
.height
== img
->height
)
23830 it
->descent
+= img
->vmargin
;
23831 it
->phys_descent
= it
->descent
;
23833 it
->pixel_width
= slice
.width
;
23835 it
->pixel_width
+= img
->hmargin
;
23836 if (slice
.x
+ slice
.width
== img
->width
)
23837 it
->pixel_width
+= img
->hmargin
;
23839 /* It's quite possible for images to have an ascent greater than
23840 their height, so don't get confused in that case. */
23841 if (it
->descent
< 0)
23846 if (face
->box
!= FACE_NO_BOX
)
23848 if (face
->box_line_width
> 0)
23851 it
->ascent
+= face
->box_line_width
;
23852 if (slice
.y
+ slice
.height
== img
->height
)
23853 it
->descent
+= face
->box_line_width
;
23856 if (it
->start_of_box_run_p
&& slice
.x
== 0)
23857 it
->pixel_width
+= eabs (face
->box_line_width
);
23858 if (it
->end_of_box_run_p
&& slice
.x
+ slice
.width
== img
->width
)
23859 it
->pixel_width
+= eabs (face
->box_line_width
);
23862 take_vertical_position_into_account (it
);
23864 /* Automatically crop wide image glyphs at right edge so we can
23865 draw the cursor on same display row. */
23866 if ((crop
= it
->pixel_width
- (it
->last_visible_x
- it
->current_x
), crop
> 0)
23867 && (it
->hpos
== 0 || it
->pixel_width
> it
->last_visible_x
/ 4))
23869 it
->pixel_width
-= crop
;
23870 slice
.width
-= crop
;
23875 struct glyph
*glyph
;
23876 enum glyph_row_area area
= it
->area
;
23878 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
23879 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
23881 glyph
->charpos
= CHARPOS (it
->position
);
23882 glyph
->object
= it
->object
;
23883 glyph
->pixel_width
= it
->pixel_width
;
23884 glyph
->ascent
= glyph_ascent
;
23885 glyph
->descent
= it
->descent
;
23886 glyph
->voffset
= it
->voffset
;
23887 glyph
->type
= IMAGE_GLYPH
;
23888 glyph
->avoid_cursor_p
= it
->avoid_cursor_p
;
23889 glyph
->multibyte_p
= it
->multibyte_p
;
23890 if (it
->glyph_row
->reversed_p
&& area
== TEXT_AREA
)
23892 /* In R2L rows, the left and the right box edges need to be
23893 drawn in reverse direction. */
23894 glyph
->right_box_line_p
= it
->start_of_box_run_p
;
23895 glyph
->left_box_line_p
= it
->end_of_box_run_p
;
23899 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
23900 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
23902 glyph
->overlaps_vertically_p
= 0;
23903 glyph
->padding_p
= 0;
23904 glyph
->glyph_not_available_p
= 0;
23905 glyph
->face_id
= it
->face_id
;
23906 glyph
->u
.img_id
= img
->id
;
23907 glyph
->slice
.img
= slice
;
23908 glyph
->font_type
= FONT_TYPE_UNKNOWN
;
23911 glyph
->resolved_level
= it
->bidi_it
.resolved_level
;
23912 if ((it
->bidi_it
.type
& 7) != it
->bidi_it
.type
)
23914 glyph
->bidi_type
= it
->bidi_it
.type
;
23916 ++it
->glyph_row
->used
[area
];
23919 IT_EXPAND_MATRIX_WIDTH (it
, area
);
23924 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
23925 of the glyph, WIDTH and HEIGHT are the width and height of the
23926 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
23929 append_stretch_glyph (struct it
*it
, Lisp_Object object
,
23930 int width
, int height
, int ascent
)
23932 struct glyph
*glyph
;
23933 enum glyph_row_area area
= it
->area
;
23935 eassert (ascent
>= 0 && ascent
<= height
);
23937 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
23938 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
23940 /* If the glyph row is reversed, we need to prepend the glyph
23941 rather than append it. */
23942 if (it
->glyph_row
->reversed_p
&& area
== TEXT_AREA
)
23946 /* Make room for the additional glyph. */
23947 for (g
= glyph
- 1; g
>= it
->glyph_row
->glyphs
[area
]; g
--)
23949 glyph
= it
->glyph_row
->glyphs
[area
];
23951 glyph
->charpos
= CHARPOS (it
->position
);
23952 glyph
->object
= object
;
23953 glyph
->pixel_width
= width
;
23954 glyph
->ascent
= ascent
;
23955 glyph
->descent
= height
- ascent
;
23956 glyph
->voffset
= it
->voffset
;
23957 glyph
->type
= STRETCH_GLYPH
;
23958 glyph
->avoid_cursor_p
= it
->avoid_cursor_p
;
23959 glyph
->multibyte_p
= it
->multibyte_p
;
23960 if (it
->glyph_row
->reversed_p
&& area
== TEXT_AREA
)
23962 /* In R2L rows, the left and the right box edges need to be
23963 drawn in reverse direction. */
23964 glyph
->right_box_line_p
= it
->start_of_box_run_p
;
23965 glyph
->left_box_line_p
= it
->end_of_box_run_p
;
23969 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
23970 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
23972 glyph
->overlaps_vertically_p
= 0;
23973 glyph
->padding_p
= 0;
23974 glyph
->glyph_not_available_p
= 0;
23975 glyph
->face_id
= it
->face_id
;
23976 glyph
->u
.stretch
.ascent
= ascent
;
23977 glyph
->u
.stretch
.height
= height
;
23978 glyph
->slice
.img
= null_glyph_slice
;
23979 glyph
->font_type
= FONT_TYPE_UNKNOWN
;
23982 glyph
->resolved_level
= it
->bidi_it
.resolved_level
;
23983 if ((it
->bidi_it
.type
& 7) != it
->bidi_it
.type
)
23985 glyph
->bidi_type
= it
->bidi_it
.type
;
23989 glyph
->resolved_level
= 0;
23990 glyph
->bidi_type
= UNKNOWN_BT
;
23992 ++it
->glyph_row
->used
[area
];
23995 IT_EXPAND_MATRIX_WIDTH (it
, area
);
23998 #endif /* HAVE_WINDOW_SYSTEM */
24000 /* Produce a stretch glyph for iterator IT. IT->object is the value
24001 of the glyph property displayed. The value must be a list
24002 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
24005 1. `:width WIDTH' specifies that the space should be WIDTH *
24006 canonical char width wide. WIDTH may be an integer or floating
24009 2. `:relative-width FACTOR' specifies that the width of the stretch
24010 should be computed from the width of the first character having the
24011 `glyph' property, and should be FACTOR times that width.
24013 3. `:align-to HPOS' specifies that the space should be wide enough
24014 to reach HPOS, a value in canonical character units.
24016 Exactly one of the above pairs must be present.
24018 4. `:height HEIGHT' specifies that the height of the stretch produced
24019 should be HEIGHT, measured in canonical character units.
24021 5. `:relative-height FACTOR' specifies that the height of the
24022 stretch should be FACTOR times the height of the characters having
24023 the glyph property.
24025 Either none or exactly one of 4 or 5 must be present.
24027 6. `:ascent ASCENT' specifies that ASCENT percent of the height
24028 of the stretch should be used for the ascent of the stretch.
24029 ASCENT must be in the range 0 <= ASCENT <= 100. */
24032 produce_stretch_glyph (struct it
*it
)
24034 /* (space :width WIDTH :height HEIGHT ...) */
24035 Lisp_Object prop
, plist
;
24036 int width
= 0, height
= 0, align_to
= -1;
24037 int zero_width_ok_p
= 0;
24039 struct font
*font
= NULL
;
24041 #ifdef HAVE_WINDOW_SYSTEM
24043 int zero_height_ok_p
= 0;
24045 if (FRAME_WINDOW_P (it
->f
))
24047 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
24048 font
= face
->font
? face
->font
: FRAME_FONT (it
->f
);
24049 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
24053 /* List should start with `space'. */
24054 eassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
24055 plist
= XCDR (it
->object
);
24057 /* Compute the width of the stretch. */
24058 if ((prop
= Fplist_get (plist
, QCwidth
), !NILP (prop
))
24059 && calc_pixel_width_or_height (&tem
, it
, prop
, font
, 1, 0))
24061 /* Absolute width `:width WIDTH' specified and valid. */
24062 zero_width_ok_p
= 1;
24065 #ifdef HAVE_WINDOW_SYSTEM
24066 else if (FRAME_WINDOW_P (it
->f
)
24067 && (prop
= Fplist_get (plist
, QCrelative_width
), NUMVAL (prop
) > 0))
24069 /* Relative width `:relative-width FACTOR' specified and valid.
24070 Compute the width of the characters having the `glyph'
24073 unsigned char *p
= BYTE_POS_ADDR (IT_BYTEPOS (*it
));
24076 if (it
->multibyte_p
)
24077 it2
.c
= it2
.char_to_display
= STRING_CHAR_AND_LENGTH (p
, it2
.len
);
24080 it2
.c
= it2
.char_to_display
= *p
, it2
.len
= 1;
24081 if (! ASCII_CHAR_P (it2
.c
))
24082 it2
.char_to_display
= BYTE8_TO_CHAR (it2
.c
);
24085 it2
.glyph_row
= NULL
;
24086 it2
.what
= IT_CHARACTER
;
24087 x_produce_glyphs (&it2
);
24088 width
= NUMVAL (prop
) * it2
.pixel_width
;
24090 #endif /* HAVE_WINDOW_SYSTEM */
24091 else if ((prop
= Fplist_get (plist
, QCalign_to
), !NILP (prop
))
24092 && calc_pixel_width_or_height (&tem
, it
, prop
, font
, 1, &align_to
))
24094 if (it
->glyph_row
== NULL
|| !it
->glyph_row
->mode_line_p
)
24095 align_to
= (align_to
< 0
24097 : align_to
- window_box_left_offset (it
->w
, TEXT_AREA
));
24098 else if (align_to
< 0)
24099 align_to
= window_box_left_offset (it
->w
, TEXT_AREA
);
24100 width
= max (0, (int)tem
+ align_to
- it
->current_x
);
24101 zero_width_ok_p
= 1;
24104 /* Nothing specified -> width defaults to canonical char width. */
24105 width
= FRAME_COLUMN_WIDTH (it
->f
);
24107 if (width
<= 0 && (width
< 0 || !zero_width_ok_p
))
24110 #ifdef HAVE_WINDOW_SYSTEM
24111 /* Compute height. */
24112 if (FRAME_WINDOW_P (it
->f
))
24114 if ((prop
= Fplist_get (plist
, QCheight
), !NILP (prop
))
24115 && calc_pixel_width_or_height (&tem
, it
, prop
, font
, 0, 0))
24118 zero_height_ok_p
= 1;
24120 else if (prop
= Fplist_get (plist
, QCrelative_height
),
24122 height
= FONT_HEIGHT (font
) * NUMVAL (prop
);
24124 height
= FONT_HEIGHT (font
);
24126 if (height
<= 0 && (height
< 0 || !zero_height_ok_p
))
24129 /* Compute percentage of height used for ascent. If
24130 `:ascent ASCENT' is present and valid, use that. Otherwise,
24131 derive the ascent from the font in use. */
24132 if (prop
= Fplist_get (plist
, QCascent
),
24133 NUMVAL (prop
) > 0 && NUMVAL (prop
) <= 100)
24134 ascent
= height
* NUMVAL (prop
) / 100.0;
24135 else if (!NILP (prop
)
24136 && calc_pixel_width_or_height (&tem
, it
, prop
, font
, 0, 0))
24137 ascent
= min (max (0, (int)tem
), height
);
24139 ascent
= (height
* FONT_BASE (font
)) / FONT_HEIGHT (font
);
24142 #endif /* HAVE_WINDOW_SYSTEM */
24145 if (width
> 0 && it
->line_wrap
!= TRUNCATE
24146 && it
->current_x
+ width
> it
->last_visible_x
)
24148 width
= it
->last_visible_x
- it
->current_x
;
24149 #ifdef HAVE_WINDOW_SYSTEM
24150 /* Subtract one more pixel from the stretch width, but only on
24151 GUI frames, since on a TTY each glyph is one "pixel" wide. */
24152 width
-= FRAME_WINDOW_P (it
->f
);
24156 if (width
> 0 && height
> 0 && it
->glyph_row
)
24158 Lisp_Object o_object
= it
->object
;
24159 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
24162 if (!STRINGP (object
))
24163 object
= it
->w
->contents
;
24164 #ifdef HAVE_WINDOW_SYSTEM
24165 if (FRAME_WINDOW_P (it
->f
))
24166 append_stretch_glyph (it
, object
, width
, height
, ascent
);
24170 it
->object
= object
;
24171 it
->char_to_display
= ' ';
24172 it
->pixel_width
= it
->len
= 1;
24174 tty_append_glyph (it
);
24175 it
->object
= o_object
;
24179 it
->pixel_width
= width
;
24180 #ifdef HAVE_WINDOW_SYSTEM
24181 if (FRAME_WINDOW_P (it
->f
))
24183 it
->ascent
= it
->phys_ascent
= ascent
;
24184 it
->descent
= it
->phys_descent
= height
- it
->ascent
;
24185 it
->nglyphs
= width
> 0 && height
> 0 ? 1 : 0;
24186 take_vertical_position_into_account (it
);
24190 it
->nglyphs
= width
;
24193 /* Get information about special display element WHAT in an
24194 environment described by IT. WHAT is one of IT_TRUNCATION or
24195 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
24196 non-null glyph_row member. This function ensures that fields like
24197 face_id, c, len of IT are left untouched. */
24200 produce_special_glyphs (struct it
*it
, enum display_element_type what
)
24207 temp_it
.object
= make_number (0);
24208 memset (&temp_it
.current
, 0, sizeof temp_it
.current
);
24210 if (what
== IT_CONTINUATION
)
24212 /* Continuation glyph. For R2L lines, we mirror it by hand. */
24213 if (it
->bidi_it
.paragraph_dir
== R2L
)
24214 SET_GLYPH_FROM_CHAR (glyph
, '/');
24216 SET_GLYPH_FROM_CHAR (glyph
, '\\');
24218 && (gc
= DISP_CONTINUE_GLYPH (it
->dp
), GLYPH_CODE_P (gc
)))
24220 /* FIXME: Should we mirror GC for R2L lines? */
24221 SET_GLYPH_FROM_GLYPH_CODE (glyph
, gc
);
24222 spec_glyph_lookup_face (XWINDOW (it
->window
), &glyph
);
24225 else if (what
== IT_TRUNCATION
)
24227 /* Truncation glyph. */
24228 SET_GLYPH_FROM_CHAR (glyph
, '$');
24230 && (gc
= DISP_TRUNC_GLYPH (it
->dp
), GLYPH_CODE_P (gc
)))
24232 /* FIXME: Should we mirror GC for R2L lines? */
24233 SET_GLYPH_FROM_GLYPH_CODE (glyph
, gc
);
24234 spec_glyph_lookup_face (XWINDOW (it
->window
), &glyph
);
24240 #ifdef HAVE_WINDOW_SYSTEM
24241 /* On a GUI frame, when the right fringe (left fringe for R2L rows)
24242 is turned off, we precede the truncation/continuation glyphs by a
24243 stretch glyph whose width is computed such that these special
24244 glyphs are aligned at the window margin, even when very different
24245 fonts are used in different glyph rows. */
24246 if (FRAME_WINDOW_P (temp_it
.f
)
24247 /* init_iterator calls this with it->glyph_row == NULL, and it
24248 wants only the pixel width of the truncation/continuation
24250 && temp_it
.glyph_row
24251 /* insert_left_trunc_glyphs calls us at the beginning of the
24252 row, and it has its own calculation of the stretch glyph
24254 && temp_it
.glyph_row
->used
[TEXT_AREA
] > 0
24255 && (temp_it
.glyph_row
->reversed_p
24256 ? WINDOW_LEFT_FRINGE_WIDTH (temp_it
.w
)
24257 : WINDOW_RIGHT_FRINGE_WIDTH (temp_it
.w
)) == 0)
24259 int stretch_width
= temp_it
.last_visible_x
- temp_it
.current_x
;
24261 if (stretch_width
> 0)
24263 struct face
*face
= FACE_FROM_ID (temp_it
.f
, temp_it
.face_id
);
24264 struct font
*font
=
24265 face
->font
? face
->font
: FRAME_FONT (temp_it
.f
);
24266 int stretch_ascent
=
24267 (((temp_it
.ascent
+ temp_it
.descent
)
24268 * FONT_BASE (font
)) / FONT_HEIGHT (font
));
24270 append_stretch_glyph (&temp_it
, make_number (0), stretch_width
,
24271 temp_it
.ascent
+ temp_it
.descent
,
24278 temp_it
.what
= IT_CHARACTER
;
24280 temp_it
.c
= temp_it
.char_to_display
= GLYPH_CHAR (glyph
);
24281 temp_it
.face_id
= GLYPH_FACE (glyph
);
24282 temp_it
.len
= CHAR_BYTES (temp_it
.c
);
24284 PRODUCE_GLYPHS (&temp_it
);
24285 it
->pixel_width
= temp_it
.pixel_width
;
24286 it
->nglyphs
= temp_it
.pixel_width
;
24289 #ifdef HAVE_WINDOW_SYSTEM
24291 /* Calculate line-height and line-spacing properties.
24292 An integer value specifies explicit pixel value.
24293 A float value specifies relative value to current face height.
24294 A cons (float . face-name) specifies relative value to
24295 height of specified face font.
24297 Returns height in pixels, or nil. */
24301 calc_line_height_property (struct it
*it
, Lisp_Object val
, struct font
*font
,
24302 int boff
, int override
)
24304 Lisp_Object face_name
= Qnil
;
24305 int ascent
, descent
, height
;
24307 if (NILP (val
) || INTEGERP (val
) || (override
&& EQ (val
, Qt
)))
24312 face_name
= XCAR (val
);
24314 if (!NUMBERP (val
))
24315 val
= make_number (1);
24316 if (NILP (face_name
))
24318 height
= it
->ascent
+ it
->descent
;
24323 if (NILP (face_name
))
24325 font
= FRAME_FONT (it
->f
);
24326 boff
= FRAME_BASELINE_OFFSET (it
->f
);
24328 else if (EQ (face_name
, Qt
))
24337 face_id
= lookup_named_face (it
->f
, face_name
, 0);
24339 return make_number (-1);
24341 face
= FACE_FROM_ID (it
->f
, face_id
);
24344 return make_number (-1);
24345 boff
= font
->baseline_offset
;
24346 if (font
->vertical_centering
)
24347 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
24350 ascent
= FONT_BASE (font
) + boff
;
24351 descent
= FONT_DESCENT (font
) - boff
;
24355 it
->override_ascent
= ascent
;
24356 it
->override_descent
= descent
;
24357 it
->override_boff
= boff
;
24360 height
= ascent
+ descent
;
24364 height
= (int)(XFLOAT_DATA (val
) * height
);
24365 else if (INTEGERP (val
))
24366 height
*= XINT (val
);
24368 return make_number (height
);
24372 /* Append a glyph for a glyphless character to IT->glyph_row. FACE_ID
24373 is a face ID to be used for the glyph. FOR_NO_FONT is nonzero if
24374 and only if this is for a character for which no font was found.
24376 If the display method (it->glyphless_method) is
24377 GLYPHLESS_DISPLAY_ACRONYM or GLYPHLESS_DISPLAY_HEX_CODE, LEN is a
24378 length of the acronym or the hexadecimal string, UPPER_XOFF and
24379 UPPER_YOFF are pixel offsets for the upper part of the string,
24380 LOWER_XOFF and LOWER_YOFF are for the lower part.
24382 For the other display methods, LEN through LOWER_YOFF are zero. */
24385 append_glyphless_glyph (struct it
*it
, int face_id
, int for_no_font
, int len
,
24386 short upper_xoff
, short upper_yoff
,
24387 short lower_xoff
, short lower_yoff
)
24389 struct glyph
*glyph
;
24390 enum glyph_row_area area
= it
->area
;
24392 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
24393 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
24395 /* If the glyph row is reversed, we need to prepend the glyph
24396 rather than append it. */
24397 if (it
->glyph_row
->reversed_p
&& area
== TEXT_AREA
)
24401 /* Make room for the additional glyph. */
24402 for (g
= glyph
- 1; g
>= it
->glyph_row
->glyphs
[area
]; g
--)
24404 glyph
= it
->glyph_row
->glyphs
[area
];
24406 glyph
->charpos
= CHARPOS (it
->position
);
24407 glyph
->object
= it
->object
;
24408 glyph
->pixel_width
= it
->pixel_width
;
24409 glyph
->ascent
= it
->ascent
;
24410 glyph
->descent
= it
->descent
;
24411 glyph
->voffset
= it
->voffset
;
24412 glyph
->type
= GLYPHLESS_GLYPH
;
24413 glyph
->u
.glyphless
.method
= it
->glyphless_method
;
24414 glyph
->u
.glyphless
.for_no_font
= for_no_font
;
24415 glyph
->u
.glyphless
.len
= len
;
24416 glyph
->u
.glyphless
.ch
= it
->c
;
24417 glyph
->slice
.glyphless
.upper_xoff
= upper_xoff
;
24418 glyph
->slice
.glyphless
.upper_yoff
= upper_yoff
;
24419 glyph
->slice
.glyphless
.lower_xoff
= lower_xoff
;
24420 glyph
->slice
.glyphless
.lower_yoff
= lower_yoff
;
24421 glyph
->avoid_cursor_p
= it
->avoid_cursor_p
;
24422 glyph
->multibyte_p
= it
->multibyte_p
;
24423 if (it
->glyph_row
->reversed_p
&& area
== TEXT_AREA
)
24425 /* In R2L rows, the left and the right box edges need to be
24426 drawn in reverse direction. */
24427 glyph
->right_box_line_p
= it
->start_of_box_run_p
;
24428 glyph
->left_box_line_p
= it
->end_of_box_run_p
;
24432 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
24433 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
24435 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
24436 || it
->phys_descent
> it
->descent
);
24437 glyph
->padding_p
= 0;
24438 glyph
->glyph_not_available_p
= 0;
24439 glyph
->face_id
= face_id
;
24440 glyph
->font_type
= FONT_TYPE_UNKNOWN
;
24443 glyph
->resolved_level
= it
->bidi_it
.resolved_level
;
24444 if ((it
->bidi_it
.type
& 7) != it
->bidi_it
.type
)
24446 glyph
->bidi_type
= it
->bidi_it
.type
;
24448 ++it
->glyph_row
->used
[area
];
24451 IT_EXPAND_MATRIX_WIDTH (it
, area
);
24455 /* Produce a glyph for a glyphless character for iterator IT.
24456 IT->glyphless_method specifies which method to use for displaying
24457 the character. See the description of enum
24458 glyphless_display_method in dispextern.h for the detail.
24460 FOR_NO_FONT is nonzero if and only if this is for a character for
24461 which no font was found. ACRONYM, if non-nil, is an acronym string
24462 for the character. */
24465 produce_glyphless_glyph (struct it
*it
, int for_no_font
, Lisp_Object acronym
)
24470 int base_width
, base_height
, width
, height
;
24471 short upper_xoff
, upper_yoff
, lower_xoff
, lower_yoff
;
24474 /* Get the metrics of the base font. We always refer to the current
24476 face
= FACE_FROM_ID (it
->f
, it
->face_id
)->ascii_face
;
24477 font
= face
->font
? face
->font
: FRAME_FONT (it
->f
);
24478 it
->ascent
= FONT_BASE (font
) + font
->baseline_offset
;
24479 it
->descent
= FONT_DESCENT (font
) - font
->baseline_offset
;
24480 base_height
= it
->ascent
+ it
->descent
;
24481 base_width
= font
->average_width
;
24483 /* Get a face ID for the glyph by utilizing a cache (the same way as
24484 done for `escape-glyph' in get_next_display_element). */
24485 if (it
->f
== last_glyphless_glyph_frame
24486 && it
->face_id
== last_glyphless_glyph_face_id
)
24488 face_id
= last_glyphless_glyph_merged_face_id
;
24492 /* Merge the `glyphless-char' face into the current face. */
24493 face_id
= merge_faces (it
->f
, Qglyphless_char
, 0, it
->face_id
);
24494 last_glyphless_glyph_frame
= it
->f
;
24495 last_glyphless_glyph_face_id
= it
->face_id
;
24496 last_glyphless_glyph_merged_face_id
= face_id
;
24499 if (it
->glyphless_method
== GLYPHLESS_DISPLAY_THIN_SPACE
)
24501 it
->pixel_width
= THIN_SPACE_WIDTH
;
24503 upper_xoff
= upper_yoff
= lower_xoff
= lower_yoff
= 0;
24505 else if (it
->glyphless_method
== GLYPHLESS_DISPLAY_EMPTY_BOX
)
24507 width
= CHAR_WIDTH (it
->c
);
24510 else if (width
> 4)
24512 it
->pixel_width
= base_width
* width
;
24514 upper_xoff
= upper_yoff
= lower_xoff
= lower_yoff
= 0;
24520 unsigned int code
[6];
24522 int ascent
, descent
;
24523 struct font_metrics metrics_upper
, metrics_lower
;
24525 face
= FACE_FROM_ID (it
->f
, face_id
);
24526 font
= face
->font
? face
->font
: FRAME_FONT (it
->f
);
24527 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
24529 if (it
->glyphless_method
== GLYPHLESS_DISPLAY_ACRONYM
)
24531 if (! STRINGP (acronym
) && CHAR_TABLE_P (Vglyphless_char_display
))
24532 acronym
= CHAR_TABLE_REF (Vglyphless_char_display
, it
->c
);
24533 if (CONSP (acronym
))
24534 acronym
= XCAR (acronym
);
24535 str
= STRINGP (acronym
) ? SSDATA (acronym
) : "";
24539 eassert (it
->glyphless_method
== GLYPHLESS_DISPLAY_HEX_CODE
);
24540 sprintf (buf
, "%0*X", it
->c
< 0x10000 ? 4 : 6, it
->c
);
24543 for (len
= 0; str
[len
] && ASCII_BYTE_P (str
[len
]) && len
< 6; len
++)
24544 code
[len
] = font
->driver
->encode_char (font
, str
[len
]);
24545 upper_len
= (len
+ 1) / 2;
24546 font
->driver
->text_extents (font
, code
, upper_len
,
24548 font
->driver
->text_extents (font
, code
+ upper_len
, len
- upper_len
,
24553 /* +4 is for vertical bars of a box plus 1-pixel spaces at both side. */
24554 width
= max (metrics_upper
.width
, metrics_lower
.width
) + 4;
24555 upper_xoff
= upper_yoff
= 2; /* the typical case */
24556 if (base_width
>= width
)
24558 /* Align the upper to the left, the lower to the right. */
24559 it
->pixel_width
= base_width
;
24560 lower_xoff
= base_width
- 2 - metrics_lower
.width
;
24564 /* Center the shorter one. */
24565 it
->pixel_width
= width
;
24566 if (metrics_upper
.width
>= metrics_lower
.width
)
24567 lower_xoff
= (width
- metrics_lower
.width
) / 2;
24570 /* FIXME: This code doesn't look right. It formerly was
24571 missing the "lower_xoff = 0;", which couldn't have
24572 been right since it left lower_xoff uninitialized. */
24574 upper_xoff
= (width
- metrics_upper
.width
) / 2;
24578 /* +5 is for horizontal bars of a box plus 1-pixel spaces at
24579 top, bottom, and between upper and lower strings. */
24580 height
= (metrics_upper
.ascent
+ metrics_upper
.descent
24581 + metrics_lower
.ascent
+ metrics_lower
.descent
) + 5;
24582 /* Center vertically.
24583 H:base_height, D:base_descent
24584 h:height, ld:lower_descent, la:lower_ascent, ud:upper_descent
24586 ascent = - (D - H/2 - h/2 + 1); "+ 1" for rounding up
24587 descent = D - H/2 + h/2;
24588 lower_yoff = descent - 2 - ld;
24589 upper_yoff = lower_yoff - la - 1 - ud; */
24590 ascent
= - (it
->descent
- (base_height
+ height
+ 1) / 2);
24591 descent
= it
->descent
- (base_height
- height
) / 2;
24592 lower_yoff
= descent
- 2 - metrics_lower
.descent
;
24593 upper_yoff
= (lower_yoff
- metrics_lower
.ascent
- 1
24594 - metrics_upper
.descent
);
24595 /* Don't make the height shorter than the base height. */
24596 if (height
> base_height
)
24598 it
->ascent
= ascent
;
24599 it
->descent
= descent
;
24603 it
->phys_ascent
= it
->ascent
;
24604 it
->phys_descent
= it
->descent
;
24606 append_glyphless_glyph (it
, face_id
, for_no_font
, len
,
24607 upper_xoff
, upper_yoff
,
24608 lower_xoff
, lower_yoff
);
24610 take_vertical_position_into_account (it
);
24615 Produce glyphs/get display metrics for the display element IT is
24616 loaded with. See the description of struct it in dispextern.h
24617 for an overview of struct it. */
24620 x_produce_glyphs (struct it
*it
)
24622 int extra_line_spacing
= it
->extra_line_spacing
;
24624 it
->glyph_not_available_p
= 0;
24626 if (it
->what
== IT_CHARACTER
)
24629 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
24630 struct font
*font
= face
->font
;
24631 struct font_metrics
*pcm
= NULL
;
24632 int boff
; /* baseline offset */
24636 /* When no suitable font is found, display this character by
24637 the method specified in the first extra slot of
24638 Vglyphless_char_display. */
24639 Lisp_Object acronym
= lookup_glyphless_char_display (-1, it
);
24641 eassert (it
->what
== IT_GLYPHLESS
);
24642 produce_glyphless_glyph (it
, 1, STRINGP (acronym
) ? acronym
: Qnil
);
24646 boff
= font
->baseline_offset
;
24647 if (font
->vertical_centering
)
24648 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
24650 if (it
->char_to_display
!= '\n' && it
->char_to_display
!= '\t')
24656 if (it
->override_ascent
>= 0)
24658 it
->ascent
= it
->override_ascent
;
24659 it
->descent
= it
->override_descent
;
24660 boff
= it
->override_boff
;
24664 it
->ascent
= FONT_BASE (font
) + boff
;
24665 it
->descent
= FONT_DESCENT (font
) - boff
;
24668 if (get_char_glyph_code (it
->char_to_display
, font
, &char2b
))
24670 pcm
= get_per_char_metric (font
, &char2b
);
24671 if (pcm
->width
== 0
24672 && pcm
->rbearing
== 0 && pcm
->lbearing
== 0)
24678 it
->phys_ascent
= pcm
->ascent
+ boff
;
24679 it
->phys_descent
= pcm
->descent
- boff
;
24680 it
->pixel_width
= pcm
->width
;
24684 it
->glyph_not_available_p
= 1;
24685 it
->phys_ascent
= it
->ascent
;
24686 it
->phys_descent
= it
->descent
;
24687 it
->pixel_width
= font
->space_width
;
24690 if (it
->constrain_row_ascent_descent_p
)
24692 if (it
->descent
> it
->max_descent
)
24694 it
->ascent
+= it
->descent
- it
->max_descent
;
24695 it
->descent
= it
->max_descent
;
24697 if (it
->ascent
> it
->max_ascent
)
24699 it
->descent
= min (it
->max_descent
, it
->descent
+ it
->ascent
- it
->max_ascent
);
24700 it
->ascent
= it
->max_ascent
;
24702 it
->phys_ascent
= min (it
->phys_ascent
, it
->ascent
);
24703 it
->phys_descent
= min (it
->phys_descent
, it
->descent
);
24704 extra_line_spacing
= 0;
24707 /* If this is a space inside a region of text with
24708 `space-width' property, change its width. */
24709 stretched_p
= it
->char_to_display
== ' ' && !NILP (it
->space_width
);
24711 it
->pixel_width
*= XFLOATINT (it
->space_width
);
24713 /* If face has a box, add the box thickness to the character
24714 height. If character has a box line to the left and/or
24715 right, add the box line width to the character's width. */
24716 if (face
->box
!= FACE_NO_BOX
)
24718 int thick
= face
->box_line_width
;
24722 it
->ascent
+= thick
;
24723 it
->descent
+= thick
;
24728 if (it
->start_of_box_run_p
)
24729 it
->pixel_width
+= thick
;
24730 if (it
->end_of_box_run_p
)
24731 it
->pixel_width
+= thick
;
24734 /* If face has an overline, add the height of the overline
24735 (1 pixel) and a 1 pixel margin to the character height. */
24736 if (face
->overline_p
)
24737 it
->ascent
+= overline_margin
;
24739 if (it
->constrain_row_ascent_descent_p
)
24741 if (it
->ascent
> it
->max_ascent
)
24742 it
->ascent
= it
->max_ascent
;
24743 if (it
->descent
> it
->max_descent
)
24744 it
->descent
= it
->max_descent
;
24747 take_vertical_position_into_account (it
);
24749 /* If we have to actually produce glyphs, do it. */
24754 /* Translate a space with a `space-width' property
24755 into a stretch glyph. */
24756 int ascent
= (((it
->ascent
+ it
->descent
) * FONT_BASE (font
))
24757 / FONT_HEIGHT (font
));
24758 append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
24759 it
->ascent
+ it
->descent
, ascent
);
24764 /* If characters with lbearing or rbearing are displayed
24765 in this line, record that fact in a flag of the
24766 glyph row. This is used to optimize X output code. */
24767 if (pcm
&& (pcm
->lbearing
< 0 || pcm
->rbearing
> pcm
->width
))
24768 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
24770 if (! stretched_p
&& it
->pixel_width
== 0)
24771 /* We assure that all visible glyphs have at least 1-pixel
24773 it
->pixel_width
= 1;
24775 else if (it
->char_to_display
== '\n')
24777 /* A newline has no width, but we need the height of the
24778 line. But if previous part of the line sets a height,
24779 don't increase that height */
24781 Lisp_Object height
;
24782 Lisp_Object total_height
= Qnil
;
24784 it
->override_ascent
= -1;
24785 it
->pixel_width
= 0;
24788 height
= get_it_property (it
, Qline_height
);
24789 /* Split (line-height total-height) list */
24791 && CONSP (XCDR (height
))
24792 && NILP (XCDR (XCDR (height
))))
24794 total_height
= XCAR (XCDR (height
));
24795 height
= XCAR (height
);
24797 height
= calc_line_height_property (it
, height
, font
, boff
, 1);
24799 if (it
->override_ascent
>= 0)
24801 it
->ascent
= it
->override_ascent
;
24802 it
->descent
= it
->override_descent
;
24803 boff
= it
->override_boff
;
24807 it
->ascent
= FONT_BASE (font
) + boff
;
24808 it
->descent
= FONT_DESCENT (font
) - boff
;
24811 if (EQ (height
, Qt
))
24813 if (it
->descent
> it
->max_descent
)
24815 it
->ascent
+= it
->descent
- it
->max_descent
;
24816 it
->descent
= it
->max_descent
;
24818 if (it
->ascent
> it
->max_ascent
)
24820 it
->descent
= min (it
->max_descent
, it
->descent
+ it
->ascent
- it
->max_ascent
);
24821 it
->ascent
= it
->max_ascent
;
24823 it
->phys_ascent
= min (it
->phys_ascent
, it
->ascent
);
24824 it
->phys_descent
= min (it
->phys_descent
, it
->descent
);
24825 it
->constrain_row_ascent_descent_p
= 1;
24826 extra_line_spacing
= 0;
24830 Lisp_Object spacing
;
24832 it
->phys_ascent
= it
->ascent
;
24833 it
->phys_descent
= it
->descent
;
24835 if ((it
->max_ascent
> 0 || it
->max_descent
> 0)
24836 && face
->box
!= FACE_NO_BOX
24837 && face
->box_line_width
> 0)
24839 it
->ascent
+= face
->box_line_width
;
24840 it
->descent
+= face
->box_line_width
;
24843 && XINT (height
) > it
->ascent
+ it
->descent
)
24844 it
->ascent
= XINT (height
) - it
->descent
;
24846 if (!NILP (total_height
))
24847 spacing
= calc_line_height_property (it
, total_height
, font
, boff
, 0);
24850 spacing
= get_it_property (it
, Qline_spacing
);
24851 spacing
= calc_line_height_property (it
, spacing
, font
, boff
, 0);
24853 if (INTEGERP (spacing
))
24855 extra_line_spacing
= XINT (spacing
);
24856 if (!NILP (total_height
))
24857 extra_line_spacing
-= (it
->phys_ascent
+ it
->phys_descent
);
24861 else /* i.e. (it->char_to_display == '\t') */
24863 if (font
->space_width
> 0)
24865 int tab_width
= it
->tab_width
* font
->space_width
;
24866 int x
= it
->current_x
+ it
->continuation_lines_width
;
24867 int next_tab_x
= ((1 + x
+ tab_width
- 1) / tab_width
) * tab_width
;
24869 /* If the distance from the current position to the next tab
24870 stop is less than a space character width, use the
24871 tab stop after that. */
24872 if (next_tab_x
- x
< font
->space_width
)
24873 next_tab_x
+= tab_width
;
24875 it
->pixel_width
= next_tab_x
- x
;
24877 it
->ascent
= it
->phys_ascent
= FONT_BASE (font
) + boff
;
24878 it
->descent
= it
->phys_descent
= FONT_DESCENT (font
) - boff
;
24882 append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
24883 it
->ascent
+ it
->descent
, it
->ascent
);
24888 it
->pixel_width
= 0;
24893 else if (it
->what
== IT_COMPOSITION
&& it
->cmp_it
.ch
< 0)
24895 /* A static composition.
24897 Note: A composition is represented as one glyph in the
24898 glyph matrix. There are no padding glyphs.
24900 Important note: pixel_width, ascent, and descent are the
24901 values of what is drawn by draw_glyphs (i.e. the values of
24902 the overall glyphs composed). */
24903 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
24904 int boff
; /* baseline offset */
24905 struct composition
*cmp
= composition_table
[it
->cmp_it
.id
];
24906 int glyph_len
= cmp
->glyph_len
;
24907 struct font
*font
= face
->font
;
24911 /* If we have not yet calculated pixel size data of glyphs of
24912 the composition for the current face font, calculate them
24913 now. Theoretically, we have to check all fonts for the
24914 glyphs, but that requires much time and memory space. So,
24915 here we check only the font of the first glyph. This may
24916 lead to incorrect display, but it's very rare, and C-l
24917 (recenter-top-bottom) can correct the display anyway. */
24918 if (! cmp
->font
|| cmp
->font
!= font
)
24920 /* Ascent and descent of the font of the first character
24921 of this composition (adjusted by baseline offset).
24922 Ascent and descent of overall glyphs should not be less
24923 than these, respectively. */
24924 int font_ascent
, font_descent
, font_height
;
24925 /* Bounding box of the overall glyphs. */
24926 int leftmost
, rightmost
, lowest
, highest
;
24927 int lbearing
, rbearing
;
24928 int i
, width
, ascent
, descent
;
24929 int left_padded
= 0, right_padded
= 0;
24930 int c
IF_LINT (= 0); /* cmp->glyph_len can't be zero; see Bug#8512 */
24932 struct font_metrics
*pcm
;
24933 int font_not_found_p
;
24936 for (glyph_len
= cmp
->glyph_len
; glyph_len
> 0; glyph_len
--)
24937 if ((c
= COMPOSITION_GLYPH (cmp
, glyph_len
- 1)) != '\t')
24939 if (glyph_len
< cmp
->glyph_len
)
24941 for (i
= 0; i
< glyph_len
; i
++)
24943 if ((c
= COMPOSITION_GLYPH (cmp
, i
)) != '\t')
24945 cmp
->offsets
[i
* 2] = cmp
->offsets
[i
* 2 + 1] = 0;
24950 pos
= (STRINGP (it
->string
) ? IT_STRING_CHARPOS (*it
)
24951 : IT_CHARPOS (*it
));
24952 /* If no suitable font is found, use the default font. */
24953 font_not_found_p
= font
== NULL
;
24954 if (font_not_found_p
)
24956 face
= face
->ascii_face
;
24959 boff
= font
->baseline_offset
;
24960 if (font
->vertical_centering
)
24961 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
24962 font_ascent
= FONT_BASE (font
) + boff
;
24963 font_descent
= FONT_DESCENT (font
) - boff
;
24964 font_height
= FONT_HEIGHT (font
);
24969 if (! font_not_found_p
)
24971 get_char_face_and_encoding (it
->f
, c
, it
->face_id
,
24973 pcm
= get_per_char_metric (font
, &char2b
);
24976 /* Initialize the bounding box. */
24979 width
= cmp
->glyph_len
> 0 ? pcm
->width
: 0;
24980 ascent
= pcm
->ascent
;
24981 descent
= pcm
->descent
;
24982 lbearing
= pcm
->lbearing
;
24983 rbearing
= pcm
->rbearing
;
24987 width
= cmp
->glyph_len
> 0 ? font
->space_width
: 0;
24988 ascent
= FONT_BASE (font
);
24989 descent
= FONT_DESCENT (font
);
24996 lowest
= - descent
+ boff
;
24997 highest
= ascent
+ boff
;
24999 if (! font_not_found_p
25000 && font
->default_ascent
25001 && CHAR_TABLE_P (Vuse_default_ascent
)
25002 && !NILP (Faref (Vuse_default_ascent
,
25003 make_number (it
->char_to_display
))))
25004 highest
= font
->default_ascent
+ boff
;
25006 /* Draw the first glyph at the normal position. It may be
25007 shifted to right later if some other glyphs are drawn
25009 cmp
->offsets
[i
* 2] = 0;
25010 cmp
->offsets
[i
* 2 + 1] = boff
;
25011 cmp
->lbearing
= lbearing
;
25012 cmp
->rbearing
= rbearing
;
25014 /* Set cmp->offsets for the remaining glyphs. */
25015 for (i
++; i
< glyph_len
; i
++)
25017 int left
, right
, btm
, top
;
25018 int ch
= COMPOSITION_GLYPH (cmp
, i
);
25020 struct face
*this_face
;
25024 face_id
= FACE_FOR_CHAR (it
->f
, face
, ch
, pos
, it
->string
);
25025 this_face
= FACE_FROM_ID (it
->f
, face_id
);
25026 font
= this_face
->font
;
25032 get_char_face_and_encoding (it
->f
, ch
, face_id
,
25034 pcm
= get_per_char_metric (font
, &char2b
);
25037 cmp
->offsets
[i
* 2] = cmp
->offsets
[i
* 2 + 1] = 0;
25040 width
= pcm
->width
;
25041 ascent
= pcm
->ascent
;
25042 descent
= pcm
->descent
;
25043 lbearing
= pcm
->lbearing
;
25044 rbearing
= pcm
->rbearing
;
25045 if (cmp
->method
!= COMPOSITION_WITH_RULE_ALTCHARS
)
25047 /* Relative composition with or without
25048 alternate chars. */
25049 left
= (leftmost
+ rightmost
- width
) / 2;
25050 btm
= - descent
+ boff
;
25051 if (font
->relative_compose
25052 && (! CHAR_TABLE_P (Vignore_relative_composition
)
25053 || NILP (Faref (Vignore_relative_composition
,
25054 make_number (ch
)))))
25057 if (- descent
>= font
->relative_compose
)
25058 /* One extra pixel between two glyphs. */
25060 else if (ascent
<= 0)
25061 /* One extra pixel between two glyphs. */
25062 btm
= lowest
- 1 - ascent
- descent
;
25067 /* A composition rule is specified by an integer
25068 value that encodes global and new reference
25069 points (GREF and NREF). GREF and NREF are
25070 specified by numbers as below:
25072 0---1---2 -- ascent
25076 9--10--11 -- center
25078 ---3---4---5--- baseline
25080 6---7---8 -- descent
25082 int rule
= COMPOSITION_RULE (cmp
, i
);
25083 int gref
, nref
, grefx
, grefy
, nrefx
, nrefy
, xoff
, yoff
;
25085 COMPOSITION_DECODE_RULE (rule
, gref
, nref
, xoff
, yoff
);
25086 grefx
= gref
% 3, nrefx
= nref
% 3;
25087 grefy
= gref
/ 3, nrefy
= nref
/ 3;
25089 xoff
= font_height
* (xoff
- 128) / 256;
25091 yoff
= font_height
* (yoff
- 128) / 256;
25094 + grefx
* (rightmost
- leftmost
) / 2
25095 - nrefx
* width
/ 2
25098 btm
= ((grefy
== 0 ? highest
25100 : grefy
== 2 ? lowest
25101 : (highest
+ lowest
) / 2)
25102 - (nrefy
== 0 ? ascent
+ descent
25103 : nrefy
== 1 ? descent
- boff
25105 : (ascent
+ descent
) / 2)
25109 cmp
->offsets
[i
* 2] = left
;
25110 cmp
->offsets
[i
* 2 + 1] = btm
+ descent
;
25112 /* Update the bounding box of the overall glyphs. */
25115 right
= left
+ width
;
25116 if (left
< leftmost
)
25118 if (right
> rightmost
)
25121 top
= btm
+ descent
+ ascent
;
25127 if (cmp
->lbearing
> left
+ lbearing
)
25128 cmp
->lbearing
= left
+ lbearing
;
25129 if (cmp
->rbearing
< left
+ rbearing
)
25130 cmp
->rbearing
= left
+ rbearing
;
25134 /* If there are glyphs whose x-offsets are negative,
25135 shift all glyphs to the right and make all x-offsets
25139 for (i
= 0; i
< cmp
->glyph_len
; i
++)
25140 cmp
->offsets
[i
* 2] -= leftmost
;
25141 rightmost
-= leftmost
;
25142 cmp
->lbearing
-= leftmost
;
25143 cmp
->rbearing
-= leftmost
;
25146 if (left_padded
&& cmp
->lbearing
< 0)
25148 for (i
= 0; i
< cmp
->glyph_len
; i
++)
25149 cmp
->offsets
[i
* 2] -= cmp
->lbearing
;
25150 rightmost
-= cmp
->lbearing
;
25151 cmp
->rbearing
-= cmp
->lbearing
;
25154 if (right_padded
&& rightmost
< cmp
->rbearing
)
25156 rightmost
= cmp
->rbearing
;
25159 cmp
->pixel_width
= rightmost
;
25160 cmp
->ascent
= highest
;
25161 cmp
->descent
= - lowest
;
25162 if (cmp
->ascent
< font_ascent
)
25163 cmp
->ascent
= font_ascent
;
25164 if (cmp
->descent
< font_descent
)
25165 cmp
->descent
= font_descent
;
25169 && (cmp
->lbearing
< 0
25170 || cmp
->rbearing
> cmp
->pixel_width
))
25171 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
25173 it
->pixel_width
= cmp
->pixel_width
;
25174 it
->ascent
= it
->phys_ascent
= cmp
->ascent
;
25175 it
->descent
= it
->phys_descent
= cmp
->descent
;
25176 if (face
->box
!= FACE_NO_BOX
)
25178 int thick
= face
->box_line_width
;
25182 it
->ascent
+= thick
;
25183 it
->descent
+= thick
;
25188 if (it
->start_of_box_run_p
)
25189 it
->pixel_width
+= thick
;
25190 if (it
->end_of_box_run_p
)
25191 it
->pixel_width
+= thick
;
25194 /* If face has an overline, add the height of the overline
25195 (1 pixel) and a 1 pixel margin to the character height. */
25196 if (face
->overline_p
)
25197 it
->ascent
+= overline_margin
;
25199 take_vertical_position_into_account (it
);
25200 if (it
->ascent
< 0)
25202 if (it
->descent
< 0)
25205 if (it
->glyph_row
&& cmp
->glyph_len
> 0)
25206 append_composite_glyph (it
);
25208 else if (it
->what
== IT_COMPOSITION
)
25210 /* A dynamic (automatic) composition. */
25211 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
25212 Lisp_Object gstring
;
25213 struct font_metrics metrics
;
25217 gstring
= composition_gstring_from_id (it
->cmp_it
.id
);
25219 = composition_gstring_width (gstring
, it
->cmp_it
.from
, it
->cmp_it
.to
,
25222 && (metrics
.lbearing
< 0 || metrics
.rbearing
> metrics
.width
))
25223 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
25224 it
->ascent
= it
->phys_ascent
= metrics
.ascent
;
25225 it
->descent
= it
->phys_descent
= metrics
.descent
;
25226 if (face
->box
!= FACE_NO_BOX
)
25228 int thick
= face
->box_line_width
;
25232 it
->ascent
+= thick
;
25233 it
->descent
+= thick
;
25238 if (it
->start_of_box_run_p
)
25239 it
->pixel_width
+= thick
;
25240 if (it
->end_of_box_run_p
)
25241 it
->pixel_width
+= thick
;
25243 /* If face has an overline, add the height of the overline
25244 (1 pixel) and a 1 pixel margin to the character height. */
25245 if (face
->overline_p
)
25246 it
->ascent
+= overline_margin
;
25247 take_vertical_position_into_account (it
);
25248 if (it
->ascent
< 0)
25250 if (it
->descent
< 0)
25254 append_composite_glyph (it
);
25256 else if (it
->what
== IT_GLYPHLESS
)
25257 produce_glyphless_glyph (it
, 0, Qnil
);
25258 else if (it
->what
== IT_IMAGE
)
25259 produce_image_glyph (it
);
25260 else if (it
->what
== IT_STRETCH
)
25261 produce_stretch_glyph (it
);
25264 /* Accumulate dimensions. Note: can't assume that it->descent > 0
25265 because this isn't true for images with `:ascent 100'. */
25266 eassert (it
->ascent
>= 0 && it
->descent
>= 0);
25267 if (it
->area
== TEXT_AREA
)
25268 it
->current_x
+= it
->pixel_width
;
25270 if (extra_line_spacing
> 0)
25272 it
->descent
+= extra_line_spacing
;
25273 if (extra_line_spacing
> it
->max_extra_line_spacing
)
25274 it
->max_extra_line_spacing
= extra_line_spacing
;
25277 it
->max_ascent
= max (it
->max_ascent
, it
->ascent
);
25278 it
->max_descent
= max (it
->max_descent
, it
->descent
);
25279 it
->max_phys_ascent
= max (it
->max_phys_ascent
, it
->phys_ascent
);
25280 it
->max_phys_descent
= max (it
->max_phys_descent
, it
->phys_descent
);
25284 Output LEN glyphs starting at START at the nominal cursor position.
25285 Advance the nominal cursor over the text. The global variable
25286 updated_window contains the window being updated, updated_row is
25287 the glyph row being updated, and updated_area is the area of that
25288 row being updated. */
25291 x_write_glyphs (struct glyph
*start
, int len
)
25293 int x
, hpos
, chpos
= updated_window
->phys_cursor
.hpos
;
25295 eassert (updated_window
&& updated_row
);
25296 /* When the window is hscrolled, cursor hpos can legitimately be out
25297 of bounds, but we draw the cursor at the corresponding window
25298 margin in that case. */
25299 if (!updated_row
->reversed_p
&& chpos
< 0)
25301 if (updated_row
->reversed_p
&& chpos
>= updated_row
->used
[TEXT_AREA
])
25302 chpos
= updated_row
->used
[TEXT_AREA
] - 1;
25306 /* Write glyphs. */
25308 hpos
= start
- updated_row
->glyphs
[updated_area
];
25309 x
= draw_glyphs (updated_window
, output_cursor
.x
,
25310 updated_row
, updated_area
,
25312 DRAW_NORMAL_TEXT
, 0);
25314 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
25315 if (updated_area
== TEXT_AREA
25316 && updated_window
->phys_cursor_on_p
25317 && updated_window
->phys_cursor
.vpos
== output_cursor
.vpos
25319 && chpos
< hpos
+ len
)
25320 updated_window
->phys_cursor_on_p
= 0;
25324 /* Advance the output cursor. */
25325 output_cursor
.hpos
+= len
;
25326 output_cursor
.x
= x
;
25331 Insert LEN glyphs from START at the nominal cursor position. */
25334 x_insert_glyphs (struct glyph
*start
, int len
)
25338 int line_height
, shift_by_width
, shifted_region_width
;
25339 struct glyph_row
*row
;
25340 struct glyph
*glyph
;
25341 int frame_x
, frame_y
;
25344 eassert (updated_window
&& updated_row
);
25346 w
= updated_window
;
25347 f
= XFRAME (WINDOW_FRAME (w
));
25349 /* Get the height of the line we are in. */
25351 line_height
= row
->height
;
25353 /* Get the width of the glyphs to insert. */
25354 shift_by_width
= 0;
25355 for (glyph
= start
; glyph
< start
+ len
; ++glyph
)
25356 shift_by_width
+= glyph
->pixel_width
;
25358 /* Get the width of the region to shift right. */
25359 shifted_region_width
= (window_box_width (w
, updated_area
)
25364 frame_x
= window_box_left (w
, updated_area
) + output_cursor
.x
;
25365 frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, output_cursor
.y
);
25367 FRAME_RIF (f
)->shift_glyphs_for_insert (f
, frame_x
, frame_y
, shifted_region_width
,
25368 line_height
, shift_by_width
);
25370 /* Write the glyphs. */
25371 hpos
= start
- row
->glyphs
[updated_area
];
25372 draw_glyphs (w
, output_cursor
.x
, row
, updated_area
,
25374 DRAW_NORMAL_TEXT
, 0);
25376 /* Advance the output cursor. */
25377 output_cursor
.hpos
+= len
;
25378 output_cursor
.x
+= shift_by_width
;
25384 Erase the current text line from the nominal cursor position
25385 (inclusive) to pixel column TO_X (exclusive). The idea is that
25386 everything from TO_X onward is already erased.
25388 TO_X is a pixel position relative to updated_area of
25389 updated_window. TO_X == -1 means clear to the end of this area. */
25392 x_clear_end_of_line (int to_x
)
25395 struct window
*w
= updated_window
;
25396 int max_x
, min_y
, max_y
;
25397 int from_x
, from_y
, to_y
;
25399 eassert (updated_window
&& updated_row
);
25400 f
= XFRAME (w
->frame
);
25402 if (updated_row
->full_width_p
)
25403 max_x
= WINDOW_TOTAL_WIDTH (w
);
25405 max_x
= window_box_width (w
, updated_area
);
25406 max_y
= window_text_bottom_y (w
);
25408 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
25409 of window. For TO_X > 0, truncate to end of drawing area. */
25415 to_x
= min (to_x
, max_x
);
25417 to_y
= min (max_y
, output_cursor
.y
+ updated_row
->height
);
25419 /* Notice if the cursor will be cleared by this operation. */
25420 if (!updated_row
->full_width_p
)
25421 notice_overwritten_cursor (w
, updated_area
,
25422 output_cursor
.x
, -1,
25424 MATRIX_ROW_BOTTOM_Y (updated_row
));
25426 from_x
= output_cursor
.x
;
25428 /* Translate to frame coordinates. */
25429 if (updated_row
->full_width_p
)
25431 from_x
= WINDOW_TO_FRAME_PIXEL_X (w
, from_x
);
25432 to_x
= WINDOW_TO_FRAME_PIXEL_X (w
, to_x
);
25436 int area_left
= window_box_left (w
, updated_area
);
25437 from_x
+= area_left
;
25441 min_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
25442 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (min_y
, output_cursor
.y
));
25443 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, to_y
);
25445 /* Prevent inadvertently clearing to end of the X window. */
25446 if (to_x
> from_x
&& to_y
> from_y
)
25449 FRAME_RIF (f
)->clear_frame_area (f
, from_x
, from_y
,
25450 to_x
- from_x
, to_y
- from_y
);
25455 #endif /* HAVE_WINDOW_SYSTEM */
25459 /***********************************************************************
25461 ***********************************************************************/
25463 /* Value is the internal representation of the specified cursor type
25464 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
25465 of the bar cursor. */
25467 static enum text_cursor_kinds
25468 get_specified_cursor_type (Lisp_Object arg
, int *width
)
25470 enum text_cursor_kinds type
;
25475 if (EQ (arg
, Qbox
))
25476 return FILLED_BOX_CURSOR
;
25478 if (EQ (arg
, Qhollow
))
25479 return HOLLOW_BOX_CURSOR
;
25481 if (EQ (arg
, Qbar
))
25488 && EQ (XCAR (arg
), Qbar
)
25489 && RANGED_INTEGERP (0, XCDR (arg
), INT_MAX
))
25491 *width
= XINT (XCDR (arg
));
25495 if (EQ (arg
, Qhbar
))
25498 return HBAR_CURSOR
;
25502 && EQ (XCAR (arg
), Qhbar
)
25503 && RANGED_INTEGERP (0, XCDR (arg
), INT_MAX
))
25505 *width
= XINT (XCDR (arg
));
25506 return HBAR_CURSOR
;
25509 /* Treat anything unknown as "hollow box cursor".
25510 It was bad to signal an error; people have trouble fixing
25511 .Xdefaults with Emacs, when it has something bad in it. */
25512 type
= HOLLOW_BOX_CURSOR
;
25517 /* Set the default cursor types for specified frame. */
25519 set_frame_cursor_types (struct frame
*f
, Lisp_Object arg
)
25524 FRAME_DESIRED_CURSOR (f
) = get_specified_cursor_type (arg
, &width
);
25525 FRAME_CURSOR_WIDTH (f
) = width
;
25527 /* By default, set up the blink-off state depending on the on-state. */
25529 tem
= Fassoc (arg
, Vblink_cursor_alist
);
25532 FRAME_BLINK_OFF_CURSOR (f
)
25533 = get_specified_cursor_type (XCDR (tem
), &width
);
25534 FRAME_BLINK_OFF_CURSOR_WIDTH (f
) = width
;
25537 FRAME_BLINK_OFF_CURSOR (f
) = DEFAULT_CURSOR
;
25541 #ifdef HAVE_WINDOW_SYSTEM
25543 /* Return the cursor we want to be displayed in window W. Return
25544 width of bar/hbar cursor through WIDTH arg. Return with
25545 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
25546 (i.e. if the `system caret' should track this cursor).
25548 In a mini-buffer window, we want the cursor only to appear if we
25549 are reading input from this window. For the selected window, we
25550 want the cursor type given by the frame parameter or buffer local
25551 setting of cursor-type. If explicitly marked off, draw no cursor.
25552 In all other cases, we want a hollow box cursor. */
25554 static enum text_cursor_kinds
25555 get_window_cursor_type (struct window
*w
, struct glyph
*glyph
, int *width
,
25556 int *active_cursor
)
25558 struct frame
*f
= XFRAME (w
->frame
);
25559 struct buffer
*b
= XBUFFER (w
->contents
);
25560 int cursor_type
= DEFAULT_CURSOR
;
25561 Lisp_Object alt_cursor
;
25562 int non_selected
= 0;
25564 *active_cursor
= 1;
25567 if (cursor_in_echo_area
25568 && FRAME_HAS_MINIBUF_P (f
)
25569 && EQ (FRAME_MINIBUF_WINDOW (f
), echo_area_window
))
25571 if (w
== XWINDOW (echo_area_window
))
25573 if (EQ (BVAR (b
, cursor_type
), Qt
) || NILP (BVAR (b
, cursor_type
)))
25575 *width
= FRAME_CURSOR_WIDTH (f
);
25576 return FRAME_DESIRED_CURSOR (f
);
25579 return get_specified_cursor_type (BVAR (b
, cursor_type
), width
);
25582 *active_cursor
= 0;
25586 /* Detect a nonselected window or nonselected frame. */
25587 else if (w
!= XWINDOW (f
->selected_window
)
25588 || f
!= FRAME_X_DISPLAY_INFO (f
)->x_highlight_frame
)
25590 *active_cursor
= 0;
25592 if (MINI_WINDOW_P (w
) && minibuf_level
== 0)
25598 /* Never display a cursor in a window in which cursor-type is nil. */
25599 if (NILP (BVAR (b
, cursor_type
)))
25602 /* Get the normal cursor type for this window. */
25603 if (EQ (BVAR (b
, cursor_type
), Qt
))
25605 cursor_type
= FRAME_DESIRED_CURSOR (f
);
25606 *width
= FRAME_CURSOR_WIDTH (f
);
25609 cursor_type
= get_specified_cursor_type (BVAR (b
, cursor_type
), width
);
25611 /* Use cursor-in-non-selected-windows instead
25612 for non-selected window or frame. */
25615 alt_cursor
= BVAR (b
, cursor_in_non_selected_windows
);
25616 if (!EQ (Qt
, alt_cursor
))
25617 return get_specified_cursor_type (alt_cursor
, width
);
25618 /* t means modify the normal cursor type. */
25619 if (cursor_type
== FILLED_BOX_CURSOR
)
25620 cursor_type
= HOLLOW_BOX_CURSOR
;
25621 else if (cursor_type
== BAR_CURSOR
&& *width
> 1)
25623 return cursor_type
;
25626 /* Use normal cursor if not blinked off. */
25627 if (!w
->cursor_off_p
)
25629 if (glyph
!= NULL
&& glyph
->type
== IMAGE_GLYPH
)
25631 if (cursor_type
== FILLED_BOX_CURSOR
)
25633 /* Using a block cursor on large images can be very annoying.
25634 So use a hollow cursor for "large" images.
25635 If image is not transparent (no mask), also use hollow cursor. */
25636 struct image
*img
= IMAGE_FROM_ID (f
, glyph
->u
.img_id
);
25637 if (img
!= NULL
&& IMAGEP (img
->spec
))
25639 /* Arbitrarily, interpret "Large" as >32x32 and >NxN
25640 where N = size of default frame font size.
25641 This should cover most of the "tiny" icons people may use. */
25643 || img
->width
> max (32, WINDOW_FRAME_COLUMN_WIDTH (w
))
25644 || img
->height
> max (32, WINDOW_FRAME_LINE_HEIGHT (w
)))
25645 cursor_type
= HOLLOW_BOX_CURSOR
;
25648 else if (cursor_type
!= NO_CURSOR
)
25650 /* Display current only supports BOX and HOLLOW cursors for images.
25651 So for now, unconditionally use a HOLLOW cursor when cursor is
25652 not a solid box cursor. */
25653 cursor_type
= HOLLOW_BOX_CURSOR
;
25656 return cursor_type
;
25659 /* Cursor is blinked off, so determine how to "toggle" it. */
25661 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
25662 if ((alt_cursor
= Fassoc (BVAR (b
, cursor_type
), Vblink_cursor_alist
), !NILP (alt_cursor
)))
25663 return get_specified_cursor_type (XCDR (alt_cursor
), width
);
25665 /* Then see if frame has specified a specific blink off cursor type. */
25666 if (FRAME_BLINK_OFF_CURSOR (f
) != DEFAULT_CURSOR
)
25668 *width
= FRAME_BLINK_OFF_CURSOR_WIDTH (f
);
25669 return FRAME_BLINK_OFF_CURSOR (f
);
25673 /* Some people liked having a permanently visible blinking cursor,
25674 while others had very strong opinions against it. So it was
25675 decided to remove it. KFS 2003-09-03 */
25677 /* Finally perform built-in cursor blinking:
25678 filled box <-> hollow box
25679 wide [h]bar <-> narrow [h]bar
25680 narrow [h]bar <-> no cursor
25681 other type <-> no cursor */
25683 if (cursor_type
== FILLED_BOX_CURSOR
)
25684 return HOLLOW_BOX_CURSOR
;
25686 if ((cursor_type
== BAR_CURSOR
|| cursor_type
== HBAR_CURSOR
) && *width
> 1)
25689 return cursor_type
;
25697 /* Notice when the text cursor of window W has been completely
25698 overwritten by a drawing operation that outputs glyphs in AREA
25699 starting at X0 and ending at X1 in the line starting at Y0 and
25700 ending at Y1. X coordinates are area-relative. X1 < 0 means all
25701 the rest of the line after X0 has been written. Y coordinates
25702 are window-relative. */
25705 notice_overwritten_cursor (struct window
*w
, enum glyph_row_area area
,
25706 int x0
, int x1
, int y0
, int y1
)
25708 int cx0
, cx1
, cy0
, cy1
;
25709 struct glyph_row
*row
;
25711 if (!w
->phys_cursor_on_p
)
25713 if (area
!= TEXT_AREA
)
25716 if (w
->phys_cursor
.vpos
< 0
25717 || w
->phys_cursor
.vpos
>= w
->current_matrix
->nrows
25718 || (row
= w
->current_matrix
->rows
+ w
->phys_cursor
.vpos
,
25719 !(row
->enabled_p
&& MATRIX_ROW_DISPLAYS_TEXT_P (row
))))
25722 if (row
->cursor_in_fringe_p
)
25724 row
->cursor_in_fringe_p
= 0;
25725 draw_fringe_bitmap (w
, row
, row
->reversed_p
);
25726 w
->phys_cursor_on_p
= 0;
25730 cx0
= w
->phys_cursor
.x
;
25731 cx1
= cx0
+ w
->phys_cursor_width
;
25732 if (x0
> cx0
|| (x1
>= 0 && x1
< cx1
))
25735 /* The cursor image will be completely removed from the
25736 screen if the output area intersects the cursor area in
25737 y-direction. When we draw in [y0 y1[, and some part of
25738 the cursor is at y < y0, that part must have been drawn
25739 before. When scrolling, the cursor is erased before
25740 actually scrolling, so we don't come here. When not
25741 scrolling, the rows above the old cursor row must have
25742 changed, and in this case these rows must have written
25743 over the cursor image.
25745 Likewise if part of the cursor is below y1, with the
25746 exception of the cursor being in the first blank row at
25747 the buffer and window end because update_text_area
25748 doesn't draw that row. (Except when it does, but
25749 that's handled in update_text_area.) */
25751 cy0
= w
->phys_cursor
.y
;
25752 cy1
= cy0
+ w
->phys_cursor_height
;
25753 if ((y0
< cy0
|| y0
>= cy1
) && (y1
<= cy0
|| y1
>= cy1
))
25756 w
->phys_cursor_on_p
= 0;
25759 #endif /* HAVE_WINDOW_SYSTEM */
25762 /************************************************************************
25764 ************************************************************************/
25766 #ifdef HAVE_WINDOW_SYSTEM
25769 Fix the display of area AREA of overlapping row ROW in window W
25770 with respect to the overlapping part OVERLAPS. */
25773 x_fix_overlapping_area (struct window
*w
, struct glyph_row
*row
,
25774 enum glyph_row_area area
, int overlaps
)
25781 for (i
= 0; i
< row
->used
[area
];)
25783 if (row
->glyphs
[area
][i
].overlaps_vertically_p
)
25785 int start
= i
, start_x
= x
;
25789 x
+= row
->glyphs
[area
][i
].pixel_width
;
25792 while (i
< row
->used
[area
]
25793 && row
->glyphs
[area
][i
].overlaps_vertically_p
);
25795 draw_glyphs (w
, start_x
, row
, area
,
25797 DRAW_NORMAL_TEXT
, overlaps
);
25801 x
+= row
->glyphs
[area
][i
].pixel_width
;
25811 Draw the cursor glyph of window W in glyph row ROW. See the
25812 comment of draw_glyphs for the meaning of HL. */
25815 draw_phys_cursor_glyph (struct window
*w
, struct glyph_row
*row
,
25816 enum draw_glyphs_face hl
)
25818 /* If cursor hpos is out of bounds, don't draw garbage. This can
25819 happen in mini-buffer windows when switching between echo area
25820 glyphs and mini-buffer. */
25821 if ((row
->reversed_p
25822 ? (w
->phys_cursor
.hpos
>= 0)
25823 : (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])))
25825 int on_p
= w
->phys_cursor_on_p
;
25827 int hpos
= w
->phys_cursor
.hpos
;
25829 /* When the window is hscrolled, cursor hpos can legitimately be
25830 out of bounds, but we draw the cursor at the corresponding
25831 window margin in that case. */
25832 if (!row
->reversed_p
&& hpos
< 0)
25834 if (row
->reversed_p
&& hpos
>= row
->used
[TEXT_AREA
])
25835 hpos
= row
->used
[TEXT_AREA
] - 1;
25837 x1
= draw_glyphs (w
, w
->phys_cursor
.x
, row
, TEXT_AREA
, hpos
, hpos
+ 1,
25839 w
->phys_cursor_on_p
= on_p
;
25841 if (hl
== DRAW_CURSOR
)
25842 w
->phys_cursor_width
= x1
- w
->phys_cursor
.x
;
25843 /* When we erase the cursor, and ROW is overlapped by other
25844 rows, make sure that these overlapping parts of other rows
25846 else if (hl
== DRAW_NORMAL_TEXT
&& row
->overlapped_p
)
25848 w
->phys_cursor_width
= x1
- w
->phys_cursor
.x
;
25850 if (row
> w
->current_matrix
->rows
25851 && MATRIX_ROW_OVERLAPS_SUCC_P (row
- 1))
25852 x_fix_overlapping_area (w
, row
- 1, TEXT_AREA
,
25853 OVERLAPS_ERASED_CURSOR
);
25855 if (MATRIX_ROW_BOTTOM_Y (row
) < window_text_bottom_y (w
)
25856 && MATRIX_ROW_OVERLAPS_PRED_P (row
+ 1))
25857 x_fix_overlapping_area (w
, row
+ 1, TEXT_AREA
,
25858 OVERLAPS_ERASED_CURSOR
);
25865 Erase the image of a cursor of window W from the screen. */
25868 erase_phys_cursor (struct window
*w
)
25870 struct frame
*f
= XFRAME (w
->frame
);
25871 Mouse_HLInfo
*hlinfo
= MOUSE_HL_INFO (f
);
25872 int hpos
= w
->phys_cursor
.hpos
;
25873 int vpos
= w
->phys_cursor
.vpos
;
25874 int mouse_face_here_p
= 0;
25875 struct glyph_matrix
*active_glyphs
= w
->current_matrix
;
25876 struct glyph_row
*cursor_row
;
25877 struct glyph
*cursor_glyph
;
25878 enum draw_glyphs_face hl
;
25880 /* No cursor displayed or row invalidated => nothing to do on the
25882 if (w
->phys_cursor_type
== NO_CURSOR
)
25883 goto mark_cursor_off
;
25885 /* VPOS >= active_glyphs->nrows means that window has been resized.
25886 Don't bother to erase the cursor. */
25887 if (vpos
>= active_glyphs
->nrows
)
25888 goto mark_cursor_off
;
25890 /* If row containing cursor is marked invalid, there is nothing we
25892 cursor_row
= MATRIX_ROW (active_glyphs
, vpos
);
25893 if (!cursor_row
->enabled_p
)
25894 goto mark_cursor_off
;
25896 /* If line spacing is > 0, old cursor may only be partially visible in
25897 window after split-window. So adjust visible height. */
25898 cursor_row
->visible_height
= min (cursor_row
->visible_height
,
25899 window_text_bottom_y (w
) - cursor_row
->y
);
25901 /* If row is completely invisible, don't attempt to delete a cursor which
25902 isn't there. This can happen if cursor is at top of a window, and
25903 we switch to a buffer with a header line in that window. */
25904 if (cursor_row
->visible_height
<= 0)
25905 goto mark_cursor_off
;
25907 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
25908 if (cursor_row
->cursor_in_fringe_p
)
25910 cursor_row
->cursor_in_fringe_p
= 0;
25911 draw_fringe_bitmap (w
, cursor_row
, cursor_row
->reversed_p
);
25912 goto mark_cursor_off
;
25915 /* This can happen when the new row is shorter than the old one.
25916 In this case, either draw_glyphs or clear_end_of_line
25917 should have cleared the cursor. Note that we wouldn't be
25918 able to erase the cursor in this case because we don't have a
25919 cursor glyph at hand. */
25920 if ((cursor_row
->reversed_p
25921 ? (w
->phys_cursor
.hpos
< 0)
25922 : (w
->phys_cursor
.hpos
>= cursor_row
->used
[TEXT_AREA
])))
25923 goto mark_cursor_off
;
25925 /* When the window is hscrolled, cursor hpos can legitimately be out
25926 of bounds, but we draw the cursor at the corresponding window
25927 margin in that case. */
25928 if (!cursor_row
->reversed_p
&& hpos
< 0)
25930 if (cursor_row
->reversed_p
&& hpos
>= cursor_row
->used
[TEXT_AREA
])
25931 hpos
= cursor_row
->used
[TEXT_AREA
] - 1;
25933 /* If the cursor is in the mouse face area, redisplay that when
25934 we clear the cursor. */
25935 if (! NILP (hlinfo
->mouse_face_window
)
25936 && coords_in_mouse_face_p (w
, hpos
, vpos
)
25937 /* Don't redraw the cursor's spot in mouse face if it is at the
25938 end of a line (on a newline). The cursor appears there, but
25939 mouse highlighting does not. */
25940 && cursor_row
->used
[TEXT_AREA
] > hpos
&& hpos
>= 0)
25941 mouse_face_here_p
= 1;
25943 /* Maybe clear the display under the cursor. */
25944 if (w
->phys_cursor_type
== HOLLOW_BOX_CURSOR
)
25947 int header_line_height
= WINDOW_HEADER_LINE_HEIGHT (w
);
25950 cursor_glyph
= get_phys_cursor_glyph (w
);
25951 if (cursor_glyph
== NULL
)
25952 goto mark_cursor_off
;
25954 width
= cursor_glyph
->pixel_width
;
25955 left_x
= window_box_left_offset (w
, TEXT_AREA
);
25956 x
= w
->phys_cursor
.x
;
25958 width
-= left_x
- x
;
25959 width
= min (width
, window_box_width (w
, TEXT_AREA
) - x
);
25960 y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
, cursor_row
->y
));
25961 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, max (x
, left_x
));
25964 FRAME_RIF (f
)->clear_frame_area (f
, x
, y
, width
, cursor_row
->visible_height
);
25967 /* Erase the cursor by redrawing the character underneath it. */
25968 if (mouse_face_here_p
)
25969 hl
= DRAW_MOUSE_FACE
;
25971 hl
= DRAW_NORMAL_TEXT
;
25972 draw_phys_cursor_glyph (w
, cursor_row
, hl
);
25975 w
->phys_cursor_on_p
= 0;
25976 w
->phys_cursor_type
= NO_CURSOR
;
25981 Display or clear cursor of window W. If ON is zero, clear the
25982 cursor. If it is non-zero, display the cursor. If ON is nonzero,
25983 where to put the cursor is specified by HPOS, VPOS, X and Y. */
25986 display_and_set_cursor (struct window
*w
, int on
,
25987 int hpos
, int vpos
, int x
, int y
)
25989 struct frame
*f
= XFRAME (w
->frame
);
25990 int new_cursor_type
;
25991 int new_cursor_width
;
25993 struct glyph_row
*glyph_row
;
25994 struct glyph
*glyph
;
25996 /* This is pointless on invisible frames, and dangerous on garbaged
25997 windows and frames; in the latter case, the frame or window may
25998 be in the midst of changing its size, and x and y may be off the
26000 if (! FRAME_VISIBLE_P (f
)
26001 || FRAME_GARBAGED_P (f
)
26002 || vpos
>= w
->current_matrix
->nrows
26003 || hpos
>= w
->current_matrix
->matrix_w
)
26006 /* If cursor is off and we want it off, return quickly. */
26007 if (!on
&& !w
->phys_cursor_on_p
)
26010 glyph_row
= MATRIX_ROW (w
->current_matrix
, vpos
);
26011 /* If cursor row is not enabled, we don't really know where to
26012 display the cursor. */
26013 if (!glyph_row
->enabled_p
)
26015 w
->phys_cursor_on_p
= 0;
26020 if (!glyph_row
->exact_window_width_line_p
26021 || (0 <= hpos
&& hpos
< glyph_row
->used
[TEXT_AREA
]))
26022 glyph
= glyph_row
->glyphs
[TEXT_AREA
] + hpos
;
26024 eassert (input_blocked_p ());
26026 /* Set new_cursor_type to the cursor we want to be displayed. */
26027 new_cursor_type
= get_window_cursor_type (w
, glyph
,
26028 &new_cursor_width
, &active_cursor
);
26030 /* If cursor is currently being shown and we don't want it to be or
26031 it is in the wrong place, or the cursor type is not what we want,
26033 if (w
->phys_cursor_on_p
26035 || w
->phys_cursor
.x
!= x
26036 || w
->phys_cursor
.y
!= y
26037 || new_cursor_type
!= w
->phys_cursor_type
26038 || ((new_cursor_type
== BAR_CURSOR
|| new_cursor_type
== HBAR_CURSOR
)
26039 && new_cursor_width
!= w
->phys_cursor_width
)))
26040 erase_phys_cursor (w
);
26042 /* Don't check phys_cursor_on_p here because that flag is only set
26043 to zero in some cases where we know that the cursor has been
26044 completely erased, to avoid the extra work of erasing the cursor
26045 twice. In other words, phys_cursor_on_p can be 1 and the cursor
26046 still not be visible, or it has only been partly erased. */
26049 w
->phys_cursor_ascent
= glyph_row
->ascent
;
26050 w
->phys_cursor_height
= glyph_row
->height
;
26052 /* Set phys_cursor_.* before x_draw_.* is called because some
26053 of them may need the information. */
26054 w
->phys_cursor
.x
= x
;
26055 w
->phys_cursor
.y
= glyph_row
->y
;
26056 w
->phys_cursor
.hpos
= hpos
;
26057 w
->phys_cursor
.vpos
= vpos
;
26060 FRAME_RIF (f
)->draw_window_cursor (w
, glyph_row
, x
, y
,
26061 new_cursor_type
, new_cursor_width
,
26062 on
, active_cursor
);
26066 /* Switch the display of W's cursor on or off, according to the value
26070 update_window_cursor (struct window
*w
, int on
)
26072 /* Don't update cursor in windows whose frame is in the process
26073 of being deleted. */
26074 if (w
->current_matrix
)
26076 int hpos
= w
->phys_cursor
.hpos
;
26077 int vpos
= w
->phys_cursor
.vpos
;
26078 struct glyph_row
*row
;
26080 if (vpos
>= w
->current_matrix
->nrows
26081 || hpos
>= w
->current_matrix
->matrix_w
)
26084 row
= MATRIX_ROW (w
->current_matrix
, vpos
);
26086 /* When the window is hscrolled, cursor hpos can legitimately be
26087 out of bounds, but we draw the cursor at the corresponding
26088 window margin in that case. */
26089 if (!row
->reversed_p
&& hpos
< 0)
26091 if (row
->reversed_p
&& hpos
>= row
->used
[TEXT_AREA
])
26092 hpos
= row
->used
[TEXT_AREA
] - 1;
26095 display_and_set_cursor (w
, on
, hpos
, vpos
,
26096 w
->phys_cursor
.x
, w
->phys_cursor
.y
);
26102 /* Call update_window_cursor with parameter ON_P on all leaf windows
26103 in the window tree rooted at W. */
26106 update_cursor_in_window_tree (struct window
*w
, int on_p
)
26110 if (WINDOWP (w
->contents
))
26111 update_cursor_in_window_tree (XWINDOW (w
->contents
), on_p
);
26113 update_window_cursor (w
, on_p
);
26115 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
26121 Display the cursor on window W, or clear it, according to ON_P.
26122 Don't change the cursor's position. */
26125 x_update_cursor (struct frame
*f
, int on_p
)
26127 update_cursor_in_window_tree (XWINDOW (f
->root_window
), on_p
);
26132 Clear the cursor of window W to background color, and mark the
26133 cursor as not shown. This is used when the text where the cursor
26134 is about to be rewritten. */
26137 x_clear_cursor (struct window
*w
)
26139 if (FRAME_VISIBLE_P (XFRAME (w
->frame
)) && w
->phys_cursor_on_p
)
26140 update_window_cursor (w
, 0);
26143 #endif /* HAVE_WINDOW_SYSTEM */
26145 /* Implementation of draw_row_with_mouse_face for GUI sessions, GPM,
26148 draw_row_with_mouse_face (struct window
*w
, int start_x
, struct glyph_row
*row
,
26149 int start_hpos
, int end_hpos
,
26150 enum draw_glyphs_face draw
)
26152 #ifdef HAVE_WINDOW_SYSTEM
26153 if (FRAME_WINDOW_P (XFRAME (w
->frame
)))
26155 draw_glyphs (w
, start_x
, row
, TEXT_AREA
, start_hpos
, end_hpos
, draw
, 0);
26159 #if defined (HAVE_GPM) || defined (MSDOS) || defined (WINDOWSNT)
26160 tty_draw_row_with_mouse_face (w
, row
, start_hpos
, end_hpos
, draw
);
26164 /* Display the active region described by mouse_face_* according to DRAW. */
26167 show_mouse_face (Mouse_HLInfo
*hlinfo
, enum draw_glyphs_face draw
)
26169 struct window
*w
= XWINDOW (hlinfo
->mouse_face_window
);
26170 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
26172 if (/* If window is in the process of being destroyed, don't bother
26174 w
->current_matrix
!= NULL
26175 /* Don't update mouse highlight if hidden */
26176 && (draw
!= DRAW_MOUSE_FACE
|| !hlinfo
->mouse_face_hidden
)
26177 /* Recognize when we are called to operate on rows that don't exist
26178 anymore. This can happen when a window is split. */
26179 && hlinfo
->mouse_face_end_row
< w
->current_matrix
->nrows
)
26181 int phys_cursor_on_p
= w
->phys_cursor_on_p
;
26182 struct glyph_row
*row
, *first
, *last
;
26184 first
= MATRIX_ROW (w
->current_matrix
, hlinfo
->mouse_face_beg_row
);
26185 last
= MATRIX_ROW (w
->current_matrix
, hlinfo
->mouse_face_end_row
);
26187 for (row
= first
; row
<= last
&& row
->enabled_p
; ++row
)
26189 int start_hpos
, end_hpos
, start_x
;
26191 /* For all but the first row, the highlight starts at column 0. */
26194 /* R2L rows have BEG and END in reversed order, but the
26195 screen drawing geometry is always left to right. So
26196 we need to mirror the beginning and end of the
26197 highlighted area in R2L rows. */
26198 if (!row
->reversed_p
)
26200 start_hpos
= hlinfo
->mouse_face_beg_col
;
26201 start_x
= hlinfo
->mouse_face_beg_x
;
26203 else if (row
== last
)
26205 start_hpos
= hlinfo
->mouse_face_end_col
;
26206 start_x
= hlinfo
->mouse_face_end_x
;
26214 else if (row
->reversed_p
&& row
== last
)
26216 start_hpos
= hlinfo
->mouse_face_end_col
;
26217 start_x
= hlinfo
->mouse_face_end_x
;
26227 if (!row
->reversed_p
)
26228 end_hpos
= hlinfo
->mouse_face_end_col
;
26229 else if (row
== first
)
26230 end_hpos
= hlinfo
->mouse_face_beg_col
;
26233 end_hpos
= row
->used
[TEXT_AREA
];
26234 if (draw
== DRAW_NORMAL_TEXT
)
26235 row
->fill_line_p
= 1; /* Clear to end of line */
26238 else if (row
->reversed_p
&& row
== first
)
26239 end_hpos
= hlinfo
->mouse_face_beg_col
;
26242 end_hpos
= row
->used
[TEXT_AREA
];
26243 if (draw
== DRAW_NORMAL_TEXT
)
26244 row
->fill_line_p
= 1; /* Clear to end of line */
26247 if (end_hpos
> start_hpos
)
26249 draw_row_with_mouse_face (w
, start_x
, row
,
26250 start_hpos
, end_hpos
, draw
);
26253 = draw
== DRAW_MOUSE_FACE
|| draw
== DRAW_IMAGE_RAISED
;
26257 #ifdef HAVE_WINDOW_SYSTEM
26258 /* When we've written over the cursor, arrange for it to
26259 be displayed again. */
26260 if (FRAME_WINDOW_P (f
)
26261 && phys_cursor_on_p
&& !w
->phys_cursor_on_p
)
26263 int hpos
= w
->phys_cursor
.hpos
;
26265 /* When the window is hscrolled, cursor hpos can legitimately be
26266 out of bounds, but we draw the cursor at the corresponding
26267 window margin in that case. */
26268 if (!row
->reversed_p
&& hpos
< 0)
26270 if (row
->reversed_p
&& hpos
>= row
->used
[TEXT_AREA
])
26271 hpos
= row
->used
[TEXT_AREA
] - 1;
26274 display_and_set_cursor (w
, 1, hpos
, w
->phys_cursor
.vpos
,
26275 w
->phys_cursor
.x
, w
->phys_cursor
.y
);
26278 #endif /* HAVE_WINDOW_SYSTEM */
26281 #ifdef HAVE_WINDOW_SYSTEM
26282 /* Change the mouse cursor. */
26283 if (FRAME_WINDOW_P (f
))
26285 if (draw
== DRAW_NORMAL_TEXT
26286 && !EQ (hlinfo
->mouse_face_window
, f
->tool_bar_window
))
26287 FRAME_RIF (f
)->define_frame_cursor (f
, FRAME_X_OUTPUT (f
)->text_cursor
);
26288 else if (draw
== DRAW_MOUSE_FACE
)
26289 FRAME_RIF (f
)->define_frame_cursor (f
, FRAME_X_OUTPUT (f
)->hand_cursor
);
26291 FRAME_RIF (f
)->define_frame_cursor (f
, FRAME_X_OUTPUT (f
)->nontext_cursor
);
26293 #endif /* HAVE_WINDOW_SYSTEM */
26297 Clear out the mouse-highlighted active region.
26298 Redraw it un-highlighted first. Value is non-zero if mouse
26299 face was actually drawn unhighlighted. */
26302 clear_mouse_face (Mouse_HLInfo
*hlinfo
)
26306 if (!hlinfo
->mouse_face_hidden
&& !NILP (hlinfo
->mouse_face_window
))
26308 show_mouse_face (hlinfo
, DRAW_NORMAL_TEXT
);
26312 hlinfo
->mouse_face_beg_row
= hlinfo
->mouse_face_beg_col
= -1;
26313 hlinfo
->mouse_face_end_row
= hlinfo
->mouse_face_end_col
= -1;
26314 hlinfo
->mouse_face_window
= Qnil
;
26315 hlinfo
->mouse_face_overlay
= Qnil
;
26319 /* Return non-zero if the coordinates HPOS and VPOS on windows W are
26320 within the mouse face on that window. */
26322 coords_in_mouse_face_p (struct window
*w
, int hpos
, int vpos
)
26324 Mouse_HLInfo
*hlinfo
= MOUSE_HL_INFO (XFRAME (w
->frame
));
26326 /* Quickly resolve the easy cases. */
26327 if (!(WINDOWP (hlinfo
->mouse_face_window
)
26328 && XWINDOW (hlinfo
->mouse_face_window
) == w
))
26330 if (vpos
< hlinfo
->mouse_face_beg_row
26331 || vpos
> hlinfo
->mouse_face_end_row
)
26333 if (vpos
> hlinfo
->mouse_face_beg_row
26334 && vpos
< hlinfo
->mouse_face_end_row
)
26337 if (!MATRIX_ROW (w
->current_matrix
, vpos
)->reversed_p
)
26339 if (hlinfo
->mouse_face_beg_row
== hlinfo
->mouse_face_end_row
)
26341 if (hlinfo
->mouse_face_beg_col
<= hpos
&& hpos
< hlinfo
->mouse_face_end_col
)
26344 else if ((vpos
== hlinfo
->mouse_face_beg_row
26345 && hpos
>= hlinfo
->mouse_face_beg_col
)
26346 || (vpos
== hlinfo
->mouse_face_end_row
26347 && hpos
< hlinfo
->mouse_face_end_col
))
26352 if (hlinfo
->mouse_face_beg_row
== hlinfo
->mouse_face_end_row
)
26354 if (hlinfo
->mouse_face_end_col
< hpos
&& hpos
<= hlinfo
->mouse_face_beg_col
)
26357 else if ((vpos
== hlinfo
->mouse_face_beg_row
26358 && hpos
<= hlinfo
->mouse_face_beg_col
)
26359 || (vpos
== hlinfo
->mouse_face_end_row
26360 && hpos
> hlinfo
->mouse_face_end_col
))
26368 Non-zero if physical cursor of window W is within mouse face. */
26371 cursor_in_mouse_face_p (struct window
*w
)
26373 int hpos
= w
->phys_cursor
.hpos
;
26374 int vpos
= w
->phys_cursor
.vpos
;
26375 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, vpos
);
26377 /* When the window is hscrolled, cursor hpos can legitimately be out
26378 of bounds, but we draw the cursor at the corresponding window
26379 margin in that case. */
26380 if (!row
->reversed_p
&& hpos
< 0)
26382 if (row
->reversed_p
&& hpos
>= row
->used
[TEXT_AREA
])
26383 hpos
= row
->used
[TEXT_AREA
] - 1;
26385 return coords_in_mouse_face_p (w
, hpos
, vpos
);
26390 /* Find the glyph rows START_ROW and END_ROW of window W that display
26391 characters between buffer positions START_CHARPOS and END_CHARPOS
26392 (excluding END_CHARPOS). DISP_STRING is a display string that
26393 covers these buffer positions. This is similar to
26394 row_containing_pos, but is more accurate when bidi reordering makes
26395 buffer positions change non-linearly with glyph rows. */
26397 rows_from_pos_range (struct window
*w
,
26398 ptrdiff_t start_charpos
, ptrdiff_t end_charpos
,
26399 Lisp_Object disp_string
,
26400 struct glyph_row
**start
, struct glyph_row
**end
)
26402 struct glyph_row
*first
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
26403 int last_y
= window_text_bottom_y (w
);
26404 struct glyph_row
*row
;
26409 while (!first
->enabled_p
26410 && first
< MATRIX_BOTTOM_TEXT_ROW (w
->current_matrix
, w
))
26413 /* Find the START row. */
26415 row
->enabled_p
&& MATRIX_ROW_BOTTOM_Y (row
) <= last_y
;
26418 /* A row can potentially be the START row if the range of the
26419 characters it displays intersects the range
26420 [START_CHARPOS..END_CHARPOS). */
26421 if (! ((start_charpos
< MATRIX_ROW_START_CHARPOS (row
)
26422 && end_charpos
< MATRIX_ROW_START_CHARPOS (row
))
26423 /* See the commentary in row_containing_pos, for the
26424 explanation of the complicated way to check whether
26425 some position is beyond the end of the characters
26426 displayed by a row. */
26427 || ((start_charpos
> MATRIX_ROW_END_CHARPOS (row
)
26428 || (start_charpos
== MATRIX_ROW_END_CHARPOS (row
)
26429 && !row
->ends_at_zv_p
26430 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row
)))
26431 && (end_charpos
> MATRIX_ROW_END_CHARPOS (row
)
26432 || (end_charpos
== MATRIX_ROW_END_CHARPOS (row
)
26433 && !row
->ends_at_zv_p
26434 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row
))))))
26436 /* Found a candidate row. Now make sure at least one of the
26437 glyphs it displays has a charpos from the range
26438 [START_CHARPOS..END_CHARPOS).
26440 This is not obvious because bidi reordering could make
26441 buffer positions of a row be 1,2,3,102,101,100, and if we
26442 want to highlight characters in [50..60), we don't want
26443 this row, even though [50..60) does intersect [1..103),
26444 the range of character positions given by the row's start
26445 and end positions. */
26446 struct glyph
*g
= row
->glyphs
[TEXT_AREA
];
26447 struct glyph
*e
= g
+ row
->used
[TEXT_AREA
];
26451 if (((BUFFERP (g
->object
) || INTEGERP (g
->object
))
26452 && start_charpos
<= g
->charpos
&& g
->charpos
< end_charpos
)
26453 /* A glyph that comes from DISP_STRING is by
26454 definition to be highlighted. */
26455 || EQ (g
->object
, disp_string
))
26464 /* Find the END row. */
26466 /* If the last row is partially visible, start looking for END
26467 from that row, instead of starting from FIRST. */
26468 && !(row
->enabled_p
26469 && row
->y
< last_y
&& MATRIX_ROW_BOTTOM_Y (row
) > last_y
))
26471 for ( ; row
->enabled_p
&& MATRIX_ROW_BOTTOM_Y (row
) <= last_y
; row
++)
26473 struct glyph_row
*next
= row
+ 1;
26474 ptrdiff_t next_start
= MATRIX_ROW_START_CHARPOS (next
);
26476 if (!next
->enabled_p
26477 || next
>= MATRIX_BOTTOM_TEXT_ROW (w
->current_matrix
, w
)
26478 /* The first row >= START whose range of displayed characters
26479 does NOT intersect the range [START_CHARPOS..END_CHARPOS]
26480 is the row END + 1. */
26481 || (start_charpos
< next_start
26482 && end_charpos
< next_start
)
26483 || ((start_charpos
> MATRIX_ROW_END_CHARPOS (next
)
26484 || (start_charpos
== MATRIX_ROW_END_CHARPOS (next
)
26485 && !next
->ends_at_zv_p
26486 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next
)))
26487 && (end_charpos
> MATRIX_ROW_END_CHARPOS (next
)
26488 || (end_charpos
== MATRIX_ROW_END_CHARPOS (next
)
26489 && !next
->ends_at_zv_p
26490 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next
)))))
26497 /* If the next row's edges intersect [START_CHARPOS..END_CHARPOS],
26498 but none of the characters it displays are in the range, it is
26500 struct glyph
*g
= next
->glyphs
[TEXT_AREA
];
26501 struct glyph
*s
= g
;
26502 struct glyph
*e
= g
+ next
->used
[TEXT_AREA
];
26506 if (((BUFFERP (g
->object
) || INTEGERP (g
->object
))
26507 && ((start_charpos
<= g
->charpos
&& g
->charpos
< end_charpos
)
26508 /* If the buffer position of the first glyph in
26509 the row is equal to END_CHARPOS, it means
26510 the last character to be highlighted is the
26511 newline of ROW, and we must consider NEXT as
26513 || (((!next
->reversed_p
&& g
== s
)
26514 || (next
->reversed_p
&& g
== e
- 1))
26515 && (g
->charpos
== end_charpos
26516 /* Special case for when NEXT is an
26517 empty line at ZV. */
26518 || (g
->charpos
== -1
26519 && !row
->ends_at_zv_p
26520 && next_start
== end_charpos
)))))
26521 /* A glyph that comes from DISP_STRING is by
26522 definition to be highlighted. */
26523 || EQ (g
->object
, disp_string
))
26532 /* The first row that ends at ZV must be the last to be
26534 else if (next
->ends_at_zv_p
)
26543 /* This function sets the mouse_face_* elements of HLINFO, assuming
26544 the mouse cursor is on a glyph with buffer charpos MOUSE_CHARPOS in
26545 window WINDOW. START_CHARPOS and END_CHARPOS are buffer positions
26546 for the overlay or run of text properties specifying the mouse
26547 face. BEFORE_STRING and AFTER_STRING, if non-nil, are a
26548 before-string and after-string that must also be highlighted.
26549 DISP_STRING, if non-nil, is a display string that may cover some
26550 or all of the highlighted text. */
26553 mouse_face_from_buffer_pos (Lisp_Object window
,
26554 Mouse_HLInfo
*hlinfo
,
26555 ptrdiff_t mouse_charpos
,
26556 ptrdiff_t start_charpos
,
26557 ptrdiff_t end_charpos
,
26558 Lisp_Object before_string
,
26559 Lisp_Object after_string
,
26560 Lisp_Object disp_string
)
26562 struct window
*w
= XWINDOW (window
);
26563 struct glyph_row
*first
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
26564 struct glyph_row
*r1
, *r2
;
26565 struct glyph
*glyph
, *end
;
26566 ptrdiff_t ignore
, pos
;
26569 eassert (NILP (disp_string
) || STRINGP (disp_string
));
26570 eassert (NILP (before_string
) || STRINGP (before_string
));
26571 eassert (NILP (after_string
) || STRINGP (after_string
));
26573 /* Find the rows corresponding to START_CHARPOS and END_CHARPOS. */
26574 rows_from_pos_range (w
, start_charpos
, end_charpos
, disp_string
, &r1
, &r2
);
26576 r1
= MATRIX_ROW (w
->current_matrix
, XFASTINT (w
->window_end_vpos
));
26577 /* If the before-string or display-string contains newlines,
26578 rows_from_pos_range skips to its last row. Move back. */
26579 if (!NILP (before_string
) || !NILP (disp_string
))
26581 struct glyph_row
*prev
;
26582 while ((prev
= r1
- 1, prev
>= first
)
26583 && MATRIX_ROW_END_CHARPOS (prev
) == start_charpos
26584 && prev
->used
[TEXT_AREA
] > 0)
26586 struct glyph
*beg
= prev
->glyphs
[TEXT_AREA
];
26587 glyph
= beg
+ prev
->used
[TEXT_AREA
];
26588 while (--glyph
>= beg
&& INTEGERP (glyph
->object
));
26590 || !(EQ (glyph
->object
, before_string
)
26591 || EQ (glyph
->object
, disp_string
)))
26598 r2
= MATRIX_ROW (w
->current_matrix
, XFASTINT (w
->window_end_vpos
));
26599 hlinfo
->mouse_face_past_end
= 1;
26601 else if (!NILP (after_string
))
26603 /* If the after-string has newlines, advance to its last row. */
26604 struct glyph_row
*next
;
26605 struct glyph_row
*last
26606 = MATRIX_ROW (w
->current_matrix
, XFASTINT (w
->window_end_vpos
));
26608 for (next
= r2
+ 1;
26610 && next
->used
[TEXT_AREA
] > 0
26611 && EQ (next
->glyphs
[TEXT_AREA
]->object
, after_string
);
26615 /* The rest of the display engine assumes that mouse_face_beg_row is
26616 either above mouse_face_end_row or identical to it. But with
26617 bidi-reordered continued lines, the row for START_CHARPOS could
26618 be below the row for END_CHARPOS. If so, swap the rows and store
26619 them in correct order. */
26622 struct glyph_row
*tem
= r2
;
26628 hlinfo
->mouse_face_beg_y
= r1
->y
;
26629 hlinfo
->mouse_face_beg_row
= MATRIX_ROW_VPOS (r1
, w
->current_matrix
);
26630 hlinfo
->mouse_face_end_y
= r2
->y
;
26631 hlinfo
->mouse_face_end_row
= MATRIX_ROW_VPOS (r2
, w
->current_matrix
);
26633 /* For a bidi-reordered row, the positions of BEFORE_STRING,
26634 AFTER_STRING, DISP_STRING, START_CHARPOS, and END_CHARPOS
26635 could be anywhere in the row and in any order. The strategy
26636 below is to find the leftmost and the rightmost glyph that
26637 belongs to either of these 3 strings, or whose position is
26638 between START_CHARPOS and END_CHARPOS, and highlight all the
26639 glyphs between those two. This may cover more than just the text
26640 between START_CHARPOS and END_CHARPOS if the range of characters
26641 strides the bidi level boundary, e.g. if the beginning is in R2L
26642 text while the end is in L2R text or vice versa. */
26643 if (!r1
->reversed_p
)
26645 /* This row is in a left to right paragraph. Scan it left to
26647 glyph
= r1
->glyphs
[TEXT_AREA
];
26648 end
= glyph
+ r1
->used
[TEXT_AREA
];
26651 /* Skip truncation glyphs at the start of the glyph row. */
26652 if (MATRIX_ROW_DISPLAYS_TEXT_P (r1
))
26654 && INTEGERP (glyph
->object
)
26655 && glyph
->charpos
< 0;
26657 x
+= glyph
->pixel_width
;
26659 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
26660 or DISP_STRING, and the first glyph from buffer whose
26661 position is between START_CHARPOS and END_CHARPOS. */
26663 && !INTEGERP (glyph
->object
)
26664 && !EQ (glyph
->object
, disp_string
)
26665 && !(BUFFERP (glyph
->object
)
26666 && (glyph
->charpos
>= start_charpos
26667 && glyph
->charpos
< end_charpos
));
26670 /* BEFORE_STRING or AFTER_STRING are only relevant if they
26671 are present at buffer positions between START_CHARPOS and
26672 END_CHARPOS, or if they come from an overlay. */
26673 if (EQ (glyph
->object
, before_string
))
26675 pos
= string_buffer_position (before_string
,
26677 /* If pos == 0, it means before_string came from an
26678 overlay, not from a buffer position. */
26679 if (!pos
|| (pos
>= start_charpos
&& pos
< end_charpos
))
26682 else if (EQ (glyph
->object
, after_string
))
26684 pos
= string_buffer_position (after_string
, end_charpos
);
26685 if (!pos
|| (pos
>= start_charpos
&& pos
< end_charpos
))
26688 x
+= glyph
->pixel_width
;
26690 hlinfo
->mouse_face_beg_x
= x
;
26691 hlinfo
->mouse_face_beg_col
= glyph
- r1
->glyphs
[TEXT_AREA
];
26695 /* This row is in a right to left paragraph. Scan it right to
26699 end
= r1
->glyphs
[TEXT_AREA
] - 1;
26700 glyph
= end
+ r1
->used
[TEXT_AREA
];
26702 /* Skip truncation glyphs at the start of the glyph row. */
26703 if (MATRIX_ROW_DISPLAYS_TEXT_P (r1
))
26705 && INTEGERP (glyph
->object
)
26706 && glyph
->charpos
< 0;
26710 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
26711 or DISP_STRING, and the first glyph from buffer whose
26712 position is between START_CHARPOS and END_CHARPOS. */
26714 && !INTEGERP (glyph
->object
)
26715 && !EQ (glyph
->object
, disp_string
)
26716 && !(BUFFERP (glyph
->object
)
26717 && (glyph
->charpos
>= start_charpos
26718 && glyph
->charpos
< end_charpos
));
26721 /* BEFORE_STRING or AFTER_STRING are only relevant if they
26722 are present at buffer positions between START_CHARPOS and
26723 END_CHARPOS, or if they come from an overlay. */
26724 if (EQ (glyph
->object
, before_string
))
26726 pos
= string_buffer_position (before_string
, start_charpos
);
26727 /* If pos == 0, it means before_string came from an
26728 overlay, not from a buffer position. */
26729 if (!pos
|| (pos
>= start_charpos
&& pos
< end_charpos
))
26732 else if (EQ (glyph
->object
, after_string
))
26734 pos
= string_buffer_position (after_string
, end_charpos
);
26735 if (!pos
|| (pos
>= start_charpos
&& pos
< end_charpos
))
26740 glyph
++; /* first glyph to the right of the highlighted area */
26741 for (g
= r1
->glyphs
[TEXT_AREA
], x
= r1
->x
; g
< glyph
; g
++)
26742 x
+= g
->pixel_width
;
26743 hlinfo
->mouse_face_beg_x
= x
;
26744 hlinfo
->mouse_face_beg_col
= glyph
- r1
->glyphs
[TEXT_AREA
];
26747 /* If the highlight ends in a different row, compute GLYPH and END
26748 for the end row. Otherwise, reuse the values computed above for
26749 the row where the highlight begins. */
26752 if (!r2
->reversed_p
)
26754 glyph
= r2
->glyphs
[TEXT_AREA
];
26755 end
= glyph
+ r2
->used
[TEXT_AREA
];
26760 end
= r2
->glyphs
[TEXT_AREA
] - 1;
26761 glyph
= end
+ r2
->used
[TEXT_AREA
];
26765 if (!r2
->reversed_p
)
26767 /* Skip truncation and continuation glyphs near the end of the
26768 row, and also blanks and stretch glyphs inserted by
26769 extend_face_to_end_of_line. */
26771 && INTEGERP ((end
- 1)->object
))
26773 /* Scan the rest of the glyph row from the end, looking for the
26774 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
26775 DISP_STRING, or whose position is between START_CHARPOS
26779 && !INTEGERP (end
->object
)
26780 && !EQ (end
->object
, disp_string
)
26781 && !(BUFFERP (end
->object
)
26782 && (end
->charpos
>= start_charpos
26783 && end
->charpos
< end_charpos
));
26786 /* BEFORE_STRING or AFTER_STRING are only relevant if they
26787 are present at buffer positions between START_CHARPOS and
26788 END_CHARPOS, or if they come from an overlay. */
26789 if (EQ (end
->object
, before_string
))
26791 pos
= string_buffer_position (before_string
, start_charpos
);
26792 if (!pos
|| (pos
>= start_charpos
&& pos
< end_charpos
))
26795 else if (EQ (end
->object
, after_string
))
26797 pos
= string_buffer_position (after_string
, end_charpos
);
26798 if (!pos
|| (pos
>= start_charpos
&& pos
< end_charpos
))
26802 /* Find the X coordinate of the last glyph to be highlighted. */
26803 for (; glyph
<= end
; ++glyph
)
26804 x
+= glyph
->pixel_width
;
26806 hlinfo
->mouse_face_end_x
= x
;
26807 hlinfo
->mouse_face_end_col
= glyph
- r2
->glyphs
[TEXT_AREA
];
26811 /* Skip truncation and continuation glyphs near the end of the
26812 row, and also blanks and stretch glyphs inserted by
26813 extend_face_to_end_of_line. */
26817 && INTEGERP (end
->object
))
26819 x
+= end
->pixel_width
;
26822 /* Scan the rest of the glyph row from the end, looking for the
26823 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
26824 DISP_STRING, or whose position is between START_CHARPOS
26828 && !INTEGERP (end
->object
)
26829 && !EQ (end
->object
, disp_string
)
26830 && !(BUFFERP (end
->object
)
26831 && (end
->charpos
>= start_charpos
26832 && end
->charpos
< end_charpos
));
26835 /* BEFORE_STRING or AFTER_STRING are only relevant if they
26836 are present at buffer positions between START_CHARPOS and
26837 END_CHARPOS, or if they come from an overlay. */
26838 if (EQ (end
->object
, before_string
))
26840 pos
= string_buffer_position (before_string
, start_charpos
);
26841 if (!pos
|| (pos
>= start_charpos
&& pos
< end_charpos
))
26844 else if (EQ (end
->object
, after_string
))
26846 pos
= string_buffer_position (after_string
, end_charpos
);
26847 if (!pos
|| (pos
>= start_charpos
&& pos
< end_charpos
))
26850 x
+= end
->pixel_width
;
26852 /* If we exited the above loop because we arrived at the last
26853 glyph of the row, and its buffer position is still not in
26854 range, it means the last character in range is the preceding
26855 newline. Bump the end column and x values to get past the
26858 && BUFFERP (end
->object
)
26859 && (end
->charpos
< start_charpos
26860 || end
->charpos
>= end_charpos
))
26862 x
+= end
->pixel_width
;
26865 hlinfo
->mouse_face_end_x
= x
;
26866 hlinfo
->mouse_face_end_col
= end
- r2
->glyphs
[TEXT_AREA
];
26869 hlinfo
->mouse_face_window
= window
;
26870 hlinfo
->mouse_face_face_id
26871 = face_at_buffer_position (w
, mouse_charpos
, 0, 0, &ignore
,
26873 !hlinfo
->mouse_face_hidden
, -1);
26874 show_mouse_face (hlinfo
, DRAW_MOUSE_FACE
);
26877 /* The following function is not used anymore (replaced with
26878 mouse_face_from_string_pos), but I leave it here for the time
26879 being, in case someone would. */
26881 #if 0 /* not used */
26883 /* Find the position of the glyph for position POS in OBJECT in
26884 window W's current matrix, and return in *X, *Y the pixel
26885 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
26887 RIGHT_P non-zero means return the position of the right edge of the
26888 glyph, RIGHT_P zero means return the left edge position.
26890 If no glyph for POS exists in the matrix, return the position of
26891 the glyph with the next smaller position that is in the matrix, if
26892 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
26893 exists in the matrix, return the position of the glyph with the
26894 next larger position in OBJECT.
26896 Value is non-zero if a glyph was found. */
26899 fast_find_string_pos (struct window
*w
, ptrdiff_t pos
, Lisp_Object object
,
26900 int *hpos
, int *vpos
, int *x
, int *y
, int right_p
)
26902 int yb
= window_text_bottom_y (w
);
26903 struct glyph_row
*r
;
26904 struct glyph
*best_glyph
= NULL
;
26905 struct glyph_row
*best_row
= NULL
;
26908 for (r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
26909 r
->enabled_p
&& r
->y
< yb
;
26912 struct glyph
*g
= r
->glyphs
[TEXT_AREA
];
26913 struct glyph
*e
= g
+ r
->used
[TEXT_AREA
];
26916 for (gx
= r
->x
; g
< e
; gx
+= g
->pixel_width
, ++g
)
26917 if (EQ (g
->object
, object
))
26919 if (g
->charpos
== pos
)
26926 else if (best_glyph
== NULL
26927 || ((eabs (g
->charpos
- pos
)
26928 < eabs (best_glyph
->charpos
- pos
))
26931 : g
->charpos
> pos
)))
26945 *hpos
= best_glyph
- best_row
->glyphs
[TEXT_AREA
];
26949 *x
+= best_glyph
->pixel_width
;
26954 *vpos
= MATRIX_ROW_VPOS (best_row
, w
->current_matrix
);
26957 return best_glyph
!= NULL
;
26959 #endif /* not used */
26961 /* Find the positions of the first and the last glyphs in window W's
26962 current matrix that occlude positions [STARTPOS..ENDPOS] in OBJECT
26963 (assumed to be a string), and return in HLINFO's mouse_face_*
26964 members the pixel and column/row coordinates of those glyphs. */
26967 mouse_face_from_string_pos (struct window
*w
, Mouse_HLInfo
*hlinfo
,
26968 Lisp_Object object
,
26969 ptrdiff_t startpos
, ptrdiff_t endpos
)
26971 int yb
= window_text_bottom_y (w
);
26972 struct glyph_row
*r
;
26973 struct glyph
*g
, *e
;
26977 /* Find the glyph row with at least one position in the range
26978 [STARTPOS..ENDPOS], and the first glyph in that row whose
26979 position belongs to that range. */
26980 for (r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
26981 r
->enabled_p
&& r
->y
< yb
;
26984 if (!r
->reversed_p
)
26986 g
= r
->glyphs
[TEXT_AREA
];
26987 e
= g
+ r
->used
[TEXT_AREA
];
26988 for (gx
= r
->x
; g
< e
; gx
+= g
->pixel_width
, ++g
)
26989 if (EQ (g
->object
, object
)
26990 && startpos
<= g
->charpos
&& g
->charpos
<= endpos
)
26992 hlinfo
->mouse_face_beg_row
26993 = MATRIX_ROW_VPOS (r
, w
->current_matrix
);
26994 hlinfo
->mouse_face_beg_y
= r
->y
;
26995 hlinfo
->mouse_face_beg_col
= g
- r
->glyphs
[TEXT_AREA
];
26996 hlinfo
->mouse_face_beg_x
= gx
;
27005 e
= r
->glyphs
[TEXT_AREA
];
27006 g
= e
+ r
->used
[TEXT_AREA
];
27007 for ( ; g
> e
; --g
)
27008 if (EQ ((g
-1)->object
, object
)
27009 && startpos
<= (g
-1)->charpos
&& (g
-1)->charpos
<= endpos
)
27011 hlinfo
->mouse_face_beg_row
27012 = MATRIX_ROW_VPOS (r
, w
->current_matrix
);
27013 hlinfo
->mouse_face_beg_y
= r
->y
;
27014 hlinfo
->mouse_face_beg_col
= g
- r
->glyphs
[TEXT_AREA
];
27015 for (gx
= r
->x
, g1
= r
->glyphs
[TEXT_AREA
]; g1
< g
; ++g1
)
27016 gx
+= g1
->pixel_width
;
27017 hlinfo
->mouse_face_beg_x
= gx
;
27029 /* Starting with the next row, look for the first row which does NOT
27030 include any glyphs whose positions are in the range. */
27031 for (++r
; r
->enabled_p
&& r
->y
< yb
; ++r
)
27033 g
= r
->glyphs
[TEXT_AREA
];
27034 e
= g
+ r
->used
[TEXT_AREA
];
27036 for ( ; g
< e
; ++g
)
27037 if (EQ (g
->object
, object
)
27038 && startpos
<= g
->charpos
&& g
->charpos
<= endpos
)
27047 /* The highlighted region ends on the previous row. */
27050 /* Set the end row and its vertical pixel coordinate. */
27051 hlinfo
->mouse_face_end_row
= MATRIX_ROW_VPOS (r
, w
->current_matrix
);
27052 hlinfo
->mouse_face_end_y
= r
->y
;
27054 /* Compute and set the end column and the end column's horizontal
27055 pixel coordinate. */
27056 if (!r
->reversed_p
)
27058 g
= r
->glyphs
[TEXT_AREA
];
27059 e
= g
+ r
->used
[TEXT_AREA
];
27060 for ( ; e
> g
; --e
)
27061 if (EQ ((e
-1)->object
, object
)
27062 && startpos
<= (e
-1)->charpos
&& (e
-1)->charpos
<= endpos
)
27064 hlinfo
->mouse_face_end_col
= e
- g
;
27066 for (gx
= r
->x
; g
< e
; ++g
)
27067 gx
+= g
->pixel_width
;
27068 hlinfo
->mouse_face_end_x
= gx
;
27072 e
= r
->glyphs
[TEXT_AREA
];
27073 g
= e
+ r
->used
[TEXT_AREA
];
27074 for (gx
= r
->x
; e
< g
; ++e
)
27076 if (EQ (e
->object
, object
)
27077 && startpos
<= e
->charpos
&& e
->charpos
<= endpos
)
27079 gx
+= e
->pixel_width
;
27081 hlinfo
->mouse_face_end_col
= e
- r
->glyphs
[TEXT_AREA
];
27082 hlinfo
->mouse_face_end_x
= gx
;
27086 #ifdef HAVE_WINDOW_SYSTEM
27088 /* See if position X, Y is within a hot-spot of an image. */
27091 on_hot_spot_p (Lisp_Object hot_spot
, int x
, int y
)
27093 if (!CONSP (hot_spot
))
27096 if (EQ (XCAR (hot_spot
), Qrect
))
27098 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
27099 Lisp_Object rect
= XCDR (hot_spot
);
27103 if (!CONSP (XCAR (rect
)))
27105 if (!CONSP (XCDR (rect
)))
27107 if (!(tem
= XCAR (XCAR (rect
)), INTEGERP (tem
) && x
>= XINT (tem
)))
27109 if (!(tem
= XCDR (XCAR (rect
)), INTEGERP (tem
) && y
>= XINT (tem
)))
27111 if (!(tem
= XCAR (XCDR (rect
)), INTEGERP (tem
) && x
<= XINT (tem
)))
27113 if (!(tem
= XCDR (XCDR (rect
)), INTEGERP (tem
) && y
<= XINT (tem
)))
27117 else if (EQ (XCAR (hot_spot
), Qcircle
))
27119 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
27120 Lisp_Object circ
= XCDR (hot_spot
);
27121 Lisp_Object lr
, lx0
, ly0
;
27123 && CONSP (XCAR (circ
))
27124 && (lr
= XCDR (circ
), INTEGERP (lr
) || FLOATP (lr
))
27125 && (lx0
= XCAR (XCAR (circ
)), INTEGERP (lx0
))
27126 && (ly0
= XCDR (XCAR (circ
)), INTEGERP (ly0
)))
27128 double r
= XFLOATINT (lr
);
27129 double dx
= XINT (lx0
) - x
;
27130 double dy
= XINT (ly0
) - y
;
27131 return (dx
* dx
+ dy
* dy
<= r
* r
);
27134 else if (EQ (XCAR (hot_spot
), Qpoly
))
27136 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
27137 if (VECTORP (XCDR (hot_spot
)))
27139 struct Lisp_Vector
*v
= XVECTOR (XCDR (hot_spot
));
27140 Lisp_Object
*poly
= v
->contents
;
27141 ptrdiff_t n
= v
->header
.size
;
27144 Lisp_Object lx
, ly
;
27147 /* Need an even number of coordinates, and at least 3 edges. */
27148 if (n
< 6 || n
& 1)
27151 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
27152 If count is odd, we are inside polygon. Pixels on edges
27153 may or may not be included depending on actual geometry of the
27155 if ((lx
= poly
[n
-2], !INTEGERP (lx
))
27156 || (ly
= poly
[n
-1], !INTEGERP (lx
)))
27158 x0
= XINT (lx
), y0
= XINT (ly
);
27159 for (i
= 0; i
< n
; i
+= 2)
27161 int x1
= x0
, y1
= y0
;
27162 if ((lx
= poly
[i
], !INTEGERP (lx
))
27163 || (ly
= poly
[i
+1], !INTEGERP (ly
)))
27165 x0
= XINT (lx
), y0
= XINT (ly
);
27167 /* Does this segment cross the X line? */
27175 if (y
> y0
&& y
> y1
)
27177 if (y
< y0
+ ((y1
- y0
) * (x
- x0
)) / (x1
- x0
))
27187 find_hot_spot (Lisp_Object map
, int x
, int y
)
27189 while (CONSP (map
))
27191 if (CONSP (XCAR (map
))
27192 && on_hot_spot_p (XCAR (XCAR (map
)), x
, y
))
27200 DEFUN ("lookup-image-map", Flookup_image_map
, Slookup_image_map
,
27202 doc
: /* Lookup in image map MAP coordinates X and Y.
27203 An image map is an alist where each element has the format (AREA ID PLIST).
27204 An AREA is specified as either a rectangle, a circle, or a polygon:
27205 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
27206 pixel coordinates of the upper left and bottom right corners.
27207 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
27208 and the radius of the circle; r may be a float or integer.
27209 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
27210 vector describes one corner in the polygon.
27211 Returns the alist element for the first matching AREA in MAP. */)
27212 (Lisp_Object map
, Lisp_Object x
, Lisp_Object y
)
27220 return find_hot_spot (map
,
27221 clip_to_bounds (INT_MIN
, XINT (x
), INT_MAX
),
27222 clip_to_bounds (INT_MIN
, XINT (y
), INT_MAX
));
27226 /* Display frame CURSOR, optionally using shape defined by POINTER. */
27228 define_frame_cursor1 (struct frame
*f
, Cursor cursor
, Lisp_Object pointer
)
27230 /* Do not change cursor shape while dragging mouse. */
27231 if (!NILP (do_mouse_tracking
))
27234 if (!NILP (pointer
))
27236 if (EQ (pointer
, Qarrow
))
27237 cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
27238 else if (EQ (pointer
, Qhand
))
27239 cursor
= FRAME_X_OUTPUT (f
)->hand_cursor
;
27240 else if (EQ (pointer
, Qtext
))
27241 cursor
= FRAME_X_OUTPUT (f
)->text_cursor
;
27242 else if (EQ (pointer
, intern ("hdrag")))
27243 cursor
= FRAME_X_OUTPUT (f
)->horizontal_drag_cursor
;
27244 #ifdef HAVE_X_WINDOWS
27245 else if (EQ (pointer
, intern ("vdrag")))
27246 cursor
= FRAME_X_DISPLAY_INFO (f
)->vertical_scroll_bar_cursor
;
27248 else if (EQ (pointer
, intern ("hourglass")))
27249 cursor
= FRAME_X_OUTPUT (f
)->hourglass_cursor
;
27250 else if (EQ (pointer
, Qmodeline
))
27251 cursor
= FRAME_X_OUTPUT (f
)->modeline_cursor
;
27253 cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
27256 if (cursor
!= No_Cursor
)
27257 FRAME_RIF (f
)->define_frame_cursor (f
, cursor
);
27260 #endif /* HAVE_WINDOW_SYSTEM */
27262 /* Take proper action when mouse has moved to the mode or header line
27263 or marginal area AREA of window W, x-position X and y-position Y.
27264 X is relative to the start of the text display area of W, so the
27265 width of bitmap areas and scroll bars must be subtracted to get a
27266 position relative to the start of the mode line. */
27269 note_mode_line_or_margin_highlight (Lisp_Object window
, int x
, int y
,
27270 enum window_part area
)
27272 struct window
*w
= XWINDOW (window
);
27273 struct frame
*f
= XFRAME (w
->frame
);
27274 Mouse_HLInfo
*hlinfo
= MOUSE_HL_INFO (f
);
27275 #ifdef HAVE_WINDOW_SYSTEM
27276 Display_Info
*dpyinfo
;
27278 Cursor cursor
= No_Cursor
;
27279 Lisp_Object pointer
= Qnil
;
27280 int dx
, dy
, width
, height
;
27282 Lisp_Object string
, object
= Qnil
;
27283 Lisp_Object pos
IF_LINT (= Qnil
), help
;
27285 Lisp_Object mouse_face
;
27286 int original_x_pixel
= x
;
27287 struct glyph
* glyph
= NULL
, * row_start_glyph
= NULL
;
27288 struct glyph_row
*row
IF_LINT (= 0);
27290 if (area
== ON_MODE_LINE
|| area
== ON_HEADER_LINE
)
27295 /* Kludge alert: mode_line_string takes X/Y in pixels, but
27296 returns them in row/column units! */
27297 string
= mode_line_string (w
, area
, &x
, &y
, &charpos
,
27298 &object
, &dx
, &dy
, &width
, &height
);
27300 row
= (area
== ON_MODE_LINE
27301 ? MATRIX_MODE_LINE_ROW (w
->current_matrix
)
27302 : MATRIX_HEADER_LINE_ROW (w
->current_matrix
));
27304 /* Find the glyph under the mouse pointer. */
27305 if (row
->mode_line_p
&& row
->enabled_p
)
27307 glyph
= row_start_glyph
= row
->glyphs
[TEXT_AREA
];
27308 end
= glyph
+ row
->used
[TEXT_AREA
];
27310 for (x0
= original_x_pixel
;
27311 glyph
< end
&& x0
>= glyph
->pixel_width
;
27313 x0
-= glyph
->pixel_width
;
27321 x
-= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w
);
27322 /* Kludge alert: marginal_area_string takes X/Y in pixels, but
27323 returns them in row/column units! */
27324 string
= marginal_area_string (w
, area
, &x
, &y
, &charpos
,
27325 &object
, &dx
, &dy
, &width
, &height
);
27330 #ifdef HAVE_WINDOW_SYSTEM
27331 if (IMAGEP (object
))
27333 Lisp_Object image_map
, hotspot
;
27334 if ((image_map
= Fplist_get (XCDR (object
), QCmap
),
27336 && (hotspot
= find_hot_spot (image_map
, dx
, dy
),
27338 && (hotspot
= XCDR (hotspot
), CONSP (hotspot
)))
27342 /* Could check XCAR (hotspot) to see if we enter/leave this hot-spot.
27343 If so, we could look for mouse-enter, mouse-leave
27344 properties in PLIST (and do something...). */
27345 hotspot
= XCDR (hotspot
);
27346 if (CONSP (hotspot
)
27347 && (plist
= XCAR (hotspot
), CONSP (plist
)))
27349 pointer
= Fplist_get (plist
, Qpointer
);
27350 if (NILP (pointer
))
27352 help
= Fplist_get (plist
, Qhelp_echo
);
27355 help_echo_string
= help
;
27356 XSETWINDOW (help_echo_window
, w
);
27357 help_echo_object
= w
->contents
;
27358 help_echo_pos
= charpos
;
27362 if (NILP (pointer
))
27363 pointer
= Fplist_get (XCDR (object
), QCpointer
);
27365 #endif /* HAVE_WINDOW_SYSTEM */
27367 if (STRINGP (string
))
27368 pos
= make_number (charpos
);
27370 /* Set the help text and mouse pointer. If the mouse is on a part
27371 of the mode line without any text (e.g. past the right edge of
27372 the mode line text), use the default help text and pointer. */
27373 if (STRINGP (string
) || area
== ON_MODE_LINE
)
27375 /* Arrange to display the help by setting the global variables
27376 help_echo_string, help_echo_object, and help_echo_pos. */
27379 if (STRINGP (string
))
27380 help
= Fget_text_property (pos
, Qhelp_echo
, string
);
27384 help_echo_string
= help
;
27385 XSETWINDOW (help_echo_window
, w
);
27386 help_echo_object
= string
;
27387 help_echo_pos
= charpos
;
27389 else if (area
== ON_MODE_LINE
)
27391 Lisp_Object default_help
27392 = buffer_local_value_1 (Qmode_line_default_help_echo
,
27395 if (STRINGP (default_help
))
27397 help_echo_string
= default_help
;
27398 XSETWINDOW (help_echo_window
, w
);
27399 help_echo_object
= Qnil
;
27400 help_echo_pos
= -1;
27405 #ifdef HAVE_WINDOW_SYSTEM
27406 /* Change the mouse pointer according to what is under it. */
27407 if (FRAME_WINDOW_P (f
))
27409 dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
27410 if (STRINGP (string
))
27412 cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
27414 if (NILP (pointer
))
27415 pointer
= Fget_text_property (pos
, Qpointer
, string
);
27417 /* Change the mouse pointer according to what is under X/Y. */
27419 && ((area
== ON_MODE_LINE
) || (area
== ON_HEADER_LINE
)))
27422 map
= Fget_text_property (pos
, Qlocal_map
, string
);
27423 if (!KEYMAPP (map
))
27424 map
= Fget_text_property (pos
, Qkeymap
, string
);
27425 if (!KEYMAPP (map
))
27426 cursor
= dpyinfo
->vertical_scroll_bar_cursor
;
27430 /* Default mode-line pointer. */
27431 cursor
= FRAME_X_DISPLAY_INFO (f
)->vertical_scroll_bar_cursor
;
27436 /* Change the mouse face according to what is under X/Y. */
27437 if (STRINGP (string
))
27439 mouse_face
= Fget_text_property (pos
, Qmouse_face
, string
);
27440 if (!NILP (Vmouse_highlight
) && !NILP (mouse_face
)
27441 && ((area
== ON_MODE_LINE
) || (area
== ON_HEADER_LINE
))
27446 struct glyph
* tmp_glyph
;
27450 int total_pixel_width
;
27451 ptrdiff_t begpos
, endpos
, ignore
;
27455 b
= Fprevious_single_property_change (make_number (charpos
+ 1),
27456 Qmouse_face
, string
, Qnil
);
27462 e
= Fnext_single_property_change (pos
, Qmouse_face
, string
, Qnil
);
27464 endpos
= SCHARS (string
);
27468 /* Calculate the glyph position GPOS of GLYPH in the
27469 displayed string, relative to the beginning of the
27470 highlighted part of the string.
27472 Note: GPOS is different from CHARPOS. CHARPOS is the
27473 position of GLYPH in the internal string object. A mode
27474 line string format has structures which are converted to
27475 a flattened string by the Emacs Lisp interpreter. The
27476 internal string is an element of those structures. The
27477 displayed string is the flattened string. */
27478 tmp_glyph
= row_start_glyph
;
27479 while (tmp_glyph
< glyph
27480 && (!(EQ (tmp_glyph
->object
, glyph
->object
)
27481 && begpos
<= tmp_glyph
->charpos
27482 && tmp_glyph
->charpos
< endpos
)))
27484 gpos
= glyph
- tmp_glyph
;
27486 /* Calculate the length GSEQ_LENGTH of the glyph sequence of
27487 the highlighted part of the displayed string to which
27488 GLYPH belongs. Note: GSEQ_LENGTH is different from
27489 SCHARS (STRING), because the latter returns the length of
27490 the internal string. */
27491 for (tmp_glyph
= row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
] - 1;
27493 && (!(EQ (tmp_glyph
->object
, glyph
->object
)
27494 && begpos
<= tmp_glyph
->charpos
27495 && tmp_glyph
->charpos
< endpos
));
27498 gseq_length
= gpos
+ (tmp_glyph
- glyph
) + 1;
27500 /* Calculate the total pixel width of all the glyphs between
27501 the beginning of the highlighted area and GLYPH. */
27502 total_pixel_width
= 0;
27503 for (tmp_glyph
= glyph
- gpos
; tmp_glyph
!= glyph
; tmp_glyph
++)
27504 total_pixel_width
+= tmp_glyph
->pixel_width
;
27506 /* Pre calculation of re-rendering position. Note: X is in
27507 column units here, after the call to mode_line_string or
27508 marginal_area_string. */
27510 vpos
= (area
== ON_MODE_LINE
27511 ? (w
->current_matrix
)->nrows
- 1
27514 /* If GLYPH's position is included in the region that is
27515 already drawn in mouse face, we have nothing to do. */
27516 if ( EQ (window
, hlinfo
->mouse_face_window
)
27517 && (!row
->reversed_p
27518 ? (hlinfo
->mouse_face_beg_col
<= hpos
27519 && hpos
< hlinfo
->mouse_face_end_col
)
27520 /* In R2L rows we swap BEG and END, see below. */
27521 : (hlinfo
->mouse_face_end_col
<= hpos
27522 && hpos
< hlinfo
->mouse_face_beg_col
))
27523 && hlinfo
->mouse_face_beg_row
== vpos
)
27526 if (clear_mouse_face (hlinfo
))
27527 cursor
= No_Cursor
;
27529 if (!row
->reversed_p
)
27531 hlinfo
->mouse_face_beg_col
= hpos
;
27532 hlinfo
->mouse_face_beg_x
= original_x_pixel
27533 - (total_pixel_width
+ dx
);
27534 hlinfo
->mouse_face_end_col
= hpos
+ gseq_length
;
27535 hlinfo
->mouse_face_end_x
= 0;
27539 /* In R2L rows, show_mouse_face expects BEG and END
27540 coordinates to be swapped. */
27541 hlinfo
->mouse_face_end_col
= hpos
;
27542 hlinfo
->mouse_face_end_x
= original_x_pixel
27543 - (total_pixel_width
+ dx
);
27544 hlinfo
->mouse_face_beg_col
= hpos
+ gseq_length
;
27545 hlinfo
->mouse_face_beg_x
= 0;
27548 hlinfo
->mouse_face_beg_row
= vpos
;
27549 hlinfo
->mouse_face_end_row
= hlinfo
->mouse_face_beg_row
;
27550 hlinfo
->mouse_face_beg_y
= 0;
27551 hlinfo
->mouse_face_end_y
= 0;
27552 hlinfo
->mouse_face_past_end
= 0;
27553 hlinfo
->mouse_face_window
= window
;
27555 hlinfo
->mouse_face_face_id
= face_at_string_position (w
, string
,
27561 show_mouse_face (hlinfo
, DRAW_MOUSE_FACE
);
27563 if (NILP (pointer
))
27566 else if ((area
== ON_MODE_LINE
) || (area
== ON_HEADER_LINE
))
27567 clear_mouse_face (hlinfo
);
27569 #ifdef HAVE_WINDOW_SYSTEM
27570 if (FRAME_WINDOW_P (f
))
27571 define_frame_cursor1 (f
, cursor
, pointer
);
27577 Take proper action when the mouse has moved to position X, Y on
27578 frame F with regards to highlighting portions of display that have
27579 mouse-face properties. Also de-highlight portions of display where
27580 the mouse was before, set the mouse pointer shape as appropriate
27581 for the mouse coordinates, and activate help echo (tooltips).
27582 X and Y can be negative or out of range. */
27585 note_mouse_highlight (struct frame
*f
, int x
, int y
)
27587 Mouse_HLInfo
*hlinfo
= MOUSE_HL_INFO (f
);
27588 enum window_part part
= ON_NOTHING
;
27589 Lisp_Object window
;
27591 Cursor cursor
= No_Cursor
;
27592 Lisp_Object pointer
= Qnil
; /* Takes precedence over cursor! */
27595 /* When a menu is active, don't highlight because this looks odd. */
27596 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) || defined (MSDOS)
27597 if (popup_activated ())
27601 if (!f
->glyphs_initialized_p
27602 || f
->pointer_invisible
)
27605 hlinfo
->mouse_face_mouse_x
= x
;
27606 hlinfo
->mouse_face_mouse_y
= y
;
27607 hlinfo
->mouse_face_mouse_frame
= f
;
27609 if (hlinfo
->mouse_face_defer
)
27612 /* Which window is that in? */
27613 window
= window_from_coordinates (f
, x
, y
, &part
, 1);
27615 /* If displaying active text in another window, clear that. */
27616 if (! EQ (window
, hlinfo
->mouse_face_window
)
27617 /* Also clear if we move out of text area in same window. */
27618 || (!NILP (hlinfo
->mouse_face_window
)
27621 && part
!= ON_MODE_LINE
27622 && part
!= ON_HEADER_LINE
))
27623 clear_mouse_face (hlinfo
);
27625 /* Not on a window -> return. */
27626 if (!WINDOWP (window
))
27629 /* Reset help_echo_string. It will get recomputed below. */
27630 help_echo_string
= Qnil
;
27632 /* Convert to window-relative pixel coordinates. */
27633 w
= XWINDOW (window
);
27634 frame_to_window_pixel_xy (w
, &x
, &y
);
27636 #ifdef HAVE_WINDOW_SYSTEM
27637 /* Handle tool-bar window differently since it doesn't display a
27639 if (EQ (window
, f
->tool_bar_window
))
27641 note_tool_bar_highlight (f
, x
, y
);
27646 /* Mouse is on the mode, header line or margin? */
27647 if (part
== ON_MODE_LINE
|| part
== ON_HEADER_LINE
27648 || part
== ON_LEFT_MARGIN
|| part
== ON_RIGHT_MARGIN
)
27650 note_mode_line_or_margin_highlight (window
, x
, y
, part
);
27654 #ifdef HAVE_WINDOW_SYSTEM
27655 if (part
== ON_VERTICAL_BORDER
)
27657 cursor
= FRAME_X_OUTPUT (f
)->horizontal_drag_cursor
;
27658 help_echo_string
= build_string ("drag-mouse-1: resize");
27660 else if (part
== ON_LEFT_FRINGE
|| part
== ON_RIGHT_FRINGE
27661 || part
== ON_SCROLL_BAR
)
27662 cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
27664 cursor
= FRAME_X_OUTPUT (f
)->text_cursor
;
27667 /* Are we in a window whose display is up to date?
27668 And verify the buffer's text has not changed. */
27669 b
= XBUFFER (w
->contents
);
27670 if (part
== ON_TEXT
27671 && w
->window_end_valid
27672 && w
->last_modified
== BUF_MODIFF (b
)
27673 && w
->last_overlay_modified
== BUF_OVERLAY_MODIFF (b
))
27675 int hpos
, vpos
, dx
, dy
, area
= LAST_AREA
;
27677 struct glyph
*glyph
;
27678 Lisp_Object object
;
27679 Lisp_Object mouse_face
= Qnil
, position
;
27680 Lisp_Object
*overlay_vec
= NULL
;
27681 ptrdiff_t i
, noverlays
;
27682 struct buffer
*obuf
;
27683 ptrdiff_t obegv
, ozv
;
27686 /* Find the glyph under X/Y. */
27687 glyph
= x_y_to_hpos_vpos (w
, x
, y
, &hpos
, &vpos
, &dx
, &dy
, &area
);
27689 #ifdef HAVE_WINDOW_SYSTEM
27690 /* Look for :pointer property on image. */
27691 if (glyph
!= NULL
&& glyph
->type
== IMAGE_GLYPH
)
27693 struct image
*img
= IMAGE_FROM_ID (f
, glyph
->u
.img_id
);
27694 if (img
!= NULL
&& IMAGEP (img
->spec
))
27696 Lisp_Object image_map
, hotspot
;
27697 if ((image_map
= Fplist_get (XCDR (img
->spec
), QCmap
),
27699 && (hotspot
= find_hot_spot (image_map
,
27700 glyph
->slice
.img
.x
+ dx
,
27701 glyph
->slice
.img
.y
+ dy
),
27703 && (hotspot
= XCDR (hotspot
), CONSP (hotspot
)))
27707 /* Could check XCAR (hotspot) to see if we enter/leave
27709 If so, we could look for mouse-enter, mouse-leave
27710 properties in PLIST (and do something...). */
27711 hotspot
= XCDR (hotspot
);
27712 if (CONSP (hotspot
)
27713 && (plist
= XCAR (hotspot
), CONSP (plist
)))
27715 pointer
= Fplist_get (plist
, Qpointer
);
27716 if (NILP (pointer
))
27718 help_echo_string
= Fplist_get (plist
, Qhelp_echo
);
27719 if (!NILP (help_echo_string
))
27721 help_echo_window
= window
;
27722 help_echo_object
= glyph
->object
;
27723 help_echo_pos
= glyph
->charpos
;
27727 if (NILP (pointer
))
27728 pointer
= Fplist_get (XCDR (img
->spec
), QCpointer
);
27731 #endif /* HAVE_WINDOW_SYSTEM */
27733 /* Clear mouse face if X/Y not over text. */
27735 || area
!= TEXT_AREA
27736 || !MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w
->current_matrix
, vpos
))
27737 /* Glyph's OBJECT is an integer for glyphs inserted by the
27738 display engine for its internal purposes, like truncation
27739 and continuation glyphs and blanks beyond the end of
27740 line's text on text terminals. If we are over such a
27741 glyph, we are not over any text. */
27742 || INTEGERP (glyph
->object
)
27743 /* R2L rows have a stretch glyph at their front, which
27744 stands for no text, whereas L2R rows have no glyphs at
27745 all beyond the end of text. Treat such stretch glyphs
27746 like we do with NULL glyphs in L2R rows. */
27747 || (MATRIX_ROW (w
->current_matrix
, vpos
)->reversed_p
27748 && glyph
== MATRIX_ROW_GLYPH_START (w
->current_matrix
, vpos
)
27749 && glyph
->type
== STRETCH_GLYPH
27750 && glyph
->avoid_cursor_p
))
27752 if (clear_mouse_face (hlinfo
))
27753 cursor
= No_Cursor
;
27754 #ifdef HAVE_WINDOW_SYSTEM
27755 if (FRAME_WINDOW_P (f
) && NILP (pointer
))
27757 if (area
!= TEXT_AREA
)
27758 cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
27760 pointer
= Vvoid_text_area_pointer
;
27766 pos
= glyph
->charpos
;
27767 object
= glyph
->object
;
27768 if (!STRINGP (object
) && !BUFFERP (object
))
27771 /* If we get an out-of-range value, return now; avoid an error. */
27772 if (BUFFERP (object
) && pos
> BUF_Z (b
))
27775 /* Make the window's buffer temporarily current for
27776 overlays_at and compute_char_face. */
27777 obuf
= current_buffer
;
27778 current_buffer
= b
;
27784 /* Is this char mouse-active or does it have help-echo? */
27785 position
= make_number (pos
);
27787 if (BUFFERP (object
))
27789 /* Put all the overlays we want in a vector in overlay_vec. */
27790 GET_OVERLAYS_AT (pos
, overlay_vec
, noverlays
, NULL
, 0);
27791 /* Sort overlays into increasing priority order. */
27792 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
27797 if (NILP (Vmouse_highlight
))
27799 clear_mouse_face (hlinfo
);
27800 goto check_help_echo
;
27803 same_region
= coords_in_mouse_face_p (w
, hpos
, vpos
);
27806 cursor
= No_Cursor
;
27808 /* Check mouse-face highlighting. */
27810 /* If there exists an overlay with mouse-face overlapping
27811 the one we are currently highlighting, we have to
27812 check if we enter the overlapping overlay, and then
27813 highlight only that. */
27814 || (OVERLAYP (hlinfo
->mouse_face_overlay
)
27815 && mouse_face_overlay_overlaps (hlinfo
->mouse_face_overlay
)))
27817 /* Find the highest priority overlay with a mouse-face. */
27818 Lisp_Object overlay
= Qnil
;
27819 for (i
= noverlays
- 1; i
>= 0 && NILP (overlay
); --i
)
27821 mouse_face
= Foverlay_get (overlay_vec
[i
], Qmouse_face
);
27822 if (!NILP (mouse_face
))
27823 overlay
= overlay_vec
[i
];
27826 /* If we're highlighting the same overlay as before, there's
27827 no need to do that again. */
27828 if (!NILP (overlay
) && EQ (overlay
, hlinfo
->mouse_face_overlay
))
27829 goto check_help_echo
;
27830 hlinfo
->mouse_face_overlay
= overlay
;
27832 /* Clear the display of the old active region, if any. */
27833 if (clear_mouse_face (hlinfo
))
27834 cursor
= No_Cursor
;
27836 /* If no overlay applies, get a text property. */
27837 if (NILP (overlay
))
27838 mouse_face
= Fget_text_property (position
, Qmouse_face
, object
);
27840 /* Next, compute the bounds of the mouse highlighting and
27842 if (!NILP (mouse_face
) && STRINGP (object
))
27844 /* The mouse-highlighting comes from a display string
27845 with a mouse-face. */
27849 s
= Fprevious_single_property_change
27850 (make_number (pos
+ 1), Qmouse_face
, object
, Qnil
);
27851 e
= Fnext_single_property_change
27852 (position
, Qmouse_face
, object
, Qnil
);
27854 s
= make_number (0);
27856 e
= make_number (SCHARS (object
) - 1);
27857 mouse_face_from_string_pos (w
, hlinfo
, object
,
27858 XINT (s
), XINT (e
));
27859 hlinfo
->mouse_face_past_end
= 0;
27860 hlinfo
->mouse_face_window
= window
;
27861 hlinfo
->mouse_face_face_id
27862 = face_at_string_position (w
, object
, pos
, 0, 0, 0, &ignore
,
27863 glyph
->face_id
, 1);
27864 show_mouse_face (hlinfo
, DRAW_MOUSE_FACE
);
27865 cursor
= No_Cursor
;
27869 /* The mouse-highlighting, if any, comes from an overlay
27870 or text property in the buffer. */
27871 Lisp_Object buffer
IF_LINT (= Qnil
);
27872 Lisp_Object disp_string
IF_LINT (= Qnil
);
27874 if (STRINGP (object
))
27876 /* If we are on a display string with no mouse-face,
27877 check if the text under it has one. */
27878 struct glyph_row
*r
= MATRIX_ROW (w
->current_matrix
, vpos
);
27879 ptrdiff_t start
= MATRIX_ROW_START_CHARPOS (r
);
27880 pos
= string_buffer_position (object
, start
);
27883 mouse_face
= get_char_property_and_overlay
27884 (make_number (pos
), Qmouse_face
, w
->contents
, &overlay
);
27885 buffer
= w
->contents
;
27886 disp_string
= object
;
27892 disp_string
= Qnil
;
27895 if (!NILP (mouse_face
))
27897 Lisp_Object before
, after
;
27898 Lisp_Object before_string
, after_string
;
27899 /* To correctly find the limits of mouse highlight
27900 in a bidi-reordered buffer, we must not use the
27901 optimization of limiting the search in
27902 previous-single-property-change and
27903 next-single-property-change, because
27904 rows_from_pos_range needs the real start and end
27905 positions to DTRT in this case. That's because
27906 the first row visible in a window does not
27907 necessarily display the character whose position
27908 is the smallest. */
27910 NILP (BVAR (XBUFFER (buffer
), bidi_display_reordering
))
27911 ? Fmarker_position (w
->start
)
27914 NILP (BVAR (XBUFFER (buffer
), bidi_display_reordering
))
27915 ? make_number (BUF_Z (XBUFFER (buffer
))
27916 - XFASTINT (w
->window_end_pos
))
27919 if (NILP (overlay
))
27921 /* Handle the text property case. */
27922 before
= Fprevious_single_property_change
27923 (make_number (pos
+ 1), Qmouse_face
, buffer
, lim1
);
27924 after
= Fnext_single_property_change
27925 (make_number (pos
), Qmouse_face
, buffer
, lim2
);
27926 before_string
= after_string
= Qnil
;
27930 /* Handle the overlay case. */
27931 before
= Foverlay_start (overlay
);
27932 after
= Foverlay_end (overlay
);
27933 before_string
= Foverlay_get (overlay
, Qbefore_string
);
27934 after_string
= Foverlay_get (overlay
, Qafter_string
);
27936 if (!STRINGP (before_string
)) before_string
= Qnil
;
27937 if (!STRINGP (after_string
)) after_string
= Qnil
;
27940 mouse_face_from_buffer_pos (window
, hlinfo
, pos
,
27943 : XFASTINT (before
),
27945 ? BUF_Z (XBUFFER (buffer
))
27946 : XFASTINT (after
),
27947 before_string
, after_string
,
27949 cursor
= No_Cursor
;
27956 /* Look for a `help-echo' property. */
27957 if (NILP (help_echo_string
)) {
27958 Lisp_Object help
, overlay
;
27960 /* Check overlays first. */
27961 help
= overlay
= Qnil
;
27962 for (i
= noverlays
- 1; i
>= 0 && NILP (help
); --i
)
27964 overlay
= overlay_vec
[i
];
27965 help
= Foverlay_get (overlay
, Qhelp_echo
);
27970 help_echo_string
= help
;
27971 help_echo_window
= window
;
27972 help_echo_object
= overlay
;
27973 help_echo_pos
= pos
;
27977 Lisp_Object obj
= glyph
->object
;
27978 ptrdiff_t charpos
= glyph
->charpos
;
27980 /* Try text properties. */
27983 && charpos
< SCHARS (obj
))
27985 help
= Fget_text_property (make_number (charpos
),
27989 /* If the string itself doesn't specify a help-echo,
27990 see if the buffer text ``under'' it does. */
27991 struct glyph_row
*r
27992 = MATRIX_ROW (w
->current_matrix
, vpos
);
27993 ptrdiff_t start
= MATRIX_ROW_START_CHARPOS (r
);
27994 ptrdiff_t p
= string_buffer_position (obj
, start
);
27997 help
= Fget_char_property (make_number (p
),
27998 Qhelp_echo
, w
->contents
);
28007 else if (BUFFERP (obj
)
28010 help
= Fget_text_property (make_number (charpos
), Qhelp_echo
,
28015 help_echo_string
= help
;
28016 help_echo_window
= window
;
28017 help_echo_object
= obj
;
28018 help_echo_pos
= charpos
;
28023 #ifdef HAVE_WINDOW_SYSTEM
28024 /* Look for a `pointer' property. */
28025 if (FRAME_WINDOW_P (f
) && NILP (pointer
))
28027 /* Check overlays first. */
28028 for (i
= noverlays
- 1; i
>= 0 && NILP (pointer
); --i
)
28029 pointer
= Foverlay_get (overlay_vec
[i
], Qpointer
);
28031 if (NILP (pointer
))
28033 Lisp_Object obj
= glyph
->object
;
28034 ptrdiff_t charpos
= glyph
->charpos
;
28036 /* Try text properties. */
28039 && charpos
< SCHARS (obj
))
28041 pointer
= Fget_text_property (make_number (charpos
),
28043 if (NILP (pointer
))
28045 /* If the string itself doesn't specify a pointer,
28046 see if the buffer text ``under'' it does. */
28047 struct glyph_row
*r
28048 = MATRIX_ROW (w
->current_matrix
, vpos
);
28049 ptrdiff_t start
= MATRIX_ROW_START_CHARPOS (r
);
28050 ptrdiff_t p
= string_buffer_position (obj
, start
);
28052 pointer
= Fget_char_property (make_number (p
),
28053 Qpointer
, w
->contents
);
28056 else if (BUFFERP (obj
)
28059 pointer
= Fget_text_property (make_number (charpos
),
28063 #endif /* HAVE_WINDOW_SYSTEM */
28067 current_buffer
= obuf
;
28072 #ifdef HAVE_WINDOW_SYSTEM
28073 if (FRAME_WINDOW_P (f
))
28074 define_frame_cursor1 (f
, cursor
, pointer
);
28076 /* This is here to prevent a compiler error, about "label at end of
28077 compound statement". */
28084 Clear any mouse-face on window W. This function is part of the
28085 redisplay interface, and is called from try_window_id and similar
28086 functions to ensure the mouse-highlight is off. */
28089 x_clear_window_mouse_face (struct window
*w
)
28091 Mouse_HLInfo
*hlinfo
= MOUSE_HL_INFO (XFRAME (w
->frame
));
28092 Lisp_Object window
;
28095 XSETWINDOW (window
, w
);
28096 if (EQ (window
, hlinfo
->mouse_face_window
))
28097 clear_mouse_face (hlinfo
);
28103 Just discard the mouse face information for frame F, if any.
28104 This is used when the size of F is changed. */
28107 cancel_mouse_face (struct frame
*f
)
28109 Lisp_Object window
;
28110 Mouse_HLInfo
*hlinfo
= MOUSE_HL_INFO (f
);
28112 window
= hlinfo
->mouse_face_window
;
28113 if (! NILP (window
) && XFRAME (XWINDOW (window
)->frame
) == f
)
28115 hlinfo
->mouse_face_beg_row
= hlinfo
->mouse_face_beg_col
= -1;
28116 hlinfo
->mouse_face_end_row
= hlinfo
->mouse_face_end_col
= -1;
28117 hlinfo
->mouse_face_window
= Qnil
;
28123 /***********************************************************************
28125 ***********************************************************************/
28127 #ifdef HAVE_WINDOW_SYSTEM
28129 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
28130 which intersects rectangle R. R is in window-relative coordinates. */
28133 expose_area (struct window
*w
, struct glyph_row
*row
, XRectangle
*r
,
28134 enum glyph_row_area area
)
28136 struct glyph
*first
= row
->glyphs
[area
];
28137 struct glyph
*end
= row
->glyphs
[area
] + row
->used
[area
];
28138 struct glyph
*last
;
28139 int first_x
, start_x
, x
;
28141 if (area
== TEXT_AREA
&& row
->fill_line_p
)
28142 /* If row extends face to end of line write the whole line. */
28143 draw_glyphs (w
, 0, row
, area
,
28144 0, row
->used
[area
],
28145 DRAW_NORMAL_TEXT
, 0);
28148 /* Set START_X to the window-relative start position for drawing glyphs of
28149 AREA. The first glyph of the text area can be partially visible.
28150 The first glyphs of other areas cannot. */
28151 start_x
= window_box_left_offset (w
, area
);
28153 if (area
== TEXT_AREA
)
28156 /* Find the first glyph that must be redrawn. */
28158 && x
+ first
->pixel_width
< r
->x
)
28160 x
+= first
->pixel_width
;
28164 /* Find the last one. */
28168 && x
< r
->x
+ r
->width
)
28170 x
+= last
->pixel_width
;
28176 draw_glyphs (w
, first_x
- start_x
, row
, area
,
28177 first
- row
->glyphs
[area
], last
- row
->glyphs
[area
],
28178 DRAW_NORMAL_TEXT
, 0);
28183 /* Redraw the parts of the glyph row ROW on window W intersecting
28184 rectangle R. R is in window-relative coordinates. Value is
28185 non-zero if mouse-face was overwritten. */
28188 expose_line (struct window
*w
, struct glyph_row
*row
, XRectangle
*r
)
28190 eassert (row
->enabled_p
);
28192 if (row
->mode_line_p
|| w
->pseudo_window_p
)
28193 draw_glyphs (w
, 0, row
, TEXT_AREA
,
28194 0, row
->used
[TEXT_AREA
],
28195 DRAW_NORMAL_TEXT
, 0);
28198 if (row
->used
[LEFT_MARGIN_AREA
])
28199 expose_area (w
, row
, r
, LEFT_MARGIN_AREA
);
28200 if (row
->used
[TEXT_AREA
])
28201 expose_area (w
, row
, r
, TEXT_AREA
);
28202 if (row
->used
[RIGHT_MARGIN_AREA
])
28203 expose_area (w
, row
, r
, RIGHT_MARGIN_AREA
);
28204 draw_row_fringe_bitmaps (w
, row
);
28207 return row
->mouse_face_p
;
28211 /* Redraw those parts of glyphs rows during expose event handling that
28212 overlap other rows. Redrawing of an exposed line writes over parts
28213 of lines overlapping that exposed line; this function fixes that.
28215 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
28216 row in W's current matrix that is exposed and overlaps other rows.
28217 LAST_OVERLAPPING_ROW is the last such row. */
28220 expose_overlaps (struct window
*w
,
28221 struct glyph_row
*first_overlapping_row
,
28222 struct glyph_row
*last_overlapping_row
,
28225 struct glyph_row
*row
;
28227 for (row
= first_overlapping_row
; row
<= last_overlapping_row
; ++row
)
28228 if (row
->overlapping_p
)
28230 eassert (row
->enabled_p
&& !row
->mode_line_p
);
28233 if (row
->used
[LEFT_MARGIN_AREA
])
28234 x_fix_overlapping_area (w
, row
, LEFT_MARGIN_AREA
, OVERLAPS_BOTH
);
28236 if (row
->used
[TEXT_AREA
])
28237 x_fix_overlapping_area (w
, row
, TEXT_AREA
, OVERLAPS_BOTH
);
28239 if (row
->used
[RIGHT_MARGIN_AREA
])
28240 x_fix_overlapping_area (w
, row
, RIGHT_MARGIN_AREA
, OVERLAPS_BOTH
);
28246 /* Return non-zero if W's cursor intersects rectangle R. */
28249 phys_cursor_in_rect_p (struct window
*w
, XRectangle
*r
)
28251 XRectangle cr
, result
;
28252 struct glyph
*cursor_glyph
;
28253 struct glyph_row
*row
;
28255 if (w
->phys_cursor
.vpos
>= 0
28256 && w
->phys_cursor
.vpos
< w
->current_matrix
->nrows
28257 && (row
= MATRIX_ROW (w
->current_matrix
, w
->phys_cursor
.vpos
),
28259 && row
->cursor_in_fringe_p
)
28261 /* Cursor is in the fringe. */
28262 cr
.x
= window_box_right_offset (w
,
28263 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
28264 ? RIGHT_MARGIN_AREA
28267 cr
.width
= WINDOW_RIGHT_FRINGE_WIDTH (w
);
28268 cr
.height
= row
->height
;
28269 return x_intersect_rectangles (&cr
, r
, &result
);
28272 cursor_glyph
= get_phys_cursor_glyph (w
);
28275 /* r is relative to W's box, but w->phys_cursor.x is relative
28276 to left edge of W's TEXT area. Adjust it. */
28277 cr
.x
= window_box_left_offset (w
, TEXT_AREA
) + w
->phys_cursor
.x
;
28278 cr
.y
= w
->phys_cursor
.y
;
28279 cr
.width
= cursor_glyph
->pixel_width
;
28280 cr
.height
= w
->phys_cursor_height
;
28281 /* ++KFS: W32 version used W32-specific IntersectRect here, but
28282 I assume the effect is the same -- and this is portable. */
28283 return x_intersect_rectangles (&cr
, r
, &result
);
28285 /* If we don't understand the format, pretend we're not in the hot-spot. */
28291 Draw a vertical window border to the right of window W if W doesn't
28292 have vertical scroll bars. */
28295 x_draw_vertical_border (struct window
*w
)
28297 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
28299 /* We could do better, if we knew what type of scroll-bar the adjacent
28300 windows (on either side) have... But we don't :-(
28301 However, I think this works ok. ++KFS 2003-04-25 */
28303 /* Redraw borders between horizontally adjacent windows. Don't
28304 do it for frames with vertical scroll bars because either the
28305 right scroll bar of a window, or the left scroll bar of its
28306 neighbor will suffice as a border. */
28307 if (FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (w
->frame
)))
28310 /* Note: It is necessary to redraw both the left and the right
28311 borders, for when only this single window W is being
28313 if (!WINDOW_RIGHTMOST_P (w
)
28314 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w
))
28316 int x0
, x1
, y0
, y1
;
28318 window_box_edges (w
, -1, &x0
, &y0
, &x1
, &y1
);
28321 if (WINDOW_LEFT_FRINGE_WIDTH (w
) == 0)
28324 FRAME_RIF (f
)->draw_vertical_window_border (w
, x1
, y0
, y1
);
28326 if (!WINDOW_LEFTMOST_P (w
)
28327 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w
))
28329 int x0
, x1
, y0
, y1
;
28331 window_box_edges (w
, -1, &x0
, &y0
, &x1
, &y1
);
28334 if (WINDOW_LEFT_FRINGE_WIDTH (w
) == 0)
28337 FRAME_RIF (f
)->draw_vertical_window_border (w
, x0
, y0
, y1
);
28342 /* Redraw the part of window W intersection rectangle FR. Pixel
28343 coordinates in FR are frame-relative. Call this function with
28344 input blocked. Value is non-zero if the exposure overwrites
28348 expose_window (struct window
*w
, XRectangle
*fr
)
28350 struct frame
*f
= XFRAME (w
->frame
);
28352 int mouse_face_overwritten_p
= 0;
28354 /* If window is not yet fully initialized, do nothing. This can
28355 happen when toolkit scroll bars are used and a window is split.
28356 Reconfiguring the scroll bar will generate an expose for a newly
28358 if (w
->current_matrix
== NULL
)
28361 /* When we're currently updating the window, display and current
28362 matrix usually don't agree. Arrange for a thorough display
28364 if (w
== updated_window
)
28366 SET_FRAME_GARBAGED (f
);
28370 /* Frame-relative pixel rectangle of W. */
28371 wr
.x
= WINDOW_LEFT_EDGE_X (w
);
28372 wr
.y
= WINDOW_TOP_EDGE_Y (w
);
28373 wr
.width
= WINDOW_TOTAL_WIDTH (w
);
28374 wr
.height
= WINDOW_TOTAL_HEIGHT (w
);
28376 if (x_intersect_rectangles (fr
, &wr
, &r
))
28378 int yb
= window_text_bottom_y (w
);
28379 struct glyph_row
*row
;
28380 int cursor_cleared_p
, phys_cursor_on_p
;
28381 struct glyph_row
*first_overlapping_row
, *last_overlapping_row
;
28383 TRACE ((stderr
, "expose_window (%d, %d, %d, %d)\n",
28384 r
.x
, r
.y
, r
.width
, r
.height
));
28386 /* Convert to window coordinates. */
28387 r
.x
-= WINDOW_LEFT_EDGE_X (w
);
28388 r
.y
-= WINDOW_TOP_EDGE_Y (w
);
28390 /* Turn off the cursor. */
28391 if (!w
->pseudo_window_p
28392 && phys_cursor_in_rect_p (w
, &r
))
28394 x_clear_cursor (w
);
28395 cursor_cleared_p
= 1;
28398 cursor_cleared_p
= 0;
28400 /* If the row containing the cursor extends face to end of line,
28401 then expose_area might overwrite the cursor outside the
28402 rectangle and thus notice_overwritten_cursor might clear
28403 w->phys_cursor_on_p. We remember the original value and
28404 check later if it is changed. */
28405 phys_cursor_on_p
= w
->phys_cursor_on_p
;
28407 /* Update lines intersecting rectangle R. */
28408 first_overlapping_row
= last_overlapping_row
= NULL
;
28409 for (row
= w
->current_matrix
->rows
;
28414 int y1
= MATRIX_ROW_BOTTOM_Y (row
);
28416 if ((y0
>= r
.y
&& y0
< r
.y
+ r
.height
)
28417 || (y1
> r
.y
&& y1
< r
.y
+ r
.height
)
28418 || (r
.y
>= y0
&& r
.y
< y1
)
28419 || (r
.y
+ r
.height
> y0
&& r
.y
+ r
.height
< y1
))
28421 /* A header line may be overlapping, but there is no need
28422 to fix overlapping areas for them. KFS 2005-02-12 */
28423 if (row
->overlapping_p
&& !row
->mode_line_p
)
28425 if (first_overlapping_row
== NULL
)
28426 first_overlapping_row
= row
;
28427 last_overlapping_row
= row
;
28431 if (expose_line (w
, row
, &r
))
28432 mouse_face_overwritten_p
= 1;
28435 else if (row
->overlapping_p
)
28437 /* We must redraw a row overlapping the exposed area. */
28439 ? y0
+ row
->phys_height
> r
.y
28440 : y0
+ row
->ascent
- row
->phys_ascent
< r
.y
+r
.height
)
28442 if (first_overlapping_row
== NULL
)
28443 first_overlapping_row
= row
;
28444 last_overlapping_row
= row
;
28452 /* Display the mode line if there is one. */
28453 if (WINDOW_WANTS_MODELINE_P (w
)
28454 && (row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
),
28456 && row
->y
< r
.y
+ r
.height
)
28458 if (expose_line (w
, row
, &r
))
28459 mouse_face_overwritten_p
= 1;
28462 if (!w
->pseudo_window_p
)
28464 /* Fix the display of overlapping rows. */
28465 if (first_overlapping_row
)
28466 expose_overlaps (w
, first_overlapping_row
, last_overlapping_row
,
28469 /* Draw border between windows. */
28470 x_draw_vertical_border (w
);
28472 /* Turn the cursor on again. */
28473 if (cursor_cleared_p
28474 || (phys_cursor_on_p
&& !w
->phys_cursor_on_p
))
28475 update_window_cursor (w
, 1);
28479 return mouse_face_overwritten_p
;
28484 /* Redraw (parts) of all windows in the window tree rooted at W that
28485 intersect R. R contains frame pixel coordinates. Value is
28486 non-zero if the exposure overwrites mouse-face. */
28489 expose_window_tree (struct window
*w
, XRectangle
*r
)
28491 struct frame
*f
= XFRAME (w
->frame
);
28492 int mouse_face_overwritten_p
= 0;
28494 while (w
&& !FRAME_GARBAGED_P (f
))
28496 if (WINDOWP (w
->contents
))
28497 mouse_face_overwritten_p
28498 |= expose_window_tree (XWINDOW (w
->contents
), r
);
28500 mouse_face_overwritten_p
|= expose_window (w
, r
);
28502 w
= NILP (w
->next
) ? NULL
: XWINDOW (w
->next
);
28505 return mouse_face_overwritten_p
;
28510 Redisplay an exposed area of frame F. X and Y are the upper-left
28511 corner of the exposed rectangle. W and H are width and height of
28512 the exposed area. All are pixel values. W or H zero means redraw
28513 the entire frame. */
28516 expose_frame (struct frame
*f
, int x
, int y
, int w
, int h
)
28519 int mouse_face_overwritten_p
= 0;
28521 TRACE ((stderr
, "expose_frame "));
28523 /* No need to redraw if frame will be redrawn soon. */
28524 if (FRAME_GARBAGED_P (f
))
28526 TRACE ((stderr
, " garbaged\n"));
28530 /* If basic faces haven't been realized yet, there is no point in
28531 trying to redraw anything. This can happen when we get an expose
28532 event while Emacs is starting, e.g. by moving another window. */
28533 if (FRAME_FACE_CACHE (f
) == NULL
28534 || FRAME_FACE_CACHE (f
)->used
< BASIC_FACE_ID_SENTINEL
)
28536 TRACE ((stderr
, " no faces\n"));
28540 if (w
== 0 || h
== 0)
28543 r
.width
= FRAME_COLUMN_WIDTH (f
) * FRAME_COLS (f
);
28544 r
.height
= FRAME_LINE_HEIGHT (f
) * FRAME_LINES (f
);
28554 TRACE ((stderr
, "(%d, %d, %d, %d)\n", r
.x
, r
.y
, r
.width
, r
.height
));
28555 mouse_face_overwritten_p
= expose_window_tree (XWINDOW (f
->root_window
), &r
);
28557 if (WINDOWP (f
->tool_bar_window
))
28558 mouse_face_overwritten_p
28559 |= expose_window (XWINDOW (f
->tool_bar_window
), &r
);
28561 #ifdef HAVE_X_WINDOWS
28563 #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
28564 if (WINDOWP (f
->menu_bar_window
))
28565 mouse_face_overwritten_p
28566 |= expose_window (XWINDOW (f
->menu_bar_window
), &r
);
28567 #endif /* not USE_X_TOOLKIT and not USE_GTK */
28571 /* Some window managers support a focus-follows-mouse style with
28572 delayed raising of frames. Imagine a partially obscured frame,
28573 and moving the mouse into partially obscured mouse-face on that
28574 frame. The visible part of the mouse-face will be highlighted,
28575 then the WM raises the obscured frame. With at least one WM, KDE
28576 2.1, Emacs is not getting any event for the raising of the frame
28577 (even tried with SubstructureRedirectMask), only Expose events.
28578 These expose events will draw text normally, i.e. not
28579 highlighted. Which means we must redo the highlight here.
28580 Subsume it under ``we love X''. --gerd 2001-08-15 */
28581 /* Included in Windows version because Windows most likely does not
28582 do the right thing if any third party tool offers
28583 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
28584 if (mouse_face_overwritten_p
&& !FRAME_GARBAGED_P (f
))
28586 Mouse_HLInfo
*hlinfo
= MOUSE_HL_INFO (f
);
28587 if (f
== hlinfo
->mouse_face_mouse_frame
)
28589 int mouse_x
= hlinfo
->mouse_face_mouse_x
;
28590 int mouse_y
= hlinfo
->mouse_face_mouse_y
;
28591 clear_mouse_face (hlinfo
);
28592 note_mouse_highlight (f
, mouse_x
, mouse_y
);
28599 Determine the intersection of two rectangles R1 and R2. Return
28600 the intersection in *RESULT. Value is non-zero if RESULT is not
28604 x_intersect_rectangles (XRectangle
*r1
, XRectangle
*r2
, XRectangle
*result
)
28606 XRectangle
*left
, *right
;
28607 XRectangle
*upper
, *lower
;
28608 int intersection_p
= 0;
28610 /* Rearrange so that R1 is the left-most rectangle. */
28612 left
= r1
, right
= r2
;
28614 left
= r2
, right
= r1
;
28616 /* X0 of the intersection is right.x0, if this is inside R1,
28617 otherwise there is no intersection. */
28618 if (right
->x
<= left
->x
+ left
->width
)
28620 result
->x
= right
->x
;
28622 /* The right end of the intersection is the minimum of
28623 the right ends of left and right. */
28624 result
->width
= (min (left
->x
+ left
->width
, right
->x
+ right
->width
)
28627 /* Same game for Y. */
28629 upper
= r1
, lower
= r2
;
28631 upper
= r2
, lower
= r1
;
28633 /* The upper end of the intersection is lower.y0, if this is inside
28634 of upper. Otherwise, there is no intersection. */
28635 if (lower
->y
<= upper
->y
+ upper
->height
)
28637 result
->y
= lower
->y
;
28639 /* The lower end of the intersection is the minimum of the lower
28640 ends of upper and lower. */
28641 result
->height
= (min (lower
->y
+ lower
->height
,
28642 upper
->y
+ upper
->height
)
28644 intersection_p
= 1;
28648 return intersection_p
;
28651 #endif /* HAVE_WINDOW_SYSTEM */
28654 /***********************************************************************
28656 ***********************************************************************/
28659 syms_of_xdisp (void)
28661 Vwith_echo_area_save_vector
= Qnil
;
28662 staticpro (&Vwith_echo_area_save_vector
);
28664 Vmessage_stack
= Qnil
;
28665 staticpro (&Vmessage_stack
);
28667 DEFSYM (Qinhibit_redisplay
, "inhibit-redisplay");
28668 DEFSYM (Qredisplay_internal
, "redisplay_internal (C function)");
28670 message_dolog_marker1
= Fmake_marker ();
28671 staticpro (&message_dolog_marker1
);
28672 message_dolog_marker2
= Fmake_marker ();
28673 staticpro (&message_dolog_marker2
);
28674 message_dolog_marker3
= Fmake_marker ();
28675 staticpro (&message_dolog_marker3
);
28678 defsubr (&Sdump_frame_glyph_matrix
);
28679 defsubr (&Sdump_glyph_matrix
);
28680 defsubr (&Sdump_glyph_row
);
28681 defsubr (&Sdump_tool_bar_row
);
28682 defsubr (&Strace_redisplay
);
28683 defsubr (&Strace_to_stderr
);
28685 #ifdef HAVE_WINDOW_SYSTEM
28686 defsubr (&Stool_bar_lines_needed
);
28687 defsubr (&Slookup_image_map
);
28689 defsubr (&Sformat_mode_line
);
28690 defsubr (&Sinvisible_p
);
28691 defsubr (&Scurrent_bidi_paragraph_direction
);
28693 DEFSYM (Qmenu_bar_update_hook
, "menu-bar-update-hook");
28694 DEFSYM (Qoverriding_terminal_local_map
, "overriding-terminal-local-map");
28695 DEFSYM (Qoverriding_local_map
, "overriding-local-map");
28696 DEFSYM (Qwindow_scroll_functions
, "window-scroll-functions");
28697 DEFSYM (Qwindow_text_change_functions
, "window-text-change-functions");
28698 DEFSYM (Qredisplay_end_trigger_functions
, "redisplay-end-trigger-functions");
28699 DEFSYM (Qinhibit_point_motion_hooks
, "inhibit-point-motion-hooks");
28700 DEFSYM (Qeval
, "eval");
28701 DEFSYM (QCdata
, ":data");
28702 DEFSYM (Qdisplay
, "display");
28703 DEFSYM (Qspace_width
, "space-width");
28704 DEFSYM (Qraise
, "raise");
28705 DEFSYM (Qslice
, "slice");
28706 DEFSYM (Qspace
, "space");
28707 DEFSYM (Qmargin
, "margin");
28708 DEFSYM (Qpointer
, "pointer");
28709 DEFSYM (Qleft_margin
, "left-margin");
28710 DEFSYM (Qright_margin
, "right-margin");
28711 DEFSYM (Qcenter
, "center");
28712 DEFSYM (Qline_height
, "line-height");
28713 DEFSYM (QCalign_to
, ":align-to");
28714 DEFSYM (QCrelative_width
, ":relative-width");
28715 DEFSYM (QCrelative_height
, ":relative-height");
28716 DEFSYM (QCeval
, ":eval");
28717 DEFSYM (QCpropertize
, ":propertize");
28718 DEFSYM (QCfile
, ":file");
28719 DEFSYM (Qfontified
, "fontified");
28720 DEFSYM (Qfontification_functions
, "fontification-functions");
28721 DEFSYM (Qtrailing_whitespace
, "trailing-whitespace");
28722 DEFSYM (Qescape_glyph
, "escape-glyph");
28723 DEFSYM (Qnobreak_space
, "nobreak-space");
28724 DEFSYM (Qimage
, "image");
28725 DEFSYM (Qtext
, "text");
28726 DEFSYM (Qboth
, "both");
28727 DEFSYM (Qboth_horiz
, "both-horiz");
28728 DEFSYM (Qtext_image_horiz
, "text-image-horiz");
28729 DEFSYM (QCmap
, ":map");
28730 DEFSYM (QCpointer
, ":pointer");
28731 DEFSYM (Qrect
, "rect");
28732 DEFSYM (Qcircle
, "circle");
28733 DEFSYM (Qpoly
, "poly");
28734 DEFSYM (Qmessage_truncate_lines
, "message-truncate-lines");
28735 DEFSYM (Qgrow_only
, "grow-only");
28736 DEFSYM (Qinhibit_menubar_update
, "inhibit-menubar-update");
28737 DEFSYM (Qinhibit_eval_during_redisplay
, "inhibit-eval-during-redisplay");
28738 DEFSYM (Qposition
, "position");
28739 DEFSYM (Qbuffer_position
, "buffer-position");
28740 DEFSYM (Qobject
, "object");
28741 DEFSYM (Qbar
, "bar");
28742 DEFSYM (Qhbar
, "hbar");
28743 DEFSYM (Qbox
, "box");
28744 DEFSYM (Qhollow
, "hollow");
28745 DEFSYM (Qhand
, "hand");
28746 DEFSYM (Qarrow
, "arrow");
28747 DEFSYM (Qinhibit_free_realized_faces
, "inhibit-free-realized-faces");
28749 list_of_error
= Fcons (Fcons (intern_c_string ("error"),
28750 Fcons (intern_c_string ("void-variable"), Qnil
)),
28752 staticpro (&list_of_error
);
28754 DEFSYM (Qlast_arrow_position
, "last-arrow-position");
28755 DEFSYM (Qlast_arrow_string
, "last-arrow-string");
28756 DEFSYM (Qoverlay_arrow_string
, "overlay-arrow-string");
28757 DEFSYM (Qoverlay_arrow_bitmap
, "overlay-arrow-bitmap");
28759 echo_buffer
[0] = echo_buffer
[1] = Qnil
;
28760 staticpro (&echo_buffer
[0]);
28761 staticpro (&echo_buffer
[1]);
28763 echo_area_buffer
[0] = echo_area_buffer
[1] = Qnil
;
28764 staticpro (&echo_area_buffer
[0]);
28765 staticpro (&echo_area_buffer
[1]);
28767 Vmessages_buffer_name
= build_pure_c_string ("*Messages*");
28768 staticpro (&Vmessages_buffer_name
);
28770 mode_line_proptrans_alist
= Qnil
;
28771 staticpro (&mode_line_proptrans_alist
);
28772 mode_line_string_list
= Qnil
;
28773 staticpro (&mode_line_string_list
);
28774 mode_line_string_face
= Qnil
;
28775 staticpro (&mode_line_string_face
);
28776 mode_line_string_face_prop
= Qnil
;
28777 staticpro (&mode_line_string_face_prop
);
28778 Vmode_line_unwind_vector
= Qnil
;
28779 staticpro (&Vmode_line_unwind_vector
);
28781 DEFSYM (Qmode_line_default_help_echo
, "mode-line-default-help-echo");
28783 help_echo_string
= Qnil
;
28784 staticpro (&help_echo_string
);
28785 help_echo_object
= Qnil
;
28786 staticpro (&help_echo_object
);
28787 help_echo_window
= Qnil
;
28788 staticpro (&help_echo_window
);
28789 previous_help_echo_string
= Qnil
;
28790 staticpro (&previous_help_echo_string
);
28791 help_echo_pos
= -1;
28793 DEFSYM (Qright_to_left
, "right-to-left");
28794 DEFSYM (Qleft_to_right
, "left-to-right");
28796 #ifdef HAVE_WINDOW_SYSTEM
28797 DEFVAR_BOOL ("x-stretch-cursor", x_stretch_cursor_p
,
28798 doc
: /* Non-nil means draw block cursor as wide as the glyph under it.
28799 For example, if a block cursor is over a tab, it will be drawn as
28800 wide as that tab on the display. */);
28801 x_stretch_cursor_p
= 0;
28804 DEFVAR_LISP ("show-trailing-whitespace", Vshow_trailing_whitespace
,
28805 doc
: /* Non-nil means highlight trailing whitespace.
28806 The face used for trailing whitespace is `trailing-whitespace'. */);
28807 Vshow_trailing_whitespace
= Qnil
;
28809 DEFVAR_LISP ("nobreak-char-display", Vnobreak_char_display
,
28810 doc
: /* Control highlighting of non-ASCII space and hyphen chars.
28811 If the value is t, Emacs highlights non-ASCII chars which have the
28812 same appearance as an ASCII space or hyphen, using the `nobreak-space'
28813 or `escape-glyph' face respectively.
28815 U+00A0 (no-break space), U+00AD (soft hyphen), U+2010 (hyphen), and
28816 U+2011 (non-breaking hyphen) are affected.
28818 Any other non-nil value means to display these characters as a escape
28819 glyph followed by an ordinary space or hyphen.
28821 A value of nil means no special handling of these characters. */);
28822 Vnobreak_char_display
= Qt
;
28824 DEFVAR_LISP ("void-text-area-pointer", Vvoid_text_area_pointer
,
28825 doc
: /* The pointer shape to show in void text areas.
28826 A value of nil means to show the text pointer. Other options are `arrow',
28827 `text', `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
28828 Vvoid_text_area_pointer
= Qarrow
;
28830 DEFVAR_LISP ("inhibit-redisplay", Vinhibit_redisplay
,
28831 doc
: /* Non-nil means don't actually do any redisplay.
28832 This is used for internal purposes. */);
28833 Vinhibit_redisplay
= Qnil
;
28835 DEFVAR_LISP ("global-mode-string", Vglobal_mode_string
,
28836 doc
: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
28837 Vglobal_mode_string
= Qnil
;
28839 DEFVAR_LISP ("overlay-arrow-position", Voverlay_arrow_position
,
28840 doc
: /* Marker for where to display an arrow on top of the buffer text.
28841 This must be the beginning of a line in order to work.
28842 See also `overlay-arrow-string'. */);
28843 Voverlay_arrow_position
= Qnil
;
28845 DEFVAR_LISP ("overlay-arrow-string", Voverlay_arrow_string
,
28846 doc
: /* String to display as an arrow in non-window frames.
28847 See also `overlay-arrow-position'. */);
28848 Voverlay_arrow_string
= build_pure_c_string ("=>");
28850 DEFVAR_LISP ("overlay-arrow-variable-list", Voverlay_arrow_variable_list
,
28851 doc
: /* List of variables (symbols) which hold markers for overlay arrows.
28852 The symbols on this list are examined during redisplay to determine
28853 where to display overlay arrows. */);
28854 Voverlay_arrow_variable_list
28855 = Fcons (intern_c_string ("overlay-arrow-position"), Qnil
);
28857 DEFVAR_INT ("scroll-step", emacs_scroll_step
,
28858 doc
: /* The number of lines to try scrolling a window by when point moves out.
28859 If that fails to bring point back on frame, point is centered instead.
28860 If this is zero, point is always centered after it moves off frame.
28861 If you want scrolling to always be a line at a time, you should set
28862 `scroll-conservatively' to a large value rather than set this to 1. */);
28864 DEFVAR_INT ("scroll-conservatively", scroll_conservatively
,
28865 doc
: /* Scroll up to this many lines, to bring point back on screen.
28866 If point moves off-screen, redisplay will scroll by up to
28867 `scroll-conservatively' lines in order to bring point just barely
28868 onto the screen again. If that cannot be done, then redisplay
28869 recenters point as usual.
28871 If the value is greater than 100, redisplay will never recenter point,
28872 but will always scroll just enough text to bring point into view, even
28873 if you move far away.
28875 A value of zero means always recenter point if it moves off screen. */);
28876 scroll_conservatively
= 0;
28878 DEFVAR_INT ("scroll-margin", scroll_margin
,
28879 doc
: /* Number of lines of margin at the top and bottom of a window.
28880 Recenter the window whenever point gets within this many lines
28881 of the top or bottom of the window. */);
28884 DEFVAR_LISP ("display-pixels-per-inch", Vdisplay_pixels_per_inch
,
28885 doc
: /* Pixels per inch value for non-window system displays.
28886 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
28887 Vdisplay_pixels_per_inch
= make_float (72.0);
28890 DEFVAR_INT ("debug-end-pos", debug_end_pos
, doc
: /* Don't ask. */);
28893 DEFVAR_LISP ("truncate-partial-width-windows",
28894 Vtruncate_partial_width_windows
,
28895 doc
: /* Non-nil means truncate lines in windows narrower than the frame.
28896 For an integer value, truncate lines in each window narrower than the
28897 full frame width, provided the window width is less than that integer;
28898 otherwise, respect the value of `truncate-lines'.
28900 For any other non-nil value, truncate lines in all windows that do
28901 not span the full frame width.
28903 A value of nil means to respect the value of `truncate-lines'.
28905 If `word-wrap' is enabled, you might want to reduce this. */);
28906 Vtruncate_partial_width_windows
= make_number (50);
28908 DEFVAR_LISP ("line-number-display-limit", Vline_number_display_limit
,
28909 doc
: /* Maximum buffer size for which line number should be displayed.
28910 If the buffer is bigger than this, the line number does not appear
28911 in the mode line. A value of nil means no limit. */);
28912 Vline_number_display_limit
= Qnil
;
28914 DEFVAR_INT ("line-number-display-limit-width",
28915 line_number_display_limit_width
,
28916 doc
: /* Maximum line width (in characters) for line number display.
28917 If the average length of the lines near point is bigger than this, then the
28918 line number may be omitted from the mode line. */);
28919 line_number_display_limit_width
= 200;
28921 DEFVAR_BOOL ("highlight-nonselected-windows", highlight_nonselected_windows
,
28922 doc
: /* Non-nil means highlight region even in nonselected windows. */);
28923 highlight_nonselected_windows
= 0;
28925 DEFVAR_BOOL ("multiple-frames", multiple_frames
,
28926 doc
: /* Non-nil if more than one frame is visible on this display.
28927 Minibuffer-only frames don't count, but iconified frames do.
28928 This variable is not guaranteed to be accurate except while processing
28929 `frame-title-format' and `icon-title-format'. */);
28931 DEFVAR_LISP ("frame-title-format", Vframe_title_format
,
28932 doc
: /* Template for displaying the title bar of visible frames.
28933 \(Assuming the window manager supports this feature.)
28935 This variable has the same structure as `mode-line-format', except that
28936 the %c and %l constructs are ignored. It is used only on frames for
28937 which no explicit name has been set \(see `modify-frame-parameters'). */);
28939 DEFVAR_LISP ("icon-title-format", Vicon_title_format
,
28940 doc
: /* Template for displaying the title bar of an iconified frame.
28941 \(Assuming the window manager supports this feature.)
28942 This variable has the same structure as `mode-line-format' (which see),
28943 and is used only on frames for which no explicit name has been set
28944 \(see `modify-frame-parameters'). */);
28946 = Vframe_title_format
28947 = listn (CONSTYPE_PURE
, 3,
28948 intern_c_string ("multiple-frames"),
28949 build_pure_c_string ("%b"),
28950 listn (CONSTYPE_PURE
, 4,
28951 empty_unibyte_string
,
28952 intern_c_string ("invocation-name"),
28953 build_pure_c_string ("@"),
28954 intern_c_string ("system-name")));
28956 DEFVAR_LISP ("message-log-max", Vmessage_log_max
,
28957 doc
: /* Maximum number of lines to keep in the message log buffer.
28958 If nil, disable message logging. If t, log messages but don't truncate
28959 the buffer when it becomes large. */);
28960 Vmessage_log_max
= make_number (1000);
28962 DEFVAR_LISP ("window-size-change-functions", Vwindow_size_change_functions
,
28963 doc
: /* Functions called before redisplay, if window sizes have changed.
28964 The value should be a list of functions that take one argument.
28965 Just before redisplay, for each frame, if any of its windows have changed
28966 size since the last redisplay, or have been split or deleted,
28967 all the functions in the list are called, with the frame as argument. */);
28968 Vwindow_size_change_functions
= Qnil
;
28970 DEFVAR_LISP ("window-scroll-functions", Vwindow_scroll_functions
,
28971 doc
: /* List of functions to call before redisplaying a window with scrolling.
28972 Each function is called with two arguments, the window and its new
28973 display-start position. Note that these functions are also called by
28974 `set-window-buffer'. Also note that the value of `window-end' is not
28975 valid when these functions are called.
28977 Warning: Do not use this feature to alter the way the window
28978 is scrolled. It is not designed for that, and such use probably won't
28980 Vwindow_scroll_functions
= Qnil
;
28982 DEFVAR_LISP ("window-text-change-functions",
28983 Vwindow_text_change_functions
,
28984 doc
: /* Functions to call in redisplay when text in the window might change. */);
28985 Vwindow_text_change_functions
= Qnil
;
28987 DEFVAR_LISP ("redisplay-end-trigger-functions", Vredisplay_end_trigger_functions
,
28988 doc
: /* Functions called when redisplay of a window reaches the end trigger.
28989 Each function is called with two arguments, the window and the end trigger value.
28990 See `set-window-redisplay-end-trigger'. */);
28991 Vredisplay_end_trigger_functions
= Qnil
;
28993 DEFVAR_LISP ("mouse-autoselect-window", Vmouse_autoselect_window
,
28994 doc
: /* Non-nil means autoselect window with mouse pointer.
28995 If nil, do not autoselect windows.
28996 A positive number means delay autoselection by that many seconds: a
28997 window is autoselected only after the mouse has remained in that
28998 window for the duration of the delay.
28999 A negative number has a similar effect, but causes windows to be
29000 autoselected only after the mouse has stopped moving. \(Because of
29001 the way Emacs compares mouse events, you will occasionally wait twice
29002 that time before the window gets selected.\)
29003 Any other value means to autoselect window instantaneously when the
29004 mouse pointer enters it.
29006 Autoselection selects the minibuffer only if it is active, and never
29007 unselects the minibuffer if it is active.
29009 When customizing this variable make sure that the actual value of
29010 `focus-follows-mouse' matches the behavior of your window manager. */);
29011 Vmouse_autoselect_window
= Qnil
;
29013 DEFVAR_LISP ("auto-resize-tool-bars", Vauto_resize_tool_bars
,
29014 doc
: /* Non-nil means automatically resize tool-bars.
29015 This dynamically changes the tool-bar's height to the minimum height
29016 that is needed to make all tool-bar items visible.
29017 If value is `grow-only', the tool-bar's height is only increased
29018 automatically; to decrease the tool-bar height, use \\[recenter]. */);
29019 Vauto_resize_tool_bars
= Qt
;
29021 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", auto_raise_tool_bar_buttons_p
,
29022 doc
: /* Non-nil means raise tool-bar buttons when the mouse moves over them. */);
29023 auto_raise_tool_bar_buttons_p
= 1;
29025 DEFVAR_BOOL ("make-cursor-line-fully-visible", make_cursor_line_fully_visible_p
,
29026 doc
: /* Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
29027 make_cursor_line_fully_visible_p
= 1;
29029 DEFVAR_LISP ("tool-bar-border", Vtool_bar_border
,
29030 doc
: /* Border below tool-bar in pixels.
29031 If an integer, use it as the height of the border.
29032 If it is one of `internal-border-width' or `border-width', use the
29033 value of the corresponding frame parameter.
29034 Otherwise, no border is added below the tool-bar. */);
29035 Vtool_bar_border
= Qinternal_border_width
;
29037 DEFVAR_LISP ("tool-bar-button-margin", Vtool_bar_button_margin
,
29038 doc
: /* Margin around tool-bar buttons in pixels.
29039 If an integer, use that for both horizontal and vertical margins.
29040 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
29041 HORZ specifying the horizontal margin, and VERT specifying the
29042 vertical margin. */);
29043 Vtool_bar_button_margin
= make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN
);
29045 DEFVAR_INT ("tool-bar-button-relief", tool_bar_button_relief
,
29046 doc
: /* Relief thickness of tool-bar buttons. */);
29047 tool_bar_button_relief
= DEFAULT_TOOL_BAR_BUTTON_RELIEF
;
29049 DEFVAR_LISP ("tool-bar-style", Vtool_bar_style
,
29050 doc
: /* Tool bar style to use.
29052 image - show images only
29053 text - show text only
29054 both - show both, text below image
29055 both-horiz - show text to the right of the image
29056 text-image-horiz - show text to the left of the image
29057 any other - use system default or image if no system default.
29059 This variable only affects the GTK+ toolkit version of Emacs. */);
29060 Vtool_bar_style
= Qnil
;
29062 DEFVAR_INT ("tool-bar-max-label-size", tool_bar_max_label_size
,
29063 doc
: /* Maximum number of characters a label can have to be shown.
29064 The tool bar style must also show labels for this to have any effect, see
29065 `tool-bar-style'. */);
29066 tool_bar_max_label_size
= DEFAULT_TOOL_BAR_LABEL_SIZE
;
29068 DEFVAR_LISP ("fontification-functions", Vfontification_functions
,
29069 doc
: /* List of functions to call to fontify regions of text.
29070 Each function is called with one argument POS. Functions must
29071 fontify a region starting at POS in the current buffer, and give
29072 fontified regions the property `fontified'. */);
29073 Vfontification_functions
= Qnil
;
29074 Fmake_variable_buffer_local (Qfontification_functions
);
29076 DEFVAR_BOOL ("unibyte-display-via-language-environment",
29077 unibyte_display_via_language_environment
,
29078 doc
: /* Non-nil means display unibyte text according to language environment.
29079 Specifically, this means that raw bytes in the range 160-255 decimal
29080 are displayed by converting them to the equivalent multibyte characters
29081 according to the current language environment. As a result, they are
29082 displayed according to the current fontset.
29084 Note that this variable affects only how these bytes are displayed,
29085 but does not change the fact they are interpreted as raw bytes. */);
29086 unibyte_display_via_language_environment
= 0;
29088 DEFVAR_LISP ("max-mini-window-height", Vmax_mini_window_height
,
29089 doc
: /* Maximum height for resizing mini-windows (the minibuffer and the echo area).
29090 If a float, it specifies a fraction of the mini-window frame's height.
29091 If an integer, it specifies a number of lines. */);
29092 Vmax_mini_window_height
= make_float (0.25);
29094 DEFVAR_LISP ("resize-mini-windows", Vresize_mini_windows
,
29095 doc
: /* How to resize mini-windows (the minibuffer and the echo area).
29096 A value of nil means don't automatically resize mini-windows.
29097 A value of t means resize them to fit the text displayed in them.
29098 A value of `grow-only', the default, means let mini-windows grow only;
29099 they return to their normal size when the minibuffer is closed, or the
29100 echo area becomes empty. */);
29101 Vresize_mini_windows
= Qgrow_only
;
29103 DEFVAR_LISP ("blink-cursor-alist", Vblink_cursor_alist
,
29104 doc
: /* Alist specifying how to blink the cursor off.
29105 Each element has the form (ON-STATE . OFF-STATE). Whenever the
29106 `cursor-type' frame-parameter or variable equals ON-STATE,
29107 comparing using `equal', Emacs uses OFF-STATE to specify
29108 how to blink it off. ON-STATE and OFF-STATE are values for
29109 the `cursor-type' frame parameter.
29111 If a frame's ON-STATE has no entry in this list,
29112 the frame's other specifications determine how to blink the cursor off. */);
29113 Vblink_cursor_alist
= Qnil
;
29115 DEFVAR_BOOL ("auto-hscroll-mode", automatic_hscrolling_p
,
29116 doc
: /* Allow or disallow automatic horizontal scrolling of windows.
29117 If non-nil, windows are automatically scrolled horizontally to make
29118 point visible. */);
29119 automatic_hscrolling_p
= 1;
29120 DEFSYM (Qauto_hscroll_mode
, "auto-hscroll-mode");
29122 DEFVAR_INT ("hscroll-margin", hscroll_margin
,
29123 doc
: /* How many columns away from the window edge point is allowed to get
29124 before automatic hscrolling will horizontally scroll the window. */);
29125 hscroll_margin
= 5;
29127 DEFVAR_LISP ("hscroll-step", Vhscroll_step
,
29128 doc
: /* How many columns to scroll the window when point gets too close to the edge.
29129 When point is less than `hscroll-margin' columns from the window
29130 edge, automatic hscrolling will scroll the window by the amount of columns
29131 determined by this variable. If its value is a positive integer, scroll that
29132 many columns. If it's a positive floating-point number, it specifies the
29133 fraction of the window's width to scroll. If it's nil or zero, point will be
29134 centered horizontally after the scroll. Any other value, including negative
29135 numbers, are treated as if the value were zero.
29137 Automatic hscrolling always moves point outside the scroll margin, so if
29138 point was more than scroll step columns inside the margin, the window will
29139 scroll more than the value given by the scroll step.
29141 Note that the lower bound for automatic hscrolling specified by `scroll-left'
29142 and `scroll-right' overrides this variable's effect. */);
29143 Vhscroll_step
= make_number (0);
29145 DEFVAR_BOOL ("message-truncate-lines", message_truncate_lines
,
29146 doc
: /* If non-nil, messages are truncated instead of resizing the echo area.
29147 Bind this around calls to `message' to let it take effect. */);
29148 message_truncate_lines
= 0;
29150 DEFVAR_LISP ("menu-bar-update-hook", Vmenu_bar_update_hook
,
29151 doc
: /* Normal hook run to update the menu bar definitions.
29152 Redisplay runs this hook before it redisplays the menu bar.
29153 This is used to update submenus such as Buffers,
29154 whose contents depend on various data. */);
29155 Vmenu_bar_update_hook
= Qnil
;
29157 DEFVAR_LISP ("menu-updating-frame", Vmenu_updating_frame
,
29158 doc
: /* Frame for which we are updating a menu.
29159 The enable predicate for a menu binding should check this variable. */);
29160 Vmenu_updating_frame
= Qnil
;
29162 DEFVAR_BOOL ("inhibit-menubar-update", inhibit_menubar_update
,
29163 doc
: /* Non-nil means don't update menu bars. Internal use only. */);
29164 inhibit_menubar_update
= 0;
29166 DEFVAR_LISP ("wrap-prefix", Vwrap_prefix
,
29167 doc
: /* Prefix prepended to all continuation lines at display time.
29168 The value may be a string, an image, or a stretch-glyph; it is
29169 interpreted in the same way as the value of a `display' text property.
29171 This variable is overridden by any `wrap-prefix' text or overlay
29174 To add a prefix to non-continuation lines, use `line-prefix'. */);
29175 Vwrap_prefix
= Qnil
;
29176 DEFSYM (Qwrap_prefix
, "wrap-prefix");
29177 Fmake_variable_buffer_local (Qwrap_prefix
);
29179 DEFVAR_LISP ("line-prefix", Vline_prefix
,
29180 doc
: /* Prefix prepended to all non-continuation lines at display time.
29181 The value may be a string, an image, or a stretch-glyph; it is
29182 interpreted in the same way as the value of a `display' text property.
29184 This variable is overridden by any `line-prefix' text or overlay
29187 To add a prefix to continuation lines, use `wrap-prefix'. */);
29188 Vline_prefix
= Qnil
;
29189 DEFSYM (Qline_prefix
, "line-prefix");
29190 Fmake_variable_buffer_local (Qline_prefix
);
29192 DEFVAR_BOOL ("inhibit-eval-during-redisplay", inhibit_eval_during_redisplay
,
29193 doc
: /* Non-nil means don't eval Lisp during redisplay. */);
29194 inhibit_eval_during_redisplay
= 0;
29196 DEFVAR_BOOL ("inhibit-free-realized-faces", inhibit_free_realized_faces
,
29197 doc
: /* Non-nil means don't free realized faces. Internal use only. */);
29198 inhibit_free_realized_faces
= 0;
29201 DEFVAR_BOOL ("inhibit-try-window-id", inhibit_try_window_id
,
29202 doc
: /* Inhibit try_window_id display optimization. */);
29203 inhibit_try_window_id
= 0;
29205 DEFVAR_BOOL ("inhibit-try-window-reusing", inhibit_try_window_reusing
,
29206 doc
: /* Inhibit try_window_reusing display optimization. */);
29207 inhibit_try_window_reusing
= 0;
29209 DEFVAR_BOOL ("inhibit-try-cursor-movement", inhibit_try_cursor_movement
,
29210 doc
: /* Inhibit try_cursor_movement display optimization. */);
29211 inhibit_try_cursor_movement
= 0;
29212 #endif /* GLYPH_DEBUG */
29214 DEFVAR_INT ("overline-margin", overline_margin
,
29215 doc
: /* Space between overline and text, in pixels.
29216 The default value is 2: the height of the overline (1 pixel) plus 1 pixel
29217 margin to the character height. */);
29218 overline_margin
= 2;
29220 DEFVAR_INT ("underline-minimum-offset",
29221 underline_minimum_offset
,
29222 doc
: /* Minimum distance between baseline and underline.
29223 This can improve legibility of underlined text at small font sizes,
29224 particularly when using variable `x-use-underline-position-properties'
29225 with fonts that specify an UNDERLINE_POSITION relatively close to the
29226 baseline. The default value is 1. */);
29227 underline_minimum_offset
= 1;
29229 DEFVAR_BOOL ("display-hourglass", display_hourglass_p
,
29230 doc
: /* Non-nil means show an hourglass pointer, when Emacs is busy.
29231 This feature only works when on a window system that can change
29232 cursor shapes. */);
29233 display_hourglass_p
= 1;
29235 DEFVAR_LISP ("hourglass-delay", Vhourglass_delay
,
29236 doc
: /* Seconds to wait before displaying an hourglass pointer when Emacs is busy. */);
29237 Vhourglass_delay
= make_number (DEFAULT_HOURGLASS_DELAY
);
29239 hourglass_atimer
= NULL
;
29240 hourglass_shown_p
= 0;
29242 DEFSYM (Qglyphless_char
, "glyphless-char");
29243 DEFSYM (Qhex_code
, "hex-code");
29244 DEFSYM (Qempty_box
, "empty-box");
29245 DEFSYM (Qthin_space
, "thin-space");
29246 DEFSYM (Qzero_width
, "zero-width");
29248 DEFSYM (Qglyphless_char_display
, "glyphless-char-display");
29249 /* Intern this now in case it isn't already done.
29250 Setting this variable twice is harmless.
29251 But don't staticpro it here--that is done in alloc.c. */
29252 Qchar_table_extra_slots
= intern_c_string ("char-table-extra-slots");
29253 Fput (Qglyphless_char_display
, Qchar_table_extra_slots
, make_number (1));
29255 DEFVAR_LISP ("glyphless-char-display", Vglyphless_char_display
,
29256 doc
: /* Char-table defining glyphless characters.
29257 Each element, if non-nil, should be one of the following:
29258 an ASCII acronym string: display this string in a box
29259 `hex-code': display the hexadecimal code of a character in a box
29260 `empty-box': display as an empty box
29261 `thin-space': display as 1-pixel width space
29262 `zero-width': don't display
29263 An element may also be a cons cell (GRAPHICAL . TEXT), which specifies the
29264 display method for graphical terminals and text terminals respectively.
29265 GRAPHICAL and TEXT should each have one of the values listed above.
29267 The char-table has one extra slot to control the display of a character for
29268 which no font is found. This slot only takes effect on graphical terminals.
29269 Its value should be an ASCII acronym string, `hex-code', `empty-box', or
29270 `thin-space'. The default is `empty-box'. */);
29271 Vglyphless_char_display
= Fmake_char_table (Qglyphless_char_display
, Qnil
);
29272 Fset_char_table_extra_slot (Vglyphless_char_display
, make_number (0),
29275 DEFVAR_LISP ("debug-on-message", Vdebug_on_message
,
29276 doc
: /* If non-nil, debug if a message matching this regexp is displayed. */);
29277 Vdebug_on_message
= Qnil
;
29281 /* Initialize this module when Emacs starts. */
29286 current_header_line_height
= current_mode_line_height
= -1;
29288 CHARPOS (this_line_start_pos
) = 0;
29290 if (!noninteractive
)
29292 struct window
*m
= XWINDOW (minibuf_window
);
29293 Lisp_Object frame
= m
->frame
;
29294 struct frame
*f
= XFRAME (frame
);
29295 Lisp_Object root
= FRAME_ROOT_WINDOW (f
);
29296 struct window
*r
= XWINDOW (root
);
29299 echo_area_window
= minibuf_window
;
29301 r
->top_line
= FRAME_TOP_MARGIN (f
);
29302 r
->total_lines
= FRAME_LINES (f
) - 1 - FRAME_TOP_MARGIN (f
);
29303 r
->total_cols
= FRAME_COLS (f
);
29305 m
->top_line
= FRAME_LINES (f
) - 1;
29306 m
->total_lines
= 1;
29307 m
->total_cols
= FRAME_COLS (f
);
29309 scratch_glyph_row
.glyphs
[TEXT_AREA
] = scratch_glyphs
;
29310 scratch_glyph_row
.glyphs
[TEXT_AREA
+ 1]
29311 = scratch_glyphs
+ MAX_SCRATCH_GLYPHS
;
29313 /* The default ellipsis glyphs `...'. */
29314 for (i
= 0; i
< 3; ++i
)
29315 default_invis_vector
[i
] = make_number ('.');
29319 /* Allocate the buffer for frame titles.
29320 Also used for `format-mode-line'. */
29322 mode_line_noprop_buf
= xmalloc (size
);
29323 mode_line_noprop_buf_end
= mode_line_noprop_buf
+ size
;
29324 mode_line_noprop_ptr
= mode_line_noprop_buf
;
29325 mode_line_target
= MODE_LINE_DISPLAY
;
29328 help_echo_showing_p
= 0;
29331 /* Platform-independent portion of hourglass implementation. */
29333 /* Cancel a currently active hourglass timer, and start a new one. */
29335 start_hourglass (void)
29337 #if defined (HAVE_WINDOW_SYSTEM)
29340 cancel_hourglass ();
29342 if (INTEGERP (Vhourglass_delay
)
29343 && XINT (Vhourglass_delay
) > 0)
29344 delay
= make_emacs_time (min (XINT (Vhourglass_delay
),
29345 TYPE_MAXIMUM (time_t)),
29347 else if (FLOATP (Vhourglass_delay
)
29348 && XFLOAT_DATA (Vhourglass_delay
) > 0)
29349 delay
= EMACS_TIME_FROM_DOUBLE (XFLOAT_DATA (Vhourglass_delay
));
29351 delay
= make_emacs_time (DEFAULT_HOURGLASS_DELAY
, 0);
29355 extern void w32_note_current_window (void);
29356 w32_note_current_window ();
29358 #endif /* HAVE_NTGUI */
29360 hourglass_atimer
= start_atimer (ATIMER_RELATIVE
, delay
,
29361 show_hourglass
, NULL
);
29366 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
29369 cancel_hourglass (void)
29371 #if defined (HAVE_WINDOW_SYSTEM)
29372 if (hourglass_atimer
)
29374 cancel_atimer (hourglass_atimer
);
29375 hourglass_atimer
= NULL
;
29378 if (hourglass_shown_p
)