src/xdisp.c (single_display_spec_string): Correct a FIXME comment.
[emacs.git] / src / xdisp.c
blob23667388b56313791e5af590a96696f5c4c77ab7
1 /* Display generation from window structure and buffer text.
3 Copyright (C) 1985-1988, 1993-1995, 1997-2011 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
20 /* New redisplay written by Gerd Moellmann <gerd@gnu.org>.
22 Redisplay.
24 Emacs separates the task of updating the display from code
25 modifying global state, e.g. buffer text. This way functions
26 operating on buffers don't also have to be concerned with updating
27 the display.
29 Updating the display is triggered by the Lisp interpreter when it
30 decides it's time to do it. This is done either automatically for
31 you as part of the interpreter's command loop or as the result of
32 calling Lisp functions like `sit-for'. The C function `redisplay'
33 in xdisp.c is the only entry into the inner redisplay code.
35 The following diagram shows how redisplay code is invoked. As you
36 can see, Lisp calls redisplay and vice versa. Under window systems
37 like X, some portions of the redisplay code are also called
38 asynchronously during mouse movement or expose events. It is very
39 important that these code parts do NOT use the C library (malloc,
40 free) because many C libraries under Unix are not reentrant. They
41 may also NOT call functions of the Lisp interpreter which could
42 change the interpreter's state. If you don't follow these rules,
43 you will encounter bugs which are very hard to explain.
45 +--------------+ redisplay +----------------+
46 | Lisp machine |---------------->| Redisplay code |<--+
47 +--------------+ (xdisp.c) +----------------+ |
48 ^ | |
49 +----------------------------------+ |
50 Don't use this path when called |
51 asynchronously! |
53 expose_window (asynchronous) |
55 X expose events -----+
57 What does redisplay do? Obviously, it has to figure out somehow what
58 has been changed since the last time the display has been updated,
59 and to make these changes visible. Preferably it would do that in
60 a moderately intelligent way, i.e. fast.
62 Changes in buffer text can be deduced from window and buffer
63 structures, and from some global variables like `beg_unchanged' and
64 `end_unchanged'. The contents of the display are additionally
65 recorded in a `glyph matrix', a two-dimensional matrix of glyph
66 structures. Each row in such a matrix corresponds to a line on the
67 display, and each glyph in a row corresponds to a column displaying
68 a character, an image, or what else. This matrix is called the
69 `current glyph matrix' or `current matrix' in redisplay
70 terminology.
72 For buffer parts that have been changed since the last update, a
73 second glyph matrix is constructed, the so called `desired glyph
74 matrix' or short `desired matrix'. Current and desired matrix are
75 then compared to find a cheap way to update the display, e.g. by
76 reusing part of the display by scrolling lines.
78 You will find a lot of redisplay optimizations when you start
79 looking at the innards of redisplay. The overall goal of all these
80 optimizations is to make redisplay fast because it is done
81 frequently. Some of these optimizations are implemented by the
82 following functions:
84 . try_cursor_movement
86 This function tries to update the display if the text in the
87 window did not change and did not scroll, only point moved, and
88 it did not move off the displayed portion of the text.
90 . try_window_reusing_current_matrix
92 This function reuses the current matrix of a window when text
93 has not changed, but the window start changed (e.g., due to
94 scrolling).
96 . try_window_id
98 This function attempts to redisplay a window by reusing parts of
99 its existing display. It finds and reuses the part that was not
100 changed, and redraws the rest.
102 . try_window
104 This function performs the full redisplay of a single window
105 assuming that its fonts were not changed and that the cursor
106 will not end up in the scroll margins. (Loading fonts requires
107 re-adjustment of dimensions of glyph matrices, which makes this
108 method impossible to use.)
110 These optimizations are tried in sequence (some can be skipped if
111 it is known that they are not applicable). If none of the
112 optimizations were successful, redisplay calls redisplay_windows,
113 which performs a full redisplay of all windows.
115 Desired matrices.
117 Desired matrices are always built per Emacs window. The function
118 `display_line' is the central function to look at if you are
119 interested. It constructs one row in a desired matrix given an
120 iterator structure containing both a buffer position and a
121 description of the environment in which the text is to be
122 displayed. But this is too early, read on.
124 Characters and pixmaps displayed for a range of buffer text depend
125 on various settings of buffers and windows, on overlays and text
126 properties, on display tables, on selective display. The good news
127 is that all this hairy stuff is hidden behind a small set of
128 interface functions taking an iterator structure (struct it)
129 argument.
131 Iteration over things to be displayed is then simple. It is
132 started by initializing an iterator with a call to init_iterator.
133 Calls to get_next_display_element fill the iterator structure with
134 relevant information about the next thing to display. Calls to
135 set_iterator_to_next move the iterator to the next thing.
137 Besides this, an iterator also contains information about the
138 display environment in which glyphs for display elements are to be
139 produced. It has fields for the width and height of the display,
140 the information whether long lines are truncated or continued, a
141 current X and Y position, and lots of other stuff you can better
142 see in dispextern.h.
144 Glyphs in a desired matrix are normally constructed in a loop
145 calling get_next_display_element and then PRODUCE_GLYPHS. The call
146 to PRODUCE_GLYPHS will fill the iterator structure with pixel
147 information about the element being displayed and at the same time
148 produce glyphs for it. If the display element fits on the line
149 being displayed, set_iterator_to_next is called next, otherwise the
150 glyphs produced are discarded. The function display_line is the
151 workhorse of filling glyph rows in the desired matrix with glyphs.
152 In addition to producing glyphs, it also handles line truncation
153 and continuation, word wrap, and cursor positioning (for the
154 latter, see also set_cursor_from_row).
156 Frame matrices.
158 That just couldn't be all, could it? What about terminal types not
159 supporting operations on sub-windows of the screen? To update the
160 display on such a terminal, window-based glyph matrices are not
161 well suited. To be able to reuse part of the display (scrolling
162 lines up and down), we must instead have a view of the whole
163 screen. This is what `frame matrices' are for. They are a trick.
165 Frames on terminals like above have a glyph pool. Windows on such
166 a frame sub-allocate their glyph memory from their frame's glyph
167 pool. The frame itself is given its own glyph matrices. By
168 coincidence---or maybe something else---rows in window glyph
169 matrices are slices of corresponding rows in frame matrices. Thus
170 writing to window matrices implicitly updates a frame matrix which
171 provides us with the view of the whole screen that we originally
172 wanted to have without having to move many bytes around. To be
173 honest, there is a little bit more done, but not much more. If you
174 plan to extend that code, take a look at dispnew.c. The function
175 build_frame_matrix is a good starting point.
177 Bidirectional display.
179 Bidirectional display adds quite some hair to this already complex
180 design. The good news are that a large portion of that hairy stuff
181 is hidden in bidi.c behind only 3 interfaces. bidi.c implements a
182 reordering engine which is called by set_iterator_to_next and
183 returns the next character to display in the visual order. See
184 commentary on bidi.c for more details. As far as redisplay is
185 concerned, the effect of calling bidi_move_to_visually_next, the
186 main interface of the reordering engine, is that the iterator gets
187 magically placed on the buffer or string position that is to be
188 displayed next. In other words, a linear iteration through the
189 buffer/string is replaced with a non-linear one. All the rest of
190 the redisplay is oblivious to the bidi reordering.
192 Well, almost oblivious---there are still complications, most of
193 them due to the fact that buffer and string positions no longer
194 change monotonously with glyph indices in a glyph row. Moreover,
195 for continued lines, the buffer positions may not even be
196 monotonously changing with vertical positions. Also, accounting
197 for face changes, overlays, etc. becomes more complex because
198 non-linear iteration could potentially skip many positions with
199 changes, and then cross them again on the way back...
201 One other prominent effect of bidirectional display is that some
202 paragraphs of text need to be displayed starting at the right
203 margin of the window---the so-called right-to-left, or R2L
204 paragraphs. R2L paragraphs are displayed with R2L glyph rows,
205 which have their reversed_p flag set. The bidi reordering engine
206 produces characters in such rows starting from the character which
207 should be the rightmost on display. PRODUCE_GLYPHS then reverses
208 the order, when it fills up the glyph row whose reversed_p flag is
209 set, by prepending each new glyph to what is already there, instead
210 of appending it. When the glyph row is complete, the function
211 extend_face_to_end_of_line fills the empty space to the left of the
212 leftmost character with special glyphs, which will display as,
213 well, empty. On text terminals, these special glyphs are simply
214 blank characters. On graphics terminals, there's a single stretch
215 glyph of a suitably computed width. Both the blanks and the
216 stretch glyph are given the face of the background of the line.
217 This way, the terminal-specific back-end can still draw the glyphs
218 left to right, even for R2L lines.
220 Bidirectional display and character compositions
222 Some scripts cannot be displayed by drawing each character
223 individually, because adjacent characters change each other's shape
224 on display. For example, Arabic and Indic scripts belong to this
225 category.
227 Emacs display supports this by providing "character compositions",
228 most of which is implemented in composite.c. During the buffer
229 scan that delivers characters to PRODUCE_GLYPHS, if the next
230 character to be delivered is a composed character, the iteration
231 calls composition_reseat_it and next_element_from_composition. If
232 they succeed to compose the character with one or more of the
233 following characters, the whole sequence of characters that where
234 composed is recorded in the `struct composition_it' object that is
235 part of the buffer iterator. The composed sequence could produce
236 one or more font glyphs (called "grapheme clusters") on the screen.
237 Each of these grapheme clusters is then delivered to PRODUCE_GLYPHS
238 in the direction corresponding to the current bidi scan direction
239 (recorded in the scan_dir member of the `struct bidi_it' object
240 that is part of the buffer iterator). In particular, if the bidi
241 iterator currently scans the buffer backwards, the grapheme
242 clusters are delivered back to front. This reorders the grapheme
243 clusters as appropriate for the current bidi context. Note that
244 this means that the grapheme clusters are always stored in the
245 LGSTRING object (see composite.c) in the logical order.
247 Moving an iterator in bidirectional text
248 without producing glyphs
250 Note one important detail mentioned above: that the bidi reordering
251 engine, driven by the iterator, produces characters in R2L rows
252 starting at the character that will be the rightmost on display.
253 As far as the iterator is concerned, the geometry of such rows is
254 still left to right, i.e. the iterator "thinks" the first character
255 is at the leftmost pixel position. The iterator does not know that
256 PRODUCE_GLYPHS reverses the order of the glyphs that the iterator
257 delivers. This is important when functions from the the move_it_*
258 family are used to get to certain screen position or to match
259 screen coordinates with buffer coordinates: these functions use the
260 iterator geometry, which is left to right even in R2L paragraphs.
261 This works well with most callers of move_it_*, because they need
262 to get to a specific column, and columns are still numbered in the
263 reading order, i.e. the rightmost character in a R2L paragraph is
264 still column zero. But some callers do not get well with this; a
265 notable example is mouse clicks that need to find the character
266 that corresponds to certain pixel coordinates. See
267 buffer_posn_from_coords in dispnew.c for how this is handled. */
269 #include <config.h>
270 #include <stdio.h>
271 #include <limits.h>
272 #include <setjmp.h>
274 #include "lisp.h"
275 #include "keyboard.h"
276 #include "frame.h"
277 #include "window.h"
278 #include "termchar.h"
279 #include "dispextern.h"
280 #include "buffer.h"
281 #include "character.h"
282 #include "charset.h"
283 #include "indent.h"
284 #include "commands.h"
285 #include "keymap.h"
286 #include "macros.h"
287 #include "disptab.h"
288 #include "termhooks.h"
289 #include "termopts.h"
290 #include "intervals.h"
291 #include "coding.h"
292 #include "process.h"
293 #include "region-cache.h"
294 #include "font.h"
295 #include "fontset.h"
296 #include "blockinput.h"
298 #ifdef HAVE_X_WINDOWS
299 #include "xterm.h"
300 #endif
301 #ifdef WINDOWSNT
302 #include "w32term.h"
303 #endif
304 #ifdef HAVE_NS
305 #include "nsterm.h"
306 #endif
307 #ifdef USE_GTK
308 #include "gtkutil.h"
309 #endif
311 #include "font.h"
313 #ifndef FRAME_X_OUTPUT
314 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
315 #endif
317 #define INFINITY 10000000
319 Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
320 Lisp_Object Qwindow_scroll_functions;
321 static Lisp_Object Qwindow_text_change_functions;
322 static Lisp_Object Qredisplay_end_trigger_functions;
323 Lisp_Object Qinhibit_point_motion_hooks;
324 static Lisp_Object QCeval, QCpropertize;
325 Lisp_Object QCfile, QCdata;
326 static Lisp_Object Qfontified;
327 static Lisp_Object Qgrow_only;
328 static Lisp_Object Qinhibit_eval_during_redisplay;
329 static Lisp_Object Qbuffer_position, Qposition, Qobject;
330 static Lisp_Object Qright_to_left, Qleft_to_right;
332 /* Cursor shapes */
333 Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
335 /* Pointer shapes */
336 static Lisp_Object Qarrow, Qhand;
337 Lisp_Object Qtext;
339 /* Holds the list (error). */
340 static Lisp_Object list_of_error;
342 static Lisp_Object Qfontification_functions;
344 static Lisp_Object Qwrap_prefix;
345 static Lisp_Object Qline_prefix;
347 /* Non-nil means don't actually do any redisplay. */
349 Lisp_Object Qinhibit_redisplay;
351 /* Names of text properties relevant for redisplay. */
353 Lisp_Object Qdisplay;
355 Lisp_Object Qspace, QCalign_to;
356 static Lisp_Object QCrelative_width, QCrelative_height;
357 Lisp_Object Qleft_margin, Qright_margin;
358 static Lisp_Object Qspace_width, Qraise;
359 static Lisp_Object Qslice;
360 Lisp_Object Qcenter;
361 static Lisp_Object Qmargin, Qpointer;
362 static Lisp_Object Qline_height;
364 #ifdef HAVE_WINDOW_SYSTEM
366 /* Test if overflow newline into fringe. Called with iterator IT
367 at or past right window margin, and with IT->current_x set. */
369 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(IT) \
370 (!NILP (Voverflow_newline_into_fringe) \
371 && FRAME_WINDOW_P ((IT)->f) \
372 && ((IT)->bidi_it.paragraph_dir == R2L \
373 ? (WINDOW_LEFT_FRINGE_WIDTH ((IT)->w) > 0) \
374 : (WINDOW_RIGHT_FRINGE_WIDTH ((IT)->w) > 0)) \
375 && (IT)->current_x == (IT)->last_visible_x \
376 && (IT)->line_wrap != WORD_WRAP)
378 #else /* !HAVE_WINDOW_SYSTEM */
379 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) 0
380 #endif /* HAVE_WINDOW_SYSTEM */
382 /* Test if the display element loaded in IT is a space or tab
383 character. This is used to determine word wrapping. */
385 #define IT_DISPLAYING_WHITESPACE(it) \
386 (it->what == IT_CHARACTER && (it->c == ' ' || it->c == '\t'))
388 /* Name of the face used to highlight trailing whitespace. */
390 static Lisp_Object Qtrailing_whitespace;
392 /* Name and number of the face used to highlight escape glyphs. */
394 static Lisp_Object Qescape_glyph;
396 /* Name and number of the face used to highlight non-breaking spaces. */
398 static Lisp_Object Qnobreak_space;
400 /* The symbol `image' which is the car of the lists used to represent
401 images in Lisp. Also a tool bar style. */
403 Lisp_Object Qimage;
405 /* The image map types. */
406 Lisp_Object QCmap;
407 static Lisp_Object QCpointer;
408 static Lisp_Object Qrect, Qcircle, Qpoly;
410 /* Tool bar styles */
411 Lisp_Object Qboth, Qboth_horiz, Qtext_image_horiz;
413 /* Non-zero means print newline to stdout before next mini-buffer
414 message. */
416 int noninteractive_need_newline;
418 /* Non-zero means print newline to message log before next message. */
420 static int message_log_need_newline;
422 /* Three markers that message_dolog uses.
423 It could allocate them itself, but that causes trouble
424 in handling memory-full errors. */
425 static Lisp_Object message_dolog_marker1;
426 static Lisp_Object message_dolog_marker2;
427 static Lisp_Object message_dolog_marker3;
429 /* The buffer position of the first character appearing entirely or
430 partially on the line of the selected window which contains the
431 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
432 redisplay optimization in redisplay_internal. */
434 static struct text_pos this_line_start_pos;
436 /* Number of characters past the end of the line above, including the
437 terminating newline. */
439 static struct text_pos this_line_end_pos;
441 /* The vertical positions and the height of this line. */
443 static int this_line_vpos;
444 static int this_line_y;
445 static int this_line_pixel_height;
447 /* X position at which this display line starts. Usually zero;
448 negative if first character is partially visible. */
450 static int this_line_start_x;
452 /* The smallest character position seen by move_it_* functions as they
453 move across display lines. Used to set MATRIX_ROW_START_CHARPOS of
454 hscrolled lines, see display_line. */
456 static struct text_pos this_line_min_pos;
458 /* Buffer that this_line_.* variables are referring to. */
460 static struct buffer *this_line_buffer;
463 /* Values of those variables at last redisplay are stored as
464 properties on `overlay-arrow-position' symbol. However, if
465 Voverlay_arrow_position is a marker, last-arrow-position is its
466 numerical position. */
468 static Lisp_Object Qlast_arrow_position, Qlast_arrow_string;
470 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
471 properties on a symbol in overlay-arrow-variable-list. */
473 static Lisp_Object Qoverlay_arrow_string, Qoverlay_arrow_bitmap;
475 Lisp_Object Qmenu_bar_update_hook;
477 /* Nonzero if an overlay arrow has been displayed in this window. */
479 static int overlay_arrow_seen;
481 /* Number of windows showing the buffer of the selected window (or
482 another buffer with the same base buffer). keyboard.c refers to
483 this. */
485 int buffer_shared;
487 /* Vector containing glyphs for an ellipsis `...'. */
489 static Lisp_Object default_invis_vector[3];
491 /* This is the window where the echo area message was displayed. It
492 is always a mini-buffer window, but it may not be the same window
493 currently active as a mini-buffer. */
495 Lisp_Object echo_area_window;
497 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
498 pushes the current message and the value of
499 message_enable_multibyte on the stack, the function restore_message
500 pops the stack and displays MESSAGE again. */
502 static Lisp_Object Vmessage_stack;
504 /* Nonzero means multibyte characters were enabled when the echo area
505 message was specified. */
507 static int message_enable_multibyte;
509 /* Nonzero if we should redraw the mode lines on the next redisplay. */
511 int update_mode_lines;
513 /* Nonzero if window sizes or contents have changed since last
514 redisplay that finished. */
516 int windows_or_buffers_changed;
518 /* Nonzero means a frame's cursor type has been changed. */
520 int cursor_type_changed;
522 /* Nonzero after display_mode_line if %l was used and it displayed a
523 line number. */
525 static int line_number_displayed;
527 /* The name of the *Messages* buffer, a string. */
529 static Lisp_Object Vmessages_buffer_name;
531 /* Current, index 0, and last displayed echo area message. Either
532 buffers from echo_buffers, or nil to indicate no message. */
534 Lisp_Object echo_area_buffer[2];
536 /* The buffers referenced from echo_area_buffer. */
538 static Lisp_Object echo_buffer[2];
540 /* A vector saved used in with_area_buffer to reduce consing. */
542 static Lisp_Object Vwith_echo_area_save_vector;
544 /* Non-zero means display_echo_area should display the last echo area
545 message again. Set by redisplay_preserve_echo_area. */
547 static int display_last_displayed_message_p;
549 /* Nonzero if echo area is being used by print; zero if being used by
550 message. */
552 static int message_buf_print;
554 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
556 static Lisp_Object Qinhibit_menubar_update;
557 static Lisp_Object Qmessage_truncate_lines;
559 /* Set to 1 in clear_message to make redisplay_internal aware
560 of an emptied echo area. */
562 static int message_cleared_p;
564 /* A scratch glyph row with contents used for generating truncation
565 glyphs. Also used in direct_output_for_insert. */
567 #define MAX_SCRATCH_GLYPHS 100
568 static struct glyph_row scratch_glyph_row;
569 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
571 /* Ascent and height of the last line processed by move_it_to. */
573 static int last_max_ascent, last_height;
575 /* Non-zero if there's a help-echo in the echo area. */
577 int help_echo_showing_p;
579 /* If >= 0, computed, exact values of mode-line and header-line height
580 to use in the macros CURRENT_MODE_LINE_HEIGHT and
581 CURRENT_HEADER_LINE_HEIGHT. */
583 int current_mode_line_height, current_header_line_height;
585 /* The maximum distance to look ahead for text properties. Values
586 that are too small let us call compute_char_face and similar
587 functions too often which is expensive. Values that are too large
588 let us call compute_char_face and alike too often because we
589 might not be interested in text properties that far away. */
591 #define TEXT_PROP_DISTANCE_LIMIT 100
593 #if GLYPH_DEBUG
595 /* Non-zero means print traces of redisplay if compiled with
596 GLYPH_DEBUG != 0. */
598 int trace_redisplay_p;
600 #endif /* GLYPH_DEBUG */
602 #ifdef DEBUG_TRACE_MOVE
603 /* Non-zero means trace with TRACE_MOVE to stderr. */
604 int trace_move;
606 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
607 #else
608 #define TRACE_MOVE(x) (void) 0
609 #endif
611 static Lisp_Object Qauto_hscroll_mode;
613 /* Buffer being redisplayed -- for redisplay_window_error. */
615 static struct buffer *displayed_buffer;
617 /* Value returned from text property handlers (see below). */
619 enum prop_handled
621 HANDLED_NORMALLY,
622 HANDLED_RECOMPUTE_PROPS,
623 HANDLED_OVERLAY_STRING_CONSUMED,
624 HANDLED_RETURN
627 /* A description of text properties that redisplay is interested
628 in. */
630 struct props
632 /* The name of the property. */
633 Lisp_Object *name;
635 /* A unique index for the property. */
636 enum prop_idx idx;
638 /* A handler function called to set up iterator IT from the property
639 at IT's current position. Value is used to steer handle_stop. */
640 enum prop_handled (*handler) (struct it *it);
643 static enum prop_handled handle_face_prop (struct it *);
644 static enum prop_handled handle_invisible_prop (struct it *);
645 static enum prop_handled handle_display_prop (struct it *);
646 static enum prop_handled handle_composition_prop (struct it *);
647 static enum prop_handled handle_overlay_change (struct it *);
648 static enum prop_handled handle_fontified_prop (struct it *);
650 /* Properties handled by iterators. */
652 static struct props it_props[] =
654 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
655 /* Handle `face' before `display' because some sub-properties of
656 `display' need to know the face. */
657 {&Qface, FACE_PROP_IDX, handle_face_prop},
658 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
659 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
660 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
661 {NULL, 0, NULL}
664 /* Value is the position described by X. If X is a marker, value is
665 the marker_position of X. Otherwise, value is X. */
667 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
669 /* Enumeration returned by some move_it_.* functions internally. */
671 enum move_it_result
673 /* Not used. Undefined value. */
674 MOVE_UNDEFINED,
676 /* Move ended at the requested buffer position or ZV. */
677 MOVE_POS_MATCH_OR_ZV,
679 /* Move ended at the requested X pixel position. */
680 MOVE_X_REACHED,
682 /* Move within a line ended at the end of a line that must be
683 continued. */
684 MOVE_LINE_CONTINUED,
686 /* Move within a line ended at the end of a line that would
687 be displayed truncated. */
688 MOVE_LINE_TRUNCATED,
690 /* Move within a line ended at a line end. */
691 MOVE_NEWLINE_OR_CR
694 /* This counter is used to clear the face cache every once in a while
695 in redisplay_internal. It is incremented for each redisplay.
696 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
697 cleared. */
699 #define CLEAR_FACE_CACHE_COUNT 500
700 static int clear_face_cache_count;
702 /* Similarly for the image cache. */
704 #ifdef HAVE_WINDOW_SYSTEM
705 #define CLEAR_IMAGE_CACHE_COUNT 101
706 static int clear_image_cache_count;
708 /* Null glyph slice */
709 static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 };
710 #endif
712 /* Non-zero while redisplay_internal is in progress. */
714 int redisplaying_p;
716 static Lisp_Object Qinhibit_free_realized_faces;
718 /* If a string, XTread_socket generates an event to display that string.
719 (The display is done in read_char.) */
721 Lisp_Object help_echo_string;
722 Lisp_Object help_echo_window;
723 Lisp_Object help_echo_object;
724 EMACS_INT help_echo_pos;
726 /* Temporary variable for XTread_socket. */
728 Lisp_Object previous_help_echo_string;
730 /* Platform-independent portion of hourglass implementation. */
732 /* Non-zero means an hourglass cursor is currently shown. */
733 int hourglass_shown_p;
735 /* If non-null, an asynchronous timer that, when it expires, displays
736 an hourglass cursor on all frames. */
737 struct atimer *hourglass_atimer;
739 /* Name of the face used to display glyphless characters. */
740 Lisp_Object Qglyphless_char;
742 /* Symbol for the purpose of Vglyphless_char_display. */
743 static Lisp_Object Qglyphless_char_display;
745 /* Method symbols for Vglyphless_char_display. */
746 static Lisp_Object Qhex_code, Qempty_box, Qthin_space, Qzero_width;
748 /* Default pixel width of `thin-space' display method. */
749 #define THIN_SPACE_WIDTH 1
751 /* Default number of seconds to wait before displaying an hourglass
752 cursor. */
753 #define DEFAULT_HOURGLASS_DELAY 1
756 /* Function prototypes. */
758 static void setup_for_ellipsis (struct it *, int);
759 static void set_iterator_to_next (struct it *, int);
760 static void mark_window_display_accurate_1 (struct window *, int);
761 static int single_display_spec_string_p (Lisp_Object, Lisp_Object);
762 static int display_prop_string_p (Lisp_Object, Lisp_Object);
763 static int cursor_row_p (struct glyph_row *);
764 static int redisplay_mode_lines (Lisp_Object, int);
765 static char *decode_mode_spec_coding (Lisp_Object, char *, int);
767 static Lisp_Object get_it_property (struct it *it, Lisp_Object prop);
769 static void handle_line_prefix (struct it *);
771 static void pint2str (char *, int, EMACS_INT);
772 static void pint2hrstr (char *, int, EMACS_INT);
773 static struct text_pos run_window_scroll_functions (Lisp_Object,
774 struct text_pos);
775 static void reconsider_clip_changes (struct window *, struct buffer *);
776 static int text_outside_line_unchanged_p (struct window *,
777 EMACS_INT, EMACS_INT);
778 static void store_mode_line_noprop_char (char);
779 static int store_mode_line_noprop (const char *, int, int);
780 static void handle_stop (struct it *);
781 static void handle_stop_backwards (struct it *, EMACS_INT);
782 static int single_display_spec_intangible_p (Lisp_Object);
783 static void vmessage (const char *, va_list) ATTRIBUTE_FORMAT_PRINTF (1, 0);
784 static void ensure_echo_area_buffers (void);
785 static Lisp_Object unwind_with_echo_area_buffer (Lisp_Object);
786 static Lisp_Object with_echo_area_buffer_unwind_data (struct window *);
787 static int with_echo_area_buffer (struct window *, int,
788 int (*) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
789 EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
790 static void clear_garbaged_frames (void);
791 static int current_message_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
792 static void pop_message (void);
793 static int truncate_message_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
794 static void set_message (const char *, Lisp_Object, EMACS_INT, int);
795 static int set_message_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
796 static int display_echo_area (struct window *);
797 static int display_echo_area_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
798 static int resize_mini_window_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
799 static Lisp_Object unwind_redisplay (Lisp_Object);
800 static int string_char_and_length (const unsigned char *, int *);
801 static struct text_pos display_prop_end (struct it *, Lisp_Object,
802 struct text_pos);
803 static int compute_window_start_on_continuation_line (struct window *);
804 static Lisp_Object safe_eval_handler (Lisp_Object);
805 static void insert_left_trunc_glyphs (struct it *);
806 static struct glyph_row *get_overlay_arrow_glyph_row (struct window *,
807 Lisp_Object);
808 static void extend_face_to_end_of_line (struct it *);
809 static int append_space_for_newline (struct it *, int);
810 static int cursor_row_fully_visible_p (struct window *, int, int);
811 static int try_scrolling (Lisp_Object, int, EMACS_INT, EMACS_INT, int, int);
812 static int try_cursor_movement (Lisp_Object, struct text_pos, int *);
813 static int trailing_whitespace_p (EMACS_INT);
814 static unsigned long int message_log_check_duplicate (EMACS_INT, EMACS_INT);
815 static void push_it (struct it *, struct text_pos *);
816 static void pop_it (struct it *);
817 static void sync_frame_with_window_matrix_rows (struct window *);
818 static void select_frame_for_redisplay (Lisp_Object);
819 static void redisplay_internal (void);
820 static int echo_area_display (int);
821 static void redisplay_windows (Lisp_Object);
822 static void redisplay_window (Lisp_Object, int);
823 static Lisp_Object redisplay_window_error (Lisp_Object);
824 static Lisp_Object redisplay_window_0 (Lisp_Object);
825 static Lisp_Object redisplay_window_1 (Lisp_Object);
826 static int set_cursor_from_row (struct window *, struct glyph_row *,
827 struct glyph_matrix *, EMACS_INT, EMACS_INT,
828 int, int);
829 static int update_menu_bar (struct frame *, int, int);
830 static int try_window_reusing_current_matrix (struct window *);
831 static int try_window_id (struct window *);
832 static int display_line (struct it *);
833 static int display_mode_lines (struct window *);
834 static int display_mode_line (struct window *, enum face_id, Lisp_Object);
835 static int display_mode_element (struct it *, int, int, int, Lisp_Object, Lisp_Object, int);
836 static int store_mode_line_string (const char *, Lisp_Object, int, int, int, Lisp_Object);
837 static const char *decode_mode_spec (struct window *, int, int, Lisp_Object *);
838 static void display_menu_bar (struct window *);
839 static EMACS_INT display_count_lines (EMACS_INT, EMACS_INT, EMACS_INT,
840 EMACS_INT *);
841 static int display_string (const char *, Lisp_Object, Lisp_Object,
842 EMACS_INT, EMACS_INT, struct it *, int, int, int, int);
843 static void compute_line_metrics (struct it *);
844 static void run_redisplay_end_trigger_hook (struct it *);
845 static int get_overlay_strings (struct it *, EMACS_INT);
846 static int get_overlay_strings_1 (struct it *, EMACS_INT, int);
847 static void next_overlay_string (struct it *);
848 static void reseat (struct it *, struct text_pos, int);
849 static void reseat_1 (struct it *, struct text_pos, int);
850 static void back_to_previous_visible_line_start (struct it *);
851 void reseat_at_previous_visible_line_start (struct it *);
852 static void reseat_at_next_visible_line_start (struct it *, int);
853 static int next_element_from_ellipsis (struct it *);
854 static int next_element_from_display_vector (struct it *);
855 static int next_element_from_string (struct it *);
856 static int next_element_from_c_string (struct it *);
857 static int next_element_from_buffer (struct it *);
858 static int next_element_from_composition (struct it *);
859 static int next_element_from_image (struct it *);
860 static int next_element_from_stretch (struct it *);
861 static void load_overlay_strings (struct it *, EMACS_INT);
862 static int init_from_display_pos (struct it *, struct window *,
863 struct display_pos *);
864 static void reseat_to_string (struct it *, const char *,
865 Lisp_Object, EMACS_INT, EMACS_INT, int, int);
866 static int get_next_display_element (struct it *);
867 static enum move_it_result
868 move_it_in_display_line_to (struct it *, EMACS_INT, int,
869 enum move_operation_enum);
870 void move_it_vertically_backward (struct it *, int);
871 static void init_to_row_start (struct it *, struct window *,
872 struct glyph_row *);
873 static int init_to_row_end (struct it *, struct window *,
874 struct glyph_row *);
875 static void back_to_previous_line_start (struct it *);
876 static int forward_to_next_line_start (struct it *, int *);
877 static struct text_pos string_pos_nchars_ahead (struct text_pos,
878 Lisp_Object, EMACS_INT);
879 static struct text_pos string_pos (EMACS_INT, Lisp_Object);
880 static struct text_pos c_string_pos (EMACS_INT, const char *, int);
881 static EMACS_INT number_of_chars (const char *, int);
882 static void compute_stop_pos (struct it *);
883 static void compute_string_pos (struct text_pos *, struct text_pos,
884 Lisp_Object);
885 static int face_before_or_after_it_pos (struct it *, int);
886 static EMACS_INT next_overlay_change (EMACS_INT);
887 static int handle_display_spec (struct it *, Lisp_Object, Lisp_Object,
888 Lisp_Object, struct text_pos *, EMACS_INT, int);
889 static int handle_single_display_spec (struct it *, Lisp_Object,
890 Lisp_Object, Lisp_Object,
891 struct text_pos *, EMACS_INT, int, int);
892 static int underlying_face_id (struct it *);
893 static int in_ellipses_for_invisible_text_p (struct display_pos *,
894 struct window *);
896 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
897 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
899 #ifdef HAVE_WINDOW_SYSTEM
901 static void x_consider_frame_title (Lisp_Object);
902 static int tool_bar_lines_needed (struct frame *, int *);
903 static void update_tool_bar (struct frame *, int);
904 static void build_desired_tool_bar_string (struct frame *f);
905 static int redisplay_tool_bar (struct frame *);
906 static void display_tool_bar_line (struct it *, int);
907 static void notice_overwritten_cursor (struct window *,
908 enum glyph_row_area,
909 int, int, int, int);
910 static void append_stretch_glyph (struct it *, Lisp_Object,
911 int, int, int);
914 #endif /* HAVE_WINDOW_SYSTEM */
916 static void show_mouse_face (Mouse_HLInfo *, enum draw_glyphs_face);
917 static int coords_in_mouse_face_p (struct window *, int, int);
921 /***********************************************************************
922 Window display dimensions
923 ***********************************************************************/
925 /* Return the bottom boundary y-position for text lines in window W.
926 This is the first y position at which a line cannot start.
927 It is relative to the top of the window.
929 This is the height of W minus the height of a mode line, if any. */
931 INLINE int
932 window_text_bottom_y (struct window *w)
934 int height = WINDOW_TOTAL_HEIGHT (w);
936 if (WINDOW_WANTS_MODELINE_P (w))
937 height -= CURRENT_MODE_LINE_HEIGHT (w);
938 return height;
941 /* Return the pixel width of display area AREA of window W. AREA < 0
942 means return the total width of W, not including fringes to
943 the left and right of the window. */
945 INLINE int
946 window_box_width (struct window *w, int area)
948 int cols = XFASTINT (w->total_cols);
949 int pixels = 0;
951 if (!w->pseudo_window_p)
953 cols -= WINDOW_SCROLL_BAR_COLS (w);
955 if (area == TEXT_AREA)
957 if (INTEGERP (w->left_margin_cols))
958 cols -= XFASTINT (w->left_margin_cols);
959 if (INTEGERP (w->right_margin_cols))
960 cols -= XFASTINT (w->right_margin_cols);
961 pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w);
963 else if (area == LEFT_MARGIN_AREA)
965 cols = (INTEGERP (w->left_margin_cols)
966 ? XFASTINT (w->left_margin_cols) : 0);
967 pixels = 0;
969 else if (area == RIGHT_MARGIN_AREA)
971 cols = (INTEGERP (w->right_margin_cols)
972 ? XFASTINT (w->right_margin_cols) : 0);
973 pixels = 0;
977 return cols * WINDOW_FRAME_COLUMN_WIDTH (w) + pixels;
981 /* Return the pixel height of the display area of window W, not
982 including mode lines of W, if any. */
984 INLINE int
985 window_box_height (struct window *w)
987 struct frame *f = XFRAME (w->frame);
988 int height = WINDOW_TOTAL_HEIGHT (w);
990 xassert (height >= 0);
992 /* Note: the code below that determines the mode-line/header-line
993 height is essentially the same as that contained in the macro
994 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
995 the appropriate glyph row has its `mode_line_p' flag set,
996 and if it doesn't, uses estimate_mode_line_height instead. */
998 if (WINDOW_WANTS_MODELINE_P (w))
1000 struct glyph_row *ml_row
1001 = (w->current_matrix && w->current_matrix->rows
1002 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
1003 : 0);
1004 if (ml_row && ml_row->mode_line_p)
1005 height -= ml_row->height;
1006 else
1007 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
1010 if (WINDOW_WANTS_HEADER_LINE_P (w))
1012 struct glyph_row *hl_row
1013 = (w->current_matrix && w->current_matrix->rows
1014 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
1015 : 0);
1016 if (hl_row && hl_row->mode_line_p)
1017 height -= hl_row->height;
1018 else
1019 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1022 /* With a very small font and a mode-line that's taller than
1023 default, we might end up with a negative height. */
1024 return max (0, height);
1027 /* Return the window-relative coordinate of the left edge of display
1028 area AREA of window W. AREA < 0 means return the left edge of the
1029 whole window, to the right of the left fringe of W. */
1031 INLINE int
1032 window_box_left_offset (struct window *w, int area)
1034 int x;
1036 if (w->pseudo_window_p)
1037 return 0;
1039 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
1041 if (area == TEXT_AREA)
1042 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1043 + window_box_width (w, LEFT_MARGIN_AREA));
1044 else if (area == RIGHT_MARGIN_AREA)
1045 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1046 + window_box_width (w, LEFT_MARGIN_AREA)
1047 + window_box_width (w, TEXT_AREA)
1048 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1050 : WINDOW_RIGHT_FRINGE_WIDTH (w)));
1051 else if (area == LEFT_MARGIN_AREA
1052 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1053 x += WINDOW_LEFT_FRINGE_WIDTH (w);
1055 return x;
1059 /* Return the window-relative coordinate of the right edge of display
1060 area AREA of window W. AREA < 0 means return the right edge of the
1061 whole window, to the left of the right fringe of W. */
1063 INLINE int
1064 window_box_right_offset (struct window *w, int area)
1066 return window_box_left_offset (w, area) + window_box_width (w, area);
1069 /* Return the frame-relative coordinate of the left edge of display
1070 area AREA of window W. AREA < 0 means return the left edge of the
1071 whole window, to the right of the left fringe of W. */
1073 INLINE int
1074 window_box_left (struct window *w, int area)
1076 struct frame *f = XFRAME (w->frame);
1077 int x;
1079 if (w->pseudo_window_p)
1080 return FRAME_INTERNAL_BORDER_WIDTH (f);
1082 x = (WINDOW_LEFT_EDGE_X (w)
1083 + window_box_left_offset (w, area));
1085 return x;
1089 /* Return the frame-relative coordinate of the right edge of display
1090 area AREA of window W. AREA < 0 means return the right edge of the
1091 whole window, to the left of the right fringe of W. */
1093 INLINE int
1094 window_box_right (struct window *w, int area)
1096 return window_box_left (w, area) + window_box_width (w, area);
1099 /* Get the bounding box of the display area AREA of window W, without
1100 mode lines, in frame-relative coordinates. AREA < 0 means the
1101 whole window, not including the left and right fringes of
1102 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1103 coordinates of the upper-left corner of the box. Return in
1104 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1106 INLINE void
1107 window_box (struct window *w, int area, int *box_x, int *box_y,
1108 int *box_width, int *box_height)
1110 if (box_width)
1111 *box_width = window_box_width (w, area);
1112 if (box_height)
1113 *box_height = window_box_height (w);
1114 if (box_x)
1115 *box_x = window_box_left (w, area);
1116 if (box_y)
1118 *box_y = WINDOW_TOP_EDGE_Y (w);
1119 if (WINDOW_WANTS_HEADER_LINE_P (w))
1120 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1125 /* Get the bounding box of the display area AREA of window W, without
1126 mode lines. AREA < 0 means the whole window, not including the
1127 left and right fringe of the window. Return in *TOP_LEFT_X
1128 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1129 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1130 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1131 box. */
1133 static INLINE void
1134 window_box_edges (struct window *w, int area, int *top_left_x, int *top_left_y,
1135 int *bottom_right_x, int *bottom_right_y)
1137 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
1138 bottom_right_y);
1139 *bottom_right_x += *top_left_x;
1140 *bottom_right_y += *top_left_y;
1145 /***********************************************************************
1146 Utilities
1147 ***********************************************************************/
1149 /* Return the bottom y-position of the line the iterator IT is in.
1150 This can modify IT's settings. */
1153 line_bottom_y (struct it *it)
1155 int line_height = it->max_ascent + it->max_descent;
1156 int line_top_y = it->current_y;
1158 if (line_height == 0)
1160 if (last_height)
1161 line_height = last_height;
1162 else if (IT_CHARPOS (*it) < ZV)
1164 move_it_by_lines (it, 1);
1165 line_height = (it->max_ascent || it->max_descent
1166 ? it->max_ascent + it->max_descent
1167 : last_height);
1169 else
1171 struct glyph_row *row = it->glyph_row;
1173 /* Use the default character height. */
1174 it->glyph_row = NULL;
1175 it->what = IT_CHARACTER;
1176 it->c = ' ';
1177 it->len = 1;
1178 PRODUCE_GLYPHS (it);
1179 line_height = it->ascent + it->descent;
1180 it->glyph_row = row;
1184 return line_top_y + line_height;
1188 /* Return 1 if position CHARPOS is visible in window W.
1189 CHARPOS < 0 means return info about WINDOW_END position.
1190 If visible, set *X and *Y to pixel coordinates of top left corner.
1191 Set *RTOP and *RBOT to pixel height of an invisible area of glyph at POS.
1192 Set *ROWH and *VPOS to row's visible height and VPOS (row number). */
1195 pos_visible_p (struct window *w, EMACS_INT charpos, int *x, int *y,
1196 int *rtop, int *rbot, int *rowh, int *vpos)
1198 struct it it;
1199 struct text_pos top;
1200 int visible_p = 0;
1201 struct buffer *old_buffer = NULL;
1203 if (FRAME_INITIAL_P (XFRAME (WINDOW_FRAME (w))))
1204 return visible_p;
1206 if (XBUFFER (w->buffer) != current_buffer)
1208 old_buffer = current_buffer;
1209 set_buffer_internal_1 (XBUFFER (w->buffer));
1212 SET_TEXT_POS_FROM_MARKER (top, w->start);
1214 /* Compute exact mode line heights. */
1215 if (WINDOW_WANTS_MODELINE_P (w))
1216 current_mode_line_height
1217 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1218 BVAR (current_buffer, mode_line_format));
1220 if (WINDOW_WANTS_HEADER_LINE_P (w))
1221 current_header_line_height
1222 = display_mode_line (w, HEADER_LINE_FACE_ID,
1223 BVAR (current_buffer, header_line_format));
1225 start_display (&it, w, top);
1226 move_it_to (&it, charpos, -1, it.last_visible_y-1, -1,
1227 (charpos >= 0 ? MOVE_TO_POS : 0) | MOVE_TO_Y);
1229 if (charpos >= 0 && IT_CHARPOS (it) >= charpos)
1231 /* We have reached CHARPOS, or passed it. How the call to
1232 move_it_to can overshoot: (i) If CHARPOS is on invisible
1233 text, move_it_to stops at the end of the invisible text,
1234 after CHARPOS. (ii) If CHARPOS is in a display vector,
1235 move_it_to stops on its last glyph. */
1236 int top_x = it.current_x;
1237 int top_y = it.current_y;
1238 enum it_method it_method = it.method;
1239 /* Calling line_bottom_y may change it.method, it.position, etc. */
1240 int bottom_y = (last_height = 0, line_bottom_y (&it));
1241 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1243 if (top_y < window_top_y)
1244 visible_p = bottom_y > window_top_y;
1245 else if (top_y < it.last_visible_y)
1246 visible_p = 1;
1247 if (visible_p)
1249 if (it_method == GET_FROM_DISPLAY_VECTOR)
1251 /* We stopped on the last glyph of a display vector.
1252 Try and recompute. Hack alert! */
1253 if (charpos < 2 || top.charpos >= charpos)
1254 top_x = it.glyph_row->x;
1255 else
1257 struct it it2;
1258 start_display (&it2, w, top);
1259 move_it_to (&it2, charpos - 1, -1, -1, -1, MOVE_TO_POS);
1260 get_next_display_element (&it2);
1261 PRODUCE_GLYPHS (&it2);
1262 if (ITERATOR_AT_END_OF_LINE_P (&it2)
1263 || it2.current_x > it2.last_visible_x)
1264 top_x = it.glyph_row->x;
1265 else
1267 top_x = it2.current_x;
1268 top_y = it2.current_y;
1273 *x = top_x;
1274 *y = max (top_y + max (0, it.max_ascent - it.ascent), window_top_y);
1275 *rtop = max (0, window_top_y - top_y);
1276 *rbot = max (0, bottom_y - it.last_visible_y);
1277 *rowh = max (0, (min (bottom_y, it.last_visible_y)
1278 - max (top_y, window_top_y)));
1279 *vpos = it.vpos;
1282 else
1284 struct it it2;
1286 it2 = it;
1287 if (IT_CHARPOS (it) < ZV && FETCH_BYTE (IT_BYTEPOS (it)) != '\n')
1288 move_it_by_lines (&it, 1);
1289 if (charpos < IT_CHARPOS (it)
1290 || (it.what == IT_EOB && charpos == IT_CHARPOS (it)))
1292 visible_p = 1;
1293 move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
1294 *x = it2.current_x;
1295 *y = it2.current_y + it2.max_ascent - it2.ascent;
1296 *rtop = max (0, -it2.current_y);
1297 *rbot = max (0, ((it2.current_y + it2.max_ascent + it2.max_descent)
1298 - it.last_visible_y));
1299 *rowh = max (0, (min (it2.current_y + it2.max_ascent + it2.max_descent,
1300 it.last_visible_y)
1301 - max (it2.current_y,
1302 WINDOW_HEADER_LINE_HEIGHT (w))));
1303 *vpos = it2.vpos;
1307 if (old_buffer)
1308 set_buffer_internal_1 (old_buffer);
1310 current_header_line_height = current_mode_line_height = -1;
1312 if (visible_p && XFASTINT (w->hscroll) > 0)
1313 *x -= XFASTINT (w->hscroll) * WINDOW_FRAME_COLUMN_WIDTH (w);
1315 #if 0
1316 /* Debugging code. */
1317 if (visible_p)
1318 fprintf (stderr, "+pv pt=%d vs=%d --> x=%d y=%d rt=%d rb=%d rh=%d vp=%d\n",
1319 charpos, w->vscroll, *x, *y, *rtop, *rbot, *rowh, *vpos);
1320 else
1321 fprintf (stderr, "-pv pt=%d vs=%d\n", charpos, w->vscroll);
1322 #endif
1324 return visible_p;
1328 /* Return the next character from STR. Return in *LEN the length of
1329 the character. This is like STRING_CHAR_AND_LENGTH but never
1330 returns an invalid character. If we find one, we return a `?', but
1331 with the length of the invalid character. */
1333 static INLINE int
1334 string_char_and_length (const unsigned char *str, int *len)
1336 int c;
1338 c = STRING_CHAR_AND_LENGTH (str, *len);
1339 if (!CHAR_VALID_P (c, 1))
1340 /* We may not change the length here because other places in Emacs
1341 don't use this function, i.e. they silently accept invalid
1342 characters. */
1343 c = '?';
1345 return c;
1350 /* Given a position POS containing a valid character and byte position
1351 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1353 static struct text_pos
1354 string_pos_nchars_ahead (struct text_pos pos, Lisp_Object string, EMACS_INT nchars)
1356 xassert (STRINGP (string) && nchars >= 0);
1358 if (STRING_MULTIBYTE (string))
1360 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1361 int len;
1363 while (nchars--)
1365 string_char_and_length (p, &len);
1366 p += len;
1367 CHARPOS (pos) += 1;
1368 BYTEPOS (pos) += len;
1371 else
1372 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1374 return pos;
1378 /* Value is the text position, i.e. character and byte position,
1379 for character position CHARPOS in STRING. */
1381 static INLINE struct text_pos
1382 string_pos (EMACS_INT charpos, Lisp_Object string)
1384 struct text_pos pos;
1385 xassert (STRINGP (string));
1386 xassert (charpos >= 0);
1387 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1388 return pos;
1392 /* Value is a text position, i.e. character and byte position, for
1393 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1394 means recognize multibyte characters. */
1396 static struct text_pos
1397 c_string_pos (EMACS_INT charpos, const char *s, int multibyte_p)
1399 struct text_pos pos;
1401 xassert (s != NULL);
1402 xassert (charpos >= 0);
1404 if (multibyte_p)
1406 int len;
1408 SET_TEXT_POS (pos, 0, 0);
1409 while (charpos--)
1411 string_char_and_length ((const unsigned char *) s, &len);
1412 s += len;
1413 CHARPOS (pos) += 1;
1414 BYTEPOS (pos) += len;
1417 else
1418 SET_TEXT_POS (pos, charpos, charpos);
1420 return pos;
1424 /* Value is the number of characters in C string S. MULTIBYTE_P
1425 non-zero means recognize multibyte characters. */
1427 static EMACS_INT
1428 number_of_chars (const char *s, int multibyte_p)
1430 EMACS_INT nchars;
1432 if (multibyte_p)
1434 EMACS_INT rest = strlen (s);
1435 int len;
1436 const unsigned char *p = (const unsigned char *) s;
1438 for (nchars = 0; rest > 0; ++nchars)
1440 string_char_and_length (p, &len);
1441 rest -= len, p += len;
1444 else
1445 nchars = strlen (s);
1447 return nchars;
1451 /* Compute byte position NEWPOS->bytepos corresponding to
1452 NEWPOS->charpos. POS is a known position in string STRING.
1453 NEWPOS->charpos must be >= POS.charpos. */
1455 static void
1456 compute_string_pos (struct text_pos *newpos, struct text_pos pos, Lisp_Object string)
1458 xassert (STRINGP (string));
1459 xassert (CHARPOS (*newpos) >= CHARPOS (pos));
1461 if (STRING_MULTIBYTE (string))
1462 *newpos = string_pos_nchars_ahead (pos, string,
1463 CHARPOS (*newpos) - CHARPOS (pos));
1464 else
1465 BYTEPOS (*newpos) = CHARPOS (*newpos);
1468 /* EXPORT:
1469 Return an estimation of the pixel height of mode or header lines on
1470 frame F. FACE_ID specifies what line's height to estimate. */
1473 estimate_mode_line_height (struct frame *f, enum face_id face_id)
1475 #ifdef HAVE_WINDOW_SYSTEM
1476 if (FRAME_WINDOW_P (f))
1478 int height = FONT_HEIGHT (FRAME_FONT (f));
1480 /* This function is called so early when Emacs starts that the face
1481 cache and mode line face are not yet initialized. */
1482 if (FRAME_FACE_CACHE (f))
1484 struct face *face = FACE_FROM_ID (f, face_id);
1485 if (face)
1487 if (face->font)
1488 height = FONT_HEIGHT (face->font);
1489 if (face->box_line_width > 0)
1490 height += 2 * face->box_line_width;
1494 return height;
1496 #endif
1498 return 1;
1501 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1502 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1503 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1504 not force the value into range. */
1506 void
1507 pixel_to_glyph_coords (FRAME_PTR f, register int pix_x, register int pix_y,
1508 int *x, int *y, NativeRectangle *bounds, int noclip)
1511 #ifdef HAVE_WINDOW_SYSTEM
1512 if (FRAME_WINDOW_P (f))
1514 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1515 even for negative values. */
1516 if (pix_x < 0)
1517 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1518 if (pix_y < 0)
1519 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1521 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1522 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1524 if (bounds)
1525 STORE_NATIVE_RECT (*bounds,
1526 FRAME_COL_TO_PIXEL_X (f, pix_x),
1527 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1528 FRAME_COLUMN_WIDTH (f) - 1,
1529 FRAME_LINE_HEIGHT (f) - 1);
1531 if (!noclip)
1533 if (pix_x < 0)
1534 pix_x = 0;
1535 else if (pix_x > FRAME_TOTAL_COLS (f))
1536 pix_x = FRAME_TOTAL_COLS (f);
1538 if (pix_y < 0)
1539 pix_y = 0;
1540 else if (pix_y > FRAME_LINES (f))
1541 pix_y = FRAME_LINES (f);
1544 #endif
1546 *x = pix_x;
1547 *y = pix_y;
1551 /* Find the glyph under window-relative coordinates X/Y in window W.
1552 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1553 strings. Return in *HPOS and *VPOS the row and column number of
1554 the glyph found. Return in *AREA the glyph area containing X.
1555 Value is a pointer to the glyph found or null if X/Y is not on
1556 text, or we can't tell because W's current matrix is not up to
1557 date. */
1559 static
1560 struct glyph *
1561 x_y_to_hpos_vpos (struct window *w, int x, int y, int *hpos, int *vpos,
1562 int *dx, int *dy, int *area)
1564 struct glyph *glyph, *end;
1565 struct glyph_row *row = NULL;
1566 int x0, i;
1568 /* Find row containing Y. Give up if some row is not enabled. */
1569 for (i = 0; i < w->current_matrix->nrows; ++i)
1571 row = MATRIX_ROW (w->current_matrix, i);
1572 if (!row->enabled_p)
1573 return NULL;
1574 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1575 break;
1578 *vpos = i;
1579 *hpos = 0;
1581 /* Give up if Y is not in the window. */
1582 if (i == w->current_matrix->nrows)
1583 return NULL;
1585 /* Get the glyph area containing X. */
1586 if (w->pseudo_window_p)
1588 *area = TEXT_AREA;
1589 x0 = 0;
1591 else
1593 if (x < window_box_left_offset (w, TEXT_AREA))
1595 *area = LEFT_MARGIN_AREA;
1596 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
1598 else if (x < window_box_right_offset (w, TEXT_AREA))
1600 *area = TEXT_AREA;
1601 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
1603 else
1605 *area = RIGHT_MARGIN_AREA;
1606 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
1610 /* Find glyph containing X. */
1611 glyph = row->glyphs[*area];
1612 end = glyph + row->used[*area];
1613 x -= x0;
1614 while (glyph < end && x >= glyph->pixel_width)
1616 x -= glyph->pixel_width;
1617 ++glyph;
1620 if (glyph == end)
1621 return NULL;
1623 if (dx)
1625 *dx = x;
1626 *dy = y - (row->y + row->ascent - glyph->ascent);
1629 *hpos = glyph - row->glyphs[*area];
1630 return glyph;
1633 /* Convert frame-relative x/y to coordinates relative to window W.
1634 Takes pseudo-windows into account. */
1636 static void
1637 frame_to_window_pixel_xy (struct window *w, int *x, int *y)
1639 if (w->pseudo_window_p)
1641 /* A pseudo-window is always full-width, and starts at the
1642 left edge of the frame, plus a frame border. */
1643 struct frame *f = XFRAME (w->frame);
1644 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
1645 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1647 else
1649 *x -= WINDOW_LEFT_EDGE_X (w);
1650 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1654 #ifdef HAVE_WINDOW_SYSTEM
1656 /* EXPORT:
1657 Return in RECTS[] at most N clipping rectangles for glyph string S.
1658 Return the number of stored rectangles. */
1661 get_glyph_string_clip_rects (struct glyph_string *s, NativeRectangle *rects, int n)
1663 XRectangle r;
1665 if (n <= 0)
1666 return 0;
1668 if (s->row->full_width_p)
1670 /* Draw full-width. X coordinates are relative to S->w->left_col. */
1671 r.x = WINDOW_LEFT_EDGE_X (s->w);
1672 r.width = WINDOW_TOTAL_WIDTH (s->w);
1674 /* Unless displaying a mode or menu bar line, which are always
1675 fully visible, clip to the visible part of the row. */
1676 if (s->w->pseudo_window_p)
1677 r.height = s->row->visible_height;
1678 else
1679 r.height = s->height;
1681 else
1683 /* This is a text line that may be partially visible. */
1684 r.x = window_box_left (s->w, s->area);
1685 r.width = window_box_width (s->w, s->area);
1686 r.height = s->row->visible_height;
1689 if (s->clip_head)
1690 if (r.x < s->clip_head->x)
1692 if (r.width >= s->clip_head->x - r.x)
1693 r.width -= s->clip_head->x - r.x;
1694 else
1695 r.width = 0;
1696 r.x = s->clip_head->x;
1698 if (s->clip_tail)
1699 if (r.x + r.width > s->clip_tail->x + s->clip_tail->background_width)
1701 if (s->clip_tail->x + s->clip_tail->background_width >= r.x)
1702 r.width = s->clip_tail->x + s->clip_tail->background_width - r.x;
1703 else
1704 r.width = 0;
1707 /* If S draws overlapping rows, it's sufficient to use the top and
1708 bottom of the window for clipping because this glyph string
1709 intentionally draws over other lines. */
1710 if (s->for_overlaps)
1712 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1713 r.height = window_text_bottom_y (s->w) - r.y;
1715 /* Alas, the above simple strategy does not work for the
1716 environments with anti-aliased text: if the same text is
1717 drawn onto the same place multiple times, it gets thicker.
1718 If the overlap we are processing is for the erased cursor, we
1719 take the intersection with the rectagle of the cursor. */
1720 if (s->for_overlaps & OVERLAPS_ERASED_CURSOR)
1722 XRectangle rc, r_save = r;
1724 rc.x = WINDOW_TEXT_TO_FRAME_PIXEL_X (s->w, s->w->phys_cursor.x);
1725 rc.y = s->w->phys_cursor.y;
1726 rc.width = s->w->phys_cursor_width;
1727 rc.height = s->w->phys_cursor_height;
1729 x_intersect_rectangles (&r_save, &rc, &r);
1732 else
1734 /* Don't use S->y for clipping because it doesn't take partially
1735 visible lines into account. For example, it can be negative for
1736 partially visible lines at the top of a window. */
1737 if (!s->row->full_width_p
1738 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
1739 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1740 else
1741 r.y = max (0, s->row->y);
1744 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
1746 /* If drawing the cursor, don't let glyph draw outside its
1747 advertised boundaries. Cleartype does this under some circumstances. */
1748 if (s->hl == DRAW_CURSOR)
1750 struct glyph *glyph = s->first_glyph;
1751 int height, max_y;
1753 if (s->x > r.x)
1755 r.width -= s->x - r.x;
1756 r.x = s->x;
1758 r.width = min (r.width, glyph->pixel_width);
1760 /* If r.y is below window bottom, ensure that we still see a cursor. */
1761 height = min (glyph->ascent + glyph->descent,
1762 min (FRAME_LINE_HEIGHT (s->f), s->row->visible_height));
1763 max_y = window_text_bottom_y (s->w) - height;
1764 max_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, max_y);
1765 if (s->ybase - glyph->ascent > max_y)
1767 r.y = max_y;
1768 r.height = height;
1770 else
1772 /* Don't draw cursor glyph taller than our actual glyph. */
1773 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
1774 if (height < r.height)
1776 max_y = r.y + r.height;
1777 r.y = min (max_y, max (r.y, s->ybase + glyph->descent - height));
1778 r.height = min (max_y - r.y, height);
1783 if (s->row->clip)
1785 XRectangle r_save = r;
1787 if (! x_intersect_rectangles (&r_save, s->row->clip, &r))
1788 r.width = 0;
1791 if ((s->for_overlaps & OVERLAPS_BOTH) == 0
1792 || ((s->for_overlaps & OVERLAPS_BOTH) == OVERLAPS_BOTH && n == 1))
1794 #ifdef CONVERT_FROM_XRECT
1795 CONVERT_FROM_XRECT (r, *rects);
1796 #else
1797 *rects = r;
1798 #endif
1799 return 1;
1801 else
1803 /* If we are processing overlapping and allowed to return
1804 multiple clipping rectangles, we exclude the row of the glyph
1805 string from the clipping rectangle. This is to avoid drawing
1806 the same text on the environment with anti-aliasing. */
1807 #ifdef CONVERT_FROM_XRECT
1808 XRectangle rs[2];
1809 #else
1810 XRectangle *rs = rects;
1811 #endif
1812 int i = 0, row_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, s->row->y);
1814 if (s->for_overlaps & OVERLAPS_PRED)
1816 rs[i] = r;
1817 if (r.y + r.height > row_y)
1819 if (r.y < row_y)
1820 rs[i].height = row_y - r.y;
1821 else
1822 rs[i].height = 0;
1824 i++;
1826 if (s->for_overlaps & OVERLAPS_SUCC)
1828 rs[i] = r;
1829 if (r.y < row_y + s->row->visible_height)
1831 if (r.y + r.height > row_y + s->row->visible_height)
1833 rs[i].y = row_y + s->row->visible_height;
1834 rs[i].height = r.y + r.height - rs[i].y;
1836 else
1837 rs[i].height = 0;
1839 i++;
1842 n = i;
1843 #ifdef CONVERT_FROM_XRECT
1844 for (i = 0; i < n; i++)
1845 CONVERT_FROM_XRECT (rs[i], rects[i]);
1846 #endif
1847 return n;
1851 /* EXPORT:
1852 Return in *NR the clipping rectangle for glyph string S. */
1854 void
1855 get_glyph_string_clip_rect (struct glyph_string *s, NativeRectangle *nr)
1857 get_glyph_string_clip_rects (s, nr, 1);
1861 /* EXPORT:
1862 Return the position and height of the phys cursor in window W.
1863 Set w->phys_cursor_width to width of phys cursor.
1866 void
1867 get_phys_cursor_geometry (struct window *w, struct glyph_row *row,
1868 struct glyph *glyph, int *xp, int *yp, int *heightp)
1870 struct frame *f = XFRAME (WINDOW_FRAME (w));
1871 int x, y, wd, h, h0, y0;
1873 /* Compute the width of the rectangle to draw. If on a stretch
1874 glyph, and `x-stretch-block-cursor' is nil, don't draw a
1875 rectangle as wide as the glyph, but use a canonical character
1876 width instead. */
1877 wd = glyph->pixel_width - 1;
1878 #if defined(HAVE_NTGUI) || defined(HAVE_NS)
1879 wd++; /* Why? */
1880 #endif
1882 x = w->phys_cursor.x;
1883 if (x < 0)
1885 wd += x;
1886 x = 0;
1889 if (glyph->type == STRETCH_GLYPH
1890 && !x_stretch_cursor_p)
1891 wd = min (FRAME_COLUMN_WIDTH (f), wd);
1892 w->phys_cursor_width = wd;
1894 y = w->phys_cursor.y + row->ascent - glyph->ascent;
1896 /* If y is below window bottom, ensure that we still see a cursor. */
1897 h0 = min (FRAME_LINE_HEIGHT (f), row->visible_height);
1899 h = max (h0, glyph->ascent + glyph->descent);
1900 h0 = min (h0, glyph->ascent + glyph->descent);
1902 y0 = WINDOW_HEADER_LINE_HEIGHT (w);
1903 if (y < y0)
1905 h = max (h - (y0 - y) + 1, h0);
1906 y = y0 - 1;
1908 else
1910 y0 = window_text_bottom_y (w) - h0;
1911 if (y > y0)
1913 h += y - y0;
1914 y = y0;
1918 *xp = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x);
1919 *yp = WINDOW_TO_FRAME_PIXEL_Y (w, y);
1920 *heightp = h;
1924 * Remember which glyph the mouse is over.
1927 void
1928 remember_mouse_glyph (struct frame *f, int gx, int gy, NativeRectangle *rect)
1930 Lisp_Object window;
1931 struct window *w;
1932 struct glyph_row *r, *gr, *end_row;
1933 enum window_part part;
1934 enum glyph_row_area area;
1935 int x, y, width, height;
1937 /* Try to determine frame pixel position and size of the glyph under
1938 frame pixel coordinates X/Y on frame F. */
1940 if (!f->glyphs_initialized_p
1941 || (window = window_from_coordinates (f, gx, gy, &part, 0),
1942 NILP (window)))
1944 width = FRAME_SMALLEST_CHAR_WIDTH (f);
1945 height = FRAME_SMALLEST_FONT_HEIGHT (f);
1946 goto virtual_glyph;
1949 w = XWINDOW (window);
1950 width = WINDOW_FRAME_COLUMN_WIDTH (w);
1951 height = WINDOW_FRAME_LINE_HEIGHT (w);
1953 x = window_relative_x_coord (w, part, gx);
1954 y = gy - WINDOW_TOP_EDGE_Y (w);
1956 r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
1957 end_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
1959 if (w->pseudo_window_p)
1961 area = TEXT_AREA;
1962 part = ON_MODE_LINE; /* Don't adjust margin. */
1963 goto text_glyph;
1966 switch (part)
1968 case ON_LEFT_MARGIN:
1969 area = LEFT_MARGIN_AREA;
1970 goto text_glyph;
1972 case ON_RIGHT_MARGIN:
1973 area = RIGHT_MARGIN_AREA;
1974 goto text_glyph;
1976 case ON_HEADER_LINE:
1977 case ON_MODE_LINE:
1978 gr = (part == ON_HEADER_LINE
1979 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
1980 : MATRIX_MODE_LINE_ROW (w->current_matrix));
1981 gy = gr->y;
1982 area = TEXT_AREA;
1983 goto text_glyph_row_found;
1985 case ON_TEXT:
1986 area = TEXT_AREA;
1988 text_glyph:
1989 gr = 0; gy = 0;
1990 for (; r <= end_row && r->enabled_p; ++r)
1991 if (r->y + r->height > y)
1993 gr = r; gy = r->y;
1994 break;
1997 text_glyph_row_found:
1998 if (gr && gy <= y)
2000 struct glyph *g = gr->glyphs[area];
2001 struct glyph *end = g + gr->used[area];
2003 height = gr->height;
2004 for (gx = gr->x; g < end; gx += g->pixel_width, ++g)
2005 if (gx + g->pixel_width > x)
2006 break;
2008 if (g < end)
2010 if (g->type == IMAGE_GLYPH)
2012 /* Don't remember when mouse is over image, as
2013 image may have hot-spots. */
2014 STORE_NATIVE_RECT (*rect, 0, 0, 0, 0);
2015 return;
2017 width = g->pixel_width;
2019 else
2021 /* Use nominal char spacing at end of line. */
2022 x -= gx;
2023 gx += (x / width) * width;
2026 if (part != ON_MODE_LINE && part != ON_HEADER_LINE)
2027 gx += window_box_left_offset (w, area);
2029 else
2031 /* Use nominal line height at end of window. */
2032 gx = (x / width) * width;
2033 y -= gy;
2034 gy += (y / height) * height;
2036 break;
2038 case ON_LEFT_FRINGE:
2039 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2040 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w)
2041 : window_box_right_offset (w, LEFT_MARGIN_AREA));
2042 width = WINDOW_LEFT_FRINGE_WIDTH (w);
2043 goto row_glyph;
2045 case ON_RIGHT_FRINGE:
2046 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2047 ? window_box_right_offset (w, RIGHT_MARGIN_AREA)
2048 : window_box_right_offset (w, TEXT_AREA));
2049 width = WINDOW_RIGHT_FRINGE_WIDTH (w);
2050 goto row_glyph;
2052 case ON_SCROLL_BAR:
2053 gx = (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)
2055 : (window_box_right_offset (w, RIGHT_MARGIN_AREA)
2056 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2057 ? WINDOW_RIGHT_FRINGE_WIDTH (w)
2058 : 0)));
2059 width = WINDOW_SCROLL_BAR_AREA_WIDTH (w);
2061 row_glyph:
2062 gr = 0, gy = 0;
2063 for (; r <= end_row && r->enabled_p; ++r)
2064 if (r->y + r->height > y)
2066 gr = r; gy = r->y;
2067 break;
2070 if (gr && gy <= y)
2071 height = gr->height;
2072 else
2074 /* Use nominal line height at end of window. */
2075 y -= gy;
2076 gy += (y / height) * height;
2078 break;
2080 default:
2082 virtual_glyph:
2083 /* If there is no glyph under the mouse, then we divide the screen
2084 into a grid of the smallest glyph in the frame, and use that
2085 as our "glyph". */
2087 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to
2088 round down even for negative values. */
2089 if (gx < 0)
2090 gx -= width - 1;
2091 if (gy < 0)
2092 gy -= height - 1;
2094 gx = (gx / width) * width;
2095 gy = (gy / height) * height;
2097 goto store_rect;
2100 gx += WINDOW_LEFT_EDGE_X (w);
2101 gy += WINDOW_TOP_EDGE_Y (w);
2103 store_rect:
2104 STORE_NATIVE_RECT (*rect, gx, gy, width, height);
2106 /* Visible feedback for debugging. */
2107 #if 0
2108 #if HAVE_X_WINDOWS
2109 XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2110 f->output_data.x->normal_gc,
2111 gx, gy, width, height);
2112 #endif
2113 #endif
2117 #endif /* HAVE_WINDOW_SYSTEM */
2120 /***********************************************************************
2121 Lisp form evaluation
2122 ***********************************************************************/
2124 /* Error handler for safe_eval and safe_call. */
2126 static Lisp_Object
2127 safe_eval_handler (Lisp_Object arg)
2129 add_to_log ("Error during redisplay: %S", arg, Qnil);
2130 return Qnil;
2134 /* Evaluate SEXPR and return the result, or nil if something went
2135 wrong. Prevent redisplay during the evaluation. */
2137 /* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1].
2138 Return the result, or nil if something went wrong. Prevent
2139 redisplay during the evaluation. */
2141 Lisp_Object
2142 safe_call (size_t nargs, Lisp_Object *args)
2144 Lisp_Object val;
2146 if (inhibit_eval_during_redisplay)
2147 val = Qnil;
2148 else
2150 int count = SPECPDL_INDEX ();
2151 struct gcpro gcpro1;
2153 GCPRO1 (args[0]);
2154 gcpro1.nvars = nargs;
2155 specbind (Qinhibit_redisplay, Qt);
2156 /* Use Qt to ensure debugger does not run,
2157 so there is no possibility of wanting to redisplay. */
2158 val = internal_condition_case_n (Ffuncall, nargs, args, Qt,
2159 safe_eval_handler);
2160 UNGCPRO;
2161 val = unbind_to (count, val);
2164 return val;
2168 /* Call function FN with one argument ARG.
2169 Return the result, or nil if something went wrong. */
2171 Lisp_Object
2172 safe_call1 (Lisp_Object fn, Lisp_Object arg)
2174 Lisp_Object args[2];
2175 args[0] = fn;
2176 args[1] = arg;
2177 return safe_call (2, args);
2180 static Lisp_Object Qeval;
2182 Lisp_Object
2183 safe_eval (Lisp_Object sexpr)
2185 return safe_call1 (Qeval, sexpr);
2188 /* Call function FN with one argument ARG.
2189 Return the result, or nil if something went wrong. */
2191 Lisp_Object
2192 safe_call2 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2)
2194 Lisp_Object args[3];
2195 args[0] = fn;
2196 args[1] = arg1;
2197 args[2] = arg2;
2198 return safe_call (3, args);
2203 /***********************************************************************
2204 Debugging
2205 ***********************************************************************/
2207 #if 0
2209 /* Define CHECK_IT to perform sanity checks on iterators.
2210 This is for debugging. It is too slow to do unconditionally. */
2212 static void
2213 check_it (it)
2214 struct it *it;
2216 if (it->method == GET_FROM_STRING)
2218 xassert (STRINGP (it->string));
2219 xassert (IT_STRING_CHARPOS (*it) >= 0);
2221 else
2223 xassert (IT_STRING_CHARPOS (*it) < 0);
2224 if (it->method == GET_FROM_BUFFER)
2226 /* Check that character and byte positions agree. */
2227 xassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
2231 if (it->dpvec)
2232 xassert (it->current.dpvec_index >= 0);
2233 else
2234 xassert (it->current.dpvec_index < 0);
2237 #define CHECK_IT(IT) check_it ((IT))
2239 #else /* not 0 */
2241 #define CHECK_IT(IT) (void) 0
2243 #endif /* not 0 */
2246 #if GLYPH_DEBUG
2248 /* Check that the window end of window W is what we expect it
2249 to be---the last row in the current matrix displaying text. */
2251 static void
2252 check_window_end (w)
2253 struct window *w;
2255 if (!MINI_WINDOW_P (w)
2256 && !NILP (w->window_end_valid))
2258 struct glyph_row *row;
2259 xassert ((row = MATRIX_ROW (w->current_matrix,
2260 XFASTINT (w->window_end_vpos)),
2261 !row->enabled_p
2262 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
2263 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
2267 #define CHECK_WINDOW_END(W) check_window_end ((W))
2269 #else /* not GLYPH_DEBUG */
2271 #define CHECK_WINDOW_END(W) (void) 0
2273 #endif /* not GLYPH_DEBUG */
2277 /***********************************************************************
2278 Iterator initialization
2279 ***********************************************************************/
2281 /* Initialize IT for displaying current_buffer in window W, starting
2282 at character position CHARPOS. CHARPOS < 0 means that no buffer
2283 position is specified which is useful when the iterator is assigned
2284 a position later. BYTEPOS is the byte position corresponding to
2285 CHARPOS. BYTEPOS < 0 means compute it from CHARPOS.
2287 If ROW is not null, calls to produce_glyphs with IT as parameter
2288 will produce glyphs in that row.
2290 BASE_FACE_ID is the id of a base face to use. It must be one of
2291 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2292 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2293 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2295 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2296 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2297 will be initialized to use the corresponding mode line glyph row of
2298 the desired matrix of W. */
2300 void
2301 init_iterator (struct it *it, struct window *w,
2302 EMACS_INT charpos, EMACS_INT bytepos,
2303 struct glyph_row *row, enum face_id base_face_id)
2305 int highlight_region_p;
2306 enum face_id remapped_base_face_id = base_face_id;
2308 /* Some precondition checks. */
2309 xassert (w != NULL && it != NULL);
2310 xassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
2311 && charpos <= ZV));
2313 /* If face attributes have been changed since the last redisplay,
2314 free realized faces now because they depend on face definitions
2315 that might have changed. Don't free faces while there might be
2316 desired matrices pending which reference these faces. */
2317 if (face_change_count && !inhibit_free_realized_faces)
2319 face_change_count = 0;
2320 free_all_realized_faces (Qnil);
2323 /* Perhaps remap BASE_FACE_ID to a user-specified alternative. */
2324 if (! NILP (Vface_remapping_alist))
2325 remapped_base_face_id = lookup_basic_face (XFRAME (w->frame), base_face_id);
2327 /* Use one of the mode line rows of W's desired matrix if
2328 appropriate. */
2329 if (row == NULL)
2331 if (base_face_id == MODE_LINE_FACE_ID
2332 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
2333 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
2334 else if (base_face_id == HEADER_LINE_FACE_ID)
2335 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
2338 /* Clear IT. */
2339 memset (it, 0, sizeof *it);
2340 it->current.overlay_string_index = -1;
2341 it->current.dpvec_index = -1;
2342 it->base_face_id = remapped_base_face_id;
2343 it->string = Qnil;
2344 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
2346 /* The window in which we iterate over current_buffer: */
2347 XSETWINDOW (it->window, w);
2348 it->w = w;
2349 it->f = XFRAME (w->frame);
2351 it->cmp_it.id = -1;
2353 /* Extra space between lines (on window systems only). */
2354 if (base_face_id == DEFAULT_FACE_ID
2355 && FRAME_WINDOW_P (it->f))
2357 if (NATNUMP (BVAR (current_buffer, extra_line_spacing)))
2358 it->extra_line_spacing = XFASTINT (BVAR (current_buffer, extra_line_spacing));
2359 else if (FLOATP (BVAR (current_buffer, extra_line_spacing)))
2360 it->extra_line_spacing = (XFLOAT_DATA (BVAR (current_buffer, extra_line_spacing))
2361 * FRAME_LINE_HEIGHT (it->f));
2362 else if (it->f->extra_line_spacing > 0)
2363 it->extra_line_spacing = it->f->extra_line_spacing;
2364 it->max_extra_line_spacing = 0;
2367 /* If realized faces have been removed, e.g. because of face
2368 attribute changes of named faces, recompute them. When running
2369 in batch mode, the face cache of the initial frame is null. If
2370 we happen to get called, make a dummy face cache. */
2371 if (FRAME_FACE_CACHE (it->f) == NULL)
2372 init_frame_faces (it->f);
2373 if (FRAME_FACE_CACHE (it->f)->used == 0)
2374 recompute_basic_faces (it->f);
2376 /* Current value of the `slice', `space-width', and 'height' properties. */
2377 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
2378 it->space_width = Qnil;
2379 it->font_height = Qnil;
2380 it->override_ascent = -1;
2382 /* Are control characters displayed as `^C'? */
2383 it->ctl_arrow_p = !NILP (BVAR (current_buffer, ctl_arrow));
2385 /* -1 means everything between a CR and the following line end
2386 is invisible. >0 means lines indented more than this value are
2387 invisible. */
2388 it->selective = (INTEGERP (BVAR (current_buffer, selective_display))
2389 ? XFASTINT (BVAR (current_buffer, selective_display))
2390 : (!NILP (BVAR (current_buffer, selective_display))
2391 ? -1 : 0));
2392 it->selective_display_ellipsis_p
2393 = !NILP (BVAR (current_buffer, selective_display_ellipses));
2395 /* Display table to use. */
2396 it->dp = window_display_table (w);
2398 /* Are multibyte characters enabled in current_buffer? */
2399 it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
2401 /* Do we need to reorder bidirectional text? Not if this is a
2402 unibyte buffer: by definition, none of the single-byte characters
2403 are strong R2L, so no reordering is needed. And bidi.c doesn't
2404 support unibyte buffers anyway. */
2405 it->bidi_p
2406 = !NILP (BVAR (current_buffer, bidi_display_reordering)) && it->multibyte_p;
2408 /* Non-zero if we should highlight the region. */
2409 highlight_region_p
2410 = (!NILP (Vtransient_mark_mode)
2411 && !NILP (BVAR (current_buffer, mark_active))
2412 && XMARKER (BVAR (current_buffer, mark))->buffer != 0);
2414 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
2415 start and end of a visible region in window IT->w. Set both to
2416 -1 to indicate no region. */
2417 if (highlight_region_p
2418 /* Maybe highlight only in selected window. */
2419 && (/* Either show region everywhere. */
2420 highlight_nonselected_windows
2421 /* Or show region in the selected window. */
2422 || w == XWINDOW (selected_window)
2423 /* Or show the region if we are in the mini-buffer and W is
2424 the window the mini-buffer refers to. */
2425 || (MINI_WINDOW_P (XWINDOW (selected_window))
2426 && WINDOWP (minibuf_selected_window)
2427 && w == XWINDOW (minibuf_selected_window))))
2429 EMACS_INT markpos = marker_position (BVAR (current_buffer, mark));
2430 it->region_beg_charpos = min (PT, markpos);
2431 it->region_end_charpos = max (PT, markpos);
2433 else
2434 it->region_beg_charpos = it->region_end_charpos = -1;
2436 /* Get the position at which the redisplay_end_trigger hook should
2437 be run, if it is to be run at all. */
2438 if (MARKERP (w->redisplay_end_trigger)
2439 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2440 it->redisplay_end_trigger_charpos
2441 = marker_position (w->redisplay_end_trigger);
2442 else if (INTEGERP (w->redisplay_end_trigger))
2443 it->redisplay_end_trigger_charpos = XINT (w->redisplay_end_trigger);
2445 /* Correct bogus values of tab_width. */
2446 it->tab_width = XINT (BVAR (current_buffer, tab_width));
2447 if (it->tab_width <= 0 || it->tab_width > 1000)
2448 it->tab_width = 8;
2450 /* Are lines in the display truncated? */
2451 if (base_face_id != DEFAULT_FACE_ID
2452 || XINT (it->w->hscroll)
2453 || (! WINDOW_FULL_WIDTH_P (it->w)
2454 && ((!NILP (Vtruncate_partial_width_windows)
2455 && !INTEGERP (Vtruncate_partial_width_windows))
2456 || (INTEGERP (Vtruncate_partial_width_windows)
2457 && (WINDOW_TOTAL_COLS (it->w)
2458 < XINT (Vtruncate_partial_width_windows))))))
2459 it->line_wrap = TRUNCATE;
2460 else if (NILP (BVAR (current_buffer, truncate_lines)))
2461 it->line_wrap = NILP (BVAR (current_buffer, word_wrap))
2462 ? WINDOW_WRAP : WORD_WRAP;
2463 else
2464 it->line_wrap = TRUNCATE;
2466 /* Get dimensions of truncation and continuation glyphs. These are
2467 displayed as fringe bitmaps under X, so we don't need them for such
2468 frames. */
2469 if (!FRAME_WINDOW_P (it->f))
2471 if (it->line_wrap == TRUNCATE)
2473 /* We will need the truncation glyph. */
2474 xassert (it->glyph_row == NULL);
2475 produce_special_glyphs (it, IT_TRUNCATION);
2476 it->truncation_pixel_width = it->pixel_width;
2478 else
2480 /* We will need the continuation glyph. */
2481 xassert (it->glyph_row == NULL);
2482 produce_special_glyphs (it, IT_CONTINUATION);
2483 it->continuation_pixel_width = it->pixel_width;
2486 /* Reset these values to zero because the produce_special_glyphs
2487 above has changed them. */
2488 it->pixel_width = it->ascent = it->descent = 0;
2489 it->phys_ascent = it->phys_descent = 0;
2492 /* Set this after getting the dimensions of truncation and
2493 continuation glyphs, so that we don't produce glyphs when calling
2494 produce_special_glyphs, above. */
2495 it->glyph_row = row;
2496 it->area = TEXT_AREA;
2498 /* Forget any previous info about this row being reversed. */
2499 if (it->glyph_row)
2500 it->glyph_row->reversed_p = 0;
2502 /* Get the dimensions of the display area. The display area
2503 consists of the visible window area plus a horizontally scrolled
2504 part to the left of the window. All x-values are relative to the
2505 start of this total display area. */
2506 if (base_face_id != DEFAULT_FACE_ID)
2508 /* Mode lines, menu bar in terminal frames. */
2509 it->first_visible_x = 0;
2510 it->last_visible_x = WINDOW_TOTAL_WIDTH (w);
2512 else
2514 it->first_visible_x
2515 = XFASTINT (it->w->hscroll) * FRAME_COLUMN_WIDTH (it->f);
2516 it->last_visible_x = (it->first_visible_x
2517 + window_box_width (w, TEXT_AREA));
2519 /* If we truncate lines, leave room for the truncator glyph(s) at
2520 the right margin. Otherwise, leave room for the continuation
2521 glyph(s). Truncation and continuation glyphs are not inserted
2522 for window-based redisplay. */
2523 if (!FRAME_WINDOW_P (it->f))
2525 if (it->line_wrap == TRUNCATE)
2526 it->last_visible_x -= it->truncation_pixel_width;
2527 else
2528 it->last_visible_x -= it->continuation_pixel_width;
2531 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
2532 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
2535 /* Leave room for a border glyph. */
2536 if (!FRAME_WINDOW_P (it->f)
2537 && !WINDOW_RIGHTMOST_P (it->w))
2538 it->last_visible_x -= 1;
2540 it->last_visible_y = window_text_bottom_y (w);
2542 /* For mode lines and alike, arrange for the first glyph having a
2543 left box line if the face specifies a box. */
2544 if (base_face_id != DEFAULT_FACE_ID)
2546 struct face *face;
2548 it->face_id = remapped_base_face_id;
2550 /* If we have a boxed mode line, make the first character appear
2551 with a left box line. */
2552 face = FACE_FROM_ID (it->f, remapped_base_face_id);
2553 if (face->box != FACE_NO_BOX)
2554 it->start_of_box_run_p = 1;
2557 /* If we are to reorder bidirectional text, init the bidi
2558 iterator. */
2559 if (it->bidi_p)
2561 /* Note the paragraph direction that this buffer wants to
2562 use. */
2563 if (EQ (BVAR (current_buffer, bidi_paragraph_direction), Qleft_to_right))
2564 it->paragraph_embedding = L2R;
2565 else if (EQ (BVAR (current_buffer, bidi_paragraph_direction), Qright_to_left))
2566 it->paragraph_embedding = R2L;
2567 else
2568 it->paragraph_embedding = NEUTRAL_DIR;
2569 bidi_init_it (charpos, bytepos, FRAME_WINDOW_P (it->f), &it->bidi_it);
2572 /* If a buffer position was specified, set the iterator there,
2573 getting overlays and face properties from that position. */
2574 if (charpos >= BUF_BEG (current_buffer))
2576 it->end_charpos = ZV;
2577 it->face_id = -1;
2578 IT_CHARPOS (*it) = charpos;
2580 /* Compute byte position if not specified. */
2581 if (bytepos < charpos)
2582 IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos);
2583 else
2584 IT_BYTEPOS (*it) = bytepos;
2586 it->start = it->current;
2588 /* Compute faces etc. */
2589 reseat (it, it->current.pos, 1);
2592 CHECK_IT (it);
2596 /* Initialize IT for the display of window W with window start POS. */
2598 void
2599 start_display (struct it *it, struct window *w, struct text_pos pos)
2601 struct glyph_row *row;
2602 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
2604 row = w->desired_matrix->rows + first_vpos;
2605 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
2606 it->first_vpos = first_vpos;
2608 /* Don't reseat to previous visible line start if current start
2609 position is in a string or image. */
2610 if (it->method == GET_FROM_BUFFER && it->line_wrap != TRUNCATE)
2612 int start_at_line_beg_p;
2613 int first_y = it->current_y;
2615 /* If window start is not at a line start, skip forward to POS to
2616 get the correct continuation lines width. */
2617 start_at_line_beg_p = (CHARPOS (pos) == BEGV
2618 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
2619 if (!start_at_line_beg_p)
2621 int new_x;
2623 reseat_at_previous_visible_line_start (it);
2624 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
2626 new_x = it->current_x + it->pixel_width;
2628 /* If lines are continued, this line may end in the middle
2629 of a multi-glyph character (e.g. a control character
2630 displayed as \003, or in the middle of an overlay
2631 string). In this case move_it_to above will not have
2632 taken us to the start of the continuation line but to the
2633 end of the continued line. */
2634 if (it->current_x > 0
2635 && it->line_wrap != TRUNCATE /* Lines are continued. */
2636 && (/* And glyph doesn't fit on the line. */
2637 new_x > it->last_visible_x
2638 /* Or it fits exactly and we're on a window
2639 system frame. */
2640 || (new_x == it->last_visible_x
2641 && FRAME_WINDOW_P (it->f))))
2643 if (it->current.dpvec_index >= 0
2644 || it->current.overlay_string_index >= 0)
2646 set_iterator_to_next (it, 1);
2647 move_it_in_display_line_to (it, -1, -1, 0);
2650 it->continuation_lines_width += it->current_x;
2653 /* We're starting a new display line, not affected by the
2654 height of the continued line, so clear the appropriate
2655 fields in the iterator structure. */
2656 it->max_ascent = it->max_descent = 0;
2657 it->max_phys_ascent = it->max_phys_descent = 0;
2659 it->current_y = first_y;
2660 it->vpos = 0;
2661 it->current_x = it->hpos = 0;
2667 /* Return 1 if POS is a position in ellipses displayed for invisible
2668 text. W is the window we display, for text property lookup. */
2670 static int
2671 in_ellipses_for_invisible_text_p (struct display_pos *pos, struct window *w)
2673 Lisp_Object prop, window;
2674 int ellipses_p = 0;
2675 EMACS_INT charpos = CHARPOS (pos->pos);
2677 /* If POS specifies a position in a display vector, this might
2678 be for an ellipsis displayed for invisible text. We won't
2679 get the iterator set up for delivering that ellipsis unless
2680 we make sure that it gets aware of the invisible text. */
2681 if (pos->dpvec_index >= 0
2682 && pos->overlay_string_index < 0
2683 && CHARPOS (pos->string_pos) < 0
2684 && charpos > BEGV
2685 && (XSETWINDOW (window, w),
2686 prop = Fget_char_property (make_number (charpos),
2687 Qinvisible, window),
2688 !TEXT_PROP_MEANS_INVISIBLE (prop)))
2690 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
2691 window);
2692 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
2695 return ellipses_p;
2699 /* Initialize IT for stepping through current_buffer in window W,
2700 starting at position POS that includes overlay string and display
2701 vector/ control character translation position information. Value
2702 is zero if there are overlay strings with newlines at POS. */
2704 static int
2705 init_from_display_pos (struct it *it, struct window *w, struct display_pos *pos)
2707 EMACS_INT charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
2708 int i, overlay_strings_with_newlines = 0;
2710 /* If POS specifies a position in a display vector, this might
2711 be for an ellipsis displayed for invisible text. We won't
2712 get the iterator set up for delivering that ellipsis unless
2713 we make sure that it gets aware of the invisible text. */
2714 if (in_ellipses_for_invisible_text_p (pos, w))
2716 --charpos;
2717 bytepos = 0;
2720 /* Keep in mind: the call to reseat in init_iterator skips invisible
2721 text, so we might end up at a position different from POS. This
2722 is only a problem when POS is a row start after a newline and an
2723 overlay starts there with an after-string, and the overlay has an
2724 invisible property. Since we don't skip invisible text in
2725 display_line and elsewhere immediately after consuming the
2726 newline before the row start, such a POS will not be in a string,
2727 but the call to init_iterator below will move us to the
2728 after-string. */
2729 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
2731 /* This only scans the current chunk -- it should scan all chunks.
2732 However, OVERLAY_STRING_CHUNK_SIZE has been increased from 3 in 21.1
2733 to 16 in 22.1 to make this a lesser problem. */
2734 for (i = 0; i < it->n_overlay_strings && i < OVERLAY_STRING_CHUNK_SIZE; ++i)
2736 const char *s = SSDATA (it->overlay_strings[i]);
2737 const char *e = s + SBYTES (it->overlay_strings[i]);
2739 while (s < e && *s != '\n')
2740 ++s;
2742 if (s < e)
2744 overlay_strings_with_newlines = 1;
2745 break;
2749 /* If position is within an overlay string, set up IT to the right
2750 overlay string. */
2751 if (pos->overlay_string_index >= 0)
2753 int relative_index;
2755 /* If the first overlay string happens to have a `display'
2756 property for an image, the iterator will be set up for that
2757 image, and we have to undo that setup first before we can
2758 correct the overlay string index. */
2759 if (it->method == GET_FROM_IMAGE)
2760 pop_it (it);
2762 /* We already have the first chunk of overlay strings in
2763 IT->overlay_strings. Load more until the one for
2764 pos->overlay_string_index is in IT->overlay_strings. */
2765 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
2767 int n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
2768 it->current.overlay_string_index = 0;
2769 while (n--)
2771 load_overlay_strings (it, 0);
2772 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
2776 it->current.overlay_string_index = pos->overlay_string_index;
2777 relative_index = (it->current.overlay_string_index
2778 % OVERLAY_STRING_CHUNK_SIZE);
2779 it->string = it->overlay_strings[relative_index];
2780 xassert (STRINGP (it->string));
2781 it->current.string_pos = pos->string_pos;
2782 it->method = GET_FROM_STRING;
2785 if (CHARPOS (pos->string_pos) >= 0)
2787 /* Recorded position is not in an overlay string, but in another
2788 string. This can only be a string from a `display' property.
2789 IT should already be filled with that string. */
2790 it->current.string_pos = pos->string_pos;
2791 xassert (STRINGP (it->string));
2794 /* Restore position in display vector translations, control
2795 character translations or ellipses. */
2796 if (pos->dpvec_index >= 0)
2798 if (it->dpvec == NULL)
2799 get_next_display_element (it);
2800 xassert (it->dpvec && it->current.dpvec_index == 0);
2801 it->current.dpvec_index = pos->dpvec_index;
2804 CHECK_IT (it);
2805 return !overlay_strings_with_newlines;
2809 /* Initialize IT for stepping through current_buffer in window W
2810 starting at ROW->start. */
2812 static void
2813 init_to_row_start (struct it *it, struct window *w, struct glyph_row *row)
2815 init_from_display_pos (it, w, &row->start);
2816 it->start = row->start;
2817 it->continuation_lines_width = row->continuation_lines_width;
2818 CHECK_IT (it);
2822 /* Initialize IT for stepping through current_buffer in window W
2823 starting in the line following ROW, i.e. starting at ROW->end.
2824 Value is zero if there are overlay strings with newlines at ROW's
2825 end position. */
2827 static int
2828 init_to_row_end (struct it *it, struct window *w, struct glyph_row *row)
2830 int success = 0;
2832 if (init_from_display_pos (it, w, &row->end))
2834 if (row->continued_p)
2835 it->continuation_lines_width
2836 = row->continuation_lines_width + row->pixel_width;
2837 CHECK_IT (it);
2838 success = 1;
2841 return success;
2847 /***********************************************************************
2848 Text properties
2849 ***********************************************************************/
2851 /* Called when IT reaches IT->stop_charpos. Handle text property and
2852 overlay changes. Set IT->stop_charpos to the next position where
2853 to stop. */
2855 static void
2856 handle_stop (struct it *it)
2858 enum prop_handled handled;
2859 int handle_overlay_change_p;
2860 struct props *p;
2862 it->dpvec = NULL;
2863 it->current.dpvec_index = -1;
2864 handle_overlay_change_p = !it->ignore_overlay_strings_at_pos_p;
2865 it->ignore_overlay_strings_at_pos_p = 0;
2866 it->ellipsis_p = 0;
2868 /* Use face of preceding text for ellipsis (if invisible) */
2869 if (it->selective_display_ellipsis_p)
2870 it->saved_face_id = it->face_id;
2874 handled = HANDLED_NORMALLY;
2876 /* Call text property handlers. */
2877 for (p = it_props; p->handler; ++p)
2879 handled = p->handler (it);
2881 if (handled == HANDLED_RECOMPUTE_PROPS)
2882 break;
2883 else if (handled == HANDLED_RETURN)
2885 /* We still want to show before and after strings from
2886 overlays even if the actual buffer text is replaced. */
2887 if (!handle_overlay_change_p
2888 || it->sp > 1
2889 || !get_overlay_strings_1 (it, 0, 0))
2891 if (it->ellipsis_p)
2892 setup_for_ellipsis (it, 0);
2893 /* When handling a display spec, we might load an
2894 empty string. In that case, discard it here. We
2895 used to discard it in handle_single_display_spec,
2896 but that causes get_overlay_strings_1, above, to
2897 ignore overlay strings that we must check. */
2898 if (STRINGP (it->string) && !SCHARS (it->string))
2899 pop_it (it);
2900 return;
2902 else if (STRINGP (it->string) && !SCHARS (it->string))
2903 pop_it (it);
2904 else
2906 it->ignore_overlay_strings_at_pos_p = 1;
2907 it->string_from_display_prop_p = 0;
2908 handle_overlay_change_p = 0;
2910 handled = HANDLED_RECOMPUTE_PROPS;
2911 break;
2913 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
2914 handle_overlay_change_p = 0;
2917 if (handled != HANDLED_RECOMPUTE_PROPS)
2919 /* Don't check for overlay strings below when set to deliver
2920 characters from a display vector. */
2921 if (it->method == GET_FROM_DISPLAY_VECTOR)
2922 handle_overlay_change_p = 0;
2924 /* Handle overlay changes.
2925 This sets HANDLED to HANDLED_RECOMPUTE_PROPS
2926 if it finds overlays. */
2927 if (handle_overlay_change_p)
2928 handled = handle_overlay_change (it);
2931 if (it->ellipsis_p)
2933 setup_for_ellipsis (it, 0);
2934 break;
2937 while (handled == HANDLED_RECOMPUTE_PROPS);
2939 /* Determine where to stop next. */
2940 if (handled == HANDLED_NORMALLY)
2941 compute_stop_pos (it);
2945 /* Compute IT->stop_charpos from text property and overlay change
2946 information for IT's current position. */
2948 static void
2949 compute_stop_pos (struct it *it)
2951 register INTERVAL iv, next_iv;
2952 Lisp_Object object, limit, position;
2953 EMACS_INT charpos, bytepos;
2955 /* If nowhere else, stop at the end. */
2956 it->stop_charpos = it->end_charpos;
2958 if (STRINGP (it->string))
2960 /* Strings are usually short, so don't limit the search for
2961 properties. */
2962 object = it->string;
2963 limit = Qnil;
2964 charpos = IT_STRING_CHARPOS (*it);
2965 bytepos = IT_STRING_BYTEPOS (*it);
2967 else
2969 EMACS_INT pos;
2971 /* If next overlay change is in front of the current stop pos
2972 (which is IT->end_charpos), stop there. Note: value of
2973 next_overlay_change is point-max if no overlay change
2974 follows. */
2975 charpos = IT_CHARPOS (*it);
2976 bytepos = IT_BYTEPOS (*it);
2977 pos = next_overlay_change (charpos);
2978 if (pos < it->stop_charpos)
2979 it->stop_charpos = pos;
2981 /* If showing the region, we have to stop at the region
2982 start or end because the face might change there. */
2983 if (it->region_beg_charpos > 0)
2985 if (IT_CHARPOS (*it) < it->region_beg_charpos)
2986 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
2987 else if (IT_CHARPOS (*it) < it->region_end_charpos)
2988 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
2991 /* Set up variables for computing the stop position from text
2992 property changes. */
2993 XSETBUFFER (object, current_buffer);
2994 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
2997 /* Get the interval containing IT's position. Value is a null
2998 interval if there isn't such an interval. */
2999 position = make_number (charpos);
3000 iv = validate_interval_range (object, &position, &position, 0);
3001 if (!NULL_INTERVAL_P (iv))
3003 Lisp_Object values_here[LAST_PROP_IDX];
3004 struct props *p;
3006 /* Get properties here. */
3007 for (p = it_props; p->handler; ++p)
3008 values_here[p->idx] = textget (iv->plist, *p->name);
3010 /* Look for an interval following iv that has different
3011 properties. */
3012 for (next_iv = next_interval (iv);
3013 (!NULL_INTERVAL_P (next_iv)
3014 && (NILP (limit)
3015 || XFASTINT (limit) > next_iv->position));
3016 next_iv = next_interval (next_iv))
3018 for (p = it_props; p->handler; ++p)
3020 Lisp_Object new_value;
3022 new_value = textget (next_iv->plist, *p->name);
3023 if (!EQ (values_here[p->idx], new_value))
3024 break;
3027 if (p->handler)
3028 break;
3031 if (!NULL_INTERVAL_P (next_iv))
3033 if (INTEGERP (limit)
3034 && next_iv->position >= XFASTINT (limit))
3035 /* No text property change up to limit. */
3036 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
3037 else
3038 /* Text properties change in next_iv. */
3039 it->stop_charpos = min (it->stop_charpos, next_iv->position);
3043 if (it->cmp_it.id < 0)
3045 EMACS_INT stoppos = it->end_charpos;
3047 if (it->bidi_p && it->bidi_it.scan_dir < 0)
3048 stoppos = -1;
3049 composition_compute_stop_pos (&it->cmp_it, charpos, bytepos,
3050 stoppos, it->string);
3053 xassert (STRINGP (it->string)
3054 || (it->stop_charpos >= BEGV
3055 && it->stop_charpos >= IT_CHARPOS (*it)));
3059 /* Return the position of the next overlay change after POS in
3060 current_buffer. Value is point-max if no overlay change
3061 follows. This is like `next-overlay-change' but doesn't use
3062 xmalloc. */
3064 static EMACS_INT
3065 next_overlay_change (EMACS_INT pos)
3067 int noverlays;
3068 EMACS_INT endpos;
3069 Lisp_Object *overlays;
3070 int i;
3072 /* Get all overlays at the given position. */
3073 GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, 1);
3075 /* If any of these overlays ends before endpos,
3076 use its ending point instead. */
3077 for (i = 0; i < noverlays; ++i)
3079 Lisp_Object oend;
3080 EMACS_INT oendpos;
3082 oend = OVERLAY_END (overlays[i]);
3083 oendpos = OVERLAY_POSITION (oend);
3084 endpos = min (endpos, oendpos);
3087 return endpos;
3090 /* Return the character position of a display string at or after CHARPOS.
3091 If no display string exists at or after CHARPOS, return ZV. A
3092 display string is either an overlay with `display' property whose
3093 value is a string, or a `display' text property whose value is a
3094 string. FRAME_WINDOW_P is non-zero when we are displaying a window
3095 on a GUI frame. */
3096 EMACS_INT
3097 compute_display_string_pos (EMACS_INT charpos, int frame_window_p)
3099 /* FIXME: Support display properties on strings (object = Qnil means
3100 current buffer). */
3101 Lisp_Object object = Qnil;
3102 Lisp_Object pos, spec;
3103 struct text_pos position;
3104 EMACS_INT bufpos;
3106 if (charpos >= ZV)
3107 return ZV;
3109 /* If the character at CHARPOS is where the display string begins,
3110 return CHARPOS. */
3111 pos = make_number (charpos);
3112 CHARPOS (position) = charpos;
3113 BYTEPOS (position) = CHAR_TO_BYTE (charpos);
3114 bufpos = charpos; /* FIXME! support strings as well */
3115 if (!NILP (spec = Fget_char_property (pos, Qdisplay, object))
3116 && (charpos <= BEGV
3117 || !EQ (Fget_char_property (make_number (charpos - 1), Qdisplay,
3118 object),
3119 spec))
3120 && handle_display_spec (NULL, spec, object, Qnil, &position, bufpos,
3121 frame_window_p))
3122 return charpos;
3124 /* Look forward for the first character with a `display' property
3125 that will replace the underlying text when displayed. */
3126 do {
3127 pos = Fnext_single_char_property_change (pos, Qdisplay, object, Qnil);
3128 CHARPOS (position) = XFASTINT (pos);
3129 BYTEPOS (position) = CHAR_TO_BYTE (CHARPOS (position));
3130 if (CHARPOS (position) >= ZV)
3131 break;
3132 spec = Fget_char_property (pos, Qdisplay, object);
3133 bufpos = CHARPOS (position); /* FIXME! support strings as well */
3134 } while (NILP (spec)
3135 || !handle_display_spec (NULL, spec, object, Qnil, &position, bufpos,
3136 frame_window_p));
3138 return CHARPOS (position);
3141 /* Return the character position of the end of the display string that
3142 started at CHARPOS. A display string is either an overlay with
3143 `display' property whose value is a string or a `display' text
3144 property whose value is a string. */
3145 EMACS_INT
3146 compute_display_string_end (EMACS_INT charpos)
3148 /* FIXME: Support display properties on strings (object = Qnil means
3149 current buffer). */
3150 Lisp_Object object = Qnil;
3151 Lisp_Object pos = make_number (charpos);
3153 if (charpos >= ZV)
3154 return ZV;
3156 if (NILP (Fget_char_property (pos, Qdisplay, object)))
3157 abort ();
3159 /* Look forward for the first character where the `display' property
3160 changes. */
3161 pos = Fnext_single_char_property_change (pos, Qdisplay, object, Qnil);
3163 return XFASTINT (pos);
3168 /***********************************************************************
3169 Fontification
3170 ***********************************************************************/
3172 /* Handle changes in the `fontified' property of the current buffer by
3173 calling hook functions from Qfontification_functions to fontify
3174 regions of text. */
3176 static enum prop_handled
3177 handle_fontified_prop (struct it *it)
3179 Lisp_Object prop, pos;
3180 enum prop_handled handled = HANDLED_NORMALLY;
3182 if (!NILP (Vmemory_full))
3183 return handled;
3185 /* Get the value of the `fontified' property at IT's current buffer
3186 position. (The `fontified' property doesn't have a special
3187 meaning in strings.) If the value is nil, call functions from
3188 Qfontification_functions. */
3189 if (!STRINGP (it->string)
3190 && it->s == NULL
3191 && !NILP (Vfontification_functions)
3192 && !NILP (Vrun_hooks)
3193 && (pos = make_number (IT_CHARPOS (*it)),
3194 prop = Fget_char_property (pos, Qfontified, Qnil),
3195 /* Ignore the special cased nil value always present at EOB since
3196 no amount of fontifying will be able to change it. */
3197 NILP (prop) && IT_CHARPOS (*it) < Z))
3199 int count = SPECPDL_INDEX ();
3200 Lisp_Object val;
3201 struct buffer *obuf = current_buffer;
3202 int begv = BEGV, zv = ZV;
3203 int old_clip_changed = current_buffer->clip_changed;
3205 val = Vfontification_functions;
3206 specbind (Qfontification_functions, Qnil);
3208 xassert (it->end_charpos == ZV);
3210 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
3211 safe_call1 (val, pos);
3212 else
3214 Lisp_Object fns, fn;
3215 struct gcpro gcpro1, gcpro2;
3217 fns = Qnil;
3218 GCPRO2 (val, fns);
3220 for (; CONSP (val); val = XCDR (val))
3222 fn = XCAR (val);
3224 if (EQ (fn, Qt))
3226 /* A value of t indicates this hook has a local
3227 binding; it means to run the global binding too.
3228 In a global value, t should not occur. If it
3229 does, we must ignore it to avoid an endless
3230 loop. */
3231 for (fns = Fdefault_value (Qfontification_functions);
3232 CONSP (fns);
3233 fns = XCDR (fns))
3235 fn = XCAR (fns);
3236 if (!EQ (fn, Qt))
3237 safe_call1 (fn, pos);
3240 else
3241 safe_call1 (fn, pos);
3244 UNGCPRO;
3247 unbind_to (count, Qnil);
3249 /* Fontification functions routinely call `save-restriction'.
3250 Normally, this tags clip_changed, which can confuse redisplay
3251 (see discussion in Bug#6671). Since we don't perform any
3252 special handling of fontification changes in the case where
3253 `save-restriction' isn't called, there's no point doing so in
3254 this case either. So, if the buffer's restrictions are
3255 actually left unchanged, reset clip_changed. */
3256 if (obuf == current_buffer)
3258 if (begv == BEGV && zv == ZV)
3259 current_buffer->clip_changed = old_clip_changed;
3261 /* There isn't much we can reasonably do to protect against
3262 misbehaving fontification, but here's a fig leaf. */
3263 else if (!NILP (BVAR (obuf, name)))
3264 set_buffer_internal_1 (obuf);
3266 /* The fontification code may have added/removed text.
3267 It could do even a lot worse, but let's at least protect against
3268 the most obvious case where only the text past `pos' gets changed',
3269 as is/was done in grep.el where some escapes sequences are turned
3270 into face properties (bug#7876). */
3271 it->end_charpos = ZV;
3273 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
3274 something. This avoids an endless loop if they failed to
3275 fontify the text for which reason ever. */
3276 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
3277 handled = HANDLED_RECOMPUTE_PROPS;
3280 return handled;
3285 /***********************************************************************
3286 Faces
3287 ***********************************************************************/
3289 /* Set up iterator IT from face properties at its current position.
3290 Called from handle_stop. */
3292 static enum prop_handled
3293 handle_face_prop (struct it *it)
3295 int new_face_id;
3296 EMACS_INT next_stop;
3298 if (!STRINGP (it->string))
3300 new_face_id
3301 = face_at_buffer_position (it->w,
3302 IT_CHARPOS (*it),
3303 it->region_beg_charpos,
3304 it->region_end_charpos,
3305 &next_stop,
3306 (IT_CHARPOS (*it)
3307 + TEXT_PROP_DISTANCE_LIMIT),
3308 0, it->base_face_id);
3310 /* Is this a start of a run of characters with box face?
3311 Caveat: this can be called for a freshly initialized
3312 iterator; face_id is -1 in this case. We know that the new
3313 face will not change until limit, i.e. if the new face has a
3314 box, all characters up to limit will have one. But, as
3315 usual, we don't know whether limit is really the end. */
3316 if (new_face_id != it->face_id)
3318 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3320 /* If new face has a box but old face has not, this is
3321 the start of a run of characters with box, i.e. it has
3322 a shadow on the left side. The value of face_id of the
3323 iterator will be -1 if this is the initial call that gets
3324 the face. In this case, we have to look in front of IT's
3325 position and see whether there is a face != new_face_id. */
3326 it->start_of_box_run_p
3327 = (new_face->box != FACE_NO_BOX
3328 && (it->face_id >= 0
3329 || IT_CHARPOS (*it) == BEG
3330 || new_face_id != face_before_it_pos (it)));
3331 it->face_box_p = new_face->box != FACE_NO_BOX;
3334 else
3336 int base_face_id;
3337 EMACS_INT bufpos;
3338 int i;
3339 Lisp_Object from_overlay
3340 = (it->current.overlay_string_index >= 0
3341 ? it->string_overlays[it->current.overlay_string_index]
3342 : Qnil);
3344 /* See if we got to this string directly or indirectly from
3345 an overlay property. That includes the before-string or
3346 after-string of an overlay, strings in display properties
3347 provided by an overlay, their text properties, etc.
3349 FROM_OVERLAY is the overlay that brought us here, or nil if none. */
3350 if (! NILP (from_overlay))
3351 for (i = it->sp - 1; i >= 0; i--)
3353 if (it->stack[i].current.overlay_string_index >= 0)
3354 from_overlay
3355 = it->string_overlays[it->stack[i].current.overlay_string_index];
3356 else if (! NILP (it->stack[i].from_overlay))
3357 from_overlay = it->stack[i].from_overlay;
3359 if (!NILP (from_overlay))
3360 break;
3363 if (! NILP (from_overlay))
3365 bufpos = IT_CHARPOS (*it);
3366 /* For a string from an overlay, the base face depends
3367 only on text properties and ignores overlays. */
3368 base_face_id
3369 = face_for_overlay_string (it->w,
3370 IT_CHARPOS (*it),
3371 it->region_beg_charpos,
3372 it->region_end_charpos,
3373 &next_stop,
3374 (IT_CHARPOS (*it)
3375 + TEXT_PROP_DISTANCE_LIMIT),
3377 from_overlay);
3379 else
3381 bufpos = 0;
3383 /* For strings from a `display' property, use the face at
3384 IT's current buffer position as the base face to merge
3385 with, so that overlay strings appear in the same face as
3386 surrounding text, unless they specify their own
3387 faces. */
3388 base_face_id = underlying_face_id (it);
3391 new_face_id = face_at_string_position (it->w,
3392 it->string,
3393 IT_STRING_CHARPOS (*it),
3394 bufpos,
3395 it->region_beg_charpos,
3396 it->region_end_charpos,
3397 &next_stop,
3398 base_face_id, 0);
3400 /* Is this a start of a run of characters with box? Caveat:
3401 this can be called for a freshly allocated iterator; face_id
3402 is -1 is this case. We know that the new face will not
3403 change until the next check pos, i.e. if the new face has a
3404 box, all characters up to that position will have a
3405 box. But, as usual, we don't know whether that position
3406 is really the end. */
3407 if (new_face_id != it->face_id)
3409 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3410 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
3412 /* If new face has a box but old face hasn't, this is the
3413 start of a run of characters with box, i.e. it has a
3414 shadow on the left side. */
3415 it->start_of_box_run_p
3416 = new_face->box && (old_face == NULL || !old_face->box);
3417 it->face_box_p = new_face->box != FACE_NO_BOX;
3421 it->face_id = new_face_id;
3422 return HANDLED_NORMALLY;
3426 /* Return the ID of the face ``underlying'' IT's current position,
3427 which is in a string. If the iterator is associated with a
3428 buffer, return the face at IT's current buffer position.
3429 Otherwise, use the iterator's base_face_id. */
3431 static int
3432 underlying_face_id (struct it *it)
3434 int face_id = it->base_face_id, i;
3436 xassert (STRINGP (it->string));
3438 for (i = it->sp - 1; i >= 0; --i)
3439 if (NILP (it->stack[i].string))
3440 face_id = it->stack[i].face_id;
3442 return face_id;
3446 /* Compute the face one character before or after the current position
3447 of IT. BEFORE_P non-zero means get the face in front of IT's
3448 position. Value is the id of the face. */
3450 static int
3451 face_before_or_after_it_pos (struct it *it, int before_p)
3453 int face_id, limit;
3454 EMACS_INT next_check_charpos;
3455 struct text_pos pos;
3457 xassert (it->s == NULL);
3459 if (STRINGP (it->string))
3461 EMACS_INT bufpos;
3462 int base_face_id;
3464 /* No face change past the end of the string (for the case
3465 we are padding with spaces). No face change before the
3466 string start. */
3467 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
3468 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
3469 return it->face_id;
3471 /* Set pos to the position before or after IT's current position. */
3472 if (before_p)
3473 pos = string_pos (IT_STRING_CHARPOS (*it) - 1, it->string);
3474 else
3475 /* For composition, we must check the character after the
3476 composition. */
3477 pos = (it->what == IT_COMPOSITION
3478 ? string_pos (IT_STRING_CHARPOS (*it)
3479 + it->cmp_it.nchars, it->string)
3480 : string_pos (IT_STRING_CHARPOS (*it) + 1, it->string));
3482 if (it->current.overlay_string_index >= 0)
3483 bufpos = IT_CHARPOS (*it);
3484 else
3485 bufpos = 0;
3487 base_face_id = underlying_face_id (it);
3489 /* Get the face for ASCII, or unibyte. */
3490 face_id = face_at_string_position (it->w,
3491 it->string,
3492 CHARPOS (pos),
3493 bufpos,
3494 it->region_beg_charpos,
3495 it->region_end_charpos,
3496 &next_check_charpos,
3497 base_face_id, 0);
3499 /* Correct the face for charsets different from ASCII. Do it
3500 for the multibyte case only. The face returned above is
3501 suitable for unibyte text if IT->string is unibyte. */
3502 if (STRING_MULTIBYTE (it->string))
3504 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos);
3505 int c, len;
3506 struct face *face = FACE_FROM_ID (it->f, face_id);
3508 c = string_char_and_length (p, &len);
3509 face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), it->string);
3512 else
3514 if ((IT_CHARPOS (*it) >= ZV && !before_p)
3515 || (IT_CHARPOS (*it) <= BEGV && before_p))
3516 return it->face_id;
3518 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
3519 pos = it->current.pos;
3521 if (before_p)
3522 DEC_TEXT_POS (pos, it->multibyte_p);
3523 else
3525 if (it->what == IT_COMPOSITION)
3526 /* For composition, we must check the position after the
3527 composition. */
3528 pos.charpos += it->cmp_it.nchars, pos.bytepos += it->len;
3529 else
3530 INC_TEXT_POS (pos, it->multibyte_p);
3533 /* Determine face for CHARSET_ASCII, or unibyte. */
3534 face_id = face_at_buffer_position (it->w,
3535 CHARPOS (pos),
3536 it->region_beg_charpos,
3537 it->region_end_charpos,
3538 &next_check_charpos,
3539 limit, 0, -1);
3541 /* Correct the face for charsets different from ASCII. Do it
3542 for the multibyte case only. The face returned above is
3543 suitable for unibyte text if current_buffer is unibyte. */
3544 if (it->multibyte_p)
3546 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
3547 struct face *face = FACE_FROM_ID (it->f, face_id);
3548 face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), Qnil);
3552 return face_id;
3557 /***********************************************************************
3558 Invisible text
3559 ***********************************************************************/
3561 /* Set up iterator IT from invisible properties at its current
3562 position. Called from handle_stop. */
3564 static enum prop_handled
3565 handle_invisible_prop (struct it *it)
3567 enum prop_handled handled = HANDLED_NORMALLY;
3569 if (STRINGP (it->string))
3571 Lisp_Object prop, end_charpos, limit, charpos;
3573 /* Get the value of the invisible text property at the
3574 current position. Value will be nil if there is no such
3575 property. */
3576 charpos = make_number (IT_STRING_CHARPOS (*it));
3577 prop = Fget_text_property (charpos, Qinvisible, it->string);
3579 if (!NILP (prop)
3580 && IT_STRING_CHARPOS (*it) < it->end_charpos)
3582 handled = HANDLED_RECOMPUTE_PROPS;
3584 /* Get the position at which the next change of the
3585 invisible text property can be found in IT->string.
3586 Value will be nil if the property value is the same for
3587 all the rest of IT->string. */
3588 XSETINT (limit, SCHARS (it->string));
3589 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
3590 it->string, limit);
3592 /* Text at current position is invisible. The next
3593 change in the property is at position end_charpos.
3594 Move IT's current position to that position. */
3595 if (INTEGERP (end_charpos)
3596 && XFASTINT (end_charpos) < XFASTINT (limit))
3598 struct text_pos old;
3599 old = it->current.string_pos;
3600 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
3601 compute_string_pos (&it->current.string_pos, old, it->string);
3603 else
3605 /* The rest of the string is invisible. If this is an
3606 overlay string, proceed with the next overlay string
3607 or whatever comes and return a character from there. */
3608 if (it->current.overlay_string_index >= 0)
3610 next_overlay_string (it);
3611 /* Don't check for overlay strings when we just
3612 finished processing them. */
3613 handled = HANDLED_OVERLAY_STRING_CONSUMED;
3615 else
3617 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
3618 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
3623 else
3625 int invis_p;
3626 EMACS_INT newpos, next_stop, start_charpos, tem;
3627 Lisp_Object pos, prop, overlay;
3629 /* First of all, is there invisible text at this position? */
3630 tem = start_charpos = IT_CHARPOS (*it);
3631 pos = make_number (tem);
3632 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
3633 &overlay);
3634 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3636 /* If we are on invisible text, skip over it. */
3637 if (invis_p && start_charpos < it->end_charpos)
3639 /* Record whether we have to display an ellipsis for the
3640 invisible text. */
3641 int display_ellipsis_p = invis_p == 2;
3643 handled = HANDLED_RECOMPUTE_PROPS;
3645 /* Loop skipping over invisible text. The loop is left at
3646 ZV or with IT on the first char being visible again. */
3649 /* Try to skip some invisible text. Return value is the
3650 position reached which can be equal to where we start
3651 if there is nothing invisible there. This skips both
3652 over invisible text properties and overlays with
3653 invisible property. */
3654 newpos = skip_invisible (tem, &next_stop, ZV, it->window);
3656 /* If we skipped nothing at all we weren't at invisible
3657 text in the first place. If everything to the end of
3658 the buffer was skipped, end the loop. */
3659 if (newpos == tem || newpos >= ZV)
3660 invis_p = 0;
3661 else
3663 /* We skipped some characters but not necessarily
3664 all there are. Check if we ended up on visible
3665 text. Fget_char_property returns the property of
3666 the char before the given position, i.e. if we
3667 get invis_p = 0, this means that the char at
3668 newpos is visible. */
3669 pos = make_number (newpos);
3670 prop = Fget_char_property (pos, Qinvisible, it->window);
3671 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3674 /* If we ended up on invisible text, proceed to
3675 skip starting with next_stop. */
3676 if (invis_p)
3677 tem = next_stop;
3679 /* If there are adjacent invisible texts, don't lose the
3680 second one's ellipsis. */
3681 if (invis_p == 2)
3682 display_ellipsis_p = 1;
3684 while (invis_p);
3686 /* The position newpos is now either ZV or on visible text. */
3687 if (it->bidi_p && newpos < ZV)
3689 /* With bidi iteration, the region of invisible text
3690 could start and/or end in the middle of a non-base
3691 embedding level. Therefore, we need to skip
3692 invisible text using the bidi iterator, starting at
3693 IT's current position, until we find ourselves
3694 outside the invisible text. Skipping invisible text
3695 _after_ bidi iteration avoids affecting the visual
3696 order of the displayed text when invisible properties
3697 are added or removed. */
3698 if (it->bidi_it.first_elt && it->bidi_it.charpos < ZV)
3700 /* If we were `reseat'ed to a new paragraph,
3701 determine the paragraph base direction. We need
3702 to do it now because next_element_from_buffer may
3703 not have a chance to do it, if we are going to
3704 skip any text at the beginning, which resets the
3705 FIRST_ELT flag. */
3706 bidi_paragraph_init (it->paragraph_embedding,
3707 &it->bidi_it, 1);
3711 bidi_move_to_visually_next (&it->bidi_it);
3713 while (it->stop_charpos <= it->bidi_it.charpos
3714 && it->bidi_it.charpos < newpos);
3715 IT_CHARPOS (*it) = it->bidi_it.charpos;
3716 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
3717 /* If we overstepped NEWPOS, record its position in the
3718 iterator, so that we skip invisible text if later the
3719 bidi iteration lands us in the invisible region
3720 again. */
3721 if (IT_CHARPOS (*it) >= newpos)
3722 it->prev_stop = newpos;
3724 else
3726 IT_CHARPOS (*it) = newpos;
3727 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
3730 /* If there are before-strings at the start of invisible
3731 text, and the text is invisible because of a text
3732 property, arrange to show before-strings because 20.x did
3733 it that way. (If the text is invisible because of an
3734 overlay property instead of a text property, this is
3735 already handled in the overlay code.) */
3736 if (NILP (overlay)
3737 && get_overlay_strings (it, it->stop_charpos))
3739 handled = HANDLED_RECOMPUTE_PROPS;
3740 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
3742 else if (display_ellipsis_p)
3744 /* Make sure that the glyphs of the ellipsis will get
3745 correct `charpos' values. If we would not update
3746 it->position here, the glyphs would belong to the
3747 last visible character _before_ the invisible
3748 text, which confuses `set_cursor_from_row'.
3750 We use the last invisible position instead of the
3751 first because this way the cursor is always drawn on
3752 the first "." of the ellipsis, whenever PT is inside
3753 the invisible text. Otherwise the cursor would be
3754 placed _after_ the ellipsis when the point is after the
3755 first invisible character. */
3756 if (!STRINGP (it->object))
3758 it->position.charpos = newpos - 1;
3759 it->position.bytepos = CHAR_TO_BYTE (it->position.charpos);
3761 it->ellipsis_p = 1;
3762 /* Let the ellipsis display before
3763 considering any properties of the following char.
3764 Fixes jasonr@gnu.org 01 Oct 07 bug. */
3765 handled = HANDLED_RETURN;
3770 return handled;
3774 /* Make iterator IT return `...' next.
3775 Replaces LEN characters from buffer. */
3777 static void
3778 setup_for_ellipsis (struct it *it, int len)
3780 /* Use the display table definition for `...'. Invalid glyphs
3781 will be handled by the method returning elements from dpvec. */
3782 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
3784 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
3785 it->dpvec = v->contents;
3786 it->dpend = v->contents + v->header.size;
3788 else
3790 /* Default `...'. */
3791 it->dpvec = default_invis_vector;
3792 it->dpend = default_invis_vector + 3;
3795 it->dpvec_char_len = len;
3796 it->current.dpvec_index = 0;
3797 it->dpvec_face_id = -1;
3799 /* Remember the current face id in case glyphs specify faces.
3800 IT's face is restored in set_iterator_to_next.
3801 saved_face_id was set to preceding char's face in handle_stop. */
3802 if (it->saved_face_id < 0 || it->saved_face_id != it->face_id)
3803 it->saved_face_id = it->face_id = DEFAULT_FACE_ID;
3805 it->method = GET_FROM_DISPLAY_VECTOR;
3806 it->ellipsis_p = 1;
3811 /***********************************************************************
3812 'display' property
3813 ***********************************************************************/
3815 /* Set up iterator IT from `display' property at its current position.
3816 Called from handle_stop.
3817 We return HANDLED_RETURN if some part of the display property
3818 overrides the display of the buffer text itself.
3819 Otherwise we return HANDLED_NORMALLY. */
3821 static enum prop_handled
3822 handle_display_prop (struct it *it)
3824 Lisp_Object propval, object, overlay;
3825 struct text_pos *position;
3826 EMACS_INT bufpos;
3827 /* Nonzero if some property replaces the display of the text itself. */
3828 int display_replaced_p = 0;
3830 if (STRINGP (it->string))
3832 object = it->string;
3833 position = &it->current.string_pos;
3834 bufpos = CHARPOS (it->current.pos);
3836 else
3838 XSETWINDOW (object, it->w);
3839 position = &it->current.pos;
3840 bufpos = CHARPOS (*position);
3843 /* Reset those iterator values set from display property values. */
3844 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
3845 it->space_width = Qnil;
3846 it->font_height = Qnil;
3847 it->voffset = 0;
3849 /* We don't support recursive `display' properties, i.e. string
3850 values that have a string `display' property, that have a string
3851 `display' property etc. */
3852 if (!it->string_from_display_prop_p)
3853 it->area = TEXT_AREA;
3855 propval = get_char_property_and_overlay (make_number (position->charpos),
3856 Qdisplay, object, &overlay);
3857 if (NILP (propval))
3858 return HANDLED_NORMALLY;
3859 /* Now OVERLAY is the overlay that gave us this property, or nil
3860 if it was a text property. */
3862 if (!STRINGP (it->string))
3863 object = it->w->buffer;
3865 display_replaced_p = handle_display_spec (it, propval, object, overlay,
3866 position, bufpos,
3867 FRAME_WINDOW_P (it->f));
3869 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
3872 /* Subroutine of handle_display_prop. Returns non-zero if the display
3873 specification in SPEC is a replacing specification, i.e. it would
3874 replace the text covered by `display' property with something else,
3875 such as an image or a display string.
3877 See handle_single_display_spec for documentation of arguments.
3878 frame_window_p is non-zero if the window being redisplayed is on a
3879 GUI frame; this argument is used only if IT is NULL, see below.
3881 IT can be NULL, if this is called by the bidi reordering code
3882 through compute_display_string_pos, which see. In that case, this
3883 function only examines SPEC, but does not otherwise "handle" it, in
3884 the sense that it doesn't set up members of IT from the display
3885 spec. */
3886 static int
3887 handle_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
3888 Lisp_Object overlay, struct text_pos *position,
3889 EMACS_INT bufpos, int frame_window_p)
3891 int replacing_p = 0;
3893 if (CONSP (spec)
3894 /* Simple specerties. */
3895 && !EQ (XCAR (spec), Qimage)
3896 && !EQ (XCAR (spec), Qspace)
3897 && !EQ (XCAR (spec), Qwhen)
3898 && !EQ (XCAR (spec), Qslice)
3899 && !EQ (XCAR (spec), Qspace_width)
3900 && !EQ (XCAR (spec), Qheight)
3901 && !EQ (XCAR (spec), Qraise)
3902 /* Marginal area specifications. */
3903 && !(CONSP (XCAR (spec)) && EQ (XCAR (XCAR (spec)), Qmargin))
3904 && !EQ (XCAR (spec), Qleft_fringe)
3905 && !EQ (XCAR (spec), Qright_fringe)
3906 && !NILP (XCAR (spec)))
3908 for (; CONSP (spec); spec = XCDR (spec))
3910 if (handle_single_display_spec (it, XCAR (spec), object, overlay,
3911 position, bufpos, replacing_p,
3912 frame_window_p))
3914 replacing_p = 1;
3915 /* If some text in a string is replaced, `position' no
3916 longer points to the position of `object'. */
3917 if (!it || STRINGP (object))
3918 break;
3922 else if (VECTORP (spec))
3924 int i;
3925 for (i = 0; i < ASIZE (spec); ++i)
3926 if (handle_single_display_spec (it, AREF (spec, i), object, overlay,
3927 position, bufpos, replacing_p,
3928 frame_window_p))
3930 replacing_p = 1;
3931 /* If some text in a string is replaced, `position' no
3932 longer points to the position of `object'. */
3933 if (!it || STRINGP (object))
3934 break;
3937 else
3939 if (handle_single_display_spec (it, spec, object, overlay,
3940 position, bufpos, 0, frame_window_p))
3941 replacing_p = 1;
3944 return replacing_p;
3947 /* Value is the position of the end of the `display' property starting
3948 at START_POS in OBJECT. */
3950 static struct text_pos
3951 display_prop_end (struct it *it, Lisp_Object object, struct text_pos start_pos)
3953 Lisp_Object end;
3954 struct text_pos end_pos;
3956 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
3957 Qdisplay, object, Qnil);
3958 CHARPOS (end_pos) = XFASTINT (end);
3959 if (STRINGP (object))
3960 compute_string_pos (&end_pos, start_pos, it->string);
3961 else
3962 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
3964 return end_pos;
3968 /* Set up IT from a single `display' property specification SPEC. OBJECT
3969 is the object in which the `display' property was found. *POSITION
3970 is the position in OBJECT at which the `display' property was found.
3971 BUFPOS is the buffer position of OBJECT (different from POSITION if
3972 OBJECT is not a buffer). DISPLAY_REPLACED_P non-zero means that we
3973 previously saw a display specification which already replaced text
3974 display with something else, for example an image; we ignore such
3975 properties after the first one has been processed.
3977 OVERLAY is the overlay this `display' property came from,
3978 or nil if it was a text property.
3980 If SPEC is a `space' or `image' specification, and in some other
3981 cases too, set *POSITION to the position where the `display'
3982 property ends.
3984 If IT is NULL, only examine the property specification in SPEC, but
3985 don't set up IT. In that case, FRAME_WINDOW_P non-zero means SPEC
3986 is intended to be displayed in a window on a GUI frame.
3988 Value is non-zero if something was found which replaces the display
3989 of buffer or string text. */
3991 static int
3992 handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
3993 Lisp_Object overlay, struct text_pos *position,
3994 EMACS_INT bufpos, int display_replaced_p,
3995 int frame_window_p)
3997 Lisp_Object form;
3998 Lisp_Object location, value;
3999 struct text_pos start_pos = *position;
4000 int valid_p;
4002 /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
4003 If the result is non-nil, use VALUE instead of SPEC. */
4004 form = Qt;
4005 if (CONSP (spec) && EQ (XCAR (spec), Qwhen))
4007 spec = XCDR (spec);
4008 if (!CONSP (spec))
4009 return 0;
4010 form = XCAR (spec);
4011 spec = XCDR (spec);
4014 if (!NILP (form) && !EQ (form, Qt))
4016 int count = SPECPDL_INDEX ();
4017 struct gcpro gcpro1;
4019 /* Bind `object' to the object having the `display' property, a
4020 buffer or string. Bind `position' to the position in the
4021 object where the property was found, and `buffer-position'
4022 to the current position in the buffer. */
4024 if (NILP (object))
4025 XSETBUFFER (object, current_buffer);
4026 specbind (Qobject, object);
4027 specbind (Qposition, make_number (CHARPOS (*position)));
4028 specbind (Qbuffer_position, make_number (bufpos));
4029 GCPRO1 (form);
4030 form = safe_eval (form);
4031 UNGCPRO;
4032 unbind_to (count, Qnil);
4035 if (NILP (form))
4036 return 0;
4038 /* Handle `(height HEIGHT)' specifications. */
4039 if (CONSP (spec)
4040 && EQ (XCAR (spec), Qheight)
4041 && CONSP (XCDR (spec)))
4043 if (it)
4045 if (!FRAME_WINDOW_P (it->f))
4046 return 0;
4048 it->font_height = XCAR (XCDR (spec));
4049 if (!NILP (it->font_height))
4051 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4052 int new_height = -1;
4054 if (CONSP (it->font_height)
4055 && (EQ (XCAR (it->font_height), Qplus)
4056 || EQ (XCAR (it->font_height), Qminus))
4057 && CONSP (XCDR (it->font_height))
4058 && INTEGERP (XCAR (XCDR (it->font_height))))
4060 /* `(+ N)' or `(- N)' where N is an integer. */
4061 int steps = XINT (XCAR (XCDR (it->font_height)));
4062 if (EQ (XCAR (it->font_height), Qplus))
4063 steps = - steps;
4064 it->face_id = smaller_face (it->f, it->face_id, steps);
4066 else if (FUNCTIONP (it->font_height))
4068 /* Call function with current height as argument.
4069 Value is the new height. */
4070 Lisp_Object height;
4071 height = safe_call1 (it->font_height,
4072 face->lface[LFACE_HEIGHT_INDEX]);
4073 if (NUMBERP (height))
4074 new_height = XFLOATINT (height);
4076 else if (NUMBERP (it->font_height))
4078 /* Value is a multiple of the canonical char height. */
4079 struct face *f;
4081 f = FACE_FROM_ID (it->f,
4082 lookup_basic_face (it->f, DEFAULT_FACE_ID));
4083 new_height = (XFLOATINT (it->font_height)
4084 * XINT (f->lface[LFACE_HEIGHT_INDEX]));
4086 else
4088 /* Evaluate IT->font_height with `height' bound to the
4089 current specified height to get the new height. */
4090 int count = SPECPDL_INDEX ();
4092 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
4093 value = safe_eval (it->font_height);
4094 unbind_to (count, Qnil);
4096 if (NUMBERP (value))
4097 new_height = XFLOATINT (value);
4100 if (new_height > 0)
4101 it->face_id = face_with_height (it->f, it->face_id, new_height);
4105 return 0;
4108 /* Handle `(space-width WIDTH)'. */
4109 if (CONSP (spec)
4110 && EQ (XCAR (spec), Qspace_width)
4111 && CONSP (XCDR (spec)))
4113 if (it)
4115 if (!FRAME_WINDOW_P (it->f))
4116 return 0;
4118 value = XCAR (XCDR (spec));
4119 if (NUMBERP (value) && XFLOATINT (value) > 0)
4120 it->space_width = value;
4123 return 0;
4126 /* Handle `(slice X Y WIDTH HEIGHT)'. */
4127 if (CONSP (spec)
4128 && EQ (XCAR (spec), Qslice))
4130 Lisp_Object tem;
4132 if (it)
4134 if (!FRAME_WINDOW_P (it->f))
4135 return 0;
4137 if (tem = XCDR (spec), CONSP (tem))
4139 it->slice.x = XCAR (tem);
4140 if (tem = XCDR (tem), CONSP (tem))
4142 it->slice.y = XCAR (tem);
4143 if (tem = XCDR (tem), CONSP (tem))
4145 it->slice.width = XCAR (tem);
4146 if (tem = XCDR (tem), CONSP (tem))
4147 it->slice.height = XCAR (tem);
4153 return 0;
4156 /* Handle `(raise FACTOR)'. */
4157 if (CONSP (spec)
4158 && EQ (XCAR (spec), Qraise)
4159 && CONSP (XCDR (spec)))
4161 if (it)
4163 if (!FRAME_WINDOW_P (it->f))
4164 return 0;
4166 #ifdef HAVE_WINDOW_SYSTEM
4167 value = XCAR (XCDR (spec));
4168 if (NUMBERP (value))
4170 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4171 it->voffset = - (XFLOATINT (value)
4172 * (FONT_HEIGHT (face->font)));
4174 #endif /* HAVE_WINDOW_SYSTEM */
4177 return 0;
4180 /* Don't handle the other kinds of display specifications
4181 inside a string that we got from a `display' property. */
4182 if (it && it->string_from_display_prop_p)
4183 return 0;
4185 /* Characters having this form of property are not displayed, so
4186 we have to find the end of the property. */
4187 if (it)
4189 start_pos = *position;
4190 *position = display_prop_end (it, object, start_pos);
4192 value = Qnil;
4194 /* Stop the scan at that end position--we assume that all
4195 text properties change there. */
4196 if (it)
4197 it->stop_charpos = position->charpos;
4199 /* Handle `(left-fringe BITMAP [FACE])'
4200 and `(right-fringe BITMAP [FACE])'. */
4201 if (CONSP (spec)
4202 && (EQ (XCAR (spec), Qleft_fringe)
4203 || EQ (XCAR (spec), Qright_fringe))
4204 && CONSP (XCDR (spec)))
4206 int fringe_bitmap;
4208 if (it)
4210 if (!FRAME_WINDOW_P (it->f))
4211 /* If we return here, POSITION has been advanced
4212 across the text with this property. */
4213 return 0;
4215 else if (!frame_window_p)
4216 return 0;
4218 #ifdef HAVE_WINDOW_SYSTEM
4219 value = XCAR (XCDR (spec));
4220 if (!SYMBOLP (value)
4221 || !(fringe_bitmap = lookup_fringe_bitmap (value)))
4222 /* If we return here, POSITION has been advanced
4223 across the text with this property. */
4224 return 0;
4226 if (it)
4228 int face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);;
4230 if (CONSP (XCDR (XCDR (spec))))
4232 Lisp_Object face_name = XCAR (XCDR (XCDR (spec)));
4233 int face_id2 = lookup_derived_face (it->f, face_name,
4234 FRINGE_FACE_ID, 0);
4235 if (face_id2 >= 0)
4236 face_id = face_id2;
4239 /* Save current settings of IT so that we can restore them
4240 when we are finished with the glyph property value. */
4241 push_it (it, position);
4243 it->area = TEXT_AREA;
4244 it->what = IT_IMAGE;
4245 it->image_id = -1; /* no image */
4246 it->position = start_pos;
4247 it->object = NILP (object) ? it->w->buffer : object;
4248 it->method = GET_FROM_IMAGE;
4249 it->from_overlay = Qnil;
4250 it->face_id = face_id;
4252 /* Say that we haven't consumed the characters with
4253 `display' property yet. The call to pop_it in
4254 set_iterator_to_next will clean this up. */
4255 *position = start_pos;
4257 if (EQ (XCAR (spec), Qleft_fringe))
4259 it->left_user_fringe_bitmap = fringe_bitmap;
4260 it->left_user_fringe_face_id = face_id;
4262 else
4264 it->right_user_fringe_bitmap = fringe_bitmap;
4265 it->right_user_fringe_face_id = face_id;
4268 #endif /* HAVE_WINDOW_SYSTEM */
4269 return 1;
4272 /* Prepare to handle `((margin left-margin) ...)',
4273 `((margin right-margin) ...)' and `((margin nil) ...)'
4274 prefixes for display specifications. */
4275 location = Qunbound;
4276 if (CONSP (spec) && CONSP (XCAR (spec)))
4278 Lisp_Object tem;
4280 value = XCDR (spec);
4281 if (CONSP (value))
4282 value = XCAR (value);
4284 tem = XCAR (spec);
4285 if (EQ (XCAR (tem), Qmargin)
4286 && (tem = XCDR (tem),
4287 tem = CONSP (tem) ? XCAR (tem) : Qnil,
4288 (NILP (tem)
4289 || EQ (tem, Qleft_margin)
4290 || EQ (tem, Qright_margin))))
4291 location = tem;
4294 if (EQ (location, Qunbound))
4296 location = Qnil;
4297 value = spec;
4300 /* After this point, VALUE is the property after any
4301 margin prefix has been stripped. It must be a string,
4302 an image specification, or `(space ...)'.
4304 LOCATION specifies where to display: `left-margin',
4305 `right-margin' or nil. */
4307 valid_p = (STRINGP (value)
4308 #ifdef HAVE_WINDOW_SYSTEM
4309 || ((it ? FRAME_WINDOW_P (it->f) : frame_window_p)
4310 && valid_image_p (value))
4311 #endif /* not HAVE_WINDOW_SYSTEM */
4312 || (CONSP (value) && EQ (XCAR (value), Qspace)));
4314 if (valid_p && !display_replaced_p)
4316 if (!it)
4317 return 1;
4319 /* Save current settings of IT so that we can restore them
4320 when we are finished with the glyph property value. */
4321 push_it (it, position);
4322 it->from_overlay = overlay;
4324 if (NILP (location))
4325 it->area = TEXT_AREA;
4326 else if (EQ (location, Qleft_margin))
4327 it->area = LEFT_MARGIN_AREA;
4328 else
4329 it->area = RIGHT_MARGIN_AREA;
4331 if (STRINGP (value))
4333 it->string = value;
4334 it->multibyte_p = STRING_MULTIBYTE (it->string);
4335 it->current.overlay_string_index = -1;
4336 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
4337 it->end_charpos = it->string_nchars = SCHARS (it->string);
4338 it->method = GET_FROM_STRING;
4339 it->stop_charpos = 0;
4340 it->string_from_display_prop_p = 1;
4341 /* Say that we haven't consumed the characters with
4342 `display' property yet. The call to pop_it in
4343 set_iterator_to_next will clean this up. */
4344 if (BUFFERP (object))
4345 *position = start_pos;
4347 else if (CONSP (value) && EQ (XCAR (value), Qspace))
4349 it->method = GET_FROM_STRETCH;
4350 it->object = value;
4351 *position = it->position = start_pos;
4353 #ifdef HAVE_WINDOW_SYSTEM
4354 else
4356 it->what = IT_IMAGE;
4357 it->image_id = lookup_image (it->f, value);
4358 it->position = start_pos;
4359 it->object = NILP (object) ? it->w->buffer : object;
4360 it->method = GET_FROM_IMAGE;
4362 /* Say that we haven't consumed the characters with
4363 `display' property yet. The call to pop_it in
4364 set_iterator_to_next will clean this up. */
4365 *position = start_pos;
4367 #endif /* HAVE_WINDOW_SYSTEM */
4369 return 1;
4372 /* Invalid property or property not supported. Restore
4373 POSITION to what it was before. */
4374 *position = start_pos;
4375 return 0;
4378 /* Check if PROP is a display property value whose text should be
4379 treated as intangible. OVERLAY is the overlay from which PROP
4380 came, or nil if it came from a text property. CHARPOS and BYTEPOS
4381 specify the buffer position covered by PROP. */
4384 display_prop_intangible_p (Lisp_Object prop, Lisp_Object overlay,
4385 EMACS_INT charpos, EMACS_INT bytepos)
4387 int frame_window_p = FRAME_WINDOW_P (XFRAME (selected_frame));
4388 struct text_pos position;
4390 SET_TEXT_POS (position, charpos, bytepos);
4391 return handle_display_spec (NULL, prop, Qnil, overlay,
4392 &position, charpos, frame_window_p);
4396 /* Return 1 if PROP is a display sub-property value containing STRING.
4398 Implementation note: this and the following function are really
4399 special cases of handle_display_spec and
4400 handle_single_display_spec, and should ideally use the same code.
4401 Until they do, these two pairs must be consistent and must be
4402 modified in sync. */
4404 static int
4405 single_display_spec_string_p (Lisp_Object prop, Lisp_Object string)
4407 if (EQ (string, prop))
4408 return 1;
4410 /* Skip over `when FORM'. */
4411 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
4413 prop = XCDR (prop);
4414 if (!CONSP (prop))
4415 return 0;
4416 /* Actually, the condition following `when' should be eval'ed,
4417 like handle_single_display_spec does, and we should return
4418 zero if it evaluates to nil. However, this function is
4419 called only when the buffer was already displayed and some
4420 glyph in the glyph matrix was found to come from a display
4421 string. Therefore, the condition was already evaluated, and
4422 the result was non-nil, otherwise the display string wouldn't
4423 have been displayed and we would have never been called for
4424 this property. Thus, we can skip the evaluation and assume
4425 its result is non-nil. */
4426 prop = XCDR (prop);
4429 if (CONSP (prop))
4430 /* Skip over `margin LOCATION'. */
4431 if (EQ (XCAR (prop), Qmargin))
4433 prop = XCDR (prop);
4434 if (!CONSP (prop))
4435 return 0;
4437 prop = XCDR (prop);
4438 if (!CONSP (prop))
4439 return 0;
4442 return EQ (prop, string) || (CONSP (prop) && EQ (XCAR (prop), string));
4446 /* Return 1 if STRING appears in the `display' property PROP. */
4448 static int
4449 display_prop_string_p (Lisp_Object prop, Lisp_Object string)
4451 if (CONSP (prop)
4452 && !EQ (XCAR (prop), Qwhen)
4453 && !(CONSP (XCAR (prop)) && EQ (Qmargin, XCAR (XCAR (prop)))))
4455 /* A list of sub-properties. */
4456 while (CONSP (prop))
4458 if (single_display_spec_string_p (XCAR (prop), string))
4459 return 1;
4460 prop = XCDR (prop);
4463 else if (VECTORP (prop))
4465 /* A vector of sub-properties. */
4466 int i;
4467 for (i = 0; i < ASIZE (prop); ++i)
4468 if (single_display_spec_string_p (AREF (prop, i), string))
4469 return 1;
4471 else
4472 return single_display_spec_string_p (prop, string);
4474 return 0;
4477 /* Look for STRING in overlays and text properties in the current
4478 buffer, between character positions FROM and TO (excluding TO).
4479 BACK_P non-zero means look back (in this case, TO is supposed to be
4480 less than FROM).
4481 Value is the first character position where STRING was found, or
4482 zero if it wasn't found before hitting TO.
4484 This function may only use code that doesn't eval because it is
4485 called asynchronously from note_mouse_highlight. */
4487 static EMACS_INT
4488 string_buffer_position_lim (Lisp_Object string,
4489 EMACS_INT from, EMACS_INT to, int back_p)
4491 Lisp_Object limit, prop, pos;
4492 int found = 0;
4494 pos = make_number (from);
4496 if (!back_p) /* looking forward */
4498 limit = make_number (min (to, ZV));
4499 while (!found && !EQ (pos, limit))
4501 prop = Fget_char_property (pos, Qdisplay, Qnil);
4502 if (!NILP (prop) && display_prop_string_p (prop, string))
4503 found = 1;
4504 else
4505 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil,
4506 limit);
4509 else /* looking back */
4511 limit = make_number (max (to, BEGV));
4512 while (!found && !EQ (pos, limit))
4514 prop = Fget_char_property (pos, Qdisplay, Qnil);
4515 if (!NILP (prop) && display_prop_string_p (prop, string))
4516 found = 1;
4517 else
4518 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
4519 limit);
4523 return found ? XINT (pos) : 0;
4526 /* Determine which buffer position in current buffer STRING comes from.
4527 AROUND_CHARPOS is an approximate position where it could come from.
4528 Value is the buffer position or 0 if it couldn't be determined.
4530 This function is necessary because we don't record buffer positions
4531 in glyphs generated from strings (to keep struct glyph small).
4532 This function may only use code that doesn't eval because it is
4533 called asynchronously from note_mouse_highlight. */
4535 static EMACS_INT
4536 string_buffer_position (Lisp_Object string, EMACS_INT around_charpos)
4538 const int MAX_DISTANCE = 1000;
4539 EMACS_INT found = string_buffer_position_lim (string, around_charpos,
4540 around_charpos + MAX_DISTANCE,
4543 if (!found)
4544 found = string_buffer_position_lim (string, around_charpos,
4545 around_charpos - MAX_DISTANCE, 1);
4546 return found;
4551 /***********************************************************************
4552 `composition' property
4553 ***********************************************************************/
4555 /* Set up iterator IT from `composition' property at its current
4556 position. Called from handle_stop. */
4558 static enum prop_handled
4559 handle_composition_prop (struct it *it)
4561 Lisp_Object prop, string;
4562 EMACS_INT pos, pos_byte, start, end;
4564 if (STRINGP (it->string))
4566 unsigned char *s;
4568 pos = IT_STRING_CHARPOS (*it);
4569 pos_byte = IT_STRING_BYTEPOS (*it);
4570 string = it->string;
4571 s = SDATA (string) + pos_byte;
4572 it->c = STRING_CHAR (s);
4574 else
4576 pos = IT_CHARPOS (*it);
4577 pos_byte = IT_BYTEPOS (*it);
4578 string = Qnil;
4579 it->c = FETCH_CHAR (pos_byte);
4582 /* If there's a valid composition and point is not inside of the
4583 composition (in the case that the composition is from the current
4584 buffer), draw a glyph composed from the composition components. */
4585 if (find_composition (pos, -1, &start, &end, &prop, string)
4586 && COMPOSITION_VALID_P (start, end, prop)
4587 && (STRINGP (it->string) || (PT <= start || PT >= end)))
4589 if (start != pos)
4591 if (STRINGP (it->string))
4592 pos_byte = string_char_to_byte (it->string, start);
4593 else
4594 pos_byte = CHAR_TO_BYTE (start);
4596 it->cmp_it.id = get_composition_id (start, pos_byte, end - start,
4597 prop, string);
4599 if (it->cmp_it.id >= 0)
4601 it->cmp_it.ch = -1;
4602 it->cmp_it.nchars = COMPOSITION_LENGTH (prop);
4603 it->cmp_it.nglyphs = -1;
4607 return HANDLED_NORMALLY;
4612 /***********************************************************************
4613 Overlay strings
4614 ***********************************************************************/
4616 /* The following structure is used to record overlay strings for
4617 later sorting in load_overlay_strings. */
4619 struct overlay_entry
4621 Lisp_Object overlay;
4622 Lisp_Object string;
4623 int priority;
4624 int after_string_p;
4628 /* Set up iterator IT from overlay strings at its current position.
4629 Called from handle_stop. */
4631 static enum prop_handled
4632 handle_overlay_change (struct it *it)
4634 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
4635 return HANDLED_RECOMPUTE_PROPS;
4636 else
4637 return HANDLED_NORMALLY;
4641 /* Set up the next overlay string for delivery by IT, if there is an
4642 overlay string to deliver. Called by set_iterator_to_next when the
4643 end of the current overlay string is reached. If there are more
4644 overlay strings to display, IT->string and
4645 IT->current.overlay_string_index are set appropriately here.
4646 Otherwise IT->string is set to nil. */
4648 static void
4649 next_overlay_string (struct it *it)
4651 ++it->current.overlay_string_index;
4652 if (it->current.overlay_string_index == it->n_overlay_strings)
4654 /* No more overlay strings. Restore IT's settings to what
4655 they were before overlay strings were processed, and
4656 continue to deliver from current_buffer. */
4658 it->ellipsis_p = (it->stack[it->sp - 1].display_ellipsis_p != 0);
4659 pop_it (it);
4660 xassert (it->sp > 0
4661 || (NILP (it->string)
4662 && it->method == GET_FROM_BUFFER
4663 && it->stop_charpos >= BEGV
4664 && it->stop_charpos <= it->end_charpos));
4665 it->current.overlay_string_index = -1;
4666 it->n_overlay_strings = 0;
4667 it->overlay_strings_charpos = -1;
4669 /* If we're at the end of the buffer, record that we have
4670 processed the overlay strings there already, so that
4671 next_element_from_buffer doesn't try it again. */
4672 if (NILP (it->string) && IT_CHARPOS (*it) >= it->end_charpos)
4673 it->overlay_strings_at_end_processed_p = 1;
4675 else
4677 /* There are more overlay strings to process. If
4678 IT->current.overlay_string_index has advanced to a position
4679 where we must load IT->overlay_strings with more strings, do
4680 it. We must load at the IT->overlay_strings_charpos where
4681 IT->n_overlay_strings was originally computed; when invisible
4682 text is present, this might not be IT_CHARPOS (Bug#7016). */
4683 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
4685 if (it->current.overlay_string_index && i == 0)
4686 load_overlay_strings (it, it->overlay_strings_charpos);
4688 /* Initialize IT to deliver display elements from the overlay
4689 string. */
4690 it->string = it->overlay_strings[i];
4691 it->multibyte_p = STRING_MULTIBYTE (it->string);
4692 SET_TEXT_POS (it->current.string_pos, 0, 0);
4693 it->method = GET_FROM_STRING;
4694 it->stop_charpos = 0;
4695 if (it->cmp_it.stop_pos >= 0)
4696 it->cmp_it.stop_pos = 0;
4699 CHECK_IT (it);
4703 /* Compare two overlay_entry structures E1 and E2. Used as a
4704 comparison function for qsort in load_overlay_strings. Overlay
4705 strings for the same position are sorted so that
4707 1. All after-strings come in front of before-strings, except
4708 when they come from the same overlay.
4710 2. Within after-strings, strings are sorted so that overlay strings
4711 from overlays with higher priorities come first.
4713 2. Within before-strings, strings are sorted so that overlay
4714 strings from overlays with higher priorities come last.
4716 Value is analogous to strcmp. */
4719 static int
4720 compare_overlay_entries (const void *e1, const void *e2)
4722 struct overlay_entry *entry1 = (struct overlay_entry *) e1;
4723 struct overlay_entry *entry2 = (struct overlay_entry *) e2;
4724 int result;
4726 if (entry1->after_string_p != entry2->after_string_p)
4728 /* Let after-strings appear in front of before-strings if
4729 they come from different overlays. */
4730 if (EQ (entry1->overlay, entry2->overlay))
4731 result = entry1->after_string_p ? 1 : -1;
4732 else
4733 result = entry1->after_string_p ? -1 : 1;
4735 else if (entry1->after_string_p)
4736 /* After-strings sorted in order of decreasing priority. */
4737 result = entry2->priority - entry1->priority;
4738 else
4739 /* Before-strings sorted in order of increasing priority. */
4740 result = entry1->priority - entry2->priority;
4742 return result;
4746 /* Load the vector IT->overlay_strings with overlay strings from IT's
4747 current buffer position, or from CHARPOS if that is > 0. Set
4748 IT->n_overlays to the total number of overlay strings found.
4750 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
4751 a time. On entry into load_overlay_strings,
4752 IT->current.overlay_string_index gives the number of overlay
4753 strings that have already been loaded by previous calls to this
4754 function.
4756 IT->add_overlay_start contains an additional overlay start
4757 position to consider for taking overlay strings from, if non-zero.
4758 This position comes into play when the overlay has an `invisible'
4759 property, and both before and after-strings. When we've skipped to
4760 the end of the overlay, because of its `invisible' property, we
4761 nevertheless want its before-string to appear.
4762 IT->add_overlay_start will contain the overlay start position
4763 in this case.
4765 Overlay strings are sorted so that after-string strings come in
4766 front of before-string strings. Within before and after-strings,
4767 strings are sorted by overlay priority. See also function
4768 compare_overlay_entries. */
4770 static void
4771 load_overlay_strings (struct it *it, EMACS_INT charpos)
4773 Lisp_Object overlay, window, str, invisible;
4774 struct Lisp_Overlay *ov;
4775 EMACS_INT start, end;
4776 int size = 20;
4777 int n = 0, i, j, invis_p;
4778 struct overlay_entry *entries
4779 = (struct overlay_entry *) alloca (size * sizeof *entries);
4781 if (charpos <= 0)
4782 charpos = IT_CHARPOS (*it);
4784 /* Append the overlay string STRING of overlay OVERLAY to vector
4785 `entries' which has size `size' and currently contains `n'
4786 elements. AFTER_P non-zero means STRING is an after-string of
4787 OVERLAY. */
4788 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
4789 do \
4791 Lisp_Object priority; \
4793 if (n == size) \
4795 int new_size = 2 * size; \
4796 struct overlay_entry *old = entries; \
4797 entries = \
4798 (struct overlay_entry *) alloca (new_size \
4799 * sizeof *entries); \
4800 memcpy (entries, old, size * sizeof *entries); \
4801 size = new_size; \
4804 entries[n].string = (STRING); \
4805 entries[n].overlay = (OVERLAY); \
4806 priority = Foverlay_get ((OVERLAY), Qpriority); \
4807 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
4808 entries[n].after_string_p = (AFTER_P); \
4809 ++n; \
4811 while (0)
4813 /* Process overlay before the overlay center. */
4814 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
4816 XSETMISC (overlay, ov);
4817 xassert (OVERLAYP (overlay));
4818 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4819 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4821 if (end < charpos)
4822 break;
4824 /* Skip this overlay if it doesn't start or end at IT's current
4825 position. */
4826 if (end != charpos && start != charpos)
4827 continue;
4829 /* Skip this overlay if it doesn't apply to IT->w. */
4830 window = Foverlay_get (overlay, Qwindow);
4831 if (WINDOWP (window) && XWINDOW (window) != it->w)
4832 continue;
4834 /* If the text ``under'' the overlay is invisible, both before-
4835 and after-strings from this overlay are visible; start and
4836 end position are indistinguishable. */
4837 invisible = Foverlay_get (overlay, Qinvisible);
4838 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4840 /* If overlay has a non-empty before-string, record it. */
4841 if ((start == charpos || (end == charpos && invis_p))
4842 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4843 && SCHARS (str))
4844 RECORD_OVERLAY_STRING (overlay, str, 0);
4846 /* If overlay has a non-empty after-string, record it. */
4847 if ((end == charpos || (start == charpos && invis_p))
4848 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4849 && SCHARS (str))
4850 RECORD_OVERLAY_STRING (overlay, str, 1);
4853 /* Process overlays after the overlay center. */
4854 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
4856 XSETMISC (overlay, ov);
4857 xassert (OVERLAYP (overlay));
4858 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4859 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4861 if (start > charpos)
4862 break;
4864 /* Skip this overlay if it doesn't start or end at IT's current
4865 position. */
4866 if (end != charpos && start != charpos)
4867 continue;
4869 /* Skip this overlay if it doesn't apply to IT->w. */
4870 window = Foverlay_get (overlay, Qwindow);
4871 if (WINDOWP (window) && XWINDOW (window) != it->w)
4872 continue;
4874 /* If the text ``under'' the overlay is invisible, it has a zero
4875 dimension, and both before- and after-strings apply. */
4876 invisible = Foverlay_get (overlay, Qinvisible);
4877 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4879 /* If overlay has a non-empty before-string, record it. */
4880 if ((start == charpos || (end == charpos && invis_p))
4881 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4882 && SCHARS (str))
4883 RECORD_OVERLAY_STRING (overlay, str, 0);
4885 /* If overlay has a non-empty after-string, record it. */
4886 if ((end == charpos || (start == charpos && invis_p))
4887 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4888 && SCHARS (str))
4889 RECORD_OVERLAY_STRING (overlay, str, 1);
4892 #undef RECORD_OVERLAY_STRING
4894 /* Sort entries. */
4895 if (n > 1)
4896 qsort (entries, n, sizeof *entries, compare_overlay_entries);
4898 /* Record number of overlay strings, and where we computed it. */
4899 it->n_overlay_strings = n;
4900 it->overlay_strings_charpos = charpos;
4902 /* IT->current.overlay_string_index is the number of overlay strings
4903 that have already been consumed by IT. Copy some of the
4904 remaining overlay strings to IT->overlay_strings. */
4905 i = 0;
4906 j = it->current.overlay_string_index;
4907 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
4909 it->overlay_strings[i] = entries[j].string;
4910 it->string_overlays[i++] = entries[j++].overlay;
4913 CHECK_IT (it);
4917 /* Get the first chunk of overlay strings at IT's current buffer
4918 position, or at CHARPOS if that is > 0. Value is non-zero if at
4919 least one overlay string was found. */
4921 static int
4922 get_overlay_strings_1 (struct it *it, EMACS_INT charpos, int compute_stop_p)
4924 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
4925 process. This fills IT->overlay_strings with strings, and sets
4926 IT->n_overlay_strings to the total number of strings to process.
4927 IT->pos.overlay_string_index has to be set temporarily to zero
4928 because load_overlay_strings needs this; it must be set to -1
4929 when no overlay strings are found because a zero value would
4930 indicate a position in the first overlay string. */
4931 it->current.overlay_string_index = 0;
4932 load_overlay_strings (it, charpos);
4934 /* If we found overlay strings, set up IT to deliver display
4935 elements from the first one. Otherwise set up IT to deliver
4936 from current_buffer. */
4937 if (it->n_overlay_strings)
4939 /* Make sure we know settings in current_buffer, so that we can
4940 restore meaningful values when we're done with the overlay
4941 strings. */
4942 if (compute_stop_p)
4943 compute_stop_pos (it);
4944 xassert (it->face_id >= 0);
4946 /* Save IT's settings. They are restored after all overlay
4947 strings have been processed. */
4948 xassert (!compute_stop_p || it->sp == 0);
4950 /* When called from handle_stop, there might be an empty display
4951 string loaded. In that case, don't bother saving it. */
4952 if (!STRINGP (it->string) || SCHARS (it->string))
4953 push_it (it, NULL);
4955 /* Set up IT to deliver display elements from the first overlay
4956 string. */
4957 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
4958 it->string = it->overlay_strings[0];
4959 it->from_overlay = Qnil;
4960 it->stop_charpos = 0;
4961 xassert (STRINGP (it->string));
4962 it->end_charpos = SCHARS (it->string);
4963 it->multibyte_p = STRING_MULTIBYTE (it->string);
4964 it->method = GET_FROM_STRING;
4965 return 1;
4968 it->current.overlay_string_index = -1;
4969 return 0;
4972 static int
4973 get_overlay_strings (struct it *it, EMACS_INT charpos)
4975 it->string = Qnil;
4976 it->method = GET_FROM_BUFFER;
4978 (void) get_overlay_strings_1 (it, charpos, 1);
4980 CHECK_IT (it);
4982 /* Value is non-zero if we found at least one overlay string. */
4983 return STRINGP (it->string);
4988 /***********************************************************************
4989 Saving and restoring state
4990 ***********************************************************************/
4992 /* Save current settings of IT on IT->stack. Called, for example,
4993 before setting up IT for an overlay string, to be able to restore
4994 IT's settings to what they were after the overlay string has been
4995 processed. If POSITION is non-NULL, it is the position to save on
4996 the stack instead of IT->position. */
4998 static void
4999 push_it (struct it *it, struct text_pos *position)
5001 struct iterator_stack_entry *p;
5003 xassert (it->sp < IT_STACK_SIZE);
5004 p = it->stack + it->sp;
5006 p->stop_charpos = it->stop_charpos;
5007 p->prev_stop = it->prev_stop;
5008 p->base_level_stop = it->base_level_stop;
5009 p->cmp_it = it->cmp_it;
5010 xassert (it->face_id >= 0);
5011 p->face_id = it->face_id;
5012 p->string = it->string;
5013 p->method = it->method;
5014 p->from_overlay = it->from_overlay;
5015 switch (p->method)
5017 case GET_FROM_IMAGE:
5018 p->u.image.object = it->object;
5019 p->u.image.image_id = it->image_id;
5020 p->u.image.slice = it->slice;
5021 break;
5022 case GET_FROM_STRETCH:
5023 p->u.stretch.object = it->object;
5024 break;
5026 p->position = position ? *position : it->position;
5027 p->current = it->current;
5028 p->end_charpos = it->end_charpos;
5029 p->string_nchars = it->string_nchars;
5030 p->area = it->area;
5031 p->multibyte_p = it->multibyte_p;
5032 p->avoid_cursor_p = it->avoid_cursor_p;
5033 p->space_width = it->space_width;
5034 p->font_height = it->font_height;
5035 p->voffset = it->voffset;
5036 p->string_from_display_prop_p = it->string_from_display_prop_p;
5037 p->display_ellipsis_p = 0;
5038 p->line_wrap = it->line_wrap;
5039 ++it->sp;
5042 static void
5043 iterate_out_of_display_property (struct it *it)
5045 /* Maybe initialize paragraph direction. If we are at the beginning
5046 of a new paragraph, next_element_from_buffer may not have a
5047 chance to do that. */
5048 if (it->bidi_it.first_elt && it->bidi_it.charpos < ZV)
5049 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
5050 /* prev_stop can be zero, so check against BEGV as well. */
5051 while (it->bidi_it.charpos >= BEGV
5052 && it->prev_stop <= it->bidi_it.charpos
5053 && it->bidi_it.charpos < CHARPOS (it->position))
5054 bidi_move_to_visually_next (&it->bidi_it);
5055 /* Record the stop_pos we just crossed, for when we cross it
5056 back, maybe. */
5057 if (it->bidi_it.charpos > CHARPOS (it->position))
5058 it->prev_stop = CHARPOS (it->position);
5059 /* If we ended up not where pop_it put us, resync IT's
5060 positional members with the bidi iterator. */
5061 if (it->bidi_it.charpos != CHARPOS (it->position))
5063 SET_TEXT_POS (it->position,
5064 it->bidi_it.charpos, it->bidi_it.bytepos);
5065 it->current.pos = it->position;
5069 /* Restore IT's settings from IT->stack. Called, for example, when no
5070 more overlay strings must be processed, and we return to delivering
5071 display elements from a buffer, or when the end of a string from a
5072 `display' property is reached and we return to delivering display
5073 elements from an overlay string, or from a buffer. */
5075 static void
5076 pop_it (struct it *it)
5078 struct iterator_stack_entry *p;
5080 xassert (it->sp > 0);
5081 --it->sp;
5082 p = it->stack + it->sp;
5083 it->stop_charpos = p->stop_charpos;
5084 it->prev_stop = p->prev_stop;
5085 it->base_level_stop = p->base_level_stop;
5086 it->cmp_it = p->cmp_it;
5087 it->face_id = p->face_id;
5088 it->current = p->current;
5089 it->position = p->position;
5090 it->string = p->string;
5091 it->from_overlay = p->from_overlay;
5092 if (NILP (it->string))
5093 SET_TEXT_POS (it->current.string_pos, -1, -1);
5094 it->method = p->method;
5095 switch (it->method)
5097 case GET_FROM_IMAGE:
5098 it->image_id = p->u.image.image_id;
5099 it->object = p->u.image.object;
5100 it->slice = p->u.image.slice;
5101 break;
5102 case GET_FROM_STRETCH:
5103 it->object = p->u.comp.object;
5104 break;
5105 case GET_FROM_BUFFER:
5106 it->object = it->w->buffer;
5107 if (it->bidi_p)
5109 /* Bidi-iterate until we get out of the portion of text, if
5110 any, covered by a `display' text property or an overlay
5111 with `display' property. (We cannot just jump there,
5112 because the internal coherency of the bidi iterator state
5113 can not be preserved across such jumps.) We also must
5114 determine the paragraph base direction if the overlay we
5115 just processed is at the beginning of a new
5116 paragraph. */
5117 iterate_out_of_display_property (it);
5119 break;
5120 case GET_FROM_STRING:
5121 it->object = it->string;
5122 break;
5123 case GET_FROM_DISPLAY_VECTOR:
5124 if (it->s)
5125 it->method = GET_FROM_C_STRING;
5126 else if (STRINGP (it->string))
5127 it->method = GET_FROM_STRING;
5128 else
5130 it->method = GET_FROM_BUFFER;
5131 it->object = it->w->buffer;
5134 it->end_charpos = p->end_charpos;
5135 it->string_nchars = p->string_nchars;
5136 it->area = p->area;
5137 it->multibyte_p = p->multibyte_p;
5138 it->avoid_cursor_p = p->avoid_cursor_p;
5139 it->space_width = p->space_width;
5140 it->font_height = p->font_height;
5141 it->voffset = p->voffset;
5142 it->string_from_display_prop_p = p->string_from_display_prop_p;
5143 it->line_wrap = p->line_wrap;
5148 /***********************************************************************
5149 Moving over lines
5150 ***********************************************************************/
5152 /* Set IT's current position to the previous line start. */
5154 static void
5155 back_to_previous_line_start (struct it *it)
5157 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
5158 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
5162 /* Move IT to the next line start.
5164 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
5165 we skipped over part of the text (as opposed to moving the iterator
5166 continuously over the text). Otherwise, don't change the value
5167 of *SKIPPED_P.
5169 Newlines may come from buffer text, overlay strings, or strings
5170 displayed via the `display' property. That's the reason we can't
5171 simply use find_next_newline_no_quit.
5173 Note that this function may not skip over invisible text that is so
5174 because of text properties and immediately follows a newline. If
5175 it would, function reseat_at_next_visible_line_start, when called
5176 from set_iterator_to_next, would effectively make invisible
5177 characters following a newline part of the wrong glyph row, which
5178 leads to wrong cursor motion. */
5180 static int
5181 forward_to_next_line_start (struct it *it, int *skipped_p)
5183 int old_selective, newline_found_p, n;
5184 const int MAX_NEWLINE_DISTANCE = 500;
5186 /* If already on a newline, just consume it to avoid unintended
5187 skipping over invisible text below. */
5188 if (it->what == IT_CHARACTER
5189 && it->c == '\n'
5190 && CHARPOS (it->position) == IT_CHARPOS (*it))
5192 set_iterator_to_next (it, 0);
5193 it->c = 0;
5194 return 1;
5197 /* Don't handle selective display in the following. It's (a)
5198 unnecessary because it's done by the caller, and (b) leads to an
5199 infinite recursion because next_element_from_ellipsis indirectly
5200 calls this function. */
5201 old_selective = it->selective;
5202 it->selective = 0;
5204 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
5205 from buffer text. */
5206 for (n = newline_found_p = 0;
5207 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
5208 n += STRINGP (it->string) ? 0 : 1)
5210 if (!get_next_display_element (it))
5211 return 0;
5212 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
5213 set_iterator_to_next (it, 0);
5216 /* If we didn't find a newline near enough, see if we can use a
5217 short-cut. */
5218 if (!newline_found_p)
5220 EMACS_INT start = IT_CHARPOS (*it);
5221 EMACS_INT limit = find_next_newline_no_quit (start, 1);
5222 Lisp_Object pos;
5224 xassert (!STRINGP (it->string));
5226 /* If there isn't any `display' property in sight, and no
5227 overlays, we can just use the position of the newline in
5228 buffer text. */
5229 if (it->stop_charpos >= limit
5230 || ((pos = Fnext_single_property_change (make_number (start),
5231 Qdisplay,
5232 Qnil, make_number (limit)),
5233 NILP (pos))
5234 && next_overlay_change (start) == ZV))
5236 IT_CHARPOS (*it) = limit;
5237 IT_BYTEPOS (*it) = CHAR_TO_BYTE (limit);
5238 *skipped_p = newline_found_p = 1;
5240 else
5242 while (get_next_display_element (it)
5243 && !newline_found_p)
5245 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
5246 set_iterator_to_next (it, 0);
5251 it->selective = old_selective;
5252 return newline_found_p;
5256 /* Set IT's current position to the previous visible line start. Skip
5257 invisible text that is so either due to text properties or due to
5258 selective display. Caution: this does not change IT->current_x and
5259 IT->hpos. */
5261 static void
5262 back_to_previous_visible_line_start (struct it *it)
5264 while (IT_CHARPOS (*it) > BEGV)
5266 back_to_previous_line_start (it);
5268 if (IT_CHARPOS (*it) <= BEGV)
5269 break;
5271 /* If selective > 0, then lines indented more than its value are
5272 invisible. */
5273 if (it->selective > 0
5274 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
5275 (double) it->selective)) /* iftc */
5276 continue;
5278 /* Check the newline before point for invisibility. */
5280 Lisp_Object prop;
5281 prop = Fget_char_property (make_number (IT_CHARPOS (*it) - 1),
5282 Qinvisible, it->window);
5283 if (TEXT_PROP_MEANS_INVISIBLE (prop))
5284 continue;
5287 if (IT_CHARPOS (*it) <= BEGV)
5288 break;
5291 struct it it2;
5292 EMACS_INT pos;
5293 EMACS_INT beg, end;
5294 Lisp_Object val, overlay;
5296 /* If newline is part of a composition, continue from start of composition */
5297 if (find_composition (IT_CHARPOS (*it), -1, &beg, &end, &val, Qnil)
5298 && beg < IT_CHARPOS (*it))
5299 goto replaced;
5301 /* If newline is replaced by a display property, find start of overlay
5302 or interval and continue search from that point. */
5303 it2 = *it;
5304 pos = --IT_CHARPOS (it2);
5305 --IT_BYTEPOS (it2);
5306 it2.sp = 0;
5307 it2.string_from_display_prop_p = 0;
5308 if (handle_display_prop (&it2) == HANDLED_RETURN
5309 && !NILP (val = get_char_property_and_overlay
5310 (make_number (pos), Qdisplay, Qnil, &overlay))
5311 && (OVERLAYP (overlay)
5312 ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
5313 : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
5314 goto replaced;
5316 /* Newline is not replaced by anything -- so we are done. */
5317 break;
5319 replaced:
5320 if (beg < BEGV)
5321 beg = BEGV;
5322 IT_CHARPOS (*it) = beg;
5323 IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg);
5327 it->continuation_lines_width = 0;
5329 xassert (IT_CHARPOS (*it) >= BEGV);
5330 xassert (IT_CHARPOS (*it) == BEGV
5331 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
5332 CHECK_IT (it);
5336 /* Reseat iterator IT at the previous visible line start. Skip
5337 invisible text that is so either due to text properties or due to
5338 selective display. At the end, update IT's overlay information,
5339 face information etc. */
5341 void
5342 reseat_at_previous_visible_line_start (struct it *it)
5344 back_to_previous_visible_line_start (it);
5345 reseat (it, it->current.pos, 1);
5346 CHECK_IT (it);
5350 /* Reseat iterator IT on the next visible line start in the current
5351 buffer. ON_NEWLINE_P non-zero means position IT on the newline
5352 preceding the line start. Skip over invisible text that is so
5353 because of selective display. Compute faces, overlays etc at the
5354 new position. Note that this function does not skip over text that
5355 is invisible because of text properties. */
5357 static void
5358 reseat_at_next_visible_line_start (struct it *it, int on_newline_p)
5360 int newline_found_p, skipped_p = 0;
5362 newline_found_p = forward_to_next_line_start (it, &skipped_p);
5364 /* Skip over lines that are invisible because they are indented
5365 more than the value of IT->selective. */
5366 if (it->selective > 0)
5367 while (IT_CHARPOS (*it) < ZV
5368 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
5369 (double) it->selective)) /* iftc */
5371 xassert (IT_BYTEPOS (*it) == BEGV
5372 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
5373 newline_found_p = forward_to_next_line_start (it, &skipped_p);
5376 /* Position on the newline if that's what's requested. */
5377 if (on_newline_p && newline_found_p)
5379 if (STRINGP (it->string))
5381 if (IT_STRING_CHARPOS (*it) > 0)
5383 --IT_STRING_CHARPOS (*it);
5384 --IT_STRING_BYTEPOS (*it);
5387 else if (IT_CHARPOS (*it) > BEGV)
5389 --IT_CHARPOS (*it);
5390 --IT_BYTEPOS (*it);
5391 reseat (it, it->current.pos, 0);
5394 else if (skipped_p)
5395 reseat (it, it->current.pos, 0);
5397 CHECK_IT (it);
5402 /***********************************************************************
5403 Changing an iterator's position
5404 ***********************************************************************/
5406 /* Change IT's current position to POS in current_buffer. If FORCE_P
5407 is non-zero, always check for text properties at the new position.
5408 Otherwise, text properties are only looked up if POS >=
5409 IT->check_charpos of a property. */
5411 static void
5412 reseat (struct it *it, struct text_pos pos, int force_p)
5414 EMACS_INT original_pos = IT_CHARPOS (*it);
5416 reseat_1 (it, pos, 0);
5418 /* Determine where to check text properties. Avoid doing it
5419 where possible because text property lookup is very expensive. */
5420 if (force_p
5421 || CHARPOS (pos) > it->stop_charpos
5422 || CHARPOS (pos) < original_pos)
5424 if (it->bidi_p)
5426 /* For bidi iteration, we need to prime prev_stop and
5427 base_level_stop with our best estimations. */
5428 if (CHARPOS (pos) < it->prev_stop)
5430 handle_stop_backwards (it, BEGV);
5431 if (CHARPOS (pos) < it->base_level_stop)
5432 it->base_level_stop = 0;
5434 else if (CHARPOS (pos) > it->stop_charpos
5435 && it->stop_charpos >= BEGV)
5436 handle_stop_backwards (it, it->stop_charpos);
5437 else /* force_p */
5438 handle_stop (it);
5440 else
5442 handle_stop (it);
5443 it->prev_stop = it->base_level_stop = 0;
5448 CHECK_IT (it);
5452 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
5453 IT->stop_pos to POS, also. */
5455 static void
5456 reseat_1 (struct it *it, struct text_pos pos, int set_stop_p)
5458 /* Don't call this function when scanning a C string. */
5459 xassert (it->s == NULL);
5461 /* POS must be a reasonable value. */
5462 xassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
5464 it->current.pos = it->position = pos;
5465 it->end_charpos = ZV;
5466 it->dpvec = NULL;
5467 it->current.dpvec_index = -1;
5468 it->current.overlay_string_index = -1;
5469 IT_STRING_CHARPOS (*it) = -1;
5470 IT_STRING_BYTEPOS (*it) = -1;
5471 it->string = Qnil;
5472 it->string_from_display_prop_p = 0;
5473 it->method = GET_FROM_BUFFER;
5474 it->object = it->w->buffer;
5475 it->area = TEXT_AREA;
5476 it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
5477 it->sp = 0;
5478 it->string_from_display_prop_p = 0;
5479 it->face_before_selective_p = 0;
5480 if (it->bidi_p)
5482 it->bidi_it.first_elt = 1;
5483 it->bidi_it.paragraph_dir = NEUTRAL_DIR;
5484 it->bidi_it.disp_pos = -1;
5487 if (set_stop_p)
5489 it->stop_charpos = CHARPOS (pos);
5490 it->base_level_stop = CHARPOS (pos);
5495 /* Set up IT for displaying a string, starting at CHARPOS in window W.
5496 If S is non-null, it is a C string to iterate over. Otherwise,
5497 STRING gives a Lisp string to iterate over.
5499 If PRECISION > 0, don't return more then PRECISION number of
5500 characters from the string.
5502 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
5503 characters have been returned. FIELD_WIDTH < 0 means an infinite
5504 field width.
5506 MULTIBYTE = 0 means disable processing of multibyte characters,
5507 MULTIBYTE > 0 means enable it,
5508 MULTIBYTE < 0 means use IT->multibyte_p.
5510 IT must be initialized via a prior call to init_iterator before
5511 calling this function. */
5513 static void
5514 reseat_to_string (struct it *it, const char *s, Lisp_Object string,
5515 EMACS_INT charpos, EMACS_INT precision, int field_width,
5516 int multibyte)
5518 /* No region in strings. */
5519 it->region_beg_charpos = it->region_end_charpos = -1;
5521 /* No text property checks performed by default, but see below. */
5522 it->stop_charpos = -1;
5524 /* Set iterator position and end position. */
5525 memset (&it->current, 0, sizeof it->current);
5526 it->current.overlay_string_index = -1;
5527 it->current.dpvec_index = -1;
5528 xassert (charpos >= 0);
5530 /* If STRING is specified, use its multibyteness, otherwise use the
5531 setting of MULTIBYTE, if specified. */
5532 if (multibyte >= 0)
5533 it->multibyte_p = multibyte > 0;
5535 if (s == NULL)
5537 xassert (STRINGP (string));
5538 it->string = string;
5539 it->s = NULL;
5540 it->end_charpos = it->string_nchars = SCHARS (string);
5541 it->method = GET_FROM_STRING;
5542 it->current.string_pos = string_pos (charpos, string);
5544 else
5546 it->s = (const unsigned char *) s;
5547 it->string = Qnil;
5549 /* Note that we use IT->current.pos, not it->current.string_pos,
5550 for displaying C strings. */
5551 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
5552 if (it->multibyte_p)
5554 it->current.pos = c_string_pos (charpos, s, 1);
5555 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
5557 else
5559 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
5560 it->end_charpos = it->string_nchars = strlen (s);
5563 it->method = GET_FROM_C_STRING;
5566 /* PRECISION > 0 means don't return more than PRECISION characters
5567 from the string. */
5568 if (precision > 0 && it->end_charpos - charpos > precision)
5569 it->end_charpos = it->string_nchars = charpos + precision;
5571 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
5572 characters have been returned. FIELD_WIDTH == 0 means don't pad,
5573 FIELD_WIDTH < 0 means infinite field width. This is useful for
5574 padding with `-' at the end of a mode line. */
5575 if (field_width < 0)
5576 field_width = INFINITY;
5577 if (field_width > it->end_charpos - charpos)
5578 it->end_charpos = charpos + field_width;
5580 /* Use the standard display table for displaying strings. */
5581 if (DISP_TABLE_P (Vstandard_display_table))
5582 it->dp = XCHAR_TABLE (Vstandard_display_table);
5584 it->stop_charpos = charpos;
5585 if (s == NULL && it->multibyte_p)
5587 EMACS_INT endpos = SCHARS (it->string);
5588 if (endpos > it->end_charpos)
5589 endpos = it->end_charpos;
5590 composition_compute_stop_pos (&it->cmp_it, charpos, -1, endpos,
5591 it->string);
5593 CHECK_IT (it);
5598 /***********************************************************************
5599 Iteration
5600 ***********************************************************************/
5602 /* Map enum it_method value to corresponding next_element_from_* function. */
5604 static int (* get_next_element[NUM_IT_METHODS]) (struct it *it) =
5606 next_element_from_buffer,
5607 next_element_from_display_vector,
5608 next_element_from_string,
5609 next_element_from_c_string,
5610 next_element_from_image,
5611 next_element_from_stretch
5614 #define GET_NEXT_DISPLAY_ELEMENT(it) (*get_next_element[(it)->method]) (it)
5617 /* Return 1 iff a character at CHARPOS (and BYTEPOS) is composed
5618 (possibly with the following characters). */
5620 #define CHAR_COMPOSED_P(IT,CHARPOS,BYTEPOS,END_CHARPOS) \
5621 ((IT)->cmp_it.id >= 0 \
5622 || ((IT)->cmp_it.stop_pos == (CHARPOS) \
5623 && composition_reseat_it (&(IT)->cmp_it, CHARPOS, BYTEPOS, \
5624 END_CHARPOS, (IT)->w, \
5625 FACE_FROM_ID ((IT)->f, (IT)->face_id), \
5626 (IT)->string)))
5629 /* Lookup the char-table Vglyphless_char_display for character C (-1
5630 if we want information for no-font case), and return the display
5631 method symbol. By side-effect, update it->what and
5632 it->glyphless_method. This function is called from
5633 get_next_display_element for each character element, and from
5634 x_produce_glyphs when no suitable font was found. */
5636 Lisp_Object
5637 lookup_glyphless_char_display (int c, struct it *it)
5639 Lisp_Object glyphless_method = Qnil;
5641 if (CHAR_TABLE_P (Vglyphless_char_display)
5642 && CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display)) >= 1)
5644 if (c >= 0)
5646 glyphless_method = CHAR_TABLE_REF (Vglyphless_char_display, c);
5647 if (CONSP (glyphless_method))
5648 glyphless_method = FRAME_WINDOW_P (it->f)
5649 ? XCAR (glyphless_method)
5650 : XCDR (glyphless_method);
5652 else
5653 glyphless_method = XCHAR_TABLE (Vglyphless_char_display)->extras[0];
5656 retry:
5657 if (NILP (glyphless_method))
5659 if (c >= 0)
5660 /* The default is to display the character by a proper font. */
5661 return Qnil;
5662 /* The default for the no-font case is to display an empty box. */
5663 glyphless_method = Qempty_box;
5665 if (EQ (glyphless_method, Qzero_width))
5667 if (c >= 0)
5668 return glyphless_method;
5669 /* This method can't be used for the no-font case. */
5670 glyphless_method = Qempty_box;
5672 if (EQ (glyphless_method, Qthin_space))
5673 it->glyphless_method = GLYPHLESS_DISPLAY_THIN_SPACE;
5674 else if (EQ (glyphless_method, Qempty_box))
5675 it->glyphless_method = GLYPHLESS_DISPLAY_EMPTY_BOX;
5676 else if (EQ (glyphless_method, Qhex_code))
5677 it->glyphless_method = GLYPHLESS_DISPLAY_HEX_CODE;
5678 else if (STRINGP (glyphless_method))
5679 it->glyphless_method = GLYPHLESS_DISPLAY_ACRONYM;
5680 else
5682 /* Invalid value. We use the default method. */
5683 glyphless_method = Qnil;
5684 goto retry;
5686 it->what = IT_GLYPHLESS;
5687 return glyphless_method;
5690 /* Load IT's display element fields with information about the next
5691 display element from the current position of IT. Value is zero if
5692 end of buffer (or C string) is reached. */
5694 static struct frame *last_escape_glyph_frame = NULL;
5695 static unsigned last_escape_glyph_face_id = (1 << FACE_ID_BITS);
5696 static int last_escape_glyph_merged_face_id = 0;
5698 struct frame *last_glyphless_glyph_frame = NULL;
5699 unsigned last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
5700 int last_glyphless_glyph_merged_face_id = 0;
5702 static int
5703 get_next_display_element (struct it *it)
5705 /* Non-zero means that we found a display element. Zero means that
5706 we hit the end of what we iterate over. Performance note: the
5707 function pointer `method' used here turns out to be faster than
5708 using a sequence of if-statements. */
5709 int success_p;
5711 get_next:
5712 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
5714 if (it->what == IT_CHARACTER)
5716 /* UAX#9, L4: "A character is depicted by a mirrored glyph if
5717 and only if (a) the resolved directionality of that character
5718 is R..." */
5719 /* FIXME: Do we need an exception for characters from display
5720 tables? */
5721 if (it->bidi_p && it->bidi_it.type == STRONG_R)
5722 it->c = bidi_mirror_char (it->c);
5723 /* Map via display table or translate control characters.
5724 IT->c, IT->len etc. have been set to the next character by
5725 the function call above. If we have a display table, and it
5726 contains an entry for IT->c, translate it. Don't do this if
5727 IT->c itself comes from a display table, otherwise we could
5728 end up in an infinite recursion. (An alternative could be to
5729 count the recursion depth of this function and signal an
5730 error when a certain maximum depth is reached.) Is it worth
5731 it? */
5732 if (success_p && it->dpvec == NULL)
5734 Lisp_Object dv;
5735 struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte);
5736 enum { char_is_other = 0, char_is_nbsp, char_is_soft_hyphen }
5737 nbsp_or_shy = char_is_other;
5738 int c = it->c; /* This is the character to display. */
5740 if (! it->multibyte_p && ! ASCII_CHAR_P (c))
5742 xassert (SINGLE_BYTE_CHAR_P (c));
5743 if (unibyte_display_via_language_environment)
5745 c = DECODE_CHAR (unibyte, c);
5746 if (c < 0)
5747 c = BYTE8_TO_CHAR (it->c);
5749 else
5750 c = BYTE8_TO_CHAR (it->c);
5753 if (it->dp
5754 && (dv = DISP_CHAR_VECTOR (it->dp, c),
5755 VECTORP (dv)))
5757 struct Lisp_Vector *v = XVECTOR (dv);
5759 /* Return the first character from the display table
5760 entry, if not empty. If empty, don't display the
5761 current character. */
5762 if (v->header.size)
5764 it->dpvec_char_len = it->len;
5765 it->dpvec = v->contents;
5766 it->dpend = v->contents + v->header.size;
5767 it->current.dpvec_index = 0;
5768 it->dpvec_face_id = -1;
5769 it->saved_face_id = it->face_id;
5770 it->method = GET_FROM_DISPLAY_VECTOR;
5771 it->ellipsis_p = 0;
5773 else
5775 set_iterator_to_next (it, 0);
5777 goto get_next;
5780 if (! NILP (lookup_glyphless_char_display (c, it)))
5782 if (it->what == IT_GLYPHLESS)
5783 goto done;
5784 /* Don't display this character. */
5785 set_iterator_to_next (it, 0);
5786 goto get_next;
5789 if (! ASCII_CHAR_P (c) && ! NILP (Vnobreak_char_display))
5790 nbsp_or_shy = (c == 0xA0 ? char_is_nbsp
5791 : c == 0xAD ? char_is_soft_hyphen
5792 : char_is_other);
5794 /* Translate control characters into `\003' or `^C' form.
5795 Control characters coming from a display table entry are
5796 currently not translated because we use IT->dpvec to hold
5797 the translation. This could easily be changed but I
5798 don't believe that it is worth doing.
5800 NBSP and SOFT-HYPEN are property translated too.
5802 Non-printable characters and raw-byte characters are also
5803 translated to octal form. */
5804 if (((c < ' ' || c == 127) /* ASCII control chars */
5805 ? (it->area != TEXT_AREA
5806 /* In mode line, treat \n, \t like other crl chars. */
5807 || (c != '\t'
5808 && it->glyph_row
5809 && (it->glyph_row->mode_line_p || it->avoid_cursor_p))
5810 || (c != '\n' && c != '\t'))
5811 : (nbsp_or_shy
5812 || CHAR_BYTE8_P (c)
5813 || ! CHAR_PRINTABLE_P (c))))
5815 /* C is a control character, NBSP, SOFT-HYPEN, raw-byte,
5816 or a non-printable character which must be displayed
5817 either as '\003' or as `^C' where the '\\' and '^'
5818 can be defined in the display table. Fill
5819 IT->ctl_chars with glyphs for what we have to
5820 display. Then, set IT->dpvec to these glyphs. */
5821 Lisp_Object gc;
5822 int ctl_len;
5823 int face_id, lface_id = 0 ;
5824 int escape_glyph;
5826 /* Handle control characters with ^. */
5828 if (ASCII_CHAR_P (c) && it->ctl_arrow_p)
5830 int g;
5832 g = '^'; /* default glyph for Control */
5833 /* Set IT->ctl_chars[0] to the glyph for `^'. */
5834 if (it->dp
5835 && (gc = DISP_CTRL_GLYPH (it->dp), GLYPH_CODE_P (gc))
5836 && GLYPH_CODE_CHAR_VALID_P (gc))
5838 g = GLYPH_CODE_CHAR (gc);
5839 lface_id = GLYPH_CODE_FACE (gc);
5841 if (lface_id)
5843 face_id = merge_faces (it->f, Qt, lface_id, it->face_id);
5845 else if (it->f == last_escape_glyph_frame
5846 && it->face_id == last_escape_glyph_face_id)
5848 face_id = last_escape_glyph_merged_face_id;
5850 else
5852 /* Merge the escape-glyph face into the current face. */
5853 face_id = merge_faces (it->f, Qescape_glyph, 0,
5854 it->face_id);
5855 last_escape_glyph_frame = it->f;
5856 last_escape_glyph_face_id = it->face_id;
5857 last_escape_glyph_merged_face_id = face_id;
5860 XSETINT (it->ctl_chars[0], g);
5861 XSETINT (it->ctl_chars[1], c ^ 0100);
5862 ctl_len = 2;
5863 goto display_control;
5866 /* Handle non-break space in the mode where it only gets
5867 highlighting. */
5869 if (EQ (Vnobreak_char_display, Qt)
5870 && nbsp_or_shy == char_is_nbsp)
5872 /* Merge the no-break-space face into the current face. */
5873 face_id = merge_faces (it->f, Qnobreak_space, 0,
5874 it->face_id);
5876 c = ' ';
5877 XSETINT (it->ctl_chars[0], ' ');
5878 ctl_len = 1;
5879 goto display_control;
5882 /* Handle sequences that start with the "escape glyph". */
5884 /* the default escape glyph is \. */
5885 escape_glyph = '\\';
5887 if (it->dp
5888 && (gc = DISP_ESCAPE_GLYPH (it->dp), GLYPH_CODE_P (gc))
5889 && GLYPH_CODE_CHAR_VALID_P (gc))
5891 escape_glyph = GLYPH_CODE_CHAR (gc);
5892 lface_id = GLYPH_CODE_FACE (gc);
5894 if (lface_id)
5896 /* The display table specified a face.
5897 Merge it into face_id and also into escape_glyph. */
5898 face_id = merge_faces (it->f, Qt, lface_id,
5899 it->face_id);
5901 else if (it->f == last_escape_glyph_frame
5902 && it->face_id == last_escape_glyph_face_id)
5904 face_id = last_escape_glyph_merged_face_id;
5906 else
5908 /* Merge the escape-glyph face into the current face. */
5909 face_id = merge_faces (it->f, Qescape_glyph, 0,
5910 it->face_id);
5911 last_escape_glyph_frame = it->f;
5912 last_escape_glyph_face_id = it->face_id;
5913 last_escape_glyph_merged_face_id = face_id;
5916 /* Handle soft hyphens in the mode where they only get
5917 highlighting. */
5919 if (EQ (Vnobreak_char_display, Qt)
5920 && nbsp_or_shy == char_is_soft_hyphen)
5922 XSETINT (it->ctl_chars[0], '-');
5923 ctl_len = 1;
5924 goto display_control;
5927 /* Handle non-break space and soft hyphen
5928 with the escape glyph. */
5930 if (nbsp_or_shy)
5932 XSETINT (it->ctl_chars[0], escape_glyph);
5933 c = (nbsp_or_shy == char_is_nbsp ? ' ' : '-');
5934 XSETINT (it->ctl_chars[1], c);
5935 ctl_len = 2;
5936 goto display_control;
5940 char str[10];
5941 int len, i;
5943 if (CHAR_BYTE8_P (c))
5944 /* Display \200 instead of \17777600. */
5945 c = CHAR_TO_BYTE8 (c);
5946 len = sprintf (str, "%03o", c);
5948 XSETINT (it->ctl_chars[0], escape_glyph);
5949 for (i = 0; i < len; i++)
5950 XSETINT (it->ctl_chars[i + 1], str[i]);
5951 ctl_len = len + 1;
5954 display_control:
5955 /* Set up IT->dpvec and return first character from it. */
5956 it->dpvec_char_len = it->len;
5957 it->dpvec = it->ctl_chars;
5958 it->dpend = it->dpvec + ctl_len;
5959 it->current.dpvec_index = 0;
5960 it->dpvec_face_id = face_id;
5961 it->saved_face_id = it->face_id;
5962 it->method = GET_FROM_DISPLAY_VECTOR;
5963 it->ellipsis_p = 0;
5964 goto get_next;
5966 it->char_to_display = c;
5968 else if (success_p)
5970 it->char_to_display = it->c;
5974 /* Adjust face id for a multibyte character. There are no multibyte
5975 character in unibyte text. */
5976 if ((it->what == IT_CHARACTER || it->what == IT_COMPOSITION)
5977 && it->multibyte_p
5978 && success_p
5979 && FRAME_WINDOW_P (it->f))
5981 struct face *face = FACE_FROM_ID (it->f, it->face_id);
5983 if (it->what == IT_COMPOSITION && it->cmp_it.ch >= 0)
5985 /* Automatic composition with glyph-string. */
5986 Lisp_Object gstring = composition_gstring_from_id (it->cmp_it.id);
5988 it->face_id = face_for_font (it->f, LGSTRING_FONT (gstring), face);
5990 else
5992 EMACS_INT pos = (it->s ? -1
5993 : STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
5994 : IT_CHARPOS (*it));
5996 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display, pos,
5997 it->string);
6001 done:
6002 /* Is this character the last one of a run of characters with
6003 box? If yes, set IT->end_of_box_run_p to 1. */
6004 if (it->face_box_p
6005 && it->s == NULL)
6007 if (it->method == GET_FROM_STRING && it->sp)
6009 int face_id = underlying_face_id (it);
6010 struct face *face = FACE_FROM_ID (it->f, face_id);
6012 if (face)
6014 if (face->box == FACE_NO_BOX)
6016 /* If the box comes from face properties in a
6017 display string, check faces in that string. */
6018 int string_face_id = face_after_it_pos (it);
6019 it->end_of_box_run_p
6020 = (FACE_FROM_ID (it->f, string_face_id)->box
6021 == FACE_NO_BOX);
6023 /* Otherwise, the box comes from the underlying face.
6024 If this is the last string character displayed, check
6025 the next buffer location. */
6026 else if ((IT_STRING_CHARPOS (*it) >= SCHARS (it->string) - 1)
6027 && (it->current.overlay_string_index
6028 == it->n_overlay_strings - 1))
6030 EMACS_INT ignore;
6031 int next_face_id;
6032 struct text_pos pos = it->current.pos;
6033 INC_TEXT_POS (pos, it->multibyte_p);
6035 next_face_id = face_at_buffer_position
6036 (it->w, CHARPOS (pos), it->region_beg_charpos,
6037 it->region_end_charpos, &ignore,
6038 (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT), 0,
6039 -1);
6040 it->end_of_box_run_p
6041 = (FACE_FROM_ID (it->f, next_face_id)->box
6042 == FACE_NO_BOX);
6046 else
6048 int face_id = face_after_it_pos (it);
6049 it->end_of_box_run_p
6050 = (face_id != it->face_id
6051 && FACE_FROM_ID (it->f, face_id)->box == FACE_NO_BOX);
6055 /* Value is 0 if end of buffer or string reached. */
6056 return success_p;
6060 /* Move IT to the next display element.
6062 RESEAT_P non-zero means if called on a newline in buffer text,
6063 skip to the next visible line start.
6065 Functions get_next_display_element and set_iterator_to_next are
6066 separate because I find this arrangement easier to handle than a
6067 get_next_display_element function that also increments IT's
6068 position. The way it is we can first look at an iterator's current
6069 display element, decide whether it fits on a line, and if it does,
6070 increment the iterator position. The other way around we probably
6071 would either need a flag indicating whether the iterator has to be
6072 incremented the next time, or we would have to implement a
6073 decrement position function which would not be easy to write. */
6075 void
6076 set_iterator_to_next (struct it *it, int reseat_p)
6078 /* Reset flags indicating start and end of a sequence of characters
6079 with box. Reset them at the start of this function because
6080 moving the iterator to a new position might set them. */
6081 it->start_of_box_run_p = it->end_of_box_run_p = 0;
6083 switch (it->method)
6085 case GET_FROM_BUFFER:
6086 /* The current display element of IT is a character from
6087 current_buffer. Advance in the buffer, and maybe skip over
6088 invisible lines that are so because of selective display. */
6089 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
6090 reseat_at_next_visible_line_start (it, 0);
6091 else if (it->cmp_it.id >= 0)
6093 /* We are currently getting glyphs from a composition. */
6094 int i;
6096 if (! it->bidi_p)
6098 IT_CHARPOS (*it) += it->cmp_it.nchars;
6099 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
6100 if (it->cmp_it.to < it->cmp_it.nglyphs)
6102 it->cmp_it.from = it->cmp_it.to;
6104 else
6106 it->cmp_it.id = -1;
6107 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
6108 IT_BYTEPOS (*it),
6109 it->end_charpos, Qnil);
6112 else if (! it->cmp_it.reversed_p)
6114 /* Composition created while scanning forward. */
6115 /* Update IT's char/byte positions to point to the first
6116 character of the next grapheme cluster, or to the
6117 character visually after the current composition. */
6118 for (i = 0; i < it->cmp_it.nchars; i++)
6119 bidi_move_to_visually_next (&it->bidi_it);
6120 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6121 IT_CHARPOS (*it) = it->bidi_it.charpos;
6123 if (it->cmp_it.to < it->cmp_it.nglyphs)
6125 /* Proceed to the next grapheme cluster. */
6126 it->cmp_it.from = it->cmp_it.to;
6128 else
6130 /* No more grapheme clusters in this composition.
6131 Find the next stop position. */
6132 EMACS_INT stop = it->end_charpos;
6133 if (it->bidi_it.scan_dir < 0)
6134 /* Now we are scanning backward and don't know
6135 where to stop. */
6136 stop = -1;
6137 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
6138 IT_BYTEPOS (*it), stop, Qnil);
6141 else
6143 /* Composition created while scanning backward. */
6144 /* Update IT's char/byte positions to point to the last
6145 character of the previous grapheme cluster, or the
6146 character visually after the current composition. */
6147 for (i = 0; i < it->cmp_it.nchars; i++)
6148 bidi_move_to_visually_next (&it->bidi_it);
6149 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6150 IT_CHARPOS (*it) = it->bidi_it.charpos;
6151 if (it->cmp_it.from > 0)
6153 /* Proceed to the previous grapheme cluster. */
6154 it->cmp_it.to = it->cmp_it.from;
6156 else
6158 /* No more grapheme clusters in this composition.
6159 Find the next stop position. */
6160 EMACS_INT stop = it->end_charpos;
6161 if (it->bidi_it.scan_dir < 0)
6162 /* Now we are scanning backward and don't know
6163 where to stop. */
6164 stop = -1;
6165 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
6166 IT_BYTEPOS (*it), stop, Qnil);
6170 else
6172 xassert (it->len != 0);
6174 if (!it->bidi_p)
6176 IT_BYTEPOS (*it) += it->len;
6177 IT_CHARPOS (*it) += 1;
6179 else
6181 int prev_scan_dir = it->bidi_it.scan_dir;
6182 /* If this is a new paragraph, determine its base
6183 direction (a.k.a. its base embedding level). */
6184 if (it->bidi_it.new_paragraph)
6185 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 0);
6186 bidi_move_to_visually_next (&it->bidi_it);
6187 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6188 IT_CHARPOS (*it) = it->bidi_it.charpos;
6189 if (prev_scan_dir != it->bidi_it.scan_dir)
6191 /* As the scan direction was changed, we must
6192 re-compute the stop position for composition. */
6193 EMACS_INT stop = it->end_charpos;
6194 if (it->bidi_it.scan_dir < 0)
6195 stop = -1;
6196 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
6197 IT_BYTEPOS (*it), stop, Qnil);
6200 xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
6202 break;
6204 case GET_FROM_C_STRING:
6205 /* Current display element of IT is from a C string. */
6206 IT_BYTEPOS (*it) += it->len;
6207 IT_CHARPOS (*it) += 1;
6208 break;
6210 case GET_FROM_DISPLAY_VECTOR:
6211 /* Current display element of IT is from a display table entry.
6212 Advance in the display table definition. Reset it to null if
6213 end reached, and continue with characters from buffers/
6214 strings. */
6215 ++it->current.dpvec_index;
6217 /* Restore face of the iterator to what they were before the
6218 display vector entry (these entries may contain faces). */
6219 it->face_id = it->saved_face_id;
6221 if (it->dpvec + it->current.dpvec_index == it->dpend)
6223 int recheck_faces = it->ellipsis_p;
6225 if (it->s)
6226 it->method = GET_FROM_C_STRING;
6227 else if (STRINGP (it->string))
6228 it->method = GET_FROM_STRING;
6229 else
6231 it->method = GET_FROM_BUFFER;
6232 it->object = it->w->buffer;
6235 it->dpvec = NULL;
6236 it->current.dpvec_index = -1;
6238 /* Skip over characters which were displayed via IT->dpvec. */
6239 if (it->dpvec_char_len < 0)
6240 reseat_at_next_visible_line_start (it, 1);
6241 else if (it->dpvec_char_len > 0)
6243 if (it->method == GET_FROM_STRING
6244 && it->n_overlay_strings > 0)
6245 it->ignore_overlay_strings_at_pos_p = 1;
6246 it->len = it->dpvec_char_len;
6247 set_iterator_to_next (it, reseat_p);
6250 /* Maybe recheck faces after display vector */
6251 if (recheck_faces)
6252 it->stop_charpos = IT_CHARPOS (*it);
6254 break;
6256 case GET_FROM_STRING:
6257 /* Current display element is a character from a Lisp string. */
6258 xassert (it->s == NULL && STRINGP (it->string));
6259 if (it->cmp_it.id >= 0)
6261 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
6262 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
6263 if (it->cmp_it.to < it->cmp_it.nglyphs)
6264 it->cmp_it.from = it->cmp_it.to;
6265 else
6267 it->cmp_it.id = -1;
6268 composition_compute_stop_pos (&it->cmp_it,
6269 IT_STRING_CHARPOS (*it),
6270 IT_STRING_BYTEPOS (*it),
6271 it->end_charpos, it->string);
6274 else
6276 IT_STRING_BYTEPOS (*it) += it->len;
6277 IT_STRING_CHARPOS (*it) += 1;
6280 consider_string_end:
6282 if (it->current.overlay_string_index >= 0)
6284 /* IT->string is an overlay string. Advance to the
6285 next, if there is one. */
6286 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
6288 it->ellipsis_p = 0;
6289 next_overlay_string (it);
6290 if (it->ellipsis_p)
6291 setup_for_ellipsis (it, 0);
6294 else
6296 /* IT->string is not an overlay string. If we reached
6297 its end, and there is something on IT->stack, proceed
6298 with what is on the stack. This can be either another
6299 string, this time an overlay string, or a buffer. */
6300 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
6301 && it->sp > 0)
6303 pop_it (it);
6304 if (it->method == GET_FROM_STRING)
6305 goto consider_string_end;
6308 break;
6310 case GET_FROM_IMAGE:
6311 case GET_FROM_STRETCH:
6312 /* The position etc with which we have to proceed are on
6313 the stack. The position may be at the end of a string,
6314 if the `display' property takes up the whole string. */
6315 xassert (it->sp > 0);
6316 pop_it (it);
6317 if (it->method == GET_FROM_STRING)
6318 goto consider_string_end;
6319 break;
6321 default:
6322 /* There are no other methods defined, so this should be a bug. */
6323 abort ();
6326 xassert (it->method != GET_FROM_STRING
6327 || (STRINGP (it->string)
6328 && IT_STRING_CHARPOS (*it) >= 0));
6331 /* Load IT's display element fields with information about the next
6332 display element which comes from a display table entry or from the
6333 result of translating a control character to one of the forms `^C'
6334 or `\003'.
6336 IT->dpvec holds the glyphs to return as characters.
6337 IT->saved_face_id holds the face id before the display vector--it
6338 is restored into IT->face_id in set_iterator_to_next. */
6340 static int
6341 next_element_from_display_vector (struct it *it)
6343 Lisp_Object gc;
6345 /* Precondition. */
6346 xassert (it->dpvec && it->current.dpvec_index >= 0);
6348 it->face_id = it->saved_face_id;
6350 /* KFS: This code used to check ip->dpvec[0] instead of the current element.
6351 That seemed totally bogus - so I changed it... */
6352 gc = it->dpvec[it->current.dpvec_index];
6354 if (GLYPH_CODE_P (gc) && GLYPH_CODE_CHAR_VALID_P (gc))
6356 it->c = GLYPH_CODE_CHAR (gc);
6357 it->len = CHAR_BYTES (it->c);
6359 /* The entry may contain a face id to use. Such a face id is
6360 the id of a Lisp face, not a realized face. A face id of
6361 zero means no face is specified. */
6362 if (it->dpvec_face_id >= 0)
6363 it->face_id = it->dpvec_face_id;
6364 else
6366 int lface_id = GLYPH_CODE_FACE (gc);
6367 if (lface_id > 0)
6368 it->face_id = merge_faces (it->f, Qt, lface_id,
6369 it->saved_face_id);
6372 else
6373 /* Display table entry is invalid. Return a space. */
6374 it->c = ' ', it->len = 1;
6376 /* Don't change position and object of the iterator here. They are
6377 still the values of the character that had this display table
6378 entry or was translated, and that's what we want. */
6379 it->what = IT_CHARACTER;
6380 return 1;
6384 /* Load IT with the next display element from Lisp string IT->string.
6385 IT->current.string_pos is the current position within the string.
6386 If IT->current.overlay_string_index >= 0, the Lisp string is an
6387 overlay string. */
6389 static int
6390 next_element_from_string (struct it *it)
6392 struct text_pos position;
6394 xassert (STRINGP (it->string));
6395 xassert (IT_STRING_CHARPOS (*it) >= 0);
6396 position = it->current.string_pos;
6398 /* Time to check for invisible text? */
6399 if (IT_STRING_CHARPOS (*it) < it->end_charpos
6400 && IT_STRING_CHARPOS (*it) == it->stop_charpos)
6402 handle_stop (it);
6404 /* Since a handler may have changed IT->method, we must
6405 recurse here. */
6406 return GET_NEXT_DISPLAY_ELEMENT (it);
6409 if (it->current.overlay_string_index >= 0)
6411 /* Get the next character from an overlay string. In overlay
6412 strings, There is no field width or padding with spaces to
6413 do. */
6414 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
6416 it->what = IT_EOB;
6417 return 0;
6419 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
6420 IT_STRING_BYTEPOS (*it), SCHARS (it->string))
6421 && next_element_from_composition (it))
6423 return 1;
6425 else if (STRING_MULTIBYTE (it->string))
6427 const unsigned char *s = (SDATA (it->string)
6428 + IT_STRING_BYTEPOS (*it));
6429 it->c = string_char_and_length (s, &it->len);
6431 else
6433 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
6434 it->len = 1;
6437 else
6439 /* Get the next character from a Lisp string that is not an
6440 overlay string. Such strings come from the mode line, for
6441 example. We may have to pad with spaces, or truncate the
6442 string. See also next_element_from_c_string. */
6443 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
6445 it->what = IT_EOB;
6446 return 0;
6448 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
6450 /* Pad with spaces. */
6451 it->c = ' ', it->len = 1;
6452 CHARPOS (position) = BYTEPOS (position) = -1;
6454 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
6455 IT_STRING_BYTEPOS (*it), it->string_nchars)
6456 && next_element_from_composition (it))
6458 return 1;
6460 else if (STRING_MULTIBYTE (it->string))
6462 const unsigned char *s = (SDATA (it->string)
6463 + IT_STRING_BYTEPOS (*it));
6464 it->c = string_char_and_length (s, &it->len);
6466 else
6468 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
6469 it->len = 1;
6473 /* Record what we have and where it came from. */
6474 it->what = IT_CHARACTER;
6475 it->object = it->string;
6476 it->position = position;
6477 return 1;
6481 /* Load IT with next display element from C string IT->s.
6482 IT->string_nchars is the maximum number of characters to return
6483 from the string. IT->end_charpos may be greater than
6484 IT->string_nchars when this function is called, in which case we
6485 may have to return padding spaces. Value is zero if end of string
6486 reached, including padding spaces. */
6488 static int
6489 next_element_from_c_string (struct it *it)
6491 int success_p = 1;
6493 xassert (it->s);
6494 it->what = IT_CHARACTER;
6495 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
6496 it->object = Qnil;
6498 /* IT's position can be greater IT->string_nchars in case a field
6499 width or precision has been specified when the iterator was
6500 initialized. */
6501 if (IT_CHARPOS (*it) >= it->end_charpos)
6503 /* End of the game. */
6504 it->what = IT_EOB;
6505 success_p = 0;
6507 else if (IT_CHARPOS (*it) >= it->string_nchars)
6509 /* Pad with spaces. */
6510 it->c = ' ', it->len = 1;
6511 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
6513 else if (it->multibyte_p)
6514 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it), &it->len);
6515 else
6516 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
6518 return success_p;
6522 /* Set up IT to return characters from an ellipsis, if appropriate.
6523 The definition of the ellipsis glyphs may come from a display table
6524 entry. This function fills IT with the first glyph from the
6525 ellipsis if an ellipsis is to be displayed. */
6527 static int
6528 next_element_from_ellipsis (struct it *it)
6530 if (it->selective_display_ellipsis_p)
6531 setup_for_ellipsis (it, it->len);
6532 else
6534 /* The face at the current position may be different from the
6535 face we find after the invisible text. Remember what it
6536 was in IT->saved_face_id, and signal that it's there by
6537 setting face_before_selective_p. */
6538 it->saved_face_id = it->face_id;
6539 it->method = GET_FROM_BUFFER;
6540 it->object = it->w->buffer;
6541 reseat_at_next_visible_line_start (it, 1);
6542 it->face_before_selective_p = 1;
6545 return GET_NEXT_DISPLAY_ELEMENT (it);
6549 /* Deliver an image display element. The iterator IT is already
6550 filled with image information (done in handle_display_prop). Value
6551 is always 1. */
6554 static int
6555 next_element_from_image (struct it *it)
6557 it->what = IT_IMAGE;
6558 it->ignore_overlay_strings_at_pos_p = 0;
6559 return 1;
6563 /* Fill iterator IT with next display element from a stretch glyph
6564 property. IT->object is the value of the text property. Value is
6565 always 1. */
6567 static int
6568 next_element_from_stretch (struct it *it)
6570 it->what = IT_STRETCH;
6571 return 1;
6574 /* Scan forward from CHARPOS in the current buffer, until we find a
6575 stop position > current IT's position. Then handle the stop
6576 position before that. This is called when we bump into a stop
6577 position while reordering bidirectional text. CHARPOS should be
6578 the last previously processed stop_pos (or BEGV, if none were
6579 processed yet) whose position is less that IT's current
6580 position. */
6582 static void
6583 handle_stop_backwards (struct it *it, EMACS_INT charpos)
6585 EMACS_INT where_we_are = IT_CHARPOS (*it);
6586 struct display_pos save_current = it->current;
6587 struct text_pos save_position = it->position;
6588 struct text_pos pos1;
6589 EMACS_INT next_stop;
6591 /* Scan in strict logical order. */
6592 it->bidi_p = 0;
6595 it->prev_stop = charpos;
6596 SET_TEXT_POS (pos1, charpos, CHAR_TO_BYTE (charpos));
6597 reseat_1 (it, pos1, 0);
6598 compute_stop_pos (it);
6599 /* We must advance forward, right? */
6600 if (it->stop_charpos <= it->prev_stop)
6601 abort ();
6602 charpos = it->stop_charpos;
6604 while (charpos <= where_we_are);
6606 next_stop = it->stop_charpos;
6607 it->stop_charpos = it->prev_stop;
6608 it->bidi_p = 1;
6609 it->current = save_current;
6610 it->position = save_position;
6611 handle_stop (it);
6612 it->stop_charpos = next_stop;
6615 /* Load IT with the next display element from current_buffer. Value
6616 is zero if end of buffer reached. IT->stop_charpos is the next
6617 position at which to stop and check for text properties or buffer
6618 end. */
6620 static int
6621 next_element_from_buffer (struct it *it)
6623 int success_p = 1;
6625 xassert (IT_CHARPOS (*it) >= BEGV);
6627 /* With bidi reordering, the character to display might not be the
6628 character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that
6629 we were reseat()ed to a new buffer position, which is potentially
6630 a different paragraph. */
6631 if (it->bidi_p && it->bidi_it.first_elt)
6633 it->bidi_it.charpos = IT_CHARPOS (*it);
6634 it->bidi_it.bytepos = IT_BYTEPOS (*it);
6635 if (it->bidi_it.bytepos == ZV_BYTE)
6637 /* Nothing to do, but reset the FIRST_ELT flag, like
6638 bidi_paragraph_init does, because we are not going to
6639 call it. */
6640 it->bidi_it.first_elt = 0;
6642 else if (it->bidi_it.bytepos == BEGV_BYTE
6643 /* FIXME: Should support all Unicode line separators. */
6644 || FETCH_CHAR (it->bidi_it.bytepos - 1) == '\n'
6645 || FETCH_CHAR (it->bidi_it.bytepos) == '\n')
6647 /* If we are at the beginning of a line, we can produce the
6648 next element right away. */
6649 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
6650 bidi_move_to_visually_next (&it->bidi_it);
6652 else
6654 EMACS_INT orig_bytepos = IT_BYTEPOS (*it);
6656 /* We need to prime the bidi iterator starting at the line's
6657 beginning, before we will be able to produce the next
6658 element. */
6659 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it), -1);
6660 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
6661 it->bidi_it.charpos = IT_CHARPOS (*it);
6662 it->bidi_it.bytepos = IT_BYTEPOS (*it);
6663 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
6666 /* Now return to buffer position where we were asked to
6667 get the next display element, and produce that. */
6668 bidi_move_to_visually_next (&it->bidi_it);
6670 while (it->bidi_it.bytepos != orig_bytepos
6671 && it->bidi_it.bytepos < ZV_BYTE);
6674 it->bidi_it.first_elt = 0; /* paranoia: bidi.c does this */
6675 /* Adjust IT's position information to where we ended up. */
6676 IT_CHARPOS (*it) = it->bidi_it.charpos;
6677 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6678 SET_TEXT_POS (it->position, IT_CHARPOS (*it), IT_BYTEPOS (*it));
6680 EMACS_INT stop = it->end_charpos;
6681 if (it->bidi_it.scan_dir < 0)
6682 stop = -1;
6683 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
6684 IT_BYTEPOS (*it), stop, Qnil);
6688 if (IT_CHARPOS (*it) >= it->stop_charpos)
6690 if (IT_CHARPOS (*it) >= it->end_charpos)
6692 int overlay_strings_follow_p;
6694 /* End of the game, except when overlay strings follow that
6695 haven't been returned yet. */
6696 if (it->overlay_strings_at_end_processed_p)
6697 overlay_strings_follow_p = 0;
6698 else
6700 it->overlay_strings_at_end_processed_p = 1;
6701 overlay_strings_follow_p = get_overlay_strings (it, 0);
6704 if (overlay_strings_follow_p)
6705 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
6706 else
6708 it->what = IT_EOB;
6709 it->position = it->current.pos;
6710 success_p = 0;
6713 else if (!(!it->bidi_p
6714 || BIDI_AT_BASE_LEVEL (it->bidi_it)
6715 || IT_CHARPOS (*it) == it->stop_charpos))
6717 /* With bidi non-linear iteration, we could find ourselves
6718 far beyond the last computed stop_charpos, with several
6719 other stop positions in between that we missed. Scan
6720 them all now, in buffer's logical order, until we find
6721 and handle the last stop_charpos that precedes our
6722 current position. */
6723 handle_stop_backwards (it, it->stop_charpos);
6724 return GET_NEXT_DISPLAY_ELEMENT (it);
6726 else
6728 if (it->bidi_p)
6730 /* Take note of the stop position we just moved across,
6731 for when we will move back across it. */
6732 it->prev_stop = it->stop_charpos;
6733 /* If we are at base paragraph embedding level, take
6734 note of the last stop position seen at this
6735 level. */
6736 if (BIDI_AT_BASE_LEVEL (it->bidi_it))
6737 it->base_level_stop = it->stop_charpos;
6739 handle_stop (it);
6740 return GET_NEXT_DISPLAY_ELEMENT (it);
6743 else if (it->bidi_p
6744 /* We can sometimes back up for reasons that have nothing
6745 to do with bidi reordering. E.g., compositions. The
6746 code below is only needed when we are above the base
6747 embedding level, so test for that explicitly. */
6748 && !BIDI_AT_BASE_LEVEL (it->bidi_it)
6749 && IT_CHARPOS (*it) < it->prev_stop)
6751 if (it->base_level_stop <= 0)
6752 it->base_level_stop = BEGV;
6753 if (IT_CHARPOS (*it) < it->base_level_stop)
6754 abort ();
6755 handle_stop_backwards (it, it->base_level_stop);
6756 return GET_NEXT_DISPLAY_ELEMENT (it);
6758 else
6760 /* No face changes, overlays etc. in sight, so just return a
6761 character from current_buffer. */
6762 unsigned char *p;
6763 EMACS_INT stop;
6765 /* Maybe run the redisplay end trigger hook. Performance note:
6766 This doesn't seem to cost measurable time. */
6767 if (it->redisplay_end_trigger_charpos
6768 && it->glyph_row
6769 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
6770 run_redisplay_end_trigger_hook (it);
6772 stop = it->bidi_it.scan_dir < 0 ? -1 : it->end_charpos;
6773 if (CHAR_COMPOSED_P (it, IT_CHARPOS (*it), IT_BYTEPOS (*it),
6774 stop)
6775 && next_element_from_composition (it))
6777 return 1;
6780 /* Get the next character, maybe multibyte. */
6781 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
6782 if (it->multibyte_p && !ASCII_BYTE_P (*p))
6783 it->c = STRING_CHAR_AND_LENGTH (p, it->len);
6784 else
6785 it->c = *p, it->len = 1;
6787 /* Record what we have and where it came from. */
6788 it->what = IT_CHARACTER;
6789 it->object = it->w->buffer;
6790 it->position = it->current.pos;
6792 /* Normally we return the character found above, except when we
6793 really want to return an ellipsis for selective display. */
6794 if (it->selective)
6796 if (it->c == '\n')
6798 /* A value of selective > 0 means hide lines indented more
6799 than that number of columns. */
6800 if (it->selective > 0
6801 && IT_CHARPOS (*it) + 1 < ZV
6802 && indented_beyond_p (IT_CHARPOS (*it) + 1,
6803 IT_BYTEPOS (*it) + 1,
6804 (double) it->selective)) /* iftc */
6806 success_p = next_element_from_ellipsis (it);
6807 it->dpvec_char_len = -1;
6810 else if (it->c == '\r' && it->selective == -1)
6812 /* A value of selective == -1 means that everything from the
6813 CR to the end of the line is invisible, with maybe an
6814 ellipsis displayed for it. */
6815 success_p = next_element_from_ellipsis (it);
6816 it->dpvec_char_len = -1;
6821 /* Value is zero if end of buffer reached. */
6822 xassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
6823 return success_p;
6827 /* Run the redisplay end trigger hook for IT. */
6829 static void
6830 run_redisplay_end_trigger_hook (struct it *it)
6832 Lisp_Object args[3];
6834 /* IT->glyph_row should be non-null, i.e. we should be actually
6835 displaying something, or otherwise we should not run the hook. */
6836 xassert (it->glyph_row);
6838 /* Set up hook arguments. */
6839 args[0] = Qredisplay_end_trigger_functions;
6840 args[1] = it->window;
6841 XSETINT (args[2], it->redisplay_end_trigger_charpos);
6842 it->redisplay_end_trigger_charpos = 0;
6844 /* Since we are *trying* to run these functions, don't try to run
6845 them again, even if they get an error. */
6846 it->w->redisplay_end_trigger = Qnil;
6847 Frun_hook_with_args (3, args);
6849 /* Notice if it changed the face of the character we are on. */
6850 handle_face_prop (it);
6854 /* Deliver a composition display element. Unlike the other
6855 next_element_from_XXX, this function is not registered in the array
6856 get_next_element[]. It is called from next_element_from_buffer and
6857 next_element_from_string when necessary. */
6859 static int
6860 next_element_from_composition (struct it *it)
6862 it->what = IT_COMPOSITION;
6863 it->len = it->cmp_it.nbytes;
6864 if (STRINGP (it->string))
6866 if (it->c < 0)
6868 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
6869 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
6870 return 0;
6872 it->position = it->current.string_pos;
6873 it->object = it->string;
6874 it->c = composition_update_it (&it->cmp_it, IT_STRING_CHARPOS (*it),
6875 IT_STRING_BYTEPOS (*it), it->string);
6877 else
6879 if (it->c < 0)
6881 IT_CHARPOS (*it) += it->cmp_it.nchars;
6882 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
6883 if (it->bidi_p)
6885 if (it->bidi_it.new_paragraph)
6886 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 0);
6887 /* Resync the bidi iterator with IT's new position.
6888 FIXME: this doesn't support bidirectional text. */
6889 while (it->bidi_it.charpos < IT_CHARPOS (*it))
6890 bidi_move_to_visually_next (&it->bidi_it);
6892 return 0;
6894 it->position = it->current.pos;
6895 it->object = it->w->buffer;
6896 it->c = composition_update_it (&it->cmp_it, IT_CHARPOS (*it),
6897 IT_BYTEPOS (*it), Qnil);
6899 return 1;
6904 /***********************************************************************
6905 Moving an iterator without producing glyphs
6906 ***********************************************************************/
6908 /* Check if iterator is at a position corresponding to a valid buffer
6909 position after some move_it_ call. */
6911 #define IT_POS_VALID_AFTER_MOVE_P(it) \
6912 ((it)->method == GET_FROM_STRING \
6913 ? IT_STRING_CHARPOS (*it) == 0 \
6914 : 1)
6917 /* Move iterator IT to a specified buffer or X position within one
6918 line on the display without producing glyphs.
6920 OP should be a bit mask including some or all of these bits:
6921 MOVE_TO_X: Stop upon reaching x-position TO_X.
6922 MOVE_TO_POS: Stop upon reaching buffer or string position TO_CHARPOS.
6923 Regardless of OP's value, stop upon reaching the end of the display line.
6925 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
6926 This means, in particular, that TO_X includes window's horizontal
6927 scroll amount.
6929 The return value has several possible values that
6930 say what condition caused the scan to stop:
6932 MOVE_POS_MATCH_OR_ZV
6933 - when TO_POS or ZV was reached.
6935 MOVE_X_REACHED
6936 -when TO_X was reached before TO_POS or ZV were reached.
6938 MOVE_LINE_CONTINUED
6939 - when we reached the end of the display area and the line must
6940 be continued.
6942 MOVE_LINE_TRUNCATED
6943 - when we reached the end of the display area and the line is
6944 truncated.
6946 MOVE_NEWLINE_OR_CR
6947 - when we stopped at a line end, i.e. a newline or a CR and selective
6948 display is on. */
6950 static enum move_it_result
6951 move_it_in_display_line_to (struct it *it,
6952 EMACS_INT to_charpos, int to_x,
6953 enum move_operation_enum op)
6955 enum move_it_result result = MOVE_UNDEFINED;
6956 struct glyph_row *saved_glyph_row;
6957 struct it wrap_it, atpos_it, atx_it;
6958 int may_wrap = 0;
6959 enum it_method prev_method = it->method;
6960 EMACS_INT prev_pos = IT_CHARPOS (*it);
6962 /* Don't produce glyphs in produce_glyphs. */
6963 saved_glyph_row = it->glyph_row;
6964 it->glyph_row = NULL;
6966 /* Use wrap_it to save a copy of IT wherever a word wrap could
6967 occur. Use atpos_it to save a copy of IT at the desired buffer
6968 position, if found, so that we can scan ahead and check if the
6969 word later overshoots the window edge. Use atx_it similarly, for
6970 pixel positions. */
6971 wrap_it.sp = -1;
6972 atpos_it.sp = -1;
6973 atx_it.sp = -1;
6975 #define BUFFER_POS_REACHED_P() \
6976 ((op & MOVE_TO_POS) != 0 \
6977 && BUFFERP (it->object) \
6978 && (IT_CHARPOS (*it) == to_charpos \
6979 || (!it->bidi_p && IT_CHARPOS (*it) > to_charpos)) \
6980 && (it->method == GET_FROM_BUFFER \
6981 || (it->method == GET_FROM_DISPLAY_VECTOR \
6982 && it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
6984 /* If there's a line-/wrap-prefix, handle it. */
6985 if (it->hpos == 0 && it->method == GET_FROM_BUFFER
6986 && it->current_y < it->last_visible_y)
6987 handle_line_prefix (it);
6989 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
6990 SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it));
6992 while (1)
6994 int x, i, ascent = 0, descent = 0;
6996 /* Utility macro to reset an iterator with x, ascent, and descent. */
6997 #define IT_RESET_X_ASCENT_DESCENT(IT) \
6998 ((IT)->current_x = x, (IT)->max_ascent = ascent, \
6999 (IT)->max_descent = descent)
7001 /* Stop if we move beyond TO_CHARPOS (after an image or stretch
7002 glyph). */
7003 if ((op & MOVE_TO_POS) != 0
7004 && BUFFERP (it->object)
7005 && it->method == GET_FROM_BUFFER
7006 && ((!it->bidi_p && IT_CHARPOS (*it) > to_charpos)
7007 || (it->bidi_p
7008 && (prev_method == GET_FROM_IMAGE
7009 || prev_method == GET_FROM_STRETCH)
7010 /* Passed TO_CHARPOS from left to right. */
7011 && ((prev_pos < to_charpos
7012 && IT_CHARPOS (*it) > to_charpos)
7013 /* Passed TO_CHARPOS from right to left. */
7014 || (prev_pos > to_charpos
7015 && IT_CHARPOS (*it) < to_charpos)))))
7017 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
7019 result = MOVE_POS_MATCH_OR_ZV;
7020 break;
7022 else if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
7023 /* If wrap_it is valid, the current position might be in a
7024 word that is wrapped. So, save the iterator in
7025 atpos_it and continue to see if wrapping happens. */
7026 atpos_it = *it;
7029 prev_method = it->method;
7030 if (it->method == GET_FROM_BUFFER)
7031 prev_pos = IT_CHARPOS (*it);
7032 /* Stop when ZV reached.
7033 We used to stop here when TO_CHARPOS reached as well, but that is
7034 too soon if this glyph does not fit on this line. So we handle it
7035 explicitly below. */
7036 if (!get_next_display_element (it))
7038 result = MOVE_POS_MATCH_OR_ZV;
7039 break;
7042 if (it->line_wrap == TRUNCATE)
7044 if (BUFFER_POS_REACHED_P ())
7046 result = MOVE_POS_MATCH_OR_ZV;
7047 break;
7050 else
7052 if (it->line_wrap == WORD_WRAP)
7054 if (IT_DISPLAYING_WHITESPACE (it))
7055 may_wrap = 1;
7056 else if (may_wrap)
7058 /* We have reached a glyph that follows one or more
7059 whitespace characters. If the position is
7060 already found, we are done. */
7061 if (atpos_it.sp >= 0)
7063 *it = atpos_it;
7064 result = MOVE_POS_MATCH_OR_ZV;
7065 goto done;
7067 if (atx_it.sp >= 0)
7069 *it = atx_it;
7070 result = MOVE_X_REACHED;
7071 goto done;
7073 /* Otherwise, we can wrap here. */
7074 wrap_it = *it;
7075 may_wrap = 0;
7080 /* Remember the line height for the current line, in case
7081 the next element doesn't fit on the line. */
7082 ascent = it->max_ascent;
7083 descent = it->max_descent;
7085 /* The call to produce_glyphs will get the metrics of the
7086 display element IT is loaded with. Record the x-position
7087 before this display element, in case it doesn't fit on the
7088 line. */
7089 x = it->current_x;
7091 PRODUCE_GLYPHS (it);
7093 if (it->area != TEXT_AREA)
7095 set_iterator_to_next (it, 1);
7096 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
7097 SET_TEXT_POS (this_line_min_pos,
7098 IT_CHARPOS (*it), IT_BYTEPOS (*it));
7099 continue;
7102 /* The number of glyphs we get back in IT->nglyphs will normally
7103 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
7104 character on a terminal frame, or (iii) a line end. For the
7105 second case, IT->nglyphs - 1 padding glyphs will be present.
7106 (On X frames, there is only one glyph produced for a
7107 composite character.)
7109 The behavior implemented below means, for continuation lines,
7110 that as many spaces of a TAB as fit on the current line are
7111 displayed there. For terminal frames, as many glyphs of a
7112 multi-glyph character are displayed in the current line, too.
7113 This is what the old redisplay code did, and we keep it that
7114 way. Under X, the whole shape of a complex character must
7115 fit on the line or it will be completely displayed in the
7116 next line.
7118 Note that both for tabs and padding glyphs, all glyphs have
7119 the same width. */
7120 if (it->nglyphs)
7122 /* More than one glyph or glyph doesn't fit on line. All
7123 glyphs have the same width. */
7124 int single_glyph_width = it->pixel_width / it->nglyphs;
7125 int new_x;
7126 int x_before_this_char = x;
7127 int hpos_before_this_char = it->hpos;
7129 for (i = 0; i < it->nglyphs; ++i, x = new_x)
7131 new_x = x + single_glyph_width;
7133 /* We want to leave anything reaching TO_X to the caller. */
7134 if ((op & MOVE_TO_X) && new_x > to_x)
7136 if (BUFFER_POS_REACHED_P ())
7138 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
7139 goto buffer_pos_reached;
7140 if (atpos_it.sp < 0)
7142 atpos_it = *it;
7143 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
7146 else
7148 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
7150 it->current_x = x;
7151 result = MOVE_X_REACHED;
7152 break;
7154 if (atx_it.sp < 0)
7156 atx_it = *it;
7157 IT_RESET_X_ASCENT_DESCENT (&atx_it);
7162 if (/* Lines are continued. */
7163 it->line_wrap != TRUNCATE
7164 && (/* And glyph doesn't fit on the line. */
7165 new_x > it->last_visible_x
7166 /* Or it fits exactly and we're on a window
7167 system frame. */
7168 || (new_x == it->last_visible_x
7169 && FRAME_WINDOW_P (it->f))))
7171 if (/* IT->hpos == 0 means the very first glyph
7172 doesn't fit on the line, e.g. a wide image. */
7173 it->hpos == 0
7174 || (new_x == it->last_visible_x
7175 && FRAME_WINDOW_P (it->f)))
7177 ++it->hpos;
7178 it->current_x = new_x;
7180 /* The character's last glyph just barely fits
7181 in this row. */
7182 if (i == it->nglyphs - 1)
7184 /* If this is the destination position,
7185 return a position *before* it in this row,
7186 now that we know it fits in this row. */
7187 if (BUFFER_POS_REACHED_P ())
7189 if (it->line_wrap != WORD_WRAP
7190 || wrap_it.sp < 0)
7192 it->hpos = hpos_before_this_char;
7193 it->current_x = x_before_this_char;
7194 result = MOVE_POS_MATCH_OR_ZV;
7195 break;
7197 if (it->line_wrap == WORD_WRAP
7198 && atpos_it.sp < 0)
7200 atpos_it = *it;
7201 atpos_it.current_x = x_before_this_char;
7202 atpos_it.hpos = hpos_before_this_char;
7206 set_iterator_to_next (it, 1);
7207 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
7208 SET_TEXT_POS (this_line_min_pos,
7209 IT_CHARPOS (*it), IT_BYTEPOS (*it));
7210 /* On graphical terminals, newlines may
7211 "overflow" into the fringe if
7212 overflow-newline-into-fringe is non-nil.
7213 On text-only terminals, newlines may
7214 overflow into the last glyph on the
7215 display line.*/
7216 if (!FRAME_WINDOW_P (it->f)
7217 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
7219 if (!get_next_display_element (it))
7221 result = MOVE_POS_MATCH_OR_ZV;
7222 break;
7224 if (BUFFER_POS_REACHED_P ())
7226 if (ITERATOR_AT_END_OF_LINE_P (it))
7227 result = MOVE_POS_MATCH_OR_ZV;
7228 else
7229 result = MOVE_LINE_CONTINUED;
7230 break;
7232 if (ITERATOR_AT_END_OF_LINE_P (it))
7234 result = MOVE_NEWLINE_OR_CR;
7235 break;
7240 else
7241 IT_RESET_X_ASCENT_DESCENT (it);
7243 if (wrap_it.sp >= 0)
7245 *it = wrap_it;
7246 atpos_it.sp = -1;
7247 atx_it.sp = -1;
7250 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
7251 IT_CHARPOS (*it)));
7252 result = MOVE_LINE_CONTINUED;
7253 break;
7256 if (BUFFER_POS_REACHED_P ())
7258 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
7259 goto buffer_pos_reached;
7260 if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
7262 atpos_it = *it;
7263 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
7267 if (new_x > it->first_visible_x)
7269 /* Glyph is visible. Increment number of glyphs that
7270 would be displayed. */
7271 ++it->hpos;
7275 if (result != MOVE_UNDEFINED)
7276 break;
7278 else if (BUFFER_POS_REACHED_P ())
7280 buffer_pos_reached:
7281 IT_RESET_X_ASCENT_DESCENT (it);
7282 result = MOVE_POS_MATCH_OR_ZV;
7283 break;
7285 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
7287 /* Stop when TO_X specified and reached. This check is
7288 necessary here because of lines consisting of a line end,
7289 only. The line end will not produce any glyphs and we
7290 would never get MOVE_X_REACHED. */
7291 xassert (it->nglyphs == 0);
7292 result = MOVE_X_REACHED;
7293 break;
7296 /* Is this a line end? If yes, we're done. */
7297 if (ITERATOR_AT_END_OF_LINE_P (it))
7299 result = MOVE_NEWLINE_OR_CR;
7300 break;
7303 if (it->method == GET_FROM_BUFFER)
7304 prev_pos = IT_CHARPOS (*it);
7305 /* The current display element has been consumed. Advance
7306 to the next. */
7307 set_iterator_to_next (it, 1);
7308 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
7309 SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it));
7311 /* Stop if lines are truncated and IT's current x-position is
7312 past the right edge of the window now. */
7313 if (it->line_wrap == TRUNCATE
7314 && it->current_x >= it->last_visible_x)
7316 if (!FRAME_WINDOW_P (it->f)
7317 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
7319 if (!get_next_display_element (it)
7320 || BUFFER_POS_REACHED_P ())
7322 result = MOVE_POS_MATCH_OR_ZV;
7323 break;
7325 if (ITERATOR_AT_END_OF_LINE_P (it))
7327 result = MOVE_NEWLINE_OR_CR;
7328 break;
7331 result = MOVE_LINE_TRUNCATED;
7332 break;
7334 #undef IT_RESET_X_ASCENT_DESCENT
7337 #undef BUFFER_POS_REACHED_P
7339 /* If we scanned beyond to_pos and didn't find a point to wrap at,
7340 restore the saved iterator. */
7341 if (atpos_it.sp >= 0)
7342 *it = atpos_it;
7343 else if (atx_it.sp >= 0)
7344 *it = atx_it;
7346 done:
7348 /* Restore the iterator settings altered at the beginning of this
7349 function. */
7350 it->glyph_row = saved_glyph_row;
7351 return result;
7354 /* For external use. */
7355 void
7356 move_it_in_display_line (struct it *it,
7357 EMACS_INT to_charpos, int to_x,
7358 enum move_operation_enum op)
7360 if (it->line_wrap == WORD_WRAP
7361 && (op & MOVE_TO_X))
7363 struct it save_it = *it;
7364 int skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
7365 /* When word-wrap is on, TO_X may lie past the end
7366 of a wrapped line. Then it->current is the
7367 character on the next line, so backtrack to the
7368 space before the wrap point. */
7369 if (skip == MOVE_LINE_CONTINUED)
7371 int prev_x = max (it->current_x - 1, 0);
7372 *it = save_it;
7373 move_it_in_display_line_to
7374 (it, -1, prev_x, MOVE_TO_X);
7377 else
7378 move_it_in_display_line_to (it, to_charpos, to_x, op);
7382 /* Move IT forward until it satisfies one or more of the criteria in
7383 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
7385 OP is a bit-mask that specifies where to stop, and in particular,
7386 which of those four position arguments makes a difference. See the
7387 description of enum move_operation_enum.
7389 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
7390 screen line, this function will set IT to the next position >
7391 TO_CHARPOS. */
7393 void
7394 move_it_to (struct it *it, EMACS_INT to_charpos, int to_x, int to_y, int to_vpos, int op)
7396 enum move_it_result skip, skip2 = MOVE_X_REACHED;
7397 int line_height, line_start_x = 0, reached = 0;
7399 for (;;)
7401 if (op & MOVE_TO_VPOS)
7403 /* If no TO_CHARPOS and no TO_X specified, stop at the
7404 start of the line TO_VPOS. */
7405 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
7407 if (it->vpos == to_vpos)
7409 reached = 1;
7410 break;
7412 else
7413 skip = move_it_in_display_line_to (it, -1, -1, 0);
7415 else
7417 /* TO_VPOS >= 0 means stop at TO_X in the line at
7418 TO_VPOS, or at TO_POS, whichever comes first. */
7419 if (it->vpos == to_vpos)
7421 reached = 2;
7422 break;
7425 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
7427 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
7429 reached = 3;
7430 break;
7432 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
7434 /* We have reached TO_X but not in the line we want. */
7435 skip = move_it_in_display_line_to (it, to_charpos,
7436 -1, MOVE_TO_POS);
7437 if (skip == MOVE_POS_MATCH_OR_ZV)
7439 reached = 4;
7440 break;
7445 else if (op & MOVE_TO_Y)
7447 struct it it_backup;
7449 if (it->line_wrap == WORD_WRAP)
7450 it_backup = *it;
7452 /* TO_Y specified means stop at TO_X in the line containing
7453 TO_Y---or at TO_CHARPOS if this is reached first. The
7454 problem is that we can't really tell whether the line
7455 contains TO_Y before we have completely scanned it, and
7456 this may skip past TO_X. What we do is to first scan to
7457 TO_X.
7459 If TO_X is not specified, use a TO_X of zero. The reason
7460 is to make the outcome of this function more predictable.
7461 If we didn't use TO_X == 0, we would stop at the end of
7462 the line which is probably not what a caller would expect
7463 to happen. */
7464 skip = move_it_in_display_line_to
7465 (it, to_charpos, ((op & MOVE_TO_X) ? to_x : 0),
7466 (MOVE_TO_X | (op & MOVE_TO_POS)));
7468 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
7469 if (skip == MOVE_POS_MATCH_OR_ZV)
7470 reached = 5;
7471 else if (skip == MOVE_X_REACHED)
7473 /* If TO_X was reached, we want to know whether TO_Y is
7474 in the line. We know this is the case if the already
7475 scanned glyphs make the line tall enough. Otherwise,
7476 we must check by scanning the rest of the line. */
7477 line_height = it->max_ascent + it->max_descent;
7478 if (to_y >= it->current_y
7479 && to_y < it->current_y + line_height)
7481 reached = 6;
7482 break;
7484 it_backup = *it;
7485 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
7486 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
7487 op & MOVE_TO_POS);
7488 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
7489 line_height = it->max_ascent + it->max_descent;
7490 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
7492 if (to_y >= it->current_y
7493 && to_y < it->current_y + line_height)
7495 /* If TO_Y is in this line and TO_X was reached
7496 above, we scanned too far. We have to restore
7497 IT's settings to the ones before skipping. */
7498 *it = it_backup;
7499 reached = 6;
7501 else
7503 skip = skip2;
7504 if (skip == MOVE_POS_MATCH_OR_ZV)
7505 reached = 7;
7508 else
7510 /* Check whether TO_Y is in this line. */
7511 line_height = it->max_ascent + it->max_descent;
7512 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
7514 if (to_y >= it->current_y
7515 && to_y < it->current_y + line_height)
7517 /* When word-wrap is on, TO_X may lie past the end
7518 of a wrapped line. Then it->current is the
7519 character on the next line, so backtrack to the
7520 space before the wrap point. */
7521 if (skip == MOVE_LINE_CONTINUED
7522 && it->line_wrap == WORD_WRAP)
7524 int prev_x = max (it->current_x - 1, 0);
7525 *it = it_backup;
7526 skip = move_it_in_display_line_to
7527 (it, -1, prev_x, MOVE_TO_X);
7529 reached = 6;
7533 if (reached)
7534 break;
7536 else if (BUFFERP (it->object)
7537 && (it->method == GET_FROM_BUFFER
7538 || it->method == GET_FROM_STRETCH)
7539 && IT_CHARPOS (*it) >= to_charpos)
7540 skip = MOVE_POS_MATCH_OR_ZV;
7541 else
7542 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
7544 switch (skip)
7546 case MOVE_POS_MATCH_OR_ZV:
7547 reached = 8;
7548 goto out;
7550 case MOVE_NEWLINE_OR_CR:
7551 set_iterator_to_next (it, 1);
7552 it->continuation_lines_width = 0;
7553 break;
7555 case MOVE_LINE_TRUNCATED:
7556 it->continuation_lines_width = 0;
7557 reseat_at_next_visible_line_start (it, 0);
7558 if ((op & MOVE_TO_POS) != 0
7559 && IT_CHARPOS (*it) > to_charpos)
7561 reached = 9;
7562 goto out;
7564 break;
7566 case MOVE_LINE_CONTINUED:
7567 /* For continued lines ending in a tab, some of the glyphs
7568 associated with the tab are displayed on the current
7569 line. Since it->current_x does not include these glyphs,
7570 we use it->last_visible_x instead. */
7571 if (it->c == '\t')
7573 it->continuation_lines_width += it->last_visible_x;
7574 /* When moving by vpos, ensure that the iterator really
7575 advances to the next line (bug#847, bug#969). Fixme:
7576 do we need to do this in other circumstances? */
7577 if (it->current_x != it->last_visible_x
7578 && (op & MOVE_TO_VPOS)
7579 && !(op & (MOVE_TO_X | MOVE_TO_POS)))
7581 line_start_x = it->current_x + it->pixel_width
7582 - it->last_visible_x;
7583 set_iterator_to_next (it, 0);
7586 else
7587 it->continuation_lines_width += it->current_x;
7588 break;
7590 default:
7591 abort ();
7594 /* Reset/increment for the next run. */
7595 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
7596 it->current_x = line_start_x;
7597 line_start_x = 0;
7598 it->hpos = 0;
7599 it->current_y += it->max_ascent + it->max_descent;
7600 ++it->vpos;
7601 last_height = it->max_ascent + it->max_descent;
7602 last_max_ascent = it->max_ascent;
7603 it->max_ascent = it->max_descent = 0;
7606 out:
7608 /* On text terminals, we may stop at the end of a line in the middle
7609 of a multi-character glyph. If the glyph itself is continued,
7610 i.e. it is actually displayed on the next line, don't treat this
7611 stopping point as valid; move to the next line instead (unless
7612 that brings us offscreen). */
7613 if (!FRAME_WINDOW_P (it->f)
7614 && op & MOVE_TO_POS
7615 && IT_CHARPOS (*it) == to_charpos
7616 && it->what == IT_CHARACTER
7617 && it->nglyphs > 1
7618 && it->line_wrap == WINDOW_WRAP
7619 && it->current_x == it->last_visible_x - 1
7620 && it->c != '\n'
7621 && it->c != '\t'
7622 && it->vpos < XFASTINT (it->w->window_end_vpos))
7624 it->continuation_lines_width += it->current_x;
7625 it->current_x = it->hpos = it->max_ascent = it->max_descent = 0;
7626 it->current_y += it->max_ascent + it->max_descent;
7627 ++it->vpos;
7628 last_height = it->max_ascent + it->max_descent;
7629 last_max_ascent = it->max_ascent;
7632 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
7636 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
7638 If DY > 0, move IT backward at least that many pixels. DY = 0
7639 means move IT backward to the preceding line start or BEGV. This
7640 function may move over more than DY pixels if IT->current_y - DY
7641 ends up in the middle of a line; in this case IT->current_y will be
7642 set to the top of the line moved to. */
7644 void
7645 move_it_vertically_backward (struct it *it, int dy)
7647 int nlines, h;
7648 struct it it2, it3;
7649 EMACS_INT start_pos;
7651 move_further_back:
7652 xassert (dy >= 0);
7654 start_pos = IT_CHARPOS (*it);
7656 /* Estimate how many newlines we must move back. */
7657 nlines = max (1, dy / FRAME_LINE_HEIGHT (it->f));
7659 /* Set the iterator's position that many lines back. */
7660 while (nlines-- && IT_CHARPOS (*it) > BEGV)
7661 back_to_previous_visible_line_start (it);
7663 /* Reseat the iterator here. When moving backward, we don't want
7664 reseat to skip forward over invisible text, set up the iterator
7665 to deliver from overlay strings at the new position etc. So,
7666 use reseat_1 here. */
7667 reseat_1 (it, it->current.pos, 1);
7669 /* We are now surely at a line start. */
7670 it->current_x = it->hpos = 0;
7671 it->continuation_lines_width = 0;
7673 /* Move forward and see what y-distance we moved. First move to the
7674 start of the next line so that we get its height. We need this
7675 height to be able to tell whether we reached the specified
7676 y-distance. */
7677 it2 = *it;
7678 it2.max_ascent = it2.max_descent = 0;
7681 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
7682 MOVE_TO_POS | MOVE_TO_VPOS);
7684 while (!IT_POS_VALID_AFTER_MOVE_P (&it2));
7685 xassert (IT_CHARPOS (*it) >= BEGV);
7686 it3 = it2;
7688 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
7689 xassert (IT_CHARPOS (*it) >= BEGV);
7690 /* H is the actual vertical distance from the position in *IT
7691 and the starting position. */
7692 h = it2.current_y - it->current_y;
7693 /* NLINES is the distance in number of lines. */
7694 nlines = it2.vpos - it->vpos;
7696 /* Correct IT's y and vpos position
7697 so that they are relative to the starting point. */
7698 it->vpos -= nlines;
7699 it->current_y -= h;
7701 if (dy == 0)
7703 /* DY == 0 means move to the start of the screen line. The
7704 value of nlines is > 0 if continuation lines were involved. */
7705 if (nlines > 0)
7706 move_it_by_lines (it, nlines);
7708 else
7710 /* The y-position we try to reach, relative to *IT.
7711 Note that H has been subtracted in front of the if-statement. */
7712 int target_y = it->current_y + h - dy;
7713 int y0 = it3.current_y;
7714 int y1 = line_bottom_y (&it3);
7715 int line_height = y1 - y0;
7717 /* If we did not reach target_y, try to move further backward if
7718 we can. If we moved too far backward, try to move forward. */
7719 if (target_y < it->current_y
7720 /* This is heuristic. In a window that's 3 lines high, with
7721 a line height of 13 pixels each, recentering with point
7722 on the bottom line will try to move -39/2 = 19 pixels
7723 backward. Try to avoid moving into the first line. */
7724 && (it->current_y - target_y
7725 > min (window_box_height (it->w), line_height * 2 / 3))
7726 && IT_CHARPOS (*it) > BEGV)
7728 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
7729 target_y - it->current_y));
7730 dy = it->current_y - target_y;
7731 goto move_further_back;
7733 else if (target_y >= it->current_y + line_height
7734 && IT_CHARPOS (*it) < ZV)
7736 /* Should move forward by at least one line, maybe more.
7738 Note: Calling move_it_by_lines can be expensive on
7739 terminal frames, where compute_motion is used (via
7740 vmotion) to do the job, when there are very long lines
7741 and truncate-lines is nil. That's the reason for
7742 treating terminal frames specially here. */
7744 if (!FRAME_WINDOW_P (it->f))
7745 move_it_vertically (it, target_y - (it->current_y + line_height));
7746 else
7750 move_it_by_lines (it, 1);
7752 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
7759 /* Move IT by a specified amount of pixel lines DY. DY negative means
7760 move backwards. DY = 0 means move to start of screen line. At the
7761 end, IT will be on the start of a screen line. */
7763 void
7764 move_it_vertically (struct it *it, int dy)
7766 if (dy <= 0)
7767 move_it_vertically_backward (it, -dy);
7768 else
7770 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
7771 move_it_to (it, ZV, -1, it->current_y + dy, -1,
7772 MOVE_TO_POS | MOVE_TO_Y);
7773 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
7775 /* If buffer ends in ZV without a newline, move to the start of
7776 the line to satisfy the post-condition. */
7777 if (IT_CHARPOS (*it) == ZV
7778 && ZV > BEGV
7779 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
7780 move_it_by_lines (it, 0);
7785 /* Move iterator IT past the end of the text line it is in. */
7787 void
7788 move_it_past_eol (struct it *it)
7790 enum move_it_result rc;
7792 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
7793 if (rc == MOVE_NEWLINE_OR_CR)
7794 set_iterator_to_next (it, 0);
7798 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
7799 negative means move up. DVPOS == 0 means move to the start of the
7800 screen line.
7802 Optimization idea: If we would know that IT->f doesn't use
7803 a face with proportional font, we could be faster for
7804 truncate-lines nil. */
7806 void
7807 move_it_by_lines (struct it *it, int dvpos)
7810 /* The commented-out optimization uses vmotion on terminals. This
7811 gives bad results, because elements like it->what, on which
7812 callers such as pos_visible_p rely, aren't updated. */
7813 /* struct position pos;
7814 if (!FRAME_WINDOW_P (it->f))
7816 struct text_pos textpos;
7818 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
7819 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
7820 reseat (it, textpos, 1);
7821 it->vpos += pos.vpos;
7822 it->current_y += pos.vpos;
7824 else */
7826 if (dvpos == 0)
7828 /* DVPOS == 0 means move to the start of the screen line. */
7829 move_it_vertically_backward (it, 0);
7830 xassert (it->current_x == 0 && it->hpos == 0);
7831 /* Let next call to line_bottom_y calculate real line height */
7832 last_height = 0;
7834 else if (dvpos > 0)
7836 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
7837 if (!IT_POS_VALID_AFTER_MOVE_P (it))
7838 move_it_to (it, IT_CHARPOS (*it) + 1, -1, -1, -1, MOVE_TO_POS);
7840 else
7842 struct it it2;
7843 EMACS_INT start_charpos, i;
7845 /* Start at the beginning of the screen line containing IT's
7846 position. This may actually move vertically backwards,
7847 in case of overlays, so adjust dvpos accordingly. */
7848 dvpos += it->vpos;
7849 move_it_vertically_backward (it, 0);
7850 dvpos -= it->vpos;
7852 /* Go back -DVPOS visible lines and reseat the iterator there. */
7853 start_charpos = IT_CHARPOS (*it);
7854 for (i = -dvpos; i > 0 && IT_CHARPOS (*it) > BEGV; --i)
7855 back_to_previous_visible_line_start (it);
7856 reseat (it, it->current.pos, 1);
7858 /* Move further back if we end up in a string or an image. */
7859 while (!IT_POS_VALID_AFTER_MOVE_P (it))
7861 /* First try to move to start of display line. */
7862 dvpos += it->vpos;
7863 move_it_vertically_backward (it, 0);
7864 dvpos -= it->vpos;
7865 if (IT_POS_VALID_AFTER_MOVE_P (it))
7866 break;
7867 /* If start of line is still in string or image,
7868 move further back. */
7869 back_to_previous_visible_line_start (it);
7870 reseat (it, it->current.pos, 1);
7871 dvpos--;
7874 it->current_x = it->hpos = 0;
7876 /* Above call may have moved too far if continuation lines
7877 are involved. Scan forward and see if it did. */
7878 it2 = *it;
7879 it2.vpos = it2.current_y = 0;
7880 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
7881 it->vpos -= it2.vpos;
7882 it->current_y -= it2.current_y;
7883 it->current_x = it->hpos = 0;
7885 /* If we moved too far back, move IT some lines forward. */
7886 if (it2.vpos > -dvpos)
7888 int delta = it2.vpos + dvpos;
7889 it2 = *it;
7890 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
7891 /* Move back again if we got too far ahead. */
7892 if (IT_CHARPOS (*it) >= start_charpos)
7893 *it = it2;
7898 /* Return 1 if IT points into the middle of a display vector. */
7901 in_display_vector_p (struct it *it)
7903 return (it->method == GET_FROM_DISPLAY_VECTOR
7904 && it->current.dpvec_index > 0
7905 && it->dpvec + it->current.dpvec_index != it->dpend);
7909 /***********************************************************************
7910 Messages
7911 ***********************************************************************/
7914 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
7915 to *Messages*. */
7917 void
7918 add_to_log (const char *format, Lisp_Object arg1, Lisp_Object arg2)
7920 Lisp_Object args[3];
7921 Lisp_Object msg, fmt;
7922 char *buffer;
7923 EMACS_INT len;
7924 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
7925 USE_SAFE_ALLOCA;
7927 /* Do nothing if called asynchronously. Inserting text into
7928 a buffer may call after-change-functions and alike and
7929 that would means running Lisp asynchronously. */
7930 if (handling_signal)
7931 return;
7933 fmt = msg = Qnil;
7934 GCPRO4 (fmt, msg, arg1, arg2);
7936 args[0] = fmt = build_string (format);
7937 args[1] = arg1;
7938 args[2] = arg2;
7939 msg = Fformat (3, args);
7941 len = SBYTES (msg) + 1;
7942 SAFE_ALLOCA (buffer, char *, len);
7943 memcpy (buffer, SDATA (msg), len);
7945 message_dolog (buffer, len - 1, 1, 0);
7946 SAFE_FREE ();
7948 UNGCPRO;
7952 /* Output a newline in the *Messages* buffer if "needs" one. */
7954 void
7955 message_log_maybe_newline (void)
7957 if (message_log_need_newline)
7958 message_dolog ("", 0, 1, 0);
7962 /* Add a string M of length NBYTES to the message log, optionally
7963 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
7964 nonzero, means interpret the contents of M as multibyte. This
7965 function calls low-level routines in order to bypass text property
7966 hooks, etc. which might not be safe to run.
7968 This may GC (insert may run before/after change hooks),
7969 so the buffer M must NOT point to a Lisp string. */
7971 void
7972 message_dolog (const char *m, EMACS_INT nbytes, int nlflag, int multibyte)
7974 const unsigned char *msg = (const unsigned char *) m;
7976 if (!NILP (Vmemory_full))
7977 return;
7979 if (!NILP (Vmessage_log_max))
7981 struct buffer *oldbuf;
7982 Lisp_Object oldpoint, oldbegv, oldzv;
7983 int old_windows_or_buffers_changed = windows_or_buffers_changed;
7984 EMACS_INT point_at_end = 0;
7985 EMACS_INT zv_at_end = 0;
7986 Lisp_Object old_deactivate_mark, tem;
7987 struct gcpro gcpro1;
7989 old_deactivate_mark = Vdeactivate_mark;
7990 oldbuf = current_buffer;
7991 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
7992 BVAR (current_buffer, undo_list) = Qt;
7994 oldpoint = message_dolog_marker1;
7995 set_marker_restricted (oldpoint, make_number (PT), Qnil);
7996 oldbegv = message_dolog_marker2;
7997 set_marker_restricted (oldbegv, make_number (BEGV), Qnil);
7998 oldzv = message_dolog_marker3;
7999 set_marker_restricted (oldzv, make_number (ZV), Qnil);
8000 GCPRO1 (old_deactivate_mark);
8002 if (PT == Z)
8003 point_at_end = 1;
8004 if (ZV == Z)
8005 zv_at_end = 1;
8007 BEGV = BEG;
8008 BEGV_BYTE = BEG_BYTE;
8009 ZV = Z;
8010 ZV_BYTE = Z_BYTE;
8011 TEMP_SET_PT_BOTH (Z, Z_BYTE);
8013 /* Insert the string--maybe converting multibyte to single byte
8014 or vice versa, so that all the text fits the buffer. */
8015 if (multibyte
8016 && NILP (BVAR (current_buffer, enable_multibyte_characters)))
8018 EMACS_INT i;
8019 int c, char_bytes;
8020 char work[1];
8022 /* Convert a multibyte string to single-byte
8023 for the *Message* buffer. */
8024 for (i = 0; i < nbytes; i += char_bytes)
8026 c = string_char_and_length (msg + i, &char_bytes);
8027 work[0] = (ASCII_CHAR_P (c)
8029 : multibyte_char_to_unibyte (c));
8030 insert_1_both (work, 1, 1, 1, 0, 0);
8033 else if (! multibyte
8034 && ! NILP (BVAR (current_buffer, enable_multibyte_characters)))
8036 EMACS_INT i;
8037 int c, char_bytes;
8038 unsigned char str[MAX_MULTIBYTE_LENGTH];
8039 /* Convert a single-byte string to multibyte
8040 for the *Message* buffer. */
8041 for (i = 0; i < nbytes; i++)
8043 c = msg[i];
8044 MAKE_CHAR_MULTIBYTE (c);
8045 char_bytes = CHAR_STRING (c, str);
8046 insert_1_both ((char *) str, 1, char_bytes, 1, 0, 0);
8049 else if (nbytes)
8050 insert_1 (m, nbytes, 1, 0, 0);
8052 if (nlflag)
8054 EMACS_INT this_bol, this_bol_byte, prev_bol, prev_bol_byte;
8055 unsigned long int dups;
8056 insert_1 ("\n", 1, 1, 0, 0);
8058 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
8059 this_bol = PT;
8060 this_bol_byte = PT_BYTE;
8062 /* See if this line duplicates the previous one.
8063 If so, combine duplicates. */
8064 if (this_bol > BEG)
8066 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
8067 prev_bol = PT;
8068 prev_bol_byte = PT_BYTE;
8070 dups = message_log_check_duplicate (prev_bol_byte,
8071 this_bol_byte);
8072 if (dups)
8074 del_range_both (prev_bol, prev_bol_byte,
8075 this_bol, this_bol_byte, 0);
8076 if (dups > 1)
8078 char dupstr[40];
8079 int duplen;
8081 /* If you change this format, don't forget to also
8082 change message_log_check_duplicate. */
8083 sprintf (dupstr, " [%lu times]", dups);
8084 duplen = strlen (dupstr);
8085 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
8086 insert_1 (dupstr, duplen, 1, 0, 1);
8091 /* If we have more than the desired maximum number of lines
8092 in the *Messages* buffer now, delete the oldest ones.
8093 This is safe because we don't have undo in this buffer. */
8095 if (NATNUMP (Vmessage_log_max))
8097 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
8098 -XFASTINT (Vmessage_log_max) - 1, 0);
8099 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
8102 BEGV = XMARKER (oldbegv)->charpos;
8103 BEGV_BYTE = marker_byte_position (oldbegv);
8105 if (zv_at_end)
8107 ZV = Z;
8108 ZV_BYTE = Z_BYTE;
8110 else
8112 ZV = XMARKER (oldzv)->charpos;
8113 ZV_BYTE = marker_byte_position (oldzv);
8116 if (point_at_end)
8117 TEMP_SET_PT_BOTH (Z, Z_BYTE);
8118 else
8119 /* We can't do Fgoto_char (oldpoint) because it will run some
8120 Lisp code. */
8121 TEMP_SET_PT_BOTH (XMARKER (oldpoint)->charpos,
8122 XMARKER (oldpoint)->bytepos);
8124 UNGCPRO;
8125 unchain_marker (XMARKER (oldpoint));
8126 unchain_marker (XMARKER (oldbegv));
8127 unchain_marker (XMARKER (oldzv));
8129 tem = Fget_buffer_window (Fcurrent_buffer (), Qt);
8130 set_buffer_internal (oldbuf);
8131 if (NILP (tem))
8132 windows_or_buffers_changed = old_windows_or_buffers_changed;
8133 message_log_need_newline = !nlflag;
8134 Vdeactivate_mark = old_deactivate_mark;
8139 /* We are at the end of the buffer after just having inserted a newline.
8140 (Note: We depend on the fact we won't be crossing the gap.)
8141 Check to see if the most recent message looks a lot like the previous one.
8142 Return 0 if different, 1 if the new one should just replace it, or a
8143 value N > 1 if we should also append " [N times]". */
8145 static unsigned long int
8146 message_log_check_duplicate (EMACS_INT prev_bol_byte, EMACS_INT this_bol_byte)
8148 EMACS_INT i;
8149 EMACS_INT len = Z_BYTE - 1 - this_bol_byte;
8150 int seen_dots = 0;
8151 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
8152 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
8154 for (i = 0; i < len; i++)
8156 if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.')
8157 seen_dots = 1;
8158 if (p1[i] != p2[i])
8159 return seen_dots;
8161 p1 += len;
8162 if (*p1 == '\n')
8163 return 2;
8164 if (*p1++ == ' ' && *p1++ == '[')
8166 char *pend;
8167 unsigned long int n = strtoul ((char *) p1, &pend, 10);
8168 if (strncmp (pend, " times]\n", 8) == 0)
8169 return n+1;
8171 return 0;
8175 /* Display an echo area message M with a specified length of NBYTES
8176 bytes. The string may include null characters. If M is 0, clear
8177 out any existing message, and let the mini-buffer text show
8178 through.
8180 This may GC, so the buffer M must NOT point to a Lisp string. */
8182 void
8183 message2 (const char *m, EMACS_INT nbytes, int multibyte)
8185 /* First flush out any partial line written with print. */
8186 message_log_maybe_newline ();
8187 if (m)
8188 message_dolog (m, nbytes, 1, multibyte);
8189 message2_nolog (m, nbytes, multibyte);
8193 /* The non-logging counterpart of message2. */
8195 void
8196 message2_nolog (const char *m, EMACS_INT nbytes, int multibyte)
8198 struct frame *sf = SELECTED_FRAME ();
8199 message_enable_multibyte = multibyte;
8201 if (FRAME_INITIAL_P (sf))
8203 if (noninteractive_need_newline)
8204 putc ('\n', stderr);
8205 noninteractive_need_newline = 0;
8206 if (m)
8207 fwrite (m, nbytes, 1, stderr);
8208 if (cursor_in_echo_area == 0)
8209 fprintf (stderr, "\n");
8210 fflush (stderr);
8212 /* A null message buffer means that the frame hasn't really been
8213 initialized yet. Error messages get reported properly by
8214 cmd_error, so this must be just an informative message; toss it. */
8215 else if (INTERACTIVE
8216 && sf->glyphs_initialized_p
8217 && FRAME_MESSAGE_BUF (sf))
8219 Lisp_Object mini_window;
8220 struct frame *f;
8222 /* Get the frame containing the mini-buffer
8223 that the selected frame is using. */
8224 mini_window = FRAME_MINIBUF_WINDOW (sf);
8225 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
8227 FRAME_SAMPLE_VISIBILITY (f);
8228 if (FRAME_VISIBLE_P (sf)
8229 && ! FRAME_VISIBLE_P (f))
8230 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
8232 if (m)
8234 set_message (m, Qnil, nbytes, multibyte);
8235 if (minibuffer_auto_raise)
8236 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
8238 else
8239 clear_message (1, 1);
8241 do_pending_window_change (0);
8242 echo_area_display (1);
8243 do_pending_window_change (0);
8244 if (FRAME_TERMINAL (f)->frame_up_to_date_hook != 0 && ! gc_in_progress)
8245 (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
8250 /* Display an echo area message M with a specified length of NBYTES
8251 bytes. The string may include null characters. If M is not a
8252 string, clear out any existing message, and let the mini-buffer
8253 text show through.
8255 This function cancels echoing. */
8257 void
8258 message3 (Lisp_Object m, EMACS_INT nbytes, int multibyte)
8260 struct gcpro gcpro1;
8262 GCPRO1 (m);
8263 clear_message (1,1);
8264 cancel_echoing ();
8266 /* First flush out any partial line written with print. */
8267 message_log_maybe_newline ();
8268 if (STRINGP (m))
8270 char *buffer;
8271 USE_SAFE_ALLOCA;
8273 SAFE_ALLOCA (buffer, char *, nbytes);
8274 memcpy (buffer, SDATA (m), nbytes);
8275 message_dolog (buffer, nbytes, 1, multibyte);
8276 SAFE_FREE ();
8278 message3_nolog (m, nbytes, multibyte);
8280 UNGCPRO;
8284 /* The non-logging version of message3.
8285 This does not cancel echoing, because it is used for echoing.
8286 Perhaps we need to make a separate function for echoing
8287 and make this cancel echoing. */
8289 void
8290 message3_nolog (Lisp_Object m, EMACS_INT nbytes, int multibyte)
8292 struct frame *sf = SELECTED_FRAME ();
8293 message_enable_multibyte = multibyte;
8295 if (FRAME_INITIAL_P (sf))
8297 if (noninteractive_need_newline)
8298 putc ('\n', stderr);
8299 noninteractive_need_newline = 0;
8300 if (STRINGP (m))
8301 fwrite (SDATA (m), nbytes, 1, stderr);
8302 if (cursor_in_echo_area == 0)
8303 fprintf (stderr, "\n");
8304 fflush (stderr);
8306 /* A null message buffer means that the frame hasn't really been
8307 initialized yet. Error messages get reported properly by
8308 cmd_error, so this must be just an informative message; toss it. */
8309 else if (INTERACTIVE
8310 && sf->glyphs_initialized_p
8311 && FRAME_MESSAGE_BUF (sf))
8313 Lisp_Object mini_window;
8314 Lisp_Object frame;
8315 struct frame *f;
8317 /* Get the frame containing the mini-buffer
8318 that the selected frame is using. */
8319 mini_window = FRAME_MINIBUF_WINDOW (sf);
8320 frame = XWINDOW (mini_window)->frame;
8321 f = XFRAME (frame);
8323 FRAME_SAMPLE_VISIBILITY (f);
8324 if (FRAME_VISIBLE_P (sf)
8325 && !FRAME_VISIBLE_P (f))
8326 Fmake_frame_visible (frame);
8328 if (STRINGP (m) && SCHARS (m) > 0)
8330 set_message (NULL, m, nbytes, multibyte);
8331 if (minibuffer_auto_raise)
8332 Fraise_frame (frame);
8333 /* Assume we are not echoing.
8334 (If we are, echo_now will override this.) */
8335 echo_message_buffer = Qnil;
8337 else
8338 clear_message (1, 1);
8340 do_pending_window_change (0);
8341 echo_area_display (1);
8342 do_pending_window_change (0);
8343 if (FRAME_TERMINAL (f)->frame_up_to_date_hook != 0 && ! gc_in_progress)
8344 (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
8349 /* Display a null-terminated echo area message M. If M is 0, clear
8350 out any existing message, and let the mini-buffer text show through.
8352 The buffer M must continue to exist until after the echo area gets
8353 cleared or some other message gets displayed there. Do not pass
8354 text that is stored in a Lisp string. Do not pass text in a buffer
8355 that was alloca'd. */
8357 void
8358 message1 (const char *m)
8360 message2 (m, (m ? strlen (m) : 0), 0);
8364 /* The non-logging counterpart of message1. */
8366 void
8367 message1_nolog (const char *m)
8369 message2_nolog (m, (m ? strlen (m) : 0), 0);
8372 /* Display a message M which contains a single %s
8373 which gets replaced with STRING. */
8375 void
8376 message_with_string (const char *m, Lisp_Object string, int log)
8378 CHECK_STRING (string);
8380 if (noninteractive)
8382 if (m)
8384 if (noninteractive_need_newline)
8385 putc ('\n', stderr);
8386 noninteractive_need_newline = 0;
8387 fprintf (stderr, m, SDATA (string));
8388 if (!cursor_in_echo_area)
8389 fprintf (stderr, "\n");
8390 fflush (stderr);
8393 else if (INTERACTIVE)
8395 /* The frame whose minibuffer we're going to display the message on.
8396 It may be larger than the selected frame, so we need
8397 to use its buffer, not the selected frame's buffer. */
8398 Lisp_Object mini_window;
8399 struct frame *f, *sf = SELECTED_FRAME ();
8401 /* Get the frame containing the minibuffer
8402 that the selected frame is using. */
8403 mini_window = FRAME_MINIBUF_WINDOW (sf);
8404 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
8406 /* A null message buffer means that the frame hasn't really been
8407 initialized yet. Error messages get reported properly by
8408 cmd_error, so this must be just an informative message; toss it. */
8409 if (FRAME_MESSAGE_BUF (f))
8411 Lisp_Object args[2], msg;
8412 struct gcpro gcpro1, gcpro2;
8414 args[0] = build_string (m);
8415 args[1] = msg = string;
8416 GCPRO2 (args[0], msg);
8417 gcpro1.nvars = 2;
8419 msg = Fformat (2, args);
8421 if (log)
8422 message3 (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
8423 else
8424 message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
8426 UNGCPRO;
8428 /* Print should start at the beginning of the message
8429 buffer next time. */
8430 message_buf_print = 0;
8436 /* Dump an informative message to the minibuf. If M is 0, clear out
8437 any existing message, and let the mini-buffer text show through. */
8439 static void
8440 vmessage (const char *m, va_list ap)
8442 if (noninteractive)
8444 if (m)
8446 if (noninteractive_need_newline)
8447 putc ('\n', stderr);
8448 noninteractive_need_newline = 0;
8449 vfprintf (stderr, m, ap);
8450 if (cursor_in_echo_area == 0)
8451 fprintf (stderr, "\n");
8452 fflush (stderr);
8455 else if (INTERACTIVE)
8457 /* The frame whose mini-buffer we're going to display the message
8458 on. It may be larger than the selected frame, so we need to
8459 use its buffer, not the selected frame's buffer. */
8460 Lisp_Object mini_window;
8461 struct frame *f, *sf = SELECTED_FRAME ();
8463 /* Get the frame containing the mini-buffer
8464 that the selected frame is using. */
8465 mini_window = FRAME_MINIBUF_WINDOW (sf);
8466 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
8468 /* A null message buffer means that the frame hasn't really been
8469 initialized yet. Error messages get reported properly by
8470 cmd_error, so this must be just an informative message; toss
8471 it. */
8472 if (FRAME_MESSAGE_BUF (f))
8474 if (m)
8476 size_t len;
8478 len = doprnt (FRAME_MESSAGE_BUF (f),
8479 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, ap);
8481 message2 (FRAME_MESSAGE_BUF (f), len, 0);
8483 else
8484 message1 (0);
8486 /* Print should start at the beginning of the message
8487 buffer next time. */
8488 message_buf_print = 0;
8493 void
8494 message (const char *m, ...)
8496 va_list ap;
8497 va_start (ap, m);
8498 vmessage (m, ap);
8499 va_end (ap);
8503 #if 0
8504 /* The non-logging version of message. */
8506 void
8507 message_nolog (const char *m, ...)
8509 Lisp_Object old_log_max;
8510 va_list ap;
8511 va_start (ap, m);
8512 old_log_max = Vmessage_log_max;
8513 Vmessage_log_max = Qnil;
8514 vmessage (m, ap);
8515 Vmessage_log_max = old_log_max;
8516 va_end (ap);
8518 #endif
8521 /* Display the current message in the current mini-buffer. This is
8522 only called from error handlers in process.c, and is not time
8523 critical. */
8525 void
8526 update_echo_area (void)
8528 if (!NILP (echo_area_buffer[0]))
8530 Lisp_Object string;
8531 string = Fcurrent_message ();
8532 message3 (string, SBYTES (string),
8533 !NILP (BVAR (current_buffer, enable_multibyte_characters)));
8538 /* Make sure echo area buffers in `echo_buffers' are live.
8539 If they aren't, make new ones. */
8541 static void
8542 ensure_echo_area_buffers (void)
8544 int i;
8546 for (i = 0; i < 2; ++i)
8547 if (!BUFFERP (echo_buffer[i])
8548 || NILP (BVAR (XBUFFER (echo_buffer[i]), name)))
8550 char name[30];
8551 Lisp_Object old_buffer;
8552 int j;
8554 old_buffer = echo_buffer[i];
8555 sprintf (name, " *Echo Area %d*", i);
8556 echo_buffer[i] = Fget_buffer_create (build_string (name));
8557 BVAR (XBUFFER (echo_buffer[i]), truncate_lines) = Qnil;
8558 /* to force word wrap in echo area -
8559 it was decided to postpone this*/
8560 /* XBUFFER (echo_buffer[i])->word_wrap = Qt; */
8562 for (j = 0; j < 2; ++j)
8563 if (EQ (old_buffer, echo_area_buffer[j]))
8564 echo_area_buffer[j] = echo_buffer[i];
8569 /* Call FN with args A1..A4 with either the current or last displayed
8570 echo_area_buffer as current buffer.
8572 WHICH zero means use the current message buffer
8573 echo_area_buffer[0]. If that is nil, choose a suitable buffer
8574 from echo_buffer[] and clear it.
8576 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
8577 suitable buffer from echo_buffer[] and clear it.
8579 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
8580 that the current message becomes the last displayed one, make
8581 choose a suitable buffer for echo_area_buffer[0], and clear it.
8583 Value is what FN returns. */
8585 static int
8586 with_echo_area_buffer (struct window *w, int which,
8587 int (*fn) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
8588 EMACS_INT a1, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4)
8590 Lisp_Object buffer;
8591 int this_one, the_other, clear_buffer_p, rc;
8592 int count = SPECPDL_INDEX ();
8594 /* If buffers aren't live, make new ones. */
8595 ensure_echo_area_buffers ();
8597 clear_buffer_p = 0;
8599 if (which == 0)
8600 this_one = 0, the_other = 1;
8601 else if (which > 0)
8602 this_one = 1, the_other = 0;
8603 else
8605 this_one = 0, the_other = 1;
8606 clear_buffer_p = 1;
8608 /* We need a fresh one in case the current echo buffer equals
8609 the one containing the last displayed echo area message. */
8610 if (!NILP (echo_area_buffer[this_one])
8611 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
8612 echo_area_buffer[this_one] = Qnil;
8615 /* Choose a suitable buffer from echo_buffer[] is we don't
8616 have one. */
8617 if (NILP (echo_area_buffer[this_one]))
8619 echo_area_buffer[this_one]
8620 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
8621 ? echo_buffer[the_other]
8622 : echo_buffer[this_one]);
8623 clear_buffer_p = 1;
8626 buffer = echo_area_buffer[this_one];
8628 /* Don't get confused by reusing the buffer used for echoing
8629 for a different purpose. */
8630 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
8631 cancel_echoing ();
8633 record_unwind_protect (unwind_with_echo_area_buffer,
8634 with_echo_area_buffer_unwind_data (w));
8636 /* Make the echo area buffer current. Note that for display
8637 purposes, it is not necessary that the displayed window's buffer
8638 == current_buffer, except for text property lookup. So, let's
8639 only set that buffer temporarily here without doing a full
8640 Fset_window_buffer. We must also change w->pointm, though,
8641 because otherwise an assertions in unshow_buffer fails, and Emacs
8642 aborts. */
8643 set_buffer_internal_1 (XBUFFER (buffer));
8644 if (w)
8646 w->buffer = buffer;
8647 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
8650 BVAR (current_buffer, undo_list) = Qt;
8651 BVAR (current_buffer, read_only) = Qnil;
8652 specbind (Qinhibit_read_only, Qt);
8653 specbind (Qinhibit_modification_hooks, Qt);
8655 if (clear_buffer_p && Z > BEG)
8656 del_range (BEG, Z);
8658 xassert (BEGV >= BEG);
8659 xassert (ZV <= Z && ZV >= BEGV);
8661 rc = fn (a1, a2, a3, a4);
8663 xassert (BEGV >= BEG);
8664 xassert (ZV <= Z && ZV >= BEGV);
8666 unbind_to (count, Qnil);
8667 return rc;
8671 /* Save state that should be preserved around the call to the function
8672 FN called in with_echo_area_buffer. */
8674 static Lisp_Object
8675 with_echo_area_buffer_unwind_data (struct window *w)
8677 int i = 0;
8678 Lisp_Object vector, tmp;
8680 /* Reduce consing by keeping one vector in
8681 Vwith_echo_area_save_vector. */
8682 vector = Vwith_echo_area_save_vector;
8683 Vwith_echo_area_save_vector = Qnil;
8685 if (NILP (vector))
8686 vector = Fmake_vector (make_number (7), Qnil);
8688 XSETBUFFER (tmp, current_buffer); ASET (vector, i, tmp); ++i;
8689 ASET (vector, i, Vdeactivate_mark); ++i;
8690 ASET (vector, i, make_number (windows_or_buffers_changed)); ++i;
8692 if (w)
8694 XSETWINDOW (tmp, w); ASET (vector, i, tmp); ++i;
8695 ASET (vector, i, w->buffer); ++i;
8696 ASET (vector, i, make_number (XMARKER (w->pointm)->charpos)); ++i;
8697 ASET (vector, i, make_number (XMARKER (w->pointm)->bytepos)); ++i;
8699 else
8701 int end = i + 4;
8702 for (; i < end; ++i)
8703 ASET (vector, i, Qnil);
8706 xassert (i == ASIZE (vector));
8707 return vector;
8711 /* Restore global state from VECTOR which was created by
8712 with_echo_area_buffer_unwind_data. */
8714 static Lisp_Object
8715 unwind_with_echo_area_buffer (Lisp_Object vector)
8717 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
8718 Vdeactivate_mark = AREF (vector, 1);
8719 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
8721 if (WINDOWP (AREF (vector, 3)))
8723 struct window *w;
8724 Lisp_Object buffer, charpos, bytepos;
8726 w = XWINDOW (AREF (vector, 3));
8727 buffer = AREF (vector, 4);
8728 charpos = AREF (vector, 5);
8729 bytepos = AREF (vector, 6);
8731 w->buffer = buffer;
8732 set_marker_both (w->pointm, buffer,
8733 XFASTINT (charpos), XFASTINT (bytepos));
8736 Vwith_echo_area_save_vector = vector;
8737 return Qnil;
8741 /* Set up the echo area for use by print functions. MULTIBYTE_P
8742 non-zero means we will print multibyte. */
8744 void
8745 setup_echo_area_for_printing (int multibyte_p)
8747 /* If we can't find an echo area any more, exit. */
8748 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
8749 Fkill_emacs (Qnil);
8751 ensure_echo_area_buffers ();
8753 if (!message_buf_print)
8755 /* A message has been output since the last time we printed.
8756 Choose a fresh echo area buffer. */
8757 if (EQ (echo_area_buffer[1], echo_buffer[0]))
8758 echo_area_buffer[0] = echo_buffer[1];
8759 else
8760 echo_area_buffer[0] = echo_buffer[0];
8762 /* Switch to that buffer and clear it. */
8763 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
8764 BVAR (current_buffer, truncate_lines) = Qnil;
8766 if (Z > BEG)
8768 int count = SPECPDL_INDEX ();
8769 specbind (Qinhibit_read_only, Qt);
8770 /* Note that undo recording is always disabled. */
8771 del_range (BEG, Z);
8772 unbind_to (count, Qnil);
8774 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
8776 /* Set up the buffer for the multibyteness we need. */
8777 if (multibyte_p
8778 != !NILP (BVAR (current_buffer, enable_multibyte_characters)))
8779 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
8781 /* Raise the frame containing the echo area. */
8782 if (minibuffer_auto_raise)
8784 struct frame *sf = SELECTED_FRAME ();
8785 Lisp_Object mini_window;
8786 mini_window = FRAME_MINIBUF_WINDOW (sf);
8787 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
8790 message_log_maybe_newline ();
8791 message_buf_print = 1;
8793 else
8795 if (NILP (echo_area_buffer[0]))
8797 if (EQ (echo_area_buffer[1], echo_buffer[0]))
8798 echo_area_buffer[0] = echo_buffer[1];
8799 else
8800 echo_area_buffer[0] = echo_buffer[0];
8803 if (current_buffer != XBUFFER (echo_area_buffer[0]))
8805 /* Someone switched buffers between print requests. */
8806 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
8807 BVAR (current_buffer, truncate_lines) = Qnil;
8813 /* Display an echo area message in window W. Value is non-zero if W's
8814 height is changed. If display_last_displayed_message_p is
8815 non-zero, display the message that was last displayed, otherwise
8816 display the current message. */
8818 static int
8819 display_echo_area (struct window *w)
8821 int i, no_message_p, window_height_changed_p, count;
8823 /* Temporarily disable garbage collections while displaying the echo
8824 area. This is done because a GC can print a message itself.
8825 That message would modify the echo area buffer's contents while a
8826 redisplay of the buffer is going on, and seriously confuse
8827 redisplay. */
8828 count = inhibit_garbage_collection ();
8830 /* If there is no message, we must call display_echo_area_1
8831 nevertheless because it resizes the window. But we will have to
8832 reset the echo_area_buffer in question to nil at the end because
8833 with_echo_area_buffer will sets it to an empty buffer. */
8834 i = display_last_displayed_message_p ? 1 : 0;
8835 no_message_p = NILP (echo_area_buffer[i]);
8837 window_height_changed_p
8838 = with_echo_area_buffer (w, display_last_displayed_message_p,
8839 display_echo_area_1,
8840 (intptr_t) w, Qnil, 0, 0);
8842 if (no_message_p)
8843 echo_area_buffer[i] = Qnil;
8845 unbind_to (count, Qnil);
8846 return window_height_changed_p;
8850 /* Helper for display_echo_area. Display the current buffer which
8851 contains the current echo area message in window W, a mini-window,
8852 a pointer to which is passed in A1. A2..A4 are currently not used.
8853 Change the height of W so that all of the message is displayed.
8854 Value is non-zero if height of W was changed. */
8856 static int
8857 display_echo_area_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4)
8859 intptr_t i1 = a1;
8860 struct window *w = (struct window *) i1;
8861 Lisp_Object window;
8862 struct text_pos start;
8863 int window_height_changed_p = 0;
8865 /* Do this before displaying, so that we have a large enough glyph
8866 matrix for the display. If we can't get enough space for the
8867 whole text, display the last N lines. That works by setting w->start. */
8868 window_height_changed_p = resize_mini_window (w, 0);
8870 /* Use the starting position chosen by resize_mini_window. */
8871 SET_TEXT_POS_FROM_MARKER (start, w->start);
8873 /* Display. */
8874 clear_glyph_matrix (w->desired_matrix);
8875 XSETWINDOW (window, w);
8876 try_window (window, start, 0);
8878 return window_height_changed_p;
8882 /* Resize the echo area window to exactly the size needed for the
8883 currently displayed message, if there is one. If a mini-buffer
8884 is active, don't shrink it. */
8886 void
8887 resize_echo_area_exactly (void)
8889 if (BUFFERP (echo_area_buffer[0])
8890 && WINDOWP (echo_area_window))
8892 struct window *w = XWINDOW (echo_area_window);
8893 int resized_p;
8894 Lisp_Object resize_exactly;
8896 if (minibuf_level == 0)
8897 resize_exactly = Qt;
8898 else
8899 resize_exactly = Qnil;
8901 resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
8902 (intptr_t) w, resize_exactly,
8903 0, 0);
8904 if (resized_p)
8906 ++windows_or_buffers_changed;
8907 ++update_mode_lines;
8908 redisplay_internal ();
8914 /* Callback function for with_echo_area_buffer, when used from
8915 resize_echo_area_exactly. A1 contains a pointer to the window to
8916 resize, EXACTLY non-nil means resize the mini-window exactly to the
8917 size of the text displayed. A3 and A4 are not used. Value is what
8918 resize_mini_window returns. */
8920 static int
8921 resize_mini_window_1 (EMACS_INT a1, Lisp_Object exactly, EMACS_INT a3, EMACS_INT a4)
8923 intptr_t i1 = a1;
8924 return resize_mini_window ((struct window *) i1, !NILP (exactly));
8928 /* Resize mini-window W to fit the size of its contents. EXACT_P
8929 means size the window exactly to the size needed. Otherwise, it's
8930 only enlarged until W's buffer is empty.
8932 Set W->start to the right place to begin display. If the whole
8933 contents fit, start at the beginning. Otherwise, start so as
8934 to make the end of the contents appear. This is particularly
8935 important for y-or-n-p, but seems desirable generally.
8937 Value is non-zero if the window height has been changed. */
8940 resize_mini_window (struct window *w, int exact_p)
8942 struct frame *f = XFRAME (w->frame);
8943 int window_height_changed_p = 0;
8945 xassert (MINI_WINDOW_P (w));
8947 /* By default, start display at the beginning. */
8948 set_marker_both (w->start, w->buffer,
8949 BUF_BEGV (XBUFFER (w->buffer)),
8950 BUF_BEGV_BYTE (XBUFFER (w->buffer)));
8952 /* Don't resize windows while redisplaying a window; it would
8953 confuse redisplay functions when the size of the window they are
8954 displaying changes from under them. Such a resizing can happen,
8955 for instance, when which-func prints a long message while
8956 we are running fontification-functions. We're running these
8957 functions with safe_call which binds inhibit-redisplay to t. */
8958 if (!NILP (Vinhibit_redisplay))
8959 return 0;
8961 /* Nil means don't try to resize. */
8962 if (NILP (Vresize_mini_windows)
8963 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
8964 return 0;
8966 if (!FRAME_MINIBUF_ONLY_P (f))
8968 struct it it;
8969 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
8970 int total_height = WINDOW_TOTAL_LINES (root) + WINDOW_TOTAL_LINES (w);
8971 int height, max_height;
8972 int unit = FRAME_LINE_HEIGHT (f);
8973 struct text_pos start;
8974 struct buffer *old_current_buffer = NULL;
8976 if (current_buffer != XBUFFER (w->buffer))
8978 old_current_buffer = current_buffer;
8979 set_buffer_internal (XBUFFER (w->buffer));
8982 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
8984 /* Compute the max. number of lines specified by the user. */
8985 if (FLOATP (Vmax_mini_window_height))
8986 max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_LINES (f);
8987 else if (INTEGERP (Vmax_mini_window_height))
8988 max_height = XINT (Vmax_mini_window_height);
8989 else
8990 max_height = total_height / 4;
8992 /* Correct that max. height if it's bogus. */
8993 max_height = max (1, max_height);
8994 max_height = min (total_height, max_height);
8996 /* Find out the height of the text in the window. */
8997 if (it.line_wrap == TRUNCATE)
8998 height = 1;
8999 else
9001 last_height = 0;
9002 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
9003 if (it.max_ascent == 0 && it.max_descent == 0)
9004 height = it.current_y + last_height;
9005 else
9006 height = it.current_y + it.max_ascent + it.max_descent;
9007 height -= min (it.extra_line_spacing, it.max_extra_line_spacing);
9008 height = (height + unit - 1) / unit;
9011 /* Compute a suitable window start. */
9012 if (height > max_height)
9014 height = max_height;
9015 init_iterator (&it, w, ZV, ZV_BYTE, NULL, DEFAULT_FACE_ID);
9016 move_it_vertically_backward (&it, (height - 1) * unit);
9017 start = it.current.pos;
9019 else
9020 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
9021 SET_MARKER_FROM_TEXT_POS (w->start, start);
9023 if (EQ (Vresize_mini_windows, Qgrow_only))
9025 /* Let it grow only, until we display an empty message, in which
9026 case the window shrinks again. */
9027 if (height > WINDOW_TOTAL_LINES (w))
9029 int old_height = WINDOW_TOTAL_LINES (w);
9030 freeze_window_starts (f, 1);
9031 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
9032 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
9034 else if (height < WINDOW_TOTAL_LINES (w)
9035 && (exact_p || BEGV == ZV))
9037 int old_height = WINDOW_TOTAL_LINES (w);
9038 freeze_window_starts (f, 0);
9039 shrink_mini_window (w);
9040 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
9043 else
9045 /* Always resize to exact size needed. */
9046 if (height > WINDOW_TOTAL_LINES (w))
9048 int old_height = WINDOW_TOTAL_LINES (w);
9049 freeze_window_starts (f, 1);
9050 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
9051 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
9053 else if (height < WINDOW_TOTAL_LINES (w))
9055 int old_height = WINDOW_TOTAL_LINES (w);
9056 freeze_window_starts (f, 0);
9057 shrink_mini_window (w);
9059 if (height)
9061 freeze_window_starts (f, 1);
9062 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
9065 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
9069 if (old_current_buffer)
9070 set_buffer_internal (old_current_buffer);
9073 return window_height_changed_p;
9077 /* Value is the current message, a string, or nil if there is no
9078 current message. */
9080 Lisp_Object
9081 current_message (void)
9083 Lisp_Object msg;
9085 if (!BUFFERP (echo_area_buffer[0]))
9086 msg = Qnil;
9087 else
9089 with_echo_area_buffer (0, 0, current_message_1,
9090 (intptr_t) &msg, Qnil, 0, 0);
9091 if (NILP (msg))
9092 echo_area_buffer[0] = Qnil;
9095 return msg;
9099 static int
9100 current_message_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4)
9102 intptr_t i1 = a1;
9103 Lisp_Object *msg = (Lisp_Object *) i1;
9105 if (Z > BEG)
9106 *msg = make_buffer_string (BEG, Z, 1);
9107 else
9108 *msg = Qnil;
9109 return 0;
9113 /* Push the current message on Vmessage_stack for later restauration
9114 by restore_message. Value is non-zero if the current message isn't
9115 empty. This is a relatively infrequent operation, so it's not
9116 worth optimizing. */
9119 push_message (void)
9121 Lisp_Object msg;
9122 msg = current_message ();
9123 Vmessage_stack = Fcons (msg, Vmessage_stack);
9124 return STRINGP (msg);
9128 /* Restore message display from the top of Vmessage_stack. */
9130 void
9131 restore_message (void)
9133 Lisp_Object msg;
9135 xassert (CONSP (Vmessage_stack));
9136 msg = XCAR (Vmessage_stack);
9137 if (STRINGP (msg))
9138 message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
9139 else
9140 message3_nolog (msg, 0, 0);
9144 /* Handler for record_unwind_protect calling pop_message. */
9146 Lisp_Object
9147 pop_message_unwind (Lisp_Object dummy)
9149 pop_message ();
9150 return Qnil;
9153 /* Pop the top-most entry off Vmessage_stack. */
9155 static void
9156 pop_message (void)
9158 xassert (CONSP (Vmessage_stack));
9159 Vmessage_stack = XCDR (Vmessage_stack);
9163 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
9164 exits. If the stack is not empty, we have a missing pop_message
9165 somewhere. */
9167 void
9168 check_message_stack (void)
9170 if (!NILP (Vmessage_stack))
9171 abort ();
9175 /* Truncate to NCHARS what will be displayed in the echo area the next
9176 time we display it---but don't redisplay it now. */
9178 void
9179 truncate_echo_area (EMACS_INT nchars)
9181 if (nchars == 0)
9182 echo_area_buffer[0] = Qnil;
9183 /* A null message buffer means that the frame hasn't really been
9184 initialized yet. Error messages get reported properly by
9185 cmd_error, so this must be just an informative message; toss it. */
9186 else if (!noninteractive
9187 && INTERACTIVE
9188 && !NILP (echo_area_buffer[0]))
9190 struct frame *sf = SELECTED_FRAME ();
9191 if (FRAME_MESSAGE_BUF (sf))
9192 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil, 0, 0);
9197 /* Helper function for truncate_echo_area. Truncate the current
9198 message to at most NCHARS characters. */
9200 static int
9201 truncate_message_1 (EMACS_INT nchars, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4)
9203 if (BEG + nchars < Z)
9204 del_range (BEG + nchars, Z);
9205 if (Z == BEG)
9206 echo_area_buffer[0] = Qnil;
9207 return 0;
9211 /* Set the current message to a substring of S or STRING.
9213 If STRING is a Lisp string, set the message to the first NBYTES
9214 bytes from STRING. NBYTES zero means use the whole string. If
9215 STRING is multibyte, the message will be displayed multibyte.
9217 If S is not null, set the message to the first LEN bytes of S. LEN
9218 zero means use the whole string. MULTIBYTE_P non-zero means S is
9219 multibyte. Display the message multibyte in that case.
9221 Doesn't GC, as with_echo_area_buffer binds Qinhibit_modification_hooks
9222 to t before calling set_message_1 (which calls insert).
9225 static void
9226 set_message (const char *s, Lisp_Object string,
9227 EMACS_INT nbytes, int multibyte_p)
9229 message_enable_multibyte
9230 = ((s && multibyte_p)
9231 || (STRINGP (string) && STRING_MULTIBYTE (string)));
9233 with_echo_area_buffer (0, -1, set_message_1,
9234 (intptr_t) s, string, nbytes, multibyte_p);
9235 message_buf_print = 0;
9236 help_echo_showing_p = 0;
9240 /* Helper function for set_message. Arguments have the same meaning
9241 as there, with A1 corresponding to S and A2 corresponding to STRING
9242 This function is called with the echo area buffer being
9243 current. */
9245 static int
9246 set_message_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT nbytes, EMACS_INT multibyte_p)
9248 intptr_t i1 = a1;
9249 const char *s = (const char *) i1;
9250 const unsigned char *msg = (const unsigned char *) s;
9251 Lisp_Object string = a2;
9253 /* Change multibyteness of the echo buffer appropriately. */
9254 if (message_enable_multibyte
9255 != !NILP (BVAR (current_buffer, enable_multibyte_characters)))
9256 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
9258 BVAR (current_buffer, truncate_lines) = message_truncate_lines ? Qt : Qnil;
9259 if (!NILP (BVAR (current_buffer, bidi_display_reordering)))
9260 BVAR (current_buffer, bidi_paragraph_direction) = Qleft_to_right;
9262 /* Insert new message at BEG. */
9263 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
9265 if (STRINGP (string))
9267 EMACS_INT nchars;
9269 if (nbytes == 0)
9270 nbytes = SBYTES (string);
9271 nchars = string_byte_to_char (string, nbytes);
9273 /* This function takes care of single/multibyte conversion. We
9274 just have to ensure that the echo area buffer has the right
9275 setting of enable_multibyte_characters. */
9276 insert_from_string (string, 0, 0, nchars, nbytes, 1);
9278 else if (s)
9280 if (nbytes == 0)
9281 nbytes = strlen (s);
9283 if (multibyte_p && NILP (BVAR (current_buffer, enable_multibyte_characters)))
9285 /* Convert from multi-byte to single-byte. */
9286 EMACS_INT i;
9287 int c, n;
9288 char work[1];
9290 /* Convert a multibyte string to single-byte. */
9291 for (i = 0; i < nbytes; i += n)
9293 c = string_char_and_length (msg + i, &n);
9294 work[0] = (ASCII_CHAR_P (c)
9296 : multibyte_char_to_unibyte (c));
9297 insert_1_both (work, 1, 1, 1, 0, 0);
9300 else if (!multibyte_p
9301 && !NILP (BVAR (current_buffer, enable_multibyte_characters)))
9303 /* Convert from single-byte to multi-byte. */
9304 EMACS_INT i;
9305 int c, n;
9306 unsigned char str[MAX_MULTIBYTE_LENGTH];
9308 /* Convert a single-byte string to multibyte. */
9309 for (i = 0; i < nbytes; i++)
9311 c = msg[i];
9312 MAKE_CHAR_MULTIBYTE (c);
9313 n = CHAR_STRING (c, str);
9314 insert_1_both ((char *) str, 1, n, 1, 0, 0);
9317 else
9318 insert_1 (s, nbytes, 1, 0, 0);
9321 return 0;
9325 /* Clear messages. CURRENT_P non-zero means clear the current
9326 message. LAST_DISPLAYED_P non-zero means clear the message
9327 last displayed. */
9329 void
9330 clear_message (int current_p, int last_displayed_p)
9332 if (current_p)
9334 echo_area_buffer[0] = Qnil;
9335 message_cleared_p = 1;
9338 if (last_displayed_p)
9339 echo_area_buffer[1] = Qnil;
9341 message_buf_print = 0;
9344 /* Clear garbaged frames.
9346 This function is used where the old redisplay called
9347 redraw_garbaged_frames which in turn called redraw_frame which in
9348 turn called clear_frame. The call to clear_frame was a source of
9349 flickering. I believe a clear_frame is not necessary. It should
9350 suffice in the new redisplay to invalidate all current matrices,
9351 and ensure a complete redisplay of all windows. */
9353 static void
9354 clear_garbaged_frames (void)
9356 if (frame_garbaged)
9358 Lisp_Object tail, frame;
9359 int changed_count = 0;
9361 FOR_EACH_FRAME (tail, frame)
9363 struct frame *f = XFRAME (frame);
9365 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
9367 if (f->resized_p)
9369 Fredraw_frame (frame);
9370 f->force_flush_display_p = 1;
9372 clear_current_matrices (f);
9373 changed_count++;
9374 f->garbaged = 0;
9375 f->resized_p = 0;
9379 frame_garbaged = 0;
9380 if (changed_count)
9381 ++windows_or_buffers_changed;
9386 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
9387 is non-zero update selected_frame. Value is non-zero if the
9388 mini-windows height has been changed. */
9390 static int
9391 echo_area_display (int update_frame_p)
9393 Lisp_Object mini_window;
9394 struct window *w;
9395 struct frame *f;
9396 int window_height_changed_p = 0;
9397 struct frame *sf = SELECTED_FRAME ();
9399 mini_window = FRAME_MINIBUF_WINDOW (sf);
9400 w = XWINDOW (mini_window);
9401 f = XFRAME (WINDOW_FRAME (w));
9403 /* Don't display if frame is invisible or not yet initialized. */
9404 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
9405 return 0;
9407 #ifdef HAVE_WINDOW_SYSTEM
9408 /* When Emacs starts, selected_frame may be the initial terminal
9409 frame. If we let this through, a message would be displayed on
9410 the terminal. */
9411 if (FRAME_INITIAL_P (XFRAME (selected_frame)))
9412 return 0;
9413 #endif /* HAVE_WINDOW_SYSTEM */
9415 /* Redraw garbaged frames. */
9416 if (frame_garbaged)
9417 clear_garbaged_frames ();
9419 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
9421 echo_area_window = mini_window;
9422 window_height_changed_p = display_echo_area (w);
9423 w->must_be_updated_p = 1;
9425 /* Update the display, unless called from redisplay_internal.
9426 Also don't update the screen during redisplay itself. The
9427 update will happen at the end of redisplay, and an update
9428 here could cause confusion. */
9429 if (update_frame_p && !redisplaying_p)
9431 int n = 0;
9433 /* If the display update has been interrupted by pending
9434 input, update mode lines in the frame. Due to the
9435 pending input, it might have been that redisplay hasn't
9436 been called, so that mode lines above the echo area are
9437 garbaged. This looks odd, so we prevent it here. */
9438 if (!display_completed)
9439 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), 0);
9441 if (window_height_changed_p
9442 /* Don't do this if Emacs is shutting down. Redisplay
9443 needs to run hooks. */
9444 && !NILP (Vrun_hooks))
9446 /* Must update other windows. Likewise as in other
9447 cases, don't let this update be interrupted by
9448 pending input. */
9449 int count = SPECPDL_INDEX ();
9450 specbind (Qredisplay_dont_pause, Qt);
9451 windows_or_buffers_changed = 1;
9452 redisplay_internal ();
9453 unbind_to (count, Qnil);
9455 else if (FRAME_WINDOW_P (f) && n == 0)
9457 /* Window configuration is the same as before.
9458 Can do with a display update of the echo area,
9459 unless we displayed some mode lines. */
9460 update_single_window (w, 1);
9461 FRAME_RIF (f)->flush_display (f);
9463 else
9464 update_frame (f, 1, 1);
9466 /* If cursor is in the echo area, make sure that the next
9467 redisplay displays the minibuffer, so that the cursor will
9468 be replaced with what the minibuffer wants. */
9469 if (cursor_in_echo_area)
9470 ++windows_or_buffers_changed;
9473 else if (!EQ (mini_window, selected_window))
9474 windows_or_buffers_changed++;
9476 /* Last displayed message is now the current message. */
9477 echo_area_buffer[1] = echo_area_buffer[0];
9478 /* Inform read_char that we're not echoing. */
9479 echo_message_buffer = Qnil;
9481 /* Prevent redisplay optimization in redisplay_internal by resetting
9482 this_line_start_pos. This is done because the mini-buffer now
9483 displays the message instead of its buffer text. */
9484 if (EQ (mini_window, selected_window))
9485 CHARPOS (this_line_start_pos) = 0;
9487 return window_height_changed_p;
9492 /***********************************************************************
9493 Mode Lines and Frame Titles
9494 ***********************************************************************/
9496 /* A buffer for constructing non-propertized mode-line strings and
9497 frame titles in it; allocated from the heap in init_xdisp and
9498 resized as needed in store_mode_line_noprop_char. */
9500 static char *mode_line_noprop_buf;
9502 /* The buffer's end, and a current output position in it. */
9504 static char *mode_line_noprop_buf_end;
9505 static char *mode_line_noprop_ptr;
9507 #define MODE_LINE_NOPROP_LEN(start) \
9508 ((mode_line_noprop_ptr - mode_line_noprop_buf) - start)
9510 static enum {
9511 MODE_LINE_DISPLAY = 0,
9512 MODE_LINE_TITLE,
9513 MODE_LINE_NOPROP,
9514 MODE_LINE_STRING
9515 } mode_line_target;
9517 /* Alist that caches the results of :propertize.
9518 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
9519 static Lisp_Object mode_line_proptrans_alist;
9521 /* List of strings making up the mode-line. */
9522 static Lisp_Object mode_line_string_list;
9524 /* Base face property when building propertized mode line string. */
9525 static Lisp_Object mode_line_string_face;
9526 static Lisp_Object mode_line_string_face_prop;
9529 /* Unwind data for mode line strings */
9531 static Lisp_Object Vmode_line_unwind_vector;
9533 static Lisp_Object
9534 format_mode_line_unwind_data (struct buffer *obuf,
9535 Lisp_Object owin,
9536 int save_proptrans)
9538 Lisp_Object vector, tmp;
9540 /* Reduce consing by keeping one vector in
9541 Vwith_echo_area_save_vector. */
9542 vector = Vmode_line_unwind_vector;
9543 Vmode_line_unwind_vector = Qnil;
9545 if (NILP (vector))
9546 vector = Fmake_vector (make_number (8), Qnil);
9548 ASET (vector, 0, make_number (mode_line_target));
9549 ASET (vector, 1, make_number (MODE_LINE_NOPROP_LEN (0)));
9550 ASET (vector, 2, mode_line_string_list);
9551 ASET (vector, 3, save_proptrans ? mode_line_proptrans_alist : Qt);
9552 ASET (vector, 4, mode_line_string_face);
9553 ASET (vector, 5, mode_line_string_face_prop);
9555 if (obuf)
9556 XSETBUFFER (tmp, obuf);
9557 else
9558 tmp = Qnil;
9559 ASET (vector, 6, tmp);
9560 ASET (vector, 7, owin);
9562 return vector;
9565 static Lisp_Object
9566 unwind_format_mode_line (Lisp_Object vector)
9568 mode_line_target = XINT (AREF (vector, 0));
9569 mode_line_noprop_ptr = mode_line_noprop_buf + XINT (AREF (vector, 1));
9570 mode_line_string_list = AREF (vector, 2);
9571 if (! EQ (AREF (vector, 3), Qt))
9572 mode_line_proptrans_alist = AREF (vector, 3);
9573 mode_line_string_face = AREF (vector, 4);
9574 mode_line_string_face_prop = AREF (vector, 5);
9576 if (!NILP (AREF (vector, 7)))
9577 /* Select window before buffer, since it may change the buffer. */
9578 Fselect_window (AREF (vector, 7), Qt);
9580 if (!NILP (AREF (vector, 6)))
9582 set_buffer_internal_1 (XBUFFER (AREF (vector, 6)));
9583 ASET (vector, 6, Qnil);
9586 Vmode_line_unwind_vector = vector;
9587 return Qnil;
9591 /* Store a single character C for the frame title in mode_line_noprop_buf.
9592 Re-allocate mode_line_noprop_buf if necessary. */
9594 static void
9595 store_mode_line_noprop_char (char c)
9597 /* If output position has reached the end of the allocated buffer,
9598 double the buffer's size. */
9599 if (mode_line_noprop_ptr == mode_line_noprop_buf_end)
9601 int len = MODE_LINE_NOPROP_LEN (0);
9602 int new_size = 2 * len * sizeof *mode_line_noprop_buf;
9603 mode_line_noprop_buf = (char *) xrealloc (mode_line_noprop_buf, new_size);
9604 mode_line_noprop_buf_end = mode_line_noprop_buf + new_size;
9605 mode_line_noprop_ptr = mode_line_noprop_buf + len;
9608 *mode_line_noprop_ptr++ = c;
9612 /* Store part of a frame title in mode_line_noprop_buf, beginning at
9613 mode_line_noprop_ptr. STRING is the string to store. Do not copy
9614 characters that yield more columns than PRECISION; PRECISION <= 0
9615 means copy the whole string. Pad with spaces until FIELD_WIDTH
9616 number of characters have been copied; FIELD_WIDTH <= 0 means don't
9617 pad. Called from display_mode_element when it is used to build a
9618 frame title. */
9620 static int
9621 store_mode_line_noprop (const char *string, int field_width, int precision)
9623 const unsigned char *str = (const unsigned char *) string;
9624 int n = 0;
9625 EMACS_INT dummy, nbytes;
9627 /* Copy at most PRECISION chars from STR. */
9628 nbytes = strlen (string);
9629 n += c_string_width (str, nbytes, precision, &dummy, &nbytes);
9630 while (nbytes--)
9631 store_mode_line_noprop_char (*str++);
9633 /* Fill up with spaces until FIELD_WIDTH reached. */
9634 while (field_width > 0
9635 && n < field_width)
9637 store_mode_line_noprop_char (' ');
9638 ++n;
9641 return n;
9644 /***********************************************************************
9645 Frame Titles
9646 ***********************************************************************/
9648 #ifdef HAVE_WINDOW_SYSTEM
9650 /* Set the title of FRAME, if it has changed. The title format is
9651 Vicon_title_format if FRAME is iconified, otherwise it is
9652 frame_title_format. */
9654 static void
9655 x_consider_frame_title (Lisp_Object frame)
9657 struct frame *f = XFRAME (frame);
9659 if (FRAME_WINDOW_P (f)
9660 || FRAME_MINIBUF_ONLY_P (f)
9661 || f->explicit_name)
9663 /* Do we have more than one visible frame on this X display? */
9664 Lisp_Object tail;
9665 Lisp_Object fmt;
9666 int title_start;
9667 char *title;
9668 int len;
9669 struct it it;
9670 int count = SPECPDL_INDEX ();
9672 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
9674 Lisp_Object other_frame = XCAR (tail);
9675 struct frame *tf = XFRAME (other_frame);
9677 if (tf != f
9678 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
9679 && !FRAME_MINIBUF_ONLY_P (tf)
9680 && !EQ (other_frame, tip_frame)
9681 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
9682 break;
9685 /* Set global variable indicating that multiple frames exist. */
9686 multiple_frames = CONSP (tail);
9688 /* Switch to the buffer of selected window of the frame. Set up
9689 mode_line_target so that display_mode_element will output into
9690 mode_line_noprop_buf; then display the title. */
9691 record_unwind_protect (unwind_format_mode_line,
9692 format_mode_line_unwind_data
9693 (current_buffer, selected_window, 0));
9695 Fselect_window (f->selected_window, Qt);
9696 set_buffer_internal_1 (XBUFFER (XWINDOW (f->selected_window)->buffer));
9697 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
9699 mode_line_target = MODE_LINE_TITLE;
9700 title_start = MODE_LINE_NOPROP_LEN (0);
9701 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
9702 NULL, DEFAULT_FACE_ID);
9703 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
9704 len = MODE_LINE_NOPROP_LEN (title_start);
9705 title = mode_line_noprop_buf + title_start;
9706 unbind_to (count, Qnil);
9708 /* Set the title only if it's changed. This avoids consing in
9709 the common case where it hasn't. (If it turns out that we've
9710 already wasted too much time by walking through the list with
9711 display_mode_element, then we might need to optimize at a
9712 higher level than this.) */
9713 if (! STRINGP (f->name)
9714 || SBYTES (f->name) != len
9715 || memcmp (title, SDATA (f->name), len) != 0)
9716 x_implicitly_set_name (f, make_string (title, len), Qnil);
9720 #endif /* not HAVE_WINDOW_SYSTEM */
9725 /***********************************************************************
9726 Menu Bars
9727 ***********************************************************************/
9730 /* Prepare for redisplay by updating menu-bar item lists when
9731 appropriate. This can call eval. */
9733 void
9734 prepare_menu_bars (void)
9736 int all_windows;
9737 struct gcpro gcpro1, gcpro2;
9738 struct frame *f;
9739 Lisp_Object tooltip_frame;
9741 #ifdef HAVE_WINDOW_SYSTEM
9742 tooltip_frame = tip_frame;
9743 #else
9744 tooltip_frame = Qnil;
9745 #endif
9747 /* Update all frame titles based on their buffer names, etc. We do
9748 this before the menu bars so that the buffer-menu will show the
9749 up-to-date frame titles. */
9750 #ifdef HAVE_WINDOW_SYSTEM
9751 if (windows_or_buffers_changed || update_mode_lines)
9753 Lisp_Object tail, frame;
9755 FOR_EACH_FRAME (tail, frame)
9757 f = XFRAME (frame);
9758 if (!EQ (frame, tooltip_frame)
9759 && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)))
9760 x_consider_frame_title (frame);
9763 #endif /* HAVE_WINDOW_SYSTEM */
9765 /* Update the menu bar item lists, if appropriate. This has to be
9766 done before any actual redisplay or generation of display lines. */
9767 all_windows = (update_mode_lines
9768 || buffer_shared > 1
9769 || windows_or_buffers_changed);
9770 if (all_windows)
9772 Lisp_Object tail, frame;
9773 int count = SPECPDL_INDEX ();
9774 /* 1 means that update_menu_bar has run its hooks
9775 so any further calls to update_menu_bar shouldn't do so again. */
9776 int menu_bar_hooks_run = 0;
9778 record_unwind_save_match_data ();
9780 FOR_EACH_FRAME (tail, frame)
9782 f = XFRAME (frame);
9784 /* Ignore tooltip frame. */
9785 if (EQ (frame, tooltip_frame))
9786 continue;
9788 /* If a window on this frame changed size, report that to
9789 the user and clear the size-change flag. */
9790 if (FRAME_WINDOW_SIZES_CHANGED (f))
9792 Lisp_Object functions;
9794 /* Clear flag first in case we get an error below. */
9795 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
9796 functions = Vwindow_size_change_functions;
9797 GCPRO2 (tail, functions);
9799 while (CONSP (functions))
9801 if (!EQ (XCAR (functions), Qt))
9802 call1 (XCAR (functions), frame);
9803 functions = XCDR (functions);
9805 UNGCPRO;
9808 GCPRO1 (tail);
9809 menu_bar_hooks_run = update_menu_bar (f, 0, menu_bar_hooks_run);
9810 #ifdef HAVE_WINDOW_SYSTEM
9811 update_tool_bar (f, 0);
9812 #endif
9813 #ifdef HAVE_NS
9814 if (windows_or_buffers_changed
9815 && FRAME_NS_P (f))
9816 ns_set_doc_edited (f, Fbuffer_modified_p
9817 (XWINDOW (f->selected_window)->buffer));
9818 #endif
9819 UNGCPRO;
9822 unbind_to (count, Qnil);
9824 else
9826 struct frame *sf = SELECTED_FRAME ();
9827 update_menu_bar (sf, 1, 0);
9828 #ifdef HAVE_WINDOW_SYSTEM
9829 update_tool_bar (sf, 1);
9830 #endif
9835 /* Update the menu bar item list for frame F. This has to be done
9836 before we start to fill in any display lines, because it can call
9837 eval.
9839 If SAVE_MATCH_DATA is non-zero, we must save and restore it here.
9841 If HOOKS_RUN is 1, that means a previous call to update_menu_bar
9842 already ran the menu bar hooks for this redisplay, so there
9843 is no need to run them again. The return value is the
9844 updated value of this flag, to pass to the next call. */
9846 static int
9847 update_menu_bar (struct frame *f, int save_match_data, int hooks_run)
9849 Lisp_Object window;
9850 register struct window *w;
9852 /* If called recursively during a menu update, do nothing. This can
9853 happen when, for instance, an activate-menubar-hook causes a
9854 redisplay. */
9855 if (inhibit_menubar_update)
9856 return hooks_run;
9858 window = FRAME_SELECTED_WINDOW (f);
9859 w = XWINDOW (window);
9861 if (FRAME_WINDOW_P (f)
9863 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
9864 || defined (HAVE_NS) || defined (USE_GTK)
9865 FRAME_EXTERNAL_MENU_BAR (f)
9866 #else
9867 FRAME_MENU_BAR_LINES (f) > 0
9868 #endif
9869 : FRAME_MENU_BAR_LINES (f) > 0)
9871 /* If the user has switched buffers or windows, we need to
9872 recompute to reflect the new bindings. But we'll
9873 recompute when update_mode_lines is set too; that means
9874 that people can use force-mode-line-update to request
9875 that the menu bar be recomputed. The adverse effect on
9876 the rest of the redisplay algorithm is about the same as
9877 windows_or_buffers_changed anyway. */
9878 if (windows_or_buffers_changed
9879 /* This used to test w->update_mode_line, but we believe
9880 there is no need to recompute the menu in that case. */
9881 || update_mode_lines
9882 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
9883 < BUF_MODIFF (XBUFFER (w->buffer)))
9884 != !NILP (w->last_had_star))
9885 || ((!NILP (Vtransient_mark_mode)
9886 && !NILP (BVAR (XBUFFER (w->buffer), mark_active)))
9887 != !NILP (w->region_showing)))
9889 struct buffer *prev = current_buffer;
9890 int count = SPECPDL_INDEX ();
9892 specbind (Qinhibit_menubar_update, Qt);
9894 set_buffer_internal_1 (XBUFFER (w->buffer));
9895 if (save_match_data)
9896 record_unwind_save_match_data ();
9897 if (NILP (Voverriding_local_map_menu_flag))
9899 specbind (Qoverriding_terminal_local_map, Qnil);
9900 specbind (Qoverriding_local_map, Qnil);
9903 if (!hooks_run)
9905 /* Run the Lucid hook. */
9906 safe_run_hooks (Qactivate_menubar_hook);
9908 /* If it has changed current-menubar from previous value,
9909 really recompute the menu-bar from the value. */
9910 if (! NILP (Vlucid_menu_bar_dirty_flag))
9911 call0 (Qrecompute_lucid_menubar);
9913 safe_run_hooks (Qmenu_bar_update_hook);
9915 hooks_run = 1;
9918 XSETFRAME (Vmenu_updating_frame, f);
9919 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
9921 /* Redisplay the menu bar in case we changed it. */
9922 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
9923 || defined (HAVE_NS) || defined (USE_GTK)
9924 if (FRAME_WINDOW_P (f))
9926 #if defined (HAVE_NS)
9927 /* All frames on Mac OS share the same menubar. So only
9928 the selected frame should be allowed to set it. */
9929 if (f == SELECTED_FRAME ())
9930 #endif
9931 set_frame_menubar (f, 0, 0);
9933 else
9934 /* On a terminal screen, the menu bar is an ordinary screen
9935 line, and this makes it get updated. */
9936 w->update_mode_line = Qt;
9937 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
9938 /* In the non-toolkit version, the menu bar is an ordinary screen
9939 line, and this makes it get updated. */
9940 w->update_mode_line = Qt;
9941 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
9943 unbind_to (count, Qnil);
9944 set_buffer_internal_1 (prev);
9948 return hooks_run;
9953 /***********************************************************************
9954 Output Cursor
9955 ***********************************************************************/
9957 #ifdef HAVE_WINDOW_SYSTEM
9959 /* EXPORT:
9960 Nominal cursor position -- where to draw output.
9961 HPOS and VPOS are window relative glyph matrix coordinates.
9962 X and Y are window relative pixel coordinates. */
9964 struct cursor_pos output_cursor;
9967 /* EXPORT:
9968 Set the global variable output_cursor to CURSOR. All cursor
9969 positions are relative to updated_window. */
9971 void
9972 set_output_cursor (struct cursor_pos *cursor)
9974 output_cursor.hpos = cursor->hpos;
9975 output_cursor.vpos = cursor->vpos;
9976 output_cursor.x = cursor->x;
9977 output_cursor.y = cursor->y;
9981 /* EXPORT for RIF:
9982 Set a nominal cursor position.
9984 HPOS and VPOS are column/row positions in a window glyph matrix. X
9985 and Y are window text area relative pixel positions.
9987 If this is done during an update, updated_window will contain the
9988 window that is being updated and the position is the future output
9989 cursor position for that window. If updated_window is null, use
9990 selected_window and display the cursor at the given position. */
9992 void
9993 x_cursor_to (int vpos, int hpos, int y, int x)
9995 struct window *w;
9997 /* If updated_window is not set, work on selected_window. */
9998 if (updated_window)
9999 w = updated_window;
10000 else
10001 w = XWINDOW (selected_window);
10003 /* Set the output cursor. */
10004 output_cursor.hpos = hpos;
10005 output_cursor.vpos = vpos;
10006 output_cursor.x = x;
10007 output_cursor.y = y;
10009 /* If not called as part of an update, really display the cursor.
10010 This will also set the cursor position of W. */
10011 if (updated_window == NULL)
10013 BLOCK_INPUT;
10014 display_and_set_cursor (w, 1, hpos, vpos, x, y);
10015 if (FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
10016 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (SELECTED_FRAME ());
10017 UNBLOCK_INPUT;
10021 #endif /* HAVE_WINDOW_SYSTEM */
10024 /***********************************************************************
10025 Tool-bars
10026 ***********************************************************************/
10028 #ifdef HAVE_WINDOW_SYSTEM
10030 /* Where the mouse was last time we reported a mouse event. */
10032 FRAME_PTR last_mouse_frame;
10034 /* Tool-bar item index of the item on which a mouse button was pressed
10035 or -1. */
10037 int last_tool_bar_item;
10040 static Lisp_Object
10041 update_tool_bar_unwind (Lisp_Object frame)
10043 selected_frame = frame;
10044 return Qnil;
10047 /* Update the tool-bar item list for frame F. This has to be done
10048 before we start to fill in any display lines. Called from
10049 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
10050 and restore it here. */
10052 static void
10053 update_tool_bar (struct frame *f, int save_match_data)
10055 #if defined (USE_GTK) || defined (HAVE_NS)
10056 int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
10057 #else
10058 int do_update = WINDOWP (f->tool_bar_window)
10059 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0;
10060 #endif
10062 if (do_update)
10064 Lisp_Object window;
10065 struct window *w;
10067 window = FRAME_SELECTED_WINDOW (f);
10068 w = XWINDOW (window);
10070 /* If the user has switched buffers or windows, we need to
10071 recompute to reflect the new bindings. But we'll
10072 recompute when update_mode_lines is set too; that means
10073 that people can use force-mode-line-update to request
10074 that the menu bar be recomputed. The adverse effect on
10075 the rest of the redisplay algorithm is about the same as
10076 windows_or_buffers_changed anyway. */
10077 if (windows_or_buffers_changed
10078 || !NILP (w->update_mode_line)
10079 || update_mode_lines
10080 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
10081 < BUF_MODIFF (XBUFFER (w->buffer)))
10082 != !NILP (w->last_had_star))
10083 || ((!NILP (Vtransient_mark_mode)
10084 && !NILP (BVAR (XBUFFER (w->buffer), mark_active)))
10085 != !NILP (w->region_showing)))
10087 struct buffer *prev = current_buffer;
10088 int count = SPECPDL_INDEX ();
10089 Lisp_Object frame, new_tool_bar;
10090 int new_n_tool_bar;
10091 struct gcpro gcpro1;
10093 /* Set current_buffer to the buffer of the selected
10094 window of the frame, so that we get the right local
10095 keymaps. */
10096 set_buffer_internal_1 (XBUFFER (w->buffer));
10098 /* Save match data, if we must. */
10099 if (save_match_data)
10100 record_unwind_save_match_data ();
10102 /* Make sure that we don't accidentally use bogus keymaps. */
10103 if (NILP (Voverriding_local_map_menu_flag))
10105 specbind (Qoverriding_terminal_local_map, Qnil);
10106 specbind (Qoverriding_local_map, Qnil);
10109 GCPRO1 (new_tool_bar);
10111 /* We must temporarily set the selected frame to this frame
10112 before calling tool_bar_items, because the calculation of
10113 the tool-bar keymap uses the selected frame (see
10114 `tool-bar-make-keymap' in tool-bar.el). */
10115 record_unwind_protect (update_tool_bar_unwind, selected_frame);
10116 XSETFRAME (frame, f);
10117 selected_frame = frame;
10119 /* Build desired tool-bar items from keymaps. */
10120 new_tool_bar = tool_bar_items (Fcopy_sequence (f->tool_bar_items),
10121 &new_n_tool_bar);
10123 /* Redisplay the tool-bar if we changed it. */
10124 if (new_n_tool_bar != f->n_tool_bar_items
10125 || NILP (Fequal (new_tool_bar, f->tool_bar_items)))
10127 /* Redisplay that happens asynchronously due to an expose event
10128 may access f->tool_bar_items. Make sure we update both
10129 variables within BLOCK_INPUT so no such event interrupts. */
10130 BLOCK_INPUT;
10131 f->tool_bar_items = new_tool_bar;
10132 f->n_tool_bar_items = new_n_tool_bar;
10133 w->update_mode_line = Qt;
10134 UNBLOCK_INPUT;
10137 UNGCPRO;
10139 unbind_to (count, Qnil);
10140 set_buffer_internal_1 (prev);
10146 /* Set F->desired_tool_bar_string to a Lisp string representing frame
10147 F's desired tool-bar contents. F->tool_bar_items must have
10148 been set up previously by calling prepare_menu_bars. */
10150 static void
10151 build_desired_tool_bar_string (struct frame *f)
10153 int i, size, size_needed;
10154 struct gcpro gcpro1, gcpro2, gcpro3;
10155 Lisp_Object image, plist, props;
10157 image = plist = props = Qnil;
10158 GCPRO3 (image, plist, props);
10160 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
10161 Otherwise, make a new string. */
10163 /* The size of the string we might be able to reuse. */
10164 size = (STRINGP (f->desired_tool_bar_string)
10165 ? SCHARS (f->desired_tool_bar_string)
10166 : 0);
10168 /* We need one space in the string for each image. */
10169 size_needed = f->n_tool_bar_items;
10171 /* Reuse f->desired_tool_bar_string, if possible. */
10172 if (size < size_needed || NILP (f->desired_tool_bar_string))
10173 f->desired_tool_bar_string = Fmake_string (make_number (size_needed),
10174 make_number (' '));
10175 else
10177 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
10178 Fremove_text_properties (make_number (0), make_number (size),
10179 props, f->desired_tool_bar_string);
10182 /* Put a `display' property on the string for the images to display,
10183 put a `menu_item' property on tool-bar items with a value that
10184 is the index of the item in F's tool-bar item vector. */
10185 for (i = 0; i < f->n_tool_bar_items; ++i)
10187 #define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
10189 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
10190 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
10191 int hmargin, vmargin, relief, idx, end;
10193 /* If image is a vector, choose the image according to the
10194 button state. */
10195 image = PROP (TOOL_BAR_ITEM_IMAGES);
10196 if (VECTORP (image))
10198 if (enabled_p)
10199 idx = (selected_p
10200 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
10201 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
10202 else
10203 idx = (selected_p
10204 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
10205 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
10207 xassert (ASIZE (image) >= idx);
10208 image = AREF (image, idx);
10210 else
10211 idx = -1;
10213 /* Ignore invalid image specifications. */
10214 if (!valid_image_p (image))
10215 continue;
10217 /* Display the tool-bar button pressed, or depressed. */
10218 plist = Fcopy_sequence (XCDR (image));
10220 /* Compute margin and relief to draw. */
10221 relief = (tool_bar_button_relief >= 0
10222 ? tool_bar_button_relief
10223 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
10224 hmargin = vmargin = relief;
10226 if (INTEGERP (Vtool_bar_button_margin)
10227 && XINT (Vtool_bar_button_margin) > 0)
10229 hmargin += XFASTINT (Vtool_bar_button_margin);
10230 vmargin += XFASTINT (Vtool_bar_button_margin);
10232 else if (CONSP (Vtool_bar_button_margin))
10234 if (INTEGERP (XCAR (Vtool_bar_button_margin))
10235 && XINT (XCAR (Vtool_bar_button_margin)) > 0)
10236 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
10238 if (INTEGERP (XCDR (Vtool_bar_button_margin))
10239 && XINT (XCDR (Vtool_bar_button_margin)) > 0)
10240 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
10243 if (auto_raise_tool_bar_buttons_p)
10245 /* Add a `:relief' property to the image spec if the item is
10246 selected. */
10247 if (selected_p)
10249 plist = Fplist_put (plist, QCrelief, make_number (-relief));
10250 hmargin -= relief;
10251 vmargin -= relief;
10254 else
10256 /* If image is selected, display it pressed, i.e. with a
10257 negative relief. If it's not selected, display it with a
10258 raised relief. */
10259 plist = Fplist_put (plist, QCrelief,
10260 (selected_p
10261 ? make_number (-relief)
10262 : make_number (relief)));
10263 hmargin -= relief;
10264 vmargin -= relief;
10267 /* Put a margin around the image. */
10268 if (hmargin || vmargin)
10270 if (hmargin == vmargin)
10271 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
10272 else
10273 plist = Fplist_put (plist, QCmargin,
10274 Fcons (make_number (hmargin),
10275 make_number (vmargin)));
10278 /* If button is not enabled, and we don't have special images
10279 for the disabled state, make the image appear disabled by
10280 applying an appropriate algorithm to it. */
10281 if (!enabled_p && idx < 0)
10282 plist = Fplist_put (plist, QCconversion, Qdisabled);
10284 /* Put a `display' text property on the string for the image to
10285 display. Put a `menu-item' property on the string that gives
10286 the start of this item's properties in the tool-bar items
10287 vector. */
10288 image = Fcons (Qimage, plist);
10289 props = list4 (Qdisplay, image,
10290 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS));
10292 /* Let the last image hide all remaining spaces in the tool bar
10293 string. The string can be longer than needed when we reuse a
10294 previous string. */
10295 if (i + 1 == f->n_tool_bar_items)
10296 end = SCHARS (f->desired_tool_bar_string);
10297 else
10298 end = i + 1;
10299 Fadd_text_properties (make_number (i), make_number (end),
10300 props, f->desired_tool_bar_string);
10301 #undef PROP
10304 UNGCPRO;
10308 /* Display one line of the tool-bar of frame IT->f.
10310 HEIGHT specifies the desired height of the tool-bar line.
10311 If the actual height of the glyph row is less than HEIGHT, the
10312 row's height is increased to HEIGHT, and the icons are centered
10313 vertically in the new height.
10315 If HEIGHT is -1, we are counting needed tool-bar lines, so don't
10316 count a final empty row in case the tool-bar width exactly matches
10317 the window width.
10320 static void
10321 display_tool_bar_line (struct it *it, int height)
10323 struct glyph_row *row = it->glyph_row;
10324 int max_x = it->last_visible_x;
10325 struct glyph *last;
10327 prepare_desired_row (row);
10328 row->y = it->current_y;
10330 /* Note that this isn't made use of if the face hasn't a box,
10331 so there's no need to check the face here. */
10332 it->start_of_box_run_p = 1;
10334 while (it->current_x < max_x)
10336 int x, n_glyphs_before, i, nglyphs;
10337 struct it it_before;
10339 /* Get the next display element. */
10340 if (!get_next_display_element (it))
10342 /* Don't count empty row if we are counting needed tool-bar lines. */
10343 if (height < 0 && !it->hpos)
10344 return;
10345 break;
10348 /* Produce glyphs. */
10349 n_glyphs_before = row->used[TEXT_AREA];
10350 it_before = *it;
10352 PRODUCE_GLYPHS (it);
10354 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
10355 i = 0;
10356 x = it_before.current_x;
10357 while (i < nglyphs)
10359 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
10361 if (x + glyph->pixel_width > max_x)
10363 /* Glyph doesn't fit on line. Backtrack. */
10364 row->used[TEXT_AREA] = n_glyphs_before;
10365 *it = it_before;
10366 /* If this is the only glyph on this line, it will never fit on the
10367 tool-bar, so skip it. But ensure there is at least one glyph,
10368 so we don't accidentally disable the tool-bar. */
10369 if (n_glyphs_before == 0
10370 && (it->vpos > 0 || IT_STRING_CHARPOS (*it) < it->end_charpos-1))
10371 break;
10372 goto out;
10375 ++it->hpos;
10376 x += glyph->pixel_width;
10377 ++i;
10380 /* Stop at line ends. */
10381 if (ITERATOR_AT_END_OF_LINE_P (it))
10382 break;
10384 set_iterator_to_next (it, 1);
10387 out:;
10389 row->displays_text_p = row->used[TEXT_AREA] != 0;
10391 /* Use default face for the border below the tool bar.
10393 FIXME: When auto-resize-tool-bars is grow-only, there is
10394 no additional border below the possibly empty tool-bar lines.
10395 So to make the extra empty lines look "normal", we have to
10396 use the tool-bar face for the border too. */
10397 if (!row->displays_text_p && !EQ (Vauto_resize_tool_bars, Qgrow_only))
10398 it->face_id = DEFAULT_FACE_ID;
10400 extend_face_to_end_of_line (it);
10401 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
10402 last->right_box_line_p = 1;
10403 if (last == row->glyphs[TEXT_AREA])
10404 last->left_box_line_p = 1;
10406 /* Make line the desired height and center it vertically. */
10407 if ((height -= it->max_ascent + it->max_descent) > 0)
10409 /* Don't add more than one line height. */
10410 height %= FRAME_LINE_HEIGHT (it->f);
10411 it->max_ascent += height / 2;
10412 it->max_descent += (height + 1) / 2;
10415 compute_line_metrics (it);
10417 /* If line is empty, make it occupy the rest of the tool-bar. */
10418 if (!row->displays_text_p)
10420 row->height = row->phys_height = it->last_visible_y - row->y;
10421 row->visible_height = row->height;
10422 row->ascent = row->phys_ascent = 0;
10423 row->extra_line_spacing = 0;
10426 row->full_width_p = 1;
10427 row->continued_p = 0;
10428 row->truncated_on_left_p = 0;
10429 row->truncated_on_right_p = 0;
10431 it->current_x = it->hpos = 0;
10432 it->current_y += row->height;
10433 ++it->vpos;
10434 ++it->glyph_row;
10438 /* Max tool-bar height. */
10440 #define MAX_FRAME_TOOL_BAR_HEIGHT(f) \
10441 ((FRAME_LINE_HEIGHT (f) * FRAME_LINES (f)))
10443 /* Value is the number of screen lines needed to make all tool-bar
10444 items of frame F visible. The number of actual rows needed is
10445 returned in *N_ROWS if non-NULL. */
10447 static int
10448 tool_bar_lines_needed (struct frame *f, int *n_rows)
10450 struct window *w = XWINDOW (f->tool_bar_window);
10451 struct it it;
10452 /* tool_bar_lines_needed is called from redisplay_tool_bar after building
10453 the desired matrix, so use (unused) mode-line row as temporary row to
10454 avoid destroying the first tool-bar row. */
10455 struct glyph_row *temp_row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
10457 /* Initialize an iterator for iteration over
10458 F->desired_tool_bar_string in the tool-bar window of frame F. */
10459 init_iterator (&it, w, -1, -1, temp_row, TOOL_BAR_FACE_ID);
10460 it.first_visible_x = 0;
10461 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
10462 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
10464 while (!ITERATOR_AT_END_P (&it))
10466 clear_glyph_row (temp_row);
10467 it.glyph_row = temp_row;
10468 display_tool_bar_line (&it, -1);
10470 clear_glyph_row (temp_row);
10472 /* f->n_tool_bar_rows == 0 means "unknown"; -1 means no tool-bar. */
10473 if (n_rows)
10474 *n_rows = it.vpos > 0 ? it.vpos : -1;
10476 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
10480 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
10481 0, 1, 0,
10482 doc: /* Return the number of lines occupied by the tool bar of FRAME. */)
10483 (Lisp_Object frame)
10485 struct frame *f;
10486 struct window *w;
10487 int nlines = 0;
10489 if (NILP (frame))
10490 frame = selected_frame;
10491 else
10492 CHECK_FRAME (frame);
10493 f = XFRAME (frame);
10495 if (WINDOWP (f->tool_bar_window)
10496 || (w = XWINDOW (f->tool_bar_window),
10497 WINDOW_TOTAL_LINES (w) > 0))
10499 update_tool_bar (f, 1);
10500 if (f->n_tool_bar_items)
10502 build_desired_tool_bar_string (f);
10503 nlines = tool_bar_lines_needed (f, NULL);
10507 return make_number (nlines);
10511 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
10512 height should be changed. */
10514 static int
10515 redisplay_tool_bar (struct frame *f)
10517 struct window *w;
10518 struct it it;
10519 struct glyph_row *row;
10521 #if defined (USE_GTK) || defined (HAVE_NS)
10522 if (FRAME_EXTERNAL_TOOL_BAR (f))
10523 update_frame_tool_bar (f);
10524 return 0;
10525 #endif
10527 /* If frame hasn't a tool-bar window or if it is zero-height, don't
10528 do anything. This means you must start with tool-bar-lines
10529 non-zero to get the auto-sizing effect. Or in other words, you
10530 can turn off tool-bars by specifying tool-bar-lines zero. */
10531 if (!WINDOWP (f->tool_bar_window)
10532 || (w = XWINDOW (f->tool_bar_window),
10533 WINDOW_TOTAL_LINES (w) == 0))
10534 return 0;
10536 /* Set up an iterator for the tool-bar window. */
10537 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
10538 it.first_visible_x = 0;
10539 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
10540 row = it.glyph_row;
10542 /* Build a string that represents the contents of the tool-bar. */
10543 build_desired_tool_bar_string (f);
10544 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
10546 if (f->n_tool_bar_rows == 0)
10548 int nlines;
10550 if ((nlines = tool_bar_lines_needed (f, &f->n_tool_bar_rows),
10551 nlines != WINDOW_TOTAL_LINES (w)))
10553 Lisp_Object frame;
10554 int old_height = WINDOW_TOTAL_LINES (w);
10556 XSETFRAME (frame, f);
10557 Fmodify_frame_parameters (frame,
10558 Fcons (Fcons (Qtool_bar_lines,
10559 make_number (nlines)),
10560 Qnil));
10561 if (WINDOW_TOTAL_LINES (w) != old_height)
10563 clear_glyph_matrix (w->desired_matrix);
10564 fonts_changed_p = 1;
10565 return 1;
10570 /* Display as many lines as needed to display all tool-bar items. */
10572 if (f->n_tool_bar_rows > 0)
10574 int border, rows, height, extra;
10576 if (INTEGERP (Vtool_bar_border))
10577 border = XINT (Vtool_bar_border);
10578 else if (EQ (Vtool_bar_border, Qinternal_border_width))
10579 border = FRAME_INTERNAL_BORDER_WIDTH (f);
10580 else if (EQ (Vtool_bar_border, Qborder_width))
10581 border = f->border_width;
10582 else
10583 border = 0;
10584 if (border < 0)
10585 border = 0;
10587 rows = f->n_tool_bar_rows;
10588 height = max (1, (it.last_visible_y - border) / rows);
10589 extra = it.last_visible_y - border - height * rows;
10591 while (it.current_y < it.last_visible_y)
10593 int h = 0;
10594 if (extra > 0 && rows-- > 0)
10596 h = (extra + rows - 1) / rows;
10597 extra -= h;
10599 display_tool_bar_line (&it, height + h);
10602 else
10604 while (it.current_y < it.last_visible_y)
10605 display_tool_bar_line (&it, 0);
10608 /* It doesn't make much sense to try scrolling in the tool-bar
10609 window, so don't do it. */
10610 w->desired_matrix->no_scrolling_p = 1;
10611 w->must_be_updated_p = 1;
10613 if (!NILP (Vauto_resize_tool_bars))
10615 int max_tool_bar_height = MAX_FRAME_TOOL_BAR_HEIGHT (f);
10616 int change_height_p = 0;
10618 /* If we couldn't display everything, change the tool-bar's
10619 height if there is room for more. */
10620 if (IT_STRING_CHARPOS (it) < it.end_charpos
10621 && it.current_y < max_tool_bar_height)
10622 change_height_p = 1;
10624 row = it.glyph_row - 1;
10626 /* If there are blank lines at the end, except for a partially
10627 visible blank line at the end that is smaller than
10628 FRAME_LINE_HEIGHT, change the tool-bar's height. */
10629 if (!row->displays_text_p
10630 && row->height >= FRAME_LINE_HEIGHT (f))
10631 change_height_p = 1;
10633 /* If row displays tool-bar items, but is partially visible,
10634 change the tool-bar's height. */
10635 if (row->displays_text_p
10636 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y
10637 && MATRIX_ROW_BOTTOM_Y (row) < max_tool_bar_height)
10638 change_height_p = 1;
10640 /* Resize windows as needed by changing the `tool-bar-lines'
10641 frame parameter. */
10642 if (change_height_p)
10644 Lisp_Object frame;
10645 int old_height = WINDOW_TOTAL_LINES (w);
10646 int nrows;
10647 int nlines = tool_bar_lines_needed (f, &nrows);
10649 change_height_p = ((EQ (Vauto_resize_tool_bars, Qgrow_only)
10650 && !f->minimize_tool_bar_window_p)
10651 ? (nlines > old_height)
10652 : (nlines != old_height));
10653 f->minimize_tool_bar_window_p = 0;
10655 if (change_height_p)
10657 XSETFRAME (frame, f);
10658 Fmodify_frame_parameters (frame,
10659 Fcons (Fcons (Qtool_bar_lines,
10660 make_number (nlines)),
10661 Qnil));
10662 if (WINDOW_TOTAL_LINES (w) != old_height)
10664 clear_glyph_matrix (w->desired_matrix);
10665 f->n_tool_bar_rows = nrows;
10666 fonts_changed_p = 1;
10667 return 1;
10673 f->minimize_tool_bar_window_p = 0;
10674 return 0;
10678 /* Get information about the tool-bar item which is displayed in GLYPH
10679 on frame F. Return in *PROP_IDX the index where tool-bar item
10680 properties start in F->tool_bar_items. Value is zero if
10681 GLYPH doesn't display a tool-bar item. */
10683 static int
10684 tool_bar_item_info (struct frame *f, struct glyph *glyph, int *prop_idx)
10686 Lisp_Object prop;
10687 int success_p;
10688 int charpos;
10690 /* This function can be called asynchronously, which means we must
10691 exclude any possibility that Fget_text_property signals an
10692 error. */
10693 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
10694 charpos = max (0, charpos);
10696 /* Get the text property `menu-item' at pos. The value of that
10697 property is the start index of this item's properties in
10698 F->tool_bar_items. */
10699 prop = Fget_text_property (make_number (charpos),
10700 Qmenu_item, f->current_tool_bar_string);
10701 if (INTEGERP (prop))
10703 *prop_idx = XINT (prop);
10704 success_p = 1;
10706 else
10707 success_p = 0;
10709 return success_p;
10713 /* Get information about the tool-bar item at position X/Y on frame F.
10714 Return in *GLYPH a pointer to the glyph of the tool-bar item in
10715 the current matrix of the tool-bar window of F, or NULL if not
10716 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
10717 item in F->tool_bar_items. Value is
10719 -1 if X/Y is not on a tool-bar item
10720 0 if X/Y is on the same item that was highlighted before.
10721 1 otherwise. */
10723 static int
10724 get_tool_bar_item (struct frame *f, int x, int y, struct glyph **glyph,
10725 int *hpos, int *vpos, int *prop_idx)
10727 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
10728 struct window *w = XWINDOW (f->tool_bar_window);
10729 int area;
10731 /* Find the glyph under X/Y. */
10732 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
10733 if (*glyph == NULL)
10734 return -1;
10736 /* Get the start of this tool-bar item's properties in
10737 f->tool_bar_items. */
10738 if (!tool_bar_item_info (f, *glyph, prop_idx))
10739 return -1;
10741 /* Is mouse on the highlighted item? */
10742 if (EQ (f->tool_bar_window, hlinfo->mouse_face_window)
10743 && *vpos >= hlinfo->mouse_face_beg_row
10744 && *vpos <= hlinfo->mouse_face_end_row
10745 && (*vpos > hlinfo->mouse_face_beg_row
10746 || *hpos >= hlinfo->mouse_face_beg_col)
10747 && (*vpos < hlinfo->mouse_face_end_row
10748 || *hpos < hlinfo->mouse_face_end_col
10749 || hlinfo->mouse_face_past_end))
10750 return 0;
10752 return 1;
10756 /* EXPORT:
10757 Handle mouse button event on the tool-bar of frame F, at
10758 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
10759 0 for button release. MODIFIERS is event modifiers for button
10760 release. */
10762 void
10763 handle_tool_bar_click (struct frame *f, int x, int y, int down_p,
10764 unsigned int modifiers)
10766 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
10767 struct window *w = XWINDOW (f->tool_bar_window);
10768 int hpos, vpos, prop_idx;
10769 struct glyph *glyph;
10770 Lisp_Object enabled_p;
10772 /* If not on the highlighted tool-bar item, return. */
10773 frame_to_window_pixel_xy (w, &x, &y);
10774 if (get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0)
10775 return;
10777 /* If item is disabled, do nothing. */
10778 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
10779 if (NILP (enabled_p))
10780 return;
10782 if (down_p)
10784 /* Show item in pressed state. */
10785 show_mouse_face (hlinfo, DRAW_IMAGE_SUNKEN);
10786 hlinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN;
10787 last_tool_bar_item = prop_idx;
10789 else
10791 Lisp_Object key, frame;
10792 struct input_event event;
10793 EVENT_INIT (event);
10795 /* Show item in released state. */
10796 show_mouse_face (hlinfo, DRAW_IMAGE_RAISED);
10797 hlinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
10799 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
10801 XSETFRAME (frame, f);
10802 event.kind = TOOL_BAR_EVENT;
10803 event.frame_or_window = frame;
10804 event.arg = frame;
10805 kbd_buffer_store_event (&event);
10807 event.kind = TOOL_BAR_EVENT;
10808 event.frame_or_window = frame;
10809 event.arg = key;
10810 event.modifiers = modifiers;
10811 kbd_buffer_store_event (&event);
10812 last_tool_bar_item = -1;
10817 /* Possibly highlight a tool-bar item on frame F when mouse moves to
10818 tool-bar window-relative coordinates X/Y. Called from
10819 note_mouse_highlight. */
10821 static void
10822 note_tool_bar_highlight (struct frame *f, int x, int y)
10824 Lisp_Object window = f->tool_bar_window;
10825 struct window *w = XWINDOW (window);
10826 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
10827 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
10828 int hpos, vpos;
10829 struct glyph *glyph;
10830 struct glyph_row *row;
10831 int i;
10832 Lisp_Object enabled_p;
10833 int prop_idx;
10834 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
10835 int mouse_down_p, rc;
10837 /* Function note_mouse_highlight is called with negative X/Y
10838 values when mouse moves outside of the frame. */
10839 if (x <= 0 || y <= 0)
10841 clear_mouse_face (hlinfo);
10842 return;
10845 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
10846 if (rc < 0)
10848 /* Not on tool-bar item. */
10849 clear_mouse_face (hlinfo);
10850 return;
10852 else if (rc == 0)
10853 /* On same tool-bar item as before. */
10854 goto set_help_echo;
10856 clear_mouse_face (hlinfo);
10858 /* Mouse is down, but on different tool-bar item? */
10859 mouse_down_p = (dpyinfo->grabbed
10860 && f == last_mouse_frame
10861 && FRAME_LIVE_P (f));
10862 if (mouse_down_p
10863 && last_tool_bar_item != prop_idx)
10864 return;
10866 hlinfo->mouse_face_image_state = DRAW_NORMAL_TEXT;
10867 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
10869 /* If tool-bar item is not enabled, don't highlight it. */
10870 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
10871 if (!NILP (enabled_p))
10873 /* Compute the x-position of the glyph. In front and past the
10874 image is a space. We include this in the highlighted area. */
10875 row = MATRIX_ROW (w->current_matrix, vpos);
10876 for (i = x = 0; i < hpos; ++i)
10877 x += row->glyphs[TEXT_AREA][i].pixel_width;
10879 /* Record this as the current active region. */
10880 hlinfo->mouse_face_beg_col = hpos;
10881 hlinfo->mouse_face_beg_row = vpos;
10882 hlinfo->mouse_face_beg_x = x;
10883 hlinfo->mouse_face_beg_y = row->y;
10884 hlinfo->mouse_face_past_end = 0;
10886 hlinfo->mouse_face_end_col = hpos + 1;
10887 hlinfo->mouse_face_end_row = vpos;
10888 hlinfo->mouse_face_end_x = x + glyph->pixel_width;
10889 hlinfo->mouse_face_end_y = row->y;
10890 hlinfo->mouse_face_window = window;
10891 hlinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
10893 /* Display it as active. */
10894 show_mouse_face (hlinfo, draw);
10895 hlinfo->mouse_face_image_state = draw;
10898 set_help_echo:
10900 /* Set help_echo_string to a help string to display for this tool-bar item.
10901 XTread_socket does the rest. */
10902 help_echo_object = help_echo_window = Qnil;
10903 help_echo_pos = -1;
10904 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
10905 if (NILP (help_echo_string))
10906 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
10909 #endif /* HAVE_WINDOW_SYSTEM */
10913 /************************************************************************
10914 Horizontal scrolling
10915 ************************************************************************/
10917 static int hscroll_window_tree (Lisp_Object);
10918 static int hscroll_windows (Lisp_Object);
10920 /* For all leaf windows in the window tree rooted at WINDOW, set their
10921 hscroll value so that PT is (i) visible in the window, and (ii) so
10922 that it is not within a certain margin at the window's left and
10923 right border. Value is non-zero if any window's hscroll has been
10924 changed. */
10926 static int
10927 hscroll_window_tree (Lisp_Object window)
10929 int hscrolled_p = 0;
10930 int hscroll_relative_p = FLOATP (Vhscroll_step);
10931 int hscroll_step_abs = 0;
10932 double hscroll_step_rel = 0;
10934 if (hscroll_relative_p)
10936 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
10937 if (hscroll_step_rel < 0)
10939 hscroll_relative_p = 0;
10940 hscroll_step_abs = 0;
10943 else if (INTEGERP (Vhscroll_step))
10945 hscroll_step_abs = XINT (Vhscroll_step);
10946 if (hscroll_step_abs < 0)
10947 hscroll_step_abs = 0;
10949 else
10950 hscroll_step_abs = 0;
10952 while (WINDOWP (window))
10954 struct window *w = XWINDOW (window);
10956 if (WINDOWP (w->hchild))
10957 hscrolled_p |= hscroll_window_tree (w->hchild);
10958 else if (WINDOWP (w->vchild))
10959 hscrolled_p |= hscroll_window_tree (w->vchild);
10960 else if (w->cursor.vpos >= 0)
10962 int h_margin;
10963 int text_area_width;
10964 struct glyph_row *current_cursor_row
10965 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
10966 struct glyph_row *desired_cursor_row
10967 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
10968 struct glyph_row *cursor_row
10969 = (desired_cursor_row->enabled_p
10970 ? desired_cursor_row
10971 : current_cursor_row);
10973 text_area_width = window_box_width (w, TEXT_AREA);
10975 /* Scroll when cursor is inside this scroll margin. */
10976 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
10978 if (!NILP (Fbuffer_local_value (Qauto_hscroll_mode, w->buffer))
10979 && ((XFASTINT (w->hscroll)
10980 && w->cursor.x <= h_margin)
10981 || (cursor_row->enabled_p
10982 && cursor_row->truncated_on_right_p
10983 && (w->cursor.x >= text_area_width - h_margin))))
10985 struct it it;
10986 int hscroll;
10987 struct buffer *saved_current_buffer;
10988 EMACS_INT pt;
10989 int wanted_x;
10991 /* Find point in a display of infinite width. */
10992 saved_current_buffer = current_buffer;
10993 current_buffer = XBUFFER (w->buffer);
10995 if (w == XWINDOW (selected_window))
10996 pt = PT;
10997 else
10999 pt = marker_position (w->pointm);
11000 pt = max (BEGV, pt);
11001 pt = min (ZV, pt);
11004 /* Move iterator to pt starting at cursor_row->start in
11005 a line with infinite width. */
11006 init_to_row_start (&it, w, cursor_row);
11007 it.last_visible_x = INFINITY;
11008 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
11009 current_buffer = saved_current_buffer;
11011 /* Position cursor in window. */
11012 if (!hscroll_relative_p && hscroll_step_abs == 0)
11013 hscroll = max (0, (it.current_x
11014 - (ITERATOR_AT_END_OF_LINE_P (&it)
11015 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
11016 : (text_area_width / 2))))
11017 / FRAME_COLUMN_WIDTH (it.f);
11018 else if (w->cursor.x >= text_area_width - h_margin)
11020 if (hscroll_relative_p)
11021 wanted_x = text_area_width * (1 - hscroll_step_rel)
11022 - h_margin;
11023 else
11024 wanted_x = text_area_width
11025 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
11026 - h_margin;
11027 hscroll
11028 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
11030 else
11032 if (hscroll_relative_p)
11033 wanted_x = text_area_width * hscroll_step_rel
11034 + h_margin;
11035 else
11036 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
11037 + h_margin;
11038 hscroll
11039 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
11041 hscroll = max (hscroll, XFASTINT (w->min_hscroll));
11043 /* Don't call Fset_window_hscroll if value hasn't
11044 changed because it will prevent redisplay
11045 optimizations. */
11046 if (XFASTINT (w->hscroll) != hscroll)
11048 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
11049 w->hscroll = make_number (hscroll);
11050 hscrolled_p = 1;
11055 window = w->next;
11058 /* Value is non-zero if hscroll of any leaf window has been changed. */
11059 return hscrolled_p;
11063 /* Set hscroll so that cursor is visible and not inside horizontal
11064 scroll margins for all windows in the tree rooted at WINDOW. See
11065 also hscroll_window_tree above. Value is non-zero if any window's
11066 hscroll has been changed. If it has, desired matrices on the frame
11067 of WINDOW are cleared. */
11069 static int
11070 hscroll_windows (Lisp_Object window)
11072 int hscrolled_p = hscroll_window_tree (window);
11073 if (hscrolled_p)
11074 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
11075 return hscrolled_p;
11080 /************************************************************************
11081 Redisplay
11082 ************************************************************************/
11084 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
11085 to a non-zero value. This is sometimes handy to have in a debugger
11086 session. */
11088 #if GLYPH_DEBUG
11090 /* First and last unchanged row for try_window_id. */
11092 int debug_first_unchanged_at_end_vpos;
11093 int debug_last_unchanged_at_beg_vpos;
11095 /* Delta vpos and y. */
11097 int debug_dvpos, debug_dy;
11099 /* Delta in characters and bytes for try_window_id. */
11101 EMACS_INT debug_delta, debug_delta_bytes;
11103 /* Values of window_end_pos and window_end_vpos at the end of
11104 try_window_id. */
11106 EMACS_INT debug_end_vpos;
11108 /* Append a string to W->desired_matrix->method. FMT is a printf
11109 format string. A1...A9 are a supplement for a variable-length
11110 argument list. If trace_redisplay_p is non-zero also printf the
11111 resulting string to stderr. */
11113 static void
11114 debug_method_add (w, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
11115 struct window *w;
11116 char *fmt;
11117 int a1, a2, a3, a4, a5, a6, a7, a8, a9;
11119 char buffer[512];
11120 char *method = w->desired_matrix->method;
11121 int len = strlen (method);
11122 int size = sizeof w->desired_matrix->method;
11123 int remaining = size - len - 1;
11125 sprintf (buffer, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
11126 if (len && remaining)
11128 method[len] = '|';
11129 --remaining, ++len;
11132 strncpy (method + len, buffer, remaining);
11134 if (trace_redisplay_p)
11135 fprintf (stderr, "%p (%s): %s\n",
11137 ((BUFFERP (w->buffer)
11138 && STRINGP (XBUFFER (w->buffer)->name))
11139 ? SSDATA (XBUFFER (w->buffer)->name)
11140 : "no buffer"),
11141 buffer);
11144 #endif /* GLYPH_DEBUG */
11147 /* Value is non-zero if all changes in window W, which displays
11148 current_buffer, are in the text between START and END. START is a
11149 buffer position, END is given as a distance from Z. Used in
11150 redisplay_internal for display optimization. */
11152 static INLINE int
11153 text_outside_line_unchanged_p (struct window *w,
11154 EMACS_INT start, EMACS_INT end)
11156 int unchanged_p = 1;
11158 /* If text or overlays have changed, see where. */
11159 if (XFASTINT (w->last_modified) < MODIFF
11160 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
11162 /* Gap in the line? */
11163 if (GPT < start || Z - GPT < end)
11164 unchanged_p = 0;
11166 /* Changes start in front of the line, or end after it? */
11167 if (unchanged_p
11168 && (BEG_UNCHANGED < start - 1
11169 || END_UNCHANGED < end))
11170 unchanged_p = 0;
11172 /* If selective display, can't optimize if changes start at the
11173 beginning of the line. */
11174 if (unchanged_p
11175 && INTEGERP (BVAR (current_buffer, selective_display))
11176 && XINT (BVAR (current_buffer, selective_display)) > 0
11177 && (BEG_UNCHANGED < start || GPT <= start))
11178 unchanged_p = 0;
11180 /* If there are overlays at the start or end of the line, these
11181 may have overlay strings with newlines in them. A change at
11182 START, for instance, may actually concern the display of such
11183 overlay strings as well, and they are displayed on different
11184 lines. So, quickly rule out this case. (For the future, it
11185 might be desirable to implement something more telling than
11186 just BEG/END_UNCHANGED.) */
11187 if (unchanged_p)
11189 if (BEG + BEG_UNCHANGED == start
11190 && overlay_touches_p (start))
11191 unchanged_p = 0;
11192 if (END_UNCHANGED == end
11193 && overlay_touches_p (Z - end))
11194 unchanged_p = 0;
11197 /* Under bidi reordering, adding or deleting a character in the
11198 beginning of a paragraph, before the first strong directional
11199 character, can change the base direction of the paragraph (unless
11200 the buffer specifies a fixed paragraph direction), which will
11201 require to redisplay the whole paragraph. It might be worthwhile
11202 to find the paragraph limits and widen the range of redisplayed
11203 lines to that, but for now just give up this optimization. */
11204 if (!NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering))
11205 && NILP (BVAR (XBUFFER (w->buffer), bidi_paragraph_direction)))
11206 unchanged_p = 0;
11209 return unchanged_p;
11213 /* Do a frame update, taking possible shortcuts into account. This is
11214 the main external entry point for redisplay.
11216 If the last redisplay displayed an echo area message and that message
11217 is no longer requested, we clear the echo area or bring back the
11218 mini-buffer if that is in use. */
11220 void
11221 redisplay (void)
11223 redisplay_internal ();
11227 static Lisp_Object
11228 overlay_arrow_string_or_property (Lisp_Object var)
11230 Lisp_Object val;
11232 if (val = Fget (var, Qoverlay_arrow_string), STRINGP (val))
11233 return val;
11235 return Voverlay_arrow_string;
11238 /* Return 1 if there are any overlay-arrows in current_buffer. */
11239 static int
11240 overlay_arrow_in_current_buffer_p (void)
11242 Lisp_Object vlist;
11244 for (vlist = Voverlay_arrow_variable_list;
11245 CONSP (vlist);
11246 vlist = XCDR (vlist))
11248 Lisp_Object var = XCAR (vlist);
11249 Lisp_Object val;
11251 if (!SYMBOLP (var))
11252 continue;
11253 val = find_symbol_value (var);
11254 if (MARKERP (val)
11255 && current_buffer == XMARKER (val)->buffer)
11256 return 1;
11258 return 0;
11262 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
11263 has changed. */
11265 static int
11266 overlay_arrows_changed_p (void)
11268 Lisp_Object vlist;
11270 for (vlist = Voverlay_arrow_variable_list;
11271 CONSP (vlist);
11272 vlist = XCDR (vlist))
11274 Lisp_Object var = XCAR (vlist);
11275 Lisp_Object val, pstr;
11277 if (!SYMBOLP (var))
11278 continue;
11279 val = find_symbol_value (var);
11280 if (!MARKERP (val))
11281 continue;
11282 if (! EQ (COERCE_MARKER (val),
11283 Fget (var, Qlast_arrow_position))
11284 || ! (pstr = overlay_arrow_string_or_property (var),
11285 EQ (pstr, Fget (var, Qlast_arrow_string))))
11286 return 1;
11288 return 0;
11291 /* Mark overlay arrows to be updated on next redisplay. */
11293 static void
11294 update_overlay_arrows (int up_to_date)
11296 Lisp_Object vlist;
11298 for (vlist = Voverlay_arrow_variable_list;
11299 CONSP (vlist);
11300 vlist = XCDR (vlist))
11302 Lisp_Object var = XCAR (vlist);
11304 if (!SYMBOLP (var))
11305 continue;
11307 if (up_to_date > 0)
11309 Lisp_Object val = find_symbol_value (var);
11310 Fput (var, Qlast_arrow_position,
11311 COERCE_MARKER (val));
11312 Fput (var, Qlast_arrow_string,
11313 overlay_arrow_string_or_property (var));
11315 else if (up_to_date < 0
11316 || !NILP (Fget (var, Qlast_arrow_position)))
11318 Fput (var, Qlast_arrow_position, Qt);
11319 Fput (var, Qlast_arrow_string, Qt);
11325 /* Return overlay arrow string to display at row.
11326 Return integer (bitmap number) for arrow bitmap in left fringe.
11327 Return nil if no overlay arrow. */
11329 static Lisp_Object
11330 overlay_arrow_at_row (struct it *it, struct glyph_row *row)
11332 Lisp_Object vlist;
11334 for (vlist = Voverlay_arrow_variable_list;
11335 CONSP (vlist);
11336 vlist = XCDR (vlist))
11338 Lisp_Object var = XCAR (vlist);
11339 Lisp_Object val;
11341 if (!SYMBOLP (var))
11342 continue;
11344 val = find_symbol_value (var);
11346 if (MARKERP (val)
11347 && current_buffer == XMARKER (val)->buffer
11348 && (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
11350 if (FRAME_WINDOW_P (it->f)
11351 /* FIXME: if ROW->reversed_p is set, this should test
11352 the right fringe, not the left one. */
11353 && WINDOW_LEFT_FRINGE_WIDTH (it->w) > 0)
11355 #ifdef HAVE_WINDOW_SYSTEM
11356 if (val = Fget (var, Qoverlay_arrow_bitmap), SYMBOLP (val))
11358 int fringe_bitmap;
11359 if ((fringe_bitmap = lookup_fringe_bitmap (val)) != 0)
11360 return make_number (fringe_bitmap);
11362 #endif
11363 return make_number (-1); /* Use default arrow bitmap */
11365 return overlay_arrow_string_or_property (var);
11369 return Qnil;
11372 /* Return 1 if point moved out of or into a composition. Otherwise
11373 return 0. PREV_BUF and PREV_PT are the last point buffer and
11374 position. BUF and PT are the current point buffer and position. */
11376 static int
11377 check_point_in_composition (struct buffer *prev_buf, EMACS_INT prev_pt,
11378 struct buffer *buf, EMACS_INT pt)
11380 EMACS_INT start, end;
11381 Lisp_Object prop;
11382 Lisp_Object buffer;
11384 XSETBUFFER (buffer, buf);
11385 /* Check a composition at the last point if point moved within the
11386 same buffer. */
11387 if (prev_buf == buf)
11389 if (prev_pt == pt)
11390 /* Point didn't move. */
11391 return 0;
11393 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
11394 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
11395 && COMPOSITION_VALID_P (start, end, prop)
11396 && start < prev_pt && end > prev_pt)
11397 /* The last point was within the composition. Return 1 iff
11398 point moved out of the composition. */
11399 return (pt <= start || pt >= end);
11402 /* Check a composition at the current point. */
11403 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
11404 && find_composition (pt, -1, &start, &end, &prop, buffer)
11405 && COMPOSITION_VALID_P (start, end, prop)
11406 && start < pt && end > pt);
11410 /* Reconsider the setting of B->clip_changed which is displayed
11411 in window W. */
11413 static INLINE void
11414 reconsider_clip_changes (struct window *w, struct buffer *b)
11416 if (b->clip_changed
11417 && !NILP (w->window_end_valid)
11418 && w->current_matrix->buffer == b
11419 && w->current_matrix->zv == BUF_ZV (b)
11420 && w->current_matrix->begv == BUF_BEGV (b))
11421 b->clip_changed = 0;
11423 /* If display wasn't paused, and W is not a tool bar window, see if
11424 point has been moved into or out of a composition. In that case,
11425 we set b->clip_changed to 1 to force updating the screen. If
11426 b->clip_changed has already been set to 1, we can skip this
11427 check. */
11428 if (!b->clip_changed
11429 && BUFFERP (w->buffer) && !NILP (w->window_end_valid))
11431 EMACS_INT pt;
11433 if (w == XWINDOW (selected_window))
11434 pt = PT;
11435 else
11436 pt = marker_position (w->pointm);
11438 if ((w->current_matrix->buffer != XBUFFER (w->buffer)
11439 || pt != XINT (w->last_point))
11440 && check_point_in_composition (w->current_matrix->buffer,
11441 XINT (w->last_point),
11442 XBUFFER (w->buffer), pt))
11443 b->clip_changed = 1;
11448 /* Select FRAME to forward the values of frame-local variables into C
11449 variables so that the redisplay routines can access those values
11450 directly. */
11452 static void
11453 select_frame_for_redisplay (Lisp_Object frame)
11455 Lisp_Object tail, tem;
11456 Lisp_Object old = selected_frame;
11457 struct Lisp_Symbol *sym;
11459 xassert (FRAMEP (frame) && FRAME_LIVE_P (XFRAME (frame)));
11461 selected_frame = frame;
11463 do {
11464 for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail))
11465 if (CONSP (XCAR (tail))
11466 && (tem = XCAR (XCAR (tail)),
11467 SYMBOLP (tem))
11468 && (sym = indirect_variable (XSYMBOL (tem)),
11469 sym->redirect == SYMBOL_LOCALIZED)
11470 && sym->val.blv->frame_local)
11471 /* Use find_symbol_value rather than Fsymbol_value
11472 to avoid an error if it is void. */
11473 find_symbol_value (tem);
11474 } while (!EQ (frame, old) && (frame = old, 1));
11478 #define STOP_POLLING \
11479 do { if (! polling_stopped_here) stop_polling (); \
11480 polling_stopped_here = 1; } while (0)
11482 #define RESUME_POLLING \
11483 do { if (polling_stopped_here) start_polling (); \
11484 polling_stopped_here = 0; } while (0)
11487 /* Perhaps in the future avoid recentering windows if it
11488 is not necessary; currently that causes some problems. */
11490 static void
11491 redisplay_internal (void)
11493 struct window *w = XWINDOW (selected_window);
11494 struct window *sw;
11495 struct frame *fr;
11496 int pending;
11497 int must_finish = 0;
11498 struct text_pos tlbufpos, tlendpos;
11499 int number_of_visible_frames;
11500 int count, count1;
11501 struct frame *sf;
11502 int polling_stopped_here = 0;
11503 Lisp_Object old_frame = selected_frame;
11505 /* Non-zero means redisplay has to consider all windows on all
11506 frames. Zero means, only selected_window is considered. */
11507 int consider_all_windows_p;
11509 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
11511 /* No redisplay if running in batch mode or frame is not yet fully
11512 initialized, or redisplay is explicitly turned off by setting
11513 Vinhibit_redisplay. */
11514 if (FRAME_INITIAL_P (SELECTED_FRAME ())
11515 || !NILP (Vinhibit_redisplay))
11516 return;
11518 /* Don't examine these until after testing Vinhibit_redisplay.
11519 When Emacs is shutting down, perhaps because its connection to
11520 X has dropped, we should not look at them at all. */
11521 fr = XFRAME (w->frame);
11522 sf = SELECTED_FRAME ();
11524 if (!fr->glyphs_initialized_p)
11525 return;
11527 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS)
11528 if (popup_activated ())
11529 return;
11530 #endif
11532 /* I don't think this happens but let's be paranoid. */
11533 if (redisplaying_p)
11534 return;
11536 /* Record a function that resets redisplaying_p to its old value
11537 when we leave this function. */
11538 count = SPECPDL_INDEX ();
11539 record_unwind_protect (unwind_redisplay,
11540 Fcons (make_number (redisplaying_p), selected_frame));
11541 ++redisplaying_p;
11542 specbind (Qinhibit_free_realized_faces, Qnil);
11545 Lisp_Object tail, frame;
11547 FOR_EACH_FRAME (tail, frame)
11549 struct frame *f = XFRAME (frame);
11550 f->already_hscrolled_p = 0;
11554 retry:
11555 /* Remember the currently selected window. */
11556 sw = w;
11558 if (!EQ (old_frame, selected_frame)
11559 && FRAME_LIVE_P (XFRAME (old_frame)))
11560 /* When running redisplay, we play a bit fast-and-loose and allow e.g.
11561 selected_frame and selected_window to be temporarily out-of-sync so
11562 when we come back here via `goto retry', we need to resync because we
11563 may need to run Elisp code (via prepare_menu_bars). */
11564 select_frame_for_redisplay (old_frame);
11566 pending = 0;
11567 reconsider_clip_changes (w, current_buffer);
11568 last_escape_glyph_frame = NULL;
11569 last_escape_glyph_face_id = (1 << FACE_ID_BITS);
11570 last_glyphless_glyph_frame = NULL;
11571 last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
11573 /* If new fonts have been loaded that make a glyph matrix adjustment
11574 necessary, do it. */
11575 if (fonts_changed_p)
11577 adjust_glyphs (NULL);
11578 ++windows_or_buffers_changed;
11579 fonts_changed_p = 0;
11582 /* If face_change_count is non-zero, init_iterator will free all
11583 realized faces, which includes the faces referenced from current
11584 matrices. So, we can't reuse current matrices in this case. */
11585 if (face_change_count)
11586 ++windows_or_buffers_changed;
11588 if ((FRAME_TERMCAP_P (sf) || FRAME_MSDOS_P (sf))
11589 && FRAME_TTY (sf)->previous_frame != sf)
11591 /* Since frames on a single ASCII terminal share the same
11592 display area, displaying a different frame means redisplay
11593 the whole thing. */
11594 windows_or_buffers_changed++;
11595 SET_FRAME_GARBAGED (sf);
11596 #ifndef DOS_NT
11597 set_tty_color_mode (FRAME_TTY (sf), sf);
11598 #endif
11599 FRAME_TTY (sf)->previous_frame = sf;
11602 /* Set the visible flags for all frames. Do this before checking
11603 for resized or garbaged frames; they want to know if their frames
11604 are visible. See the comment in frame.h for
11605 FRAME_SAMPLE_VISIBILITY. */
11607 Lisp_Object tail, frame;
11609 number_of_visible_frames = 0;
11611 FOR_EACH_FRAME (tail, frame)
11613 struct frame *f = XFRAME (frame);
11615 FRAME_SAMPLE_VISIBILITY (f);
11616 if (FRAME_VISIBLE_P (f))
11617 ++number_of_visible_frames;
11618 clear_desired_matrices (f);
11622 /* Notice any pending interrupt request to change frame size. */
11623 do_pending_window_change (1);
11625 /* do_pending_window_change could change the selected_window due to
11626 frame resizing which makes the selected window too small. */
11627 if (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw)
11629 sw = w;
11630 reconsider_clip_changes (w, current_buffer);
11633 /* Clear frames marked as garbaged. */
11634 if (frame_garbaged)
11635 clear_garbaged_frames ();
11637 /* Build menubar and tool-bar items. */
11638 if (NILP (Vmemory_full))
11639 prepare_menu_bars ();
11641 if (windows_or_buffers_changed)
11642 update_mode_lines++;
11644 /* Detect case that we need to write or remove a star in the mode line. */
11645 if ((SAVE_MODIFF < MODIFF) != !NILP (w->last_had_star))
11647 w->update_mode_line = Qt;
11648 if (buffer_shared > 1)
11649 update_mode_lines++;
11652 /* Avoid invocation of point motion hooks by `current_column' below. */
11653 count1 = SPECPDL_INDEX ();
11654 specbind (Qinhibit_point_motion_hooks, Qt);
11656 /* If %c is in the mode line, update it if needed. */
11657 if (!NILP (w->column_number_displayed)
11658 /* This alternative quickly identifies a common case
11659 where no change is needed. */
11660 && !(PT == XFASTINT (w->last_point)
11661 && XFASTINT (w->last_modified) >= MODIFF
11662 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
11663 && (XFASTINT (w->column_number_displayed) != current_column ()))
11664 w->update_mode_line = Qt;
11666 unbind_to (count1, Qnil);
11668 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
11670 /* The variable buffer_shared is set in redisplay_window and
11671 indicates that we redisplay a buffer in different windows. See
11672 there. */
11673 consider_all_windows_p = (update_mode_lines || buffer_shared > 1
11674 || cursor_type_changed);
11676 /* If specs for an arrow have changed, do thorough redisplay
11677 to ensure we remove any arrow that should no longer exist. */
11678 if (overlay_arrows_changed_p ())
11679 consider_all_windows_p = windows_or_buffers_changed = 1;
11681 /* Normally the message* functions will have already displayed and
11682 updated the echo area, but the frame may have been trashed, or
11683 the update may have been preempted, so display the echo area
11684 again here. Checking message_cleared_p captures the case that
11685 the echo area should be cleared. */
11686 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
11687 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
11688 || (message_cleared_p
11689 && minibuf_level == 0
11690 /* If the mini-window is currently selected, this means the
11691 echo-area doesn't show through. */
11692 && !MINI_WINDOW_P (XWINDOW (selected_window))))
11694 int window_height_changed_p = echo_area_display (0);
11695 must_finish = 1;
11697 /* If we don't display the current message, don't clear the
11698 message_cleared_p flag, because, if we did, we wouldn't clear
11699 the echo area in the next redisplay which doesn't preserve
11700 the echo area. */
11701 if (!display_last_displayed_message_p)
11702 message_cleared_p = 0;
11704 if (fonts_changed_p)
11705 goto retry;
11706 else if (window_height_changed_p)
11708 consider_all_windows_p = 1;
11709 ++update_mode_lines;
11710 ++windows_or_buffers_changed;
11712 /* If window configuration was changed, frames may have been
11713 marked garbaged. Clear them or we will experience
11714 surprises wrt scrolling. */
11715 if (frame_garbaged)
11716 clear_garbaged_frames ();
11719 else if (EQ (selected_window, minibuf_window)
11720 && (current_buffer->clip_changed
11721 || XFASTINT (w->last_modified) < MODIFF
11722 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
11723 && resize_mini_window (w, 0))
11725 /* Resized active mini-window to fit the size of what it is
11726 showing if its contents might have changed. */
11727 must_finish = 1;
11728 /* FIXME: this causes all frames to be updated, which seems unnecessary
11729 since only the current frame needs to be considered. This function needs
11730 to be rewritten with two variables, consider_all_windows and
11731 consider_all_frames. */
11732 consider_all_windows_p = 1;
11733 ++windows_or_buffers_changed;
11734 ++update_mode_lines;
11736 /* If window configuration was changed, frames may have been
11737 marked garbaged. Clear them or we will experience
11738 surprises wrt scrolling. */
11739 if (frame_garbaged)
11740 clear_garbaged_frames ();
11744 /* If showing the region, and mark has changed, we must redisplay
11745 the whole window. The assignment to this_line_start_pos prevents
11746 the optimization directly below this if-statement. */
11747 if (((!NILP (Vtransient_mark_mode)
11748 && !NILP (BVAR (XBUFFER (w->buffer), mark_active)))
11749 != !NILP (w->region_showing))
11750 || (!NILP (w->region_showing)
11751 && !EQ (w->region_showing,
11752 Fmarker_position (BVAR (XBUFFER (w->buffer), mark)))))
11753 CHARPOS (this_line_start_pos) = 0;
11755 /* Optimize the case that only the line containing the cursor in the
11756 selected window has changed. Variables starting with this_ are
11757 set in display_line and record information about the line
11758 containing the cursor. */
11759 tlbufpos = this_line_start_pos;
11760 tlendpos = this_line_end_pos;
11761 if (!consider_all_windows_p
11762 && CHARPOS (tlbufpos) > 0
11763 && NILP (w->update_mode_line)
11764 && !current_buffer->clip_changed
11765 && !current_buffer->prevent_redisplay_optimizations_p
11766 && FRAME_VISIBLE_P (XFRAME (w->frame))
11767 && !FRAME_OBSCURED_P (XFRAME (w->frame))
11768 /* Make sure recorded data applies to current buffer, etc. */
11769 && this_line_buffer == current_buffer
11770 && current_buffer == XBUFFER (w->buffer)
11771 && NILP (w->force_start)
11772 && NILP (w->optional_new_start)
11773 /* Point must be on the line that we have info recorded about. */
11774 && PT >= CHARPOS (tlbufpos)
11775 && PT <= Z - CHARPOS (tlendpos)
11776 /* All text outside that line, including its final newline,
11777 must be unchanged. */
11778 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
11779 CHARPOS (tlendpos)))
11781 if (CHARPOS (tlbufpos) > BEGV
11782 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
11783 && (CHARPOS (tlbufpos) == ZV
11784 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
11785 /* Former continuation line has disappeared by becoming empty. */
11786 goto cancel;
11787 else if (XFASTINT (w->last_modified) < MODIFF
11788 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF
11789 || MINI_WINDOW_P (w))
11791 /* We have to handle the case of continuation around a
11792 wide-column character (see the comment in indent.c around
11793 line 1340).
11795 For instance, in the following case:
11797 -------- Insert --------
11798 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
11799 J_I_ ==> J_I_ `^^' are cursors.
11800 ^^ ^^
11801 -------- --------
11803 As we have to redraw the line above, we cannot use this
11804 optimization. */
11806 struct it it;
11807 int line_height_before = this_line_pixel_height;
11809 /* Note that start_display will handle the case that the
11810 line starting at tlbufpos is a continuation line. */
11811 start_display (&it, w, tlbufpos);
11813 /* Implementation note: It this still necessary? */
11814 if (it.current_x != this_line_start_x)
11815 goto cancel;
11817 TRACE ((stderr, "trying display optimization 1\n"));
11818 w->cursor.vpos = -1;
11819 overlay_arrow_seen = 0;
11820 it.vpos = this_line_vpos;
11821 it.current_y = this_line_y;
11822 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
11823 display_line (&it);
11825 /* If line contains point, is not continued,
11826 and ends at same distance from eob as before, we win. */
11827 if (w->cursor.vpos >= 0
11828 /* Line is not continued, otherwise this_line_start_pos
11829 would have been set to 0 in display_line. */
11830 && CHARPOS (this_line_start_pos)
11831 /* Line ends as before. */
11832 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
11833 /* Line has same height as before. Otherwise other lines
11834 would have to be shifted up or down. */
11835 && this_line_pixel_height == line_height_before)
11837 /* If this is not the window's last line, we must adjust
11838 the charstarts of the lines below. */
11839 if (it.current_y < it.last_visible_y)
11841 struct glyph_row *row
11842 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
11843 EMACS_INT delta, delta_bytes;
11845 /* We used to distinguish between two cases here,
11846 conditioned by Z - CHARPOS (tlendpos) == ZV, for
11847 when the line ends in a newline or the end of the
11848 buffer's accessible portion. But both cases did
11849 the same, so they were collapsed. */
11850 delta = (Z
11851 - CHARPOS (tlendpos)
11852 - MATRIX_ROW_START_CHARPOS (row));
11853 delta_bytes = (Z_BYTE
11854 - BYTEPOS (tlendpos)
11855 - MATRIX_ROW_START_BYTEPOS (row));
11857 increment_matrix_positions (w->current_matrix,
11858 this_line_vpos + 1,
11859 w->current_matrix->nrows,
11860 delta, delta_bytes);
11863 /* If this row displays text now but previously didn't,
11864 or vice versa, w->window_end_vpos may have to be
11865 adjusted. */
11866 if ((it.glyph_row - 1)->displays_text_p)
11868 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
11869 XSETINT (w->window_end_vpos, this_line_vpos);
11871 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
11872 && this_line_vpos > 0)
11873 XSETINT (w->window_end_vpos, this_line_vpos - 1);
11874 w->window_end_valid = Qnil;
11876 /* Update hint: No need to try to scroll in update_window. */
11877 w->desired_matrix->no_scrolling_p = 1;
11879 #if GLYPH_DEBUG
11880 *w->desired_matrix->method = 0;
11881 debug_method_add (w, "optimization 1");
11882 #endif
11883 #ifdef HAVE_WINDOW_SYSTEM
11884 update_window_fringes (w, 0);
11885 #endif
11886 goto update;
11888 else
11889 goto cancel;
11891 else if (/* Cursor position hasn't changed. */
11892 PT == XFASTINT (w->last_point)
11893 /* Make sure the cursor was last displayed
11894 in this window. Otherwise we have to reposition it. */
11895 && 0 <= w->cursor.vpos
11896 && WINDOW_TOTAL_LINES (w) > w->cursor.vpos)
11898 if (!must_finish)
11900 do_pending_window_change (1);
11901 /* If selected_window changed, redisplay again. */
11902 if (WINDOWP (selected_window)
11903 && (w = XWINDOW (selected_window)) != sw)
11904 goto retry;
11906 /* We used to always goto end_of_redisplay here, but this
11907 isn't enough if we have a blinking cursor. */
11908 if (w->cursor_off_p == w->last_cursor_off_p)
11909 goto end_of_redisplay;
11911 goto update;
11913 /* If highlighting the region, or if the cursor is in the echo area,
11914 then we can't just move the cursor. */
11915 else if (! (!NILP (Vtransient_mark_mode)
11916 && !NILP (BVAR (current_buffer, mark_active)))
11917 && (EQ (selected_window, BVAR (current_buffer, last_selected_window))
11918 || highlight_nonselected_windows)
11919 && NILP (w->region_showing)
11920 && NILP (Vshow_trailing_whitespace)
11921 && !cursor_in_echo_area)
11923 struct it it;
11924 struct glyph_row *row;
11926 /* Skip from tlbufpos to PT and see where it is. Note that
11927 PT may be in invisible text. If so, we will end at the
11928 next visible position. */
11929 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
11930 NULL, DEFAULT_FACE_ID);
11931 it.current_x = this_line_start_x;
11932 it.current_y = this_line_y;
11933 it.vpos = this_line_vpos;
11935 /* The call to move_it_to stops in front of PT, but
11936 moves over before-strings. */
11937 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
11939 if (it.vpos == this_line_vpos
11940 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
11941 row->enabled_p))
11943 xassert (this_line_vpos == it.vpos);
11944 xassert (this_line_y == it.current_y);
11945 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11946 #if GLYPH_DEBUG
11947 *w->desired_matrix->method = 0;
11948 debug_method_add (w, "optimization 3");
11949 #endif
11950 goto update;
11952 else
11953 goto cancel;
11956 cancel:
11957 /* Text changed drastically or point moved off of line. */
11958 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
11961 CHARPOS (this_line_start_pos) = 0;
11962 consider_all_windows_p |= buffer_shared > 1;
11963 ++clear_face_cache_count;
11964 #ifdef HAVE_WINDOW_SYSTEM
11965 ++clear_image_cache_count;
11966 #endif
11968 /* Build desired matrices, and update the display. If
11969 consider_all_windows_p is non-zero, do it for all windows on all
11970 frames. Otherwise do it for selected_window, only. */
11972 if (consider_all_windows_p)
11974 Lisp_Object tail, frame;
11976 FOR_EACH_FRAME (tail, frame)
11977 XFRAME (frame)->updated_p = 0;
11979 /* Recompute # windows showing selected buffer. This will be
11980 incremented each time such a window is displayed. */
11981 buffer_shared = 0;
11983 FOR_EACH_FRAME (tail, frame)
11985 struct frame *f = XFRAME (frame);
11987 if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf)
11989 if (! EQ (frame, selected_frame))
11990 /* Select the frame, for the sake of frame-local
11991 variables. */
11992 select_frame_for_redisplay (frame);
11994 /* Mark all the scroll bars to be removed; we'll redeem
11995 the ones we want when we redisplay their windows. */
11996 if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
11997 FRAME_TERMINAL (f)->condemn_scroll_bars_hook (f);
11999 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
12000 redisplay_windows (FRAME_ROOT_WINDOW (f));
12002 /* The X error handler may have deleted that frame. */
12003 if (!FRAME_LIVE_P (f))
12004 continue;
12006 /* Any scroll bars which redisplay_windows should have
12007 nuked should now go away. */
12008 if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
12009 FRAME_TERMINAL (f)->judge_scroll_bars_hook (f);
12011 /* If fonts changed, display again. */
12012 /* ??? rms: I suspect it is a mistake to jump all the way
12013 back to retry here. It should just retry this frame. */
12014 if (fonts_changed_p)
12015 goto retry;
12017 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
12019 /* See if we have to hscroll. */
12020 if (!f->already_hscrolled_p)
12022 f->already_hscrolled_p = 1;
12023 if (hscroll_windows (f->root_window))
12024 goto retry;
12027 /* Prevent various kinds of signals during display
12028 update. stdio is not robust about handling
12029 signals, which can cause an apparent I/O
12030 error. */
12031 if (interrupt_input)
12032 unrequest_sigio ();
12033 STOP_POLLING;
12035 /* Update the display. */
12036 set_window_update_flags (XWINDOW (f->root_window), 1);
12037 pending |= update_frame (f, 0, 0);
12038 f->updated_p = 1;
12043 if (!EQ (old_frame, selected_frame)
12044 && FRAME_LIVE_P (XFRAME (old_frame)))
12045 /* We played a bit fast-and-loose above and allowed selected_frame
12046 and selected_window to be temporarily out-of-sync but let's make
12047 sure this stays contained. */
12048 select_frame_for_redisplay (old_frame);
12049 eassert (EQ (XFRAME (selected_frame)->selected_window, selected_window));
12051 if (!pending)
12053 /* Do the mark_window_display_accurate after all windows have
12054 been redisplayed because this call resets flags in buffers
12055 which are needed for proper redisplay. */
12056 FOR_EACH_FRAME (tail, frame)
12058 struct frame *f = XFRAME (frame);
12059 if (f->updated_p)
12061 mark_window_display_accurate (f->root_window, 1);
12062 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
12063 FRAME_TERMINAL (f)->frame_up_to_date_hook (f);
12068 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
12070 Lisp_Object mini_window;
12071 struct frame *mini_frame;
12073 displayed_buffer = XBUFFER (XWINDOW (selected_window)->buffer);
12074 /* Use list_of_error, not Qerror, so that
12075 we catch only errors and don't run the debugger. */
12076 internal_condition_case_1 (redisplay_window_1, selected_window,
12077 list_of_error,
12078 redisplay_window_error);
12080 /* Compare desired and current matrices, perform output. */
12082 update:
12083 /* If fonts changed, display again. */
12084 if (fonts_changed_p)
12085 goto retry;
12087 /* Prevent various kinds of signals during display update.
12088 stdio is not robust about handling signals,
12089 which can cause an apparent I/O error. */
12090 if (interrupt_input)
12091 unrequest_sigio ();
12092 STOP_POLLING;
12094 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
12096 if (hscroll_windows (selected_window))
12097 goto retry;
12099 XWINDOW (selected_window)->must_be_updated_p = 1;
12100 pending = update_frame (sf, 0, 0);
12103 /* We may have called echo_area_display at the top of this
12104 function. If the echo area is on another frame, that may
12105 have put text on a frame other than the selected one, so the
12106 above call to update_frame would not have caught it. Catch
12107 it here. */
12108 mini_window = FRAME_MINIBUF_WINDOW (sf);
12109 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
12111 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
12113 XWINDOW (mini_window)->must_be_updated_p = 1;
12114 pending |= update_frame (mini_frame, 0, 0);
12115 if (!pending && hscroll_windows (mini_window))
12116 goto retry;
12120 /* If display was paused because of pending input, make sure we do a
12121 thorough update the next time. */
12122 if (pending)
12124 /* Prevent the optimization at the beginning of
12125 redisplay_internal that tries a single-line update of the
12126 line containing the cursor in the selected window. */
12127 CHARPOS (this_line_start_pos) = 0;
12129 /* Let the overlay arrow be updated the next time. */
12130 update_overlay_arrows (0);
12132 /* If we pause after scrolling, some rows in the current
12133 matrices of some windows are not valid. */
12134 if (!WINDOW_FULL_WIDTH_P (w)
12135 && !FRAME_WINDOW_P (XFRAME (w->frame)))
12136 update_mode_lines = 1;
12138 else
12140 if (!consider_all_windows_p)
12142 /* This has already been done above if
12143 consider_all_windows_p is set. */
12144 mark_window_display_accurate_1 (w, 1);
12146 /* Say overlay arrows are up to date. */
12147 update_overlay_arrows (1);
12149 if (FRAME_TERMINAL (sf)->frame_up_to_date_hook != 0)
12150 FRAME_TERMINAL (sf)->frame_up_to_date_hook (sf);
12153 update_mode_lines = 0;
12154 windows_or_buffers_changed = 0;
12155 cursor_type_changed = 0;
12158 /* Start SIGIO interrupts coming again. Having them off during the
12159 code above makes it less likely one will discard output, but not
12160 impossible, since there might be stuff in the system buffer here.
12161 But it is much hairier to try to do anything about that. */
12162 if (interrupt_input)
12163 request_sigio ();
12164 RESUME_POLLING;
12166 /* If a frame has become visible which was not before, redisplay
12167 again, so that we display it. Expose events for such a frame
12168 (which it gets when becoming visible) don't call the parts of
12169 redisplay constructing glyphs, so simply exposing a frame won't
12170 display anything in this case. So, we have to display these
12171 frames here explicitly. */
12172 if (!pending)
12174 Lisp_Object tail, frame;
12175 int new_count = 0;
12177 FOR_EACH_FRAME (tail, frame)
12179 int this_is_visible = 0;
12181 if (XFRAME (frame)->visible)
12182 this_is_visible = 1;
12183 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
12184 if (XFRAME (frame)->visible)
12185 this_is_visible = 1;
12187 if (this_is_visible)
12188 new_count++;
12191 if (new_count != number_of_visible_frames)
12192 windows_or_buffers_changed++;
12195 /* Change frame size now if a change is pending. */
12196 do_pending_window_change (1);
12198 /* If we just did a pending size change, or have additional
12199 visible frames, or selected_window changed, redisplay again. */
12200 if ((windows_or_buffers_changed && !pending)
12201 || (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw))
12202 goto retry;
12204 /* Clear the face and image caches.
12206 We used to do this only if consider_all_windows_p. But the cache
12207 needs to be cleared if a timer creates images in the current
12208 buffer (e.g. the test case in Bug#6230). */
12210 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
12212 clear_face_cache (0);
12213 clear_face_cache_count = 0;
12216 #ifdef HAVE_WINDOW_SYSTEM
12217 if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT)
12219 clear_image_caches (Qnil);
12220 clear_image_cache_count = 0;
12222 #endif /* HAVE_WINDOW_SYSTEM */
12224 end_of_redisplay:
12225 unbind_to (count, Qnil);
12226 RESUME_POLLING;
12230 /* Redisplay, but leave alone any recent echo area message unless
12231 another message has been requested in its place.
12233 This is useful in situations where you need to redisplay but no
12234 user action has occurred, making it inappropriate for the message
12235 area to be cleared. See tracking_off and
12236 wait_reading_process_output for examples of these situations.
12238 FROM_WHERE is an integer saying from where this function was
12239 called. This is useful for debugging. */
12241 void
12242 redisplay_preserve_echo_area (int from_where)
12244 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
12246 if (!NILP (echo_area_buffer[1]))
12248 /* We have a previously displayed message, but no current
12249 message. Redisplay the previous message. */
12250 display_last_displayed_message_p = 1;
12251 redisplay_internal ();
12252 display_last_displayed_message_p = 0;
12254 else
12255 redisplay_internal ();
12257 if (FRAME_RIF (SELECTED_FRAME ()) != NULL
12258 && FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
12259 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (NULL);
12263 /* Function registered with record_unwind_protect in
12264 redisplay_internal. Reset redisplaying_p to the value it had
12265 before redisplay_internal was called, and clear
12266 prevent_freeing_realized_faces_p. It also selects the previously
12267 selected frame, unless it has been deleted (by an X connection
12268 failure during redisplay, for example). */
12270 static Lisp_Object
12271 unwind_redisplay (Lisp_Object val)
12273 Lisp_Object old_redisplaying_p, old_frame;
12275 old_redisplaying_p = XCAR (val);
12276 redisplaying_p = XFASTINT (old_redisplaying_p);
12277 old_frame = XCDR (val);
12278 if (! EQ (old_frame, selected_frame)
12279 && FRAME_LIVE_P (XFRAME (old_frame)))
12280 select_frame_for_redisplay (old_frame);
12281 return Qnil;
12285 /* Mark the display of window W as accurate or inaccurate. If
12286 ACCURATE_P is non-zero mark display of W as accurate. If
12287 ACCURATE_P is zero, arrange for W to be redisplayed the next time
12288 redisplay_internal is called. */
12290 static void
12291 mark_window_display_accurate_1 (struct window *w, int accurate_p)
12293 if (BUFFERP (w->buffer))
12295 struct buffer *b = XBUFFER (w->buffer);
12297 w->last_modified
12298 = make_number (accurate_p ? BUF_MODIFF (b) : 0);
12299 w->last_overlay_modified
12300 = make_number (accurate_p ? BUF_OVERLAY_MODIFF (b) : 0);
12301 w->last_had_star
12302 = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b) ? Qt : Qnil;
12304 if (accurate_p)
12306 b->clip_changed = 0;
12307 b->prevent_redisplay_optimizations_p = 0;
12309 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
12310 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
12311 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
12312 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
12314 w->current_matrix->buffer = b;
12315 w->current_matrix->begv = BUF_BEGV (b);
12316 w->current_matrix->zv = BUF_ZV (b);
12318 w->last_cursor = w->cursor;
12319 w->last_cursor_off_p = w->cursor_off_p;
12321 if (w == XWINDOW (selected_window))
12322 w->last_point = make_number (BUF_PT (b));
12323 else
12324 w->last_point = make_number (XMARKER (w->pointm)->charpos);
12328 if (accurate_p)
12330 w->window_end_valid = w->buffer;
12331 w->update_mode_line = Qnil;
12336 /* Mark the display of windows in the window tree rooted at WINDOW as
12337 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
12338 windows as accurate. If ACCURATE_P is zero, arrange for windows to
12339 be redisplayed the next time redisplay_internal is called. */
12341 void
12342 mark_window_display_accurate (Lisp_Object window, int accurate_p)
12344 struct window *w;
12346 for (; !NILP (window); window = w->next)
12348 w = XWINDOW (window);
12349 mark_window_display_accurate_1 (w, accurate_p);
12351 if (!NILP (w->vchild))
12352 mark_window_display_accurate (w->vchild, accurate_p);
12353 if (!NILP (w->hchild))
12354 mark_window_display_accurate (w->hchild, accurate_p);
12357 if (accurate_p)
12359 update_overlay_arrows (1);
12361 else
12363 /* Force a thorough redisplay the next time by setting
12364 last_arrow_position and last_arrow_string to t, which is
12365 unequal to any useful value of Voverlay_arrow_... */
12366 update_overlay_arrows (-1);
12371 /* Return value in display table DP (Lisp_Char_Table *) for character
12372 C. Since a display table doesn't have any parent, we don't have to
12373 follow parent. Do not call this function directly but use the
12374 macro DISP_CHAR_VECTOR. */
12376 Lisp_Object
12377 disp_char_vector (struct Lisp_Char_Table *dp, int c)
12379 Lisp_Object val;
12381 if (ASCII_CHAR_P (c))
12383 val = dp->ascii;
12384 if (SUB_CHAR_TABLE_P (val))
12385 val = XSUB_CHAR_TABLE (val)->contents[c];
12387 else
12389 Lisp_Object table;
12391 XSETCHAR_TABLE (table, dp);
12392 val = char_table_ref (table, c);
12394 if (NILP (val))
12395 val = dp->defalt;
12396 return val;
12401 /***********************************************************************
12402 Window Redisplay
12403 ***********************************************************************/
12405 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
12407 static void
12408 redisplay_windows (Lisp_Object window)
12410 while (!NILP (window))
12412 struct window *w = XWINDOW (window);
12414 if (!NILP (w->hchild))
12415 redisplay_windows (w->hchild);
12416 else if (!NILP (w->vchild))
12417 redisplay_windows (w->vchild);
12418 else if (!NILP (w->buffer))
12420 displayed_buffer = XBUFFER (w->buffer);
12421 /* Use list_of_error, not Qerror, so that
12422 we catch only errors and don't run the debugger. */
12423 internal_condition_case_1 (redisplay_window_0, window,
12424 list_of_error,
12425 redisplay_window_error);
12428 window = w->next;
12432 static Lisp_Object
12433 redisplay_window_error (Lisp_Object ignore)
12435 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
12436 return Qnil;
12439 static Lisp_Object
12440 redisplay_window_0 (Lisp_Object window)
12442 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
12443 redisplay_window (window, 0);
12444 return Qnil;
12447 static Lisp_Object
12448 redisplay_window_1 (Lisp_Object window)
12450 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
12451 redisplay_window (window, 1);
12452 return Qnil;
12456 /* Set cursor position of W. PT is assumed to be displayed in ROW.
12457 DELTA and DELTA_BYTES are the numbers of characters and bytes by
12458 which positions recorded in ROW differ from current buffer
12459 positions.
12461 Return 0 if cursor is not on this row, 1 otherwise. */
12463 static int
12464 set_cursor_from_row (struct window *w, struct glyph_row *row,
12465 struct glyph_matrix *matrix,
12466 EMACS_INT delta, EMACS_INT delta_bytes,
12467 int dy, int dvpos)
12469 struct glyph *glyph = row->glyphs[TEXT_AREA];
12470 struct glyph *end = glyph + row->used[TEXT_AREA];
12471 struct glyph *cursor = NULL;
12472 /* The last known character position in row. */
12473 EMACS_INT last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
12474 int x = row->x;
12475 EMACS_INT pt_old = PT - delta;
12476 EMACS_INT pos_before = MATRIX_ROW_START_CHARPOS (row) + delta;
12477 EMACS_INT pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
12478 struct glyph *glyph_before = glyph - 1, *glyph_after = end;
12479 /* A glyph beyond the edge of TEXT_AREA which we should never
12480 touch. */
12481 struct glyph *glyphs_end = end;
12482 /* Non-zero means we've found a match for cursor position, but that
12483 glyph has the avoid_cursor_p flag set. */
12484 int match_with_avoid_cursor = 0;
12485 /* Non-zero means we've seen at least one glyph that came from a
12486 display string. */
12487 int string_seen = 0;
12488 /* Largest and smalles buffer positions seen so far during scan of
12489 glyph row. */
12490 EMACS_INT bpos_max = pos_before;
12491 EMACS_INT bpos_min = pos_after;
12492 /* Last buffer position covered by an overlay string with an integer
12493 `cursor' property. */
12494 EMACS_INT bpos_covered = 0;
12496 /* Skip over glyphs not having an object at the start and the end of
12497 the row. These are special glyphs like truncation marks on
12498 terminal frames. */
12499 if (row->displays_text_p)
12501 if (!row->reversed_p)
12503 while (glyph < end
12504 && INTEGERP (glyph->object)
12505 && glyph->charpos < 0)
12507 x += glyph->pixel_width;
12508 ++glyph;
12510 while (end > glyph
12511 && INTEGERP ((end - 1)->object)
12512 /* CHARPOS is zero for blanks and stretch glyphs
12513 inserted by extend_face_to_end_of_line. */
12514 && (end - 1)->charpos <= 0)
12515 --end;
12516 glyph_before = glyph - 1;
12517 glyph_after = end;
12519 else
12521 struct glyph *g;
12523 /* If the glyph row is reversed, we need to process it from back
12524 to front, so swap the edge pointers. */
12525 glyphs_end = end = glyph - 1;
12526 glyph += row->used[TEXT_AREA] - 1;
12528 while (glyph > end + 1
12529 && INTEGERP (glyph->object)
12530 && glyph->charpos < 0)
12532 --glyph;
12533 x -= glyph->pixel_width;
12535 if (INTEGERP (glyph->object) && glyph->charpos < 0)
12536 --glyph;
12537 /* By default, in reversed rows we put the cursor on the
12538 rightmost (first in the reading order) glyph. */
12539 for (g = end + 1; g < glyph; g++)
12540 x += g->pixel_width;
12541 while (end < glyph
12542 && INTEGERP ((end + 1)->object)
12543 && (end + 1)->charpos <= 0)
12544 ++end;
12545 glyph_before = glyph + 1;
12546 glyph_after = end;
12549 else if (row->reversed_p)
12551 /* In R2L rows that don't display text, put the cursor on the
12552 rightmost glyph. Case in point: an empty last line that is
12553 part of an R2L paragraph. */
12554 cursor = end - 1;
12555 /* Avoid placing the cursor on the last glyph of the row, where
12556 on terminal frames we hold the vertical border between
12557 adjacent windows. */
12558 if (!FRAME_WINDOW_P (WINDOW_XFRAME (w))
12559 && !WINDOW_RIGHTMOST_P (w)
12560 && cursor == row->glyphs[LAST_AREA] - 1)
12561 cursor--;
12562 x = -1; /* will be computed below, at label compute_x */
12565 /* Step 1: Try to find the glyph whose character position
12566 corresponds to point. If that's not possible, find 2 glyphs
12567 whose character positions are the closest to point, one before
12568 point, the other after it. */
12569 if (!row->reversed_p)
12570 while (/* not marched to end of glyph row */
12571 glyph < end
12572 /* glyph was not inserted by redisplay for internal purposes */
12573 && !INTEGERP (glyph->object))
12575 if (BUFFERP (glyph->object))
12577 EMACS_INT dpos = glyph->charpos - pt_old;
12579 if (glyph->charpos > bpos_max)
12580 bpos_max = glyph->charpos;
12581 if (glyph->charpos < bpos_min)
12582 bpos_min = glyph->charpos;
12583 if (!glyph->avoid_cursor_p)
12585 /* If we hit point, we've found the glyph on which to
12586 display the cursor. */
12587 if (dpos == 0)
12589 match_with_avoid_cursor = 0;
12590 break;
12592 /* See if we've found a better approximation to
12593 POS_BEFORE or to POS_AFTER. Note that we want the
12594 first (leftmost) glyph of all those that are the
12595 closest from below, and the last (rightmost) of all
12596 those from above. */
12597 if (0 > dpos && dpos > pos_before - pt_old)
12599 pos_before = glyph->charpos;
12600 glyph_before = glyph;
12602 else if (0 < dpos && dpos <= pos_after - pt_old)
12604 pos_after = glyph->charpos;
12605 glyph_after = glyph;
12608 else if (dpos == 0)
12609 match_with_avoid_cursor = 1;
12611 else if (STRINGP (glyph->object))
12613 Lisp_Object chprop;
12614 EMACS_INT glyph_pos = glyph->charpos;
12616 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
12617 glyph->object);
12618 if (INTEGERP (chprop))
12620 bpos_covered = bpos_max + XINT (chprop);
12621 /* If the `cursor' property covers buffer positions up
12622 to and including point, we should display cursor on
12623 this glyph. Note that overlays and text properties
12624 with string values stop bidi reordering, so every
12625 buffer position to the left of the string is always
12626 smaller than any position to the right of the
12627 string. Therefore, if a `cursor' property on one
12628 of the string's characters has an integer value, we
12629 will break out of the loop below _before_ we get to
12630 the position match above. IOW, integer values of
12631 the `cursor' property override the "exact match for
12632 point" strategy of positioning the cursor. */
12633 /* Implementation note: bpos_max == pt_old when, e.g.,
12634 we are in an empty line, where bpos_max is set to
12635 MATRIX_ROW_START_CHARPOS, see above. */
12636 if (bpos_max <= pt_old && bpos_covered >= pt_old)
12638 cursor = glyph;
12639 break;
12643 string_seen = 1;
12645 x += glyph->pixel_width;
12646 ++glyph;
12648 else if (glyph > end) /* row is reversed */
12649 while (!INTEGERP (glyph->object))
12651 if (BUFFERP (glyph->object))
12653 EMACS_INT dpos = glyph->charpos - pt_old;
12655 if (glyph->charpos > bpos_max)
12656 bpos_max = glyph->charpos;
12657 if (glyph->charpos < bpos_min)
12658 bpos_min = glyph->charpos;
12659 if (!glyph->avoid_cursor_p)
12661 if (dpos == 0)
12663 match_with_avoid_cursor = 0;
12664 break;
12666 if (0 > dpos && dpos > pos_before - pt_old)
12668 pos_before = glyph->charpos;
12669 glyph_before = glyph;
12671 else if (0 < dpos && dpos <= pos_after - pt_old)
12673 pos_after = glyph->charpos;
12674 glyph_after = glyph;
12677 else if (dpos == 0)
12678 match_with_avoid_cursor = 1;
12680 else if (STRINGP (glyph->object))
12682 Lisp_Object chprop;
12683 EMACS_INT glyph_pos = glyph->charpos;
12685 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
12686 glyph->object);
12687 if (INTEGERP (chprop))
12689 bpos_covered = bpos_max + XINT (chprop);
12690 /* If the `cursor' property covers buffer positions up
12691 to and including point, we should display cursor on
12692 this glyph. */
12693 if (bpos_max <= pt_old && bpos_covered >= pt_old)
12695 cursor = glyph;
12696 break;
12699 string_seen = 1;
12701 --glyph;
12702 if (glyph == glyphs_end) /* don't dereference outside TEXT_AREA */
12704 x--; /* can't use any pixel_width */
12705 break;
12707 x -= glyph->pixel_width;
12710 /* Step 2: If we didn't find an exact match for point, we need to
12711 look for a proper place to put the cursor among glyphs between
12712 GLYPH_BEFORE and GLYPH_AFTER. */
12713 if (!((row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
12714 && BUFFERP (glyph->object) && glyph->charpos == pt_old)
12715 && bpos_covered < pt_old)
12717 /* An empty line has a single glyph whose OBJECT is zero and
12718 whose CHARPOS is the position of a newline on that line.
12719 Note that on a TTY, there are more glyphs after that, which
12720 were produced by extend_face_to_end_of_line, but their
12721 CHARPOS is zero or negative. */
12722 int empty_line_p =
12723 (row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
12724 && INTEGERP (glyph->object) && glyph->charpos > 0;
12726 if (row->ends_in_ellipsis_p && pos_after == last_pos)
12728 EMACS_INT ellipsis_pos;
12730 /* Scan back over the ellipsis glyphs. */
12731 if (!row->reversed_p)
12733 ellipsis_pos = (glyph - 1)->charpos;
12734 while (glyph > row->glyphs[TEXT_AREA]
12735 && (glyph - 1)->charpos == ellipsis_pos)
12736 glyph--, x -= glyph->pixel_width;
12737 /* That loop always goes one position too far, including
12738 the glyph before the ellipsis. So scan forward over
12739 that one. */
12740 x += glyph->pixel_width;
12741 glyph++;
12743 else /* row is reversed */
12745 ellipsis_pos = (glyph + 1)->charpos;
12746 while (glyph < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
12747 && (glyph + 1)->charpos == ellipsis_pos)
12748 glyph++, x += glyph->pixel_width;
12749 x -= glyph->pixel_width;
12750 glyph--;
12753 else if (match_with_avoid_cursor
12754 /* A truncated row may not include PT among its
12755 character positions. Setting the cursor inside the
12756 scroll margin will trigger recalculation of hscroll
12757 in hscroll_window_tree. */
12758 || (row->truncated_on_left_p && pt_old < bpos_min)
12759 || (row->truncated_on_right_p && pt_old > bpos_max)
12760 /* Zero-width characters produce no glyphs. */
12761 || (!string_seen
12762 && !empty_line_p
12763 && (row->reversed_p
12764 ? glyph_after > glyphs_end
12765 : glyph_after < glyphs_end)))
12767 cursor = glyph_after;
12768 x = -1;
12770 else if (string_seen)
12772 int incr = row->reversed_p ? -1 : +1;
12774 /* Need to find the glyph that came out of a string which is
12775 present at point. That glyph is somewhere between
12776 GLYPH_BEFORE and GLYPH_AFTER, and it came from a string
12777 positioned between POS_BEFORE and POS_AFTER in the
12778 buffer. */
12779 struct glyph *start, *stop;
12780 EMACS_INT pos = pos_before;
12782 x = -1;
12784 /* GLYPH_BEFORE and GLYPH_AFTER are the glyphs that
12785 correspond to POS_BEFORE and POS_AFTER, respectively. We
12786 need START and STOP in the order that corresponds to the
12787 row's direction as given by its reversed_p flag. If the
12788 directionality of characters between POS_BEFORE and
12789 POS_AFTER is the opposite of the row's base direction,
12790 these characters will have been reordered for display,
12791 and we need to reverse START and STOP. */
12792 if (!row->reversed_p)
12794 start = min (glyph_before, glyph_after);
12795 stop = max (glyph_before, glyph_after);
12797 else
12799 start = max (glyph_before, glyph_after);
12800 stop = min (glyph_before, glyph_after);
12802 for (glyph = start + incr;
12803 row->reversed_p ? glyph > stop : glyph < stop; )
12806 /* Any glyphs that come from the buffer are here because
12807 of bidi reordering. Skip them, and only pay
12808 attention to glyphs that came from some string. */
12809 if (STRINGP (glyph->object))
12811 Lisp_Object str;
12812 EMACS_INT tem;
12814 str = glyph->object;
12815 tem = string_buffer_position_lim (str, pos, pos_after, 0);
12816 if (tem == 0 /* from overlay */
12817 || pos <= tem)
12819 /* If the string from which this glyph came is
12820 found in the buffer at point, then we've
12821 found the glyph we've been looking for. If
12822 it comes from an overlay (tem == 0), and it
12823 has the `cursor' property on one of its
12824 glyphs, record that glyph as a candidate for
12825 displaying the cursor. (As in the
12826 unidirectional version, we will display the
12827 cursor on the last candidate we find.) */
12828 if (tem == 0 || tem == pt_old)
12830 /* The glyphs from this string could have
12831 been reordered. Find the one with the
12832 smallest string position. Or there could
12833 be a character in the string with the
12834 `cursor' property, which means display
12835 cursor on that character's glyph. */
12836 EMACS_INT strpos = glyph->charpos;
12838 if (tem)
12839 cursor = glyph;
12840 for ( ;
12841 (row->reversed_p ? glyph > stop : glyph < stop)
12842 && EQ (glyph->object, str);
12843 glyph += incr)
12845 Lisp_Object cprop;
12846 EMACS_INT gpos = glyph->charpos;
12848 cprop = Fget_char_property (make_number (gpos),
12849 Qcursor,
12850 glyph->object);
12851 if (!NILP (cprop))
12853 cursor = glyph;
12854 break;
12856 if (tem && glyph->charpos < strpos)
12858 strpos = glyph->charpos;
12859 cursor = glyph;
12863 if (tem == pt_old)
12864 goto compute_x;
12866 if (tem)
12867 pos = tem + 1; /* don't find previous instances */
12869 /* This string is not what we want; skip all of the
12870 glyphs that came from it. */
12871 while ((row->reversed_p ? glyph > stop : glyph < stop)
12872 && EQ (glyph->object, str))
12873 glyph += incr;
12875 else
12876 glyph += incr;
12879 /* If we reached the end of the line, and END was from a string,
12880 the cursor is not on this line. */
12881 if (cursor == NULL
12882 && (row->reversed_p ? glyph <= end : glyph >= end)
12883 && STRINGP (end->object)
12884 && row->continued_p)
12885 return 0;
12889 compute_x:
12890 if (cursor != NULL)
12891 glyph = cursor;
12892 if (x < 0)
12894 struct glyph *g;
12896 /* Need to compute x that corresponds to GLYPH. */
12897 for (g = row->glyphs[TEXT_AREA], x = row->x; g < glyph; g++)
12899 if (g >= row->glyphs[TEXT_AREA] + row->used[TEXT_AREA])
12900 abort ();
12901 x += g->pixel_width;
12905 /* ROW could be part of a continued line, which, under bidi
12906 reordering, might have other rows whose start and end charpos
12907 occlude point. Only set w->cursor if we found a better
12908 approximation to the cursor position than we have from previously
12909 examined candidate rows belonging to the same continued line. */
12910 if (/* we already have a candidate row */
12911 w->cursor.vpos >= 0
12912 /* that candidate is not the row we are processing */
12913 && MATRIX_ROW (matrix, w->cursor.vpos) != row
12914 /* the row we are processing is part of a continued line */
12915 && (row->continued_p || MATRIX_ROW_CONTINUATION_LINE_P (row))
12916 /* Make sure cursor.vpos specifies a row whose start and end
12917 charpos occlude point. This is because some callers of this
12918 function leave cursor.vpos at the row where the cursor was
12919 displayed during the last redisplay cycle. */
12920 && MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos)) <= pt_old
12921 && pt_old < MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos)))
12923 struct glyph *g1 =
12924 MATRIX_ROW_GLYPH_START (matrix, w->cursor.vpos) + w->cursor.hpos;
12926 /* Don't consider glyphs that are outside TEXT_AREA. */
12927 if (!(row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end))
12928 return 0;
12929 /* Keep the candidate whose buffer position is the closest to
12930 point. */
12931 if (/* previous candidate is a glyph in TEXT_AREA of that row */
12932 w->cursor.hpos >= 0
12933 && w->cursor.hpos < MATRIX_ROW_USED (matrix, w->cursor.vpos)
12934 && BUFFERP (g1->object)
12935 && (g1->charpos == pt_old /* an exact match always wins */
12936 || (BUFFERP (glyph->object)
12937 && eabs (g1->charpos - pt_old)
12938 < eabs (glyph->charpos - pt_old))))
12939 return 0;
12940 /* If this candidate gives an exact match, use that. */
12941 if (!(BUFFERP (glyph->object) && glyph->charpos == pt_old)
12942 /* Otherwise, keep the candidate that comes from a row
12943 spanning less buffer positions. This may win when one or
12944 both candidate positions are on glyphs that came from
12945 display strings, for which we cannot compare buffer
12946 positions. */
12947 && MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
12948 - MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
12949 < MATRIX_ROW_END_CHARPOS (row) - MATRIX_ROW_START_CHARPOS (row))
12950 return 0;
12952 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
12953 w->cursor.x = x;
12954 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
12955 w->cursor.y = row->y + dy;
12957 if (w == XWINDOW (selected_window))
12959 if (!row->continued_p
12960 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
12961 && row->x == 0)
12963 this_line_buffer = XBUFFER (w->buffer);
12965 CHARPOS (this_line_start_pos)
12966 = MATRIX_ROW_START_CHARPOS (row) + delta;
12967 BYTEPOS (this_line_start_pos)
12968 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
12970 CHARPOS (this_line_end_pos)
12971 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
12972 BYTEPOS (this_line_end_pos)
12973 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
12975 this_line_y = w->cursor.y;
12976 this_line_pixel_height = row->height;
12977 this_line_vpos = w->cursor.vpos;
12978 this_line_start_x = row->x;
12980 else
12981 CHARPOS (this_line_start_pos) = 0;
12984 return 1;
12988 /* Run window scroll functions, if any, for WINDOW with new window
12989 start STARTP. Sets the window start of WINDOW to that position.
12991 We assume that the window's buffer is really current. */
12993 static INLINE struct text_pos
12994 run_window_scroll_functions (Lisp_Object window, struct text_pos startp)
12996 struct window *w = XWINDOW (window);
12997 SET_MARKER_FROM_TEXT_POS (w->start, startp);
12999 if (current_buffer != XBUFFER (w->buffer))
13000 abort ();
13002 if (!NILP (Vwindow_scroll_functions))
13004 run_hook_with_args_2 (Qwindow_scroll_functions, window,
13005 make_number (CHARPOS (startp)));
13006 SET_TEXT_POS_FROM_MARKER (startp, w->start);
13007 /* In case the hook functions switch buffers. */
13008 if (current_buffer != XBUFFER (w->buffer))
13009 set_buffer_internal_1 (XBUFFER (w->buffer));
13012 return startp;
13016 /* Make sure the line containing the cursor is fully visible.
13017 A value of 1 means there is nothing to be done.
13018 (Either the line is fully visible, or it cannot be made so,
13019 or we cannot tell.)
13021 If FORCE_P is non-zero, return 0 even if partial visible cursor row
13022 is higher than window.
13024 A value of 0 means the caller should do scrolling
13025 as if point had gone off the screen. */
13027 static int
13028 cursor_row_fully_visible_p (struct window *w, int force_p, int current_matrix_p)
13030 struct glyph_matrix *matrix;
13031 struct glyph_row *row;
13032 int window_height;
13034 if (!make_cursor_line_fully_visible_p)
13035 return 1;
13037 /* It's not always possible to find the cursor, e.g, when a window
13038 is full of overlay strings. Don't do anything in that case. */
13039 if (w->cursor.vpos < 0)
13040 return 1;
13042 matrix = current_matrix_p ? w->current_matrix : w->desired_matrix;
13043 row = MATRIX_ROW (matrix, w->cursor.vpos);
13045 /* If the cursor row is not partially visible, there's nothing to do. */
13046 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row))
13047 return 1;
13049 /* If the row the cursor is in is taller than the window's height,
13050 it's not clear what to do, so do nothing. */
13051 window_height = window_box_height (w);
13052 if (row->height >= window_height)
13054 if (!force_p || MINI_WINDOW_P (w)
13055 || w->vscroll || w->cursor.vpos == 0)
13056 return 1;
13058 return 0;
13062 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
13063 non-zero means only WINDOW is redisplayed in redisplay_internal.
13064 TEMP_SCROLL_STEP has the same meaning as emacs_scroll_step, and is used
13065 in redisplay_window to bring a partially visible line into view in
13066 the case that only the cursor has moved.
13068 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
13069 last screen line's vertical height extends past the end of the screen.
13071 Value is
13073 1 if scrolling succeeded
13075 0 if scrolling didn't find point.
13077 -1 if new fonts have been loaded so that we must interrupt
13078 redisplay, adjust glyph matrices, and try again. */
13080 enum
13082 SCROLLING_SUCCESS,
13083 SCROLLING_FAILED,
13084 SCROLLING_NEED_LARGER_MATRICES
13087 /* If scroll-conservatively is more than this, never recenter.
13089 If you change this, don't forget to update the doc string of
13090 `scroll-conservatively' and the Emacs manual. */
13091 #define SCROLL_LIMIT 100
13093 static int
13094 try_scrolling (Lisp_Object window, int just_this_one_p,
13095 EMACS_INT arg_scroll_conservatively, EMACS_INT scroll_step,
13096 int temp_scroll_step, int last_line_misfit)
13098 struct window *w = XWINDOW (window);
13099 struct frame *f = XFRAME (w->frame);
13100 struct text_pos pos, startp;
13101 struct it it;
13102 int this_scroll_margin, scroll_max, rc, height;
13103 int dy = 0, amount_to_scroll = 0, scroll_down_p = 0;
13104 int extra_scroll_margin_lines = last_line_misfit ? 1 : 0;
13105 Lisp_Object aggressive;
13106 /* We will never try scrolling more than this number of lines. */
13107 int scroll_limit = SCROLL_LIMIT;
13109 #if GLYPH_DEBUG
13110 debug_method_add (w, "try_scrolling");
13111 #endif
13113 SET_TEXT_POS_FROM_MARKER (startp, w->start);
13115 /* Compute scroll margin height in pixels. We scroll when point is
13116 within this distance from the top or bottom of the window. */
13117 if (scroll_margin > 0)
13118 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4)
13119 * FRAME_LINE_HEIGHT (f);
13120 else
13121 this_scroll_margin = 0;
13123 /* Force arg_scroll_conservatively to have a reasonable value, to
13124 avoid scrolling too far away with slow move_it_* functions. Note
13125 that the user can supply scroll-conservatively equal to
13126 `most-positive-fixnum', which can be larger than INT_MAX. */
13127 if (arg_scroll_conservatively > scroll_limit)
13129 arg_scroll_conservatively = scroll_limit + 1;
13130 scroll_max = scroll_limit * FRAME_LINE_HEIGHT (f);
13132 else if (scroll_step || arg_scroll_conservatively || temp_scroll_step)
13133 /* Compute how much we should try to scroll maximally to bring
13134 point into view. */
13135 scroll_max = (max (scroll_step,
13136 max (arg_scroll_conservatively, temp_scroll_step))
13137 * FRAME_LINE_HEIGHT (f));
13138 else if (NUMBERP (BVAR (current_buffer, scroll_down_aggressively))
13139 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively)))
13140 /* We're trying to scroll because of aggressive scrolling but no
13141 scroll_step is set. Choose an arbitrary one. */
13142 scroll_max = 10 * FRAME_LINE_HEIGHT (f);
13143 else
13144 scroll_max = 0;
13146 too_near_end:
13148 /* Decide whether to scroll down. */
13149 if (PT > CHARPOS (startp))
13151 int scroll_margin_y;
13153 /* Compute the pixel ypos of the scroll margin, then move it to
13154 either that ypos or PT, whichever comes first. */
13155 start_display (&it, w, startp);
13156 scroll_margin_y = it.last_visible_y - this_scroll_margin
13157 - FRAME_LINE_HEIGHT (f) * extra_scroll_margin_lines;
13158 move_it_to (&it, PT, -1, scroll_margin_y - 1, -1,
13159 (MOVE_TO_POS | MOVE_TO_Y));
13161 if (PT > CHARPOS (it.current.pos))
13163 int y0 = line_bottom_y (&it);
13164 /* Compute how many pixels below window bottom to stop searching
13165 for PT. This avoids costly search for PT that is far away if
13166 the user limited scrolling by a small number of lines, but
13167 always finds PT if scroll_conservatively is set to a large
13168 number, such as most-positive-fixnum. */
13169 int slack = max (scroll_max, 10 * FRAME_LINE_HEIGHT (f));
13170 int y_to_move = it.last_visible_y + slack;
13172 /* Compute the distance from the scroll margin to PT or to
13173 the scroll limit, whichever comes first. This should
13174 include the height of the cursor line, to make that line
13175 fully visible. */
13176 move_it_to (&it, PT, -1, y_to_move,
13177 -1, MOVE_TO_POS | MOVE_TO_Y);
13178 dy = line_bottom_y (&it) - y0;
13180 if (dy > scroll_max)
13181 return SCROLLING_FAILED;
13183 scroll_down_p = 1;
13187 if (scroll_down_p)
13189 /* Point is in or below the bottom scroll margin, so move the
13190 window start down. If scrolling conservatively, move it just
13191 enough down to make point visible. If scroll_step is set,
13192 move it down by scroll_step. */
13193 if (arg_scroll_conservatively)
13194 amount_to_scroll
13195 = min (max (dy, FRAME_LINE_HEIGHT (f)),
13196 FRAME_LINE_HEIGHT (f) * arg_scroll_conservatively);
13197 else if (scroll_step || temp_scroll_step)
13198 amount_to_scroll = scroll_max;
13199 else
13201 aggressive = BVAR (current_buffer, scroll_up_aggressively);
13202 height = WINDOW_BOX_TEXT_HEIGHT (w);
13203 if (NUMBERP (aggressive))
13205 double float_amount = XFLOATINT (aggressive) * height;
13206 amount_to_scroll = float_amount;
13207 if (amount_to_scroll == 0 && float_amount > 0)
13208 amount_to_scroll = 1;
13209 /* Don't let point enter the scroll margin near top of
13210 the window. */
13211 if (amount_to_scroll > height - 2*this_scroll_margin + dy)
13212 amount_to_scroll = height - 2*this_scroll_margin + dy;
13216 if (amount_to_scroll <= 0)
13217 return SCROLLING_FAILED;
13219 start_display (&it, w, startp);
13220 if (arg_scroll_conservatively <= scroll_limit)
13221 move_it_vertically (&it, amount_to_scroll);
13222 else
13224 /* Extra precision for users who set scroll-conservatively
13225 to a large number: make sure the amount we scroll
13226 the window start is never less than amount_to_scroll,
13227 which was computed as distance from window bottom to
13228 point. This matters when lines at window top and lines
13229 below window bottom have different height. */
13230 struct it it1 = it;
13231 /* We use a temporary it1 because line_bottom_y can modify
13232 its argument, if it moves one line down; see there. */
13233 int start_y = line_bottom_y (&it1);
13235 do {
13236 move_it_by_lines (&it, 1);
13237 it1 = it;
13238 } while (line_bottom_y (&it1) - start_y < amount_to_scroll);
13241 /* If STARTP is unchanged, move it down another screen line. */
13242 if (CHARPOS (it.current.pos) == CHARPOS (startp))
13243 move_it_by_lines (&it, 1);
13244 startp = it.current.pos;
13246 else
13248 struct text_pos scroll_margin_pos = startp;
13250 /* See if point is inside the scroll margin at the top of the
13251 window. */
13252 if (this_scroll_margin)
13254 start_display (&it, w, startp);
13255 move_it_vertically (&it, this_scroll_margin);
13256 scroll_margin_pos = it.current.pos;
13259 if (PT < CHARPOS (scroll_margin_pos))
13261 /* Point is in the scroll margin at the top of the window or
13262 above what is displayed in the window. */
13263 int y0, y_to_move;
13265 /* Compute the vertical distance from PT to the scroll
13266 margin position. Move as far as scroll_max allows, or
13267 one screenful, or 10 screen lines, whichever is largest.
13268 Give up if distance is greater than scroll_max. */
13269 SET_TEXT_POS (pos, PT, PT_BYTE);
13270 start_display (&it, w, pos);
13271 y0 = it.current_y;
13272 y_to_move = max (it.last_visible_y,
13273 max (scroll_max, 10 * FRAME_LINE_HEIGHT (f)));
13274 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
13275 y_to_move, -1,
13276 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
13277 dy = it.current_y - y0;
13278 if (dy > scroll_max)
13279 return SCROLLING_FAILED;
13281 /* Compute new window start. */
13282 start_display (&it, w, startp);
13284 if (arg_scroll_conservatively)
13285 amount_to_scroll = max (dy, FRAME_LINE_HEIGHT (f) *
13286 max (scroll_step, temp_scroll_step));
13287 else if (scroll_step || temp_scroll_step)
13288 amount_to_scroll = scroll_max;
13289 else
13291 aggressive = BVAR (current_buffer, scroll_down_aggressively);
13292 height = WINDOW_BOX_TEXT_HEIGHT (w);
13293 if (NUMBERP (aggressive))
13295 double float_amount = XFLOATINT (aggressive) * height;
13296 amount_to_scroll = float_amount;
13297 if (amount_to_scroll == 0 && float_amount > 0)
13298 amount_to_scroll = 1;
13299 amount_to_scroll -=
13300 this_scroll_margin - dy - FRAME_LINE_HEIGHT (f);
13301 /* Don't let point enter the scroll margin near
13302 bottom of the window. */
13303 if (amount_to_scroll > height - 2*this_scroll_margin + dy)
13304 amount_to_scroll = height - 2*this_scroll_margin + dy;
13308 if (amount_to_scroll <= 0)
13309 return SCROLLING_FAILED;
13311 move_it_vertically_backward (&it, amount_to_scroll);
13312 startp = it.current.pos;
13316 /* Run window scroll functions. */
13317 startp = run_window_scroll_functions (window, startp);
13319 /* Display the window. Give up if new fonts are loaded, or if point
13320 doesn't appear. */
13321 if (!try_window (window, startp, 0))
13322 rc = SCROLLING_NEED_LARGER_MATRICES;
13323 else if (w->cursor.vpos < 0)
13325 clear_glyph_matrix (w->desired_matrix);
13326 rc = SCROLLING_FAILED;
13328 else
13330 /* Maybe forget recorded base line for line number display. */
13331 if (!just_this_one_p
13332 || current_buffer->clip_changed
13333 || BEG_UNCHANGED < CHARPOS (startp))
13334 w->base_line_number = Qnil;
13336 /* If cursor ends up on a partially visible line,
13337 treat that as being off the bottom of the screen. */
13338 if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1, 0)
13339 /* It's possible that the cursor is on the first line of the
13340 buffer, which is partially obscured due to a vscroll
13341 (Bug#7537). In that case, avoid looping forever . */
13342 && extra_scroll_margin_lines < w->desired_matrix->nrows - 1)
13344 clear_glyph_matrix (w->desired_matrix);
13345 ++extra_scroll_margin_lines;
13346 goto too_near_end;
13348 rc = SCROLLING_SUCCESS;
13351 return rc;
13355 /* Compute a suitable window start for window W if display of W starts
13356 on a continuation line. Value is non-zero if a new window start
13357 was computed.
13359 The new window start will be computed, based on W's width, starting
13360 from the start of the continued line. It is the start of the
13361 screen line with the minimum distance from the old start W->start. */
13363 static int
13364 compute_window_start_on_continuation_line (struct window *w)
13366 struct text_pos pos, start_pos;
13367 int window_start_changed_p = 0;
13369 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
13371 /* If window start is on a continuation line... Window start may be
13372 < BEGV in case there's invisible text at the start of the
13373 buffer (M-x rmail, for example). */
13374 if (CHARPOS (start_pos) > BEGV
13375 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
13377 struct it it;
13378 struct glyph_row *row;
13380 /* Handle the case that the window start is out of range. */
13381 if (CHARPOS (start_pos) < BEGV)
13382 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
13383 else if (CHARPOS (start_pos) > ZV)
13384 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
13386 /* Find the start of the continued line. This should be fast
13387 because scan_buffer is fast (newline cache). */
13388 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
13389 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
13390 row, DEFAULT_FACE_ID);
13391 reseat_at_previous_visible_line_start (&it);
13393 /* If the line start is "too far" away from the window start,
13394 say it takes too much time to compute a new window start. */
13395 if (CHARPOS (start_pos) - IT_CHARPOS (it)
13396 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
13398 int min_distance, distance;
13400 /* Move forward by display lines to find the new window
13401 start. If window width was enlarged, the new start can
13402 be expected to be > the old start. If window width was
13403 decreased, the new window start will be < the old start.
13404 So, we're looking for the display line start with the
13405 minimum distance from the old window start. */
13406 pos = it.current.pos;
13407 min_distance = INFINITY;
13408 while ((distance = eabs (CHARPOS (start_pos) - IT_CHARPOS (it))),
13409 distance < min_distance)
13411 min_distance = distance;
13412 pos = it.current.pos;
13413 move_it_by_lines (&it, 1);
13416 /* Set the window start there. */
13417 SET_MARKER_FROM_TEXT_POS (w->start, pos);
13418 window_start_changed_p = 1;
13422 return window_start_changed_p;
13426 /* Try cursor movement in case text has not changed in window WINDOW,
13427 with window start STARTP. Value is
13429 CURSOR_MOVEMENT_SUCCESS if successful
13431 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
13433 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
13434 display. *SCROLL_STEP is set to 1, under certain circumstances, if
13435 we want to scroll as if scroll-step were set to 1. See the code.
13437 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
13438 which case we have to abort this redisplay, and adjust matrices
13439 first. */
13441 enum
13443 CURSOR_MOVEMENT_SUCCESS,
13444 CURSOR_MOVEMENT_CANNOT_BE_USED,
13445 CURSOR_MOVEMENT_MUST_SCROLL,
13446 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
13449 static int
13450 try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_step)
13452 struct window *w = XWINDOW (window);
13453 struct frame *f = XFRAME (w->frame);
13454 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
13456 #if GLYPH_DEBUG
13457 if (inhibit_try_cursor_movement)
13458 return rc;
13459 #endif
13461 /* Handle case where text has not changed, only point, and it has
13462 not moved off the frame. */
13463 if (/* Point may be in this window. */
13464 PT >= CHARPOS (startp)
13465 /* Selective display hasn't changed. */
13466 && !current_buffer->clip_changed
13467 /* Function force-mode-line-update is used to force a thorough
13468 redisplay. It sets either windows_or_buffers_changed or
13469 update_mode_lines. So don't take a shortcut here for these
13470 cases. */
13471 && !update_mode_lines
13472 && !windows_or_buffers_changed
13473 && !cursor_type_changed
13474 /* Can't use this case if highlighting a region. When a
13475 region exists, cursor movement has to do more than just
13476 set the cursor. */
13477 && !(!NILP (Vtransient_mark_mode)
13478 && !NILP (BVAR (current_buffer, mark_active)))
13479 && NILP (w->region_showing)
13480 && NILP (Vshow_trailing_whitespace)
13481 /* Right after splitting windows, last_point may be nil. */
13482 && INTEGERP (w->last_point)
13483 /* This code is not used for mini-buffer for the sake of the case
13484 of redisplaying to replace an echo area message; since in
13485 that case the mini-buffer contents per se are usually
13486 unchanged. This code is of no real use in the mini-buffer
13487 since the handling of this_line_start_pos, etc., in redisplay
13488 handles the same cases. */
13489 && !EQ (window, minibuf_window)
13490 /* When splitting windows or for new windows, it happens that
13491 redisplay is called with a nil window_end_vpos or one being
13492 larger than the window. This should really be fixed in
13493 window.c. I don't have this on my list, now, so we do
13494 approximately the same as the old redisplay code. --gerd. */
13495 && INTEGERP (w->window_end_vpos)
13496 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
13497 && (FRAME_WINDOW_P (f)
13498 || !overlay_arrow_in_current_buffer_p ()))
13500 int this_scroll_margin, top_scroll_margin;
13501 struct glyph_row *row = NULL;
13503 #if GLYPH_DEBUG
13504 debug_method_add (w, "cursor movement");
13505 #endif
13507 /* Scroll if point within this distance from the top or bottom
13508 of the window. This is a pixel value. */
13509 if (scroll_margin > 0)
13511 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
13512 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
13514 else
13515 this_scroll_margin = 0;
13517 top_scroll_margin = this_scroll_margin;
13518 if (WINDOW_WANTS_HEADER_LINE_P (w))
13519 top_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w);
13521 /* Start with the row the cursor was displayed during the last
13522 not paused redisplay. Give up if that row is not valid. */
13523 if (w->last_cursor.vpos < 0
13524 || w->last_cursor.vpos >= w->current_matrix->nrows)
13525 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13526 else
13528 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
13529 if (row->mode_line_p)
13530 ++row;
13531 if (!row->enabled_p)
13532 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13535 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
13537 int scroll_p = 0, must_scroll = 0;
13538 int last_y = window_text_bottom_y (w) - this_scroll_margin;
13540 if (PT > XFASTINT (w->last_point))
13542 /* Point has moved forward. */
13543 while (MATRIX_ROW_END_CHARPOS (row) < PT
13544 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
13546 xassert (row->enabled_p);
13547 ++row;
13550 /* If the end position of a row equals the start
13551 position of the next row, and PT is at that position,
13552 we would rather display cursor in the next line. */
13553 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
13554 && MATRIX_ROW_END_CHARPOS (row) == PT
13555 && row < w->current_matrix->rows
13556 + w->current_matrix->nrows - 1
13557 && MATRIX_ROW_START_CHARPOS (row+1) == PT
13558 && !cursor_row_p (row))
13559 ++row;
13561 /* If within the scroll margin, scroll. Note that
13562 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
13563 the next line would be drawn, and that
13564 this_scroll_margin can be zero. */
13565 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
13566 || PT > MATRIX_ROW_END_CHARPOS (row)
13567 /* Line is completely visible last line in window
13568 and PT is to be set in the next line. */
13569 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
13570 && PT == MATRIX_ROW_END_CHARPOS (row)
13571 && !row->ends_at_zv_p
13572 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
13573 scroll_p = 1;
13575 else if (PT < XFASTINT (w->last_point))
13577 /* Cursor has to be moved backward. Note that PT >=
13578 CHARPOS (startp) because of the outer if-statement. */
13579 while (!row->mode_line_p
13580 && (MATRIX_ROW_START_CHARPOS (row) > PT
13581 || (MATRIX_ROW_START_CHARPOS (row) == PT
13582 && (MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)
13583 || (/* STARTS_IN_MIDDLE_OF_STRING_P (row) */
13584 row > w->current_matrix->rows
13585 && (row-1)->ends_in_newline_from_string_p))))
13586 && (row->y > top_scroll_margin
13587 || CHARPOS (startp) == BEGV))
13589 xassert (row->enabled_p);
13590 --row;
13593 /* Consider the following case: Window starts at BEGV,
13594 there is invisible, intangible text at BEGV, so that
13595 display starts at some point START > BEGV. It can
13596 happen that we are called with PT somewhere between
13597 BEGV and START. Try to handle that case. */
13598 if (row < w->current_matrix->rows
13599 || row->mode_line_p)
13601 row = w->current_matrix->rows;
13602 if (row->mode_line_p)
13603 ++row;
13606 /* Due to newlines in overlay strings, we may have to
13607 skip forward over overlay strings. */
13608 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
13609 && MATRIX_ROW_END_CHARPOS (row) == PT
13610 && !cursor_row_p (row))
13611 ++row;
13613 /* If within the scroll margin, scroll. */
13614 if (row->y < top_scroll_margin
13615 && CHARPOS (startp) != BEGV)
13616 scroll_p = 1;
13618 else
13620 /* Cursor did not move. So don't scroll even if cursor line
13621 is partially visible, as it was so before. */
13622 rc = CURSOR_MOVEMENT_SUCCESS;
13625 if (PT < MATRIX_ROW_START_CHARPOS (row)
13626 || PT > MATRIX_ROW_END_CHARPOS (row))
13628 /* if PT is not in the glyph row, give up. */
13629 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13630 must_scroll = 1;
13632 else if (rc != CURSOR_MOVEMENT_SUCCESS
13633 && !NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering)))
13635 /* If rows are bidi-reordered and point moved, back up
13636 until we find a row that does not belong to a
13637 continuation line. This is because we must consider
13638 all rows of a continued line as candidates for the
13639 new cursor positioning, since row start and end
13640 positions change non-linearly with vertical position
13641 in such rows. */
13642 /* FIXME: Revisit this when glyph ``spilling'' in
13643 continuation lines' rows is implemented for
13644 bidi-reordered rows. */
13645 while (MATRIX_ROW_CONTINUATION_LINE_P (row))
13647 xassert (row->enabled_p);
13648 --row;
13649 /* If we hit the beginning of the displayed portion
13650 without finding the first row of a continued
13651 line, give up. */
13652 if (row <= w->current_matrix->rows)
13654 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13655 break;
13660 if (must_scroll)
13662 else if (rc != CURSOR_MOVEMENT_SUCCESS
13663 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
13664 && make_cursor_line_fully_visible_p)
13666 if (PT == MATRIX_ROW_END_CHARPOS (row)
13667 && !row->ends_at_zv_p
13668 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
13669 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13670 else if (row->height > window_box_height (w))
13672 /* If we end up in a partially visible line, let's
13673 make it fully visible, except when it's taller
13674 than the window, in which case we can't do much
13675 about it. */
13676 *scroll_step = 1;
13677 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13679 else
13681 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
13682 if (!cursor_row_fully_visible_p (w, 0, 1))
13683 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13684 else
13685 rc = CURSOR_MOVEMENT_SUCCESS;
13688 else if (scroll_p)
13689 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13690 else if (rc != CURSOR_MOVEMENT_SUCCESS
13691 && !NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering)))
13693 /* With bidi-reordered rows, there could be more than
13694 one candidate row whose start and end positions
13695 occlude point. We need to let set_cursor_from_row
13696 find the best candidate. */
13697 /* FIXME: Revisit this when glyph ``spilling'' in
13698 continuation lines' rows is implemented for
13699 bidi-reordered rows. */
13700 int rv = 0;
13704 if (MATRIX_ROW_START_CHARPOS (row) <= PT
13705 && PT <= MATRIX_ROW_END_CHARPOS (row)
13706 && cursor_row_p (row))
13707 rv |= set_cursor_from_row (w, row, w->current_matrix,
13708 0, 0, 0, 0);
13709 /* As soon as we've found the first suitable row
13710 whose ends_at_zv_p flag is set, we are done. */
13711 if (rv
13712 && MATRIX_ROW (w->current_matrix, w->cursor.vpos)->ends_at_zv_p)
13714 rc = CURSOR_MOVEMENT_SUCCESS;
13715 break;
13717 ++row;
13719 while ((MATRIX_ROW_CONTINUATION_LINE_P (row)
13720 && MATRIX_ROW_BOTTOM_Y (row) <= last_y)
13721 || (MATRIX_ROW_START_CHARPOS (row) == PT
13722 && MATRIX_ROW_BOTTOM_Y (row) < last_y));
13723 /* If we didn't find any candidate rows, or exited the
13724 loop before all the candidates were examined, signal
13725 to the caller that this method failed. */
13726 if (rc != CURSOR_MOVEMENT_SUCCESS
13727 && (!rv || MATRIX_ROW_CONTINUATION_LINE_P (row)))
13728 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13729 else if (rv)
13730 rc = CURSOR_MOVEMENT_SUCCESS;
13732 else
13736 if (set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0))
13738 rc = CURSOR_MOVEMENT_SUCCESS;
13739 break;
13741 ++row;
13743 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
13744 && MATRIX_ROW_START_CHARPOS (row) == PT
13745 && cursor_row_p (row));
13750 return rc;
13753 #if !defined USE_TOOLKIT_SCROLL_BARS || defined USE_GTK
13754 static
13755 #endif
13756 void
13757 set_vertical_scroll_bar (struct window *w)
13759 EMACS_INT start, end, whole;
13761 /* Calculate the start and end positions for the current window.
13762 At some point, it would be nice to choose between scrollbars
13763 which reflect the whole buffer size, with special markers
13764 indicating narrowing, and scrollbars which reflect only the
13765 visible region.
13767 Note that mini-buffers sometimes aren't displaying any text. */
13768 if (!MINI_WINDOW_P (w)
13769 || (w == XWINDOW (minibuf_window)
13770 && NILP (echo_area_buffer[0])))
13772 struct buffer *buf = XBUFFER (w->buffer);
13773 whole = BUF_ZV (buf) - BUF_BEGV (buf);
13774 start = marker_position (w->start) - BUF_BEGV (buf);
13775 /* I don't think this is guaranteed to be right. For the
13776 moment, we'll pretend it is. */
13777 end = BUF_Z (buf) - XFASTINT (w->window_end_pos) - BUF_BEGV (buf);
13779 if (end < start)
13780 end = start;
13781 if (whole < (end - start))
13782 whole = end - start;
13784 else
13785 start = end = whole = 0;
13787 /* Indicate what this scroll bar ought to be displaying now. */
13788 if (FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
13789 (*FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
13790 (w, end - start, whole, start);
13794 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
13795 selected_window is redisplayed.
13797 We can return without actually redisplaying the window if
13798 fonts_changed_p is nonzero. In that case, redisplay_internal will
13799 retry. */
13801 static void
13802 redisplay_window (Lisp_Object window, int just_this_one_p)
13804 struct window *w = XWINDOW (window);
13805 struct frame *f = XFRAME (w->frame);
13806 struct buffer *buffer = XBUFFER (w->buffer);
13807 struct buffer *old = current_buffer;
13808 struct text_pos lpoint, opoint, startp;
13809 int update_mode_line;
13810 int tem;
13811 struct it it;
13812 /* Record it now because it's overwritten. */
13813 int current_matrix_up_to_date_p = 0;
13814 int used_current_matrix_p = 0;
13815 /* This is less strict than current_matrix_up_to_date_p.
13816 It indictes that the buffer contents and narrowing are unchanged. */
13817 int buffer_unchanged_p = 0;
13818 int temp_scroll_step = 0;
13819 int count = SPECPDL_INDEX ();
13820 int rc;
13821 int centering_position = -1;
13822 int last_line_misfit = 0;
13823 EMACS_INT beg_unchanged, end_unchanged;
13825 SET_TEXT_POS (lpoint, PT, PT_BYTE);
13826 opoint = lpoint;
13828 /* W must be a leaf window here. */
13829 xassert (!NILP (w->buffer));
13830 #if GLYPH_DEBUG
13831 *w->desired_matrix->method = 0;
13832 #endif
13834 restart:
13835 reconsider_clip_changes (w, buffer);
13837 /* Has the mode line to be updated? */
13838 update_mode_line = (!NILP (w->update_mode_line)
13839 || update_mode_lines
13840 || buffer->clip_changed
13841 || buffer->prevent_redisplay_optimizations_p);
13843 if (MINI_WINDOW_P (w))
13845 if (w == XWINDOW (echo_area_window)
13846 && !NILP (echo_area_buffer[0]))
13848 if (update_mode_line)
13849 /* We may have to update a tty frame's menu bar or a
13850 tool-bar. Example `M-x C-h C-h C-g'. */
13851 goto finish_menu_bars;
13852 else
13853 /* We've already displayed the echo area glyphs in this window. */
13854 goto finish_scroll_bars;
13856 else if ((w != XWINDOW (minibuf_window)
13857 || minibuf_level == 0)
13858 /* When buffer is nonempty, redisplay window normally. */
13859 && BUF_Z (XBUFFER (w->buffer)) == BUF_BEG (XBUFFER (w->buffer))
13860 /* Quail displays non-mini buffers in minibuffer window.
13861 In that case, redisplay the window normally. */
13862 && !NILP (Fmemq (w->buffer, Vminibuffer_list)))
13864 /* W is a mini-buffer window, but it's not active, so clear
13865 it. */
13866 int yb = window_text_bottom_y (w);
13867 struct glyph_row *row;
13868 int y;
13870 for (y = 0, row = w->desired_matrix->rows;
13871 y < yb;
13872 y += row->height, ++row)
13873 blank_row (w, row, y);
13874 goto finish_scroll_bars;
13877 clear_glyph_matrix (w->desired_matrix);
13880 /* Otherwise set up data on this window; select its buffer and point
13881 value. */
13882 /* Really select the buffer, for the sake of buffer-local
13883 variables. */
13884 set_buffer_internal_1 (XBUFFER (w->buffer));
13886 current_matrix_up_to_date_p
13887 = (!NILP (w->window_end_valid)
13888 && !current_buffer->clip_changed
13889 && !current_buffer->prevent_redisplay_optimizations_p
13890 && XFASTINT (w->last_modified) >= MODIFF
13891 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
13893 /* Run the window-bottom-change-functions
13894 if it is possible that the text on the screen has changed
13895 (either due to modification of the text, or any other reason). */
13896 if (!current_matrix_up_to_date_p
13897 && !NILP (Vwindow_text_change_functions))
13899 safe_run_hooks (Qwindow_text_change_functions);
13900 goto restart;
13903 beg_unchanged = BEG_UNCHANGED;
13904 end_unchanged = END_UNCHANGED;
13906 SET_TEXT_POS (opoint, PT, PT_BYTE);
13908 specbind (Qinhibit_point_motion_hooks, Qt);
13910 buffer_unchanged_p
13911 = (!NILP (w->window_end_valid)
13912 && !current_buffer->clip_changed
13913 && XFASTINT (w->last_modified) >= MODIFF
13914 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
13916 /* When windows_or_buffers_changed is non-zero, we can't rely on
13917 the window end being valid, so set it to nil there. */
13918 if (windows_or_buffers_changed)
13920 /* If window starts on a continuation line, maybe adjust the
13921 window start in case the window's width changed. */
13922 if (XMARKER (w->start)->buffer == current_buffer)
13923 compute_window_start_on_continuation_line (w);
13925 w->window_end_valid = Qnil;
13928 /* Some sanity checks. */
13929 CHECK_WINDOW_END (w);
13930 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
13931 abort ();
13932 if (BYTEPOS (opoint) < CHARPOS (opoint))
13933 abort ();
13935 /* If %c is in mode line, update it if needed. */
13936 if (!NILP (w->column_number_displayed)
13937 /* This alternative quickly identifies a common case
13938 where no change is needed. */
13939 && !(PT == XFASTINT (w->last_point)
13940 && XFASTINT (w->last_modified) >= MODIFF
13941 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
13942 && (XFASTINT (w->column_number_displayed) != current_column ()))
13943 update_mode_line = 1;
13945 /* Count number of windows showing the selected buffer. An indirect
13946 buffer counts as its base buffer. */
13947 if (!just_this_one_p)
13949 struct buffer *current_base, *window_base;
13950 current_base = current_buffer;
13951 window_base = XBUFFER (XWINDOW (selected_window)->buffer);
13952 if (current_base->base_buffer)
13953 current_base = current_base->base_buffer;
13954 if (window_base->base_buffer)
13955 window_base = window_base->base_buffer;
13956 if (current_base == window_base)
13957 buffer_shared++;
13960 /* Point refers normally to the selected window. For any other
13961 window, set up appropriate value. */
13962 if (!EQ (window, selected_window))
13964 EMACS_INT new_pt = XMARKER (w->pointm)->charpos;
13965 EMACS_INT new_pt_byte = marker_byte_position (w->pointm);
13966 if (new_pt < BEGV)
13968 new_pt = BEGV;
13969 new_pt_byte = BEGV_BYTE;
13970 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
13972 else if (new_pt > (ZV - 1))
13974 new_pt = ZV;
13975 new_pt_byte = ZV_BYTE;
13976 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
13979 /* We don't use SET_PT so that the point-motion hooks don't run. */
13980 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
13983 /* If any of the character widths specified in the display table
13984 have changed, invalidate the width run cache. It's true that
13985 this may be a bit late to catch such changes, but the rest of
13986 redisplay goes (non-fatally) haywire when the display table is
13987 changed, so why should we worry about doing any better? */
13988 if (current_buffer->width_run_cache)
13990 struct Lisp_Char_Table *disptab = buffer_display_table ();
13992 if (! disptab_matches_widthtab (disptab,
13993 XVECTOR (BVAR (current_buffer, width_table))))
13995 invalidate_region_cache (current_buffer,
13996 current_buffer->width_run_cache,
13997 BEG, Z);
13998 recompute_width_table (current_buffer, disptab);
14002 /* If window-start is screwed up, choose a new one. */
14003 if (XMARKER (w->start)->buffer != current_buffer)
14004 goto recenter;
14006 SET_TEXT_POS_FROM_MARKER (startp, w->start);
14008 /* If someone specified a new starting point but did not insist,
14009 check whether it can be used. */
14010 if (!NILP (w->optional_new_start)
14011 && CHARPOS (startp) >= BEGV
14012 && CHARPOS (startp) <= ZV)
14014 w->optional_new_start = Qnil;
14015 start_display (&it, w, startp);
14016 move_it_to (&it, PT, 0, it.last_visible_y, -1,
14017 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
14018 if (IT_CHARPOS (it) == PT)
14019 w->force_start = Qt;
14020 /* IT may overshoot PT if text at PT is invisible. */
14021 else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT)
14022 w->force_start = Qt;
14025 force_start:
14027 /* Handle case where place to start displaying has been specified,
14028 unless the specified location is outside the accessible range. */
14029 if (!NILP (w->force_start)
14030 || w->frozen_window_start_p)
14032 /* We set this later on if we have to adjust point. */
14033 int new_vpos = -1;
14035 w->force_start = Qnil;
14036 w->vscroll = 0;
14037 w->window_end_valid = Qnil;
14039 /* Forget any recorded base line for line number display. */
14040 if (!buffer_unchanged_p)
14041 w->base_line_number = Qnil;
14043 /* Redisplay the mode line. Select the buffer properly for that.
14044 Also, run the hook window-scroll-functions
14045 because we have scrolled. */
14046 /* Note, we do this after clearing force_start because
14047 if there's an error, it is better to forget about force_start
14048 than to get into an infinite loop calling the hook functions
14049 and having them get more errors. */
14050 if (!update_mode_line
14051 || ! NILP (Vwindow_scroll_functions))
14053 update_mode_line = 1;
14054 w->update_mode_line = Qt;
14055 startp = run_window_scroll_functions (window, startp);
14058 w->last_modified = make_number (0);
14059 w->last_overlay_modified = make_number (0);
14060 if (CHARPOS (startp) < BEGV)
14061 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
14062 else if (CHARPOS (startp) > ZV)
14063 SET_TEXT_POS (startp, ZV, ZV_BYTE);
14065 /* Redisplay, then check if cursor has been set during the
14066 redisplay. Give up if new fonts were loaded. */
14067 /* We used to issue a CHECK_MARGINS argument to try_window here,
14068 but this causes scrolling to fail when point begins inside
14069 the scroll margin (bug#148) -- cyd */
14070 if (!try_window (window, startp, 0))
14072 w->force_start = Qt;
14073 clear_glyph_matrix (w->desired_matrix);
14074 goto need_larger_matrices;
14077 if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
14079 /* If point does not appear, try to move point so it does
14080 appear. The desired matrix has been built above, so we
14081 can use it here. */
14082 new_vpos = window_box_height (w) / 2;
14085 if (!cursor_row_fully_visible_p (w, 0, 0))
14087 /* Point does appear, but on a line partly visible at end of window.
14088 Move it back to a fully-visible line. */
14089 new_vpos = window_box_height (w);
14092 /* If we need to move point for either of the above reasons,
14093 now actually do it. */
14094 if (new_vpos >= 0)
14096 struct glyph_row *row;
14098 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
14099 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
14100 ++row;
14102 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
14103 MATRIX_ROW_START_BYTEPOS (row));
14105 if (w != XWINDOW (selected_window))
14106 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
14107 else if (current_buffer == old)
14108 SET_TEXT_POS (lpoint, PT, PT_BYTE);
14110 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
14112 /* If we are highlighting the region, then we just changed
14113 the region, so redisplay to show it. */
14114 if (!NILP (Vtransient_mark_mode)
14115 && !NILP (BVAR (current_buffer, mark_active)))
14117 clear_glyph_matrix (w->desired_matrix);
14118 if (!try_window (window, startp, 0))
14119 goto need_larger_matrices;
14123 #if GLYPH_DEBUG
14124 debug_method_add (w, "forced window start");
14125 #endif
14126 goto done;
14129 /* Handle case where text has not changed, only point, and it has
14130 not moved off the frame, and we are not retrying after hscroll.
14131 (current_matrix_up_to_date_p is nonzero when retrying.) */
14132 if (current_matrix_up_to_date_p
14133 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
14134 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
14136 switch (rc)
14138 case CURSOR_MOVEMENT_SUCCESS:
14139 used_current_matrix_p = 1;
14140 goto done;
14142 case CURSOR_MOVEMENT_MUST_SCROLL:
14143 goto try_to_scroll;
14145 default:
14146 abort ();
14149 /* If current starting point was originally the beginning of a line
14150 but no longer is, find a new starting point. */
14151 else if (!NILP (w->start_at_line_beg)
14152 && !(CHARPOS (startp) <= BEGV
14153 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
14155 #if GLYPH_DEBUG
14156 debug_method_add (w, "recenter 1");
14157 #endif
14158 goto recenter;
14161 /* Try scrolling with try_window_id. Value is > 0 if update has
14162 been done, it is -1 if we know that the same window start will
14163 not work. It is 0 if unsuccessful for some other reason. */
14164 else if ((tem = try_window_id (w)) != 0)
14166 #if GLYPH_DEBUG
14167 debug_method_add (w, "try_window_id %d", tem);
14168 #endif
14170 if (fonts_changed_p)
14171 goto need_larger_matrices;
14172 if (tem > 0)
14173 goto done;
14175 /* Otherwise try_window_id has returned -1 which means that we
14176 don't want the alternative below this comment to execute. */
14178 else if (CHARPOS (startp) >= BEGV
14179 && CHARPOS (startp) <= ZV
14180 && PT >= CHARPOS (startp)
14181 && (CHARPOS (startp) < ZV
14182 /* Avoid starting at end of buffer. */
14183 || CHARPOS (startp) == BEGV
14184 || (XFASTINT (w->last_modified) >= MODIFF
14185 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)))
14188 /* If first window line is a continuation line, and window start
14189 is inside the modified region, but the first change is before
14190 current window start, we must select a new window start.
14192 However, if this is the result of a down-mouse event (e.g. by
14193 extending the mouse-drag-overlay), we don't want to select a
14194 new window start, since that would change the position under
14195 the mouse, resulting in an unwanted mouse-movement rather
14196 than a simple mouse-click. */
14197 if (NILP (w->start_at_line_beg)
14198 && NILP (do_mouse_tracking)
14199 && CHARPOS (startp) > BEGV
14200 && CHARPOS (startp) > BEG + beg_unchanged
14201 && CHARPOS (startp) <= Z - end_unchanged
14202 /* Even if w->start_at_line_beg is nil, a new window may
14203 start at a line_beg, since that's how set_buffer_window
14204 sets it. So, we need to check the return value of
14205 compute_window_start_on_continuation_line. (See also
14206 bug#197). */
14207 && XMARKER (w->start)->buffer == current_buffer
14208 && compute_window_start_on_continuation_line (w))
14210 w->force_start = Qt;
14211 SET_TEXT_POS_FROM_MARKER (startp, w->start);
14212 goto force_start;
14215 #if GLYPH_DEBUG
14216 debug_method_add (w, "same window start");
14217 #endif
14219 /* Try to redisplay starting at same place as before.
14220 If point has not moved off frame, accept the results. */
14221 if (!current_matrix_up_to_date_p
14222 /* Don't use try_window_reusing_current_matrix in this case
14223 because a window scroll function can have changed the
14224 buffer. */
14225 || !NILP (Vwindow_scroll_functions)
14226 || MINI_WINDOW_P (w)
14227 || !(used_current_matrix_p
14228 = try_window_reusing_current_matrix (w)))
14230 IF_DEBUG (debug_method_add (w, "1"));
14231 if (try_window (window, startp, TRY_WINDOW_CHECK_MARGINS) < 0)
14232 /* -1 means we need to scroll.
14233 0 means we need new matrices, but fonts_changed_p
14234 is set in that case, so we will detect it below. */
14235 goto try_to_scroll;
14238 if (fonts_changed_p)
14239 goto need_larger_matrices;
14241 if (w->cursor.vpos >= 0)
14243 if (!just_this_one_p
14244 || current_buffer->clip_changed
14245 || BEG_UNCHANGED < CHARPOS (startp))
14246 /* Forget any recorded base line for line number display. */
14247 w->base_line_number = Qnil;
14249 if (!cursor_row_fully_visible_p (w, 1, 0))
14251 clear_glyph_matrix (w->desired_matrix);
14252 last_line_misfit = 1;
14254 /* Drop through and scroll. */
14255 else
14256 goto done;
14258 else
14259 clear_glyph_matrix (w->desired_matrix);
14262 try_to_scroll:
14264 w->last_modified = make_number (0);
14265 w->last_overlay_modified = make_number (0);
14267 /* Redisplay the mode line. Select the buffer properly for that. */
14268 if (!update_mode_line)
14270 update_mode_line = 1;
14271 w->update_mode_line = Qt;
14274 /* Try to scroll by specified few lines. */
14275 if ((scroll_conservatively
14276 || emacs_scroll_step
14277 || temp_scroll_step
14278 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively))
14279 || NUMBERP (BVAR (current_buffer, scroll_down_aggressively)))
14280 && CHARPOS (startp) >= BEGV
14281 && CHARPOS (startp) <= ZV)
14283 /* The function returns -1 if new fonts were loaded, 1 if
14284 successful, 0 if not successful. */
14285 int ss = try_scrolling (window, just_this_one_p,
14286 scroll_conservatively,
14287 emacs_scroll_step,
14288 temp_scroll_step, last_line_misfit);
14289 switch (ss)
14291 case SCROLLING_SUCCESS:
14292 goto done;
14294 case SCROLLING_NEED_LARGER_MATRICES:
14295 goto need_larger_matrices;
14297 case SCROLLING_FAILED:
14298 break;
14300 default:
14301 abort ();
14305 /* Finally, just choose a place to start which positions point
14306 according to user preferences. */
14308 recenter:
14310 #if GLYPH_DEBUG
14311 debug_method_add (w, "recenter");
14312 #endif
14314 /* w->vscroll = 0; */
14316 /* Forget any previously recorded base line for line number display. */
14317 if (!buffer_unchanged_p)
14318 w->base_line_number = Qnil;
14320 /* Determine the window start relative to point. */
14321 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
14322 it.current_y = it.last_visible_y;
14323 if (centering_position < 0)
14325 int margin =
14326 scroll_margin > 0
14327 ? min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4)
14328 : 0;
14329 EMACS_INT margin_pos = CHARPOS (startp);
14330 int scrolling_up;
14331 Lisp_Object aggressive;
14333 /* If there is a scroll margin at the top of the window, find
14334 its character position. */
14335 if (margin
14336 /* Cannot call start_display if startp is not in the
14337 accessible region of the buffer. This can happen when we
14338 have just switched to a different buffer and/or changed
14339 its restriction. In that case, startp is initialized to
14340 the character position 1 (BEG) because we did not yet
14341 have chance to display the buffer even once. */
14342 && BEGV <= CHARPOS (startp) && CHARPOS (startp) <= ZV)
14344 struct it it1;
14346 start_display (&it1, w, startp);
14347 move_it_vertically (&it1, margin);
14348 margin_pos = IT_CHARPOS (it1);
14350 scrolling_up = PT > margin_pos;
14351 aggressive =
14352 scrolling_up
14353 ? BVAR (current_buffer, scroll_up_aggressively)
14354 : BVAR (current_buffer, scroll_down_aggressively);
14356 if (!MINI_WINDOW_P (w)
14357 && (scroll_conservatively > SCROLL_LIMIT || NUMBERP (aggressive)))
14359 int pt_offset = 0;
14361 /* Setting scroll-conservatively overrides
14362 scroll-*-aggressively. */
14363 if (!scroll_conservatively && NUMBERP (aggressive))
14365 double float_amount = XFLOATINT (aggressive);
14367 pt_offset = float_amount * WINDOW_BOX_TEXT_HEIGHT (w);
14368 if (pt_offset == 0 && float_amount > 0)
14369 pt_offset = 1;
14370 if (pt_offset)
14371 margin -= 1;
14373 /* Compute how much to move the window start backward from
14374 point so that point will be displayed where the user
14375 wants it. */
14376 if (scrolling_up)
14378 centering_position = it.last_visible_y;
14379 if (pt_offset)
14380 centering_position -= pt_offset;
14381 centering_position -=
14382 FRAME_LINE_HEIGHT (f) * (1 + margin + (last_line_misfit != 0));
14383 /* Don't let point enter the scroll margin near top of
14384 the window. */
14385 if (centering_position < margin * FRAME_LINE_HEIGHT (f))
14386 centering_position = margin * FRAME_LINE_HEIGHT (f);
14388 else
14389 centering_position = margin * FRAME_LINE_HEIGHT (f) + pt_offset;
14391 else
14392 /* Set the window start half the height of the window backward
14393 from point. */
14394 centering_position = window_box_height (w) / 2;
14396 move_it_vertically_backward (&it, centering_position);
14398 xassert (IT_CHARPOS (it) >= BEGV);
14400 /* The function move_it_vertically_backward may move over more
14401 than the specified y-distance. If it->w is small, e.g. a
14402 mini-buffer window, we may end up in front of the window's
14403 display area. Start displaying at the start of the line
14404 containing PT in this case. */
14405 if (it.current_y <= 0)
14407 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
14408 move_it_vertically_backward (&it, 0);
14409 it.current_y = 0;
14412 it.current_x = it.hpos = 0;
14414 /* Set the window start position here explicitly, to avoid an
14415 infinite loop in case the functions in window-scroll-functions
14416 get errors. */
14417 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
14419 /* Run scroll hooks. */
14420 startp = run_window_scroll_functions (window, it.current.pos);
14422 /* Redisplay the window. */
14423 if (!current_matrix_up_to_date_p
14424 || windows_or_buffers_changed
14425 || cursor_type_changed
14426 /* Don't use try_window_reusing_current_matrix in this case
14427 because it can have changed the buffer. */
14428 || !NILP (Vwindow_scroll_functions)
14429 || !just_this_one_p
14430 || MINI_WINDOW_P (w)
14431 || !(used_current_matrix_p
14432 = try_window_reusing_current_matrix (w)))
14433 try_window (window, startp, 0);
14435 /* If new fonts have been loaded (due to fontsets), give up. We
14436 have to start a new redisplay since we need to re-adjust glyph
14437 matrices. */
14438 if (fonts_changed_p)
14439 goto need_larger_matrices;
14441 /* If cursor did not appear assume that the middle of the window is
14442 in the first line of the window. Do it again with the next line.
14443 (Imagine a window of height 100, displaying two lines of height
14444 60. Moving back 50 from it->last_visible_y will end in the first
14445 line.) */
14446 if (w->cursor.vpos < 0)
14448 if (!NILP (w->window_end_valid)
14449 && PT >= Z - XFASTINT (w->window_end_pos))
14451 clear_glyph_matrix (w->desired_matrix);
14452 move_it_by_lines (&it, 1);
14453 try_window (window, it.current.pos, 0);
14455 else if (PT < IT_CHARPOS (it))
14457 clear_glyph_matrix (w->desired_matrix);
14458 move_it_by_lines (&it, -1);
14459 try_window (window, it.current.pos, 0);
14461 else
14463 /* Not much we can do about it. */
14467 /* Consider the following case: Window starts at BEGV, there is
14468 invisible, intangible text at BEGV, so that display starts at
14469 some point START > BEGV. It can happen that we are called with
14470 PT somewhere between BEGV and START. Try to handle that case. */
14471 if (w->cursor.vpos < 0)
14473 struct glyph_row *row = w->current_matrix->rows;
14474 if (row->mode_line_p)
14475 ++row;
14476 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
14479 if (!cursor_row_fully_visible_p (w, 0, 0))
14481 /* If vscroll is enabled, disable it and try again. */
14482 if (w->vscroll)
14484 w->vscroll = 0;
14485 clear_glyph_matrix (w->desired_matrix);
14486 goto recenter;
14489 /* If centering point failed to make the whole line visible,
14490 put point at the top instead. That has to make the whole line
14491 visible, if it can be done. */
14492 if (centering_position == 0)
14493 goto done;
14495 clear_glyph_matrix (w->desired_matrix);
14496 centering_position = 0;
14497 goto recenter;
14500 done:
14502 SET_TEXT_POS_FROM_MARKER (startp, w->start);
14503 w->start_at_line_beg = ((CHARPOS (startp) == BEGV
14504 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n')
14505 ? Qt : Qnil);
14507 /* Display the mode line, if we must. */
14508 if ((update_mode_line
14509 /* If window not full width, must redo its mode line
14510 if (a) the window to its side is being redone and
14511 (b) we do a frame-based redisplay. This is a consequence
14512 of how inverted lines are drawn in frame-based redisplay. */
14513 || (!just_this_one_p
14514 && !FRAME_WINDOW_P (f)
14515 && !WINDOW_FULL_WIDTH_P (w))
14516 /* Line number to display. */
14517 || INTEGERP (w->base_line_pos)
14518 /* Column number is displayed and different from the one displayed. */
14519 || (!NILP (w->column_number_displayed)
14520 && (XFASTINT (w->column_number_displayed) != current_column ())))
14521 /* This means that the window has a mode line. */
14522 && (WINDOW_WANTS_MODELINE_P (w)
14523 || WINDOW_WANTS_HEADER_LINE_P (w)))
14525 display_mode_lines (w);
14527 /* If mode line height has changed, arrange for a thorough
14528 immediate redisplay using the correct mode line height. */
14529 if (WINDOW_WANTS_MODELINE_P (w)
14530 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
14532 fonts_changed_p = 1;
14533 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
14534 = DESIRED_MODE_LINE_HEIGHT (w);
14537 /* If header line height has changed, arrange for a thorough
14538 immediate redisplay using the correct header line height. */
14539 if (WINDOW_WANTS_HEADER_LINE_P (w)
14540 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
14542 fonts_changed_p = 1;
14543 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
14544 = DESIRED_HEADER_LINE_HEIGHT (w);
14547 if (fonts_changed_p)
14548 goto need_larger_matrices;
14551 if (!line_number_displayed
14552 && !BUFFERP (w->base_line_pos))
14554 w->base_line_pos = Qnil;
14555 w->base_line_number = Qnil;
14558 finish_menu_bars:
14560 /* When we reach a frame's selected window, redo the frame's menu bar. */
14561 if (update_mode_line
14562 && EQ (FRAME_SELECTED_WINDOW (f), window))
14564 int redisplay_menu_p = 0;
14566 if (FRAME_WINDOW_P (f))
14568 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
14569 || defined (HAVE_NS) || defined (USE_GTK)
14570 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
14571 #else
14572 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
14573 #endif
14575 else
14576 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
14578 if (redisplay_menu_p)
14579 display_menu_bar (w);
14581 #ifdef HAVE_WINDOW_SYSTEM
14582 if (FRAME_WINDOW_P (f))
14584 #if defined (USE_GTK) || defined (HAVE_NS)
14585 if (FRAME_EXTERNAL_TOOL_BAR (f))
14586 redisplay_tool_bar (f);
14587 #else
14588 if (WINDOWP (f->tool_bar_window)
14589 && (FRAME_TOOL_BAR_LINES (f) > 0
14590 || !NILP (Vauto_resize_tool_bars))
14591 && redisplay_tool_bar (f))
14592 ignore_mouse_drag_p = 1;
14593 #endif
14595 #endif
14598 #ifdef HAVE_WINDOW_SYSTEM
14599 if (FRAME_WINDOW_P (f)
14600 && update_window_fringes (w, (just_this_one_p
14601 || (!used_current_matrix_p && !overlay_arrow_seen)
14602 || w->pseudo_window_p)))
14604 update_begin (f);
14605 BLOCK_INPUT;
14606 if (draw_window_fringes (w, 1))
14607 x_draw_vertical_border (w);
14608 UNBLOCK_INPUT;
14609 update_end (f);
14611 #endif /* HAVE_WINDOW_SYSTEM */
14613 /* We go to this label, with fonts_changed_p nonzero,
14614 if it is necessary to try again using larger glyph matrices.
14615 We have to redeem the scroll bar even in this case,
14616 because the loop in redisplay_internal expects that. */
14617 need_larger_matrices:
14619 finish_scroll_bars:
14621 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
14623 /* Set the thumb's position and size. */
14624 set_vertical_scroll_bar (w);
14626 /* Note that we actually used the scroll bar attached to this
14627 window, so it shouldn't be deleted at the end of redisplay. */
14628 if (FRAME_TERMINAL (f)->redeem_scroll_bar_hook)
14629 (*FRAME_TERMINAL (f)->redeem_scroll_bar_hook) (w);
14632 /* Restore current_buffer and value of point in it. The window
14633 update may have changed the buffer, so first make sure `opoint'
14634 is still valid (Bug#6177). */
14635 if (CHARPOS (opoint) < BEGV)
14636 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
14637 else if (CHARPOS (opoint) > ZV)
14638 TEMP_SET_PT_BOTH (Z, Z_BYTE);
14639 else
14640 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
14642 set_buffer_internal_1 (old);
14643 /* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become
14644 shorter. This can be caused by log truncation in *Messages*. */
14645 if (CHARPOS (lpoint) <= ZV)
14646 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
14648 unbind_to (count, Qnil);
14652 /* Build the complete desired matrix of WINDOW with a window start
14653 buffer position POS.
14655 Value is 1 if successful. It is zero if fonts were loaded during
14656 redisplay which makes re-adjusting glyph matrices necessary, and -1
14657 if point would appear in the scroll margins.
14658 (We check the former only if TRY_WINDOW_IGNORE_FONTS_CHANGE is
14659 unset in FLAGS, and the latter only if TRY_WINDOW_CHECK_MARGINS is
14660 set in FLAGS.) */
14663 try_window (Lisp_Object window, struct text_pos pos, int flags)
14665 struct window *w = XWINDOW (window);
14666 struct it it;
14667 struct glyph_row *last_text_row = NULL;
14668 struct frame *f = XFRAME (w->frame);
14670 /* Make POS the new window start. */
14671 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
14673 /* Mark cursor position as unknown. No overlay arrow seen. */
14674 w->cursor.vpos = -1;
14675 overlay_arrow_seen = 0;
14677 /* Initialize iterator and info to start at POS. */
14678 start_display (&it, w, pos);
14680 /* Display all lines of W. */
14681 while (it.current_y < it.last_visible_y)
14683 if (display_line (&it))
14684 last_text_row = it.glyph_row - 1;
14685 if (fonts_changed_p && !(flags & TRY_WINDOW_IGNORE_FONTS_CHANGE))
14686 return 0;
14689 /* Don't let the cursor end in the scroll margins. */
14690 if ((flags & TRY_WINDOW_CHECK_MARGINS)
14691 && !MINI_WINDOW_P (w))
14693 int this_scroll_margin;
14695 if (scroll_margin > 0)
14697 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
14698 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
14700 else
14701 this_scroll_margin = 0;
14703 if ((w->cursor.y >= 0 /* not vscrolled */
14704 && w->cursor.y < this_scroll_margin
14705 && CHARPOS (pos) > BEGV
14706 && IT_CHARPOS (it) < ZV)
14707 /* rms: considering make_cursor_line_fully_visible_p here
14708 seems to give wrong results. We don't want to recenter
14709 when the last line is partly visible, we want to allow
14710 that case to be handled in the usual way. */
14711 || w->cursor.y > it.last_visible_y - this_scroll_margin - 1)
14713 w->cursor.vpos = -1;
14714 clear_glyph_matrix (w->desired_matrix);
14715 return -1;
14719 /* If bottom moved off end of frame, change mode line percentage. */
14720 if (XFASTINT (w->window_end_pos) <= 0
14721 && Z != IT_CHARPOS (it))
14722 w->update_mode_line = Qt;
14724 /* Set window_end_pos to the offset of the last character displayed
14725 on the window from the end of current_buffer. Set
14726 window_end_vpos to its row number. */
14727 if (last_text_row)
14729 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
14730 w->window_end_bytepos
14731 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
14732 w->window_end_pos
14733 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
14734 w->window_end_vpos
14735 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
14736 xassert (MATRIX_ROW (w->desired_matrix, XFASTINT (w->window_end_vpos))
14737 ->displays_text_p);
14739 else
14741 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
14742 w->window_end_pos = make_number (Z - ZV);
14743 w->window_end_vpos = make_number (0);
14746 /* But that is not valid info until redisplay finishes. */
14747 w->window_end_valid = Qnil;
14748 return 1;
14753 /************************************************************************
14754 Window redisplay reusing current matrix when buffer has not changed
14755 ************************************************************************/
14757 /* Try redisplay of window W showing an unchanged buffer with a
14758 different window start than the last time it was displayed by
14759 reusing its current matrix. Value is non-zero if successful.
14760 W->start is the new window start. */
14762 static int
14763 try_window_reusing_current_matrix (struct window *w)
14765 struct frame *f = XFRAME (w->frame);
14766 struct glyph_row *bottom_row;
14767 struct it it;
14768 struct run run;
14769 struct text_pos start, new_start;
14770 int nrows_scrolled, i;
14771 struct glyph_row *last_text_row;
14772 struct glyph_row *last_reused_text_row;
14773 struct glyph_row *start_row;
14774 int start_vpos, min_y, max_y;
14776 #if GLYPH_DEBUG
14777 if (inhibit_try_window_reusing)
14778 return 0;
14779 #endif
14781 if (/* This function doesn't handle terminal frames. */
14782 !FRAME_WINDOW_P (f)
14783 /* Don't try to reuse the display if windows have been split
14784 or such. */
14785 || windows_or_buffers_changed
14786 || cursor_type_changed)
14787 return 0;
14789 /* Can't do this if region may have changed. */
14790 if ((!NILP (Vtransient_mark_mode)
14791 && !NILP (BVAR (current_buffer, mark_active)))
14792 || !NILP (w->region_showing)
14793 || !NILP (Vshow_trailing_whitespace))
14794 return 0;
14796 /* If top-line visibility has changed, give up. */
14797 if (WINDOW_WANTS_HEADER_LINE_P (w)
14798 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
14799 return 0;
14801 /* Give up if old or new display is scrolled vertically. We could
14802 make this function handle this, but right now it doesn't. */
14803 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
14804 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row))
14805 return 0;
14807 /* The variable new_start now holds the new window start. The old
14808 start `start' can be determined from the current matrix. */
14809 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
14810 start = start_row->minpos;
14811 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
14813 /* Clear the desired matrix for the display below. */
14814 clear_glyph_matrix (w->desired_matrix);
14816 if (CHARPOS (new_start) <= CHARPOS (start))
14818 /* Don't use this method if the display starts with an ellipsis
14819 displayed for invisible text. It's not easy to handle that case
14820 below, and it's certainly not worth the effort since this is
14821 not a frequent case. */
14822 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
14823 return 0;
14825 IF_DEBUG (debug_method_add (w, "twu1"));
14827 /* Display up to a row that can be reused. The variable
14828 last_text_row is set to the last row displayed that displays
14829 text. Note that it.vpos == 0 if or if not there is a
14830 header-line; it's not the same as the MATRIX_ROW_VPOS! */
14831 start_display (&it, w, new_start);
14832 w->cursor.vpos = -1;
14833 last_text_row = last_reused_text_row = NULL;
14835 while (it.current_y < it.last_visible_y
14836 && !fonts_changed_p)
14838 /* If we have reached into the characters in the START row,
14839 that means the line boundaries have changed. So we
14840 can't start copying with the row START. Maybe it will
14841 work to start copying with the following row. */
14842 while (IT_CHARPOS (it) > CHARPOS (start))
14844 /* Advance to the next row as the "start". */
14845 start_row++;
14846 start = start_row->minpos;
14847 /* If there are no more rows to try, or just one, give up. */
14848 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
14849 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row)
14850 || CHARPOS (start) == ZV)
14852 clear_glyph_matrix (w->desired_matrix);
14853 return 0;
14856 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
14858 /* If we have reached alignment,
14859 we can copy the rest of the rows. */
14860 if (IT_CHARPOS (it) == CHARPOS (start))
14861 break;
14863 if (display_line (&it))
14864 last_text_row = it.glyph_row - 1;
14867 /* A value of current_y < last_visible_y means that we stopped
14868 at the previous window start, which in turn means that we
14869 have at least one reusable row. */
14870 if (it.current_y < it.last_visible_y)
14872 struct glyph_row *row;
14874 /* IT.vpos always starts from 0; it counts text lines. */
14875 nrows_scrolled = it.vpos - (start_row - MATRIX_FIRST_TEXT_ROW (w->current_matrix));
14877 /* Find PT if not already found in the lines displayed. */
14878 if (w->cursor.vpos < 0)
14880 int dy = it.current_y - start_row->y;
14882 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
14883 row = row_containing_pos (w, PT, row, NULL, dy);
14884 if (row)
14885 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
14886 dy, nrows_scrolled);
14887 else
14889 clear_glyph_matrix (w->desired_matrix);
14890 return 0;
14894 /* Scroll the display. Do it before the current matrix is
14895 changed. The problem here is that update has not yet
14896 run, i.e. part of the current matrix is not up to date.
14897 scroll_run_hook will clear the cursor, and use the
14898 current matrix to get the height of the row the cursor is
14899 in. */
14900 run.current_y = start_row->y;
14901 run.desired_y = it.current_y;
14902 run.height = it.last_visible_y - it.current_y;
14904 if (run.height > 0 && run.current_y != run.desired_y)
14906 update_begin (f);
14907 FRAME_RIF (f)->update_window_begin_hook (w);
14908 FRAME_RIF (f)->clear_window_mouse_face (w);
14909 FRAME_RIF (f)->scroll_run_hook (w, &run);
14910 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
14911 update_end (f);
14914 /* Shift current matrix down by nrows_scrolled lines. */
14915 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
14916 rotate_matrix (w->current_matrix,
14917 start_vpos,
14918 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
14919 nrows_scrolled);
14921 /* Disable lines that must be updated. */
14922 for (i = 0; i < nrows_scrolled; ++i)
14923 (start_row + i)->enabled_p = 0;
14925 /* Re-compute Y positions. */
14926 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
14927 max_y = it.last_visible_y;
14928 for (row = start_row + nrows_scrolled;
14929 row < bottom_row;
14930 ++row)
14932 row->y = it.current_y;
14933 row->visible_height = row->height;
14935 if (row->y < min_y)
14936 row->visible_height -= min_y - row->y;
14937 if (row->y + row->height > max_y)
14938 row->visible_height -= row->y + row->height - max_y;
14939 row->redraw_fringe_bitmaps_p = 1;
14941 it.current_y += row->height;
14943 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
14944 last_reused_text_row = row;
14945 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
14946 break;
14949 /* Disable lines in the current matrix which are now
14950 below the window. */
14951 for (++row; row < bottom_row; ++row)
14952 row->enabled_p = row->mode_line_p = 0;
14955 /* Update window_end_pos etc.; last_reused_text_row is the last
14956 reused row from the current matrix containing text, if any.
14957 The value of last_text_row is the last displayed line
14958 containing text. */
14959 if (last_reused_text_row)
14961 w->window_end_bytepos
14962 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
14963 w->window_end_pos
14964 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_reused_text_row));
14965 w->window_end_vpos
14966 = make_number (MATRIX_ROW_VPOS (last_reused_text_row,
14967 w->current_matrix));
14969 else if (last_text_row)
14971 w->window_end_bytepos
14972 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
14973 w->window_end_pos
14974 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
14975 w->window_end_vpos
14976 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
14978 else
14980 /* This window must be completely empty. */
14981 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
14982 w->window_end_pos = make_number (Z - ZV);
14983 w->window_end_vpos = make_number (0);
14985 w->window_end_valid = Qnil;
14987 /* Update hint: don't try scrolling again in update_window. */
14988 w->desired_matrix->no_scrolling_p = 1;
14990 #if GLYPH_DEBUG
14991 debug_method_add (w, "try_window_reusing_current_matrix 1");
14992 #endif
14993 return 1;
14995 else if (CHARPOS (new_start) > CHARPOS (start))
14997 struct glyph_row *pt_row, *row;
14998 struct glyph_row *first_reusable_row;
14999 struct glyph_row *first_row_to_display;
15000 int dy;
15001 int yb = window_text_bottom_y (w);
15003 /* Find the row starting at new_start, if there is one. Don't
15004 reuse a partially visible line at the end. */
15005 first_reusable_row = start_row;
15006 while (first_reusable_row->enabled_p
15007 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
15008 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
15009 < CHARPOS (new_start)))
15010 ++first_reusable_row;
15012 /* Give up if there is no row to reuse. */
15013 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
15014 || !first_reusable_row->enabled_p
15015 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
15016 != CHARPOS (new_start)))
15017 return 0;
15019 /* We can reuse fully visible rows beginning with
15020 first_reusable_row to the end of the window. Set
15021 first_row_to_display to the first row that cannot be reused.
15022 Set pt_row to the row containing point, if there is any. */
15023 pt_row = NULL;
15024 for (first_row_to_display = first_reusable_row;
15025 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
15026 ++first_row_to_display)
15028 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
15029 && PT < MATRIX_ROW_END_CHARPOS (first_row_to_display))
15030 pt_row = first_row_to_display;
15033 /* Start displaying at the start of first_row_to_display. */
15034 xassert (first_row_to_display->y < yb);
15035 init_to_row_start (&it, w, first_row_to_display);
15037 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
15038 - start_vpos);
15039 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
15040 - nrows_scrolled);
15041 it.current_y = (first_row_to_display->y - first_reusable_row->y
15042 + WINDOW_HEADER_LINE_HEIGHT (w));
15044 /* Display lines beginning with first_row_to_display in the
15045 desired matrix. Set last_text_row to the last row displayed
15046 that displays text. */
15047 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
15048 if (pt_row == NULL)
15049 w->cursor.vpos = -1;
15050 last_text_row = NULL;
15051 while (it.current_y < it.last_visible_y && !fonts_changed_p)
15052 if (display_line (&it))
15053 last_text_row = it.glyph_row - 1;
15055 /* If point is in a reused row, adjust y and vpos of the cursor
15056 position. */
15057 if (pt_row)
15059 w->cursor.vpos -= nrows_scrolled;
15060 w->cursor.y -= first_reusable_row->y - start_row->y;
15063 /* Give up if point isn't in a row displayed or reused. (This
15064 also handles the case where w->cursor.vpos < nrows_scrolled
15065 after the calls to display_line, which can happen with scroll
15066 margins. See bug#1295.) */
15067 if (w->cursor.vpos < 0)
15069 clear_glyph_matrix (w->desired_matrix);
15070 return 0;
15073 /* Scroll the display. */
15074 run.current_y = first_reusable_row->y;
15075 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
15076 run.height = it.last_visible_y - run.current_y;
15077 dy = run.current_y - run.desired_y;
15079 if (run.height)
15081 update_begin (f);
15082 FRAME_RIF (f)->update_window_begin_hook (w);
15083 FRAME_RIF (f)->clear_window_mouse_face (w);
15084 FRAME_RIF (f)->scroll_run_hook (w, &run);
15085 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
15086 update_end (f);
15089 /* Adjust Y positions of reused rows. */
15090 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
15091 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
15092 max_y = it.last_visible_y;
15093 for (row = first_reusable_row; row < first_row_to_display; ++row)
15095 row->y -= dy;
15096 row->visible_height = row->height;
15097 if (row->y < min_y)
15098 row->visible_height -= min_y - row->y;
15099 if (row->y + row->height > max_y)
15100 row->visible_height -= row->y + row->height - max_y;
15101 row->redraw_fringe_bitmaps_p = 1;
15104 /* Scroll the current matrix. */
15105 xassert (nrows_scrolled > 0);
15106 rotate_matrix (w->current_matrix,
15107 start_vpos,
15108 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
15109 -nrows_scrolled);
15111 /* Disable rows not reused. */
15112 for (row -= nrows_scrolled; row < bottom_row; ++row)
15113 row->enabled_p = 0;
15115 /* Point may have moved to a different line, so we cannot assume that
15116 the previous cursor position is valid; locate the correct row. */
15117 if (pt_row)
15119 for (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
15120 row < bottom_row && PT >= MATRIX_ROW_END_CHARPOS (row);
15121 row++)
15123 w->cursor.vpos++;
15124 w->cursor.y = row->y;
15126 if (row < bottom_row)
15128 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
15129 struct glyph *end = glyph + row->used[TEXT_AREA];
15131 /* Can't use this optimization with bidi-reordered glyph
15132 rows, unless cursor is already at point. */
15133 if (!NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering)))
15135 if (!(w->cursor.hpos >= 0
15136 && w->cursor.hpos < row->used[TEXT_AREA]
15137 && BUFFERP (glyph->object)
15138 && glyph->charpos == PT))
15139 return 0;
15141 else
15142 for (; glyph < end
15143 && (!BUFFERP (glyph->object)
15144 || glyph->charpos < PT);
15145 glyph++)
15147 w->cursor.hpos++;
15148 w->cursor.x += glyph->pixel_width;
15153 /* Adjust window end. A null value of last_text_row means that
15154 the window end is in reused rows which in turn means that
15155 only its vpos can have changed. */
15156 if (last_text_row)
15158 w->window_end_bytepos
15159 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
15160 w->window_end_pos
15161 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
15162 w->window_end_vpos
15163 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
15165 else
15167 w->window_end_vpos
15168 = make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled);
15171 w->window_end_valid = Qnil;
15172 w->desired_matrix->no_scrolling_p = 1;
15174 #if GLYPH_DEBUG
15175 debug_method_add (w, "try_window_reusing_current_matrix 2");
15176 #endif
15177 return 1;
15180 return 0;
15185 /************************************************************************
15186 Window redisplay reusing current matrix when buffer has changed
15187 ************************************************************************/
15189 static struct glyph_row *find_last_unchanged_at_beg_row (struct window *);
15190 static struct glyph_row *find_first_unchanged_at_end_row (struct window *,
15191 EMACS_INT *, EMACS_INT *);
15192 static struct glyph_row *
15193 find_last_row_displaying_text (struct glyph_matrix *, struct it *,
15194 struct glyph_row *);
15197 /* Return the last row in MATRIX displaying text. If row START is
15198 non-null, start searching with that row. IT gives the dimensions
15199 of the display. Value is null if matrix is empty; otherwise it is
15200 a pointer to the row found. */
15202 static struct glyph_row *
15203 find_last_row_displaying_text (struct glyph_matrix *matrix, struct it *it,
15204 struct glyph_row *start)
15206 struct glyph_row *row, *row_found;
15208 /* Set row_found to the last row in IT->w's current matrix
15209 displaying text. The loop looks funny but think of partially
15210 visible lines. */
15211 row_found = NULL;
15212 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
15213 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
15215 xassert (row->enabled_p);
15216 row_found = row;
15217 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
15218 break;
15219 ++row;
15222 return row_found;
15226 /* Return the last row in the current matrix of W that is not affected
15227 by changes at the start of current_buffer that occurred since W's
15228 current matrix was built. Value is null if no such row exists.
15230 BEG_UNCHANGED us the number of characters unchanged at the start of
15231 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
15232 first changed character in current_buffer. Characters at positions <
15233 BEG + BEG_UNCHANGED are at the same buffer positions as they were
15234 when the current matrix was built. */
15236 static struct glyph_row *
15237 find_last_unchanged_at_beg_row (struct window *w)
15239 EMACS_INT first_changed_pos = BEG + BEG_UNCHANGED;
15240 struct glyph_row *row;
15241 struct glyph_row *row_found = NULL;
15242 int yb = window_text_bottom_y (w);
15244 /* Find the last row displaying unchanged text. */
15245 for (row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
15246 MATRIX_ROW_DISPLAYS_TEXT_P (row)
15247 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos;
15248 ++row)
15250 if (/* If row ends before first_changed_pos, it is unchanged,
15251 except in some case. */
15252 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
15253 /* When row ends in ZV and we write at ZV it is not
15254 unchanged. */
15255 && !row->ends_at_zv_p
15256 /* When first_changed_pos is the end of a continued line,
15257 row is not unchanged because it may be no longer
15258 continued. */
15259 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
15260 && (row->continued_p
15261 || row->exact_window_width_line_p)))
15262 row_found = row;
15264 /* Stop if last visible row. */
15265 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
15266 break;
15269 return row_found;
15273 /* Find the first glyph row in the current matrix of W that is not
15274 affected by changes at the end of current_buffer since the
15275 time W's current matrix was built.
15277 Return in *DELTA the number of chars by which buffer positions in
15278 unchanged text at the end of current_buffer must be adjusted.
15280 Return in *DELTA_BYTES the corresponding number of bytes.
15282 Value is null if no such row exists, i.e. all rows are affected by
15283 changes. */
15285 static struct glyph_row *
15286 find_first_unchanged_at_end_row (struct window *w,
15287 EMACS_INT *delta, EMACS_INT *delta_bytes)
15289 struct glyph_row *row;
15290 struct glyph_row *row_found = NULL;
15292 *delta = *delta_bytes = 0;
15294 /* Display must not have been paused, otherwise the current matrix
15295 is not up to date. */
15296 eassert (!NILP (w->window_end_valid));
15298 /* A value of window_end_pos >= END_UNCHANGED means that the window
15299 end is in the range of changed text. If so, there is no
15300 unchanged row at the end of W's current matrix. */
15301 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
15302 return NULL;
15304 /* Set row to the last row in W's current matrix displaying text. */
15305 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
15307 /* If matrix is entirely empty, no unchanged row exists. */
15308 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
15310 /* The value of row is the last glyph row in the matrix having a
15311 meaningful buffer position in it. The end position of row
15312 corresponds to window_end_pos. This allows us to translate
15313 buffer positions in the current matrix to current buffer
15314 positions for characters not in changed text. */
15315 EMACS_INT Z_old =
15316 MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
15317 EMACS_INT Z_BYTE_old =
15318 MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
15319 EMACS_INT last_unchanged_pos, last_unchanged_pos_old;
15320 struct glyph_row *first_text_row
15321 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
15323 *delta = Z - Z_old;
15324 *delta_bytes = Z_BYTE - Z_BYTE_old;
15326 /* Set last_unchanged_pos to the buffer position of the last
15327 character in the buffer that has not been changed. Z is the
15328 index + 1 of the last character in current_buffer, i.e. by
15329 subtracting END_UNCHANGED we get the index of the last
15330 unchanged character, and we have to add BEG to get its buffer
15331 position. */
15332 last_unchanged_pos = Z - END_UNCHANGED + BEG;
15333 last_unchanged_pos_old = last_unchanged_pos - *delta;
15335 /* Search backward from ROW for a row displaying a line that
15336 starts at a minimum position >= last_unchanged_pos_old. */
15337 for (; row > first_text_row; --row)
15339 /* This used to abort, but it can happen.
15340 It is ok to just stop the search instead here. KFS. */
15341 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
15342 break;
15344 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
15345 row_found = row;
15349 eassert (!row_found || MATRIX_ROW_DISPLAYS_TEXT_P (row_found));
15351 return row_found;
15355 /* Make sure that glyph rows in the current matrix of window W
15356 reference the same glyph memory as corresponding rows in the
15357 frame's frame matrix. This function is called after scrolling W's
15358 current matrix on a terminal frame in try_window_id and
15359 try_window_reusing_current_matrix. */
15361 static void
15362 sync_frame_with_window_matrix_rows (struct window *w)
15364 struct frame *f = XFRAME (w->frame);
15365 struct glyph_row *window_row, *window_row_end, *frame_row;
15367 /* Preconditions: W must be a leaf window and full-width. Its frame
15368 must have a frame matrix. */
15369 xassert (NILP (w->hchild) && NILP (w->vchild));
15370 xassert (WINDOW_FULL_WIDTH_P (w));
15371 xassert (!FRAME_WINDOW_P (f));
15373 /* If W is a full-width window, glyph pointers in W's current matrix
15374 have, by definition, to be the same as glyph pointers in the
15375 corresponding frame matrix. Note that frame matrices have no
15376 marginal areas (see build_frame_matrix). */
15377 window_row = w->current_matrix->rows;
15378 window_row_end = window_row + w->current_matrix->nrows;
15379 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
15380 while (window_row < window_row_end)
15382 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
15383 struct glyph *end = window_row->glyphs[LAST_AREA];
15385 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
15386 frame_row->glyphs[TEXT_AREA] = start;
15387 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
15388 frame_row->glyphs[LAST_AREA] = end;
15390 /* Disable frame rows whose corresponding window rows have
15391 been disabled in try_window_id. */
15392 if (!window_row->enabled_p)
15393 frame_row->enabled_p = 0;
15395 ++window_row, ++frame_row;
15400 /* Find the glyph row in window W containing CHARPOS. Consider all
15401 rows between START and END (not inclusive). END null means search
15402 all rows to the end of the display area of W. Value is the row
15403 containing CHARPOS or null. */
15405 struct glyph_row *
15406 row_containing_pos (struct window *w, EMACS_INT charpos,
15407 struct glyph_row *start, struct glyph_row *end, int dy)
15409 struct glyph_row *row = start;
15410 struct glyph_row *best_row = NULL;
15411 EMACS_INT mindif = BUF_ZV (XBUFFER (w->buffer)) + 1;
15412 int last_y;
15414 /* If we happen to start on a header-line, skip that. */
15415 if (row->mode_line_p)
15416 ++row;
15418 if ((end && row >= end) || !row->enabled_p)
15419 return NULL;
15421 last_y = window_text_bottom_y (w) - dy;
15423 while (1)
15425 /* Give up if we have gone too far. */
15426 if (end && row >= end)
15427 return NULL;
15428 /* This formerly returned if they were equal.
15429 I think that both quantities are of a "last plus one" type;
15430 if so, when they are equal, the row is within the screen. -- rms. */
15431 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
15432 return NULL;
15434 /* If it is in this row, return this row. */
15435 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
15436 || (MATRIX_ROW_END_CHARPOS (row) == charpos
15437 /* The end position of a row equals the start
15438 position of the next row. If CHARPOS is there, we
15439 would rather display it in the next line, except
15440 when this line ends in ZV. */
15441 && !row->ends_at_zv_p
15442 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
15443 && charpos >= MATRIX_ROW_START_CHARPOS (row))
15445 struct glyph *g;
15447 if (NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering))
15448 || (!best_row && !row->continued_p))
15449 return row;
15450 /* In bidi-reordered rows, there could be several rows
15451 occluding point, all of them belonging to the same
15452 continued line. We need to find the row which fits
15453 CHARPOS the best. */
15454 for (g = row->glyphs[TEXT_AREA];
15455 g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
15456 g++)
15458 if (!STRINGP (g->object))
15460 if (g->charpos > 0 && eabs (g->charpos - charpos) < mindif)
15462 mindif = eabs (g->charpos - charpos);
15463 best_row = row;
15464 /* Exact match always wins. */
15465 if (mindif == 0)
15466 return best_row;
15471 else if (best_row && !row->continued_p)
15472 return best_row;
15473 ++row;
15478 /* Try to redisplay window W by reusing its existing display. W's
15479 current matrix must be up to date when this function is called,
15480 i.e. window_end_valid must not be nil.
15482 Value is
15484 1 if display has been updated
15485 0 if otherwise unsuccessful
15486 -1 if redisplay with same window start is known not to succeed
15488 The following steps are performed:
15490 1. Find the last row in the current matrix of W that is not
15491 affected by changes at the start of current_buffer. If no such row
15492 is found, give up.
15494 2. Find the first row in W's current matrix that is not affected by
15495 changes at the end of current_buffer. Maybe there is no such row.
15497 3. Display lines beginning with the row + 1 found in step 1 to the
15498 row found in step 2 or, if step 2 didn't find a row, to the end of
15499 the window.
15501 4. If cursor is not known to appear on the window, give up.
15503 5. If display stopped at the row found in step 2, scroll the
15504 display and current matrix as needed.
15506 6. Maybe display some lines at the end of W, if we must. This can
15507 happen under various circumstances, like a partially visible line
15508 becoming fully visible, or because newly displayed lines are displayed
15509 in smaller font sizes.
15511 7. Update W's window end information. */
15513 static int
15514 try_window_id (struct window *w)
15516 struct frame *f = XFRAME (w->frame);
15517 struct glyph_matrix *current_matrix = w->current_matrix;
15518 struct glyph_matrix *desired_matrix = w->desired_matrix;
15519 struct glyph_row *last_unchanged_at_beg_row;
15520 struct glyph_row *first_unchanged_at_end_row;
15521 struct glyph_row *row;
15522 struct glyph_row *bottom_row;
15523 int bottom_vpos;
15524 struct it it;
15525 EMACS_INT delta = 0, delta_bytes = 0, stop_pos;
15526 int dvpos, dy;
15527 struct text_pos start_pos;
15528 struct run run;
15529 int first_unchanged_at_end_vpos = 0;
15530 struct glyph_row *last_text_row, *last_text_row_at_end;
15531 struct text_pos start;
15532 EMACS_INT first_changed_charpos, last_changed_charpos;
15534 #if GLYPH_DEBUG
15535 if (inhibit_try_window_id)
15536 return 0;
15537 #endif
15539 /* This is handy for debugging. */
15540 #if 0
15541 #define GIVE_UP(X) \
15542 do { \
15543 fprintf (stderr, "try_window_id give up %d\n", (X)); \
15544 return 0; \
15545 } while (0)
15546 #else
15547 #define GIVE_UP(X) return 0
15548 #endif
15550 SET_TEXT_POS_FROM_MARKER (start, w->start);
15552 /* Don't use this for mini-windows because these can show
15553 messages and mini-buffers, and we don't handle that here. */
15554 if (MINI_WINDOW_P (w))
15555 GIVE_UP (1);
15557 /* This flag is used to prevent redisplay optimizations. */
15558 if (windows_or_buffers_changed || cursor_type_changed)
15559 GIVE_UP (2);
15561 /* Verify that narrowing has not changed.
15562 Also verify that we were not told to prevent redisplay optimizations.
15563 It would be nice to further
15564 reduce the number of cases where this prevents try_window_id. */
15565 if (current_buffer->clip_changed
15566 || current_buffer->prevent_redisplay_optimizations_p)
15567 GIVE_UP (3);
15569 /* Window must either use window-based redisplay or be full width. */
15570 if (!FRAME_WINDOW_P (f)
15571 && (!FRAME_LINE_INS_DEL_OK (f)
15572 || !WINDOW_FULL_WIDTH_P (w)))
15573 GIVE_UP (4);
15575 /* Give up if point is known NOT to appear in W. */
15576 if (PT < CHARPOS (start))
15577 GIVE_UP (5);
15579 /* Another way to prevent redisplay optimizations. */
15580 if (XFASTINT (w->last_modified) == 0)
15581 GIVE_UP (6);
15583 /* Verify that window is not hscrolled. */
15584 if (XFASTINT (w->hscroll) != 0)
15585 GIVE_UP (7);
15587 /* Verify that display wasn't paused. */
15588 if (NILP (w->window_end_valid))
15589 GIVE_UP (8);
15591 /* Can't use this if highlighting a region because a cursor movement
15592 will do more than just set the cursor. */
15593 if (!NILP (Vtransient_mark_mode)
15594 && !NILP (BVAR (current_buffer, mark_active)))
15595 GIVE_UP (9);
15597 /* Likewise if highlighting trailing whitespace. */
15598 if (!NILP (Vshow_trailing_whitespace))
15599 GIVE_UP (11);
15601 /* Likewise if showing a region. */
15602 if (!NILP (w->region_showing))
15603 GIVE_UP (10);
15605 /* Can't use this if overlay arrow position and/or string have
15606 changed. */
15607 if (overlay_arrows_changed_p ())
15608 GIVE_UP (12);
15610 /* When word-wrap is on, adding a space to the first word of a
15611 wrapped line can change the wrap position, altering the line
15612 above it. It might be worthwhile to handle this more
15613 intelligently, but for now just redisplay from scratch. */
15614 if (!NILP (BVAR (XBUFFER (w->buffer), word_wrap)))
15615 GIVE_UP (21);
15617 /* Under bidi reordering, adding or deleting a character in the
15618 beginning of a paragraph, before the first strong directional
15619 character, can change the base direction of the paragraph (unless
15620 the buffer specifies a fixed paragraph direction), which will
15621 require to redisplay the whole paragraph. It might be worthwhile
15622 to find the paragraph limits and widen the range of redisplayed
15623 lines to that, but for now just give up this optimization and
15624 redisplay from scratch. */
15625 if (!NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering))
15626 && NILP (BVAR (XBUFFER (w->buffer), bidi_paragraph_direction)))
15627 GIVE_UP (22);
15629 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
15630 only if buffer has really changed. The reason is that the gap is
15631 initially at Z for freshly visited files. The code below would
15632 set end_unchanged to 0 in that case. */
15633 if (MODIFF > SAVE_MODIFF
15634 /* This seems to happen sometimes after saving a buffer. */
15635 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
15637 if (GPT - BEG < BEG_UNCHANGED)
15638 BEG_UNCHANGED = GPT - BEG;
15639 if (Z - GPT < END_UNCHANGED)
15640 END_UNCHANGED = Z - GPT;
15643 /* The position of the first and last character that has been changed. */
15644 first_changed_charpos = BEG + BEG_UNCHANGED;
15645 last_changed_charpos = Z - END_UNCHANGED;
15647 /* If window starts after a line end, and the last change is in
15648 front of that newline, then changes don't affect the display.
15649 This case happens with stealth-fontification. Note that although
15650 the display is unchanged, glyph positions in the matrix have to
15651 be adjusted, of course. */
15652 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
15653 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
15654 && ((last_changed_charpos < CHARPOS (start)
15655 && CHARPOS (start) == BEGV)
15656 || (last_changed_charpos < CHARPOS (start) - 1
15657 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
15659 EMACS_INT Z_old, Z_delta, Z_BYTE_old, Z_delta_bytes;
15660 struct glyph_row *r0;
15662 /* Compute how many chars/bytes have been added to or removed
15663 from the buffer. */
15664 Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
15665 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
15666 Z_delta = Z - Z_old;
15667 Z_delta_bytes = Z_BYTE - Z_BYTE_old;
15669 /* Give up if PT is not in the window. Note that it already has
15670 been checked at the start of try_window_id that PT is not in
15671 front of the window start. */
15672 if (PT >= MATRIX_ROW_END_CHARPOS (row) + Z_delta)
15673 GIVE_UP (13);
15675 /* If window start is unchanged, we can reuse the whole matrix
15676 as is, after adjusting glyph positions. No need to compute
15677 the window end again, since its offset from Z hasn't changed. */
15678 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
15679 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + Z_delta
15680 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + Z_delta_bytes
15681 /* PT must not be in a partially visible line. */
15682 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + Z_delta
15683 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
15685 /* Adjust positions in the glyph matrix. */
15686 if (Z_delta || Z_delta_bytes)
15688 struct glyph_row *r1
15689 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
15690 increment_matrix_positions (w->current_matrix,
15691 MATRIX_ROW_VPOS (r0, current_matrix),
15692 MATRIX_ROW_VPOS (r1, current_matrix),
15693 Z_delta, Z_delta_bytes);
15696 /* Set the cursor. */
15697 row = row_containing_pos (w, PT, r0, NULL, 0);
15698 if (row)
15699 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
15700 else
15701 abort ();
15702 return 1;
15706 /* Handle the case that changes are all below what is displayed in
15707 the window, and that PT is in the window. This shortcut cannot
15708 be taken if ZV is visible in the window, and text has been added
15709 there that is visible in the window. */
15710 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
15711 /* ZV is not visible in the window, or there are no
15712 changes at ZV, actually. */
15713 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
15714 || first_changed_charpos == last_changed_charpos))
15716 struct glyph_row *r0;
15718 /* Give up if PT is not in the window. Note that it already has
15719 been checked at the start of try_window_id that PT is not in
15720 front of the window start. */
15721 if (PT >= MATRIX_ROW_END_CHARPOS (row))
15722 GIVE_UP (14);
15724 /* If window start is unchanged, we can reuse the whole matrix
15725 as is, without changing glyph positions since no text has
15726 been added/removed in front of the window end. */
15727 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
15728 if (TEXT_POS_EQUAL_P (start, r0->minpos)
15729 /* PT must not be in a partially visible line. */
15730 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
15731 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
15733 /* We have to compute the window end anew since text
15734 could have been added/removed after it. */
15735 w->window_end_pos
15736 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
15737 w->window_end_bytepos
15738 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
15740 /* Set the cursor. */
15741 row = row_containing_pos (w, PT, r0, NULL, 0);
15742 if (row)
15743 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
15744 else
15745 abort ();
15746 return 2;
15750 /* Give up if window start is in the changed area.
15752 The condition used to read
15754 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
15756 but why that was tested escapes me at the moment. */
15757 if (CHARPOS (start) >= first_changed_charpos
15758 && CHARPOS (start) <= last_changed_charpos)
15759 GIVE_UP (15);
15761 /* Check that window start agrees with the start of the first glyph
15762 row in its current matrix. Check this after we know the window
15763 start is not in changed text, otherwise positions would not be
15764 comparable. */
15765 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
15766 if (!TEXT_POS_EQUAL_P (start, row->minpos))
15767 GIVE_UP (16);
15769 /* Give up if the window ends in strings. Overlay strings
15770 at the end are difficult to handle, so don't try. */
15771 row = MATRIX_ROW (current_matrix, XFASTINT (w->window_end_vpos));
15772 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
15773 GIVE_UP (20);
15775 /* Compute the position at which we have to start displaying new
15776 lines. Some of the lines at the top of the window might be
15777 reusable because they are not displaying changed text. Find the
15778 last row in W's current matrix not affected by changes at the
15779 start of current_buffer. Value is null if changes start in the
15780 first line of window. */
15781 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
15782 if (last_unchanged_at_beg_row)
15784 /* Avoid starting to display in the moddle of a character, a TAB
15785 for instance. This is easier than to set up the iterator
15786 exactly, and it's not a frequent case, so the additional
15787 effort wouldn't really pay off. */
15788 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
15789 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
15790 && last_unchanged_at_beg_row > w->current_matrix->rows)
15791 --last_unchanged_at_beg_row;
15793 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
15794 GIVE_UP (17);
15796 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
15797 GIVE_UP (18);
15798 start_pos = it.current.pos;
15800 /* Start displaying new lines in the desired matrix at the same
15801 vpos we would use in the current matrix, i.e. below
15802 last_unchanged_at_beg_row. */
15803 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
15804 current_matrix);
15805 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
15806 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
15808 xassert (it.hpos == 0 && it.current_x == 0);
15810 else
15812 /* There are no reusable lines at the start of the window.
15813 Start displaying in the first text line. */
15814 start_display (&it, w, start);
15815 it.vpos = it.first_vpos;
15816 start_pos = it.current.pos;
15819 /* Find the first row that is not affected by changes at the end of
15820 the buffer. Value will be null if there is no unchanged row, in
15821 which case we must redisplay to the end of the window. delta
15822 will be set to the value by which buffer positions beginning with
15823 first_unchanged_at_end_row have to be adjusted due to text
15824 changes. */
15825 first_unchanged_at_end_row
15826 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
15827 IF_DEBUG (debug_delta = delta);
15828 IF_DEBUG (debug_delta_bytes = delta_bytes);
15830 /* Set stop_pos to the buffer position up to which we will have to
15831 display new lines. If first_unchanged_at_end_row != NULL, this
15832 is the buffer position of the start of the line displayed in that
15833 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
15834 that we don't stop at a buffer position. */
15835 stop_pos = 0;
15836 if (first_unchanged_at_end_row)
15838 xassert (last_unchanged_at_beg_row == NULL
15839 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
15841 /* If this is a continuation line, move forward to the next one
15842 that isn't. Changes in lines above affect this line.
15843 Caution: this may move first_unchanged_at_end_row to a row
15844 not displaying text. */
15845 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
15846 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
15847 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
15848 < it.last_visible_y))
15849 ++first_unchanged_at_end_row;
15851 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
15852 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
15853 >= it.last_visible_y))
15854 first_unchanged_at_end_row = NULL;
15855 else
15857 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
15858 + delta);
15859 first_unchanged_at_end_vpos
15860 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
15861 xassert (stop_pos >= Z - END_UNCHANGED);
15864 else if (last_unchanged_at_beg_row == NULL)
15865 GIVE_UP (19);
15868 #if GLYPH_DEBUG
15870 /* Either there is no unchanged row at the end, or the one we have
15871 now displays text. This is a necessary condition for the window
15872 end pos calculation at the end of this function. */
15873 xassert (first_unchanged_at_end_row == NULL
15874 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
15876 debug_last_unchanged_at_beg_vpos
15877 = (last_unchanged_at_beg_row
15878 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
15879 : -1);
15880 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
15882 #endif /* GLYPH_DEBUG != 0 */
15885 /* Display new lines. Set last_text_row to the last new line
15886 displayed which has text on it, i.e. might end up as being the
15887 line where the window_end_vpos is. */
15888 w->cursor.vpos = -1;
15889 last_text_row = NULL;
15890 overlay_arrow_seen = 0;
15891 while (it.current_y < it.last_visible_y
15892 && !fonts_changed_p
15893 && (first_unchanged_at_end_row == NULL
15894 || IT_CHARPOS (it) < stop_pos))
15896 if (display_line (&it))
15897 last_text_row = it.glyph_row - 1;
15900 if (fonts_changed_p)
15901 return -1;
15904 /* Compute differences in buffer positions, y-positions etc. for
15905 lines reused at the bottom of the window. Compute what we can
15906 scroll. */
15907 if (first_unchanged_at_end_row
15908 /* No lines reused because we displayed everything up to the
15909 bottom of the window. */
15910 && it.current_y < it.last_visible_y)
15912 dvpos = (it.vpos
15913 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
15914 current_matrix));
15915 dy = it.current_y - first_unchanged_at_end_row->y;
15916 run.current_y = first_unchanged_at_end_row->y;
15917 run.desired_y = run.current_y + dy;
15918 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
15920 else
15922 delta = delta_bytes = dvpos = dy
15923 = run.current_y = run.desired_y = run.height = 0;
15924 first_unchanged_at_end_row = NULL;
15926 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
15929 /* Find the cursor if not already found. We have to decide whether
15930 PT will appear on this window (it sometimes doesn't, but this is
15931 not a very frequent case.) This decision has to be made before
15932 the current matrix is altered. A value of cursor.vpos < 0 means
15933 that PT is either in one of the lines beginning at
15934 first_unchanged_at_end_row or below the window. Don't care for
15935 lines that might be displayed later at the window end; as
15936 mentioned, this is not a frequent case. */
15937 if (w->cursor.vpos < 0)
15939 /* Cursor in unchanged rows at the top? */
15940 if (PT < CHARPOS (start_pos)
15941 && last_unchanged_at_beg_row)
15943 row = row_containing_pos (w, PT,
15944 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
15945 last_unchanged_at_beg_row + 1, 0);
15946 if (row)
15947 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
15950 /* Start from first_unchanged_at_end_row looking for PT. */
15951 else if (first_unchanged_at_end_row)
15953 row = row_containing_pos (w, PT - delta,
15954 first_unchanged_at_end_row, NULL, 0);
15955 if (row)
15956 set_cursor_from_row (w, row, w->current_matrix, delta,
15957 delta_bytes, dy, dvpos);
15960 /* Give up if cursor was not found. */
15961 if (w->cursor.vpos < 0)
15963 clear_glyph_matrix (w->desired_matrix);
15964 return -1;
15968 /* Don't let the cursor end in the scroll margins. */
15970 int this_scroll_margin, cursor_height;
15972 this_scroll_margin = max (0, scroll_margin);
15973 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
15974 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
15975 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
15977 if ((w->cursor.y < this_scroll_margin
15978 && CHARPOS (start) > BEGV)
15979 /* Old redisplay didn't take scroll margin into account at the bottom,
15980 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
15981 || (w->cursor.y + (make_cursor_line_fully_visible_p
15982 ? cursor_height + this_scroll_margin
15983 : 1)) > it.last_visible_y)
15985 w->cursor.vpos = -1;
15986 clear_glyph_matrix (w->desired_matrix);
15987 return -1;
15991 /* Scroll the display. Do it before changing the current matrix so
15992 that xterm.c doesn't get confused about where the cursor glyph is
15993 found. */
15994 if (dy && run.height)
15996 update_begin (f);
15998 if (FRAME_WINDOW_P (f))
16000 FRAME_RIF (f)->update_window_begin_hook (w);
16001 FRAME_RIF (f)->clear_window_mouse_face (w);
16002 FRAME_RIF (f)->scroll_run_hook (w, &run);
16003 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
16005 else
16007 /* Terminal frame. In this case, dvpos gives the number of
16008 lines to scroll by; dvpos < 0 means scroll up. */
16009 int from_vpos
16010 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
16011 int from = WINDOW_TOP_EDGE_LINE (w) + from_vpos;
16012 int end = (WINDOW_TOP_EDGE_LINE (w)
16013 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
16014 + window_internal_height (w));
16016 #if defined (HAVE_GPM) || defined (MSDOS)
16017 x_clear_window_mouse_face (w);
16018 #endif
16019 /* Perform the operation on the screen. */
16020 if (dvpos > 0)
16022 /* Scroll last_unchanged_at_beg_row to the end of the
16023 window down dvpos lines. */
16024 set_terminal_window (f, end);
16026 /* On dumb terminals delete dvpos lines at the end
16027 before inserting dvpos empty lines. */
16028 if (!FRAME_SCROLL_REGION_OK (f))
16029 ins_del_lines (f, end - dvpos, -dvpos);
16031 /* Insert dvpos empty lines in front of
16032 last_unchanged_at_beg_row. */
16033 ins_del_lines (f, from, dvpos);
16035 else if (dvpos < 0)
16037 /* Scroll up last_unchanged_at_beg_vpos to the end of
16038 the window to last_unchanged_at_beg_vpos - |dvpos|. */
16039 set_terminal_window (f, end);
16041 /* Delete dvpos lines in front of
16042 last_unchanged_at_beg_vpos. ins_del_lines will set
16043 the cursor to the given vpos and emit |dvpos| delete
16044 line sequences. */
16045 ins_del_lines (f, from + dvpos, dvpos);
16047 /* On a dumb terminal insert dvpos empty lines at the
16048 end. */
16049 if (!FRAME_SCROLL_REGION_OK (f))
16050 ins_del_lines (f, end + dvpos, -dvpos);
16053 set_terminal_window (f, 0);
16056 update_end (f);
16059 /* Shift reused rows of the current matrix to the right position.
16060 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
16061 text. */
16062 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
16063 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
16064 if (dvpos < 0)
16066 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
16067 bottom_vpos, dvpos);
16068 enable_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
16069 bottom_vpos, 0);
16071 else if (dvpos > 0)
16073 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
16074 bottom_vpos, dvpos);
16075 enable_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
16076 first_unchanged_at_end_vpos + dvpos, 0);
16079 /* For frame-based redisplay, make sure that current frame and window
16080 matrix are in sync with respect to glyph memory. */
16081 if (!FRAME_WINDOW_P (f))
16082 sync_frame_with_window_matrix_rows (w);
16084 /* Adjust buffer positions in reused rows. */
16085 if (delta || delta_bytes)
16086 increment_matrix_positions (current_matrix,
16087 first_unchanged_at_end_vpos + dvpos,
16088 bottom_vpos, delta, delta_bytes);
16090 /* Adjust Y positions. */
16091 if (dy)
16092 shift_glyph_matrix (w, current_matrix,
16093 first_unchanged_at_end_vpos + dvpos,
16094 bottom_vpos, dy);
16096 if (first_unchanged_at_end_row)
16098 first_unchanged_at_end_row += dvpos;
16099 if (first_unchanged_at_end_row->y >= it.last_visible_y
16100 || !MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row))
16101 first_unchanged_at_end_row = NULL;
16104 /* If scrolling up, there may be some lines to display at the end of
16105 the window. */
16106 last_text_row_at_end = NULL;
16107 if (dy < 0)
16109 /* Scrolling up can leave for example a partially visible line
16110 at the end of the window to be redisplayed. */
16111 /* Set last_row to the glyph row in the current matrix where the
16112 window end line is found. It has been moved up or down in
16113 the matrix by dvpos. */
16114 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
16115 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
16117 /* If last_row is the window end line, it should display text. */
16118 xassert (last_row->displays_text_p);
16120 /* If window end line was partially visible before, begin
16121 displaying at that line. Otherwise begin displaying with the
16122 line following it. */
16123 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
16125 init_to_row_start (&it, w, last_row);
16126 it.vpos = last_vpos;
16127 it.current_y = last_row->y;
16129 else
16131 init_to_row_end (&it, w, last_row);
16132 it.vpos = 1 + last_vpos;
16133 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
16134 ++last_row;
16137 /* We may start in a continuation line. If so, we have to
16138 get the right continuation_lines_width and current_x. */
16139 it.continuation_lines_width = last_row->continuation_lines_width;
16140 it.hpos = it.current_x = 0;
16142 /* Display the rest of the lines at the window end. */
16143 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
16144 while (it.current_y < it.last_visible_y
16145 && !fonts_changed_p)
16147 /* Is it always sure that the display agrees with lines in
16148 the current matrix? I don't think so, so we mark rows
16149 displayed invalid in the current matrix by setting their
16150 enabled_p flag to zero. */
16151 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
16152 if (display_line (&it))
16153 last_text_row_at_end = it.glyph_row - 1;
16157 /* Update window_end_pos and window_end_vpos. */
16158 if (first_unchanged_at_end_row
16159 && !last_text_row_at_end)
16161 /* Window end line if one of the preserved rows from the current
16162 matrix. Set row to the last row displaying text in current
16163 matrix starting at first_unchanged_at_end_row, after
16164 scrolling. */
16165 xassert (first_unchanged_at_end_row->displays_text_p);
16166 row = find_last_row_displaying_text (w->current_matrix, &it,
16167 first_unchanged_at_end_row);
16168 xassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
16170 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
16171 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
16172 w->window_end_vpos
16173 = make_number (MATRIX_ROW_VPOS (row, w->current_matrix));
16174 xassert (w->window_end_bytepos >= 0);
16175 IF_DEBUG (debug_method_add (w, "A"));
16177 else if (last_text_row_at_end)
16179 w->window_end_pos
16180 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end));
16181 w->window_end_bytepos
16182 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
16183 w->window_end_vpos
16184 = make_number (MATRIX_ROW_VPOS (last_text_row_at_end, desired_matrix));
16185 xassert (w->window_end_bytepos >= 0);
16186 IF_DEBUG (debug_method_add (w, "B"));
16188 else if (last_text_row)
16190 /* We have displayed either to the end of the window or at the
16191 end of the window, i.e. the last row with text is to be found
16192 in the desired matrix. */
16193 w->window_end_pos
16194 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
16195 w->window_end_bytepos
16196 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
16197 w->window_end_vpos
16198 = make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix));
16199 xassert (w->window_end_bytepos >= 0);
16201 else if (first_unchanged_at_end_row == NULL
16202 && last_text_row == NULL
16203 && last_text_row_at_end == NULL)
16205 /* Displayed to end of window, but no line containing text was
16206 displayed. Lines were deleted at the end of the window. */
16207 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
16208 int vpos = XFASTINT (w->window_end_vpos);
16209 struct glyph_row *current_row = current_matrix->rows + vpos;
16210 struct glyph_row *desired_row = desired_matrix->rows + vpos;
16212 for (row = NULL;
16213 row == NULL && vpos >= first_vpos;
16214 --vpos, --current_row, --desired_row)
16216 if (desired_row->enabled_p)
16218 if (desired_row->displays_text_p)
16219 row = desired_row;
16221 else if (current_row->displays_text_p)
16222 row = current_row;
16225 xassert (row != NULL);
16226 w->window_end_vpos = make_number (vpos + 1);
16227 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
16228 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
16229 xassert (w->window_end_bytepos >= 0);
16230 IF_DEBUG (debug_method_add (w, "C"));
16232 else
16233 abort ();
16235 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
16236 debug_end_vpos = XFASTINT (w->window_end_vpos));
16238 /* Record that display has not been completed. */
16239 w->window_end_valid = Qnil;
16240 w->desired_matrix->no_scrolling_p = 1;
16241 return 3;
16243 #undef GIVE_UP
16248 /***********************************************************************
16249 More debugging support
16250 ***********************************************************************/
16252 #if GLYPH_DEBUG
16254 void dump_glyph_row (struct glyph_row *, int, int);
16255 void dump_glyph_matrix (struct glyph_matrix *, int);
16256 void dump_glyph (struct glyph_row *, struct glyph *, int);
16259 /* Dump the contents of glyph matrix MATRIX on stderr.
16261 GLYPHS 0 means don't show glyph contents.
16262 GLYPHS 1 means show glyphs in short form
16263 GLYPHS > 1 means show glyphs in long form. */
16265 void
16266 dump_glyph_matrix (matrix, glyphs)
16267 struct glyph_matrix *matrix;
16268 int glyphs;
16270 int i;
16271 for (i = 0; i < matrix->nrows; ++i)
16272 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
16276 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
16277 the glyph row and area where the glyph comes from. */
16279 void
16280 dump_glyph (row, glyph, area)
16281 struct glyph_row *row;
16282 struct glyph *glyph;
16283 int area;
16285 if (glyph->type == CHAR_GLYPH)
16287 fprintf (stderr,
16288 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
16289 glyph - row->glyphs[TEXT_AREA],
16290 'C',
16291 glyph->charpos,
16292 (BUFFERP (glyph->object)
16293 ? 'B'
16294 : (STRINGP (glyph->object)
16295 ? 'S'
16296 : '-')),
16297 glyph->pixel_width,
16298 glyph->u.ch,
16299 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
16300 ? glyph->u.ch
16301 : '.'),
16302 glyph->face_id,
16303 glyph->left_box_line_p,
16304 glyph->right_box_line_p);
16306 else if (glyph->type == STRETCH_GLYPH)
16308 fprintf (stderr,
16309 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
16310 glyph - row->glyphs[TEXT_AREA],
16311 'S',
16312 glyph->charpos,
16313 (BUFFERP (glyph->object)
16314 ? 'B'
16315 : (STRINGP (glyph->object)
16316 ? 'S'
16317 : '-')),
16318 glyph->pixel_width,
16320 '.',
16321 glyph->face_id,
16322 glyph->left_box_line_p,
16323 glyph->right_box_line_p);
16325 else if (glyph->type == IMAGE_GLYPH)
16327 fprintf (stderr,
16328 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
16329 glyph - row->glyphs[TEXT_AREA],
16330 'I',
16331 glyph->charpos,
16332 (BUFFERP (glyph->object)
16333 ? 'B'
16334 : (STRINGP (glyph->object)
16335 ? 'S'
16336 : '-')),
16337 glyph->pixel_width,
16338 glyph->u.img_id,
16339 '.',
16340 glyph->face_id,
16341 glyph->left_box_line_p,
16342 glyph->right_box_line_p);
16344 else if (glyph->type == COMPOSITE_GLYPH)
16346 fprintf (stderr,
16347 " %5d %4c %6d %c %3d 0x%05x",
16348 glyph - row->glyphs[TEXT_AREA],
16349 '+',
16350 glyph->charpos,
16351 (BUFFERP (glyph->object)
16352 ? 'B'
16353 : (STRINGP (glyph->object)
16354 ? 'S'
16355 : '-')),
16356 glyph->pixel_width,
16357 glyph->u.cmp.id);
16358 if (glyph->u.cmp.automatic)
16359 fprintf (stderr,
16360 "[%d-%d]",
16361 glyph->slice.cmp.from, glyph->slice.cmp.to);
16362 fprintf (stderr, " . %4d %1.1d%1.1d\n",
16363 glyph->face_id,
16364 glyph->left_box_line_p,
16365 glyph->right_box_line_p);
16370 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
16371 GLYPHS 0 means don't show glyph contents.
16372 GLYPHS 1 means show glyphs in short form
16373 GLYPHS > 1 means show glyphs in long form. */
16375 void
16376 dump_glyph_row (row, vpos, glyphs)
16377 struct glyph_row *row;
16378 int vpos, glyphs;
16380 if (glyphs != 1)
16382 fprintf (stderr, "Row Start End Used oE><\\CTZFesm X Y W H V A P\n");
16383 fprintf (stderr, "======================================================================\n");
16385 fprintf (stderr, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d\
16386 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
16387 vpos,
16388 MATRIX_ROW_START_CHARPOS (row),
16389 MATRIX_ROW_END_CHARPOS (row),
16390 row->used[TEXT_AREA],
16391 row->contains_overlapping_glyphs_p,
16392 row->enabled_p,
16393 row->truncated_on_left_p,
16394 row->truncated_on_right_p,
16395 row->continued_p,
16396 MATRIX_ROW_CONTINUATION_LINE_P (row),
16397 row->displays_text_p,
16398 row->ends_at_zv_p,
16399 row->fill_line_p,
16400 row->ends_in_middle_of_char_p,
16401 row->starts_in_middle_of_char_p,
16402 row->mouse_face_p,
16403 row->x,
16404 row->y,
16405 row->pixel_width,
16406 row->height,
16407 row->visible_height,
16408 row->ascent,
16409 row->phys_ascent);
16410 fprintf (stderr, "%9d %5d\t%5d\n", row->start.overlay_string_index,
16411 row->end.overlay_string_index,
16412 row->continuation_lines_width);
16413 fprintf (stderr, "%9d %5d\n",
16414 CHARPOS (row->start.string_pos),
16415 CHARPOS (row->end.string_pos));
16416 fprintf (stderr, "%9d %5d\n", row->start.dpvec_index,
16417 row->end.dpvec_index);
16420 if (glyphs > 1)
16422 int area;
16424 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
16426 struct glyph *glyph = row->glyphs[area];
16427 struct glyph *glyph_end = glyph + row->used[area];
16429 /* Glyph for a line end in text. */
16430 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
16431 ++glyph_end;
16433 if (glyph < glyph_end)
16434 fprintf (stderr, " Glyph Type Pos O W Code C Face LR\n");
16436 for (; glyph < glyph_end; ++glyph)
16437 dump_glyph (row, glyph, area);
16440 else if (glyphs == 1)
16442 int area;
16444 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
16446 char *s = (char *) alloca (row->used[area] + 1);
16447 int i;
16449 for (i = 0; i < row->used[area]; ++i)
16451 struct glyph *glyph = row->glyphs[area] + i;
16452 if (glyph->type == CHAR_GLYPH
16453 && glyph->u.ch < 0x80
16454 && glyph->u.ch >= ' ')
16455 s[i] = glyph->u.ch;
16456 else
16457 s[i] = '.';
16460 s[i] = '\0';
16461 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
16467 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
16468 Sdump_glyph_matrix, 0, 1, "p",
16469 doc: /* Dump the current matrix of the selected window to stderr.
16470 Shows contents of glyph row structures. With non-nil
16471 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
16472 glyphs in short form, otherwise show glyphs in long form. */)
16473 (Lisp_Object glyphs)
16475 struct window *w = XWINDOW (selected_window);
16476 struct buffer *buffer = XBUFFER (w->buffer);
16478 fprintf (stderr, "PT = %d, BEGV = %d. ZV = %d\n",
16479 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
16480 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
16481 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
16482 fprintf (stderr, "=============================================\n");
16483 dump_glyph_matrix (w->current_matrix,
16484 NILP (glyphs) ? 0 : XINT (glyphs));
16485 return Qnil;
16489 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
16490 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
16491 (void)
16493 struct frame *f = XFRAME (selected_frame);
16494 dump_glyph_matrix (f->current_matrix, 1);
16495 return Qnil;
16499 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
16500 doc: /* Dump glyph row ROW to stderr.
16501 GLYPH 0 means don't dump glyphs.
16502 GLYPH 1 means dump glyphs in short form.
16503 GLYPH > 1 or omitted means dump glyphs in long form. */)
16504 (Lisp_Object row, Lisp_Object glyphs)
16506 struct glyph_matrix *matrix;
16507 int vpos;
16509 CHECK_NUMBER (row);
16510 matrix = XWINDOW (selected_window)->current_matrix;
16511 vpos = XINT (row);
16512 if (vpos >= 0 && vpos < matrix->nrows)
16513 dump_glyph_row (MATRIX_ROW (matrix, vpos),
16514 vpos,
16515 INTEGERP (glyphs) ? XINT (glyphs) : 2);
16516 return Qnil;
16520 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
16521 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
16522 GLYPH 0 means don't dump glyphs.
16523 GLYPH 1 means dump glyphs in short form.
16524 GLYPH > 1 or omitted means dump glyphs in long form. */)
16525 (Lisp_Object row, Lisp_Object glyphs)
16527 struct frame *sf = SELECTED_FRAME ();
16528 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
16529 int vpos;
16531 CHECK_NUMBER (row);
16532 vpos = XINT (row);
16533 if (vpos >= 0 && vpos < m->nrows)
16534 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
16535 INTEGERP (glyphs) ? XINT (glyphs) : 2);
16536 return Qnil;
16540 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
16541 doc: /* Toggle tracing of redisplay.
16542 With ARG, turn tracing on if and only if ARG is positive. */)
16543 (Lisp_Object arg)
16545 if (NILP (arg))
16546 trace_redisplay_p = !trace_redisplay_p;
16547 else
16549 arg = Fprefix_numeric_value (arg);
16550 trace_redisplay_p = XINT (arg) > 0;
16553 return Qnil;
16557 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
16558 doc: /* Like `format', but print result to stderr.
16559 usage: (trace-to-stderr STRING &rest OBJECTS) */)
16560 (size_t nargs, Lisp_Object *args)
16562 Lisp_Object s = Fformat (nargs, args);
16563 fprintf (stderr, "%s", SDATA (s));
16564 return Qnil;
16567 #endif /* GLYPH_DEBUG */
16571 /***********************************************************************
16572 Building Desired Matrix Rows
16573 ***********************************************************************/
16575 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
16576 Used for non-window-redisplay windows, and for windows w/o left fringe. */
16578 static struct glyph_row *
16579 get_overlay_arrow_glyph_row (struct window *w, Lisp_Object overlay_arrow_string)
16581 struct frame *f = XFRAME (WINDOW_FRAME (w));
16582 struct buffer *buffer = XBUFFER (w->buffer);
16583 struct buffer *old = current_buffer;
16584 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
16585 int arrow_len = SCHARS (overlay_arrow_string);
16586 const unsigned char *arrow_end = arrow_string + arrow_len;
16587 const unsigned char *p;
16588 struct it it;
16589 int multibyte_p;
16590 int n_glyphs_before;
16592 set_buffer_temp (buffer);
16593 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
16594 it.glyph_row->used[TEXT_AREA] = 0;
16595 SET_TEXT_POS (it.position, 0, 0);
16597 multibyte_p = !NILP (BVAR (buffer, enable_multibyte_characters));
16598 p = arrow_string;
16599 while (p < arrow_end)
16601 Lisp_Object face, ilisp;
16603 /* Get the next character. */
16604 if (multibyte_p)
16605 it.c = it.char_to_display = string_char_and_length (p, &it.len);
16606 else
16608 it.c = it.char_to_display = *p, it.len = 1;
16609 if (! ASCII_CHAR_P (it.c))
16610 it.char_to_display = BYTE8_TO_CHAR (it.c);
16612 p += it.len;
16614 /* Get its face. */
16615 ilisp = make_number (p - arrow_string);
16616 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
16617 it.face_id = compute_char_face (f, it.char_to_display, face);
16619 /* Compute its width, get its glyphs. */
16620 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
16621 SET_TEXT_POS (it.position, -1, -1);
16622 PRODUCE_GLYPHS (&it);
16624 /* If this character doesn't fit any more in the line, we have
16625 to remove some glyphs. */
16626 if (it.current_x > it.last_visible_x)
16628 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
16629 break;
16633 set_buffer_temp (old);
16634 return it.glyph_row;
16638 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
16639 glyphs are only inserted for terminal frames since we can't really
16640 win with truncation glyphs when partially visible glyphs are
16641 involved. Which glyphs to insert is determined by
16642 produce_special_glyphs. */
16644 static void
16645 insert_left_trunc_glyphs (struct it *it)
16647 struct it truncate_it;
16648 struct glyph *from, *end, *to, *toend;
16650 xassert (!FRAME_WINDOW_P (it->f));
16652 /* Get the truncation glyphs. */
16653 truncate_it = *it;
16654 truncate_it.current_x = 0;
16655 truncate_it.face_id = DEFAULT_FACE_ID;
16656 truncate_it.glyph_row = &scratch_glyph_row;
16657 truncate_it.glyph_row->used[TEXT_AREA] = 0;
16658 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
16659 truncate_it.object = make_number (0);
16660 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
16662 /* Overwrite glyphs from IT with truncation glyphs. */
16663 if (!it->glyph_row->reversed_p)
16665 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
16666 end = from + truncate_it.glyph_row->used[TEXT_AREA];
16667 to = it->glyph_row->glyphs[TEXT_AREA];
16668 toend = to + it->glyph_row->used[TEXT_AREA];
16670 while (from < end)
16671 *to++ = *from++;
16673 /* There may be padding glyphs left over. Overwrite them too. */
16674 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
16676 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
16677 while (from < end)
16678 *to++ = *from++;
16681 if (to > toend)
16682 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
16684 else
16686 /* In R2L rows, overwrite the last (rightmost) glyphs, and do
16687 that back to front. */
16688 end = truncate_it.glyph_row->glyphs[TEXT_AREA];
16689 from = end + truncate_it.glyph_row->used[TEXT_AREA] - 1;
16690 toend = it->glyph_row->glyphs[TEXT_AREA];
16691 to = toend + it->glyph_row->used[TEXT_AREA] - 1;
16693 while (from >= end && to >= toend)
16694 *to-- = *from--;
16695 while (to >= toend && CHAR_GLYPH_PADDING_P (*to))
16697 from =
16698 truncate_it.glyph_row->glyphs[TEXT_AREA]
16699 + truncate_it.glyph_row->used[TEXT_AREA] - 1;
16700 while (from >= end && to >= toend)
16701 *to-- = *from--;
16703 if (from >= end)
16705 /* Need to free some room before prepending additional
16706 glyphs. */
16707 int move_by = from - end + 1;
16708 struct glyph *g0 = it->glyph_row->glyphs[TEXT_AREA];
16709 struct glyph *g = g0 + it->glyph_row->used[TEXT_AREA] - 1;
16711 for ( ; g >= g0; g--)
16712 g[move_by] = *g;
16713 while (from >= end)
16714 *to-- = *from--;
16715 it->glyph_row->used[TEXT_AREA] += move_by;
16721 /* Compute the pixel height and width of IT->glyph_row.
16723 Most of the time, ascent and height of a display line will be equal
16724 to the max_ascent and max_height values of the display iterator
16725 structure. This is not the case if
16727 1. We hit ZV without displaying anything. In this case, max_ascent
16728 and max_height will be zero.
16730 2. We have some glyphs that don't contribute to the line height.
16731 (The glyph row flag contributes_to_line_height_p is for future
16732 pixmap extensions).
16734 The first case is easily covered by using default values because in
16735 these cases, the line height does not really matter, except that it
16736 must not be zero. */
16738 static void
16739 compute_line_metrics (struct it *it)
16741 struct glyph_row *row = it->glyph_row;
16743 if (FRAME_WINDOW_P (it->f))
16745 int i, min_y, max_y;
16747 /* The line may consist of one space only, that was added to
16748 place the cursor on it. If so, the row's height hasn't been
16749 computed yet. */
16750 if (row->height == 0)
16752 if (it->max_ascent + it->max_descent == 0)
16753 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
16754 row->ascent = it->max_ascent;
16755 row->height = it->max_ascent + it->max_descent;
16756 row->phys_ascent = it->max_phys_ascent;
16757 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
16758 row->extra_line_spacing = it->max_extra_line_spacing;
16761 /* Compute the width of this line. */
16762 row->pixel_width = row->x;
16763 for (i = 0; i < row->used[TEXT_AREA]; ++i)
16764 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
16766 xassert (row->pixel_width >= 0);
16767 xassert (row->ascent >= 0 && row->height > 0);
16769 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
16770 || MATRIX_ROW_OVERLAPS_PRED_P (row));
16772 /* If first line's physical ascent is larger than its logical
16773 ascent, use the physical ascent, and make the row taller.
16774 This makes accented characters fully visible. */
16775 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
16776 && row->phys_ascent > row->ascent)
16778 row->height += row->phys_ascent - row->ascent;
16779 row->ascent = row->phys_ascent;
16782 /* Compute how much of the line is visible. */
16783 row->visible_height = row->height;
16785 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
16786 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
16788 if (row->y < min_y)
16789 row->visible_height -= min_y - row->y;
16790 if (row->y + row->height > max_y)
16791 row->visible_height -= row->y + row->height - max_y;
16793 else
16795 row->pixel_width = row->used[TEXT_AREA];
16796 if (row->continued_p)
16797 row->pixel_width -= it->continuation_pixel_width;
16798 else if (row->truncated_on_right_p)
16799 row->pixel_width -= it->truncation_pixel_width;
16800 row->ascent = row->phys_ascent = 0;
16801 row->height = row->phys_height = row->visible_height = 1;
16802 row->extra_line_spacing = 0;
16805 /* Compute a hash code for this row. */
16807 int area, i;
16808 row->hash = 0;
16809 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
16810 for (i = 0; i < row->used[area]; ++i)
16811 row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff)
16812 + row->glyphs[area][i].u.val
16813 + row->glyphs[area][i].face_id
16814 + row->glyphs[area][i].padding_p
16815 + (row->glyphs[area][i].type << 2));
16818 it->max_ascent = it->max_descent = 0;
16819 it->max_phys_ascent = it->max_phys_descent = 0;
16823 /* Append one space to the glyph row of iterator IT if doing a
16824 window-based redisplay. The space has the same face as
16825 IT->face_id. Value is non-zero if a space was added.
16827 This function is called to make sure that there is always one glyph
16828 at the end of a glyph row that the cursor can be set on under
16829 window-systems. (If there weren't such a glyph we would not know
16830 how wide and tall a box cursor should be displayed).
16832 At the same time this space let's a nicely handle clearing to the
16833 end of the line if the row ends in italic text. */
16835 static int
16836 append_space_for_newline (struct it *it, int default_face_p)
16838 if (FRAME_WINDOW_P (it->f))
16840 int n = it->glyph_row->used[TEXT_AREA];
16842 if (it->glyph_row->glyphs[TEXT_AREA] + n
16843 < it->glyph_row->glyphs[1 + TEXT_AREA])
16845 /* Save some values that must not be changed.
16846 Must save IT->c and IT->len because otherwise
16847 ITERATOR_AT_END_P wouldn't work anymore after
16848 append_space_for_newline has been called. */
16849 enum display_element_type saved_what = it->what;
16850 int saved_c = it->c, saved_len = it->len;
16851 int saved_char_to_display = it->char_to_display;
16852 int saved_x = it->current_x;
16853 int saved_face_id = it->face_id;
16854 struct text_pos saved_pos;
16855 Lisp_Object saved_object;
16856 struct face *face;
16858 saved_object = it->object;
16859 saved_pos = it->position;
16861 it->what = IT_CHARACTER;
16862 memset (&it->position, 0, sizeof it->position);
16863 it->object = make_number (0);
16864 it->c = it->char_to_display = ' ';
16865 it->len = 1;
16867 if (default_face_p)
16868 it->face_id = DEFAULT_FACE_ID;
16869 else if (it->face_before_selective_p)
16870 it->face_id = it->saved_face_id;
16871 face = FACE_FROM_ID (it->f, it->face_id);
16872 it->face_id = FACE_FOR_CHAR (it->f, face, 0, -1, Qnil);
16874 PRODUCE_GLYPHS (it);
16876 it->override_ascent = -1;
16877 it->constrain_row_ascent_descent_p = 0;
16878 it->current_x = saved_x;
16879 it->object = saved_object;
16880 it->position = saved_pos;
16881 it->what = saved_what;
16882 it->face_id = saved_face_id;
16883 it->len = saved_len;
16884 it->c = saved_c;
16885 it->char_to_display = saved_char_to_display;
16886 return 1;
16890 return 0;
16894 /* Extend the face of the last glyph in the text area of IT->glyph_row
16895 to the end of the display line. Called from display_line. If the
16896 glyph row is empty, add a space glyph to it so that we know the
16897 face to draw. Set the glyph row flag fill_line_p. If the glyph
16898 row is R2L, prepend a stretch glyph to cover the empty space to the
16899 left of the leftmost glyph. */
16901 static void
16902 extend_face_to_end_of_line (struct it *it)
16904 struct face *face;
16905 struct frame *f = it->f;
16907 /* If line is already filled, do nothing. Non window-system frames
16908 get a grace of one more ``pixel'' because their characters are
16909 1-``pixel'' wide, so they hit the equality too early. This grace
16910 is needed only for R2L rows that are not continued, to produce
16911 one extra blank where we could display the cursor. */
16912 if (it->current_x >= it->last_visible_x
16913 + (!FRAME_WINDOW_P (f)
16914 && it->glyph_row->reversed_p
16915 && !it->glyph_row->continued_p))
16916 return;
16918 /* Face extension extends the background and box of IT->face_id
16919 to the end of the line. If the background equals the background
16920 of the frame, we don't have to do anything. */
16921 if (it->face_before_selective_p)
16922 face = FACE_FROM_ID (f, it->saved_face_id);
16923 else
16924 face = FACE_FROM_ID (f, it->face_id);
16926 if (FRAME_WINDOW_P (f)
16927 && it->glyph_row->displays_text_p
16928 && face->box == FACE_NO_BOX
16929 && face->background == FRAME_BACKGROUND_PIXEL (f)
16930 && !face->stipple
16931 && !it->glyph_row->reversed_p)
16932 return;
16934 /* Set the glyph row flag indicating that the face of the last glyph
16935 in the text area has to be drawn to the end of the text area. */
16936 it->glyph_row->fill_line_p = 1;
16938 /* If current character of IT is not ASCII, make sure we have the
16939 ASCII face. This will be automatically undone the next time
16940 get_next_display_element returns a multibyte character. Note
16941 that the character will always be single byte in unibyte
16942 text. */
16943 if (!ASCII_CHAR_P (it->c))
16945 it->face_id = FACE_FOR_CHAR (f, face, 0, -1, Qnil);
16948 if (FRAME_WINDOW_P (f))
16950 /* If the row is empty, add a space with the current face of IT,
16951 so that we know which face to draw. */
16952 if (it->glyph_row->used[TEXT_AREA] == 0)
16954 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
16955 it->glyph_row->glyphs[TEXT_AREA][0].face_id = it->face_id;
16956 it->glyph_row->used[TEXT_AREA] = 1;
16958 #ifdef HAVE_WINDOW_SYSTEM
16959 if (it->glyph_row->reversed_p)
16961 /* Prepend a stretch glyph to the row, such that the
16962 rightmost glyph will be drawn flushed all the way to the
16963 right margin of the window. The stretch glyph that will
16964 occupy the empty space, if any, to the left of the
16965 glyphs. */
16966 struct font *font = face->font ? face->font : FRAME_FONT (f);
16967 struct glyph *row_start = it->glyph_row->glyphs[TEXT_AREA];
16968 struct glyph *row_end = row_start + it->glyph_row->used[TEXT_AREA];
16969 struct glyph *g;
16970 int row_width, stretch_ascent, stretch_width;
16971 struct text_pos saved_pos;
16972 int saved_face_id, saved_avoid_cursor;
16974 for (row_width = 0, g = row_start; g < row_end; g++)
16975 row_width += g->pixel_width;
16976 stretch_width = window_box_width (it->w, TEXT_AREA) - row_width;
16977 if (stretch_width > 0)
16979 stretch_ascent =
16980 (((it->ascent + it->descent)
16981 * FONT_BASE (font)) / FONT_HEIGHT (font));
16982 saved_pos = it->position;
16983 memset (&it->position, 0, sizeof it->position);
16984 saved_avoid_cursor = it->avoid_cursor_p;
16985 it->avoid_cursor_p = 1;
16986 saved_face_id = it->face_id;
16987 /* The last row's stretch glyph should get the default
16988 face, to avoid painting the rest of the window with
16989 the region face, if the region ends at ZV. */
16990 if (it->glyph_row->ends_at_zv_p)
16991 it->face_id = DEFAULT_FACE_ID;
16992 else
16993 it->face_id = face->id;
16994 append_stretch_glyph (it, make_number (0), stretch_width,
16995 it->ascent + it->descent, stretch_ascent);
16996 it->position = saved_pos;
16997 it->avoid_cursor_p = saved_avoid_cursor;
16998 it->face_id = saved_face_id;
17001 #endif /* HAVE_WINDOW_SYSTEM */
17003 else
17005 /* Save some values that must not be changed. */
17006 int saved_x = it->current_x;
17007 struct text_pos saved_pos;
17008 Lisp_Object saved_object;
17009 enum display_element_type saved_what = it->what;
17010 int saved_face_id = it->face_id;
17012 saved_object = it->object;
17013 saved_pos = it->position;
17015 it->what = IT_CHARACTER;
17016 memset (&it->position, 0, sizeof it->position);
17017 it->object = make_number (0);
17018 it->c = it->char_to_display = ' ';
17019 it->len = 1;
17020 /* The last row's blank glyphs should get the default face, to
17021 avoid painting the rest of the window with the region face,
17022 if the region ends at ZV. */
17023 if (it->glyph_row->ends_at_zv_p)
17024 it->face_id = DEFAULT_FACE_ID;
17025 else
17026 it->face_id = face->id;
17028 PRODUCE_GLYPHS (it);
17030 while (it->current_x <= it->last_visible_x)
17031 PRODUCE_GLYPHS (it);
17033 /* Don't count these blanks really. It would let us insert a left
17034 truncation glyph below and make us set the cursor on them, maybe. */
17035 it->current_x = saved_x;
17036 it->object = saved_object;
17037 it->position = saved_pos;
17038 it->what = saved_what;
17039 it->face_id = saved_face_id;
17044 /* Value is non-zero if text starting at CHARPOS in current_buffer is
17045 trailing whitespace. */
17047 static int
17048 trailing_whitespace_p (EMACS_INT charpos)
17050 EMACS_INT bytepos = CHAR_TO_BYTE (charpos);
17051 int c = 0;
17053 while (bytepos < ZV_BYTE
17054 && (c = FETCH_CHAR (bytepos),
17055 c == ' ' || c == '\t'))
17056 ++bytepos;
17058 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
17060 if (bytepos != PT_BYTE)
17061 return 1;
17063 return 0;
17067 /* Highlight trailing whitespace, if any, in ROW. */
17069 static void
17070 highlight_trailing_whitespace (struct frame *f, struct glyph_row *row)
17072 int used = row->used[TEXT_AREA];
17074 if (used)
17076 struct glyph *start = row->glyphs[TEXT_AREA];
17077 struct glyph *glyph = start + used - 1;
17079 if (row->reversed_p)
17081 /* Right-to-left rows need to be processed in the opposite
17082 direction, so swap the edge pointers. */
17083 glyph = start;
17084 start = row->glyphs[TEXT_AREA] + used - 1;
17087 /* Skip over glyphs inserted to display the cursor at the
17088 end of a line, for extending the face of the last glyph
17089 to the end of the line on terminals, and for truncation
17090 and continuation glyphs. */
17091 if (!row->reversed_p)
17093 while (glyph >= start
17094 && glyph->type == CHAR_GLYPH
17095 && INTEGERP (glyph->object))
17096 --glyph;
17098 else
17100 while (glyph <= start
17101 && glyph->type == CHAR_GLYPH
17102 && INTEGERP (glyph->object))
17103 ++glyph;
17106 /* If last glyph is a space or stretch, and it's trailing
17107 whitespace, set the face of all trailing whitespace glyphs in
17108 IT->glyph_row to `trailing-whitespace'. */
17109 if ((row->reversed_p ? glyph <= start : glyph >= start)
17110 && BUFFERP (glyph->object)
17111 && (glyph->type == STRETCH_GLYPH
17112 || (glyph->type == CHAR_GLYPH
17113 && glyph->u.ch == ' '))
17114 && trailing_whitespace_p (glyph->charpos))
17116 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0);
17117 if (face_id < 0)
17118 return;
17120 if (!row->reversed_p)
17122 while (glyph >= start
17123 && BUFFERP (glyph->object)
17124 && (glyph->type == STRETCH_GLYPH
17125 || (glyph->type == CHAR_GLYPH
17126 && glyph->u.ch == ' ')))
17127 (glyph--)->face_id = face_id;
17129 else
17131 while (glyph <= start
17132 && BUFFERP (glyph->object)
17133 && (glyph->type == STRETCH_GLYPH
17134 || (glyph->type == CHAR_GLYPH
17135 && glyph->u.ch == ' ')))
17136 (glyph++)->face_id = face_id;
17143 /* Value is non-zero if glyph row ROW should be
17144 used to hold the cursor. */
17146 static int
17147 cursor_row_p (struct glyph_row *row)
17149 int result = 1;
17151 if (PT == CHARPOS (row->end.pos))
17153 /* Suppose the row ends on a string.
17154 Unless the row is continued, that means it ends on a newline
17155 in the string. If it's anything other than a display string
17156 (e.g. a before-string from an overlay), we don't want the
17157 cursor there. (This heuristic seems to give the optimal
17158 behavior for the various types of multi-line strings.) */
17159 if (CHARPOS (row->end.string_pos) >= 0)
17161 if (row->continued_p)
17162 result = 1;
17163 else
17165 /* Check for `display' property. */
17166 struct glyph *beg = row->glyphs[TEXT_AREA];
17167 struct glyph *end = beg + row->used[TEXT_AREA] - 1;
17168 struct glyph *glyph;
17170 result = 0;
17171 for (glyph = end; glyph >= beg; --glyph)
17172 if (STRINGP (glyph->object))
17174 Lisp_Object prop
17175 = Fget_char_property (make_number (PT),
17176 Qdisplay, Qnil);
17177 result =
17178 (!NILP (prop)
17179 && display_prop_string_p (prop, glyph->object));
17180 break;
17184 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
17186 /* If the row ends in middle of a real character,
17187 and the line is continued, we want the cursor here.
17188 That's because CHARPOS (ROW->end.pos) would equal
17189 PT if PT is before the character. */
17190 if (!row->ends_in_ellipsis_p)
17191 result = row->continued_p;
17192 else
17193 /* If the row ends in an ellipsis, then
17194 CHARPOS (ROW->end.pos) will equal point after the
17195 invisible text. We want that position to be displayed
17196 after the ellipsis. */
17197 result = 0;
17199 /* If the row ends at ZV, display the cursor at the end of that
17200 row instead of at the start of the row below. */
17201 else if (row->ends_at_zv_p)
17202 result = 1;
17203 else
17204 result = 0;
17207 return result;
17212 /* Push the display property PROP so that it will be rendered at the
17213 current position in IT. Return 1 if PROP was successfully pushed,
17214 0 otherwise. */
17216 static int
17217 push_display_prop (struct it *it, Lisp_Object prop)
17219 push_it (it, NULL);
17221 if (STRINGP (prop))
17223 if (SCHARS (prop) == 0)
17225 pop_it (it);
17226 return 0;
17229 it->string = prop;
17230 it->multibyte_p = STRING_MULTIBYTE (it->string);
17231 it->current.overlay_string_index = -1;
17232 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
17233 it->end_charpos = it->string_nchars = SCHARS (it->string);
17234 it->method = GET_FROM_STRING;
17235 it->stop_charpos = 0;
17237 else if (CONSP (prop) && EQ (XCAR (prop), Qspace))
17239 it->method = GET_FROM_STRETCH;
17240 it->object = prop;
17242 #ifdef HAVE_WINDOW_SYSTEM
17243 else if (IMAGEP (prop))
17245 it->what = IT_IMAGE;
17246 it->image_id = lookup_image (it->f, prop);
17247 it->method = GET_FROM_IMAGE;
17249 #endif /* HAVE_WINDOW_SYSTEM */
17250 else
17252 pop_it (it); /* bogus display property, give up */
17253 return 0;
17256 return 1;
17259 /* Return the character-property PROP at the current position in IT. */
17261 static Lisp_Object
17262 get_it_property (struct it *it, Lisp_Object prop)
17264 Lisp_Object position;
17266 if (STRINGP (it->object))
17267 position = make_number (IT_STRING_CHARPOS (*it));
17268 else if (BUFFERP (it->object))
17269 position = make_number (IT_CHARPOS (*it));
17270 else
17271 return Qnil;
17273 return Fget_char_property (position, prop, it->object);
17276 /* See if there's a line- or wrap-prefix, and if so, push it on IT. */
17278 static void
17279 handle_line_prefix (struct it *it)
17281 Lisp_Object prefix;
17282 if (it->continuation_lines_width > 0)
17284 prefix = get_it_property (it, Qwrap_prefix);
17285 if (NILP (prefix))
17286 prefix = Vwrap_prefix;
17288 else
17290 prefix = get_it_property (it, Qline_prefix);
17291 if (NILP (prefix))
17292 prefix = Vline_prefix;
17294 if (! NILP (prefix) && push_display_prop (it, prefix))
17296 /* If the prefix is wider than the window, and we try to wrap
17297 it, it would acquire its own wrap prefix, and so on till the
17298 iterator stack overflows. So, don't wrap the prefix. */
17299 it->line_wrap = TRUNCATE;
17300 it->avoid_cursor_p = 1;
17306 /* Remove N glyphs at the start of a reversed IT->glyph_row. Called
17307 only for R2L lines from display_line, when it decides that too many
17308 glyphs were produced by PRODUCE_GLYPHS, and the line needs to be
17309 continued. */
17310 static void
17311 unproduce_glyphs (struct it *it, int n)
17313 struct glyph *glyph, *end;
17315 xassert (it->glyph_row);
17316 xassert (it->glyph_row->reversed_p);
17317 xassert (it->area == TEXT_AREA);
17318 xassert (n <= it->glyph_row->used[TEXT_AREA]);
17320 if (n > it->glyph_row->used[TEXT_AREA])
17321 n = it->glyph_row->used[TEXT_AREA];
17322 glyph = it->glyph_row->glyphs[TEXT_AREA] + n;
17323 end = it->glyph_row->glyphs[TEXT_AREA] + it->glyph_row->used[TEXT_AREA];
17324 for ( ; glyph < end; glyph++)
17325 glyph[-n] = *glyph;
17328 /* Find the positions in a bidi-reordered ROW to serve as ROW->minpos
17329 and ROW->maxpos. */
17330 static void
17331 find_row_edges (struct it *it, struct glyph_row *row,
17332 EMACS_INT min_pos, EMACS_INT min_bpos,
17333 EMACS_INT max_pos, EMACS_INT max_bpos)
17335 /* FIXME: Revisit this when glyph ``spilling'' in continuation
17336 lines' rows is implemented for bidi-reordered rows. */
17338 /* ROW->minpos is the value of min_pos, the minimal buffer position
17339 we have in ROW. */
17340 if (min_pos <= ZV)
17341 SET_TEXT_POS (row->minpos, min_pos, min_bpos);
17342 else
17343 /* We didn't find _any_ valid buffer positions in any of the
17344 glyphs, so we must trust the iterator's computed positions. */
17345 row->minpos = row->start.pos;
17346 if (max_pos <= 0)
17348 max_pos = CHARPOS (it->current.pos);
17349 max_bpos = BYTEPOS (it->current.pos);
17352 /* Here are the various use-cases for ending the row, and the
17353 corresponding values for ROW->maxpos:
17355 Line ends in a newline from buffer eol_pos + 1
17356 Line is continued from buffer max_pos + 1
17357 Line is truncated on right it->current.pos
17358 Line ends in a newline from string max_pos
17359 Line is continued from string max_pos
17360 Line is continued from display vector max_pos
17361 Line is entirely from a string min_pos == max_pos
17362 Line is entirely from a display vector min_pos == max_pos
17363 Line that ends at ZV ZV
17365 If you discover other use-cases, please add them here as
17366 appropriate. */
17367 if (row->ends_at_zv_p)
17368 row->maxpos = it->current.pos;
17369 else if (row->used[TEXT_AREA])
17371 if (row->ends_in_newline_from_string_p)
17372 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
17373 else if (CHARPOS (it->eol_pos) > 0)
17374 SET_TEXT_POS (row->maxpos,
17375 CHARPOS (it->eol_pos) + 1, BYTEPOS (it->eol_pos) + 1);
17376 else if (row->continued_p)
17378 /* If max_pos is different from IT's current position, it
17379 means IT->method does not belong to the display element
17380 at max_pos. However, it also means that the display
17381 element at max_pos was displayed in its entirety on this
17382 line, which is equivalent to saying that the next line
17383 starts at the next buffer position. */
17384 if (IT_CHARPOS (*it) == max_pos && it->method != GET_FROM_BUFFER)
17385 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
17386 else
17388 INC_BOTH (max_pos, max_bpos);
17389 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
17392 else if (row->truncated_on_right_p)
17393 /* display_line already called reseat_at_next_visible_line_start,
17394 which puts the iterator at the beginning of the next line, in
17395 the logical order. */
17396 row->maxpos = it->current.pos;
17397 else if (max_pos == min_pos && it->method != GET_FROM_BUFFER)
17398 /* A line that is entirely from a string/image/stretch... */
17399 row->maxpos = row->minpos;
17400 else
17401 abort ();
17403 else
17404 row->maxpos = it->current.pos;
17407 /* Construct the glyph row IT->glyph_row in the desired matrix of
17408 IT->w from text at the current position of IT. See dispextern.h
17409 for an overview of struct it. Value is non-zero if
17410 IT->glyph_row displays text, as opposed to a line displaying ZV
17411 only. */
17413 static int
17414 display_line (struct it *it)
17416 struct glyph_row *row = it->glyph_row;
17417 Lisp_Object overlay_arrow_string;
17418 struct it wrap_it;
17419 int may_wrap = 0, wrap_x IF_LINT (= 0);
17420 int wrap_row_used = -1;
17421 int wrap_row_ascent IF_LINT (= 0), wrap_row_height IF_LINT (= 0);
17422 int wrap_row_phys_ascent IF_LINT (= 0), wrap_row_phys_height IF_LINT (= 0);
17423 int wrap_row_extra_line_spacing IF_LINT (= 0);
17424 EMACS_INT wrap_row_min_pos IF_LINT (= 0), wrap_row_min_bpos IF_LINT (= 0);
17425 EMACS_INT wrap_row_max_pos IF_LINT (= 0), wrap_row_max_bpos IF_LINT (= 0);
17426 int cvpos;
17427 EMACS_INT min_pos = ZV + 1, max_pos = 0;
17428 EMACS_INT min_bpos IF_LINT (= 0), max_bpos IF_LINT (= 0);
17430 /* We always start displaying at hpos zero even if hscrolled. */
17431 xassert (it->hpos == 0 && it->current_x == 0);
17433 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
17434 >= it->w->desired_matrix->nrows)
17436 it->w->nrows_scale_factor++;
17437 fonts_changed_p = 1;
17438 return 0;
17441 /* Is IT->w showing the region? */
17442 it->w->region_showing = it->region_beg_charpos > 0 ? Qt : Qnil;
17444 /* Clear the result glyph row and enable it. */
17445 prepare_desired_row (row);
17447 row->y = it->current_y;
17448 row->start = it->start;
17449 row->continuation_lines_width = it->continuation_lines_width;
17450 row->displays_text_p = 1;
17451 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
17452 it->starts_in_middle_of_char_p = 0;
17454 /* Arrange the overlays nicely for our purposes. Usually, we call
17455 display_line on only one line at a time, in which case this
17456 can't really hurt too much, or we call it on lines which appear
17457 one after another in the buffer, in which case all calls to
17458 recenter_overlay_lists but the first will be pretty cheap. */
17459 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
17461 /* Move over display elements that are not visible because we are
17462 hscrolled. This may stop at an x-position < IT->first_visible_x
17463 if the first glyph is partially visible or if we hit a line end. */
17464 if (it->current_x < it->first_visible_x)
17466 this_line_min_pos = row->start.pos;
17467 move_it_in_display_line_to (it, ZV, it->first_visible_x,
17468 MOVE_TO_POS | MOVE_TO_X);
17469 /* Record the smallest positions seen while we moved over
17470 display elements that are not visible. This is needed by
17471 redisplay_internal for optimizing the case where the cursor
17472 stays inside the same line. The rest of this function only
17473 considers positions that are actually displayed, so
17474 RECORD_MAX_MIN_POS will not otherwise record positions that
17475 are hscrolled to the left of the left edge of the window. */
17476 min_pos = CHARPOS (this_line_min_pos);
17477 min_bpos = BYTEPOS (this_line_min_pos);
17479 else
17481 /* We only do this when not calling `move_it_in_display_line_to'
17482 above, because move_it_in_display_line_to calls
17483 handle_line_prefix itself. */
17484 handle_line_prefix (it);
17487 /* Get the initial row height. This is either the height of the
17488 text hscrolled, if there is any, or zero. */
17489 row->ascent = it->max_ascent;
17490 row->height = it->max_ascent + it->max_descent;
17491 row->phys_ascent = it->max_phys_ascent;
17492 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
17493 row->extra_line_spacing = it->max_extra_line_spacing;
17495 /* Utility macro to record max and min buffer positions seen until now. */
17496 #define RECORD_MAX_MIN_POS(IT) \
17497 do \
17499 if (IT_CHARPOS (*(IT)) < min_pos) \
17501 min_pos = IT_CHARPOS (*(IT)); \
17502 min_bpos = IT_BYTEPOS (*(IT)); \
17504 if (IT_CHARPOS (*(IT)) > max_pos) \
17506 max_pos = IT_CHARPOS (*(IT)); \
17507 max_bpos = IT_BYTEPOS (*(IT)); \
17510 while (0)
17512 /* Loop generating characters. The loop is left with IT on the next
17513 character to display. */
17514 while (1)
17516 int n_glyphs_before, hpos_before, x_before;
17517 int x, nglyphs;
17518 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
17520 /* Retrieve the next thing to display. Value is zero if end of
17521 buffer reached. */
17522 if (!get_next_display_element (it))
17524 /* Maybe add a space at the end of this line that is used to
17525 display the cursor there under X. Set the charpos of the
17526 first glyph of blank lines not corresponding to any text
17527 to -1. */
17528 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
17529 row->exact_window_width_line_p = 1;
17530 else if ((append_space_for_newline (it, 1) && row->used[TEXT_AREA] == 1)
17531 || row->used[TEXT_AREA] == 0)
17533 row->glyphs[TEXT_AREA]->charpos = -1;
17534 row->displays_text_p = 0;
17536 if (!NILP (BVAR (XBUFFER (it->w->buffer), indicate_empty_lines))
17537 && (!MINI_WINDOW_P (it->w)
17538 || (minibuf_level && EQ (it->window, minibuf_window))))
17539 row->indicate_empty_line_p = 1;
17542 it->continuation_lines_width = 0;
17543 row->ends_at_zv_p = 1;
17544 /* A row that displays right-to-left text must always have
17545 its last face extended all the way to the end of line,
17546 even if this row ends in ZV, because we still write to
17547 the screen left to right. */
17548 if (row->reversed_p)
17549 extend_face_to_end_of_line (it);
17550 break;
17553 /* Now, get the metrics of what we want to display. This also
17554 generates glyphs in `row' (which is IT->glyph_row). */
17555 n_glyphs_before = row->used[TEXT_AREA];
17556 x = it->current_x;
17558 /* Remember the line height so far in case the next element doesn't
17559 fit on the line. */
17560 if (it->line_wrap != TRUNCATE)
17562 ascent = it->max_ascent;
17563 descent = it->max_descent;
17564 phys_ascent = it->max_phys_ascent;
17565 phys_descent = it->max_phys_descent;
17567 if (it->line_wrap == WORD_WRAP && it->area == TEXT_AREA)
17569 if (IT_DISPLAYING_WHITESPACE (it))
17570 may_wrap = 1;
17571 else if (may_wrap)
17573 wrap_it = *it;
17574 wrap_x = x;
17575 wrap_row_used = row->used[TEXT_AREA];
17576 wrap_row_ascent = row->ascent;
17577 wrap_row_height = row->height;
17578 wrap_row_phys_ascent = row->phys_ascent;
17579 wrap_row_phys_height = row->phys_height;
17580 wrap_row_extra_line_spacing = row->extra_line_spacing;
17581 wrap_row_min_pos = min_pos;
17582 wrap_row_min_bpos = min_bpos;
17583 wrap_row_max_pos = max_pos;
17584 wrap_row_max_bpos = max_bpos;
17585 may_wrap = 0;
17590 PRODUCE_GLYPHS (it);
17592 /* If this display element was in marginal areas, continue with
17593 the next one. */
17594 if (it->area != TEXT_AREA)
17596 row->ascent = max (row->ascent, it->max_ascent);
17597 row->height = max (row->height, it->max_ascent + it->max_descent);
17598 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
17599 row->phys_height = max (row->phys_height,
17600 it->max_phys_ascent + it->max_phys_descent);
17601 row->extra_line_spacing = max (row->extra_line_spacing,
17602 it->max_extra_line_spacing);
17603 set_iterator_to_next (it, 1);
17604 continue;
17607 /* Does the display element fit on the line? If we truncate
17608 lines, we should draw past the right edge of the window. If
17609 we don't truncate, we want to stop so that we can display the
17610 continuation glyph before the right margin. If lines are
17611 continued, there are two possible strategies for characters
17612 resulting in more than 1 glyph (e.g. tabs): Display as many
17613 glyphs as possible in this line and leave the rest for the
17614 continuation line, or display the whole element in the next
17615 line. Original redisplay did the former, so we do it also. */
17616 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
17617 hpos_before = it->hpos;
17618 x_before = x;
17620 if (/* Not a newline. */
17621 nglyphs > 0
17622 /* Glyphs produced fit entirely in the line. */
17623 && it->current_x < it->last_visible_x)
17625 it->hpos += nglyphs;
17626 row->ascent = max (row->ascent, it->max_ascent);
17627 row->height = max (row->height, it->max_ascent + it->max_descent);
17628 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
17629 row->phys_height = max (row->phys_height,
17630 it->max_phys_ascent + it->max_phys_descent);
17631 row->extra_line_spacing = max (row->extra_line_spacing,
17632 it->max_extra_line_spacing);
17633 if (it->current_x - it->pixel_width < it->first_visible_x)
17634 row->x = x - it->first_visible_x;
17635 /* Record the maximum and minimum buffer positions seen so
17636 far in glyphs that will be displayed by this row. */
17637 if (it->bidi_p)
17638 RECORD_MAX_MIN_POS (it);
17640 else
17642 int i, new_x;
17643 struct glyph *glyph;
17645 for (i = 0; i < nglyphs; ++i, x = new_x)
17647 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
17648 new_x = x + glyph->pixel_width;
17650 if (/* Lines are continued. */
17651 it->line_wrap != TRUNCATE
17652 && (/* Glyph doesn't fit on the line. */
17653 new_x > it->last_visible_x
17654 /* Or it fits exactly on a window system frame. */
17655 || (new_x == it->last_visible_x
17656 && FRAME_WINDOW_P (it->f))))
17658 /* End of a continued line. */
17660 if (it->hpos == 0
17661 || (new_x == it->last_visible_x
17662 && FRAME_WINDOW_P (it->f)))
17664 /* Current glyph is the only one on the line or
17665 fits exactly on the line. We must continue
17666 the line because we can't draw the cursor
17667 after the glyph. */
17668 row->continued_p = 1;
17669 it->current_x = new_x;
17670 it->continuation_lines_width += new_x;
17671 ++it->hpos;
17672 /* Record the maximum and minimum buffer
17673 positions seen so far in glyphs that will be
17674 displayed by this row. */
17675 if (it->bidi_p)
17676 RECORD_MAX_MIN_POS (it);
17677 if (i == nglyphs - 1)
17679 /* If line-wrap is on, check if a previous
17680 wrap point was found. */
17681 if (wrap_row_used > 0
17682 /* Even if there is a previous wrap
17683 point, continue the line here as
17684 usual, if (i) the previous character
17685 was a space or tab AND (ii) the
17686 current character is not. */
17687 && (!may_wrap
17688 || IT_DISPLAYING_WHITESPACE (it)))
17689 goto back_to_wrap;
17691 set_iterator_to_next (it, 1);
17692 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
17694 if (!get_next_display_element (it))
17696 row->exact_window_width_line_p = 1;
17697 it->continuation_lines_width = 0;
17698 row->continued_p = 0;
17699 row->ends_at_zv_p = 1;
17701 else if (ITERATOR_AT_END_OF_LINE_P (it))
17703 row->continued_p = 0;
17704 row->exact_window_width_line_p = 1;
17709 else if (CHAR_GLYPH_PADDING_P (*glyph)
17710 && !FRAME_WINDOW_P (it->f))
17712 /* A padding glyph that doesn't fit on this line.
17713 This means the whole character doesn't fit
17714 on the line. */
17715 if (row->reversed_p)
17716 unproduce_glyphs (it, row->used[TEXT_AREA]
17717 - n_glyphs_before);
17718 row->used[TEXT_AREA] = n_glyphs_before;
17720 /* Fill the rest of the row with continuation
17721 glyphs like in 20.x. */
17722 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
17723 < row->glyphs[1 + TEXT_AREA])
17724 produce_special_glyphs (it, IT_CONTINUATION);
17726 row->continued_p = 1;
17727 it->current_x = x_before;
17728 it->continuation_lines_width += x_before;
17730 /* Restore the height to what it was before the
17731 element not fitting on the line. */
17732 it->max_ascent = ascent;
17733 it->max_descent = descent;
17734 it->max_phys_ascent = phys_ascent;
17735 it->max_phys_descent = phys_descent;
17737 else if (wrap_row_used > 0)
17739 back_to_wrap:
17740 if (row->reversed_p)
17741 unproduce_glyphs (it,
17742 row->used[TEXT_AREA] - wrap_row_used);
17743 *it = wrap_it;
17744 it->continuation_lines_width += wrap_x;
17745 row->used[TEXT_AREA] = wrap_row_used;
17746 row->ascent = wrap_row_ascent;
17747 row->height = wrap_row_height;
17748 row->phys_ascent = wrap_row_phys_ascent;
17749 row->phys_height = wrap_row_phys_height;
17750 row->extra_line_spacing = wrap_row_extra_line_spacing;
17751 min_pos = wrap_row_min_pos;
17752 min_bpos = wrap_row_min_bpos;
17753 max_pos = wrap_row_max_pos;
17754 max_bpos = wrap_row_max_bpos;
17755 row->continued_p = 1;
17756 row->ends_at_zv_p = 0;
17757 row->exact_window_width_line_p = 0;
17758 it->continuation_lines_width += x;
17760 /* Make sure that a non-default face is extended
17761 up to the right margin of the window. */
17762 extend_face_to_end_of_line (it);
17764 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
17766 /* A TAB that extends past the right edge of the
17767 window. This produces a single glyph on
17768 window system frames. We leave the glyph in
17769 this row and let it fill the row, but don't
17770 consume the TAB. */
17771 it->continuation_lines_width += it->last_visible_x;
17772 row->ends_in_middle_of_char_p = 1;
17773 row->continued_p = 1;
17774 glyph->pixel_width = it->last_visible_x - x;
17775 it->starts_in_middle_of_char_p = 1;
17777 else
17779 /* Something other than a TAB that draws past
17780 the right edge of the window. Restore
17781 positions to values before the element. */
17782 if (row->reversed_p)
17783 unproduce_glyphs (it, row->used[TEXT_AREA]
17784 - (n_glyphs_before + i));
17785 row->used[TEXT_AREA] = n_glyphs_before + i;
17787 /* Display continuation glyphs. */
17788 if (!FRAME_WINDOW_P (it->f))
17789 produce_special_glyphs (it, IT_CONTINUATION);
17790 row->continued_p = 1;
17792 it->current_x = x_before;
17793 it->continuation_lines_width += x;
17794 extend_face_to_end_of_line (it);
17796 if (nglyphs > 1 && i > 0)
17798 row->ends_in_middle_of_char_p = 1;
17799 it->starts_in_middle_of_char_p = 1;
17802 /* Restore the height to what it was before the
17803 element not fitting on the line. */
17804 it->max_ascent = ascent;
17805 it->max_descent = descent;
17806 it->max_phys_ascent = phys_ascent;
17807 it->max_phys_descent = phys_descent;
17810 break;
17812 else if (new_x > it->first_visible_x)
17814 /* Increment number of glyphs actually displayed. */
17815 ++it->hpos;
17817 /* Record the maximum and minimum buffer positions
17818 seen so far in glyphs that will be displayed by
17819 this row. */
17820 if (it->bidi_p)
17821 RECORD_MAX_MIN_POS (it);
17823 if (x < it->first_visible_x)
17824 /* Glyph is partially visible, i.e. row starts at
17825 negative X position. */
17826 row->x = x - it->first_visible_x;
17828 else
17830 /* Glyph is completely off the left margin of the
17831 window. This should not happen because of the
17832 move_it_in_display_line at the start of this
17833 function, unless the text display area of the
17834 window is empty. */
17835 xassert (it->first_visible_x <= it->last_visible_x);
17839 row->ascent = max (row->ascent, it->max_ascent);
17840 row->height = max (row->height, it->max_ascent + it->max_descent);
17841 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
17842 row->phys_height = max (row->phys_height,
17843 it->max_phys_ascent + it->max_phys_descent);
17844 row->extra_line_spacing = max (row->extra_line_spacing,
17845 it->max_extra_line_spacing);
17847 /* End of this display line if row is continued. */
17848 if (row->continued_p || row->ends_at_zv_p)
17849 break;
17852 at_end_of_line:
17853 /* Is this a line end? If yes, we're also done, after making
17854 sure that a non-default face is extended up to the right
17855 margin of the window. */
17856 if (ITERATOR_AT_END_OF_LINE_P (it))
17858 int used_before = row->used[TEXT_AREA];
17860 row->ends_in_newline_from_string_p = STRINGP (it->object);
17862 /* Add a space at the end of the line that is used to
17863 display the cursor there. */
17864 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
17865 append_space_for_newline (it, 0);
17867 /* Extend the face to the end of the line. */
17868 extend_face_to_end_of_line (it);
17870 /* Make sure we have the position. */
17871 if (used_before == 0)
17872 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
17874 /* Record the position of the newline, for use in
17875 find_row_edges. */
17876 it->eol_pos = it->current.pos;
17878 /* Consume the line end. This skips over invisible lines. */
17879 set_iterator_to_next (it, 1);
17880 it->continuation_lines_width = 0;
17881 break;
17884 /* Proceed with next display element. Note that this skips
17885 over lines invisible because of selective display. */
17886 set_iterator_to_next (it, 1);
17888 /* If we truncate lines, we are done when the last displayed
17889 glyphs reach past the right margin of the window. */
17890 if (it->line_wrap == TRUNCATE
17891 && (FRAME_WINDOW_P (it->f)
17892 ? (it->current_x >= it->last_visible_x)
17893 : (it->current_x > it->last_visible_x)))
17895 /* Maybe add truncation glyphs. */
17896 if (!FRAME_WINDOW_P (it->f))
17898 int i, n;
17900 if (!row->reversed_p)
17902 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
17903 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
17904 break;
17906 else
17908 for (i = 0; i < row->used[TEXT_AREA]; i++)
17909 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
17910 break;
17911 /* Remove any padding glyphs at the front of ROW, to
17912 make room for the truncation glyphs we will be
17913 adding below. The loop below always inserts at
17914 least one truncation glyph, so also remove the
17915 last glyph added to ROW. */
17916 unproduce_glyphs (it, i + 1);
17917 /* Adjust i for the loop below. */
17918 i = row->used[TEXT_AREA] - (i + 1);
17921 for (n = row->used[TEXT_AREA]; i < n; ++i)
17923 row->used[TEXT_AREA] = i;
17924 produce_special_glyphs (it, IT_TRUNCATION);
17927 else if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
17929 /* Don't truncate if we can overflow newline into fringe. */
17930 if (!get_next_display_element (it))
17932 it->continuation_lines_width = 0;
17933 row->ends_at_zv_p = 1;
17934 row->exact_window_width_line_p = 1;
17935 break;
17937 if (ITERATOR_AT_END_OF_LINE_P (it))
17939 row->exact_window_width_line_p = 1;
17940 goto at_end_of_line;
17944 row->truncated_on_right_p = 1;
17945 it->continuation_lines_width = 0;
17946 reseat_at_next_visible_line_start (it, 0);
17947 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
17948 it->hpos = hpos_before;
17949 it->current_x = x_before;
17950 break;
17954 /* If line is not empty and hscrolled, maybe insert truncation glyphs
17955 at the left window margin. */
17956 if (it->first_visible_x
17957 && IT_CHARPOS (*it) != CHARPOS (row->start.pos))
17959 if (!FRAME_WINDOW_P (it->f))
17960 insert_left_trunc_glyphs (it);
17961 row->truncated_on_left_p = 1;
17964 /* Remember the position at which this line ends.
17966 BIDI Note: any code that needs MATRIX_ROW_START/END_CHARPOS
17967 cannot be before the call to find_row_edges below, since that is
17968 where these positions are determined. */
17969 row->end = it->current;
17970 if (!it->bidi_p)
17972 row->minpos = row->start.pos;
17973 row->maxpos = row->end.pos;
17975 else
17977 /* ROW->minpos and ROW->maxpos must be the smallest and
17978 `1 + the largest' buffer positions in ROW. But if ROW was
17979 bidi-reordered, these two positions can be anywhere in the
17980 row, so we must determine them now. */
17981 find_row_edges (it, row, min_pos, min_bpos, max_pos, max_bpos);
17984 /* If the start of this line is the overlay arrow-position, then
17985 mark this glyph row as the one containing the overlay arrow.
17986 This is clearly a mess with variable size fonts. It would be
17987 better to let it be displayed like cursors under X. */
17988 if ((row->displays_text_p || !overlay_arrow_seen)
17989 && (overlay_arrow_string = overlay_arrow_at_row (it, row),
17990 !NILP (overlay_arrow_string)))
17992 /* Overlay arrow in window redisplay is a fringe bitmap. */
17993 if (STRINGP (overlay_arrow_string))
17995 struct glyph_row *arrow_row
17996 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
17997 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
17998 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
17999 struct glyph *p = row->glyphs[TEXT_AREA];
18000 struct glyph *p2, *end;
18002 /* Copy the arrow glyphs. */
18003 while (glyph < arrow_end)
18004 *p++ = *glyph++;
18006 /* Throw away padding glyphs. */
18007 p2 = p;
18008 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
18009 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
18010 ++p2;
18011 if (p2 > p)
18013 while (p2 < end)
18014 *p++ = *p2++;
18015 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
18018 else
18020 xassert (INTEGERP (overlay_arrow_string));
18021 row->overlay_arrow_bitmap = XINT (overlay_arrow_string);
18023 overlay_arrow_seen = 1;
18026 /* Compute pixel dimensions of this line. */
18027 compute_line_metrics (it);
18029 /* Record whether this row ends inside an ellipsis. */
18030 row->ends_in_ellipsis_p
18031 = (it->method == GET_FROM_DISPLAY_VECTOR
18032 && it->ellipsis_p);
18034 /* Save fringe bitmaps in this row. */
18035 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
18036 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
18037 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
18038 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
18040 it->left_user_fringe_bitmap = 0;
18041 it->left_user_fringe_face_id = 0;
18042 it->right_user_fringe_bitmap = 0;
18043 it->right_user_fringe_face_id = 0;
18045 /* Maybe set the cursor. */
18046 cvpos = it->w->cursor.vpos;
18047 if ((cvpos < 0
18048 /* In bidi-reordered rows, keep checking for proper cursor
18049 position even if one has been found already, because buffer
18050 positions in such rows change non-linearly with ROW->VPOS,
18051 when a line is continued. One exception: when we are at ZV,
18052 display cursor on the first suitable glyph row, since all
18053 the empty rows after that also have their position set to ZV. */
18054 /* FIXME: Revisit this when glyph ``spilling'' in continuation
18055 lines' rows is implemented for bidi-reordered rows. */
18056 || (it->bidi_p
18057 && !MATRIX_ROW (it->w->desired_matrix, cvpos)->ends_at_zv_p))
18058 && PT >= MATRIX_ROW_START_CHARPOS (row)
18059 && PT <= MATRIX_ROW_END_CHARPOS (row)
18060 && cursor_row_p (row))
18061 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
18063 /* Highlight trailing whitespace. */
18064 if (!NILP (Vshow_trailing_whitespace))
18065 highlight_trailing_whitespace (it->f, it->glyph_row);
18067 /* Prepare for the next line. This line starts horizontally at (X
18068 HPOS) = (0 0). Vertical positions are incremented. As a
18069 convenience for the caller, IT->glyph_row is set to the next
18070 row to be used. */
18071 it->current_x = it->hpos = 0;
18072 it->current_y += row->height;
18073 SET_TEXT_POS (it->eol_pos, 0, 0);
18074 ++it->vpos;
18075 ++it->glyph_row;
18076 /* The next row should by default use the same value of the
18077 reversed_p flag as this one. set_iterator_to_next decides when
18078 it's a new paragraph, and PRODUCE_GLYPHS recomputes the value of
18079 the flag accordingly. */
18080 if (it->glyph_row < MATRIX_BOTTOM_TEXT_ROW (it->w->desired_matrix, it->w))
18081 it->glyph_row->reversed_p = row->reversed_p;
18082 it->start = row->end;
18083 return row->displays_text_p;
18085 #undef RECORD_MAX_MIN_POS
18088 DEFUN ("current-bidi-paragraph-direction", Fcurrent_bidi_paragraph_direction,
18089 Scurrent_bidi_paragraph_direction, 0, 1, 0,
18090 doc: /* Return paragraph direction at point in BUFFER.
18091 Value is either `left-to-right' or `right-to-left'.
18092 If BUFFER is omitted or nil, it defaults to the current buffer.
18094 Paragraph direction determines how the text in the paragraph is displayed.
18095 In left-to-right paragraphs, text begins at the left margin of the window
18096 and the reading direction is generally left to right. In right-to-left
18097 paragraphs, text begins at the right margin and is read from right to left.
18099 See also `bidi-paragraph-direction'. */)
18100 (Lisp_Object buffer)
18102 struct buffer *buf = current_buffer;
18103 struct buffer *old = buf;
18105 if (! NILP (buffer))
18107 CHECK_BUFFER (buffer);
18108 buf = XBUFFER (buffer);
18111 if (NILP (BVAR (buf, bidi_display_reordering)))
18112 return Qleft_to_right;
18113 else if (!NILP (BVAR (buf, bidi_paragraph_direction)))
18114 return BVAR (buf, bidi_paragraph_direction);
18115 else
18117 /* Determine the direction from buffer text. We could try to
18118 use current_matrix if it is up to date, but this seems fast
18119 enough as it is. */
18120 struct bidi_it itb;
18121 EMACS_INT pos = BUF_PT (buf);
18122 EMACS_INT bytepos = BUF_PT_BYTE (buf);
18123 int c;
18125 set_buffer_temp (buf);
18126 /* bidi_paragraph_init finds the base direction of the paragraph
18127 by searching forward from paragraph start. We need the base
18128 direction of the current or _previous_ paragraph, so we need
18129 to make sure we are within that paragraph. To that end, find
18130 the previous non-empty line. */
18131 if (pos >= ZV && pos > BEGV)
18133 pos--;
18134 bytepos = CHAR_TO_BYTE (pos);
18136 while ((c = FETCH_BYTE (bytepos)) == '\n'
18137 || c == ' ' || c == '\t' || c == '\f')
18139 if (bytepos <= BEGV_BYTE)
18140 break;
18141 bytepos--;
18142 pos--;
18144 while (!CHAR_HEAD_P (FETCH_BYTE (bytepos)))
18145 bytepos--;
18146 itb.charpos = pos;
18147 itb.bytepos = bytepos;
18148 itb.nchars = -1;
18149 itb.frame_window_p = FRAME_WINDOW_P (SELECTED_FRAME ()); /* guesswork */
18150 itb.first_elt = 1;
18151 itb.separator_limit = -1;
18152 itb.paragraph_dir = NEUTRAL_DIR;
18154 bidi_paragraph_init (NEUTRAL_DIR, &itb, 1);
18155 set_buffer_temp (old);
18156 switch (itb.paragraph_dir)
18158 case L2R:
18159 return Qleft_to_right;
18160 break;
18161 case R2L:
18162 return Qright_to_left;
18163 break;
18164 default:
18165 abort ();
18172 /***********************************************************************
18173 Menu Bar
18174 ***********************************************************************/
18176 /* Redisplay the menu bar in the frame for window W.
18178 The menu bar of X frames that don't have X toolkit support is
18179 displayed in a special window W->frame->menu_bar_window.
18181 The menu bar of terminal frames is treated specially as far as
18182 glyph matrices are concerned. Menu bar lines are not part of
18183 windows, so the update is done directly on the frame matrix rows
18184 for the menu bar. */
18186 static void
18187 display_menu_bar (struct window *w)
18189 struct frame *f = XFRAME (WINDOW_FRAME (w));
18190 struct it it;
18191 Lisp_Object items;
18192 int i;
18194 /* Don't do all this for graphical frames. */
18195 #ifdef HAVE_NTGUI
18196 if (FRAME_W32_P (f))
18197 return;
18198 #endif
18199 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
18200 if (FRAME_X_P (f))
18201 return;
18202 #endif
18204 #ifdef HAVE_NS
18205 if (FRAME_NS_P (f))
18206 return;
18207 #endif /* HAVE_NS */
18209 #ifdef USE_X_TOOLKIT
18210 xassert (!FRAME_WINDOW_P (f));
18211 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
18212 it.first_visible_x = 0;
18213 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
18214 #else /* not USE_X_TOOLKIT */
18215 if (FRAME_WINDOW_P (f))
18217 /* Menu bar lines are displayed in the desired matrix of the
18218 dummy window menu_bar_window. */
18219 struct window *menu_w;
18220 xassert (WINDOWP (f->menu_bar_window));
18221 menu_w = XWINDOW (f->menu_bar_window);
18222 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
18223 MENU_FACE_ID);
18224 it.first_visible_x = 0;
18225 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
18227 else
18229 /* This is a TTY frame, i.e. character hpos/vpos are used as
18230 pixel x/y. */
18231 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
18232 MENU_FACE_ID);
18233 it.first_visible_x = 0;
18234 it.last_visible_x = FRAME_COLS (f);
18236 #endif /* not USE_X_TOOLKIT */
18238 if (! mode_line_inverse_video)
18239 /* Force the menu-bar to be displayed in the default face. */
18240 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
18242 /* Clear all rows of the menu bar. */
18243 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
18245 struct glyph_row *row = it.glyph_row + i;
18246 clear_glyph_row (row);
18247 row->enabled_p = 1;
18248 row->full_width_p = 1;
18251 /* Display all items of the menu bar. */
18252 items = FRAME_MENU_BAR_ITEMS (it.f);
18253 for (i = 0; i < ASIZE (items); i += 4)
18255 Lisp_Object string;
18257 /* Stop at nil string. */
18258 string = AREF (items, i + 1);
18259 if (NILP (string))
18260 break;
18262 /* Remember where item was displayed. */
18263 ASET (items, i + 3, make_number (it.hpos));
18265 /* Display the item, pad with one space. */
18266 if (it.current_x < it.last_visible_x)
18267 display_string (NULL, string, Qnil, 0, 0, &it,
18268 SCHARS (string) + 1, 0, 0, -1);
18271 /* Fill out the line with spaces. */
18272 if (it.current_x < it.last_visible_x)
18273 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
18275 /* Compute the total height of the lines. */
18276 compute_line_metrics (&it);
18281 /***********************************************************************
18282 Mode Line
18283 ***********************************************************************/
18285 /* Redisplay mode lines in the window tree whose root is WINDOW. If
18286 FORCE is non-zero, redisplay mode lines unconditionally.
18287 Otherwise, redisplay only mode lines that are garbaged. Value is
18288 the number of windows whose mode lines were redisplayed. */
18290 static int
18291 redisplay_mode_lines (Lisp_Object window, int force)
18293 int nwindows = 0;
18295 while (!NILP (window))
18297 struct window *w = XWINDOW (window);
18299 if (WINDOWP (w->hchild))
18300 nwindows += redisplay_mode_lines (w->hchild, force);
18301 else if (WINDOWP (w->vchild))
18302 nwindows += redisplay_mode_lines (w->vchild, force);
18303 else if (force
18304 || FRAME_GARBAGED_P (XFRAME (w->frame))
18305 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
18307 struct text_pos lpoint;
18308 struct buffer *old = current_buffer;
18310 /* Set the window's buffer for the mode line display. */
18311 SET_TEXT_POS (lpoint, PT, PT_BYTE);
18312 set_buffer_internal_1 (XBUFFER (w->buffer));
18314 /* Point refers normally to the selected window. For any
18315 other window, set up appropriate value. */
18316 if (!EQ (window, selected_window))
18318 struct text_pos pt;
18320 SET_TEXT_POS_FROM_MARKER (pt, w->pointm);
18321 if (CHARPOS (pt) < BEGV)
18322 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
18323 else if (CHARPOS (pt) > (ZV - 1))
18324 TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
18325 else
18326 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
18329 /* Display mode lines. */
18330 clear_glyph_matrix (w->desired_matrix);
18331 if (display_mode_lines (w))
18333 ++nwindows;
18334 w->must_be_updated_p = 1;
18337 /* Restore old settings. */
18338 set_buffer_internal_1 (old);
18339 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
18342 window = w->next;
18345 return nwindows;
18349 /* Display the mode and/or header line of window W. Value is the
18350 sum number of mode lines and header lines displayed. */
18352 static int
18353 display_mode_lines (struct window *w)
18355 Lisp_Object old_selected_window, old_selected_frame;
18356 int n = 0;
18358 old_selected_frame = selected_frame;
18359 selected_frame = w->frame;
18360 old_selected_window = selected_window;
18361 XSETWINDOW (selected_window, w);
18363 /* These will be set while the mode line specs are processed. */
18364 line_number_displayed = 0;
18365 w->column_number_displayed = Qnil;
18367 if (WINDOW_WANTS_MODELINE_P (w))
18369 struct window *sel_w = XWINDOW (old_selected_window);
18371 /* Select mode line face based on the real selected window. */
18372 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
18373 BVAR (current_buffer, mode_line_format));
18374 ++n;
18377 if (WINDOW_WANTS_HEADER_LINE_P (w))
18379 display_mode_line (w, HEADER_LINE_FACE_ID,
18380 BVAR (current_buffer, header_line_format));
18381 ++n;
18384 selected_frame = old_selected_frame;
18385 selected_window = old_selected_window;
18386 return n;
18390 /* Display mode or header line of window W. FACE_ID specifies which
18391 line to display; it is either MODE_LINE_FACE_ID or
18392 HEADER_LINE_FACE_ID. FORMAT is the mode/header line format to
18393 display. Value is the pixel height of the mode/header line
18394 displayed. */
18396 static int
18397 display_mode_line (struct window *w, enum face_id face_id, Lisp_Object format)
18399 struct it it;
18400 struct face *face;
18401 int count = SPECPDL_INDEX ();
18403 init_iterator (&it, w, -1, -1, NULL, face_id);
18404 /* Don't extend on a previously drawn mode-line.
18405 This may happen if called from pos_visible_p. */
18406 it.glyph_row->enabled_p = 0;
18407 prepare_desired_row (it.glyph_row);
18409 it.glyph_row->mode_line_p = 1;
18411 if (! mode_line_inverse_video)
18412 /* Force the mode-line to be displayed in the default face. */
18413 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
18415 record_unwind_protect (unwind_format_mode_line,
18416 format_mode_line_unwind_data (NULL, Qnil, 0));
18418 mode_line_target = MODE_LINE_DISPLAY;
18420 /* Temporarily make frame's keyboard the current kboard so that
18421 kboard-local variables in the mode_line_format will get the right
18422 values. */
18423 push_kboard (FRAME_KBOARD (it.f));
18424 record_unwind_save_match_data ();
18425 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
18426 pop_kboard ();
18428 unbind_to (count, Qnil);
18430 /* Fill up with spaces. */
18431 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
18433 compute_line_metrics (&it);
18434 it.glyph_row->full_width_p = 1;
18435 it.glyph_row->continued_p = 0;
18436 it.glyph_row->truncated_on_left_p = 0;
18437 it.glyph_row->truncated_on_right_p = 0;
18439 /* Make a 3D mode-line have a shadow at its right end. */
18440 face = FACE_FROM_ID (it.f, face_id);
18441 extend_face_to_end_of_line (&it);
18442 if (face->box != FACE_NO_BOX)
18444 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
18445 + it.glyph_row->used[TEXT_AREA] - 1);
18446 last->right_box_line_p = 1;
18449 return it.glyph_row->height;
18452 /* Move element ELT in LIST to the front of LIST.
18453 Return the updated list. */
18455 static Lisp_Object
18456 move_elt_to_front (Lisp_Object elt, Lisp_Object list)
18458 register Lisp_Object tail, prev;
18459 register Lisp_Object tem;
18461 tail = list;
18462 prev = Qnil;
18463 while (CONSP (tail))
18465 tem = XCAR (tail);
18467 if (EQ (elt, tem))
18469 /* Splice out the link TAIL. */
18470 if (NILP (prev))
18471 list = XCDR (tail);
18472 else
18473 Fsetcdr (prev, XCDR (tail));
18475 /* Now make it the first. */
18476 Fsetcdr (tail, list);
18477 return tail;
18479 else
18480 prev = tail;
18481 tail = XCDR (tail);
18482 QUIT;
18485 /* Not found--return unchanged LIST. */
18486 return list;
18489 /* Contribute ELT to the mode line for window IT->w. How it
18490 translates into text depends on its data type.
18492 IT describes the display environment in which we display, as usual.
18494 DEPTH is the depth in recursion. It is used to prevent
18495 infinite recursion here.
18497 FIELD_WIDTH is the number of characters the display of ELT should
18498 occupy in the mode line, and PRECISION is the maximum number of
18499 characters to display from ELT's representation. See
18500 display_string for details.
18502 Returns the hpos of the end of the text generated by ELT.
18504 PROPS is a property list to add to any string we encounter.
18506 If RISKY is nonzero, remove (disregard) any properties in any string
18507 we encounter, and ignore :eval and :propertize.
18509 The global variable `mode_line_target' determines whether the
18510 output is passed to `store_mode_line_noprop',
18511 `store_mode_line_string', or `display_string'. */
18513 static int
18514 display_mode_element (struct it *it, int depth, int field_width, int precision,
18515 Lisp_Object elt, Lisp_Object props, int risky)
18517 int n = 0, field, prec;
18518 int literal = 0;
18520 tail_recurse:
18521 if (depth > 100)
18522 elt = build_string ("*too-deep*");
18524 depth++;
18526 switch (SWITCH_ENUM_CAST (XTYPE (elt)))
18528 case Lisp_String:
18530 /* A string: output it and check for %-constructs within it. */
18531 unsigned char c;
18532 EMACS_INT offset = 0;
18534 if (SCHARS (elt) > 0
18535 && (!NILP (props) || risky))
18537 Lisp_Object oprops, aelt;
18538 oprops = Ftext_properties_at (make_number (0), elt);
18540 /* If the starting string's properties are not what
18541 we want, translate the string. Also, if the string
18542 is risky, do that anyway. */
18544 if (NILP (Fequal (props, oprops)) || risky)
18546 /* If the starting string has properties,
18547 merge the specified ones onto the existing ones. */
18548 if (! NILP (oprops) && !risky)
18550 Lisp_Object tem;
18552 oprops = Fcopy_sequence (oprops);
18553 tem = props;
18554 while (CONSP (tem))
18556 oprops = Fplist_put (oprops, XCAR (tem),
18557 XCAR (XCDR (tem)));
18558 tem = XCDR (XCDR (tem));
18560 props = oprops;
18563 aelt = Fassoc (elt, mode_line_proptrans_alist);
18564 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
18566 /* AELT is what we want. Move it to the front
18567 without consing. */
18568 elt = XCAR (aelt);
18569 mode_line_proptrans_alist
18570 = move_elt_to_front (aelt, mode_line_proptrans_alist);
18572 else
18574 Lisp_Object tem;
18576 /* If AELT has the wrong props, it is useless.
18577 so get rid of it. */
18578 if (! NILP (aelt))
18579 mode_line_proptrans_alist
18580 = Fdelq (aelt, mode_line_proptrans_alist);
18582 elt = Fcopy_sequence (elt);
18583 Fset_text_properties (make_number (0), Flength (elt),
18584 props, elt);
18585 /* Add this item to mode_line_proptrans_alist. */
18586 mode_line_proptrans_alist
18587 = Fcons (Fcons (elt, props),
18588 mode_line_proptrans_alist);
18589 /* Truncate mode_line_proptrans_alist
18590 to at most 50 elements. */
18591 tem = Fnthcdr (make_number (50),
18592 mode_line_proptrans_alist);
18593 if (! NILP (tem))
18594 XSETCDR (tem, Qnil);
18599 offset = 0;
18601 if (literal)
18603 prec = precision - n;
18604 switch (mode_line_target)
18606 case MODE_LINE_NOPROP:
18607 case MODE_LINE_TITLE:
18608 n += store_mode_line_noprop (SSDATA (elt), -1, prec);
18609 break;
18610 case MODE_LINE_STRING:
18611 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
18612 break;
18613 case MODE_LINE_DISPLAY:
18614 n += display_string (NULL, elt, Qnil, 0, 0, it,
18615 0, prec, 0, STRING_MULTIBYTE (elt));
18616 break;
18619 break;
18622 /* Handle the non-literal case. */
18624 while ((precision <= 0 || n < precision)
18625 && SREF (elt, offset) != 0
18626 && (mode_line_target != MODE_LINE_DISPLAY
18627 || it->current_x < it->last_visible_x))
18629 EMACS_INT last_offset = offset;
18631 /* Advance to end of string or next format specifier. */
18632 while ((c = SREF (elt, offset++)) != '\0' && c != '%')
18635 if (offset - 1 != last_offset)
18637 EMACS_INT nchars, nbytes;
18639 /* Output to end of string or up to '%'. Field width
18640 is length of string. Don't output more than
18641 PRECISION allows us. */
18642 offset--;
18644 prec = c_string_width (SDATA (elt) + last_offset,
18645 offset - last_offset, precision - n,
18646 &nchars, &nbytes);
18648 switch (mode_line_target)
18650 case MODE_LINE_NOPROP:
18651 case MODE_LINE_TITLE:
18652 n += store_mode_line_noprop (SSDATA (elt) + last_offset, 0, prec);
18653 break;
18654 case MODE_LINE_STRING:
18656 EMACS_INT bytepos = last_offset;
18657 EMACS_INT charpos = string_byte_to_char (elt, bytepos);
18658 EMACS_INT endpos = (precision <= 0
18659 ? string_byte_to_char (elt, offset)
18660 : charpos + nchars);
18662 n += store_mode_line_string (NULL,
18663 Fsubstring (elt, make_number (charpos),
18664 make_number (endpos)),
18665 0, 0, 0, Qnil);
18667 break;
18668 case MODE_LINE_DISPLAY:
18670 EMACS_INT bytepos = last_offset;
18671 EMACS_INT charpos = string_byte_to_char (elt, bytepos);
18673 if (precision <= 0)
18674 nchars = string_byte_to_char (elt, offset) - charpos;
18675 n += display_string (NULL, elt, Qnil, 0, charpos,
18676 it, 0, nchars, 0,
18677 STRING_MULTIBYTE (elt));
18679 break;
18682 else /* c == '%' */
18684 EMACS_INT percent_position = offset;
18686 /* Get the specified minimum width. Zero means
18687 don't pad. */
18688 field = 0;
18689 while ((c = SREF (elt, offset++)) >= '0' && c <= '9')
18690 field = field * 10 + c - '0';
18692 /* Don't pad beyond the total padding allowed. */
18693 if (field_width - n > 0 && field > field_width - n)
18694 field = field_width - n;
18696 /* Note that either PRECISION <= 0 or N < PRECISION. */
18697 prec = precision - n;
18699 if (c == 'M')
18700 n += display_mode_element (it, depth, field, prec,
18701 Vglobal_mode_string, props,
18702 risky);
18703 else if (c != 0)
18705 int multibyte;
18706 EMACS_INT bytepos, charpos;
18707 const char *spec;
18708 Lisp_Object string;
18710 bytepos = percent_position;
18711 charpos = (STRING_MULTIBYTE (elt)
18712 ? string_byte_to_char (elt, bytepos)
18713 : bytepos);
18714 spec = decode_mode_spec (it->w, c, field, &string);
18715 multibyte = STRINGP (string) && STRING_MULTIBYTE (string);
18717 switch (mode_line_target)
18719 case MODE_LINE_NOPROP:
18720 case MODE_LINE_TITLE:
18721 n += store_mode_line_noprop (spec, field, prec);
18722 break;
18723 case MODE_LINE_STRING:
18725 int len = strlen (spec);
18726 Lisp_Object tem = make_string (spec, len);
18727 props = Ftext_properties_at (make_number (charpos), elt);
18728 /* Should only keep face property in props */
18729 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
18731 break;
18732 case MODE_LINE_DISPLAY:
18734 int nglyphs_before, nwritten;
18736 nglyphs_before = it->glyph_row->used[TEXT_AREA];
18737 nwritten = display_string (spec, string, elt,
18738 charpos, 0, it,
18739 field, prec, 0,
18740 multibyte);
18742 /* Assign to the glyphs written above the
18743 string where the `%x' came from, position
18744 of the `%'. */
18745 if (nwritten > 0)
18747 struct glyph *glyph
18748 = (it->glyph_row->glyphs[TEXT_AREA]
18749 + nglyphs_before);
18750 int i;
18752 for (i = 0; i < nwritten; ++i)
18754 glyph[i].object = elt;
18755 glyph[i].charpos = charpos;
18758 n += nwritten;
18761 break;
18764 else /* c == 0 */
18765 break;
18769 break;
18771 case Lisp_Symbol:
18772 /* A symbol: process the value of the symbol recursively
18773 as if it appeared here directly. Avoid error if symbol void.
18774 Special case: if value of symbol is a string, output the string
18775 literally. */
18777 register Lisp_Object tem;
18779 /* If the variable is not marked as risky to set
18780 then its contents are risky to use. */
18781 if (NILP (Fget (elt, Qrisky_local_variable)))
18782 risky = 1;
18784 tem = Fboundp (elt);
18785 if (!NILP (tem))
18787 tem = Fsymbol_value (elt);
18788 /* If value is a string, output that string literally:
18789 don't check for % within it. */
18790 if (STRINGP (tem))
18791 literal = 1;
18793 if (!EQ (tem, elt))
18795 /* Give up right away for nil or t. */
18796 elt = tem;
18797 goto tail_recurse;
18801 break;
18803 case Lisp_Cons:
18805 register Lisp_Object car, tem;
18807 /* A cons cell: five distinct cases.
18808 If first element is :eval or :propertize, do something special.
18809 If first element is a string or a cons, process all the elements
18810 and effectively concatenate them.
18811 If first element is a negative number, truncate displaying cdr to
18812 at most that many characters. If positive, pad (with spaces)
18813 to at least that many characters.
18814 If first element is a symbol, process the cadr or caddr recursively
18815 according to whether the symbol's value is non-nil or nil. */
18816 car = XCAR (elt);
18817 if (EQ (car, QCeval))
18819 /* An element of the form (:eval FORM) means evaluate FORM
18820 and use the result as mode line elements. */
18822 if (risky)
18823 break;
18825 if (CONSP (XCDR (elt)))
18827 Lisp_Object spec;
18828 spec = safe_eval (XCAR (XCDR (elt)));
18829 n += display_mode_element (it, depth, field_width - n,
18830 precision - n, spec, props,
18831 risky);
18834 else if (EQ (car, QCpropertize))
18836 /* An element of the form (:propertize ELT PROPS...)
18837 means display ELT but applying properties PROPS. */
18839 if (risky)
18840 break;
18842 if (CONSP (XCDR (elt)))
18843 n += display_mode_element (it, depth, field_width - n,
18844 precision - n, XCAR (XCDR (elt)),
18845 XCDR (XCDR (elt)), risky);
18847 else if (SYMBOLP (car))
18849 tem = Fboundp (car);
18850 elt = XCDR (elt);
18851 if (!CONSP (elt))
18852 goto invalid;
18853 /* elt is now the cdr, and we know it is a cons cell.
18854 Use its car if CAR has a non-nil value. */
18855 if (!NILP (tem))
18857 tem = Fsymbol_value (car);
18858 if (!NILP (tem))
18860 elt = XCAR (elt);
18861 goto tail_recurse;
18864 /* Symbol's value is nil (or symbol is unbound)
18865 Get the cddr of the original list
18866 and if possible find the caddr and use that. */
18867 elt = XCDR (elt);
18868 if (NILP (elt))
18869 break;
18870 else if (!CONSP (elt))
18871 goto invalid;
18872 elt = XCAR (elt);
18873 goto tail_recurse;
18875 else if (INTEGERP (car))
18877 register int lim = XINT (car);
18878 elt = XCDR (elt);
18879 if (lim < 0)
18881 /* Negative int means reduce maximum width. */
18882 if (precision <= 0)
18883 precision = -lim;
18884 else
18885 precision = min (precision, -lim);
18887 else if (lim > 0)
18889 /* Padding specified. Don't let it be more than
18890 current maximum. */
18891 if (precision > 0)
18892 lim = min (precision, lim);
18894 /* If that's more padding than already wanted, queue it.
18895 But don't reduce padding already specified even if
18896 that is beyond the current truncation point. */
18897 field_width = max (lim, field_width);
18899 goto tail_recurse;
18901 else if (STRINGP (car) || CONSP (car))
18903 Lisp_Object halftail = elt;
18904 int len = 0;
18906 while (CONSP (elt)
18907 && (precision <= 0 || n < precision))
18909 n += display_mode_element (it, depth,
18910 /* Do padding only after the last
18911 element in the list. */
18912 (! CONSP (XCDR (elt))
18913 ? field_width - n
18914 : 0),
18915 precision - n, XCAR (elt),
18916 props, risky);
18917 elt = XCDR (elt);
18918 len++;
18919 if ((len & 1) == 0)
18920 halftail = XCDR (halftail);
18921 /* Check for cycle. */
18922 if (EQ (halftail, elt))
18923 break;
18927 break;
18929 default:
18930 invalid:
18931 elt = build_string ("*invalid*");
18932 goto tail_recurse;
18935 /* Pad to FIELD_WIDTH. */
18936 if (field_width > 0 && n < field_width)
18938 switch (mode_line_target)
18940 case MODE_LINE_NOPROP:
18941 case MODE_LINE_TITLE:
18942 n += store_mode_line_noprop ("", field_width - n, 0);
18943 break;
18944 case MODE_LINE_STRING:
18945 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
18946 break;
18947 case MODE_LINE_DISPLAY:
18948 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
18949 0, 0, 0);
18950 break;
18954 return n;
18957 /* Store a mode-line string element in mode_line_string_list.
18959 If STRING is non-null, display that C string. Otherwise, the Lisp
18960 string LISP_STRING is displayed.
18962 FIELD_WIDTH is the minimum number of output glyphs to produce.
18963 If STRING has fewer characters than FIELD_WIDTH, pad to the right
18964 with spaces. FIELD_WIDTH <= 0 means don't pad.
18966 PRECISION is the maximum number of characters to output from
18967 STRING. PRECISION <= 0 means don't truncate the string.
18969 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
18970 properties to the string.
18972 PROPS are the properties to add to the string.
18973 The mode_line_string_face face property is always added to the string.
18976 static int
18977 store_mode_line_string (const char *string, Lisp_Object lisp_string, int copy_string,
18978 int field_width, int precision, Lisp_Object props)
18980 EMACS_INT len;
18981 int n = 0;
18983 if (string != NULL)
18985 len = strlen (string);
18986 if (precision > 0 && len > precision)
18987 len = precision;
18988 lisp_string = make_string (string, len);
18989 if (NILP (props))
18990 props = mode_line_string_face_prop;
18991 else if (!NILP (mode_line_string_face))
18993 Lisp_Object face = Fplist_get (props, Qface);
18994 props = Fcopy_sequence (props);
18995 if (NILP (face))
18996 face = mode_line_string_face;
18997 else
18998 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
18999 props = Fplist_put (props, Qface, face);
19001 Fadd_text_properties (make_number (0), make_number (len),
19002 props, lisp_string);
19004 else
19006 len = XFASTINT (Flength (lisp_string));
19007 if (precision > 0 && len > precision)
19009 len = precision;
19010 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
19011 precision = -1;
19013 if (!NILP (mode_line_string_face))
19015 Lisp_Object face;
19016 if (NILP (props))
19017 props = Ftext_properties_at (make_number (0), lisp_string);
19018 face = Fplist_get (props, Qface);
19019 if (NILP (face))
19020 face = mode_line_string_face;
19021 else
19022 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
19023 props = Fcons (Qface, Fcons (face, Qnil));
19024 if (copy_string)
19025 lisp_string = Fcopy_sequence (lisp_string);
19027 if (!NILP (props))
19028 Fadd_text_properties (make_number (0), make_number (len),
19029 props, lisp_string);
19032 if (len > 0)
19034 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
19035 n += len;
19038 if (field_width > len)
19040 field_width -= len;
19041 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
19042 if (!NILP (props))
19043 Fadd_text_properties (make_number (0), make_number (field_width),
19044 props, lisp_string);
19045 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
19046 n += field_width;
19049 return n;
19053 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
19054 1, 4, 0,
19055 doc: /* Format a string out of a mode line format specification.
19056 First arg FORMAT specifies the mode line format (see `mode-line-format'
19057 for details) to use.
19059 By default, the format is evaluated for the currently selected window.
19061 Optional second arg FACE specifies the face property to put on all
19062 characters for which no face is specified. The value nil means the
19063 default face. The value t means whatever face the window's mode line
19064 currently uses (either `mode-line' or `mode-line-inactive',
19065 depending on whether the window is the selected window or not).
19066 An integer value means the value string has no text
19067 properties.
19069 Optional third and fourth args WINDOW and BUFFER specify the window
19070 and buffer to use as the context for the formatting (defaults
19071 are the selected window and the WINDOW's buffer). */)
19072 (Lisp_Object format, Lisp_Object face,
19073 Lisp_Object window, Lisp_Object buffer)
19075 struct it it;
19076 int len;
19077 struct window *w;
19078 struct buffer *old_buffer = NULL;
19079 int face_id;
19080 int no_props = INTEGERP (face);
19081 int count = SPECPDL_INDEX ();
19082 Lisp_Object str;
19083 int string_start = 0;
19085 if (NILP (window))
19086 window = selected_window;
19087 CHECK_WINDOW (window);
19088 w = XWINDOW (window);
19090 if (NILP (buffer))
19091 buffer = w->buffer;
19092 CHECK_BUFFER (buffer);
19094 /* Make formatting the modeline a non-op when noninteractive, otherwise
19095 there will be problems later caused by a partially initialized frame. */
19096 if (NILP (format) || noninteractive)
19097 return empty_unibyte_string;
19099 if (no_props)
19100 face = Qnil;
19102 face_id = (NILP (face) || EQ (face, Qdefault)) ? DEFAULT_FACE_ID
19103 : EQ (face, Qt) ? (EQ (window, selected_window)
19104 ? MODE_LINE_FACE_ID : MODE_LINE_INACTIVE_FACE_ID)
19105 : EQ (face, Qmode_line) ? MODE_LINE_FACE_ID
19106 : EQ (face, Qmode_line_inactive) ? MODE_LINE_INACTIVE_FACE_ID
19107 : EQ (face, Qheader_line) ? HEADER_LINE_FACE_ID
19108 : EQ (face, Qtool_bar) ? TOOL_BAR_FACE_ID
19109 : DEFAULT_FACE_ID;
19111 if (XBUFFER (buffer) != current_buffer)
19112 old_buffer = current_buffer;
19114 /* Save things including mode_line_proptrans_alist,
19115 and set that to nil so that we don't alter the outer value. */
19116 record_unwind_protect (unwind_format_mode_line,
19117 format_mode_line_unwind_data
19118 (old_buffer, selected_window, 1));
19119 mode_line_proptrans_alist = Qnil;
19121 Fselect_window (window, Qt);
19122 if (old_buffer)
19123 set_buffer_internal_1 (XBUFFER (buffer));
19125 init_iterator (&it, w, -1, -1, NULL, face_id);
19127 if (no_props)
19129 mode_line_target = MODE_LINE_NOPROP;
19130 mode_line_string_face_prop = Qnil;
19131 mode_line_string_list = Qnil;
19132 string_start = MODE_LINE_NOPROP_LEN (0);
19134 else
19136 mode_line_target = MODE_LINE_STRING;
19137 mode_line_string_list = Qnil;
19138 mode_line_string_face = face;
19139 mode_line_string_face_prop
19140 = (NILP (face) ? Qnil : Fcons (Qface, Fcons (face, Qnil)));
19143 push_kboard (FRAME_KBOARD (it.f));
19144 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
19145 pop_kboard ();
19147 if (no_props)
19149 len = MODE_LINE_NOPROP_LEN (string_start);
19150 str = make_string (mode_line_noprop_buf + string_start, len);
19152 else
19154 mode_line_string_list = Fnreverse (mode_line_string_list);
19155 str = Fmapconcat (intern ("identity"), mode_line_string_list,
19156 empty_unibyte_string);
19159 unbind_to (count, Qnil);
19160 return str;
19163 /* Write a null-terminated, right justified decimal representation of
19164 the positive integer D to BUF using a minimal field width WIDTH. */
19166 static void
19167 pint2str (register char *buf, register int width, register EMACS_INT d)
19169 register char *p = buf;
19171 if (d <= 0)
19172 *p++ = '0';
19173 else
19175 while (d > 0)
19177 *p++ = d % 10 + '0';
19178 d /= 10;
19182 for (width -= (int) (p - buf); width > 0; --width)
19183 *p++ = ' ';
19184 *p-- = '\0';
19185 while (p > buf)
19187 d = *buf;
19188 *buf++ = *p;
19189 *p-- = d;
19193 /* Write a null-terminated, right justified decimal and "human
19194 readable" representation of the nonnegative integer D to BUF using
19195 a minimal field width WIDTH. D should be smaller than 999.5e24. */
19197 static const char power_letter[] =
19199 0, /* no letter */
19200 'k', /* kilo */
19201 'M', /* mega */
19202 'G', /* giga */
19203 'T', /* tera */
19204 'P', /* peta */
19205 'E', /* exa */
19206 'Z', /* zetta */
19207 'Y' /* yotta */
19210 static void
19211 pint2hrstr (char *buf, int width, EMACS_INT d)
19213 /* We aim to represent the nonnegative integer D as
19214 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
19215 EMACS_INT quotient = d;
19216 int remainder = 0;
19217 /* -1 means: do not use TENTHS. */
19218 int tenths = -1;
19219 int exponent = 0;
19221 /* Length of QUOTIENT.TENTHS as a string. */
19222 int length;
19224 char * psuffix;
19225 char * p;
19227 if (1000 <= quotient)
19229 /* Scale to the appropriate EXPONENT. */
19232 remainder = quotient % 1000;
19233 quotient /= 1000;
19234 exponent++;
19236 while (1000 <= quotient);
19238 /* Round to nearest and decide whether to use TENTHS or not. */
19239 if (quotient <= 9)
19241 tenths = remainder / 100;
19242 if (50 <= remainder % 100)
19244 if (tenths < 9)
19245 tenths++;
19246 else
19248 quotient++;
19249 if (quotient == 10)
19250 tenths = -1;
19251 else
19252 tenths = 0;
19256 else
19257 if (500 <= remainder)
19259 if (quotient < 999)
19260 quotient++;
19261 else
19263 quotient = 1;
19264 exponent++;
19265 tenths = 0;
19270 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
19271 if (tenths == -1 && quotient <= 99)
19272 if (quotient <= 9)
19273 length = 1;
19274 else
19275 length = 2;
19276 else
19277 length = 3;
19278 p = psuffix = buf + max (width, length);
19280 /* Print EXPONENT. */
19281 *psuffix++ = power_letter[exponent];
19282 *psuffix = '\0';
19284 /* Print TENTHS. */
19285 if (tenths >= 0)
19287 *--p = '0' + tenths;
19288 *--p = '.';
19291 /* Print QUOTIENT. */
19294 int digit = quotient % 10;
19295 *--p = '0' + digit;
19297 while ((quotient /= 10) != 0);
19299 /* Print leading spaces. */
19300 while (buf < p)
19301 *--p = ' ';
19304 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
19305 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
19306 type of CODING_SYSTEM. Return updated pointer into BUF. */
19308 static unsigned char invalid_eol_type[] = "(*invalid*)";
19310 static char *
19311 decode_mode_spec_coding (Lisp_Object coding_system, register char *buf, int eol_flag)
19313 Lisp_Object val;
19314 int multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters));
19315 const unsigned char *eol_str;
19316 int eol_str_len;
19317 /* The EOL conversion we are using. */
19318 Lisp_Object eoltype;
19320 val = CODING_SYSTEM_SPEC (coding_system);
19321 eoltype = Qnil;
19323 if (!VECTORP (val)) /* Not yet decided. */
19325 if (multibyte)
19326 *buf++ = '-';
19327 if (eol_flag)
19328 eoltype = eol_mnemonic_undecided;
19329 /* Don't mention EOL conversion if it isn't decided. */
19331 else
19333 Lisp_Object attrs;
19334 Lisp_Object eolvalue;
19336 attrs = AREF (val, 0);
19337 eolvalue = AREF (val, 2);
19339 if (multibyte)
19340 *buf++ = XFASTINT (CODING_ATTR_MNEMONIC (attrs));
19342 if (eol_flag)
19344 /* The EOL conversion that is normal on this system. */
19346 if (NILP (eolvalue)) /* Not yet decided. */
19347 eoltype = eol_mnemonic_undecided;
19348 else if (VECTORP (eolvalue)) /* Not yet decided. */
19349 eoltype = eol_mnemonic_undecided;
19350 else /* eolvalue is Qunix, Qdos, or Qmac. */
19351 eoltype = (EQ (eolvalue, Qunix)
19352 ? eol_mnemonic_unix
19353 : (EQ (eolvalue, Qdos) == 1
19354 ? eol_mnemonic_dos : eol_mnemonic_mac));
19358 if (eol_flag)
19360 /* Mention the EOL conversion if it is not the usual one. */
19361 if (STRINGP (eoltype))
19363 eol_str = SDATA (eoltype);
19364 eol_str_len = SBYTES (eoltype);
19366 else if (CHARACTERP (eoltype))
19368 unsigned char *tmp = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
19369 eol_str_len = CHAR_STRING (XINT (eoltype), tmp);
19370 eol_str = tmp;
19372 else
19374 eol_str = invalid_eol_type;
19375 eol_str_len = sizeof (invalid_eol_type) - 1;
19377 memcpy (buf, eol_str, eol_str_len);
19378 buf += eol_str_len;
19381 return buf;
19384 /* Return a string for the output of a mode line %-spec for window W,
19385 generated by character C. FIELD_WIDTH > 0 means pad the string
19386 returned with spaces to that value. Return a Lisp string in
19387 *STRING if the resulting string is taken from that Lisp string.
19389 Note we operate on the current buffer for most purposes,
19390 the exception being w->base_line_pos. */
19392 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
19394 static const char *
19395 decode_mode_spec (struct window *w, register int c, int field_width,
19396 Lisp_Object *string)
19398 Lisp_Object obj;
19399 struct frame *f = XFRAME (WINDOW_FRAME (w));
19400 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
19401 struct buffer *b = current_buffer;
19403 obj = Qnil;
19404 *string = Qnil;
19406 switch (c)
19408 case '*':
19409 if (!NILP (BVAR (b, read_only)))
19410 return "%";
19411 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
19412 return "*";
19413 return "-";
19415 case '+':
19416 /* This differs from %* only for a modified read-only buffer. */
19417 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
19418 return "*";
19419 if (!NILP (BVAR (b, read_only)))
19420 return "%";
19421 return "-";
19423 case '&':
19424 /* This differs from %* in ignoring read-only-ness. */
19425 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
19426 return "*";
19427 return "-";
19429 case '%':
19430 return "%";
19432 case '[':
19434 int i;
19435 char *p;
19437 if (command_loop_level > 5)
19438 return "[[[... ";
19439 p = decode_mode_spec_buf;
19440 for (i = 0; i < command_loop_level; i++)
19441 *p++ = '[';
19442 *p = 0;
19443 return decode_mode_spec_buf;
19446 case ']':
19448 int i;
19449 char *p;
19451 if (command_loop_level > 5)
19452 return " ...]]]";
19453 p = decode_mode_spec_buf;
19454 for (i = 0; i < command_loop_level; i++)
19455 *p++ = ']';
19456 *p = 0;
19457 return decode_mode_spec_buf;
19460 case '-':
19462 register int i;
19464 /* Let lots_of_dashes be a string of infinite length. */
19465 if (mode_line_target == MODE_LINE_NOPROP ||
19466 mode_line_target == MODE_LINE_STRING)
19467 return "--";
19468 if (field_width <= 0
19469 || field_width > sizeof (lots_of_dashes))
19471 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
19472 decode_mode_spec_buf[i] = '-';
19473 decode_mode_spec_buf[i] = '\0';
19474 return decode_mode_spec_buf;
19476 else
19477 return lots_of_dashes;
19480 case 'b':
19481 obj = BVAR (b, name);
19482 break;
19484 case 'c':
19485 /* %c and %l are ignored in `frame-title-format'.
19486 (In redisplay_internal, the frame title is drawn _before_ the
19487 windows are updated, so the stuff which depends on actual
19488 window contents (such as %l) may fail to render properly, or
19489 even crash emacs.) */
19490 if (mode_line_target == MODE_LINE_TITLE)
19491 return "";
19492 else
19494 EMACS_INT col = current_column ();
19495 w->column_number_displayed = make_number (col);
19496 pint2str (decode_mode_spec_buf, field_width, col);
19497 return decode_mode_spec_buf;
19500 case 'e':
19501 #ifndef SYSTEM_MALLOC
19503 if (NILP (Vmemory_full))
19504 return "";
19505 else
19506 return "!MEM FULL! ";
19508 #else
19509 return "";
19510 #endif
19512 case 'F':
19513 /* %F displays the frame name. */
19514 if (!NILP (f->title))
19515 return SSDATA (f->title);
19516 if (f->explicit_name || ! FRAME_WINDOW_P (f))
19517 return SSDATA (f->name);
19518 return "Emacs";
19520 case 'f':
19521 obj = BVAR (b, filename);
19522 break;
19524 case 'i':
19526 EMACS_INT size = ZV - BEGV;
19527 pint2str (decode_mode_spec_buf, field_width, size);
19528 return decode_mode_spec_buf;
19531 case 'I':
19533 EMACS_INT size = ZV - BEGV;
19534 pint2hrstr (decode_mode_spec_buf, field_width, size);
19535 return decode_mode_spec_buf;
19538 case 'l':
19540 EMACS_INT startpos, startpos_byte, line, linepos, linepos_byte;
19541 EMACS_INT topline, nlines, height;
19542 EMACS_INT junk;
19544 /* %c and %l are ignored in `frame-title-format'. */
19545 if (mode_line_target == MODE_LINE_TITLE)
19546 return "";
19548 startpos = XMARKER (w->start)->charpos;
19549 startpos_byte = marker_byte_position (w->start);
19550 height = WINDOW_TOTAL_LINES (w);
19552 /* If we decided that this buffer isn't suitable for line numbers,
19553 don't forget that too fast. */
19554 if (EQ (w->base_line_pos, w->buffer))
19555 goto no_value;
19556 /* But do forget it, if the window shows a different buffer now. */
19557 else if (BUFFERP (w->base_line_pos))
19558 w->base_line_pos = Qnil;
19560 /* If the buffer is very big, don't waste time. */
19561 if (INTEGERP (Vline_number_display_limit)
19562 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
19564 w->base_line_pos = Qnil;
19565 w->base_line_number = Qnil;
19566 goto no_value;
19569 if (INTEGERP (w->base_line_number)
19570 && INTEGERP (w->base_line_pos)
19571 && XFASTINT (w->base_line_pos) <= startpos)
19573 line = XFASTINT (w->base_line_number);
19574 linepos = XFASTINT (w->base_line_pos);
19575 linepos_byte = buf_charpos_to_bytepos (b, linepos);
19577 else
19579 line = 1;
19580 linepos = BUF_BEGV (b);
19581 linepos_byte = BUF_BEGV_BYTE (b);
19584 /* Count lines from base line to window start position. */
19585 nlines = display_count_lines (linepos_byte,
19586 startpos_byte,
19587 startpos, &junk);
19589 topline = nlines + line;
19591 /* Determine a new base line, if the old one is too close
19592 or too far away, or if we did not have one.
19593 "Too close" means it's plausible a scroll-down would
19594 go back past it. */
19595 if (startpos == BUF_BEGV (b))
19597 w->base_line_number = make_number (topline);
19598 w->base_line_pos = make_number (BUF_BEGV (b));
19600 else if (nlines < height + 25 || nlines > height * 3 + 50
19601 || linepos == BUF_BEGV (b))
19603 EMACS_INT limit = BUF_BEGV (b);
19604 EMACS_INT limit_byte = BUF_BEGV_BYTE (b);
19605 EMACS_INT position;
19606 EMACS_INT distance =
19607 (height * 2 + 30) * line_number_display_limit_width;
19609 if (startpos - distance > limit)
19611 limit = startpos - distance;
19612 limit_byte = CHAR_TO_BYTE (limit);
19615 nlines = display_count_lines (startpos_byte,
19616 limit_byte,
19617 - (height * 2 + 30),
19618 &position);
19619 /* If we couldn't find the lines we wanted within
19620 line_number_display_limit_width chars per line,
19621 give up on line numbers for this window. */
19622 if (position == limit_byte && limit == startpos - distance)
19624 w->base_line_pos = w->buffer;
19625 w->base_line_number = Qnil;
19626 goto no_value;
19629 w->base_line_number = make_number (topline - nlines);
19630 w->base_line_pos = make_number (BYTE_TO_CHAR (position));
19633 /* Now count lines from the start pos to point. */
19634 nlines = display_count_lines (startpos_byte,
19635 PT_BYTE, PT, &junk);
19637 /* Record that we did display the line number. */
19638 line_number_displayed = 1;
19640 /* Make the string to show. */
19641 pint2str (decode_mode_spec_buf, field_width, topline + nlines);
19642 return decode_mode_spec_buf;
19643 no_value:
19645 char* p = decode_mode_spec_buf;
19646 int pad = field_width - 2;
19647 while (pad-- > 0)
19648 *p++ = ' ';
19649 *p++ = '?';
19650 *p++ = '?';
19651 *p = '\0';
19652 return decode_mode_spec_buf;
19655 break;
19657 case 'm':
19658 obj = BVAR (b, mode_name);
19659 break;
19661 case 'n':
19662 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
19663 return " Narrow";
19664 break;
19666 case 'p':
19668 EMACS_INT pos = marker_position (w->start);
19669 EMACS_INT total = BUF_ZV (b) - BUF_BEGV (b);
19671 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
19673 if (pos <= BUF_BEGV (b))
19674 return "All";
19675 else
19676 return "Bottom";
19678 else if (pos <= BUF_BEGV (b))
19679 return "Top";
19680 else
19682 if (total > 1000000)
19683 /* Do it differently for a large value, to avoid overflow. */
19684 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
19685 else
19686 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
19687 /* We can't normally display a 3-digit number,
19688 so get us a 2-digit number that is close. */
19689 if (total == 100)
19690 total = 99;
19691 sprintf (decode_mode_spec_buf, "%2"pI"d%%", total);
19692 return decode_mode_spec_buf;
19696 /* Display percentage of size above the bottom of the screen. */
19697 case 'P':
19699 EMACS_INT toppos = marker_position (w->start);
19700 EMACS_INT botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
19701 EMACS_INT total = BUF_ZV (b) - BUF_BEGV (b);
19703 if (botpos >= BUF_ZV (b))
19705 if (toppos <= BUF_BEGV (b))
19706 return "All";
19707 else
19708 return "Bottom";
19710 else
19712 if (total > 1000000)
19713 /* Do it differently for a large value, to avoid overflow. */
19714 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
19715 else
19716 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
19717 /* We can't normally display a 3-digit number,
19718 so get us a 2-digit number that is close. */
19719 if (total == 100)
19720 total = 99;
19721 if (toppos <= BUF_BEGV (b))
19722 sprintf (decode_mode_spec_buf, "Top%2"pI"d%%", total);
19723 else
19724 sprintf (decode_mode_spec_buf, "%2"pI"d%%", total);
19725 return decode_mode_spec_buf;
19729 case 's':
19730 /* status of process */
19731 obj = Fget_buffer_process (Fcurrent_buffer ());
19732 if (NILP (obj))
19733 return "no process";
19734 #ifndef MSDOS
19735 obj = Fsymbol_name (Fprocess_status (obj));
19736 #endif
19737 break;
19739 case '@':
19741 int count = inhibit_garbage_collection ();
19742 Lisp_Object val = call1 (intern ("file-remote-p"),
19743 BVAR (current_buffer, directory));
19744 unbind_to (count, Qnil);
19746 if (NILP (val))
19747 return "-";
19748 else
19749 return "@";
19752 case 't': /* indicate TEXT or BINARY */
19753 return "T";
19755 case 'z':
19756 /* coding-system (not including end-of-line format) */
19757 case 'Z':
19758 /* coding-system (including end-of-line type) */
19760 int eol_flag = (c == 'Z');
19761 char *p = decode_mode_spec_buf;
19763 if (! FRAME_WINDOW_P (f))
19765 /* No need to mention EOL here--the terminal never needs
19766 to do EOL conversion. */
19767 p = decode_mode_spec_coding (CODING_ID_NAME
19768 (FRAME_KEYBOARD_CODING (f)->id),
19769 p, 0);
19770 p = decode_mode_spec_coding (CODING_ID_NAME
19771 (FRAME_TERMINAL_CODING (f)->id),
19772 p, 0);
19774 p = decode_mode_spec_coding (BVAR (b, buffer_file_coding_system),
19775 p, eol_flag);
19777 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
19778 #ifdef subprocesses
19779 obj = Fget_buffer_process (Fcurrent_buffer ());
19780 if (PROCESSP (obj))
19782 p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system,
19783 p, eol_flag);
19784 p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system,
19785 p, eol_flag);
19787 #endif /* subprocesses */
19788 #endif /* 0 */
19789 *p = 0;
19790 return decode_mode_spec_buf;
19794 if (STRINGP (obj))
19796 *string = obj;
19797 return SSDATA (obj);
19799 else
19800 return "";
19804 /* Count up to COUNT lines starting from START_BYTE.
19805 But don't go beyond LIMIT_BYTE.
19806 Return the number of lines thus found (always nonnegative).
19808 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
19810 static EMACS_INT
19811 display_count_lines (EMACS_INT start_byte,
19812 EMACS_INT limit_byte, EMACS_INT count,
19813 EMACS_INT *byte_pos_ptr)
19815 register unsigned char *cursor;
19816 unsigned char *base;
19818 register EMACS_INT ceiling;
19819 register unsigned char *ceiling_addr;
19820 EMACS_INT orig_count = count;
19822 /* If we are not in selective display mode,
19823 check only for newlines. */
19824 int selective_display = (!NILP (BVAR (current_buffer, selective_display))
19825 && !INTEGERP (BVAR (current_buffer, selective_display)));
19827 if (count > 0)
19829 while (start_byte < limit_byte)
19831 ceiling = BUFFER_CEILING_OF (start_byte);
19832 ceiling = min (limit_byte - 1, ceiling);
19833 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
19834 base = (cursor = BYTE_POS_ADDR (start_byte));
19835 while (1)
19837 if (selective_display)
19838 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
19840 else
19841 while (*cursor != '\n' && ++cursor != ceiling_addr)
19844 if (cursor != ceiling_addr)
19846 if (--count == 0)
19848 start_byte += cursor - base + 1;
19849 *byte_pos_ptr = start_byte;
19850 return orig_count;
19852 else
19853 if (++cursor == ceiling_addr)
19854 break;
19856 else
19857 break;
19859 start_byte += cursor - base;
19862 else
19864 while (start_byte > limit_byte)
19866 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
19867 ceiling = max (limit_byte, ceiling);
19868 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1;
19869 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
19870 while (1)
19872 if (selective_display)
19873 while (--cursor != ceiling_addr
19874 && *cursor != '\n' && *cursor != 015)
19876 else
19877 while (--cursor != ceiling_addr && *cursor != '\n')
19880 if (cursor != ceiling_addr)
19882 if (++count == 0)
19884 start_byte += cursor - base + 1;
19885 *byte_pos_ptr = start_byte;
19886 /* When scanning backwards, we should
19887 not count the newline posterior to which we stop. */
19888 return - orig_count - 1;
19891 else
19892 break;
19894 /* Here we add 1 to compensate for the last decrement
19895 of CURSOR, which took it past the valid range. */
19896 start_byte += cursor - base + 1;
19900 *byte_pos_ptr = limit_byte;
19902 if (count < 0)
19903 return - orig_count + count;
19904 return orig_count - count;
19910 /***********************************************************************
19911 Displaying strings
19912 ***********************************************************************/
19914 /* Display a NUL-terminated string, starting with index START.
19916 If STRING is non-null, display that C string. Otherwise, the Lisp
19917 string LISP_STRING is displayed. There's a case that STRING is
19918 non-null and LISP_STRING is not nil. It means STRING is a string
19919 data of LISP_STRING. In that case, we display LISP_STRING while
19920 ignoring its text properties.
19922 If FACE_STRING is not nil, FACE_STRING_POS is a position in
19923 FACE_STRING. Display STRING or LISP_STRING with the face at
19924 FACE_STRING_POS in FACE_STRING:
19926 Display the string in the environment given by IT, but use the
19927 standard display table, temporarily.
19929 FIELD_WIDTH is the minimum number of output glyphs to produce.
19930 If STRING has fewer characters than FIELD_WIDTH, pad to the right
19931 with spaces. If STRING has more characters, more than FIELD_WIDTH
19932 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
19934 PRECISION is the maximum number of characters to output from
19935 STRING. PRECISION < 0 means don't truncate the string.
19937 This is roughly equivalent to printf format specifiers:
19939 FIELD_WIDTH PRECISION PRINTF
19940 ----------------------------------------
19941 -1 -1 %s
19942 -1 10 %.10s
19943 10 -1 %10s
19944 20 10 %20.10s
19946 MULTIBYTE zero means do not display multibyte chars, > 0 means do
19947 display them, and < 0 means obey the current buffer's value of
19948 enable_multibyte_characters.
19950 Value is the number of columns displayed. */
19952 static int
19953 display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_string,
19954 EMACS_INT face_string_pos, EMACS_INT start, struct it *it,
19955 int field_width, int precision, int max_x, int multibyte)
19957 int hpos_at_start = it->hpos;
19958 int saved_face_id = it->face_id;
19959 struct glyph_row *row = it->glyph_row;
19961 /* Initialize the iterator IT for iteration over STRING beginning
19962 with index START. */
19963 reseat_to_string (it, NILP (lisp_string) ? string : NULL, lisp_string, start,
19964 precision, field_width, multibyte);
19965 if (string && STRINGP (lisp_string))
19966 /* LISP_STRING is the one returned by decode_mode_spec. We should
19967 ignore its text properties. */
19968 it->stop_charpos = -1;
19970 /* If displaying STRING, set up the face of the iterator
19971 from LISP_STRING, if that's given. */
19972 if (STRINGP (face_string))
19974 EMACS_INT endptr;
19975 struct face *face;
19977 it->face_id
19978 = face_at_string_position (it->w, face_string, face_string_pos,
19979 0, it->region_beg_charpos,
19980 it->region_end_charpos,
19981 &endptr, it->base_face_id, 0);
19982 face = FACE_FROM_ID (it->f, it->face_id);
19983 it->face_box_p = face->box != FACE_NO_BOX;
19986 /* Set max_x to the maximum allowed X position. Don't let it go
19987 beyond the right edge of the window. */
19988 if (max_x <= 0)
19989 max_x = it->last_visible_x;
19990 else
19991 max_x = min (max_x, it->last_visible_x);
19993 /* Skip over display elements that are not visible. because IT->w is
19994 hscrolled. */
19995 if (it->current_x < it->first_visible_x)
19996 move_it_in_display_line_to (it, 100000, it->first_visible_x,
19997 MOVE_TO_POS | MOVE_TO_X);
19999 row->ascent = it->max_ascent;
20000 row->height = it->max_ascent + it->max_descent;
20001 row->phys_ascent = it->max_phys_ascent;
20002 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
20003 row->extra_line_spacing = it->max_extra_line_spacing;
20005 /* This condition is for the case that we are called with current_x
20006 past last_visible_x. */
20007 while (it->current_x < max_x)
20009 int x_before, x, n_glyphs_before, i, nglyphs;
20011 /* Get the next display element. */
20012 if (!get_next_display_element (it))
20013 break;
20015 /* Produce glyphs. */
20016 x_before = it->current_x;
20017 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
20018 PRODUCE_GLYPHS (it);
20020 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
20021 i = 0;
20022 x = x_before;
20023 while (i < nglyphs)
20025 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
20027 if (it->line_wrap != TRUNCATE
20028 && x + glyph->pixel_width > max_x)
20030 /* End of continued line or max_x reached. */
20031 if (CHAR_GLYPH_PADDING_P (*glyph))
20033 /* A wide character is unbreakable. */
20034 it->glyph_row->used[TEXT_AREA] = n_glyphs_before;
20035 it->current_x = x_before;
20037 else
20039 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
20040 it->current_x = x;
20042 break;
20044 else if (x + glyph->pixel_width >= it->first_visible_x)
20046 /* Glyph is at least partially visible. */
20047 ++it->hpos;
20048 if (x < it->first_visible_x)
20049 it->glyph_row->x = x - it->first_visible_x;
20051 else
20053 /* Glyph is off the left margin of the display area.
20054 Should not happen. */
20055 abort ();
20058 row->ascent = max (row->ascent, it->max_ascent);
20059 row->height = max (row->height, it->max_ascent + it->max_descent);
20060 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
20061 row->phys_height = max (row->phys_height,
20062 it->max_phys_ascent + it->max_phys_descent);
20063 row->extra_line_spacing = max (row->extra_line_spacing,
20064 it->max_extra_line_spacing);
20065 x += glyph->pixel_width;
20066 ++i;
20069 /* Stop if max_x reached. */
20070 if (i < nglyphs)
20071 break;
20073 /* Stop at line ends. */
20074 if (ITERATOR_AT_END_OF_LINE_P (it))
20076 it->continuation_lines_width = 0;
20077 break;
20080 set_iterator_to_next (it, 1);
20082 /* Stop if truncating at the right edge. */
20083 if (it->line_wrap == TRUNCATE
20084 && it->current_x >= it->last_visible_x)
20086 /* Add truncation mark, but don't do it if the line is
20087 truncated at a padding space. */
20088 if (IT_CHARPOS (*it) < it->string_nchars)
20090 if (!FRAME_WINDOW_P (it->f))
20092 int ii, n;
20094 if (it->current_x > it->last_visible_x)
20096 for (ii = row->used[TEXT_AREA] - 1; ii > 0; --ii)
20097 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
20098 break;
20099 for (n = row->used[TEXT_AREA]; ii < n; ++ii)
20101 row->used[TEXT_AREA] = ii;
20102 produce_special_glyphs (it, IT_TRUNCATION);
20105 produce_special_glyphs (it, IT_TRUNCATION);
20107 it->glyph_row->truncated_on_right_p = 1;
20109 break;
20113 /* Maybe insert a truncation at the left. */
20114 if (it->first_visible_x
20115 && IT_CHARPOS (*it) > 0)
20117 if (!FRAME_WINDOW_P (it->f))
20118 insert_left_trunc_glyphs (it);
20119 it->glyph_row->truncated_on_left_p = 1;
20122 it->face_id = saved_face_id;
20124 /* Value is number of columns displayed. */
20125 return it->hpos - hpos_at_start;
20130 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
20131 appears as an element of LIST or as the car of an element of LIST.
20132 If PROPVAL is a list, compare each element against LIST in that
20133 way, and return 1/2 if any element of PROPVAL is found in LIST.
20134 Otherwise return 0. This function cannot quit.
20135 The return value is 2 if the text is invisible but with an ellipsis
20136 and 1 if it's invisible and without an ellipsis. */
20139 invisible_p (register Lisp_Object propval, Lisp_Object list)
20141 register Lisp_Object tail, proptail;
20143 for (tail = list; CONSP (tail); tail = XCDR (tail))
20145 register Lisp_Object tem;
20146 tem = XCAR (tail);
20147 if (EQ (propval, tem))
20148 return 1;
20149 if (CONSP (tem) && EQ (propval, XCAR (tem)))
20150 return NILP (XCDR (tem)) ? 1 : 2;
20153 if (CONSP (propval))
20155 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
20157 Lisp_Object propelt;
20158 propelt = XCAR (proptail);
20159 for (tail = list; CONSP (tail); tail = XCDR (tail))
20161 register Lisp_Object tem;
20162 tem = XCAR (tail);
20163 if (EQ (propelt, tem))
20164 return 1;
20165 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
20166 return NILP (XCDR (tem)) ? 1 : 2;
20171 return 0;
20174 DEFUN ("invisible-p", Finvisible_p, Sinvisible_p, 1, 1, 0,
20175 doc: /* Non-nil if the property makes the text invisible.
20176 POS-OR-PROP can be a marker or number, in which case it is taken to be
20177 a position in the current buffer and the value of the `invisible' property
20178 is checked; or it can be some other value, which is then presumed to be the
20179 value of the `invisible' property of the text of interest.
20180 The non-nil value returned can be t for truly invisible text or something
20181 else if the text is replaced by an ellipsis. */)
20182 (Lisp_Object pos_or_prop)
20184 Lisp_Object prop
20185 = (NATNUMP (pos_or_prop) || MARKERP (pos_or_prop)
20186 ? Fget_char_property (pos_or_prop, Qinvisible, Qnil)
20187 : pos_or_prop);
20188 int invis = TEXT_PROP_MEANS_INVISIBLE (prop);
20189 return (invis == 0 ? Qnil
20190 : invis == 1 ? Qt
20191 : make_number (invis));
20194 /* Calculate a width or height in pixels from a specification using
20195 the following elements:
20197 SPEC ::=
20198 NUM - a (fractional) multiple of the default font width/height
20199 (NUM) - specifies exactly NUM pixels
20200 UNIT - a fixed number of pixels, see below.
20201 ELEMENT - size of a display element in pixels, see below.
20202 (NUM . SPEC) - equals NUM * SPEC
20203 (+ SPEC SPEC ...) - add pixel values
20204 (- SPEC SPEC ...) - subtract pixel values
20205 (- SPEC) - negate pixel value
20207 NUM ::=
20208 INT or FLOAT - a number constant
20209 SYMBOL - use symbol's (buffer local) variable binding.
20211 UNIT ::=
20212 in - pixels per inch *)
20213 mm - pixels per 1/1000 meter *)
20214 cm - pixels per 1/100 meter *)
20215 width - width of current font in pixels.
20216 height - height of current font in pixels.
20218 *) using the ratio(s) defined in display-pixels-per-inch.
20220 ELEMENT ::=
20222 left-fringe - left fringe width in pixels
20223 right-fringe - right fringe width in pixels
20225 left-margin - left margin width in pixels
20226 right-margin - right margin width in pixels
20228 scroll-bar - scroll-bar area width in pixels
20230 Examples:
20232 Pixels corresponding to 5 inches:
20233 (5 . in)
20235 Total width of non-text areas on left side of window (if scroll-bar is on left):
20236 '(space :width (+ left-fringe left-margin scroll-bar))
20238 Align to first text column (in header line):
20239 '(space :align-to 0)
20241 Align to middle of text area minus half the width of variable `my-image'
20242 containing a loaded image:
20243 '(space :align-to (0.5 . (- text my-image)))
20245 Width of left margin minus width of 1 character in the default font:
20246 '(space :width (- left-margin 1))
20248 Width of left margin minus width of 2 characters in the current font:
20249 '(space :width (- left-margin (2 . width)))
20251 Center 1 character over left-margin (in header line):
20252 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
20254 Different ways to express width of left fringe plus left margin minus one pixel:
20255 '(space :width (- (+ left-fringe left-margin) (1)))
20256 '(space :width (+ left-fringe left-margin (- (1))))
20257 '(space :width (+ left-fringe left-margin (-1)))
20261 #define NUMVAL(X) \
20262 ((INTEGERP (X) || FLOATP (X)) \
20263 ? XFLOATINT (X) \
20264 : - 1)
20267 calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
20268 struct font *font, int width_p, int *align_to)
20270 double pixels;
20272 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
20273 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
20275 if (NILP (prop))
20276 return OK_PIXELS (0);
20278 xassert (FRAME_LIVE_P (it->f));
20280 if (SYMBOLP (prop))
20282 if (SCHARS (SYMBOL_NAME (prop)) == 2)
20284 char *unit = SSDATA (SYMBOL_NAME (prop));
20286 if (unit[0] == 'i' && unit[1] == 'n')
20287 pixels = 1.0;
20288 else if (unit[0] == 'm' && unit[1] == 'm')
20289 pixels = 25.4;
20290 else if (unit[0] == 'c' && unit[1] == 'm')
20291 pixels = 2.54;
20292 else
20293 pixels = 0;
20294 if (pixels > 0)
20296 double ppi;
20297 #ifdef HAVE_WINDOW_SYSTEM
20298 if (FRAME_WINDOW_P (it->f)
20299 && (ppi = (width_p
20300 ? FRAME_X_DISPLAY_INFO (it->f)->resx
20301 : FRAME_X_DISPLAY_INFO (it->f)->resy),
20302 ppi > 0))
20303 return OK_PIXELS (ppi / pixels);
20304 #endif
20306 if ((ppi = NUMVAL (Vdisplay_pixels_per_inch), ppi > 0)
20307 || (CONSP (Vdisplay_pixels_per_inch)
20308 && (ppi = (width_p
20309 ? NUMVAL (XCAR (Vdisplay_pixels_per_inch))
20310 : NUMVAL (XCDR (Vdisplay_pixels_per_inch))),
20311 ppi > 0)))
20312 return OK_PIXELS (ppi / pixels);
20314 return 0;
20318 #ifdef HAVE_WINDOW_SYSTEM
20319 if (EQ (prop, Qheight))
20320 return OK_PIXELS (font ? FONT_HEIGHT (font) : FRAME_LINE_HEIGHT (it->f));
20321 if (EQ (prop, Qwidth))
20322 return OK_PIXELS (font ? FONT_WIDTH (font) : FRAME_COLUMN_WIDTH (it->f));
20323 #else
20324 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
20325 return OK_PIXELS (1);
20326 #endif
20328 if (EQ (prop, Qtext))
20329 return OK_PIXELS (width_p
20330 ? window_box_width (it->w, TEXT_AREA)
20331 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
20333 if (align_to && *align_to < 0)
20335 *res = 0;
20336 if (EQ (prop, Qleft))
20337 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA));
20338 if (EQ (prop, Qright))
20339 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
20340 if (EQ (prop, Qcenter))
20341 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
20342 + window_box_width (it->w, TEXT_AREA) / 2);
20343 if (EQ (prop, Qleft_fringe))
20344 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
20345 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
20346 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
20347 if (EQ (prop, Qright_fringe))
20348 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
20349 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
20350 : window_box_right_offset (it->w, TEXT_AREA));
20351 if (EQ (prop, Qleft_margin))
20352 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
20353 if (EQ (prop, Qright_margin))
20354 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
20355 if (EQ (prop, Qscroll_bar))
20356 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
20358 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
20359 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
20360 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
20361 : 0)));
20363 else
20365 if (EQ (prop, Qleft_fringe))
20366 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
20367 if (EQ (prop, Qright_fringe))
20368 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
20369 if (EQ (prop, Qleft_margin))
20370 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
20371 if (EQ (prop, Qright_margin))
20372 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
20373 if (EQ (prop, Qscroll_bar))
20374 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
20377 prop = Fbuffer_local_value (prop, it->w->buffer);
20380 if (INTEGERP (prop) || FLOATP (prop))
20382 int base_unit = (width_p
20383 ? FRAME_COLUMN_WIDTH (it->f)
20384 : FRAME_LINE_HEIGHT (it->f));
20385 return OK_PIXELS (XFLOATINT (prop) * base_unit);
20388 if (CONSP (prop))
20390 Lisp_Object car = XCAR (prop);
20391 Lisp_Object cdr = XCDR (prop);
20393 if (SYMBOLP (car))
20395 #ifdef HAVE_WINDOW_SYSTEM
20396 if (FRAME_WINDOW_P (it->f)
20397 && valid_image_p (prop))
20399 int id = lookup_image (it->f, prop);
20400 struct image *img = IMAGE_FROM_ID (it->f, id);
20402 return OK_PIXELS (width_p ? img->width : img->height);
20404 #endif
20405 if (EQ (car, Qplus) || EQ (car, Qminus))
20407 int first = 1;
20408 double px;
20410 pixels = 0;
20411 while (CONSP (cdr))
20413 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
20414 font, width_p, align_to))
20415 return 0;
20416 if (first)
20417 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
20418 else
20419 pixels += px;
20420 cdr = XCDR (cdr);
20422 if (EQ (car, Qminus))
20423 pixels = -pixels;
20424 return OK_PIXELS (pixels);
20427 car = Fbuffer_local_value (car, it->w->buffer);
20430 if (INTEGERP (car) || FLOATP (car))
20432 double fact;
20433 pixels = XFLOATINT (car);
20434 if (NILP (cdr))
20435 return OK_PIXELS (pixels);
20436 if (calc_pixel_width_or_height (&fact, it, cdr,
20437 font, width_p, align_to))
20438 return OK_PIXELS (pixels * fact);
20439 return 0;
20442 return 0;
20445 return 0;
20449 /***********************************************************************
20450 Glyph Display
20451 ***********************************************************************/
20453 #ifdef HAVE_WINDOW_SYSTEM
20455 #if GLYPH_DEBUG
20457 void
20458 dump_glyph_string (s)
20459 struct glyph_string *s;
20461 fprintf (stderr, "glyph string\n");
20462 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
20463 s->x, s->y, s->width, s->height);
20464 fprintf (stderr, " ybase = %d\n", s->ybase);
20465 fprintf (stderr, " hl = %d\n", s->hl);
20466 fprintf (stderr, " left overhang = %d, right = %d\n",
20467 s->left_overhang, s->right_overhang);
20468 fprintf (stderr, " nchars = %d\n", s->nchars);
20469 fprintf (stderr, " extends to end of line = %d\n",
20470 s->extends_to_end_of_line_p);
20471 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
20472 fprintf (stderr, " bg width = %d\n", s->background_width);
20475 #endif /* GLYPH_DEBUG */
20477 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
20478 of XChar2b structures for S; it can't be allocated in
20479 init_glyph_string because it must be allocated via `alloca'. W
20480 is the window on which S is drawn. ROW and AREA are the glyph row
20481 and area within the row from which S is constructed. START is the
20482 index of the first glyph structure covered by S. HL is a
20483 face-override for drawing S. */
20485 #ifdef HAVE_NTGUI
20486 #define OPTIONAL_HDC(hdc) HDC hdc,
20487 #define DECLARE_HDC(hdc) HDC hdc;
20488 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
20489 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
20490 #endif
20492 #ifndef OPTIONAL_HDC
20493 #define OPTIONAL_HDC(hdc)
20494 #define DECLARE_HDC(hdc)
20495 #define ALLOCATE_HDC(hdc, f)
20496 #define RELEASE_HDC(hdc, f)
20497 #endif
20499 static void
20500 init_glyph_string (struct glyph_string *s,
20501 OPTIONAL_HDC (hdc)
20502 XChar2b *char2b, struct window *w, struct glyph_row *row,
20503 enum glyph_row_area area, int start, enum draw_glyphs_face hl)
20505 memset (s, 0, sizeof *s);
20506 s->w = w;
20507 s->f = XFRAME (w->frame);
20508 #ifdef HAVE_NTGUI
20509 s->hdc = hdc;
20510 #endif
20511 s->display = FRAME_X_DISPLAY (s->f);
20512 s->window = FRAME_X_WINDOW (s->f);
20513 s->char2b = char2b;
20514 s->hl = hl;
20515 s->row = row;
20516 s->area = area;
20517 s->first_glyph = row->glyphs[area] + start;
20518 s->height = row->height;
20519 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
20520 s->ybase = s->y + row->ascent;
20524 /* Append the list of glyph strings with head H and tail T to the list
20525 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
20527 static INLINE void
20528 append_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
20529 struct glyph_string *h, struct glyph_string *t)
20531 if (h)
20533 if (*head)
20534 (*tail)->next = h;
20535 else
20536 *head = h;
20537 h->prev = *tail;
20538 *tail = t;
20543 /* Prepend the list of glyph strings with head H and tail T to the
20544 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
20545 result. */
20547 static INLINE void
20548 prepend_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
20549 struct glyph_string *h, struct glyph_string *t)
20551 if (h)
20553 if (*head)
20554 (*head)->prev = t;
20555 else
20556 *tail = t;
20557 t->next = *head;
20558 *head = h;
20563 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
20564 Set *HEAD and *TAIL to the resulting list. */
20566 static INLINE void
20567 append_glyph_string (struct glyph_string **head, struct glyph_string **tail,
20568 struct glyph_string *s)
20570 s->next = s->prev = NULL;
20571 append_glyph_string_lists (head, tail, s, s);
20575 /* Get face and two-byte form of character C in face FACE_ID on frame F.
20576 The encoding of C is returned in *CHAR2B. DISPLAY_P non-zero means
20577 make sure that X resources for the face returned are allocated.
20578 Value is a pointer to a realized face that is ready for display if
20579 DISPLAY_P is non-zero. */
20581 static INLINE struct face *
20582 get_char_face_and_encoding (struct frame *f, int c, int face_id,
20583 XChar2b *char2b, int display_p)
20585 struct face *face = FACE_FROM_ID (f, face_id);
20587 if (face->font)
20589 unsigned code = face->font->driver->encode_char (face->font, c);
20591 if (code != FONT_INVALID_CODE)
20592 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
20593 else
20594 STORE_XCHAR2B (char2b, 0, 0);
20597 /* Make sure X resources of the face are allocated. */
20598 #ifdef HAVE_X_WINDOWS
20599 if (display_p)
20600 #endif
20602 xassert (face != NULL);
20603 PREPARE_FACE_FOR_DISPLAY (f, face);
20606 return face;
20610 /* Get face and two-byte form of character glyph GLYPH on frame F.
20611 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
20612 a pointer to a realized face that is ready for display. */
20614 static INLINE struct face *
20615 get_glyph_face_and_encoding (struct frame *f, struct glyph *glyph,
20616 XChar2b *char2b, int *two_byte_p)
20618 struct face *face;
20620 xassert (glyph->type == CHAR_GLYPH);
20621 face = FACE_FROM_ID (f, glyph->face_id);
20623 if (two_byte_p)
20624 *two_byte_p = 0;
20626 if (face->font)
20628 unsigned code;
20630 if (CHAR_BYTE8_P (glyph->u.ch))
20631 code = CHAR_TO_BYTE8 (glyph->u.ch);
20632 else
20633 code = face->font->driver->encode_char (face->font, glyph->u.ch);
20635 if (code != FONT_INVALID_CODE)
20636 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
20637 else
20638 STORE_XCHAR2B (char2b, 0, 0);
20641 /* Make sure X resources of the face are allocated. */
20642 xassert (face != NULL);
20643 PREPARE_FACE_FOR_DISPLAY (f, face);
20644 return face;
20648 /* Get glyph code of character C in FONT in the two-byte form CHAR2B.
20649 Retunr 1 if FONT has a glyph for C, otherwise return 0. */
20651 static INLINE int
20652 get_char_glyph_code (int c, struct font *font, XChar2b *char2b)
20654 unsigned code;
20656 if (CHAR_BYTE8_P (c))
20657 code = CHAR_TO_BYTE8 (c);
20658 else
20659 code = font->driver->encode_char (font, c);
20661 if (code == FONT_INVALID_CODE)
20662 return 0;
20663 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
20664 return 1;
20668 /* Fill glyph string S with composition components specified by S->cmp.
20670 BASE_FACE is the base face of the composition.
20671 S->cmp_from is the index of the first component for S.
20673 OVERLAPS non-zero means S should draw the foreground only, and use
20674 its physical height for clipping. See also draw_glyphs.
20676 Value is the index of a component not in S. */
20678 static int
20679 fill_composite_glyph_string (struct glyph_string *s, struct face *base_face,
20680 int overlaps)
20682 int i;
20683 /* For all glyphs of this composition, starting at the offset
20684 S->cmp_from, until we reach the end of the definition or encounter a
20685 glyph that requires the different face, add it to S. */
20686 struct face *face;
20688 xassert (s);
20690 s->for_overlaps = overlaps;
20691 s->face = NULL;
20692 s->font = NULL;
20693 for (i = s->cmp_from; i < s->cmp->glyph_len; i++)
20695 int c = COMPOSITION_GLYPH (s->cmp, i);
20697 if (c != '\t')
20699 int face_id = FACE_FOR_CHAR (s->f, base_face->ascii_face, c,
20700 -1, Qnil);
20702 face = get_char_face_and_encoding (s->f, c, face_id,
20703 s->char2b + i, 1);
20704 if (face)
20706 if (! s->face)
20708 s->face = face;
20709 s->font = s->face->font;
20711 else if (s->face != face)
20712 break;
20715 ++s->nchars;
20717 s->cmp_to = i;
20719 /* All glyph strings for the same composition has the same width,
20720 i.e. the width set for the first component of the composition. */
20721 s->width = s->first_glyph->pixel_width;
20723 /* If the specified font could not be loaded, use the frame's
20724 default font, but record the fact that we couldn't load it in
20725 the glyph string so that we can draw rectangles for the
20726 characters of the glyph string. */
20727 if (s->font == NULL)
20729 s->font_not_found_p = 1;
20730 s->font = FRAME_FONT (s->f);
20733 /* Adjust base line for subscript/superscript text. */
20734 s->ybase += s->first_glyph->voffset;
20736 /* This glyph string must always be drawn with 16-bit functions. */
20737 s->two_byte_p = 1;
20739 return s->cmp_to;
20742 static int
20743 fill_gstring_glyph_string (struct glyph_string *s, int face_id,
20744 int start, int end, int overlaps)
20746 struct glyph *glyph, *last;
20747 Lisp_Object lgstring;
20748 int i;
20750 s->for_overlaps = overlaps;
20751 glyph = s->row->glyphs[s->area] + start;
20752 last = s->row->glyphs[s->area] + end;
20753 s->cmp_id = glyph->u.cmp.id;
20754 s->cmp_from = glyph->slice.cmp.from;
20755 s->cmp_to = glyph->slice.cmp.to + 1;
20756 s->face = FACE_FROM_ID (s->f, face_id);
20757 lgstring = composition_gstring_from_id (s->cmp_id);
20758 s->font = XFONT_OBJECT (LGSTRING_FONT (lgstring));
20759 glyph++;
20760 while (glyph < last
20761 && glyph->u.cmp.automatic
20762 && glyph->u.cmp.id == s->cmp_id
20763 && s->cmp_to == glyph->slice.cmp.from)
20764 s->cmp_to = (glyph++)->slice.cmp.to + 1;
20766 for (i = s->cmp_from; i < s->cmp_to; i++)
20768 Lisp_Object lglyph = LGSTRING_GLYPH (lgstring, i);
20769 unsigned code = LGLYPH_CODE (lglyph);
20771 STORE_XCHAR2B ((s->char2b + i), code >> 8, code & 0xFF);
20773 s->width = composition_gstring_width (lgstring, s->cmp_from, s->cmp_to, NULL);
20774 return glyph - s->row->glyphs[s->area];
20778 /* Fill glyph string S from a sequence glyphs for glyphless characters.
20779 See the comment of fill_glyph_string for arguments.
20780 Value is the index of the first glyph not in S. */
20783 static int
20784 fill_glyphless_glyph_string (struct glyph_string *s, int face_id,
20785 int start, int end, int overlaps)
20787 struct glyph *glyph, *last;
20788 int voffset;
20790 xassert (s->first_glyph->type == GLYPHLESS_GLYPH);
20791 s->for_overlaps = overlaps;
20792 glyph = s->row->glyphs[s->area] + start;
20793 last = s->row->glyphs[s->area] + end;
20794 voffset = glyph->voffset;
20795 s->face = FACE_FROM_ID (s->f, face_id);
20796 s->font = s->face->font;
20797 s->nchars = 1;
20798 s->width = glyph->pixel_width;
20799 glyph++;
20800 while (glyph < last
20801 && glyph->type == GLYPHLESS_GLYPH
20802 && glyph->voffset == voffset
20803 && glyph->face_id == face_id)
20805 s->nchars++;
20806 s->width += glyph->pixel_width;
20807 glyph++;
20809 s->ybase += voffset;
20810 return glyph - s->row->glyphs[s->area];
20814 /* Fill glyph string S from a sequence of character glyphs.
20816 FACE_ID is the face id of the string. START is the index of the
20817 first glyph to consider, END is the index of the last + 1.
20818 OVERLAPS non-zero means S should draw the foreground only, and use
20819 its physical height for clipping. See also draw_glyphs.
20821 Value is the index of the first glyph not in S. */
20823 static int
20824 fill_glyph_string (struct glyph_string *s, int face_id,
20825 int start, int end, int overlaps)
20827 struct glyph *glyph, *last;
20828 int voffset;
20829 int glyph_not_available_p;
20831 xassert (s->f == XFRAME (s->w->frame));
20832 xassert (s->nchars == 0);
20833 xassert (start >= 0 && end > start);
20835 s->for_overlaps = overlaps;
20836 glyph = s->row->glyphs[s->area] + start;
20837 last = s->row->glyphs[s->area] + end;
20838 voffset = glyph->voffset;
20839 s->padding_p = glyph->padding_p;
20840 glyph_not_available_p = glyph->glyph_not_available_p;
20842 while (glyph < last
20843 && glyph->type == CHAR_GLYPH
20844 && glyph->voffset == voffset
20845 /* Same face id implies same font, nowadays. */
20846 && glyph->face_id == face_id
20847 && glyph->glyph_not_available_p == glyph_not_available_p)
20849 int two_byte_p;
20851 s->face = get_glyph_face_and_encoding (s->f, glyph,
20852 s->char2b + s->nchars,
20853 &two_byte_p);
20854 s->two_byte_p = two_byte_p;
20855 ++s->nchars;
20856 xassert (s->nchars <= end - start);
20857 s->width += glyph->pixel_width;
20858 if (glyph++->padding_p != s->padding_p)
20859 break;
20862 s->font = s->face->font;
20864 /* If the specified font could not be loaded, use the frame's font,
20865 but record the fact that we couldn't load it in
20866 S->font_not_found_p so that we can draw rectangles for the
20867 characters of the glyph string. */
20868 if (s->font == NULL || glyph_not_available_p)
20870 s->font_not_found_p = 1;
20871 s->font = FRAME_FONT (s->f);
20874 /* Adjust base line for subscript/superscript text. */
20875 s->ybase += voffset;
20877 xassert (s->face && s->face->gc);
20878 return glyph - s->row->glyphs[s->area];
20882 /* Fill glyph string S from image glyph S->first_glyph. */
20884 static void
20885 fill_image_glyph_string (struct glyph_string *s)
20887 xassert (s->first_glyph->type == IMAGE_GLYPH);
20888 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
20889 xassert (s->img);
20890 s->slice = s->first_glyph->slice.img;
20891 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
20892 s->font = s->face->font;
20893 s->width = s->first_glyph->pixel_width;
20895 /* Adjust base line for subscript/superscript text. */
20896 s->ybase += s->first_glyph->voffset;
20900 /* Fill glyph string S from a sequence of stretch glyphs.
20902 START is the index of the first glyph to consider,
20903 END is the index of the last + 1.
20905 Value is the index of the first glyph not in S. */
20907 static int
20908 fill_stretch_glyph_string (struct glyph_string *s, int start, int end)
20910 struct glyph *glyph, *last;
20911 int voffset, face_id;
20913 xassert (s->first_glyph->type == STRETCH_GLYPH);
20915 glyph = s->row->glyphs[s->area] + start;
20916 last = s->row->glyphs[s->area] + end;
20917 face_id = glyph->face_id;
20918 s->face = FACE_FROM_ID (s->f, face_id);
20919 s->font = s->face->font;
20920 s->width = glyph->pixel_width;
20921 s->nchars = 1;
20922 voffset = glyph->voffset;
20924 for (++glyph;
20925 (glyph < last
20926 && glyph->type == STRETCH_GLYPH
20927 && glyph->voffset == voffset
20928 && glyph->face_id == face_id);
20929 ++glyph)
20930 s->width += glyph->pixel_width;
20932 /* Adjust base line for subscript/superscript text. */
20933 s->ybase += voffset;
20935 /* The case that face->gc == 0 is handled when drawing the glyph
20936 string by calling PREPARE_FACE_FOR_DISPLAY. */
20937 xassert (s->face);
20938 return glyph - s->row->glyphs[s->area];
20941 static struct font_metrics *
20942 get_per_char_metric (struct font *font, XChar2b *char2b)
20944 static struct font_metrics metrics;
20945 unsigned code = (XCHAR2B_BYTE1 (char2b) << 8) | XCHAR2B_BYTE2 (char2b);
20947 if (! font || code == FONT_INVALID_CODE)
20948 return NULL;
20949 font->driver->text_extents (font, &code, 1, &metrics);
20950 return &metrics;
20953 /* EXPORT for RIF:
20954 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
20955 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
20956 assumed to be zero. */
20958 void
20959 x_get_glyph_overhangs (struct glyph *glyph, struct frame *f, int *left, int *right)
20961 *left = *right = 0;
20963 if (glyph->type == CHAR_GLYPH)
20965 struct face *face;
20966 XChar2b char2b;
20967 struct font_metrics *pcm;
20969 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
20970 if (face->font && (pcm = get_per_char_metric (face->font, &char2b)))
20972 if (pcm->rbearing > pcm->width)
20973 *right = pcm->rbearing - pcm->width;
20974 if (pcm->lbearing < 0)
20975 *left = -pcm->lbearing;
20978 else if (glyph->type == COMPOSITE_GLYPH)
20980 if (! glyph->u.cmp.automatic)
20982 struct composition *cmp = composition_table[glyph->u.cmp.id];
20984 if (cmp->rbearing > cmp->pixel_width)
20985 *right = cmp->rbearing - cmp->pixel_width;
20986 if (cmp->lbearing < 0)
20987 *left = - cmp->lbearing;
20989 else
20991 Lisp_Object gstring = composition_gstring_from_id (glyph->u.cmp.id);
20992 struct font_metrics metrics;
20994 composition_gstring_width (gstring, glyph->slice.cmp.from,
20995 glyph->slice.cmp.to + 1, &metrics);
20996 if (metrics.rbearing > metrics.width)
20997 *right = metrics.rbearing - metrics.width;
20998 if (metrics.lbearing < 0)
20999 *left = - metrics.lbearing;
21005 /* Return the index of the first glyph preceding glyph string S that
21006 is overwritten by S because of S's left overhang. Value is -1
21007 if no glyphs are overwritten. */
21009 static int
21010 left_overwritten (struct glyph_string *s)
21012 int k;
21014 if (s->left_overhang)
21016 int x = 0, i;
21017 struct glyph *glyphs = s->row->glyphs[s->area];
21018 int first = s->first_glyph - glyphs;
21020 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
21021 x -= glyphs[i].pixel_width;
21023 k = i + 1;
21025 else
21026 k = -1;
21028 return k;
21032 /* Return the index of the first glyph preceding glyph string S that
21033 is overwriting S because of its right overhang. Value is -1 if no
21034 glyph in front of S overwrites S. */
21036 static int
21037 left_overwriting (struct glyph_string *s)
21039 int i, k, x;
21040 struct glyph *glyphs = s->row->glyphs[s->area];
21041 int first = s->first_glyph - glyphs;
21043 k = -1;
21044 x = 0;
21045 for (i = first - 1; i >= 0; --i)
21047 int left, right;
21048 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
21049 if (x + right > 0)
21050 k = i;
21051 x -= glyphs[i].pixel_width;
21054 return k;
21058 /* Return the index of the last glyph following glyph string S that is
21059 overwritten by S because of S's right overhang. Value is -1 if
21060 no such glyph is found. */
21062 static int
21063 right_overwritten (struct glyph_string *s)
21065 int k = -1;
21067 if (s->right_overhang)
21069 int x = 0, i;
21070 struct glyph *glyphs = s->row->glyphs[s->area];
21071 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
21072 int end = s->row->used[s->area];
21074 for (i = first; i < end && s->right_overhang > x; ++i)
21075 x += glyphs[i].pixel_width;
21077 k = i;
21080 return k;
21084 /* Return the index of the last glyph following glyph string S that
21085 overwrites S because of its left overhang. Value is negative
21086 if no such glyph is found. */
21088 static int
21089 right_overwriting (struct glyph_string *s)
21091 int i, k, x;
21092 int end = s->row->used[s->area];
21093 struct glyph *glyphs = s->row->glyphs[s->area];
21094 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
21096 k = -1;
21097 x = 0;
21098 for (i = first; i < end; ++i)
21100 int left, right;
21101 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
21102 if (x - left < 0)
21103 k = i;
21104 x += glyphs[i].pixel_width;
21107 return k;
21111 /* Set background width of glyph string S. START is the index of the
21112 first glyph following S. LAST_X is the right-most x-position + 1
21113 in the drawing area. */
21115 static INLINE void
21116 set_glyph_string_background_width (struct glyph_string *s, int start, int last_x)
21118 /* If the face of this glyph string has to be drawn to the end of
21119 the drawing area, set S->extends_to_end_of_line_p. */
21121 if (start == s->row->used[s->area]
21122 && s->area == TEXT_AREA
21123 && ((s->row->fill_line_p
21124 && (s->hl == DRAW_NORMAL_TEXT
21125 || s->hl == DRAW_IMAGE_RAISED
21126 || s->hl == DRAW_IMAGE_SUNKEN))
21127 || s->hl == DRAW_MOUSE_FACE))
21128 s->extends_to_end_of_line_p = 1;
21130 /* If S extends its face to the end of the line, set its
21131 background_width to the distance to the right edge of the drawing
21132 area. */
21133 if (s->extends_to_end_of_line_p)
21134 s->background_width = last_x - s->x + 1;
21135 else
21136 s->background_width = s->width;
21140 /* Compute overhangs and x-positions for glyph string S and its
21141 predecessors, or successors. X is the starting x-position for S.
21142 BACKWARD_P non-zero means process predecessors. */
21144 static void
21145 compute_overhangs_and_x (struct glyph_string *s, int x, int backward_p)
21147 if (backward_p)
21149 while (s)
21151 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
21152 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
21153 x -= s->width;
21154 s->x = x;
21155 s = s->prev;
21158 else
21160 while (s)
21162 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
21163 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
21164 s->x = x;
21165 x += s->width;
21166 s = s->next;
21173 /* The following macros are only called from draw_glyphs below.
21174 They reference the following parameters of that function directly:
21175 `w', `row', `area', and `overlap_p'
21176 as well as the following local variables:
21177 `s', `f', and `hdc' (in W32) */
21179 #ifdef HAVE_NTGUI
21180 /* On W32, silently add local `hdc' variable to argument list of
21181 init_glyph_string. */
21182 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
21183 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
21184 #else
21185 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
21186 init_glyph_string (s, char2b, w, row, area, start, hl)
21187 #endif
21189 /* Add a glyph string for a stretch glyph to the list of strings
21190 between HEAD and TAIL. START is the index of the stretch glyph in
21191 row area AREA of glyph row ROW. END is the index of the last glyph
21192 in that glyph row area. X is the current output position assigned
21193 to the new glyph string constructed. HL overrides that face of the
21194 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
21195 is the right-most x-position of the drawing area. */
21197 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
21198 and below -- keep them on one line. */
21199 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
21200 do \
21202 s = (struct glyph_string *) alloca (sizeof *s); \
21203 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
21204 START = fill_stretch_glyph_string (s, START, END); \
21205 append_glyph_string (&HEAD, &TAIL, s); \
21206 s->x = (X); \
21208 while (0)
21211 /* Add a glyph string for an image glyph to the list of strings
21212 between HEAD and TAIL. START is the index of the image glyph in
21213 row area AREA of glyph row ROW. END is the index of the last glyph
21214 in that glyph row area. X is the current output position assigned
21215 to the new glyph string constructed. HL overrides that face of the
21216 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
21217 is the right-most x-position of the drawing area. */
21219 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
21220 do \
21222 s = (struct glyph_string *) alloca (sizeof *s); \
21223 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
21224 fill_image_glyph_string (s); \
21225 append_glyph_string (&HEAD, &TAIL, s); \
21226 ++START; \
21227 s->x = (X); \
21229 while (0)
21232 /* Add a glyph string for a sequence of character glyphs to the list
21233 of strings between HEAD and TAIL. START is the index of the first
21234 glyph in row area AREA of glyph row ROW that is part of the new
21235 glyph string. END is the index of the last glyph in that glyph row
21236 area. X is the current output position assigned to the new glyph
21237 string constructed. HL overrides that face of the glyph; e.g. it
21238 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
21239 right-most x-position of the drawing area. */
21241 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
21242 do \
21244 int face_id; \
21245 XChar2b *char2b; \
21247 face_id = (row)->glyphs[area][START].face_id; \
21249 s = (struct glyph_string *) alloca (sizeof *s); \
21250 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
21251 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
21252 append_glyph_string (&HEAD, &TAIL, s); \
21253 s->x = (X); \
21254 START = fill_glyph_string (s, face_id, START, END, overlaps); \
21256 while (0)
21259 /* Add a glyph string for a composite sequence to the list of strings
21260 between HEAD and TAIL. START is the index of the first glyph in
21261 row area AREA of glyph row ROW that is part of the new glyph
21262 string. END is the index of the last glyph in that glyph row area.
21263 X is the current output position assigned to the new glyph string
21264 constructed. HL overrides that face of the glyph; e.g. it is
21265 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
21266 x-position of the drawing area. */
21268 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
21269 do { \
21270 int face_id = (row)->glyphs[area][START].face_id; \
21271 struct face *base_face = FACE_FROM_ID (f, face_id); \
21272 int cmp_id = (row)->glyphs[area][START].u.cmp.id; \
21273 struct composition *cmp = composition_table[cmp_id]; \
21274 XChar2b *char2b; \
21275 struct glyph_string *first_s IF_LINT (= NULL); \
21276 int n; \
21278 char2b = (XChar2b *) alloca ((sizeof *char2b) * cmp->glyph_len); \
21280 /* Make glyph_strings for each glyph sequence that is drawable by \
21281 the same face, and append them to HEAD/TAIL. */ \
21282 for (n = 0; n < cmp->glyph_len;) \
21284 s = (struct glyph_string *) alloca (sizeof *s); \
21285 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
21286 append_glyph_string (&(HEAD), &(TAIL), s); \
21287 s->cmp = cmp; \
21288 s->cmp_from = n; \
21289 s->x = (X); \
21290 if (n == 0) \
21291 first_s = s; \
21292 n = fill_composite_glyph_string (s, base_face, overlaps); \
21295 ++START; \
21296 s = first_s; \
21297 } while (0)
21300 /* Add a glyph string for a glyph-string sequence to the list of strings
21301 between HEAD and TAIL. */
21303 #define BUILD_GSTRING_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
21304 do { \
21305 int face_id; \
21306 XChar2b *char2b; \
21307 Lisp_Object gstring; \
21309 face_id = (row)->glyphs[area][START].face_id; \
21310 gstring = (composition_gstring_from_id \
21311 ((row)->glyphs[area][START].u.cmp.id)); \
21312 s = (struct glyph_string *) alloca (sizeof *s); \
21313 char2b = (XChar2b *) alloca ((sizeof *char2b) \
21314 * LGSTRING_GLYPH_LEN (gstring)); \
21315 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
21316 append_glyph_string (&(HEAD), &(TAIL), s); \
21317 s->x = (X); \
21318 START = fill_gstring_glyph_string (s, face_id, START, END, overlaps); \
21319 } while (0)
21322 /* Add a glyph string for a sequence of glyphless character's glyphs
21323 to the list of strings between HEAD and TAIL. The meanings of
21324 arguments are the same as those of BUILD_CHAR_GLYPH_STRINGS. */
21326 #define BUILD_GLYPHLESS_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
21327 do \
21329 int face_id; \
21331 face_id = (row)->glyphs[area][START].face_id; \
21333 s = (struct glyph_string *) alloca (sizeof *s); \
21334 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
21335 append_glyph_string (&HEAD, &TAIL, s); \
21336 s->x = (X); \
21337 START = fill_glyphless_glyph_string (s, face_id, START, END, \
21338 overlaps); \
21340 while (0)
21343 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
21344 of AREA of glyph row ROW on window W between indices START and END.
21345 HL overrides the face for drawing glyph strings, e.g. it is
21346 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
21347 x-positions of the drawing area.
21349 This is an ugly monster macro construct because we must use alloca
21350 to allocate glyph strings (because draw_glyphs can be called
21351 asynchronously). */
21353 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
21354 do \
21356 HEAD = TAIL = NULL; \
21357 while (START < END) \
21359 struct glyph *first_glyph = (row)->glyphs[area] + START; \
21360 switch (first_glyph->type) \
21362 case CHAR_GLYPH: \
21363 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
21364 HL, X, LAST_X); \
21365 break; \
21367 case COMPOSITE_GLYPH: \
21368 if (first_glyph->u.cmp.automatic) \
21369 BUILD_GSTRING_GLYPH_STRING (START, END, HEAD, TAIL, \
21370 HL, X, LAST_X); \
21371 else \
21372 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
21373 HL, X, LAST_X); \
21374 break; \
21376 case STRETCH_GLYPH: \
21377 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
21378 HL, X, LAST_X); \
21379 break; \
21381 case IMAGE_GLYPH: \
21382 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
21383 HL, X, LAST_X); \
21384 break; \
21386 case GLYPHLESS_GLYPH: \
21387 BUILD_GLYPHLESS_GLYPH_STRING (START, END, HEAD, TAIL, \
21388 HL, X, LAST_X); \
21389 break; \
21391 default: \
21392 abort (); \
21395 if (s) \
21397 set_glyph_string_background_width (s, START, LAST_X); \
21398 (X) += s->width; \
21401 } while (0)
21404 /* Draw glyphs between START and END in AREA of ROW on window W,
21405 starting at x-position X. X is relative to AREA in W. HL is a
21406 face-override with the following meaning:
21408 DRAW_NORMAL_TEXT draw normally
21409 DRAW_CURSOR draw in cursor face
21410 DRAW_MOUSE_FACE draw in mouse face.
21411 DRAW_INVERSE_VIDEO draw in mode line face
21412 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
21413 DRAW_IMAGE_RAISED draw an image with a raised relief around it
21415 If OVERLAPS is non-zero, draw only the foreground of characters and
21416 clip to the physical height of ROW. Non-zero value also defines
21417 the overlapping part to be drawn:
21419 OVERLAPS_PRED overlap with preceding rows
21420 OVERLAPS_SUCC overlap with succeeding rows
21421 OVERLAPS_BOTH overlap with both preceding/succeeding rows
21422 OVERLAPS_ERASED_CURSOR overlap with erased cursor area
21424 Value is the x-position reached, relative to AREA of W. */
21426 static int
21427 draw_glyphs (struct window *w, int x, struct glyph_row *row,
21428 enum glyph_row_area area, EMACS_INT start, EMACS_INT end,
21429 enum draw_glyphs_face hl, int overlaps)
21431 struct glyph_string *head, *tail;
21432 struct glyph_string *s;
21433 struct glyph_string *clip_head = NULL, *clip_tail = NULL;
21434 int i, j, x_reached, last_x, area_left = 0;
21435 struct frame *f = XFRAME (WINDOW_FRAME (w));
21436 DECLARE_HDC (hdc);
21438 ALLOCATE_HDC (hdc, f);
21440 /* Let's rather be paranoid than getting a SEGV. */
21441 end = min (end, row->used[area]);
21442 start = max (0, start);
21443 start = min (end, start);
21445 /* Translate X to frame coordinates. Set last_x to the right
21446 end of the drawing area. */
21447 if (row->full_width_p)
21449 /* X is relative to the left edge of W, without scroll bars
21450 or fringes. */
21451 area_left = WINDOW_LEFT_EDGE_X (w);
21452 last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
21454 else
21456 area_left = window_box_left (w, area);
21457 last_x = area_left + window_box_width (w, area);
21459 x += area_left;
21461 /* Build a doubly-linked list of glyph_string structures between
21462 head and tail from what we have to draw. Note that the macro
21463 BUILD_GLYPH_STRINGS will modify its start parameter. That's
21464 the reason we use a separate variable `i'. */
21465 i = start;
21466 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
21467 if (tail)
21468 x_reached = tail->x + tail->background_width;
21469 else
21470 x_reached = x;
21472 /* If there are any glyphs with lbearing < 0 or rbearing > width in
21473 the row, redraw some glyphs in front or following the glyph
21474 strings built above. */
21475 if (head && !overlaps && row->contains_overlapping_glyphs_p)
21477 struct glyph_string *h, *t;
21478 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
21479 int mouse_beg_col IF_LINT (= 0), mouse_end_col IF_LINT (= 0);
21480 int check_mouse_face = 0;
21481 int dummy_x = 0;
21483 /* If mouse highlighting is on, we may need to draw adjacent
21484 glyphs using mouse-face highlighting. */
21485 if (area == TEXT_AREA && row->mouse_face_p)
21487 struct glyph_row *mouse_beg_row, *mouse_end_row;
21489 mouse_beg_row = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_beg_row);
21490 mouse_end_row = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_end_row);
21492 if (row >= mouse_beg_row && row <= mouse_end_row)
21494 check_mouse_face = 1;
21495 mouse_beg_col = (row == mouse_beg_row)
21496 ? hlinfo->mouse_face_beg_col : 0;
21497 mouse_end_col = (row == mouse_end_row)
21498 ? hlinfo->mouse_face_end_col
21499 : row->used[TEXT_AREA];
21503 /* Compute overhangs for all glyph strings. */
21504 if (FRAME_RIF (f)->compute_glyph_string_overhangs)
21505 for (s = head; s; s = s->next)
21506 FRAME_RIF (f)->compute_glyph_string_overhangs (s);
21508 /* Prepend glyph strings for glyphs in front of the first glyph
21509 string that are overwritten because of the first glyph
21510 string's left overhang. The background of all strings
21511 prepended must be drawn because the first glyph string
21512 draws over it. */
21513 i = left_overwritten (head);
21514 if (i >= 0)
21516 enum draw_glyphs_face overlap_hl;
21518 /* If this row contains mouse highlighting, attempt to draw
21519 the overlapped glyphs with the correct highlight. This
21520 code fails if the overlap encompasses more than one glyph
21521 and mouse-highlight spans only some of these glyphs.
21522 However, making it work perfectly involves a lot more
21523 code, and I don't know if the pathological case occurs in
21524 practice, so we'll stick to this for now. --- cyd */
21525 if (check_mouse_face
21526 && mouse_beg_col < start && mouse_end_col > i)
21527 overlap_hl = DRAW_MOUSE_FACE;
21528 else
21529 overlap_hl = DRAW_NORMAL_TEXT;
21531 j = i;
21532 BUILD_GLYPH_STRINGS (j, start, h, t,
21533 overlap_hl, dummy_x, last_x);
21534 start = i;
21535 compute_overhangs_and_x (t, head->x, 1);
21536 prepend_glyph_string_lists (&head, &tail, h, t);
21537 clip_head = head;
21540 /* Prepend glyph strings for glyphs in front of the first glyph
21541 string that overwrite that glyph string because of their
21542 right overhang. For these strings, only the foreground must
21543 be drawn, because it draws over the glyph string at `head'.
21544 The background must not be drawn because this would overwrite
21545 right overhangs of preceding glyphs for which no glyph
21546 strings exist. */
21547 i = left_overwriting (head);
21548 if (i >= 0)
21550 enum draw_glyphs_face overlap_hl;
21552 if (check_mouse_face
21553 && mouse_beg_col < start && mouse_end_col > i)
21554 overlap_hl = DRAW_MOUSE_FACE;
21555 else
21556 overlap_hl = DRAW_NORMAL_TEXT;
21558 clip_head = head;
21559 BUILD_GLYPH_STRINGS (i, start, h, t,
21560 overlap_hl, dummy_x, last_x);
21561 for (s = h; s; s = s->next)
21562 s->background_filled_p = 1;
21563 compute_overhangs_and_x (t, head->x, 1);
21564 prepend_glyph_string_lists (&head, &tail, h, t);
21567 /* Append glyphs strings for glyphs following the last glyph
21568 string tail that are overwritten by tail. The background of
21569 these strings has to be drawn because tail's foreground draws
21570 over it. */
21571 i = right_overwritten (tail);
21572 if (i >= 0)
21574 enum draw_glyphs_face overlap_hl;
21576 if (check_mouse_face
21577 && mouse_beg_col < i && mouse_end_col > end)
21578 overlap_hl = DRAW_MOUSE_FACE;
21579 else
21580 overlap_hl = DRAW_NORMAL_TEXT;
21582 BUILD_GLYPH_STRINGS (end, i, h, t,
21583 overlap_hl, x, last_x);
21584 /* Because BUILD_GLYPH_STRINGS updates the first argument,
21585 we don't have `end = i;' here. */
21586 compute_overhangs_and_x (h, tail->x + tail->width, 0);
21587 append_glyph_string_lists (&head, &tail, h, t);
21588 clip_tail = tail;
21591 /* Append glyph strings for glyphs following the last glyph
21592 string tail that overwrite tail. The foreground of such
21593 glyphs has to be drawn because it writes into the background
21594 of tail. The background must not be drawn because it could
21595 paint over the foreground of following glyphs. */
21596 i = right_overwriting (tail);
21597 if (i >= 0)
21599 enum draw_glyphs_face overlap_hl;
21600 if (check_mouse_face
21601 && mouse_beg_col < i && mouse_end_col > end)
21602 overlap_hl = DRAW_MOUSE_FACE;
21603 else
21604 overlap_hl = DRAW_NORMAL_TEXT;
21606 clip_tail = tail;
21607 i++; /* We must include the Ith glyph. */
21608 BUILD_GLYPH_STRINGS (end, i, h, t,
21609 overlap_hl, x, last_x);
21610 for (s = h; s; s = s->next)
21611 s->background_filled_p = 1;
21612 compute_overhangs_and_x (h, tail->x + tail->width, 0);
21613 append_glyph_string_lists (&head, &tail, h, t);
21615 if (clip_head || clip_tail)
21616 for (s = head; s; s = s->next)
21618 s->clip_head = clip_head;
21619 s->clip_tail = clip_tail;
21623 /* Draw all strings. */
21624 for (s = head; s; s = s->next)
21625 FRAME_RIF (f)->draw_glyph_string (s);
21627 #ifndef HAVE_NS
21628 /* When focus a sole frame and move horizontally, this sets on_p to 0
21629 causing a failure to erase prev cursor position. */
21630 if (area == TEXT_AREA
21631 && !row->full_width_p
21632 /* When drawing overlapping rows, only the glyph strings'
21633 foreground is drawn, which doesn't erase a cursor
21634 completely. */
21635 && !overlaps)
21637 int x0 = clip_head ? clip_head->x : (head ? head->x : x);
21638 int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width
21639 : (tail ? tail->x + tail->background_width : x));
21640 x0 -= area_left;
21641 x1 -= area_left;
21643 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
21644 row->y, MATRIX_ROW_BOTTOM_Y (row));
21646 #endif
21648 /* Value is the x-position up to which drawn, relative to AREA of W.
21649 This doesn't include parts drawn because of overhangs. */
21650 if (row->full_width_p)
21651 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
21652 else
21653 x_reached -= area_left;
21655 RELEASE_HDC (hdc, f);
21657 return x_reached;
21660 /* Expand row matrix if too narrow. Don't expand if area
21661 is not present. */
21663 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
21665 if (!fonts_changed_p \
21666 && (it->glyph_row->glyphs[area] \
21667 < it->glyph_row->glyphs[area + 1])) \
21669 it->w->ncols_scale_factor++; \
21670 fonts_changed_p = 1; \
21674 /* Store one glyph for IT->char_to_display in IT->glyph_row.
21675 Called from x_produce_glyphs when IT->glyph_row is non-null. */
21677 static INLINE void
21678 append_glyph (struct it *it)
21680 struct glyph *glyph;
21681 enum glyph_row_area area = it->area;
21683 xassert (it->glyph_row);
21684 xassert (it->char_to_display != '\n' && it->char_to_display != '\t');
21686 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
21687 if (glyph < it->glyph_row->glyphs[area + 1])
21689 /* If the glyph row is reversed, we need to prepend the glyph
21690 rather than append it. */
21691 if (it->glyph_row->reversed_p && area == TEXT_AREA)
21693 struct glyph *g;
21695 /* Make room for the additional glyph. */
21696 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
21697 g[1] = *g;
21698 glyph = it->glyph_row->glyphs[area];
21700 glyph->charpos = CHARPOS (it->position);
21701 glyph->object = it->object;
21702 if (it->pixel_width > 0)
21704 glyph->pixel_width = it->pixel_width;
21705 glyph->padding_p = 0;
21707 else
21709 /* Assure at least 1-pixel width. Otherwise, cursor can't
21710 be displayed correctly. */
21711 glyph->pixel_width = 1;
21712 glyph->padding_p = 1;
21714 glyph->ascent = it->ascent;
21715 glyph->descent = it->descent;
21716 glyph->voffset = it->voffset;
21717 glyph->type = CHAR_GLYPH;
21718 glyph->avoid_cursor_p = it->avoid_cursor_p;
21719 glyph->multibyte_p = it->multibyte_p;
21720 glyph->left_box_line_p = it->start_of_box_run_p;
21721 glyph->right_box_line_p = it->end_of_box_run_p;
21722 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
21723 || it->phys_descent > it->descent);
21724 glyph->glyph_not_available_p = it->glyph_not_available_p;
21725 glyph->face_id = it->face_id;
21726 glyph->u.ch = it->char_to_display;
21727 glyph->slice.img = null_glyph_slice;
21728 glyph->font_type = FONT_TYPE_UNKNOWN;
21729 if (it->bidi_p)
21731 glyph->resolved_level = it->bidi_it.resolved_level;
21732 if ((it->bidi_it.type & 7) != it->bidi_it.type)
21733 abort ();
21734 glyph->bidi_type = it->bidi_it.type;
21736 else
21738 glyph->resolved_level = 0;
21739 glyph->bidi_type = UNKNOWN_BT;
21741 ++it->glyph_row->used[area];
21743 else
21744 IT_EXPAND_MATRIX_WIDTH (it, area);
21747 /* Store one glyph for the composition IT->cmp_it.id in
21748 IT->glyph_row. Called from x_produce_glyphs when IT->glyph_row is
21749 non-null. */
21751 static INLINE void
21752 append_composite_glyph (struct it *it)
21754 struct glyph *glyph;
21755 enum glyph_row_area area = it->area;
21757 xassert (it->glyph_row);
21759 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
21760 if (glyph < it->glyph_row->glyphs[area + 1])
21762 /* If the glyph row is reversed, we need to prepend the glyph
21763 rather than append it. */
21764 if (it->glyph_row->reversed_p && it->area == TEXT_AREA)
21766 struct glyph *g;
21768 /* Make room for the new glyph. */
21769 for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
21770 g[1] = *g;
21771 glyph = it->glyph_row->glyphs[it->area];
21773 glyph->charpos = it->cmp_it.charpos;
21774 glyph->object = it->object;
21775 glyph->pixel_width = it->pixel_width;
21776 glyph->ascent = it->ascent;
21777 glyph->descent = it->descent;
21778 glyph->voffset = it->voffset;
21779 glyph->type = COMPOSITE_GLYPH;
21780 if (it->cmp_it.ch < 0)
21782 glyph->u.cmp.automatic = 0;
21783 glyph->u.cmp.id = it->cmp_it.id;
21784 glyph->slice.cmp.from = glyph->slice.cmp.to = 0;
21786 else
21788 glyph->u.cmp.automatic = 1;
21789 glyph->u.cmp.id = it->cmp_it.id;
21790 glyph->slice.cmp.from = it->cmp_it.from;
21791 glyph->slice.cmp.to = it->cmp_it.to - 1;
21793 glyph->avoid_cursor_p = it->avoid_cursor_p;
21794 glyph->multibyte_p = it->multibyte_p;
21795 glyph->left_box_line_p = it->start_of_box_run_p;
21796 glyph->right_box_line_p = it->end_of_box_run_p;
21797 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
21798 || it->phys_descent > it->descent);
21799 glyph->padding_p = 0;
21800 glyph->glyph_not_available_p = 0;
21801 glyph->face_id = it->face_id;
21802 glyph->font_type = FONT_TYPE_UNKNOWN;
21803 if (it->bidi_p)
21805 glyph->resolved_level = it->bidi_it.resolved_level;
21806 if ((it->bidi_it.type & 7) != it->bidi_it.type)
21807 abort ();
21808 glyph->bidi_type = it->bidi_it.type;
21810 ++it->glyph_row->used[area];
21812 else
21813 IT_EXPAND_MATRIX_WIDTH (it, area);
21817 /* Change IT->ascent and IT->height according to the setting of
21818 IT->voffset. */
21820 static INLINE void
21821 take_vertical_position_into_account (struct it *it)
21823 if (it->voffset)
21825 if (it->voffset < 0)
21826 /* Increase the ascent so that we can display the text higher
21827 in the line. */
21828 it->ascent -= it->voffset;
21829 else
21830 /* Increase the descent so that we can display the text lower
21831 in the line. */
21832 it->descent += it->voffset;
21837 /* Produce glyphs/get display metrics for the image IT is loaded with.
21838 See the description of struct display_iterator in dispextern.h for
21839 an overview of struct display_iterator. */
21841 static void
21842 produce_image_glyph (struct it *it)
21844 struct image *img;
21845 struct face *face;
21846 int glyph_ascent, crop;
21847 struct glyph_slice slice;
21849 xassert (it->what == IT_IMAGE);
21851 face = FACE_FROM_ID (it->f, it->face_id);
21852 xassert (face);
21853 /* Make sure X resources of the face is loaded. */
21854 PREPARE_FACE_FOR_DISPLAY (it->f, face);
21856 if (it->image_id < 0)
21858 /* Fringe bitmap. */
21859 it->ascent = it->phys_ascent = 0;
21860 it->descent = it->phys_descent = 0;
21861 it->pixel_width = 0;
21862 it->nglyphs = 0;
21863 return;
21866 img = IMAGE_FROM_ID (it->f, it->image_id);
21867 xassert (img);
21868 /* Make sure X resources of the image is loaded. */
21869 prepare_image_for_display (it->f, img);
21871 slice.x = slice.y = 0;
21872 slice.width = img->width;
21873 slice.height = img->height;
21875 if (INTEGERP (it->slice.x))
21876 slice.x = XINT (it->slice.x);
21877 else if (FLOATP (it->slice.x))
21878 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
21880 if (INTEGERP (it->slice.y))
21881 slice.y = XINT (it->slice.y);
21882 else if (FLOATP (it->slice.y))
21883 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
21885 if (INTEGERP (it->slice.width))
21886 slice.width = XINT (it->slice.width);
21887 else if (FLOATP (it->slice.width))
21888 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
21890 if (INTEGERP (it->slice.height))
21891 slice.height = XINT (it->slice.height);
21892 else if (FLOATP (it->slice.height))
21893 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
21895 if (slice.x >= img->width)
21896 slice.x = img->width;
21897 if (slice.y >= img->height)
21898 slice.y = img->height;
21899 if (slice.x + slice.width >= img->width)
21900 slice.width = img->width - slice.x;
21901 if (slice.y + slice.height > img->height)
21902 slice.height = img->height - slice.y;
21904 if (slice.width == 0 || slice.height == 0)
21905 return;
21907 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
21909 it->descent = slice.height - glyph_ascent;
21910 if (slice.y == 0)
21911 it->descent += img->vmargin;
21912 if (slice.y + slice.height == img->height)
21913 it->descent += img->vmargin;
21914 it->phys_descent = it->descent;
21916 it->pixel_width = slice.width;
21917 if (slice.x == 0)
21918 it->pixel_width += img->hmargin;
21919 if (slice.x + slice.width == img->width)
21920 it->pixel_width += img->hmargin;
21922 /* It's quite possible for images to have an ascent greater than
21923 their height, so don't get confused in that case. */
21924 if (it->descent < 0)
21925 it->descent = 0;
21927 it->nglyphs = 1;
21929 if (face->box != FACE_NO_BOX)
21931 if (face->box_line_width > 0)
21933 if (slice.y == 0)
21934 it->ascent += face->box_line_width;
21935 if (slice.y + slice.height == img->height)
21936 it->descent += face->box_line_width;
21939 if (it->start_of_box_run_p && slice.x == 0)
21940 it->pixel_width += eabs (face->box_line_width);
21941 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
21942 it->pixel_width += eabs (face->box_line_width);
21945 take_vertical_position_into_account (it);
21947 /* Automatically crop wide image glyphs at right edge so we can
21948 draw the cursor on same display row. */
21949 if ((crop = it->pixel_width - (it->last_visible_x - it->current_x), crop > 0)
21950 && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
21952 it->pixel_width -= crop;
21953 slice.width -= crop;
21956 if (it->glyph_row)
21958 struct glyph *glyph;
21959 enum glyph_row_area area = it->area;
21961 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
21962 if (glyph < it->glyph_row->glyphs[area + 1])
21964 glyph->charpos = CHARPOS (it->position);
21965 glyph->object = it->object;
21966 glyph->pixel_width = it->pixel_width;
21967 glyph->ascent = glyph_ascent;
21968 glyph->descent = it->descent;
21969 glyph->voffset = it->voffset;
21970 glyph->type = IMAGE_GLYPH;
21971 glyph->avoid_cursor_p = it->avoid_cursor_p;
21972 glyph->multibyte_p = it->multibyte_p;
21973 glyph->left_box_line_p = it->start_of_box_run_p;
21974 glyph->right_box_line_p = it->end_of_box_run_p;
21975 glyph->overlaps_vertically_p = 0;
21976 glyph->padding_p = 0;
21977 glyph->glyph_not_available_p = 0;
21978 glyph->face_id = it->face_id;
21979 glyph->u.img_id = img->id;
21980 glyph->slice.img = slice;
21981 glyph->font_type = FONT_TYPE_UNKNOWN;
21982 if (it->bidi_p)
21984 glyph->resolved_level = it->bidi_it.resolved_level;
21985 if ((it->bidi_it.type & 7) != it->bidi_it.type)
21986 abort ();
21987 glyph->bidi_type = it->bidi_it.type;
21989 ++it->glyph_row->used[area];
21991 else
21992 IT_EXPAND_MATRIX_WIDTH (it, area);
21997 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
21998 of the glyph, WIDTH and HEIGHT are the width and height of the
21999 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
22001 static void
22002 append_stretch_glyph (struct it *it, Lisp_Object object,
22003 int width, int height, int ascent)
22005 struct glyph *glyph;
22006 enum glyph_row_area area = it->area;
22008 xassert (ascent >= 0 && ascent <= height);
22010 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
22011 if (glyph < it->glyph_row->glyphs[area + 1])
22013 /* If the glyph row is reversed, we need to prepend the glyph
22014 rather than append it. */
22015 if (it->glyph_row->reversed_p && area == TEXT_AREA)
22017 struct glyph *g;
22019 /* Make room for the additional glyph. */
22020 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
22021 g[1] = *g;
22022 glyph = it->glyph_row->glyphs[area];
22024 glyph->charpos = CHARPOS (it->position);
22025 glyph->object = object;
22026 glyph->pixel_width = width;
22027 glyph->ascent = ascent;
22028 glyph->descent = height - ascent;
22029 glyph->voffset = it->voffset;
22030 glyph->type = STRETCH_GLYPH;
22031 glyph->avoid_cursor_p = it->avoid_cursor_p;
22032 glyph->multibyte_p = it->multibyte_p;
22033 glyph->left_box_line_p = it->start_of_box_run_p;
22034 glyph->right_box_line_p = it->end_of_box_run_p;
22035 glyph->overlaps_vertically_p = 0;
22036 glyph->padding_p = 0;
22037 glyph->glyph_not_available_p = 0;
22038 glyph->face_id = it->face_id;
22039 glyph->u.stretch.ascent = ascent;
22040 glyph->u.stretch.height = height;
22041 glyph->slice.img = null_glyph_slice;
22042 glyph->font_type = FONT_TYPE_UNKNOWN;
22043 if (it->bidi_p)
22045 glyph->resolved_level = it->bidi_it.resolved_level;
22046 if ((it->bidi_it.type & 7) != it->bidi_it.type)
22047 abort ();
22048 glyph->bidi_type = it->bidi_it.type;
22050 else
22052 glyph->resolved_level = 0;
22053 glyph->bidi_type = UNKNOWN_BT;
22055 ++it->glyph_row->used[area];
22057 else
22058 IT_EXPAND_MATRIX_WIDTH (it, area);
22062 /* Produce a stretch glyph for iterator IT. IT->object is the value
22063 of the glyph property displayed. The value must be a list
22064 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
22065 being recognized:
22067 1. `:width WIDTH' specifies that the space should be WIDTH *
22068 canonical char width wide. WIDTH may be an integer or floating
22069 point number.
22071 2. `:relative-width FACTOR' specifies that the width of the stretch
22072 should be computed from the width of the first character having the
22073 `glyph' property, and should be FACTOR times that width.
22075 3. `:align-to HPOS' specifies that the space should be wide enough
22076 to reach HPOS, a value in canonical character units.
22078 Exactly one of the above pairs must be present.
22080 4. `:height HEIGHT' specifies that the height of the stretch produced
22081 should be HEIGHT, measured in canonical character units.
22083 5. `:relative-height FACTOR' specifies that the height of the
22084 stretch should be FACTOR times the height of the characters having
22085 the glyph property.
22087 Either none or exactly one of 4 or 5 must be present.
22089 6. `:ascent ASCENT' specifies that ASCENT percent of the height
22090 of the stretch should be used for the ascent of the stretch.
22091 ASCENT must be in the range 0 <= ASCENT <= 100. */
22093 static void
22094 produce_stretch_glyph (struct it *it)
22096 /* (space :width WIDTH :height HEIGHT ...) */
22097 Lisp_Object prop, plist;
22098 int width = 0, height = 0, align_to = -1;
22099 int zero_width_ok_p = 0, zero_height_ok_p = 0;
22100 int ascent = 0;
22101 double tem;
22102 struct face *face = FACE_FROM_ID (it->f, it->face_id);
22103 struct font *font = face->font ? face->font : FRAME_FONT (it->f);
22105 PREPARE_FACE_FOR_DISPLAY (it->f, face);
22107 /* List should start with `space'. */
22108 xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
22109 plist = XCDR (it->object);
22111 /* Compute the width of the stretch. */
22112 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
22113 && calc_pixel_width_or_height (&tem, it, prop, font, 1, 0))
22115 /* Absolute width `:width WIDTH' specified and valid. */
22116 zero_width_ok_p = 1;
22117 width = (int)tem;
22119 else if (prop = Fplist_get (plist, QCrelative_width),
22120 NUMVAL (prop) > 0)
22122 /* Relative width `:relative-width FACTOR' specified and valid.
22123 Compute the width of the characters having the `glyph'
22124 property. */
22125 struct it it2;
22126 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
22128 it2 = *it;
22129 if (it->multibyte_p)
22130 it2.c = it2.char_to_display = STRING_CHAR_AND_LENGTH (p, it2.len);
22131 else
22133 it2.c = it2.char_to_display = *p, it2.len = 1;
22134 if (! ASCII_CHAR_P (it2.c))
22135 it2.char_to_display = BYTE8_TO_CHAR (it2.c);
22138 it2.glyph_row = NULL;
22139 it2.what = IT_CHARACTER;
22140 x_produce_glyphs (&it2);
22141 width = NUMVAL (prop) * it2.pixel_width;
22143 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
22144 && calc_pixel_width_or_height (&tem, it, prop, font, 1, &align_to))
22146 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
22147 align_to = (align_to < 0
22149 : align_to - window_box_left_offset (it->w, TEXT_AREA));
22150 else if (align_to < 0)
22151 align_to = window_box_left_offset (it->w, TEXT_AREA);
22152 width = max (0, (int)tem + align_to - it->current_x);
22153 zero_width_ok_p = 1;
22155 else
22156 /* Nothing specified -> width defaults to canonical char width. */
22157 width = FRAME_COLUMN_WIDTH (it->f);
22159 if (width <= 0 && (width < 0 || !zero_width_ok_p))
22160 width = 1;
22162 /* Compute height. */
22163 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
22164 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
22166 height = (int)tem;
22167 zero_height_ok_p = 1;
22169 else if (prop = Fplist_get (plist, QCrelative_height),
22170 NUMVAL (prop) > 0)
22171 height = FONT_HEIGHT (font) * NUMVAL (prop);
22172 else
22173 height = FONT_HEIGHT (font);
22175 if (height <= 0 && (height < 0 || !zero_height_ok_p))
22176 height = 1;
22178 /* Compute percentage of height used for ascent. If
22179 `:ascent ASCENT' is present and valid, use that. Otherwise,
22180 derive the ascent from the font in use. */
22181 if (prop = Fplist_get (plist, QCascent),
22182 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
22183 ascent = height * NUMVAL (prop) / 100.0;
22184 else if (!NILP (prop)
22185 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
22186 ascent = min (max (0, (int)tem), height);
22187 else
22188 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
22190 if (width > 0 && it->line_wrap != TRUNCATE
22191 && it->current_x + width > it->last_visible_x)
22192 width = it->last_visible_x - it->current_x - 1;
22194 if (width > 0 && height > 0 && it->glyph_row)
22196 Lisp_Object object = it->stack[it->sp - 1].string;
22197 if (!STRINGP (object))
22198 object = it->w->buffer;
22199 append_stretch_glyph (it, object, width, height, ascent);
22202 it->pixel_width = width;
22203 it->ascent = it->phys_ascent = ascent;
22204 it->descent = it->phys_descent = height - it->ascent;
22205 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
22207 take_vertical_position_into_account (it);
22210 /* Calculate line-height and line-spacing properties.
22211 An integer value specifies explicit pixel value.
22212 A float value specifies relative value to current face height.
22213 A cons (float . face-name) specifies relative value to
22214 height of specified face font.
22216 Returns height in pixels, or nil. */
22219 static Lisp_Object
22220 calc_line_height_property (struct it *it, Lisp_Object val, struct font *font,
22221 int boff, int override)
22223 Lisp_Object face_name = Qnil;
22224 int ascent, descent, height;
22226 if (NILP (val) || INTEGERP (val) || (override && EQ (val, Qt)))
22227 return val;
22229 if (CONSP (val))
22231 face_name = XCAR (val);
22232 val = XCDR (val);
22233 if (!NUMBERP (val))
22234 val = make_number (1);
22235 if (NILP (face_name))
22237 height = it->ascent + it->descent;
22238 goto scale;
22242 if (NILP (face_name))
22244 font = FRAME_FONT (it->f);
22245 boff = FRAME_BASELINE_OFFSET (it->f);
22247 else if (EQ (face_name, Qt))
22249 override = 0;
22251 else
22253 int face_id;
22254 struct face *face;
22256 face_id = lookup_named_face (it->f, face_name, 0);
22257 if (face_id < 0)
22258 return make_number (-1);
22260 face = FACE_FROM_ID (it->f, face_id);
22261 font = face->font;
22262 if (font == NULL)
22263 return make_number (-1);
22264 boff = font->baseline_offset;
22265 if (font->vertical_centering)
22266 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
22269 ascent = FONT_BASE (font) + boff;
22270 descent = FONT_DESCENT (font) - boff;
22272 if (override)
22274 it->override_ascent = ascent;
22275 it->override_descent = descent;
22276 it->override_boff = boff;
22279 height = ascent + descent;
22281 scale:
22282 if (FLOATP (val))
22283 height = (int)(XFLOAT_DATA (val) * height);
22284 else if (INTEGERP (val))
22285 height *= XINT (val);
22287 return make_number (height);
22291 /* Append a glyph for a glyphless character to IT->glyph_row. FACE_ID
22292 is a face ID to be used for the glyph. FOR_NO_FONT is nonzero if
22293 and only if this is for a character for which no font was found.
22295 If the display method (it->glyphless_method) is
22296 GLYPHLESS_DISPLAY_ACRONYM or GLYPHLESS_DISPLAY_HEX_CODE, LEN is a
22297 length of the acronym or the hexadecimal string, UPPER_XOFF and
22298 UPPER_YOFF are pixel offsets for the upper part of the string,
22299 LOWER_XOFF and LOWER_YOFF are for the lower part.
22301 For the other display methods, LEN through LOWER_YOFF are zero. */
22303 static void
22304 append_glyphless_glyph (struct it *it, int face_id, int for_no_font, int len,
22305 short upper_xoff, short upper_yoff,
22306 short lower_xoff, short lower_yoff)
22308 struct glyph *glyph;
22309 enum glyph_row_area area = it->area;
22311 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
22312 if (glyph < it->glyph_row->glyphs[area + 1])
22314 /* If the glyph row is reversed, we need to prepend the glyph
22315 rather than append it. */
22316 if (it->glyph_row->reversed_p && area == TEXT_AREA)
22318 struct glyph *g;
22320 /* Make room for the additional glyph. */
22321 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
22322 g[1] = *g;
22323 glyph = it->glyph_row->glyphs[area];
22325 glyph->charpos = CHARPOS (it->position);
22326 glyph->object = it->object;
22327 glyph->pixel_width = it->pixel_width;
22328 glyph->ascent = it->ascent;
22329 glyph->descent = it->descent;
22330 glyph->voffset = it->voffset;
22331 glyph->type = GLYPHLESS_GLYPH;
22332 glyph->u.glyphless.method = it->glyphless_method;
22333 glyph->u.glyphless.for_no_font = for_no_font;
22334 glyph->u.glyphless.len = len;
22335 glyph->u.glyphless.ch = it->c;
22336 glyph->slice.glyphless.upper_xoff = upper_xoff;
22337 glyph->slice.glyphless.upper_yoff = upper_yoff;
22338 glyph->slice.glyphless.lower_xoff = lower_xoff;
22339 glyph->slice.glyphless.lower_yoff = lower_yoff;
22340 glyph->avoid_cursor_p = it->avoid_cursor_p;
22341 glyph->multibyte_p = it->multibyte_p;
22342 glyph->left_box_line_p = it->start_of_box_run_p;
22343 glyph->right_box_line_p = it->end_of_box_run_p;
22344 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
22345 || it->phys_descent > it->descent);
22346 glyph->padding_p = 0;
22347 glyph->glyph_not_available_p = 0;
22348 glyph->face_id = face_id;
22349 glyph->font_type = FONT_TYPE_UNKNOWN;
22350 if (it->bidi_p)
22352 glyph->resolved_level = it->bidi_it.resolved_level;
22353 if ((it->bidi_it.type & 7) != it->bidi_it.type)
22354 abort ();
22355 glyph->bidi_type = it->bidi_it.type;
22357 ++it->glyph_row->used[area];
22359 else
22360 IT_EXPAND_MATRIX_WIDTH (it, area);
22364 /* Produce a glyph for a glyphless character for iterator IT.
22365 IT->glyphless_method specifies which method to use for displaying
22366 the character. See the description of enum
22367 glyphless_display_method in dispextern.h for the detail.
22369 FOR_NO_FONT is nonzero if and only if this is for a character for
22370 which no font was found. ACRONYM, if non-nil, is an acronym string
22371 for the character. */
22373 static void
22374 produce_glyphless_glyph (struct it *it, int for_no_font, Lisp_Object acronym)
22376 int face_id;
22377 struct face *face;
22378 struct font *font;
22379 int base_width, base_height, width, height;
22380 short upper_xoff, upper_yoff, lower_xoff, lower_yoff;
22381 int len;
22383 /* Get the metrics of the base font. We always refer to the current
22384 ASCII face. */
22385 face = FACE_FROM_ID (it->f, it->face_id)->ascii_face;
22386 font = face->font ? face->font : FRAME_FONT (it->f);
22387 it->ascent = FONT_BASE (font) + font->baseline_offset;
22388 it->descent = FONT_DESCENT (font) - font->baseline_offset;
22389 base_height = it->ascent + it->descent;
22390 base_width = font->average_width;
22392 /* Get a face ID for the glyph by utilizing a cache (the same way as
22393 doen for `escape-glyph' in get_next_display_element). */
22394 if (it->f == last_glyphless_glyph_frame
22395 && it->face_id == last_glyphless_glyph_face_id)
22397 face_id = last_glyphless_glyph_merged_face_id;
22399 else
22401 /* Merge the `glyphless-char' face into the current face. */
22402 face_id = merge_faces (it->f, Qglyphless_char, 0, it->face_id);
22403 last_glyphless_glyph_frame = it->f;
22404 last_glyphless_glyph_face_id = it->face_id;
22405 last_glyphless_glyph_merged_face_id = face_id;
22408 if (it->glyphless_method == GLYPHLESS_DISPLAY_THIN_SPACE)
22410 it->pixel_width = THIN_SPACE_WIDTH;
22411 len = 0;
22412 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
22414 else if (it->glyphless_method == GLYPHLESS_DISPLAY_EMPTY_BOX)
22416 width = CHAR_WIDTH (it->c);
22417 if (width == 0)
22418 width = 1;
22419 else if (width > 4)
22420 width = 4;
22421 it->pixel_width = base_width * width;
22422 len = 0;
22423 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
22425 else
22427 char buf[7];
22428 const char *str;
22429 unsigned int code[6];
22430 int upper_len;
22431 int ascent, descent;
22432 struct font_metrics metrics_upper, metrics_lower;
22434 face = FACE_FROM_ID (it->f, face_id);
22435 font = face->font ? face->font : FRAME_FONT (it->f);
22436 PREPARE_FACE_FOR_DISPLAY (it->f, face);
22438 if (it->glyphless_method == GLYPHLESS_DISPLAY_ACRONYM)
22440 if (! STRINGP (acronym) && CHAR_TABLE_P (Vglyphless_char_display))
22441 acronym = CHAR_TABLE_REF (Vglyphless_char_display, it->c);
22442 if (CONSP (acronym))
22443 acronym = XCAR (acronym);
22444 str = STRINGP (acronym) ? SSDATA (acronym) : "";
22446 else
22448 xassert (it->glyphless_method == GLYPHLESS_DISPLAY_HEX_CODE);
22449 sprintf (buf, "%0*X", it->c < 0x10000 ? 4 : 6, it->c);
22450 str = buf;
22452 for (len = 0; str[len] && ASCII_BYTE_P (str[len]); len++)
22453 code[len] = font->driver->encode_char (font, str[len]);
22454 upper_len = (len + 1) / 2;
22455 font->driver->text_extents (font, code, upper_len,
22456 &metrics_upper);
22457 font->driver->text_extents (font, code + upper_len, len - upper_len,
22458 &metrics_lower);
22462 /* +4 is for vertical bars of a box plus 1-pixel spaces at both side. */
22463 width = max (metrics_upper.width, metrics_lower.width) + 4;
22464 upper_xoff = upper_yoff = 2; /* the typical case */
22465 if (base_width >= width)
22467 /* Align the upper to the left, the lower to the right. */
22468 it->pixel_width = base_width;
22469 lower_xoff = base_width - 2 - metrics_lower.width;
22471 else
22473 /* Center the shorter one. */
22474 it->pixel_width = width;
22475 if (metrics_upper.width >= metrics_lower.width)
22476 lower_xoff = (width - metrics_lower.width) / 2;
22477 else
22479 /* FIXME: This code doesn't look right. It formerly was
22480 missing the "lower_xoff = 0;", which couldn't have
22481 been right since it left lower_xoff uninitialized. */
22482 lower_xoff = 0;
22483 upper_xoff = (width - metrics_upper.width) / 2;
22487 /* +5 is for horizontal bars of a box plus 1-pixel spaces at
22488 top, bottom, and between upper and lower strings. */
22489 height = (metrics_upper.ascent + metrics_upper.descent
22490 + metrics_lower.ascent + metrics_lower.descent) + 5;
22491 /* Center vertically.
22492 H:base_height, D:base_descent
22493 h:height, ld:lower_descent, la:lower_ascent, ud:upper_descent
22495 ascent = - (D - H/2 - h/2 + 1); "+ 1" for rounding up
22496 descent = D - H/2 + h/2;
22497 lower_yoff = descent - 2 - ld;
22498 upper_yoff = lower_yoff - la - 1 - ud; */
22499 ascent = - (it->descent - (base_height + height + 1) / 2);
22500 descent = it->descent - (base_height - height) / 2;
22501 lower_yoff = descent - 2 - metrics_lower.descent;
22502 upper_yoff = (lower_yoff - metrics_lower.ascent - 1
22503 - metrics_upper.descent);
22504 /* Don't make the height shorter than the base height. */
22505 if (height > base_height)
22507 it->ascent = ascent;
22508 it->descent = descent;
22512 it->phys_ascent = it->ascent;
22513 it->phys_descent = it->descent;
22514 if (it->glyph_row)
22515 append_glyphless_glyph (it, face_id, for_no_font, len,
22516 upper_xoff, upper_yoff,
22517 lower_xoff, lower_yoff);
22518 it->nglyphs = 1;
22519 take_vertical_position_into_account (it);
22523 /* RIF:
22524 Produce glyphs/get display metrics for the display element IT is
22525 loaded with. See the description of struct it in dispextern.h
22526 for an overview of struct it. */
22528 void
22529 x_produce_glyphs (struct it *it)
22531 int extra_line_spacing = it->extra_line_spacing;
22533 it->glyph_not_available_p = 0;
22535 if (it->what == IT_CHARACTER)
22537 XChar2b char2b;
22538 struct face *face = FACE_FROM_ID (it->f, it->face_id);
22539 struct font *font = face->font;
22540 struct font_metrics *pcm = NULL;
22541 int boff; /* baseline offset */
22543 if (font == NULL)
22545 /* When no suitable font is found, display this character by
22546 the method specified in the first extra slot of
22547 Vglyphless_char_display. */
22548 Lisp_Object acronym = lookup_glyphless_char_display (-1, it);
22550 xassert (it->what == IT_GLYPHLESS);
22551 produce_glyphless_glyph (it, 1, STRINGP (acronym) ? acronym : Qnil);
22552 goto done;
22555 boff = font->baseline_offset;
22556 if (font->vertical_centering)
22557 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
22559 if (it->char_to_display != '\n' && it->char_to_display != '\t')
22561 int stretched_p;
22563 it->nglyphs = 1;
22565 if (it->override_ascent >= 0)
22567 it->ascent = it->override_ascent;
22568 it->descent = it->override_descent;
22569 boff = it->override_boff;
22571 else
22573 it->ascent = FONT_BASE (font) + boff;
22574 it->descent = FONT_DESCENT (font) - boff;
22577 if (get_char_glyph_code (it->char_to_display, font, &char2b))
22579 pcm = get_per_char_metric (font, &char2b);
22580 if (pcm->width == 0
22581 && pcm->rbearing == 0 && pcm->lbearing == 0)
22582 pcm = NULL;
22585 if (pcm)
22587 it->phys_ascent = pcm->ascent + boff;
22588 it->phys_descent = pcm->descent - boff;
22589 it->pixel_width = pcm->width;
22591 else
22593 it->glyph_not_available_p = 1;
22594 it->phys_ascent = it->ascent;
22595 it->phys_descent = it->descent;
22596 it->pixel_width = font->space_width;
22599 if (it->constrain_row_ascent_descent_p)
22601 if (it->descent > it->max_descent)
22603 it->ascent += it->descent - it->max_descent;
22604 it->descent = it->max_descent;
22606 if (it->ascent > it->max_ascent)
22608 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
22609 it->ascent = it->max_ascent;
22611 it->phys_ascent = min (it->phys_ascent, it->ascent);
22612 it->phys_descent = min (it->phys_descent, it->descent);
22613 extra_line_spacing = 0;
22616 /* If this is a space inside a region of text with
22617 `space-width' property, change its width. */
22618 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
22619 if (stretched_p)
22620 it->pixel_width *= XFLOATINT (it->space_width);
22622 /* If face has a box, add the box thickness to the character
22623 height. If character has a box line to the left and/or
22624 right, add the box line width to the character's width. */
22625 if (face->box != FACE_NO_BOX)
22627 int thick = face->box_line_width;
22629 if (thick > 0)
22631 it->ascent += thick;
22632 it->descent += thick;
22634 else
22635 thick = -thick;
22637 if (it->start_of_box_run_p)
22638 it->pixel_width += thick;
22639 if (it->end_of_box_run_p)
22640 it->pixel_width += thick;
22643 /* If face has an overline, add the height of the overline
22644 (1 pixel) and a 1 pixel margin to the character height. */
22645 if (face->overline_p)
22646 it->ascent += overline_margin;
22648 if (it->constrain_row_ascent_descent_p)
22650 if (it->ascent > it->max_ascent)
22651 it->ascent = it->max_ascent;
22652 if (it->descent > it->max_descent)
22653 it->descent = it->max_descent;
22656 take_vertical_position_into_account (it);
22658 /* If we have to actually produce glyphs, do it. */
22659 if (it->glyph_row)
22661 if (stretched_p)
22663 /* Translate a space with a `space-width' property
22664 into a stretch glyph. */
22665 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
22666 / FONT_HEIGHT (font));
22667 append_stretch_glyph (it, it->object, it->pixel_width,
22668 it->ascent + it->descent, ascent);
22670 else
22671 append_glyph (it);
22673 /* If characters with lbearing or rbearing are displayed
22674 in this line, record that fact in a flag of the
22675 glyph row. This is used to optimize X output code. */
22676 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
22677 it->glyph_row->contains_overlapping_glyphs_p = 1;
22679 if (! stretched_p && it->pixel_width == 0)
22680 /* We assure that all visible glyphs have at least 1-pixel
22681 width. */
22682 it->pixel_width = 1;
22684 else if (it->char_to_display == '\n')
22686 /* A newline has no width, but we need the height of the
22687 line. But if previous part of the line sets a height,
22688 don't increase that height */
22690 Lisp_Object height;
22691 Lisp_Object total_height = Qnil;
22693 it->override_ascent = -1;
22694 it->pixel_width = 0;
22695 it->nglyphs = 0;
22697 height = get_it_property (it, Qline_height);
22698 /* Split (line-height total-height) list */
22699 if (CONSP (height)
22700 && CONSP (XCDR (height))
22701 && NILP (XCDR (XCDR (height))))
22703 total_height = XCAR (XCDR (height));
22704 height = XCAR (height);
22706 height = calc_line_height_property (it, height, font, boff, 1);
22708 if (it->override_ascent >= 0)
22710 it->ascent = it->override_ascent;
22711 it->descent = it->override_descent;
22712 boff = it->override_boff;
22714 else
22716 it->ascent = FONT_BASE (font) + boff;
22717 it->descent = FONT_DESCENT (font) - boff;
22720 if (EQ (height, Qt))
22722 if (it->descent > it->max_descent)
22724 it->ascent += it->descent - it->max_descent;
22725 it->descent = it->max_descent;
22727 if (it->ascent > it->max_ascent)
22729 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
22730 it->ascent = it->max_ascent;
22732 it->phys_ascent = min (it->phys_ascent, it->ascent);
22733 it->phys_descent = min (it->phys_descent, it->descent);
22734 it->constrain_row_ascent_descent_p = 1;
22735 extra_line_spacing = 0;
22737 else
22739 Lisp_Object spacing;
22741 it->phys_ascent = it->ascent;
22742 it->phys_descent = it->descent;
22744 if ((it->max_ascent > 0 || it->max_descent > 0)
22745 && face->box != FACE_NO_BOX
22746 && face->box_line_width > 0)
22748 it->ascent += face->box_line_width;
22749 it->descent += face->box_line_width;
22751 if (!NILP (height)
22752 && XINT (height) > it->ascent + it->descent)
22753 it->ascent = XINT (height) - it->descent;
22755 if (!NILP (total_height))
22756 spacing = calc_line_height_property (it, total_height, font, boff, 0);
22757 else
22759 spacing = get_it_property (it, Qline_spacing);
22760 spacing = calc_line_height_property (it, spacing, font, boff, 0);
22762 if (INTEGERP (spacing))
22764 extra_line_spacing = XINT (spacing);
22765 if (!NILP (total_height))
22766 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
22770 else /* i.e. (it->char_to_display == '\t') */
22772 if (font->space_width > 0)
22774 int tab_width = it->tab_width * font->space_width;
22775 int x = it->current_x + it->continuation_lines_width;
22776 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
22778 /* If the distance from the current position to the next tab
22779 stop is less than a space character width, use the
22780 tab stop after that. */
22781 if (next_tab_x - x < font->space_width)
22782 next_tab_x += tab_width;
22784 it->pixel_width = next_tab_x - x;
22785 it->nglyphs = 1;
22786 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
22787 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
22789 if (it->glyph_row)
22791 append_stretch_glyph (it, it->object, it->pixel_width,
22792 it->ascent + it->descent, it->ascent);
22795 else
22797 it->pixel_width = 0;
22798 it->nglyphs = 1;
22802 else if (it->what == IT_COMPOSITION && it->cmp_it.ch < 0)
22804 /* A static composition.
22806 Note: A composition is represented as one glyph in the
22807 glyph matrix. There are no padding glyphs.
22809 Important note: pixel_width, ascent, and descent are the
22810 values of what is drawn by draw_glyphs (i.e. the values of
22811 the overall glyphs composed). */
22812 struct face *face = FACE_FROM_ID (it->f, it->face_id);
22813 int boff; /* baseline offset */
22814 struct composition *cmp = composition_table[it->cmp_it.id];
22815 int glyph_len = cmp->glyph_len;
22816 struct font *font = face->font;
22818 it->nglyphs = 1;
22820 /* If we have not yet calculated pixel size data of glyphs of
22821 the composition for the current face font, calculate them
22822 now. Theoretically, we have to check all fonts for the
22823 glyphs, but that requires much time and memory space. So,
22824 here we check only the font of the first glyph. This may
22825 lead to incorrect display, but it's very rare, and C-l
22826 (recenter-top-bottom) can correct the display anyway. */
22827 if (! cmp->font || cmp->font != font)
22829 /* Ascent and descent of the font of the first character
22830 of this composition (adjusted by baseline offset).
22831 Ascent and descent of overall glyphs should not be less
22832 than these, respectively. */
22833 int font_ascent, font_descent, font_height;
22834 /* Bounding box of the overall glyphs. */
22835 int leftmost, rightmost, lowest, highest;
22836 int lbearing, rbearing;
22837 int i, width, ascent, descent;
22838 int left_padded = 0, right_padded = 0;
22839 int c IF_LINT (= 0); /* cmp->glyph_len can't be zero; see Bug#8512 */
22840 XChar2b char2b;
22841 struct font_metrics *pcm;
22842 int font_not_found_p;
22843 EMACS_INT pos;
22845 for (glyph_len = cmp->glyph_len; glyph_len > 0; glyph_len--)
22846 if ((c = COMPOSITION_GLYPH (cmp, glyph_len - 1)) != '\t')
22847 break;
22848 if (glyph_len < cmp->glyph_len)
22849 right_padded = 1;
22850 for (i = 0; i < glyph_len; i++)
22852 if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
22853 break;
22854 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
22856 if (i > 0)
22857 left_padded = 1;
22859 pos = (STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
22860 : IT_CHARPOS (*it));
22861 /* If no suitable font is found, use the default font. */
22862 font_not_found_p = font == NULL;
22863 if (font_not_found_p)
22865 face = face->ascii_face;
22866 font = face->font;
22868 boff = font->baseline_offset;
22869 if (font->vertical_centering)
22870 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
22871 font_ascent = FONT_BASE (font) + boff;
22872 font_descent = FONT_DESCENT (font) - boff;
22873 font_height = FONT_HEIGHT (font);
22875 cmp->font = (void *) font;
22877 pcm = NULL;
22878 if (! font_not_found_p)
22880 get_char_face_and_encoding (it->f, c, it->face_id,
22881 &char2b, 0);
22882 pcm = get_per_char_metric (font, &char2b);
22885 /* Initialize the bounding box. */
22886 if (pcm)
22888 width = pcm->width;
22889 ascent = pcm->ascent;
22890 descent = pcm->descent;
22891 lbearing = pcm->lbearing;
22892 rbearing = pcm->rbearing;
22894 else
22896 width = font->space_width;
22897 ascent = FONT_BASE (font);
22898 descent = FONT_DESCENT (font);
22899 lbearing = 0;
22900 rbearing = width;
22903 rightmost = width;
22904 leftmost = 0;
22905 lowest = - descent + boff;
22906 highest = ascent + boff;
22908 if (! font_not_found_p
22909 && font->default_ascent
22910 && CHAR_TABLE_P (Vuse_default_ascent)
22911 && !NILP (Faref (Vuse_default_ascent,
22912 make_number (it->char_to_display))))
22913 highest = font->default_ascent + boff;
22915 /* Draw the first glyph at the normal position. It may be
22916 shifted to right later if some other glyphs are drawn
22917 at the left. */
22918 cmp->offsets[i * 2] = 0;
22919 cmp->offsets[i * 2 + 1] = boff;
22920 cmp->lbearing = lbearing;
22921 cmp->rbearing = rbearing;
22923 /* Set cmp->offsets for the remaining glyphs. */
22924 for (i++; i < glyph_len; i++)
22926 int left, right, btm, top;
22927 int ch = COMPOSITION_GLYPH (cmp, i);
22928 int face_id;
22929 struct face *this_face;
22931 if (ch == '\t')
22932 ch = ' ';
22933 face_id = FACE_FOR_CHAR (it->f, face, ch, pos, it->string);
22934 this_face = FACE_FROM_ID (it->f, face_id);
22935 font = this_face->font;
22937 if (font == NULL)
22938 pcm = NULL;
22939 else
22941 get_char_face_and_encoding (it->f, ch, face_id,
22942 &char2b, 0);
22943 pcm = get_per_char_metric (font, &char2b);
22945 if (! pcm)
22946 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
22947 else
22949 width = pcm->width;
22950 ascent = pcm->ascent;
22951 descent = pcm->descent;
22952 lbearing = pcm->lbearing;
22953 rbearing = pcm->rbearing;
22954 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
22956 /* Relative composition with or without
22957 alternate chars. */
22958 left = (leftmost + rightmost - width) / 2;
22959 btm = - descent + boff;
22960 if (font->relative_compose
22961 && (! CHAR_TABLE_P (Vignore_relative_composition)
22962 || NILP (Faref (Vignore_relative_composition,
22963 make_number (ch)))))
22966 if (- descent >= font->relative_compose)
22967 /* One extra pixel between two glyphs. */
22968 btm = highest + 1;
22969 else if (ascent <= 0)
22970 /* One extra pixel between two glyphs. */
22971 btm = lowest - 1 - ascent - descent;
22974 else
22976 /* A composition rule is specified by an integer
22977 value that encodes global and new reference
22978 points (GREF and NREF). GREF and NREF are
22979 specified by numbers as below:
22981 0---1---2 -- ascent
22985 9--10--11 -- center
22987 ---3---4---5--- baseline
22989 6---7---8 -- descent
22991 int rule = COMPOSITION_RULE (cmp, i);
22992 int gref, nref, grefx, grefy, nrefx, nrefy, xoff, yoff;
22994 COMPOSITION_DECODE_RULE (rule, gref, nref, xoff, yoff);
22995 grefx = gref % 3, nrefx = nref % 3;
22996 grefy = gref / 3, nrefy = nref / 3;
22997 if (xoff)
22998 xoff = font_height * (xoff - 128) / 256;
22999 if (yoff)
23000 yoff = font_height * (yoff - 128) / 256;
23002 left = (leftmost
23003 + grefx * (rightmost - leftmost) / 2
23004 - nrefx * width / 2
23005 + xoff);
23007 btm = ((grefy == 0 ? highest
23008 : grefy == 1 ? 0
23009 : grefy == 2 ? lowest
23010 : (highest + lowest) / 2)
23011 - (nrefy == 0 ? ascent + descent
23012 : nrefy == 1 ? descent - boff
23013 : nrefy == 2 ? 0
23014 : (ascent + descent) / 2)
23015 + yoff);
23018 cmp->offsets[i * 2] = left;
23019 cmp->offsets[i * 2 + 1] = btm + descent;
23021 /* Update the bounding box of the overall glyphs. */
23022 if (width > 0)
23024 right = left + width;
23025 if (left < leftmost)
23026 leftmost = left;
23027 if (right > rightmost)
23028 rightmost = right;
23030 top = btm + descent + ascent;
23031 if (top > highest)
23032 highest = top;
23033 if (btm < lowest)
23034 lowest = btm;
23036 if (cmp->lbearing > left + lbearing)
23037 cmp->lbearing = left + lbearing;
23038 if (cmp->rbearing < left + rbearing)
23039 cmp->rbearing = left + rbearing;
23043 /* If there are glyphs whose x-offsets are negative,
23044 shift all glyphs to the right and make all x-offsets
23045 non-negative. */
23046 if (leftmost < 0)
23048 for (i = 0; i < cmp->glyph_len; i++)
23049 cmp->offsets[i * 2] -= leftmost;
23050 rightmost -= leftmost;
23051 cmp->lbearing -= leftmost;
23052 cmp->rbearing -= leftmost;
23055 if (left_padded && cmp->lbearing < 0)
23057 for (i = 0; i < cmp->glyph_len; i++)
23058 cmp->offsets[i * 2] -= cmp->lbearing;
23059 rightmost -= cmp->lbearing;
23060 cmp->rbearing -= cmp->lbearing;
23061 cmp->lbearing = 0;
23063 if (right_padded && rightmost < cmp->rbearing)
23065 rightmost = cmp->rbearing;
23068 cmp->pixel_width = rightmost;
23069 cmp->ascent = highest;
23070 cmp->descent = - lowest;
23071 if (cmp->ascent < font_ascent)
23072 cmp->ascent = font_ascent;
23073 if (cmp->descent < font_descent)
23074 cmp->descent = font_descent;
23077 if (it->glyph_row
23078 && (cmp->lbearing < 0
23079 || cmp->rbearing > cmp->pixel_width))
23080 it->glyph_row->contains_overlapping_glyphs_p = 1;
23082 it->pixel_width = cmp->pixel_width;
23083 it->ascent = it->phys_ascent = cmp->ascent;
23084 it->descent = it->phys_descent = cmp->descent;
23085 if (face->box != FACE_NO_BOX)
23087 int thick = face->box_line_width;
23089 if (thick > 0)
23091 it->ascent += thick;
23092 it->descent += thick;
23094 else
23095 thick = - thick;
23097 if (it->start_of_box_run_p)
23098 it->pixel_width += thick;
23099 if (it->end_of_box_run_p)
23100 it->pixel_width += thick;
23103 /* If face has an overline, add the height of the overline
23104 (1 pixel) and a 1 pixel margin to the character height. */
23105 if (face->overline_p)
23106 it->ascent += overline_margin;
23108 take_vertical_position_into_account (it);
23109 if (it->ascent < 0)
23110 it->ascent = 0;
23111 if (it->descent < 0)
23112 it->descent = 0;
23114 if (it->glyph_row)
23115 append_composite_glyph (it);
23117 else if (it->what == IT_COMPOSITION)
23119 /* A dynamic (automatic) composition. */
23120 struct face *face = FACE_FROM_ID (it->f, it->face_id);
23121 Lisp_Object gstring;
23122 struct font_metrics metrics;
23124 gstring = composition_gstring_from_id (it->cmp_it.id);
23125 it->pixel_width
23126 = composition_gstring_width (gstring, it->cmp_it.from, it->cmp_it.to,
23127 &metrics);
23128 if (it->glyph_row
23129 && (metrics.lbearing < 0 || metrics.rbearing > metrics.width))
23130 it->glyph_row->contains_overlapping_glyphs_p = 1;
23131 it->ascent = it->phys_ascent = metrics.ascent;
23132 it->descent = it->phys_descent = metrics.descent;
23133 if (face->box != FACE_NO_BOX)
23135 int thick = face->box_line_width;
23137 if (thick > 0)
23139 it->ascent += thick;
23140 it->descent += thick;
23142 else
23143 thick = - thick;
23145 if (it->start_of_box_run_p)
23146 it->pixel_width += thick;
23147 if (it->end_of_box_run_p)
23148 it->pixel_width += thick;
23150 /* If face has an overline, add the height of the overline
23151 (1 pixel) and a 1 pixel margin to the character height. */
23152 if (face->overline_p)
23153 it->ascent += overline_margin;
23154 take_vertical_position_into_account (it);
23155 if (it->ascent < 0)
23156 it->ascent = 0;
23157 if (it->descent < 0)
23158 it->descent = 0;
23160 if (it->glyph_row)
23161 append_composite_glyph (it);
23163 else if (it->what == IT_GLYPHLESS)
23164 produce_glyphless_glyph (it, 0, Qnil);
23165 else if (it->what == IT_IMAGE)
23166 produce_image_glyph (it);
23167 else if (it->what == IT_STRETCH)
23168 produce_stretch_glyph (it);
23170 done:
23171 /* Accumulate dimensions. Note: can't assume that it->descent > 0
23172 because this isn't true for images with `:ascent 100'. */
23173 xassert (it->ascent >= 0 && it->descent >= 0);
23174 if (it->area == TEXT_AREA)
23175 it->current_x += it->pixel_width;
23177 if (extra_line_spacing > 0)
23179 it->descent += extra_line_spacing;
23180 if (extra_line_spacing > it->max_extra_line_spacing)
23181 it->max_extra_line_spacing = extra_line_spacing;
23184 it->max_ascent = max (it->max_ascent, it->ascent);
23185 it->max_descent = max (it->max_descent, it->descent);
23186 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
23187 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
23190 /* EXPORT for RIF:
23191 Output LEN glyphs starting at START at the nominal cursor position.
23192 Advance the nominal cursor over the text. The global variable
23193 updated_window contains the window being updated, updated_row is
23194 the glyph row being updated, and updated_area is the area of that
23195 row being updated. */
23197 void
23198 x_write_glyphs (struct glyph *start, int len)
23200 int x, hpos;
23202 xassert (updated_window && updated_row);
23203 BLOCK_INPUT;
23205 /* Write glyphs. */
23207 hpos = start - updated_row->glyphs[updated_area];
23208 x = draw_glyphs (updated_window, output_cursor.x,
23209 updated_row, updated_area,
23210 hpos, hpos + len,
23211 DRAW_NORMAL_TEXT, 0);
23213 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
23214 if (updated_area == TEXT_AREA
23215 && updated_window->phys_cursor_on_p
23216 && updated_window->phys_cursor.vpos == output_cursor.vpos
23217 && updated_window->phys_cursor.hpos >= hpos
23218 && updated_window->phys_cursor.hpos < hpos + len)
23219 updated_window->phys_cursor_on_p = 0;
23221 UNBLOCK_INPUT;
23223 /* Advance the output cursor. */
23224 output_cursor.hpos += len;
23225 output_cursor.x = x;
23229 /* EXPORT for RIF:
23230 Insert LEN glyphs from START at the nominal cursor position. */
23232 void
23233 x_insert_glyphs (struct glyph *start, int len)
23235 struct frame *f;
23236 struct window *w;
23237 int line_height, shift_by_width, shifted_region_width;
23238 struct glyph_row *row;
23239 struct glyph *glyph;
23240 int frame_x, frame_y;
23241 EMACS_INT hpos;
23243 xassert (updated_window && updated_row);
23244 BLOCK_INPUT;
23245 w = updated_window;
23246 f = XFRAME (WINDOW_FRAME (w));
23248 /* Get the height of the line we are in. */
23249 row = updated_row;
23250 line_height = row->height;
23252 /* Get the width of the glyphs to insert. */
23253 shift_by_width = 0;
23254 for (glyph = start; glyph < start + len; ++glyph)
23255 shift_by_width += glyph->pixel_width;
23257 /* Get the width of the region to shift right. */
23258 shifted_region_width = (window_box_width (w, updated_area)
23259 - output_cursor.x
23260 - shift_by_width);
23262 /* Shift right. */
23263 frame_x = window_box_left (w, updated_area) + output_cursor.x;
23264 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
23266 FRAME_RIF (f)->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
23267 line_height, shift_by_width);
23269 /* Write the glyphs. */
23270 hpos = start - row->glyphs[updated_area];
23271 draw_glyphs (w, output_cursor.x, row, updated_area,
23272 hpos, hpos + len,
23273 DRAW_NORMAL_TEXT, 0);
23275 /* Advance the output cursor. */
23276 output_cursor.hpos += len;
23277 output_cursor.x += shift_by_width;
23278 UNBLOCK_INPUT;
23282 /* EXPORT for RIF:
23283 Erase the current text line from the nominal cursor position
23284 (inclusive) to pixel column TO_X (exclusive). The idea is that
23285 everything from TO_X onward is already erased.
23287 TO_X is a pixel position relative to updated_area of
23288 updated_window. TO_X == -1 means clear to the end of this area. */
23290 void
23291 x_clear_end_of_line (int to_x)
23293 struct frame *f;
23294 struct window *w = updated_window;
23295 int max_x, min_y, max_y;
23296 int from_x, from_y, to_y;
23298 xassert (updated_window && updated_row);
23299 f = XFRAME (w->frame);
23301 if (updated_row->full_width_p)
23302 max_x = WINDOW_TOTAL_WIDTH (w);
23303 else
23304 max_x = window_box_width (w, updated_area);
23305 max_y = window_text_bottom_y (w);
23307 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
23308 of window. For TO_X > 0, truncate to end of drawing area. */
23309 if (to_x == 0)
23310 return;
23311 else if (to_x < 0)
23312 to_x = max_x;
23313 else
23314 to_x = min (to_x, max_x);
23316 to_y = min (max_y, output_cursor.y + updated_row->height);
23318 /* Notice if the cursor will be cleared by this operation. */
23319 if (!updated_row->full_width_p)
23320 notice_overwritten_cursor (w, updated_area,
23321 output_cursor.x, -1,
23322 updated_row->y,
23323 MATRIX_ROW_BOTTOM_Y (updated_row));
23325 from_x = output_cursor.x;
23327 /* Translate to frame coordinates. */
23328 if (updated_row->full_width_p)
23330 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
23331 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
23333 else
23335 int area_left = window_box_left (w, updated_area);
23336 from_x += area_left;
23337 to_x += area_left;
23340 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
23341 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
23342 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
23344 /* Prevent inadvertently clearing to end of the X window. */
23345 if (to_x > from_x && to_y > from_y)
23347 BLOCK_INPUT;
23348 FRAME_RIF (f)->clear_frame_area (f, from_x, from_y,
23349 to_x - from_x, to_y - from_y);
23350 UNBLOCK_INPUT;
23354 #endif /* HAVE_WINDOW_SYSTEM */
23358 /***********************************************************************
23359 Cursor types
23360 ***********************************************************************/
23362 /* Value is the internal representation of the specified cursor type
23363 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
23364 of the bar cursor. */
23366 static enum text_cursor_kinds
23367 get_specified_cursor_type (Lisp_Object arg, int *width)
23369 enum text_cursor_kinds type;
23371 if (NILP (arg))
23372 return NO_CURSOR;
23374 if (EQ (arg, Qbox))
23375 return FILLED_BOX_CURSOR;
23377 if (EQ (arg, Qhollow))
23378 return HOLLOW_BOX_CURSOR;
23380 if (EQ (arg, Qbar))
23382 *width = 2;
23383 return BAR_CURSOR;
23386 if (CONSP (arg)
23387 && EQ (XCAR (arg), Qbar)
23388 && INTEGERP (XCDR (arg))
23389 && XINT (XCDR (arg)) >= 0)
23391 *width = XINT (XCDR (arg));
23392 return BAR_CURSOR;
23395 if (EQ (arg, Qhbar))
23397 *width = 2;
23398 return HBAR_CURSOR;
23401 if (CONSP (arg)
23402 && EQ (XCAR (arg), Qhbar)
23403 && INTEGERP (XCDR (arg))
23404 && XINT (XCDR (arg)) >= 0)
23406 *width = XINT (XCDR (arg));
23407 return HBAR_CURSOR;
23410 /* Treat anything unknown as "hollow box cursor".
23411 It was bad to signal an error; people have trouble fixing
23412 .Xdefaults with Emacs, when it has something bad in it. */
23413 type = HOLLOW_BOX_CURSOR;
23415 return type;
23418 /* Set the default cursor types for specified frame. */
23419 void
23420 set_frame_cursor_types (struct frame *f, Lisp_Object arg)
23422 int width = 1;
23423 Lisp_Object tem;
23425 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
23426 FRAME_CURSOR_WIDTH (f) = width;
23428 /* By default, set up the blink-off state depending on the on-state. */
23430 tem = Fassoc (arg, Vblink_cursor_alist);
23431 if (!NILP (tem))
23433 FRAME_BLINK_OFF_CURSOR (f)
23434 = get_specified_cursor_type (XCDR (tem), &width);
23435 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
23437 else
23438 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
23442 #ifdef HAVE_WINDOW_SYSTEM
23444 /* Return the cursor we want to be displayed in window W. Return
23445 width of bar/hbar cursor through WIDTH arg. Return with
23446 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
23447 (i.e. if the `system caret' should track this cursor).
23449 In a mini-buffer window, we want the cursor only to appear if we
23450 are reading input from this window. For the selected window, we
23451 want the cursor type given by the frame parameter or buffer local
23452 setting of cursor-type. If explicitly marked off, draw no cursor.
23453 In all other cases, we want a hollow box cursor. */
23455 static enum text_cursor_kinds
23456 get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
23457 int *active_cursor)
23459 struct frame *f = XFRAME (w->frame);
23460 struct buffer *b = XBUFFER (w->buffer);
23461 int cursor_type = DEFAULT_CURSOR;
23462 Lisp_Object alt_cursor;
23463 int non_selected = 0;
23465 *active_cursor = 1;
23467 /* Echo area */
23468 if (cursor_in_echo_area
23469 && FRAME_HAS_MINIBUF_P (f)
23470 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
23472 if (w == XWINDOW (echo_area_window))
23474 if (EQ (BVAR (b, cursor_type), Qt) || NILP (BVAR (b, cursor_type)))
23476 *width = FRAME_CURSOR_WIDTH (f);
23477 return FRAME_DESIRED_CURSOR (f);
23479 else
23480 return get_specified_cursor_type (BVAR (b, cursor_type), width);
23483 *active_cursor = 0;
23484 non_selected = 1;
23487 /* Detect a nonselected window or nonselected frame. */
23488 else if (w != XWINDOW (f->selected_window)
23489 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame)
23491 *active_cursor = 0;
23493 if (MINI_WINDOW_P (w) && minibuf_level == 0)
23494 return NO_CURSOR;
23496 non_selected = 1;
23499 /* Never display a cursor in a window in which cursor-type is nil. */
23500 if (NILP (BVAR (b, cursor_type)))
23501 return NO_CURSOR;
23503 /* Get the normal cursor type for this window. */
23504 if (EQ (BVAR (b, cursor_type), Qt))
23506 cursor_type = FRAME_DESIRED_CURSOR (f);
23507 *width = FRAME_CURSOR_WIDTH (f);
23509 else
23510 cursor_type = get_specified_cursor_type (BVAR (b, cursor_type), width);
23512 /* Use cursor-in-non-selected-windows instead
23513 for non-selected window or frame. */
23514 if (non_selected)
23516 alt_cursor = BVAR (b, cursor_in_non_selected_windows);
23517 if (!EQ (Qt, alt_cursor))
23518 return get_specified_cursor_type (alt_cursor, width);
23519 /* t means modify the normal cursor type. */
23520 if (cursor_type == FILLED_BOX_CURSOR)
23521 cursor_type = HOLLOW_BOX_CURSOR;
23522 else if (cursor_type == BAR_CURSOR && *width > 1)
23523 --*width;
23524 return cursor_type;
23527 /* Use normal cursor if not blinked off. */
23528 if (!w->cursor_off_p)
23530 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
23532 if (cursor_type == FILLED_BOX_CURSOR)
23534 /* Using a block cursor on large images can be very annoying.
23535 So use a hollow cursor for "large" images.
23536 If image is not transparent (no mask), also use hollow cursor. */
23537 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
23538 if (img != NULL && IMAGEP (img->spec))
23540 /* Arbitrarily, interpret "Large" as >32x32 and >NxN
23541 where N = size of default frame font size.
23542 This should cover most of the "tiny" icons people may use. */
23543 if (!img->mask
23544 || img->width > max (32, WINDOW_FRAME_COLUMN_WIDTH (w))
23545 || img->height > max (32, WINDOW_FRAME_LINE_HEIGHT (w)))
23546 cursor_type = HOLLOW_BOX_CURSOR;
23549 else if (cursor_type != NO_CURSOR)
23551 /* Display current only supports BOX and HOLLOW cursors for images.
23552 So for now, unconditionally use a HOLLOW cursor when cursor is
23553 not a solid box cursor. */
23554 cursor_type = HOLLOW_BOX_CURSOR;
23557 return cursor_type;
23560 /* Cursor is blinked off, so determine how to "toggle" it. */
23562 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
23563 if ((alt_cursor = Fassoc (BVAR (b, cursor_type), Vblink_cursor_alist), !NILP (alt_cursor)))
23564 return get_specified_cursor_type (XCDR (alt_cursor), width);
23566 /* Then see if frame has specified a specific blink off cursor type. */
23567 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
23569 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
23570 return FRAME_BLINK_OFF_CURSOR (f);
23573 #if 0
23574 /* Some people liked having a permanently visible blinking cursor,
23575 while others had very strong opinions against it. So it was
23576 decided to remove it. KFS 2003-09-03 */
23578 /* Finally perform built-in cursor blinking:
23579 filled box <-> hollow box
23580 wide [h]bar <-> narrow [h]bar
23581 narrow [h]bar <-> no cursor
23582 other type <-> no cursor */
23584 if (cursor_type == FILLED_BOX_CURSOR)
23585 return HOLLOW_BOX_CURSOR;
23587 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
23589 *width = 1;
23590 return cursor_type;
23592 #endif
23594 return NO_CURSOR;
23598 /* Notice when the text cursor of window W has been completely
23599 overwritten by a drawing operation that outputs glyphs in AREA
23600 starting at X0 and ending at X1 in the line starting at Y0 and
23601 ending at Y1. X coordinates are area-relative. X1 < 0 means all
23602 the rest of the line after X0 has been written. Y coordinates
23603 are window-relative. */
23605 static void
23606 notice_overwritten_cursor (struct window *w, enum glyph_row_area area,
23607 int x0, int x1, int y0, int y1)
23609 int cx0, cx1, cy0, cy1;
23610 struct glyph_row *row;
23612 if (!w->phys_cursor_on_p)
23613 return;
23614 if (area != TEXT_AREA)
23615 return;
23617 if (w->phys_cursor.vpos < 0
23618 || w->phys_cursor.vpos >= w->current_matrix->nrows
23619 || (row = w->current_matrix->rows + w->phys_cursor.vpos,
23620 !(row->enabled_p && row->displays_text_p)))
23621 return;
23623 if (row->cursor_in_fringe_p)
23625 row->cursor_in_fringe_p = 0;
23626 draw_fringe_bitmap (w, row, row->reversed_p);
23627 w->phys_cursor_on_p = 0;
23628 return;
23631 cx0 = w->phys_cursor.x;
23632 cx1 = cx0 + w->phys_cursor_width;
23633 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
23634 return;
23636 /* The cursor image will be completely removed from the
23637 screen if the output area intersects the cursor area in
23638 y-direction. When we draw in [y0 y1[, and some part of
23639 the cursor is at y < y0, that part must have been drawn
23640 before. When scrolling, the cursor is erased before
23641 actually scrolling, so we don't come here. When not
23642 scrolling, the rows above the old cursor row must have
23643 changed, and in this case these rows must have written
23644 over the cursor image.
23646 Likewise if part of the cursor is below y1, with the
23647 exception of the cursor being in the first blank row at
23648 the buffer and window end because update_text_area
23649 doesn't draw that row. (Except when it does, but
23650 that's handled in update_text_area.) */
23652 cy0 = w->phys_cursor.y;
23653 cy1 = cy0 + w->phys_cursor_height;
23654 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
23655 return;
23657 w->phys_cursor_on_p = 0;
23660 #endif /* HAVE_WINDOW_SYSTEM */
23663 /************************************************************************
23664 Mouse Face
23665 ************************************************************************/
23667 #ifdef HAVE_WINDOW_SYSTEM
23669 /* EXPORT for RIF:
23670 Fix the display of area AREA of overlapping row ROW in window W
23671 with respect to the overlapping part OVERLAPS. */
23673 void
23674 x_fix_overlapping_area (struct window *w, struct glyph_row *row,
23675 enum glyph_row_area area, int overlaps)
23677 int i, x;
23679 BLOCK_INPUT;
23681 x = 0;
23682 for (i = 0; i < row->used[area];)
23684 if (row->glyphs[area][i].overlaps_vertically_p)
23686 int start = i, start_x = x;
23690 x += row->glyphs[area][i].pixel_width;
23691 ++i;
23693 while (i < row->used[area]
23694 && row->glyphs[area][i].overlaps_vertically_p);
23696 draw_glyphs (w, start_x, row, area,
23697 start, i,
23698 DRAW_NORMAL_TEXT, overlaps);
23700 else
23702 x += row->glyphs[area][i].pixel_width;
23703 ++i;
23707 UNBLOCK_INPUT;
23711 /* EXPORT:
23712 Draw the cursor glyph of window W in glyph row ROW. See the
23713 comment of draw_glyphs for the meaning of HL. */
23715 void
23716 draw_phys_cursor_glyph (struct window *w, struct glyph_row *row,
23717 enum draw_glyphs_face hl)
23719 /* If cursor hpos is out of bounds, don't draw garbage. This can
23720 happen in mini-buffer windows when switching between echo area
23721 glyphs and mini-buffer. */
23722 if ((row->reversed_p
23723 ? (w->phys_cursor.hpos >= 0)
23724 : (w->phys_cursor.hpos < row->used[TEXT_AREA])))
23726 int on_p = w->phys_cursor_on_p;
23727 int x1;
23728 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
23729 w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
23730 hl, 0);
23731 w->phys_cursor_on_p = on_p;
23733 if (hl == DRAW_CURSOR)
23734 w->phys_cursor_width = x1 - w->phys_cursor.x;
23735 /* When we erase the cursor, and ROW is overlapped by other
23736 rows, make sure that these overlapping parts of other rows
23737 are redrawn. */
23738 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
23740 w->phys_cursor_width = x1 - w->phys_cursor.x;
23742 if (row > w->current_matrix->rows
23743 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
23744 x_fix_overlapping_area (w, row - 1, TEXT_AREA,
23745 OVERLAPS_ERASED_CURSOR);
23747 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
23748 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
23749 x_fix_overlapping_area (w, row + 1, TEXT_AREA,
23750 OVERLAPS_ERASED_CURSOR);
23756 /* EXPORT:
23757 Erase the image of a cursor of window W from the screen. */
23759 void
23760 erase_phys_cursor (struct window *w)
23762 struct frame *f = XFRAME (w->frame);
23763 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
23764 int hpos = w->phys_cursor.hpos;
23765 int vpos = w->phys_cursor.vpos;
23766 int mouse_face_here_p = 0;
23767 struct glyph_matrix *active_glyphs = w->current_matrix;
23768 struct glyph_row *cursor_row;
23769 struct glyph *cursor_glyph;
23770 enum draw_glyphs_face hl;
23772 /* No cursor displayed or row invalidated => nothing to do on the
23773 screen. */
23774 if (w->phys_cursor_type == NO_CURSOR)
23775 goto mark_cursor_off;
23777 /* VPOS >= active_glyphs->nrows means that window has been resized.
23778 Don't bother to erase the cursor. */
23779 if (vpos >= active_glyphs->nrows)
23780 goto mark_cursor_off;
23782 /* If row containing cursor is marked invalid, there is nothing we
23783 can do. */
23784 cursor_row = MATRIX_ROW (active_glyphs, vpos);
23785 if (!cursor_row->enabled_p)
23786 goto mark_cursor_off;
23788 /* If line spacing is > 0, old cursor may only be partially visible in
23789 window after split-window. So adjust visible height. */
23790 cursor_row->visible_height = min (cursor_row->visible_height,
23791 window_text_bottom_y (w) - cursor_row->y);
23793 /* If row is completely invisible, don't attempt to delete a cursor which
23794 isn't there. This can happen if cursor is at top of a window, and
23795 we switch to a buffer with a header line in that window. */
23796 if (cursor_row->visible_height <= 0)
23797 goto mark_cursor_off;
23799 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
23800 if (cursor_row->cursor_in_fringe_p)
23802 cursor_row->cursor_in_fringe_p = 0;
23803 draw_fringe_bitmap (w, cursor_row, cursor_row->reversed_p);
23804 goto mark_cursor_off;
23807 /* This can happen when the new row is shorter than the old one.
23808 In this case, either draw_glyphs or clear_end_of_line
23809 should have cleared the cursor. Note that we wouldn't be
23810 able to erase the cursor in this case because we don't have a
23811 cursor glyph at hand. */
23812 if ((cursor_row->reversed_p
23813 ? (w->phys_cursor.hpos < 0)
23814 : (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])))
23815 goto mark_cursor_off;
23817 /* If the cursor is in the mouse face area, redisplay that when
23818 we clear the cursor. */
23819 if (! NILP (hlinfo->mouse_face_window)
23820 && coords_in_mouse_face_p (w, hpos, vpos)
23821 /* Don't redraw the cursor's spot in mouse face if it is at the
23822 end of a line (on a newline). The cursor appears there, but
23823 mouse highlighting does not. */
23824 && cursor_row->used[TEXT_AREA] > hpos && hpos >= 0)
23825 mouse_face_here_p = 1;
23827 /* Maybe clear the display under the cursor. */
23828 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
23830 int x, y, left_x;
23831 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
23832 int width;
23834 cursor_glyph = get_phys_cursor_glyph (w);
23835 if (cursor_glyph == NULL)
23836 goto mark_cursor_off;
23838 width = cursor_glyph->pixel_width;
23839 left_x = window_box_left_offset (w, TEXT_AREA);
23840 x = w->phys_cursor.x;
23841 if (x < left_x)
23842 width -= left_x - x;
23843 width = min (width, window_box_width (w, TEXT_AREA) - x);
23844 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
23845 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, max (x, left_x));
23847 if (width > 0)
23848 FRAME_RIF (f)->clear_frame_area (f, x, y, width, cursor_row->visible_height);
23851 /* Erase the cursor by redrawing the character underneath it. */
23852 if (mouse_face_here_p)
23853 hl = DRAW_MOUSE_FACE;
23854 else
23855 hl = DRAW_NORMAL_TEXT;
23856 draw_phys_cursor_glyph (w, cursor_row, hl);
23858 mark_cursor_off:
23859 w->phys_cursor_on_p = 0;
23860 w->phys_cursor_type = NO_CURSOR;
23864 /* EXPORT:
23865 Display or clear cursor of window W. If ON is zero, clear the
23866 cursor. If it is non-zero, display the cursor. If ON is nonzero,
23867 where to put the cursor is specified by HPOS, VPOS, X and Y. */
23869 void
23870 display_and_set_cursor (struct window *w, int on,
23871 int hpos, int vpos, int x, int y)
23873 struct frame *f = XFRAME (w->frame);
23874 int new_cursor_type;
23875 int new_cursor_width;
23876 int active_cursor;
23877 struct glyph_row *glyph_row;
23878 struct glyph *glyph;
23880 /* This is pointless on invisible frames, and dangerous on garbaged
23881 windows and frames; in the latter case, the frame or window may
23882 be in the midst of changing its size, and x and y may be off the
23883 window. */
23884 if (! FRAME_VISIBLE_P (f)
23885 || FRAME_GARBAGED_P (f)
23886 || vpos >= w->current_matrix->nrows
23887 || hpos >= w->current_matrix->matrix_w)
23888 return;
23890 /* If cursor is off and we want it off, return quickly. */
23891 if (!on && !w->phys_cursor_on_p)
23892 return;
23894 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
23895 /* If cursor row is not enabled, we don't really know where to
23896 display the cursor. */
23897 if (!glyph_row->enabled_p)
23899 w->phys_cursor_on_p = 0;
23900 return;
23903 glyph = NULL;
23904 if (!glyph_row->exact_window_width_line_p
23905 || (0 <= hpos && hpos < glyph_row->used[TEXT_AREA]))
23906 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
23908 xassert (interrupt_input_blocked);
23910 /* Set new_cursor_type to the cursor we want to be displayed. */
23911 new_cursor_type = get_window_cursor_type (w, glyph,
23912 &new_cursor_width, &active_cursor);
23914 /* If cursor is currently being shown and we don't want it to be or
23915 it is in the wrong place, or the cursor type is not what we want,
23916 erase it. */
23917 if (w->phys_cursor_on_p
23918 && (!on
23919 || w->phys_cursor.x != x
23920 || w->phys_cursor.y != y
23921 || new_cursor_type != w->phys_cursor_type
23922 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
23923 && new_cursor_width != w->phys_cursor_width)))
23924 erase_phys_cursor (w);
23926 /* Don't check phys_cursor_on_p here because that flag is only set
23927 to zero in some cases where we know that the cursor has been
23928 completely erased, to avoid the extra work of erasing the cursor
23929 twice. In other words, phys_cursor_on_p can be 1 and the cursor
23930 still not be visible, or it has only been partly erased. */
23931 if (on)
23933 w->phys_cursor_ascent = glyph_row->ascent;
23934 w->phys_cursor_height = glyph_row->height;
23936 /* Set phys_cursor_.* before x_draw_.* is called because some
23937 of them may need the information. */
23938 w->phys_cursor.x = x;
23939 w->phys_cursor.y = glyph_row->y;
23940 w->phys_cursor.hpos = hpos;
23941 w->phys_cursor.vpos = vpos;
23944 FRAME_RIF (f)->draw_window_cursor (w, glyph_row, x, y,
23945 new_cursor_type, new_cursor_width,
23946 on, active_cursor);
23950 /* Switch the display of W's cursor on or off, according to the value
23951 of ON. */
23953 static void
23954 update_window_cursor (struct window *w, int on)
23956 /* Don't update cursor in windows whose frame is in the process
23957 of being deleted. */
23958 if (w->current_matrix)
23960 BLOCK_INPUT;
23961 display_and_set_cursor (w, on, w->phys_cursor.hpos, w->phys_cursor.vpos,
23962 w->phys_cursor.x, w->phys_cursor.y);
23963 UNBLOCK_INPUT;
23968 /* Call update_window_cursor with parameter ON_P on all leaf windows
23969 in the window tree rooted at W. */
23971 static void
23972 update_cursor_in_window_tree (struct window *w, int on_p)
23974 while (w)
23976 if (!NILP (w->hchild))
23977 update_cursor_in_window_tree (XWINDOW (w->hchild), on_p);
23978 else if (!NILP (w->vchild))
23979 update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
23980 else
23981 update_window_cursor (w, on_p);
23983 w = NILP (w->next) ? 0 : XWINDOW (w->next);
23988 /* EXPORT:
23989 Display the cursor on window W, or clear it, according to ON_P.
23990 Don't change the cursor's position. */
23992 void
23993 x_update_cursor (struct frame *f, int on_p)
23995 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
23999 /* EXPORT:
24000 Clear the cursor of window W to background color, and mark the
24001 cursor as not shown. This is used when the text where the cursor
24002 is about to be rewritten. */
24004 void
24005 x_clear_cursor (struct window *w)
24007 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
24008 update_window_cursor (w, 0);
24011 #endif /* HAVE_WINDOW_SYSTEM */
24013 /* Implementation of draw_row_with_mouse_face for GUI sessions, GPM,
24014 and MSDOS. */
24015 static void
24016 draw_row_with_mouse_face (struct window *w, int start_x, struct glyph_row *row,
24017 int start_hpos, int end_hpos,
24018 enum draw_glyphs_face draw)
24020 #ifdef HAVE_WINDOW_SYSTEM
24021 if (FRAME_WINDOW_P (XFRAME (w->frame)))
24023 draw_glyphs (w, start_x, row, TEXT_AREA, start_hpos, end_hpos, draw, 0);
24024 return;
24026 #endif
24027 #if defined (HAVE_GPM) || defined (MSDOS)
24028 tty_draw_row_with_mouse_face (w, row, start_hpos, end_hpos, draw);
24029 #endif
24032 /* Display the active region described by mouse_face_* according to DRAW. */
24034 static void
24035 show_mouse_face (Mouse_HLInfo *hlinfo, enum draw_glyphs_face draw)
24037 struct window *w = XWINDOW (hlinfo->mouse_face_window);
24038 struct frame *f = XFRAME (WINDOW_FRAME (w));
24040 if (/* If window is in the process of being destroyed, don't bother
24041 to do anything. */
24042 w->current_matrix != NULL
24043 /* Don't update mouse highlight if hidden */
24044 && (draw != DRAW_MOUSE_FACE || !hlinfo->mouse_face_hidden)
24045 /* Recognize when we are called to operate on rows that don't exist
24046 anymore. This can happen when a window is split. */
24047 && hlinfo->mouse_face_end_row < w->current_matrix->nrows)
24049 int phys_cursor_on_p = w->phys_cursor_on_p;
24050 struct glyph_row *row, *first, *last;
24052 first = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_beg_row);
24053 last = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_end_row);
24055 for (row = first; row <= last && row->enabled_p; ++row)
24057 int start_hpos, end_hpos, start_x;
24059 /* For all but the first row, the highlight starts at column 0. */
24060 if (row == first)
24062 /* R2L rows have BEG and END in reversed order, but the
24063 screen drawing geometry is always left to right. So
24064 we need to mirror the beginning and end of the
24065 highlighted area in R2L rows. */
24066 if (!row->reversed_p)
24068 start_hpos = hlinfo->mouse_face_beg_col;
24069 start_x = hlinfo->mouse_face_beg_x;
24071 else if (row == last)
24073 start_hpos = hlinfo->mouse_face_end_col;
24074 start_x = hlinfo->mouse_face_end_x;
24076 else
24078 start_hpos = 0;
24079 start_x = 0;
24082 else if (row->reversed_p && row == last)
24084 start_hpos = hlinfo->mouse_face_end_col;
24085 start_x = hlinfo->mouse_face_end_x;
24087 else
24089 start_hpos = 0;
24090 start_x = 0;
24093 if (row == last)
24095 if (!row->reversed_p)
24096 end_hpos = hlinfo->mouse_face_end_col;
24097 else if (row == first)
24098 end_hpos = hlinfo->mouse_face_beg_col;
24099 else
24101 end_hpos = row->used[TEXT_AREA];
24102 if (draw == DRAW_NORMAL_TEXT)
24103 row->fill_line_p = 1; /* Clear to end of line */
24106 else if (row->reversed_p && row == first)
24107 end_hpos = hlinfo->mouse_face_beg_col;
24108 else
24110 end_hpos = row->used[TEXT_AREA];
24111 if (draw == DRAW_NORMAL_TEXT)
24112 row->fill_line_p = 1; /* Clear to end of line */
24115 if (end_hpos > start_hpos)
24117 draw_row_with_mouse_face (w, start_x, row,
24118 start_hpos, end_hpos, draw);
24120 row->mouse_face_p
24121 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
24125 #ifdef HAVE_WINDOW_SYSTEM
24126 /* When we've written over the cursor, arrange for it to
24127 be displayed again. */
24128 if (FRAME_WINDOW_P (f)
24129 && phys_cursor_on_p && !w->phys_cursor_on_p)
24131 BLOCK_INPUT;
24132 display_and_set_cursor (w, 1,
24133 w->phys_cursor.hpos, w->phys_cursor.vpos,
24134 w->phys_cursor.x, w->phys_cursor.y);
24135 UNBLOCK_INPUT;
24137 #endif /* HAVE_WINDOW_SYSTEM */
24140 #ifdef HAVE_WINDOW_SYSTEM
24141 /* Change the mouse cursor. */
24142 if (FRAME_WINDOW_P (f))
24144 if (draw == DRAW_NORMAL_TEXT
24145 && !EQ (hlinfo->mouse_face_window, f->tool_bar_window))
24146 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
24147 else if (draw == DRAW_MOUSE_FACE)
24148 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
24149 else
24150 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
24152 #endif /* HAVE_WINDOW_SYSTEM */
24155 /* EXPORT:
24156 Clear out the mouse-highlighted active region.
24157 Redraw it un-highlighted first. Value is non-zero if mouse
24158 face was actually drawn unhighlighted. */
24161 clear_mouse_face (Mouse_HLInfo *hlinfo)
24163 int cleared = 0;
24165 if (!hlinfo->mouse_face_hidden && !NILP (hlinfo->mouse_face_window))
24167 show_mouse_face (hlinfo, DRAW_NORMAL_TEXT);
24168 cleared = 1;
24171 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
24172 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
24173 hlinfo->mouse_face_window = Qnil;
24174 hlinfo->mouse_face_overlay = Qnil;
24175 return cleared;
24178 /* Return non-zero if the coordinates HPOS and VPOS on windows W are
24179 within the mouse face on that window. */
24180 static int
24181 coords_in_mouse_face_p (struct window *w, int hpos, int vpos)
24183 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
24185 /* Quickly resolve the easy cases. */
24186 if (!(WINDOWP (hlinfo->mouse_face_window)
24187 && XWINDOW (hlinfo->mouse_face_window) == w))
24188 return 0;
24189 if (vpos < hlinfo->mouse_face_beg_row
24190 || vpos > hlinfo->mouse_face_end_row)
24191 return 0;
24192 if (vpos > hlinfo->mouse_face_beg_row
24193 && vpos < hlinfo->mouse_face_end_row)
24194 return 1;
24196 if (!MATRIX_ROW (w->current_matrix, vpos)->reversed_p)
24198 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
24200 if (hlinfo->mouse_face_beg_col <= hpos && hpos < hlinfo->mouse_face_end_col)
24201 return 1;
24203 else if ((vpos == hlinfo->mouse_face_beg_row
24204 && hpos >= hlinfo->mouse_face_beg_col)
24205 || (vpos == hlinfo->mouse_face_end_row
24206 && hpos < hlinfo->mouse_face_end_col))
24207 return 1;
24209 else
24211 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
24213 if (hlinfo->mouse_face_end_col < hpos && hpos <= hlinfo->mouse_face_beg_col)
24214 return 1;
24216 else if ((vpos == hlinfo->mouse_face_beg_row
24217 && hpos <= hlinfo->mouse_face_beg_col)
24218 || (vpos == hlinfo->mouse_face_end_row
24219 && hpos > hlinfo->mouse_face_end_col))
24220 return 1;
24222 return 0;
24226 /* EXPORT:
24227 Non-zero if physical cursor of window W is within mouse face. */
24230 cursor_in_mouse_face_p (struct window *w)
24232 return coords_in_mouse_face_p (w, w->phys_cursor.hpos, w->phys_cursor.vpos);
24237 /* Find the glyph rows START_ROW and END_ROW of window W that display
24238 characters between buffer positions START_CHARPOS and END_CHARPOS
24239 (excluding END_CHARPOS). This is similar to row_containing_pos,
24240 but is more accurate when bidi reordering makes buffer positions
24241 change non-linearly with glyph rows. */
24242 static void
24243 rows_from_pos_range (struct window *w,
24244 EMACS_INT start_charpos, EMACS_INT end_charpos,
24245 struct glyph_row **start, struct glyph_row **end)
24247 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
24248 int last_y = window_text_bottom_y (w);
24249 struct glyph_row *row;
24251 *start = NULL;
24252 *end = NULL;
24254 while (!first->enabled_p
24255 && first < MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w))
24256 first++;
24258 /* Find the START row. */
24259 for (row = first;
24260 row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y;
24261 row++)
24263 /* A row can potentially be the START row if the range of the
24264 characters it displays intersects the range
24265 [START_CHARPOS..END_CHARPOS). */
24266 if (! ((start_charpos < MATRIX_ROW_START_CHARPOS (row)
24267 && end_charpos < MATRIX_ROW_START_CHARPOS (row))
24268 /* See the commentary in row_containing_pos, for the
24269 explanation of the complicated way to check whether
24270 some position is beyond the end of the characters
24271 displayed by a row. */
24272 || ((start_charpos > MATRIX_ROW_END_CHARPOS (row)
24273 || (start_charpos == MATRIX_ROW_END_CHARPOS (row)
24274 && !row->ends_at_zv_p
24275 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
24276 && (end_charpos > MATRIX_ROW_END_CHARPOS (row)
24277 || (end_charpos == MATRIX_ROW_END_CHARPOS (row)
24278 && !row->ends_at_zv_p
24279 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))))))
24281 /* Found a candidate row. Now make sure at least one of the
24282 glyphs it displays has a charpos from the range
24283 [START_CHARPOS..END_CHARPOS).
24285 This is not obvious because bidi reordering could make
24286 buffer positions of a row be 1,2,3,102,101,100, and if we
24287 want to highlight characters in [50..60), we don't want
24288 this row, even though [50..60) does intersect [1..103),
24289 the range of character positions given by the row's start
24290 and end positions. */
24291 struct glyph *g = row->glyphs[TEXT_AREA];
24292 struct glyph *e = g + row->used[TEXT_AREA];
24294 while (g < e)
24296 if (BUFFERP (g->object)
24297 && start_charpos <= g->charpos && g->charpos < end_charpos)
24298 *start = row;
24299 g++;
24301 if (*start)
24302 break;
24306 /* Find the END row. */
24307 if (!*start
24308 /* If the last row is partially visible, start looking for END
24309 from that row, instead of starting from FIRST. */
24310 && !(row->enabled_p
24311 && row->y < last_y && MATRIX_ROW_BOTTOM_Y (row) > last_y))
24312 row = first;
24313 for ( ; row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y; row++)
24315 struct glyph_row *next = row + 1;
24317 if (!next->enabled_p
24318 || next >= MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w)
24319 /* The first row >= START whose range of displayed characters
24320 does NOT intersect the range [START_CHARPOS..END_CHARPOS]
24321 is the row END + 1. */
24322 || (start_charpos < MATRIX_ROW_START_CHARPOS (next)
24323 && end_charpos < MATRIX_ROW_START_CHARPOS (next))
24324 || ((start_charpos > MATRIX_ROW_END_CHARPOS (next)
24325 || (start_charpos == MATRIX_ROW_END_CHARPOS (next)
24326 && !next->ends_at_zv_p
24327 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))
24328 && (end_charpos > MATRIX_ROW_END_CHARPOS (next)
24329 || (end_charpos == MATRIX_ROW_END_CHARPOS (next)
24330 && !next->ends_at_zv_p
24331 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))))
24333 *end = row;
24334 break;
24336 else
24338 /* If the next row's edges intersect [START_CHARPOS..END_CHARPOS],
24339 but none of the characters it displays are in the range, it is
24340 also END + 1. */
24341 struct glyph *g = next->glyphs[TEXT_AREA];
24342 struct glyph *e = g + next->used[TEXT_AREA];
24344 while (g < e)
24346 if (BUFFERP (g->object)
24347 && start_charpos <= g->charpos && g->charpos < end_charpos)
24348 break;
24349 g++;
24351 if (g == e)
24353 *end = row;
24354 break;
24360 /* This function sets the mouse_face_* elements of HLINFO, assuming
24361 the mouse cursor is on a glyph with buffer charpos MOUSE_CHARPOS in
24362 window WINDOW. START_CHARPOS and END_CHARPOS are buffer positions
24363 for the overlay or run of text properties specifying the mouse
24364 face. BEFORE_STRING and AFTER_STRING, if non-nil, are a
24365 before-string and after-string that must also be highlighted.
24366 COVER_STRING, if non-nil, is a display string that may cover some
24367 or all of the highlighted text. */
24369 static void
24370 mouse_face_from_buffer_pos (Lisp_Object window,
24371 Mouse_HLInfo *hlinfo,
24372 EMACS_INT mouse_charpos,
24373 EMACS_INT start_charpos,
24374 EMACS_INT end_charpos,
24375 Lisp_Object before_string,
24376 Lisp_Object after_string,
24377 Lisp_Object cover_string)
24379 struct window *w = XWINDOW (window);
24380 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
24381 struct glyph_row *r1, *r2;
24382 struct glyph *glyph, *end;
24383 EMACS_INT ignore, pos;
24384 int x;
24386 xassert (NILP (cover_string) || STRINGP (cover_string));
24387 xassert (NILP (before_string) || STRINGP (before_string));
24388 xassert (NILP (after_string) || STRINGP (after_string));
24390 /* Find the rows corresponding to START_CHARPOS and END_CHARPOS. */
24391 rows_from_pos_range (w, start_charpos, end_charpos, &r1, &r2);
24392 if (r1 == NULL)
24393 r1 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
24394 /* If the before-string or display-string contains newlines,
24395 rows_from_pos_range skips to its last row. Move back. */
24396 if (!NILP (before_string) || !NILP (cover_string))
24398 struct glyph_row *prev;
24399 while ((prev = r1 - 1, prev >= first)
24400 && MATRIX_ROW_END_CHARPOS (prev) == start_charpos
24401 && prev->used[TEXT_AREA] > 0)
24403 struct glyph *beg = prev->glyphs[TEXT_AREA];
24404 glyph = beg + prev->used[TEXT_AREA];
24405 while (--glyph >= beg && INTEGERP (glyph->object));
24406 if (glyph < beg
24407 || !(EQ (glyph->object, before_string)
24408 || EQ (glyph->object, cover_string)))
24409 break;
24410 r1 = prev;
24413 if (r2 == NULL)
24415 r2 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
24416 hlinfo->mouse_face_past_end = 1;
24418 else if (!NILP (after_string))
24420 /* If the after-string has newlines, advance to its last row. */
24421 struct glyph_row *next;
24422 struct glyph_row *last
24423 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
24425 for (next = r2 + 1;
24426 next <= last
24427 && next->used[TEXT_AREA] > 0
24428 && EQ (next->glyphs[TEXT_AREA]->object, after_string);
24429 ++next)
24430 r2 = next;
24432 /* The rest of the display engine assumes that mouse_face_beg_row is
24433 either above below mouse_face_end_row or identical to it. But
24434 with bidi-reordered continued lines, the row for START_CHARPOS
24435 could be below the row for END_CHARPOS. If so, swap the rows and
24436 store them in correct order. */
24437 if (r1->y > r2->y)
24439 struct glyph_row *tem = r2;
24441 r2 = r1;
24442 r1 = tem;
24445 hlinfo->mouse_face_beg_y = r1->y;
24446 hlinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (r1, w->current_matrix);
24447 hlinfo->mouse_face_end_y = r2->y;
24448 hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r2, w->current_matrix);
24450 /* For a bidi-reordered row, the positions of BEFORE_STRING,
24451 AFTER_STRING, COVER_STRING, START_CHARPOS, and END_CHARPOS
24452 could be anywhere in the row and in any order. The strategy
24453 below is to find the leftmost and the rightmost glyph that
24454 belongs to either of these 3 strings, or whose position is
24455 between START_CHARPOS and END_CHARPOS, and highlight all the
24456 glyphs between those two. This may cover more than just the text
24457 between START_CHARPOS and END_CHARPOS if the range of characters
24458 strides the bidi level boundary, e.g. if the beginning is in R2L
24459 text while the end is in L2R text or vice versa. */
24460 if (!r1->reversed_p)
24462 /* This row is in a left to right paragraph. Scan it left to
24463 right. */
24464 glyph = r1->glyphs[TEXT_AREA];
24465 end = glyph + r1->used[TEXT_AREA];
24466 x = r1->x;
24468 /* Skip truncation glyphs at the start of the glyph row. */
24469 if (r1->displays_text_p)
24470 for (; glyph < end
24471 && INTEGERP (glyph->object)
24472 && glyph->charpos < 0;
24473 ++glyph)
24474 x += glyph->pixel_width;
24476 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
24477 or COVER_STRING, and the first glyph from buffer whose
24478 position is between START_CHARPOS and END_CHARPOS. */
24479 for (; glyph < end
24480 && !INTEGERP (glyph->object)
24481 && !EQ (glyph->object, cover_string)
24482 && !(BUFFERP (glyph->object)
24483 && (glyph->charpos >= start_charpos
24484 && glyph->charpos < end_charpos));
24485 ++glyph)
24487 /* BEFORE_STRING or AFTER_STRING are only relevant if they
24488 are present at buffer positions between START_CHARPOS and
24489 END_CHARPOS, or if they come from an overlay. */
24490 if (EQ (glyph->object, before_string))
24492 pos = string_buffer_position (before_string,
24493 start_charpos);
24494 /* If pos == 0, it means before_string came from an
24495 overlay, not from a buffer position. */
24496 if (!pos || (pos >= start_charpos && pos < end_charpos))
24497 break;
24499 else if (EQ (glyph->object, after_string))
24501 pos = string_buffer_position (after_string, end_charpos);
24502 if (!pos || (pos >= start_charpos && pos < end_charpos))
24503 break;
24505 x += glyph->pixel_width;
24507 hlinfo->mouse_face_beg_x = x;
24508 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
24510 else
24512 /* This row is in a right to left paragraph. Scan it right to
24513 left. */
24514 struct glyph *g;
24516 end = r1->glyphs[TEXT_AREA] - 1;
24517 glyph = end + r1->used[TEXT_AREA];
24519 /* Skip truncation glyphs at the start of the glyph row. */
24520 if (r1->displays_text_p)
24521 for (; glyph > end
24522 && INTEGERP (glyph->object)
24523 && glyph->charpos < 0;
24524 --glyph)
24527 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
24528 or COVER_STRING, and the first glyph from buffer whose
24529 position is between START_CHARPOS and END_CHARPOS. */
24530 for (; glyph > end
24531 && !INTEGERP (glyph->object)
24532 && !EQ (glyph->object, cover_string)
24533 && !(BUFFERP (glyph->object)
24534 && (glyph->charpos >= start_charpos
24535 && glyph->charpos < end_charpos));
24536 --glyph)
24538 /* BEFORE_STRING or AFTER_STRING are only relevant if they
24539 are present at buffer positions between START_CHARPOS and
24540 END_CHARPOS, or if they come from an overlay. */
24541 if (EQ (glyph->object, before_string))
24543 pos = string_buffer_position (before_string, start_charpos);
24544 /* If pos == 0, it means before_string came from an
24545 overlay, not from a buffer position. */
24546 if (!pos || (pos >= start_charpos && pos < end_charpos))
24547 break;
24549 else if (EQ (glyph->object, after_string))
24551 pos = string_buffer_position (after_string, end_charpos);
24552 if (!pos || (pos >= start_charpos && pos < end_charpos))
24553 break;
24557 glyph++; /* first glyph to the right of the highlighted area */
24558 for (g = r1->glyphs[TEXT_AREA], x = r1->x; g < glyph; g++)
24559 x += g->pixel_width;
24560 hlinfo->mouse_face_beg_x = x;
24561 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
24564 /* If the highlight ends in a different row, compute GLYPH and END
24565 for the end row. Otherwise, reuse the values computed above for
24566 the row where the highlight begins. */
24567 if (r2 != r1)
24569 if (!r2->reversed_p)
24571 glyph = r2->glyphs[TEXT_AREA];
24572 end = glyph + r2->used[TEXT_AREA];
24573 x = r2->x;
24575 else
24577 end = r2->glyphs[TEXT_AREA] - 1;
24578 glyph = end + r2->used[TEXT_AREA];
24582 if (!r2->reversed_p)
24584 /* Skip truncation and continuation glyphs near the end of the
24585 row, and also blanks and stretch glyphs inserted by
24586 extend_face_to_end_of_line. */
24587 while (end > glyph
24588 && INTEGERP ((end - 1)->object)
24589 && (end - 1)->charpos <= 0)
24590 --end;
24591 /* Scan the rest of the glyph row from the end, looking for the
24592 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
24593 COVER_STRING, or whose position is between START_CHARPOS
24594 and END_CHARPOS */
24595 for (--end;
24596 end > glyph
24597 && !INTEGERP (end->object)
24598 && !EQ (end->object, cover_string)
24599 && !(BUFFERP (end->object)
24600 && (end->charpos >= start_charpos
24601 && end->charpos < end_charpos));
24602 --end)
24604 /* BEFORE_STRING or AFTER_STRING are only relevant if they
24605 are present at buffer positions between START_CHARPOS and
24606 END_CHARPOS, or if they come from an overlay. */
24607 if (EQ (end->object, before_string))
24609 pos = string_buffer_position (before_string, start_charpos);
24610 if (!pos || (pos >= start_charpos && pos < end_charpos))
24611 break;
24613 else if (EQ (end->object, after_string))
24615 pos = string_buffer_position (after_string, end_charpos);
24616 if (!pos || (pos >= start_charpos && pos < end_charpos))
24617 break;
24620 /* Find the X coordinate of the last glyph to be highlighted. */
24621 for (; glyph <= end; ++glyph)
24622 x += glyph->pixel_width;
24624 hlinfo->mouse_face_end_x = x;
24625 hlinfo->mouse_face_end_col = glyph - r2->glyphs[TEXT_AREA];
24627 else
24629 /* Skip truncation and continuation glyphs near the end of the
24630 row, and also blanks and stretch glyphs inserted by
24631 extend_face_to_end_of_line. */
24632 x = r2->x;
24633 end++;
24634 while (end < glyph
24635 && INTEGERP (end->object)
24636 && end->charpos <= 0)
24638 x += end->pixel_width;
24639 ++end;
24641 /* Scan the rest of the glyph row from the end, looking for the
24642 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
24643 COVER_STRING, or whose position is between START_CHARPOS
24644 and END_CHARPOS */
24645 for ( ;
24646 end < glyph
24647 && !INTEGERP (end->object)
24648 && !EQ (end->object, cover_string)
24649 && !(BUFFERP (end->object)
24650 && (end->charpos >= start_charpos
24651 && end->charpos < end_charpos));
24652 ++end)
24654 /* BEFORE_STRING or AFTER_STRING are only relevant if they
24655 are present at buffer positions between START_CHARPOS and
24656 END_CHARPOS, or if they come from an overlay. */
24657 if (EQ (end->object, before_string))
24659 pos = string_buffer_position (before_string, start_charpos);
24660 if (!pos || (pos >= start_charpos && pos < end_charpos))
24661 break;
24663 else if (EQ (end->object, after_string))
24665 pos = string_buffer_position (after_string, end_charpos);
24666 if (!pos || (pos >= start_charpos && pos < end_charpos))
24667 break;
24669 x += end->pixel_width;
24671 hlinfo->mouse_face_end_x = x;
24672 hlinfo->mouse_face_end_col = end - r2->glyphs[TEXT_AREA];
24675 hlinfo->mouse_face_window = window;
24676 hlinfo->mouse_face_face_id
24677 = face_at_buffer_position (w, mouse_charpos, 0, 0, &ignore,
24678 mouse_charpos + 1,
24679 !hlinfo->mouse_face_hidden, -1);
24680 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
24683 /* The following function is not used anymore (replaced with
24684 mouse_face_from_string_pos), but I leave it here for the time
24685 being, in case someone would. */
24687 #if 0 /* not used */
24689 /* Find the position of the glyph for position POS in OBJECT in
24690 window W's current matrix, and return in *X, *Y the pixel
24691 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
24693 RIGHT_P non-zero means return the position of the right edge of the
24694 glyph, RIGHT_P zero means return the left edge position.
24696 If no glyph for POS exists in the matrix, return the position of
24697 the glyph with the next smaller position that is in the matrix, if
24698 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
24699 exists in the matrix, return the position of the glyph with the
24700 next larger position in OBJECT.
24702 Value is non-zero if a glyph was found. */
24704 static int
24705 fast_find_string_pos (struct window *w, EMACS_INT pos, Lisp_Object object,
24706 int *hpos, int *vpos, int *x, int *y, int right_p)
24708 int yb = window_text_bottom_y (w);
24709 struct glyph_row *r;
24710 struct glyph *best_glyph = NULL;
24711 struct glyph_row *best_row = NULL;
24712 int best_x = 0;
24714 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
24715 r->enabled_p && r->y < yb;
24716 ++r)
24718 struct glyph *g = r->glyphs[TEXT_AREA];
24719 struct glyph *e = g + r->used[TEXT_AREA];
24720 int gx;
24722 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
24723 if (EQ (g->object, object))
24725 if (g->charpos == pos)
24727 best_glyph = g;
24728 best_x = gx;
24729 best_row = r;
24730 goto found;
24732 else if (best_glyph == NULL
24733 || ((eabs (g->charpos - pos)
24734 < eabs (best_glyph->charpos - pos))
24735 && (right_p
24736 ? g->charpos < pos
24737 : g->charpos > pos)))
24739 best_glyph = g;
24740 best_x = gx;
24741 best_row = r;
24746 found:
24748 if (best_glyph)
24750 *x = best_x;
24751 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
24753 if (right_p)
24755 *x += best_glyph->pixel_width;
24756 ++*hpos;
24759 *y = best_row->y;
24760 *vpos = best_row - w->current_matrix->rows;
24763 return best_glyph != NULL;
24765 #endif /* not used */
24767 /* Find the positions of the first and the last glyphs in window W's
24768 current matrix that occlude positions [STARTPOS..ENDPOS] in OBJECT
24769 (assumed to be a string), and return in HLINFO's mouse_face_*
24770 members the pixel and column/row coordinates of those glyphs. */
24772 static void
24773 mouse_face_from_string_pos (struct window *w, Mouse_HLInfo *hlinfo,
24774 Lisp_Object object,
24775 EMACS_INT startpos, EMACS_INT endpos)
24777 int yb = window_text_bottom_y (w);
24778 struct glyph_row *r;
24779 struct glyph *g, *e;
24780 int gx;
24781 int found = 0;
24783 /* Find the glyph row with at least one position in the range
24784 [STARTPOS..ENDPOS], and the first glyph in that row whose
24785 position belongs to that range. */
24786 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
24787 r->enabled_p && r->y < yb;
24788 ++r)
24790 if (!r->reversed_p)
24792 g = r->glyphs[TEXT_AREA];
24793 e = g + r->used[TEXT_AREA];
24794 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
24795 if (EQ (g->object, object)
24796 && startpos <= g->charpos && g->charpos <= endpos)
24798 hlinfo->mouse_face_beg_row = r - w->current_matrix->rows;
24799 hlinfo->mouse_face_beg_y = r->y;
24800 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
24801 hlinfo->mouse_face_beg_x = gx;
24802 found = 1;
24803 break;
24806 else
24808 struct glyph *g1;
24810 e = r->glyphs[TEXT_AREA];
24811 g = e + r->used[TEXT_AREA];
24812 for ( ; g > e; --g)
24813 if (EQ ((g-1)->object, object)
24814 && startpos <= (g-1)->charpos && (g-1)->charpos <= endpos)
24816 hlinfo->mouse_face_beg_row = r - w->current_matrix->rows;
24817 hlinfo->mouse_face_beg_y = r->y;
24818 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
24819 for (gx = r->x, g1 = r->glyphs[TEXT_AREA]; g1 < g; ++g1)
24820 gx += g1->pixel_width;
24821 hlinfo->mouse_face_beg_x = gx;
24822 found = 1;
24823 break;
24826 if (found)
24827 break;
24830 if (!found)
24831 return;
24833 /* Starting with the next row, look for the first row which does NOT
24834 include any glyphs whose positions are in the range. */
24835 for (++r; r->enabled_p && r->y < yb; ++r)
24837 g = r->glyphs[TEXT_AREA];
24838 e = g + r->used[TEXT_AREA];
24839 found = 0;
24840 for ( ; g < e; ++g)
24841 if (EQ (g->object, object)
24842 && startpos <= g->charpos && g->charpos <= endpos)
24844 found = 1;
24845 break;
24847 if (!found)
24848 break;
24851 /* The highlighted region ends on the previous row. */
24852 r--;
24854 /* Set the end row and its vertical pixel coordinate. */
24855 hlinfo->mouse_face_end_row = r - w->current_matrix->rows;
24856 hlinfo->mouse_face_end_y = r->y;
24858 /* Compute and set the end column and the end column's horizontal
24859 pixel coordinate. */
24860 if (!r->reversed_p)
24862 g = r->glyphs[TEXT_AREA];
24863 e = g + r->used[TEXT_AREA];
24864 for ( ; e > g; --e)
24865 if (EQ ((e-1)->object, object)
24866 && startpos <= (e-1)->charpos && (e-1)->charpos <= endpos)
24867 break;
24868 hlinfo->mouse_face_end_col = e - g;
24870 for (gx = r->x; g < e; ++g)
24871 gx += g->pixel_width;
24872 hlinfo->mouse_face_end_x = gx;
24874 else
24876 e = r->glyphs[TEXT_AREA];
24877 g = e + r->used[TEXT_AREA];
24878 for (gx = r->x ; e < g; ++e)
24880 if (EQ (e->object, object)
24881 && startpos <= e->charpos && e->charpos <= endpos)
24882 break;
24883 gx += e->pixel_width;
24885 hlinfo->mouse_face_end_col = e - r->glyphs[TEXT_AREA];
24886 hlinfo->mouse_face_end_x = gx;
24890 #ifdef HAVE_WINDOW_SYSTEM
24892 /* See if position X, Y is within a hot-spot of an image. */
24894 static int
24895 on_hot_spot_p (Lisp_Object hot_spot, int x, int y)
24897 if (!CONSP (hot_spot))
24898 return 0;
24900 if (EQ (XCAR (hot_spot), Qrect))
24902 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
24903 Lisp_Object rect = XCDR (hot_spot);
24904 Lisp_Object tem;
24905 if (!CONSP (rect))
24906 return 0;
24907 if (!CONSP (XCAR (rect)))
24908 return 0;
24909 if (!CONSP (XCDR (rect)))
24910 return 0;
24911 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
24912 return 0;
24913 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
24914 return 0;
24915 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
24916 return 0;
24917 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
24918 return 0;
24919 return 1;
24921 else if (EQ (XCAR (hot_spot), Qcircle))
24923 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
24924 Lisp_Object circ = XCDR (hot_spot);
24925 Lisp_Object lr, lx0, ly0;
24926 if (CONSP (circ)
24927 && CONSP (XCAR (circ))
24928 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
24929 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
24930 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
24932 double r = XFLOATINT (lr);
24933 double dx = XINT (lx0) - x;
24934 double dy = XINT (ly0) - y;
24935 return (dx * dx + dy * dy <= r * r);
24938 else if (EQ (XCAR (hot_spot), Qpoly))
24940 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
24941 if (VECTORP (XCDR (hot_spot)))
24943 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
24944 Lisp_Object *poly = v->contents;
24945 int n = v->header.size;
24946 int i;
24947 int inside = 0;
24948 Lisp_Object lx, ly;
24949 int x0, y0;
24951 /* Need an even number of coordinates, and at least 3 edges. */
24952 if (n < 6 || n & 1)
24953 return 0;
24955 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
24956 If count is odd, we are inside polygon. Pixels on edges
24957 may or may not be included depending on actual geometry of the
24958 polygon. */
24959 if ((lx = poly[n-2], !INTEGERP (lx))
24960 || (ly = poly[n-1], !INTEGERP (lx)))
24961 return 0;
24962 x0 = XINT (lx), y0 = XINT (ly);
24963 for (i = 0; i < n; i += 2)
24965 int x1 = x0, y1 = y0;
24966 if ((lx = poly[i], !INTEGERP (lx))
24967 || (ly = poly[i+1], !INTEGERP (ly)))
24968 return 0;
24969 x0 = XINT (lx), y0 = XINT (ly);
24971 /* Does this segment cross the X line? */
24972 if (x0 >= x)
24974 if (x1 >= x)
24975 continue;
24977 else if (x1 < x)
24978 continue;
24979 if (y > y0 && y > y1)
24980 continue;
24981 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
24982 inside = !inside;
24984 return inside;
24987 return 0;
24990 Lisp_Object
24991 find_hot_spot (Lisp_Object map, int x, int y)
24993 while (CONSP (map))
24995 if (CONSP (XCAR (map))
24996 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
24997 return XCAR (map);
24998 map = XCDR (map);
25001 return Qnil;
25004 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
25005 3, 3, 0,
25006 doc: /* Lookup in image map MAP coordinates X and Y.
25007 An image map is an alist where each element has the format (AREA ID PLIST).
25008 An AREA is specified as either a rectangle, a circle, or a polygon:
25009 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
25010 pixel coordinates of the upper left and bottom right corners.
25011 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
25012 and the radius of the circle; r may be a float or integer.
25013 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
25014 vector describes one corner in the polygon.
25015 Returns the alist element for the first matching AREA in MAP. */)
25016 (Lisp_Object map, Lisp_Object x, Lisp_Object y)
25018 if (NILP (map))
25019 return Qnil;
25021 CHECK_NUMBER (x);
25022 CHECK_NUMBER (y);
25024 return find_hot_spot (map, XINT (x), XINT (y));
25028 /* Display frame CURSOR, optionally using shape defined by POINTER. */
25029 static void
25030 define_frame_cursor1 (struct frame *f, Cursor cursor, Lisp_Object pointer)
25032 /* Do not change cursor shape while dragging mouse. */
25033 if (!NILP (do_mouse_tracking))
25034 return;
25036 if (!NILP (pointer))
25038 if (EQ (pointer, Qarrow))
25039 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
25040 else if (EQ (pointer, Qhand))
25041 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
25042 else if (EQ (pointer, Qtext))
25043 cursor = FRAME_X_OUTPUT (f)->text_cursor;
25044 else if (EQ (pointer, intern ("hdrag")))
25045 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
25046 #ifdef HAVE_X_WINDOWS
25047 else if (EQ (pointer, intern ("vdrag")))
25048 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
25049 #endif
25050 else if (EQ (pointer, intern ("hourglass")))
25051 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
25052 else if (EQ (pointer, Qmodeline))
25053 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
25054 else
25055 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
25058 if (cursor != No_Cursor)
25059 FRAME_RIF (f)->define_frame_cursor (f, cursor);
25062 #endif /* HAVE_WINDOW_SYSTEM */
25064 /* Take proper action when mouse has moved to the mode or header line
25065 or marginal area AREA of window W, x-position X and y-position Y.
25066 X is relative to the start of the text display area of W, so the
25067 width of bitmap areas and scroll bars must be subtracted to get a
25068 position relative to the start of the mode line. */
25070 static void
25071 note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
25072 enum window_part area)
25074 struct window *w = XWINDOW (window);
25075 struct frame *f = XFRAME (w->frame);
25076 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
25077 #ifdef HAVE_WINDOW_SYSTEM
25078 Display_Info *dpyinfo;
25079 #endif
25080 Cursor cursor = No_Cursor;
25081 Lisp_Object pointer = Qnil;
25082 int dx, dy, width, height;
25083 EMACS_INT charpos;
25084 Lisp_Object string, object = Qnil;
25085 Lisp_Object pos, help;
25087 Lisp_Object mouse_face;
25088 int original_x_pixel = x;
25089 struct glyph * glyph = NULL, * row_start_glyph = NULL;
25090 struct glyph_row *row;
25092 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
25094 int x0;
25095 struct glyph *end;
25097 /* Kludge alert: mode_line_string takes X/Y in pixels, but
25098 returns them in row/column units! */
25099 string = mode_line_string (w, area, &x, &y, &charpos,
25100 &object, &dx, &dy, &width, &height);
25102 row = (area == ON_MODE_LINE
25103 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
25104 : MATRIX_HEADER_LINE_ROW (w->current_matrix));
25106 /* Find the glyph under the mouse pointer. */
25107 if (row->mode_line_p && row->enabled_p)
25109 glyph = row_start_glyph = row->glyphs[TEXT_AREA];
25110 end = glyph + row->used[TEXT_AREA];
25112 for (x0 = original_x_pixel;
25113 glyph < end && x0 >= glyph->pixel_width;
25114 ++glyph)
25115 x0 -= glyph->pixel_width;
25117 if (glyph >= end)
25118 glyph = NULL;
25121 else
25123 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
25124 /* Kludge alert: marginal_area_string takes X/Y in pixels, but
25125 returns them in row/column units! */
25126 string = marginal_area_string (w, area, &x, &y, &charpos,
25127 &object, &dx, &dy, &width, &height);
25130 help = Qnil;
25132 #ifdef HAVE_WINDOW_SYSTEM
25133 if (IMAGEP (object))
25135 Lisp_Object image_map, hotspot;
25136 if ((image_map = Fplist_get (XCDR (object), QCmap),
25137 !NILP (image_map))
25138 && (hotspot = find_hot_spot (image_map, dx, dy),
25139 CONSP (hotspot))
25140 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
25142 Lisp_Object plist;
25144 /* Could check XCAR (hotspot) to see if we enter/leave this hot-spot.
25145 If so, we could look for mouse-enter, mouse-leave
25146 properties in PLIST (and do something...). */
25147 hotspot = XCDR (hotspot);
25148 if (CONSP (hotspot)
25149 && (plist = XCAR (hotspot), CONSP (plist)))
25151 pointer = Fplist_get (plist, Qpointer);
25152 if (NILP (pointer))
25153 pointer = Qhand;
25154 help = Fplist_get (plist, Qhelp_echo);
25155 if (!NILP (help))
25157 help_echo_string = help;
25158 /* Is this correct? ++kfs */
25159 XSETWINDOW (help_echo_window, w);
25160 help_echo_object = w->buffer;
25161 help_echo_pos = charpos;
25165 if (NILP (pointer))
25166 pointer = Fplist_get (XCDR (object), QCpointer);
25168 #endif /* HAVE_WINDOW_SYSTEM */
25170 if (STRINGP (string))
25172 pos = make_number (charpos);
25173 /* If we're on a string with `help-echo' text property, arrange
25174 for the help to be displayed. This is done by setting the
25175 global variable help_echo_string to the help string. */
25176 if (NILP (help))
25178 help = Fget_text_property (pos, Qhelp_echo, string);
25179 if (!NILP (help))
25181 help_echo_string = help;
25182 XSETWINDOW (help_echo_window, w);
25183 help_echo_object = string;
25184 help_echo_pos = charpos;
25188 #ifdef HAVE_WINDOW_SYSTEM
25189 if (FRAME_WINDOW_P (f))
25191 dpyinfo = FRAME_X_DISPLAY_INFO (f);
25192 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
25193 if (NILP (pointer))
25194 pointer = Fget_text_property (pos, Qpointer, string);
25196 /* Change the mouse pointer according to what is under X/Y. */
25197 if (NILP (pointer)
25198 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
25200 Lisp_Object map;
25201 map = Fget_text_property (pos, Qlocal_map, string);
25202 if (!KEYMAPP (map))
25203 map = Fget_text_property (pos, Qkeymap, string);
25204 if (!KEYMAPP (map))
25205 cursor = dpyinfo->vertical_scroll_bar_cursor;
25208 #endif
25210 /* Change the mouse face according to what is under X/Y. */
25211 mouse_face = Fget_text_property (pos, Qmouse_face, string);
25212 if (!NILP (mouse_face)
25213 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
25214 && glyph)
25216 Lisp_Object b, e;
25218 struct glyph * tmp_glyph;
25220 int gpos;
25221 int gseq_length;
25222 int total_pixel_width;
25223 EMACS_INT begpos, endpos, ignore;
25225 int vpos, hpos;
25227 b = Fprevious_single_property_change (make_number (charpos + 1),
25228 Qmouse_face, string, Qnil);
25229 if (NILP (b))
25230 begpos = 0;
25231 else
25232 begpos = XINT (b);
25234 e = Fnext_single_property_change (pos, Qmouse_face, string, Qnil);
25235 if (NILP (e))
25236 endpos = SCHARS (string);
25237 else
25238 endpos = XINT (e);
25240 /* Calculate the glyph position GPOS of GLYPH in the
25241 displayed string, relative to the beginning of the
25242 highlighted part of the string.
25244 Note: GPOS is different from CHARPOS. CHARPOS is the
25245 position of GLYPH in the internal string object. A mode
25246 line string format has structures which are converted to
25247 a flattened string by the Emacs Lisp interpreter. The
25248 internal string is an element of those structures. The
25249 displayed string is the flattened string. */
25250 tmp_glyph = row_start_glyph;
25251 while (tmp_glyph < glyph
25252 && (!(EQ (tmp_glyph->object, glyph->object)
25253 && begpos <= tmp_glyph->charpos
25254 && tmp_glyph->charpos < endpos)))
25255 tmp_glyph++;
25256 gpos = glyph - tmp_glyph;
25258 /* Calculate the length GSEQ_LENGTH of the glyph sequence of
25259 the highlighted part of the displayed string to which
25260 GLYPH belongs. Note: GSEQ_LENGTH is different from
25261 SCHARS (STRING), because the latter returns the length of
25262 the internal string. */
25263 for (tmp_glyph = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
25264 tmp_glyph > glyph
25265 && (!(EQ (tmp_glyph->object, glyph->object)
25266 && begpos <= tmp_glyph->charpos
25267 && tmp_glyph->charpos < endpos));
25268 tmp_glyph--)
25270 gseq_length = gpos + (tmp_glyph - glyph) + 1;
25272 /* Calculate the total pixel width of all the glyphs between
25273 the beginning of the highlighted area and GLYPH. */
25274 total_pixel_width = 0;
25275 for (tmp_glyph = glyph - gpos; tmp_glyph != glyph; tmp_glyph++)
25276 total_pixel_width += tmp_glyph->pixel_width;
25278 /* Pre calculation of re-rendering position. Note: X is in
25279 column units here, after the call to mode_line_string or
25280 marginal_area_string. */
25281 hpos = x - gpos;
25282 vpos = (area == ON_MODE_LINE
25283 ? (w->current_matrix)->nrows - 1
25284 : 0);
25286 /* If GLYPH's position is included in the region that is
25287 already drawn in mouse face, we have nothing to do. */
25288 if ( EQ (window, hlinfo->mouse_face_window)
25289 && (!row->reversed_p
25290 ? (hlinfo->mouse_face_beg_col <= hpos
25291 && hpos < hlinfo->mouse_face_end_col)
25292 /* In R2L rows we swap BEG and END, see below. */
25293 : (hlinfo->mouse_face_end_col <= hpos
25294 && hpos < hlinfo->mouse_face_beg_col))
25295 && hlinfo->mouse_face_beg_row == vpos )
25296 return;
25298 if (clear_mouse_face (hlinfo))
25299 cursor = No_Cursor;
25301 if (!row->reversed_p)
25303 hlinfo->mouse_face_beg_col = hpos;
25304 hlinfo->mouse_face_beg_x = original_x_pixel
25305 - (total_pixel_width + dx);
25306 hlinfo->mouse_face_end_col = hpos + gseq_length;
25307 hlinfo->mouse_face_end_x = 0;
25309 else
25311 /* In R2L rows, show_mouse_face expects BEG and END
25312 coordinates to be swapped. */
25313 hlinfo->mouse_face_end_col = hpos;
25314 hlinfo->mouse_face_end_x = original_x_pixel
25315 - (total_pixel_width + dx);
25316 hlinfo->mouse_face_beg_col = hpos + gseq_length;
25317 hlinfo->mouse_face_beg_x = 0;
25320 hlinfo->mouse_face_beg_row = vpos;
25321 hlinfo->mouse_face_end_row = hlinfo->mouse_face_beg_row;
25322 hlinfo->mouse_face_beg_y = 0;
25323 hlinfo->mouse_face_end_y = 0;
25324 hlinfo->mouse_face_past_end = 0;
25325 hlinfo->mouse_face_window = window;
25327 hlinfo->mouse_face_face_id = face_at_string_position (w, string,
25328 charpos,
25329 0, 0, 0,
25330 &ignore,
25331 glyph->face_id,
25333 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
25335 if (NILP (pointer))
25336 pointer = Qhand;
25338 else if ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
25339 clear_mouse_face (hlinfo);
25341 #ifdef HAVE_WINDOW_SYSTEM
25342 if (FRAME_WINDOW_P (f))
25343 define_frame_cursor1 (f, cursor, pointer);
25344 #endif
25348 /* EXPORT:
25349 Take proper action when the mouse has moved to position X, Y on
25350 frame F as regards highlighting characters that have mouse-face
25351 properties. Also de-highlighting chars where the mouse was before.
25352 X and Y can be negative or out of range. */
25354 void
25355 note_mouse_highlight (struct frame *f, int x, int y)
25357 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
25358 enum window_part part;
25359 Lisp_Object window;
25360 struct window *w;
25361 Cursor cursor = No_Cursor;
25362 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
25363 struct buffer *b;
25365 /* When a menu is active, don't highlight because this looks odd. */
25366 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) || defined (MSDOS)
25367 if (popup_activated ())
25368 return;
25369 #endif
25371 if (NILP (Vmouse_highlight)
25372 || !f->glyphs_initialized_p
25373 || f->pointer_invisible)
25374 return;
25376 hlinfo->mouse_face_mouse_x = x;
25377 hlinfo->mouse_face_mouse_y = y;
25378 hlinfo->mouse_face_mouse_frame = f;
25380 if (hlinfo->mouse_face_defer)
25381 return;
25383 if (gc_in_progress)
25385 hlinfo->mouse_face_deferred_gc = 1;
25386 return;
25389 /* Which window is that in? */
25390 window = window_from_coordinates (f, x, y, &part, 1);
25392 /* If we were displaying active text in another window, clear that.
25393 Also clear if we move out of text area in same window. */
25394 if (! EQ (window, hlinfo->mouse_face_window)
25395 || (part != ON_TEXT && part != ON_MODE_LINE && part != ON_HEADER_LINE
25396 && !NILP (hlinfo->mouse_face_window)))
25397 clear_mouse_face (hlinfo);
25399 /* Not on a window -> return. */
25400 if (!WINDOWP (window))
25401 return;
25403 /* Reset help_echo_string. It will get recomputed below. */
25404 help_echo_string = Qnil;
25406 /* Convert to window-relative pixel coordinates. */
25407 w = XWINDOW (window);
25408 frame_to_window_pixel_xy (w, &x, &y);
25410 #ifdef HAVE_WINDOW_SYSTEM
25411 /* Handle tool-bar window differently since it doesn't display a
25412 buffer. */
25413 if (EQ (window, f->tool_bar_window))
25415 note_tool_bar_highlight (f, x, y);
25416 return;
25418 #endif
25420 /* Mouse is on the mode, header line or margin? */
25421 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
25422 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
25424 note_mode_line_or_margin_highlight (window, x, y, part);
25425 return;
25428 #ifdef HAVE_WINDOW_SYSTEM
25429 if (part == ON_VERTICAL_BORDER)
25431 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
25432 help_echo_string = build_string ("drag-mouse-1: resize");
25434 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
25435 || part == ON_SCROLL_BAR)
25436 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
25437 else
25438 cursor = FRAME_X_OUTPUT (f)->text_cursor;
25439 #endif
25441 /* Are we in a window whose display is up to date?
25442 And verify the buffer's text has not changed. */
25443 b = XBUFFER (w->buffer);
25444 if (part == ON_TEXT
25445 && EQ (w->window_end_valid, w->buffer)
25446 && XFASTINT (w->last_modified) == BUF_MODIFF (b)
25447 && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
25449 int hpos, vpos, i, dx, dy, area;
25450 EMACS_INT pos;
25451 struct glyph *glyph;
25452 Lisp_Object object;
25453 Lisp_Object mouse_face = Qnil, position;
25454 Lisp_Object *overlay_vec = NULL;
25455 int noverlays;
25456 struct buffer *obuf;
25457 EMACS_INT obegv, ozv;
25458 int same_region;
25460 /* Find the glyph under X/Y. */
25461 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
25463 #ifdef HAVE_WINDOW_SYSTEM
25464 /* Look for :pointer property on image. */
25465 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
25467 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
25468 if (img != NULL && IMAGEP (img->spec))
25470 Lisp_Object image_map, hotspot;
25471 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
25472 !NILP (image_map))
25473 && (hotspot = find_hot_spot (image_map,
25474 glyph->slice.img.x + dx,
25475 glyph->slice.img.y + dy),
25476 CONSP (hotspot))
25477 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
25479 Lisp_Object plist;
25481 /* Could check XCAR (hotspot) to see if we enter/leave
25482 this hot-spot.
25483 If so, we could look for mouse-enter, mouse-leave
25484 properties in PLIST (and do something...). */
25485 hotspot = XCDR (hotspot);
25486 if (CONSP (hotspot)
25487 && (plist = XCAR (hotspot), CONSP (plist)))
25489 pointer = Fplist_get (plist, Qpointer);
25490 if (NILP (pointer))
25491 pointer = Qhand;
25492 help_echo_string = Fplist_get (plist, Qhelp_echo);
25493 if (!NILP (help_echo_string))
25495 help_echo_window = window;
25496 help_echo_object = glyph->object;
25497 help_echo_pos = glyph->charpos;
25501 if (NILP (pointer))
25502 pointer = Fplist_get (XCDR (img->spec), QCpointer);
25505 #endif /* HAVE_WINDOW_SYSTEM */
25507 /* Clear mouse face if X/Y not over text. */
25508 if (glyph == NULL
25509 || area != TEXT_AREA
25510 || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p
25511 /* Glyph's OBJECT is an integer for glyphs inserted by the
25512 display engine for its internal purposes, like truncation
25513 and continuation glyphs and blanks beyond the end of
25514 line's text on text terminals. If we are over such a
25515 glyph, we are not over any text. */
25516 || INTEGERP (glyph->object)
25517 /* R2L rows have a stretch glyph at their front, which
25518 stands for no text, whereas L2R rows have no glyphs at
25519 all beyond the end of text. Treat such stretch glyphs
25520 like we do with NULL glyphs in L2R rows. */
25521 || (MATRIX_ROW (w->current_matrix, vpos)->reversed_p
25522 && glyph == MATRIX_ROW (w->current_matrix, vpos)->glyphs[TEXT_AREA]
25523 && glyph->type == STRETCH_GLYPH
25524 && glyph->avoid_cursor_p))
25526 if (clear_mouse_face (hlinfo))
25527 cursor = No_Cursor;
25528 #ifdef HAVE_WINDOW_SYSTEM
25529 if (FRAME_WINDOW_P (f) && NILP (pointer))
25531 if (area != TEXT_AREA)
25532 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
25533 else
25534 pointer = Vvoid_text_area_pointer;
25536 #endif
25537 goto set_cursor;
25540 pos = glyph->charpos;
25541 object = glyph->object;
25542 if (!STRINGP (object) && !BUFFERP (object))
25543 goto set_cursor;
25545 /* If we get an out-of-range value, return now; avoid an error. */
25546 if (BUFFERP (object) && pos > BUF_Z (b))
25547 goto set_cursor;
25549 /* Make the window's buffer temporarily current for
25550 overlays_at and compute_char_face. */
25551 obuf = current_buffer;
25552 current_buffer = b;
25553 obegv = BEGV;
25554 ozv = ZV;
25555 BEGV = BEG;
25556 ZV = Z;
25558 /* Is this char mouse-active or does it have help-echo? */
25559 position = make_number (pos);
25561 if (BUFFERP (object))
25563 /* Put all the overlays we want in a vector in overlay_vec. */
25564 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
25565 /* Sort overlays into increasing priority order. */
25566 noverlays = sort_overlays (overlay_vec, noverlays, w);
25568 else
25569 noverlays = 0;
25571 same_region = coords_in_mouse_face_p (w, hpos, vpos);
25573 if (same_region)
25574 cursor = No_Cursor;
25576 /* Check mouse-face highlighting. */
25577 if (! same_region
25578 /* If there exists an overlay with mouse-face overlapping
25579 the one we are currently highlighting, we have to
25580 check if we enter the overlapping overlay, and then
25581 highlight only that. */
25582 || (OVERLAYP (hlinfo->mouse_face_overlay)
25583 && mouse_face_overlay_overlaps (hlinfo->mouse_face_overlay)))
25585 /* Find the highest priority overlay with a mouse-face. */
25586 Lisp_Object overlay = Qnil;
25587 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
25589 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
25590 if (!NILP (mouse_face))
25591 overlay = overlay_vec[i];
25594 /* If we're highlighting the same overlay as before, there's
25595 no need to do that again. */
25596 if (!NILP (overlay) && EQ (overlay, hlinfo->mouse_face_overlay))
25597 goto check_help_echo;
25598 hlinfo->mouse_face_overlay = overlay;
25600 /* Clear the display of the old active region, if any. */
25601 if (clear_mouse_face (hlinfo))
25602 cursor = No_Cursor;
25604 /* If no overlay applies, get a text property. */
25605 if (NILP (overlay))
25606 mouse_face = Fget_text_property (position, Qmouse_face, object);
25608 /* Next, compute the bounds of the mouse highlighting and
25609 display it. */
25610 if (!NILP (mouse_face) && STRINGP (object))
25612 /* The mouse-highlighting comes from a display string
25613 with a mouse-face. */
25614 Lisp_Object s, e;
25615 EMACS_INT ignore;
25617 s = Fprevious_single_property_change
25618 (make_number (pos + 1), Qmouse_face, object, Qnil);
25619 e = Fnext_single_property_change
25620 (position, Qmouse_face, object, Qnil);
25621 if (NILP (s))
25622 s = make_number (0);
25623 if (NILP (e))
25624 e = make_number (SCHARS (object) - 1);
25625 mouse_face_from_string_pos (w, hlinfo, object,
25626 XINT (s), XINT (e));
25627 hlinfo->mouse_face_past_end = 0;
25628 hlinfo->mouse_face_window = window;
25629 hlinfo->mouse_face_face_id
25630 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
25631 glyph->face_id, 1);
25632 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
25633 cursor = No_Cursor;
25635 else
25637 /* The mouse-highlighting, if any, comes from an overlay
25638 or text property in the buffer. */
25639 Lisp_Object buffer IF_LINT (= Qnil);
25640 Lisp_Object cover_string IF_LINT (= Qnil);
25642 if (STRINGP (object))
25644 /* If we are on a display string with no mouse-face,
25645 check if the text under it has one. */
25646 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
25647 EMACS_INT start = MATRIX_ROW_START_CHARPOS (r);
25648 pos = string_buffer_position (object, start);
25649 if (pos > 0)
25651 mouse_face = get_char_property_and_overlay
25652 (make_number (pos), Qmouse_face, w->buffer, &overlay);
25653 buffer = w->buffer;
25654 cover_string = object;
25657 else
25659 buffer = object;
25660 cover_string = Qnil;
25663 if (!NILP (mouse_face))
25665 Lisp_Object before, after;
25666 Lisp_Object before_string, after_string;
25667 /* To correctly find the limits of mouse highlight
25668 in a bidi-reordered buffer, we must not use the
25669 optimization of limiting the search in
25670 previous-single-property-change and
25671 next-single-property-change, because
25672 rows_from_pos_range needs the real start and end
25673 positions to DTRT in this case. That's because
25674 the first row visible in a window does not
25675 necessarily display the character whose position
25676 is the smallest. */
25677 Lisp_Object lim1 =
25678 NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
25679 ? Fmarker_position (w->start)
25680 : Qnil;
25681 Lisp_Object lim2 =
25682 NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
25683 ? make_number (BUF_Z (XBUFFER (buffer))
25684 - XFASTINT (w->window_end_pos))
25685 : Qnil;
25687 if (NILP (overlay))
25689 /* Handle the text property case. */
25690 before = Fprevious_single_property_change
25691 (make_number (pos + 1), Qmouse_face, buffer, lim1);
25692 after = Fnext_single_property_change
25693 (make_number (pos), Qmouse_face, buffer, lim2);
25694 before_string = after_string = Qnil;
25696 else
25698 /* Handle the overlay case. */
25699 before = Foverlay_start (overlay);
25700 after = Foverlay_end (overlay);
25701 before_string = Foverlay_get (overlay, Qbefore_string);
25702 after_string = Foverlay_get (overlay, Qafter_string);
25704 if (!STRINGP (before_string)) before_string = Qnil;
25705 if (!STRINGP (after_string)) after_string = Qnil;
25708 mouse_face_from_buffer_pos (window, hlinfo, pos,
25709 XFASTINT (before),
25710 XFASTINT (after),
25711 before_string, after_string,
25712 cover_string);
25713 cursor = No_Cursor;
25718 check_help_echo:
25720 /* Look for a `help-echo' property. */
25721 if (NILP (help_echo_string)) {
25722 Lisp_Object help, overlay;
25724 /* Check overlays first. */
25725 help = overlay = Qnil;
25726 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
25728 overlay = overlay_vec[i];
25729 help = Foverlay_get (overlay, Qhelp_echo);
25732 if (!NILP (help))
25734 help_echo_string = help;
25735 help_echo_window = window;
25736 help_echo_object = overlay;
25737 help_echo_pos = pos;
25739 else
25741 Lisp_Object obj = glyph->object;
25742 EMACS_INT charpos = glyph->charpos;
25744 /* Try text properties. */
25745 if (STRINGP (obj)
25746 && charpos >= 0
25747 && charpos < SCHARS (obj))
25749 help = Fget_text_property (make_number (charpos),
25750 Qhelp_echo, obj);
25751 if (NILP (help))
25753 /* If the string itself doesn't specify a help-echo,
25754 see if the buffer text ``under'' it does. */
25755 struct glyph_row *r
25756 = MATRIX_ROW (w->current_matrix, vpos);
25757 EMACS_INT start = MATRIX_ROW_START_CHARPOS (r);
25758 EMACS_INT p = string_buffer_position (obj, start);
25759 if (p > 0)
25761 help = Fget_char_property (make_number (p),
25762 Qhelp_echo, w->buffer);
25763 if (!NILP (help))
25765 charpos = p;
25766 obj = w->buffer;
25771 else if (BUFFERP (obj)
25772 && charpos >= BEGV
25773 && charpos < ZV)
25774 help = Fget_text_property (make_number (charpos), Qhelp_echo,
25775 obj);
25777 if (!NILP (help))
25779 help_echo_string = help;
25780 help_echo_window = window;
25781 help_echo_object = obj;
25782 help_echo_pos = charpos;
25787 #ifdef HAVE_WINDOW_SYSTEM
25788 /* Look for a `pointer' property. */
25789 if (FRAME_WINDOW_P (f) && NILP (pointer))
25791 /* Check overlays first. */
25792 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
25793 pointer = Foverlay_get (overlay_vec[i], Qpointer);
25795 if (NILP (pointer))
25797 Lisp_Object obj = glyph->object;
25798 EMACS_INT charpos = glyph->charpos;
25800 /* Try text properties. */
25801 if (STRINGP (obj)
25802 && charpos >= 0
25803 && charpos < SCHARS (obj))
25805 pointer = Fget_text_property (make_number (charpos),
25806 Qpointer, obj);
25807 if (NILP (pointer))
25809 /* If the string itself doesn't specify a pointer,
25810 see if the buffer text ``under'' it does. */
25811 struct glyph_row *r
25812 = MATRIX_ROW (w->current_matrix, vpos);
25813 EMACS_INT start = MATRIX_ROW_START_CHARPOS (r);
25814 EMACS_INT p = string_buffer_position (obj, start);
25815 if (p > 0)
25816 pointer = Fget_char_property (make_number (p),
25817 Qpointer, w->buffer);
25820 else if (BUFFERP (obj)
25821 && charpos >= BEGV
25822 && charpos < ZV)
25823 pointer = Fget_text_property (make_number (charpos),
25824 Qpointer, obj);
25827 #endif /* HAVE_WINDOW_SYSTEM */
25829 BEGV = obegv;
25830 ZV = ozv;
25831 current_buffer = obuf;
25834 set_cursor:
25836 #ifdef HAVE_WINDOW_SYSTEM
25837 if (FRAME_WINDOW_P (f))
25838 define_frame_cursor1 (f, cursor, pointer);
25839 #else
25840 /* This is here to prevent a compiler error, about "label at end of
25841 compound statement". */
25842 return;
25843 #endif
25847 /* EXPORT for RIF:
25848 Clear any mouse-face on window W. This function is part of the
25849 redisplay interface, and is called from try_window_id and similar
25850 functions to ensure the mouse-highlight is off. */
25852 void
25853 x_clear_window_mouse_face (struct window *w)
25855 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
25856 Lisp_Object window;
25858 BLOCK_INPUT;
25859 XSETWINDOW (window, w);
25860 if (EQ (window, hlinfo->mouse_face_window))
25861 clear_mouse_face (hlinfo);
25862 UNBLOCK_INPUT;
25866 /* EXPORT:
25867 Just discard the mouse face information for frame F, if any.
25868 This is used when the size of F is changed. */
25870 void
25871 cancel_mouse_face (struct frame *f)
25873 Lisp_Object window;
25874 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
25876 window = hlinfo->mouse_face_window;
25877 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
25879 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
25880 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
25881 hlinfo->mouse_face_window = Qnil;
25887 /***********************************************************************
25888 Exposure Events
25889 ***********************************************************************/
25891 #ifdef HAVE_WINDOW_SYSTEM
25893 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
25894 which intersects rectangle R. R is in window-relative coordinates. */
25896 static void
25897 expose_area (struct window *w, struct glyph_row *row, XRectangle *r,
25898 enum glyph_row_area area)
25900 struct glyph *first = row->glyphs[area];
25901 struct glyph *end = row->glyphs[area] + row->used[area];
25902 struct glyph *last;
25903 int first_x, start_x, x;
25905 if (area == TEXT_AREA && row->fill_line_p)
25906 /* If row extends face to end of line write the whole line. */
25907 draw_glyphs (w, 0, row, area,
25908 0, row->used[area],
25909 DRAW_NORMAL_TEXT, 0);
25910 else
25912 /* Set START_X to the window-relative start position for drawing glyphs of
25913 AREA. The first glyph of the text area can be partially visible.
25914 The first glyphs of other areas cannot. */
25915 start_x = window_box_left_offset (w, area);
25916 x = start_x;
25917 if (area == TEXT_AREA)
25918 x += row->x;
25920 /* Find the first glyph that must be redrawn. */
25921 while (first < end
25922 && x + first->pixel_width < r->x)
25924 x += first->pixel_width;
25925 ++first;
25928 /* Find the last one. */
25929 last = first;
25930 first_x = x;
25931 while (last < end
25932 && x < r->x + r->width)
25934 x += last->pixel_width;
25935 ++last;
25938 /* Repaint. */
25939 if (last > first)
25940 draw_glyphs (w, first_x - start_x, row, area,
25941 first - row->glyphs[area], last - row->glyphs[area],
25942 DRAW_NORMAL_TEXT, 0);
25947 /* Redraw the parts of the glyph row ROW on window W intersecting
25948 rectangle R. R is in window-relative coordinates. Value is
25949 non-zero if mouse-face was overwritten. */
25951 static int
25952 expose_line (struct window *w, struct glyph_row *row, XRectangle *r)
25954 xassert (row->enabled_p);
25956 if (row->mode_line_p || w->pseudo_window_p)
25957 draw_glyphs (w, 0, row, TEXT_AREA,
25958 0, row->used[TEXT_AREA],
25959 DRAW_NORMAL_TEXT, 0);
25960 else
25962 if (row->used[LEFT_MARGIN_AREA])
25963 expose_area (w, row, r, LEFT_MARGIN_AREA);
25964 if (row->used[TEXT_AREA])
25965 expose_area (w, row, r, TEXT_AREA);
25966 if (row->used[RIGHT_MARGIN_AREA])
25967 expose_area (w, row, r, RIGHT_MARGIN_AREA);
25968 draw_row_fringe_bitmaps (w, row);
25971 return row->mouse_face_p;
25975 /* Redraw those parts of glyphs rows during expose event handling that
25976 overlap other rows. Redrawing of an exposed line writes over parts
25977 of lines overlapping that exposed line; this function fixes that.
25979 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
25980 row in W's current matrix that is exposed and overlaps other rows.
25981 LAST_OVERLAPPING_ROW is the last such row. */
25983 static void
25984 expose_overlaps (struct window *w,
25985 struct glyph_row *first_overlapping_row,
25986 struct glyph_row *last_overlapping_row,
25987 XRectangle *r)
25989 struct glyph_row *row;
25991 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
25992 if (row->overlapping_p)
25994 xassert (row->enabled_p && !row->mode_line_p);
25996 row->clip = r;
25997 if (row->used[LEFT_MARGIN_AREA])
25998 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA, OVERLAPS_BOTH);
26000 if (row->used[TEXT_AREA])
26001 x_fix_overlapping_area (w, row, TEXT_AREA, OVERLAPS_BOTH);
26003 if (row->used[RIGHT_MARGIN_AREA])
26004 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, OVERLAPS_BOTH);
26005 row->clip = NULL;
26010 /* Return non-zero if W's cursor intersects rectangle R. */
26012 static int
26013 phys_cursor_in_rect_p (struct window *w, XRectangle *r)
26015 XRectangle cr, result;
26016 struct glyph *cursor_glyph;
26017 struct glyph_row *row;
26019 if (w->phys_cursor.vpos >= 0
26020 && w->phys_cursor.vpos < w->current_matrix->nrows
26021 && (row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos),
26022 row->enabled_p)
26023 && row->cursor_in_fringe_p)
26025 /* Cursor is in the fringe. */
26026 cr.x = window_box_right_offset (w,
26027 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
26028 ? RIGHT_MARGIN_AREA
26029 : TEXT_AREA));
26030 cr.y = row->y;
26031 cr.width = WINDOW_RIGHT_FRINGE_WIDTH (w);
26032 cr.height = row->height;
26033 return x_intersect_rectangles (&cr, r, &result);
26036 cursor_glyph = get_phys_cursor_glyph (w);
26037 if (cursor_glyph)
26039 /* r is relative to W's box, but w->phys_cursor.x is relative
26040 to left edge of W's TEXT area. Adjust it. */
26041 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
26042 cr.y = w->phys_cursor.y;
26043 cr.width = cursor_glyph->pixel_width;
26044 cr.height = w->phys_cursor_height;
26045 /* ++KFS: W32 version used W32-specific IntersectRect here, but
26046 I assume the effect is the same -- and this is portable. */
26047 return x_intersect_rectangles (&cr, r, &result);
26049 /* If we don't understand the format, pretend we're not in the hot-spot. */
26050 return 0;
26054 /* EXPORT:
26055 Draw a vertical window border to the right of window W if W doesn't
26056 have vertical scroll bars. */
26058 void
26059 x_draw_vertical_border (struct window *w)
26061 struct frame *f = XFRAME (WINDOW_FRAME (w));
26063 /* We could do better, if we knew what type of scroll-bar the adjacent
26064 windows (on either side) have... But we don't :-(
26065 However, I think this works ok. ++KFS 2003-04-25 */
26067 /* Redraw borders between horizontally adjacent windows. Don't
26068 do it for frames with vertical scroll bars because either the
26069 right scroll bar of a window, or the left scroll bar of its
26070 neighbor will suffice as a border. */
26071 if (FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (w->frame)))
26072 return;
26074 if (!WINDOW_RIGHTMOST_P (w)
26075 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
26077 int x0, x1, y0, y1;
26079 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
26080 y1 -= 1;
26082 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
26083 x1 -= 1;
26085 FRAME_RIF (f)->draw_vertical_window_border (w, x1, y0, y1);
26087 else if (!WINDOW_LEFTMOST_P (w)
26088 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
26090 int x0, x1, y0, y1;
26092 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
26093 y1 -= 1;
26095 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
26096 x0 -= 1;
26098 FRAME_RIF (f)->draw_vertical_window_border (w, x0, y0, y1);
26103 /* Redraw the part of window W intersection rectangle FR. Pixel
26104 coordinates in FR are frame-relative. Call this function with
26105 input blocked. Value is non-zero if the exposure overwrites
26106 mouse-face. */
26108 static int
26109 expose_window (struct window *w, XRectangle *fr)
26111 struct frame *f = XFRAME (w->frame);
26112 XRectangle wr, r;
26113 int mouse_face_overwritten_p = 0;
26115 /* If window is not yet fully initialized, do nothing. This can
26116 happen when toolkit scroll bars are used and a window is split.
26117 Reconfiguring the scroll bar will generate an expose for a newly
26118 created window. */
26119 if (w->current_matrix == NULL)
26120 return 0;
26122 /* When we're currently updating the window, display and current
26123 matrix usually don't agree. Arrange for a thorough display
26124 later. */
26125 if (w == updated_window)
26127 SET_FRAME_GARBAGED (f);
26128 return 0;
26131 /* Frame-relative pixel rectangle of W. */
26132 wr.x = WINDOW_LEFT_EDGE_X (w);
26133 wr.y = WINDOW_TOP_EDGE_Y (w);
26134 wr.width = WINDOW_TOTAL_WIDTH (w);
26135 wr.height = WINDOW_TOTAL_HEIGHT (w);
26137 if (x_intersect_rectangles (fr, &wr, &r))
26139 int yb = window_text_bottom_y (w);
26140 struct glyph_row *row;
26141 int cursor_cleared_p;
26142 struct glyph_row *first_overlapping_row, *last_overlapping_row;
26144 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
26145 r.x, r.y, r.width, r.height));
26147 /* Convert to window coordinates. */
26148 r.x -= WINDOW_LEFT_EDGE_X (w);
26149 r.y -= WINDOW_TOP_EDGE_Y (w);
26151 /* Turn off the cursor. */
26152 if (!w->pseudo_window_p
26153 && phys_cursor_in_rect_p (w, &r))
26155 x_clear_cursor (w);
26156 cursor_cleared_p = 1;
26158 else
26159 cursor_cleared_p = 0;
26161 /* Update lines intersecting rectangle R. */
26162 first_overlapping_row = last_overlapping_row = NULL;
26163 for (row = w->current_matrix->rows;
26164 row->enabled_p;
26165 ++row)
26167 int y0 = row->y;
26168 int y1 = MATRIX_ROW_BOTTOM_Y (row);
26170 if ((y0 >= r.y && y0 < r.y + r.height)
26171 || (y1 > r.y && y1 < r.y + r.height)
26172 || (r.y >= y0 && r.y < y1)
26173 || (r.y + r.height > y0 && r.y + r.height < y1))
26175 /* A header line may be overlapping, but there is no need
26176 to fix overlapping areas for them. KFS 2005-02-12 */
26177 if (row->overlapping_p && !row->mode_line_p)
26179 if (first_overlapping_row == NULL)
26180 first_overlapping_row = row;
26181 last_overlapping_row = row;
26184 row->clip = fr;
26185 if (expose_line (w, row, &r))
26186 mouse_face_overwritten_p = 1;
26187 row->clip = NULL;
26189 else if (row->overlapping_p)
26191 /* We must redraw a row overlapping the exposed area. */
26192 if (y0 < r.y
26193 ? y0 + row->phys_height > r.y
26194 : y0 + row->ascent - row->phys_ascent < r.y +r.height)
26196 if (first_overlapping_row == NULL)
26197 first_overlapping_row = row;
26198 last_overlapping_row = row;
26202 if (y1 >= yb)
26203 break;
26206 /* Display the mode line if there is one. */
26207 if (WINDOW_WANTS_MODELINE_P (w)
26208 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
26209 row->enabled_p)
26210 && row->y < r.y + r.height)
26212 if (expose_line (w, row, &r))
26213 mouse_face_overwritten_p = 1;
26216 if (!w->pseudo_window_p)
26218 /* Fix the display of overlapping rows. */
26219 if (first_overlapping_row)
26220 expose_overlaps (w, first_overlapping_row, last_overlapping_row,
26221 fr);
26223 /* Draw border between windows. */
26224 x_draw_vertical_border (w);
26226 /* Turn the cursor on again. */
26227 if (cursor_cleared_p)
26228 update_window_cursor (w, 1);
26232 return mouse_face_overwritten_p;
26237 /* Redraw (parts) of all windows in the window tree rooted at W that
26238 intersect R. R contains frame pixel coordinates. Value is
26239 non-zero if the exposure overwrites mouse-face. */
26241 static int
26242 expose_window_tree (struct window *w, XRectangle *r)
26244 struct frame *f = XFRAME (w->frame);
26245 int mouse_face_overwritten_p = 0;
26247 while (w && !FRAME_GARBAGED_P (f))
26249 if (!NILP (w->hchild))
26250 mouse_face_overwritten_p
26251 |= expose_window_tree (XWINDOW (w->hchild), r);
26252 else if (!NILP (w->vchild))
26253 mouse_face_overwritten_p
26254 |= expose_window_tree (XWINDOW (w->vchild), r);
26255 else
26256 mouse_face_overwritten_p |= expose_window (w, r);
26258 w = NILP (w->next) ? NULL : XWINDOW (w->next);
26261 return mouse_face_overwritten_p;
26265 /* EXPORT:
26266 Redisplay an exposed area of frame F. X and Y are the upper-left
26267 corner of the exposed rectangle. W and H are width and height of
26268 the exposed area. All are pixel values. W or H zero means redraw
26269 the entire frame. */
26271 void
26272 expose_frame (struct frame *f, int x, int y, int w, int h)
26274 XRectangle r;
26275 int mouse_face_overwritten_p = 0;
26277 TRACE ((stderr, "expose_frame "));
26279 /* No need to redraw if frame will be redrawn soon. */
26280 if (FRAME_GARBAGED_P (f))
26282 TRACE ((stderr, " garbaged\n"));
26283 return;
26286 /* If basic faces haven't been realized yet, there is no point in
26287 trying to redraw anything. This can happen when we get an expose
26288 event while Emacs is starting, e.g. by moving another window. */
26289 if (FRAME_FACE_CACHE (f) == NULL
26290 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
26292 TRACE ((stderr, " no faces\n"));
26293 return;
26296 if (w == 0 || h == 0)
26298 r.x = r.y = 0;
26299 r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f);
26300 r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f);
26302 else
26304 r.x = x;
26305 r.y = y;
26306 r.width = w;
26307 r.height = h;
26310 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
26311 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
26313 if (WINDOWP (f->tool_bar_window))
26314 mouse_face_overwritten_p
26315 |= expose_window (XWINDOW (f->tool_bar_window), &r);
26317 #ifdef HAVE_X_WINDOWS
26318 #ifndef MSDOS
26319 #ifndef USE_X_TOOLKIT
26320 if (WINDOWP (f->menu_bar_window))
26321 mouse_face_overwritten_p
26322 |= expose_window (XWINDOW (f->menu_bar_window), &r);
26323 #endif /* not USE_X_TOOLKIT */
26324 #endif
26325 #endif
26327 /* Some window managers support a focus-follows-mouse style with
26328 delayed raising of frames. Imagine a partially obscured frame,
26329 and moving the mouse into partially obscured mouse-face on that
26330 frame. The visible part of the mouse-face will be highlighted,
26331 then the WM raises the obscured frame. With at least one WM, KDE
26332 2.1, Emacs is not getting any event for the raising of the frame
26333 (even tried with SubstructureRedirectMask), only Expose events.
26334 These expose events will draw text normally, i.e. not
26335 highlighted. Which means we must redo the highlight here.
26336 Subsume it under ``we love X''. --gerd 2001-08-15 */
26337 /* Included in Windows version because Windows most likely does not
26338 do the right thing if any third party tool offers
26339 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
26340 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
26342 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
26343 if (f == hlinfo->mouse_face_mouse_frame)
26345 int mouse_x = hlinfo->mouse_face_mouse_x;
26346 int mouse_y = hlinfo->mouse_face_mouse_y;
26347 clear_mouse_face (hlinfo);
26348 note_mouse_highlight (f, mouse_x, mouse_y);
26354 /* EXPORT:
26355 Determine the intersection of two rectangles R1 and R2. Return
26356 the intersection in *RESULT. Value is non-zero if RESULT is not
26357 empty. */
26360 x_intersect_rectangles (XRectangle *r1, XRectangle *r2, XRectangle *result)
26362 XRectangle *left, *right;
26363 XRectangle *upper, *lower;
26364 int intersection_p = 0;
26366 /* Rearrange so that R1 is the left-most rectangle. */
26367 if (r1->x < r2->x)
26368 left = r1, right = r2;
26369 else
26370 left = r2, right = r1;
26372 /* X0 of the intersection is right.x0, if this is inside R1,
26373 otherwise there is no intersection. */
26374 if (right->x <= left->x + left->width)
26376 result->x = right->x;
26378 /* The right end of the intersection is the minimum of the
26379 the right ends of left and right. */
26380 result->width = (min (left->x + left->width, right->x + right->width)
26381 - result->x);
26383 /* Same game for Y. */
26384 if (r1->y < r2->y)
26385 upper = r1, lower = r2;
26386 else
26387 upper = r2, lower = r1;
26389 /* The upper end of the intersection is lower.y0, if this is inside
26390 of upper. Otherwise, there is no intersection. */
26391 if (lower->y <= upper->y + upper->height)
26393 result->y = lower->y;
26395 /* The lower end of the intersection is the minimum of the lower
26396 ends of upper and lower. */
26397 result->height = (min (lower->y + lower->height,
26398 upper->y + upper->height)
26399 - result->y);
26400 intersection_p = 1;
26404 return intersection_p;
26407 #endif /* HAVE_WINDOW_SYSTEM */
26410 /***********************************************************************
26411 Initialization
26412 ***********************************************************************/
26414 void
26415 syms_of_xdisp (void)
26417 Vwith_echo_area_save_vector = Qnil;
26418 staticpro (&Vwith_echo_area_save_vector);
26420 Vmessage_stack = Qnil;
26421 staticpro (&Vmessage_stack);
26423 Qinhibit_redisplay = intern_c_string ("inhibit-redisplay");
26424 staticpro (&Qinhibit_redisplay);
26426 message_dolog_marker1 = Fmake_marker ();
26427 staticpro (&message_dolog_marker1);
26428 message_dolog_marker2 = Fmake_marker ();
26429 staticpro (&message_dolog_marker2);
26430 message_dolog_marker3 = Fmake_marker ();
26431 staticpro (&message_dolog_marker3);
26433 #if GLYPH_DEBUG
26434 defsubr (&Sdump_frame_glyph_matrix);
26435 defsubr (&Sdump_glyph_matrix);
26436 defsubr (&Sdump_glyph_row);
26437 defsubr (&Sdump_tool_bar_row);
26438 defsubr (&Strace_redisplay);
26439 defsubr (&Strace_to_stderr);
26440 #endif
26441 #ifdef HAVE_WINDOW_SYSTEM
26442 defsubr (&Stool_bar_lines_needed);
26443 defsubr (&Slookup_image_map);
26444 #endif
26445 defsubr (&Sformat_mode_line);
26446 defsubr (&Sinvisible_p);
26447 defsubr (&Scurrent_bidi_paragraph_direction);
26449 staticpro (&Qmenu_bar_update_hook);
26450 Qmenu_bar_update_hook = intern_c_string ("menu-bar-update-hook");
26452 staticpro (&Qoverriding_terminal_local_map);
26453 Qoverriding_terminal_local_map = intern_c_string ("overriding-terminal-local-map");
26455 staticpro (&Qoverriding_local_map);
26456 Qoverriding_local_map = intern_c_string ("overriding-local-map");
26458 staticpro (&Qwindow_scroll_functions);
26459 Qwindow_scroll_functions = intern_c_string ("window-scroll-functions");
26461 staticpro (&Qwindow_text_change_functions);
26462 Qwindow_text_change_functions = intern_c_string ("window-text-change-functions");
26464 staticpro (&Qredisplay_end_trigger_functions);
26465 Qredisplay_end_trigger_functions = intern_c_string ("redisplay-end-trigger-functions");
26467 staticpro (&Qinhibit_point_motion_hooks);
26468 Qinhibit_point_motion_hooks = intern_c_string ("inhibit-point-motion-hooks");
26470 Qeval = intern_c_string ("eval");
26471 staticpro (&Qeval);
26473 QCdata = intern_c_string (":data");
26474 staticpro (&QCdata);
26475 Qdisplay = intern_c_string ("display");
26476 staticpro (&Qdisplay);
26477 Qspace_width = intern_c_string ("space-width");
26478 staticpro (&Qspace_width);
26479 Qraise = intern_c_string ("raise");
26480 staticpro (&Qraise);
26481 Qslice = intern_c_string ("slice");
26482 staticpro (&Qslice);
26483 Qspace = intern_c_string ("space");
26484 staticpro (&Qspace);
26485 Qmargin = intern_c_string ("margin");
26486 staticpro (&Qmargin);
26487 Qpointer = intern_c_string ("pointer");
26488 staticpro (&Qpointer);
26489 Qleft_margin = intern_c_string ("left-margin");
26490 staticpro (&Qleft_margin);
26491 Qright_margin = intern_c_string ("right-margin");
26492 staticpro (&Qright_margin);
26493 Qcenter = intern_c_string ("center");
26494 staticpro (&Qcenter);
26495 Qline_height = intern_c_string ("line-height");
26496 staticpro (&Qline_height);
26497 QCalign_to = intern_c_string (":align-to");
26498 staticpro (&QCalign_to);
26499 QCrelative_width = intern_c_string (":relative-width");
26500 staticpro (&QCrelative_width);
26501 QCrelative_height = intern_c_string (":relative-height");
26502 staticpro (&QCrelative_height);
26503 QCeval = intern_c_string (":eval");
26504 staticpro (&QCeval);
26505 QCpropertize = intern_c_string (":propertize");
26506 staticpro (&QCpropertize);
26507 QCfile = intern_c_string (":file");
26508 staticpro (&QCfile);
26509 Qfontified = intern_c_string ("fontified");
26510 staticpro (&Qfontified);
26511 Qfontification_functions = intern_c_string ("fontification-functions");
26512 staticpro (&Qfontification_functions);
26513 Qtrailing_whitespace = intern_c_string ("trailing-whitespace");
26514 staticpro (&Qtrailing_whitespace);
26515 Qescape_glyph = intern_c_string ("escape-glyph");
26516 staticpro (&Qescape_glyph);
26517 Qnobreak_space = intern_c_string ("nobreak-space");
26518 staticpro (&Qnobreak_space);
26519 Qimage = intern_c_string ("image");
26520 staticpro (&Qimage);
26521 Qtext = intern_c_string ("text");
26522 staticpro (&Qtext);
26523 Qboth = intern_c_string ("both");
26524 staticpro (&Qboth);
26525 Qboth_horiz = intern_c_string ("both-horiz");
26526 staticpro (&Qboth_horiz);
26527 Qtext_image_horiz = intern_c_string ("text-image-horiz");
26528 staticpro (&Qtext_image_horiz);
26529 QCmap = intern_c_string (":map");
26530 staticpro (&QCmap);
26531 QCpointer = intern_c_string (":pointer");
26532 staticpro (&QCpointer);
26533 Qrect = intern_c_string ("rect");
26534 staticpro (&Qrect);
26535 Qcircle = intern_c_string ("circle");
26536 staticpro (&Qcircle);
26537 Qpoly = intern_c_string ("poly");
26538 staticpro (&Qpoly);
26539 Qmessage_truncate_lines = intern_c_string ("message-truncate-lines");
26540 staticpro (&Qmessage_truncate_lines);
26541 Qgrow_only = intern_c_string ("grow-only");
26542 staticpro (&Qgrow_only);
26543 Qinhibit_menubar_update = intern_c_string ("inhibit-menubar-update");
26544 staticpro (&Qinhibit_menubar_update);
26545 Qinhibit_eval_during_redisplay = intern_c_string ("inhibit-eval-during-redisplay");
26546 staticpro (&Qinhibit_eval_during_redisplay);
26547 Qposition = intern_c_string ("position");
26548 staticpro (&Qposition);
26549 Qbuffer_position = intern_c_string ("buffer-position");
26550 staticpro (&Qbuffer_position);
26551 Qobject = intern_c_string ("object");
26552 staticpro (&Qobject);
26553 Qbar = intern_c_string ("bar");
26554 staticpro (&Qbar);
26555 Qhbar = intern_c_string ("hbar");
26556 staticpro (&Qhbar);
26557 Qbox = intern_c_string ("box");
26558 staticpro (&Qbox);
26559 Qhollow = intern_c_string ("hollow");
26560 staticpro (&Qhollow);
26561 Qhand = intern_c_string ("hand");
26562 staticpro (&Qhand);
26563 Qarrow = intern_c_string ("arrow");
26564 staticpro (&Qarrow);
26565 Qtext = intern_c_string ("text");
26566 staticpro (&Qtext);
26567 Qinhibit_free_realized_faces = intern_c_string ("inhibit-free-realized-faces");
26568 staticpro (&Qinhibit_free_realized_faces);
26570 list_of_error = Fcons (Fcons (intern_c_string ("error"),
26571 Fcons (intern_c_string ("void-variable"), Qnil)),
26572 Qnil);
26573 staticpro (&list_of_error);
26575 Qlast_arrow_position = intern_c_string ("last-arrow-position");
26576 staticpro (&Qlast_arrow_position);
26577 Qlast_arrow_string = intern_c_string ("last-arrow-string");
26578 staticpro (&Qlast_arrow_string);
26580 Qoverlay_arrow_string = intern_c_string ("overlay-arrow-string");
26581 staticpro (&Qoverlay_arrow_string);
26582 Qoverlay_arrow_bitmap = intern_c_string ("overlay-arrow-bitmap");
26583 staticpro (&Qoverlay_arrow_bitmap);
26585 echo_buffer[0] = echo_buffer[1] = Qnil;
26586 staticpro (&echo_buffer[0]);
26587 staticpro (&echo_buffer[1]);
26589 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
26590 staticpro (&echo_area_buffer[0]);
26591 staticpro (&echo_area_buffer[1]);
26593 Vmessages_buffer_name = make_pure_c_string ("*Messages*");
26594 staticpro (&Vmessages_buffer_name);
26596 mode_line_proptrans_alist = Qnil;
26597 staticpro (&mode_line_proptrans_alist);
26598 mode_line_string_list = Qnil;
26599 staticpro (&mode_line_string_list);
26600 mode_line_string_face = Qnil;
26601 staticpro (&mode_line_string_face);
26602 mode_line_string_face_prop = Qnil;
26603 staticpro (&mode_line_string_face_prop);
26604 Vmode_line_unwind_vector = Qnil;
26605 staticpro (&Vmode_line_unwind_vector);
26607 help_echo_string = Qnil;
26608 staticpro (&help_echo_string);
26609 help_echo_object = Qnil;
26610 staticpro (&help_echo_object);
26611 help_echo_window = Qnil;
26612 staticpro (&help_echo_window);
26613 previous_help_echo_string = Qnil;
26614 staticpro (&previous_help_echo_string);
26615 help_echo_pos = -1;
26617 Qright_to_left = intern_c_string ("right-to-left");
26618 staticpro (&Qright_to_left);
26619 Qleft_to_right = intern_c_string ("left-to-right");
26620 staticpro (&Qleft_to_right);
26622 #ifdef HAVE_WINDOW_SYSTEM
26623 DEFVAR_BOOL ("x-stretch-cursor", x_stretch_cursor_p,
26624 doc: /* *Non-nil means draw block cursor as wide as the glyph under it.
26625 For example, if a block cursor is over a tab, it will be drawn as
26626 wide as that tab on the display. */);
26627 x_stretch_cursor_p = 0;
26628 #endif
26630 DEFVAR_LISP ("show-trailing-whitespace", Vshow_trailing_whitespace,
26631 doc: /* *Non-nil means highlight trailing whitespace.
26632 The face used for trailing whitespace is `trailing-whitespace'. */);
26633 Vshow_trailing_whitespace = Qnil;
26635 DEFVAR_LISP ("nobreak-char-display", Vnobreak_char_display,
26636 doc: /* *Control highlighting of nobreak space and soft hyphen.
26637 A value of t means highlight the character itself (for nobreak space,
26638 use face `nobreak-space').
26639 A value of nil means no highlighting.
26640 Other values mean display the escape glyph followed by an ordinary
26641 space or ordinary hyphen. */);
26642 Vnobreak_char_display = Qt;
26644 DEFVAR_LISP ("void-text-area-pointer", Vvoid_text_area_pointer,
26645 doc: /* *The pointer shape to show in void text areas.
26646 A value of nil means to show the text pointer. Other options are `arrow',
26647 `text', `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
26648 Vvoid_text_area_pointer = Qarrow;
26650 DEFVAR_LISP ("inhibit-redisplay", Vinhibit_redisplay,
26651 doc: /* Non-nil means don't actually do any redisplay.
26652 This is used for internal purposes. */);
26653 Vinhibit_redisplay = Qnil;
26655 DEFVAR_LISP ("global-mode-string", Vglobal_mode_string,
26656 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
26657 Vglobal_mode_string = Qnil;
26659 DEFVAR_LISP ("overlay-arrow-position", Voverlay_arrow_position,
26660 doc: /* Marker for where to display an arrow on top of the buffer text.
26661 This must be the beginning of a line in order to work.
26662 See also `overlay-arrow-string'. */);
26663 Voverlay_arrow_position = Qnil;
26665 DEFVAR_LISP ("overlay-arrow-string", Voverlay_arrow_string,
26666 doc: /* String to display as an arrow in non-window frames.
26667 See also `overlay-arrow-position'. */);
26668 Voverlay_arrow_string = make_pure_c_string ("=>");
26670 DEFVAR_LISP ("overlay-arrow-variable-list", Voverlay_arrow_variable_list,
26671 doc: /* List of variables (symbols) which hold markers for overlay arrows.
26672 The symbols on this list are examined during redisplay to determine
26673 where to display overlay arrows. */);
26674 Voverlay_arrow_variable_list
26675 = Fcons (intern_c_string ("overlay-arrow-position"), Qnil);
26677 DEFVAR_INT ("scroll-step", emacs_scroll_step,
26678 doc: /* *The number of lines to try scrolling a window by when point moves out.
26679 If that fails to bring point back on frame, point is centered instead.
26680 If this is zero, point is always centered after it moves off frame.
26681 If you want scrolling to always be a line at a time, you should set
26682 `scroll-conservatively' to a large value rather than set this to 1. */);
26684 DEFVAR_INT ("scroll-conservatively", scroll_conservatively,
26685 doc: /* *Scroll up to this many lines, to bring point back on screen.
26686 If point moves off-screen, redisplay will scroll by up to
26687 `scroll-conservatively' lines in order to bring point just barely
26688 onto the screen again. If that cannot be done, then redisplay
26689 recenters point as usual.
26691 If the value is greater than 100, redisplay will never recenter point,
26692 but will always scroll just enough text to bring point into view, even
26693 if you move far away.
26695 A value of zero means always recenter point if it moves off screen. */);
26696 scroll_conservatively = 0;
26698 DEFVAR_INT ("scroll-margin", scroll_margin,
26699 doc: /* *Number of lines of margin at the top and bottom of a window.
26700 Recenter the window whenever point gets within this many lines
26701 of the top or bottom of the window. */);
26702 scroll_margin = 0;
26704 DEFVAR_LISP ("display-pixels-per-inch", Vdisplay_pixels_per_inch,
26705 doc: /* Pixels per inch value for non-window system displays.
26706 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
26707 Vdisplay_pixels_per_inch = make_float (72.0);
26709 #if GLYPH_DEBUG
26710 DEFVAR_INT ("debug-end-pos", debug_end_pos, doc: /* Don't ask. */);
26711 #endif
26713 DEFVAR_LISP ("truncate-partial-width-windows",
26714 Vtruncate_partial_width_windows,
26715 doc: /* Non-nil means truncate lines in windows narrower than the frame.
26716 For an integer value, truncate lines in each window narrower than the
26717 full frame width, provided the window width is less than that integer;
26718 otherwise, respect the value of `truncate-lines'.
26720 For any other non-nil value, truncate lines in all windows that do
26721 not span the full frame width.
26723 A value of nil means to respect the value of `truncate-lines'.
26725 If `word-wrap' is enabled, you might want to reduce this. */);
26726 Vtruncate_partial_width_windows = make_number (50);
26728 DEFVAR_BOOL ("mode-line-inverse-video", mode_line_inverse_video,
26729 doc: /* When nil, display the mode-line/header-line/menu-bar in the default face.
26730 Any other value means to use the appropriate face, `mode-line',
26731 `header-line', or `menu' respectively. */);
26732 mode_line_inverse_video = 1;
26734 DEFVAR_LISP ("line-number-display-limit", Vline_number_display_limit,
26735 doc: /* *Maximum buffer size for which line number should be displayed.
26736 If the buffer is bigger than this, the line number does not appear
26737 in the mode line. A value of nil means no limit. */);
26738 Vline_number_display_limit = Qnil;
26740 DEFVAR_INT ("line-number-display-limit-width",
26741 line_number_display_limit_width,
26742 doc: /* *Maximum line width (in characters) for line number display.
26743 If the average length of the lines near point is bigger than this, then the
26744 line number may be omitted from the mode line. */);
26745 line_number_display_limit_width = 200;
26747 DEFVAR_BOOL ("highlight-nonselected-windows", highlight_nonselected_windows,
26748 doc: /* *Non-nil means highlight region even in nonselected windows. */);
26749 highlight_nonselected_windows = 0;
26751 DEFVAR_BOOL ("multiple-frames", multiple_frames,
26752 doc: /* Non-nil if more than one frame is visible on this display.
26753 Minibuffer-only frames don't count, but iconified frames do.
26754 This variable is not guaranteed to be accurate except while processing
26755 `frame-title-format' and `icon-title-format'. */);
26757 DEFVAR_LISP ("frame-title-format", Vframe_title_format,
26758 doc: /* Template for displaying the title bar of visible frames.
26759 \(Assuming the window manager supports this feature.)
26761 This variable has the same structure as `mode-line-format', except that
26762 the %c and %l constructs are ignored. It is used only on frames for
26763 which no explicit name has been set \(see `modify-frame-parameters'). */);
26765 DEFVAR_LISP ("icon-title-format", Vicon_title_format,
26766 doc: /* Template for displaying the title bar of an iconified frame.
26767 \(Assuming the window manager supports this feature.)
26768 This variable has the same structure as `mode-line-format' (which see),
26769 and is used only on frames for which no explicit name has been set
26770 \(see `modify-frame-parameters'). */);
26771 Vicon_title_format
26772 = Vframe_title_format
26773 = pure_cons (intern_c_string ("multiple-frames"),
26774 pure_cons (make_pure_c_string ("%b"),
26775 pure_cons (pure_cons (empty_unibyte_string,
26776 pure_cons (intern_c_string ("invocation-name"),
26777 pure_cons (make_pure_c_string ("@"),
26778 pure_cons (intern_c_string ("system-name"),
26779 Qnil)))),
26780 Qnil)));
26782 DEFVAR_LISP ("message-log-max", Vmessage_log_max,
26783 doc: /* Maximum number of lines to keep in the message log buffer.
26784 If nil, disable message logging. If t, log messages but don't truncate
26785 the buffer when it becomes large. */);
26786 Vmessage_log_max = make_number (100);
26788 DEFVAR_LISP ("window-size-change-functions", Vwindow_size_change_functions,
26789 doc: /* Functions called before redisplay, if window sizes have changed.
26790 The value should be a list of functions that take one argument.
26791 Just before redisplay, for each frame, if any of its windows have changed
26792 size since the last redisplay, or have been split or deleted,
26793 all the functions in the list are called, with the frame as argument. */);
26794 Vwindow_size_change_functions = Qnil;
26796 DEFVAR_LISP ("window-scroll-functions", Vwindow_scroll_functions,
26797 doc: /* List of functions to call before redisplaying a window with scrolling.
26798 Each function is called with two arguments, the window and its new
26799 display-start position. Note that these functions are also called by
26800 `set-window-buffer'. Also note that the value of `window-end' is not
26801 valid when these functions are called. */);
26802 Vwindow_scroll_functions = Qnil;
26804 DEFVAR_LISP ("window-text-change-functions",
26805 Vwindow_text_change_functions,
26806 doc: /* Functions to call in redisplay when text in the window might change. */);
26807 Vwindow_text_change_functions = Qnil;
26809 DEFVAR_LISP ("redisplay-end-trigger-functions", Vredisplay_end_trigger_functions,
26810 doc: /* Functions called when redisplay of a window reaches the end trigger.
26811 Each function is called with two arguments, the window and the end trigger value.
26812 See `set-window-redisplay-end-trigger'. */);
26813 Vredisplay_end_trigger_functions = Qnil;
26815 DEFVAR_LISP ("mouse-autoselect-window", Vmouse_autoselect_window,
26816 doc: /* *Non-nil means autoselect window with mouse pointer.
26817 If nil, do not autoselect windows.
26818 A positive number means delay autoselection by that many seconds: a
26819 window is autoselected only after the mouse has remained in that
26820 window for the duration of the delay.
26821 A negative number has a similar effect, but causes windows to be
26822 autoselected only after the mouse has stopped moving. \(Because of
26823 the way Emacs compares mouse events, you will occasionally wait twice
26824 that time before the window gets selected.\)
26825 Any other value means to autoselect window instantaneously when the
26826 mouse pointer enters it.
26828 Autoselection selects the minibuffer only if it is active, and never
26829 unselects the minibuffer if it is active.
26831 When customizing this variable make sure that the actual value of
26832 `focus-follows-mouse' matches the behavior of your window manager. */);
26833 Vmouse_autoselect_window = Qnil;
26835 DEFVAR_LISP ("auto-resize-tool-bars", Vauto_resize_tool_bars,
26836 doc: /* *Non-nil means automatically resize tool-bars.
26837 This dynamically changes the tool-bar's height to the minimum height
26838 that is needed to make all tool-bar items visible.
26839 If value is `grow-only', the tool-bar's height is only increased
26840 automatically; to decrease the tool-bar height, use \\[recenter]. */);
26841 Vauto_resize_tool_bars = Qt;
26843 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", auto_raise_tool_bar_buttons_p,
26844 doc: /* *Non-nil means raise tool-bar buttons when the mouse moves over them. */);
26845 auto_raise_tool_bar_buttons_p = 1;
26847 DEFVAR_BOOL ("make-cursor-line-fully-visible", make_cursor_line_fully_visible_p,
26848 doc: /* *Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
26849 make_cursor_line_fully_visible_p = 1;
26851 DEFVAR_LISP ("tool-bar-border", Vtool_bar_border,
26852 doc: /* *Border below tool-bar in pixels.
26853 If an integer, use it as the height of the border.
26854 If it is one of `internal-border-width' or `border-width', use the
26855 value of the corresponding frame parameter.
26856 Otherwise, no border is added below the tool-bar. */);
26857 Vtool_bar_border = Qinternal_border_width;
26859 DEFVAR_LISP ("tool-bar-button-margin", Vtool_bar_button_margin,
26860 doc: /* *Margin around tool-bar buttons in pixels.
26861 If an integer, use that for both horizontal and vertical margins.
26862 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
26863 HORZ specifying the horizontal margin, and VERT specifying the
26864 vertical margin. */);
26865 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
26867 DEFVAR_INT ("tool-bar-button-relief", tool_bar_button_relief,
26868 doc: /* *Relief thickness of tool-bar buttons. */);
26869 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
26871 DEFVAR_LISP ("tool-bar-style", Vtool_bar_style,
26872 doc: /* Tool bar style to use.
26873 It can be one of
26874 image - show images only
26875 text - show text only
26876 both - show both, text below image
26877 both-horiz - show text to the right of the image
26878 text-image-horiz - show text to the left of the image
26879 any other - use system default or image if no system default. */);
26880 Vtool_bar_style = Qnil;
26882 DEFVAR_INT ("tool-bar-max-label-size", tool_bar_max_label_size,
26883 doc: /* *Maximum number of characters a label can have to be shown.
26884 The tool bar style must also show labels for this to have any effect, see
26885 `tool-bar-style'. */);
26886 tool_bar_max_label_size = DEFAULT_TOOL_BAR_LABEL_SIZE;
26888 DEFVAR_LISP ("fontification-functions", Vfontification_functions,
26889 doc: /* List of functions to call to fontify regions of text.
26890 Each function is called with one argument POS. Functions must
26891 fontify a region starting at POS in the current buffer, and give
26892 fontified regions the property `fontified'. */);
26893 Vfontification_functions = Qnil;
26894 Fmake_variable_buffer_local (Qfontification_functions);
26896 DEFVAR_BOOL ("unibyte-display-via-language-environment",
26897 unibyte_display_via_language_environment,
26898 doc: /* *Non-nil means display unibyte text according to language environment.
26899 Specifically, this means that raw bytes in the range 160-255 decimal
26900 are displayed by converting them to the equivalent multibyte characters
26901 according to the current language environment. As a result, they are
26902 displayed according to the current fontset.
26904 Note that this variable affects only how these bytes are displayed,
26905 but does not change the fact they are interpreted as raw bytes. */);
26906 unibyte_display_via_language_environment = 0;
26908 DEFVAR_LISP ("max-mini-window-height", Vmax_mini_window_height,
26909 doc: /* *Maximum height for resizing mini-windows.
26910 If a float, it specifies a fraction of the mini-window frame's height.
26911 If an integer, it specifies a number of lines. */);
26912 Vmax_mini_window_height = make_float (0.25);
26914 DEFVAR_LISP ("resize-mini-windows", Vresize_mini_windows,
26915 doc: /* *How to resize mini-windows.
26916 A value of nil means don't automatically resize mini-windows.
26917 A value of t means resize them to fit the text displayed in them.
26918 A value of `grow-only', the default, means let mini-windows grow
26919 only, until their display becomes empty, at which point the windows
26920 go back to their normal size. */);
26921 Vresize_mini_windows = Qgrow_only;
26923 DEFVAR_LISP ("blink-cursor-alist", Vblink_cursor_alist,
26924 doc: /* Alist specifying how to blink the cursor off.
26925 Each element has the form (ON-STATE . OFF-STATE). Whenever the
26926 `cursor-type' frame-parameter or variable equals ON-STATE,
26927 comparing using `equal', Emacs uses OFF-STATE to specify
26928 how to blink it off. ON-STATE and OFF-STATE are values for
26929 the `cursor-type' frame parameter.
26931 If a frame's ON-STATE has no entry in this list,
26932 the frame's other specifications determine how to blink the cursor off. */);
26933 Vblink_cursor_alist = Qnil;
26935 DEFVAR_BOOL ("auto-hscroll-mode", automatic_hscrolling_p,
26936 doc: /* Allow or disallow automatic horizontal scrolling of windows.
26937 If non-nil, windows are automatically scrolled horizontally to make
26938 point visible. */);
26939 automatic_hscrolling_p = 1;
26940 Qauto_hscroll_mode = intern_c_string ("auto-hscroll-mode");
26941 staticpro (&Qauto_hscroll_mode);
26943 DEFVAR_INT ("hscroll-margin", hscroll_margin,
26944 doc: /* *How many columns away from the window edge point is allowed to get
26945 before automatic hscrolling will horizontally scroll the window. */);
26946 hscroll_margin = 5;
26948 DEFVAR_LISP ("hscroll-step", Vhscroll_step,
26949 doc: /* *How many columns to scroll the window when point gets too close to the edge.
26950 When point is less than `hscroll-margin' columns from the window
26951 edge, automatic hscrolling will scroll the window by the amount of columns
26952 determined by this variable. If its value is a positive integer, scroll that
26953 many columns. If it's a positive floating-point number, it specifies the
26954 fraction of the window's width to scroll. If it's nil or zero, point will be
26955 centered horizontally after the scroll. Any other value, including negative
26956 numbers, are treated as if the value were zero.
26958 Automatic hscrolling always moves point outside the scroll margin, so if
26959 point was more than scroll step columns inside the margin, the window will
26960 scroll more than the value given by the scroll step.
26962 Note that the lower bound for automatic hscrolling specified by `scroll-left'
26963 and `scroll-right' overrides this variable's effect. */);
26964 Vhscroll_step = make_number (0);
26966 DEFVAR_BOOL ("message-truncate-lines", message_truncate_lines,
26967 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
26968 Bind this around calls to `message' to let it take effect. */);
26969 message_truncate_lines = 0;
26971 DEFVAR_LISP ("menu-bar-update-hook", Vmenu_bar_update_hook,
26972 doc: /* Normal hook run to update the menu bar definitions.
26973 Redisplay runs this hook before it redisplays the menu bar.
26974 This is used to update submenus such as Buffers,
26975 whose contents depend on various data. */);
26976 Vmenu_bar_update_hook = Qnil;
26978 DEFVAR_LISP ("menu-updating-frame", Vmenu_updating_frame,
26979 doc: /* Frame for which we are updating a menu.
26980 The enable predicate for a menu binding should check this variable. */);
26981 Vmenu_updating_frame = Qnil;
26983 DEFVAR_BOOL ("inhibit-menubar-update", inhibit_menubar_update,
26984 doc: /* Non-nil means don't update menu bars. Internal use only. */);
26985 inhibit_menubar_update = 0;
26987 DEFVAR_LISP ("wrap-prefix", Vwrap_prefix,
26988 doc: /* Prefix prepended to all continuation lines at display time.
26989 The value may be a string, an image, or a stretch-glyph; it is
26990 interpreted in the same way as the value of a `display' text property.
26992 This variable is overridden by any `wrap-prefix' text or overlay
26993 property.
26995 To add a prefix to non-continuation lines, use `line-prefix'. */);
26996 Vwrap_prefix = Qnil;
26997 staticpro (&Qwrap_prefix);
26998 Qwrap_prefix = intern_c_string ("wrap-prefix");
26999 Fmake_variable_buffer_local (Qwrap_prefix);
27001 DEFVAR_LISP ("line-prefix", Vline_prefix,
27002 doc: /* Prefix prepended to all non-continuation lines at display time.
27003 The value may be a string, an image, or a stretch-glyph; it is
27004 interpreted in the same way as the value of a `display' text property.
27006 This variable is overridden by any `line-prefix' text or overlay
27007 property.
27009 To add a prefix to continuation lines, use `wrap-prefix'. */);
27010 Vline_prefix = Qnil;
27011 staticpro (&Qline_prefix);
27012 Qline_prefix = intern_c_string ("line-prefix");
27013 Fmake_variable_buffer_local (Qline_prefix);
27015 DEFVAR_BOOL ("inhibit-eval-during-redisplay", inhibit_eval_during_redisplay,
27016 doc: /* Non-nil means don't eval Lisp during redisplay. */);
27017 inhibit_eval_during_redisplay = 0;
27019 DEFVAR_BOOL ("inhibit-free-realized-faces", inhibit_free_realized_faces,
27020 doc: /* Non-nil means don't free realized faces. Internal use only. */);
27021 inhibit_free_realized_faces = 0;
27023 #if GLYPH_DEBUG
27024 DEFVAR_BOOL ("inhibit-try-window-id", inhibit_try_window_id,
27025 doc: /* Inhibit try_window_id display optimization. */);
27026 inhibit_try_window_id = 0;
27028 DEFVAR_BOOL ("inhibit-try-window-reusing", inhibit_try_window_reusing,
27029 doc: /* Inhibit try_window_reusing display optimization. */);
27030 inhibit_try_window_reusing = 0;
27032 DEFVAR_BOOL ("inhibit-try-cursor-movement", inhibit_try_cursor_movement,
27033 doc: /* Inhibit try_cursor_movement display optimization. */);
27034 inhibit_try_cursor_movement = 0;
27035 #endif /* GLYPH_DEBUG */
27037 DEFVAR_INT ("overline-margin", overline_margin,
27038 doc: /* *Space between overline and text, in pixels.
27039 The default value is 2: the height of the overline (1 pixel) plus 1 pixel
27040 margin to the caracter height. */);
27041 overline_margin = 2;
27043 DEFVAR_INT ("underline-minimum-offset",
27044 underline_minimum_offset,
27045 doc: /* Minimum distance between baseline and underline.
27046 This can improve legibility of underlined text at small font sizes,
27047 particularly when using variable `x-use-underline-position-properties'
27048 with fonts that specify an UNDERLINE_POSITION relatively close to the
27049 baseline. The default value is 1. */);
27050 underline_minimum_offset = 1;
27052 DEFVAR_BOOL ("display-hourglass", display_hourglass_p,
27053 doc: /* Non-nil means show an hourglass pointer, when Emacs is busy.
27054 This feature only works when on a window system that can change
27055 cursor shapes. */);
27056 display_hourglass_p = 1;
27058 DEFVAR_LISP ("hourglass-delay", Vhourglass_delay,
27059 doc: /* *Seconds to wait before displaying an hourglass pointer when Emacs is busy. */);
27060 Vhourglass_delay = make_number (DEFAULT_HOURGLASS_DELAY);
27062 hourglass_atimer = NULL;
27063 hourglass_shown_p = 0;
27065 DEFSYM (Qglyphless_char, "glyphless-char");
27066 DEFSYM (Qhex_code, "hex-code");
27067 DEFSYM (Qempty_box, "empty-box");
27068 DEFSYM (Qthin_space, "thin-space");
27069 DEFSYM (Qzero_width, "zero-width");
27071 DEFSYM (Qglyphless_char_display, "glyphless-char-display");
27072 /* Intern this now in case it isn't already done.
27073 Setting this variable twice is harmless.
27074 But don't staticpro it here--that is done in alloc.c. */
27075 Qchar_table_extra_slots = intern_c_string ("char-table-extra-slots");
27076 Fput (Qglyphless_char_display, Qchar_table_extra_slots, make_number (1));
27078 DEFVAR_LISP ("glyphless-char-display", Vglyphless_char_display,
27079 doc: /* Char-table defining glyphless characters.
27080 Each element, if non-nil, should be one of the following:
27081 an ASCII acronym string: display this string in a box
27082 `hex-code': display the hexadecimal code of a character in a box
27083 `empty-box': display as an empty box
27084 `thin-space': display as 1-pixel width space
27085 `zero-width': don't display
27086 An element may also be a cons cell (GRAPHICAL . TEXT), which specifies the
27087 display method for graphical terminals and text terminals respectively.
27088 GRAPHICAL and TEXT should each have one of the values listed above.
27090 The char-table has one extra slot to control the display of a character for
27091 which no font is found. This slot only takes effect on graphical terminals.
27092 Its value should be an ASCII acronym string, `hex-code', `empty-box', or
27093 `thin-space'. The default is `empty-box'. */);
27094 Vglyphless_char_display = Fmake_char_table (Qglyphless_char_display, Qnil);
27095 Fset_char_table_extra_slot (Vglyphless_char_display, make_number (0),
27096 Qempty_box);
27100 /* Initialize this module when Emacs starts. */
27102 void
27103 init_xdisp (void)
27105 Lisp_Object root_window;
27106 struct window *mini_w;
27108 current_header_line_height = current_mode_line_height = -1;
27110 CHARPOS (this_line_start_pos) = 0;
27112 mini_w = XWINDOW (minibuf_window);
27113 root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w)));
27114 echo_area_window = minibuf_window;
27116 if (!noninteractive)
27118 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (root_window)));
27119 int i;
27121 XWINDOW (root_window)->top_line = make_number (FRAME_TOP_MARGIN (f));
27122 set_window_height (root_window,
27123 FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f),
27125 mini_w->top_line = make_number (FRAME_LINES (f) - 1);
27126 set_window_height (minibuf_window, 1, 0);
27128 XWINDOW (root_window)->total_cols = make_number (FRAME_COLS (f));
27129 mini_w->total_cols = make_number (FRAME_COLS (f));
27131 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
27132 scratch_glyph_row.glyphs[TEXT_AREA + 1]
27133 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
27135 /* The default ellipsis glyphs `...'. */
27136 for (i = 0; i < 3; ++i)
27137 default_invis_vector[i] = make_number ('.');
27141 /* Allocate the buffer for frame titles.
27142 Also used for `format-mode-line'. */
27143 int size = 100;
27144 mode_line_noprop_buf = (char *) xmalloc (size);
27145 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
27146 mode_line_noprop_ptr = mode_line_noprop_buf;
27147 mode_line_target = MODE_LINE_DISPLAY;
27150 help_echo_showing_p = 0;
27153 /* Since w32 does not support atimers, it defines its own implementation of
27154 the following three functions in w32fns.c. */
27155 #ifndef WINDOWSNT
27157 /* Platform-independent portion of hourglass implementation. */
27159 /* Return non-zero if houglass timer has been started or hourglass is shown. */
27161 hourglass_started (void)
27163 return hourglass_shown_p || hourglass_atimer != NULL;
27166 /* Cancel a currently active hourglass timer, and start a new one. */
27167 void
27168 start_hourglass (void)
27170 #if defined (HAVE_WINDOW_SYSTEM)
27171 EMACS_TIME delay;
27172 int secs, usecs = 0;
27174 cancel_hourglass ();
27176 if (INTEGERP (Vhourglass_delay)
27177 && XINT (Vhourglass_delay) > 0)
27178 secs = XFASTINT (Vhourglass_delay);
27179 else if (FLOATP (Vhourglass_delay)
27180 && XFLOAT_DATA (Vhourglass_delay) > 0)
27182 Lisp_Object tem;
27183 tem = Ftruncate (Vhourglass_delay, Qnil);
27184 secs = XFASTINT (tem);
27185 usecs = (XFLOAT_DATA (Vhourglass_delay) - secs) * 1000000;
27187 else
27188 secs = DEFAULT_HOURGLASS_DELAY;
27190 EMACS_SET_SECS_USECS (delay, secs, usecs);
27191 hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
27192 show_hourglass, NULL);
27193 #endif
27197 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
27198 shown. */
27199 void
27200 cancel_hourglass (void)
27202 #if defined (HAVE_WINDOW_SYSTEM)
27203 if (hourglass_atimer)
27205 cancel_atimer (hourglass_atimer);
27206 hourglass_atimer = NULL;
27209 if (hourglass_shown_p)
27210 hide_hourglass ();
27211 #endif
27213 #endif /* ! WINDOWSNT */