src/ChangeLog: Fix format.
[emacs.git] / src / xdisp.c
blob9d3e501787bcac806f97235ac28e38a308cd26c2
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 passing it the buffer position where to start iteration. For
134 iteration over strings, pass -1 as the position to init_iterator,
135 and call reseat_to_string when the string is ready, to initialize
136 the iterator for that string. Thereafter, calls to
137 get_next_display_element fill the iterator structure with relevant
138 information about the next thing to display. Calls to
139 set_iterator_to_next move the iterator to the next thing.
141 Besides this, an iterator also contains information about the
142 display environment in which glyphs for display elements are to be
143 produced. It has fields for the width and height of the display,
144 the information whether long lines are truncated or continued, a
145 current X and Y position, and lots of other stuff you can better
146 see in dispextern.h.
148 Glyphs in a desired matrix are normally constructed in a loop
149 calling get_next_display_element and then PRODUCE_GLYPHS. The call
150 to PRODUCE_GLYPHS will fill the iterator structure with pixel
151 information about the element being displayed and at the same time
152 produce glyphs for it. If the display element fits on the line
153 being displayed, set_iterator_to_next is called next, otherwise the
154 glyphs produced are discarded. The function display_line is the
155 workhorse of filling glyph rows in the desired matrix with glyphs.
156 In addition to producing glyphs, it also handles line truncation
157 and continuation, word wrap, and cursor positioning (for the
158 latter, see also set_cursor_from_row).
160 Frame matrices.
162 That just couldn't be all, could it? What about terminal types not
163 supporting operations on sub-windows of the screen? To update the
164 display on such a terminal, window-based glyph matrices are not
165 well suited. To be able to reuse part of the display (scrolling
166 lines up and down), we must instead have a view of the whole
167 screen. This is what `frame matrices' are for. They are a trick.
169 Frames on terminals like above have a glyph pool. Windows on such
170 a frame sub-allocate their glyph memory from their frame's glyph
171 pool. The frame itself is given its own glyph matrices. By
172 coincidence---or maybe something else---rows in window glyph
173 matrices are slices of corresponding rows in frame matrices. Thus
174 writing to window matrices implicitly updates a frame matrix which
175 provides us with the view of the whole screen that we originally
176 wanted to have without having to move many bytes around. To be
177 honest, there is a little bit more done, but not much more. If you
178 plan to extend that code, take a look at dispnew.c. The function
179 build_frame_matrix is a good starting point.
181 Bidirectional display.
183 Bidirectional display adds quite some hair to this already complex
184 design. The good news are that a large portion of that hairy stuff
185 is hidden in bidi.c behind only 3 interfaces. bidi.c implements a
186 reordering engine which is called by set_iterator_to_next and
187 returns the next character to display in the visual order. See
188 commentary on bidi.c for more details. As far as redisplay is
189 concerned, the effect of calling bidi_move_to_visually_next, the
190 main interface of the reordering engine, is that the iterator gets
191 magically placed on the buffer or string position that is to be
192 displayed next. In other words, a linear iteration through the
193 buffer/string is replaced with a non-linear one. All the rest of
194 the redisplay is oblivious to the bidi reordering.
196 Well, almost oblivious---there are still complications, most of
197 them due to the fact that buffer and string positions no longer
198 change monotonously with glyph indices in a glyph row. Moreover,
199 for continued lines, the buffer positions may not even be
200 monotonously changing with vertical positions. Also, accounting
201 for face changes, overlays, etc. becomes more complex because
202 non-linear iteration could potentially skip many positions with
203 changes, and then cross them again on the way back...
205 One other prominent effect of bidirectional display is that some
206 paragraphs of text need to be displayed starting at the right
207 margin of the window---the so-called right-to-left, or R2L
208 paragraphs. R2L paragraphs are displayed with R2L glyph rows,
209 which have their reversed_p flag set. The bidi reordering engine
210 produces characters in such rows starting from the character which
211 should be the rightmost on display. PRODUCE_GLYPHS then reverses
212 the order, when it fills up the glyph row whose reversed_p flag is
213 set, by prepending each new glyph to what is already there, instead
214 of appending it. When the glyph row is complete, the function
215 extend_face_to_end_of_line fills the empty space to the left of the
216 leftmost character with special glyphs, which will display as,
217 well, empty. On text terminals, these special glyphs are simply
218 blank characters. On graphics terminals, there's a single stretch
219 glyph of a suitably computed width. Both the blanks and the
220 stretch glyph are given the face of the background of the line.
221 This way, the terminal-specific back-end can still draw the glyphs
222 left to right, even for R2L lines.
224 Bidirectional display and character compositions
226 Some scripts cannot be displayed by drawing each character
227 individually, because adjacent characters change each other's shape
228 on display. For example, Arabic and Indic scripts belong to this
229 category.
231 Emacs display supports this by providing "character compositions",
232 most of which is implemented in composite.c. During the buffer
233 scan that delivers characters to PRODUCE_GLYPHS, if the next
234 character to be delivered is a composed character, the iteration
235 calls composition_reseat_it and next_element_from_composition. If
236 they succeed to compose the character with one or more of the
237 following characters, the whole sequence of characters that where
238 composed is recorded in the `struct composition_it' object that is
239 part of the buffer iterator. The composed sequence could produce
240 one or more font glyphs (called "grapheme clusters") on the screen.
241 Each of these grapheme clusters is then delivered to PRODUCE_GLYPHS
242 in the direction corresponding to the current bidi scan direction
243 (recorded in the scan_dir member of the `struct bidi_it' object
244 that is part of the buffer iterator). In particular, if the bidi
245 iterator currently scans the buffer backwards, the grapheme
246 clusters are delivered back to front. This reorders the grapheme
247 clusters as appropriate for the current bidi context. Note that
248 this means that the grapheme clusters are always stored in the
249 LGSTRING object (see composite.c) in the logical order.
251 Moving an iterator in bidirectional text
252 without producing glyphs
254 Note one important detail mentioned above: that the bidi reordering
255 engine, driven by the iterator, produces characters in R2L rows
256 starting at the character that will be the rightmost on display.
257 As far as the iterator is concerned, the geometry of such rows is
258 still left to right, i.e. the iterator "thinks" the first character
259 is at the leftmost pixel position. The iterator does not know that
260 PRODUCE_GLYPHS reverses the order of the glyphs that the iterator
261 delivers. This is important when functions from the move_it_*
262 family are used to get to certain screen position or to match
263 screen coordinates with buffer coordinates: these functions use the
264 iterator geometry, which is left to right even in R2L paragraphs.
265 This works well with most callers of move_it_*, because they need
266 to get to a specific column, and columns are still numbered in the
267 reading order, i.e. the rightmost character in a R2L paragraph is
268 still column zero. But some callers do not get well with this; a
269 notable example is mouse clicks that need to find the character
270 that corresponds to certain pixel coordinates. See
271 buffer_posn_from_coords in dispnew.c for how this is handled. */
273 #include <config.h>
274 #include <stdio.h>
275 #include <limits.h>
276 #include <setjmp.h>
278 #include "lisp.h"
279 #include "keyboard.h"
280 #include "frame.h"
281 #include "window.h"
282 #include "termchar.h"
283 #include "dispextern.h"
284 #include "buffer.h"
285 #include "character.h"
286 #include "charset.h"
287 #include "indent.h"
288 #include "commands.h"
289 #include "keymap.h"
290 #include "macros.h"
291 #include "disptab.h"
292 #include "termhooks.h"
293 #include "termopts.h"
294 #include "intervals.h"
295 #include "coding.h"
296 #include "process.h"
297 #include "region-cache.h"
298 #include "font.h"
299 #include "fontset.h"
300 #include "blockinput.h"
302 #ifdef HAVE_X_WINDOWS
303 #include "xterm.h"
304 #endif
305 #ifdef WINDOWSNT
306 #include "w32term.h"
307 #endif
308 #ifdef HAVE_NS
309 #include "nsterm.h"
310 #endif
311 #ifdef USE_GTK
312 #include "gtkutil.h"
313 #endif
315 #include "font.h"
317 #ifndef FRAME_X_OUTPUT
318 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
319 #endif
321 #define INFINITY 10000000
323 Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
324 Lisp_Object Qwindow_scroll_functions;
325 static Lisp_Object Qwindow_text_change_functions;
326 static Lisp_Object Qredisplay_end_trigger_functions;
327 Lisp_Object Qinhibit_point_motion_hooks;
328 static Lisp_Object QCeval, QCpropertize;
329 Lisp_Object QCfile, QCdata;
330 static Lisp_Object Qfontified;
331 static Lisp_Object Qgrow_only;
332 static Lisp_Object Qinhibit_eval_during_redisplay;
333 static Lisp_Object Qbuffer_position, Qposition, Qobject;
334 static Lisp_Object Qright_to_left, Qleft_to_right;
336 /* Cursor shapes */
337 Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
339 /* Pointer shapes */
340 static Lisp_Object Qarrow, Qhand;
341 Lisp_Object Qtext;
343 /* Holds the list (error). */
344 static Lisp_Object list_of_error;
346 static Lisp_Object Qfontification_functions;
348 static Lisp_Object Qwrap_prefix;
349 static Lisp_Object Qline_prefix;
351 /* Non-nil means don't actually do any redisplay. */
353 Lisp_Object Qinhibit_redisplay;
355 /* Names of text properties relevant for redisplay. */
357 Lisp_Object Qdisplay;
359 Lisp_Object Qspace, QCalign_to;
360 static Lisp_Object QCrelative_width, QCrelative_height;
361 Lisp_Object Qleft_margin, Qright_margin;
362 static Lisp_Object Qspace_width, Qraise;
363 static Lisp_Object Qslice;
364 Lisp_Object Qcenter;
365 static Lisp_Object Qmargin, Qpointer;
366 static Lisp_Object Qline_height;
368 #ifdef HAVE_WINDOW_SYSTEM
370 /* Test if overflow newline into fringe. Called with iterator IT
371 at or past right window margin, and with IT->current_x set. */
373 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(IT) \
374 (!NILP (Voverflow_newline_into_fringe) \
375 && FRAME_WINDOW_P ((IT)->f) \
376 && ((IT)->bidi_it.paragraph_dir == R2L \
377 ? (WINDOW_LEFT_FRINGE_WIDTH ((IT)->w) > 0) \
378 : (WINDOW_RIGHT_FRINGE_WIDTH ((IT)->w) > 0)) \
379 && (IT)->current_x == (IT)->last_visible_x \
380 && (IT)->line_wrap != WORD_WRAP)
382 #else /* !HAVE_WINDOW_SYSTEM */
383 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) 0
384 #endif /* HAVE_WINDOW_SYSTEM */
386 /* Test if the display element loaded in IT is a space or tab
387 character. This is used to determine word wrapping. */
389 #define IT_DISPLAYING_WHITESPACE(it) \
390 (it->what == IT_CHARACTER && (it->c == ' ' || it->c == '\t'))
392 /* Name of the face used to highlight trailing whitespace. */
394 static Lisp_Object Qtrailing_whitespace;
396 /* Name and number of the face used to highlight escape glyphs. */
398 static Lisp_Object Qescape_glyph;
400 /* Name and number of the face used to highlight non-breaking spaces. */
402 static Lisp_Object Qnobreak_space;
404 /* The symbol `image' which is the car of the lists used to represent
405 images in Lisp. Also a tool bar style. */
407 Lisp_Object Qimage;
409 /* The image map types. */
410 Lisp_Object QCmap;
411 static Lisp_Object QCpointer;
412 static Lisp_Object Qrect, Qcircle, Qpoly;
414 /* Tool bar styles */
415 Lisp_Object Qboth, Qboth_horiz, Qtext_image_horiz;
417 /* Non-zero means print newline to stdout before next mini-buffer
418 message. */
420 int noninteractive_need_newline;
422 /* Non-zero means print newline to message log before next message. */
424 static int message_log_need_newline;
426 /* Three markers that message_dolog uses.
427 It could allocate them itself, but that causes trouble
428 in handling memory-full errors. */
429 static Lisp_Object message_dolog_marker1;
430 static Lisp_Object message_dolog_marker2;
431 static Lisp_Object message_dolog_marker3;
433 /* The buffer position of the first character appearing entirely or
434 partially on the line of the selected window which contains the
435 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
436 redisplay optimization in redisplay_internal. */
438 static struct text_pos this_line_start_pos;
440 /* Number of characters past the end of the line above, including the
441 terminating newline. */
443 static struct text_pos this_line_end_pos;
445 /* The vertical positions and the height of this line. */
447 static int this_line_vpos;
448 static int this_line_y;
449 static int this_line_pixel_height;
451 /* X position at which this display line starts. Usually zero;
452 negative if first character is partially visible. */
454 static int this_line_start_x;
456 /* The smallest character position seen by move_it_* functions as they
457 move across display lines. Used to set MATRIX_ROW_START_CHARPOS of
458 hscrolled lines, see display_line. */
460 static struct text_pos this_line_min_pos;
462 /* Buffer that this_line_.* variables are referring to. */
464 static struct buffer *this_line_buffer;
467 /* Values of those variables at last redisplay are stored as
468 properties on `overlay-arrow-position' symbol. However, if
469 Voverlay_arrow_position is a marker, last-arrow-position is its
470 numerical position. */
472 static Lisp_Object Qlast_arrow_position, Qlast_arrow_string;
474 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
475 properties on a symbol in overlay-arrow-variable-list. */
477 static Lisp_Object Qoverlay_arrow_string, Qoverlay_arrow_bitmap;
479 Lisp_Object Qmenu_bar_update_hook;
481 /* Nonzero if an overlay arrow has been displayed in this window. */
483 static int overlay_arrow_seen;
485 /* Number of windows showing the buffer of the selected window (or
486 another buffer with the same base buffer). keyboard.c refers to
487 this. */
489 int buffer_shared;
491 /* Vector containing glyphs for an ellipsis `...'. */
493 static Lisp_Object default_invis_vector[3];
495 /* This is the window where the echo area message was displayed. It
496 is always a mini-buffer window, but it may not be the same window
497 currently active as a mini-buffer. */
499 Lisp_Object echo_area_window;
501 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
502 pushes the current message and the value of
503 message_enable_multibyte on the stack, the function restore_message
504 pops the stack and displays MESSAGE again. */
506 static Lisp_Object Vmessage_stack;
508 /* Nonzero means multibyte characters were enabled when the echo area
509 message was specified. */
511 static int message_enable_multibyte;
513 /* Nonzero if we should redraw the mode lines on the next redisplay. */
515 int update_mode_lines;
517 /* Nonzero if window sizes or contents have changed since last
518 redisplay that finished. */
520 int windows_or_buffers_changed;
522 /* Nonzero means a frame's cursor type has been changed. */
524 int cursor_type_changed;
526 /* Nonzero after display_mode_line if %l was used and it displayed a
527 line number. */
529 static int line_number_displayed;
531 /* The name of the *Messages* buffer, a string. */
533 static Lisp_Object Vmessages_buffer_name;
535 /* Current, index 0, and last displayed echo area message. Either
536 buffers from echo_buffers, or nil to indicate no message. */
538 Lisp_Object echo_area_buffer[2];
540 /* The buffers referenced from echo_area_buffer. */
542 static Lisp_Object echo_buffer[2];
544 /* A vector saved used in with_area_buffer to reduce consing. */
546 static Lisp_Object Vwith_echo_area_save_vector;
548 /* Non-zero means display_echo_area should display the last echo area
549 message again. Set by redisplay_preserve_echo_area. */
551 static int display_last_displayed_message_p;
553 /* Nonzero if echo area is being used by print; zero if being used by
554 message. */
556 static int message_buf_print;
558 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
560 static Lisp_Object Qinhibit_menubar_update;
561 static Lisp_Object Qmessage_truncate_lines;
563 /* Set to 1 in clear_message to make redisplay_internal aware
564 of an emptied echo area. */
566 static int message_cleared_p;
568 /* A scratch glyph row with contents used for generating truncation
569 glyphs. Also used in direct_output_for_insert. */
571 #define MAX_SCRATCH_GLYPHS 100
572 static struct glyph_row scratch_glyph_row;
573 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
575 /* Ascent and height of the last line processed by move_it_to. */
577 static int last_max_ascent, last_height;
579 /* Non-zero if there's a help-echo in the echo area. */
581 int help_echo_showing_p;
583 /* If >= 0, computed, exact values of mode-line and header-line height
584 to use in the macros CURRENT_MODE_LINE_HEIGHT and
585 CURRENT_HEADER_LINE_HEIGHT. */
587 int current_mode_line_height, current_header_line_height;
589 /* The maximum distance to look ahead for text properties. Values
590 that are too small let us call compute_char_face and similar
591 functions too often which is expensive. Values that are too large
592 let us call compute_char_face and alike too often because we
593 might not be interested in text properties that far away. */
595 #define TEXT_PROP_DISTANCE_LIMIT 100
597 /* SAVE_IT and RESTORE_IT are called when we save a snapshot of the
598 iterator state and later restore it. This is needed because the
599 bidi iterator on bidi.c keeps a stacked cache of its states, which
600 is really a singleton. When we use scratch iterator objects to
601 move around the buffer, we can cause the bidi cache to be pushed or
602 popped, and therefore we need to restore the cache state when we
603 return to the original iterator. */
604 #define SAVE_IT(ITCOPY,ITORIG,CACHE) \
605 do { \
606 if (CACHE) \
607 xfree (CACHE); \
608 ITCOPY = ITORIG; \
609 CACHE = bidi_shelve_cache(); \
610 } while (0)
612 #define RESTORE_IT(pITORIG,pITCOPY,CACHE) \
613 do { \
614 if (pITORIG != pITCOPY) \
615 *(pITORIG) = *(pITCOPY); \
616 bidi_unshelve_cache (CACHE); \
617 CACHE = NULL; \
618 } while (0)
620 #if GLYPH_DEBUG
622 /* Non-zero means print traces of redisplay if compiled with
623 GLYPH_DEBUG != 0. */
625 int trace_redisplay_p;
627 #endif /* GLYPH_DEBUG */
629 #ifdef DEBUG_TRACE_MOVE
630 /* Non-zero means trace with TRACE_MOVE to stderr. */
631 int trace_move;
633 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
634 #else
635 #define TRACE_MOVE(x) (void) 0
636 #endif
638 static Lisp_Object Qauto_hscroll_mode;
640 /* Buffer being redisplayed -- for redisplay_window_error. */
642 static struct buffer *displayed_buffer;
644 /* Value returned from text property handlers (see below). */
646 enum prop_handled
648 HANDLED_NORMALLY,
649 HANDLED_RECOMPUTE_PROPS,
650 HANDLED_OVERLAY_STRING_CONSUMED,
651 HANDLED_RETURN
654 /* A description of text properties that redisplay is interested
655 in. */
657 struct props
659 /* The name of the property. */
660 Lisp_Object *name;
662 /* A unique index for the property. */
663 enum prop_idx idx;
665 /* A handler function called to set up iterator IT from the property
666 at IT's current position. Value is used to steer handle_stop. */
667 enum prop_handled (*handler) (struct it *it);
670 static enum prop_handled handle_face_prop (struct it *);
671 static enum prop_handled handle_invisible_prop (struct it *);
672 static enum prop_handled handle_display_prop (struct it *);
673 static enum prop_handled handle_composition_prop (struct it *);
674 static enum prop_handled handle_overlay_change (struct it *);
675 static enum prop_handled handle_fontified_prop (struct it *);
677 /* Properties handled by iterators. */
679 static struct props it_props[] =
681 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
682 /* Handle `face' before `display' because some sub-properties of
683 `display' need to know the face. */
684 {&Qface, FACE_PROP_IDX, handle_face_prop},
685 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
686 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
687 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
688 {NULL, 0, NULL}
691 /* Value is the position described by X. If X is a marker, value is
692 the marker_position of X. Otherwise, value is X. */
694 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
696 /* Enumeration returned by some move_it_.* functions internally. */
698 enum move_it_result
700 /* Not used. Undefined value. */
701 MOVE_UNDEFINED,
703 /* Move ended at the requested buffer position or ZV. */
704 MOVE_POS_MATCH_OR_ZV,
706 /* Move ended at the requested X pixel position. */
707 MOVE_X_REACHED,
709 /* Move within a line ended at the end of a line that must be
710 continued. */
711 MOVE_LINE_CONTINUED,
713 /* Move within a line ended at the end of a line that would
714 be displayed truncated. */
715 MOVE_LINE_TRUNCATED,
717 /* Move within a line ended at a line end. */
718 MOVE_NEWLINE_OR_CR
721 /* This counter is used to clear the face cache every once in a while
722 in redisplay_internal. It is incremented for each redisplay.
723 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
724 cleared. */
726 #define CLEAR_FACE_CACHE_COUNT 500
727 static int clear_face_cache_count;
729 /* Similarly for the image cache. */
731 #ifdef HAVE_WINDOW_SYSTEM
732 #define CLEAR_IMAGE_CACHE_COUNT 101
733 static int clear_image_cache_count;
735 /* Null glyph slice */
736 static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 };
737 #endif
739 /* Non-zero while redisplay_internal is in progress. */
741 int redisplaying_p;
743 static Lisp_Object Qinhibit_free_realized_faces;
745 /* If a string, XTread_socket generates an event to display that string.
746 (The display is done in read_char.) */
748 Lisp_Object help_echo_string;
749 Lisp_Object help_echo_window;
750 Lisp_Object help_echo_object;
751 EMACS_INT help_echo_pos;
753 /* Temporary variable for XTread_socket. */
755 Lisp_Object previous_help_echo_string;
757 /* Platform-independent portion of hourglass implementation. */
759 /* Non-zero means an hourglass cursor is currently shown. */
760 int hourglass_shown_p;
762 /* If non-null, an asynchronous timer that, when it expires, displays
763 an hourglass cursor on all frames. */
764 struct atimer *hourglass_atimer;
766 /* Name of the face used to display glyphless characters. */
767 Lisp_Object Qglyphless_char;
769 /* Symbol for the purpose of Vglyphless_char_display. */
770 static Lisp_Object Qglyphless_char_display;
772 /* Method symbols for Vglyphless_char_display. */
773 static Lisp_Object Qhex_code, Qempty_box, Qthin_space, Qzero_width;
775 /* Default pixel width of `thin-space' display method. */
776 #define THIN_SPACE_WIDTH 1
778 /* Default number of seconds to wait before displaying an hourglass
779 cursor. */
780 #define DEFAULT_HOURGLASS_DELAY 1
783 /* Function prototypes. */
785 static void setup_for_ellipsis (struct it *, int);
786 static void set_iterator_to_next (struct it *, int);
787 static void mark_window_display_accurate_1 (struct window *, int);
788 static int single_display_spec_string_p (Lisp_Object, Lisp_Object);
789 static int display_prop_string_p (Lisp_Object, Lisp_Object);
790 static int cursor_row_p (struct glyph_row *);
791 static int redisplay_mode_lines (Lisp_Object, int);
792 static char *decode_mode_spec_coding (Lisp_Object, char *, int);
794 static Lisp_Object get_it_property (struct it *it, Lisp_Object prop);
796 static void handle_line_prefix (struct it *);
798 static void pint2str (char *, int, EMACS_INT);
799 static void pint2hrstr (char *, int, EMACS_INT);
800 static struct text_pos run_window_scroll_functions (Lisp_Object,
801 struct text_pos);
802 static void reconsider_clip_changes (struct window *, struct buffer *);
803 static int text_outside_line_unchanged_p (struct window *,
804 EMACS_INT, EMACS_INT);
805 static void store_mode_line_noprop_char (char);
806 static int store_mode_line_noprop (const char *, int, int);
807 static void handle_stop (struct it *);
808 static void handle_stop_backwards (struct it *, EMACS_INT);
809 static void vmessage (const char *, va_list) ATTRIBUTE_FORMAT_PRINTF (1, 0);
810 static void ensure_echo_area_buffers (void);
811 static Lisp_Object unwind_with_echo_area_buffer (Lisp_Object);
812 static Lisp_Object with_echo_area_buffer_unwind_data (struct window *);
813 static int with_echo_area_buffer (struct window *, int,
814 int (*) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
815 EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
816 static void clear_garbaged_frames (void);
817 static int current_message_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
818 static void pop_message (void);
819 static int truncate_message_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
820 static void set_message (const char *, Lisp_Object, EMACS_INT, int);
821 static int set_message_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
822 static int display_echo_area (struct window *);
823 static int display_echo_area_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
824 static int resize_mini_window_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
825 static Lisp_Object unwind_redisplay (Lisp_Object);
826 static int string_char_and_length (const unsigned char *, int *);
827 static struct text_pos display_prop_end (struct it *, Lisp_Object,
828 struct text_pos);
829 static int compute_window_start_on_continuation_line (struct window *);
830 static Lisp_Object safe_eval_handler (Lisp_Object);
831 static void insert_left_trunc_glyphs (struct it *);
832 static struct glyph_row *get_overlay_arrow_glyph_row (struct window *,
833 Lisp_Object);
834 static void extend_face_to_end_of_line (struct it *);
835 static int append_space_for_newline (struct it *, int);
836 static int cursor_row_fully_visible_p (struct window *, int, int);
837 static int try_scrolling (Lisp_Object, int, EMACS_INT, EMACS_INT, int, int);
838 static int try_cursor_movement (Lisp_Object, struct text_pos, int *);
839 static int trailing_whitespace_p (EMACS_INT);
840 static intmax_t message_log_check_duplicate (EMACS_INT, EMACS_INT);
841 static void push_it (struct it *, struct text_pos *);
842 static void pop_it (struct it *);
843 static void sync_frame_with_window_matrix_rows (struct window *);
844 static void select_frame_for_redisplay (Lisp_Object);
845 static void redisplay_internal (void);
846 static int echo_area_display (int);
847 static void redisplay_windows (Lisp_Object);
848 static void redisplay_window (Lisp_Object, int);
849 static Lisp_Object redisplay_window_error (Lisp_Object);
850 static Lisp_Object redisplay_window_0 (Lisp_Object);
851 static Lisp_Object redisplay_window_1 (Lisp_Object);
852 static int set_cursor_from_row (struct window *, struct glyph_row *,
853 struct glyph_matrix *, EMACS_INT, EMACS_INT,
854 int, int);
855 static int update_menu_bar (struct frame *, int, int);
856 static int try_window_reusing_current_matrix (struct window *);
857 static int try_window_id (struct window *);
858 static int display_line (struct it *);
859 static int display_mode_lines (struct window *);
860 static int display_mode_line (struct window *, enum face_id, Lisp_Object);
861 static int display_mode_element (struct it *, int, int, int, Lisp_Object, Lisp_Object, int);
862 static int store_mode_line_string (const char *, Lisp_Object, int, int, int, Lisp_Object);
863 static const char *decode_mode_spec (struct window *, int, int, Lisp_Object *);
864 static void display_menu_bar (struct window *);
865 static EMACS_INT display_count_lines (EMACS_INT, EMACS_INT, EMACS_INT,
866 EMACS_INT *);
867 static int display_string (const char *, Lisp_Object, Lisp_Object,
868 EMACS_INT, EMACS_INT, struct it *, int, int, int, int);
869 static void compute_line_metrics (struct it *);
870 static void run_redisplay_end_trigger_hook (struct it *);
871 static int get_overlay_strings (struct it *, EMACS_INT);
872 static int get_overlay_strings_1 (struct it *, EMACS_INT, int);
873 static void next_overlay_string (struct it *);
874 static void reseat (struct it *, struct text_pos, int);
875 static void reseat_1 (struct it *, struct text_pos, int);
876 static void back_to_previous_visible_line_start (struct it *);
877 void reseat_at_previous_visible_line_start (struct it *);
878 static void reseat_at_next_visible_line_start (struct it *, int);
879 static int next_element_from_ellipsis (struct it *);
880 static int next_element_from_display_vector (struct it *);
881 static int next_element_from_string (struct it *);
882 static int next_element_from_c_string (struct it *);
883 static int next_element_from_buffer (struct it *);
884 static int next_element_from_composition (struct it *);
885 static int next_element_from_image (struct it *);
886 static int next_element_from_stretch (struct it *);
887 static void load_overlay_strings (struct it *, EMACS_INT);
888 static int init_from_display_pos (struct it *, struct window *,
889 struct display_pos *);
890 static void reseat_to_string (struct it *, const char *,
891 Lisp_Object, EMACS_INT, EMACS_INT, int, int);
892 static int get_next_display_element (struct it *);
893 static enum move_it_result
894 move_it_in_display_line_to (struct it *, EMACS_INT, int,
895 enum move_operation_enum);
896 void move_it_vertically_backward (struct it *, int);
897 static void init_to_row_start (struct it *, struct window *,
898 struct glyph_row *);
899 static int init_to_row_end (struct it *, struct window *,
900 struct glyph_row *);
901 static void back_to_previous_line_start (struct it *);
902 static int forward_to_next_line_start (struct it *, int *, struct bidi_it *);
903 static struct text_pos string_pos_nchars_ahead (struct text_pos,
904 Lisp_Object, EMACS_INT);
905 static struct text_pos string_pos (EMACS_INT, Lisp_Object);
906 static struct text_pos c_string_pos (EMACS_INT, const char *, int);
907 static EMACS_INT number_of_chars (const char *, int);
908 static void compute_stop_pos (struct it *);
909 static void compute_string_pos (struct text_pos *, struct text_pos,
910 Lisp_Object);
911 static int face_before_or_after_it_pos (struct it *, int);
912 static EMACS_INT next_overlay_change (EMACS_INT);
913 static int handle_display_spec (struct it *, Lisp_Object, Lisp_Object,
914 Lisp_Object, struct text_pos *, EMACS_INT, int);
915 static int handle_single_display_spec (struct it *, Lisp_Object,
916 Lisp_Object, Lisp_Object,
917 struct text_pos *, EMACS_INT, int, int);
918 static int underlying_face_id (struct it *);
919 static int in_ellipses_for_invisible_text_p (struct display_pos *,
920 struct window *);
922 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
923 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
925 #ifdef HAVE_WINDOW_SYSTEM
927 static void x_consider_frame_title (Lisp_Object);
928 static int tool_bar_lines_needed (struct frame *, int *);
929 static void update_tool_bar (struct frame *, int);
930 static void build_desired_tool_bar_string (struct frame *f);
931 static int redisplay_tool_bar (struct frame *);
932 static void display_tool_bar_line (struct it *, int);
933 static void notice_overwritten_cursor (struct window *,
934 enum glyph_row_area,
935 int, int, int, int);
936 static void append_stretch_glyph (struct it *, Lisp_Object,
937 int, int, int);
940 #endif /* HAVE_WINDOW_SYSTEM */
942 static void show_mouse_face (Mouse_HLInfo *, enum draw_glyphs_face);
943 static int coords_in_mouse_face_p (struct window *, int, int);
947 /***********************************************************************
948 Window display dimensions
949 ***********************************************************************/
951 /* Return the bottom boundary y-position for text lines in window W.
952 This is the first y position at which a line cannot start.
953 It is relative to the top of the window.
955 This is the height of W minus the height of a mode line, if any. */
957 inline int
958 window_text_bottom_y (struct window *w)
960 int height = WINDOW_TOTAL_HEIGHT (w);
962 if (WINDOW_WANTS_MODELINE_P (w))
963 height -= CURRENT_MODE_LINE_HEIGHT (w);
964 return height;
967 /* Return the pixel width of display area AREA of window W. AREA < 0
968 means return the total width of W, not including fringes to
969 the left and right of the window. */
971 inline int
972 window_box_width (struct window *w, int area)
974 int cols = XFASTINT (w->total_cols);
975 int pixels = 0;
977 if (!w->pseudo_window_p)
979 cols -= WINDOW_SCROLL_BAR_COLS (w);
981 if (area == TEXT_AREA)
983 if (INTEGERP (w->left_margin_cols))
984 cols -= XFASTINT (w->left_margin_cols);
985 if (INTEGERP (w->right_margin_cols))
986 cols -= XFASTINT (w->right_margin_cols);
987 pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w);
989 else if (area == LEFT_MARGIN_AREA)
991 cols = (INTEGERP (w->left_margin_cols)
992 ? XFASTINT (w->left_margin_cols) : 0);
993 pixels = 0;
995 else if (area == RIGHT_MARGIN_AREA)
997 cols = (INTEGERP (w->right_margin_cols)
998 ? XFASTINT (w->right_margin_cols) : 0);
999 pixels = 0;
1003 return cols * WINDOW_FRAME_COLUMN_WIDTH (w) + pixels;
1007 /* Return the pixel height of the display area of window W, not
1008 including mode lines of W, if any. */
1010 inline int
1011 window_box_height (struct window *w)
1013 struct frame *f = XFRAME (w->frame);
1014 int height = WINDOW_TOTAL_HEIGHT (w);
1016 xassert (height >= 0);
1018 /* Note: the code below that determines the mode-line/header-line
1019 height is essentially the same as that contained in the macro
1020 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1021 the appropriate glyph row has its `mode_line_p' flag set,
1022 and if it doesn't, uses estimate_mode_line_height instead. */
1024 if (WINDOW_WANTS_MODELINE_P (w))
1026 struct glyph_row *ml_row
1027 = (w->current_matrix && w->current_matrix->rows
1028 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
1029 : 0);
1030 if (ml_row && ml_row->mode_line_p)
1031 height -= ml_row->height;
1032 else
1033 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
1036 if (WINDOW_WANTS_HEADER_LINE_P (w))
1038 struct glyph_row *hl_row
1039 = (w->current_matrix && w->current_matrix->rows
1040 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
1041 : 0);
1042 if (hl_row && hl_row->mode_line_p)
1043 height -= hl_row->height;
1044 else
1045 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1048 /* With a very small font and a mode-line that's taller than
1049 default, we might end up with a negative height. */
1050 return max (0, height);
1053 /* Return the window-relative coordinate of the left edge of display
1054 area AREA of window W. AREA < 0 means return the left edge of the
1055 whole window, to the right of the left fringe of W. */
1057 inline int
1058 window_box_left_offset (struct window *w, int area)
1060 int x;
1062 if (w->pseudo_window_p)
1063 return 0;
1065 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
1067 if (area == TEXT_AREA)
1068 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1069 + window_box_width (w, LEFT_MARGIN_AREA));
1070 else if (area == RIGHT_MARGIN_AREA)
1071 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1072 + window_box_width (w, LEFT_MARGIN_AREA)
1073 + window_box_width (w, TEXT_AREA)
1074 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1076 : WINDOW_RIGHT_FRINGE_WIDTH (w)));
1077 else if (area == LEFT_MARGIN_AREA
1078 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1079 x += WINDOW_LEFT_FRINGE_WIDTH (w);
1081 return x;
1085 /* Return the window-relative coordinate of the right edge of display
1086 area AREA of window W. AREA < 0 means return the right edge of the
1087 whole window, to the left of the right fringe of W. */
1089 inline int
1090 window_box_right_offset (struct window *w, int area)
1092 return window_box_left_offset (w, area) + window_box_width (w, area);
1095 /* Return the frame-relative coordinate of the left edge of display
1096 area AREA of window W. AREA < 0 means return the left edge of the
1097 whole window, to the right of the left fringe of W. */
1099 inline int
1100 window_box_left (struct window *w, int area)
1102 struct frame *f = XFRAME (w->frame);
1103 int x;
1105 if (w->pseudo_window_p)
1106 return FRAME_INTERNAL_BORDER_WIDTH (f);
1108 x = (WINDOW_LEFT_EDGE_X (w)
1109 + window_box_left_offset (w, area));
1111 return x;
1115 /* Return the frame-relative coordinate of the right edge of display
1116 area AREA of window W. AREA < 0 means return the right edge of the
1117 whole window, to the left of the right fringe of W. */
1119 inline int
1120 window_box_right (struct window *w, int area)
1122 return window_box_left (w, area) + window_box_width (w, area);
1125 /* Get the bounding box of the display area AREA of window W, without
1126 mode lines, in frame-relative coordinates. AREA < 0 means the
1127 whole window, not including the left and right fringes of
1128 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1129 coordinates of the upper-left corner of the box. Return in
1130 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1132 inline void
1133 window_box (struct window *w, int area, int *box_x, int *box_y,
1134 int *box_width, int *box_height)
1136 if (box_width)
1137 *box_width = window_box_width (w, area);
1138 if (box_height)
1139 *box_height = window_box_height (w);
1140 if (box_x)
1141 *box_x = window_box_left (w, area);
1142 if (box_y)
1144 *box_y = WINDOW_TOP_EDGE_Y (w);
1145 if (WINDOW_WANTS_HEADER_LINE_P (w))
1146 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1151 /* Get the bounding box of the display area AREA of window W, without
1152 mode lines. AREA < 0 means the whole window, not including the
1153 left and right fringe of the window. Return in *TOP_LEFT_X
1154 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1155 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1156 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1157 box. */
1159 static inline void
1160 window_box_edges (struct window *w, int area, int *top_left_x, int *top_left_y,
1161 int *bottom_right_x, int *bottom_right_y)
1163 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
1164 bottom_right_y);
1165 *bottom_right_x += *top_left_x;
1166 *bottom_right_y += *top_left_y;
1171 /***********************************************************************
1172 Utilities
1173 ***********************************************************************/
1175 /* Return the bottom y-position of the line the iterator IT is in.
1176 This can modify IT's settings. */
1179 line_bottom_y (struct it *it)
1181 int line_height = it->max_ascent + it->max_descent;
1182 int line_top_y = it->current_y;
1184 if (line_height == 0)
1186 if (last_height)
1187 line_height = last_height;
1188 else if (IT_CHARPOS (*it) < ZV)
1190 move_it_by_lines (it, 1);
1191 line_height = (it->max_ascent || it->max_descent
1192 ? it->max_ascent + it->max_descent
1193 : last_height);
1195 else
1197 struct glyph_row *row = it->glyph_row;
1199 /* Use the default character height. */
1200 it->glyph_row = NULL;
1201 it->what = IT_CHARACTER;
1202 it->c = ' ';
1203 it->len = 1;
1204 PRODUCE_GLYPHS (it);
1205 line_height = it->ascent + it->descent;
1206 it->glyph_row = row;
1210 return line_top_y + line_height;
1214 /* Return 1 if position CHARPOS is visible in window W.
1215 CHARPOS < 0 means return info about WINDOW_END position.
1216 If visible, set *X and *Y to pixel coordinates of top left corner.
1217 Set *RTOP and *RBOT to pixel height of an invisible area of glyph at POS.
1218 Set *ROWH and *VPOS to row's visible height and VPOS (row number). */
1221 pos_visible_p (struct window *w, EMACS_INT charpos, int *x, int *y,
1222 int *rtop, int *rbot, int *rowh, int *vpos)
1224 struct it it;
1225 void *itdata = bidi_shelve_cache ();
1226 struct text_pos top;
1227 int visible_p = 0;
1228 struct buffer *old_buffer = NULL;
1230 if (FRAME_INITIAL_P (XFRAME (WINDOW_FRAME (w))))
1231 return visible_p;
1233 if (XBUFFER (w->buffer) != current_buffer)
1235 old_buffer = current_buffer;
1236 set_buffer_internal_1 (XBUFFER (w->buffer));
1239 SET_TEXT_POS_FROM_MARKER (top, w->start);
1241 /* Compute exact mode line heights. */
1242 if (WINDOW_WANTS_MODELINE_P (w))
1243 current_mode_line_height
1244 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1245 BVAR (current_buffer, mode_line_format));
1247 if (WINDOW_WANTS_HEADER_LINE_P (w))
1248 current_header_line_height
1249 = display_mode_line (w, HEADER_LINE_FACE_ID,
1250 BVAR (current_buffer, header_line_format));
1252 start_display (&it, w, top);
1253 move_it_to (&it, charpos, -1, it.last_visible_y-1, -1,
1254 (charpos >= 0 ? MOVE_TO_POS : 0) | MOVE_TO_Y);
1256 if (charpos >= 0
1257 && (((!it.bidi_p || it.bidi_it.scan_dir == 1)
1258 && IT_CHARPOS (it) >= charpos)
1259 /* When scanning backwards under bidi iteration, move_it_to
1260 stops at or _before_ CHARPOS, because it stops at or to
1261 the _right_ of the character at CHARPOS. */
1262 || (it.bidi_p && it.bidi_it.scan_dir == -1
1263 && IT_CHARPOS (it) <= charpos)))
1265 /* We have reached CHARPOS, or passed it. How the call to
1266 move_it_to can overshoot: (i) If CHARPOS is on invisible text
1267 or covered by a display property, move_it_to stops at the end
1268 of the invisible text, to the right of CHARPOS. (ii) If
1269 CHARPOS is in a display vector, move_it_to stops on its last
1270 glyph. */
1271 int top_x = it.current_x;
1272 int top_y = it.current_y;
1273 enum it_method it_method = it.method;
1274 /* Calling line_bottom_y may change it.method, it.position, etc. */
1275 int bottom_y = (last_height = 0, line_bottom_y (&it));
1276 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1278 if (top_y < window_top_y)
1279 visible_p = bottom_y > window_top_y;
1280 else if (top_y < it.last_visible_y)
1281 visible_p = 1;
1282 if (visible_p)
1284 if (it_method == GET_FROM_DISPLAY_VECTOR)
1286 /* We stopped on the last glyph of a display vector.
1287 Try and recompute. Hack alert! */
1288 if (charpos < 2 || top.charpos >= charpos)
1289 top_x = it.glyph_row->x;
1290 else
1292 struct it it2;
1293 start_display (&it2, w, top);
1294 move_it_to (&it2, charpos - 1, -1, -1, -1, MOVE_TO_POS);
1295 get_next_display_element (&it2);
1296 PRODUCE_GLYPHS (&it2);
1297 if (ITERATOR_AT_END_OF_LINE_P (&it2)
1298 || it2.current_x > it2.last_visible_x)
1299 top_x = it.glyph_row->x;
1300 else
1302 top_x = it2.current_x;
1303 top_y = it2.current_y;
1308 *x = top_x;
1309 *y = max (top_y + max (0, it.max_ascent - it.ascent), window_top_y);
1310 *rtop = max (0, window_top_y - top_y);
1311 *rbot = max (0, bottom_y - it.last_visible_y);
1312 *rowh = max (0, (min (bottom_y, it.last_visible_y)
1313 - max (top_y, window_top_y)));
1314 *vpos = it.vpos;
1317 else
1319 /* We were asked to provide info about WINDOW_END. */
1320 struct it it2;
1321 void *it2data = NULL;
1323 SAVE_IT (it2, it, it2data);
1324 if (IT_CHARPOS (it) < ZV && FETCH_BYTE (IT_BYTEPOS (it)) != '\n')
1325 move_it_by_lines (&it, 1);
1326 if (charpos < IT_CHARPOS (it)
1327 || (it.what == IT_EOB && charpos == IT_CHARPOS (it)))
1329 visible_p = 1;
1330 RESTORE_IT (&it2, &it2, it2data);
1331 move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
1332 *x = it2.current_x;
1333 *y = it2.current_y + it2.max_ascent - it2.ascent;
1334 *rtop = max (0, -it2.current_y);
1335 *rbot = max (0, ((it2.current_y + it2.max_ascent + it2.max_descent)
1336 - it.last_visible_y));
1337 *rowh = max (0, (min (it2.current_y + it2.max_ascent + it2.max_descent,
1338 it.last_visible_y)
1339 - max (it2.current_y,
1340 WINDOW_HEADER_LINE_HEIGHT (w))));
1341 *vpos = it2.vpos;
1343 else
1344 xfree (it2data);
1346 bidi_unshelve_cache (itdata);
1348 if (old_buffer)
1349 set_buffer_internal_1 (old_buffer);
1351 current_header_line_height = current_mode_line_height = -1;
1353 if (visible_p && XFASTINT (w->hscroll) > 0)
1354 *x -= XFASTINT (w->hscroll) * WINDOW_FRAME_COLUMN_WIDTH (w);
1356 #if 0
1357 /* Debugging code. */
1358 if (visible_p)
1359 fprintf (stderr, "+pv pt=%d vs=%d --> x=%d y=%d rt=%d rb=%d rh=%d vp=%d\n",
1360 charpos, w->vscroll, *x, *y, *rtop, *rbot, *rowh, *vpos);
1361 else
1362 fprintf (stderr, "-pv pt=%d vs=%d\n", charpos, w->vscroll);
1363 #endif
1365 return visible_p;
1369 /* Return the next character from STR. Return in *LEN the length of
1370 the character. This is like STRING_CHAR_AND_LENGTH but never
1371 returns an invalid character. If we find one, we return a `?', but
1372 with the length of the invalid character. */
1374 static inline int
1375 string_char_and_length (const unsigned char *str, int *len)
1377 int c;
1379 c = STRING_CHAR_AND_LENGTH (str, *len);
1380 if (!CHAR_VALID_P (c))
1381 /* We may not change the length here because other places in Emacs
1382 don't use this function, i.e. they silently accept invalid
1383 characters. */
1384 c = '?';
1386 return c;
1391 /* Given a position POS containing a valid character and byte position
1392 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1394 static struct text_pos
1395 string_pos_nchars_ahead (struct text_pos pos, Lisp_Object string, EMACS_INT nchars)
1397 xassert (STRINGP (string) && nchars >= 0);
1399 if (STRING_MULTIBYTE (string))
1401 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1402 int len;
1404 while (nchars--)
1406 string_char_and_length (p, &len);
1407 p += len;
1408 CHARPOS (pos) += 1;
1409 BYTEPOS (pos) += len;
1412 else
1413 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1415 return pos;
1419 /* Value is the text position, i.e. character and byte position,
1420 for character position CHARPOS in STRING. */
1422 static inline struct text_pos
1423 string_pos (EMACS_INT charpos, Lisp_Object string)
1425 struct text_pos pos;
1426 xassert (STRINGP (string));
1427 xassert (charpos >= 0);
1428 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1429 return pos;
1433 /* Value is a text position, i.e. character and byte position, for
1434 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1435 means recognize multibyte characters. */
1437 static struct text_pos
1438 c_string_pos (EMACS_INT charpos, const char *s, int multibyte_p)
1440 struct text_pos pos;
1442 xassert (s != NULL);
1443 xassert (charpos >= 0);
1445 if (multibyte_p)
1447 int len;
1449 SET_TEXT_POS (pos, 0, 0);
1450 while (charpos--)
1452 string_char_and_length ((const unsigned char *) s, &len);
1453 s += len;
1454 CHARPOS (pos) += 1;
1455 BYTEPOS (pos) += len;
1458 else
1459 SET_TEXT_POS (pos, charpos, charpos);
1461 return pos;
1465 /* Value is the number of characters in C string S. MULTIBYTE_P
1466 non-zero means recognize multibyte characters. */
1468 static EMACS_INT
1469 number_of_chars (const char *s, int multibyte_p)
1471 EMACS_INT nchars;
1473 if (multibyte_p)
1475 EMACS_INT rest = strlen (s);
1476 int len;
1477 const unsigned char *p = (const unsigned char *) s;
1479 for (nchars = 0; rest > 0; ++nchars)
1481 string_char_and_length (p, &len);
1482 rest -= len, p += len;
1485 else
1486 nchars = strlen (s);
1488 return nchars;
1492 /* Compute byte position NEWPOS->bytepos corresponding to
1493 NEWPOS->charpos. POS is a known position in string STRING.
1494 NEWPOS->charpos must be >= POS.charpos. */
1496 static void
1497 compute_string_pos (struct text_pos *newpos, struct text_pos pos, Lisp_Object string)
1499 xassert (STRINGP (string));
1500 xassert (CHARPOS (*newpos) >= CHARPOS (pos));
1502 if (STRING_MULTIBYTE (string))
1503 *newpos = string_pos_nchars_ahead (pos, string,
1504 CHARPOS (*newpos) - CHARPOS (pos));
1505 else
1506 BYTEPOS (*newpos) = CHARPOS (*newpos);
1509 /* EXPORT:
1510 Return an estimation of the pixel height of mode or header lines on
1511 frame F. FACE_ID specifies what line's height to estimate. */
1514 estimate_mode_line_height (struct frame *f, enum face_id face_id)
1516 #ifdef HAVE_WINDOW_SYSTEM
1517 if (FRAME_WINDOW_P (f))
1519 int height = FONT_HEIGHT (FRAME_FONT (f));
1521 /* This function is called so early when Emacs starts that the face
1522 cache and mode line face are not yet initialized. */
1523 if (FRAME_FACE_CACHE (f))
1525 struct face *face = FACE_FROM_ID (f, face_id);
1526 if (face)
1528 if (face->font)
1529 height = FONT_HEIGHT (face->font);
1530 if (face->box_line_width > 0)
1531 height += 2 * face->box_line_width;
1535 return height;
1537 #endif
1539 return 1;
1542 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1543 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1544 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1545 not force the value into range. */
1547 void
1548 pixel_to_glyph_coords (FRAME_PTR f, register int pix_x, register int pix_y,
1549 int *x, int *y, NativeRectangle *bounds, int noclip)
1552 #ifdef HAVE_WINDOW_SYSTEM
1553 if (FRAME_WINDOW_P (f))
1555 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1556 even for negative values. */
1557 if (pix_x < 0)
1558 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1559 if (pix_y < 0)
1560 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1562 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1563 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1565 if (bounds)
1566 STORE_NATIVE_RECT (*bounds,
1567 FRAME_COL_TO_PIXEL_X (f, pix_x),
1568 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1569 FRAME_COLUMN_WIDTH (f) - 1,
1570 FRAME_LINE_HEIGHT (f) - 1);
1572 if (!noclip)
1574 if (pix_x < 0)
1575 pix_x = 0;
1576 else if (pix_x > FRAME_TOTAL_COLS (f))
1577 pix_x = FRAME_TOTAL_COLS (f);
1579 if (pix_y < 0)
1580 pix_y = 0;
1581 else if (pix_y > FRAME_LINES (f))
1582 pix_y = FRAME_LINES (f);
1585 #endif
1587 *x = pix_x;
1588 *y = pix_y;
1592 /* Find the glyph under window-relative coordinates X/Y in window W.
1593 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1594 strings. Return in *HPOS and *VPOS the row and column number of
1595 the glyph found. Return in *AREA the glyph area containing X.
1596 Value is a pointer to the glyph found or null if X/Y is not on
1597 text, or we can't tell because W's current matrix is not up to
1598 date. */
1600 static
1601 struct glyph *
1602 x_y_to_hpos_vpos (struct window *w, int x, int y, int *hpos, int *vpos,
1603 int *dx, int *dy, int *area)
1605 struct glyph *glyph, *end;
1606 struct glyph_row *row = NULL;
1607 int x0, i;
1609 /* Find row containing Y. Give up if some row is not enabled. */
1610 for (i = 0; i < w->current_matrix->nrows; ++i)
1612 row = MATRIX_ROW (w->current_matrix, i);
1613 if (!row->enabled_p)
1614 return NULL;
1615 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1616 break;
1619 *vpos = i;
1620 *hpos = 0;
1622 /* Give up if Y is not in the window. */
1623 if (i == w->current_matrix->nrows)
1624 return NULL;
1626 /* Get the glyph area containing X. */
1627 if (w->pseudo_window_p)
1629 *area = TEXT_AREA;
1630 x0 = 0;
1632 else
1634 if (x < window_box_left_offset (w, TEXT_AREA))
1636 *area = LEFT_MARGIN_AREA;
1637 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
1639 else if (x < window_box_right_offset (w, TEXT_AREA))
1641 *area = TEXT_AREA;
1642 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
1644 else
1646 *area = RIGHT_MARGIN_AREA;
1647 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
1651 /* Find glyph containing X. */
1652 glyph = row->glyphs[*area];
1653 end = glyph + row->used[*area];
1654 x -= x0;
1655 while (glyph < end && x >= glyph->pixel_width)
1657 x -= glyph->pixel_width;
1658 ++glyph;
1661 if (glyph == end)
1662 return NULL;
1664 if (dx)
1666 *dx = x;
1667 *dy = y - (row->y + row->ascent - glyph->ascent);
1670 *hpos = glyph - row->glyphs[*area];
1671 return glyph;
1674 /* Convert frame-relative x/y to coordinates relative to window W.
1675 Takes pseudo-windows into account. */
1677 static void
1678 frame_to_window_pixel_xy (struct window *w, int *x, int *y)
1680 if (w->pseudo_window_p)
1682 /* A pseudo-window is always full-width, and starts at the
1683 left edge of the frame, plus a frame border. */
1684 struct frame *f = XFRAME (w->frame);
1685 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
1686 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1688 else
1690 *x -= WINDOW_LEFT_EDGE_X (w);
1691 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1695 #ifdef HAVE_WINDOW_SYSTEM
1697 /* EXPORT:
1698 Return in RECTS[] at most N clipping rectangles for glyph string S.
1699 Return the number of stored rectangles. */
1702 get_glyph_string_clip_rects (struct glyph_string *s, NativeRectangle *rects, int n)
1704 XRectangle r;
1706 if (n <= 0)
1707 return 0;
1709 if (s->row->full_width_p)
1711 /* Draw full-width. X coordinates are relative to S->w->left_col. */
1712 r.x = WINDOW_LEFT_EDGE_X (s->w);
1713 r.width = WINDOW_TOTAL_WIDTH (s->w);
1715 /* Unless displaying a mode or menu bar line, which are always
1716 fully visible, clip to the visible part of the row. */
1717 if (s->w->pseudo_window_p)
1718 r.height = s->row->visible_height;
1719 else
1720 r.height = s->height;
1722 else
1724 /* This is a text line that may be partially visible. */
1725 r.x = window_box_left (s->w, s->area);
1726 r.width = window_box_width (s->w, s->area);
1727 r.height = s->row->visible_height;
1730 if (s->clip_head)
1731 if (r.x < s->clip_head->x)
1733 if (r.width >= s->clip_head->x - r.x)
1734 r.width -= s->clip_head->x - r.x;
1735 else
1736 r.width = 0;
1737 r.x = s->clip_head->x;
1739 if (s->clip_tail)
1740 if (r.x + r.width > s->clip_tail->x + s->clip_tail->background_width)
1742 if (s->clip_tail->x + s->clip_tail->background_width >= r.x)
1743 r.width = s->clip_tail->x + s->clip_tail->background_width - r.x;
1744 else
1745 r.width = 0;
1748 /* If S draws overlapping rows, it's sufficient to use the top and
1749 bottom of the window for clipping because this glyph string
1750 intentionally draws over other lines. */
1751 if (s->for_overlaps)
1753 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1754 r.height = window_text_bottom_y (s->w) - r.y;
1756 /* Alas, the above simple strategy does not work for the
1757 environments with anti-aliased text: if the same text is
1758 drawn onto the same place multiple times, it gets thicker.
1759 If the overlap we are processing is for the erased cursor, we
1760 take the intersection with the rectagle of the cursor. */
1761 if (s->for_overlaps & OVERLAPS_ERASED_CURSOR)
1763 XRectangle rc, r_save = r;
1765 rc.x = WINDOW_TEXT_TO_FRAME_PIXEL_X (s->w, s->w->phys_cursor.x);
1766 rc.y = s->w->phys_cursor.y;
1767 rc.width = s->w->phys_cursor_width;
1768 rc.height = s->w->phys_cursor_height;
1770 x_intersect_rectangles (&r_save, &rc, &r);
1773 else
1775 /* Don't use S->y for clipping because it doesn't take partially
1776 visible lines into account. For example, it can be negative for
1777 partially visible lines at the top of a window. */
1778 if (!s->row->full_width_p
1779 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
1780 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1781 else
1782 r.y = max (0, s->row->y);
1785 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
1787 /* If drawing the cursor, don't let glyph draw outside its
1788 advertised boundaries. Cleartype does this under some circumstances. */
1789 if (s->hl == DRAW_CURSOR)
1791 struct glyph *glyph = s->first_glyph;
1792 int height, max_y;
1794 if (s->x > r.x)
1796 r.width -= s->x - r.x;
1797 r.x = s->x;
1799 r.width = min (r.width, glyph->pixel_width);
1801 /* If r.y is below window bottom, ensure that we still see a cursor. */
1802 height = min (glyph->ascent + glyph->descent,
1803 min (FRAME_LINE_HEIGHT (s->f), s->row->visible_height));
1804 max_y = window_text_bottom_y (s->w) - height;
1805 max_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, max_y);
1806 if (s->ybase - glyph->ascent > max_y)
1808 r.y = max_y;
1809 r.height = height;
1811 else
1813 /* Don't draw cursor glyph taller than our actual glyph. */
1814 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
1815 if (height < r.height)
1817 max_y = r.y + r.height;
1818 r.y = min (max_y, max (r.y, s->ybase + glyph->descent - height));
1819 r.height = min (max_y - r.y, height);
1824 if (s->row->clip)
1826 XRectangle r_save = r;
1828 if (! x_intersect_rectangles (&r_save, s->row->clip, &r))
1829 r.width = 0;
1832 if ((s->for_overlaps & OVERLAPS_BOTH) == 0
1833 || ((s->for_overlaps & OVERLAPS_BOTH) == OVERLAPS_BOTH && n == 1))
1835 #ifdef CONVERT_FROM_XRECT
1836 CONVERT_FROM_XRECT (r, *rects);
1837 #else
1838 *rects = r;
1839 #endif
1840 return 1;
1842 else
1844 /* If we are processing overlapping and allowed to return
1845 multiple clipping rectangles, we exclude the row of the glyph
1846 string from the clipping rectangle. This is to avoid drawing
1847 the same text on the environment with anti-aliasing. */
1848 #ifdef CONVERT_FROM_XRECT
1849 XRectangle rs[2];
1850 #else
1851 XRectangle *rs = rects;
1852 #endif
1853 int i = 0, row_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, s->row->y);
1855 if (s->for_overlaps & OVERLAPS_PRED)
1857 rs[i] = r;
1858 if (r.y + r.height > row_y)
1860 if (r.y < row_y)
1861 rs[i].height = row_y - r.y;
1862 else
1863 rs[i].height = 0;
1865 i++;
1867 if (s->for_overlaps & OVERLAPS_SUCC)
1869 rs[i] = r;
1870 if (r.y < row_y + s->row->visible_height)
1872 if (r.y + r.height > row_y + s->row->visible_height)
1874 rs[i].y = row_y + s->row->visible_height;
1875 rs[i].height = r.y + r.height - rs[i].y;
1877 else
1878 rs[i].height = 0;
1880 i++;
1883 n = i;
1884 #ifdef CONVERT_FROM_XRECT
1885 for (i = 0; i < n; i++)
1886 CONVERT_FROM_XRECT (rs[i], rects[i]);
1887 #endif
1888 return n;
1892 /* EXPORT:
1893 Return in *NR the clipping rectangle for glyph string S. */
1895 void
1896 get_glyph_string_clip_rect (struct glyph_string *s, NativeRectangle *nr)
1898 get_glyph_string_clip_rects (s, nr, 1);
1902 /* EXPORT:
1903 Return the position and height of the phys cursor in window W.
1904 Set w->phys_cursor_width to width of phys cursor.
1907 void
1908 get_phys_cursor_geometry (struct window *w, struct glyph_row *row,
1909 struct glyph *glyph, int *xp, int *yp, int *heightp)
1911 struct frame *f = XFRAME (WINDOW_FRAME (w));
1912 int x, y, wd, h, h0, y0;
1914 /* Compute the width of the rectangle to draw. If on a stretch
1915 glyph, and `x-stretch-block-cursor' is nil, don't draw a
1916 rectangle as wide as the glyph, but use a canonical character
1917 width instead. */
1918 wd = glyph->pixel_width - 1;
1919 #if defined(HAVE_NTGUI) || defined(HAVE_NS)
1920 wd++; /* Why? */
1921 #endif
1923 x = w->phys_cursor.x;
1924 if (x < 0)
1926 wd += x;
1927 x = 0;
1930 if (glyph->type == STRETCH_GLYPH
1931 && !x_stretch_cursor_p)
1932 wd = min (FRAME_COLUMN_WIDTH (f), wd);
1933 w->phys_cursor_width = wd;
1935 y = w->phys_cursor.y + row->ascent - glyph->ascent;
1937 /* If y is below window bottom, ensure that we still see a cursor. */
1938 h0 = min (FRAME_LINE_HEIGHT (f), row->visible_height);
1940 h = max (h0, glyph->ascent + glyph->descent);
1941 h0 = min (h0, glyph->ascent + glyph->descent);
1943 y0 = WINDOW_HEADER_LINE_HEIGHT (w);
1944 if (y < y0)
1946 h = max (h - (y0 - y) + 1, h0);
1947 y = y0 - 1;
1949 else
1951 y0 = window_text_bottom_y (w) - h0;
1952 if (y > y0)
1954 h += y - y0;
1955 y = y0;
1959 *xp = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x);
1960 *yp = WINDOW_TO_FRAME_PIXEL_Y (w, y);
1961 *heightp = h;
1965 * Remember which glyph the mouse is over.
1968 void
1969 remember_mouse_glyph (struct frame *f, int gx, int gy, NativeRectangle *rect)
1971 Lisp_Object window;
1972 struct window *w;
1973 struct glyph_row *r, *gr, *end_row;
1974 enum window_part part;
1975 enum glyph_row_area area;
1976 int x, y, width, height;
1978 /* Try to determine frame pixel position and size of the glyph under
1979 frame pixel coordinates X/Y on frame F. */
1981 if (!f->glyphs_initialized_p
1982 || (window = window_from_coordinates (f, gx, gy, &part, 0),
1983 NILP (window)))
1985 width = FRAME_SMALLEST_CHAR_WIDTH (f);
1986 height = FRAME_SMALLEST_FONT_HEIGHT (f);
1987 goto virtual_glyph;
1990 w = XWINDOW (window);
1991 width = WINDOW_FRAME_COLUMN_WIDTH (w);
1992 height = WINDOW_FRAME_LINE_HEIGHT (w);
1994 x = window_relative_x_coord (w, part, gx);
1995 y = gy - WINDOW_TOP_EDGE_Y (w);
1997 r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
1998 end_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
2000 if (w->pseudo_window_p)
2002 area = TEXT_AREA;
2003 part = ON_MODE_LINE; /* Don't adjust margin. */
2004 goto text_glyph;
2007 switch (part)
2009 case ON_LEFT_MARGIN:
2010 area = LEFT_MARGIN_AREA;
2011 goto text_glyph;
2013 case ON_RIGHT_MARGIN:
2014 area = RIGHT_MARGIN_AREA;
2015 goto text_glyph;
2017 case ON_HEADER_LINE:
2018 case ON_MODE_LINE:
2019 gr = (part == ON_HEADER_LINE
2020 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
2021 : MATRIX_MODE_LINE_ROW (w->current_matrix));
2022 gy = gr->y;
2023 area = TEXT_AREA;
2024 goto text_glyph_row_found;
2026 case ON_TEXT:
2027 area = TEXT_AREA;
2029 text_glyph:
2030 gr = 0; gy = 0;
2031 for (; r <= end_row && r->enabled_p; ++r)
2032 if (r->y + r->height > y)
2034 gr = r; gy = r->y;
2035 break;
2038 text_glyph_row_found:
2039 if (gr && gy <= y)
2041 struct glyph *g = gr->glyphs[area];
2042 struct glyph *end = g + gr->used[area];
2044 height = gr->height;
2045 for (gx = gr->x; g < end; gx += g->pixel_width, ++g)
2046 if (gx + g->pixel_width > x)
2047 break;
2049 if (g < end)
2051 if (g->type == IMAGE_GLYPH)
2053 /* Don't remember when mouse is over image, as
2054 image may have hot-spots. */
2055 STORE_NATIVE_RECT (*rect, 0, 0, 0, 0);
2056 return;
2058 width = g->pixel_width;
2060 else
2062 /* Use nominal char spacing at end of line. */
2063 x -= gx;
2064 gx += (x / width) * width;
2067 if (part != ON_MODE_LINE && part != ON_HEADER_LINE)
2068 gx += window_box_left_offset (w, area);
2070 else
2072 /* Use nominal line height at end of window. */
2073 gx = (x / width) * width;
2074 y -= gy;
2075 gy += (y / height) * height;
2077 break;
2079 case ON_LEFT_FRINGE:
2080 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2081 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w)
2082 : window_box_right_offset (w, LEFT_MARGIN_AREA));
2083 width = WINDOW_LEFT_FRINGE_WIDTH (w);
2084 goto row_glyph;
2086 case ON_RIGHT_FRINGE:
2087 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2088 ? window_box_right_offset (w, RIGHT_MARGIN_AREA)
2089 : window_box_right_offset (w, TEXT_AREA));
2090 width = WINDOW_RIGHT_FRINGE_WIDTH (w);
2091 goto row_glyph;
2093 case ON_SCROLL_BAR:
2094 gx = (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)
2096 : (window_box_right_offset (w, RIGHT_MARGIN_AREA)
2097 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2098 ? WINDOW_RIGHT_FRINGE_WIDTH (w)
2099 : 0)));
2100 width = WINDOW_SCROLL_BAR_AREA_WIDTH (w);
2102 row_glyph:
2103 gr = 0, gy = 0;
2104 for (; r <= end_row && r->enabled_p; ++r)
2105 if (r->y + r->height > y)
2107 gr = r; gy = r->y;
2108 break;
2111 if (gr && gy <= y)
2112 height = gr->height;
2113 else
2115 /* Use nominal line height at end of window. */
2116 y -= gy;
2117 gy += (y / height) * height;
2119 break;
2121 default:
2123 virtual_glyph:
2124 /* If there is no glyph under the mouse, then we divide the screen
2125 into a grid of the smallest glyph in the frame, and use that
2126 as our "glyph". */
2128 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to
2129 round down even for negative values. */
2130 if (gx < 0)
2131 gx -= width - 1;
2132 if (gy < 0)
2133 gy -= height - 1;
2135 gx = (gx / width) * width;
2136 gy = (gy / height) * height;
2138 goto store_rect;
2141 gx += WINDOW_LEFT_EDGE_X (w);
2142 gy += WINDOW_TOP_EDGE_Y (w);
2144 store_rect:
2145 STORE_NATIVE_RECT (*rect, gx, gy, width, height);
2147 /* Visible feedback for debugging. */
2148 #if 0
2149 #if HAVE_X_WINDOWS
2150 XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2151 f->output_data.x->normal_gc,
2152 gx, gy, width, height);
2153 #endif
2154 #endif
2158 #endif /* HAVE_WINDOW_SYSTEM */
2161 /***********************************************************************
2162 Lisp form evaluation
2163 ***********************************************************************/
2165 /* Error handler for safe_eval and safe_call. */
2167 static Lisp_Object
2168 safe_eval_handler (Lisp_Object arg)
2170 add_to_log ("Error during redisplay: %S", arg, Qnil);
2171 return Qnil;
2175 /* Evaluate SEXPR and return the result, or nil if something went
2176 wrong. Prevent redisplay during the evaluation. */
2178 /* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1].
2179 Return the result, or nil if something went wrong. Prevent
2180 redisplay during the evaluation. */
2182 Lisp_Object
2183 safe_call (ptrdiff_t nargs, Lisp_Object *args)
2185 Lisp_Object val;
2187 if (inhibit_eval_during_redisplay)
2188 val = Qnil;
2189 else
2191 int count = SPECPDL_INDEX ();
2192 struct gcpro gcpro1;
2194 GCPRO1 (args[0]);
2195 gcpro1.nvars = nargs;
2196 specbind (Qinhibit_redisplay, Qt);
2197 /* Use Qt to ensure debugger does not run,
2198 so there is no possibility of wanting to redisplay. */
2199 val = internal_condition_case_n (Ffuncall, nargs, args, Qt,
2200 safe_eval_handler);
2201 UNGCPRO;
2202 val = unbind_to (count, val);
2205 return val;
2209 /* Call function FN with one argument ARG.
2210 Return the result, or nil if something went wrong. */
2212 Lisp_Object
2213 safe_call1 (Lisp_Object fn, Lisp_Object arg)
2215 Lisp_Object args[2];
2216 args[0] = fn;
2217 args[1] = arg;
2218 return safe_call (2, args);
2221 static Lisp_Object Qeval;
2223 Lisp_Object
2224 safe_eval (Lisp_Object sexpr)
2226 return safe_call1 (Qeval, sexpr);
2229 /* Call function FN with one argument ARG.
2230 Return the result, or nil if something went wrong. */
2232 Lisp_Object
2233 safe_call2 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2)
2235 Lisp_Object args[3];
2236 args[0] = fn;
2237 args[1] = arg1;
2238 args[2] = arg2;
2239 return safe_call (3, args);
2244 /***********************************************************************
2245 Debugging
2246 ***********************************************************************/
2248 #if 0
2250 /* Define CHECK_IT to perform sanity checks on iterators.
2251 This is for debugging. It is too slow to do unconditionally. */
2253 static void
2254 check_it (struct it *it)
2256 if (it->method == GET_FROM_STRING)
2258 xassert (STRINGP (it->string));
2259 xassert (IT_STRING_CHARPOS (*it) >= 0);
2261 else
2263 xassert (IT_STRING_CHARPOS (*it) < 0);
2264 if (it->method == GET_FROM_BUFFER)
2266 /* Check that character and byte positions agree. */
2267 xassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
2271 if (it->dpvec)
2272 xassert (it->current.dpvec_index >= 0);
2273 else
2274 xassert (it->current.dpvec_index < 0);
2277 #define CHECK_IT(IT) check_it ((IT))
2279 #else /* not 0 */
2281 #define CHECK_IT(IT) (void) 0
2283 #endif /* not 0 */
2286 #if GLYPH_DEBUG && XASSERTS
2288 /* Check that the window end of window W is what we expect it
2289 to be---the last row in the current matrix displaying text. */
2291 static void
2292 check_window_end (struct window *w)
2294 if (!MINI_WINDOW_P (w)
2295 && !NILP (w->window_end_valid))
2297 struct glyph_row *row;
2298 xassert ((row = MATRIX_ROW (w->current_matrix,
2299 XFASTINT (w->window_end_vpos)),
2300 !row->enabled_p
2301 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
2302 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
2306 #define CHECK_WINDOW_END(W) check_window_end ((W))
2308 #else
2310 #define CHECK_WINDOW_END(W) (void) 0
2312 #endif
2316 /***********************************************************************
2317 Iterator initialization
2318 ***********************************************************************/
2320 /* Initialize IT for displaying current_buffer in window W, starting
2321 at character position CHARPOS. CHARPOS < 0 means that no buffer
2322 position is specified which is useful when the iterator is assigned
2323 a position later. BYTEPOS is the byte position corresponding to
2324 CHARPOS. BYTEPOS < 0 means compute it from CHARPOS.
2326 If ROW is not null, calls to produce_glyphs with IT as parameter
2327 will produce glyphs in that row.
2329 BASE_FACE_ID is the id of a base face to use. It must be one of
2330 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2331 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2332 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2334 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2335 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2336 will be initialized to use the corresponding mode line glyph row of
2337 the desired matrix of W. */
2339 void
2340 init_iterator (struct it *it, struct window *w,
2341 EMACS_INT charpos, EMACS_INT bytepos,
2342 struct glyph_row *row, enum face_id base_face_id)
2344 int highlight_region_p;
2345 enum face_id remapped_base_face_id = base_face_id;
2347 /* Some precondition checks. */
2348 xassert (w != NULL && it != NULL);
2349 xassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
2350 && charpos <= ZV));
2352 /* If face attributes have been changed since the last redisplay,
2353 free realized faces now because they depend on face definitions
2354 that might have changed. Don't free faces while there might be
2355 desired matrices pending which reference these faces. */
2356 if (face_change_count && !inhibit_free_realized_faces)
2358 face_change_count = 0;
2359 free_all_realized_faces (Qnil);
2362 /* Perhaps remap BASE_FACE_ID to a user-specified alternative. */
2363 if (! NILP (Vface_remapping_alist))
2364 remapped_base_face_id = lookup_basic_face (XFRAME (w->frame), base_face_id);
2366 /* Use one of the mode line rows of W's desired matrix if
2367 appropriate. */
2368 if (row == NULL)
2370 if (base_face_id == MODE_LINE_FACE_ID
2371 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
2372 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
2373 else if (base_face_id == HEADER_LINE_FACE_ID)
2374 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
2377 /* Clear IT. */
2378 memset (it, 0, sizeof *it);
2379 it->current.overlay_string_index = -1;
2380 it->current.dpvec_index = -1;
2381 it->base_face_id = remapped_base_face_id;
2382 it->string = Qnil;
2383 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
2384 it->paragraph_embedding = L2R;
2385 it->bidi_it.string.lstring = Qnil;
2386 it->bidi_it.string.s = NULL;
2387 it->bidi_it.string.bufpos = 0;
2389 /* The window in which we iterate over current_buffer: */
2390 XSETWINDOW (it->window, w);
2391 it->w = w;
2392 it->f = XFRAME (w->frame);
2394 it->cmp_it.id = -1;
2396 /* Extra space between lines (on window systems only). */
2397 if (base_face_id == DEFAULT_FACE_ID
2398 && FRAME_WINDOW_P (it->f))
2400 if (NATNUMP (BVAR (current_buffer, extra_line_spacing)))
2401 it->extra_line_spacing = XFASTINT (BVAR (current_buffer, extra_line_spacing));
2402 else if (FLOATP (BVAR (current_buffer, extra_line_spacing)))
2403 it->extra_line_spacing = (XFLOAT_DATA (BVAR (current_buffer, extra_line_spacing))
2404 * FRAME_LINE_HEIGHT (it->f));
2405 else if (it->f->extra_line_spacing > 0)
2406 it->extra_line_spacing = it->f->extra_line_spacing;
2407 it->max_extra_line_spacing = 0;
2410 /* If realized faces have been removed, e.g. because of face
2411 attribute changes of named faces, recompute them. When running
2412 in batch mode, the face cache of the initial frame is null. If
2413 we happen to get called, make a dummy face cache. */
2414 if (FRAME_FACE_CACHE (it->f) == NULL)
2415 init_frame_faces (it->f);
2416 if (FRAME_FACE_CACHE (it->f)->used == 0)
2417 recompute_basic_faces (it->f);
2419 /* Current value of the `slice', `space-width', and 'height' properties. */
2420 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
2421 it->space_width = Qnil;
2422 it->font_height = Qnil;
2423 it->override_ascent = -1;
2425 /* Are control characters displayed as `^C'? */
2426 it->ctl_arrow_p = !NILP (BVAR (current_buffer, ctl_arrow));
2428 /* -1 means everything between a CR and the following line end
2429 is invisible. >0 means lines indented more than this value are
2430 invisible. */
2431 it->selective = (INTEGERP (BVAR (current_buffer, selective_display))
2432 ? XINT (BVAR (current_buffer, selective_display))
2433 : (!NILP (BVAR (current_buffer, selective_display))
2434 ? -1 : 0));
2435 it->selective_display_ellipsis_p
2436 = !NILP (BVAR (current_buffer, selective_display_ellipses));
2438 /* Display table to use. */
2439 it->dp = window_display_table (w);
2441 /* Are multibyte characters enabled in current_buffer? */
2442 it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
2444 /* Non-zero if we should highlight the region. */
2445 highlight_region_p
2446 = (!NILP (Vtransient_mark_mode)
2447 && !NILP (BVAR (current_buffer, mark_active))
2448 && XMARKER (BVAR (current_buffer, mark))->buffer != 0);
2450 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
2451 start and end of a visible region in window IT->w. Set both to
2452 -1 to indicate no region. */
2453 if (highlight_region_p
2454 /* Maybe highlight only in selected window. */
2455 && (/* Either show region everywhere. */
2456 highlight_nonselected_windows
2457 /* Or show region in the selected window. */
2458 || w == XWINDOW (selected_window)
2459 /* Or show the region if we are in the mini-buffer and W is
2460 the window the mini-buffer refers to. */
2461 || (MINI_WINDOW_P (XWINDOW (selected_window))
2462 && WINDOWP (minibuf_selected_window)
2463 && w == XWINDOW (minibuf_selected_window))))
2465 EMACS_INT markpos = marker_position (BVAR (current_buffer, mark));
2466 it->region_beg_charpos = min (PT, markpos);
2467 it->region_end_charpos = max (PT, markpos);
2469 else
2470 it->region_beg_charpos = it->region_end_charpos = -1;
2472 /* Get the position at which the redisplay_end_trigger hook should
2473 be run, if it is to be run at all. */
2474 if (MARKERP (w->redisplay_end_trigger)
2475 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2476 it->redisplay_end_trigger_charpos
2477 = marker_position (w->redisplay_end_trigger);
2478 else if (INTEGERP (w->redisplay_end_trigger))
2479 it->redisplay_end_trigger_charpos = XINT (w->redisplay_end_trigger);
2481 /* Correct bogus values of tab_width. */
2482 it->tab_width = XINT (BVAR (current_buffer, tab_width));
2483 if (it->tab_width <= 0 || it->tab_width > 1000)
2484 it->tab_width = 8;
2486 /* Are lines in the display truncated? */
2487 if (base_face_id != DEFAULT_FACE_ID
2488 || XINT (it->w->hscroll)
2489 || (! WINDOW_FULL_WIDTH_P (it->w)
2490 && ((!NILP (Vtruncate_partial_width_windows)
2491 && !INTEGERP (Vtruncate_partial_width_windows))
2492 || (INTEGERP (Vtruncate_partial_width_windows)
2493 && (WINDOW_TOTAL_COLS (it->w)
2494 < XINT (Vtruncate_partial_width_windows))))))
2495 it->line_wrap = TRUNCATE;
2496 else if (NILP (BVAR (current_buffer, truncate_lines)))
2497 it->line_wrap = NILP (BVAR (current_buffer, word_wrap))
2498 ? WINDOW_WRAP : WORD_WRAP;
2499 else
2500 it->line_wrap = TRUNCATE;
2502 /* Get dimensions of truncation and continuation glyphs. These are
2503 displayed as fringe bitmaps under X, so we don't need them for such
2504 frames. */
2505 if (!FRAME_WINDOW_P (it->f))
2507 if (it->line_wrap == TRUNCATE)
2509 /* We will need the truncation glyph. */
2510 xassert (it->glyph_row == NULL);
2511 produce_special_glyphs (it, IT_TRUNCATION);
2512 it->truncation_pixel_width = it->pixel_width;
2514 else
2516 /* We will need the continuation glyph. */
2517 xassert (it->glyph_row == NULL);
2518 produce_special_glyphs (it, IT_CONTINUATION);
2519 it->continuation_pixel_width = it->pixel_width;
2522 /* Reset these values to zero because the produce_special_glyphs
2523 above has changed them. */
2524 it->pixel_width = it->ascent = it->descent = 0;
2525 it->phys_ascent = it->phys_descent = 0;
2528 /* Set this after getting the dimensions of truncation and
2529 continuation glyphs, so that we don't produce glyphs when calling
2530 produce_special_glyphs, above. */
2531 it->glyph_row = row;
2532 it->area = TEXT_AREA;
2534 /* Forget any previous info about this row being reversed. */
2535 if (it->glyph_row)
2536 it->glyph_row->reversed_p = 0;
2538 /* Get the dimensions of the display area. The display area
2539 consists of the visible window area plus a horizontally scrolled
2540 part to the left of the window. All x-values are relative to the
2541 start of this total display area. */
2542 if (base_face_id != DEFAULT_FACE_ID)
2544 /* Mode lines, menu bar in terminal frames. */
2545 it->first_visible_x = 0;
2546 it->last_visible_x = WINDOW_TOTAL_WIDTH (w);
2548 else
2550 it->first_visible_x
2551 = XFASTINT (it->w->hscroll) * FRAME_COLUMN_WIDTH (it->f);
2552 it->last_visible_x = (it->first_visible_x
2553 + window_box_width (w, TEXT_AREA));
2555 /* If we truncate lines, leave room for the truncator glyph(s) at
2556 the right margin. Otherwise, leave room for the continuation
2557 glyph(s). Truncation and continuation glyphs are not inserted
2558 for window-based redisplay. */
2559 if (!FRAME_WINDOW_P (it->f))
2561 if (it->line_wrap == TRUNCATE)
2562 it->last_visible_x -= it->truncation_pixel_width;
2563 else
2564 it->last_visible_x -= it->continuation_pixel_width;
2567 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
2568 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
2571 /* Leave room for a border glyph. */
2572 if (!FRAME_WINDOW_P (it->f)
2573 && !WINDOW_RIGHTMOST_P (it->w))
2574 it->last_visible_x -= 1;
2576 it->last_visible_y = window_text_bottom_y (w);
2578 /* For mode lines and alike, arrange for the first glyph having a
2579 left box line if the face specifies a box. */
2580 if (base_face_id != DEFAULT_FACE_ID)
2582 struct face *face;
2584 it->face_id = remapped_base_face_id;
2586 /* If we have a boxed mode line, make the first character appear
2587 with a left box line. */
2588 face = FACE_FROM_ID (it->f, remapped_base_face_id);
2589 if (face->box != FACE_NO_BOX)
2590 it->start_of_box_run_p = 1;
2593 /* If a buffer position was specified, set the iterator there,
2594 getting overlays and face properties from that position. */
2595 if (charpos >= BUF_BEG (current_buffer))
2597 it->end_charpos = ZV;
2598 it->face_id = -1;
2599 IT_CHARPOS (*it) = charpos;
2601 /* Compute byte position if not specified. */
2602 if (bytepos < charpos)
2603 IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos);
2604 else
2605 IT_BYTEPOS (*it) = bytepos;
2607 it->start = it->current;
2608 /* Do we need to reorder bidirectional text? Not if this is a
2609 unibyte buffer: by definition, none of the single-byte
2610 characters are strong R2L, so no reordering is needed. And
2611 bidi.c doesn't support unibyte buffers anyway. */
2612 it->bidi_p =
2613 !NILP (BVAR (current_buffer, bidi_display_reordering))
2614 && it->multibyte_p;
2616 /* If we are to reorder bidirectional text, init the bidi
2617 iterator. */
2618 if (it->bidi_p)
2620 /* Note the paragraph direction that this buffer wants to
2621 use. */
2622 if (EQ (BVAR (current_buffer, bidi_paragraph_direction),
2623 Qleft_to_right))
2624 it->paragraph_embedding = L2R;
2625 else if (EQ (BVAR (current_buffer, bidi_paragraph_direction),
2626 Qright_to_left))
2627 it->paragraph_embedding = R2L;
2628 else
2629 it->paragraph_embedding = NEUTRAL_DIR;
2630 bidi_unshelve_cache (NULL);
2631 bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
2632 &it->bidi_it);
2635 /* Compute faces etc. */
2636 reseat (it, it->current.pos, 1);
2639 CHECK_IT (it);
2643 /* Initialize IT for the display of window W with window start POS. */
2645 void
2646 start_display (struct it *it, struct window *w, struct text_pos pos)
2648 struct glyph_row *row;
2649 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
2651 row = w->desired_matrix->rows + first_vpos;
2652 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
2653 it->first_vpos = first_vpos;
2655 /* Don't reseat to previous visible line start if current start
2656 position is in a string or image. */
2657 if (it->method == GET_FROM_BUFFER && it->line_wrap != TRUNCATE)
2659 int start_at_line_beg_p;
2660 int first_y = it->current_y;
2662 /* If window start is not at a line start, skip forward to POS to
2663 get the correct continuation lines width. */
2664 start_at_line_beg_p = (CHARPOS (pos) == BEGV
2665 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
2666 if (!start_at_line_beg_p)
2668 int new_x;
2670 reseat_at_previous_visible_line_start (it);
2671 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
2673 new_x = it->current_x + it->pixel_width;
2675 /* If lines are continued, this line may end in the middle
2676 of a multi-glyph character (e.g. a control character
2677 displayed as \003, or in the middle of an overlay
2678 string). In this case move_it_to above will not have
2679 taken us to the start of the continuation line but to the
2680 end of the continued line. */
2681 if (it->current_x > 0
2682 && it->line_wrap != TRUNCATE /* Lines are continued. */
2683 && (/* And glyph doesn't fit on the line. */
2684 new_x > it->last_visible_x
2685 /* Or it fits exactly and we're on a window
2686 system frame. */
2687 || (new_x == it->last_visible_x
2688 && FRAME_WINDOW_P (it->f))))
2690 if (it->current.dpvec_index >= 0
2691 || it->current.overlay_string_index >= 0)
2693 set_iterator_to_next (it, 1);
2694 move_it_in_display_line_to (it, -1, -1, 0);
2697 it->continuation_lines_width += it->current_x;
2700 /* We're starting a new display line, not affected by the
2701 height of the continued line, so clear the appropriate
2702 fields in the iterator structure. */
2703 it->max_ascent = it->max_descent = 0;
2704 it->max_phys_ascent = it->max_phys_descent = 0;
2706 it->current_y = first_y;
2707 it->vpos = 0;
2708 it->current_x = it->hpos = 0;
2714 /* Return 1 if POS is a position in ellipses displayed for invisible
2715 text. W is the window we display, for text property lookup. */
2717 static int
2718 in_ellipses_for_invisible_text_p (struct display_pos *pos, struct window *w)
2720 Lisp_Object prop, window;
2721 int ellipses_p = 0;
2722 EMACS_INT charpos = CHARPOS (pos->pos);
2724 /* If POS specifies a position in a display vector, this might
2725 be for an ellipsis displayed for invisible text. We won't
2726 get the iterator set up for delivering that ellipsis unless
2727 we make sure that it gets aware of the invisible text. */
2728 if (pos->dpvec_index >= 0
2729 && pos->overlay_string_index < 0
2730 && CHARPOS (pos->string_pos) < 0
2731 && charpos > BEGV
2732 && (XSETWINDOW (window, w),
2733 prop = Fget_char_property (make_number (charpos),
2734 Qinvisible, window),
2735 !TEXT_PROP_MEANS_INVISIBLE (prop)))
2737 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
2738 window);
2739 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
2742 return ellipses_p;
2746 /* Initialize IT for stepping through current_buffer in window W,
2747 starting at position POS that includes overlay string and display
2748 vector/ control character translation position information. Value
2749 is zero if there are overlay strings with newlines at POS. */
2751 static int
2752 init_from_display_pos (struct it *it, struct window *w, struct display_pos *pos)
2754 EMACS_INT charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
2755 int i, overlay_strings_with_newlines = 0;
2757 /* If POS specifies a position in a display vector, this might
2758 be for an ellipsis displayed for invisible text. We won't
2759 get the iterator set up for delivering that ellipsis unless
2760 we make sure that it gets aware of the invisible text. */
2761 if (in_ellipses_for_invisible_text_p (pos, w))
2763 --charpos;
2764 bytepos = 0;
2767 /* Keep in mind: the call to reseat in init_iterator skips invisible
2768 text, so we might end up at a position different from POS. This
2769 is only a problem when POS is a row start after a newline and an
2770 overlay starts there with an after-string, and the overlay has an
2771 invisible property. Since we don't skip invisible text in
2772 display_line and elsewhere immediately after consuming the
2773 newline before the row start, such a POS will not be in a string,
2774 but the call to init_iterator below will move us to the
2775 after-string. */
2776 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
2778 /* This only scans the current chunk -- it should scan all chunks.
2779 However, OVERLAY_STRING_CHUNK_SIZE has been increased from 3 in 21.1
2780 to 16 in 22.1 to make this a lesser problem. */
2781 for (i = 0; i < it->n_overlay_strings && i < OVERLAY_STRING_CHUNK_SIZE; ++i)
2783 const char *s = SSDATA (it->overlay_strings[i]);
2784 const char *e = s + SBYTES (it->overlay_strings[i]);
2786 while (s < e && *s != '\n')
2787 ++s;
2789 if (s < e)
2791 overlay_strings_with_newlines = 1;
2792 break;
2796 /* If position is within an overlay string, set up IT to the right
2797 overlay string. */
2798 if (pos->overlay_string_index >= 0)
2800 int relative_index;
2802 /* If the first overlay string happens to have a `display'
2803 property for an image, the iterator will be set up for that
2804 image, and we have to undo that setup first before we can
2805 correct the overlay string index. */
2806 if (it->method == GET_FROM_IMAGE)
2807 pop_it (it);
2809 /* We already have the first chunk of overlay strings in
2810 IT->overlay_strings. Load more until the one for
2811 pos->overlay_string_index is in IT->overlay_strings. */
2812 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
2814 int n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
2815 it->current.overlay_string_index = 0;
2816 while (n--)
2818 load_overlay_strings (it, 0);
2819 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
2823 it->current.overlay_string_index = pos->overlay_string_index;
2824 relative_index = (it->current.overlay_string_index
2825 % OVERLAY_STRING_CHUNK_SIZE);
2826 it->string = it->overlay_strings[relative_index];
2827 xassert (STRINGP (it->string));
2828 it->current.string_pos = pos->string_pos;
2829 it->method = GET_FROM_STRING;
2832 if (CHARPOS (pos->string_pos) >= 0)
2834 /* Recorded position is not in an overlay string, but in another
2835 string. This can only be a string from a `display' property.
2836 IT should already be filled with that string. */
2837 it->current.string_pos = pos->string_pos;
2838 xassert (STRINGP (it->string));
2841 /* Restore position in display vector translations, control
2842 character translations or ellipses. */
2843 if (pos->dpvec_index >= 0)
2845 if (it->dpvec == NULL)
2846 get_next_display_element (it);
2847 xassert (it->dpvec && it->current.dpvec_index == 0);
2848 it->current.dpvec_index = pos->dpvec_index;
2851 CHECK_IT (it);
2852 return !overlay_strings_with_newlines;
2856 /* Initialize IT for stepping through current_buffer in window W
2857 starting at ROW->start. */
2859 static void
2860 init_to_row_start (struct it *it, struct window *w, struct glyph_row *row)
2862 init_from_display_pos (it, w, &row->start);
2863 it->start = row->start;
2864 it->continuation_lines_width = row->continuation_lines_width;
2865 CHECK_IT (it);
2869 /* Initialize IT for stepping through current_buffer in window W
2870 starting in the line following ROW, i.e. starting at ROW->end.
2871 Value is zero if there are overlay strings with newlines at ROW's
2872 end position. */
2874 static int
2875 init_to_row_end (struct it *it, struct window *w, struct glyph_row *row)
2877 int success = 0;
2879 if (init_from_display_pos (it, w, &row->end))
2881 if (row->continued_p)
2882 it->continuation_lines_width
2883 = row->continuation_lines_width + row->pixel_width;
2884 CHECK_IT (it);
2885 success = 1;
2888 return success;
2894 /***********************************************************************
2895 Text properties
2896 ***********************************************************************/
2898 /* Called when IT reaches IT->stop_charpos. Handle text property and
2899 overlay changes. Set IT->stop_charpos to the next position where
2900 to stop. */
2902 static void
2903 handle_stop (struct it *it)
2905 enum prop_handled handled;
2906 int handle_overlay_change_p;
2907 struct props *p;
2909 it->dpvec = NULL;
2910 it->current.dpvec_index = -1;
2911 handle_overlay_change_p = !it->ignore_overlay_strings_at_pos_p;
2912 it->ignore_overlay_strings_at_pos_p = 0;
2913 it->ellipsis_p = 0;
2915 /* Use face of preceding text for ellipsis (if invisible) */
2916 if (it->selective_display_ellipsis_p)
2917 it->saved_face_id = it->face_id;
2921 handled = HANDLED_NORMALLY;
2923 /* Call text property handlers. */
2924 for (p = it_props; p->handler; ++p)
2926 handled = p->handler (it);
2928 if (handled == HANDLED_RECOMPUTE_PROPS)
2929 break;
2930 else if (handled == HANDLED_RETURN)
2932 /* We still want to show before and after strings from
2933 overlays even if the actual buffer text is replaced. */
2934 if (!handle_overlay_change_p
2935 || it->sp > 1
2936 || !get_overlay_strings_1 (it, 0, 0))
2938 if (it->ellipsis_p)
2939 setup_for_ellipsis (it, 0);
2940 /* When handling a display spec, we might load an
2941 empty string. In that case, discard it here. We
2942 used to discard it in handle_single_display_spec,
2943 but that causes get_overlay_strings_1, above, to
2944 ignore overlay strings that we must check. */
2945 if (STRINGP (it->string) && !SCHARS (it->string))
2946 pop_it (it);
2947 return;
2949 else if (STRINGP (it->string) && !SCHARS (it->string))
2950 pop_it (it);
2951 else
2953 it->ignore_overlay_strings_at_pos_p = 1;
2954 it->string_from_display_prop_p = 0;
2955 it->from_disp_prop_p = 0;
2956 handle_overlay_change_p = 0;
2958 handled = HANDLED_RECOMPUTE_PROPS;
2959 break;
2961 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
2962 handle_overlay_change_p = 0;
2965 if (handled != HANDLED_RECOMPUTE_PROPS)
2967 /* Don't check for overlay strings below when set to deliver
2968 characters from a display vector. */
2969 if (it->method == GET_FROM_DISPLAY_VECTOR)
2970 handle_overlay_change_p = 0;
2972 /* Handle overlay changes.
2973 This sets HANDLED to HANDLED_RECOMPUTE_PROPS
2974 if it finds overlays. */
2975 if (handle_overlay_change_p)
2976 handled = handle_overlay_change (it);
2979 if (it->ellipsis_p)
2981 setup_for_ellipsis (it, 0);
2982 break;
2985 while (handled == HANDLED_RECOMPUTE_PROPS);
2987 /* Determine where to stop next. */
2988 if (handled == HANDLED_NORMALLY)
2989 compute_stop_pos (it);
2993 /* Compute IT->stop_charpos from text property and overlay change
2994 information for IT's current position. */
2996 static void
2997 compute_stop_pos (struct it *it)
2999 register INTERVAL iv, next_iv;
3000 Lisp_Object object, limit, position;
3001 EMACS_INT charpos, bytepos;
3003 /* If nowhere else, stop at the end. */
3004 it->stop_charpos = it->end_charpos;
3006 if (STRINGP (it->string))
3008 /* Strings are usually short, so don't limit the search for
3009 properties. */
3010 object = it->string;
3011 limit = Qnil;
3012 charpos = IT_STRING_CHARPOS (*it);
3013 bytepos = IT_STRING_BYTEPOS (*it);
3015 else
3017 EMACS_INT pos;
3019 /* If next overlay change is in front of the current stop pos
3020 (which is IT->end_charpos), stop there. Note: value of
3021 next_overlay_change is point-max if no overlay change
3022 follows. */
3023 charpos = IT_CHARPOS (*it);
3024 bytepos = IT_BYTEPOS (*it);
3025 pos = next_overlay_change (charpos);
3026 if (pos < it->stop_charpos)
3027 it->stop_charpos = pos;
3029 /* If showing the region, we have to stop at the region
3030 start or end because the face might change there. */
3031 if (it->region_beg_charpos > 0)
3033 if (IT_CHARPOS (*it) < it->region_beg_charpos)
3034 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
3035 else if (IT_CHARPOS (*it) < it->region_end_charpos)
3036 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
3039 /* Set up variables for computing the stop position from text
3040 property changes. */
3041 XSETBUFFER (object, current_buffer);
3042 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
3045 /* Get the interval containing IT's position. Value is a null
3046 interval if there isn't such an interval. */
3047 position = make_number (charpos);
3048 iv = validate_interval_range (object, &position, &position, 0);
3049 if (!NULL_INTERVAL_P (iv))
3051 Lisp_Object values_here[LAST_PROP_IDX];
3052 struct props *p;
3054 /* Get properties here. */
3055 for (p = it_props; p->handler; ++p)
3056 values_here[p->idx] = textget (iv->plist, *p->name);
3058 /* Look for an interval following iv that has different
3059 properties. */
3060 for (next_iv = next_interval (iv);
3061 (!NULL_INTERVAL_P (next_iv)
3062 && (NILP (limit)
3063 || XFASTINT (limit) > next_iv->position));
3064 next_iv = next_interval (next_iv))
3066 for (p = it_props; p->handler; ++p)
3068 Lisp_Object new_value;
3070 new_value = textget (next_iv->plist, *p->name);
3071 if (!EQ (values_here[p->idx], new_value))
3072 break;
3075 if (p->handler)
3076 break;
3079 if (!NULL_INTERVAL_P (next_iv))
3081 if (INTEGERP (limit)
3082 && next_iv->position >= XFASTINT (limit))
3083 /* No text property change up to limit. */
3084 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
3085 else
3086 /* Text properties change in next_iv. */
3087 it->stop_charpos = min (it->stop_charpos, next_iv->position);
3091 if (it->cmp_it.id < 0)
3093 EMACS_INT stoppos = it->end_charpos;
3095 if (it->bidi_p && it->bidi_it.scan_dir < 0)
3096 stoppos = -1;
3097 composition_compute_stop_pos (&it->cmp_it, charpos, bytepos,
3098 stoppos, it->string);
3101 xassert (STRINGP (it->string)
3102 || (it->stop_charpos >= BEGV
3103 && it->stop_charpos >= IT_CHARPOS (*it)));
3107 /* Return the position of the next overlay change after POS in
3108 current_buffer. Value is point-max if no overlay change
3109 follows. This is like `next-overlay-change' but doesn't use
3110 xmalloc. */
3112 static EMACS_INT
3113 next_overlay_change (EMACS_INT pos)
3115 ptrdiff_t i, noverlays;
3116 EMACS_INT endpos;
3117 Lisp_Object *overlays;
3119 /* Get all overlays at the given position. */
3120 GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, 1);
3122 /* If any of these overlays ends before endpos,
3123 use its ending point instead. */
3124 for (i = 0; i < noverlays; ++i)
3126 Lisp_Object oend;
3127 EMACS_INT oendpos;
3129 oend = OVERLAY_END (overlays[i]);
3130 oendpos = OVERLAY_POSITION (oend);
3131 endpos = min (endpos, oendpos);
3134 return endpos;
3137 /* Record one cached display string position found recently by
3138 compute_display_string_pos. */
3139 static EMACS_INT cached_disp_pos;
3140 static EMACS_INT cached_prev_pos = -1;
3141 static struct buffer *cached_disp_buffer;
3142 static int cached_disp_modiff;
3143 static int cached_disp_overlay_modiff;
3145 /* Return the character position of a display string at or after
3146 position specified by POSITION. If no display string exists at or
3147 after POSITION, return ZV. A display string is either an overlay
3148 with `display' property whose value is a string, or a `display'
3149 text property whose value is a string. STRING is data about the
3150 string to iterate; if STRING->lstring is nil, we are iterating a
3151 buffer. FRAME_WINDOW_P is non-zero when we are displaying a window
3152 on a GUI frame. */
3153 EMACS_INT
3154 compute_display_string_pos (struct text_pos *position,
3155 struct bidi_string_data *string, int frame_window_p)
3157 /* OBJECT = nil means current buffer. */
3158 Lisp_Object object =
3159 (string && STRINGP (string->lstring)) ? string->lstring : Qnil;
3160 Lisp_Object pos, spec;
3161 int string_p = (string && (STRINGP (string->lstring) || string->s));
3162 EMACS_INT eob = string_p ? string->schars : ZV;
3163 EMACS_INT begb = string_p ? 0 : BEGV;
3164 EMACS_INT bufpos, charpos = CHARPOS (*position);
3165 struct text_pos tpos;
3166 struct buffer *b;
3168 if (charpos >= eob
3169 /* We don't support display properties whose values are strings
3170 that have display string properties. */
3171 || string->from_disp_str
3172 /* C strings cannot have display properties. */
3173 || (string->s && !STRINGP (object)))
3174 return eob;
3176 /* Check the cached values. */
3177 if (!STRINGP (object))
3179 if (NILP (object))
3180 b = current_buffer;
3181 else
3182 b = XBUFFER (object);
3183 if (b == cached_disp_buffer
3184 && BUF_MODIFF (b) == cached_disp_modiff
3185 && BUF_OVERLAY_MODIFF (b) == cached_disp_overlay_modiff
3186 && !b->clip_changed)
3188 if (cached_prev_pos >= 0
3189 && cached_prev_pos < charpos && charpos <= cached_disp_pos)
3190 return cached_disp_pos;
3191 /* Handle overstepping either end of the known interval. */
3192 if (charpos > cached_disp_pos)
3193 cached_prev_pos = cached_disp_pos;
3194 else /* charpos <= cached_prev_pos */
3195 cached_prev_pos = max (charpos - 1, 0);
3198 /* Record new values in the cache. */
3199 if (b != cached_disp_buffer)
3201 cached_disp_buffer = b;
3202 cached_prev_pos = max (charpos - 1, 0);
3204 cached_disp_modiff = BUF_MODIFF (b);
3205 cached_disp_overlay_modiff = BUF_OVERLAY_MODIFF (b);
3208 /* If the character at CHARPOS is where the display string begins,
3209 return CHARPOS. */
3210 pos = make_number (charpos);
3211 if (STRINGP (object))
3212 bufpos = string->bufpos;
3213 else
3214 bufpos = charpos;
3215 tpos = *position;
3216 if (!NILP (spec = Fget_char_property (pos, Qdisplay, object))
3217 && (charpos <= begb
3218 || !EQ (Fget_char_property (make_number (charpos - 1), Qdisplay,
3219 object),
3220 spec))
3221 && handle_display_spec (NULL, spec, object, Qnil, &tpos, bufpos,
3222 frame_window_p))
3224 if (!STRINGP (object))
3225 cached_disp_pos = charpos;
3226 return charpos;
3229 /* Look forward for the first character with a `display' property
3230 that will replace the underlying text when displayed. */
3231 do {
3232 pos = Fnext_single_char_property_change (pos, Qdisplay, object, Qnil);
3233 CHARPOS (tpos) = XFASTINT (pos);
3234 if (STRINGP (object))
3235 BYTEPOS (tpos) = string_char_to_byte (object, CHARPOS (tpos));
3236 else
3237 BYTEPOS (tpos) = CHAR_TO_BYTE (CHARPOS (tpos));
3238 if (CHARPOS (tpos) >= eob)
3239 break;
3240 spec = Fget_char_property (pos, Qdisplay, object);
3241 if (!STRINGP (object))
3242 bufpos = CHARPOS (tpos);
3243 } while (NILP (spec)
3244 || !handle_display_spec (NULL, spec, object, Qnil, &tpos, bufpos,
3245 frame_window_p));
3247 if (!STRINGP (object))
3248 cached_disp_pos = CHARPOS (tpos);
3249 return CHARPOS (tpos);
3252 /* Return the character position of the end of the display string that
3253 started at CHARPOS. A display string is either an overlay with
3254 `display' property whose value is a string or a `display' text
3255 property whose value is a string. */
3256 EMACS_INT
3257 compute_display_string_end (EMACS_INT charpos, struct bidi_string_data *string)
3259 /* OBJECT = nil means current buffer. */
3260 Lisp_Object object =
3261 (string && STRINGP (string->lstring)) ? string->lstring : Qnil;
3262 Lisp_Object pos = make_number (charpos);
3263 EMACS_INT eob =
3264 (STRINGP (object) || (string && string->s)) ? string->schars : ZV;
3266 if (charpos >= eob || (string->s && !STRINGP (object)))
3267 return eob;
3269 if (NILP (Fget_char_property (pos, Qdisplay, object)))
3270 abort ();
3272 /* Look forward for the first character where the `display' property
3273 changes. */
3274 pos = Fnext_single_char_property_change (pos, Qdisplay, object, Qnil);
3276 return XFASTINT (pos);
3281 /***********************************************************************
3282 Fontification
3283 ***********************************************************************/
3285 /* Handle changes in the `fontified' property of the current buffer by
3286 calling hook functions from Qfontification_functions to fontify
3287 regions of text. */
3289 static enum prop_handled
3290 handle_fontified_prop (struct it *it)
3292 Lisp_Object prop, pos;
3293 enum prop_handled handled = HANDLED_NORMALLY;
3295 if (!NILP (Vmemory_full))
3296 return handled;
3298 /* Get the value of the `fontified' property at IT's current buffer
3299 position. (The `fontified' property doesn't have a special
3300 meaning in strings.) If the value is nil, call functions from
3301 Qfontification_functions. */
3302 if (!STRINGP (it->string)
3303 && it->s == NULL
3304 && !NILP (Vfontification_functions)
3305 && !NILP (Vrun_hooks)
3306 && (pos = make_number (IT_CHARPOS (*it)),
3307 prop = Fget_char_property (pos, Qfontified, Qnil),
3308 /* Ignore the special cased nil value always present at EOB since
3309 no amount of fontifying will be able to change it. */
3310 NILP (prop) && IT_CHARPOS (*it) < Z))
3312 int count = SPECPDL_INDEX ();
3313 Lisp_Object val;
3314 struct buffer *obuf = current_buffer;
3315 int begv = BEGV, zv = ZV;
3316 int old_clip_changed = current_buffer->clip_changed;
3318 val = Vfontification_functions;
3319 specbind (Qfontification_functions, Qnil);
3321 xassert (it->end_charpos == ZV);
3323 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
3324 safe_call1 (val, pos);
3325 else
3327 Lisp_Object fns, fn;
3328 struct gcpro gcpro1, gcpro2;
3330 fns = Qnil;
3331 GCPRO2 (val, fns);
3333 for (; CONSP (val); val = XCDR (val))
3335 fn = XCAR (val);
3337 if (EQ (fn, Qt))
3339 /* A value of t indicates this hook has a local
3340 binding; it means to run the global binding too.
3341 In a global value, t should not occur. If it
3342 does, we must ignore it to avoid an endless
3343 loop. */
3344 for (fns = Fdefault_value (Qfontification_functions);
3345 CONSP (fns);
3346 fns = XCDR (fns))
3348 fn = XCAR (fns);
3349 if (!EQ (fn, Qt))
3350 safe_call1 (fn, pos);
3353 else
3354 safe_call1 (fn, pos);
3357 UNGCPRO;
3360 unbind_to (count, Qnil);
3362 /* Fontification functions routinely call `save-restriction'.
3363 Normally, this tags clip_changed, which can confuse redisplay
3364 (see discussion in Bug#6671). Since we don't perform any
3365 special handling of fontification changes in the case where
3366 `save-restriction' isn't called, there's no point doing so in
3367 this case either. So, if the buffer's restrictions are
3368 actually left unchanged, reset clip_changed. */
3369 if (obuf == current_buffer)
3371 if (begv == BEGV && zv == ZV)
3372 current_buffer->clip_changed = old_clip_changed;
3374 /* There isn't much we can reasonably do to protect against
3375 misbehaving fontification, but here's a fig leaf. */
3376 else if (!NILP (BVAR (obuf, name)))
3377 set_buffer_internal_1 (obuf);
3379 /* The fontification code may have added/removed text.
3380 It could do even a lot worse, but let's at least protect against
3381 the most obvious case where only the text past `pos' gets changed',
3382 as is/was done in grep.el where some escapes sequences are turned
3383 into face properties (bug#7876). */
3384 it->end_charpos = ZV;
3386 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
3387 something. This avoids an endless loop if they failed to
3388 fontify the text for which reason ever. */
3389 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
3390 handled = HANDLED_RECOMPUTE_PROPS;
3393 return handled;
3398 /***********************************************************************
3399 Faces
3400 ***********************************************************************/
3402 /* Set up iterator IT from face properties at its current position.
3403 Called from handle_stop. */
3405 static enum prop_handled
3406 handle_face_prop (struct it *it)
3408 int new_face_id;
3409 EMACS_INT next_stop;
3411 if (!STRINGP (it->string))
3413 new_face_id
3414 = face_at_buffer_position (it->w,
3415 IT_CHARPOS (*it),
3416 it->region_beg_charpos,
3417 it->region_end_charpos,
3418 &next_stop,
3419 (IT_CHARPOS (*it)
3420 + TEXT_PROP_DISTANCE_LIMIT),
3421 0, it->base_face_id);
3423 /* Is this a start of a run of characters with box face?
3424 Caveat: this can be called for a freshly initialized
3425 iterator; face_id is -1 in this case. We know that the new
3426 face will not change until limit, i.e. if the new face has a
3427 box, all characters up to limit will have one. But, as
3428 usual, we don't know whether limit is really the end. */
3429 if (new_face_id != it->face_id)
3431 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3433 /* If new face has a box but old face has not, this is
3434 the start of a run of characters with box, i.e. it has
3435 a shadow on the left side. The value of face_id of the
3436 iterator will be -1 if this is the initial call that gets
3437 the face. In this case, we have to look in front of IT's
3438 position and see whether there is a face != new_face_id. */
3439 it->start_of_box_run_p
3440 = (new_face->box != FACE_NO_BOX
3441 && (it->face_id >= 0
3442 || IT_CHARPOS (*it) == BEG
3443 || new_face_id != face_before_it_pos (it)));
3444 it->face_box_p = new_face->box != FACE_NO_BOX;
3447 else
3449 int base_face_id;
3450 EMACS_INT bufpos;
3451 int i;
3452 Lisp_Object from_overlay
3453 = (it->current.overlay_string_index >= 0
3454 ? it->string_overlays[it->current.overlay_string_index]
3455 : Qnil);
3457 /* See if we got to this string directly or indirectly from
3458 an overlay property. That includes the before-string or
3459 after-string of an overlay, strings in display properties
3460 provided by an overlay, their text properties, etc.
3462 FROM_OVERLAY is the overlay that brought us here, or nil if none. */
3463 if (! NILP (from_overlay))
3464 for (i = it->sp - 1; i >= 0; i--)
3466 if (it->stack[i].current.overlay_string_index >= 0)
3467 from_overlay
3468 = it->string_overlays[it->stack[i].current.overlay_string_index];
3469 else if (! NILP (it->stack[i].from_overlay))
3470 from_overlay = it->stack[i].from_overlay;
3472 if (!NILP (from_overlay))
3473 break;
3476 if (! NILP (from_overlay))
3478 bufpos = IT_CHARPOS (*it);
3479 /* For a string from an overlay, the base face depends
3480 only on text properties and ignores overlays. */
3481 base_face_id
3482 = face_for_overlay_string (it->w,
3483 IT_CHARPOS (*it),
3484 it->region_beg_charpos,
3485 it->region_end_charpos,
3486 &next_stop,
3487 (IT_CHARPOS (*it)
3488 + TEXT_PROP_DISTANCE_LIMIT),
3490 from_overlay);
3492 else
3494 bufpos = 0;
3496 /* For strings from a `display' property, use the face at
3497 IT's current buffer position as the base face to merge
3498 with, so that overlay strings appear in the same face as
3499 surrounding text, unless they specify their own
3500 faces. */
3501 base_face_id = underlying_face_id (it);
3504 new_face_id = face_at_string_position (it->w,
3505 it->string,
3506 IT_STRING_CHARPOS (*it),
3507 bufpos,
3508 it->region_beg_charpos,
3509 it->region_end_charpos,
3510 &next_stop,
3511 base_face_id, 0);
3513 /* Is this a start of a run of characters with box? Caveat:
3514 this can be called for a freshly allocated iterator; face_id
3515 is -1 is this case. We know that the new face will not
3516 change until the next check pos, i.e. if the new face has a
3517 box, all characters up to that position will have a
3518 box. But, as usual, we don't know whether that position
3519 is really the end. */
3520 if (new_face_id != it->face_id)
3522 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3523 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
3525 /* If new face has a box but old face hasn't, this is the
3526 start of a run of characters with box, i.e. it has a
3527 shadow on the left side. */
3528 it->start_of_box_run_p
3529 = new_face->box && (old_face == NULL || !old_face->box);
3530 it->face_box_p = new_face->box != FACE_NO_BOX;
3534 it->face_id = new_face_id;
3535 return HANDLED_NORMALLY;
3539 /* Return the ID of the face ``underlying'' IT's current position,
3540 which is in a string. If the iterator is associated with a
3541 buffer, return the face at IT's current buffer position.
3542 Otherwise, use the iterator's base_face_id. */
3544 static int
3545 underlying_face_id (struct it *it)
3547 int face_id = it->base_face_id, i;
3549 xassert (STRINGP (it->string));
3551 for (i = it->sp - 1; i >= 0; --i)
3552 if (NILP (it->stack[i].string))
3553 face_id = it->stack[i].face_id;
3555 return face_id;
3559 /* Compute the face one character before or after the current position
3560 of IT, in the visual order. BEFORE_P non-zero means get the face
3561 in front (to the left in L2R paragraphs, to the right in R2L
3562 paragraphs) of IT's screen position. Value is the ID of the face. */
3564 static int
3565 face_before_or_after_it_pos (struct it *it, int before_p)
3567 int face_id, limit;
3568 EMACS_INT next_check_charpos;
3569 struct it it_copy;
3570 void *it_copy_data = NULL;
3572 xassert (it->s == NULL);
3574 if (STRINGP (it->string))
3576 EMACS_INT bufpos, charpos;
3577 int base_face_id;
3579 /* No face change past the end of the string (for the case
3580 we are padding with spaces). No face change before the
3581 string start. */
3582 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
3583 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
3584 return it->face_id;
3586 if (!it->bidi_p)
3588 /* Set charpos to the position before or after IT's current
3589 position, in the logical order, which in the non-bidi
3590 case is the same as the visual order. */
3591 if (before_p)
3592 charpos = IT_STRING_CHARPOS (*it) - 1;
3593 else if (it->what == IT_COMPOSITION)
3594 /* For composition, we must check the character after the
3595 composition. */
3596 charpos = IT_STRING_CHARPOS (*it) + it->cmp_it.nchars;
3597 else
3598 charpos = IT_STRING_CHARPOS (*it) + 1;
3600 else
3602 if (before_p)
3604 /* With bidi iteration, the character before the current
3605 in the visual order cannot be found by simple
3606 iteration, because "reverse" reordering is not
3607 supported. Instead, we need to use the move_it_*
3608 family of functions. */
3609 /* Ignore face changes before the first visible
3610 character on this display line. */
3611 if (it->current_x <= it->first_visible_x)
3612 return it->face_id;
3613 SAVE_IT (it_copy, *it, it_copy_data);
3614 /* Implementation note: Since move_it_in_display_line
3615 works in the iterator geometry, and thinks the first
3616 character is always the leftmost, even in R2L lines,
3617 we don't need to distinguish between the R2L and L2R
3618 cases here. */
3619 move_it_in_display_line (&it_copy, SCHARS (it_copy.string),
3620 it_copy.current_x - 1, MOVE_TO_X);
3621 charpos = IT_STRING_CHARPOS (it_copy);
3622 RESTORE_IT (it, it, it_copy_data);
3624 else
3626 /* Set charpos to the string position of the character
3627 that comes after IT's current position in the visual
3628 order. */
3629 int n = (it->what == IT_COMPOSITION ? it->cmp_it.nchars : 1);
3631 it_copy = *it;
3632 while (n--)
3633 bidi_move_to_visually_next (&it_copy.bidi_it);
3635 charpos = it_copy.bidi_it.charpos;
3638 xassert (0 <= charpos && charpos <= SCHARS (it->string));
3640 if (it->current.overlay_string_index >= 0)
3641 bufpos = IT_CHARPOS (*it);
3642 else
3643 bufpos = 0;
3645 base_face_id = underlying_face_id (it);
3647 /* Get the face for ASCII, or unibyte. */
3648 face_id = face_at_string_position (it->w,
3649 it->string,
3650 charpos,
3651 bufpos,
3652 it->region_beg_charpos,
3653 it->region_end_charpos,
3654 &next_check_charpos,
3655 base_face_id, 0);
3657 /* Correct the face for charsets different from ASCII. Do it
3658 for the multibyte case only. The face returned above is
3659 suitable for unibyte text if IT->string is unibyte. */
3660 if (STRING_MULTIBYTE (it->string))
3662 struct text_pos pos1 = string_pos (charpos, it->string);
3663 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos1);
3664 int c, len;
3665 struct face *face = FACE_FROM_ID (it->f, face_id);
3667 c = string_char_and_length (p, &len);
3668 face_id = FACE_FOR_CHAR (it->f, face, c, charpos, it->string);
3671 else
3673 struct text_pos pos;
3675 if ((IT_CHARPOS (*it) >= ZV && !before_p)
3676 || (IT_CHARPOS (*it) <= BEGV && before_p))
3677 return it->face_id;
3679 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
3680 pos = it->current.pos;
3682 if (!it->bidi_p)
3684 if (before_p)
3685 DEC_TEXT_POS (pos, it->multibyte_p);
3686 else
3688 if (it->what == IT_COMPOSITION)
3690 /* For composition, we must check the position after
3691 the composition. */
3692 pos.charpos += it->cmp_it.nchars;
3693 pos.bytepos += it->len;
3695 else
3696 INC_TEXT_POS (pos, it->multibyte_p);
3699 else
3701 if (before_p)
3703 /* With bidi iteration, the character before the current
3704 in the visual order cannot be found by simple
3705 iteration, because "reverse" reordering is not
3706 supported. Instead, we need to use the move_it_*
3707 family of functions. */
3708 /* Ignore face changes before the first visible
3709 character on this display line. */
3710 if (it->current_x <= it->first_visible_x)
3711 return it->face_id;
3712 SAVE_IT (it_copy, *it, it_copy_data);
3713 /* Implementation note: Since move_it_in_display_line
3714 works in the iterator geometry, and thinks the first
3715 character is always the leftmost, even in R2L lines,
3716 we don't need to distinguish between the R2L and L2R
3717 cases here. */
3718 move_it_in_display_line (&it_copy, ZV,
3719 it_copy.current_x - 1, MOVE_TO_X);
3720 pos = it_copy.current.pos;
3721 RESTORE_IT (it, it, it_copy_data);
3723 else
3725 /* Set charpos to the buffer position of the character
3726 that comes after IT's current position in the visual
3727 order. */
3728 int n = (it->what == IT_COMPOSITION ? it->cmp_it.nchars : 1);
3730 it_copy = *it;
3731 while (n--)
3732 bidi_move_to_visually_next (&it_copy.bidi_it);
3734 SET_TEXT_POS (pos,
3735 it_copy.bidi_it.charpos, it_copy.bidi_it.bytepos);
3738 xassert (BEGV <= CHARPOS (pos) && CHARPOS (pos) <= ZV);
3740 /* Determine face for CHARSET_ASCII, or unibyte. */
3741 face_id = face_at_buffer_position (it->w,
3742 CHARPOS (pos),
3743 it->region_beg_charpos,
3744 it->region_end_charpos,
3745 &next_check_charpos,
3746 limit, 0, -1);
3748 /* Correct the face for charsets different from ASCII. Do it
3749 for the multibyte case only. The face returned above is
3750 suitable for unibyte text if current_buffer is unibyte. */
3751 if (it->multibyte_p)
3753 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
3754 struct face *face = FACE_FROM_ID (it->f, face_id);
3755 face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), Qnil);
3759 return face_id;
3764 /***********************************************************************
3765 Invisible text
3766 ***********************************************************************/
3768 /* Set up iterator IT from invisible properties at its current
3769 position. Called from handle_stop. */
3771 static enum prop_handled
3772 handle_invisible_prop (struct it *it)
3774 enum prop_handled handled = HANDLED_NORMALLY;
3776 if (STRINGP (it->string))
3778 Lisp_Object prop, end_charpos, limit, charpos;
3780 /* Get the value of the invisible text property at the
3781 current position. Value will be nil if there is no such
3782 property. */
3783 charpos = make_number (IT_STRING_CHARPOS (*it));
3784 prop = Fget_text_property (charpos, Qinvisible, it->string);
3786 if (!NILP (prop)
3787 && IT_STRING_CHARPOS (*it) < it->end_charpos)
3789 EMACS_INT endpos;
3791 handled = HANDLED_RECOMPUTE_PROPS;
3793 /* Get the position at which the next change of the
3794 invisible text property can be found in IT->string.
3795 Value will be nil if the property value is the same for
3796 all the rest of IT->string. */
3797 XSETINT (limit, SCHARS (it->string));
3798 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
3799 it->string, limit);
3801 /* Text at current position is invisible. The next
3802 change in the property is at position end_charpos.
3803 Move IT's current position to that position. */
3804 if (INTEGERP (end_charpos)
3805 && (endpos = XFASTINT (end_charpos)) < XFASTINT (limit))
3807 struct text_pos old;
3808 EMACS_INT oldpos;
3810 old = it->current.string_pos;
3811 oldpos = CHARPOS (old);
3812 if (it->bidi_p)
3814 if (it->bidi_it.first_elt
3815 && it->bidi_it.charpos < SCHARS (it->string))
3816 bidi_paragraph_init (it->paragraph_embedding,
3817 &it->bidi_it, 1);
3818 /* Bidi-iterate out of the invisible text. */
3821 bidi_move_to_visually_next (&it->bidi_it);
3823 while (oldpos <= it->bidi_it.charpos
3824 && it->bidi_it.charpos < endpos);
3826 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
3827 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
3828 if (IT_CHARPOS (*it) >= endpos)
3829 it->prev_stop = endpos;
3831 else
3833 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
3834 compute_string_pos (&it->current.string_pos, old, it->string);
3837 else
3839 /* The rest of the string is invisible. If this is an
3840 overlay string, proceed with the next overlay string
3841 or whatever comes and return a character from there. */
3842 if (it->current.overlay_string_index >= 0)
3844 next_overlay_string (it);
3845 /* Don't check for overlay strings when we just
3846 finished processing them. */
3847 handled = HANDLED_OVERLAY_STRING_CONSUMED;
3849 else
3851 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
3852 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
3857 else
3859 int invis_p;
3860 EMACS_INT newpos, next_stop, start_charpos, tem;
3861 Lisp_Object pos, prop, overlay;
3863 /* First of all, is there invisible text at this position? */
3864 tem = start_charpos = IT_CHARPOS (*it);
3865 pos = make_number (tem);
3866 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
3867 &overlay);
3868 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3870 /* If we are on invisible text, skip over it. */
3871 if (invis_p && start_charpos < it->end_charpos)
3873 /* Record whether we have to display an ellipsis for the
3874 invisible text. */
3875 int display_ellipsis_p = invis_p == 2;
3877 handled = HANDLED_RECOMPUTE_PROPS;
3879 /* Loop skipping over invisible text. The loop is left at
3880 ZV or with IT on the first char being visible again. */
3883 /* Try to skip some invisible text. Return value is the
3884 position reached which can be equal to where we start
3885 if there is nothing invisible there. This skips both
3886 over invisible text properties and overlays with
3887 invisible property. */
3888 newpos = skip_invisible (tem, &next_stop, ZV, it->window);
3890 /* If we skipped nothing at all we weren't at invisible
3891 text in the first place. If everything to the end of
3892 the buffer was skipped, end the loop. */
3893 if (newpos == tem || newpos >= ZV)
3894 invis_p = 0;
3895 else
3897 /* We skipped some characters but not necessarily
3898 all there are. Check if we ended up on visible
3899 text. Fget_char_property returns the property of
3900 the char before the given position, i.e. if we
3901 get invis_p = 0, this means that the char at
3902 newpos is visible. */
3903 pos = make_number (newpos);
3904 prop = Fget_char_property (pos, Qinvisible, it->window);
3905 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3908 /* If we ended up on invisible text, proceed to
3909 skip starting with next_stop. */
3910 if (invis_p)
3911 tem = next_stop;
3913 /* If there are adjacent invisible texts, don't lose the
3914 second one's ellipsis. */
3915 if (invis_p == 2)
3916 display_ellipsis_p = 1;
3918 while (invis_p);
3920 /* The position newpos is now either ZV or on visible text. */
3921 if (it->bidi_p && newpos < ZV)
3923 /* With bidi iteration, the region of invisible text
3924 could start and/or end in the middle of a non-base
3925 embedding level. Therefore, we need to skip
3926 invisible text using the bidi iterator, starting at
3927 IT's current position, until we find ourselves
3928 outside the invisible text. Skipping invisible text
3929 _after_ bidi iteration avoids affecting the visual
3930 order of the displayed text when invisible properties
3931 are added or removed. */
3932 if (it->bidi_it.first_elt && it->bidi_it.charpos < ZV)
3934 /* If we were `reseat'ed to a new paragraph,
3935 determine the paragraph base direction. We need
3936 to do it now because next_element_from_buffer may
3937 not have a chance to do it, if we are going to
3938 skip any text at the beginning, which resets the
3939 FIRST_ELT flag. */
3940 bidi_paragraph_init (it->paragraph_embedding,
3941 &it->bidi_it, 1);
3945 bidi_move_to_visually_next (&it->bidi_it);
3947 while (it->stop_charpos <= it->bidi_it.charpos
3948 && it->bidi_it.charpos < newpos);
3949 IT_CHARPOS (*it) = it->bidi_it.charpos;
3950 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
3951 /* If we overstepped NEWPOS, record its position in the
3952 iterator, so that we skip invisible text if later the
3953 bidi iteration lands us in the invisible region
3954 again. */
3955 if (IT_CHARPOS (*it) >= newpos)
3956 it->prev_stop = newpos;
3958 else
3960 IT_CHARPOS (*it) = newpos;
3961 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
3964 /* If there are before-strings at the start of invisible
3965 text, and the text is invisible because of a text
3966 property, arrange to show before-strings because 20.x did
3967 it that way. (If the text is invisible because of an
3968 overlay property instead of a text property, this is
3969 already handled in the overlay code.) */
3970 if (NILP (overlay)
3971 && get_overlay_strings (it, it->stop_charpos))
3973 handled = HANDLED_RECOMPUTE_PROPS;
3974 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
3976 else if (display_ellipsis_p)
3978 /* Make sure that the glyphs of the ellipsis will get
3979 correct `charpos' values. If we would not update
3980 it->position here, the glyphs would belong to the
3981 last visible character _before_ the invisible
3982 text, which confuses `set_cursor_from_row'.
3984 We use the last invisible position instead of the
3985 first because this way the cursor is always drawn on
3986 the first "." of the ellipsis, whenever PT is inside
3987 the invisible text. Otherwise the cursor would be
3988 placed _after_ the ellipsis when the point is after the
3989 first invisible character. */
3990 if (!STRINGP (it->object))
3992 it->position.charpos = newpos - 1;
3993 it->position.bytepos = CHAR_TO_BYTE (it->position.charpos);
3995 it->ellipsis_p = 1;
3996 /* Let the ellipsis display before
3997 considering any properties of the following char.
3998 Fixes jasonr@gnu.org 01 Oct 07 bug. */
3999 handled = HANDLED_RETURN;
4004 return handled;
4008 /* Make iterator IT return `...' next.
4009 Replaces LEN characters from buffer. */
4011 static void
4012 setup_for_ellipsis (struct it *it, int len)
4014 /* Use the display table definition for `...'. Invalid glyphs
4015 will be handled by the method returning elements from dpvec. */
4016 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
4018 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
4019 it->dpvec = v->contents;
4020 it->dpend = v->contents + v->header.size;
4022 else
4024 /* Default `...'. */
4025 it->dpvec = default_invis_vector;
4026 it->dpend = default_invis_vector + 3;
4029 it->dpvec_char_len = len;
4030 it->current.dpvec_index = 0;
4031 it->dpvec_face_id = -1;
4033 /* Remember the current face id in case glyphs specify faces.
4034 IT's face is restored in set_iterator_to_next.
4035 saved_face_id was set to preceding char's face in handle_stop. */
4036 if (it->saved_face_id < 0 || it->saved_face_id != it->face_id)
4037 it->saved_face_id = it->face_id = DEFAULT_FACE_ID;
4039 it->method = GET_FROM_DISPLAY_VECTOR;
4040 it->ellipsis_p = 1;
4045 /***********************************************************************
4046 'display' property
4047 ***********************************************************************/
4049 /* Set up iterator IT from `display' property at its current position.
4050 Called from handle_stop.
4051 We return HANDLED_RETURN if some part of the display property
4052 overrides the display of the buffer text itself.
4053 Otherwise we return HANDLED_NORMALLY. */
4055 static enum prop_handled
4056 handle_display_prop (struct it *it)
4058 Lisp_Object propval, object, overlay;
4059 struct text_pos *position;
4060 EMACS_INT bufpos;
4061 /* Nonzero if some property replaces the display of the text itself. */
4062 int display_replaced_p = 0;
4064 if (STRINGP (it->string))
4066 object = it->string;
4067 position = &it->current.string_pos;
4068 bufpos = CHARPOS (it->current.pos);
4070 else
4072 XSETWINDOW (object, it->w);
4073 position = &it->current.pos;
4074 bufpos = CHARPOS (*position);
4077 /* Reset those iterator values set from display property values. */
4078 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
4079 it->space_width = Qnil;
4080 it->font_height = Qnil;
4081 it->voffset = 0;
4083 /* We don't support recursive `display' properties, i.e. string
4084 values that have a string `display' property, that have a string
4085 `display' property etc. */
4086 if (!it->string_from_display_prop_p)
4087 it->area = TEXT_AREA;
4089 propval = get_char_property_and_overlay (make_number (position->charpos),
4090 Qdisplay, object, &overlay);
4091 if (NILP (propval))
4092 return HANDLED_NORMALLY;
4093 /* Now OVERLAY is the overlay that gave us this property, or nil
4094 if it was a text property. */
4096 if (!STRINGP (it->string))
4097 object = it->w->buffer;
4099 display_replaced_p = handle_display_spec (it, propval, object, overlay,
4100 position, bufpos,
4101 FRAME_WINDOW_P (it->f));
4103 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
4106 /* Subroutine of handle_display_prop. Returns non-zero if the display
4107 specification in SPEC is a replacing specification, i.e. it would
4108 replace the text covered by `display' property with something else,
4109 such as an image or a display string.
4111 See handle_single_display_spec for documentation of arguments.
4112 frame_window_p is non-zero if the window being redisplayed is on a
4113 GUI frame; this argument is used only if IT is NULL, see below.
4115 IT can be NULL, if this is called by the bidi reordering code
4116 through compute_display_string_pos, which see. In that case, this
4117 function only examines SPEC, but does not otherwise "handle" it, in
4118 the sense that it doesn't set up members of IT from the display
4119 spec. */
4120 static int
4121 handle_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4122 Lisp_Object overlay, struct text_pos *position,
4123 EMACS_INT bufpos, int frame_window_p)
4125 int replacing_p = 0;
4127 if (CONSP (spec)
4128 /* Simple specerties. */
4129 && !EQ (XCAR (spec), Qimage)
4130 && !EQ (XCAR (spec), Qspace)
4131 && !EQ (XCAR (spec), Qwhen)
4132 && !EQ (XCAR (spec), Qslice)
4133 && !EQ (XCAR (spec), Qspace_width)
4134 && !EQ (XCAR (spec), Qheight)
4135 && !EQ (XCAR (spec), Qraise)
4136 /* Marginal area specifications. */
4137 && !(CONSP (XCAR (spec)) && EQ (XCAR (XCAR (spec)), Qmargin))
4138 && !EQ (XCAR (spec), Qleft_fringe)
4139 && !EQ (XCAR (spec), Qright_fringe)
4140 && !NILP (XCAR (spec)))
4142 for (; CONSP (spec); spec = XCDR (spec))
4144 if (handle_single_display_spec (it, XCAR (spec), object, overlay,
4145 position, bufpos, replacing_p,
4146 frame_window_p))
4148 replacing_p = 1;
4149 /* If some text in a string is replaced, `position' no
4150 longer points to the position of `object'. */
4151 if (!it || STRINGP (object))
4152 break;
4156 else if (VECTORP (spec))
4158 int i;
4159 for (i = 0; i < ASIZE (spec); ++i)
4160 if (handle_single_display_spec (it, AREF (spec, i), object, overlay,
4161 position, bufpos, replacing_p,
4162 frame_window_p))
4164 replacing_p = 1;
4165 /* If some text in a string is replaced, `position' no
4166 longer points to the position of `object'. */
4167 if (!it || STRINGP (object))
4168 break;
4171 else
4173 if (handle_single_display_spec (it, spec, object, overlay,
4174 position, bufpos, 0, frame_window_p))
4175 replacing_p = 1;
4178 return replacing_p;
4181 /* Value is the position of the end of the `display' property starting
4182 at START_POS in OBJECT. */
4184 static struct text_pos
4185 display_prop_end (struct it *it, Lisp_Object object, struct text_pos start_pos)
4187 Lisp_Object end;
4188 struct text_pos end_pos;
4190 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
4191 Qdisplay, object, Qnil);
4192 CHARPOS (end_pos) = XFASTINT (end);
4193 if (STRINGP (object))
4194 compute_string_pos (&end_pos, start_pos, it->string);
4195 else
4196 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
4198 return end_pos;
4202 /* Set up IT from a single `display' property specification SPEC. OBJECT
4203 is the object in which the `display' property was found. *POSITION
4204 is the position in OBJECT at which the `display' property was found.
4205 BUFPOS is the buffer position of OBJECT (different from POSITION if
4206 OBJECT is not a buffer). DISPLAY_REPLACED_P non-zero means that we
4207 previously saw a display specification which already replaced text
4208 display with something else, for example an image; we ignore such
4209 properties after the first one has been processed.
4211 OVERLAY is the overlay this `display' property came from,
4212 or nil if it was a text property.
4214 If SPEC is a `space' or `image' specification, and in some other
4215 cases too, set *POSITION to the position where the `display'
4216 property ends.
4218 If IT is NULL, only examine the property specification in SPEC, but
4219 don't set up IT. In that case, FRAME_WINDOW_P non-zero means SPEC
4220 is intended to be displayed in a window on a GUI frame.
4222 Value is non-zero if something was found which replaces the display
4223 of buffer or string text. */
4225 static int
4226 handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4227 Lisp_Object overlay, struct text_pos *position,
4228 EMACS_INT bufpos, int display_replaced_p,
4229 int frame_window_p)
4231 Lisp_Object form;
4232 Lisp_Object location, value;
4233 struct text_pos start_pos = *position;
4234 int valid_p;
4236 /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
4237 If the result is non-nil, use VALUE instead of SPEC. */
4238 form = Qt;
4239 if (CONSP (spec) && EQ (XCAR (spec), Qwhen))
4241 spec = XCDR (spec);
4242 if (!CONSP (spec))
4243 return 0;
4244 form = XCAR (spec);
4245 spec = XCDR (spec);
4248 if (!NILP (form) && !EQ (form, Qt))
4250 int count = SPECPDL_INDEX ();
4251 struct gcpro gcpro1;
4253 /* Bind `object' to the object having the `display' property, a
4254 buffer or string. Bind `position' to the position in the
4255 object where the property was found, and `buffer-position'
4256 to the current position in the buffer. */
4258 if (NILP (object))
4259 XSETBUFFER (object, current_buffer);
4260 specbind (Qobject, object);
4261 specbind (Qposition, make_number (CHARPOS (*position)));
4262 specbind (Qbuffer_position, make_number (bufpos));
4263 GCPRO1 (form);
4264 form = safe_eval (form);
4265 UNGCPRO;
4266 unbind_to (count, Qnil);
4269 if (NILP (form))
4270 return 0;
4272 /* Handle `(height HEIGHT)' specifications. */
4273 if (CONSP (spec)
4274 && EQ (XCAR (spec), Qheight)
4275 && CONSP (XCDR (spec)))
4277 if (it)
4279 if (!FRAME_WINDOW_P (it->f))
4280 return 0;
4282 it->font_height = XCAR (XCDR (spec));
4283 if (!NILP (it->font_height))
4285 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4286 int new_height = -1;
4288 if (CONSP (it->font_height)
4289 && (EQ (XCAR (it->font_height), Qplus)
4290 || EQ (XCAR (it->font_height), Qminus))
4291 && CONSP (XCDR (it->font_height))
4292 && INTEGERP (XCAR (XCDR (it->font_height))))
4294 /* `(+ N)' or `(- N)' where N is an integer. */
4295 int steps = XINT (XCAR (XCDR (it->font_height)));
4296 if (EQ (XCAR (it->font_height), Qplus))
4297 steps = - steps;
4298 it->face_id = smaller_face (it->f, it->face_id, steps);
4300 else if (FUNCTIONP (it->font_height))
4302 /* Call function with current height as argument.
4303 Value is the new height. */
4304 Lisp_Object height;
4305 height = safe_call1 (it->font_height,
4306 face->lface[LFACE_HEIGHT_INDEX]);
4307 if (NUMBERP (height))
4308 new_height = XFLOATINT (height);
4310 else if (NUMBERP (it->font_height))
4312 /* Value is a multiple of the canonical char height. */
4313 struct face *f;
4315 f = FACE_FROM_ID (it->f,
4316 lookup_basic_face (it->f, DEFAULT_FACE_ID));
4317 new_height = (XFLOATINT (it->font_height)
4318 * XINT (f->lface[LFACE_HEIGHT_INDEX]));
4320 else
4322 /* Evaluate IT->font_height with `height' bound to the
4323 current specified height to get the new height. */
4324 int count = SPECPDL_INDEX ();
4326 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
4327 value = safe_eval (it->font_height);
4328 unbind_to (count, Qnil);
4330 if (NUMBERP (value))
4331 new_height = XFLOATINT (value);
4334 if (new_height > 0)
4335 it->face_id = face_with_height (it->f, it->face_id, new_height);
4339 return 0;
4342 /* Handle `(space-width WIDTH)'. */
4343 if (CONSP (spec)
4344 && EQ (XCAR (spec), Qspace_width)
4345 && CONSP (XCDR (spec)))
4347 if (it)
4349 if (!FRAME_WINDOW_P (it->f))
4350 return 0;
4352 value = XCAR (XCDR (spec));
4353 if (NUMBERP (value) && XFLOATINT (value) > 0)
4354 it->space_width = value;
4357 return 0;
4360 /* Handle `(slice X Y WIDTH HEIGHT)'. */
4361 if (CONSP (spec)
4362 && EQ (XCAR (spec), Qslice))
4364 Lisp_Object tem;
4366 if (it)
4368 if (!FRAME_WINDOW_P (it->f))
4369 return 0;
4371 if (tem = XCDR (spec), CONSP (tem))
4373 it->slice.x = XCAR (tem);
4374 if (tem = XCDR (tem), CONSP (tem))
4376 it->slice.y = XCAR (tem);
4377 if (tem = XCDR (tem), CONSP (tem))
4379 it->slice.width = XCAR (tem);
4380 if (tem = XCDR (tem), CONSP (tem))
4381 it->slice.height = XCAR (tem);
4387 return 0;
4390 /* Handle `(raise FACTOR)'. */
4391 if (CONSP (spec)
4392 && EQ (XCAR (spec), Qraise)
4393 && CONSP (XCDR (spec)))
4395 if (it)
4397 if (!FRAME_WINDOW_P (it->f))
4398 return 0;
4400 #ifdef HAVE_WINDOW_SYSTEM
4401 value = XCAR (XCDR (spec));
4402 if (NUMBERP (value))
4404 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4405 it->voffset = - (XFLOATINT (value)
4406 * (FONT_HEIGHT (face->font)));
4408 #endif /* HAVE_WINDOW_SYSTEM */
4411 return 0;
4414 /* Don't handle the other kinds of display specifications
4415 inside a string that we got from a `display' property. */
4416 if (it && it->string_from_display_prop_p)
4417 return 0;
4419 /* Characters having this form of property are not displayed, so
4420 we have to find the end of the property. */
4421 if (it)
4423 start_pos = *position;
4424 *position = display_prop_end (it, object, start_pos);
4426 value = Qnil;
4428 /* Stop the scan at that end position--we assume that all
4429 text properties change there. */
4430 if (it)
4431 it->stop_charpos = position->charpos;
4433 /* Handle `(left-fringe BITMAP [FACE])'
4434 and `(right-fringe BITMAP [FACE])'. */
4435 if (CONSP (spec)
4436 && (EQ (XCAR (spec), Qleft_fringe)
4437 || EQ (XCAR (spec), Qright_fringe))
4438 && CONSP (XCDR (spec)))
4440 int fringe_bitmap;
4442 if (it)
4444 if (!FRAME_WINDOW_P (it->f))
4445 /* If we return here, POSITION has been advanced
4446 across the text with this property. */
4447 return 0;
4449 else if (!frame_window_p)
4450 return 0;
4452 #ifdef HAVE_WINDOW_SYSTEM
4453 value = XCAR (XCDR (spec));
4454 if (!SYMBOLP (value)
4455 || !(fringe_bitmap = lookup_fringe_bitmap (value)))
4456 /* If we return here, POSITION has been advanced
4457 across the text with this property. */
4458 return 0;
4460 if (it)
4462 int face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);;
4464 if (CONSP (XCDR (XCDR (spec))))
4466 Lisp_Object face_name = XCAR (XCDR (XCDR (spec)));
4467 int face_id2 = lookup_derived_face (it->f, face_name,
4468 FRINGE_FACE_ID, 0);
4469 if (face_id2 >= 0)
4470 face_id = face_id2;
4473 /* Save current settings of IT so that we can restore them
4474 when we are finished with the glyph property value. */
4475 push_it (it, position);
4477 it->area = TEXT_AREA;
4478 it->what = IT_IMAGE;
4479 it->image_id = -1; /* no image */
4480 it->position = start_pos;
4481 it->object = NILP (object) ? it->w->buffer : object;
4482 it->method = GET_FROM_IMAGE;
4483 it->from_overlay = Qnil;
4484 it->face_id = face_id;
4485 it->from_disp_prop_p = 1;
4487 /* Say that we haven't consumed the characters with
4488 `display' property yet. The call to pop_it in
4489 set_iterator_to_next will clean this up. */
4490 *position = start_pos;
4492 if (EQ (XCAR (spec), Qleft_fringe))
4494 it->left_user_fringe_bitmap = fringe_bitmap;
4495 it->left_user_fringe_face_id = face_id;
4497 else
4499 it->right_user_fringe_bitmap = fringe_bitmap;
4500 it->right_user_fringe_face_id = face_id;
4503 #endif /* HAVE_WINDOW_SYSTEM */
4504 return 1;
4507 /* Prepare to handle `((margin left-margin) ...)',
4508 `((margin right-margin) ...)' and `((margin nil) ...)'
4509 prefixes for display specifications. */
4510 location = Qunbound;
4511 if (CONSP (spec) && CONSP (XCAR (spec)))
4513 Lisp_Object tem;
4515 value = XCDR (spec);
4516 if (CONSP (value))
4517 value = XCAR (value);
4519 tem = XCAR (spec);
4520 if (EQ (XCAR (tem), Qmargin)
4521 && (tem = XCDR (tem),
4522 tem = CONSP (tem) ? XCAR (tem) : Qnil,
4523 (NILP (tem)
4524 || EQ (tem, Qleft_margin)
4525 || EQ (tem, Qright_margin))))
4526 location = tem;
4529 if (EQ (location, Qunbound))
4531 location = Qnil;
4532 value = spec;
4535 /* After this point, VALUE is the property after any
4536 margin prefix has been stripped. It must be a string,
4537 an image specification, or `(space ...)'.
4539 LOCATION specifies where to display: `left-margin',
4540 `right-margin' or nil. */
4542 valid_p = (STRINGP (value)
4543 #ifdef HAVE_WINDOW_SYSTEM
4544 || ((it ? FRAME_WINDOW_P (it->f) : frame_window_p)
4545 && valid_image_p (value))
4546 #endif /* not HAVE_WINDOW_SYSTEM */
4547 || (CONSP (value) && EQ (XCAR (value), Qspace)));
4549 if (valid_p && !display_replaced_p)
4551 if (!it)
4552 return 1;
4554 /* Save current settings of IT so that we can restore them
4555 when we are finished with the glyph property value. */
4556 push_it (it, position);
4557 it->from_overlay = overlay;
4558 it->from_disp_prop_p = 1;
4560 if (NILP (location))
4561 it->area = TEXT_AREA;
4562 else if (EQ (location, Qleft_margin))
4563 it->area = LEFT_MARGIN_AREA;
4564 else
4565 it->area = RIGHT_MARGIN_AREA;
4567 if (STRINGP (value))
4569 it->string = value;
4570 it->multibyte_p = STRING_MULTIBYTE (it->string);
4571 it->current.overlay_string_index = -1;
4572 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
4573 it->end_charpos = it->string_nchars = SCHARS (it->string);
4574 it->method = GET_FROM_STRING;
4575 it->stop_charpos = 0;
4576 it->prev_stop = 0;
4577 it->base_level_stop = 0;
4578 it->string_from_display_prop_p = 1;
4579 /* Say that we haven't consumed the characters with
4580 `display' property yet. The call to pop_it in
4581 set_iterator_to_next will clean this up. */
4582 if (BUFFERP (object))
4583 *position = start_pos;
4585 /* Force paragraph direction to be that of the parent
4586 object. If the parent object's paragraph direction is
4587 not yet determined, default to L2R. */
4588 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
4589 it->paragraph_embedding = it->bidi_it.paragraph_dir;
4590 else
4591 it->paragraph_embedding = L2R;
4593 /* Set up the bidi iterator for this display string. */
4594 if (it->bidi_p)
4596 it->bidi_it.string.lstring = it->string;
4597 it->bidi_it.string.s = NULL;
4598 it->bidi_it.string.schars = it->end_charpos;
4599 it->bidi_it.string.bufpos = bufpos;
4600 it->bidi_it.string.from_disp_str = 1;
4601 it->bidi_it.string.unibyte = !it->multibyte_p;
4602 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
4605 else if (CONSP (value) && EQ (XCAR (value), Qspace))
4607 it->method = GET_FROM_STRETCH;
4608 it->object = value;
4609 *position = it->position = start_pos;
4611 #ifdef HAVE_WINDOW_SYSTEM
4612 else
4614 it->what = IT_IMAGE;
4615 it->image_id = lookup_image (it->f, value);
4616 it->position = start_pos;
4617 it->object = NILP (object) ? it->w->buffer : object;
4618 it->method = GET_FROM_IMAGE;
4620 /* Say that we haven't consumed the characters with
4621 `display' property yet. The call to pop_it in
4622 set_iterator_to_next will clean this up. */
4623 *position = start_pos;
4625 #endif /* HAVE_WINDOW_SYSTEM */
4627 return 1;
4630 /* Invalid property or property not supported. Restore
4631 POSITION to what it was before. */
4632 *position = start_pos;
4633 return 0;
4636 /* Check if PROP is a display property value whose text should be
4637 treated as intangible. OVERLAY is the overlay from which PROP
4638 came, or nil if it came from a text property. CHARPOS and BYTEPOS
4639 specify the buffer position covered by PROP. */
4642 display_prop_intangible_p (Lisp_Object prop, Lisp_Object overlay,
4643 EMACS_INT charpos, EMACS_INT bytepos)
4645 int frame_window_p = FRAME_WINDOW_P (XFRAME (selected_frame));
4646 struct text_pos position;
4648 SET_TEXT_POS (position, charpos, bytepos);
4649 return handle_display_spec (NULL, prop, Qnil, overlay,
4650 &position, charpos, frame_window_p);
4654 /* Return 1 if PROP is a display sub-property value containing STRING.
4656 Implementation note: this and the following function are really
4657 special cases of handle_display_spec and
4658 handle_single_display_spec, and should ideally use the same code.
4659 Until they do, these two pairs must be consistent and must be
4660 modified in sync. */
4662 static int
4663 single_display_spec_string_p (Lisp_Object prop, Lisp_Object string)
4665 if (EQ (string, prop))
4666 return 1;
4668 /* Skip over `when FORM'. */
4669 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
4671 prop = XCDR (prop);
4672 if (!CONSP (prop))
4673 return 0;
4674 /* Actually, the condition following `when' should be eval'ed,
4675 like handle_single_display_spec does, and we should return
4676 zero if it evaluates to nil. However, this function is
4677 called only when the buffer was already displayed and some
4678 glyph in the glyph matrix was found to come from a display
4679 string. Therefore, the condition was already evaluated, and
4680 the result was non-nil, otherwise the display string wouldn't
4681 have been displayed and we would have never been called for
4682 this property. Thus, we can skip the evaluation and assume
4683 its result is non-nil. */
4684 prop = XCDR (prop);
4687 if (CONSP (prop))
4688 /* Skip over `margin LOCATION'. */
4689 if (EQ (XCAR (prop), Qmargin))
4691 prop = XCDR (prop);
4692 if (!CONSP (prop))
4693 return 0;
4695 prop = XCDR (prop);
4696 if (!CONSP (prop))
4697 return 0;
4700 return EQ (prop, string) || (CONSP (prop) && EQ (XCAR (prop), string));
4704 /* Return 1 if STRING appears in the `display' property PROP. */
4706 static int
4707 display_prop_string_p (Lisp_Object prop, Lisp_Object string)
4709 if (CONSP (prop)
4710 && !EQ (XCAR (prop), Qwhen)
4711 && !(CONSP (XCAR (prop)) && EQ (Qmargin, XCAR (XCAR (prop)))))
4713 /* A list of sub-properties. */
4714 while (CONSP (prop))
4716 if (single_display_spec_string_p (XCAR (prop), string))
4717 return 1;
4718 prop = XCDR (prop);
4721 else if (VECTORP (prop))
4723 /* A vector of sub-properties. */
4724 int i;
4725 for (i = 0; i < ASIZE (prop); ++i)
4726 if (single_display_spec_string_p (AREF (prop, i), string))
4727 return 1;
4729 else
4730 return single_display_spec_string_p (prop, string);
4732 return 0;
4735 /* Look for STRING in overlays and text properties in the current
4736 buffer, between character positions FROM and TO (excluding TO).
4737 BACK_P non-zero means look back (in this case, TO is supposed to be
4738 less than FROM).
4739 Value is the first character position where STRING was found, or
4740 zero if it wasn't found before hitting TO.
4742 This function may only use code that doesn't eval because it is
4743 called asynchronously from note_mouse_highlight. */
4745 static EMACS_INT
4746 string_buffer_position_lim (Lisp_Object string,
4747 EMACS_INT from, EMACS_INT to, int back_p)
4749 Lisp_Object limit, prop, pos;
4750 int found = 0;
4752 pos = make_number (from);
4754 if (!back_p) /* looking forward */
4756 limit = make_number (min (to, ZV));
4757 while (!found && !EQ (pos, limit))
4759 prop = Fget_char_property (pos, Qdisplay, Qnil);
4760 if (!NILP (prop) && display_prop_string_p (prop, string))
4761 found = 1;
4762 else
4763 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil,
4764 limit);
4767 else /* looking back */
4769 limit = make_number (max (to, BEGV));
4770 while (!found && !EQ (pos, limit))
4772 prop = Fget_char_property (pos, Qdisplay, Qnil);
4773 if (!NILP (prop) && display_prop_string_p (prop, string))
4774 found = 1;
4775 else
4776 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
4777 limit);
4781 return found ? XINT (pos) : 0;
4784 /* Determine which buffer position in current buffer STRING comes from.
4785 AROUND_CHARPOS is an approximate position where it could come from.
4786 Value is the buffer position or 0 if it couldn't be determined.
4788 This function is necessary because we don't record buffer positions
4789 in glyphs generated from strings (to keep struct glyph small).
4790 This function may only use code that doesn't eval because it is
4791 called asynchronously from note_mouse_highlight. */
4793 static EMACS_INT
4794 string_buffer_position (Lisp_Object string, EMACS_INT around_charpos)
4796 const int MAX_DISTANCE = 1000;
4797 EMACS_INT found = string_buffer_position_lim (string, around_charpos,
4798 around_charpos + MAX_DISTANCE,
4801 if (!found)
4802 found = string_buffer_position_lim (string, around_charpos,
4803 around_charpos - MAX_DISTANCE, 1);
4804 return found;
4809 /***********************************************************************
4810 `composition' property
4811 ***********************************************************************/
4813 /* Set up iterator IT from `composition' property at its current
4814 position. Called from handle_stop. */
4816 static enum prop_handled
4817 handle_composition_prop (struct it *it)
4819 Lisp_Object prop, string;
4820 EMACS_INT pos, pos_byte, start, end;
4822 if (STRINGP (it->string))
4824 unsigned char *s;
4826 pos = IT_STRING_CHARPOS (*it);
4827 pos_byte = IT_STRING_BYTEPOS (*it);
4828 string = it->string;
4829 s = SDATA (string) + pos_byte;
4830 it->c = STRING_CHAR (s);
4832 else
4834 pos = IT_CHARPOS (*it);
4835 pos_byte = IT_BYTEPOS (*it);
4836 string = Qnil;
4837 it->c = FETCH_CHAR (pos_byte);
4840 /* If there's a valid composition and point is not inside of the
4841 composition (in the case that the composition is from the current
4842 buffer), draw a glyph composed from the composition components. */
4843 if (find_composition (pos, -1, &start, &end, &prop, string)
4844 && COMPOSITION_VALID_P (start, end, prop)
4845 && (STRINGP (it->string) || (PT <= start || PT >= end)))
4847 if (start < pos)
4848 /* As we can't handle this situation (perhaps font-lock added
4849 a new composition), we just return here hoping that next
4850 redisplay will detect this composition much earlier. */
4851 return HANDLED_NORMALLY;
4852 if (start != pos)
4854 if (STRINGP (it->string))
4855 pos_byte = string_char_to_byte (it->string, start);
4856 else
4857 pos_byte = CHAR_TO_BYTE (start);
4859 it->cmp_it.id = get_composition_id (start, pos_byte, end - start,
4860 prop, string);
4862 if (it->cmp_it.id >= 0)
4864 it->cmp_it.ch = -1;
4865 it->cmp_it.nchars = COMPOSITION_LENGTH (prop);
4866 it->cmp_it.nglyphs = -1;
4870 return HANDLED_NORMALLY;
4875 /***********************************************************************
4876 Overlay strings
4877 ***********************************************************************/
4879 /* The following structure is used to record overlay strings for
4880 later sorting in load_overlay_strings. */
4882 struct overlay_entry
4884 Lisp_Object overlay;
4885 Lisp_Object string;
4886 int priority;
4887 int after_string_p;
4891 /* Set up iterator IT from overlay strings at its current position.
4892 Called from handle_stop. */
4894 static enum prop_handled
4895 handle_overlay_change (struct it *it)
4897 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
4898 return HANDLED_RECOMPUTE_PROPS;
4899 else
4900 return HANDLED_NORMALLY;
4904 /* Set up the next overlay string for delivery by IT, if there is an
4905 overlay string to deliver. Called by set_iterator_to_next when the
4906 end of the current overlay string is reached. If there are more
4907 overlay strings to display, IT->string and
4908 IT->current.overlay_string_index are set appropriately here.
4909 Otherwise IT->string is set to nil. */
4911 static void
4912 next_overlay_string (struct it *it)
4914 ++it->current.overlay_string_index;
4915 if (it->current.overlay_string_index == it->n_overlay_strings)
4917 /* No more overlay strings. Restore IT's settings to what
4918 they were before overlay strings were processed, and
4919 continue to deliver from current_buffer. */
4921 it->ellipsis_p = (it->stack[it->sp - 1].display_ellipsis_p != 0);
4922 pop_it (it);
4923 xassert (it->sp > 0
4924 || (NILP (it->string)
4925 && it->method == GET_FROM_BUFFER
4926 && it->stop_charpos >= BEGV
4927 && it->stop_charpos <= it->end_charpos));
4928 it->current.overlay_string_index = -1;
4929 it->n_overlay_strings = 0;
4930 it->overlay_strings_charpos = -1;
4932 /* If we're at the end of the buffer, record that we have
4933 processed the overlay strings there already, so that
4934 next_element_from_buffer doesn't try it again. */
4935 if (NILP (it->string) && IT_CHARPOS (*it) >= it->end_charpos)
4936 it->overlay_strings_at_end_processed_p = 1;
4938 else
4940 /* There are more overlay strings to process. If
4941 IT->current.overlay_string_index has advanced to a position
4942 where we must load IT->overlay_strings with more strings, do
4943 it. We must load at the IT->overlay_strings_charpos where
4944 IT->n_overlay_strings was originally computed; when invisible
4945 text is present, this might not be IT_CHARPOS (Bug#7016). */
4946 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
4948 if (it->current.overlay_string_index && i == 0)
4949 load_overlay_strings (it, it->overlay_strings_charpos);
4951 /* Initialize IT to deliver display elements from the overlay
4952 string. */
4953 it->string = it->overlay_strings[i];
4954 it->multibyte_p = STRING_MULTIBYTE (it->string);
4955 SET_TEXT_POS (it->current.string_pos, 0, 0);
4956 it->method = GET_FROM_STRING;
4957 it->stop_charpos = 0;
4958 if (it->cmp_it.stop_pos >= 0)
4959 it->cmp_it.stop_pos = 0;
4960 it->prev_stop = 0;
4961 it->base_level_stop = 0;
4963 /* Set up the bidi iterator for this overlay string. */
4964 if (it->bidi_p)
4966 it->bidi_it.string.lstring = it->string;
4967 it->bidi_it.string.s = NULL;
4968 it->bidi_it.string.schars = SCHARS (it->string);
4969 it->bidi_it.string.bufpos = it->overlay_strings_charpos;
4970 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
4971 it->bidi_it.string.unibyte = !it->multibyte_p;
4972 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
4976 CHECK_IT (it);
4980 /* Compare two overlay_entry structures E1 and E2. Used as a
4981 comparison function for qsort in load_overlay_strings. Overlay
4982 strings for the same position are sorted so that
4984 1. All after-strings come in front of before-strings, except
4985 when they come from the same overlay.
4987 2. Within after-strings, strings are sorted so that overlay strings
4988 from overlays with higher priorities come first.
4990 2. Within before-strings, strings are sorted so that overlay
4991 strings from overlays with higher priorities come last.
4993 Value is analogous to strcmp. */
4996 static int
4997 compare_overlay_entries (const void *e1, const void *e2)
4999 struct overlay_entry *entry1 = (struct overlay_entry *) e1;
5000 struct overlay_entry *entry2 = (struct overlay_entry *) e2;
5001 int result;
5003 if (entry1->after_string_p != entry2->after_string_p)
5005 /* Let after-strings appear in front of before-strings if
5006 they come from different overlays. */
5007 if (EQ (entry1->overlay, entry2->overlay))
5008 result = entry1->after_string_p ? 1 : -1;
5009 else
5010 result = entry1->after_string_p ? -1 : 1;
5012 else if (entry1->after_string_p)
5013 /* After-strings sorted in order of decreasing priority. */
5014 result = entry2->priority - entry1->priority;
5015 else
5016 /* Before-strings sorted in order of increasing priority. */
5017 result = entry1->priority - entry2->priority;
5019 return result;
5023 /* Load the vector IT->overlay_strings with overlay strings from IT's
5024 current buffer position, or from CHARPOS if that is > 0. Set
5025 IT->n_overlays to the total number of overlay strings found.
5027 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
5028 a time. On entry into load_overlay_strings,
5029 IT->current.overlay_string_index gives the number of overlay
5030 strings that have already been loaded by previous calls to this
5031 function.
5033 IT->add_overlay_start contains an additional overlay start
5034 position to consider for taking overlay strings from, if non-zero.
5035 This position comes into play when the overlay has an `invisible'
5036 property, and both before and after-strings. When we've skipped to
5037 the end of the overlay, because of its `invisible' property, we
5038 nevertheless want its before-string to appear.
5039 IT->add_overlay_start will contain the overlay start position
5040 in this case.
5042 Overlay strings are sorted so that after-string strings come in
5043 front of before-string strings. Within before and after-strings,
5044 strings are sorted by overlay priority. See also function
5045 compare_overlay_entries. */
5047 static void
5048 load_overlay_strings (struct it *it, EMACS_INT charpos)
5050 Lisp_Object overlay, window, str, invisible;
5051 struct Lisp_Overlay *ov;
5052 EMACS_INT start, end;
5053 int size = 20;
5054 int n = 0, i, j, invis_p;
5055 struct overlay_entry *entries
5056 = (struct overlay_entry *) alloca (size * sizeof *entries);
5058 if (charpos <= 0)
5059 charpos = IT_CHARPOS (*it);
5061 /* Append the overlay string STRING of overlay OVERLAY to vector
5062 `entries' which has size `size' and currently contains `n'
5063 elements. AFTER_P non-zero means STRING is an after-string of
5064 OVERLAY. */
5065 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
5066 do \
5068 Lisp_Object priority; \
5070 if (n == size) \
5072 int new_size = 2 * size; \
5073 struct overlay_entry *old = entries; \
5074 entries = \
5075 (struct overlay_entry *) alloca (new_size \
5076 * sizeof *entries); \
5077 memcpy (entries, old, size * sizeof *entries); \
5078 size = new_size; \
5081 entries[n].string = (STRING); \
5082 entries[n].overlay = (OVERLAY); \
5083 priority = Foverlay_get ((OVERLAY), Qpriority); \
5084 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
5085 entries[n].after_string_p = (AFTER_P); \
5086 ++n; \
5088 while (0)
5090 /* Process overlay before the overlay center. */
5091 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
5093 XSETMISC (overlay, ov);
5094 xassert (OVERLAYP (overlay));
5095 start = OVERLAY_POSITION (OVERLAY_START (overlay));
5096 end = OVERLAY_POSITION (OVERLAY_END (overlay));
5098 if (end < charpos)
5099 break;
5101 /* Skip this overlay if it doesn't start or end at IT's current
5102 position. */
5103 if (end != charpos && start != charpos)
5104 continue;
5106 /* Skip this overlay if it doesn't apply to IT->w. */
5107 window = Foverlay_get (overlay, Qwindow);
5108 if (WINDOWP (window) && XWINDOW (window) != it->w)
5109 continue;
5111 /* If the text ``under'' the overlay is invisible, both before-
5112 and after-strings from this overlay are visible; start and
5113 end position are indistinguishable. */
5114 invisible = Foverlay_get (overlay, Qinvisible);
5115 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
5117 /* If overlay has a non-empty before-string, record it. */
5118 if ((start == charpos || (end == charpos && invis_p))
5119 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
5120 && SCHARS (str))
5121 RECORD_OVERLAY_STRING (overlay, str, 0);
5123 /* If overlay has a non-empty after-string, record it. */
5124 if ((end == charpos || (start == charpos && invis_p))
5125 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
5126 && SCHARS (str))
5127 RECORD_OVERLAY_STRING (overlay, str, 1);
5130 /* Process overlays after the overlay center. */
5131 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
5133 XSETMISC (overlay, ov);
5134 xassert (OVERLAYP (overlay));
5135 start = OVERLAY_POSITION (OVERLAY_START (overlay));
5136 end = OVERLAY_POSITION (OVERLAY_END (overlay));
5138 if (start > charpos)
5139 break;
5141 /* Skip this overlay if it doesn't start or end at IT's current
5142 position. */
5143 if (end != charpos && start != charpos)
5144 continue;
5146 /* Skip this overlay if it doesn't apply to IT->w. */
5147 window = Foverlay_get (overlay, Qwindow);
5148 if (WINDOWP (window) && XWINDOW (window) != it->w)
5149 continue;
5151 /* If the text ``under'' the overlay is invisible, it has a zero
5152 dimension, and both before- and after-strings apply. */
5153 invisible = Foverlay_get (overlay, Qinvisible);
5154 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
5156 /* If overlay has a non-empty before-string, record it. */
5157 if ((start == charpos || (end == charpos && invis_p))
5158 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
5159 && SCHARS (str))
5160 RECORD_OVERLAY_STRING (overlay, str, 0);
5162 /* If overlay has a non-empty after-string, record it. */
5163 if ((end == charpos || (start == charpos && invis_p))
5164 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
5165 && SCHARS (str))
5166 RECORD_OVERLAY_STRING (overlay, str, 1);
5169 #undef RECORD_OVERLAY_STRING
5171 /* Sort entries. */
5172 if (n > 1)
5173 qsort (entries, n, sizeof *entries, compare_overlay_entries);
5175 /* Record number of overlay strings, and where we computed it. */
5176 it->n_overlay_strings = n;
5177 it->overlay_strings_charpos = charpos;
5179 /* IT->current.overlay_string_index is the number of overlay strings
5180 that have already been consumed by IT. Copy some of the
5181 remaining overlay strings to IT->overlay_strings. */
5182 i = 0;
5183 j = it->current.overlay_string_index;
5184 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
5186 it->overlay_strings[i] = entries[j].string;
5187 it->string_overlays[i++] = entries[j++].overlay;
5190 CHECK_IT (it);
5194 /* Get the first chunk of overlay strings at IT's current buffer
5195 position, or at CHARPOS if that is > 0. Value is non-zero if at
5196 least one overlay string was found. */
5198 static int
5199 get_overlay_strings_1 (struct it *it, EMACS_INT charpos, int compute_stop_p)
5201 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
5202 process. This fills IT->overlay_strings with strings, and sets
5203 IT->n_overlay_strings to the total number of strings to process.
5204 IT->pos.overlay_string_index has to be set temporarily to zero
5205 because load_overlay_strings needs this; it must be set to -1
5206 when no overlay strings are found because a zero value would
5207 indicate a position in the first overlay string. */
5208 it->current.overlay_string_index = 0;
5209 load_overlay_strings (it, charpos);
5211 /* If we found overlay strings, set up IT to deliver display
5212 elements from the first one. Otherwise set up IT to deliver
5213 from current_buffer. */
5214 if (it->n_overlay_strings)
5216 /* Make sure we know settings in current_buffer, so that we can
5217 restore meaningful values when we're done with the overlay
5218 strings. */
5219 if (compute_stop_p)
5220 compute_stop_pos (it);
5221 xassert (it->face_id >= 0);
5223 /* Save IT's settings. They are restored after all overlay
5224 strings have been processed. */
5225 xassert (!compute_stop_p || it->sp == 0);
5227 /* When called from handle_stop, there might be an empty display
5228 string loaded. In that case, don't bother saving it. */
5229 if (!STRINGP (it->string) || SCHARS (it->string))
5230 push_it (it, NULL);
5232 /* Set up IT to deliver display elements from the first overlay
5233 string. */
5234 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
5235 it->string = it->overlay_strings[0];
5236 it->from_overlay = Qnil;
5237 it->stop_charpos = 0;
5238 xassert (STRINGP (it->string));
5239 it->end_charpos = SCHARS (it->string);
5240 it->prev_stop = 0;
5241 it->base_level_stop = 0;
5242 it->multibyte_p = STRING_MULTIBYTE (it->string);
5243 it->method = GET_FROM_STRING;
5244 it->from_disp_prop_p = 0;
5246 /* Force paragraph direction to be that of the parent
5247 buffer. */
5248 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
5249 it->paragraph_embedding = it->bidi_it.paragraph_dir;
5250 else
5251 it->paragraph_embedding = L2R;
5253 /* Set up the bidi iterator for this overlay string. */
5254 if (it->bidi_p)
5256 EMACS_INT pos = (charpos > 0 ? charpos : IT_CHARPOS (*it));
5258 it->bidi_it.string.lstring = it->string;
5259 it->bidi_it.string.s = NULL;
5260 it->bidi_it.string.schars = SCHARS (it->string);
5261 it->bidi_it.string.bufpos = pos;
5262 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
5263 it->bidi_it.string.unibyte = !it->multibyte_p;
5264 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
5266 return 1;
5269 it->current.overlay_string_index = -1;
5270 return 0;
5273 static int
5274 get_overlay_strings (struct it *it, EMACS_INT charpos)
5276 it->string = Qnil;
5277 it->method = GET_FROM_BUFFER;
5279 (void) get_overlay_strings_1 (it, charpos, 1);
5281 CHECK_IT (it);
5283 /* Value is non-zero if we found at least one overlay string. */
5284 return STRINGP (it->string);
5289 /***********************************************************************
5290 Saving and restoring state
5291 ***********************************************************************/
5293 /* Save current settings of IT on IT->stack. Called, for example,
5294 before setting up IT for an overlay string, to be able to restore
5295 IT's settings to what they were after the overlay string has been
5296 processed. If POSITION is non-NULL, it is the position to save on
5297 the stack instead of IT->position. */
5299 static void
5300 push_it (struct it *it, struct text_pos *position)
5302 struct iterator_stack_entry *p;
5304 xassert (it->sp < IT_STACK_SIZE);
5305 p = it->stack + it->sp;
5307 p->stop_charpos = it->stop_charpos;
5308 p->prev_stop = it->prev_stop;
5309 p->base_level_stop = it->base_level_stop;
5310 p->cmp_it = it->cmp_it;
5311 xassert (it->face_id >= 0);
5312 p->face_id = it->face_id;
5313 p->string = it->string;
5314 p->method = it->method;
5315 p->from_overlay = it->from_overlay;
5316 switch (p->method)
5318 case GET_FROM_IMAGE:
5319 p->u.image.object = it->object;
5320 p->u.image.image_id = it->image_id;
5321 p->u.image.slice = it->slice;
5322 break;
5323 case GET_FROM_STRETCH:
5324 p->u.stretch.object = it->object;
5325 break;
5327 p->position = position ? *position : it->position;
5328 p->current = it->current;
5329 p->end_charpos = it->end_charpos;
5330 p->string_nchars = it->string_nchars;
5331 p->area = it->area;
5332 p->multibyte_p = it->multibyte_p;
5333 p->avoid_cursor_p = it->avoid_cursor_p;
5334 p->space_width = it->space_width;
5335 p->font_height = it->font_height;
5336 p->voffset = it->voffset;
5337 p->string_from_display_prop_p = it->string_from_display_prop_p;
5338 p->display_ellipsis_p = 0;
5339 p->line_wrap = it->line_wrap;
5340 p->bidi_p = it->bidi_p;
5341 p->paragraph_embedding = it->paragraph_embedding;
5342 p->from_disp_prop_p = it->from_disp_prop_p;
5343 ++it->sp;
5345 /* Save the state of the bidi iterator as well. */
5346 if (it->bidi_p)
5347 bidi_push_it (&it->bidi_it);
5350 static void
5351 iterate_out_of_display_property (struct it *it)
5353 int buffer_p = BUFFERP (it->object);
5354 EMACS_INT eob = (buffer_p ? ZV : it->end_charpos);
5355 EMACS_INT bob = (buffer_p ? BEGV : 0);
5357 /* Maybe initialize paragraph direction. If we are at the beginning
5358 of a new paragraph, next_element_from_buffer may not have a
5359 chance to do that. */
5360 if (it->bidi_it.first_elt && it->bidi_it.charpos < eob)
5361 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
5362 /* prev_stop can be zero, so check against BEGV as well. */
5363 while (it->bidi_it.charpos >= bob
5364 && it->prev_stop <= it->bidi_it.charpos
5365 && it->bidi_it.charpos < CHARPOS (it->position))
5366 bidi_move_to_visually_next (&it->bidi_it);
5367 /* Record the stop_pos we just crossed, for when we cross it
5368 back, maybe. */
5369 if (it->bidi_it.charpos > CHARPOS (it->position))
5370 it->prev_stop = CHARPOS (it->position);
5371 /* If we ended up not where pop_it put us, resync IT's
5372 positional members with the bidi iterator. */
5373 if (it->bidi_it.charpos != CHARPOS (it->position))
5375 SET_TEXT_POS (it->position,
5376 it->bidi_it.charpos, it->bidi_it.bytepos);
5377 if (buffer_p)
5378 it->current.pos = it->position;
5379 else
5380 it->current.string_pos = it->position;
5384 /* Restore IT's settings from IT->stack. Called, for example, when no
5385 more overlay strings must be processed, and we return to delivering
5386 display elements from a buffer, or when the end of a string from a
5387 `display' property is reached and we return to delivering display
5388 elements from an overlay string, or from a buffer. */
5390 static void
5391 pop_it (struct it *it)
5393 struct iterator_stack_entry *p;
5394 int from_display_prop = it->from_disp_prop_p;
5396 xassert (it->sp > 0);
5397 --it->sp;
5398 p = it->stack + it->sp;
5399 it->stop_charpos = p->stop_charpos;
5400 it->prev_stop = p->prev_stop;
5401 it->base_level_stop = p->base_level_stop;
5402 it->cmp_it = p->cmp_it;
5403 it->face_id = p->face_id;
5404 it->current = p->current;
5405 it->position = p->position;
5406 it->string = p->string;
5407 it->from_overlay = p->from_overlay;
5408 if (NILP (it->string))
5409 SET_TEXT_POS (it->current.string_pos, -1, -1);
5410 it->method = p->method;
5411 switch (it->method)
5413 case GET_FROM_IMAGE:
5414 it->image_id = p->u.image.image_id;
5415 it->object = p->u.image.object;
5416 it->slice = p->u.image.slice;
5417 break;
5418 case GET_FROM_STRETCH:
5419 it->object = p->u.stretch.object;
5420 break;
5421 case GET_FROM_BUFFER:
5422 it->object = it->w->buffer;
5423 break;
5424 case GET_FROM_STRING:
5425 it->object = it->string;
5426 break;
5427 case GET_FROM_DISPLAY_VECTOR:
5428 if (it->s)
5429 it->method = GET_FROM_C_STRING;
5430 else if (STRINGP (it->string))
5431 it->method = GET_FROM_STRING;
5432 else
5434 it->method = GET_FROM_BUFFER;
5435 it->object = it->w->buffer;
5438 it->end_charpos = p->end_charpos;
5439 it->string_nchars = p->string_nchars;
5440 it->area = p->area;
5441 it->multibyte_p = p->multibyte_p;
5442 it->avoid_cursor_p = p->avoid_cursor_p;
5443 it->space_width = p->space_width;
5444 it->font_height = p->font_height;
5445 it->voffset = p->voffset;
5446 it->string_from_display_prop_p = p->string_from_display_prop_p;
5447 it->line_wrap = p->line_wrap;
5448 it->bidi_p = p->bidi_p;
5449 it->paragraph_embedding = p->paragraph_embedding;
5450 it->from_disp_prop_p = p->from_disp_prop_p;
5451 if (it->bidi_p)
5453 bidi_pop_it (&it->bidi_it);
5454 /* Bidi-iterate until we get out of the portion of text, if any,
5455 covered by a `display' text property or by an overlay with
5456 `display' property. (We cannot just jump there, because the
5457 internal coherency of the bidi iterator state can not be
5458 preserved across such jumps.) We also must determine the
5459 paragraph base direction if the overlay we just processed is
5460 at the beginning of a new paragraph. */
5461 if (from_display_prop
5462 && (it->method == GET_FROM_BUFFER || it->method == GET_FROM_STRING))
5463 iterate_out_of_display_property (it);
5465 xassert ((BUFFERP (it->object)
5466 && IT_CHARPOS (*it) == it->bidi_it.charpos
5467 && IT_BYTEPOS (*it) == it->bidi_it.bytepos)
5468 || (STRINGP (it->object)
5469 && IT_STRING_CHARPOS (*it) == it->bidi_it.charpos
5470 && IT_STRING_BYTEPOS (*it) == it->bidi_it.bytepos));
5476 /***********************************************************************
5477 Moving over lines
5478 ***********************************************************************/
5480 /* Set IT's current position to the previous line start. */
5482 static void
5483 back_to_previous_line_start (struct it *it)
5485 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
5486 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
5490 /* Move IT to the next line start.
5492 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
5493 we skipped over part of the text (as opposed to moving the iterator
5494 continuously over the text). Otherwise, don't change the value
5495 of *SKIPPED_P.
5497 If BIDI_IT_PREV is non-NULL, store into it the state of the bidi
5498 iterator on the newline, if it was found.
5500 Newlines may come from buffer text, overlay strings, or strings
5501 displayed via the `display' property. That's the reason we can't
5502 simply use find_next_newline_no_quit.
5504 Note that this function may not skip over invisible text that is so
5505 because of text properties and immediately follows a newline. If
5506 it would, function reseat_at_next_visible_line_start, when called
5507 from set_iterator_to_next, would effectively make invisible
5508 characters following a newline part of the wrong glyph row, which
5509 leads to wrong cursor motion. */
5511 static int
5512 forward_to_next_line_start (struct it *it, int *skipped_p,
5513 struct bidi_it *bidi_it_prev)
5515 EMACS_INT old_selective;
5516 int newline_found_p, n;
5517 const int MAX_NEWLINE_DISTANCE = 500;
5519 /* If already on a newline, just consume it to avoid unintended
5520 skipping over invisible text below. */
5521 if (it->what == IT_CHARACTER
5522 && it->c == '\n'
5523 && CHARPOS (it->position) == IT_CHARPOS (*it))
5525 if (it->bidi_p && bidi_it_prev)
5526 *bidi_it_prev = it->bidi_it;
5527 set_iterator_to_next (it, 0);
5528 it->c = 0;
5529 return 1;
5532 /* Don't handle selective display in the following. It's (a)
5533 unnecessary because it's done by the caller, and (b) leads to an
5534 infinite recursion because next_element_from_ellipsis indirectly
5535 calls this function. */
5536 old_selective = it->selective;
5537 it->selective = 0;
5539 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
5540 from buffer text. */
5541 for (n = newline_found_p = 0;
5542 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
5543 n += STRINGP (it->string) ? 0 : 1)
5545 if (!get_next_display_element (it))
5546 return 0;
5547 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
5548 if (newline_found_p && it->bidi_p && bidi_it_prev)
5549 *bidi_it_prev = it->bidi_it;
5550 set_iterator_to_next (it, 0);
5553 /* If we didn't find a newline near enough, see if we can use a
5554 short-cut. */
5555 if (!newline_found_p)
5557 EMACS_INT start = IT_CHARPOS (*it);
5558 EMACS_INT limit = find_next_newline_no_quit (start, 1);
5559 Lisp_Object pos;
5561 xassert (!STRINGP (it->string));
5563 /* If we are not bidi-reordering, and there isn't any `display'
5564 property in sight, and no overlays, we can just use the
5565 position of the newline in buffer text. */
5566 if (!it->bidi_p
5567 && (it->stop_charpos >= limit
5568 || ((pos = Fnext_single_property_change (make_number (start),
5569 Qdisplay, Qnil,
5570 make_number (limit)),
5571 NILP (pos))
5572 && next_overlay_change (start) == ZV)))
5574 IT_CHARPOS (*it) = limit;
5575 IT_BYTEPOS (*it) = CHAR_TO_BYTE (limit);
5576 *skipped_p = newline_found_p = 1;
5578 else
5580 while (get_next_display_element (it)
5581 && !newline_found_p)
5583 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
5584 if (newline_found_p && it->bidi_p && bidi_it_prev)
5585 *bidi_it_prev = it->bidi_it;
5586 set_iterator_to_next (it, 0);
5591 it->selective = old_selective;
5592 return newline_found_p;
5596 /* Set IT's current position to the previous visible line start. Skip
5597 invisible text that is so either due to text properties or due to
5598 selective display. Caution: this does not change IT->current_x and
5599 IT->hpos. */
5601 static void
5602 back_to_previous_visible_line_start (struct it *it)
5604 while (IT_CHARPOS (*it) > BEGV)
5606 back_to_previous_line_start (it);
5608 if (IT_CHARPOS (*it) <= BEGV)
5609 break;
5611 /* If selective > 0, then lines indented more than its value are
5612 invisible. */
5613 if (it->selective > 0
5614 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
5615 it->selective))
5616 continue;
5618 /* Check the newline before point for invisibility. */
5620 Lisp_Object prop;
5621 prop = Fget_char_property (make_number (IT_CHARPOS (*it) - 1),
5622 Qinvisible, it->window);
5623 if (TEXT_PROP_MEANS_INVISIBLE (prop))
5624 continue;
5627 if (IT_CHARPOS (*it) <= BEGV)
5628 break;
5631 struct it it2;
5632 void *it2data = NULL;
5633 EMACS_INT pos;
5634 EMACS_INT beg, end;
5635 Lisp_Object val, overlay;
5637 SAVE_IT (it2, *it, it2data);
5639 /* If newline is part of a composition, continue from start of composition */
5640 if (find_composition (IT_CHARPOS (*it), -1, &beg, &end, &val, Qnil)
5641 && beg < IT_CHARPOS (*it))
5642 goto replaced;
5644 /* If newline is replaced by a display property, find start of overlay
5645 or interval and continue search from that point. */
5646 pos = --IT_CHARPOS (it2);
5647 --IT_BYTEPOS (it2);
5648 it2.sp = 0;
5649 bidi_unshelve_cache (NULL);
5650 it2.string_from_display_prop_p = 0;
5651 it2.from_disp_prop_p = 0;
5652 if (handle_display_prop (&it2) == HANDLED_RETURN
5653 && !NILP (val = get_char_property_and_overlay
5654 (make_number (pos), Qdisplay, Qnil, &overlay))
5655 && (OVERLAYP (overlay)
5656 ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
5657 : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
5659 RESTORE_IT (it, it, it2data);
5660 goto replaced;
5663 /* Newline is not replaced by anything -- so we are done. */
5664 RESTORE_IT (it, it, it2data);
5665 break;
5667 replaced:
5668 if (beg < BEGV)
5669 beg = BEGV;
5670 IT_CHARPOS (*it) = beg;
5671 IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg);
5675 it->continuation_lines_width = 0;
5677 xassert (IT_CHARPOS (*it) >= BEGV);
5678 xassert (IT_CHARPOS (*it) == BEGV
5679 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
5680 CHECK_IT (it);
5684 /* Reseat iterator IT at the previous visible line start. Skip
5685 invisible text that is so either due to text properties or due to
5686 selective display. At the end, update IT's overlay information,
5687 face information etc. */
5689 void
5690 reseat_at_previous_visible_line_start (struct it *it)
5692 back_to_previous_visible_line_start (it);
5693 reseat (it, it->current.pos, 1);
5694 CHECK_IT (it);
5698 /* Reseat iterator IT on the next visible line start in the current
5699 buffer. ON_NEWLINE_P non-zero means position IT on the newline
5700 preceding the line start. Skip over invisible text that is so
5701 because of selective display. Compute faces, overlays etc at the
5702 new position. Note that this function does not skip over text that
5703 is invisible because of text properties. */
5705 static void
5706 reseat_at_next_visible_line_start (struct it *it, int on_newline_p)
5708 int newline_found_p, skipped_p = 0;
5709 struct bidi_it bidi_it_prev;
5711 newline_found_p = forward_to_next_line_start (it, &skipped_p, &bidi_it_prev);
5713 /* Skip over lines that are invisible because they are indented
5714 more than the value of IT->selective. */
5715 if (it->selective > 0)
5716 while (IT_CHARPOS (*it) < ZV
5717 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
5718 it->selective))
5720 xassert (IT_BYTEPOS (*it) == BEGV
5721 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
5722 newline_found_p =
5723 forward_to_next_line_start (it, &skipped_p, &bidi_it_prev);
5726 /* Position on the newline if that's what's requested. */
5727 if (on_newline_p && newline_found_p)
5729 if (STRINGP (it->string))
5731 if (IT_STRING_CHARPOS (*it) > 0)
5733 if (!it->bidi_p)
5735 --IT_STRING_CHARPOS (*it);
5736 --IT_STRING_BYTEPOS (*it);
5738 else
5740 /* We need to restore the bidi iterator to the state
5741 it had on the newline, and resync the IT's
5742 position with that. */
5743 it->bidi_it = bidi_it_prev;
5744 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
5745 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
5749 else if (IT_CHARPOS (*it) > BEGV)
5751 if (!it->bidi_p)
5753 --IT_CHARPOS (*it);
5754 --IT_BYTEPOS (*it);
5756 else
5758 /* We need to restore the bidi iterator to the state it
5759 had on the newline and resync IT with that. */
5760 it->bidi_it = bidi_it_prev;
5761 IT_CHARPOS (*it) = it->bidi_it.charpos;
5762 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
5764 reseat (it, it->current.pos, 0);
5767 else if (skipped_p)
5768 reseat (it, it->current.pos, 0);
5770 CHECK_IT (it);
5775 /***********************************************************************
5776 Changing an iterator's position
5777 ***********************************************************************/
5779 /* Change IT's current position to POS in current_buffer. If FORCE_P
5780 is non-zero, always check for text properties at the new position.
5781 Otherwise, text properties are only looked up if POS >=
5782 IT->check_charpos of a property. */
5784 static void
5785 reseat (struct it *it, struct text_pos pos, int force_p)
5787 EMACS_INT original_pos = IT_CHARPOS (*it);
5789 reseat_1 (it, pos, 0);
5791 /* Determine where to check text properties. Avoid doing it
5792 where possible because text property lookup is very expensive. */
5793 if (force_p
5794 || CHARPOS (pos) > it->stop_charpos
5795 || CHARPOS (pos) < original_pos)
5797 if (it->bidi_p)
5799 /* For bidi iteration, we need to prime prev_stop and
5800 base_level_stop with our best estimations. */
5801 /* Implementation note: Of course, POS is not necessarily a
5802 stop position, so assigning prev_pos to it is a lie; we
5803 should have called compute_stop_backwards. However, if
5804 the current buffer does not include any R2L characters,
5805 that call would be a waste of cycles, because the
5806 iterator will never move back, and thus never cross this
5807 "fake" stop position. So we delay that backward search
5808 until the time we really need it, in next_element_from_buffer. */
5809 if (CHARPOS (pos) != it->prev_stop)
5810 it->prev_stop = CHARPOS (pos);
5811 if (CHARPOS (pos) < it->base_level_stop)
5812 it->base_level_stop = 0; /* meaning it's unknown */
5813 handle_stop (it);
5815 else
5817 handle_stop (it);
5818 it->prev_stop = it->base_level_stop = 0;
5823 CHECK_IT (it);
5827 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
5828 IT->stop_pos to POS, also. */
5830 static void
5831 reseat_1 (struct it *it, struct text_pos pos, int set_stop_p)
5833 /* Don't call this function when scanning a C string. */
5834 xassert (it->s == NULL);
5836 /* POS must be a reasonable value. */
5837 xassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
5839 it->current.pos = it->position = pos;
5840 it->end_charpos = ZV;
5841 it->dpvec = NULL;
5842 it->current.dpvec_index = -1;
5843 it->current.overlay_string_index = -1;
5844 IT_STRING_CHARPOS (*it) = -1;
5845 IT_STRING_BYTEPOS (*it) = -1;
5846 it->string = Qnil;
5847 it->method = GET_FROM_BUFFER;
5848 it->object = it->w->buffer;
5849 it->area = TEXT_AREA;
5850 it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
5851 it->sp = 0;
5852 it->string_from_display_prop_p = 0;
5853 it->from_disp_prop_p = 0;
5854 it->face_before_selective_p = 0;
5855 if (it->bidi_p)
5857 bidi_init_it (IT_CHARPOS (*it), IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
5858 &it->bidi_it);
5859 bidi_unshelve_cache (NULL);
5860 it->bidi_it.paragraph_dir = NEUTRAL_DIR;
5861 it->bidi_it.string.s = NULL;
5862 it->bidi_it.string.lstring = Qnil;
5863 it->bidi_it.string.bufpos = 0;
5864 it->bidi_it.string.unibyte = 0;
5867 if (set_stop_p)
5869 it->stop_charpos = CHARPOS (pos);
5870 it->base_level_stop = CHARPOS (pos);
5875 /* Set up IT for displaying a string, starting at CHARPOS in window W.
5876 If S is non-null, it is a C string to iterate over. Otherwise,
5877 STRING gives a Lisp string to iterate over.
5879 If PRECISION > 0, don't return more then PRECISION number of
5880 characters from the string.
5882 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
5883 characters have been returned. FIELD_WIDTH < 0 means an infinite
5884 field width.
5886 MULTIBYTE = 0 means disable processing of multibyte characters,
5887 MULTIBYTE > 0 means enable it,
5888 MULTIBYTE < 0 means use IT->multibyte_p.
5890 IT must be initialized via a prior call to init_iterator before
5891 calling this function. */
5893 static void
5894 reseat_to_string (struct it *it, const char *s, Lisp_Object string,
5895 EMACS_INT charpos, EMACS_INT precision, int field_width,
5896 int multibyte)
5898 /* No region in strings. */
5899 it->region_beg_charpos = it->region_end_charpos = -1;
5901 /* No text property checks performed by default, but see below. */
5902 it->stop_charpos = -1;
5904 /* Set iterator position and end position. */
5905 memset (&it->current, 0, sizeof it->current);
5906 it->current.overlay_string_index = -1;
5907 it->current.dpvec_index = -1;
5908 xassert (charpos >= 0);
5910 /* If STRING is specified, use its multibyteness, otherwise use the
5911 setting of MULTIBYTE, if specified. */
5912 if (multibyte >= 0)
5913 it->multibyte_p = multibyte > 0;
5915 /* Bidirectional reordering of strings is controlled by the default
5916 value of bidi-display-reordering. */
5917 it->bidi_p = !NILP (BVAR (&buffer_defaults, bidi_display_reordering));
5919 if (s == NULL)
5921 xassert (STRINGP (string));
5922 it->string = string;
5923 it->s = NULL;
5924 it->end_charpos = it->string_nchars = SCHARS (string);
5925 it->method = GET_FROM_STRING;
5926 it->current.string_pos = string_pos (charpos, string);
5928 if (it->bidi_p)
5930 it->bidi_it.string.lstring = string;
5931 it->bidi_it.string.s = NULL;
5932 it->bidi_it.string.schars = it->end_charpos;
5933 it->bidi_it.string.bufpos = 0;
5934 it->bidi_it.string.from_disp_str = 0;
5935 it->bidi_it.string.unibyte = !it->multibyte_p;
5936 bidi_init_it (charpos, IT_STRING_BYTEPOS (*it),
5937 FRAME_WINDOW_P (it->f), &it->bidi_it);
5940 else
5942 it->s = (const unsigned char *) s;
5943 it->string = Qnil;
5945 /* Note that we use IT->current.pos, not it->current.string_pos,
5946 for displaying C strings. */
5947 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
5948 if (it->multibyte_p)
5950 it->current.pos = c_string_pos (charpos, s, 1);
5951 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
5953 else
5955 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
5956 it->end_charpos = it->string_nchars = strlen (s);
5959 if (it->bidi_p)
5961 it->bidi_it.string.lstring = Qnil;
5962 it->bidi_it.string.s = (const unsigned char *) s;
5963 it->bidi_it.string.schars = it->end_charpos;
5964 it->bidi_it.string.bufpos = 0;
5965 it->bidi_it.string.from_disp_str = 0;
5966 it->bidi_it.string.unibyte = !it->multibyte_p;
5967 bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
5968 &it->bidi_it);
5970 it->method = GET_FROM_C_STRING;
5973 /* PRECISION > 0 means don't return more than PRECISION characters
5974 from the string. */
5975 if (precision > 0 && it->end_charpos - charpos > precision)
5977 it->end_charpos = it->string_nchars = charpos + precision;
5978 if (it->bidi_p)
5979 it->bidi_it.string.schars = it->end_charpos;
5982 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
5983 characters have been returned. FIELD_WIDTH == 0 means don't pad,
5984 FIELD_WIDTH < 0 means infinite field width. This is useful for
5985 padding with `-' at the end of a mode line. */
5986 if (field_width < 0)
5987 field_width = INFINITY;
5988 /* Implementation note: We deliberately don't enlarge
5989 it->bidi_it.string.schars here to fit it->end_charpos, because
5990 the bidi iterator cannot produce characters out of thin air. */
5991 if (field_width > it->end_charpos - charpos)
5992 it->end_charpos = charpos + field_width;
5994 /* Use the standard display table for displaying strings. */
5995 if (DISP_TABLE_P (Vstandard_display_table))
5996 it->dp = XCHAR_TABLE (Vstandard_display_table);
5998 it->stop_charpos = charpos;
5999 it->prev_stop = charpos;
6000 it->base_level_stop = 0;
6001 if (it->bidi_p)
6003 it->bidi_it.first_elt = 1;
6004 it->bidi_it.paragraph_dir = NEUTRAL_DIR;
6005 it->bidi_it.disp_pos = -1;
6007 if (s == NULL && it->multibyte_p)
6009 EMACS_INT endpos = SCHARS (it->string);
6010 if (endpos > it->end_charpos)
6011 endpos = it->end_charpos;
6012 composition_compute_stop_pos (&it->cmp_it, charpos, -1, endpos,
6013 it->string);
6015 CHECK_IT (it);
6020 /***********************************************************************
6021 Iteration
6022 ***********************************************************************/
6024 /* Map enum it_method value to corresponding next_element_from_* function. */
6026 static int (* get_next_element[NUM_IT_METHODS]) (struct it *it) =
6028 next_element_from_buffer,
6029 next_element_from_display_vector,
6030 next_element_from_string,
6031 next_element_from_c_string,
6032 next_element_from_image,
6033 next_element_from_stretch
6036 #define GET_NEXT_DISPLAY_ELEMENT(it) (*get_next_element[(it)->method]) (it)
6039 /* Return 1 iff a character at CHARPOS (and BYTEPOS) is composed
6040 (possibly with the following characters). */
6042 #define CHAR_COMPOSED_P(IT,CHARPOS,BYTEPOS,END_CHARPOS) \
6043 ((IT)->cmp_it.id >= 0 \
6044 || ((IT)->cmp_it.stop_pos == (CHARPOS) \
6045 && composition_reseat_it (&(IT)->cmp_it, CHARPOS, BYTEPOS, \
6046 END_CHARPOS, (IT)->w, \
6047 FACE_FROM_ID ((IT)->f, (IT)->face_id), \
6048 (IT)->string)))
6051 /* Lookup the char-table Vglyphless_char_display for character C (-1
6052 if we want information for no-font case), and return the display
6053 method symbol. By side-effect, update it->what and
6054 it->glyphless_method. This function is called from
6055 get_next_display_element for each character element, and from
6056 x_produce_glyphs when no suitable font was found. */
6058 Lisp_Object
6059 lookup_glyphless_char_display (int c, struct it *it)
6061 Lisp_Object glyphless_method = Qnil;
6063 if (CHAR_TABLE_P (Vglyphless_char_display)
6064 && CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display)) >= 1)
6066 if (c >= 0)
6068 glyphless_method = CHAR_TABLE_REF (Vglyphless_char_display, c);
6069 if (CONSP (glyphless_method))
6070 glyphless_method = FRAME_WINDOW_P (it->f)
6071 ? XCAR (glyphless_method)
6072 : XCDR (glyphless_method);
6074 else
6075 glyphless_method = XCHAR_TABLE (Vglyphless_char_display)->extras[0];
6078 retry:
6079 if (NILP (glyphless_method))
6081 if (c >= 0)
6082 /* The default is to display the character by a proper font. */
6083 return Qnil;
6084 /* The default for the no-font case is to display an empty box. */
6085 glyphless_method = Qempty_box;
6087 if (EQ (glyphless_method, Qzero_width))
6089 if (c >= 0)
6090 return glyphless_method;
6091 /* This method can't be used for the no-font case. */
6092 glyphless_method = Qempty_box;
6094 if (EQ (glyphless_method, Qthin_space))
6095 it->glyphless_method = GLYPHLESS_DISPLAY_THIN_SPACE;
6096 else if (EQ (glyphless_method, Qempty_box))
6097 it->glyphless_method = GLYPHLESS_DISPLAY_EMPTY_BOX;
6098 else if (EQ (glyphless_method, Qhex_code))
6099 it->glyphless_method = GLYPHLESS_DISPLAY_HEX_CODE;
6100 else if (STRINGP (glyphless_method))
6101 it->glyphless_method = GLYPHLESS_DISPLAY_ACRONYM;
6102 else
6104 /* Invalid value. We use the default method. */
6105 glyphless_method = Qnil;
6106 goto retry;
6108 it->what = IT_GLYPHLESS;
6109 return glyphless_method;
6112 /* Load IT's display element fields with information about the next
6113 display element from the current position of IT. Value is zero if
6114 end of buffer (or C string) is reached. */
6116 static struct frame *last_escape_glyph_frame = NULL;
6117 static unsigned last_escape_glyph_face_id = (1 << FACE_ID_BITS);
6118 static int last_escape_glyph_merged_face_id = 0;
6120 struct frame *last_glyphless_glyph_frame = NULL;
6121 unsigned last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
6122 int last_glyphless_glyph_merged_face_id = 0;
6124 static int
6125 get_next_display_element (struct it *it)
6127 /* Non-zero means that we found a display element. Zero means that
6128 we hit the end of what we iterate over. Performance note: the
6129 function pointer `method' used here turns out to be faster than
6130 using a sequence of if-statements. */
6131 int success_p;
6133 get_next:
6134 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
6136 if (it->what == IT_CHARACTER)
6138 /* UAX#9, L4: "A character is depicted by a mirrored glyph if
6139 and only if (a) the resolved directionality of that character
6140 is R..." */
6141 /* FIXME: Do we need an exception for characters from display
6142 tables? */
6143 if (it->bidi_p && it->bidi_it.type == STRONG_R)
6144 it->c = bidi_mirror_char (it->c);
6145 /* Map via display table or translate control characters.
6146 IT->c, IT->len etc. have been set to the next character by
6147 the function call above. If we have a display table, and it
6148 contains an entry for IT->c, translate it. Don't do this if
6149 IT->c itself comes from a display table, otherwise we could
6150 end up in an infinite recursion. (An alternative could be to
6151 count the recursion depth of this function and signal an
6152 error when a certain maximum depth is reached.) Is it worth
6153 it? */
6154 if (success_p && it->dpvec == NULL)
6156 Lisp_Object dv;
6157 struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte);
6158 enum { char_is_other = 0, char_is_nbsp, char_is_soft_hyphen }
6159 nbsp_or_shy = char_is_other;
6160 int c = it->c; /* This is the character to display. */
6162 if (! it->multibyte_p && ! ASCII_CHAR_P (c))
6164 xassert (SINGLE_BYTE_CHAR_P (c));
6165 if (unibyte_display_via_language_environment)
6167 c = DECODE_CHAR (unibyte, c);
6168 if (c < 0)
6169 c = BYTE8_TO_CHAR (it->c);
6171 else
6172 c = BYTE8_TO_CHAR (it->c);
6175 if (it->dp
6176 && (dv = DISP_CHAR_VECTOR (it->dp, c),
6177 VECTORP (dv)))
6179 struct Lisp_Vector *v = XVECTOR (dv);
6181 /* Return the first character from the display table
6182 entry, if not empty. If empty, don't display the
6183 current character. */
6184 if (v->header.size)
6186 it->dpvec_char_len = it->len;
6187 it->dpvec = v->contents;
6188 it->dpend = v->contents + v->header.size;
6189 it->current.dpvec_index = 0;
6190 it->dpvec_face_id = -1;
6191 it->saved_face_id = it->face_id;
6192 it->method = GET_FROM_DISPLAY_VECTOR;
6193 it->ellipsis_p = 0;
6195 else
6197 set_iterator_to_next (it, 0);
6199 goto get_next;
6202 if (! NILP (lookup_glyphless_char_display (c, it)))
6204 if (it->what == IT_GLYPHLESS)
6205 goto done;
6206 /* Don't display this character. */
6207 set_iterator_to_next (it, 0);
6208 goto get_next;
6211 if (! ASCII_CHAR_P (c) && ! NILP (Vnobreak_char_display))
6212 nbsp_or_shy = (c == 0xA0 ? char_is_nbsp
6213 : c == 0xAD ? char_is_soft_hyphen
6214 : char_is_other);
6216 /* Translate control characters into `\003' or `^C' form.
6217 Control characters coming from a display table entry are
6218 currently not translated because we use IT->dpvec to hold
6219 the translation. This could easily be changed but I
6220 don't believe that it is worth doing.
6222 NBSP and SOFT-HYPEN are property translated too.
6224 Non-printable characters and raw-byte characters are also
6225 translated to octal form. */
6226 if (((c < ' ' || c == 127) /* ASCII control chars */
6227 ? (it->area != TEXT_AREA
6228 /* In mode line, treat \n, \t like other crl chars. */
6229 || (c != '\t'
6230 && it->glyph_row
6231 && (it->glyph_row->mode_line_p || it->avoid_cursor_p))
6232 || (c != '\n' && c != '\t'))
6233 : (nbsp_or_shy
6234 || CHAR_BYTE8_P (c)
6235 || ! CHAR_PRINTABLE_P (c))))
6237 /* C is a control character, NBSP, SOFT-HYPEN, raw-byte,
6238 or a non-printable character which must be displayed
6239 either as '\003' or as `^C' where the '\\' and '^'
6240 can be defined in the display table. Fill
6241 IT->ctl_chars with glyphs for what we have to
6242 display. Then, set IT->dpvec to these glyphs. */
6243 Lisp_Object gc;
6244 int ctl_len;
6245 int face_id;
6246 EMACS_INT lface_id = 0;
6247 int escape_glyph;
6249 /* Handle control characters with ^. */
6251 if (ASCII_CHAR_P (c) && it->ctl_arrow_p)
6253 int g;
6255 g = '^'; /* default glyph for Control */
6256 /* Set IT->ctl_chars[0] to the glyph for `^'. */
6257 if (it->dp
6258 && (gc = DISP_CTRL_GLYPH (it->dp), GLYPH_CODE_P (gc))
6259 && GLYPH_CODE_CHAR_VALID_P (gc))
6261 g = GLYPH_CODE_CHAR (gc);
6262 lface_id = GLYPH_CODE_FACE (gc);
6264 if (lface_id)
6266 face_id = merge_faces (it->f, Qt, lface_id, it->face_id);
6268 else if (it->f == last_escape_glyph_frame
6269 && it->face_id == last_escape_glyph_face_id)
6271 face_id = last_escape_glyph_merged_face_id;
6273 else
6275 /* Merge the escape-glyph face into the current face. */
6276 face_id = merge_faces (it->f, Qescape_glyph, 0,
6277 it->face_id);
6278 last_escape_glyph_frame = it->f;
6279 last_escape_glyph_face_id = it->face_id;
6280 last_escape_glyph_merged_face_id = face_id;
6283 XSETINT (it->ctl_chars[0], g);
6284 XSETINT (it->ctl_chars[1], c ^ 0100);
6285 ctl_len = 2;
6286 goto display_control;
6289 /* Handle non-break space in the mode where it only gets
6290 highlighting. */
6292 if (EQ (Vnobreak_char_display, Qt)
6293 && nbsp_or_shy == char_is_nbsp)
6295 /* Merge the no-break-space face into the current face. */
6296 face_id = merge_faces (it->f, Qnobreak_space, 0,
6297 it->face_id);
6299 c = ' ';
6300 XSETINT (it->ctl_chars[0], ' ');
6301 ctl_len = 1;
6302 goto display_control;
6305 /* Handle sequences that start with the "escape glyph". */
6307 /* the default escape glyph is \. */
6308 escape_glyph = '\\';
6310 if (it->dp
6311 && (gc = DISP_ESCAPE_GLYPH (it->dp), GLYPH_CODE_P (gc))
6312 && GLYPH_CODE_CHAR_VALID_P (gc))
6314 escape_glyph = GLYPH_CODE_CHAR (gc);
6315 lface_id = GLYPH_CODE_FACE (gc);
6317 if (lface_id)
6319 /* The display table specified a face.
6320 Merge it into face_id and also into escape_glyph. */
6321 face_id = merge_faces (it->f, Qt, lface_id,
6322 it->face_id);
6324 else if (it->f == last_escape_glyph_frame
6325 && it->face_id == last_escape_glyph_face_id)
6327 face_id = last_escape_glyph_merged_face_id;
6329 else
6331 /* Merge the escape-glyph face into the current face. */
6332 face_id = merge_faces (it->f, Qescape_glyph, 0,
6333 it->face_id);
6334 last_escape_glyph_frame = it->f;
6335 last_escape_glyph_face_id = it->face_id;
6336 last_escape_glyph_merged_face_id = face_id;
6339 /* Handle soft hyphens in the mode where they only get
6340 highlighting. */
6342 if (EQ (Vnobreak_char_display, Qt)
6343 && nbsp_or_shy == char_is_soft_hyphen)
6345 XSETINT (it->ctl_chars[0], '-');
6346 ctl_len = 1;
6347 goto display_control;
6350 /* Handle non-break space and soft hyphen
6351 with the escape glyph. */
6353 if (nbsp_or_shy)
6355 XSETINT (it->ctl_chars[0], escape_glyph);
6356 c = (nbsp_or_shy == char_is_nbsp ? ' ' : '-');
6357 XSETINT (it->ctl_chars[1], c);
6358 ctl_len = 2;
6359 goto display_control;
6363 char str[10];
6364 int len, i;
6366 if (CHAR_BYTE8_P (c))
6367 /* Display \200 instead of \17777600. */
6368 c = CHAR_TO_BYTE8 (c);
6369 len = sprintf (str, "%03o", c);
6371 XSETINT (it->ctl_chars[0], escape_glyph);
6372 for (i = 0; i < len; i++)
6373 XSETINT (it->ctl_chars[i + 1], str[i]);
6374 ctl_len = len + 1;
6377 display_control:
6378 /* Set up IT->dpvec and return first character from it. */
6379 it->dpvec_char_len = it->len;
6380 it->dpvec = it->ctl_chars;
6381 it->dpend = it->dpvec + ctl_len;
6382 it->current.dpvec_index = 0;
6383 it->dpvec_face_id = face_id;
6384 it->saved_face_id = it->face_id;
6385 it->method = GET_FROM_DISPLAY_VECTOR;
6386 it->ellipsis_p = 0;
6387 goto get_next;
6389 it->char_to_display = c;
6391 else if (success_p)
6393 it->char_to_display = it->c;
6397 /* Adjust face id for a multibyte character. There are no multibyte
6398 character in unibyte text. */
6399 if ((it->what == IT_CHARACTER || it->what == IT_COMPOSITION)
6400 && it->multibyte_p
6401 && success_p
6402 && FRAME_WINDOW_P (it->f))
6404 struct face *face = FACE_FROM_ID (it->f, it->face_id);
6406 if (it->what == IT_COMPOSITION && it->cmp_it.ch >= 0)
6408 /* Automatic composition with glyph-string. */
6409 Lisp_Object gstring = composition_gstring_from_id (it->cmp_it.id);
6411 it->face_id = face_for_font (it->f, LGSTRING_FONT (gstring), face);
6413 else
6415 EMACS_INT pos = (it->s ? -1
6416 : STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
6417 : IT_CHARPOS (*it));
6418 int c;
6420 if (it->what == IT_CHARACTER)
6421 c = it->char_to_display;
6422 else
6424 struct composition *cmp = composition_table[it->cmp_it.id];
6425 int i;
6427 c = ' ';
6428 for (i = 0; i < cmp->glyph_len; i++)
6429 if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
6430 break;
6432 it->face_id = FACE_FOR_CHAR (it->f, face, c, pos, it->string);
6436 done:
6437 /* Is this character the last one of a run of characters with
6438 box? If yes, set IT->end_of_box_run_p to 1. */
6439 if (it->face_box_p
6440 && it->s == NULL)
6442 if (it->method == GET_FROM_STRING && it->sp)
6444 int face_id = underlying_face_id (it);
6445 struct face *face = FACE_FROM_ID (it->f, face_id);
6447 if (face)
6449 if (face->box == FACE_NO_BOX)
6451 /* If the box comes from face properties in a
6452 display string, check faces in that string. */
6453 int string_face_id = face_after_it_pos (it);
6454 it->end_of_box_run_p
6455 = (FACE_FROM_ID (it->f, string_face_id)->box
6456 == FACE_NO_BOX);
6458 /* Otherwise, the box comes from the underlying face.
6459 If this is the last string character displayed, check
6460 the next buffer location. */
6461 else if ((IT_STRING_CHARPOS (*it) >= SCHARS (it->string) - 1)
6462 && (it->current.overlay_string_index
6463 == it->n_overlay_strings - 1))
6465 EMACS_INT ignore;
6466 int next_face_id;
6467 struct text_pos pos = it->current.pos;
6468 INC_TEXT_POS (pos, it->multibyte_p);
6470 next_face_id = face_at_buffer_position
6471 (it->w, CHARPOS (pos), it->region_beg_charpos,
6472 it->region_end_charpos, &ignore,
6473 (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT), 0,
6474 -1);
6475 it->end_of_box_run_p
6476 = (FACE_FROM_ID (it->f, next_face_id)->box
6477 == FACE_NO_BOX);
6481 else
6483 int face_id = face_after_it_pos (it);
6484 it->end_of_box_run_p
6485 = (face_id != it->face_id
6486 && FACE_FROM_ID (it->f, face_id)->box == FACE_NO_BOX);
6490 /* Value is 0 if end of buffer or string reached. */
6491 return success_p;
6495 /* Move IT to the next display element.
6497 RESEAT_P non-zero means if called on a newline in buffer text,
6498 skip to the next visible line start.
6500 Functions get_next_display_element and set_iterator_to_next are
6501 separate because I find this arrangement easier to handle than a
6502 get_next_display_element function that also increments IT's
6503 position. The way it is we can first look at an iterator's current
6504 display element, decide whether it fits on a line, and if it does,
6505 increment the iterator position. The other way around we probably
6506 would either need a flag indicating whether the iterator has to be
6507 incremented the next time, or we would have to implement a
6508 decrement position function which would not be easy to write. */
6510 void
6511 set_iterator_to_next (struct it *it, int reseat_p)
6513 /* Reset flags indicating start and end of a sequence of characters
6514 with box. Reset them at the start of this function because
6515 moving the iterator to a new position might set them. */
6516 it->start_of_box_run_p = it->end_of_box_run_p = 0;
6518 switch (it->method)
6520 case GET_FROM_BUFFER:
6521 /* The current display element of IT is a character from
6522 current_buffer. Advance in the buffer, and maybe skip over
6523 invisible lines that are so because of selective display. */
6524 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
6525 reseat_at_next_visible_line_start (it, 0);
6526 else if (it->cmp_it.id >= 0)
6528 /* We are currently getting glyphs from a composition. */
6529 int i;
6531 if (! it->bidi_p)
6533 IT_CHARPOS (*it) += it->cmp_it.nchars;
6534 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
6535 if (it->cmp_it.to < it->cmp_it.nglyphs)
6537 it->cmp_it.from = it->cmp_it.to;
6539 else
6541 it->cmp_it.id = -1;
6542 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
6543 IT_BYTEPOS (*it),
6544 it->end_charpos, Qnil);
6547 else if (! it->cmp_it.reversed_p)
6549 /* Composition created while scanning forward. */
6550 /* Update IT's char/byte positions to point to the first
6551 character of the next grapheme cluster, or to the
6552 character visually after the current composition. */
6553 for (i = 0; i < it->cmp_it.nchars; i++)
6554 bidi_move_to_visually_next (&it->bidi_it);
6555 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6556 IT_CHARPOS (*it) = it->bidi_it.charpos;
6558 if (it->cmp_it.to < it->cmp_it.nglyphs)
6560 /* Proceed to the next grapheme cluster. */
6561 it->cmp_it.from = it->cmp_it.to;
6563 else
6565 /* No more grapheme clusters in this composition.
6566 Find the next stop position. */
6567 EMACS_INT stop = it->end_charpos;
6568 if (it->bidi_it.scan_dir < 0)
6569 /* Now we are scanning backward and don't know
6570 where to stop. */
6571 stop = -1;
6572 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
6573 IT_BYTEPOS (*it), stop, Qnil);
6576 else
6578 /* Composition created while scanning backward. */
6579 /* Update IT's char/byte positions to point to the last
6580 character of the previous grapheme cluster, or the
6581 character visually after the current composition. */
6582 for (i = 0; i < it->cmp_it.nchars; i++)
6583 bidi_move_to_visually_next (&it->bidi_it);
6584 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6585 IT_CHARPOS (*it) = it->bidi_it.charpos;
6586 if (it->cmp_it.from > 0)
6588 /* Proceed to the previous grapheme cluster. */
6589 it->cmp_it.to = it->cmp_it.from;
6591 else
6593 /* No more grapheme clusters in this composition.
6594 Find the next stop position. */
6595 EMACS_INT stop = it->end_charpos;
6596 if (it->bidi_it.scan_dir < 0)
6597 /* Now we are scanning backward and don't know
6598 where to stop. */
6599 stop = -1;
6600 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
6601 IT_BYTEPOS (*it), stop, Qnil);
6605 else
6607 xassert (it->len != 0);
6609 if (!it->bidi_p)
6611 IT_BYTEPOS (*it) += it->len;
6612 IT_CHARPOS (*it) += 1;
6614 else
6616 int prev_scan_dir = it->bidi_it.scan_dir;
6617 /* If this is a new paragraph, determine its base
6618 direction (a.k.a. its base embedding level). */
6619 if (it->bidi_it.new_paragraph)
6620 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 0);
6621 bidi_move_to_visually_next (&it->bidi_it);
6622 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6623 IT_CHARPOS (*it) = it->bidi_it.charpos;
6624 if (prev_scan_dir != it->bidi_it.scan_dir)
6626 /* As the scan direction was changed, we must
6627 re-compute the stop position for composition. */
6628 EMACS_INT stop = it->end_charpos;
6629 if (it->bidi_it.scan_dir < 0)
6630 stop = -1;
6631 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
6632 IT_BYTEPOS (*it), stop, Qnil);
6635 xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
6637 break;
6639 case GET_FROM_C_STRING:
6640 /* Current display element of IT is from a C string. */
6641 if (!it->bidi_p
6642 /* If the string position is beyond string's end, it means
6643 next_element_from_c_string is padding the string with
6644 blanks, in which case we bypass the bidi iterator,
6645 because it cannot deal with such virtual characters. */
6646 || IT_CHARPOS (*it) >= it->bidi_it.string.schars)
6648 IT_BYTEPOS (*it) += it->len;
6649 IT_CHARPOS (*it) += 1;
6651 else
6653 bidi_move_to_visually_next (&it->bidi_it);
6654 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6655 IT_CHARPOS (*it) = it->bidi_it.charpos;
6657 break;
6659 case GET_FROM_DISPLAY_VECTOR:
6660 /* Current display element of IT is from a display table entry.
6661 Advance in the display table definition. Reset it to null if
6662 end reached, and continue with characters from buffers/
6663 strings. */
6664 ++it->current.dpvec_index;
6666 /* Restore face of the iterator to what they were before the
6667 display vector entry (these entries may contain faces). */
6668 it->face_id = it->saved_face_id;
6670 if (it->dpvec + it->current.dpvec_index == it->dpend)
6672 int recheck_faces = it->ellipsis_p;
6674 if (it->s)
6675 it->method = GET_FROM_C_STRING;
6676 else if (STRINGP (it->string))
6677 it->method = GET_FROM_STRING;
6678 else
6680 it->method = GET_FROM_BUFFER;
6681 it->object = it->w->buffer;
6684 it->dpvec = NULL;
6685 it->current.dpvec_index = -1;
6687 /* Skip over characters which were displayed via IT->dpvec. */
6688 if (it->dpvec_char_len < 0)
6689 reseat_at_next_visible_line_start (it, 1);
6690 else if (it->dpvec_char_len > 0)
6692 if (it->method == GET_FROM_STRING
6693 && it->n_overlay_strings > 0)
6694 it->ignore_overlay_strings_at_pos_p = 1;
6695 it->len = it->dpvec_char_len;
6696 set_iterator_to_next (it, reseat_p);
6699 /* Maybe recheck faces after display vector */
6700 if (recheck_faces)
6701 it->stop_charpos = IT_CHARPOS (*it);
6703 break;
6705 case GET_FROM_STRING:
6706 /* Current display element is a character from a Lisp string. */
6707 xassert (it->s == NULL && STRINGP (it->string));
6708 if (it->cmp_it.id >= 0)
6710 int i;
6712 if (! it->bidi_p)
6714 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
6715 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
6716 if (it->cmp_it.to < it->cmp_it.nglyphs)
6717 it->cmp_it.from = it->cmp_it.to;
6718 else
6720 it->cmp_it.id = -1;
6721 composition_compute_stop_pos (&it->cmp_it,
6722 IT_STRING_CHARPOS (*it),
6723 IT_STRING_BYTEPOS (*it),
6724 it->end_charpos, it->string);
6727 else if (! it->cmp_it.reversed_p)
6729 for (i = 0; i < it->cmp_it.nchars; i++)
6730 bidi_move_to_visually_next (&it->bidi_it);
6731 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
6732 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
6734 if (it->cmp_it.to < it->cmp_it.nglyphs)
6735 it->cmp_it.from = it->cmp_it.to;
6736 else
6738 EMACS_INT stop = it->end_charpos;
6739 if (it->bidi_it.scan_dir < 0)
6740 stop = -1;
6741 composition_compute_stop_pos (&it->cmp_it,
6742 IT_STRING_CHARPOS (*it),
6743 IT_STRING_BYTEPOS (*it), stop,
6744 it->string);
6747 else
6749 for (i = 0; i < it->cmp_it.nchars; i++)
6750 bidi_move_to_visually_next (&it->bidi_it);
6751 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
6752 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
6753 if (it->cmp_it.from > 0)
6754 it->cmp_it.to = it->cmp_it.from;
6755 else
6757 EMACS_INT stop = it->end_charpos;
6758 if (it->bidi_it.scan_dir < 0)
6759 stop = -1;
6760 composition_compute_stop_pos (&it->cmp_it,
6761 IT_STRING_CHARPOS (*it),
6762 IT_STRING_BYTEPOS (*it), stop,
6763 it->string);
6767 else
6769 if (!it->bidi_p
6770 /* If the string position is beyond string's end, it
6771 means next_element_from_string is padding the string
6772 with blanks, in which case we bypass the bidi
6773 iterator, because it cannot deal with such virtual
6774 characters. */
6775 || IT_STRING_CHARPOS (*it) >= it->bidi_it.string.schars)
6777 IT_STRING_BYTEPOS (*it) += it->len;
6778 IT_STRING_CHARPOS (*it) += 1;
6780 else
6782 int prev_scan_dir = it->bidi_it.scan_dir;
6784 bidi_move_to_visually_next (&it->bidi_it);
6785 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
6786 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
6787 if (prev_scan_dir != it->bidi_it.scan_dir)
6789 EMACS_INT stop = it->end_charpos;
6791 if (it->bidi_it.scan_dir < 0)
6792 stop = -1;
6793 composition_compute_stop_pos (&it->cmp_it,
6794 IT_STRING_CHARPOS (*it),
6795 IT_STRING_BYTEPOS (*it), stop,
6796 it->string);
6801 consider_string_end:
6803 if (it->current.overlay_string_index >= 0)
6805 /* IT->string is an overlay string. Advance to the
6806 next, if there is one. */
6807 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
6809 it->ellipsis_p = 0;
6810 next_overlay_string (it);
6811 if (it->ellipsis_p)
6812 setup_for_ellipsis (it, 0);
6815 else
6817 /* IT->string is not an overlay string. If we reached
6818 its end, and there is something on IT->stack, proceed
6819 with what is on the stack. This can be either another
6820 string, this time an overlay string, or a buffer. */
6821 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
6822 && it->sp > 0)
6824 pop_it (it);
6825 if (it->method == GET_FROM_STRING)
6826 goto consider_string_end;
6829 break;
6831 case GET_FROM_IMAGE:
6832 case GET_FROM_STRETCH:
6833 /* The position etc with which we have to proceed are on
6834 the stack. The position may be at the end of a string,
6835 if the `display' property takes up the whole string. */
6836 xassert (it->sp > 0);
6837 pop_it (it);
6838 if (it->method == GET_FROM_STRING)
6839 goto consider_string_end;
6840 break;
6842 default:
6843 /* There are no other methods defined, so this should be a bug. */
6844 abort ();
6847 xassert (it->method != GET_FROM_STRING
6848 || (STRINGP (it->string)
6849 && IT_STRING_CHARPOS (*it) >= 0));
6852 /* Load IT's display element fields with information about the next
6853 display element which comes from a display table entry or from the
6854 result of translating a control character to one of the forms `^C'
6855 or `\003'.
6857 IT->dpvec holds the glyphs to return as characters.
6858 IT->saved_face_id holds the face id before the display vector--it
6859 is restored into IT->face_id in set_iterator_to_next. */
6861 static int
6862 next_element_from_display_vector (struct it *it)
6864 Lisp_Object gc;
6866 /* Precondition. */
6867 xassert (it->dpvec && it->current.dpvec_index >= 0);
6869 it->face_id = it->saved_face_id;
6871 /* KFS: This code used to check ip->dpvec[0] instead of the current element.
6872 That seemed totally bogus - so I changed it... */
6873 gc = it->dpvec[it->current.dpvec_index];
6875 if (GLYPH_CODE_P (gc) && GLYPH_CODE_CHAR_VALID_P (gc))
6877 it->c = GLYPH_CODE_CHAR (gc);
6878 it->len = CHAR_BYTES (it->c);
6880 /* The entry may contain a face id to use. Such a face id is
6881 the id of a Lisp face, not a realized face. A face id of
6882 zero means no face is specified. */
6883 if (it->dpvec_face_id >= 0)
6884 it->face_id = it->dpvec_face_id;
6885 else
6887 EMACS_INT lface_id = GLYPH_CODE_FACE (gc);
6888 if (lface_id > 0)
6889 it->face_id = merge_faces (it->f, Qt, lface_id,
6890 it->saved_face_id);
6893 else
6894 /* Display table entry is invalid. Return a space. */
6895 it->c = ' ', it->len = 1;
6897 /* Don't change position and object of the iterator here. They are
6898 still the values of the character that had this display table
6899 entry or was translated, and that's what we want. */
6900 it->what = IT_CHARACTER;
6901 return 1;
6904 /* Get the first element of string/buffer in the visual order, after
6905 being reseated to a new position in a string or a buffer. */
6906 static void
6907 get_visually_first_element (struct it *it)
6909 int string_p = STRINGP (it->string) || it->s;
6910 EMACS_INT eob = (string_p ? it->bidi_it.string.schars : ZV);
6911 EMACS_INT bob = (string_p ? 0 : BEGV);
6913 if (STRINGP (it->string))
6915 it->bidi_it.charpos = IT_STRING_CHARPOS (*it);
6916 it->bidi_it.bytepos = IT_STRING_BYTEPOS (*it);
6918 else
6920 it->bidi_it.charpos = IT_CHARPOS (*it);
6921 it->bidi_it.bytepos = IT_BYTEPOS (*it);
6924 if (it->bidi_it.charpos == eob)
6926 /* Nothing to do, but reset the FIRST_ELT flag, like
6927 bidi_paragraph_init does, because we are not going to
6928 call it. */
6929 it->bidi_it.first_elt = 0;
6931 else if (it->bidi_it.charpos == bob
6932 || (!string_p
6933 /* FIXME: Should support all Unicode line separators. */
6934 && (FETCH_CHAR (it->bidi_it.bytepos - 1) == '\n'
6935 || FETCH_CHAR (it->bidi_it.bytepos) == '\n')))
6937 /* If we are at the beginning of a line/string, we can produce
6938 the next element right away. */
6939 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
6940 bidi_move_to_visually_next (&it->bidi_it);
6942 else
6944 EMACS_INT orig_bytepos = it->bidi_it.bytepos;
6946 /* We need to prime the bidi iterator starting at the line's or
6947 string's beginning, before we will be able to produce the
6948 next element. */
6949 if (string_p)
6950 it->bidi_it.charpos = it->bidi_it.bytepos = 0;
6951 else
6953 it->bidi_it.charpos = find_next_newline_no_quit (IT_CHARPOS (*it),
6954 -1);
6955 it->bidi_it.bytepos = CHAR_TO_BYTE (it->bidi_it.charpos);
6957 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
6960 /* Now return to buffer/string position where we were asked
6961 to get the next display element, and produce that. */
6962 bidi_move_to_visually_next (&it->bidi_it);
6964 while (it->bidi_it.bytepos != orig_bytepos
6965 && it->bidi_it.charpos < eob);
6968 /* Adjust IT's position information to where we ended up. */
6969 if (STRINGP (it->string))
6971 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
6972 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
6974 else
6976 IT_CHARPOS (*it) = it->bidi_it.charpos;
6977 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6980 if (STRINGP (it->string) || !it->s)
6982 EMACS_INT stop, charpos, bytepos;
6984 if (STRINGP (it->string))
6986 xassert (!it->s);
6987 stop = SCHARS (it->string);
6988 if (stop > it->end_charpos)
6989 stop = it->end_charpos;
6990 charpos = IT_STRING_CHARPOS (*it);
6991 bytepos = IT_STRING_BYTEPOS (*it);
6993 else
6995 stop = it->end_charpos;
6996 charpos = IT_CHARPOS (*it);
6997 bytepos = IT_BYTEPOS (*it);
6999 if (it->bidi_it.scan_dir < 0)
7000 stop = -1;
7001 composition_compute_stop_pos (&it->cmp_it, charpos, bytepos, stop,
7002 it->string);
7006 /* Load IT with the next display element from Lisp string IT->string.
7007 IT->current.string_pos is the current position within the string.
7008 If IT->current.overlay_string_index >= 0, the Lisp string is an
7009 overlay string. */
7011 static int
7012 next_element_from_string (struct it *it)
7014 struct text_pos position;
7016 xassert (STRINGP (it->string));
7017 xassert (!it->bidi_p || EQ (it->string, it->bidi_it.string.lstring));
7018 xassert (IT_STRING_CHARPOS (*it) >= 0);
7019 position = it->current.string_pos;
7021 /* With bidi reordering, the character to display might not be the
7022 character at IT_STRING_CHARPOS. BIDI_IT.FIRST_ELT non-zero means
7023 that we were reseat()ed to a new string, whose paragraph
7024 direction is not known. */
7025 if (it->bidi_p && it->bidi_it.first_elt)
7027 get_visually_first_element (it);
7028 SET_TEXT_POS (position, IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it));
7031 /* Time to check for invisible text? */
7032 if (IT_STRING_CHARPOS (*it) < it->end_charpos)
7034 if (IT_STRING_CHARPOS (*it) >= it->stop_charpos)
7036 if (!(!it->bidi_p
7037 || BIDI_AT_BASE_LEVEL (it->bidi_it)
7038 || IT_STRING_CHARPOS (*it) == it->stop_charpos))
7040 /* With bidi non-linear iteration, we could find
7041 ourselves far beyond the last computed stop_charpos,
7042 with several other stop positions in between that we
7043 missed. Scan them all now, in buffer's logical
7044 order, until we find and handle the last stop_charpos
7045 that precedes our current position. */
7046 handle_stop_backwards (it, it->stop_charpos);
7047 return GET_NEXT_DISPLAY_ELEMENT (it);
7049 else
7051 if (it->bidi_p)
7053 /* Take note of the stop position we just moved
7054 across, for when we will move back across it. */
7055 it->prev_stop = it->stop_charpos;
7056 /* If we are at base paragraph embedding level, take
7057 note of the last stop position seen at this
7058 level. */
7059 if (BIDI_AT_BASE_LEVEL (it->bidi_it))
7060 it->base_level_stop = it->stop_charpos;
7062 handle_stop (it);
7064 /* Since a handler may have changed IT->method, we must
7065 recurse here. */
7066 return GET_NEXT_DISPLAY_ELEMENT (it);
7069 else if (it->bidi_p
7070 /* If we are before prev_stop, we may have overstepped
7071 on our way backwards a stop_pos, and if so, we need
7072 to handle that stop_pos. */
7073 && IT_STRING_CHARPOS (*it) < it->prev_stop
7074 /* We can sometimes back up for reasons that have nothing
7075 to do with bidi reordering. E.g., compositions. The
7076 code below is only needed when we are above the base
7077 embedding level, so test for that explicitly. */
7078 && !BIDI_AT_BASE_LEVEL (it->bidi_it))
7080 /* If we lost track of base_level_stop, we have no better
7081 place for handle_stop_backwards to start from than string
7082 beginning. This happens, e.g., when we were reseated to
7083 the previous screenful of text by vertical-motion. */
7084 if (it->base_level_stop <= 0
7085 || IT_STRING_CHARPOS (*it) < it->base_level_stop)
7086 it->base_level_stop = 0;
7087 handle_stop_backwards (it, it->base_level_stop);
7088 return GET_NEXT_DISPLAY_ELEMENT (it);
7092 if (it->current.overlay_string_index >= 0)
7094 /* Get the next character from an overlay string. In overlay
7095 strings, There is no field width or padding with spaces to
7096 do. */
7097 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7099 it->what = IT_EOB;
7100 return 0;
7102 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
7103 IT_STRING_BYTEPOS (*it),
7104 it->bidi_it.scan_dir < 0
7105 ? -1
7106 : SCHARS (it->string))
7107 && next_element_from_composition (it))
7109 return 1;
7111 else if (STRING_MULTIBYTE (it->string))
7113 const unsigned char *s = (SDATA (it->string)
7114 + IT_STRING_BYTEPOS (*it));
7115 it->c = string_char_and_length (s, &it->len);
7117 else
7119 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
7120 it->len = 1;
7123 else
7125 /* Get the next character from a Lisp string that is not an
7126 overlay string. Such strings come from the mode line, for
7127 example. We may have to pad with spaces, or truncate the
7128 string. See also next_element_from_c_string. */
7129 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
7131 it->what = IT_EOB;
7132 return 0;
7134 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
7136 /* Pad with spaces. */
7137 it->c = ' ', it->len = 1;
7138 CHARPOS (position) = BYTEPOS (position) = -1;
7140 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
7141 IT_STRING_BYTEPOS (*it),
7142 it->bidi_it.scan_dir < 0
7143 ? -1
7144 : it->string_nchars)
7145 && next_element_from_composition (it))
7147 return 1;
7149 else if (STRING_MULTIBYTE (it->string))
7151 const unsigned char *s = (SDATA (it->string)
7152 + IT_STRING_BYTEPOS (*it));
7153 it->c = string_char_and_length (s, &it->len);
7155 else
7157 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
7158 it->len = 1;
7162 /* Record what we have and where it came from. */
7163 it->what = IT_CHARACTER;
7164 it->object = it->string;
7165 it->position = position;
7166 return 1;
7170 /* Load IT with next display element from C string IT->s.
7171 IT->string_nchars is the maximum number of characters to return
7172 from the string. IT->end_charpos may be greater than
7173 IT->string_nchars when this function is called, in which case we
7174 may have to return padding spaces. Value is zero if end of string
7175 reached, including padding spaces. */
7177 static int
7178 next_element_from_c_string (struct it *it)
7180 int success_p = 1;
7182 xassert (it->s);
7183 xassert (!it->bidi_p || it->s == it->bidi_it.string.s);
7184 it->what = IT_CHARACTER;
7185 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
7186 it->object = Qnil;
7188 /* With bidi reordering, the character to display might not be the
7189 character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that
7190 we were reseated to a new string, whose paragraph direction is
7191 not known. */
7192 if (it->bidi_p && it->bidi_it.first_elt)
7193 get_visually_first_element (it);
7195 /* IT's position can be greater than IT->string_nchars in case a
7196 field width or precision has been specified when the iterator was
7197 initialized. */
7198 if (IT_CHARPOS (*it) >= it->end_charpos)
7200 /* End of the game. */
7201 it->what = IT_EOB;
7202 success_p = 0;
7204 else if (IT_CHARPOS (*it) >= it->string_nchars)
7206 /* Pad with spaces. */
7207 it->c = ' ', it->len = 1;
7208 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
7210 else if (it->multibyte_p)
7211 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it), &it->len);
7212 else
7213 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
7215 return success_p;
7219 /* Set up IT to return characters from an ellipsis, if appropriate.
7220 The definition of the ellipsis glyphs may come from a display table
7221 entry. This function fills IT with the first glyph from the
7222 ellipsis if an ellipsis is to be displayed. */
7224 static int
7225 next_element_from_ellipsis (struct it *it)
7227 if (it->selective_display_ellipsis_p)
7228 setup_for_ellipsis (it, it->len);
7229 else
7231 /* The face at the current position may be different from the
7232 face we find after the invisible text. Remember what it
7233 was in IT->saved_face_id, and signal that it's there by
7234 setting face_before_selective_p. */
7235 it->saved_face_id = it->face_id;
7236 it->method = GET_FROM_BUFFER;
7237 it->object = it->w->buffer;
7238 reseat_at_next_visible_line_start (it, 1);
7239 it->face_before_selective_p = 1;
7242 return GET_NEXT_DISPLAY_ELEMENT (it);
7246 /* Deliver an image display element. The iterator IT is already
7247 filled with image information (done in handle_display_prop). Value
7248 is always 1. */
7251 static int
7252 next_element_from_image (struct it *it)
7254 it->what = IT_IMAGE;
7255 it->ignore_overlay_strings_at_pos_p = 0;
7256 return 1;
7260 /* Fill iterator IT with next display element from a stretch glyph
7261 property. IT->object is the value of the text property. Value is
7262 always 1. */
7264 static int
7265 next_element_from_stretch (struct it *it)
7267 it->what = IT_STRETCH;
7268 return 1;
7271 /* Scan backwards from IT's current position until we find a stop
7272 position, or until BEGV. This is called when we find ourself
7273 before both the last known prev_stop and base_level_stop while
7274 reordering bidirectional text. */
7276 static void
7277 compute_stop_pos_backwards (struct it *it)
7279 const int SCAN_BACK_LIMIT = 1000;
7280 struct text_pos pos;
7281 struct display_pos save_current = it->current;
7282 struct text_pos save_position = it->position;
7283 EMACS_INT charpos = IT_CHARPOS (*it);
7284 EMACS_INT where_we_are = charpos;
7285 EMACS_INT save_stop_pos = it->stop_charpos;
7286 EMACS_INT save_end_pos = it->end_charpos;
7288 xassert (NILP (it->string) && !it->s);
7289 xassert (it->bidi_p);
7290 it->bidi_p = 0;
7293 it->end_charpos = min (charpos + 1, ZV);
7294 charpos = max (charpos - SCAN_BACK_LIMIT, BEGV);
7295 SET_TEXT_POS (pos, charpos, BYTE_TO_CHAR (charpos));
7296 reseat_1 (it, pos, 0);
7297 compute_stop_pos (it);
7298 /* We must advance forward, right? */
7299 if (it->stop_charpos <= charpos)
7300 abort ();
7302 while (charpos > BEGV && it->stop_charpos >= it->end_charpos);
7304 if (it->stop_charpos <= where_we_are)
7305 it->prev_stop = it->stop_charpos;
7306 else
7307 it->prev_stop = BEGV;
7308 it->bidi_p = 1;
7309 it->current = save_current;
7310 it->position = save_position;
7311 it->stop_charpos = save_stop_pos;
7312 it->end_charpos = save_end_pos;
7315 /* Scan forward from CHARPOS in the current buffer/string, until we
7316 find a stop position > current IT's position. Then handle the stop
7317 position before that. This is called when we bump into a stop
7318 position while reordering bidirectional text. CHARPOS should be
7319 the last previously processed stop_pos (or BEGV/0, if none were
7320 processed yet) whose position is less that IT's current
7321 position. */
7323 static void
7324 handle_stop_backwards (struct it *it, EMACS_INT charpos)
7326 int bufp = !STRINGP (it->string);
7327 EMACS_INT where_we_are = (bufp ? IT_CHARPOS (*it) : IT_STRING_CHARPOS (*it));
7328 struct display_pos save_current = it->current;
7329 struct text_pos save_position = it->position;
7330 struct text_pos pos1;
7331 EMACS_INT next_stop;
7333 /* Scan in strict logical order. */
7334 xassert (it->bidi_p);
7335 it->bidi_p = 0;
7338 it->prev_stop = charpos;
7339 if (bufp)
7341 SET_TEXT_POS (pos1, charpos, CHAR_TO_BYTE (charpos));
7342 reseat_1 (it, pos1, 0);
7344 else
7345 it->current.string_pos = string_pos (charpos, it->string);
7346 compute_stop_pos (it);
7347 /* We must advance forward, right? */
7348 if (it->stop_charpos <= it->prev_stop)
7349 abort ();
7350 charpos = it->stop_charpos;
7352 while (charpos <= where_we_are);
7354 it->bidi_p = 1;
7355 it->current = save_current;
7356 it->position = save_position;
7357 next_stop = it->stop_charpos;
7358 it->stop_charpos = it->prev_stop;
7359 handle_stop (it);
7360 it->stop_charpos = next_stop;
7363 /* Load IT with the next display element from current_buffer. Value
7364 is zero if end of buffer reached. IT->stop_charpos is the next
7365 position at which to stop and check for text properties or buffer
7366 end. */
7368 static int
7369 next_element_from_buffer (struct it *it)
7371 int success_p = 1;
7373 xassert (IT_CHARPOS (*it) >= BEGV);
7374 xassert (NILP (it->string) && !it->s);
7375 xassert (!it->bidi_p
7376 || (EQ (it->bidi_it.string.lstring, Qnil)
7377 && it->bidi_it.string.s == NULL));
7379 /* With bidi reordering, the character to display might not be the
7380 character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that
7381 we were reseat()ed to a new buffer position, which is potentially
7382 a different paragraph. */
7383 if (it->bidi_p && it->bidi_it.first_elt)
7385 get_visually_first_element (it);
7386 SET_TEXT_POS (it->position, IT_CHARPOS (*it), IT_BYTEPOS (*it));
7389 if (IT_CHARPOS (*it) >= it->stop_charpos)
7391 if (IT_CHARPOS (*it) >= it->end_charpos)
7393 int overlay_strings_follow_p;
7395 /* End of the game, except when overlay strings follow that
7396 haven't been returned yet. */
7397 if (it->overlay_strings_at_end_processed_p)
7398 overlay_strings_follow_p = 0;
7399 else
7401 it->overlay_strings_at_end_processed_p = 1;
7402 overlay_strings_follow_p = get_overlay_strings (it, 0);
7405 if (overlay_strings_follow_p)
7406 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
7407 else
7409 it->what = IT_EOB;
7410 it->position = it->current.pos;
7411 success_p = 0;
7414 else if (!(!it->bidi_p
7415 || BIDI_AT_BASE_LEVEL (it->bidi_it)
7416 || IT_CHARPOS (*it) == it->stop_charpos))
7418 /* With bidi non-linear iteration, we could find ourselves
7419 far beyond the last computed stop_charpos, with several
7420 other stop positions in between that we missed. Scan
7421 them all now, in buffer's logical order, until we find
7422 and handle the last stop_charpos that precedes our
7423 current position. */
7424 handle_stop_backwards (it, it->stop_charpos);
7425 return GET_NEXT_DISPLAY_ELEMENT (it);
7427 else
7429 if (it->bidi_p)
7431 /* Take note of the stop position we just moved across,
7432 for when we will move back across it. */
7433 it->prev_stop = it->stop_charpos;
7434 /* If we are at base paragraph embedding level, take
7435 note of the last stop position seen at this
7436 level. */
7437 if (BIDI_AT_BASE_LEVEL (it->bidi_it))
7438 it->base_level_stop = it->stop_charpos;
7440 handle_stop (it);
7441 return GET_NEXT_DISPLAY_ELEMENT (it);
7444 else if (it->bidi_p
7445 /* If we are before prev_stop, we may have overstepped on
7446 our way backwards a stop_pos, and if so, we need to
7447 handle that stop_pos. */
7448 && IT_CHARPOS (*it) < it->prev_stop
7449 /* We can sometimes back up for reasons that have nothing
7450 to do with bidi reordering. E.g., compositions. The
7451 code below is only needed when we are above the base
7452 embedding level, so test for that explicitly. */
7453 && !BIDI_AT_BASE_LEVEL (it->bidi_it))
7455 if (it->base_level_stop <= 0
7456 || IT_CHARPOS (*it) < it->base_level_stop)
7458 /* If we lost track of base_level_stop, we need to find
7459 prev_stop by looking backwards. This happens, e.g., when
7460 we were reseated to the previous screenful of text by
7461 vertical-motion. */
7462 it->base_level_stop = BEGV;
7463 compute_stop_pos_backwards (it);
7464 handle_stop_backwards (it, it->prev_stop);
7466 else
7467 handle_stop_backwards (it, it->base_level_stop);
7468 return GET_NEXT_DISPLAY_ELEMENT (it);
7470 else
7472 /* No face changes, overlays etc. in sight, so just return a
7473 character from current_buffer. */
7474 unsigned char *p;
7475 EMACS_INT stop;
7477 /* Maybe run the redisplay end trigger hook. Performance note:
7478 This doesn't seem to cost measurable time. */
7479 if (it->redisplay_end_trigger_charpos
7480 && it->glyph_row
7481 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
7482 run_redisplay_end_trigger_hook (it);
7484 stop = it->bidi_it.scan_dir < 0 ? -1 : it->end_charpos;
7485 if (CHAR_COMPOSED_P (it, IT_CHARPOS (*it), IT_BYTEPOS (*it),
7486 stop)
7487 && next_element_from_composition (it))
7489 return 1;
7492 /* Get the next character, maybe multibyte. */
7493 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
7494 if (it->multibyte_p && !ASCII_BYTE_P (*p))
7495 it->c = STRING_CHAR_AND_LENGTH (p, it->len);
7496 else
7497 it->c = *p, it->len = 1;
7499 /* Record what we have and where it came from. */
7500 it->what = IT_CHARACTER;
7501 it->object = it->w->buffer;
7502 it->position = it->current.pos;
7504 /* Normally we return the character found above, except when we
7505 really want to return an ellipsis for selective display. */
7506 if (it->selective)
7508 if (it->c == '\n')
7510 /* A value of selective > 0 means hide lines indented more
7511 than that number of columns. */
7512 if (it->selective > 0
7513 && IT_CHARPOS (*it) + 1 < ZV
7514 && indented_beyond_p (IT_CHARPOS (*it) + 1,
7515 IT_BYTEPOS (*it) + 1,
7516 it->selective))
7518 success_p = next_element_from_ellipsis (it);
7519 it->dpvec_char_len = -1;
7522 else if (it->c == '\r' && it->selective == -1)
7524 /* A value of selective == -1 means that everything from the
7525 CR to the end of the line is invisible, with maybe an
7526 ellipsis displayed for it. */
7527 success_p = next_element_from_ellipsis (it);
7528 it->dpvec_char_len = -1;
7533 /* Value is zero if end of buffer reached. */
7534 xassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
7535 return success_p;
7539 /* Run the redisplay end trigger hook for IT. */
7541 static void
7542 run_redisplay_end_trigger_hook (struct it *it)
7544 Lisp_Object args[3];
7546 /* IT->glyph_row should be non-null, i.e. we should be actually
7547 displaying something, or otherwise we should not run the hook. */
7548 xassert (it->glyph_row);
7550 /* Set up hook arguments. */
7551 args[0] = Qredisplay_end_trigger_functions;
7552 args[1] = it->window;
7553 XSETINT (args[2], it->redisplay_end_trigger_charpos);
7554 it->redisplay_end_trigger_charpos = 0;
7556 /* Since we are *trying* to run these functions, don't try to run
7557 them again, even if they get an error. */
7558 it->w->redisplay_end_trigger = Qnil;
7559 Frun_hook_with_args (3, args);
7561 /* Notice if it changed the face of the character we are on. */
7562 handle_face_prop (it);
7566 /* Deliver a composition display element. Unlike the other
7567 next_element_from_XXX, this function is not registered in the array
7568 get_next_element[]. It is called from next_element_from_buffer and
7569 next_element_from_string when necessary. */
7571 static int
7572 next_element_from_composition (struct it *it)
7574 it->what = IT_COMPOSITION;
7575 it->len = it->cmp_it.nbytes;
7576 if (STRINGP (it->string))
7578 if (it->c < 0)
7580 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
7581 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
7582 return 0;
7584 it->position = it->current.string_pos;
7585 it->object = it->string;
7586 it->c = composition_update_it (&it->cmp_it, IT_STRING_CHARPOS (*it),
7587 IT_STRING_BYTEPOS (*it), it->string);
7589 else
7591 if (it->c < 0)
7593 IT_CHARPOS (*it) += it->cmp_it.nchars;
7594 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
7595 if (it->bidi_p)
7597 if (it->bidi_it.new_paragraph)
7598 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 0);
7599 /* Resync the bidi iterator with IT's new position.
7600 FIXME: this doesn't support bidirectional text. */
7601 while (it->bidi_it.charpos < IT_CHARPOS (*it))
7602 bidi_move_to_visually_next (&it->bidi_it);
7604 return 0;
7606 it->position = it->current.pos;
7607 it->object = it->w->buffer;
7608 it->c = composition_update_it (&it->cmp_it, IT_CHARPOS (*it),
7609 IT_BYTEPOS (*it), Qnil);
7611 return 1;
7616 /***********************************************************************
7617 Moving an iterator without producing glyphs
7618 ***********************************************************************/
7620 /* Check if iterator is at a position corresponding to a valid buffer
7621 position after some move_it_ call. */
7623 #define IT_POS_VALID_AFTER_MOVE_P(it) \
7624 ((it)->method == GET_FROM_STRING \
7625 ? IT_STRING_CHARPOS (*it) == 0 \
7626 : 1)
7629 /* Move iterator IT to a specified buffer or X position within one
7630 line on the display without producing glyphs.
7632 OP should be a bit mask including some or all of these bits:
7633 MOVE_TO_X: Stop upon reaching x-position TO_X.
7634 MOVE_TO_POS: Stop upon reaching buffer or string position TO_CHARPOS.
7635 Regardless of OP's value, stop upon reaching the end of the display line.
7637 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
7638 This means, in particular, that TO_X includes window's horizontal
7639 scroll amount.
7641 The return value has several possible values that
7642 say what condition caused the scan to stop:
7644 MOVE_POS_MATCH_OR_ZV
7645 - when TO_POS or ZV was reached.
7647 MOVE_X_REACHED
7648 -when TO_X was reached before TO_POS or ZV were reached.
7650 MOVE_LINE_CONTINUED
7651 - when we reached the end of the display area and the line must
7652 be continued.
7654 MOVE_LINE_TRUNCATED
7655 - when we reached the end of the display area and the line is
7656 truncated.
7658 MOVE_NEWLINE_OR_CR
7659 - when we stopped at a line end, i.e. a newline or a CR and selective
7660 display is on. */
7662 static enum move_it_result
7663 move_it_in_display_line_to (struct it *it,
7664 EMACS_INT to_charpos, int to_x,
7665 enum move_operation_enum op)
7667 enum move_it_result result = MOVE_UNDEFINED;
7668 struct glyph_row *saved_glyph_row;
7669 struct it wrap_it, atpos_it, atx_it, ppos_it;
7670 void *wrap_data = NULL, *atpos_data = NULL, *atx_data = NULL;
7671 void *ppos_data = NULL;
7672 int may_wrap = 0;
7673 enum it_method prev_method = it->method;
7674 EMACS_INT prev_pos = IT_CHARPOS (*it);
7675 int saw_smaller_pos = prev_pos < to_charpos;
7677 /* Don't produce glyphs in produce_glyphs. */
7678 saved_glyph_row = it->glyph_row;
7679 it->glyph_row = NULL;
7681 /* Use wrap_it to save a copy of IT wherever a word wrap could
7682 occur. Use atpos_it to save a copy of IT at the desired buffer
7683 position, if found, so that we can scan ahead and check if the
7684 word later overshoots the window edge. Use atx_it similarly, for
7685 pixel positions. */
7686 wrap_it.sp = -1;
7687 atpos_it.sp = -1;
7688 atx_it.sp = -1;
7690 /* Use ppos_it under bidi reordering to save a copy of IT for the
7691 position > CHARPOS that is the closest to CHARPOS. We restore
7692 that position in IT when we have scanned the entire display line
7693 without finding a match for CHARPOS and all the character
7694 positions are greater than CHARPOS. */
7695 if (it->bidi_p)
7697 SAVE_IT (ppos_it, *it, ppos_data);
7698 SET_TEXT_POS (ppos_it.current.pos, ZV, ZV_BYTE);
7699 if ((op & MOVE_TO_POS) && IT_CHARPOS (*it) >= to_charpos)
7700 SAVE_IT (ppos_it, *it, ppos_data);
7703 #define BUFFER_POS_REACHED_P() \
7704 ((op & MOVE_TO_POS) != 0 \
7705 && BUFFERP (it->object) \
7706 && (IT_CHARPOS (*it) == to_charpos \
7707 || (!it->bidi_p && IT_CHARPOS (*it) > to_charpos)) \
7708 && (it->method == GET_FROM_BUFFER \
7709 || (it->method == GET_FROM_DISPLAY_VECTOR \
7710 && it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
7712 /* If there's a line-/wrap-prefix, handle it. */
7713 if (it->hpos == 0 && it->method == GET_FROM_BUFFER
7714 && it->current_y < it->last_visible_y)
7715 handle_line_prefix (it);
7717 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
7718 SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it));
7720 while (1)
7722 int x, i, ascent = 0, descent = 0;
7724 /* Utility macro to reset an iterator with x, ascent, and descent. */
7725 #define IT_RESET_X_ASCENT_DESCENT(IT) \
7726 ((IT)->current_x = x, (IT)->max_ascent = ascent, \
7727 (IT)->max_descent = descent)
7729 /* Stop if we move beyond TO_CHARPOS (after an image or a
7730 display string or stretch glyph). */
7731 if ((op & MOVE_TO_POS) != 0
7732 && BUFFERP (it->object)
7733 && it->method == GET_FROM_BUFFER
7734 && ((!it->bidi_p && IT_CHARPOS (*it) > to_charpos)
7735 || (it->bidi_p
7736 && (prev_method == GET_FROM_IMAGE
7737 || prev_method == GET_FROM_STRETCH
7738 || prev_method == GET_FROM_STRING)
7739 /* Passed TO_CHARPOS from left to right. */
7740 && ((prev_pos < to_charpos
7741 && IT_CHARPOS (*it) > to_charpos)
7742 /* Passed TO_CHARPOS from right to left. */
7743 || (prev_pos > to_charpos
7744 && IT_CHARPOS (*it) < to_charpos)))))
7746 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
7748 result = MOVE_POS_MATCH_OR_ZV;
7749 break;
7751 else if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
7752 /* If wrap_it is valid, the current position might be in a
7753 word that is wrapped. So, save the iterator in
7754 atpos_it and continue to see if wrapping happens. */
7755 SAVE_IT (atpos_it, *it, atpos_data);
7758 /* Stop when ZV reached.
7759 We used to stop here when TO_CHARPOS reached as well, but that is
7760 too soon if this glyph does not fit on this line. So we handle it
7761 explicitly below. */
7762 if (!get_next_display_element (it))
7764 result = MOVE_POS_MATCH_OR_ZV;
7765 break;
7768 if (it->line_wrap == TRUNCATE)
7770 if (BUFFER_POS_REACHED_P ())
7772 result = MOVE_POS_MATCH_OR_ZV;
7773 break;
7776 else
7778 if (it->line_wrap == WORD_WRAP)
7780 if (IT_DISPLAYING_WHITESPACE (it))
7781 may_wrap = 1;
7782 else if (may_wrap)
7784 /* We have reached a glyph that follows one or more
7785 whitespace characters. If the position is
7786 already found, we are done. */
7787 if (atpos_it.sp >= 0)
7789 RESTORE_IT (it, &atpos_it, atpos_data);
7790 result = MOVE_POS_MATCH_OR_ZV;
7791 goto done;
7793 if (atx_it.sp >= 0)
7795 RESTORE_IT (it, &atx_it, atx_data);
7796 result = MOVE_X_REACHED;
7797 goto done;
7799 /* Otherwise, we can wrap here. */
7800 SAVE_IT (wrap_it, *it, wrap_data);
7801 may_wrap = 0;
7806 /* Remember the line height for the current line, in case
7807 the next element doesn't fit on the line. */
7808 ascent = it->max_ascent;
7809 descent = it->max_descent;
7811 /* The call to produce_glyphs will get the metrics of the
7812 display element IT is loaded with. Record the x-position
7813 before this display element, in case it doesn't fit on the
7814 line. */
7815 x = it->current_x;
7817 PRODUCE_GLYPHS (it);
7819 if (it->area != TEXT_AREA)
7821 prev_method = it->method;
7822 if (it->method == GET_FROM_BUFFER)
7823 prev_pos = IT_CHARPOS (*it);
7824 set_iterator_to_next (it, 1);
7825 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
7826 SET_TEXT_POS (this_line_min_pos,
7827 IT_CHARPOS (*it), IT_BYTEPOS (*it));
7828 if (it->bidi_p
7829 && (op & MOVE_TO_POS)
7830 && IT_CHARPOS (*it) > to_charpos
7831 && IT_CHARPOS (*it) < IT_CHARPOS (ppos_it))
7832 SAVE_IT (ppos_it, *it, ppos_data);
7833 continue;
7836 /* The number of glyphs we get back in IT->nglyphs will normally
7837 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
7838 character on a terminal frame, or (iii) a line end. For the
7839 second case, IT->nglyphs - 1 padding glyphs will be present.
7840 (On X frames, there is only one glyph produced for a
7841 composite character.)
7843 The behavior implemented below means, for continuation lines,
7844 that as many spaces of a TAB as fit on the current line are
7845 displayed there. For terminal frames, as many glyphs of a
7846 multi-glyph character are displayed in the current line, too.
7847 This is what the old redisplay code did, and we keep it that
7848 way. Under X, the whole shape of a complex character must
7849 fit on the line or it will be completely displayed in the
7850 next line.
7852 Note that both for tabs and padding glyphs, all glyphs have
7853 the same width. */
7854 if (it->nglyphs)
7856 /* More than one glyph or glyph doesn't fit on line. All
7857 glyphs have the same width. */
7858 int single_glyph_width = it->pixel_width / it->nglyphs;
7859 int new_x;
7860 int x_before_this_char = x;
7861 int hpos_before_this_char = it->hpos;
7863 for (i = 0; i < it->nglyphs; ++i, x = new_x)
7865 new_x = x + single_glyph_width;
7867 /* We want to leave anything reaching TO_X to the caller. */
7868 if ((op & MOVE_TO_X) && new_x > to_x)
7870 if (BUFFER_POS_REACHED_P ())
7872 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
7873 goto buffer_pos_reached;
7874 if (atpos_it.sp < 0)
7876 SAVE_IT (atpos_it, *it, atpos_data);
7877 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
7880 else
7882 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
7884 it->current_x = x;
7885 result = MOVE_X_REACHED;
7886 break;
7888 if (atx_it.sp < 0)
7890 SAVE_IT (atx_it, *it, atx_data);
7891 IT_RESET_X_ASCENT_DESCENT (&atx_it);
7896 if (/* Lines are continued. */
7897 it->line_wrap != TRUNCATE
7898 && (/* And glyph doesn't fit on the line. */
7899 new_x > it->last_visible_x
7900 /* Or it fits exactly and we're on a window
7901 system frame. */
7902 || (new_x == it->last_visible_x
7903 && FRAME_WINDOW_P (it->f))))
7905 if (/* IT->hpos == 0 means the very first glyph
7906 doesn't fit on the line, e.g. a wide image. */
7907 it->hpos == 0
7908 || (new_x == it->last_visible_x
7909 && FRAME_WINDOW_P (it->f)))
7911 ++it->hpos;
7912 it->current_x = new_x;
7914 /* The character's last glyph just barely fits
7915 in this row. */
7916 if (i == it->nglyphs - 1)
7918 /* If this is the destination position,
7919 return a position *before* it in this row,
7920 now that we know it fits in this row. */
7921 if (BUFFER_POS_REACHED_P ())
7923 if (it->line_wrap != WORD_WRAP
7924 || wrap_it.sp < 0)
7926 it->hpos = hpos_before_this_char;
7927 it->current_x = x_before_this_char;
7928 result = MOVE_POS_MATCH_OR_ZV;
7929 break;
7931 if (it->line_wrap == WORD_WRAP
7932 && atpos_it.sp < 0)
7934 SAVE_IT (atpos_it, *it, atpos_data);
7935 atpos_it.current_x = x_before_this_char;
7936 atpos_it.hpos = hpos_before_this_char;
7940 prev_method = it->method;
7941 if (it->method == GET_FROM_BUFFER)
7942 prev_pos = IT_CHARPOS (*it);
7943 set_iterator_to_next (it, 1);
7944 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
7945 SET_TEXT_POS (this_line_min_pos,
7946 IT_CHARPOS (*it), IT_BYTEPOS (*it));
7947 /* On graphical terminals, newlines may
7948 "overflow" into the fringe if
7949 overflow-newline-into-fringe is non-nil.
7950 On text-only terminals, newlines may
7951 overflow into the last glyph on the
7952 display line.*/
7953 if (!FRAME_WINDOW_P (it->f)
7954 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
7956 if (!get_next_display_element (it))
7958 result = MOVE_POS_MATCH_OR_ZV;
7959 break;
7961 if (BUFFER_POS_REACHED_P ())
7963 if (ITERATOR_AT_END_OF_LINE_P (it))
7964 result = MOVE_POS_MATCH_OR_ZV;
7965 else
7966 result = MOVE_LINE_CONTINUED;
7967 break;
7969 if (ITERATOR_AT_END_OF_LINE_P (it))
7971 result = MOVE_NEWLINE_OR_CR;
7972 break;
7977 else
7978 IT_RESET_X_ASCENT_DESCENT (it);
7980 if (wrap_it.sp >= 0)
7982 RESTORE_IT (it, &wrap_it, wrap_data);
7983 atpos_it.sp = -1;
7984 atx_it.sp = -1;
7987 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
7988 IT_CHARPOS (*it)));
7989 result = MOVE_LINE_CONTINUED;
7990 break;
7993 if (BUFFER_POS_REACHED_P ())
7995 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
7996 goto buffer_pos_reached;
7997 if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
7999 SAVE_IT (atpos_it, *it, atpos_data);
8000 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
8004 if (new_x > it->first_visible_x)
8006 /* Glyph is visible. Increment number of glyphs that
8007 would be displayed. */
8008 ++it->hpos;
8012 if (result != MOVE_UNDEFINED)
8013 break;
8015 else if (BUFFER_POS_REACHED_P ())
8017 buffer_pos_reached:
8018 IT_RESET_X_ASCENT_DESCENT (it);
8019 result = MOVE_POS_MATCH_OR_ZV;
8020 break;
8022 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
8024 /* Stop when TO_X specified and reached. This check is
8025 necessary here because of lines consisting of a line end,
8026 only. The line end will not produce any glyphs and we
8027 would never get MOVE_X_REACHED. */
8028 xassert (it->nglyphs == 0);
8029 result = MOVE_X_REACHED;
8030 break;
8033 /* Is this a line end? If yes, we're done. */
8034 if (ITERATOR_AT_END_OF_LINE_P (it))
8036 /* If we are past TO_CHARPOS, but never saw any character
8037 positions smaller than TO_CHARPOS, return
8038 MOVE_POS_MATCH_OR_ZV, like the unidirectional display
8039 did. */
8040 if ((op & MOVE_TO_POS) != 0
8041 && !saw_smaller_pos
8042 && IT_CHARPOS (*it) > to_charpos)
8044 result = MOVE_POS_MATCH_OR_ZV;
8045 if (it->bidi_p && IT_CHARPOS (ppos_it) < ZV)
8046 RESTORE_IT (it, &ppos_it, ppos_data);
8048 else
8049 result = MOVE_NEWLINE_OR_CR;
8050 break;
8053 prev_method = it->method;
8054 if (it->method == GET_FROM_BUFFER)
8055 prev_pos = IT_CHARPOS (*it);
8056 /* The current display element has been consumed. Advance
8057 to the next. */
8058 set_iterator_to_next (it, 1);
8059 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8060 SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it));
8061 if (IT_CHARPOS (*it) < to_charpos)
8062 saw_smaller_pos = 1;
8063 if (it->bidi_p
8064 && (op & MOVE_TO_POS)
8065 && IT_CHARPOS (*it) >= to_charpos
8066 && IT_CHARPOS (*it) < IT_CHARPOS (ppos_it))
8067 SAVE_IT (ppos_it, *it, ppos_data);
8069 /* Stop if lines are truncated and IT's current x-position is
8070 past the right edge of the window now. */
8071 if (it->line_wrap == TRUNCATE
8072 && it->current_x >= it->last_visible_x)
8074 if (!FRAME_WINDOW_P (it->f)
8075 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
8077 int at_eob_p = 0;
8079 if ((at_eob_p = !get_next_display_element (it))
8080 || BUFFER_POS_REACHED_P ()
8081 /* If we are past TO_CHARPOS, but never saw any
8082 character positions smaller than TO_CHARPOS,
8083 return MOVE_POS_MATCH_OR_ZV, like the
8084 unidirectional display did. */
8085 || ((op & MOVE_TO_POS) != 0
8086 && !saw_smaller_pos
8087 && IT_CHARPOS (*it) > to_charpos))
8089 result = MOVE_POS_MATCH_OR_ZV;
8090 if (it->bidi_p && !at_eob_p && IT_CHARPOS (ppos_it) < ZV)
8091 RESTORE_IT (it, &ppos_it, ppos_data);
8092 break;
8094 if (ITERATOR_AT_END_OF_LINE_P (it))
8096 result = MOVE_NEWLINE_OR_CR;
8097 break;
8100 else if ((op & MOVE_TO_POS) != 0
8101 && !saw_smaller_pos
8102 && IT_CHARPOS (*it) > to_charpos)
8104 result = MOVE_POS_MATCH_OR_ZV;
8105 if (it->bidi_p && IT_CHARPOS (ppos_it) < ZV)
8106 RESTORE_IT (it, &ppos_it, ppos_data);
8107 break;
8109 result = MOVE_LINE_TRUNCATED;
8110 break;
8112 #undef IT_RESET_X_ASCENT_DESCENT
8115 #undef BUFFER_POS_REACHED_P
8117 /* If we scanned beyond to_pos and didn't find a point to wrap at,
8118 restore the saved iterator. */
8119 if (atpos_it.sp >= 0)
8120 RESTORE_IT (it, &atpos_it, atpos_data);
8121 else if (atx_it.sp >= 0)
8122 RESTORE_IT (it, &atx_it, atx_data);
8124 done:
8126 if (atpos_data)
8127 xfree (atpos_data);
8128 if (atx_data)
8129 xfree (atx_data);
8130 if (wrap_data)
8131 xfree (wrap_data);
8132 if (ppos_data)
8133 xfree (ppos_data);
8135 /* Restore the iterator settings altered at the beginning of this
8136 function. */
8137 it->glyph_row = saved_glyph_row;
8138 return result;
8141 /* For external use. */
8142 void
8143 move_it_in_display_line (struct it *it,
8144 EMACS_INT to_charpos, int to_x,
8145 enum move_operation_enum op)
8147 if (it->line_wrap == WORD_WRAP
8148 && (op & MOVE_TO_X))
8150 struct it save_it;
8151 void *save_data = NULL;
8152 int skip;
8154 SAVE_IT (save_it, *it, save_data);
8155 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
8156 /* When word-wrap is on, TO_X may lie past the end
8157 of a wrapped line. Then it->current is the
8158 character on the next line, so backtrack to the
8159 space before the wrap point. */
8160 if (skip == MOVE_LINE_CONTINUED)
8162 int prev_x = max (it->current_x - 1, 0);
8163 RESTORE_IT (it, &save_it, save_data);
8164 move_it_in_display_line_to
8165 (it, -1, prev_x, MOVE_TO_X);
8167 else
8168 xfree (save_data);
8170 else
8171 move_it_in_display_line_to (it, to_charpos, to_x, op);
8175 /* Move IT forward until it satisfies one or more of the criteria in
8176 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
8178 OP is a bit-mask that specifies where to stop, and in particular,
8179 which of those four position arguments makes a difference. See the
8180 description of enum move_operation_enum.
8182 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
8183 screen line, this function will set IT to the next position that is
8184 displayed to the right of TO_CHARPOS on the screen. */
8186 void
8187 move_it_to (struct it *it, EMACS_INT to_charpos, int to_x, int to_y, int to_vpos, int op)
8189 enum move_it_result skip, skip2 = MOVE_X_REACHED;
8190 int line_height, line_start_x = 0, reached = 0;
8191 void *backup_data = NULL;
8193 for (;;)
8195 if (op & MOVE_TO_VPOS)
8197 /* If no TO_CHARPOS and no TO_X specified, stop at the
8198 start of the line TO_VPOS. */
8199 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
8201 if (it->vpos == to_vpos)
8203 reached = 1;
8204 break;
8206 else
8207 skip = move_it_in_display_line_to (it, -1, -1, 0);
8209 else
8211 /* TO_VPOS >= 0 means stop at TO_X in the line at
8212 TO_VPOS, or at TO_POS, whichever comes first. */
8213 if (it->vpos == to_vpos)
8215 reached = 2;
8216 break;
8219 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
8221 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
8223 reached = 3;
8224 break;
8226 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
8228 /* We have reached TO_X but not in the line we want. */
8229 skip = move_it_in_display_line_to (it, to_charpos,
8230 -1, MOVE_TO_POS);
8231 if (skip == MOVE_POS_MATCH_OR_ZV)
8233 reached = 4;
8234 break;
8239 else if (op & MOVE_TO_Y)
8241 struct it it_backup;
8243 if (it->line_wrap == WORD_WRAP)
8244 SAVE_IT (it_backup, *it, backup_data);
8246 /* TO_Y specified means stop at TO_X in the line containing
8247 TO_Y---or at TO_CHARPOS if this is reached first. The
8248 problem is that we can't really tell whether the line
8249 contains TO_Y before we have completely scanned it, and
8250 this may skip past TO_X. What we do is to first scan to
8251 TO_X.
8253 If TO_X is not specified, use a TO_X of zero. The reason
8254 is to make the outcome of this function more predictable.
8255 If we didn't use TO_X == 0, we would stop at the end of
8256 the line which is probably not what a caller would expect
8257 to happen. */
8258 skip = move_it_in_display_line_to
8259 (it, to_charpos, ((op & MOVE_TO_X) ? to_x : 0),
8260 (MOVE_TO_X | (op & MOVE_TO_POS)));
8262 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
8263 if (skip == MOVE_POS_MATCH_OR_ZV)
8264 reached = 5;
8265 else if (skip == MOVE_X_REACHED)
8267 /* If TO_X was reached, we want to know whether TO_Y is
8268 in the line. We know this is the case if the already
8269 scanned glyphs make the line tall enough. Otherwise,
8270 we must check by scanning the rest of the line. */
8271 line_height = it->max_ascent + it->max_descent;
8272 if (to_y >= it->current_y
8273 && to_y < it->current_y + line_height)
8275 reached = 6;
8276 break;
8278 SAVE_IT (it_backup, *it, backup_data);
8279 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
8280 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
8281 op & MOVE_TO_POS);
8282 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
8283 line_height = it->max_ascent + it->max_descent;
8284 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
8286 if (to_y >= it->current_y
8287 && to_y < it->current_y + line_height)
8289 /* If TO_Y is in this line and TO_X was reached
8290 above, we scanned too far. We have to restore
8291 IT's settings to the ones before skipping. */
8292 RESTORE_IT (it, &it_backup, backup_data);
8293 reached = 6;
8295 else
8297 skip = skip2;
8298 if (skip == MOVE_POS_MATCH_OR_ZV)
8299 reached = 7;
8302 else
8304 /* Check whether TO_Y is in this line. */
8305 line_height = it->max_ascent + it->max_descent;
8306 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
8308 if (to_y >= it->current_y
8309 && to_y < it->current_y + line_height)
8311 /* When word-wrap is on, TO_X may lie past the end
8312 of a wrapped line. Then it->current is the
8313 character on the next line, so backtrack to the
8314 space before the wrap point. */
8315 if (skip == MOVE_LINE_CONTINUED
8316 && it->line_wrap == WORD_WRAP)
8318 int prev_x = max (it->current_x - 1, 0);
8319 RESTORE_IT (it, &it_backup, backup_data);
8320 skip = move_it_in_display_line_to
8321 (it, -1, prev_x, MOVE_TO_X);
8323 reached = 6;
8327 if (reached)
8328 break;
8330 else if (BUFFERP (it->object)
8331 && (it->method == GET_FROM_BUFFER
8332 || it->method == GET_FROM_STRETCH)
8333 && IT_CHARPOS (*it) >= to_charpos)
8334 skip = MOVE_POS_MATCH_OR_ZV;
8335 else
8336 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
8338 switch (skip)
8340 case MOVE_POS_MATCH_OR_ZV:
8341 reached = 8;
8342 goto out;
8344 case MOVE_NEWLINE_OR_CR:
8345 set_iterator_to_next (it, 1);
8346 it->continuation_lines_width = 0;
8347 break;
8349 case MOVE_LINE_TRUNCATED:
8350 it->continuation_lines_width = 0;
8351 reseat_at_next_visible_line_start (it, 0);
8352 if ((op & MOVE_TO_POS) != 0
8353 && IT_CHARPOS (*it) > to_charpos)
8355 reached = 9;
8356 goto out;
8358 break;
8360 case MOVE_LINE_CONTINUED:
8361 /* For continued lines ending in a tab, some of the glyphs
8362 associated with the tab are displayed on the current
8363 line. Since it->current_x does not include these glyphs,
8364 we use it->last_visible_x instead. */
8365 if (it->c == '\t')
8367 it->continuation_lines_width += it->last_visible_x;
8368 /* When moving by vpos, ensure that the iterator really
8369 advances to the next line (bug#847, bug#969). Fixme:
8370 do we need to do this in other circumstances? */
8371 if (it->current_x != it->last_visible_x
8372 && (op & MOVE_TO_VPOS)
8373 && !(op & (MOVE_TO_X | MOVE_TO_POS)))
8375 line_start_x = it->current_x + it->pixel_width
8376 - it->last_visible_x;
8377 set_iterator_to_next (it, 0);
8380 else
8381 it->continuation_lines_width += it->current_x;
8382 break;
8384 default:
8385 abort ();
8388 /* Reset/increment for the next run. */
8389 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
8390 it->current_x = line_start_x;
8391 line_start_x = 0;
8392 it->hpos = 0;
8393 it->current_y += it->max_ascent + it->max_descent;
8394 ++it->vpos;
8395 last_height = it->max_ascent + it->max_descent;
8396 last_max_ascent = it->max_ascent;
8397 it->max_ascent = it->max_descent = 0;
8400 out:
8402 /* On text terminals, we may stop at the end of a line in the middle
8403 of a multi-character glyph. If the glyph itself is continued,
8404 i.e. it is actually displayed on the next line, don't treat this
8405 stopping point as valid; move to the next line instead (unless
8406 that brings us offscreen). */
8407 if (!FRAME_WINDOW_P (it->f)
8408 && op & MOVE_TO_POS
8409 && IT_CHARPOS (*it) == to_charpos
8410 && it->what == IT_CHARACTER
8411 && it->nglyphs > 1
8412 && it->line_wrap == WINDOW_WRAP
8413 && it->current_x == it->last_visible_x - 1
8414 && it->c != '\n'
8415 && it->c != '\t'
8416 && it->vpos < XFASTINT (it->w->window_end_vpos))
8418 it->continuation_lines_width += it->current_x;
8419 it->current_x = it->hpos = it->max_ascent = it->max_descent = 0;
8420 it->current_y += it->max_ascent + it->max_descent;
8421 ++it->vpos;
8422 last_height = it->max_ascent + it->max_descent;
8423 last_max_ascent = it->max_ascent;
8426 if (backup_data)
8427 xfree (backup_data);
8429 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
8433 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
8435 If DY > 0, move IT backward at least that many pixels. DY = 0
8436 means move IT backward to the preceding line start or BEGV. This
8437 function may move over more than DY pixels if IT->current_y - DY
8438 ends up in the middle of a line; in this case IT->current_y will be
8439 set to the top of the line moved to. */
8441 void
8442 move_it_vertically_backward (struct it *it, int dy)
8444 int nlines, h;
8445 struct it it2, it3;
8446 void *it2data = NULL, *it3data = NULL;
8447 EMACS_INT start_pos;
8449 move_further_back:
8450 xassert (dy >= 0);
8452 start_pos = IT_CHARPOS (*it);
8454 /* Estimate how many newlines we must move back. */
8455 nlines = max (1, dy / FRAME_LINE_HEIGHT (it->f));
8457 /* Set the iterator's position that many lines back. */
8458 while (nlines-- && IT_CHARPOS (*it) > BEGV)
8459 back_to_previous_visible_line_start (it);
8461 /* Reseat the iterator here. When moving backward, we don't want
8462 reseat to skip forward over invisible text, set up the iterator
8463 to deliver from overlay strings at the new position etc. So,
8464 use reseat_1 here. */
8465 reseat_1 (it, it->current.pos, 1);
8467 /* We are now surely at a line start. */
8468 it->current_x = it->hpos = 0;
8469 it->continuation_lines_width = 0;
8471 /* Move forward and see what y-distance we moved. First move to the
8472 start of the next line so that we get its height. We need this
8473 height to be able to tell whether we reached the specified
8474 y-distance. */
8475 SAVE_IT (it2, *it, it2data);
8476 it2.max_ascent = it2.max_descent = 0;
8479 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
8480 MOVE_TO_POS | MOVE_TO_VPOS);
8482 while (!IT_POS_VALID_AFTER_MOVE_P (&it2));
8483 xassert (IT_CHARPOS (*it) >= BEGV);
8484 SAVE_IT (it3, it2, it3data);
8486 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
8487 xassert (IT_CHARPOS (*it) >= BEGV);
8488 /* H is the actual vertical distance from the position in *IT
8489 and the starting position. */
8490 h = it2.current_y - it->current_y;
8491 /* NLINES is the distance in number of lines. */
8492 nlines = it2.vpos - it->vpos;
8494 /* Correct IT's y and vpos position
8495 so that they are relative to the starting point. */
8496 it->vpos -= nlines;
8497 it->current_y -= h;
8499 if (dy == 0)
8501 /* DY == 0 means move to the start of the screen line. The
8502 value of nlines is > 0 if continuation lines were involved. */
8503 RESTORE_IT (it, it, it2data);
8504 if (nlines > 0)
8505 move_it_by_lines (it, nlines);
8506 xfree (it3data);
8508 else
8510 /* The y-position we try to reach, relative to *IT.
8511 Note that H has been subtracted in front of the if-statement. */
8512 int target_y = it->current_y + h - dy;
8513 int y0 = it3.current_y;
8514 int y1;
8515 int line_height;
8517 RESTORE_IT (&it3, &it3, it3data);
8518 y1 = line_bottom_y (&it3);
8519 line_height = y1 - y0;
8520 RESTORE_IT (it, it, it2data);
8521 /* If we did not reach target_y, try to move further backward if
8522 we can. If we moved too far backward, try to move forward. */
8523 if (target_y < it->current_y
8524 /* This is heuristic. In a window that's 3 lines high, with
8525 a line height of 13 pixels each, recentering with point
8526 on the bottom line will try to move -39/2 = 19 pixels
8527 backward. Try to avoid moving into the first line. */
8528 && (it->current_y - target_y
8529 > min (window_box_height (it->w), line_height * 2 / 3))
8530 && IT_CHARPOS (*it) > BEGV)
8532 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
8533 target_y - it->current_y));
8534 dy = it->current_y - target_y;
8535 goto move_further_back;
8537 else if (target_y >= it->current_y + line_height
8538 && IT_CHARPOS (*it) < ZV)
8540 /* Should move forward by at least one line, maybe more.
8542 Note: Calling move_it_by_lines can be expensive on
8543 terminal frames, where compute_motion is used (via
8544 vmotion) to do the job, when there are very long lines
8545 and truncate-lines is nil. That's the reason for
8546 treating terminal frames specially here. */
8548 if (!FRAME_WINDOW_P (it->f))
8549 move_it_vertically (it, target_y - (it->current_y + line_height));
8550 else
8554 move_it_by_lines (it, 1);
8556 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
8563 /* Move IT by a specified amount of pixel lines DY. DY negative means
8564 move backwards. DY = 0 means move to start of screen line. At the
8565 end, IT will be on the start of a screen line. */
8567 void
8568 move_it_vertically (struct it *it, int dy)
8570 if (dy <= 0)
8571 move_it_vertically_backward (it, -dy);
8572 else
8574 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
8575 move_it_to (it, ZV, -1, it->current_y + dy, -1,
8576 MOVE_TO_POS | MOVE_TO_Y);
8577 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
8579 /* If buffer ends in ZV without a newline, move to the start of
8580 the line to satisfy the post-condition. */
8581 if (IT_CHARPOS (*it) == ZV
8582 && ZV > BEGV
8583 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
8584 move_it_by_lines (it, 0);
8589 /* Move iterator IT past the end of the text line it is in. */
8591 void
8592 move_it_past_eol (struct it *it)
8594 enum move_it_result rc;
8596 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
8597 if (rc == MOVE_NEWLINE_OR_CR)
8598 set_iterator_to_next (it, 0);
8602 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
8603 negative means move up. DVPOS == 0 means move to the start of the
8604 screen line.
8606 Optimization idea: If we would know that IT->f doesn't use
8607 a face with proportional font, we could be faster for
8608 truncate-lines nil. */
8610 void
8611 move_it_by_lines (struct it *it, int dvpos)
8614 /* The commented-out optimization uses vmotion on terminals. This
8615 gives bad results, because elements like it->what, on which
8616 callers such as pos_visible_p rely, aren't updated. */
8617 /* struct position pos;
8618 if (!FRAME_WINDOW_P (it->f))
8620 struct text_pos textpos;
8622 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
8623 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
8624 reseat (it, textpos, 1);
8625 it->vpos += pos.vpos;
8626 it->current_y += pos.vpos;
8628 else */
8630 if (dvpos == 0)
8632 /* DVPOS == 0 means move to the start of the screen line. */
8633 move_it_vertically_backward (it, 0);
8634 xassert (it->current_x == 0 && it->hpos == 0);
8635 /* Let next call to line_bottom_y calculate real line height */
8636 last_height = 0;
8638 else if (dvpos > 0)
8640 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
8641 if (!IT_POS_VALID_AFTER_MOVE_P (it))
8642 move_it_to (it, IT_CHARPOS (*it) + 1, -1, -1, -1, MOVE_TO_POS);
8644 else
8646 struct it it2;
8647 void *it2data = NULL;
8648 EMACS_INT start_charpos, i;
8650 /* Start at the beginning of the screen line containing IT's
8651 position. This may actually move vertically backwards,
8652 in case of overlays, so adjust dvpos accordingly. */
8653 dvpos += it->vpos;
8654 move_it_vertically_backward (it, 0);
8655 dvpos -= it->vpos;
8657 /* Go back -DVPOS visible lines and reseat the iterator there. */
8658 start_charpos = IT_CHARPOS (*it);
8659 for (i = -dvpos; i > 0 && IT_CHARPOS (*it) > BEGV; --i)
8660 back_to_previous_visible_line_start (it);
8661 reseat (it, it->current.pos, 1);
8663 /* Move further back if we end up in a string or an image. */
8664 while (!IT_POS_VALID_AFTER_MOVE_P (it))
8666 /* First try to move to start of display line. */
8667 dvpos += it->vpos;
8668 move_it_vertically_backward (it, 0);
8669 dvpos -= it->vpos;
8670 if (IT_POS_VALID_AFTER_MOVE_P (it))
8671 break;
8672 /* If start of line is still in string or image,
8673 move further back. */
8674 back_to_previous_visible_line_start (it);
8675 reseat (it, it->current.pos, 1);
8676 dvpos--;
8679 it->current_x = it->hpos = 0;
8681 /* Above call may have moved too far if continuation lines
8682 are involved. Scan forward and see if it did. */
8683 SAVE_IT (it2, *it, it2data);
8684 it2.vpos = it2.current_y = 0;
8685 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
8686 it->vpos -= it2.vpos;
8687 it->current_y -= it2.current_y;
8688 it->current_x = it->hpos = 0;
8690 /* If we moved too far back, move IT some lines forward. */
8691 if (it2.vpos > -dvpos)
8693 int delta = it2.vpos + dvpos;
8695 RESTORE_IT (&it2, &it2, it2data);
8696 SAVE_IT (it2, *it, it2data);
8697 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
8698 /* Move back again if we got too far ahead. */
8699 if (IT_CHARPOS (*it) >= start_charpos)
8700 RESTORE_IT (it, &it2, it2data);
8701 else
8702 xfree (it2data);
8704 else
8705 RESTORE_IT (it, it, it2data);
8709 /* Return 1 if IT points into the middle of a display vector. */
8712 in_display_vector_p (struct it *it)
8714 return (it->method == GET_FROM_DISPLAY_VECTOR
8715 && it->current.dpvec_index > 0
8716 && it->dpvec + it->current.dpvec_index != it->dpend);
8720 /***********************************************************************
8721 Messages
8722 ***********************************************************************/
8725 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
8726 to *Messages*. */
8728 void
8729 add_to_log (const char *format, Lisp_Object arg1, Lisp_Object arg2)
8731 Lisp_Object args[3];
8732 Lisp_Object msg, fmt;
8733 char *buffer;
8734 EMACS_INT len;
8735 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
8736 USE_SAFE_ALLOCA;
8738 /* Do nothing if called asynchronously. Inserting text into
8739 a buffer may call after-change-functions and alike and
8740 that would means running Lisp asynchronously. */
8741 if (handling_signal)
8742 return;
8744 fmt = msg = Qnil;
8745 GCPRO4 (fmt, msg, arg1, arg2);
8747 args[0] = fmt = build_string (format);
8748 args[1] = arg1;
8749 args[2] = arg2;
8750 msg = Fformat (3, args);
8752 len = SBYTES (msg) + 1;
8753 SAFE_ALLOCA (buffer, char *, len);
8754 memcpy (buffer, SDATA (msg), len);
8756 message_dolog (buffer, len - 1, 1, 0);
8757 SAFE_FREE ();
8759 UNGCPRO;
8763 /* Output a newline in the *Messages* buffer if "needs" one. */
8765 void
8766 message_log_maybe_newline (void)
8768 if (message_log_need_newline)
8769 message_dolog ("", 0, 1, 0);
8773 /* Add a string M of length NBYTES to the message log, optionally
8774 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
8775 nonzero, means interpret the contents of M as multibyte. This
8776 function calls low-level routines in order to bypass text property
8777 hooks, etc. which might not be safe to run.
8779 This may GC (insert may run before/after change hooks),
8780 so the buffer M must NOT point to a Lisp string. */
8782 void
8783 message_dolog (const char *m, EMACS_INT nbytes, int nlflag, int multibyte)
8785 const unsigned char *msg = (const unsigned char *) m;
8787 if (!NILP (Vmemory_full))
8788 return;
8790 if (!NILP (Vmessage_log_max))
8792 struct buffer *oldbuf;
8793 Lisp_Object oldpoint, oldbegv, oldzv;
8794 int old_windows_or_buffers_changed = windows_or_buffers_changed;
8795 EMACS_INT point_at_end = 0;
8796 EMACS_INT zv_at_end = 0;
8797 Lisp_Object old_deactivate_mark, tem;
8798 struct gcpro gcpro1;
8800 old_deactivate_mark = Vdeactivate_mark;
8801 oldbuf = current_buffer;
8802 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
8803 BVAR (current_buffer, undo_list) = Qt;
8805 oldpoint = message_dolog_marker1;
8806 set_marker_restricted (oldpoint, make_number (PT), Qnil);
8807 oldbegv = message_dolog_marker2;
8808 set_marker_restricted (oldbegv, make_number (BEGV), Qnil);
8809 oldzv = message_dolog_marker3;
8810 set_marker_restricted (oldzv, make_number (ZV), Qnil);
8811 GCPRO1 (old_deactivate_mark);
8813 if (PT == Z)
8814 point_at_end = 1;
8815 if (ZV == Z)
8816 zv_at_end = 1;
8818 BEGV = BEG;
8819 BEGV_BYTE = BEG_BYTE;
8820 ZV = Z;
8821 ZV_BYTE = Z_BYTE;
8822 TEMP_SET_PT_BOTH (Z, Z_BYTE);
8824 /* Insert the string--maybe converting multibyte to single byte
8825 or vice versa, so that all the text fits the buffer. */
8826 if (multibyte
8827 && NILP (BVAR (current_buffer, enable_multibyte_characters)))
8829 EMACS_INT i;
8830 int c, char_bytes;
8831 char work[1];
8833 /* Convert a multibyte string to single-byte
8834 for the *Message* buffer. */
8835 for (i = 0; i < nbytes; i += char_bytes)
8837 c = string_char_and_length (msg + i, &char_bytes);
8838 work[0] = (ASCII_CHAR_P (c)
8840 : multibyte_char_to_unibyte (c));
8841 insert_1_both (work, 1, 1, 1, 0, 0);
8844 else if (! multibyte
8845 && ! NILP (BVAR (current_buffer, enable_multibyte_characters)))
8847 EMACS_INT i;
8848 int c, char_bytes;
8849 unsigned char str[MAX_MULTIBYTE_LENGTH];
8850 /* Convert a single-byte string to multibyte
8851 for the *Message* buffer. */
8852 for (i = 0; i < nbytes; i++)
8854 c = msg[i];
8855 MAKE_CHAR_MULTIBYTE (c);
8856 char_bytes = CHAR_STRING (c, str);
8857 insert_1_both ((char *) str, 1, char_bytes, 1, 0, 0);
8860 else if (nbytes)
8861 insert_1 (m, nbytes, 1, 0, 0);
8863 if (nlflag)
8865 EMACS_INT this_bol, this_bol_byte, prev_bol, prev_bol_byte;
8866 printmax_t dups;
8867 insert_1 ("\n", 1, 1, 0, 0);
8869 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
8870 this_bol = PT;
8871 this_bol_byte = PT_BYTE;
8873 /* See if this line duplicates the previous one.
8874 If so, combine duplicates. */
8875 if (this_bol > BEG)
8877 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
8878 prev_bol = PT;
8879 prev_bol_byte = PT_BYTE;
8881 dups = message_log_check_duplicate (prev_bol_byte,
8882 this_bol_byte);
8883 if (dups)
8885 del_range_both (prev_bol, prev_bol_byte,
8886 this_bol, this_bol_byte, 0);
8887 if (dups > 1)
8889 char dupstr[sizeof " [ times]"
8890 + INT_STRLEN_BOUND (printmax_t)];
8891 int duplen;
8893 /* If you change this format, don't forget to also
8894 change message_log_check_duplicate. */
8895 sprintf (dupstr, " [%"pMd" times]", dups);
8896 duplen = strlen (dupstr);
8897 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
8898 insert_1 (dupstr, duplen, 1, 0, 1);
8903 /* If we have more than the desired maximum number of lines
8904 in the *Messages* buffer now, delete the oldest ones.
8905 This is safe because we don't have undo in this buffer. */
8907 if (NATNUMP (Vmessage_log_max))
8909 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
8910 -XFASTINT (Vmessage_log_max) - 1, 0);
8911 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
8914 BEGV = XMARKER (oldbegv)->charpos;
8915 BEGV_BYTE = marker_byte_position (oldbegv);
8917 if (zv_at_end)
8919 ZV = Z;
8920 ZV_BYTE = Z_BYTE;
8922 else
8924 ZV = XMARKER (oldzv)->charpos;
8925 ZV_BYTE = marker_byte_position (oldzv);
8928 if (point_at_end)
8929 TEMP_SET_PT_BOTH (Z, Z_BYTE);
8930 else
8931 /* We can't do Fgoto_char (oldpoint) because it will run some
8932 Lisp code. */
8933 TEMP_SET_PT_BOTH (XMARKER (oldpoint)->charpos,
8934 XMARKER (oldpoint)->bytepos);
8936 UNGCPRO;
8937 unchain_marker (XMARKER (oldpoint));
8938 unchain_marker (XMARKER (oldbegv));
8939 unchain_marker (XMARKER (oldzv));
8941 tem = Fget_buffer_window (Fcurrent_buffer (), Qt);
8942 set_buffer_internal (oldbuf);
8943 if (NILP (tem))
8944 windows_or_buffers_changed = old_windows_or_buffers_changed;
8945 message_log_need_newline = !nlflag;
8946 Vdeactivate_mark = old_deactivate_mark;
8951 /* We are at the end of the buffer after just having inserted a newline.
8952 (Note: We depend on the fact we won't be crossing the gap.)
8953 Check to see if the most recent message looks a lot like the previous one.
8954 Return 0 if different, 1 if the new one should just replace it, or a
8955 value N > 1 if we should also append " [N times]". */
8957 static intmax_t
8958 message_log_check_duplicate (EMACS_INT prev_bol_byte, EMACS_INT this_bol_byte)
8960 EMACS_INT i;
8961 EMACS_INT len = Z_BYTE - 1 - this_bol_byte;
8962 int seen_dots = 0;
8963 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
8964 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
8966 for (i = 0; i < len; i++)
8968 if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.')
8969 seen_dots = 1;
8970 if (p1[i] != p2[i])
8971 return seen_dots;
8973 p1 += len;
8974 if (*p1 == '\n')
8975 return 2;
8976 if (*p1++ == ' ' && *p1++ == '[')
8978 char *pend;
8979 intmax_t n = strtoimax ((char *) p1, &pend, 10);
8980 if (0 < n && n < INTMAX_MAX && strncmp (pend, " times]\n", 8) == 0)
8981 return n+1;
8983 return 0;
8987 /* Display an echo area message M with a specified length of NBYTES
8988 bytes. The string may include null characters. If M is 0, clear
8989 out any existing message, and let the mini-buffer text show
8990 through.
8992 This may GC, so the buffer M must NOT point to a Lisp string. */
8994 void
8995 message2 (const char *m, EMACS_INT nbytes, int multibyte)
8997 /* First flush out any partial line written with print. */
8998 message_log_maybe_newline ();
8999 if (m)
9000 message_dolog (m, nbytes, 1, multibyte);
9001 message2_nolog (m, nbytes, multibyte);
9005 /* The non-logging counterpart of message2. */
9007 void
9008 message2_nolog (const char *m, EMACS_INT nbytes, int multibyte)
9010 struct frame *sf = SELECTED_FRAME ();
9011 message_enable_multibyte = multibyte;
9013 if (FRAME_INITIAL_P (sf))
9015 if (noninteractive_need_newline)
9016 putc ('\n', stderr);
9017 noninteractive_need_newline = 0;
9018 if (m)
9019 fwrite (m, nbytes, 1, stderr);
9020 if (cursor_in_echo_area == 0)
9021 fprintf (stderr, "\n");
9022 fflush (stderr);
9024 /* A null message buffer means that the frame hasn't really been
9025 initialized yet. Error messages get reported properly by
9026 cmd_error, so this must be just an informative message; toss it. */
9027 else if (INTERACTIVE
9028 && sf->glyphs_initialized_p
9029 && FRAME_MESSAGE_BUF (sf))
9031 Lisp_Object mini_window;
9032 struct frame *f;
9034 /* Get the frame containing the mini-buffer
9035 that the selected frame is using. */
9036 mini_window = FRAME_MINIBUF_WINDOW (sf);
9037 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
9039 FRAME_SAMPLE_VISIBILITY (f);
9040 if (FRAME_VISIBLE_P (sf)
9041 && ! FRAME_VISIBLE_P (f))
9042 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
9044 if (m)
9046 set_message (m, Qnil, nbytes, multibyte);
9047 if (minibuffer_auto_raise)
9048 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
9050 else
9051 clear_message (1, 1);
9053 do_pending_window_change (0);
9054 echo_area_display (1);
9055 do_pending_window_change (0);
9056 if (FRAME_TERMINAL (f)->frame_up_to_date_hook != 0 && ! gc_in_progress)
9057 (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
9062 /* Display an echo area message M with a specified length of NBYTES
9063 bytes. The string may include null characters. If M is not a
9064 string, clear out any existing message, and let the mini-buffer
9065 text show through.
9067 This function cancels echoing. */
9069 void
9070 message3 (Lisp_Object m, EMACS_INT nbytes, int multibyte)
9072 struct gcpro gcpro1;
9074 GCPRO1 (m);
9075 clear_message (1,1);
9076 cancel_echoing ();
9078 /* First flush out any partial line written with print. */
9079 message_log_maybe_newline ();
9080 if (STRINGP (m))
9082 char *buffer;
9083 USE_SAFE_ALLOCA;
9085 SAFE_ALLOCA (buffer, char *, nbytes);
9086 memcpy (buffer, SDATA (m), nbytes);
9087 message_dolog (buffer, nbytes, 1, multibyte);
9088 SAFE_FREE ();
9090 message3_nolog (m, nbytes, multibyte);
9092 UNGCPRO;
9096 /* The non-logging version of message3.
9097 This does not cancel echoing, because it is used for echoing.
9098 Perhaps we need to make a separate function for echoing
9099 and make this cancel echoing. */
9101 void
9102 message3_nolog (Lisp_Object m, EMACS_INT nbytes, int multibyte)
9104 struct frame *sf = SELECTED_FRAME ();
9105 message_enable_multibyte = multibyte;
9107 if (FRAME_INITIAL_P (sf))
9109 if (noninteractive_need_newline)
9110 putc ('\n', stderr);
9111 noninteractive_need_newline = 0;
9112 if (STRINGP (m))
9113 fwrite (SDATA (m), nbytes, 1, stderr);
9114 if (cursor_in_echo_area == 0)
9115 fprintf (stderr, "\n");
9116 fflush (stderr);
9118 /* A null message buffer means that the frame hasn't really been
9119 initialized yet. Error messages get reported properly by
9120 cmd_error, so this must be just an informative message; toss it. */
9121 else if (INTERACTIVE
9122 && sf->glyphs_initialized_p
9123 && FRAME_MESSAGE_BUF (sf))
9125 Lisp_Object mini_window;
9126 Lisp_Object frame;
9127 struct frame *f;
9129 /* Get the frame containing the mini-buffer
9130 that the selected frame is using. */
9131 mini_window = FRAME_MINIBUF_WINDOW (sf);
9132 frame = XWINDOW (mini_window)->frame;
9133 f = XFRAME (frame);
9135 FRAME_SAMPLE_VISIBILITY (f);
9136 if (FRAME_VISIBLE_P (sf)
9137 && !FRAME_VISIBLE_P (f))
9138 Fmake_frame_visible (frame);
9140 if (STRINGP (m) && SCHARS (m) > 0)
9142 set_message (NULL, m, nbytes, multibyte);
9143 if (minibuffer_auto_raise)
9144 Fraise_frame (frame);
9145 /* Assume we are not echoing.
9146 (If we are, echo_now will override this.) */
9147 echo_message_buffer = Qnil;
9149 else
9150 clear_message (1, 1);
9152 do_pending_window_change (0);
9153 echo_area_display (1);
9154 do_pending_window_change (0);
9155 if (FRAME_TERMINAL (f)->frame_up_to_date_hook != 0 && ! gc_in_progress)
9156 (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
9161 /* Display a null-terminated echo area message M. If M is 0, clear
9162 out any existing message, and let the mini-buffer text show through.
9164 The buffer M must continue to exist until after the echo area gets
9165 cleared or some other message gets displayed there. Do not pass
9166 text that is stored in a Lisp string. Do not pass text in a buffer
9167 that was alloca'd. */
9169 void
9170 message1 (const char *m)
9172 message2 (m, (m ? strlen (m) : 0), 0);
9176 /* The non-logging counterpart of message1. */
9178 void
9179 message1_nolog (const char *m)
9181 message2_nolog (m, (m ? strlen (m) : 0), 0);
9184 /* Display a message M which contains a single %s
9185 which gets replaced with STRING. */
9187 void
9188 message_with_string (const char *m, Lisp_Object string, int log)
9190 CHECK_STRING (string);
9192 if (noninteractive)
9194 if (m)
9196 if (noninteractive_need_newline)
9197 putc ('\n', stderr);
9198 noninteractive_need_newline = 0;
9199 fprintf (stderr, m, SDATA (string));
9200 if (!cursor_in_echo_area)
9201 fprintf (stderr, "\n");
9202 fflush (stderr);
9205 else if (INTERACTIVE)
9207 /* The frame whose minibuffer we're going to display the message on.
9208 It may be larger than the selected frame, so we need
9209 to use its buffer, not the selected frame's buffer. */
9210 Lisp_Object mini_window;
9211 struct frame *f, *sf = SELECTED_FRAME ();
9213 /* Get the frame containing the minibuffer
9214 that the selected frame is using. */
9215 mini_window = FRAME_MINIBUF_WINDOW (sf);
9216 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
9218 /* A null message buffer means that the frame hasn't really been
9219 initialized yet. Error messages get reported properly by
9220 cmd_error, so this must be just an informative message; toss it. */
9221 if (FRAME_MESSAGE_BUF (f))
9223 Lisp_Object args[2], msg;
9224 struct gcpro gcpro1, gcpro2;
9226 args[0] = build_string (m);
9227 args[1] = msg = string;
9228 GCPRO2 (args[0], msg);
9229 gcpro1.nvars = 2;
9231 msg = Fformat (2, args);
9233 if (log)
9234 message3 (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
9235 else
9236 message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
9238 UNGCPRO;
9240 /* Print should start at the beginning of the message
9241 buffer next time. */
9242 message_buf_print = 0;
9248 /* Dump an informative message to the minibuf. If M is 0, clear out
9249 any existing message, and let the mini-buffer text show through. */
9251 static void
9252 vmessage (const char *m, va_list ap)
9254 if (noninteractive)
9256 if (m)
9258 if (noninteractive_need_newline)
9259 putc ('\n', stderr);
9260 noninteractive_need_newline = 0;
9261 vfprintf (stderr, m, ap);
9262 if (cursor_in_echo_area == 0)
9263 fprintf (stderr, "\n");
9264 fflush (stderr);
9267 else if (INTERACTIVE)
9269 /* The frame whose mini-buffer we're going to display the message
9270 on. It may be larger than the selected frame, so we need to
9271 use its buffer, not the selected frame's buffer. */
9272 Lisp_Object mini_window;
9273 struct frame *f, *sf = SELECTED_FRAME ();
9275 /* Get the frame containing the mini-buffer
9276 that the selected frame is using. */
9277 mini_window = FRAME_MINIBUF_WINDOW (sf);
9278 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
9280 /* A null message buffer means that the frame hasn't really been
9281 initialized yet. Error messages get reported properly by
9282 cmd_error, so this must be just an informative message; toss
9283 it. */
9284 if (FRAME_MESSAGE_BUF (f))
9286 if (m)
9288 ptrdiff_t len;
9290 len = doprnt (FRAME_MESSAGE_BUF (f),
9291 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, ap);
9293 message2 (FRAME_MESSAGE_BUF (f), len, 0);
9295 else
9296 message1 (0);
9298 /* Print should start at the beginning of the message
9299 buffer next time. */
9300 message_buf_print = 0;
9305 void
9306 message (const char *m, ...)
9308 va_list ap;
9309 va_start (ap, m);
9310 vmessage (m, ap);
9311 va_end (ap);
9315 #if 0
9316 /* The non-logging version of message. */
9318 void
9319 message_nolog (const char *m, ...)
9321 Lisp_Object old_log_max;
9322 va_list ap;
9323 va_start (ap, m);
9324 old_log_max = Vmessage_log_max;
9325 Vmessage_log_max = Qnil;
9326 vmessage (m, ap);
9327 Vmessage_log_max = old_log_max;
9328 va_end (ap);
9330 #endif
9333 /* Display the current message in the current mini-buffer. This is
9334 only called from error handlers in process.c, and is not time
9335 critical. */
9337 void
9338 update_echo_area (void)
9340 if (!NILP (echo_area_buffer[0]))
9342 Lisp_Object string;
9343 string = Fcurrent_message ();
9344 message3 (string, SBYTES (string),
9345 !NILP (BVAR (current_buffer, enable_multibyte_characters)));
9350 /* Make sure echo area buffers in `echo_buffers' are live.
9351 If they aren't, make new ones. */
9353 static void
9354 ensure_echo_area_buffers (void)
9356 int i;
9358 for (i = 0; i < 2; ++i)
9359 if (!BUFFERP (echo_buffer[i])
9360 || NILP (BVAR (XBUFFER (echo_buffer[i]), name)))
9362 char name[30];
9363 Lisp_Object old_buffer;
9364 int j;
9366 old_buffer = echo_buffer[i];
9367 sprintf (name, " *Echo Area %d*", i);
9368 echo_buffer[i] = Fget_buffer_create (build_string (name));
9369 BVAR (XBUFFER (echo_buffer[i]), truncate_lines) = Qnil;
9370 /* to force word wrap in echo area -
9371 it was decided to postpone this*/
9372 /* XBUFFER (echo_buffer[i])->word_wrap = Qt; */
9374 for (j = 0; j < 2; ++j)
9375 if (EQ (old_buffer, echo_area_buffer[j]))
9376 echo_area_buffer[j] = echo_buffer[i];
9381 /* Call FN with args A1..A4 with either the current or last displayed
9382 echo_area_buffer as current buffer.
9384 WHICH zero means use the current message buffer
9385 echo_area_buffer[0]. If that is nil, choose a suitable buffer
9386 from echo_buffer[] and clear it.
9388 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
9389 suitable buffer from echo_buffer[] and clear it.
9391 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
9392 that the current message becomes the last displayed one, make
9393 choose a suitable buffer for echo_area_buffer[0], and clear it.
9395 Value is what FN returns. */
9397 static int
9398 with_echo_area_buffer (struct window *w, int which,
9399 int (*fn) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
9400 EMACS_INT a1, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4)
9402 Lisp_Object buffer;
9403 int this_one, the_other, clear_buffer_p, rc;
9404 int count = SPECPDL_INDEX ();
9406 /* If buffers aren't live, make new ones. */
9407 ensure_echo_area_buffers ();
9409 clear_buffer_p = 0;
9411 if (which == 0)
9412 this_one = 0, the_other = 1;
9413 else if (which > 0)
9414 this_one = 1, the_other = 0;
9415 else
9417 this_one = 0, the_other = 1;
9418 clear_buffer_p = 1;
9420 /* We need a fresh one in case the current echo buffer equals
9421 the one containing the last displayed echo area message. */
9422 if (!NILP (echo_area_buffer[this_one])
9423 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
9424 echo_area_buffer[this_one] = Qnil;
9427 /* Choose a suitable buffer from echo_buffer[] is we don't
9428 have one. */
9429 if (NILP (echo_area_buffer[this_one]))
9431 echo_area_buffer[this_one]
9432 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
9433 ? echo_buffer[the_other]
9434 : echo_buffer[this_one]);
9435 clear_buffer_p = 1;
9438 buffer = echo_area_buffer[this_one];
9440 /* Don't get confused by reusing the buffer used for echoing
9441 for a different purpose. */
9442 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
9443 cancel_echoing ();
9445 record_unwind_protect (unwind_with_echo_area_buffer,
9446 with_echo_area_buffer_unwind_data (w));
9448 /* Make the echo area buffer current. Note that for display
9449 purposes, it is not necessary that the displayed window's buffer
9450 == current_buffer, except for text property lookup. So, let's
9451 only set that buffer temporarily here without doing a full
9452 Fset_window_buffer. We must also change w->pointm, though,
9453 because otherwise an assertions in unshow_buffer fails, and Emacs
9454 aborts. */
9455 set_buffer_internal_1 (XBUFFER (buffer));
9456 if (w)
9458 w->buffer = buffer;
9459 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
9462 BVAR (current_buffer, undo_list) = Qt;
9463 BVAR (current_buffer, read_only) = Qnil;
9464 specbind (Qinhibit_read_only, Qt);
9465 specbind (Qinhibit_modification_hooks, Qt);
9467 if (clear_buffer_p && Z > BEG)
9468 del_range (BEG, Z);
9470 xassert (BEGV >= BEG);
9471 xassert (ZV <= Z && ZV >= BEGV);
9473 rc = fn (a1, a2, a3, a4);
9475 xassert (BEGV >= BEG);
9476 xassert (ZV <= Z && ZV >= BEGV);
9478 unbind_to (count, Qnil);
9479 return rc;
9483 /* Save state that should be preserved around the call to the function
9484 FN called in with_echo_area_buffer. */
9486 static Lisp_Object
9487 with_echo_area_buffer_unwind_data (struct window *w)
9489 int i = 0;
9490 Lisp_Object vector, tmp;
9492 /* Reduce consing by keeping one vector in
9493 Vwith_echo_area_save_vector. */
9494 vector = Vwith_echo_area_save_vector;
9495 Vwith_echo_area_save_vector = Qnil;
9497 if (NILP (vector))
9498 vector = Fmake_vector (make_number (7), Qnil);
9500 XSETBUFFER (tmp, current_buffer); ASET (vector, i, tmp); ++i;
9501 ASET (vector, i, Vdeactivate_mark); ++i;
9502 ASET (vector, i, make_number (windows_or_buffers_changed)); ++i;
9504 if (w)
9506 XSETWINDOW (tmp, w); ASET (vector, i, tmp); ++i;
9507 ASET (vector, i, w->buffer); ++i;
9508 ASET (vector, i, make_number (XMARKER (w->pointm)->charpos)); ++i;
9509 ASET (vector, i, make_number (XMARKER (w->pointm)->bytepos)); ++i;
9511 else
9513 int end = i + 4;
9514 for (; i < end; ++i)
9515 ASET (vector, i, Qnil);
9518 xassert (i == ASIZE (vector));
9519 return vector;
9523 /* Restore global state from VECTOR which was created by
9524 with_echo_area_buffer_unwind_data. */
9526 static Lisp_Object
9527 unwind_with_echo_area_buffer (Lisp_Object vector)
9529 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
9530 Vdeactivate_mark = AREF (vector, 1);
9531 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
9533 if (WINDOWP (AREF (vector, 3)))
9535 struct window *w;
9536 Lisp_Object buffer, charpos, bytepos;
9538 w = XWINDOW (AREF (vector, 3));
9539 buffer = AREF (vector, 4);
9540 charpos = AREF (vector, 5);
9541 bytepos = AREF (vector, 6);
9543 w->buffer = buffer;
9544 set_marker_both (w->pointm, buffer,
9545 XFASTINT (charpos), XFASTINT (bytepos));
9548 Vwith_echo_area_save_vector = vector;
9549 return Qnil;
9553 /* Set up the echo area for use by print functions. MULTIBYTE_P
9554 non-zero means we will print multibyte. */
9556 void
9557 setup_echo_area_for_printing (int multibyte_p)
9559 /* If we can't find an echo area any more, exit. */
9560 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
9561 Fkill_emacs (Qnil);
9563 ensure_echo_area_buffers ();
9565 if (!message_buf_print)
9567 /* A message has been output since the last time we printed.
9568 Choose a fresh echo area buffer. */
9569 if (EQ (echo_area_buffer[1], echo_buffer[0]))
9570 echo_area_buffer[0] = echo_buffer[1];
9571 else
9572 echo_area_buffer[0] = echo_buffer[0];
9574 /* Switch to that buffer and clear it. */
9575 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
9576 BVAR (current_buffer, truncate_lines) = Qnil;
9578 if (Z > BEG)
9580 int count = SPECPDL_INDEX ();
9581 specbind (Qinhibit_read_only, Qt);
9582 /* Note that undo recording is always disabled. */
9583 del_range (BEG, Z);
9584 unbind_to (count, Qnil);
9586 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
9588 /* Set up the buffer for the multibyteness we need. */
9589 if (multibyte_p
9590 != !NILP (BVAR (current_buffer, enable_multibyte_characters)))
9591 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
9593 /* Raise the frame containing the echo area. */
9594 if (minibuffer_auto_raise)
9596 struct frame *sf = SELECTED_FRAME ();
9597 Lisp_Object mini_window;
9598 mini_window = FRAME_MINIBUF_WINDOW (sf);
9599 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
9602 message_log_maybe_newline ();
9603 message_buf_print = 1;
9605 else
9607 if (NILP (echo_area_buffer[0]))
9609 if (EQ (echo_area_buffer[1], echo_buffer[0]))
9610 echo_area_buffer[0] = echo_buffer[1];
9611 else
9612 echo_area_buffer[0] = echo_buffer[0];
9615 if (current_buffer != XBUFFER (echo_area_buffer[0]))
9617 /* Someone switched buffers between print requests. */
9618 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
9619 BVAR (current_buffer, truncate_lines) = Qnil;
9625 /* Display an echo area message in window W. Value is non-zero if W's
9626 height is changed. If display_last_displayed_message_p is
9627 non-zero, display the message that was last displayed, otherwise
9628 display the current message. */
9630 static int
9631 display_echo_area (struct window *w)
9633 int i, no_message_p, window_height_changed_p, count;
9635 /* Temporarily disable garbage collections while displaying the echo
9636 area. This is done because a GC can print a message itself.
9637 That message would modify the echo area buffer's contents while a
9638 redisplay of the buffer is going on, and seriously confuse
9639 redisplay. */
9640 count = inhibit_garbage_collection ();
9642 /* If there is no message, we must call display_echo_area_1
9643 nevertheless because it resizes the window. But we will have to
9644 reset the echo_area_buffer in question to nil at the end because
9645 with_echo_area_buffer will sets it to an empty buffer. */
9646 i = display_last_displayed_message_p ? 1 : 0;
9647 no_message_p = NILP (echo_area_buffer[i]);
9649 window_height_changed_p
9650 = with_echo_area_buffer (w, display_last_displayed_message_p,
9651 display_echo_area_1,
9652 (intptr_t) w, Qnil, 0, 0);
9654 if (no_message_p)
9655 echo_area_buffer[i] = Qnil;
9657 unbind_to (count, Qnil);
9658 return window_height_changed_p;
9662 /* Helper for display_echo_area. Display the current buffer which
9663 contains the current echo area message in window W, a mini-window,
9664 a pointer to which is passed in A1. A2..A4 are currently not used.
9665 Change the height of W so that all of the message is displayed.
9666 Value is non-zero if height of W was changed. */
9668 static int
9669 display_echo_area_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4)
9671 intptr_t i1 = a1;
9672 struct window *w = (struct window *) i1;
9673 Lisp_Object window;
9674 struct text_pos start;
9675 int window_height_changed_p = 0;
9677 /* Do this before displaying, so that we have a large enough glyph
9678 matrix for the display. If we can't get enough space for the
9679 whole text, display the last N lines. That works by setting w->start. */
9680 window_height_changed_p = resize_mini_window (w, 0);
9682 /* Use the starting position chosen by resize_mini_window. */
9683 SET_TEXT_POS_FROM_MARKER (start, w->start);
9685 /* Display. */
9686 clear_glyph_matrix (w->desired_matrix);
9687 XSETWINDOW (window, w);
9688 try_window (window, start, 0);
9690 return window_height_changed_p;
9694 /* Resize the echo area window to exactly the size needed for the
9695 currently displayed message, if there is one. If a mini-buffer
9696 is active, don't shrink it. */
9698 void
9699 resize_echo_area_exactly (void)
9701 if (BUFFERP (echo_area_buffer[0])
9702 && WINDOWP (echo_area_window))
9704 struct window *w = XWINDOW (echo_area_window);
9705 int resized_p;
9706 Lisp_Object resize_exactly;
9708 if (minibuf_level == 0)
9709 resize_exactly = Qt;
9710 else
9711 resize_exactly = Qnil;
9713 resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
9714 (intptr_t) w, resize_exactly,
9715 0, 0);
9716 if (resized_p)
9718 ++windows_or_buffers_changed;
9719 ++update_mode_lines;
9720 redisplay_internal ();
9726 /* Callback function for with_echo_area_buffer, when used from
9727 resize_echo_area_exactly. A1 contains a pointer to the window to
9728 resize, EXACTLY non-nil means resize the mini-window exactly to the
9729 size of the text displayed. A3 and A4 are not used. Value is what
9730 resize_mini_window returns. */
9732 static int
9733 resize_mini_window_1 (EMACS_INT a1, Lisp_Object exactly, EMACS_INT a3, EMACS_INT a4)
9735 intptr_t i1 = a1;
9736 return resize_mini_window ((struct window *) i1, !NILP (exactly));
9740 /* Resize mini-window W to fit the size of its contents. EXACT_P
9741 means size the window exactly to the size needed. Otherwise, it's
9742 only enlarged until W's buffer is empty.
9744 Set W->start to the right place to begin display. If the whole
9745 contents fit, start at the beginning. Otherwise, start so as
9746 to make the end of the contents appear. This is particularly
9747 important for y-or-n-p, but seems desirable generally.
9749 Value is non-zero if the window height has been changed. */
9752 resize_mini_window (struct window *w, int exact_p)
9754 struct frame *f = XFRAME (w->frame);
9755 int window_height_changed_p = 0;
9757 xassert (MINI_WINDOW_P (w));
9759 /* By default, start display at the beginning. */
9760 set_marker_both (w->start, w->buffer,
9761 BUF_BEGV (XBUFFER (w->buffer)),
9762 BUF_BEGV_BYTE (XBUFFER (w->buffer)));
9764 /* Don't resize windows while redisplaying a window; it would
9765 confuse redisplay functions when the size of the window they are
9766 displaying changes from under them. Such a resizing can happen,
9767 for instance, when which-func prints a long message while
9768 we are running fontification-functions. We're running these
9769 functions with safe_call which binds inhibit-redisplay to t. */
9770 if (!NILP (Vinhibit_redisplay))
9771 return 0;
9773 /* Nil means don't try to resize. */
9774 if (NILP (Vresize_mini_windows)
9775 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
9776 return 0;
9778 if (!FRAME_MINIBUF_ONLY_P (f))
9780 struct it it;
9781 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
9782 int total_height = WINDOW_TOTAL_LINES (root) + WINDOW_TOTAL_LINES (w);
9783 int height, max_height;
9784 int unit = FRAME_LINE_HEIGHT (f);
9785 struct text_pos start;
9786 struct buffer *old_current_buffer = NULL;
9788 if (current_buffer != XBUFFER (w->buffer))
9790 old_current_buffer = current_buffer;
9791 set_buffer_internal (XBUFFER (w->buffer));
9794 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
9796 /* Compute the max. number of lines specified by the user. */
9797 if (FLOATP (Vmax_mini_window_height))
9798 max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_LINES (f);
9799 else if (INTEGERP (Vmax_mini_window_height))
9800 max_height = XINT (Vmax_mini_window_height);
9801 else
9802 max_height = total_height / 4;
9804 /* Correct that max. height if it's bogus. */
9805 max_height = max (1, max_height);
9806 max_height = min (total_height, max_height);
9808 /* Find out the height of the text in the window. */
9809 if (it.line_wrap == TRUNCATE)
9810 height = 1;
9811 else
9813 last_height = 0;
9814 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
9815 if (it.max_ascent == 0 && it.max_descent == 0)
9816 height = it.current_y + last_height;
9817 else
9818 height = it.current_y + it.max_ascent + it.max_descent;
9819 height -= min (it.extra_line_spacing, it.max_extra_line_spacing);
9820 height = (height + unit - 1) / unit;
9823 /* Compute a suitable window start. */
9824 if (height > max_height)
9826 height = max_height;
9827 init_iterator (&it, w, ZV, ZV_BYTE, NULL, DEFAULT_FACE_ID);
9828 move_it_vertically_backward (&it, (height - 1) * unit);
9829 start = it.current.pos;
9831 else
9832 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
9833 SET_MARKER_FROM_TEXT_POS (w->start, start);
9835 if (EQ (Vresize_mini_windows, Qgrow_only))
9837 /* Let it grow only, until we display an empty message, in which
9838 case the window shrinks again. */
9839 if (height > WINDOW_TOTAL_LINES (w))
9841 int old_height = WINDOW_TOTAL_LINES (w);
9842 freeze_window_starts (f, 1);
9843 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
9844 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
9846 else if (height < WINDOW_TOTAL_LINES (w)
9847 && (exact_p || BEGV == ZV))
9849 int old_height = WINDOW_TOTAL_LINES (w);
9850 freeze_window_starts (f, 0);
9851 shrink_mini_window (w);
9852 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
9855 else
9857 /* Always resize to exact size needed. */
9858 if (height > WINDOW_TOTAL_LINES (w))
9860 int old_height = WINDOW_TOTAL_LINES (w);
9861 freeze_window_starts (f, 1);
9862 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
9863 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
9865 else if (height < WINDOW_TOTAL_LINES (w))
9867 int old_height = WINDOW_TOTAL_LINES (w);
9868 freeze_window_starts (f, 0);
9869 shrink_mini_window (w);
9871 if (height)
9873 freeze_window_starts (f, 1);
9874 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
9877 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
9881 if (old_current_buffer)
9882 set_buffer_internal (old_current_buffer);
9885 return window_height_changed_p;
9889 /* Value is the current message, a string, or nil if there is no
9890 current message. */
9892 Lisp_Object
9893 current_message (void)
9895 Lisp_Object msg;
9897 if (!BUFFERP (echo_area_buffer[0]))
9898 msg = Qnil;
9899 else
9901 with_echo_area_buffer (0, 0, current_message_1,
9902 (intptr_t) &msg, Qnil, 0, 0);
9903 if (NILP (msg))
9904 echo_area_buffer[0] = Qnil;
9907 return msg;
9911 static int
9912 current_message_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4)
9914 intptr_t i1 = a1;
9915 Lisp_Object *msg = (Lisp_Object *) i1;
9917 if (Z > BEG)
9918 *msg = make_buffer_string (BEG, Z, 1);
9919 else
9920 *msg = Qnil;
9921 return 0;
9925 /* Push the current message on Vmessage_stack for later restauration
9926 by restore_message. Value is non-zero if the current message isn't
9927 empty. This is a relatively infrequent operation, so it's not
9928 worth optimizing. */
9931 push_message (void)
9933 Lisp_Object msg;
9934 msg = current_message ();
9935 Vmessage_stack = Fcons (msg, Vmessage_stack);
9936 return STRINGP (msg);
9940 /* Restore message display from the top of Vmessage_stack. */
9942 void
9943 restore_message (void)
9945 Lisp_Object msg;
9947 xassert (CONSP (Vmessage_stack));
9948 msg = XCAR (Vmessage_stack);
9949 if (STRINGP (msg))
9950 message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
9951 else
9952 message3_nolog (msg, 0, 0);
9956 /* Handler for record_unwind_protect calling pop_message. */
9958 Lisp_Object
9959 pop_message_unwind (Lisp_Object dummy)
9961 pop_message ();
9962 return Qnil;
9965 /* Pop the top-most entry off Vmessage_stack. */
9967 static void
9968 pop_message (void)
9970 xassert (CONSP (Vmessage_stack));
9971 Vmessage_stack = XCDR (Vmessage_stack);
9975 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
9976 exits. If the stack is not empty, we have a missing pop_message
9977 somewhere. */
9979 void
9980 check_message_stack (void)
9982 if (!NILP (Vmessage_stack))
9983 abort ();
9987 /* Truncate to NCHARS what will be displayed in the echo area the next
9988 time we display it---but don't redisplay it now. */
9990 void
9991 truncate_echo_area (EMACS_INT nchars)
9993 if (nchars == 0)
9994 echo_area_buffer[0] = Qnil;
9995 /* A null message buffer means that the frame hasn't really been
9996 initialized yet. Error messages get reported properly by
9997 cmd_error, so this must be just an informative message; toss it. */
9998 else if (!noninteractive
9999 && INTERACTIVE
10000 && !NILP (echo_area_buffer[0]))
10002 struct frame *sf = SELECTED_FRAME ();
10003 if (FRAME_MESSAGE_BUF (sf))
10004 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil, 0, 0);
10009 /* Helper function for truncate_echo_area. Truncate the current
10010 message to at most NCHARS characters. */
10012 static int
10013 truncate_message_1 (EMACS_INT nchars, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4)
10015 if (BEG + nchars < Z)
10016 del_range (BEG + nchars, Z);
10017 if (Z == BEG)
10018 echo_area_buffer[0] = Qnil;
10019 return 0;
10023 /* Set the current message to a substring of S or STRING.
10025 If STRING is a Lisp string, set the message to the first NBYTES
10026 bytes from STRING. NBYTES zero means use the whole string. If
10027 STRING is multibyte, the message will be displayed multibyte.
10029 If S is not null, set the message to the first LEN bytes of S. LEN
10030 zero means use the whole string. MULTIBYTE_P non-zero means S is
10031 multibyte. Display the message multibyte in that case.
10033 Doesn't GC, as with_echo_area_buffer binds Qinhibit_modification_hooks
10034 to t before calling set_message_1 (which calls insert).
10037 static void
10038 set_message (const char *s, Lisp_Object string,
10039 EMACS_INT nbytes, int multibyte_p)
10041 message_enable_multibyte
10042 = ((s && multibyte_p)
10043 || (STRINGP (string) && STRING_MULTIBYTE (string)));
10045 with_echo_area_buffer (0, -1, set_message_1,
10046 (intptr_t) s, string, nbytes, multibyte_p);
10047 message_buf_print = 0;
10048 help_echo_showing_p = 0;
10052 /* Helper function for set_message. Arguments have the same meaning
10053 as there, with A1 corresponding to S and A2 corresponding to STRING
10054 This function is called with the echo area buffer being
10055 current. */
10057 static int
10058 set_message_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT nbytes, EMACS_INT multibyte_p)
10060 intptr_t i1 = a1;
10061 const char *s = (const char *) i1;
10062 const unsigned char *msg = (const unsigned char *) s;
10063 Lisp_Object string = a2;
10065 /* Change multibyteness of the echo buffer appropriately. */
10066 if (message_enable_multibyte
10067 != !NILP (BVAR (current_buffer, enable_multibyte_characters)))
10068 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
10070 BVAR (current_buffer, truncate_lines) = message_truncate_lines ? Qt : Qnil;
10071 if (!NILP (BVAR (current_buffer, bidi_display_reordering)))
10072 BVAR (current_buffer, bidi_paragraph_direction) = Qleft_to_right;
10074 /* Insert new message at BEG. */
10075 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
10077 if (STRINGP (string))
10079 EMACS_INT nchars;
10081 if (nbytes == 0)
10082 nbytes = SBYTES (string);
10083 nchars = string_byte_to_char (string, nbytes);
10085 /* This function takes care of single/multibyte conversion. We
10086 just have to ensure that the echo area buffer has the right
10087 setting of enable_multibyte_characters. */
10088 insert_from_string (string, 0, 0, nchars, nbytes, 1);
10090 else if (s)
10092 if (nbytes == 0)
10093 nbytes = strlen (s);
10095 if (multibyte_p && NILP (BVAR (current_buffer, enable_multibyte_characters)))
10097 /* Convert from multi-byte to single-byte. */
10098 EMACS_INT i;
10099 int c, n;
10100 char work[1];
10102 /* Convert a multibyte string to single-byte. */
10103 for (i = 0; i < nbytes; i += n)
10105 c = string_char_and_length (msg + i, &n);
10106 work[0] = (ASCII_CHAR_P (c)
10108 : multibyte_char_to_unibyte (c));
10109 insert_1_both (work, 1, 1, 1, 0, 0);
10112 else if (!multibyte_p
10113 && !NILP (BVAR (current_buffer, enable_multibyte_characters)))
10115 /* Convert from single-byte to multi-byte. */
10116 EMACS_INT i;
10117 int c, n;
10118 unsigned char str[MAX_MULTIBYTE_LENGTH];
10120 /* Convert a single-byte string to multibyte. */
10121 for (i = 0; i < nbytes; i++)
10123 c = msg[i];
10124 MAKE_CHAR_MULTIBYTE (c);
10125 n = CHAR_STRING (c, str);
10126 insert_1_both ((char *) str, 1, n, 1, 0, 0);
10129 else
10130 insert_1 (s, nbytes, 1, 0, 0);
10133 return 0;
10137 /* Clear messages. CURRENT_P non-zero means clear the current
10138 message. LAST_DISPLAYED_P non-zero means clear the message
10139 last displayed. */
10141 void
10142 clear_message (int current_p, int last_displayed_p)
10144 if (current_p)
10146 echo_area_buffer[0] = Qnil;
10147 message_cleared_p = 1;
10150 if (last_displayed_p)
10151 echo_area_buffer[1] = Qnil;
10153 message_buf_print = 0;
10156 /* Clear garbaged frames.
10158 This function is used where the old redisplay called
10159 redraw_garbaged_frames which in turn called redraw_frame which in
10160 turn called clear_frame. The call to clear_frame was a source of
10161 flickering. I believe a clear_frame is not necessary. It should
10162 suffice in the new redisplay to invalidate all current matrices,
10163 and ensure a complete redisplay of all windows. */
10165 static void
10166 clear_garbaged_frames (void)
10168 if (frame_garbaged)
10170 Lisp_Object tail, frame;
10171 int changed_count = 0;
10173 FOR_EACH_FRAME (tail, frame)
10175 struct frame *f = XFRAME (frame);
10177 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
10179 if (f->resized_p)
10181 Fredraw_frame (frame);
10182 f->force_flush_display_p = 1;
10184 clear_current_matrices (f);
10185 changed_count++;
10186 f->garbaged = 0;
10187 f->resized_p = 0;
10191 frame_garbaged = 0;
10192 if (changed_count)
10193 ++windows_or_buffers_changed;
10198 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
10199 is non-zero update selected_frame. Value is non-zero if the
10200 mini-windows height has been changed. */
10202 static int
10203 echo_area_display (int update_frame_p)
10205 Lisp_Object mini_window;
10206 struct window *w;
10207 struct frame *f;
10208 int window_height_changed_p = 0;
10209 struct frame *sf = SELECTED_FRAME ();
10211 mini_window = FRAME_MINIBUF_WINDOW (sf);
10212 w = XWINDOW (mini_window);
10213 f = XFRAME (WINDOW_FRAME (w));
10215 /* Don't display if frame is invisible or not yet initialized. */
10216 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
10217 return 0;
10219 #ifdef HAVE_WINDOW_SYSTEM
10220 /* When Emacs starts, selected_frame may be the initial terminal
10221 frame. If we let this through, a message would be displayed on
10222 the terminal. */
10223 if (FRAME_INITIAL_P (XFRAME (selected_frame)))
10224 return 0;
10225 #endif /* HAVE_WINDOW_SYSTEM */
10227 /* Redraw garbaged frames. */
10228 if (frame_garbaged)
10229 clear_garbaged_frames ();
10231 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
10233 echo_area_window = mini_window;
10234 window_height_changed_p = display_echo_area (w);
10235 w->must_be_updated_p = 1;
10237 /* Update the display, unless called from redisplay_internal.
10238 Also don't update the screen during redisplay itself. The
10239 update will happen at the end of redisplay, and an update
10240 here could cause confusion. */
10241 if (update_frame_p && !redisplaying_p)
10243 int n = 0;
10245 /* If the display update has been interrupted by pending
10246 input, update mode lines in the frame. Due to the
10247 pending input, it might have been that redisplay hasn't
10248 been called, so that mode lines above the echo area are
10249 garbaged. This looks odd, so we prevent it here. */
10250 if (!display_completed)
10251 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), 0);
10253 if (window_height_changed_p
10254 /* Don't do this if Emacs is shutting down. Redisplay
10255 needs to run hooks. */
10256 && !NILP (Vrun_hooks))
10258 /* Must update other windows. Likewise as in other
10259 cases, don't let this update be interrupted by
10260 pending input. */
10261 int count = SPECPDL_INDEX ();
10262 specbind (Qredisplay_dont_pause, Qt);
10263 windows_or_buffers_changed = 1;
10264 redisplay_internal ();
10265 unbind_to (count, Qnil);
10267 else if (FRAME_WINDOW_P (f) && n == 0)
10269 /* Window configuration is the same as before.
10270 Can do with a display update of the echo area,
10271 unless we displayed some mode lines. */
10272 update_single_window (w, 1);
10273 FRAME_RIF (f)->flush_display (f);
10275 else
10276 update_frame (f, 1, 1);
10278 /* If cursor is in the echo area, make sure that the next
10279 redisplay displays the minibuffer, so that the cursor will
10280 be replaced with what the minibuffer wants. */
10281 if (cursor_in_echo_area)
10282 ++windows_or_buffers_changed;
10285 else if (!EQ (mini_window, selected_window))
10286 windows_or_buffers_changed++;
10288 /* Last displayed message is now the current message. */
10289 echo_area_buffer[1] = echo_area_buffer[0];
10290 /* Inform read_char that we're not echoing. */
10291 echo_message_buffer = Qnil;
10293 /* Prevent redisplay optimization in redisplay_internal by resetting
10294 this_line_start_pos. This is done because the mini-buffer now
10295 displays the message instead of its buffer text. */
10296 if (EQ (mini_window, selected_window))
10297 CHARPOS (this_line_start_pos) = 0;
10299 return window_height_changed_p;
10304 /***********************************************************************
10305 Mode Lines and Frame Titles
10306 ***********************************************************************/
10308 /* A buffer for constructing non-propertized mode-line strings and
10309 frame titles in it; allocated from the heap in init_xdisp and
10310 resized as needed in store_mode_line_noprop_char. */
10312 static char *mode_line_noprop_buf;
10314 /* The buffer's end, and a current output position in it. */
10316 static char *mode_line_noprop_buf_end;
10317 static char *mode_line_noprop_ptr;
10319 #define MODE_LINE_NOPROP_LEN(start) \
10320 ((mode_line_noprop_ptr - mode_line_noprop_buf) - start)
10322 static enum {
10323 MODE_LINE_DISPLAY = 0,
10324 MODE_LINE_TITLE,
10325 MODE_LINE_NOPROP,
10326 MODE_LINE_STRING
10327 } mode_line_target;
10329 /* Alist that caches the results of :propertize.
10330 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
10331 static Lisp_Object mode_line_proptrans_alist;
10333 /* List of strings making up the mode-line. */
10334 static Lisp_Object mode_line_string_list;
10336 /* Base face property when building propertized mode line string. */
10337 static Lisp_Object mode_line_string_face;
10338 static Lisp_Object mode_line_string_face_prop;
10341 /* Unwind data for mode line strings */
10343 static Lisp_Object Vmode_line_unwind_vector;
10345 static Lisp_Object
10346 format_mode_line_unwind_data (struct buffer *obuf,
10347 Lisp_Object owin,
10348 int save_proptrans)
10350 Lisp_Object vector, tmp;
10352 /* Reduce consing by keeping one vector in
10353 Vwith_echo_area_save_vector. */
10354 vector = Vmode_line_unwind_vector;
10355 Vmode_line_unwind_vector = Qnil;
10357 if (NILP (vector))
10358 vector = Fmake_vector (make_number (8), Qnil);
10360 ASET (vector, 0, make_number (mode_line_target));
10361 ASET (vector, 1, make_number (MODE_LINE_NOPROP_LEN (0)));
10362 ASET (vector, 2, mode_line_string_list);
10363 ASET (vector, 3, save_proptrans ? mode_line_proptrans_alist : Qt);
10364 ASET (vector, 4, mode_line_string_face);
10365 ASET (vector, 5, mode_line_string_face_prop);
10367 if (obuf)
10368 XSETBUFFER (tmp, obuf);
10369 else
10370 tmp = Qnil;
10371 ASET (vector, 6, tmp);
10372 ASET (vector, 7, owin);
10374 return vector;
10377 static Lisp_Object
10378 unwind_format_mode_line (Lisp_Object vector)
10380 mode_line_target = XINT (AREF (vector, 0));
10381 mode_line_noprop_ptr = mode_line_noprop_buf + XINT (AREF (vector, 1));
10382 mode_line_string_list = AREF (vector, 2);
10383 if (! EQ (AREF (vector, 3), Qt))
10384 mode_line_proptrans_alist = AREF (vector, 3);
10385 mode_line_string_face = AREF (vector, 4);
10386 mode_line_string_face_prop = AREF (vector, 5);
10388 if (!NILP (AREF (vector, 7)))
10389 /* Select window before buffer, since it may change the buffer. */
10390 Fselect_window (AREF (vector, 7), Qt);
10392 if (!NILP (AREF (vector, 6)))
10394 set_buffer_internal_1 (XBUFFER (AREF (vector, 6)));
10395 ASET (vector, 6, Qnil);
10398 Vmode_line_unwind_vector = vector;
10399 return Qnil;
10403 /* Store a single character C for the frame title in mode_line_noprop_buf.
10404 Re-allocate mode_line_noprop_buf if necessary. */
10406 static void
10407 store_mode_line_noprop_char (char c)
10409 /* If output position has reached the end of the allocated buffer,
10410 double the buffer's size. */
10411 if (mode_line_noprop_ptr == mode_line_noprop_buf_end)
10413 int len = MODE_LINE_NOPROP_LEN (0);
10414 int new_size = 2 * len * sizeof *mode_line_noprop_buf;
10415 mode_line_noprop_buf = (char *) xrealloc (mode_line_noprop_buf, new_size);
10416 mode_line_noprop_buf_end = mode_line_noprop_buf + new_size;
10417 mode_line_noprop_ptr = mode_line_noprop_buf + len;
10420 *mode_line_noprop_ptr++ = c;
10424 /* Store part of a frame title in mode_line_noprop_buf, beginning at
10425 mode_line_noprop_ptr. STRING is the string to store. Do not copy
10426 characters that yield more columns than PRECISION; PRECISION <= 0
10427 means copy the whole string. Pad with spaces until FIELD_WIDTH
10428 number of characters have been copied; FIELD_WIDTH <= 0 means don't
10429 pad. Called from display_mode_element when it is used to build a
10430 frame title. */
10432 static int
10433 store_mode_line_noprop (const char *string, int field_width, int precision)
10435 const unsigned char *str = (const unsigned char *) string;
10436 int n = 0;
10437 EMACS_INT dummy, nbytes;
10439 /* Copy at most PRECISION chars from STR. */
10440 nbytes = strlen (string);
10441 n += c_string_width (str, nbytes, precision, &dummy, &nbytes);
10442 while (nbytes--)
10443 store_mode_line_noprop_char (*str++);
10445 /* Fill up with spaces until FIELD_WIDTH reached. */
10446 while (field_width > 0
10447 && n < field_width)
10449 store_mode_line_noprop_char (' ');
10450 ++n;
10453 return n;
10456 /***********************************************************************
10457 Frame Titles
10458 ***********************************************************************/
10460 #ifdef HAVE_WINDOW_SYSTEM
10462 /* Set the title of FRAME, if it has changed. The title format is
10463 Vicon_title_format if FRAME is iconified, otherwise it is
10464 frame_title_format. */
10466 static void
10467 x_consider_frame_title (Lisp_Object frame)
10469 struct frame *f = XFRAME (frame);
10471 if (FRAME_WINDOW_P (f)
10472 || FRAME_MINIBUF_ONLY_P (f)
10473 || f->explicit_name)
10475 /* Do we have more than one visible frame on this X display? */
10476 Lisp_Object tail;
10477 Lisp_Object fmt;
10478 int title_start;
10479 char *title;
10480 int len;
10481 struct it it;
10482 int count = SPECPDL_INDEX ();
10484 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
10486 Lisp_Object other_frame = XCAR (tail);
10487 struct frame *tf = XFRAME (other_frame);
10489 if (tf != f
10490 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
10491 && !FRAME_MINIBUF_ONLY_P (tf)
10492 && !EQ (other_frame, tip_frame)
10493 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
10494 break;
10497 /* Set global variable indicating that multiple frames exist. */
10498 multiple_frames = CONSP (tail);
10500 /* Switch to the buffer of selected window of the frame. Set up
10501 mode_line_target so that display_mode_element will output into
10502 mode_line_noprop_buf; then display the title. */
10503 record_unwind_protect (unwind_format_mode_line,
10504 format_mode_line_unwind_data
10505 (current_buffer, selected_window, 0));
10507 Fselect_window (f->selected_window, Qt);
10508 set_buffer_internal_1 (XBUFFER (XWINDOW (f->selected_window)->buffer));
10509 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
10511 mode_line_target = MODE_LINE_TITLE;
10512 title_start = MODE_LINE_NOPROP_LEN (0);
10513 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
10514 NULL, DEFAULT_FACE_ID);
10515 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
10516 len = MODE_LINE_NOPROP_LEN (title_start);
10517 title = mode_line_noprop_buf + title_start;
10518 unbind_to (count, Qnil);
10520 /* Set the title only if it's changed. This avoids consing in
10521 the common case where it hasn't. (If it turns out that we've
10522 already wasted too much time by walking through the list with
10523 display_mode_element, then we might need to optimize at a
10524 higher level than this.) */
10525 if (! STRINGP (f->name)
10526 || SBYTES (f->name) != len
10527 || memcmp (title, SDATA (f->name), len) != 0)
10528 x_implicitly_set_name (f, make_string (title, len), Qnil);
10532 #endif /* not HAVE_WINDOW_SYSTEM */
10537 /***********************************************************************
10538 Menu Bars
10539 ***********************************************************************/
10542 /* Prepare for redisplay by updating menu-bar item lists when
10543 appropriate. This can call eval. */
10545 void
10546 prepare_menu_bars (void)
10548 int all_windows;
10549 struct gcpro gcpro1, gcpro2;
10550 struct frame *f;
10551 Lisp_Object tooltip_frame;
10553 #ifdef HAVE_WINDOW_SYSTEM
10554 tooltip_frame = tip_frame;
10555 #else
10556 tooltip_frame = Qnil;
10557 #endif
10559 /* Update all frame titles based on their buffer names, etc. We do
10560 this before the menu bars so that the buffer-menu will show the
10561 up-to-date frame titles. */
10562 #ifdef HAVE_WINDOW_SYSTEM
10563 if (windows_or_buffers_changed || update_mode_lines)
10565 Lisp_Object tail, frame;
10567 FOR_EACH_FRAME (tail, frame)
10569 f = XFRAME (frame);
10570 if (!EQ (frame, tooltip_frame)
10571 && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)))
10572 x_consider_frame_title (frame);
10575 #endif /* HAVE_WINDOW_SYSTEM */
10577 /* Update the menu bar item lists, if appropriate. This has to be
10578 done before any actual redisplay or generation of display lines. */
10579 all_windows = (update_mode_lines
10580 || buffer_shared > 1
10581 || windows_or_buffers_changed);
10582 if (all_windows)
10584 Lisp_Object tail, frame;
10585 int count = SPECPDL_INDEX ();
10586 /* 1 means that update_menu_bar has run its hooks
10587 so any further calls to update_menu_bar shouldn't do so again. */
10588 int menu_bar_hooks_run = 0;
10590 record_unwind_save_match_data ();
10592 FOR_EACH_FRAME (tail, frame)
10594 f = XFRAME (frame);
10596 /* Ignore tooltip frame. */
10597 if (EQ (frame, tooltip_frame))
10598 continue;
10600 /* If a window on this frame changed size, report that to
10601 the user and clear the size-change flag. */
10602 if (FRAME_WINDOW_SIZES_CHANGED (f))
10604 Lisp_Object functions;
10606 /* Clear flag first in case we get an error below. */
10607 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
10608 functions = Vwindow_size_change_functions;
10609 GCPRO2 (tail, functions);
10611 while (CONSP (functions))
10613 if (!EQ (XCAR (functions), Qt))
10614 call1 (XCAR (functions), frame);
10615 functions = XCDR (functions);
10617 UNGCPRO;
10620 GCPRO1 (tail);
10621 menu_bar_hooks_run = update_menu_bar (f, 0, menu_bar_hooks_run);
10622 #ifdef HAVE_WINDOW_SYSTEM
10623 update_tool_bar (f, 0);
10624 #endif
10625 #ifdef HAVE_NS
10626 if (windows_or_buffers_changed
10627 && FRAME_NS_P (f))
10628 ns_set_doc_edited (f, Fbuffer_modified_p
10629 (XWINDOW (f->selected_window)->buffer));
10630 #endif
10631 UNGCPRO;
10634 unbind_to (count, Qnil);
10636 else
10638 struct frame *sf = SELECTED_FRAME ();
10639 update_menu_bar (sf, 1, 0);
10640 #ifdef HAVE_WINDOW_SYSTEM
10641 update_tool_bar (sf, 1);
10642 #endif
10647 /* Update the menu bar item list for frame F. This has to be done
10648 before we start to fill in any display lines, because it can call
10649 eval.
10651 If SAVE_MATCH_DATA is non-zero, we must save and restore it here.
10653 If HOOKS_RUN is 1, that means a previous call to update_menu_bar
10654 already ran the menu bar hooks for this redisplay, so there
10655 is no need to run them again. The return value is the
10656 updated value of this flag, to pass to the next call. */
10658 static int
10659 update_menu_bar (struct frame *f, int save_match_data, int hooks_run)
10661 Lisp_Object window;
10662 register struct window *w;
10664 /* If called recursively during a menu update, do nothing. This can
10665 happen when, for instance, an activate-menubar-hook causes a
10666 redisplay. */
10667 if (inhibit_menubar_update)
10668 return hooks_run;
10670 window = FRAME_SELECTED_WINDOW (f);
10671 w = XWINDOW (window);
10673 if (FRAME_WINDOW_P (f)
10675 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
10676 || defined (HAVE_NS) || defined (USE_GTK)
10677 FRAME_EXTERNAL_MENU_BAR (f)
10678 #else
10679 FRAME_MENU_BAR_LINES (f) > 0
10680 #endif
10681 : FRAME_MENU_BAR_LINES (f) > 0)
10683 /* If the user has switched buffers or windows, we need to
10684 recompute to reflect the new bindings. But we'll
10685 recompute when update_mode_lines is set too; that means
10686 that people can use force-mode-line-update to request
10687 that the menu bar be recomputed. The adverse effect on
10688 the rest of the redisplay algorithm is about the same as
10689 windows_or_buffers_changed anyway. */
10690 if (windows_or_buffers_changed
10691 /* This used to test w->update_mode_line, but we believe
10692 there is no need to recompute the menu in that case. */
10693 || update_mode_lines
10694 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
10695 < BUF_MODIFF (XBUFFER (w->buffer)))
10696 != !NILP (w->last_had_star))
10697 || ((!NILP (Vtransient_mark_mode)
10698 && !NILP (BVAR (XBUFFER (w->buffer), mark_active)))
10699 != !NILP (w->region_showing)))
10701 struct buffer *prev = current_buffer;
10702 int count = SPECPDL_INDEX ();
10704 specbind (Qinhibit_menubar_update, Qt);
10706 set_buffer_internal_1 (XBUFFER (w->buffer));
10707 if (save_match_data)
10708 record_unwind_save_match_data ();
10709 if (NILP (Voverriding_local_map_menu_flag))
10711 specbind (Qoverriding_terminal_local_map, Qnil);
10712 specbind (Qoverriding_local_map, Qnil);
10715 if (!hooks_run)
10717 /* Run the Lucid hook. */
10718 safe_run_hooks (Qactivate_menubar_hook);
10720 /* If it has changed current-menubar from previous value,
10721 really recompute the menu-bar from the value. */
10722 if (! NILP (Vlucid_menu_bar_dirty_flag))
10723 call0 (Qrecompute_lucid_menubar);
10725 safe_run_hooks (Qmenu_bar_update_hook);
10727 hooks_run = 1;
10730 XSETFRAME (Vmenu_updating_frame, f);
10731 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
10733 /* Redisplay the menu bar in case we changed it. */
10734 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
10735 || defined (HAVE_NS) || defined (USE_GTK)
10736 if (FRAME_WINDOW_P (f))
10738 #if defined (HAVE_NS)
10739 /* All frames on Mac OS share the same menubar. So only
10740 the selected frame should be allowed to set it. */
10741 if (f == SELECTED_FRAME ())
10742 #endif
10743 set_frame_menubar (f, 0, 0);
10745 else
10746 /* On a terminal screen, the menu bar is an ordinary screen
10747 line, and this makes it get updated. */
10748 w->update_mode_line = Qt;
10749 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
10750 /* In the non-toolkit version, the menu bar is an ordinary screen
10751 line, and this makes it get updated. */
10752 w->update_mode_line = Qt;
10753 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
10755 unbind_to (count, Qnil);
10756 set_buffer_internal_1 (prev);
10760 return hooks_run;
10765 /***********************************************************************
10766 Output Cursor
10767 ***********************************************************************/
10769 #ifdef HAVE_WINDOW_SYSTEM
10771 /* EXPORT:
10772 Nominal cursor position -- where to draw output.
10773 HPOS and VPOS are window relative glyph matrix coordinates.
10774 X and Y are window relative pixel coordinates. */
10776 struct cursor_pos output_cursor;
10779 /* EXPORT:
10780 Set the global variable output_cursor to CURSOR. All cursor
10781 positions are relative to updated_window. */
10783 void
10784 set_output_cursor (struct cursor_pos *cursor)
10786 output_cursor.hpos = cursor->hpos;
10787 output_cursor.vpos = cursor->vpos;
10788 output_cursor.x = cursor->x;
10789 output_cursor.y = cursor->y;
10793 /* EXPORT for RIF:
10794 Set a nominal cursor position.
10796 HPOS and VPOS are column/row positions in a window glyph matrix. X
10797 and Y are window text area relative pixel positions.
10799 If this is done during an update, updated_window will contain the
10800 window that is being updated and the position is the future output
10801 cursor position for that window. If updated_window is null, use
10802 selected_window and display the cursor at the given position. */
10804 void
10805 x_cursor_to (int vpos, int hpos, int y, int x)
10807 struct window *w;
10809 /* If updated_window is not set, work on selected_window. */
10810 if (updated_window)
10811 w = updated_window;
10812 else
10813 w = XWINDOW (selected_window);
10815 /* Set the output cursor. */
10816 output_cursor.hpos = hpos;
10817 output_cursor.vpos = vpos;
10818 output_cursor.x = x;
10819 output_cursor.y = y;
10821 /* If not called as part of an update, really display the cursor.
10822 This will also set the cursor position of W. */
10823 if (updated_window == NULL)
10825 BLOCK_INPUT;
10826 display_and_set_cursor (w, 1, hpos, vpos, x, y);
10827 if (FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
10828 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (SELECTED_FRAME ());
10829 UNBLOCK_INPUT;
10833 #endif /* HAVE_WINDOW_SYSTEM */
10836 /***********************************************************************
10837 Tool-bars
10838 ***********************************************************************/
10840 #ifdef HAVE_WINDOW_SYSTEM
10842 /* Where the mouse was last time we reported a mouse event. */
10844 FRAME_PTR last_mouse_frame;
10846 /* Tool-bar item index of the item on which a mouse button was pressed
10847 or -1. */
10849 int last_tool_bar_item;
10852 static Lisp_Object
10853 update_tool_bar_unwind (Lisp_Object frame)
10855 selected_frame = frame;
10856 return Qnil;
10859 /* Update the tool-bar item list for frame F. This has to be done
10860 before we start to fill in any display lines. Called from
10861 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
10862 and restore it here. */
10864 static void
10865 update_tool_bar (struct frame *f, int save_match_data)
10867 #if defined (USE_GTK) || defined (HAVE_NS)
10868 int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
10869 #else
10870 int do_update = WINDOWP (f->tool_bar_window)
10871 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0;
10872 #endif
10874 if (do_update)
10876 Lisp_Object window;
10877 struct window *w;
10879 window = FRAME_SELECTED_WINDOW (f);
10880 w = XWINDOW (window);
10882 /* If the user has switched buffers or windows, we need to
10883 recompute to reflect the new bindings. But we'll
10884 recompute when update_mode_lines is set too; that means
10885 that people can use force-mode-line-update to request
10886 that the menu bar be recomputed. The adverse effect on
10887 the rest of the redisplay algorithm is about the same as
10888 windows_or_buffers_changed anyway. */
10889 if (windows_or_buffers_changed
10890 || !NILP (w->update_mode_line)
10891 || update_mode_lines
10892 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
10893 < BUF_MODIFF (XBUFFER (w->buffer)))
10894 != !NILP (w->last_had_star))
10895 || ((!NILP (Vtransient_mark_mode)
10896 && !NILP (BVAR (XBUFFER (w->buffer), mark_active)))
10897 != !NILP (w->region_showing)))
10899 struct buffer *prev = current_buffer;
10900 int count = SPECPDL_INDEX ();
10901 Lisp_Object frame, new_tool_bar;
10902 int new_n_tool_bar;
10903 struct gcpro gcpro1;
10905 /* Set current_buffer to the buffer of the selected
10906 window of the frame, so that we get the right local
10907 keymaps. */
10908 set_buffer_internal_1 (XBUFFER (w->buffer));
10910 /* Save match data, if we must. */
10911 if (save_match_data)
10912 record_unwind_save_match_data ();
10914 /* Make sure that we don't accidentally use bogus keymaps. */
10915 if (NILP (Voverriding_local_map_menu_flag))
10917 specbind (Qoverriding_terminal_local_map, Qnil);
10918 specbind (Qoverriding_local_map, Qnil);
10921 GCPRO1 (new_tool_bar);
10923 /* We must temporarily set the selected frame to this frame
10924 before calling tool_bar_items, because the calculation of
10925 the tool-bar keymap uses the selected frame (see
10926 `tool-bar-make-keymap' in tool-bar.el). */
10927 record_unwind_protect (update_tool_bar_unwind, selected_frame);
10928 XSETFRAME (frame, f);
10929 selected_frame = frame;
10931 /* Build desired tool-bar items from keymaps. */
10932 new_tool_bar = tool_bar_items (Fcopy_sequence (f->tool_bar_items),
10933 &new_n_tool_bar);
10935 /* Redisplay the tool-bar if we changed it. */
10936 if (new_n_tool_bar != f->n_tool_bar_items
10937 || NILP (Fequal (new_tool_bar, f->tool_bar_items)))
10939 /* Redisplay that happens asynchronously due to an expose event
10940 may access f->tool_bar_items. Make sure we update both
10941 variables within BLOCK_INPUT so no such event interrupts. */
10942 BLOCK_INPUT;
10943 f->tool_bar_items = new_tool_bar;
10944 f->n_tool_bar_items = new_n_tool_bar;
10945 w->update_mode_line = Qt;
10946 UNBLOCK_INPUT;
10949 UNGCPRO;
10951 unbind_to (count, Qnil);
10952 set_buffer_internal_1 (prev);
10958 /* Set F->desired_tool_bar_string to a Lisp string representing frame
10959 F's desired tool-bar contents. F->tool_bar_items must have
10960 been set up previously by calling prepare_menu_bars. */
10962 static void
10963 build_desired_tool_bar_string (struct frame *f)
10965 int i, size, size_needed;
10966 struct gcpro gcpro1, gcpro2, gcpro3;
10967 Lisp_Object image, plist, props;
10969 image = plist = props = Qnil;
10970 GCPRO3 (image, plist, props);
10972 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
10973 Otherwise, make a new string. */
10975 /* The size of the string we might be able to reuse. */
10976 size = (STRINGP (f->desired_tool_bar_string)
10977 ? SCHARS (f->desired_tool_bar_string)
10978 : 0);
10980 /* We need one space in the string for each image. */
10981 size_needed = f->n_tool_bar_items;
10983 /* Reuse f->desired_tool_bar_string, if possible. */
10984 if (size < size_needed || NILP (f->desired_tool_bar_string))
10985 f->desired_tool_bar_string = Fmake_string (make_number (size_needed),
10986 make_number (' '));
10987 else
10989 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
10990 Fremove_text_properties (make_number (0), make_number (size),
10991 props, f->desired_tool_bar_string);
10994 /* Put a `display' property on the string for the images to display,
10995 put a `menu_item' property on tool-bar items with a value that
10996 is the index of the item in F's tool-bar item vector. */
10997 for (i = 0; i < f->n_tool_bar_items; ++i)
10999 #define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
11001 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
11002 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
11003 int hmargin, vmargin, relief, idx, end;
11005 /* If image is a vector, choose the image according to the
11006 button state. */
11007 image = PROP (TOOL_BAR_ITEM_IMAGES);
11008 if (VECTORP (image))
11010 if (enabled_p)
11011 idx = (selected_p
11012 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
11013 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
11014 else
11015 idx = (selected_p
11016 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
11017 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
11019 xassert (ASIZE (image) >= idx);
11020 image = AREF (image, idx);
11022 else
11023 idx = -1;
11025 /* Ignore invalid image specifications. */
11026 if (!valid_image_p (image))
11027 continue;
11029 /* Display the tool-bar button pressed, or depressed. */
11030 plist = Fcopy_sequence (XCDR (image));
11032 /* Compute margin and relief to draw. */
11033 relief = (tool_bar_button_relief >= 0
11034 ? tool_bar_button_relief
11035 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
11036 hmargin = vmargin = relief;
11038 if (INTEGERP (Vtool_bar_button_margin)
11039 && XINT (Vtool_bar_button_margin) > 0)
11041 hmargin += XFASTINT (Vtool_bar_button_margin);
11042 vmargin += XFASTINT (Vtool_bar_button_margin);
11044 else if (CONSP (Vtool_bar_button_margin))
11046 if (INTEGERP (XCAR (Vtool_bar_button_margin))
11047 && XINT (XCAR (Vtool_bar_button_margin)) > 0)
11048 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
11050 if (INTEGERP (XCDR (Vtool_bar_button_margin))
11051 && XINT (XCDR (Vtool_bar_button_margin)) > 0)
11052 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
11055 if (auto_raise_tool_bar_buttons_p)
11057 /* Add a `:relief' property to the image spec if the item is
11058 selected. */
11059 if (selected_p)
11061 plist = Fplist_put (plist, QCrelief, make_number (-relief));
11062 hmargin -= relief;
11063 vmargin -= relief;
11066 else
11068 /* If image is selected, display it pressed, i.e. with a
11069 negative relief. If it's not selected, display it with a
11070 raised relief. */
11071 plist = Fplist_put (plist, QCrelief,
11072 (selected_p
11073 ? make_number (-relief)
11074 : make_number (relief)));
11075 hmargin -= relief;
11076 vmargin -= relief;
11079 /* Put a margin around the image. */
11080 if (hmargin || vmargin)
11082 if (hmargin == vmargin)
11083 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
11084 else
11085 plist = Fplist_put (plist, QCmargin,
11086 Fcons (make_number (hmargin),
11087 make_number (vmargin)));
11090 /* If button is not enabled, and we don't have special images
11091 for the disabled state, make the image appear disabled by
11092 applying an appropriate algorithm to it. */
11093 if (!enabled_p && idx < 0)
11094 plist = Fplist_put (plist, QCconversion, Qdisabled);
11096 /* Put a `display' text property on the string for the image to
11097 display. Put a `menu-item' property on the string that gives
11098 the start of this item's properties in the tool-bar items
11099 vector. */
11100 image = Fcons (Qimage, plist);
11101 props = list4 (Qdisplay, image,
11102 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS));
11104 /* Let the last image hide all remaining spaces in the tool bar
11105 string. The string can be longer than needed when we reuse a
11106 previous string. */
11107 if (i + 1 == f->n_tool_bar_items)
11108 end = SCHARS (f->desired_tool_bar_string);
11109 else
11110 end = i + 1;
11111 Fadd_text_properties (make_number (i), make_number (end),
11112 props, f->desired_tool_bar_string);
11113 #undef PROP
11116 UNGCPRO;
11120 /* Display one line of the tool-bar of frame IT->f.
11122 HEIGHT specifies the desired height of the tool-bar line.
11123 If the actual height of the glyph row is less than HEIGHT, the
11124 row's height is increased to HEIGHT, and the icons are centered
11125 vertically in the new height.
11127 If HEIGHT is -1, we are counting needed tool-bar lines, so don't
11128 count a final empty row in case the tool-bar width exactly matches
11129 the window width.
11132 static void
11133 display_tool_bar_line (struct it *it, int height)
11135 struct glyph_row *row = it->glyph_row;
11136 int max_x = it->last_visible_x;
11137 struct glyph *last;
11139 prepare_desired_row (row);
11140 row->y = it->current_y;
11142 /* Note that this isn't made use of if the face hasn't a box,
11143 so there's no need to check the face here. */
11144 it->start_of_box_run_p = 1;
11146 while (it->current_x < max_x)
11148 int x, n_glyphs_before, i, nglyphs;
11149 struct it it_before;
11151 /* Get the next display element. */
11152 if (!get_next_display_element (it))
11154 /* Don't count empty row if we are counting needed tool-bar lines. */
11155 if (height < 0 && !it->hpos)
11156 return;
11157 break;
11160 /* Produce glyphs. */
11161 n_glyphs_before = row->used[TEXT_AREA];
11162 it_before = *it;
11164 PRODUCE_GLYPHS (it);
11166 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
11167 i = 0;
11168 x = it_before.current_x;
11169 while (i < nglyphs)
11171 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
11173 if (x + glyph->pixel_width > max_x)
11175 /* Glyph doesn't fit on line. Backtrack. */
11176 row->used[TEXT_AREA] = n_glyphs_before;
11177 *it = it_before;
11178 /* If this is the only glyph on this line, it will never fit on the
11179 tool-bar, so skip it. But ensure there is at least one glyph,
11180 so we don't accidentally disable the tool-bar. */
11181 if (n_glyphs_before == 0
11182 && (it->vpos > 0 || IT_STRING_CHARPOS (*it) < it->end_charpos-1))
11183 break;
11184 goto out;
11187 ++it->hpos;
11188 x += glyph->pixel_width;
11189 ++i;
11192 /* Stop at line end. */
11193 if (ITERATOR_AT_END_OF_LINE_P (it))
11194 break;
11196 set_iterator_to_next (it, 1);
11199 out:;
11201 row->displays_text_p = row->used[TEXT_AREA] != 0;
11203 /* Use default face for the border below the tool bar.
11205 FIXME: When auto-resize-tool-bars is grow-only, there is
11206 no additional border below the possibly empty tool-bar lines.
11207 So to make the extra empty lines look "normal", we have to
11208 use the tool-bar face for the border too. */
11209 if (!row->displays_text_p && !EQ (Vauto_resize_tool_bars, Qgrow_only))
11210 it->face_id = DEFAULT_FACE_ID;
11212 extend_face_to_end_of_line (it);
11213 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
11214 last->right_box_line_p = 1;
11215 if (last == row->glyphs[TEXT_AREA])
11216 last->left_box_line_p = 1;
11218 /* Make line the desired height and center it vertically. */
11219 if ((height -= it->max_ascent + it->max_descent) > 0)
11221 /* Don't add more than one line height. */
11222 height %= FRAME_LINE_HEIGHT (it->f);
11223 it->max_ascent += height / 2;
11224 it->max_descent += (height + 1) / 2;
11227 compute_line_metrics (it);
11229 /* If line is empty, make it occupy the rest of the tool-bar. */
11230 if (!row->displays_text_p)
11232 row->height = row->phys_height = it->last_visible_y - row->y;
11233 row->visible_height = row->height;
11234 row->ascent = row->phys_ascent = 0;
11235 row->extra_line_spacing = 0;
11238 row->full_width_p = 1;
11239 row->continued_p = 0;
11240 row->truncated_on_left_p = 0;
11241 row->truncated_on_right_p = 0;
11243 it->current_x = it->hpos = 0;
11244 it->current_y += row->height;
11245 ++it->vpos;
11246 ++it->glyph_row;
11250 /* Max tool-bar height. */
11252 #define MAX_FRAME_TOOL_BAR_HEIGHT(f) \
11253 ((FRAME_LINE_HEIGHT (f) * FRAME_LINES (f)))
11255 /* Value is the number of screen lines needed to make all tool-bar
11256 items of frame F visible. The number of actual rows needed is
11257 returned in *N_ROWS if non-NULL. */
11259 static int
11260 tool_bar_lines_needed (struct frame *f, int *n_rows)
11262 struct window *w = XWINDOW (f->tool_bar_window);
11263 struct it it;
11264 /* tool_bar_lines_needed is called from redisplay_tool_bar after building
11265 the desired matrix, so use (unused) mode-line row as temporary row to
11266 avoid destroying the first tool-bar row. */
11267 struct glyph_row *temp_row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
11269 /* Initialize an iterator for iteration over
11270 F->desired_tool_bar_string in the tool-bar window of frame F. */
11271 init_iterator (&it, w, -1, -1, temp_row, TOOL_BAR_FACE_ID);
11272 it.first_visible_x = 0;
11273 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
11274 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
11275 it.paragraph_embedding = L2R;
11277 while (!ITERATOR_AT_END_P (&it))
11279 clear_glyph_row (temp_row);
11280 it.glyph_row = temp_row;
11281 display_tool_bar_line (&it, -1);
11283 clear_glyph_row (temp_row);
11285 /* f->n_tool_bar_rows == 0 means "unknown"; -1 means no tool-bar. */
11286 if (n_rows)
11287 *n_rows = it.vpos > 0 ? it.vpos : -1;
11289 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
11293 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
11294 0, 1, 0,
11295 doc: /* Return the number of lines occupied by the tool bar of FRAME. */)
11296 (Lisp_Object frame)
11298 struct frame *f;
11299 struct window *w;
11300 int nlines = 0;
11302 if (NILP (frame))
11303 frame = selected_frame;
11304 else
11305 CHECK_FRAME (frame);
11306 f = XFRAME (frame);
11308 if (WINDOWP (f->tool_bar_window)
11309 && (w = XWINDOW (f->tool_bar_window),
11310 WINDOW_TOTAL_LINES (w) > 0))
11312 update_tool_bar (f, 1);
11313 if (f->n_tool_bar_items)
11315 build_desired_tool_bar_string (f);
11316 nlines = tool_bar_lines_needed (f, NULL);
11320 return make_number (nlines);
11324 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
11325 height should be changed. */
11327 static int
11328 redisplay_tool_bar (struct frame *f)
11330 struct window *w;
11331 struct it it;
11332 struct glyph_row *row;
11334 #if defined (USE_GTK) || defined (HAVE_NS)
11335 if (FRAME_EXTERNAL_TOOL_BAR (f))
11336 update_frame_tool_bar (f);
11337 return 0;
11338 #endif
11340 /* If frame hasn't a tool-bar window or if it is zero-height, don't
11341 do anything. This means you must start with tool-bar-lines
11342 non-zero to get the auto-sizing effect. Or in other words, you
11343 can turn off tool-bars by specifying tool-bar-lines zero. */
11344 if (!WINDOWP (f->tool_bar_window)
11345 || (w = XWINDOW (f->tool_bar_window),
11346 WINDOW_TOTAL_LINES (w) == 0))
11347 return 0;
11349 /* Set up an iterator for the tool-bar window. */
11350 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
11351 it.first_visible_x = 0;
11352 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
11353 row = it.glyph_row;
11355 /* Build a string that represents the contents of the tool-bar. */
11356 build_desired_tool_bar_string (f);
11357 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
11358 /* FIXME: This should be controlled by a user option. But it
11359 doesn't make sense to have an R2L tool bar if the menu bar cannot
11360 be drawn also R2L, and making the menu bar R2L is tricky due
11361 toolkit-specific code that implements it. If an R2L tool bar is
11362 ever supported, display_tool_bar_line should also be augmented to
11363 call unproduce_glyphs like display_line and display_string
11364 do. */
11365 it.paragraph_embedding = L2R;
11367 if (f->n_tool_bar_rows == 0)
11369 int nlines;
11371 if ((nlines = tool_bar_lines_needed (f, &f->n_tool_bar_rows),
11372 nlines != WINDOW_TOTAL_LINES (w)))
11374 Lisp_Object frame;
11375 int old_height = WINDOW_TOTAL_LINES (w);
11377 XSETFRAME (frame, f);
11378 Fmodify_frame_parameters (frame,
11379 Fcons (Fcons (Qtool_bar_lines,
11380 make_number (nlines)),
11381 Qnil));
11382 if (WINDOW_TOTAL_LINES (w) != old_height)
11384 clear_glyph_matrix (w->desired_matrix);
11385 fonts_changed_p = 1;
11386 return 1;
11391 /* Display as many lines as needed to display all tool-bar items. */
11393 if (f->n_tool_bar_rows > 0)
11395 int border, rows, height, extra;
11397 if (INTEGERP (Vtool_bar_border))
11398 border = XINT (Vtool_bar_border);
11399 else if (EQ (Vtool_bar_border, Qinternal_border_width))
11400 border = FRAME_INTERNAL_BORDER_WIDTH (f);
11401 else if (EQ (Vtool_bar_border, Qborder_width))
11402 border = f->border_width;
11403 else
11404 border = 0;
11405 if (border < 0)
11406 border = 0;
11408 rows = f->n_tool_bar_rows;
11409 height = max (1, (it.last_visible_y - border) / rows);
11410 extra = it.last_visible_y - border - height * rows;
11412 while (it.current_y < it.last_visible_y)
11414 int h = 0;
11415 if (extra > 0 && rows-- > 0)
11417 h = (extra + rows - 1) / rows;
11418 extra -= h;
11420 display_tool_bar_line (&it, height + h);
11423 else
11425 while (it.current_y < it.last_visible_y)
11426 display_tool_bar_line (&it, 0);
11429 /* It doesn't make much sense to try scrolling in the tool-bar
11430 window, so don't do it. */
11431 w->desired_matrix->no_scrolling_p = 1;
11432 w->must_be_updated_p = 1;
11434 if (!NILP (Vauto_resize_tool_bars))
11436 int max_tool_bar_height = MAX_FRAME_TOOL_BAR_HEIGHT (f);
11437 int change_height_p = 0;
11439 /* If we couldn't display everything, change the tool-bar's
11440 height if there is room for more. */
11441 if (IT_STRING_CHARPOS (it) < it.end_charpos
11442 && it.current_y < max_tool_bar_height)
11443 change_height_p = 1;
11445 row = it.glyph_row - 1;
11447 /* If there are blank lines at the end, except for a partially
11448 visible blank line at the end that is smaller than
11449 FRAME_LINE_HEIGHT, change the tool-bar's height. */
11450 if (!row->displays_text_p
11451 && row->height >= FRAME_LINE_HEIGHT (f))
11452 change_height_p = 1;
11454 /* If row displays tool-bar items, but is partially visible,
11455 change the tool-bar's height. */
11456 if (row->displays_text_p
11457 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y
11458 && MATRIX_ROW_BOTTOM_Y (row) < max_tool_bar_height)
11459 change_height_p = 1;
11461 /* Resize windows as needed by changing the `tool-bar-lines'
11462 frame parameter. */
11463 if (change_height_p)
11465 Lisp_Object frame;
11466 int old_height = WINDOW_TOTAL_LINES (w);
11467 int nrows;
11468 int nlines = tool_bar_lines_needed (f, &nrows);
11470 change_height_p = ((EQ (Vauto_resize_tool_bars, Qgrow_only)
11471 && !f->minimize_tool_bar_window_p)
11472 ? (nlines > old_height)
11473 : (nlines != old_height));
11474 f->minimize_tool_bar_window_p = 0;
11476 if (change_height_p)
11478 XSETFRAME (frame, f);
11479 Fmodify_frame_parameters (frame,
11480 Fcons (Fcons (Qtool_bar_lines,
11481 make_number (nlines)),
11482 Qnil));
11483 if (WINDOW_TOTAL_LINES (w) != old_height)
11485 clear_glyph_matrix (w->desired_matrix);
11486 f->n_tool_bar_rows = nrows;
11487 fonts_changed_p = 1;
11488 return 1;
11494 f->minimize_tool_bar_window_p = 0;
11495 return 0;
11499 /* Get information about the tool-bar item which is displayed in GLYPH
11500 on frame F. Return in *PROP_IDX the index where tool-bar item
11501 properties start in F->tool_bar_items. Value is zero if
11502 GLYPH doesn't display a tool-bar item. */
11504 static int
11505 tool_bar_item_info (struct frame *f, struct glyph *glyph, int *prop_idx)
11507 Lisp_Object prop;
11508 int success_p;
11509 int charpos;
11511 /* This function can be called asynchronously, which means we must
11512 exclude any possibility that Fget_text_property signals an
11513 error. */
11514 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
11515 charpos = max (0, charpos);
11517 /* Get the text property `menu-item' at pos. The value of that
11518 property is the start index of this item's properties in
11519 F->tool_bar_items. */
11520 prop = Fget_text_property (make_number (charpos),
11521 Qmenu_item, f->current_tool_bar_string);
11522 if (INTEGERP (prop))
11524 *prop_idx = XINT (prop);
11525 success_p = 1;
11527 else
11528 success_p = 0;
11530 return success_p;
11534 /* Get information about the tool-bar item at position X/Y on frame F.
11535 Return in *GLYPH a pointer to the glyph of the tool-bar item in
11536 the current matrix of the tool-bar window of F, or NULL if not
11537 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
11538 item in F->tool_bar_items. Value is
11540 -1 if X/Y is not on a tool-bar item
11541 0 if X/Y is on the same item that was highlighted before.
11542 1 otherwise. */
11544 static int
11545 get_tool_bar_item (struct frame *f, int x, int y, struct glyph **glyph,
11546 int *hpos, int *vpos, int *prop_idx)
11548 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
11549 struct window *w = XWINDOW (f->tool_bar_window);
11550 int area;
11552 /* Find the glyph under X/Y. */
11553 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
11554 if (*glyph == NULL)
11555 return -1;
11557 /* Get the start of this tool-bar item's properties in
11558 f->tool_bar_items. */
11559 if (!tool_bar_item_info (f, *glyph, prop_idx))
11560 return -1;
11562 /* Is mouse on the highlighted item? */
11563 if (EQ (f->tool_bar_window, hlinfo->mouse_face_window)
11564 && *vpos >= hlinfo->mouse_face_beg_row
11565 && *vpos <= hlinfo->mouse_face_end_row
11566 && (*vpos > hlinfo->mouse_face_beg_row
11567 || *hpos >= hlinfo->mouse_face_beg_col)
11568 && (*vpos < hlinfo->mouse_face_end_row
11569 || *hpos < hlinfo->mouse_face_end_col
11570 || hlinfo->mouse_face_past_end))
11571 return 0;
11573 return 1;
11577 /* EXPORT:
11578 Handle mouse button event on the tool-bar of frame F, at
11579 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
11580 0 for button release. MODIFIERS is event modifiers for button
11581 release. */
11583 void
11584 handle_tool_bar_click (struct frame *f, int x, int y, int down_p,
11585 unsigned int modifiers)
11587 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
11588 struct window *w = XWINDOW (f->tool_bar_window);
11589 int hpos, vpos, prop_idx;
11590 struct glyph *glyph;
11591 Lisp_Object enabled_p;
11593 /* If not on the highlighted tool-bar item, return. */
11594 frame_to_window_pixel_xy (w, &x, &y);
11595 if (get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0)
11596 return;
11598 /* If item is disabled, do nothing. */
11599 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
11600 if (NILP (enabled_p))
11601 return;
11603 if (down_p)
11605 /* Show item in pressed state. */
11606 show_mouse_face (hlinfo, DRAW_IMAGE_SUNKEN);
11607 hlinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN;
11608 last_tool_bar_item = prop_idx;
11610 else
11612 Lisp_Object key, frame;
11613 struct input_event event;
11614 EVENT_INIT (event);
11616 /* Show item in released state. */
11617 show_mouse_face (hlinfo, DRAW_IMAGE_RAISED);
11618 hlinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
11620 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
11622 XSETFRAME (frame, f);
11623 event.kind = TOOL_BAR_EVENT;
11624 event.frame_or_window = frame;
11625 event.arg = frame;
11626 kbd_buffer_store_event (&event);
11628 event.kind = TOOL_BAR_EVENT;
11629 event.frame_or_window = frame;
11630 event.arg = key;
11631 event.modifiers = modifiers;
11632 kbd_buffer_store_event (&event);
11633 last_tool_bar_item = -1;
11638 /* Possibly highlight a tool-bar item on frame F when mouse moves to
11639 tool-bar window-relative coordinates X/Y. Called from
11640 note_mouse_highlight. */
11642 static void
11643 note_tool_bar_highlight (struct frame *f, int x, int y)
11645 Lisp_Object window = f->tool_bar_window;
11646 struct window *w = XWINDOW (window);
11647 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
11648 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
11649 int hpos, vpos;
11650 struct glyph *glyph;
11651 struct glyph_row *row;
11652 int i;
11653 Lisp_Object enabled_p;
11654 int prop_idx;
11655 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
11656 int mouse_down_p, rc;
11658 /* Function note_mouse_highlight is called with negative X/Y
11659 values when mouse moves outside of the frame. */
11660 if (x <= 0 || y <= 0)
11662 clear_mouse_face (hlinfo);
11663 return;
11666 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
11667 if (rc < 0)
11669 /* Not on tool-bar item. */
11670 clear_mouse_face (hlinfo);
11671 return;
11673 else if (rc == 0)
11674 /* On same tool-bar item as before. */
11675 goto set_help_echo;
11677 clear_mouse_face (hlinfo);
11679 /* Mouse is down, but on different tool-bar item? */
11680 mouse_down_p = (dpyinfo->grabbed
11681 && f == last_mouse_frame
11682 && FRAME_LIVE_P (f));
11683 if (mouse_down_p
11684 && last_tool_bar_item != prop_idx)
11685 return;
11687 hlinfo->mouse_face_image_state = DRAW_NORMAL_TEXT;
11688 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
11690 /* If tool-bar item is not enabled, don't highlight it. */
11691 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
11692 if (!NILP (enabled_p))
11694 /* Compute the x-position of the glyph. In front and past the
11695 image is a space. We include this in the highlighted area. */
11696 row = MATRIX_ROW (w->current_matrix, vpos);
11697 for (i = x = 0; i < hpos; ++i)
11698 x += row->glyphs[TEXT_AREA][i].pixel_width;
11700 /* Record this as the current active region. */
11701 hlinfo->mouse_face_beg_col = hpos;
11702 hlinfo->mouse_face_beg_row = vpos;
11703 hlinfo->mouse_face_beg_x = x;
11704 hlinfo->mouse_face_beg_y = row->y;
11705 hlinfo->mouse_face_past_end = 0;
11707 hlinfo->mouse_face_end_col = hpos + 1;
11708 hlinfo->mouse_face_end_row = vpos;
11709 hlinfo->mouse_face_end_x = x + glyph->pixel_width;
11710 hlinfo->mouse_face_end_y = row->y;
11711 hlinfo->mouse_face_window = window;
11712 hlinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
11714 /* Display it as active. */
11715 show_mouse_face (hlinfo, draw);
11716 hlinfo->mouse_face_image_state = draw;
11719 set_help_echo:
11721 /* Set help_echo_string to a help string to display for this tool-bar item.
11722 XTread_socket does the rest. */
11723 help_echo_object = help_echo_window = Qnil;
11724 help_echo_pos = -1;
11725 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
11726 if (NILP (help_echo_string))
11727 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
11730 #endif /* HAVE_WINDOW_SYSTEM */
11734 /************************************************************************
11735 Horizontal scrolling
11736 ************************************************************************/
11738 static int hscroll_window_tree (Lisp_Object);
11739 static int hscroll_windows (Lisp_Object);
11741 /* For all leaf windows in the window tree rooted at WINDOW, set their
11742 hscroll value so that PT is (i) visible in the window, and (ii) so
11743 that it is not within a certain margin at the window's left and
11744 right border. Value is non-zero if any window's hscroll has been
11745 changed. */
11747 static int
11748 hscroll_window_tree (Lisp_Object window)
11750 int hscrolled_p = 0;
11751 int hscroll_relative_p = FLOATP (Vhscroll_step);
11752 int hscroll_step_abs = 0;
11753 double hscroll_step_rel = 0;
11755 if (hscroll_relative_p)
11757 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
11758 if (hscroll_step_rel < 0)
11760 hscroll_relative_p = 0;
11761 hscroll_step_abs = 0;
11764 else if (INTEGERP (Vhscroll_step))
11766 hscroll_step_abs = XINT (Vhscroll_step);
11767 if (hscroll_step_abs < 0)
11768 hscroll_step_abs = 0;
11770 else
11771 hscroll_step_abs = 0;
11773 while (WINDOWP (window))
11775 struct window *w = XWINDOW (window);
11777 if (WINDOWP (w->hchild))
11778 hscrolled_p |= hscroll_window_tree (w->hchild);
11779 else if (WINDOWP (w->vchild))
11780 hscrolled_p |= hscroll_window_tree (w->vchild);
11781 else if (w->cursor.vpos >= 0)
11783 int h_margin;
11784 int text_area_width;
11785 struct glyph_row *current_cursor_row
11786 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
11787 struct glyph_row *desired_cursor_row
11788 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
11789 struct glyph_row *cursor_row
11790 = (desired_cursor_row->enabled_p
11791 ? desired_cursor_row
11792 : current_cursor_row);
11794 text_area_width = window_box_width (w, TEXT_AREA);
11796 /* Scroll when cursor is inside this scroll margin. */
11797 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
11799 if (!NILP (Fbuffer_local_value (Qauto_hscroll_mode, w->buffer))
11800 && ((XFASTINT (w->hscroll)
11801 && w->cursor.x <= h_margin)
11802 || (cursor_row->enabled_p
11803 && cursor_row->truncated_on_right_p
11804 && (w->cursor.x >= text_area_width - h_margin))))
11806 struct it it;
11807 int hscroll;
11808 struct buffer *saved_current_buffer;
11809 EMACS_INT pt;
11810 int wanted_x;
11812 /* Find point in a display of infinite width. */
11813 saved_current_buffer = current_buffer;
11814 current_buffer = XBUFFER (w->buffer);
11816 if (w == XWINDOW (selected_window))
11817 pt = PT;
11818 else
11820 pt = marker_position (w->pointm);
11821 pt = max (BEGV, pt);
11822 pt = min (ZV, pt);
11825 /* Move iterator to pt starting at cursor_row->start in
11826 a line with infinite width. */
11827 init_to_row_start (&it, w, cursor_row);
11828 it.last_visible_x = INFINITY;
11829 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
11830 current_buffer = saved_current_buffer;
11832 /* Position cursor in window. */
11833 if (!hscroll_relative_p && hscroll_step_abs == 0)
11834 hscroll = max (0, (it.current_x
11835 - (ITERATOR_AT_END_OF_LINE_P (&it)
11836 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
11837 : (text_area_width / 2))))
11838 / FRAME_COLUMN_WIDTH (it.f);
11839 else if (w->cursor.x >= text_area_width - h_margin)
11841 if (hscroll_relative_p)
11842 wanted_x = text_area_width * (1 - hscroll_step_rel)
11843 - h_margin;
11844 else
11845 wanted_x = text_area_width
11846 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
11847 - h_margin;
11848 hscroll
11849 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
11851 else
11853 if (hscroll_relative_p)
11854 wanted_x = text_area_width * hscroll_step_rel
11855 + h_margin;
11856 else
11857 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
11858 + h_margin;
11859 hscroll
11860 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
11862 hscroll = max (hscroll, XFASTINT (w->min_hscroll));
11864 /* Don't call Fset_window_hscroll if value hasn't
11865 changed because it will prevent redisplay
11866 optimizations. */
11867 if (XFASTINT (w->hscroll) != hscroll)
11869 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
11870 w->hscroll = make_number (hscroll);
11871 hscrolled_p = 1;
11876 window = w->next;
11879 /* Value is non-zero if hscroll of any leaf window has been changed. */
11880 return hscrolled_p;
11884 /* Set hscroll so that cursor is visible and not inside horizontal
11885 scroll margins for all windows in the tree rooted at WINDOW. See
11886 also hscroll_window_tree above. Value is non-zero if any window's
11887 hscroll has been changed. If it has, desired matrices on the frame
11888 of WINDOW are cleared. */
11890 static int
11891 hscroll_windows (Lisp_Object window)
11893 int hscrolled_p = hscroll_window_tree (window);
11894 if (hscrolled_p)
11895 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
11896 return hscrolled_p;
11901 /************************************************************************
11902 Redisplay
11903 ************************************************************************/
11905 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
11906 to a non-zero value. This is sometimes handy to have in a debugger
11907 session. */
11909 #if GLYPH_DEBUG
11911 /* First and last unchanged row for try_window_id. */
11913 static int debug_first_unchanged_at_end_vpos;
11914 static int debug_last_unchanged_at_beg_vpos;
11916 /* Delta vpos and y. */
11918 static int debug_dvpos, debug_dy;
11920 /* Delta in characters and bytes for try_window_id. */
11922 static EMACS_INT debug_delta, debug_delta_bytes;
11924 /* Values of window_end_pos and window_end_vpos at the end of
11925 try_window_id. */
11927 static EMACS_INT debug_end_vpos;
11929 /* Append a string to W->desired_matrix->method. FMT is a printf
11930 format string. If trace_redisplay_p is non-zero also printf the
11931 resulting string to stderr. */
11933 static void debug_method_add (struct window *, char const *, ...)
11934 ATTRIBUTE_FORMAT_PRINTF (2, 3);
11936 static void
11937 debug_method_add (struct window *w, char const *fmt, ...)
11939 char buffer[512];
11940 char *method = w->desired_matrix->method;
11941 int len = strlen (method);
11942 int size = sizeof w->desired_matrix->method;
11943 int remaining = size - len - 1;
11944 va_list ap;
11946 va_start (ap, fmt);
11947 vsprintf (buffer, fmt, ap);
11948 va_end (ap);
11949 if (len && remaining)
11951 method[len] = '|';
11952 --remaining, ++len;
11955 strncpy (method + len, buffer, remaining);
11957 if (trace_redisplay_p)
11958 fprintf (stderr, "%p (%s): %s\n",
11960 ((BUFFERP (w->buffer)
11961 && STRINGP (BVAR (XBUFFER (w->buffer), name)))
11962 ? SSDATA (BVAR (XBUFFER (w->buffer), name))
11963 : "no buffer"),
11964 buffer);
11967 #endif /* GLYPH_DEBUG */
11970 /* Value is non-zero if all changes in window W, which displays
11971 current_buffer, are in the text between START and END. START is a
11972 buffer position, END is given as a distance from Z. Used in
11973 redisplay_internal for display optimization. */
11975 static inline int
11976 text_outside_line_unchanged_p (struct window *w,
11977 EMACS_INT start, EMACS_INT end)
11979 int unchanged_p = 1;
11981 /* If text or overlays have changed, see where. */
11982 if (XFASTINT (w->last_modified) < MODIFF
11983 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
11985 /* Gap in the line? */
11986 if (GPT < start || Z - GPT < end)
11987 unchanged_p = 0;
11989 /* Changes start in front of the line, or end after it? */
11990 if (unchanged_p
11991 && (BEG_UNCHANGED < start - 1
11992 || END_UNCHANGED < end))
11993 unchanged_p = 0;
11995 /* If selective display, can't optimize if changes start at the
11996 beginning of the line. */
11997 if (unchanged_p
11998 && INTEGERP (BVAR (current_buffer, selective_display))
11999 && XINT (BVAR (current_buffer, selective_display)) > 0
12000 && (BEG_UNCHANGED < start || GPT <= start))
12001 unchanged_p = 0;
12003 /* If there are overlays at the start or end of the line, these
12004 may have overlay strings with newlines in them. A change at
12005 START, for instance, may actually concern the display of such
12006 overlay strings as well, and they are displayed on different
12007 lines. So, quickly rule out this case. (For the future, it
12008 might be desirable to implement something more telling than
12009 just BEG/END_UNCHANGED.) */
12010 if (unchanged_p)
12012 if (BEG + BEG_UNCHANGED == start
12013 && overlay_touches_p (start))
12014 unchanged_p = 0;
12015 if (END_UNCHANGED == end
12016 && overlay_touches_p (Z - end))
12017 unchanged_p = 0;
12020 /* Under bidi reordering, adding or deleting a character in the
12021 beginning of a paragraph, before the first strong directional
12022 character, can change the base direction of the paragraph (unless
12023 the buffer specifies a fixed paragraph direction), which will
12024 require to redisplay the whole paragraph. It might be worthwhile
12025 to find the paragraph limits and widen the range of redisplayed
12026 lines to that, but for now just give up this optimization. */
12027 if (!NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering))
12028 && NILP (BVAR (XBUFFER (w->buffer), bidi_paragraph_direction)))
12029 unchanged_p = 0;
12032 return unchanged_p;
12036 /* Do a frame update, taking possible shortcuts into account. This is
12037 the main external entry point for redisplay.
12039 If the last redisplay displayed an echo area message and that message
12040 is no longer requested, we clear the echo area or bring back the
12041 mini-buffer if that is in use. */
12043 void
12044 redisplay (void)
12046 redisplay_internal ();
12050 static Lisp_Object
12051 overlay_arrow_string_or_property (Lisp_Object var)
12053 Lisp_Object val;
12055 if (val = Fget (var, Qoverlay_arrow_string), STRINGP (val))
12056 return val;
12058 return Voverlay_arrow_string;
12061 /* Return 1 if there are any overlay-arrows in current_buffer. */
12062 static int
12063 overlay_arrow_in_current_buffer_p (void)
12065 Lisp_Object vlist;
12067 for (vlist = Voverlay_arrow_variable_list;
12068 CONSP (vlist);
12069 vlist = XCDR (vlist))
12071 Lisp_Object var = XCAR (vlist);
12072 Lisp_Object val;
12074 if (!SYMBOLP (var))
12075 continue;
12076 val = find_symbol_value (var);
12077 if (MARKERP (val)
12078 && current_buffer == XMARKER (val)->buffer)
12079 return 1;
12081 return 0;
12085 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
12086 has changed. */
12088 static int
12089 overlay_arrows_changed_p (void)
12091 Lisp_Object vlist;
12093 for (vlist = Voverlay_arrow_variable_list;
12094 CONSP (vlist);
12095 vlist = XCDR (vlist))
12097 Lisp_Object var = XCAR (vlist);
12098 Lisp_Object val, pstr;
12100 if (!SYMBOLP (var))
12101 continue;
12102 val = find_symbol_value (var);
12103 if (!MARKERP (val))
12104 continue;
12105 if (! EQ (COERCE_MARKER (val),
12106 Fget (var, Qlast_arrow_position))
12107 || ! (pstr = overlay_arrow_string_or_property (var),
12108 EQ (pstr, Fget (var, Qlast_arrow_string))))
12109 return 1;
12111 return 0;
12114 /* Mark overlay arrows to be updated on next redisplay. */
12116 static void
12117 update_overlay_arrows (int up_to_date)
12119 Lisp_Object vlist;
12121 for (vlist = Voverlay_arrow_variable_list;
12122 CONSP (vlist);
12123 vlist = XCDR (vlist))
12125 Lisp_Object var = XCAR (vlist);
12127 if (!SYMBOLP (var))
12128 continue;
12130 if (up_to_date > 0)
12132 Lisp_Object val = find_symbol_value (var);
12133 Fput (var, Qlast_arrow_position,
12134 COERCE_MARKER (val));
12135 Fput (var, Qlast_arrow_string,
12136 overlay_arrow_string_or_property (var));
12138 else if (up_to_date < 0
12139 || !NILP (Fget (var, Qlast_arrow_position)))
12141 Fput (var, Qlast_arrow_position, Qt);
12142 Fput (var, Qlast_arrow_string, Qt);
12148 /* Return overlay arrow string to display at row.
12149 Return integer (bitmap number) for arrow bitmap in left fringe.
12150 Return nil if no overlay arrow. */
12152 static Lisp_Object
12153 overlay_arrow_at_row (struct it *it, struct glyph_row *row)
12155 Lisp_Object vlist;
12157 for (vlist = Voverlay_arrow_variable_list;
12158 CONSP (vlist);
12159 vlist = XCDR (vlist))
12161 Lisp_Object var = XCAR (vlist);
12162 Lisp_Object val;
12164 if (!SYMBOLP (var))
12165 continue;
12167 val = find_symbol_value (var);
12169 if (MARKERP (val)
12170 && current_buffer == XMARKER (val)->buffer
12171 && (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
12173 if (FRAME_WINDOW_P (it->f)
12174 /* FIXME: if ROW->reversed_p is set, this should test
12175 the right fringe, not the left one. */
12176 && WINDOW_LEFT_FRINGE_WIDTH (it->w) > 0)
12178 #ifdef HAVE_WINDOW_SYSTEM
12179 if (val = Fget (var, Qoverlay_arrow_bitmap), SYMBOLP (val))
12181 int fringe_bitmap;
12182 if ((fringe_bitmap = lookup_fringe_bitmap (val)) != 0)
12183 return make_number (fringe_bitmap);
12185 #endif
12186 return make_number (-1); /* Use default arrow bitmap */
12188 return overlay_arrow_string_or_property (var);
12192 return Qnil;
12195 /* Return 1 if point moved out of or into a composition. Otherwise
12196 return 0. PREV_BUF and PREV_PT are the last point buffer and
12197 position. BUF and PT are the current point buffer and position. */
12199 static int
12200 check_point_in_composition (struct buffer *prev_buf, EMACS_INT prev_pt,
12201 struct buffer *buf, EMACS_INT pt)
12203 EMACS_INT start, end;
12204 Lisp_Object prop;
12205 Lisp_Object buffer;
12207 XSETBUFFER (buffer, buf);
12208 /* Check a composition at the last point if point moved within the
12209 same buffer. */
12210 if (prev_buf == buf)
12212 if (prev_pt == pt)
12213 /* Point didn't move. */
12214 return 0;
12216 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
12217 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
12218 && COMPOSITION_VALID_P (start, end, prop)
12219 && start < prev_pt && end > prev_pt)
12220 /* The last point was within the composition. Return 1 iff
12221 point moved out of the composition. */
12222 return (pt <= start || pt >= end);
12225 /* Check a composition at the current point. */
12226 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
12227 && find_composition (pt, -1, &start, &end, &prop, buffer)
12228 && COMPOSITION_VALID_P (start, end, prop)
12229 && start < pt && end > pt);
12233 /* Reconsider the setting of B->clip_changed which is displayed
12234 in window W. */
12236 static inline void
12237 reconsider_clip_changes (struct window *w, struct buffer *b)
12239 if (b->clip_changed
12240 && !NILP (w->window_end_valid)
12241 && w->current_matrix->buffer == b
12242 && w->current_matrix->zv == BUF_ZV (b)
12243 && w->current_matrix->begv == BUF_BEGV (b))
12244 b->clip_changed = 0;
12246 /* If display wasn't paused, and W is not a tool bar window, see if
12247 point has been moved into or out of a composition. In that case,
12248 we set b->clip_changed to 1 to force updating the screen. If
12249 b->clip_changed has already been set to 1, we can skip this
12250 check. */
12251 if (!b->clip_changed
12252 && BUFFERP (w->buffer) && !NILP (w->window_end_valid))
12254 EMACS_INT pt;
12256 if (w == XWINDOW (selected_window))
12257 pt = PT;
12258 else
12259 pt = marker_position (w->pointm);
12261 if ((w->current_matrix->buffer != XBUFFER (w->buffer)
12262 || pt != XINT (w->last_point))
12263 && check_point_in_composition (w->current_matrix->buffer,
12264 XINT (w->last_point),
12265 XBUFFER (w->buffer), pt))
12266 b->clip_changed = 1;
12271 /* Select FRAME to forward the values of frame-local variables into C
12272 variables so that the redisplay routines can access those values
12273 directly. */
12275 static void
12276 select_frame_for_redisplay (Lisp_Object frame)
12278 Lisp_Object tail, tem;
12279 Lisp_Object old = selected_frame;
12280 struct Lisp_Symbol *sym;
12282 xassert (FRAMEP (frame) && FRAME_LIVE_P (XFRAME (frame)));
12284 selected_frame = frame;
12286 do {
12287 for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail))
12288 if (CONSP (XCAR (tail))
12289 && (tem = XCAR (XCAR (tail)),
12290 SYMBOLP (tem))
12291 && (sym = indirect_variable (XSYMBOL (tem)),
12292 sym->redirect == SYMBOL_LOCALIZED)
12293 && sym->val.blv->frame_local)
12294 /* Use find_symbol_value rather than Fsymbol_value
12295 to avoid an error if it is void. */
12296 find_symbol_value (tem);
12297 } while (!EQ (frame, old) && (frame = old, 1));
12301 #define STOP_POLLING \
12302 do { if (! polling_stopped_here) stop_polling (); \
12303 polling_stopped_here = 1; } while (0)
12305 #define RESUME_POLLING \
12306 do { if (polling_stopped_here) start_polling (); \
12307 polling_stopped_here = 0; } while (0)
12310 /* Perhaps in the future avoid recentering windows if it
12311 is not necessary; currently that causes some problems. */
12313 static void
12314 redisplay_internal (void)
12316 struct window *w = XWINDOW (selected_window);
12317 struct window *sw;
12318 struct frame *fr;
12319 int pending;
12320 int must_finish = 0;
12321 struct text_pos tlbufpos, tlendpos;
12322 int number_of_visible_frames;
12323 int count, count1;
12324 struct frame *sf;
12325 int polling_stopped_here = 0;
12326 Lisp_Object old_frame = selected_frame;
12328 /* Non-zero means redisplay has to consider all windows on all
12329 frames. Zero means, only selected_window is considered. */
12330 int consider_all_windows_p;
12332 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
12334 /* No redisplay if running in batch mode or frame is not yet fully
12335 initialized, or redisplay is explicitly turned off by setting
12336 Vinhibit_redisplay. */
12337 if (FRAME_INITIAL_P (SELECTED_FRAME ())
12338 || !NILP (Vinhibit_redisplay))
12339 return;
12341 /* Don't examine these until after testing Vinhibit_redisplay.
12342 When Emacs is shutting down, perhaps because its connection to
12343 X has dropped, we should not look at them at all. */
12344 fr = XFRAME (w->frame);
12345 sf = SELECTED_FRAME ();
12347 if (!fr->glyphs_initialized_p)
12348 return;
12350 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS)
12351 if (popup_activated ())
12352 return;
12353 #endif
12355 /* I don't think this happens but let's be paranoid. */
12356 if (redisplaying_p)
12357 return;
12359 /* Record a function that resets redisplaying_p to its old value
12360 when we leave this function. */
12361 count = SPECPDL_INDEX ();
12362 record_unwind_protect (unwind_redisplay,
12363 Fcons (make_number (redisplaying_p), selected_frame));
12364 ++redisplaying_p;
12365 specbind (Qinhibit_free_realized_faces, Qnil);
12368 Lisp_Object tail, frame;
12370 FOR_EACH_FRAME (tail, frame)
12372 struct frame *f = XFRAME (frame);
12373 f->already_hscrolled_p = 0;
12377 retry:
12378 /* Remember the currently selected window. */
12379 sw = w;
12381 if (!EQ (old_frame, selected_frame)
12382 && FRAME_LIVE_P (XFRAME (old_frame)))
12383 /* When running redisplay, we play a bit fast-and-loose and allow e.g.
12384 selected_frame and selected_window to be temporarily out-of-sync so
12385 when we come back here via `goto retry', we need to resync because we
12386 may need to run Elisp code (via prepare_menu_bars). */
12387 select_frame_for_redisplay (old_frame);
12389 pending = 0;
12390 reconsider_clip_changes (w, current_buffer);
12391 last_escape_glyph_frame = NULL;
12392 last_escape_glyph_face_id = (1 << FACE_ID_BITS);
12393 last_glyphless_glyph_frame = NULL;
12394 last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
12396 /* If new fonts have been loaded that make a glyph matrix adjustment
12397 necessary, do it. */
12398 if (fonts_changed_p)
12400 adjust_glyphs (NULL);
12401 ++windows_or_buffers_changed;
12402 fonts_changed_p = 0;
12405 /* If face_change_count is non-zero, init_iterator will free all
12406 realized faces, which includes the faces referenced from current
12407 matrices. So, we can't reuse current matrices in this case. */
12408 if (face_change_count)
12409 ++windows_or_buffers_changed;
12411 if ((FRAME_TERMCAP_P (sf) || FRAME_MSDOS_P (sf))
12412 && FRAME_TTY (sf)->previous_frame != sf)
12414 /* Since frames on a single ASCII terminal share the same
12415 display area, displaying a different frame means redisplay
12416 the whole thing. */
12417 windows_or_buffers_changed++;
12418 SET_FRAME_GARBAGED (sf);
12419 #ifndef DOS_NT
12420 set_tty_color_mode (FRAME_TTY (sf), sf);
12421 #endif
12422 FRAME_TTY (sf)->previous_frame = sf;
12425 /* Set the visible flags for all frames. Do this before checking
12426 for resized or garbaged frames; they want to know if their frames
12427 are visible. See the comment in frame.h for
12428 FRAME_SAMPLE_VISIBILITY. */
12430 Lisp_Object tail, frame;
12432 number_of_visible_frames = 0;
12434 FOR_EACH_FRAME (tail, frame)
12436 struct frame *f = XFRAME (frame);
12438 FRAME_SAMPLE_VISIBILITY (f);
12439 if (FRAME_VISIBLE_P (f))
12440 ++number_of_visible_frames;
12441 clear_desired_matrices (f);
12445 /* Notice any pending interrupt request to change frame size. */
12446 do_pending_window_change (1);
12448 /* do_pending_window_change could change the selected_window due to
12449 frame resizing which makes the selected window too small. */
12450 if (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw)
12452 sw = w;
12453 reconsider_clip_changes (w, current_buffer);
12456 /* Clear frames marked as garbaged. */
12457 if (frame_garbaged)
12458 clear_garbaged_frames ();
12460 /* Build menubar and tool-bar items. */
12461 if (NILP (Vmemory_full))
12462 prepare_menu_bars ();
12464 if (windows_or_buffers_changed)
12465 update_mode_lines++;
12467 /* Detect case that we need to write or remove a star in the mode line. */
12468 if ((SAVE_MODIFF < MODIFF) != !NILP (w->last_had_star))
12470 w->update_mode_line = Qt;
12471 if (buffer_shared > 1)
12472 update_mode_lines++;
12475 /* Avoid invocation of point motion hooks by `current_column' below. */
12476 count1 = SPECPDL_INDEX ();
12477 specbind (Qinhibit_point_motion_hooks, Qt);
12479 /* If %c is in the mode line, update it if needed. */
12480 if (!NILP (w->column_number_displayed)
12481 /* This alternative quickly identifies a common case
12482 where no change is needed. */
12483 && !(PT == XFASTINT (w->last_point)
12484 && XFASTINT (w->last_modified) >= MODIFF
12485 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
12486 && (XFASTINT (w->column_number_displayed) != current_column ()))
12487 w->update_mode_line = Qt;
12489 unbind_to (count1, Qnil);
12491 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
12493 /* The variable buffer_shared is set in redisplay_window and
12494 indicates that we redisplay a buffer in different windows. See
12495 there. */
12496 consider_all_windows_p = (update_mode_lines || buffer_shared > 1
12497 || cursor_type_changed);
12499 /* If specs for an arrow have changed, do thorough redisplay
12500 to ensure we remove any arrow that should no longer exist. */
12501 if (overlay_arrows_changed_p ())
12502 consider_all_windows_p = windows_or_buffers_changed = 1;
12504 /* Normally the message* functions will have already displayed and
12505 updated the echo area, but the frame may have been trashed, or
12506 the update may have been preempted, so display the echo area
12507 again here. Checking message_cleared_p captures the case that
12508 the echo area should be cleared. */
12509 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
12510 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
12511 || (message_cleared_p
12512 && minibuf_level == 0
12513 /* If the mini-window is currently selected, this means the
12514 echo-area doesn't show through. */
12515 && !MINI_WINDOW_P (XWINDOW (selected_window))))
12517 int window_height_changed_p = echo_area_display (0);
12518 must_finish = 1;
12520 /* If we don't display the current message, don't clear the
12521 message_cleared_p flag, because, if we did, we wouldn't clear
12522 the echo area in the next redisplay which doesn't preserve
12523 the echo area. */
12524 if (!display_last_displayed_message_p)
12525 message_cleared_p = 0;
12527 if (fonts_changed_p)
12528 goto retry;
12529 else if (window_height_changed_p)
12531 consider_all_windows_p = 1;
12532 ++update_mode_lines;
12533 ++windows_or_buffers_changed;
12535 /* If window configuration was changed, frames may have been
12536 marked garbaged. Clear them or we will experience
12537 surprises wrt scrolling. */
12538 if (frame_garbaged)
12539 clear_garbaged_frames ();
12542 else if (EQ (selected_window, minibuf_window)
12543 && (current_buffer->clip_changed
12544 || XFASTINT (w->last_modified) < MODIFF
12545 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
12546 && resize_mini_window (w, 0))
12548 /* Resized active mini-window to fit the size of what it is
12549 showing if its contents might have changed. */
12550 must_finish = 1;
12551 /* FIXME: this causes all frames to be updated, which seems unnecessary
12552 since only the current frame needs to be considered. This function needs
12553 to be rewritten with two variables, consider_all_windows and
12554 consider_all_frames. */
12555 consider_all_windows_p = 1;
12556 ++windows_or_buffers_changed;
12557 ++update_mode_lines;
12559 /* If window configuration was changed, frames may have been
12560 marked garbaged. Clear them or we will experience
12561 surprises wrt scrolling. */
12562 if (frame_garbaged)
12563 clear_garbaged_frames ();
12567 /* If showing the region, and mark has changed, we must redisplay
12568 the whole window. The assignment to this_line_start_pos prevents
12569 the optimization directly below this if-statement. */
12570 if (((!NILP (Vtransient_mark_mode)
12571 && !NILP (BVAR (XBUFFER (w->buffer), mark_active)))
12572 != !NILP (w->region_showing))
12573 || (!NILP (w->region_showing)
12574 && !EQ (w->region_showing,
12575 Fmarker_position (BVAR (XBUFFER (w->buffer), mark)))))
12576 CHARPOS (this_line_start_pos) = 0;
12578 /* Optimize the case that only the line containing the cursor in the
12579 selected window has changed. Variables starting with this_ are
12580 set in display_line and record information about the line
12581 containing the cursor. */
12582 tlbufpos = this_line_start_pos;
12583 tlendpos = this_line_end_pos;
12584 if (!consider_all_windows_p
12585 && CHARPOS (tlbufpos) > 0
12586 && NILP (w->update_mode_line)
12587 && !current_buffer->clip_changed
12588 && !current_buffer->prevent_redisplay_optimizations_p
12589 && FRAME_VISIBLE_P (XFRAME (w->frame))
12590 && !FRAME_OBSCURED_P (XFRAME (w->frame))
12591 /* Make sure recorded data applies to current buffer, etc. */
12592 && this_line_buffer == current_buffer
12593 && current_buffer == XBUFFER (w->buffer)
12594 && NILP (w->force_start)
12595 && NILP (w->optional_new_start)
12596 /* Point must be on the line that we have info recorded about. */
12597 && PT >= CHARPOS (tlbufpos)
12598 && PT <= Z - CHARPOS (tlendpos)
12599 /* All text outside that line, including its final newline,
12600 must be unchanged. */
12601 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
12602 CHARPOS (tlendpos)))
12604 if (CHARPOS (tlbufpos) > BEGV
12605 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
12606 && (CHARPOS (tlbufpos) == ZV
12607 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
12608 /* Former continuation line has disappeared by becoming empty. */
12609 goto cancel;
12610 else if (XFASTINT (w->last_modified) < MODIFF
12611 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF
12612 || MINI_WINDOW_P (w))
12614 /* We have to handle the case of continuation around a
12615 wide-column character (see the comment in indent.c around
12616 line 1340).
12618 For instance, in the following case:
12620 -------- Insert --------
12621 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
12622 J_I_ ==> J_I_ `^^' are cursors.
12623 ^^ ^^
12624 -------- --------
12626 As we have to redraw the line above, we cannot use this
12627 optimization. */
12629 struct it it;
12630 int line_height_before = this_line_pixel_height;
12632 /* Note that start_display will handle the case that the
12633 line starting at tlbufpos is a continuation line. */
12634 start_display (&it, w, tlbufpos);
12636 /* Implementation note: It this still necessary? */
12637 if (it.current_x != this_line_start_x)
12638 goto cancel;
12640 TRACE ((stderr, "trying display optimization 1\n"));
12641 w->cursor.vpos = -1;
12642 overlay_arrow_seen = 0;
12643 it.vpos = this_line_vpos;
12644 it.current_y = this_line_y;
12645 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
12646 display_line (&it);
12648 /* If line contains point, is not continued,
12649 and ends at same distance from eob as before, we win. */
12650 if (w->cursor.vpos >= 0
12651 /* Line is not continued, otherwise this_line_start_pos
12652 would have been set to 0 in display_line. */
12653 && CHARPOS (this_line_start_pos)
12654 /* Line ends as before. */
12655 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
12656 /* Line has same height as before. Otherwise other lines
12657 would have to be shifted up or down. */
12658 && this_line_pixel_height == line_height_before)
12660 /* If this is not the window's last line, we must adjust
12661 the charstarts of the lines below. */
12662 if (it.current_y < it.last_visible_y)
12664 struct glyph_row *row
12665 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
12666 EMACS_INT delta, delta_bytes;
12668 /* We used to distinguish between two cases here,
12669 conditioned by Z - CHARPOS (tlendpos) == ZV, for
12670 when the line ends in a newline or the end of the
12671 buffer's accessible portion. But both cases did
12672 the same, so they were collapsed. */
12673 delta = (Z
12674 - CHARPOS (tlendpos)
12675 - MATRIX_ROW_START_CHARPOS (row));
12676 delta_bytes = (Z_BYTE
12677 - BYTEPOS (tlendpos)
12678 - MATRIX_ROW_START_BYTEPOS (row));
12680 increment_matrix_positions (w->current_matrix,
12681 this_line_vpos + 1,
12682 w->current_matrix->nrows,
12683 delta, delta_bytes);
12686 /* If this row displays text now but previously didn't,
12687 or vice versa, w->window_end_vpos may have to be
12688 adjusted. */
12689 if ((it.glyph_row - 1)->displays_text_p)
12691 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
12692 XSETINT (w->window_end_vpos, this_line_vpos);
12694 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
12695 && this_line_vpos > 0)
12696 XSETINT (w->window_end_vpos, this_line_vpos - 1);
12697 w->window_end_valid = Qnil;
12699 /* Update hint: No need to try to scroll in update_window. */
12700 w->desired_matrix->no_scrolling_p = 1;
12702 #if GLYPH_DEBUG
12703 *w->desired_matrix->method = 0;
12704 debug_method_add (w, "optimization 1");
12705 #endif
12706 #ifdef HAVE_WINDOW_SYSTEM
12707 update_window_fringes (w, 0);
12708 #endif
12709 goto update;
12711 else
12712 goto cancel;
12714 else if (/* Cursor position hasn't changed. */
12715 PT == XFASTINT (w->last_point)
12716 /* Make sure the cursor was last displayed
12717 in this window. Otherwise we have to reposition it. */
12718 && 0 <= w->cursor.vpos
12719 && WINDOW_TOTAL_LINES (w) > w->cursor.vpos)
12721 if (!must_finish)
12723 do_pending_window_change (1);
12724 /* If selected_window changed, redisplay again. */
12725 if (WINDOWP (selected_window)
12726 && (w = XWINDOW (selected_window)) != sw)
12727 goto retry;
12729 /* We used to always goto end_of_redisplay here, but this
12730 isn't enough if we have a blinking cursor. */
12731 if (w->cursor_off_p == w->last_cursor_off_p)
12732 goto end_of_redisplay;
12734 goto update;
12736 /* If highlighting the region, or if the cursor is in the echo area,
12737 then we can't just move the cursor. */
12738 else if (! (!NILP (Vtransient_mark_mode)
12739 && !NILP (BVAR (current_buffer, mark_active)))
12740 && (EQ (selected_window, BVAR (current_buffer, last_selected_window))
12741 || highlight_nonselected_windows)
12742 && NILP (w->region_showing)
12743 && NILP (Vshow_trailing_whitespace)
12744 && !cursor_in_echo_area)
12746 struct it it;
12747 struct glyph_row *row;
12749 /* Skip from tlbufpos to PT and see where it is. Note that
12750 PT may be in invisible text. If so, we will end at the
12751 next visible position. */
12752 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
12753 NULL, DEFAULT_FACE_ID);
12754 it.current_x = this_line_start_x;
12755 it.current_y = this_line_y;
12756 it.vpos = this_line_vpos;
12758 /* The call to move_it_to stops in front of PT, but
12759 moves over before-strings. */
12760 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
12762 if (it.vpos == this_line_vpos
12763 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
12764 row->enabled_p))
12766 xassert (this_line_vpos == it.vpos);
12767 xassert (this_line_y == it.current_y);
12768 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
12769 #if GLYPH_DEBUG
12770 *w->desired_matrix->method = 0;
12771 debug_method_add (w, "optimization 3");
12772 #endif
12773 goto update;
12775 else
12776 goto cancel;
12779 cancel:
12780 /* Text changed drastically or point moved off of line. */
12781 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
12784 CHARPOS (this_line_start_pos) = 0;
12785 consider_all_windows_p |= buffer_shared > 1;
12786 ++clear_face_cache_count;
12787 #ifdef HAVE_WINDOW_SYSTEM
12788 ++clear_image_cache_count;
12789 #endif
12791 /* Build desired matrices, and update the display. If
12792 consider_all_windows_p is non-zero, do it for all windows on all
12793 frames. Otherwise do it for selected_window, only. */
12795 if (consider_all_windows_p)
12797 Lisp_Object tail, frame;
12799 FOR_EACH_FRAME (tail, frame)
12800 XFRAME (frame)->updated_p = 0;
12802 /* Recompute # windows showing selected buffer. This will be
12803 incremented each time such a window is displayed. */
12804 buffer_shared = 0;
12806 FOR_EACH_FRAME (tail, frame)
12808 struct frame *f = XFRAME (frame);
12810 if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf)
12812 if (! EQ (frame, selected_frame))
12813 /* Select the frame, for the sake of frame-local
12814 variables. */
12815 select_frame_for_redisplay (frame);
12817 /* Mark all the scroll bars to be removed; we'll redeem
12818 the ones we want when we redisplay their windows. */
12819 if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
12820 FRAME_TERMINAL (f)->condemn_scroll_bars_hook (f);
12822 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
12823 redisplay_windows (FRAME_ROOT_WINDOW (f));
12825 /* The X error handler may have deleted that frame. */
12826 if (!FRAME_LIVE_P (f))
12827 continue;
12829 /* Any scroll bars which redisplay_windows should have
12830 nuked should now go away. */
12831 if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
12832 FRAME_TERMINAL (f)->judge_scroll_bars_hook (f);
12834 /* If fonts changed, display again. */
12835 /* ??? rms: I suspect it is a mistake to jump all the way
12836 back to retry here. It should just retry this frame. */
12837 if (fonts_changed_p)
12838 goto retry;
12840 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
12842 /* See if we have to hscroll. */
12843 if (!f->already_hscrolled_p)
12845 f->already_hscrolled_p = 1;
12846 if (hscroll_windows (f->root_window))
12847 goto retry;
12850 /* Prevent various kinds of signals during display
12851 update. stdio is not robust about handling
12852 signals, which can cause an apparent I/O
12853 error. */
12854 if (interrupt_input)
12855 unrequest_sigio ();
12856 STOP_POLLING;
12858 /* Update the display. */
12859 set_window_update_flags (XWINDOW (f->root_window), 1);
12860 pending |= update_frame (f, 0, 0);
12861 f->updated_p = 1;
12866 if (!EQ (old_frame, selected_frame)
12867 && FRAME_LIVE_P (XFRAME (old_frame)))
12868 /* We played a bit fast-and-loose above and allowed selected_frame
12869 and selected_window to be temporarily out-of-sync but let's make
12870 sure this stays contained. */
12871 select_frame_for_redisplay (old_frame);
12872 eassert (EQ (XFRAME (selected_frame)->selected_window, selected_window));
12874 if (!pending)
12876 /* Do the mark_window_display_accurate after all windows have
12877 been redisplayed because this call resets flags in buffers
12878 which are needed for proper redisplay. */
12879 FOR_EACH_FRAME (tail, frame)
12881 struct frame *f = XFRAME (frame);
12882 if (f->updated_p)
12884 mark_window_display_accurate (f->root_window, 1);
12885 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
12886 FRAME_TERMINAL (f)->frame_up_to_date_hook (f);
12891 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
12893 Lisp_Object mini_window;
12894 struct frame *mini_frame;
12896 displayed_buffer = XBUFFER (XWINDOW (selected_window)->buffer);
12897 /* Use list_of_error, not Qerror, so that
12898 we catch only errors and don't run the debugger. */
12899 internal_condition_case_1 (redisplay_window_1, selected_window,
12900 list_of_error,
12901 redisplay_window_error);
12903 /* Compare desired and current matrices, perform output. */
12905 update:
12906 /* If fonts changed, display again. */
12907 if (fonts_changed_p)
12908 goto retry;
12910 /* Prevent various kinds of signals during display update.
12911 stdio is not robust about handling signals,
12912 which can cause an apparent I/O error. */
12913 if (interrupt_input)
12914 unrequest_sigio ();
12915 STOP_POLLING;
12917 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
12919 if (hscroll_windows (selected_window))
12920 goto retry;
12922 XWINDOW (selected_window)->must_be_updated_p = 1;
12923 pending = update_frame (sf, 0, 0);
12926 /* We may have called echo_area_display at the top of this
12927 function. If the echo area is on another frame, that may
12928 have put text on a frame other than the selected one, so the
12929 above call to update_frame would not have caught it. Catch
12930 it here. */
12931 mini_window = FRAME_MINIBUF_WINDOW (sf);
12932 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
12934 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
12936 XWINDOW (mini_window)->must_be_updated_p = 1;
12937 pending |= update_frame (mini_frame, 0, 0);
12938 if (!pending && hscroll_windows (mini_window))
12939 goto retry;
12943 /* If display was paused because of pending input, make sure we do a
12944 thorough update the next time. */
12945 if (pending)
12947 /* Prevent the optimization at the beginning of
12948 redisplay_internal that tries a single-line update of the
12949 line containing the cursor in the selected window. */
12950 CHARPOS (this_line_start_pos) = 0;
12952 /* Let the overlay arrow be updated the next time. */
12953 update_overlay_arrows (0);
12955 /* If we pause after scrolling, some rows in the current
12956 matrices of some windows are not valid. */
12957 if (!WINDOW_FULL_WIDTH_P (w)
12958 && !FRAME_WINDOW_P (XFRAME (w->frame)))
12959 update_mode_lines = 1;
12961 else
12963 if (!consider_all_windows_p)
12965 /* This has already been done above if
12966 consider_all_windows_p is set. */
12967 mark_window_display_accurate_1 (w, 1);
12969 /* Say overlay arrows are up to date. */
12970 update_overlay_arrows (1);
12972 if (FRAME_TERMINAL (sf)->frame_up_to_date_hook != 0)
12973 FRAME_TERMINAL (sf)->frame_up_to_date_hook (sf);
12976 update_mode_lines = 0;
12977 windows_or_buffers_changed = 0;
12978 cursor_type_changed = 0;
12981 /* Start SIGIO interrupts coming again. Having them off during the
12982 code above makes it less likely one will discard output, but not
12983 impossible, since there might be stuff in the system buffer here.
12984 But it is much hairier to try to do anything about that. */
12985 if (interrupt_input)
12986 request_sigio ();
12987 RESUME_POLLING;
12989 /* If a frame has become visible which was not before, redisplay
12990 again, so that we display it. Expose events for such a frame
12991 (which it gets when becoming visible) don't call the parts of
12992 redisplay constructing glyphs, so simply exposing a frame won't
12993 display anything in this case. So, we have to display these
12994 frames here explicitly. */
12995 if (!pending)
12997 Lisp_Object tail, frame;
12998 int new_count = 0;
13000 FOR_EACH_FRAME (tail, frame)
13002 int this_is_visible = 0;
13004 if (XFRAME (frame)->visible)
13005 this_is_visible = 1;
13006 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
13007 if (XFRAME (frame)->visible)
13008 this_is_visible = 1;
13010 if (this_is_visible)
13011 new_count++;
13014 if (new_count != number_of_visible_frames)
13015 windows_or_buffers_changed++;
13018 /* Change frame size now if a change is pending. */
13019 do_pending_window_change (1);
13021 /* If we just did a pending size change, or have additional
13022 visible frames, or selected_window changed, redisplay again. */
13023 if ((windows_or_buffers_changed && !pending)
13024 || (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw))
13025 goto retry;
13027 /* Clear the face and image caches.
13029 We used to do this only if consider_all_windows_p. But the cache
13030 needs to be cleared if a timer creates images in the current
13031 buffer (e.g. the test case in Bug#6230). */
13033 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
13035 clear_face_cache (0);
13036 clear_face_cache_count = 0;
13039 #ifdef HAVE_WINDOW_SYSTEM
13040 if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT)
13042 clear_image_caches (Qnil);
13043 clear_image_cache_count = 0;
13045 #endif /* HAVE_WINDOW_SYSTEM */
13047 end_of_redisplay:
13048 unbind_to (count, Qnil);
13049 RESUME_POLLING;
13053 /* Redisplay, but leave alone any recent echo area message unless
13054 another message has been requested in its place.
13056 This is useful in situations where you need to redisplay but no
13057 user action has occurred, making it inappropriate for the message
13058 area to be cleared. See tracking_off and
13059 wait_reading_process_output for examples of these situations.
13061 FROM_WHERE is an integer saying from where this function was
13062 called. This is useful for debugging. */
13064 void
13065 redisplay_preserve_echo_area (int from_where)
13067 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
13069 if (!NILP (echo_area_buffer[1]))
13071 /* We have a previously displayed message, but no current
13072 message. Redisplay the previous message. */
13073 display_last_displayed_message_p = 1;
13074 redisplay_internal ();
13075 display_last_displayed_message_p = 0;
13077 else
13078 redisplay_internal ();
13080 if (FRAME_RIF (SELECTED_FRAME ()) != NULL
13081 && FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
13082 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (NULL);
13086 /* Function registered with record_unwind_protect in
13087 redisplay_internal. Reset redisplaying_p to the value it had
13088 before redisplay_internal was called, and clear
13089 prevent_freeing_realized_faces_p. It also selects the previously
13090 selected frame, unless it has been deleted (by an X connection
13091 failure during redisplay, for example). */
13093 static Lisp_Object
13094 unwind_redisplay (Lisp_Object val)
13096 Lisp_Object old_redisplaying_p, old_frame;
13098 old_redisplaying_p = XCAR (val);
13099 redisplaying_p = XFASTINT (old_redisplaying_p);
13100 old_frame = XCDR (val);
13101 if (! EQ (old_frame, selected_frame)
13102 && FRAME_LIVE_P (XFRAME (old_frame)))
13103 select_frame_for_redisplay (old_frame);
13104 return Qnil;
13108 /* Mark the display of window W as accurate or inaccurate. If
13109 ACCURATE_P is non-zero mark display of W as accurate. If
13110 ACCURATE_P is zero, arrange for W to be redisplayed the next time
13111 redisplay_internal is called. */
13113 static void
13114 mark_window_display_accurate_1 (struct window *w, int accurate_p)
13116 if (BUFFERP (w->buffer))
13118 struct buffer *b = XBUFFER (w->buffer);
13120 w->last_modified
13121 = make_number (accurate_p ? BUF_MODIFF (b) : 0);
13122 w->last_overlay_modified
13123 = make_number (accurate_p ? BUF_OVERLAY_MODIFF (b) : 0);
13124 w->last_had_star
13125 = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b) ? Qt : Qnil;
13127 if (accurate_p)
13129 b->clip_changed = 0;
13130 b->prevent_redisplay_optimizations_p = 0;
13132 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
13133 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
13134 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
13135 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
13137 w->current_matrix->buffer = b;
13138 w->current_matrix->begv = BUF_BEGV (b);
13139 w->current_matrix->zv = BUF_ZV (b);
13141 w->last_cursor = w->cursor;
13142 w->last_cursor_off_p = w->cursor_off_p;
13144 if (w == XWINDOW (selected_window))
13145 w->last_point = make_number (BUF_PT (b));
13146 else
13147 w->last_point = make_number (XMARKER (w->pointm)->charpos);
13151 if (accurate_p)
13153 w->window_end_valid = w->buffer;
13154 w->update_mode_line = Qnil;
13159 /* Mark the display of windows in the window tree rooted at WINDOW as
13160 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
13161 windows as accurate. If ACCURATE_P is zero, arrange for windows to
13162 be redisplayed the next time redisplay_internal is called. */
13164 void
13165 mark_window_display_accurate (Lisp_Object window, int accurate_p)
13167 struct window *w;
13169 for (; !NILP (window); window = w->next)
13171 w = XWINDOW (window);
13172 mark_window_display_accurate_1 (w, accurate_p);
13174 if (!NILP (w->vchild))
13175 mark_window_display_accurate (w->vchild, accurate_p);
13176 if (!NILP (w->hchild))
13177 mark_window_display_accurate (w->hchild, accurate_p);
13180 if (accurate_p)
13182 update_overlay_arrows (1);
13184 else
13186 /* Force a thorough redisplay the next time by setting
13187 last_arrow_position and last_arrow_string to t, which is
13188 unequal to any useful value of Voverlay_arrow_... */
13189 update_overlay_arrows (-1);
13194 /* Return value in display table DP (Lisp_Char_Table *) for character
13195 C. Since a display table doesn't have any parent, we don't have to
13196 follow parent. Do not call this function directly but use the
13197 macro DISP_CHAR_VECTOR. */
13199 Lisp_Object
13200 disp_char_vector (struct Lisp_Char_Table *dp, int c)
13202 Lisp_Object val;
13204 if (ASCII_CHAR_P (c))
13206 val = dp->ascii;
13207 if (SUB_CHAR_TABLE_P (val))
13208 val = XSUB_CHAR_TABLE (val)->contents[c];
13210 else
13212 Lisp_Object table;
13214 XSETCHAR_TABLE (table, dp);
13215 val = char_table_ref (table, c);
13217 if (NILP (val))
13218 val = dp->defalt;
13219 return val;
13224 /***********************************************************************
13225 Window Redisplay
13226 ***********************************************************************/
13228 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
13230 static void
13231 redisplay_windows (Lisp_Object window)
13233 while (!NILP (window))
13235 struct window *w = XWINDOW (window);
13237 if (!NILP (w->hchild))
13238 redisplay_windows (w->hchild);
13239 else if (!NILP (w->vchild))
13240 redisplay_windows (w->vchild);
13241 else if (!NILP (w->buffer))
13243 displayed_buffer = XBUFFER (w->buffer);
13244 /* Use list_of_error, not Qerror, so that
13245 we catch only errors and don't run the debugger. */
13246 internal_condition_case_1 (redisplay_window_0, window,
13247 list_of_error,
13248 redisplay_window_error);
13251 window = w->next;
13255 static Lisp_Object
13256 redisplay_window_error (Lisp_Object ignore)
13258 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
13259 return Qnil;
13262 static Lisp_Object
13263 redisplay_window_0 (Lisp_Object window)
13265 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
13266 redisplay_window (window, 0);
13267 return Qnil;
13270 static Lisp_Object
13271 redisplay_window_1 (Lisp_Object window)
13273 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
13274 redisplay_window (window, 1);
13275 return Qnil;
13279 /* Set cursor position of W. PT is assumed to be displayed in ROW.
13280 DELTA and DELTA_BYTES are the numbers of characters and bytes by
13281 which positions recorded in ROW differ from current buffer
13282 positions.
13284 Return 0 if cursor is not on this row, 1 otherwise. */
13286 static int
13287 set_cursor_from_row (struct window *w, struct glyph_row *row,
13288 struct glyph_matrix *matrix,
13289 EMACS_INT delta, EMACS_INT delta_bytes,
13290 int dy, int dvpos)
13292 struct glyph *glyph = row->glyphs[TEXT_AREA];
13293 struct glyph *end = glyph + row->used[TEXT_AREA];
13294 struct glyph *cursor = NULL;
13295 /* The last known character position in row. */
13296 EMACS_INT last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
13297 int x = row->x;
13298 EMACS_INT pt_old = PT - delta;
13299 EMACS_INT pos_before = MATRIX_ROW_START_CHARPOS (row) + delta;
13300 EMACS_INT pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
13301 struct glyph *glyph_before = glyph - 1, *glyph_after = end;
13302 /* A glyph beyond the edge of TEXT_AREA which we should never
13303 touch. */
13304 struct glyph *glyphs_end = end;
13305 /* Non-zero means we've found a match for cursor position, but that
13306 glyph has the avoid_cursor_p flag set. */
13307 int match_with_avoid_cursor = 0;
13308 /* Non-zero means we've seen at least one glyph that came from a
13309 display string. */
13310 int string_seen = 0;
13311 /* Largest and smalles buffer positions seen so far during scan of
13312 glyph row. */
13313 EMACS_INT bpos_max = pos_before;
13314 EMACS_INT bpos_min = pos_after;
13315 /* Last buffer position covered by an overlay string with an integer
13316 `cursor' property. */
13317 EMACS_INT bpos_covered = 0;
13319 /* Skip over glyphs not having an object at the start and the end of
13320 the row. These are special glyphs like truncation marks on
13321 terminal frames. */
13322 if (row->displays_text_p)
13324 if (!row->reversed_p)
13326 while (glyph < end
13327 && INTEGERP (glyph->object)
13328 && glyph->charpos < 0)
13330 x += glyph->pixel_width;
13331 ++glyph;
13333 while (end > glyph
13334 && INTEGERP ((end - 1)->object)
13335 /* CHARPOS is zero for blanks and stretch glyphs
13336 inserted by extend_face_to_end_of_line. */
13337 && (end - 1)->charpos <= 0)
13338 --end;
13339 glyph_before = glyph - 1;
13340 glyph_after = end;
13342 else
13344 struct glyph *g;
13346 /* If the glyph row is reversed, we need to process it from back
13347 to front, so swap the edge pointers. */
13348 glyphs_end = end = glyph - 1;
13349 glyph += row->used[TEXT_AREA] - 1;
13351 while (glyph > end + 1
13352 && INTEGERP (glyph->object)
13353 && glyph->charpos < 0)
13355 --glyph;
13356 x -= glyph->pixel_width;
13358 if (INTEGERP (glyph->object) && glyph->charpos < 0)
13359 --glyph;
13360 /* By default, in reversed rows we put the cursor on the
13361 rightmost (first in the reading order) glyph. */
13362 for (g = end + 1; g < glyph; g++)
13363 x += g->pixel_width;
13364 while (end < glyph
13365 && INTEGERP ((end + 1)->object)
13366 && (end + 1)->charpos <= 0)
13367 ++end;
13368 glyph_before = glyph + 1;
13369 glyph_after = end;
13372 else if (row->reversed_p)
13374 /* In R2L rows that don't display text, put the cursor on the
13375 rightmost glyph. Case in point: an empty last line that is
13376 part of an R2L paragraph. */
13377 cursor = end - 1;
13378 /* Avoid placing the cursor on the last glyph of the row, where
13379 on terminal frames we hold the vertical border between
13380 adjacent windows. */
13381 if (!FRAME_WINDOW_P (WINDOW_XFRAME (w))
13382 && !WINDOW_RIGHTMOST_P (w)
13383 && cursor == row->glyphs[LAST_AREA] - 1)
13384 cursor--;
13385 x = -1; /* will be computed below, at label compute_x */
13388 /* Step 1: Try to find the glyph whose character position
13389 corresponds to point. If that's not possible, find 2 glyphs
13390 whose character positions are the closest to point, one before
13391 point, the other after it. */
13392 if (!row->reversed_p)
13393 while (/* not marched to end of glyph row */
13394 glyph < end
13395 /* glyph was not inserted by redisplay for internal purposes */
13396 && !INTEGERP (glyph->object))
13398 if (BUFFERP (glyph->object))
13400 EMACS_INT dpos = glyph->charpos - pt_old;
13402 if (glyph->charpos > bpos_max)
13403 bpos_max = glyph->charpos;
13404 if (glyph->charpos < bpos_min)
13405 bpos_min = glyph->charpos;
13406 if (!glyph->avoid_cursor_p)
13408 /* If we hit point, we've found the glyph on which to
13409 display the cursor. */
13410 if (dpos == 0)
13412 match_with_avoid_cursor = 0;
13413 break;
13415 /* See if we've found a better approximation to
13416 POS_BEFORE or to POS_AFTER. Note that we want the
13417 first (leftmost) glyph of all those that are the
13418 closest from below, and the last (rightmost) of all
13419 those from above. */
13420 if (0 > dpos && dpos > pos_before - pt_old)
13422 pos_before = glyph->charpos;
13423 glyph_before = glyph;
13425 else if (0 < dpos && dpos <= pos_after - pt_old)
13427 pos_after = glyph->charpos;
13428 glyph_after = glyph;
13431 else if (dpos == 0)
13432 match_with_avoid_cursor = 1;
13434 else if (STRINGP (glyph->object))
13436 Lisp_Object chprop;
13437 EMACS_INT glyph_pos = glyph->charpos;
13439 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
13440 glyph->object);
13441 if (INTEGERP (chprop))
13443 bpos_covered = bpos_max + XINT (chprop);
13444 /* If the `cursor' property covers buffer positions up
13445 to and including point, we should display cursor on
13446 this glyph. Note that overlays and text properties
13447 with string values stop bidi reordering, so every
13448 buffer position to the left of the string is always
13449 smaller than any position to the right of the
13450 string. Therefore, if a `cursor' property on one
13451 of the string's characters has an integer value, we
13452 will break out of the loop below _before_ we get to
13453 the position match above. IOW, integer values of
13454 the `cursor' property override the "exact match for
13455 point" strategy of positioning the cursor. */
13456 /* Implementation note: bpos_max == pt_old when, e.g.,
13457 we are in an empty line, where bpos_max is set to
13458 MATRIX_ROW_START_CHARPOS, see above. */
13459 if (bpos_max <= pt_old && bpos_covered >= pt_old)
13461 cursor = glyph;
13462 break;
13466 string_seen = 1;
13468 x += glyph->pixel_width;
13469 ++glyph;
13471 else if (glyph > end) /* row is reversed */
13472 while (!INTEGERP (glyph->object))
13474 if (BUFFERP (glyph->object))
13476 EMACS_INT dpos = glyph->charpos - pt_old;
13478 if (glyph->charpos > bpos_max)
13479 bpos_max = glyph->charpos;
13480 if (glyph->charpos < bpos_min)
13481 bpos_min = glyph->charpos;
13482 if (!glyph->avoid_cursor_p)
13484 if (dpos == 0)
13486 match_with_avoid_cursor = 0;
13487 break;
13489 if (0 > dpos && dpos > pos_before - pt_old)
13491 pos_before = glyph->charpos;
13492 glyph_before = glyph;
13494 else if (0 < dpos && dpos <= pos_after - pt_old)
13496 pos_after = glyph->charpos;
13497 glyph_after = glyph;
13500 else if (dpos == 0)
13501 match_with_avoid_cursor = 1;
13503 else if (STRINGP (glyph->object))
13505 Lisp_Object chprop;
13506 EMACS_INT glyph_pos = glyph->charpos;
13508 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
13509 glyph->object);
13510 if (INTEGERP (chprop))
13512 bpos_covered = bpos_max + XINT (chprop);
13513 /* If the `cursor' property covers buffer positions up
13514 to and including point, we should display cursor on
13515 this glyph. */
13516 if (bpos_max <= pt_old && bpos_covered >= pt_old)
13518 cursor = glyph;
13519 break;
13522 string_seen = 1;
13524 --glyph;
13525 if (glyph == glyphs_end) /* don't dereference outside TEXT_AREA */
13527 x--; /* can't use any pixel_width */
13528 break;
13530 x -= glyph->pixel_width;
13533 /* Step 2: If we didn't find an exact match for point, we need to
13534 look for a proper place to put the cursor among glyphs between
13535 GLYPH_BEFORE and GLYPH_AFTER. */
13536 if (!((row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
13537 && BUFFERP (glyph->object) && glyph->charpos == pt_old)
13538 && bpos_covered < pt_old)
13540 /* An empty line has a single glyph whose OBJECT is zero and
13541 whose CHARPOS is the position of a newline on that line.
13542 Note that on a TTY, there are more glyphs after that, which
13543 were produced by extend_face_to_end_of_line, but their
13544 CHARPOS is zero or negative. */
13545 int empty_line_p =
13546 (row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
13547 && INTEGERP (glyph->object) && glyph->charpos > 0;
13549 if (row->ends_in_ellipsis_p && pos_after == last_pos)
13551 EMACS_INT ellipsis_pos;
13553 /* Scan back over the ellipsis glyphs. */
13554 if (!row->reversed_p)
13556 ellipsis_pos = (glyph - 1)->charpos;
13557 while (glyph > row->glyphs[TEXT_AREA]
13558 && (glyph - 1)->charpos == ellipsis_pos)
13559 glyph--, x -= glyph->pixel_width;
13560 /* That loop always goes one position too far, including
13561 the glyph before the ellipsis. So scan forward over
13562 that one. */
13563 x += glyph->pixel_width;
13564 glyph++;
13566 else /* row is reversed */
13568 ellipsis_pos = (glyph + 1)->charpos;
13569 while (glyph < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
13570 && (glyph + 1)->charpos == ellipsis_pos)
13571 glyph++, x += glyph->pixel_width;
13572 x -= glyph->pixel_width;
13573 glyph--;
13576 else if (match_with_avoid_cursor
13577 /* A truncated row may not include PT among its
13578 character positions. Setting the cursor inside the
13579 scroll margin will trigger recalculation of hscroll
13580 in hscroll_window_tree. */
13581 || (row->truncated_on_left_p && pt_old < bpos_min)
13582 || (row->truncated_on_right_p && pt_old > bpos_max)
13583 /* Zero-width characters produce no glyphs. */
13584 || (!string_seen
13585 && !empty_line_p
13586 && (row->reversed_p
13587 ? glyph_after > glyphs_end
13588 : glyph_after < glyphs_end)))
13590 cursor = glyph_after;
13591 x = -1;
13593 else if (string_seen)
13595 int incr = row->reversed_p ? -1 : +1;
13597 /* Need to find the glyph that came out of a string which is
13598 present at point. That glyph is somewhere between
13599 GLYPH_BEFORE and GLYPH_AFTER, and it came from a string
13600 positioned between POS_BEFORE and POS_AFTER in the
13601 buffer. */
13602 struct glyph *start, *stop;
13603 EMACS_INT pos = pos_before;
13605 x = -1;
13607 /* GLYPH_BEFORE and GLYPH_AFTER are the glyphs that
13608 correspond to POS_BEFORE and POS_AFTER, respectively. We
13609 need START and STOP in the order that corresponds to the
13610 row's direction as given by its reversed_p flag. If the
13611 directionality of characters between POS_BEFORE and
13612 POS_AFTER is the opposite of the row's base direction,
13613 these characters will have been reordered for display,
13614 and we need to reverse START and STOP. */
13615 if (!row->reversed_p)
13617 start = min (glyph_before, glyph_after);
13618 stop = max (glyph_before, glyph_after);
13620 else
13622 start = max (glyph_before, glyph_after);
13623 stop = min (glyph_before, glyph_after);
13625 for (glyph = start + incr;
13626 row->reversed_p ? glyph > stop : glyph < stop; )
13629 /* Any glyphs that come from the buffer are here because
13630 of bidi reordering. Skip them, and only pay
13631 attention to glyphs that came from some string. */
13632 if (STRINGP (glyph->object))
13634 Lisp_Object str;
13635 EMACS_INT tem;
13637 str = glyph->object;
13638 tem = string_buffer_position_lim (str, pos, pos_after, 0);
13639 if (tem == 0 /* from overlay */
13640 || pos <= tem)
13642 /* If the string from which this glyph came is
13643 found in the buffer at point, then we've
13644 found the glyph we've been looking for. If
13645 it comes from an overlay (tem == 0), and it
13646 has the `cursor' property on one of its
13647 glyphs, record that glyph as a candidate for
13648 displaying the cursor. (As in the
13649 unidirectional version, we will display the
13650 cursor on the last candidate we find.) */
13651 if (tem == 0 || tem == pt_old)
13653 /* The glyphs from this string could have
13654 been reordered. Find the one with the
13655 smallest string position. Or there could
13656 be a character in the string with the
13657 `cursor' property, which means display
13658 cursor on that character's glyph. */
13659 EMACS_INT strpos = glyph->charpos;
13661 if (tem)
13662 cursor = glyph;
13663 for ( ;
13664 (row->reversed_p ? glyph > stop : glyph < stop)
13665 && EQ (glyph->object, str);
13666 glyph += incr)
13668 Lisp_Object cprop;
13669 EMACS_INT gpos = glyph->charpos;
13671 cprop = Fget_char_property (make_number (gpos),
13672 Qcursor,
13673 glyph->object);
13674 if (!NILP (cprop))
13676 cursor = glyph;
13677 break;
13679 if (tem && glyph->charpos < strpos)
13681 strpos = glyph->charpos;
13682 cursor = glyph;
13686 if (tem == pt_old)
13687 goto compute_x;
13689 if (tem)
13690 pos = tem + 1; /* don't find previous instances */
13692 /* This string is not what we want; skip all of the
13693 glyphs that came from it. */
13694 while ((row->reversed_p ? glyph > stop : glyph < stop)
13695 && EQ (glyph->object, str))
13696 glyph += incr;
13698 else
13699 glyph += incr;
13702 /* If we reached the end of the line, and END was from a string,
13703 the cursor is not on this line. */
13704 if (cursor == NULL
13705 && (row->reversed_p ? glyph <= end : glyph >= end)
13706 && STRINGP (end->object)
13707 && row->continued_p)
13708 return 0;
13712 compute_x:
13713 if (cursor != NULL)
13714 glyph = cursor;
13715 if (x < 0)
13717 struct glyph *g;
13719 /* Need to compute x that corresponds to GLYPH. */
13720 for (g = row->glyphs[TEXT_AREA], x = row->x; g < glyph; g++)
13722 if (g >= row->glyphs[TEXT_AREA] + row->used[TEXT_AREA])
13723 abort ();
13724 x += g->pixel_width;
13728 /* ROW could be part of a continued line, which, under bidi
13729 reordering, might have other rows whose start and end charpos
13730 occlude point. Only set w->cursor if we found a better
13731 approximation to the cursor position than we have from previously
13732 examined candidate rows belonging to the same continued line. */
13733 if (/* we already have a candidate row */
13734 w->cursor.vpos >= 0
13735 /* that candidate is not the row we are processing */
13736 && MATRIX_ROW (matrix, w->cursor.vpos) != row
13737 /* the row we are processing is part of a continued line */
13738 && (row->continued_p || MATRIX_ROW_CONTINUATION_LINE_P (row))
13739 /* Make sure cursor.vpos specifies a row whose start and end
13740 charpos occlude point. This is because some callers of this
13741 function leave cursor.vpos at the row where the cursor was
13742 displayed during the last redisplay cycle. */
13743 && MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos)) <= pt_old
13744 && pt_old < MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos)))
13746 struct glyph *g1 =
13747 MATRIX_ROW_GLYPH_START (matrix, w->cursor.vpos) + w->cursor.hpos;
13749 /* Don't consider glyphs that are outside TEXT_AREA. */
13750 if (!(row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end))
13751 return 0;
13752 /* Keep the candidate whose buffer position is the closest to
13753 point. */
13754 if (/* previous candidate is a glyph in TEXT_AREA of that row */
13755 w->cursor.hpos >= 0
13756 && w->cursor.hpos < MATRIX_ROW_USED (matrix, w->cursor.vpos)
13757 && BUFFERP (g1->object)
13758 && (g1->charpos == pt_old /* an exact match always wins */
13759 || (BUFFERP (glyph->object)
13760 && eabs (g1->charpos - pt_old)
13761 < eabs (glyph->charpos - pt_old))))
13762 return 0;
13763 /* If this candidate gives an exact match, use that. */
13764 if (!(BUFFERP (glyph->object) && glyph->charpos == pt_old)
13765 /* Otherwise, keep the candidate that comes from a row
13766 spanning less buffer positions. This may win when one or
13767 both candidate positions are on glyphs that came from
13768 display strings, for which we cannot compare buffer
13769 positions. */
13770 && MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
13771 - MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
13772 < MATRIX_ROW_END_CHARPOS (row) - MATRIX_ROW_START_CHARPOS (row))
13773 return 0;
13775 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
13776 w->cursor.x = x;
13777 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
13778 w->cursor.y = row->y + dy;
13780 if (w == XWINDOW (selected_window))
13782 if (!row->continued_p
13783 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
13784 && row->x == 0)
13786 this_line_buffer = XBUFFER (w->buffer);
13788 CHARPOS (this_line_start_pos)
13789 = MATRIX_ROW_START_CHARPOS (row) + delta;
13790 BYTEPOS (this_line_start_pos)
13791 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
13793 CHARPOS (this_line_end_pos)
13794 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
13795 BYTEPOS (this_line_end_pos)
13796 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
13798 this_line_y = w->cursor.y;
13799 this_line_pixel_height = row->height;
13800 this_line_vpos = w->cursor.vpos;
13801 this_line_start_x = row->x;
13803 else
13804 CHARPOS (this_line_start_pos) = 0;
13807 return 1;
13811 /* Run window scroll functions, if any, for WINDOW with new window
13812 start STARTP. Sets the window start of WINDOW to that position.
13814 We assume that the window's buffer is really current. */
13816 static inline struct text_pos
13817 run_window_scroll_functions (Lisp_Object window, struct text_pos startp)
13819 struct window *w = XWINDOW (window);
13820 SET_MARKER_FROM_TEXT_POS (w->start, startp);
13822 if (current_buffer != XBUFFER (w->buffer))
13823 abort ();
13825 if (!NILP (Vwindow_scroll_functions))
13827 run_hook_with_args_2 (Qwindow_scroll_functions, window,
13828 make_number (CHARPOS (startp)));
13829 SET_TEXT_POS_FROM_MARKER (startp, w->start);
13830 /* In case the hook functions switch buffers. */
13831 if (current_buffer != XBUFFER (w->buffer))
13832 set_buffer_internal_1 (XBUFFER (w->buffer));
13835 return startp;
13839 /* Make sure the line containing the cursor is fully visible.
13840 A value of 1 means there is nothing to be done.
13841 (Either the line is fully visible, or it cannot be made so,
13842 or we cannot tell.)
13844 If FORCE_P is non-zero, return 0 even if partial visible cursor row
13845 is higher than window.
13847 A value of 0 means the caller should do scrolling
13848 as if point had gone off the screen. */
13850 static int
13851 cursor_row_fully_visible_p (struct window *w, int force_p, int current_matrix_p)
13853 struct glyph_matrix *matrix;
13854 struct glyph_row *row;
13855 int window_height;
13857 if (!make_cursor_line_fully_visible_p)
13858 return 1;
13860 /* It's not always possible to find the cursor, e.g, when a window
13861 is full of overlay strings. Don't do anything in that case. */
13862 if (w->cursor.vpos < 0)
13863 return 1;
13865 matrix = current_matrix_p ? w->current_matrix : w->desired_matrix;
13866 row = MATRIX_ROW (matrix, w->cursor.vpos);
13868 /* If the cursor row is not partially visible, there's nothing to do. */
13869 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row))
13870 return 1;
13872 /* If the row the cursor is in is taller than the window's height,
13873 it's not clear what to do, so do nothing. */
13874 window_height = window_box_height (w);
13875 if (row->height >= window_height)
13877 if (!force_p || MINI_WINDOW_P (w)
13878 || w->vscroll || w->cursor.vpos == 0)
13879 return 1;
13881 return 0;
13885 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
13886 non-zero means only WINDOW is redisplayed in redisplay_internal.
13887 TEMP_SCROLL_STEP has the same meaning as emacs_scroll_step, and is used
13888 in redisplay_window to bring a partially visible line into view in
13889 the case that only the cursor has moved.
13891 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
13892 last screen line's vertical height extends past the end of the screen.
13894 Value is
13896 1 if scrolling succeeded
13898 0 if scrolling didn't find point.
13900 -1 if new fonts have been loaded so that we must interrupt
13901 redisplay, adjust glyph matrices, and try again. */
13903 enum
13905 SCROLLING_SUCCESS,
13906 SCROLLING_FAILED,
13907 SCROLLING_NEED_LARGER_MATRICES
13910 /* If scroll-conservatively is more than this, never recenter.
13912 If you change this, don't forget to update the doc string of
13913 `scroll-conservatively' and the Emacs manual. */
13914 #define SCROLL_LIMIT 100
13916 static int
13917 try_scrolling (Lisp_Object window, int just_this_one_p,
13918 EMACS_INT arg_scroll_conservatively, EMACS_INT scroll_step,
13919 int temp_scroll_step, int last_line_misfit)
13921 struct window *w = XWINDOW (window);
13922 struct frame *f = XFRAME (w->frame);
13923 struct text_pos pos, startp;
13924 struct it it;
13925 int this_scroll_margin, scroll_max, rc, height;
13926 int dy = 0, amount_to_scroll = 0, scroll_down_p = 0;
13927 int extra_scroll_margin_lines = last_line_misfit ? 1 : 0;
13928 Lisp_Object aggressive;
13929 /* We will never try scrolling more than this number of lines. */
13930 int scroll_limit = SCROLL_LIMIT;
13932 #if GLYPH_DEBUG
13933 debug_method_add (w, "try_scrolling");
13934 #endif
13936 SET_TEXT_POS_FROM_MARKER (startp, w->start);
13938 /* Compute scroll margin height in pixels. We scroll when point is
13939 within this distance from the top or bottom of the window. */
13940 if (scroll_margin > 0)
13941 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4)
13942 * FRAME_LINE_HEIGHT (f);
13943 else
13944 this_scroll_margin = 0;
13946 /* Force arg_scroll_conservatively to have a reasonable value, to
13947 avoid scrolling too far away with slow move_it_* functions. Note
13948 that the user can supply scroll-conservatively equal to
13949 `most-positive-fixnum', which can be larger than INT_MAX. */
13950 if (arg_scroll_conservatively > scroll_limit)
13952 arg_scroll_conservatively = scroll_limit + 1;
13953 scroll_max = scroll_limit * FRAME_LINE_HEIGHT (f);
13955 else if (scroll_step || arg_scroll_conservatively || temp_scroll_step)
13956 /* Compute how much we should try to scroll maximally to bring
13957 point into view. */
13958 scroll_max = (max (scroll_step,
13959 max (arg_scroll_conservatively, temp_scroll_step))
13960 * FRAME_LINE_HEIGHT (f));
13961 else if (NUMBERP (BVAR (current_buffer, scroll_down_aggressively))
13962 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively)))
13963 /* We're trying to scroll because of aggressive scrolling but no
13964 scroll_step is set. Choose an arbitrary one. */
13965 scroll_max = 10 * FRAME_LINE_HEIGHT (f);
13966 else
13967 scroll_max = 0;
13969 too_near_end:
13971 /* Decide whether to scroll down. */
13972 if (PT > CHARPOS (startp))
13974 int scroll_margin_y;
13976 /* Compute the pixel ypos of the scroll margin, then move it to
13977 either that ypos or PT, whichever comes first. */
13978 start_display (&it, w, startp);
13979 scroll_margin_y = it.last_visible_y - this_scroll_margin
13980 - FRAME_LINE_HEIGHT (f) * extra_scroll_margin_lines;
13981 move_it_to (&it, PT, -1, scroll_margin_y - 1, -1,
13982 (MOVE_TO_POS | MOVE_TO_Y));
13984 if (PT > CHARPOS (it.current.pos))
13986 int y0 = line_bottom_y (&it);
13987 /* Compute how many pixels below window bottom to stop searching
13988 for PT. This avoids costly search for PT that is far away if
13989 the user limited scrolling by a small number of lines, but
13990 always finds PT if scroll_conservatively is set to a large
13991 number, such as most-positive-fixnum. */
13992 int slack = max (scroll_max, 10 * FRAME_LINE_HEIGHT (f));
13993 int y_to_move = it.last_visible_y + slack;
13995 /* Compute the distance from the scroll margin to PT or to
13996 the scroll limit, whichever comes first. This should
13997 include the height of the cursor line, to make that line
13998 fully visible. */
13999 move_it_to (&it, PT, -1, y_to_move,
14000 -1, MOVE_TO_POS | MOVE_TO_Y);
14001 dy = line_bottom_y (&it) - y0;
14003 if (dy > scroll_max)
14004 return SCROLLING_FAILED;
14006 scroll_down_p = 1;
14010 if (scroll_down_p)
14012 /* Point is in or below the bottom scroll margin, so move the
14013 window start down. If scrolling conservatively, move it just
14014 enough down to make point visible. If scroll_step is set,
14015 move it down by scroll_step. */
14016 if (arg_scroll_conservatively)
14017 amount_to_scroll
14018 = min (max (dy, FRAME_LINE_HEIGHT (f)),
14019 FRAME_LINE_HEIGHT (f) * arg_scroll_conservatively);
14020 else if (scroll_step || temp_scroll_step)
14021 amount_to_scroll = scroll_max;
14022 else
14024 aggressive = BVAR (current_buffer, scroll_up_aggressively);
14025 height = WINDOW_BOX_TEXT_HEIGHT (w);
14026 if (NUMBERP (aggressive))
14028 double float_amount = XFLOATINT (aggressive) * height;
14029 amount_to_scroll = float_amount;
14030 if (amount_to_scroll == 0 && float_amount > 0)
14031 amount_to_scroll = 1;
14032 /* Don't let point enter the scroll margin near top of
14033 the window. */
14034 if (amount_to_scroll > height - 2*this_scroll_margin + dy)
14035 amount_to_scroll = height - 2*this_scroll_margin + dy;
14039 if (amount_to_scroll <= 0)
14040 return SCROLLING_FAILED;
14042 start_display (&it, w, startp);
14043 if (arg_scroll_conservatively <= scroll_limit)
14044 move_it_vertically (&it, amount_to_scroll);
14045 else
14047 /* Extra precision for users who set scroll-conservatively
14048 to a large number: make sure the amount we scroll
14049 the window start is never less than amount_to_scroll,
14050 which was computed as distance from window bottom to
14051 point. This matters when lines at window top and lines
14052 below window bottom have different height. */
14053 struct it it1;
14054 void *it1data = NULL;
14055 /* We use a temporary it1 because line_bottom_y can modify
14056 its argument, if it moves one line down; see there. */
14057 int start_y;
14059 SAVE_IT (it1, it, it1data);
14060 start_y = line_bottom_y (&it1);
14061 do {
14062 RESTORE_IT (&it, &it, it1data);
14063 move_it_by_lines (&it, 1);
14064 SAVE_IT (it1, it, it1data);
14065 } while (line_bottom_y (&it1) - start_y < amount_to_scroll);
14068 /* If STARTP is unchanged, move it down another screen line. */
14069 if (CHARPOS (it.current.pos) == CHARPOS (startp))
14070 move_it_by_lines (&it, 1);
14071 startp = it.current.pos;
14073 else
14075 struct text_pos scroll_margin_pos = startp;
14077 /* See if point is inside the scroll margin at the top of the
14078 window. */
14079 if (this_scroll_margin)
14081 start_display (&it, w, startp);
14082 move_it_vertically (&it, this_scroll_margin);
14083 scroll_margin_pos = it.current.pos;
14086 if (PT < CHARPOS (scroll_margin_pos))
14088 /* Point is in the scroll margin at the top of the window or
14089 above what is displayed in the window. */
14090 int y0, y_to_move;
14092 /* Compute the vertical distance from PT to the scroll
14093 margin position. Move as far as scroll_max allows, or
14094 one screenful, or 10 screen lines, whichever is largest.
14095 Give up if distance is greater than scroll_max. */
14096 SET_TEXT_POS (pos, PT, PT_BYTE);
14097 start_display (&it, w, pos);
14098 y0 = it.current_y;
14099 y_to_move = max (it.last_visible_y,
14100 max (scroll_max, 10 * FRAME_LINE_HEIGHT (f)));
14101 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
14102 y_to_move, -1,
14103 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
14104 dy = it.current_y - y0;
14105 if (dy > scroll_max)
14106 return SCROLLING_FAILED;
14108 /* Compute new window start. */
14109 start_display (&it, w, startp);
14111 if (arg_scroll_conservatively)
14112 amount_to_scroll = max (dy, FRAME_LINE_HEIGHT (f) *
14113 max (scroll_step, temp_scroll_step));
14114 else if (scroll_step || temp_scroll_step)
14115 amount_to_scroll = scroll_max;
14116 else
14118 aggressive = BVAR (current_buffer, scroll_down_aggressively);
14119 height = WINDOW_BOX_TEXT_HEIGHT (w);
14120 if (NUMBERP (aggressive))
14122 double float_amount = XFLOATINT (aggressive) * height;
14123 amount_to_scroll = float_amount;
14124 if (amount_to_scroll == 0 && float_amount > 0)
14125 amount_to_scroll = 1;
14126 amount_to_scroll -=
14127 this_scroll_margin - dy - FRAME_LINE_HEIGHT (f);
14128 /* Don't let point enter the scroll margin near
14129 bottom of the window. */
14130 if (amount_to_scroll > height - 2*this_scroll_margin + dy)
14131 amount_to_scroll = height - 2*this_scroll_margin + dy;
14135 if (amount_to_scroll <= 0)
14136 return SCROLLING_FAILED;
14138 move_it_vertically_backward (&it, amount_to_scroll);
14139 startp = it.current.pos;
14143 /* Run window scroll functions. */
14144 startp = run_window_scroll_functions (window, startp);
14146 /* Display the window. Give up if new fonts are loaded, or if point
14147 doesn't appear. */
14148 if (!try_window (window, startp, 0))
14149 rc = SCROLLING_NEED_LARGER_MATRICES;
14150 else if (w->cursor.vpos < 0)
14152 clear_glyph_matrix (w->desired_matrix);
14153 rc = SCROLLING_FAILED;
14155 else
14157 /* Maybe forget recorded base line for line number display. */
14158 if (!just_this_one_p
14159 || current_buffer->clip_changed
14160 || BEG_UNCHANGED < CHARPOS (startp))
14161 w->base_line_number = Qnil;
14163 /* If cursor ends up on a partially visible line,
14164 treat that as being off the bottom of the screen. */
14165 if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1, 0)
14166 /* It's possible that the cursor is on the first line of the
14167 buffer, which is partially obscured due to a vscroll
14168 (Bug#7537). In that case, avoid looping forever . */
14169 && extra_scroll_margin_lines < w->desired_matrix->nrows - 1)
14171 clear_glyph_matrix (w->desired_matrix);
14172 ++extra_scroll_margin_lines;
14173 goto too_near_end;
14175 rc = SCROLLING_SUCCESS;
14178 return rc;
14182 /* Compute a suitable window start for window W if display of W starts
14183 on a continuation line. Value is non-zero if a new window start
14184 was computed.
14186 The new window start will be computed, based on W's width, starting
14187 from the start of the continued line. It is the start of the
14188 screen line with the minimum distance from the old start W->start. */
14190 static int
14191 compute_window_start_on_continuation_line (struct window *w)
14193 struct text_pos pos, start_pos;
14194 int window_start_changed_p = 0;
14196 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
14198 /* If window start is on a continuation line... Window start may be
14199 < BEGV in case there's invisible text at the start of the
14200 buffer (M-x rmail, for example). */
14201 if (CHARPOS (start_pos) > BEGV
14202 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
14204 struct it it;
14205 struct glyph_row *row;
14207 /* Handle the case that the window start is out of range. */
14208 if (CHARPOS (start_pos) < BEGV)
14209 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
14210 else if (CHARPOS (start_pos) > ZV)
14211 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
14213 /* Find the start of the continued line. This should be fast
14214 because scan_buffer is fast (newline cache). */
14215 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
14216 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
14217 row, DEFAULT_FACE_ID);
14218 reseat_at_previous_visible_line_start (&it);
14220 /* If the line start is "too far" away from the window start,
14221 say it takes too much time to compute a new window start. */
14222 if (CHARPOS (start_pos) - IT_CHARPOS (it)
14223 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
14225 int min_distance, distance;
14227 /* Move forward by display lines to find the new window
14228 start. If window width was enlarged, the new start can
14229 be expected to be > the old start. If window width was
14230 decreased, the new window start will be < the old start.
14231 So, we're looking for the display line start with the
14232 minimum distance from the old window start. */
14233 pos = it.current.pos;
14234 min_distance = INFINITY;
14235 while ((distance = eabs (CHARPOS (start_pos) - IT_CHARPOS (it))),
14236 distance < min_distance)
14238 min_distance = distance;
14239 pos = it.current.pos;
14240 move_it_by_lines (&it, 1);
14243 /* Set the window start there. */
14244 SET_MARKER_FROM_TEXT_POS (w->start, pos);
14245 window_start_changed_p = 1;
14249 return window_start_changed_p;
14253 /* Try cursor movement in case text has not changed in window WINDOW,
14254 with window start STARTP. Value is
14256 CURSOR_MOVEMENT_SUCCESS if successful
14258 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
14260 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
14261 display. *SCROLL_STEP is set to 1, under certain circumstances, if
14262 we want to scroll as if scroll-step were set to 1. See the code.
14264 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
14265 which case we have to abort this redisplay, and adjust matrices
14266 first. */
14268 enum
14270 CURSOR_MOVEMENT_SUCCESS,
14271 CURSOR_MOVEMENT_CANNOT_BE_USED,
14272 CURSOR_MOVEMENT_MUST_SCROLL,
14273 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
14276 static int
14277 try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_step)
14279 struct window *w = XWINDOW (window);
14280 struct frame *f = XFRAME (w->frame);
14281 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
14283 #if GLYPH_DEBUG
14284 if (inhibit_try_cursor_movement)
14285 return rc;
14286 #endif
14288 /* Handle case where text has not changed, only point, and it has
14289 not moved off the frame. */
14290 if (/* Point may be in this window. */
14291 PT >= CHARPOS (startp)
14292 /* Selective display hasn't changed. */
14293 && !current_buffer->clip_changed
14294 /* Function force-mode-line-update is used to force a thorough
14295 redisplay. It sets either windows_or_buffers_changed or
14296 update_mode_lines. So don't take a shortcut here for these
14297 cases. */
14298 && !update_mode_lines
14299 && !windows_or_buffers_changed
14300 && !cursor_type_changed
14301 /* Can't use this case if highlighting a region. When a
14302 region exists, cursor movement has to do more than just
14303 set the cursor. */
14304 && !(!NILP (Vtransient_mark_mode)
14305 && !NILP (BVAR (current_buffer, mark_active)))
14306 && NILP (w->region_showing)
14307 && NILP (Vshow_trailing_whitespace)
14308 /* Right after splitting windows, last_point may be nil. */
14309 && INTEGERP (w->last_point)
14310 /* This code is not used for mini-buffer for the sake of the case
14311 of redisplaying to replace an echo area message; since in
14312 that case the mini-buffer contents per se are usually
14313 unchanged. This code is of no real use in the mini-buffer
14314 since the handling of this_line_start_pos, etc., in redisplay
14315 handles the same cases. */
14316 && !EQ (window, minibuf_window)
14317 /* When splitting windows or for new windows, it happens that
14318 redisplay is called with a nil window_end_vpos or one being
14319 larger than the window. This should really be fixed in
14320 window.c. I don't have this on my list, now, so we do
14321 approximately the same as the old redisplay code. --gerd. */
14322 && INTEGERP (w->window_end_vpos)
14323 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
14324 && (FRAME_WINDOW_P (f)
14325 || !overlay_arrow_in_current_buffer_p ()))
14327 int this_scroll_margin, top_scroll_margin;
14328 struct glyph_row *row = NULL;
14330 #if GLYPH_DEBUG
14331 debug_method_add (w, "cursor movement");
14332 #endif
14334 /* Scroll if point within this distance from the top or bottom
14335 of the window. This is a pixel value. */
14336 if (scroll_margin > 0)
14338 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
14339 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
14341 else
14342 this_scroll_margin = 0;
14344 top_scroll_margin = this_scroll_margin;
14345 if (WINDOW_WANTS_HEADER_LINE_P (w))
14346 top_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w);
14348 /* Start with the row the cursor was displayed during the last
14349 not paused redisplay. Give up if that row is not valid. */
14350 if (w->last_cursor.vpos < 0
14351 || w->last_cursor.vpos >= w->current_matrix->nrows)
14352 rc = CURSOR_MOVEMENT_MUST_SCROLL;
14353 else
14355 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
14356 if (row->mode_line_p)
14357 ++row;
14358 if (!row->enabled_p)
14359 rc = CURSOR_MOVEMENT_MUST_SCROLL;
14362 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
14364 int scroll_p = 0, must_scroll = 0;
14365 int last_y = window_text_bottom_y (w) - this_scroll_margin;
14367 if (PT > XFASTINT (w->last_point))
14369 /* Point has moved forward. */
14370 while (MATRIX_ROW_END_CHARPOS (row) < PT
14371 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
14373 xassert (row->enabled_p);
14374 ++row;
14377 /* If the end position of a row equals the start
14378 position of the next row, and PT is at that position,
14379 we would rather display cursor in the next line. */
14380 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
14381 && MATRIX_ROW_END_CHARPOS (row) == PT
14382 && row < w->current_matrix->rows
14383 + w->current_matrix->nrows - 1
14384 && MATRIX_ROW_START_CHARPOS (row+1) == PT
14385 && !cursor_row_p (row))
14386 ++row;
14388 /* If within the scroll margin, scroll. Note that
14389 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
14390 the next line would be drawn, and that
14391 this_scroll_margin can be zero. */
14392 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
14393 || PT > MATRIX_ROW_END_CHARPOS (row)
14394 /* Line is completely visible last line in window
14395 and PT is to be set in the next line. */
14396 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
14397 && PT == MATRIX_ROW_END_CHARPOS (row)
14398 && !row->ends_at_zv_p
14399 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
14400 scroll_p = 1;
14402 else if (PT < XFASTINT (w->last_point))
14404 /* Cursor has to be moved backward. Note that PT >=
14405 CHARPOS (startp) because of the outer if-statement. */
14406 while (!row->mode_line_p
14407 && (MATRIX_ROW_START_CHARPOS (row) > PT
14408 || (MATRIX_ROW_START_CHARPOS (row) == PT
14409 && (MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)
14410 || (/* STARTS_IN_MIDDLE_OF_STRING_P (row) */
14411 row > w->current_matrix->rows
14412 && (row-1)->ends_in_newline_from_string_p))))
14413 && (row->y > top_scroll_margin
14414 || CHARPOS (startp) == BEGV))
14416 xassert (row->enabled_p);
14417 --row;
14420 /* Consider the following case: Window starts at BEGV,
14421 there is invisible, intangible text at BEGV, so that
14422 display starts at some point START > BEGV. It can
14423 happen that we are called with PT somewhere between
14424 BEGV and START. Try to handle that case. */
14425 if (row < w->current_matrix->rows
14426 || row->mode_line_p)
14428 row = w->current_matrix->rows;
14429 if (row->mode_line_p)
14430 ++row;
14433 /* Due to newlines in overlay strings, we may have to
14434 skip forward over overlay strings. */
14435 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
14436 && MATRIX_ROW_END_CHARPOS (row) == PT
14437 && !cursor_row_p (row))
14438 ++row;
14440 /* If within the scroll margin, scroll. */
14441 if (row->y < top_scroll_margin
14442 && CHARPOS (startp) != BEGV)
14443 scroll_p = 1;
14445 else
14447 /* Cursor did not move. So don't scroll even if cursor line
14448 is partially visible, as it was so before. */
14449 rc = CURSOR_MOVEMENT_SUCCESS;
14452 if (PT < MATRIX_ROW_START_CHARPOS (row)
14453 || PT > MATRIX_ROW_END_CHARPOS (row))
14455 /* if PT is not in the glyph row, give up. */
14456 rc = CURSOR_MOVEMENT_MUST_SCROLL;
14457 must_scroll = 1;
14459 else if (rc != CURSOR_MOVEMENT_SUCCESS
14460 && !NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering)))
14462 /* If rows are bidi-reordered and point moved, back up
14463 until we find a row that does not belong to a
14464 continuation line. This is because we must consider
14465 all rows of a continued line as candidates for the
14466 new cursor positioning, since row start and end
14467 positions change non-linearly with vertical position
14468 in such rows. */
14469 /* FIXME: Revisit this when glyph ``spilling'' in
14470 continuation lines' rows is implemented for
14471 bidi-reordered rows. */
14472 while (MATRIX_ROW_CONTINUATION_LINE_P (row))
14474 xassert (row->enabled_p);
14475 --row;
14476 /* If we hit the beginning of the displayed portion
14477 without finding the first row of a continued
14478 line, give up. */
14479 if (row <= w->current_matrix->rows)
14481 rc = CURSOR_MOVEMENT_MUST_SCROLL;
14482 break;
14487 if (must_scroll)
14489 else if (rc != CURSOR_MOVEMENT_SUCCESS
14490 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
14491 && make_cursor_line_fully_visible_p)
14493 if (PT == MATRIX_ROW_END_CHARPOS (row)
14494 && !row->ends_at_zv_p
14495 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
14496 rc = CURSOR_MOVEMENT_MUST_SCROLL;
14497 else if (row->height > window_box_height (w))
14499 /* If we end up in a partially visible line, let's
14500 make it fully visible, except when it's taller
14501 than the window, in which case we can't do much
14502 about it. */
14503 *scroll_step = 1;
14504 rc = CURSOR_MOVEMENT_MUST_SCROLL;
14506 else
14508 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
14509 if (!cursor_row_fully_visible_p (w, 0, 1))
14510 rc = CURSOR_MOVEMENT_MUST_SCROLL;
14511 else
14512 rc = CURSOR_MOVEMENT_SUCCESS;
14515 else if (scroll_p)
14516 rc = CURSOR_MOVEMENT_MUST_SCROLL;
14517 else if (rc != CURSOR_MOVEMENT_SUCCESS
14518 && !NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering)))
14520 /* With bidi-reordered rows, there could be more than
14521 one candidate row whose start and end positions
14522 occlude point. We need to let set_cursor_from_row
14523 find the best candidate. */
14524 /* FIXME: Revisit this when glyph ``spilling'' in
14525 continuation lines' rows is implemented for
14526 bidi-reordered rows. */
14527 int rv = 0;
14531 if (MATRIX_ROW_START_CHARPOS (row) <= PT
14532 && PT <= MATRIX_ROW_END_CHARPOS (row)
14533 && cursor_row_p (row))
14534 rv |= set_cursor_from_row (w, row, w->current_matrix,
14535 0, 0, 0, 0);
14536 /* As soon as we've found the first suitable row
14537 whose ends_at_zv_p flag is set, we are done. */
14538 if (rv
14539 && MATRIX_ROW (w->current_matrix, w->cursor.vpos)->ends_at_zv_p)
14541 rc = CURSOR_MOVEMENT_SUCCESS;
14542 break;
14544 ++row;
14546 while ((MATRIX_ROW_CONTINUATION_LINE_P (row)
14547 && MATRIX_ROW_BOTTOM_Y (row) <= last_y)
14548 || (MATRIX_ROW_START_CHARPOS (row) == PT
14549 && MATRIX_ROW_BOTTOM_Y (row) < last_y));
14550 /* If we didn't find any candidate rows, or exited the
14551 loop before all the candidates were examined, signal
14552 to the caller that this method failed. */
14553 if (rc != CURSOR_MOVEMENT_SUCCESS
14554 && (!rv || MATRIX_ROW_CONTINUATION_LINE_P (row)))
14555 rc = CURSOR_MOVEMENT_MUST_SCROLL;
14556 else if (rv)
14557 rc = CURSOR_MOVEMENT_SUCCESS;
14559 else
14563 if (set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0))
14565 rc = CURSOR_MOVEMENT_SUCCESS;
14566 break;
14568 ++row;
14570 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
14571 && MATRIX_ROW_START_CHARPOS (row) == PT
14572 && cursor_row_p (row));
14577 return rc;
14580 #if !defined USE_TOOLKIT_SCROLL_BARS || defined USE_GTK
14581 static
14582 #endif
14583 void
14584 set_vertical_scroll_bar (struct window *w)
14586 EMACS_INT start, end, whole;
14588 /* Calculate the start and end positions for the current window.
14589 At some point, it would be nice to choose between scrollbars
14590 which reflect the whole buffer size, with special markers
14591 indicating narrowing, and scrollbars which reflect only the
14592 visible region.
14594 Note that mini-buffers sometimes aren't displaying any text. */
14595 if (!MINI_WINDOW_P (w)
14596 || (w == XWINDOW (minibuf_window)
14597 && NILP (echo_area_buffer[0])))
14599 struct buffer *buf = XBUFFER (w->buffer);
14600 whole = BUF_ZV (buf) - BUF_BEGV (buf);
14601 start = marker_position (w->start) - BUF_BEGV (buf);
14602 /* I don't think this is guaranteed to be right. For the
14603 moment, we'll pretend it is. */
14604 end = BUF_Z (buf) - XFASTINT (w->window_end_pos) - BUF_BEGV (buf);
14606 if (end < start)
14607 end = start;
14608 if (whole < (end - start))
14609 whole = end - start;
14611 else
14612 start = end = whole = 0;
14614 /* Indicate what this scroll bar ought to be displaying now. */
14615 if (FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
14616 (*FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
14617 (w, end - start, whole, start);
14621 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
14622 selected_window is redisplayed.
14624 We can return without actually redisplaying the window if
14625 fonts_changed_p is nonzero. In that case, redisplay_internal will
14626 retry. */
14628 static void
14629 redisplay_window (Lisp_Object window, int just_this_one_p)
14631 struct window *w = XWINDOW (window);
14632 struct frame *f = XFRAME (w->frame);
14633 struct buffer *buffer = XBUFFER (w->buffer);
14634 struct buffer *old = current_buffer;
14635 struct text_pos lpoint, opoint, startp;
14636 int update_mode_line;
14637 int tem;
14638 struct it it;
14639 /* Record it now because it's overwritten. */
14640 int current_matrix_up_to_date_p = 0;
14641 int used_current_matrix_p = 0;
14642 /* This is less strict than current_matrix_up_to_date_p.
14643 It indictes that the buffer contents and narrowing are unchanged. */
14644 int buffer_unchanged_p = 0;
14645 int temp_scroll_step = 0;
14646 int count = SPECPDL_INDEX ();
14647 int rc;
14648 int centering_position = -1;
14649 int last_line_misfit = 0;
14650 EMACS_INT beg_unchanged, end_unchanged;
14652 SET_TEXT_POS (lpoint, PT, PT_BYTE);
14653 opoint = lpoint;
14655 /* W must be a leaf window here. */
14656 xassert (!NILP (w->buffer));
14657 #if GLYPH_DEBUG
14658 *w->desired_matrix->method = 0;
14659 #endif
14661 restart:
14662 reconsider_clip_changes (w, buffer);
14664 /* Has the mode line to be updated? */
14665 update_mode_line = (!NILP (w->update_mode_line)
14666 || update_mode_lines
14667 || buffer->clip_changed
14668 || buffer->prevent_redisplay_optimizations_p);
14670 if (MINI_WINDOW_P (w))
14672 if (w == XWINDOW (echo_area_window)
14673 && !NILP (echo_area_buffer[0]))
14675 if (update_mode_line)
14676 /* We may have to update a tty frame's menu bar or a
14677 tool-bar. Example `M-x C-h C-h C-g'. */
14678 goto finish_menu_bars;
14679 else
14680 /* We've already displayed the echo area glyphs in this window. */
14681 goto finish_scroll_bars;
14683 else if ((w != XWINDOW (minibuf_window)
14684 || minibuf_level == 0)
14685 /* When buffer is nonempty, redisplay window normally. */
14686 && BUF_Z (XBUFFER (w->buffer)) == BUF_BEG (XBUFFER (w->buffer))
14687 /* Quail displays non-mini buffers in minibuffer window.
14688 In that case, redisplay the window normally. */
14689 && !NILP (Fmemq (w->buffer, Vminibuffer_list)))
14691 /* W is a mini-buffer window, but it's not active, so clear
14692 it. */
14693 int yb = window_text_bottom_y (w);
14694 struct glyph_row *row;
14695 int y;
14697 for (y = 0, row = w->desired_matrix->rows;
14698 y < yb;
14699 y += row->height, ++row)
14700 blank_row (w, row, y);
14701 goto finish_scroll_bars;
14704 clear_glyph_matrix (w->desired_matrix);
14707 /* Otherwise set up data on this window; select its buffer and point
14708 value. */
14709 /* Really select the buffer, for the sake of buffer-local
14710 variables. */
14711 set_buffer_internal_1 (XBUFFER (w->buffer));
14713 current_matrix_up_to_date_p
14714 = (!NILP (w->window_end_valid)
14715 && !current_buffer->clip_changed
14716 && !current_buffer->prevent_redisplay_optimizations_p
14717 && XFASTINT (w->last_modified) >= MODIFF
14718 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
14720 /* Run the window-bottom-change-functions
14721 if it is possible that the text on the screen has changed
14722 (either due to modification of the text, or any other reason). */
14723 if (!current_matrix_up_to_date_p
14724 && !NILP (Vwindow_text_change_functions))
14726 safe_run_hooks (Qwindow_text_change_functions);
14727 goto restart;
14730 beg_unchanged = BEG_UNCHANGED;
14731 end_unchanged = END_UNCHANGED;
14733 SET_TEXT_POS (opoint, PT, PT_BYTE);
14735 specbind (Qinhibit_point_motion_hooks, Qt);
14737 buffer_unchanged_p
14738 = (!NILP (w->window_end_valid)
14739 && !current_buffer->clip_changed
14740 && XFASTINT (w->last_modified) >= MODIFF
14741 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
14743 /* When windows_or_buffers_changed is non-zero, we can't rely on
14744 the window end being valid, so set it to nil there. */
14745 if (windows_or_buffers_changed)
14747 /* If window starts on a continuation line, maybe adjust the
14748 window start in case the window's width changed. */
14749 if (XMARKER (w->start)->buffer == current_buffer)
14750 compute_window_start_on_continuation_line (w);
14752 w->window_end_valid = Qnil;
14755 /* Some sanity checks. */
14756 CHECK_WINDOW_END (w);
14757 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
14758 abort ();
14759 if (BYTEPOS (opoint) < CHARPOS (opoint))
14760 abort ();
14762 /* If %c is in mode line, update it if needed. */
14763 if (!NILP (w->column_number_displayed)
14764 /* This alternative quickly identifies a common case
14765 where no change is needed. */
14766 && !(PT == XFASTINT (w->last_point)
14767 && XFASTINT (w->last_modified) >= MODIFF
14768 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
14769 && (XFASTINT (w->column_number_displayed) != current_column ()))
14770 update_mode_line = 1;
14772 /* Count number of windows showing the selected buffer. An indirect
14773 buffer counts as its base buffer. */
14774 if (!just_this_one_p)
14776 struct buffer *current_base, *window_base;
14777 current_base = current_buffer;
14778 window_base = XBUFFER (XWINDOW (selected_window)->buffer);
14779 if (current_base->base_buffer)
14780 current_base = current_base->base_buffer;
14781 if (window_base->base_buffer)
14782 window_base = window_base->base_buffer;
14783 if (current_base == window_base)
14784 buffer_shared++;
14787 /* Point refers normally to the selected window. For any other
14788 window, set up appropriate value. */
14789 if (!EQ (window, selected_window))
14791 EMACS_INT new_pt = XMARKER (w->pointm)->charpos;
14792 EMACS_INT new_pt_byte = marker_byte_position (w->pointm);
14793 if (new_pt < BEGV)
14795 new_pt = BEGV;
14796 new_pt_byte = BEGV_BYTE;
14797 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
14799 else if (new_pt > (ZV - 1))
14801 new_pt = ZV;
14802 new_pt_byte = ZV_BYTE;
14803 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
14806 /* We don't use SET_PT so that the point-motion hooks don't run. */
14807 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
14810 /* If any of the character widths specified in the display table
14811 have changed, invalidate the width run cache. It's true that
14812 this may be a bit late to catch such changes, but the rest of
14813 redisplay goes (non-fatally) haywire when the display table is
14814 changed, so why should we worry about doing any better? */
14815 if (current_buffer->width_run_cache)
14817 struct Lisp_Char_Table *disptab = buffer_display_table ();
14819 if (! disptab_matches_widthtab (disptab,
14820 XVECTOR (BVAR (current_buffer, width_table))))
14822 invalidate_region_cache (current_buffer,
14823 current_buffer->width_run_cache,
14824 BEG, Z);
14825 recompute_width_table (current_buffer, disptab);
14829 /* If window-start is screwed up, choose a new one. */
14830 if (XMARKER (w->start)->buffer != current_buffer)
14831 goto recenter;
14833 SET_TEXT_POS_FROM_MARKER (startp, w->start);
14835 /* If someone specified a new starting point but did not insist,
14836 check whether it can be used. */
14837 if (!NILP (w->optional_new_start)
14838 && CHARPOS (startp) >= BEGV
14839 && CHARPOS (startp) <= ZV)
14841 w->optional_new_start = Qnil;
14842 start_display (&it, w, startp);
14843 move_it_to (&it, PT, 0, it.last_visible_y, -1,
14844 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
14845 if (IT_CHARPOS (it) == PT)
14846 w->force_start = Qt;
14847 /* IT may overshoot PT if text at PT is invisible. */
14848 else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT)
14849 w->force_start = Qt;
14852 force_start:
14854 /* Handle case where place to start displaying has been specified,
14855 unless the specified location is outside the accessible range. */
14856 if (!NILP (w->force_start)
14857 || w->frozen_window_start_p)
14859 /* We set this later on if we have to adjust point. */
14860 int new_vpos = -1;
14862 w->force_start = Qnil;
14863 w->vscroll = 0;
14864 w->window_end_valid = Qnil;
14866 /* Forget any recorded base line for line number display. */
14867 if (!buffer_unchanged_p)
14868 w->base_line_number = Qnil;
14870 /* Redisplay the mode line. Select the buffer properly for that.
14871 Also, run the hook window-scroll-functions
14872 because we have scrolled. */
14873 /* Note, we do this after clearing force_start because
14874 if there's an error, it is better to forget about force_start
14875 than to get into an infinite loop calling the hook functions
14876 and having them get more errors. */
14877 if (!update_mode_line
14878 || ! NILP (Vwindow_scroll_functions))
14880 update_mode_line = 1;
14881 w->update_mode_line = Qt;
14882 startp = run_window_scroll_functions (window, startp);
14885 w->last_modified = make_number (0);
14886 w->last_overlay_modified = make_number (0);
14887 if (CHARPOS (startp) < BEGV)
14888 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
14889 else if (CHARPOS (startp) > ZV)
14890 SET_TEXT_POS (startp, ZV, ZV_BYTE);
14892 /* Redisplay, then check if cursor has been set during the
14893 redisplay. Give up if new fonts were loaded. */
14894 /* We used to issue a CHECK_MARGINS argument to try_window here,
14895 but this causes scrolling to fail when point begins inside
14896 the scroll margin (bug#148) -- cyd */
14897 if (!try_window (window, startp, 0))
14899 w->force_start = Qt;
14900 clear_glyph_matrix (w->desired_matrix);
14901 goto need_larger_matrices;
14904 if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
14906 /* If point does not appear, try to move point so it does
14907 appear. The desired matrix has been built above, so we
14908 can use it here. */
14909 new_vpos = window_box_height (w) / 2;
14912 if (!cursor_row_fully_visible_p (w, 0, 0))
14914 /* Point does appear, but on a line partly visible at end of window.
14915 Move it back to a fully-visible line. */
14916 new_vpos = window_box_height (w);
14919 /* If we need to move point for either of the above reasons,
14920 now actually do it. */
14921 if (new_vpos >= 0)
14923 struct glyph_row *row;
14925 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
14926 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
14927 ++row;
14929 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
14930 MATRIX_ROW_START_BYTEPOS (row));
14932 if (w != XWINDOW (selected_window))
14933 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
14934 else if (current_buffer == old)
14935 SET_TEXT_POS (lpoint, PT, PT_BYTE);
14937 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
14939 /* If we are highlighting the region, then we just changed
14940 the region, so redisplay to show it. */
14941 if (!NILP (Vtransient_mark_mode)
14942 && !NILP (BVAR (current_buffer, mark_active)))
14944 clear_glyph_matrix (w->desired_matrix);
14945 if (!try_window (window, startp, 0))
14946 goto need_larger_matrices;
14950 #if GLYPH_DEBUG
14951 debug_method_add (w, "forced window start");
14952 #endif
14953 goto done;
14956 /* Handle case where text has not changed, only point, and it has
14957 not moved off the frame, and we are not retrying after hscroll.
14958 (current_matrix_up_to_date_p is nonzero when retrying.) */
14959 if (current_matrix_up_to_date_p
14960 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
14961 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
14963 switch (rc)
14965 case CURSOR_MOVEMENT_SUCCESS:
14966 used_current_matrix_p = 1;
14967 goto done;
14969 case CURSOR_MOVEMENT_MUST_SCROLL:
14970 goto try_to_scroll;
14972 default:
14973 abort ();
14976 /* If current starting point was originally the beginning of a line
14977 but no longer is, find a new starting point. */
14978 else if (!NILP (w->start_at_line_beg)
14979 && !(CHARPOS (startp) <= BEGV
14980 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
14982 #if GLYPH_DEBUG
14983 debug_method_add (w, "recenter 1");
14984 #endif
14985 goto recenter;
14988 /* Try scrolling with try_window_id. Value is > 0 if update has
14989 been done, it is -1 if we know that the same window start will
14990 not work. It is 0 if unsuccessful for some other reason. */
14991 else if ((tem = try_window_id (w)) != 0)
14993 #if GLYPH_DEBUG
14994 debug_method_add (w, "try_window_id %d", tem);
14995 #endif
14997 if (fonts_changed_p)
14998 goto need_larger_matrices;
14999 if (tem > 0)
15000 goto done;
15002 /* Otherwise try_window_id has returned -1 which means that we
15003 don't want the alternative below this comment to execute. */
15005 else if (CHARPOS (startp) >= BEGV
15006 && CHARPOS (startp) <= ZV
15007 && PT >= CHARPOS (startp)
15008 && (CHARPOS (startp) < ZV
15009 /* Avoid starting at end of buffer. */
15010 || CHARPOS (startp) == BEGV
15011 || (XFASTINT (w->last_modified) >= MODIFF
15012 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)))
15015 /* If first window line is a continuation line, and window start
15016 is inside the modified region, but the first change is before
15017 current window start, we must select a new window start.
15019 However, if this is the result of a down-mouse event (e.g. by
15020 extending the mouse-drag-overlay), we don't want to select a
15021 new window start, since that would change the position under
15022 the mouse, resulting in an unwanted mouse-movement rather
15023 than a simple mouse-click. */
15024 if (NILP (w->start_at_line_beg)
15025 && NILP (do_mouse_tracking)
15026 && CHARPOS (startp) > BEGV
15027 && CHARPOS (startp) > BEG + beg_unchanged
15028 && CHARPOS (startp) <= Z - end_unchanged
15029 /* Even if w->start_at_line_beg is nil, a new window may
15030 start at a line_beg, since that's how set_buffer_window
15031 sets it. So, we need to check the return value of
15032 compute_window_start_on_continuation_line. (See also
15033 bug#197). */
15034 && XMARKER (w->start)->buffer == current_buffer
15035 && compute_window_start_on_continuation_line (w))
15037 w->force_start = Qt;
15038 SET_TEXT_POS_FROM_MARKER (startp, w->start);
15039 goto force_start;
15042 #if GLYPH_DEBUG
15043 debug_method_add (w, "same window start");
15044 #endif
15046 /* Try to redisplay starting at same place as before.
15047 If point has not moved off frame, accept the results. */
15048 if (!current_matrix_up_to_date_p
15049 /* Don't use try_window_reusing_current_matrix in this case
15050 because a window scroll function can have changed the
15051 buffer. */
15052 || !NILP (Vwindow_scroll_functions)
15053 || MINI_WINDOW_P (w)
15054 || !(used_current_matrix_p
15055 = try_window_reusing_current_matrix (w)))
15057 IF_DEBUG (debug_method_add (w, "1"));
15058 if (try_window (window, startp, TRY_WINDOW_CHECK_MARGINS) < 0)
15059 /* -1 means we need to scroll.
15060 0 means we need new matrices, but fonts_changed_p
15061 is set in that case, so we will detect it below. */
15062 goto try_to_scroll;
15065 if (fonts_changed_p)
15066 goto need_larger_matrices;
15068 if (w->cursor.vpos >= 0)
15070 if (!just_this_one_p
15071 || current_buffer->clip_changed
15072 || BEG_UNCHANGED < CHARPOS (startp))
15073 /* Forget any recorded base line for line number display. */
15074 w->base_line_number = Qnil;
15076 if (!cursor_row_fully_visible_p (w, 1, 0))
15078 clear_glyph_matrix (w->desired_matrix);
15079 last_line_misfit = 1;
15081 /* Drop through and scroll. */
15082 else
15083 goto done;
15085 else
15086 clear_glyph_matrix (w->desired_matrix);
15089 try_to_scroll:
15091 w->last_modified = make_number (0);
15092 w->last_overlay_modified = make_number (0);
15094 /* Redisplay the mode line. Select the buffer properly for that. */
15095 if (!update_mode_line)
15097 update_mode_line = 1;
15098 w->update_mode_line = Qt;
15101 /* Try to scroll by specified few lines. */
15102 if ((scroll_conservatively
15103 || emacs_scroll_step
15104 || temp_scroll_step
15105 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively))
15106 || NUMBERP (BVAR (current_buffer, scroll_down_aggressively)))
15107 && CHARPOS (startp) >= BEGV
15108 && CHARPOS (startp) <= ZV)
15110 /* The function returns -1 if new fonts were loaded, 1 if
15111 successful, 0 if not successful. */
15112 int ss = try_scrolling (window, just_this_one_p,
15113 scroll_conservatively,
15114 emacs_scroll_step,
15115 temp_scroll_step, last_line_misfit);
15116 switch (ss)
15118 case SCROLLING_SUCCESS:
15119 goto done;
15121 case SCROLLING_NEED_LARGER_MATRICES:
15122 goto need_larger_matrices;
15124 case SCROLLING_FAILED:
15125 break;
15127 default:
15128 abort ();
15132 /* Finally, just choose a place to start which positions point
15133 according to user preferences. */
15135 recenter:
15137 #if GLYPH_DEBUG
15138 debug_method_add (w, "recenter");
15139 #endif
15141 /* w->vscroll = 0; */
15143 /* Forget any previously recorded base line for line number display. */
15144 if (!buffer_unchanged_p)
15145 w->base_line_number = Qnil;
15147 /* Determine the window start relative to point. */
15148 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
15149 it.current_y = it.last_visible_y;
15150 if (centering_position < 0)
15152 int margin =
15153 scroll_margin > 0
15154 ? min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4)
15155 : 0;
15156 EMACS_INT margin_pos = CHARPOS (startp);
15157 int scrolling_up;
15158 Lisp_Object aggressive;
15160 /* If there is a scroll margin at the top of the window, find
15161 its character position. */
15162 if (margin
15163 /* Cannot call start_display if startp is not in the
15164 accessible region of the buffer. This can happen when we
15165 have just switched to a different buffer and/or changed
15166 its restriction. In that case, startp is initialized to
15167 the character position 1 (BEG) because we did not yet
15168 have chance to display the buffer even once. */
15169 && BEGV <= CHARPOS (startp) && CHARPOS (startp) <= ZV)
15171 struct it it1;
15172 void *it1data = NULL;
15174 SAVE_IT (it1, it, it1data);
15175 start_display (&it1, w, startp);
15176 move_it_vertically (&it1, margin);
15177 margin_pos = IT_CHARPOS (it1);
15178 RESTORE_IT (&it, &it, it1data);
15180 scrolling_up = PT > margin_pos;
15181 aggressive =
15182 scrolling_up
15183 ? BVAR (current_buffer, scroll_up_aggressively)
15184 : BVAR (current_buffer, scroll_down_aggressively);
15186 if (!MINI_WINDOW_P (w)
15187 && (scroll_conservatively > SCROLL_LIMIT || NUMBERP (aggressive)))
15189 int pt_offset = 0;
15191 /* Setting scroll-conservatively overrides
15192 scroll-*-aggressively. */
15193 if (!scroll_conservatively && NUMBERP (aggressive))
15195 double float_amount = XFLOATINT (aggressive);
15197 pt_offset = float_amount * WINDOW_BOX_TEXT_HEIGHT (w);
15198 if (pt_offset == 0 && float_amount > 0)
15199 pt_offset = 1;
15200 if (pt_offset)
15201 margin -= 1;
15203 /* Compute how much to move the window start backward from
15204 point so that point will be displayed where the user
15205 wants it. */
15206 if (scrolling_up)
15208 centering_position = it.last_visible_y;
15209 if (pt_offset)
15210 centering_position -= pt_offset;
15211 centering_position -=
15212 FRAME_LINE_HEIGHT (f) * (1 + margin + (last_line_misfit != 0));
15213 /* Don't let point enter the scroll margin near top of
15214 the window. */
15215 if (centering_position < margin * FRAME_LINE_HEIGHT (f))
15216 centering_position = margin * FRAME_LINE_HEIGHT (f);
15218 else
15219 centering_position = margin * FRAME_LINE_HEIGHT (f) + pt_offset;
15221 else
15222 /* Set the window start half the height of the window backward
15223 from point. */
15224 centering_position = window_box_height (w) / 2;
15226 move_it_vertically_backward (&it, centering_position);
15228 xassert (IT_CHARPOS (it) >= BEGV);
15230 /* The function move_it_vertically_backward may move over more
15231 than the specified y-distance. If it->w is small, e.g. a
15232 mini-buffer window, we may end up in front of the window's
15233 display area. Start displaying at the start of the line
15234 containing PT in this case. */
15235 if (it.current_y <= 0)
15237 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
15238 move_it_vertically_backward (&it, 0);
15239 it.current_y = 0;
15242 it.current_x = it.hpos = 0;
15244 /* Set the window start position here explicitly, to avoid an
15245 infinite loop in case the functions in window-scroll-functions
15246 get errors. */
15247 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
15249 /* Run scroll hooks. */
15250 startp = run_window_scroll_functions (window, it.current.pos);
15252 /* Redisplay the window. */
15253 if (!current_matrix_up_to_date_p
15254 || windows_or_buffers_changed
15255 || cursor_type_changed
15256 /* Don't use try_window_reusing_current_matrix in this case
15257 because it can have changed the buffer. */
15258 || !NILP (Vwindow_scroll_functions)
15259 || !just_this_one_p
15260 || MINI_WINDOW_P (w)
15261 || !(used_current_matrix_p
15262 = try_window_reusing_current_matrix (w)))
15263 try_window (window, startp, 0);
15265 /* If new fonts have been loaded (due to fontsets), give up. We
15266 have to start a new redisplay since we need to re-adjust glyph
15267 matrices. */
15268 if (fonts_changed_p)
15269 goto need_larger_matrices;
15271 /* If cursor did not appear assume that the middle of the window is
15272 in the first line of the window. Do it again with the next line.
15273 (Imagine a window of height 100, displaying two lines of height
15274 60. Moving back 50 from it->last_visible_y will end in the first
15275 line.) */
15276 if (w->cursor.vpos < 0)
15278 if (!NILP (w->window_end_valid)
15279 && PT >= Z - XFASTINT (w->window_end_pos))
15281 clear_glyph_matrix (w->desired_matrix);
15282 move_it_by_lines (&it, 1);
15283 try_window (window, it.current.pos, 0);
15285 else if (PT < IT_CHARPOS (it))
15287 clear_glyph_matrix (w->desired_matrix);
15288 move_it_by_lines (&it, -1);
15289 try_window (window, it.current.pos, 0);
15291 else
15293 /* Not much we can do about it. */
15297 /* Consider the following case: Window starts at BEGV, there is
15298 invisible, intangible text at BEGV, so that display starts at
15299 some point START > BEGV. It can happen that we are called with
15300 PT somewhere between BEGV and START. Try to handle that case. */
15301 if (w->cursor.vpos < 0)
15303 struct glyph_row *row = w->current_matrix->rows;
15304 if (row->mode_line_p)
15305 ++row;
15306 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
15309 if (!cursor_row_fully_visible_p (w, 0, 0))
15311 /* If vscroll is enabled, disable it and try again. */
15312 if (w->vscroll)
15314 w->vscroll = 0;
15315 clear_glyph_matrix (w->desired_matrix);
15316 goto recenter;
15319 /* If centering point failed to make the whole line visible,
15320 put point at the top instead. That has to make the whole line
15321 visible, if it can be done. */
15322 if (centering_position == 0)
15323 goto done;
15325 clear_glyph_matrix (w->desired_matrix);
15326 centering_position = 0;
15327 goto recenter;
15330 done:
15332 SET_TEXT_POS_FROM_MARKER (startp, w->start);
15333 w->start_at_line_beg = ((CHARPOS (startp) == BEGV
15334 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n')
15335 ? Qt : Qnil);
15337 /* Display the mode line, if we must. */
15338 if ((update_mode_line
15339 /* If window not full width, must redo its mode line
15340 if (a) the window to its side is being redone and
15341 (b) we do a frame-based redisplay. This is a consequence
15342 of how inverted lines are drawn in frame-based redisplay. */
15343 || (!just_this_one_p
15344 && !FRAME_WINDOW_P (f)
15345 && !WINDOW_FULL_WIDTH_P (w))
15346 /* Line number to display. */
15347 || INTEGERP (w->base_line_pos)
15348 /* Column number is displayed and different from the one displayed. */
15349 || (!NILP (w->column_number_displayed)
15350 && (XFASTINT (w->column_number_displayed) != current_column ())))
15351 /* This means that the window has a mode line. */
15352 && (WINDOW_WANTS_MODELINE_P (w)
15353 || WINDOW_WANTS_HEADER_LINE_P (w)))
15355 display_mode_lines (w);
15357 /* If mode line height has changed, arrange for a thorough
15358 immediate redisplay using the correct mode line height. */
15359 if (WINDOW_WANTS_MODELINE_P (w)
15360 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
15362 fonts_changed_p = 1;
15363 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
15364 = DESIRED_MODE_LINE_HEIGHT (w);
15367 /* If header line height has changed, arrange for a thorough
15368 immediate redisplay using the correct header line height. */
15369 if (WINDOW_WANTS_HEADER_LINE_P (w)
15370 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
15372 fonts_changed_p = 1;
15373 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
15374 = DESIRED_HEADER_LINE_HEIGHT (w);
15377 if (fonts_changed_p)
15378 goto need_larger_matrices;
15381 if (!line_number_displayed
15382 && !BUFFERP (w->base_line_pos))
15384 w->base_line_pos = Qnil;
15385 w->base_line_number = Qnil;
15388 finish_menu_bars:
15390 /* When we reach a frame's selected window, redo the frame's menu bar. */
15391 if (update_mode_line
15392 && EQ (FRAME_SELECTED_WINDOW (f), window))
15394 int redisplay_menu_p = 0;
15396 if (FRAME_WINDOW_P (f))
15398 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
15399 || defined (HAVE_NS) || defined (USE_GTK)
15400 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
15401 #else
15402 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
15403 #endif
15405 else
15406 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
15408 if (redisplay_menu_p)
15409 display_menu_bar (w);
15411 #ifdef HAVE_WINDOW_SYSTEM
15412 if (FRAME_WINDOW_P (f))
15414 #if defined (USE_GTK) || defined (HAVE_NS)
15415 if (FRAME_EXTERNAL_TOOL_BAR (f))
15416 redisplay_tool_bar (f);
15417 #else
15418 if (WINDOWP (f->tool_bar_window)
15419 && (FRAME_TOOL_BAR_LINES (f) > 0
15420 || !NILP (Vauto_resize_tool_bars))
15421 && redisplay_tool_bar (f))
15422 ignore_mouse_drag_p = 1;
15423 #endif
15425 #endif
15428 #ifdef HAVE_WINDOW_SYSTEM
15429 if (FRAME_WINDOW_P (f)
15430 && update_window_fringes (w, (just_this_one_p
15431 || (!used_current_matrix_p && !overlay_arrow_seen)
15432 || w->pseudo_window_p)))
15434 update_begin (f);
15435 BLOCK_INPUT;
15436 if (draw_window_fringes (w, 1))
15437 x_draw_vertical_border (w);
15438 UNBLOCK_INPUT;
15439 update_end (f);
15441 #endif /* HAVE_WINDOW_SYSTEM */
15443 /* We go to this label, with fonts_changed_p nonzero,
15444 if it is necessary to try again using larger glyph matrices.
15445 We have to redeem the scroll bar even in this case,
15446 because the loop in redisplay_internal expects that. */
15447 need_larger_matrices:
15449 finish_scroll_bars:
15451 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
15453 /* Set the thumb's position and size. */
15454 set_vertical_scroll_bar (w);
15456 /* Note that we actually used the scroll bar attached to this
15457 window, so it shouldn't be deleted at the end of redisplay. */
15458 if (FRAME_TERMINAL (f)->redeem_scroll_bar_hook)
15459 (*FRAME_TERMINAL (f)->redeem_scroll_bar_hook) (w);
15462 /* Restore current_buffer and value of point in it. The window
15463 update may have changed the buffer, so first make sure `opoint'
15464 is still valid (Bug#6177). */
15465 if (CHARPOS (opoint) < BEGV)
15466 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
15467 else if (CHARPOS (opoint) > ZV)
15468 TEMP_SET_PT_BOTH (Z, Z_BYTE);
15469 else
15470 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
15472 set_buffer_internal_1 (old);
15473 /* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become
15474 shorter. This can be caused by log truncation in *Messages*. */
15475 if (CHARPOS (lpoint) <= ZV)
15476 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
15478 unbind_to (count, Qnil);
15482 /* Build the complete desired matrix of WINDOW with a window start
15483 buffer position POS.
15485 Value is 1 if successful. It is zero if fonts were loaded during
15486 redisplay which makes re-adjusting glyph matrices necessary, and -1
15487 if point would appear in the scroll margins.
15488 (We check the former only if TRY_WINDOW_IGNORE_FONTS_CHANGE is
15489 unset in FLAGS, and the latter only if TRY_WINDOW_CHECK_MARGINS is
15490 set in FLAGS.) */
15493 try_window (Lisp_Object window, struct text_pos pos, int flags)
15495 struct window *w = XWINDOW (window);
15496 struct it it;
15497 struct glyph_row *last_text_row = NULL;
15498 struct frame *f = XFRAME (w->frame);
15500 /* Make POS the new window start. */
15501 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
15503 /* Mark cursor position as unknown. No overlay arrow seen. */
15504 w->cursor.vpos = -1;
15505 overlay_arrow_seen = 0;
15507 /* Initialize iterator and info to start at POS. */
15508 start_display (&it, w, pos);
15510 /* Display all lines of W. */
15511 while (it.current_y < it.last_visible_y)
15513 if (display_line (&it))
15514 last_text_row = it.glyph_row - 1;
15515 if (fonts_changed_p && !(flags & TRY_WINDOW_IGNORE_FONTS_CHANGE))
15516 return 0;
15519 /* Don't let the cursor end in the scroll margins. */
15520 if ((flags & TRY_WINDOW_CHECK_MARGINS)
15521 && !MINI_WINDOW_P (w))
15523 int this_scroll_margin;
15525 if (scroll_margin > 0)
15527 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
15528 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
15530 else
15531 this_scroll_margin = 0;
15533 if ((w->cursor.y >= 0 /* not vscrolled */
15534 && w->cursor.y < this_scroll_margin
15535 && CHARPOS (pos) > BEGV
15536 && IT_CHARPOS (it) < ZV)
15537 /* rms: considering make_cursor_line_fully_visible_p here
15538 seems to give wrong results. We don't want to recenter
15539 when the last line is partly visible, we want to allow
15540 that case to be handled in the usual way. */
15541 || w->cursor.y > it.last_visible_y - this_scroll_margin - 1)
15543 w->cursor.vpos = -1;
15544 clear_glyph_matrix (w->desired_matrix);
15545 return -1;
15549 /* If bottom moved off end of frame, change mode line percentage. */
15550 if (XFASTINT (w->window_end_pos) <= 0
15551 && Z != IT_CHARPOS (it))
15552 w->update_mode_line = Qt;
15554 /* Set window_end_pos to the offset of the last character displayed
15555 on the window from the end of current_buffer. Set
15556 window_end_vpos to its row number. */
15557 if (last_text_row)
15559 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
15560 w->window_end_bytepos
15561 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
15562 w->window_end_pos
15563 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
15564 w->window_end_vpos
15565 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
15566 xassert (MATRIX_ROW (w->desired_matrix, XFASTINT (w->window_end_vpos))
15567 ->displays_text_p);
15569 else
15571 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
15572 w->window_end_pos = make_number (Z - ZV);
15573 w->window_end_vpos = make_number (0);
15576 /* But that is not valid info until redisplay finishes. */
15577 w->window_end_valid = Qnil;
15578 return 1;
15583 /************************************************************************
15584 Window redisplay reusing current matrix when buffer has not changed
15585 ************************************************************************/
15587 /* Try redisplay of window W showing an unchanged buffer with a
15588 different window start than the last time it was displayed by
15589 reusing its current matrix. Value is non-zero if successful.
15590 W->start is the new window start. */
15592 static int
15593 try_window_reusing_current_matrix (struct window *w)
15595 struct frame *f = XFRAME (w->frame);
15596 struct glyph_row *bottom_row;
15597 struct it it;
15598 struct run run;
15599 struct text_pos start, new_start;
15600 int nrows_scrolled, i;
15601 struct glyph_row *last_text_row;
15602 struct glyph_row *last_reused_text_row;
15603 struct glyph_row *start_row;
15604 int start_vpos, min_y, max_y;
15606 #if GLYPH_DEBUG
15607 if (inhibit_try_window_reusing)
15608 return 0;
15609 #endif
15611 if (/* This function doesn't handle terminal frames. */
15612 !FRAME_WINDOW_P (f)
15613 /* Don't try to reuse the display if windows have been split
15614 or such. */
15615 || windows_or_buffers_changed
15616 || cursor_type_changed)
15617 return 0;
15619 /* Can't do this if region may have changed. */
15620 if ((!NILP (Vtransient_mark_mode)
15621 && !NILP (BVAR (current_buffer, mark_active)))
15622 || !NILP (w->region_showing)
15623 || !NILP (Vshow_trailing_whitespace))
15624 return 0;
15626 /* If top-line visibility has changed, give up. */
15627 if (WINDOW_WANTS_HEADER_LINE_P (w)
15628 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
15629 return 0;
15631 /* Give up if old or new display is scrolled vertically. We could
15632 make this function handle this, but right now it doesn't. */
15633 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
15634 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row))
15635 return 0;
15637 /* The variable new_start now holds the new window start. The old
15638 start `start' can be determined from the current matrix. */
15639 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
15640 start = start_row->minpos;
15641 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
15643 /* Clear the desired matrix for the display below. */
15644 clear_glyph_matrix (w->desired_matrix);
15646 if (CHARPOS (new_start) <= CHARPOS (start))
15648 /* Don't use this method if the display starts with an ellipsis
15649 displayed for invisible text. It's not easy to handle that case
15650 below, and it's certainly not worth the effort since this is
15651 not a frequent case. */
15652 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
15653 return 0;
15655 IF_DEBUG (debug_method_add (w, "twu1"));
15657 /* Display up to a row that can be reused. The variable
15658 last_text_row is set to the last row displayed that displays
15659 text. Note that it.vpos == 0 if or if not there is a
15660 header-line; it's not the same as the MATRIX_ROW_VPOS! */
15661 start_display (&it, w, new_start);
15662 w->cursor.vpos = -1;
15663 last_text_row = last_reused_text_row = NULL;
15665 while (it.current_y < it.last_visible_y
15666 && !fonts_changed_p)
15668 /* If we have reached into the characters in the START row,
15669 that means the line boundaries have changed. So we
15670 can't start copying with the row START. Maybe it will
15671 work to start copying with the following row. */
15672 while (IT_CHARPOS (it) > CHARPOS (start))
15674 /* Advance to the next row as the "start". */
15675 start_row++;
15676 start = start_row->minpos;
15677 /* If there are no more rows to try, or just one, give up. */
15678 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
15679 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row)
15680 || CHARPOS (start) == ZV)
15682 clear_glyph_matrix (w->desired_matrix);
15683 return 0;
15686 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
15688 /* If we have reached alignment,
15689 we can copy the rest of the rows. */
15690 if (IT_CHARPOS (it) == CHARPOS (start))
15691 break;
15693 if (display_line (&it))
15694 last_text_row = it.glyph_row - 1;
15697 /* A value of current_y < last_visible_y means that we stopped
15698 at the previous window start, which in turn means that we
15699 have at least one reusable row. */
15700 if (it.current_y < it.last_visible_y)
15702 struct glyph_row *row;
15704 /* IT.vpos always starts from 0; it counts text lines. */
15705 nrows_scrolled = it.vpos - (start_row - MATRIX_FIRST_TEXT_ROW (w->current_matrix));
15707 /* Find PT if not already found in the lines displayed. */
15708 if (w->cursor.vpos < 0)
15710 int dy = it.current_y - start_row->y;
15712 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
15713 row = row_containing_pos (w, PT, row, NULL, dy);
15714 if (row)
15715 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
15716 dy, nrows_scrolled);
15717 else
15719 clear_glyph_matrix (w->desired_matrix);
15720 return 0;
15724 /* Scroll the display. Do it before the current matrix is
15725 changed. The problem here is that update has not yet
15726 run, i.e. part of the current matrix is not up to date.
15727 scroll_run_hook will clear the cursor, and use the
15728 current matrix to get the height of the row the cursor is
15729 in. */
15730 run.current_y = start_row->y;
15731 run.desired_y = it.current_y;
15732 run.height = it.last_visible_y - it.current_y;
15734 if (run.height > 0 && run.current_y != run.desired_y)
15736 update_begin (f);
15737 FRAME_RIF (f)->update_window_begin_hook (w);
15738 FRAME_RIF (f)->clear_window_mouse_face (w);
15739 FRAME_RIF (f)->scroll_run_hook (w, &run);
15740 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
15741 update_end (f);
15744 /* Shift current matrix down by nrows_scrolled lines. */
15745 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
15746 rotate_matrix (w->current_matrix,
15747 start_vpos,
15748 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
15749 nrows_scrolled);
15751 /* Disable lines that must be updated. */
15752 for (i = 0; i < nrows_scrolled; ++i)
15753 (start_row + i)->enabled_p = 0;
15755 /* Re-compute Y positions. */
15756 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
15757 max_y = it.last_visible_y;
15758 for (row = start_row + nrows_scrolled;
15759 row < bottom_row;
15760 ++row)
15762 row->y = it.current_y;
15763 row->visible_height = row->height;
15765 if (row->y < min_y)
15766 row->visible_height -= min_y - row->y;
15767 if (row->y + row->height > max_y)
15768 row->visible_height -= row->y + row->height - max_y;
15769 if (row->fringe_bitmap_periodic_p)
15770 row->redraw_fringe_bitmaps_p = 1;
15772 it.current_y += row->height;
15774 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
15775 last_reused_text_row = row;
15776 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
15777 break;
15780 /* Disable lines in the current matrix which are now
15781 below the window. */
15782 for (++row; row < bottom_row; ++row)
15783 row->enabled_p = row->mode_line_p = 0;
15786 /* Update window_end_pos etc.; last_reused_text_row is the last
15787 reused row from the current matrix containing text, if any.
15788 The value of last_text_row is the last displayed line
15789 containing text. */
15790 if (last_reused_text_row)
15792 w->window_end_bytepos
15793 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
15794 w->window_end_pos
15795 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_reused_text_row));
15796 w->window_end_vpos
15797 = make_number (MATRIX_ROW_VPOS (last_reused_text_row,
15798 w->current_matrix));
15800 else if (last_text_row)
15802 w->window_end_bytepos
15803 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
15804 w->window_end_pos
15805 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
15806 w->window_end_vpos
15807 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
15809 else
15811 /* This window must be completely empty. */
15812 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
15813 w->window_end_pos = make_number (Z - ZV);
15814 w->window_end_vpos = make_number (0);
15816 w->window_end_valid = Qnil;
15818 /* Update hint: don't try scrolling again in update_window. */
15819 w->desired_matrix->no_scrolling_p = 1;
15821 #if GLYPH_DEBUG
15822 debug_method_add (w, "try_window_reusing_current_matrix 1");
15823 #endif
15824 return 1;
15826 else if (CHARPOS (new_start) > CHARPOS (start))
15828 struct glyph_row *pt_row, *row;
15829 struct glyph_row *first_reusable_row;
15830 struct glyph_row *first_row_to_display;
15831 int dy;
15832 int yb = window_text_bottom_y (w);
15834 /* Find the row starting at new_start, if there is one. Don't
15835 reuse a partially visible line at the end. */
15836 first_reusable_row = start_row;
15837 while (first_reusable_row->enabled_p
15838 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
15839 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
15840 < CHARPOS (new_start)))
15841 ++first_reusable_row;
15843 /* Give up if there is no row to reuse. */
15844 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
15845 || !first_reusable_row->enabled_p
15846 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
15847 != CHARPOS (new_start)))
15848 return 0;
15850 /* We can reuse fully visible rows beginning with
15851 first_reusable_row to the end of the window. Set
15852 first_row_to_display to the first row that cannot be reused.
15853 Set pt_row to the row containing point, if there is any. */
15854 pt_row = NULL;
15855 for (first_row_to_display = first_reusable_row;
15856 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
15857 ++first_row_to_display)
15859 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
15860 && PT < MATRIX_ROW_END_CHARPOS (first_row_to_display))
15861 pt_row = first_row_to_display;
15864 /* Start displaying at the start of first_row_to_display. */
15865 xassert (first_row_to_display->y < yb);
15866 init_to_row_start (&it, w, first_row_to_display);
15868 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
15869 - start_vpos);
15870 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
15871 - nrows_scrolled);
15872 it.current_y = (first_row_to_display->y - first_reusable_row->y
15873 + WINDOW_HEADER_LINE_HEIGHT (w));
15875 /* Display lines beginning with first_row_to_display in the
15876 desired matrix. Set last_text_row to the last row displayed
15877 that displays text. */
15878 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
15879 if (pt_row == NULL)
15880 w->cursor.vpos = -1;
15881 last_text_row = NULL;
15882 while (it.current_y < it.last_visible_y && !fonts_changed_p)
15883 if (display_line (&it))
15884 last_text_row = it.glyph_row - 1;
15886 /* If point is in a reused row, adjust y and vpos of the cursor
15887 position. */
15888 if (pt_row)
15890 w->cursor.vpos -= nrows_scrolled;
15891 w->cursor.y -= first_reusable_row->y - start_row->y;
15894 /* Give up if point isn't in a row displayed or reused. (This
15895 also handles the case where w->cursor.vpos < nrows_scrolled
15896 after the calls to display_line, which can happen with scroll
15897 margins. See bug#1295.) */
15898 if (w->cursor.vpos < 0)
15900 clear_glyph_matrix (w->desired_matrix);
15901 return 0;
15904 /* Scroll the display. */
15905 run.current_y = first_reusable_row->y;
15906 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
15907 run.height = it.last_visible_y - run.current_y;
15908 dy = run.current_y - run.desired_y;
15910 if (run.height)
15912 update_begin (f);
15913 FRAME_RIF (f)->update_window_begin_hook (w);
15914 FRAME_RIF (f)->clear_window_mouse_face (w);
15915 FRAME_RIF (f)->scroll_run_hook (w, &run);
15916 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
15917 update_end (f);
15920 /* Adjust Y positions of reused rows. */
15921 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
15922 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
15923 max_y = it.last_visible_y;
15924 for (row = first_reusable_row; row < first_row_to_display; ++row)
15926 row->y -= dy;
15927 row->visible_height = row->height;
15928 if (row->y < min_y)
15929 row->visible_height -= min_y - row->y;
15930 if (row->y + row->height > max_y)
15931 row->visible_height -= row->y + row->height - max_y;
15932 if (row->fringe_bitmap_periodic_p)
15933 row->redraw_fringe_bitmaps_p = 1;
15936 /* Scroll the current matrix. */
15937 xassert (nrows_scrolled > 0);
15938 rotate_matrix (w->current_matrix,
15939 start_vpos,
15940 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
15941 -nrows_scrolled);
15943 /* Disable rows not reused. */
15944 for (row -= nrows_scrolled; row < bottom_row; ++row)
15945 row->enabled_p = 0;
15947 /* Point may have moved to a different line, so we cannot assume that
15948 the previous cursor position is valid; locate the correct row. */
15949 if (pt_row)
15951 for (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
15952 row < bottom_row && PT >= MATRIX_ROW_END_CHARPOS (row);
15953 row++)
15955 w->cursor.vpos++;
15956 w->cursor.y = row->y;
15958 if (row < bottom_row)
15960 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
15961 struct glyph *end = glyph + row->used[TEXT_AREA];
15963 /* Can't use this optimization with bidi-reordered glyph
15964 rows, unless cursor is already at point. */
15965 if (!NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering)))
15967 if (!(w->cursor.hpos >= 0
15968 && w->cursor.hpos < row->used[TEXT_AREA]
15969 && BUFFERP (glyph->object)
15970 && glyph->charpos == PT))
15971 return 0;
15973 else
15974 for (; glyph < end
15975 && (!BUFFERP (glyph->object)
15976 || glyph->charpos < PT);
15977 glyph++)
15979 w->cursor.hpos++;
15980 w->cursor.x += glyph->pixel_width;
15985 /* Adjust window end. A null value of last_text_row means that
15986 the window end is in reused rows which in turn means that
15987 only its vpos can have changed. */
15988 if (last_text_row)
15990 w->window_end_bytepos
15991 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
15992 w->window_end_pos
15993 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
15994 w->window_end_vpos
15995 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
15997 else
15999 w->window_end_vpos
16000 = make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled);
16003 w->window_end_valid = Qnil;
16004 w->desired_matrix->no_scrolling_p = 1;
16006 #if GLYPH_DEBUG
16007 debug_method_add (w, "try_window_reusing_current_matrix 2");
16008 #endif
16009 return 1;
16012 return 0;
16017 /************************************************************************
16018 Window redisplay reusing current matrix when buffer has changed
16019 ************************************************************************/
16021 static struct glyph_row *find_last_unchanged_at_beg_row (struct window *);
16022 static struct glyph_row *find_first_unchanged_at_end_row (struct window *,
16023 EMACS_INT *, EMACS_INT *);
16024 static struct glyph_row *
16025 find_last_row_displaying_text (struct glyph_matrix *, struct it *,
16026 struct glyph_row *);
16029 /* Return the last row in MATRIX displaying text. If row START is
16030 non-null, start searching with that row. IT gives the dimensions
16031 of the display. Value is null if matrix is empty; otherwise it is
16032 a pointer to the row found. */
16034 static struct glyph_row *
16035 find_last_row_displaying_text (struct glyph_matrix *matrix, struct it *it,
16036 struct glyph_row *start)
16038 struct glyph_row *row, *row_found;
16040 /* Set row_found to the last row in IT->w's current matrix
16041 displaying text. The loop looks funny but think of partially
16042 visible lines. */
16043 row_found = NULL;
16044 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
16045 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
16047 xassert (row->enabled_p);
16048 row_found = row;
16049 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
16050 break;
16051 ++row;
16054 return row_found;
16058 /* Return the last row in the current matrix of W that is not affected
16059 by changes at the start of current_buffer that occurred since W's
16060 current matrix was built. Value is null if no such row exists.
16062 BEG_UNCHANGED us the number of characters unchanged at the start of
16063 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
16064 first changed character in current_buffer. Characters at positions <
16065 BEG + BEG_UNCHANGED are at the same buffer positions as they were
16066 when the current matrix was built. */
16068 static struct glyph_row *
16069 find_last_unchanged_at_beg_row (struct window *w)
16071 EMACS_INT first_changed_pos = BEG + BEG_UNCHANGED;
16072 struct glyph_row *row;
16073 struct glyph_row *row_found = NULL;
16074 int yb = window_text_bottom_y (w);
16076 /* Find the last row displaying unchanged text. */
16077 for (row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16078 MATRIX_ROW_DISPLAYS_TEXT_P (row)
16079 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos;
16080 ++row)
16082 if (/* If row ends before first_changed_pos, it is unchanged,
16083 except in some case. */
16084 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
16085 /* When row ends in ZV and we write at ZV it is not
16086 unchanged. */
16087 && !row->ends_at_zv_p
16088 /* When first_changed_pos is the end of a continued line,
16089 row is not unchanged because it may be no longer
16090 continued. */
16091 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
16092 && (row->continued_p
16093 || row->exact_window_width_line_p)))
16094 row_found = row;
16096 /* Stop if last visible row. */
16097 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
16098 break;
16101 return row_found;
16105 /* Find the first glyph row in the current matrix of W that is not
16106 affected by changes at the end of current_buffer since the
16107 time W's current matrix was built.
16109 Return in *DELTA the number of chars by which buffer positions in
16110 unchanged text at the end of current_buffer must be adjusted.
16112 Return in *DELTA_BYTES the corresponding number of bytes.
16114 Value is null if no such row exists, i.e. all rows are affected by
16115 changes. */
16117 static struct glyph_row *
16118 find_first_unchanged_at_end_row (struct window *w,
16119 EMACS_INT *delta, EMACS_INT *delta_bytes)
16121 struct glyph_row *row;
16122 struct glyph_row *row_found = NULL;
16124 *delta = *delta_bytes = 0;
16126 /* Display must not have been paused, otherwise the current matrix
16127 is not up to date. */
16128 eassert (!NILP (w->window_end_valid));
16130 /* A value of window_end_pos >= END_UNCHANGED means that the window
16131 end is in the range of changed text. If so, there is no
16132 unchanged row at the end of W's current matrix. */
16133 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
16134 return NULL;
16136 /* Set row to the last row in W's current matrix displaying text. */
16137 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
16139 /* If matrix is entirely empty, no unchanged row exists. */
16140 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
16142 /* The value of row is the last glyph row in the matrix having a
16143 meaningful buffer position in it. The end position of row
16144 corresponds to window_end_pos. This allows us to translate
16145 buffer positions in the current matrix to current buffer
16146 positions for characters not in changed text. */
16147 EMACS_INT Z_old =
16148 MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
16149 EMACS_INT Z_BYTE_old =
16150 MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
16151 EMACS_INT last_unchanged_pos, last_unchanged_pos_old;
16152 struct glyph_row *first_text_row
16153 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16155 *delta = Z - Z_old;
16156 *delta_bytes = Z_BYTE - Z_BYTE_old;
16158 /* Set last_unchanged_pos to the buffer position of the last
16159 character in the buffer that has not been changed. Z is the
16160 index + 1 of the last character in current_buffer, i.e. by
16161 subtracting END_UNCHANGED we get the index of the last
16162 unchanged character, and we have to add BEG to get its buffer
16163 position. */
16164 last_unchanged_pos = Z - END_UNCHANGED + BEG;
16165 last_unchanged_pos_old = last_unchanged_pos - *delta;
16167 /* Search backward from ROW for a row displaying a line that
16168 starts at a minimum position >= last_unchanged_pos_old. */
16169 for (; row > first_text_row; --row)
16171 /* This used to abort, but it can happen.
16172 It is ok to just stop the search instead here. KFS. */
16173 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
16174 break;
16176 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
16177 row_found = row;
16181 eassert (!row_found || MATRIX_ROW_DISPLAYS_TEXT_P (row_found));
16183 return row_found;
16187 /* Make sure that glyph rows in the current matrix of window W
16188 reference the same glyph memory as corresponding rows in the
16189 frame's frame matrix. This function is called after scrolling W's
16190 current matrix on a terminal frame in try_window_id and
16191 try_window_reusing_current_matrix. */
16193 static void
16194 sync_frame_with_window_matrix_rows (struct window *w)
16196 struct frame *f = XFRAME (w->frame);
16197 struct glyph_row *window_row, *window_row_end, *frame_row;
16199 /* Preconditions: W must be a leaf window and full-width. Its frame
16200 must have a frame matrix. */
16201 xassert (NILP (w->hchild) && NILP (w->vchild));
16202 xassert (WINDOW_FULL_WIDTH_P (w));
16203 xassert (!FRAME_WINDOW_P (f));
16205 /* If W is a full-width window, glyph pointers in W's current matrix
16206 have, by definition, to be the same as glyph pointers in the
16207 corresponding frame matrix. Note that frame matrices have no
16208 marginal areas (see build_frame_matrix). */
16209 window_row = w->current_matrix->rows;
16210 window_row_end = window_row + w->current_matrix->nrows;
16211 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
16212 while (window_row < window_row_end)
16214 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
16215 struct glyph *end = window_row->glyphs[LAST_AREA];
16217 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
16218 frame_row->glyphs[TEXT_AREA] = start;
16219 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
16220 frame_row->glyphs[LAST_AREA] = end;
16222 /* Disable frame rows whose corresponding window rows have
16223 been disabled in try_window_id. */
16224 if (!window_row->enabled_p)
16225 frame_row->enabled_p = 0;
16227 ++window_row, ++frame_row;
16232 /* Find the glyph row in window W containing CHARPOS. Consider all
16233 rows between START and END (not inclusive). END null means search
16234 all rows to the end of the display area of W. Value is the row
16235 containing CHARPOS or null. */
16237 struct glyph_row *
16238 row_containing_pos (struct window *w, EMACS_INT charpos,
16239 struct glyph_row *start, struct glyph_row *end, int dy)
16241 struct glyph_row *row = start;
16242 struct glyph_row *best_row = NULL;
16243 EMACS_INT mindif = BUF_ZV (XBUFFER (w->buffer)) + 1;
16244 int last_y;
16246 /* If we happen to start on a header-line, skip that. */
16247 if (row->mode_line_p)
16248 ++row;
16250 if ((end && row >= end) || !row->enabled_p)
16251 return NULL;
16253 last_y = window_text_bottom_y (w) - dy;
16255 while (1)
16257 /* Give up if we have gone too far. */
16258 if (end && row >= end)
16259 return NULL;
16260 /* This formerly returned if they were equal.
16261 I think that both quantities are of a "last plus one" type;
16262 if so, when they are equal, the row is within the screen. -- rms. */
16263 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
16264 return NULL;
16266 /* If it is in this row, return this row. */
16267 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
16268 || (MATRIX_ROW_END_CHARPOS (row) == charpos
16269 /* The end position of a row equals the start
16270 position of the next row. If CHARPOS is there, we
16271 would rather display it in the next line, except
16272 when this line ends in ZV. */
16273 && !row->ends_at_zv_p
16274 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
16275 && charpos >= MATRIX_ROW_START_CHARPOS (row))
16277 struct glyph *g;
16279 if (NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering))
16280 || (!best_row && !row->continued_p))
16281 return row;
16282 /* In bidi-reordered rows, there could be several rows
16283 occluding point, all of them belonging to the same
16284 continued line. We need to find the row which fits
16285 CHARPOS the best. */
16286 for (g = row->glyphs[TEXT_AREA];
16287 g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
16288 g++)
16290 if (!STRINGP (g->object))
16292 if (g->charpos > 0 && eabs (g->charpos - charpos) < mindif)
16294 mindif = eabs (g->charpos - charpos);
16295 best_row = row;
16296 /* Exact match always wins. */
16297 if (mindif == 0)
16298 return best_row;
16303 else if (best_row && !row->continued_p)
16304 return best_row;
16305 ++row;
16310 /* Try to redisplay window W by reusing its existing display. W's
16311 current matrix must be up to date when this function is called,
16312 i.e. window_end_valid must not be nil.
16314 Value is
16316 1 if display has been updated
16317 0 if otherwise unsuccessful
16318 -1 if redisplay with same window start is known not to succeed
16320 The following steps are performed:
16322 1. Find the last row in the current matrix of W that is not
16323 affected by changes at the start of current_buffer. If no such row
16324 is found, give up.
16326 2. Find the first row in W's current matrix that is not affected by
16327 changes at the end of current_buffer. Maybe there is no such row.
16329 3. Display lines beginning with the row + 1 found in step 1 to the
16330 row found in step 2 or, if step 2 didn't find a row, to the end of
16331 the window.
16333 4. If cursor is not known to appear on the window, give up.
16335 5. If display stopped at the row found in step 2, scroll the
16336 display and current matrix as needed.
16338 6. Maybe display some lines at the end of W, if we must. This can
16339 happen under various circumstances, like a partially visible line
16340 becoming fully visible, or because newly displayed lines are displayed
16341 in smaller font sizes.
16343 7. Update W's window end information. */
16345 static int
16346 try_window_id (struct window *w)
16348 struct frame *f = XFRAME (w->frame);
16349 struct glyph_matrix *current_matrix = w->current_matrix;
16350 struct glyph_matrix *desired_matrix = w->desired_matrix;
16351 struct glyph_row *last_unchanged_at_beg_row;
16352 struct glyph_row *first_unchanged_at_end_row;
16353 struct glyph_row *row;
16354 struct glyph_row *bottom_row;
16355 int bottom_vpos;
16356 struct it it;
16357 EMACS_INT delta = 0, delta_bytes = 0, stop_pos;
16358 int dvpos, dy;
16359 struct text_pos start_pos;
16360 struct run run;
16361 int first_unchanged_at_end_vpos = 0;
16362 struct glyph_row *last_text_row, *last_text_row_at_end;
16363 struct text_pos start;
16364 EMACS_INT first_changed_charpos, last_changed_charpos;
16366 #if GLYPH_DEBUG
16367 if (inhibit_try_window_id)
16368 return 0;
16369 #endif
16371 /* This is handy for debugging. */
16372 #if 0
16373 #define GIVE_UP(X) \
16374 do { \
16375 fprintf (stderr, "try_window_id give up %d\n", (X)); \
16376 return 0; \
16377 } while (0)
16378 #else
16379 #define GIVE_UP(X) return 0
16380 #endif
16382 SET_TEXT_POS_FROM_MARKER (start, w->start);
16384 /* Don't use this for mini-windows because these can show
16385 messages and mini-buffers, and we don't handle that here. */
16386 if (MINI_WINDOW_P (w))
16387 GIVE_UP (1);
16389 /* This flag is used to prevent redisplay optimizations. */
16390 if (windows_or_buffers_changed || cursor_type_changed)
16391 GIVE_UP (2);
16393 /* Verify that narrowing has not changed.
16394 Also verify that we were not told to prevent redisplay optimizations.
16395 It would be nice to further
16396 reduce the number of cases where this prevents try_window_id. */
16397 if (current_buffer->clip_changed
16398 || current_buffer->prevent_redisplay_optimizations_p)
16399 GIVE_UP (3);
16401 /* Window must either use window-based redisplay or be full width. */
16402 if (!FRAME_WINDOW_P (f)
16403 && (!FRAME_LINE_INS_DEL_OK (f)
16404 || !WINDOW_FULL_WIDTH_P (w)))
16405 GIVE_UP (4);
16407 /* Give up if point is known NOT to appear in W. */
16408 if (PT < CHARPOS (start))
16409 GIVE_UP (5);
16411 /* Another way to prevent redisplay optimizations. */
16412 if (XFASTINT (w->last_modified) == 0)
16413 GIVE_UP (6);
16415 /* Verify that window is not hscrolled. */
16416 if (XFASTINT (w->hscroll) != 0)
16417 GIVE_UP (7);
16419 /* Verify that display wasn't paused. */
16420 if (NILP (w->window_end_valid))
16421 GIVE_UP (8);
16423 /* Can't use this if highlighting a region because a cursor movement
16424 will do more than just set the cursor. */
16425 if (!NILP (Vtransient_mark_mode)
16426 && !NILP (BVAR (current_buffer, mark_active)))
16427 GIVE_UP (9);
16429 /* Likewise if highlighting trailing whitespace. */
16430 if (!NILP (Vshow_trailing_whitespace))
16431 GIVE_UP (11);
16433 /* Likewise if showing a region. */
16434 if (!NILP (w->region_showing))
16435 GIVE_UP (10);
16437 /* Can't use this if overlay arrow position and/or string have
16438 changed. */
16439 if (overlay_arrows_changed_p ())
16440 GIVE_UP (12);
16442 /* When word-wrap is on, adding a space to the first word of a
16443 wrapped line can change the wrap position, altering the line
16444 above it. It might be worthwhile to handle this more
16445 intelligently, but for now just redisplay from scratch. */
16446 if (!NILP (BVAR (XBUFFER (w->buffer), word_wrap)))
16447 GIVE_UP (21);
16449 /* Under bidi reordering, adding or deleting a character in the
16450 beginning of a paragraph, before the first strong directional
16451 character, can change the base direction of the paragraph (unless
16452 the buffer specifies a fixed paragraph direction), which will
16453 require to redisplay the whole paragraph. It might be worthwhile
16454 to find the paragraph limits and widen the range of redisplayed
16455 lines to that, but for now just give up this optimization and
16456 redisplay from scratch. */
16457 if (!NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering))
16458 && NILP (BVAR (XBUFFER (w->buffer), bidi_paragraph_direction)))
16459 GIVE_UP (22);
16461 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
16462 only if buffer has really changed. The reason is that the gap is
16463 initially at Z for freshly visited files. The code below would
16464 set end_unchanged to 0 in that case. */
16465 if (MODIFF > SAVE_MODIFF
16466 /* This seems to happen sometimes after saving a buffer. */
16467 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
16469 if (GPT - BEG < BEG_UNCHANGED)
16470 BEG_UNCHANGED = GPT - BEG;
16471 if (Z - GPT < END_UNCHANGED)
16472 END_UNCHANGED = Z - GPT;
16475 /* The position of the first and last character that has been changed. */
16476 first_changed_charpos = BEG + BEG_UNCHANGED;
16477 last_changed_charpos = Z - END_UNCHANGED;
16479 /* If window starts after a line end, and the last change is in
16480 front of that newline, then changes don't affect the display.
16481 This case happens with stealth-fontification. Note that although
16482 the display is unchanged, glyph positions in the matrix have to
16483 be adjusted, of course. */
16484 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
16485 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
16486 && ((last_changed_charpos < CHARPOS (start)
16487 && CHARPOS (start) == BEGV)
16488 || (last_changed_charpos < CHARPOS (start) - 1
16489 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
16491 EMACS_INT Z_old, Z_delta, Z_BYTE_old, Z_delta_bytes;
16492 struct glyph_row *r0;
16494 /* Compute how many chars/bytes have been added to or removed
16495 from the buffer. */
16496 Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
16497 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
16498 Z_delta = Z - Z_old;
16499 Z_delta_bytes = Z_BYTE - Z_BYTE_old;
16501 /* Give up if PT is not in the window. Note that it already has
16502 been checked at the start of try_window_id that PT is not in
16503 front of the window start. */
16504 if (PT >= MATRIX_ROW_END_CHARPOS (row) + Z_delta)
16505 GIVE_UP (13);
16507 /* If window start is unchanged, we can reuse the whole matrix
16508 as is, after adjusting glyph positions. No need to compute
16509 the window end again, since its offset from Z hasn't changed. */
16510 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
16511 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + Z_delta
16512 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + Z_delta_bytes
16513 /* PT must not be in a partially visible line. */
16514 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + Z_delta
16515 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
16517 /* Adjust positions in the glyph matrix. */
16518 if (Z_delta || Z_delta_bytes)
16520 struct glyph_row *r1
16521 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
16522 increment_matrix_positions (w->current_matrix,
16523 MATRIX_ROW_VPOS (r0, current_matrix),
16524 MATRIX_ROW_VPOS (r1, current_matrix),
16525 Z_delta, Z_delta_bytes);
16528 /* Set the cursor. */
16529 row = row_containing_pos (w, PT, r0, NULL, 0);
16530 if (row)
16531 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
16532 else
16533 abort ();
16534 return 1;
16538 /* Handle the case that changes are all below what is displayed in
16539 the window, and that PT is in the window. This shortcut cannot
16540 be taken if ZV is visible in the window, and text has been added
16541 there that is visible in the window. */
16542 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
16543 /* ZV is not visible in the window, or there are no
16544 changes at ZV, actually. */
16545 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
16546 || first_changed_charpos == last_changed_charpos))
16548 struct glyph_row *r0;
16550 /* Give up if PT is not in the window. Note that it already has
16551 been checked at the start of try_window_id that PT is not in
16552 front of the window start. */
16553 if (PT >= MATRIX_ROW_END_CHARPOS (row))
16554 GIVE_UP (14);
16556 /* If window start is unchanged, we can reuse the whole matrix
16557 as is, without changing glyph positions since no text has
16558 been added/removed in front of the window end. */
16559 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
16560 if (TEXT_POS_EQUAL_P (start, r0->minpos)
16561 /* PT must not be in a partially visible line. */
16562 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
16563 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
16565 /* We have to compute the window end anew since text
16566 could have been added/removed after it. */
16567 w->window_end_pos
16568 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
16569 w->window_end_bytepos
16570 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
16572 /* Set the cursor. */
16573 row = row_containing_pos (w, PT, r0, NULL, 0);
16574 if (row)
16575 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
16576 else
16577 abort ();
16578 return 2;
16582 /* Give up if window start is in the changed area.
16584 The condition used to read
16586 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
16588 but why that was tested escapes me at the moment. */
16589 if (CHARPOS (start) >= first_changed_charpos
16590 && CHARPOS (start) <= last_changed_charpos)
16591 GIVE_UP (15);
16593 /* Check that window start agrees with the start of the first glyph
16594 row in its current matrix. Check this after we know the window
16595 start is not in changed text, otherwise positions would not be
16596 comparable. */
16597 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
16598 if (!TEXT_POS_EQUAL_P (start, row->minpos))
16599 GIVE_UP (16);
16601 /* Give up if the window ends in strings. Overlay strings
16602 at the end are difficult to handle, so don't try. */
16603 row = MATRIX_ROW (current_matrix, XFASTINT (w->window_end_vpos));
16604 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
16605 GIVE_UP (20);
16607 /* Compute the position at which we have to start displaying new
16608 lines. Some of the lines at the top of the window might be
16609 reusable because they are not displaying changed text. Find the
16610 last row in W's current matrix not affected by changes at the
16611 start of current_buffer. Value is null if changes start in the
16612 first line of window. */
16613 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
16614 if (last_unchanged_at_beg_row)
16616 /* Avoid starting to display in the moddle of a character, a TAB
16617 for instance. This is easier than to set up the iterator
16618 exactly, and it's not a frequent case, so the additional
16619 effort wouldn't really pay off. */
16620 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
16621 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
16622 && last_unchanged_at_beg_row > w->current_matrix->rows)
16623 --last_unchanged_at_beg_row;
16625 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
16626 GIVE_UP (17);
16628 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
16629 GIVE_UP (18);
16630 start_pos = it.current.pos;
16632 /* Start displaying new lines in the desired matrix at the same
16633 vpos we would use in the current matrix, i.e. below
16634 last_unchanged_at_beg_row. */
16635 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
16636 current_matrix);
16637 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
16638 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
16640 xassert (it.hpos == 0 && it.current_x == 0);
16642 else
16644 /* There are no reusable lines at the start of the window.
16645 Start displaying in the first text line. */
16646 start_display (&it, w, start);
16647 it.vpos = it.first_vpos;
16648 start_pos = it.current.pos;
16651 /* Find the first row that is not affected by changes at the end of
16652 the buffer. Value will be null if there is no unchanged row, in
16653 which case we must redisplay to the end of the window. delta
16654 will be set to the value by which buffer positions beginning with
16655 first_unchanged_at_end_row have to be adjusted due to text
16656 changes. */
16657 first_unchanged_at_end_row
16658 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
16659 IF_DEBUG (debug_delta = delta);
16660 IF_DEBUG (debug_delta_bytes = delta_bytes);
16662 /* Set stop_pos to the buffer position up to which we will have to
16663 display new lines. If first_unchanged_at_end_row != NULL, this
16664 is the buffer position of the start of the line displayed in that
16665 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
16666 that we don't stop at a buffer position. */
16667 stop_pos = 0;
16668 if (first_unchanged_at_end_row)
16670 xassert (last_unchanged_at_beg_row == NULL
16671 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
16673 /* If this is a continuation line, move forward to the next one
16674 that isn't. Changes in lines above affect this line.
16675 Caution: this may move first_unchanged_at_end_row to a row
16676 not displaying text. */
16677 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
16678 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
16679 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
16680 < it.last_visible_y))
16681 ++first_unchanged_at_end_row;
16683 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
16684 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
16685 >= it.last_visible_y))
16686 first_unchanged_at_end_row = NULL;
16687 else
16689 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
16690 + delta);
16691 first_unchanged_at_end_vpos
16692 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
16693 xassert (stop_pos >= Z - END_UNCHANGED);
16696 else if (last_unchanged_at_beg_row == NULL)
16697 GIVE_UP (19);
16700 #if GLYPH_DEBUG
16702 /* Either there is no unchanged row at the end, or the one we have
16703 now displays text. This is a necessary condition for the window
16704 end pos calculation at the end of this function. */
16705 xassert (first_unchanged_at_end_row == NULL
16706 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
16708 debug_last_unchanged_at_beg_vpos
16709 = (last_unchanged_at_beg_row
16710 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
16711 : -1);
16712 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
16714 #endif /* GLYPH_DEBUG != 0 */
16717 /* Display new lines. Set last_text_row to the last new line
16718 displayed which has text on it, i.e. might end up as being the
16719 line where the window_end_vpos is. */
16720 w->cursor.vpos = -1;
16721 last_text_row = NULL;
16722 overlay_arrow_seen = 0;
16723 while (it.current_y < it.last_visible_y
16724 && !fonts_changed_p
16725 && (first_unchanged_at_end_row == NULL
16726 || IT_CHARPOS (it) < stop_pos))
16728 if (display_line (&it))
16729 last_text_row = it.glyph_row - 1;
16732 if (fonts_changed_p)
16733 return -1;
16736 /* Compute differences in buffer positions, y-positions etc. for
16737 lines reused at the bottom of the window. Compute what we can
16738 scroll. */
16739 if (first_unchanged_at_end_row
16740 /* No lines reused because we displayed everything up to the
16741 bottom of the window. */
16742 && it.current_y < it.last_visible_y)
16744 dvpos = (it.vpos
16745 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
16746 current_matrix));
16747 dy = it.current_y - first_unchanged_at_end_row->y;
16748 run.current_y = first_unchanged_at_end_row->y;
16749 run.desired_y = run.current_y + dy;
16750 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
16752 else
16754 delta = delta_bytes = dvpos = dy
16755 = run.current_y = run.desired_y = run.height = 0;
16756 first_unchanged_at_end_row = NULL;
16758 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
16761 /* Find the cursor if not already found. We have to decide whether
16762 PT will appear on this window (it sometimes doesn't, but this is
16763 not a very frequent case.) This decision has to be made before
16764 the current matrix is altered. A value of cursor.vpos < 0 means
16765 that PT is either in one of the lines beginning at
16766 first_unchanged_at_end_row or below the window. Don't care for
16767 lines that might be displayed later at the window end; as
16768 mentioned, this is not a frequent case. */
16769 if (w->cursor.vpos < 0)
16771 /* Cursor in unchanged rows at the top? */
16772 if (PT < CHARPOS (start_pos)
16773 && last_unchanged_at_beg_row)
16775 row = row_containing_pos (w, PT,
16776 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
16777 last_unchanged_at_beg_row + 1, 0);
16778 if (row)
16779 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
16782 /* Start from first_unchanged_at_end_row looking for PT. */
16783 else if (first_unchanged_at_end_row)
16785 row = row_containing_pos (w, PT - delta,
16786 first_unchanged_at_end_row, NULL, 0);
16787 if (row)
16788 set_cursor_from_row (w, row, w->current_matrix, delta,
16789 delta_bytes, dy, dvpos);
16792 /* Give up if cursor was not found. */
16793 if (w->cursor.vpos < 0)
16795 clear_glyph_matrix (w->desired_matrix);
16796 return -1;
16800 /* Don't let the cursor end in the scroll margins. */
16802 int this_scroll_margin, cursor_height;
16804 this_scroll_margin = max (0, scroll_margin);
16805 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
16806 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
16807 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
16809 if ((w->cursor.y < this_scroll_margin
16810 && CHARPOS (start) > BEGV)
16811 /* Old redisplay didn't take scroll margin into account at the bottom,
16812 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
16813 || (w->cursor.y + (make_cursor_line_fully_visible_p
16814 ? cursor_height + this_scroll_margin
16815 : 1)) > it.last_visible_y)
16817 w->cursor.vpos = -1;
16818 clear_glyph_matrix (w->desired_matrix);
16819 return -1;
16823 /* Scroll the display. Do it before changing the current matrix so
16824 that xterm.c doesn't get confused about where the cursor glyph is
16825 found. */
16826 if (dy && run.height)
16828 update_begin (f);
16830 if (FRAME_WINDOW_P (f))
16832 FRAME_RIF (f)->update_window_begin_hook (w);
16833 FRAME_RIF (f)->clear_window_mouse_face (w);
16834 FRAME_RIF (f)->scroll_run_hook (w, &run);
16835 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
16837 else
16839 /* Terminal frame. In this case, dvpos gives the number of
16840 lines to scroll by; dvpos < 0 means scroll up. */
16841 int from_vpos
16842 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
16843 int from = WINDOW_TOP_EDGE_LINE (w) + from_vpos;
16844 int end = (WINDOW_TOP_EDGE_LINE (w)
16845 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
16846 + window_internal_height (w));
16848 #if defined (HAVE_GPM) || defined (MSDOS)
16849 x_clear_window_mouse_face (w);
16850 #endif
16851 /* Perform the operation on the screen. */
16852 if (dvpos > 0)
16854 /* Scroll last_unchanged_at_beg_row to the end of the
16855 window down dvpos lines. */
16856 set_terminal_window (f, end);
16858 /* On dumb terminals delete dvpos lines at the end
16859 before inserting dvpos empty lines. */
16860 if (!FRAME_SCROLL_REGION_OK (f))
16861 ins_del_lines (f, end - dvpos, -dvpos);
16863 /* Insert dvpos empty lines in front of
16864 last_unchanged_at_beg_row. */
16865 ins_del_lines (f, from, dvpos);
16867 else if (dvpos < 0)
16869 /* Scroll up last_unchanged_at_beg_vpos to the end of
16870 the window to last_unchanged_at_beg_vpos - |dvpos|. */
16871 set_terminal_window (f, end);
16873 /* Delete dvpos lines in front of
16874 last_unchanged_at_beg_vpos. ins_del_lines will set
16875 the cursor to the given vpos and emit |dvpos| delete
16876 line sequences. */
16877 ins_del_lines (f, from + dvpos, dvpos);
16879 /* On a dumb terminal insert dvpos empty lines at the
16880 end. */
16881 if (!FRAME_SCROLL_REGION_OK (f))
16882 ins_del_lines (f, end + dvpos, -dvpos);
16885 set_terminal_window (f, 0);
16888 update_end (f);
16891 /* Shift reused rows of the current matrix to the right position.
16892 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
16893 text. */
16894 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
16895 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
16896 if (dvpos < 0)
16898 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
16899 bottom_vpos, dvpos);
16900 enable_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
16901 bottom_vpos, 0);
16903 else if (dvpos > 0)
16905 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
16906 bottom_vpos, dvpos);
16907 enable_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
16908 first_unchanged_at_end_vpos + dvpos, 0);
16911 /* For frame-based redisplay, make sure that current frame and window
16912 matrix are in sync with respect to glyph memory. */
16913 if (!FRAME_WINDOW_P (f))
16914 sync_frame_with_window_matrix_rows (w);
16916 /* Adjust buffer positions in reused rows. */
16917 if (delta || delta_bytes)
16918 increment_matrix_positions (current_matrix,
16919 first_unchanged_at_end_vpos + dvpos,
16920 bottom_vpos, delta, delta_bytes);
16922 /* Adjust Y positions. */
16923 if (dy)
16924 shift_glyph_matrix (w, current_matrix,
16925 first_unchanged_at_end_vpos + dvpos,
16926 bottom_vpos, dy);
16928 if (first_unchanged_at_end_row)
16930 first_unchanged_at_end_row += dvpos;
16931 if (first_unchanged_at_end_row->y >= it.last_visible_y
16932 || !MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row))
16933 first_unchanged_at_end_row = NULL;
16936 /* If scrolling up, there may be some lines to display at the end of
16937 the window. */
16938 last_text_row_at_end = NULL;
16939 if (dy < 0)
16941 /* Scrolling up can leave for example a partially visible line
16942 at the end of the window to be redisplayed. */
16943 /* Set last_row to the glyph row in the current matrix where the
16944 window end line is found. It has been moved up or down in
16945 the matrix by dvpos. */
16946 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
16947 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
16949 /* If last_row is the window end line, it should display text. */
16950 xassert (last_row->displays_text_p);
16952 /* If window end line was partially visible before, begin
16953 displaying at that line. Otherwise begin displaying with the
16954 line following it. */
16955 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
16957 init_to_row_start (&it, w, last_row);
16958 it.vpos = last_vpos;
16959 it.current_y = last_row->y;
16961 else
16963 init_to_row_end (&it, w, last_row);
16964 it.vpos = 1 + last_vpos;
16965 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
16966 ++last_row;
16969 /* We may start in a continuation line. If so, we have to
16970 get the right continuation_lines_width and current_x. */
16971 it.continuation_lines_width = last_row->continuation_lines_width;
16972 it.hpos = it.current_x = 0;
16974 /* Display the rest of the lines at the window end. */
16975 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
16976 while (it.current_y < it.last_visible_y
16977 && !fonts_changed_p)
16979 /* Is it always sure that the display agrees with lines in
16980 the current matrix? I don't think so, so we mark rows
16981 displayed invalid in the current matrix by setting their
16982 enabled_p flag to zero. */
16983 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
16984 if (display_line (&it))
16985 last_text_row_at_end = it.glyph_row - 1;
16989 /* Update window_end_pos and window_end_vpos. */
16990 if (first_unchanged_at_end_row
16991 && !last_text_row_at_end)
16993 /* Window end line if one of the preserved rows from the current
16994 matrix. Set row to the last row displaying text in current
16995 matrix starting at first_unchanged_at_end_row, after
16996 scrolling. */
16997 xassert (first_unchanged_at_end_row->displays_text_p);
16998 row = find_last_row_displaying_text (w->current_matrix, &it,
16999 first_unchanged_at_end_row);
17000 xassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
17002 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
17003 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
17004 w->window_end_vpos
17005 = make_number (MATRIX_ROW_VPOS (row, w->current_matrix));
17006 xassert (w->window_end_bytepos >= 0);
17007 IF_DEBUG (debug_method_add (w, "A"));
17009 else if (last_text_row_at_end)
17011 w->window_end_pos
17012 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end));
17013 w->window_end_bytepos
17014 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
17015 w->window_end_vpos
17016 = make_number (MATRIX_ROW_VPOS (last_text_row_at_end, desired_matrix));
17017 xassert (w->window_end_bytepos >= 0);
17018 IF_DEBUG (debug_method_add (w, "B"));
17020 else if (last_text_row)
17022 /* We have displayed either to the end of the window or at the
17023 end of the window, i.e. the last row with text is to be found
17024 in the desired matrix. */
17025 w->window_end_pos
17026 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
17027 w->window_end_bytepos
17028 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
17029 w->window_end_vpos
17030 = make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix));
17031 xassert (w->window_end_bytepos >= 0);
17033 else if (first_unchanged_at_end_row == NULL
17034 && last_text_row == NULL
17035 && last_text_row_at_end == NULL)
17037 /* Displayed to end of window, but no line containing text was
17038 displayed. Lines were deleted at the end of the window. */
17039 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
17040 int vpos = XFASTINT (w->window_end_vpos);
17041 struct glyph_row *current_row = current_matrix->rows + vpos;
17042 struct glyph_row *desired_row = desired_matrix->rows + vpos;
17044 for (row = NULL;
17045 row == NULL && vpos >= first_vpos;
17046 --vpos, --current_row, --desired_row)
17048 if (desired_row->enabled_p)
17050 if (desired_row->displays_text_p)
17051 row = desired_row;
17053 else if (current_row->displays_text_p)
17054 row = current_row;
17057 xassert (row != NULL);
17058 w->window_end_vpos = make_number (vpos + 1);
17059 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
17060 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
17061 xassert (w->window_end_bytepos >= 0);
17062 IF_DEBUG (debug_method_add (w, "C"));
17064 else
17065 abort ();
17067 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
17068 debug_end_vpos = XFASTINT (w->window_end_vpos));
17070 /* Record that display has not been completed. */
17071 w->window_end_valid = Qnil;
17072 w->desired_matrix->no_scrolling_p = 1;
17073 return 3;
17075 #undef GIVE_UP
17080 /***********************************************************************
17081 More debugging support
17082 ***********************************************************************/
17084 #if GLYPH_DEBUG
17086 void dump_glyph_row (struct glyph_row *, int, int) EXTERNALLY_VISIBLE;
17087 void dump_glyph_matrix (struct glyph_matrix *, int) EXTERNALLY_VISIBLE;
17088 void dump_glyph (struct glyph_row *, struct glyph *, int) EXTERNALLY_VISIBLE;
17091 /* Dump the contents of glyph matrix MATRIX on stderr.
17093 GLYPHS 0 means don't show glyph contents.
17094 GLYPHS 1 means show glyphs in short form
17095 GLYPHS > 1 means show glyphs in long form. */
17097 void
17098 dump_glyph_matrix (struct glyph_matrix *matrix, int glyphs)
17100 int i;
17101 for (i = 0; i < matrix->nrows; ++i)
17102 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
17106 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
17107 the glyph row and area where the glyph comes from. */
17109 void
17110 dump_glyph (struct glyph_row *row, struct glyph *glyph, int area)
17112 if (glyph->type == CHAR_GLYPH)
17114 fprintf (stderr,
17115 " %5td %4c %6"pI"d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
17116 glyph - row->glyphs[TEXT_AREA],
17117 'C',
17118 glyph->charpos,
17119 (BUFFERP (glyph->object)
17120 ? 'B'
17121 : (STRINGP (glyph->object)
17122 ? 'S'
17123 : '-')),
17124 glyph->pixel_width,
17125 glyph->u.ch,
17126 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
17127 ? glyph->u.ch
17128 : '.'),
17129 glyph->face_id,
17130 glyph->left_box_line_p,
17131 glyph->right_box_line_p);
17133 else if (glyph->type == STRETCH_GLYPH)
17135 fprintf (stderr,
17136 " %5td %4c %6"pI"d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
17137 glyph - row->glyphs[TEXT_AREA],
17138 'S',
17139 glyph->charpos,
17140 (BUFFERP (glyph->object)
17141 ? 'B'
17142 : (STRINGP (glyph->object)
17143 ? 'S'
17144 : '-')),
17145 glyph->pixel_width,
17147 '.',
17148 glyph->face_id,
17149 glyph->left_box_line_p,
17150 glyph->right_box_line_p);
17152 else if (glyph->type == IMAGE_GLYPH)
17154 fprintf (stderr,
17155 " %5td %4c %6"pI"d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
17156 glyph - row->glyphs[TEXT_AREA],
17157 'I',
17158 glyph->charpos,
17159 (BUFFERP (glyph->object)
17160 ? 'B'
17161 : (STRINGP (glyph->object)
17162 ? 'S'
17163 : '-')),
17164 glyph->pixel_width,
17165 glyph->u.img_id,
17166 '.',
17167 glyph->face_id,
17168 glyph->left_box_line_p,
17169 glyph->right_box_line_p);
17171 else if (glyph->type == COMPOSITE_GLYPH)
17173 fprintf (stderr,
17174 " %5td %4c %6"pI"d %c %3d 0x%05x",
17175 glyph - row->glyphs[TEXT_AREA],
17176 '+',
17177 glyph->charpos,
17178 (BUFFERP (glyph->object)
17179 ? 'B'
17180 : (STRINGP (glyph->object)
17181 ? 'S'
17182 : '-')),
17183 glyph->pixel_width,
17184 glyph->u.cmp.id);
17185 if (glyph->u.cmp.automatic)
17186 fprintf (stderr,
17187 "[%d-%d]",
17188 glyph->slice.cmp.from, glyph->slice.cmp.to);
17189 fprintf (stderr, " . %4d %1.1d%1.1d\n",
17190 glyph->face_id,
17191 glyph->left_box_line_p,
17192 glyph->right_box_line_p);
17197 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
17198 GLYPHS 0 means don't show glyph contents.
17199 GLYPHS 1 means show glyphs in short form
17200 GLYPHS > 1 means show glyphs in long form. */
17202 void
17203 dump_glyph_row (struct glyph_row *row, int vpos, int glyphs)
17205 if (glyphs != 1)
17207 fprintf (stderr, "Row Start End Used oE><\\CTZFesm X Y W H V A P\n");
17208 fprintf (stderr, "======================================================================\n");
17210 fprintf (stderr, "%3d %5"pI"d %5"pI"d %4d %1.1d%1.1d%1.1d%1.1d\
17211 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
17212 vpos,
17213 MATRIX_ROW_START_CHARPOS (row),
17214 MATRIX_ROW_END_CHARPOS (row),
17215 row->used[TEXT_AREA],
17216 row->contains_overlapping_glyphs_p,
17217 row->enabled_p,
17218 row->truncated_on_left_p,
17219 row->truncated_on_right_p,
17220 row->continued_p,
17221 MATRIX_ROW_CONTINUATION_LINE_P (row),
17222 row->displays_text_p,
17223 row->ends_at_zv_p,
17224 row->fill_line_p,
17225 row->ends_in_middle_of_char_p,
17226 row->starts_in_middle_of_char_p,
17227 row->mouse_face_p,
17228 row->x,
17229 row->y,
17230 row->pixel_width,
17231 row->height,
17232 row->visible_height,
17233 row->ascent,
17234 row->phys_ascent);
17235 fprintf (stderr, "%9d %5d\t%5d\n", row->start.overlay_string_index,
17236 row->end.overlay_string_index,
17237 row->continuation_lines_width);
17238 fprintf (stderr, "%9"pI"d %5"pI"d\n",
17239 CHARPOS (row->start.string_pos),
17240 CHARPOS (row->end.string_pos));
17241 fprintf (stderr, "%9d %5d\n", row->start.dpvec_index,
17242 row->end.dpvec_index);
17245 if (glyphs > 1)
17247 int area;
17249 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
17251 struct glyph *glyph = row->glyphs[area];
17252 struct glyph *glyph_end = glyph + row->used[area];
17254 /* Glyph for a line end in text. */
17255 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
17256 ++glyph_end;
17258 if (glyph < glyph_end)
17259 fprintf (stderr, " Glyph Type Pos O W Code C Face LR\n");
17261 for (; glyph < glyph_end; ++glyph)
17262 dump_glyph (row, glyph, area);
17265 else if (glyphs == 1)
17267 int area;
17269 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
17271 char *s = (char *) alloca (row->used[area] + 1);
17272 int i;
17274 for (i = 0; i < row->used[area]; ++i)
17276 struct glyph *glyph = row->glyphs[area] + i;
17277 if (glyph->type == CHAR_GLYPH
17278 && glyph->u.ch < 0x80
17279 && glyph->u.ch >= ' ')
17280 s[i] = glyph->u.ch;
17281 else
17282 s[i] = '.';
17285 s[i] = '\0';
17286 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
17292 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
17293 Sdump_glyph_matrix, 0, 1, "p",
17294 doc: /* Dump the current matrix of the selected window to stderr.
17295 Shows contents of glyph row structures. With non-nil
17296 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
17297 glyphs in short form, otherwise show glyphs in long form. */)
17298 (Lisp_Object glyphs)
17300 struct window *w = XWINDOW (selected_window);
17301 struct buffer *buffer = XBUFFER (w->buffer);
17303 fprintf (stderr, "PT = %"pI"d, BEGV = %"pI"d. ZV = %"pI"d\n",
17304 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
17305 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
17306 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
17307 fprintf (stderr, "=============================================\n");
17308 dump_glyph_matrix (w->current_matrix,
17309 NILP (glyphs) ? 0 : XINT (glyphs));
17310 return Qnil;
17314 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
17315 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
17316 (void)
17318 struct frame *f = XFRAME (selected_frame);
17319 dump_glyph_matrix (f->current_matrix, 1);
17320 return Qnil;
17324 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
17325 doc: /* Dump glyph row ROW to stderr.
17326 GLYPH 0 means don't dump glyphs.
17327 GLYPH 1 means dump glyphs in short form.
17328 GLYPH > 1 or omitted means dump glyphs in long form. */)
17329 (Lisp_Object row, Lisp_Object glyphs)
17331 struct glyph_matrix *matrix;
17332 int vpos;
17334 CHECK_NUMBER (row);
17335 matrix = XWINDOW (selected_window)->current_matrix;
17336 vpos = XINT (row);
17337 if (vpos >= 0 && vpos < matrix->nrows)
17338 dump_glyph_row (MATRIX_ROW (matrix, vpos),
17339 vpos,
17340 INTEGERP (glyphs) ? XINT (glyphs) : 2);
17341 return Qnil;
17345 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
17346 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
17347 GLYPH 0 means don't dump glyphs.
17348 GLYPH 1 means dump glyphs in short form.
17349 GLYPH > 1 or omitted means dump glyphs in long form. */)
17350 (Lisp_Object row, Lisp_Object glyphs)
17352 struct frame *sf = SELECTED_FRAME ();
17353 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
17354 int vpos;
17356 CHECK_NUMBER (row);
17357 vpos = XINT (row);
17358 if (vpos >= 0 && vpos < m->nrows)
17359 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
17360 INTEGERP (glyphs) ? XINT (glyphs) : 2);
17361 return Qnil;
17365 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
17366 doc: /* Toggle tracing of redisplay.
17367 With ARG, turn tracing on if and only if ARG is positive. */)
17368 (Lisp_Object arg)
17370 if (NILP (arg))
17371 trace_redisplay_p = !trace_redisplay_p;
17372 else
17374 arg = Fprefix_numeric_value (arg);
17375 trace_redisplay_p = XINT (arg) > 0;
17378 return Qnil;
17382 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
17383 doc: /* Like `format', but print result to stderr.
17384 usage: (trace-to-stderr STRING &rest OBJECTS) */)
17385 (ptrdiff_t nargs, Lisp_Object *args)
17387 Lisp_Object s = Fformat (nargs, args);
17388 fprintf (stderr, "%s", SDATA (s));
17389 return Qnil;
17392 #endif /* GLYPH_DEBUG */
17396 /***********************************************************************
17397 Building Desired Matrix Rows
17398 ***********************************************************************/
17400 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
17401 Used for non-window-redisplay windows, and for windows w/o left fringe. */
17403 static struct glyph_row *
17404 get_overlay_arrow_glyph_row (struct window *w, Lisp_Object overlay_arrow_string)
17406 struct frame *f = XFRAME (WINDOW_FRAME (w));
17407 struct buffer *buffer = XBUFFER (w->buffer);
17408 struct buffer *old = current_buffer;
17409 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
17410 int arrow_len = SCHARS (overlay_arrow_string);
17411 const unsigned char *arrow_end = arrow_string + arrow_len;
17412 const unsigned char *p;
17413 struct it it;
17414 int multibyte_p;
17415 int n_glyphs_before;
17417 set_buffer_temp (buffer);
17418 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
17419 it.glyph_row->used[TEXT_AREA] = 0;
17420 SET_TEXT_POS (it.position, 0, 0);
17422 multibyte_p = !NILP (BVAR (buffer, enable_multibyte_characters));
17423 p = arrow_string;
17424 while (p < arrow_end)
17426 Lisp_Object face, ilisp;
17428 /* Get the next character. */
17429 if (multibyte_p)
17430 it.c = it.char_to_display = string_char_and_length (p, &it.len);
17431 else
17433 it.c = it.char_to_display = *p, it.len = 1;
17434 if (! ASCII_CHAR_P (it.c))
17435 it.char_to_display = BYTE8_TO_CHAR (it.c);
17437 p += it.len;
17439 /* Get its face. */
17440 ilisp = make_number (p - arrow_string);
17441 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
17442 it.face_id = compute_char_face (f, it.char_to_display, face);
17444 /* Compute its width, get its glyphs. */
17445 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
17446 SET_TEXT_POS (it.position, -1, -1);
17447 PRODUCE_GLYPHS (&it);
17449 /* If this character doesn't fit any more in the line, we have
17450 to remove some glyphs. */
17451 if (it.current_x > it.last_visible_x)
17453 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
17454 break;
17458 set_buffer_temp (old);
17459 return it.glyph_row;
17463 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
17464 glyphs are only inserted for terminal frames since we can't really
17465 win with truncation glyphs when partially visible glyphs are
17466 involved. Which glyphs to insert is determined by
17467 produce_special_glyphs. */
17469 static void
17470 insert_left_trunc_glyphs (struct it *it)
17472 struct it truncate_it;
17473 struct glyph *from, *end, *to, *toend;
17475 xassert (!FRAME_WINDOW_P (it->f));
17477 /* Get the truncation glyphs. */
17478 truncate_it = *it;
17479 truncate_it.current_x = 0;
17480 truncate_it.face_id = DEFAULT_FACE_ID;
17481 truncate_it.glyph_row = &scratch_glyph_row;
17482 truncate_it.glyph_row->used[TEXT_AREA] = 0;
17483 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
17484 truncate_it.object = make_number (0);
17485 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
17487 /* Overwrite glyphs from IT with truncation glyphs. */
17488 if (!it->glyph_row->reversed_p)
17490 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
17491 end = from + truncate_it.glyph_row->used[TEXT_AREA];
17492 to = it->glyph_row->glyphs[TEXT_AREA];
17493 toend = to + it->glyph_row->used[TEXT_AREA];
17495 while (from < end)
17496 *to++ = *from++;
17498 /* There may be padding glyphs left over. Overwrite them too. */
17499 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
17501 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
17502 while (from < end)
17503 *to++ = *from++;
17506 if (to > toend)
17507 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
17509 else
17511 /* In R2L rows, overwrite the last (rightmost) glyphs, and do
17512 that back to front. */
17513 end = truncate_it.glyph_row->glyphs[TEXT_AREA];
17514 from = end + truncate_it.glyph_row->used[TEXT_AREA] - 1;
17515 toend = it->glyph_row->glyphs[TEXT_AREA];
17516 to = toend + it->glyph_row->used[TEXT_AREA] - 1;
17518 while (from >= end && to >= toend)
17519 *to-- = *from--;
17520 while (to >= toend && CHAR_GLYPH_PADDING_P (*to))
17522 from =
17523 truncate_it.glyph_row->glyphs[TEXT_AREA]
17524 + truncate_it.glyph_row->used[TEXT_AREA] - 1;
17525 while (from >= end && to >= toend)
17526 *to-- = *from--;
17528 if (from >= end)
17530 /* Need to free some room before prepending additional
17531 glyphs. */
17532 int move_by = from - end + 1;
17533 struct glyph *g0 = it->glyph_row->glyphs[TEXT_AREA];
17534 struct glyph *g = g0 + it->glyph_row->used[TEXT_AREA] - 1;
17536 for ( ; g >= g0; g--)
17537 g[move_by] = *g;
17538 while (from >= end)
17539 *to-- = *from--;
17540 it->glyph_row->used[TEXT_AREA] += move_by;
17546 /* Compute the pixel height and width of IT->glyph_row.
17548 Most of the time, ascent and height of a display line will be equal
17549 to the max_ascent and max_height values of the display iterator
17550 structure. This is not the case if
17552 1. We hit ZV without displaying anything. In this case, max_ascent
17553 and max_height will be zero.
17555 2. We have some glyphs that don't contribute to the line height.
17556 (The glyph row flag contributes_to_line_height_p is for future
17557 pixmap extensions).
17559 The first case is easily covered by using default values because in
17560 these cases, the line height does not really matter, except that it
17561 must not be zero. */
17563 static void
17564 compute_line_metrics (struct it *it)
17566 struct glyph_row *row = it->glyph_row;
17568 if (FRAME_WINDOW_P (it->f))
17570 int i, min_y, max_y;
17572 /* The line may consist of one space only, that was added to
17573 place the cursor on it. If so, the row's height hasn't been
17574 computed yet. */
17575 if (row->height == 0)
17577 if (it->max_ascent + it->max_descent == 0)
17578 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
17579 row->ascent = it->max_ascent;
17580 row->height = it->max_ascent + it->max_descent;
17581 row->phys_ascent = it->max_phys_ascent;
17582 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
17583 row->extra_line_spacing = it->max_extra_line_spacing;
17586 /* Compute the width of this line. */
17587 row->pixel_width = row->x;
17588 for (i = 0; i < row->used[TEXT_AREA]; ++i)
17589 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
17591 xassert (row->pixel_width >= 0);
17592 xassert (row->ascent >= 0 && row->height > 0);
17594 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
17595 || MATRIX_ROW_OVERLAPS_PRED_P (row));
17597 /* If first line's physical ascent is larger than its logical
17598 ascent, use the physical ascent, and make the row taller.
17599 This makes accented characters fully visible. */
17600 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
17601 && row->phys_ascent > row->ascent)
17603 row->height += row->phys_ascent - row->ascent;
17604 row->ascent = row->phys_ascent;
17607 /* Compute how much of the line is visible. */
17608 row->visible_height = row->height;
17610 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
17611 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
17613 if (row->y < min_y)
17614 row->visible_height -= min_y - row->y;
17615 if (row->y + row->height > max_y)
17616 row->visible_height -= row->y + row->height - max_y;
17618 else
17620 row->pixel_width = row->used[TEXT_AREA];
17621 if (row->continued_p)
17622 row->pixel_width -= it->continuation_pixel_width;
17623 else if (row->truncated_on_right_p)
17624 row->pixel_width -= it->truncation_pixel_width;
17625 row->ascent = row->phys_ascent = 0;
17626 row->height = row->phys_height = row->visible_height = 1;
17627 row->extra_line_spacing = 0;
17630 /* Compute a hash code for this row. */
17632 int area, i;
17633 row->hash = 0;
17634 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
17635 for (i = 0; i < row->used[area]; ++i)
17636 row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff)
17637 + row->glyphs[area][i].u.val
17638 + row->glyphs[area][i].face_id
17639 + row->glyphs[area][i].padding_p
17640 + (row->glyphs[area][i].type << 2));
17643 it->max_ascent = it->max_descent = 0;
17644 it->max_phys_ascent = it->max_phys_descent = 0;
17648 /* Append one space to the glyph row of iterator IT if doing a
17649 window-based redisplay. The space has the same face as
17650 IT->face_id. Value is non-zero if a space was added.
17652 This function is called to make sure that there is always one glyph
17653 at the end of a glyph row that the cursor can be set on under
17654 window-systems. (If there weren't such a glyph we would not know
17655 how wide and tall a box cursor should be displayed).
17657 At the same time this space let's a nicely handle clearing to the
17658 end of the line if the row ends in italic text. */
17660 static int
17661 append_space_for_newline (struct it *it, int default_face_p)
17663 if (FRAME_WINDOW_P (it->f))
17665 int n = it->glyph_row->used[TEXT_AREA];
17667 if (it->glyph_row->glyphs[TEXT_AREA] + n
17668 < it->glyph_row->glyphs[1 + TEXT_AREA])
17670 /* Save some values that must not be changed.
17671 Must save IT->c and IT->len because otherwise
17672 ITERATOR_AT_END_P wouldn't work anymore after
17673 append_space_for_newline has been called. */
17674 enum display_element_type saved_what = it->what;
17675 int saved_c = it->c, saved_len = it->len;
17676 int saved_char_to_display = it->char_to_display;
17677 int saved_x = it->current_x;
17678 int saved_face_id = it->face_id;
17679 struct text_pos saved_pos;
17680 Lisp_Object saved_object;
17681 struct face *face;
17683 saved_object = it->object;
17684 saved_pos = it->position;
17686 it->what = IT_CHARACTER;
17687 memset (&it->position, 0, sizeof it->position);
17688 it->object = make_number (0);
17689 it->c = it->char_to_display = ' ';
17690 it->len = 1;
17692 if (default_face_p)
17693 it->face_id = DEFAULT_FACE_ID;
17694 else if (it->face_before_selective_p)
17695 it->face_id = it->saved_face_id;
17696 face = FACE_FROM_ID (it->f, it->face_id);
17697 it->face_id = FACE_FOR_CHAR (it->f, face, 0, -1, Qnil);
17699 PRODUCE_GLYPHS (it);
17701 it->override_ascent = -1;
17702 it->constrain_row_ascent_descent_p = 0;
17703 it->current_x = saved_x;
17704 it->object = saved_object;
17705 it->position = saved_pos;
17706 it->what = saved_what;
17707 it->face_id = saved_face_id;
17708 it->len = saved_len;
17709 it->c = saved_c;
17710 it->char_to_display = saved_char_to_display;
17711 return 1;
17715 return 0;
17719 /* Extend the face of the last glyph in the text area of IT->glyph_row
17720 to the end of the display line. Called from display_line. If the
17721 glyph row is empty, add a space glyph to it so that we know the
17722 face to draw. Set the glyph row flag fill_line_p. If the glyph
17723 row is R2L, prepend a stretch glyph to cover the empty space to the
17724 left of the leftmost glyph. */
17726 static void
17727 extend_face_to_end_of_line (struct it *it)
17729 struct face *face;
17730 struct frame *f = it->f;
17732 /* If line is already filled, do nothing. Non window-system frames
17733 get a grace of one more ``pixel'' because their characters are
17734 1-``pixel'' wide, so they hit the equality too early. This grace
17735 is needed only for R2L rows that are not continued, to produce
17736 one extra blank where we could display the cursor. */
17737 if (it->current_x >= it->last_visible_x
17738 + (!FRAME_WINDOW_P (f)
17739 && it->glyph_row->reversed_p
17740 && !it->glyph_row->continued_p))
17741 return;
17743 /* Face extension extends the background and box of IT->face_id
17744 to the end of the line. If the background equals the background
17745 of the frame, we don't have to do anything. */
17746 if (it->face_before_selective_p)
17747 face = FACE_FROM_ID (f, it->saved_face_id);
17748 else
17749 face = FACE_FROM_ID (f, it->face_id);
17751 if (FRAME_WINDOW_P (f)
17752 && it->glyph_row->displays_text_p
17753 && face->box == FACE_NO_BOX
17754 && face->background == FRAME_BACKGROUND_PIXEL (f)
17755 && !face->stipple
17756 && !it->glyph_row->reversed_p)
17757 return;
17759 /* Set the glyph row flag indicating that the face of the last glyph
17760 in the text area has to be drawn to the end of the text area. */
17761 it->glyph_row->fill_line_p = 1;
17763 /* If current character of IT is not ASCII, make sure we have the
17764 ASCII face. This will be automatically undone the next time
17765 get_next_display_element returns a multibyte character. Note
17766 that the character will always be single byte in unibyte
17767 text. */
17768 if (!ASCII_CHAR_P (it->c))
17770 it->face_id = FACE_FOR_CHAR (f, face, 0, -1, Qnil);
17773 if (FRAME_WINDOW_P (f))
17775 /* If the row is empty, add a space with the current face of IT,
17776 so that we know which face to draw. */
17777 if (it->glyph_row->used[TEXT_AREA] == 0)
17779 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
17780 it->glyph_row->glyphs[TEXT_AREA][0].face_id = it->face_id;
17781 it->glyph_row->used[TEXT_AREA] = 1;
17783 #ifdef HAVE_WINDOW_SYSTEM
17784 if (it->glyph_row->reversed_p)
17786 /* Prepend a stretch glyph to the row, such that the
17787 rightmost glyph will be drawn flushed all the way to the
17788 right margin of the window. The stretch glyph that will
17789 occupy the empty space, if any, to the left of the
17790 glyphs. */
17791 struct font *font = face->font ? face->font : FRAME_FONT (f);
17792 struct glyph *row_start = it->glyph_row->glyphs[TEXT_AREA];
17793 struct glyph *row_end = row_start + it->glyph_row->used[TEXT_AREA];
17794 struct glyph *g;
17795 int row_width, stretch_ascent, stretch_width;
17796 struct text_pos saved_pos;
17797 int saved_face_id, saved_avoid_cursor;
17799 for (row_width = 0, g = row_start; g < row_end; g++)
17800 row_width += g->pixel_width;
17801 stretch_width = window_box_width (it->w, TEXT_AREA) - row_width;
17802 if (stretch_width > 0)
17804 stretch_ascent =
17805 (((it->ascent + it->descent)
17806 * FONT_BASE (font)) / FONT_HEIGHT (font));
17807 saved_pos = it->position;
17808 memset (&it->position, 0, sizeof it->position);
17809 saved_avoid_cursor = it->avoid_cursor_p;
17810 it->avoid_cursor_p = 1;
17811 saved_face_id = it->face_id;
17812 /* The last row's stretch glyph should get the default
17813 face, to avoid painting the rest of the window with
17814 the region face, if the region ends at ZV. */
17815 if (it->glyph_row->ends_at_zv_p)
17816 it->face_id = DEFAULT_FACE_ID;
17817 else
17818 it->face_id = face->id;
17819 append_stretch_glyph (it, make_number (0), stretch_width,
17820 it->ascent + it->descent, stretch_ascent);
17821 it->position = saved_pos;
17822 it->avoid_cursor_p = saved_avoid_cursor;
17823 it->face_id = saved_face_id;
17826 #endif /* HAVE_WINDOW_SYSTEM */
17828 else
17830 /* Save some values that must not be changed. */
17831 int saved_x = it->current_x;
17832 struct text_pos saved_pos;
17833 Lisp_Object saved_object;
17834 enum display_element_type saved_what = it->what;
17835 int saved_face_id = it->face_id;
17837 saved_object = it->object;
17838 saved_pos = it->position;
17840 it->what = IT_CHARACTER;
17841 memset (&it->position, 0, sizeof it->position);
17842 it->object = make_number (0);
17843 it->c = it->char_to_display = ' ';
17844 it->len = 1;
17845 /* The last row's blank glyphs should get the default face, to
17846 avoid painting the rest of the window with the region face,
17847 if the region ends at ZV. */
17848 if (it->glyph_row->ends_at_zv_p)
17849 it->face_id = DEFAULT_FACE_ID;
17850 else
17851 it->face_id = face->id;
17853 PRODUCE_GLYPHS (it);
17855 while (it->current_x <= it->last_visible_x)
17856 PRODUCE_GLYPHS (it);
17858 /* Don't count these blanks really. It would let us insert a left
17859 truncation glyph below and make us set the cursor on them, maybe. */
17860 it->current_x = saved_x;
17861 it->object = saved_object;
17862 it->position = saved_pos;
17863 it->what = saved_what;
17864 it->face_id = saved_face_id;
17869 /* Value is non-zero if text starting at CHARPOS in current_buffer is
17870 trailing whitespace. */
17872 static int
17873 trailing_whitespace_p (EMACS_INT charpos)
17875 EMACS_INT bytepos = CHAR_TO_BYTE (charpos);
17876 int c = 0;
17878 while (bytepos < ZV_BYTE
17879 && (c = FETCH_CHAR (bytepos),
17880 c == ' ' || c == '\t'))
17881 ++bytepos;
17883 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
17885 if (bytepos != PT_BYTE)
17886 return 1;
17888 return 0;
17892 /* Highlight trailing whitespace, if any, in ROW. */
17894 static void
17895 highlight_trailing_whitespace (struct frame *f, struct glyph_row *row)
17897 int used = row->used[TEXT_AREA];
17899 if (used)
17901 struct glyph *start = row->glyphs[TEXT_AREA];
17902 struct glyph *glyph = start + used - 1;
17904 if (row->reversed_p)
17906 /* Right-to-left rows need to be processed in the opposite
17907 direction, so swap the edge pointers. */
17908 glyph = start;
17909 start = row->glyphs[TEXT_AREA] + used - 1;
17912 /* Skip over glyphs inserted to display the cursor at the
17913 end of a line, for extending the face of the last glyph
17914 to the end of the line on terminals, and for truncation
17915 and continuation glyphs. */
17916 if (!row->reversed_p)
17918 while (glyph >= start
17919 && glyph->type == CHAR_GLYPH
17920 && INTEGERP (glyph->object))
17921 --glyph;
17923 else
17925 while (glyph <= start
17926 && glyph->type == CHAR_GLYPH
17927 && INTEGERP (glyph->object))
17928 ++glyph;
17931 /* If last glyph is a space or stretch, and it's trailing
17932 whitespace, set the face of all trailing whitespace glyphs in
17933 IT->glyph_row to `trailing-whitespace'. */
17934 if ((row->reversed_p ? glyph <= start : glyph >= start)
17935 && BUFFERP (glyph->object)
17936 && (glyph->type == STRETCH_GLYPH
17937 || (glyph->type == CHAR_GLYPH
17938 && glyph->u.ch == ' '))
17939 && trailing_whitespace_p (glyph->charpos))
17941 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0);
17942 if (face_id < 0)
17943 return;
17945 if (!row->reversed_p)
17947 while (glyph >= start
17948 && BUFFERP (glyph->object)
17949 && (glyph->type == STRETCH_GLYPH
17950 || (glyph->type == CHAR_GLYPH
17951 && glyph->u.ch == ' ')))
17952 (glyph--)->face_id = face_id;
17954 else
17956 while (glyph <= start
17957 && BUFFERP (glyph->object)
17958 && (glyph->type == STRETCH_GLYPH
17959 || (glyph->type == CHAR_GLYPH
17960 && glyph->u.ch == ' ')))
17961 (glyph++)->face_id = face_id;
17968 /* Value is non-zero if glyph row ROW should be
17969 used to hold the cursor. */
17971 static int
17972 cursor_row_p (struct glyph_row *row)
17974 int result = 1;
17976 if (PT == CHARPOS (row->end.pos))
17978 /* Suppose the row ends on a string.
17979 Unless the row is continued, that means it ends on a newline
17980 in the string. If it's anything other than a display string
17981 (e.g. a before-string from an overlay), we don't want the
17982 cursor there. (This heuristic seems to give the optimal
17983 behavior for the various types of multi-line strings.) */
17984 if (CHARPOS (row->end.string_pos) >= 0)
17986 if (row->continued_p)
17987 result = 1;
17988 else
17990 /* Check for `display' property. */
17991 struct glyph *beg = row->glyphs[TEXT_AREA];
17992 struct glyph *end = beg + row->used[TEXT_AREA] - 1;
17993 struct glyph *glyph;
17995 result = 0;
17996 for (glyph = end; glyph >= beg; --glyph)
17997 if (STRINGP (glyph->object))
17999 Lisp_Object prop
18000 = Fget_char_property (make_number (PT),
18001 Qdisplay, Qnil);
18002 result =
18003 (!NILP (prop)
18004 && display_prop_string_p (prop, glyph->object));
18005 break;
18009 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
18011 /* If the row ends in middle of a real character,
18012 and the line is continued, we want the cursor here.
18013 That's because CHARPOS (ROW->end.pos) would equal
18014 PT if PT is before the character. */
18015 if (!row->ends_in_ellipsis_p)
18016 result = row->continued_p;
18017 else
18018 /* If the row ends in an ellipsis, then
18019 CHARPOS (ROW->end.pos) will equal point after the
18020 invisible text. We want that position to be displayed
18021 after the ellipsis. */
18022 result = 0;
18024 /* If the row ends at ZV, display the cursor at the end of that
18025 row instead of at the start of the row below. */
18026 else if (row->ends_at_zv_p)
18027 result = 1;
18028 else
18029 result = 0;
18032 return result;
18037 /* Push the display property PROP so that it will be rendered at the
18038 current position in IT. Return 1 if PROP was successfully pushed,
18039 0 otherwise. */
18041 static int
18042 push_display_prop (struct it *it, Lisp_Object prop)
18044 xassert (it->method == GET_FROM_BUFFER);
18046 push_it (it, NULL);
18048 if (STRINGP (prop))
18050 if (SCHARS (prop) == 0)
18052 pop_it (it);
18053 return 0;
18056 it->string = prop;
18057 it->multibyte_p = STRING_MULTIBYTE (it->string);
18058 it->current.overlay_string_index = -1;
18059 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
18060 it->end_charpos = it->string_nchars = SCHARS (it->string);
18061 it->method = GET_FROM_STRING;
18062 it->stop_charpos = 0;
18063 it->prev_stop = 0;
18064 it->base_level_stop = 0;
18065 it->string_from_display_prop_p = 1;
18066 it->from_disp_prop_p = 1;
18068 /* Force paragraph direction to be that of the parent
18069 buffer. */
18070 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
18071 it->paragraph_embedding = it->bidi_it.paragraph_dir;
18072 else
18073 it->paragraph_embedding = L2R;
18075 /* Set up the bidi iterator for this display string. */
18076 if (it->bidi_p)
18078 it->bidi_it.string.lstring = it->string;
18079 it->bidi_it.string.s = NULL;
18080 it->bidi_it.string.schars = it->end_charpos;
18081 it->bidi_it.string.bufpos = IT_CHARPOS (*it);
18082 it->bidi_it.string.from_disp_str = 1;
18083 it->bidi_it.string.unibyte = !it->multibyte_p;
18084 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
18087 else if (CONSP (prop) && EQ (XCAR (prop), Qspace))
18089 it->method = GET_FROM_STRETCH;
18090 it->object = prop;
18092 #ifdef HAVE_WINDOW_SYSTEM
18093 else if (IMAGEP (prop))
18095 it->what = IT_IMAGE;
18096 it->image_id = lookup_image (it->f, prop);
18097 it->method = GET_FROM_IMAGE;
18099 #endif /* HAVE_WINDOW_SYSTEM */
18100 else
18102 pop_it (it); /* bogus display property, give up */
18103 return 0;
18106 return 1;
18109 /* Return the character-property PROP at the current position in IT. */
18111 static Lisp_Object
18112 get_it_property (struct it *it, Lisp_Object prop)
18114 Lisp_Object position;
18116 if (STRINGP (it->object))
18117 position = make_number (IT_STRING_CHARPOS (*it));
18118 else if (BUFFERP (it->object))
18119 position = make_number (IT_CHARPOS (*it));
18120 else
18121 return Qnil;
18123 return Fget_char_property (position, prop, it->object);
18126 /* See if there's a line- or wrap-prefix, and if so, push it on IT. */
18128 static void
18129 handle_line_prefix (struct it *it)
18131 Lisp_Object prefix;
18133 if (it->continuation_lines_width > 0)
18135 prefix = get_it_property (it, Qwrap_prefix);
18136 if (NILP (prefix))
18137 prefix = Vwrap_prefix;
18139 else
18141 prefix = get_it_property (it, Qline_prefix);
18142 if (NILP (prefix))
18143 prefix = Vline_prefix;
18145 if (! NILP (prefix) && push_display_prop (it, prefix))
18147 /* If the prefix is wider than the window, and we try to wrap
18148 it, it would acquire its own wrap prefix, and so on till the
18149 iterator stack overflows. So, don't wrap the prefix. */
18150 it->line_wrap = TRUNCATE;
18151 it->avoid_cursor_p = 1;
18157 /* Remove N glyphs at the start of a reversed IT->glyph_row. Called
18158 only for R2L lines from display_line and display_string, when they
18159 decide that too many glyphs were produced by PRODUCE_GLYPHS, and
18160 the line/string needs to be continued on the next glyph row. */
18161 static void
18162 unproduce_glyphs (struct it *it, int n)
18164 struct glyph *glyph, *end;
18166 xassert (it->glyph_row);
18167 xassert (it->glyph_row->reversed_p);
18168 xassert (it->area == TEXT_AREA);
18169 xassert (n <= it->glyph_row->used[TEXT_AREA]);
18171 if (n > it->glyph_row->used[TEXT_AREA])
18172 n = it->glyph_row->used[TEXT_AREA];
18173 glyph = it->glyph_row->glyphs[TEXT_AREA] + n;
18174 end = it->glyph_row->glyphs[TEXT_AREA] + it->glyph_row->used[TEXT_AREA];
18175 for ( ; glyph < end; glyph++)
18176 glyph[-n] = *glyph;
18179 /* Find the positions in a bidi-reordered ROW to serve as ROW->minpos
18180 and ROW->maxpos. */
18181 static void
18182 find_row_edges (struct it *it, struct glyph_row *row,
18183 EMACS_INT min_pos, EMACS_INT min_bpos,
18184 EMACS_INT max_pos, EMACS_INT max_bpos)
18186 /* FIXME: Revisit this when glyph ``spilling'' in continuation
18187 lines' rows is implemented for bidi-reordered rows. */
18189 /* ROW->minpos is the value of min_pos, the minimal buffer position
18190 we have in ROW, or ROW->start.pos if that is smaller. */
18191 if (min_pos <= ZV && min_pos < row->start.pos.charpos)
18192 SET_TEXT_POS (row->minpos, min_pos, min_bpos);
18193 else
18194 /* We didn't find buffer positions smaller than ROW->start, or
18195 didn't find _any_ valid buffer positions in any of the glyphs,
18196 so we must trust the iterator's computed positions. */
18197 row->minpos = row->start.pos;
18198 if (max_pos <= 0)
18200 max_pos = CHARPOS (it->current.pos);
18201 max_bpos = BYTEPOS (it->current.pos);
18204 /* Here are the various use-cases for ending the row, and the
18205 corresponding values for ROW->maxpos:
18207 Line ends in a newline from buffer eol_pos + 1
18208 Line is continued from buffer max_pos + 1
18209 Line is truncated on right it->current.pos
18210 Line ends in a newline from string max_pos
18211 Line is continued from string max_pos
18212 Line is continued from display vector max_pos
18213 Line is entirely from a string min_pos == max_pos
18214 Line is entirely from a display vector min_pos == max_pos
18215 Line that ends at ZV ZV
18217 If you discover other use-cases, please add them here as
18218 appropriate. */
18219 if (row->ends_at_zv_p)
18220 row->maxpos = it->current.pos;
18221 else if (row->used[TEXT_AREA])
18223 if (row->ends_in_newline_from_string_p)
18224 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
18225 else if (CHARPOS (it->eol_pos) > 0)
18226 SET_TEXT_POS (row->maxpos,
18227 CHARPOS (it->eol_pos) + 1, BYTEPOS (it->eol_pos) + 1);
18228 else if (row->continued_p)
18230 /* If max_pos is different from IT's current position, it
18231 means IT->method does not belong to the display element
18232 at max_pos. However, it also means that the display
18233 element at max_pos was displayed in its entirety on this
18234 line, which is equivalent to saying that the next line
18235 starts at the next buffer position. */
18236 if (IT_CHARPOS (*it) == max_pos && it->method != GET_FROM_BUFFER)
18237 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
18238 else
18240 INC_BOTH (max_pos, max_bpos);
18241 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
18244 else if (row->truncated_on_right_p)
18245 /* display_line already called reseat_at_next_visible_line_start,
18246 which puts the iterator at the beginning of the next line, in
18247 the logical order. */
18248 row->maxpos = it->current.pos;
18249 else if (max_pos == min_pos && it->method != GET_FROM_BUFFER)
18250 /* A line that is entirely from a string/image/stretch... */
18251 row->maxpos = row->minpos;
18252 else
18253 abort ();
18255 else
18256 row->maxpos = it->current.pos;
18259 /* Construct the glyph row IT->glyph_row in the desired matrix of
18260 IT->w from text at the current position of IT. See dispextern.h
18261 for an overview of struct it. Value is non-zero if
18262 IT->glyph_row displays text, as opposed to a line displaying ZV
18263 only. */
18265 static int
18266 display_line (struct it *it)
18268 struct glyph_row *row = it->glyph_row;
18269 Lisp_Object overlay_arrow_string;
18270 struct it wrap_it;
18271 void *wrap_data = NULL;
18272 int may_wrap = 0, wrap_x IF_LINT (= 0);
18273 int wrap_row_used = -1;
18274 int wrap_row_ascent IF_LINT (= 0), wrap_row_height IF_LINT (= 0);
18275 int wrap_row_phys_ascent IF_LINT (= 0), wrap_row_phys_height IF_LINT (= 0);
18276 int wrap_row_extra_line_spacing IF_LINT (= 0);
18277 EMACS_INT wrap_row_min_pos IF_LINT (= 0), wrap_row_min_bpos IF_LINT (= 0);
18278 EMACS_INT wrap_row_max_pos IF_LINT (= 0), wrap_row_max_bpos IF_LINT (= 0);
18279 int cvpos;
18280 EMACS_INT min_pos = ZV + 1, max_pos = 0;
18281 EMACS_INT min_bpos IF_LINT (= 0), max_bpos IF_LINT (= 0);
18283 /* We always start displaying at hpos zero even if hscrolled. */
18284 xassert (it->hpos == 0 && it->current_x == 0);
18286 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
18287 >= it->w->desired_matrix->nrows)
18289 it->w->nrows_scale_factor++;
18290 fonts_changed_p = 1;
18291 return 0;
18294 /* Is IT->w showing the region? */
18295 it->w->region_showing = it->region_beg_charpos > 0 ? Qt : Qnil;
18297 /* Clear the result glyph row and enable it. */
18298 prepare_desired_row (row);
18300 row->y = it->current_y;
18301 row->start = it->start;
18302 row->continuation_lines_width = it->continuation_lines_width;
18303 row->displays_text_p = 1;
18304 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
18305 it->starts_in_middle_of_char_p = 0;
18307 /* Arrange the overlays nicely for our purposes. Usually, we call
18308 display_line on only one line at a time, in which case this
18309 can't really hurt too much, or we call it on lines which appear
18310 one after another in the buffer, in which case all calls to
18311 recenter_overlay_lists but the first will be pretty cheap. */
18312 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
18314 /* Move over display elements that are not visible because we are
18315 hscrolled. This may stop at an x-position < IT->first_visible_x
18316 if the first glyph is partially visible or if we hit a line end. */
18317 if (it->current_x < it->first_visible_x)
18319 this_line_min_pos = row->start.pos;
18320 move_it_in_display_line_to (it, ZV, it->first_visible_x,
18321 MOVE_TO_POS | MOVE_TO_X);
18322 /* Record the smallest positions seen while we moved over
18323 display elements that are not visible. This is needed by
18324 redisplay_internal for optimizing the case where the cursor
18325 stays inside the same line. The rest of this function only
18326 considers positions that are actually displayed, so
18327 RECORD_MAX_MIN_POS will not otherwise record positions that
18328 are hscrolled to the left of the left edge of the window. */
18329 min_pos = CHARPOS (this_line_min_pos);
18330 min_bpos = BYTEPOS (this_line_min_pos);
18332 else
18334 /* We only do this when not calling `move_it_in_display_line_to'
18335 above, because move_it_in_display_line_to calls
18336 handle_line_prefix itself. */
18337 handle_line_prefix (it);
18340 /* Get the initial row height. This is either the height of the
18341 text hscrolled, if there is any, or zero. */
18342 row->ascent = it->max_ascent;
18343 row->height = it->max_ascent + it->max_descent;
18344 row->phys_ascent = it->max_phys_ascent;
18345 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
18346 row->extra_line_spacing = it->max_extra_line_spacing;
18348 /* Utility macro to record max and min buffer positions seen until now. */
18349 #define RECORD_MAX_MIN_POS(IT) \
18350 do \
18352 if (IT_CHARPOS (*(IT)) < min_pos) \
18354 min_pos = IT_CHARPOS (*(IT)); \
18355 min_bpos = IT_BYTEPOS (*(IT)); \
18357 if (IT_CHARPOS (*(IT)) > max_pos) \
18359 max_pos = IT_CHARPOS (*(IT)); \
18360 max_bpos = IT_BYTEPOS (*(IT)); \
18363 while (0)
18365 /* Loop generating characters. The loop is left with IT on the next
18366 character to display. */
18367 while (1)
18369 int n_glyphs_before, hpos_before, x_before;
18370 int x, nglyphs;
18371 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
18373 /* Retrieve the next thing to display. Value is zero if end of
18374 buffer reached. */
18375 if (!get_next_display_element (it))
18377 /* Maybe add a space at the end of this line that is used to
18378 display the cursor there under X. Set the charpos of the
18379 first glyph of blank lines not corresponding to any text
18380 to -1. */
18381 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
18382 row->exact_window_width_line_p = 1;
18383 else if ((append_space_for_newline (it, 1) && row->used[TEXT_AREA] == 1)
18384 || row->used[TEXT_AREA] == 0)
18386 row->glyphs[TEXT_AREA]->charpos = -1;
18387 row->displays_text_p = 0;
18389 if (!NILP (BVAR (XBUFFER (it->w->buffer), indicate_empty_lines))
18390 && (!MINI_WINDOW_P (it->w)
18391 || (minibuf_level && EQ (it->window, minibuf_window))))
18392 row->indicate_empty_line_p = 1;
18395 it->continuation_lines_width = 0;
18396 row->ends_at_zv_p = 1;
18397 /* A row that displays right-to-left text must always have
18398 its last face extended all the way to the end of line,
18399 even if this row ends in ZV, because we still write to
18400 the screen left to right. */
18401 if (row->reversed_p)
18402 extend_face_to_end_of_line (it);
18403 break;
18406 /* Now, get the metrics of what we want to display. This also
18407 generates glyphs in `row' (which is IT->glyph_row). */
18408 n_glyphs_before = row->used[TEXT_AREA];
18409 x = it->current_x;
18411 /* Remember the line height so far in case the next element doesn't
18412 fit on the line. */
18413 if (it->line_wrap != TRUNCATE)
18415 ascent = it->max_ascent;
18416 descent = it->max_descent;
18417 phys_ascent = it->max_phys_ascent;
18418 phys_descent = it->max_phys_descent;
18420 if (it->line_wrap == WORD_WRAP && it->area == TEXT_AREA)
18422 if (IT_DISPLAYING_WHITESPACE (it))
18423 may_wrap = 1;
18424 else if (may_wrap)
18426 SAVE_IT (wrap_it, *it, wrap_data);
18427 wrap_x = x;
18428 wrap_row_used = row->used[TEXT_AREA];
18429 wrap_row_ascent = row->ascent;
18430 wrap_row_height = row->height;
18431 wrap_row_phys_ascent = row->phys_ascent;
18432 wrap_row_phys_height = row->phys_height;
18433 wrap_row_extra_line_spacing = row->extra_line_spacing;
18434 wrap_row_min_pos = min_pos;
18435 wrap_row_min_bpos = min_bpos;
18436 wrap_row_max_pos = max_pos;
18437 wrap_row_max_bpos = max_bpos;
18438 may_wrap = 0;
18443 PRODUCE_GLYPHS (it);
18445 /* If this display element was in marginal areas, continue with
18446 the next one. */
18447 if (it->area != TEXT_AREA)
18449 row->ascent = max (row->ascent, it->max_ascent);
18450 row->height = max (row->height, it->max_ascent + it->max_descent);
18451 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
18452 row->phys_height = max (row->phys_height,
18453 it->max_phys_ascent + it->max_phys_descent);
18454 row->extra_line_spacing = max (row->extra_line_spacing,
18455 it->max_extra_line_spacing);
18456 set_iterator_to_next (it, 1);
18457 continue;
18460 /* Does the display element fit on the line? If we truncate
18461 lines, we should draw past the right edge of the window. If
18462 we don't truncate, we want to stop so that we can display the
18463 continuation glyph before the right margin. If lines are
18464 continued, there are two possible strategies for characters
18465 resulting in more than 1 glyph (e.g. tabs): Display as many
18466 glyphs as possible in this line and leave the rest for the
18467 continuation line, or display the whole element in the next
18468 line. Original redisplay did the former, so we do it also. */
18469 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
18470 hpos_before = it->hpos;
18471 x_before = x;
18473 if (/* Not a newline. */
18474 nglyphs > 0
18475 /* Glyphs produced fit entirely in the line. */
18476 && it->current_x < it->last_visible_x)
18478 it->hpos += nglyphs;
18479 row->ascent = max (row->ascent, it->max_ascent);
18480 row->height = max (row->height, it->max_ascent + it->max_descent);
18481 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
18482 row->phys_height = max (row->phys_height,
18483 it->max_phys_ascent + it->max_phys_descent);
18484 row->extra_line_spacing = max (row->extra_line_spacing,
18485 it->max_extra_line_spacing);
18486 if (it->current_x - it->pixel_width < it->first_visible_x)
18487 row->x = x - it->first_visible_x;
18488 /* Record the maximum and minimum buffer positions seen so
18489 far in glyphs that will be displayed by this row. */
18490 if (it->bidi_p)
18491 RECORD_MAX_MIN_POS (it);
18493 else
18495 int i, new_x;
18496 struct glyph *glyph;
18498 for (i = 0; i < nglyphs; ++i, x = new_x)
18500 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
18501 new_x = x + glyph->pixel_width;
18503 if (/* Lines are continued. */
18504 it->line_wrap != TRUNCATE
18505 && (/* Glyph doesn't fit on the line. */
18506 new_x > it->last_visible_x
18507 /* Or it fits exactly on a window system frame. */
18508 || (new_x == it->last_visible_x
18509 && FRAME_WINDOW_P (it->f))))
18511 /* End of a continued line. */
18513 if (it->hpos == 0
18514 || (new_x == it->last_visible_x
18515 && FRAME_WINDOW_P (it->f)))
18517 /* Current glyph is the only one on the line or
18518 fits exactly on the line. We must continue
18519 the line because we can't draw the cursor
18520 after the glyph. */
18521 row->continued_p = 1;
18522 it->current_x = new_x;
18523 it->continuation_lines_width += new_x;
18524 ++it->hpos;
18525 /* Record the maximum and minimum buffer
18526 positions seen so far in glyphs that will be
18527 displayed by this row. */
18528 if (it->bidi_p)
18529 RECORD_MAX_MIN_POS (it);
18530 if (i == nglyphs - 1)
18532 /* If line-wrap is on, check if a previous
18533 wrap point was found. */
18534 if (wrap_row_used > 0
18535 /* Even if there is a previous wrap
18536 point, continue the line here as
18537 usual, if (i) the previous character
18538 was a space or tab AND (ii) the
18539 current character is not. */
18540 && (!may_wrap
18541 || IT_DISPLAYING_WHITESPACE (it)))
18542 goto back_to_wrap;
18544 set_iterator_to_next (it, 1);
18545 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
18547 if (!get_next_display_element (it))
18549 row->exact_window_width_line_p = 1;
18550 it->continuation_lines_width = 0;
18551 row->continued_p = 0;
18552 row->ends_at_zv_p = 1;
18554 else if (ITERATOR_AT_END_OF_LINE_P (it))
18556 row->continued_p = 0;
18557 row->exact_window_width_line_p = 1;
18562 else if (CHAR_GLYPH_PADDING_P (*glyph)
18563 && !FRAME_WINDOW_P (it->f))
18565 /* A padding glyph that doesn't fit on this line.
18566 This means the whole character doesn't fit
18567 on the line. */
18568 if (row->reversed_p)
18569 unproduce_glyphs (it, row->used[TEXT_AREA]
18570 - n_glyphs_before);
18571 row->used[TEXT_AREA] = n_glyphs_before;
18573 /* Fill the rest of the row with continuation
18574 glyphs like in 20.x. */
18575 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
18576 < row->glyphs[1 + TEXT_AREA])
18577 produce_special_glyphs (it, IT_CONTINUATION);
18579 row->continued_p = 1;
18580 it->current_x = x_before;
18581 it->continuation_lines_width += x_before;
18583 /* Restore the height to what it was before the
18584 element not fitting on the line. */
18585 it->max_ascent = ascent;
18586 it->max_descent = descent;
18587 it->max_phys_ascent = phys_ascent;
18588 it->max_phys_descent = phys_descent;
18590 else if (wrap_row_used > 0)
18592 back_to_wrap:
18593 if (row->reversed_p)
18594 unproduce_glyphs (it,
18595 row->used[TEXT_AREA] - wrap_row_used);
18596 RESTORE_IT (it, &wrap_it, wrap_data);
18597 it->continuation_lines_width += wrap_x;
18598 row->used[TEXT_AREA] = wrap_row_used;
18599 row->ascent = wrap_row_ascent;
18600 row->height = wrap_row_height;
18601 row->phys_ascent = wrap_row_phys_ascent;
18602 row->phys_height = wrap_row_phys_height;
18603 row->extra_line_spacing = wrap_row_extra_line_spacing;
18604 min_pos = wrap_row_min_pos;
18605 min_bpos = wrap_row_min_bpos;
18606 max_pos = wrap_row_max_pos;
18607 max_bpos = wrap_row_max_bpos;
18608 row->continued_p = 1;
18609 row->ends_at_zv_p = 0;
18610 row->exact_window_width_line_p = 0;
18611 it->continuation_lines_width += x;
18613 /* Make sure that a non-default face is extended
18614 up to the right margin of the window. */
18615 extend_face_to_end_of_line (it);
18617 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
18619 /* A TAB that extends past the right edge of the
18620 window. This produces a single glyph on
18621 window system frames. We leave the glyph in
18622 this row and let it fill the row, but don't
18623 consume the TAB. */
18624 it->continuation_lines_width += it->last_visible_x;
18625 row->ends_in_middle_of_char_p = 1;
18626 row->continued_p = 1;
18627 glyph->pixel_width = it->last_visible_x - x;
18628 it->starts_in_middle_of_char_p = 1;
18630 else
18632 /* Something other than a TAB that draws past
18633 the right edge of the window. Restore
18634 positions to values before the element. */
18635 if (row->reversed_p)
18636 unproduce_glyphs (it, row->used[TEXT_AREA]
18637 - (n_glyphs_before + i));
18638 row->used[TEXT_AREA] = n_glyphs_before + i;
18640 /* Display continuation glyphs. */
18641 if (!FRAME_WINDOW_P (it->f))
18642 produce_special_glyphs (it, IT_CONTINUATION);
18643 row->continued_p = 1;
18645 it->current_x = x_before;
18646 it->continuation_lines_width += x;
18647 extend_face_to_end_of_line (it);
18649 if (nglyphs > 1 && i > 0)
18651 row->ends_in_middle_of_char_p = 1;
18652 it->starts_in_middle_of_char_p = 1;
18655 /* Restore the height to what it was before the
18656 element not fitting on the line. */
18657 it->max_ascent = ascent;
18658 it->max_descent = descent;
18659 it->max_phys_ascent = phys_ascent;
18660 it->max_phys_descent = phys_descent;
18663 break;
18665 else if (new_x > it->first_visible_x)
18667 /* Increment number of glyphs actually displayed. */
18668 ++it->hpos;
18670 /* Record the maximum and minimum buffer positions
18671 seen so far in glyphs that will be displayed by
18672 this row. */
18673 if (it->bidi_p)
18674 RECORD_MAX_MIN_POS (it);
18676 if (x < it->first_visible_x)
18677 /* Glyph is partially visible, i.e. row starts at
18678 negative X position. */
18679 row->x = x - it->first_visible_x;
18681 else
18683 /* Glyph is completely off the left margin of the
18684 window. This should not happen because of the
18685 move_it_in_display_line at the start of this
18686 function, unless the text display area of the
18687 window is empty. */
18688 xassert (it->first_visible_x <= it->last_visible_x);
18692 row->ascent = max (row->ascent, it->max_ascent);
18693 row->height = max (row->height, it->max_ascent + it->max_descent);
18694 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
18695 row->phys_height = max (row->phys_height,
18696 it->max_phys_ascent + it->max_phys_descent);
18697 row->extra_line_spacing = max (row->extra_line_spacing,
18698 it->max_extra_line_spacing);
18700 /* End of this display line if row is continued. */
18701 if (row->continued_p || row->ends_at_zv_p)
18702 break;
18705 at_end_of_line:
18706 /* Is this a line end? If yes, we're also done, after making
18707 sure that a non-default face is extended up to the right
18708 margin of the window. */
18709 if (ITERATOR_AT_END_OF_LINE_P (it))
18711 int used_before = row->used[TEXT_AREA];
18713 row->ends_in_newline_from_string_p = STRINGP (it->object);
18715 /* Add a space at the end of the line that is used to
18716 display the cursor there. */
18717 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
18718 append_space_for_newline (it, 0);
18720 /* Extend the face to the end of the line. */
18721 extend_face_to_end_of_line (it);
18723 /* Make sure we have the position. */
18724 if (used_before == 0)
18725 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
18727 /* Record the position of the newline, for use in
18728 find_row_edges. */
18729 it->eol_pos = it->current.pos;
18731 /* Consume the line end. This skips over invisible lines. */
18732 set_iterator_to_next (it, 1);
18733 it->continuation_lines_width = 0;
18734 break;
18737 /* Proceed with next display element. Note that this skips
18738 over lines invisible because of selective display. */
18739 set_iterator_to_next (it, 1);
18741 /* If we truncate lines, we are done when the last displayed
18742 glyphs reach past the right margin of the window. */
18743 if (it->line_wrap == TRUNCATE
18744 && (FRAME_WINDOW_P (it->f)
18745 ? (it->current_x >= it->last_visible_x)
18746 : (it->current_x > it->last_visible_x)))
18748 /* Maybe add truncation glyphs. */
18749 if (!FRAME_WINDOW_P (it->f))
18751 int i, n;
18753 if (!row->reversed_p)
18755 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
18756 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
18757 break;
18759 else
18761 for (i = 0; i < row->used[TEXT_AREA]; i++)
18762 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
18763 break;
18764 /* Remove any padding glyphs at the front of ROW, to
18765 make room for the truncation glyphs we will be
18766 adding below. The loop below always inserts at
18767 least one truncation glyph, so also remove the
18768 last glyph added to ROW. */
18769 unproduce_glyphs (it, i + 1);
18770 /* Adjust i for the loop below. */
18771 i = row->used[TEXT_AREA] - (i + 1);
18774 for (n = row->used[TEXT_AREA]; i < n; ++i)
18776 row->used[TEXT_AREA] = i;
18777 produce_special_glyphs (it, IT_TRUNCATION);
18780 else if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
18782 /* Don't truncate if we can overflow newline into fringe. */
18783 if (!get_next_display_element (it))
18785 it->continuation_lines_width = 0;
18786 row->ends_at_zv_p = 1;
18787 row->exact_window_width_line_p = 1;
18788 break;
18790 if (ITERATOR_AT_END_OF_LINE_P (it))
18792 row->exact_window_width_line_p = 1;
18793 goto at_end_of_line;
18797 row->truncated_on_right_p = 1;
18798 it->continuation_lines_width = 0;
18799 reseat_at_next_visible_line_start (it, 0);
18800 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
18801 it->hpos = hpos_before;
18802 it->current_x = x_before;
18803 break;
18807 /* If line is not empty and hscrolled, maybe insert truncation glyphs
18808 at the left window margin. */
18809 if (it->first_visible_x
18810 && IT_CHARPOS (*it) != CHARPOS (row->start.pos))
18812 if (!FRAME_WINDOW_P (it->f))
18813 insert_left_trunc_glyphs (it);
18814 row->truncated_on_left_p = 1;
18817 /* Remember the position at which this line ends.
18819 BIDI Note: any code that needs MATRIX_ROW_START/END_CHARPOS
18820 cannot be before the call to find_row_edges below, since that is
18821 where these positions are determined. */
18822 row->end = it->current;
18823 if (!it->bidi_p)
18825 row->minpos = row->start.pos;
18826 row->maxpos = row->end.pos;
18828 else
18830 /* ROW->minpos and ROW->maxpos must be the smallest and
18831 `1 + the largest' buffer positions in ROW. But if ROW was
18832 bidi-reordered, these two positions can be anywhere in the
18833 row, so we must determine them now. */
18834 find_row_edges (it, row, min_pos, min_bpos, max_pos, max_bpos);
18837 /* If the start of this line is the overlay arrow-position, then
18838 mark this glyph row as the one containing the overlay arrow.
18839 This is clearly a mess with variable size fonts. It would be
18840 better to let it be displayed like cursors under X. */
18841 if ((row->displays_text_p || !overlay_arrow_seen)
18842 && (overlay_arrow_string = overlay_arrow_at_row (it, row),
18843 !NILP (overlay_arrow_string)))
18845 /* Overlay arrow in window redisplay is a fringe bitmap. */
18846 if (STRINGP (overlay_arrow_string))
18848 struct glyph_row *arrow_row
18849 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
18850 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
18851 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
18852 struct glyph *p = row->glyphs[TEXT_AREA];
18853 struct glyph *p2, *end;
18855 /* Copy the arrow glyphs. */
18856 while (glyph < arrow_end)
18857 *p++ = *glyph++;
18859 /* Throw away padding glyphs. */
18860 p2 = p;
18861 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
18862 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
18863 ++p2;
18864 if (p2 > p)
18866 while (p2 < end)
18867 *p++ = *p2++;
18868 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
18871 else
18873 xassert (INTEGERP (overlay_arrow_string));
18874 row->overlay_arrow_bitmap = XINT (overlay_arrow_string);
18876 overlay_arrow_seen = 1;
18879 /* Compute pixel dimensions of this line. */
18880 compute_line_metrics (it);
18882 /* Record whether this row ends inside an ellipsis. */
18883 row->ends_in_ellipsis_p
18884 = (it->method == GET_FROM_DISPLAY_VECTOR
18885 && it->ellipsis_p);
18887 /* Save fringe bitmaps in this row. */
18888 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
18889 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
18890 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
18891 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
18893 it->left_user_fringe_bitmap = 0;
18894 it->left_user_fringe_face_id = 0;
18895 it->right_user_fringe_bitmap = 0;
18896 it->right_user_fringe_face_id = 0;
18898 /* Maybe set the cursor. */
18899 cvpos = it->w->cursor.vpos;
18900 if ((cvpos < 0
18901 /* In bidi-reordered rows, keep checking for proper cursor
18902 position even if one has been found already, because buffer
18903 positions in such rows change non-linearly with ROW->VPOS,
18904 when a line is continued. One exception: when we are at ZV,
18905 display cursor on the first suitable glyph row, since all
18906 the empty rows after that also have their position set to ZV. */
18907 /* FIXME: Revisit this when glyph ``spilling'' in continuation
18908 lines' rows is implemented for bidi-reordered rows. */
18909 || (it->bidi_p
18910 && !MATRIX_ROW (it->w->desired_matrix, cvpos)->ends_at_zv_p))
18911 && PT >= MATRIX_ROW_START_CHARPOS (row)
18912 && PT <= MATRIX_ROW_END_CHARPOS (row)
18913 && cursor_row_p (row))
18914 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
18916 /* Highlight trailing whitespace. */
18917 if (!NILP (Vshow_trailing_whitespace))
18918 highlight_trailing_whitespace (it->f, it->glyph_row);
18920 /* Prepare for the next line. This line starts horizontally at (X
18921 HPOS) = (0 0). Vertical positions are incremented. As a
18922 convenience for the caller, IT->glyph_row is set to the next
18923 row to be used. */
18924 it->current_x = it->hpos = 0;
18925 it->current_y += row->height;
18926 SET_TEXT_POS (it->eol_pos, 0, 0);
18927 ++it->vpos;
18928 ++it->glyph_row;
18929 /* The next row should by default use the same value of the
18930 reversed_p flag as this one. set_iterator_to_next decides when
18931 it's a new paragraph, and PRODUCE_GLYPHS recomputes the value of
18932 the flag accordingly. */
18933 if (it->glyph_row < MATRIX_BOTTOM_TEXT_ROW (it->w->desired_matrix, it->w))
18934 it->glyph_row->reversed_p = row->reversed_p;
18935 it->start = row->end;
18936 return row->displays_text_p;
18938 #undef RECORD_MAX_MIN_POS
18941 DEFUN ("current-bidi-paragraph-direction", Fcurrent_bidi_paragraph_direction,
18942 Scurrent_bidi_paragraph_direction, 0, 1, 0,
18943 doc: /* Return paragraph direction at point in BUFFER.
18944 Value is either `left-to-right' or `right-to-left'.
18945 If BUFFER is omitted or nil, it defaults to the current buffer.
18947 Paragraph direction determines how the text in the paragraph is displayed.
18948 In left-to-right paragraphs, text begins at the left margin of the window
18949 and the reading direction is generally left to right. In right-to-left
18950 paragraphs, text begins at the right margin and is read from right to left.
18952 See also `bidi-paragraph-direction'. */)
18953 (Lisp_Object buffer)
18955 struct buffer *buf = current_buffer;
18956 struct buffer *old = buf;
18958 if (! NILP (buffer))
18960 CHECK_BUFFER (buffer);
18961 buf = XBUFFER (buffer);
18964 if (NILP (BVAR (buf, bidi_display_reordering)))
18965 return Qleft_to_right;
18966 else if (!NILP (BVAR (buf, bidi_paragraph_direction)))
18967 return BVAR (buf, bidi_paragraph_direction);
18968 else
18970 /* Determine the direction from buffer text. We could try to
18971 use current_matrix if it is up to date, but this seems fast
18972 enough as it is. */
18973 struct bidi_it itb;
18974 EMACS_INT pos = BUF_PT (buf);
18975 EMACS_INT bytepos = BUF_PT_BYTE (buf);
18976 int c;
18978 set_buffer_temp (buf);
18979 /* bidi_paragraph_init finds the base direction of the paragraph
18980 by searching forward from paragraph start. We need the base
18981 direction of the current or _previous_ paragraph, so we need
18982 to make sure we are within that paragraph. To that end, find
18983 the previous non-empty line. */
18984 if (pos >= ZV && pos > BEGV)
18986 pos--;
18987 bytepos = CHAR_TO_BYTE (pos);
18989 while ((c = FETCH_BYTE (bytepos)) == '\n'
18990 || c == ' ' || c == '\t' || c == '\f')
18992 if (bytepos <= BEGV_BYTE)
18993 break;
18994 bytepos--;
18995 pos--;
18997 while (!CHAR_HEAD_P (FETCH_BYTE (bytepos)))
18998 bytepos--;
18999 itb.charpos = pos;
19000 itb.bytepos = bytepos;
19001 itb.nchars = -1;
19002 itb.string.s = NULL;
19003 itb.string.lstring = Qnil;
19004 itb.frame_window_p = FRAME_WINDOW_P (SELECTED_FRAME ()); /* guesswork */
19005 itb.first_elt = 1;
19006 itb.separator_limit = -1;
19007 itb.paragraph_dir = NEUTRAL_DIR;
19009 bidi_paragraph_init (NEUTRAL_DIR, &itb, 1);
19010 set_buffer_temp (old);
19011 switch (itb.paragraph_dir)
19013 case L2R:
19014 return Qleft_to_right;
19015 break;
19016 case R2L:
19017 return Qright_to_left;
19018 break;
19019 default:
19020 abort ();
19027 /***********************************************************************
19028 Menu Bar
19029 ***********************************************************************/
19031 /* Redisplay the menu bar in the frame for window W.
19033 The menu bar of X frames that don't have X toolkit support is
19034 displayed in a special window W->frame->menu_bar_window.
19036 The menu bar of terminal frames is treated specially as far as
19037 glyph matrices are concerned. Menu bar lines are not part of
19038 windows, so the update is done directly on the frame matrix rows
19039 for the menu bar. */
19041 static void
19042 display_menu_bar (struct window *w)
19044 struct frame *f = XFRAME (WINDOW_FRAME (w));
19045 struct it it;
19046 Lisp_Object items;
19047 int i;
19049 /* Don't do all this for graphical frames. */
19050 #ifdef HAVE_NTGUI
19051 if (FRAME_W32_P (f))
19052 return;
19053 #endif
19054 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
19055 if (FRAME_X_P (f))
19056 return;
19057 #endif
19059 #ifdef HAVE_NS
19060 if (FRAME_NS_P (f))
19061 return;
19062 #endif /* HAVE_NS */
19064 #ifdef USE_X_TOOLKIT
19065 xassert (!FRAME_WINDOW_P (f));
19066 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
19067 it.first_visible_x = 0;
19068 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
19069 #else /* not USE_X_TOOLKIT */
19070 if (FRAME_WINDOW_P (f))
19072 /* Menu bar lines are displayed in the desired matrix of the
19073 dummy window menu_bar_window. */
19074 struct window *menu_w;
19075 xassert (WINDOWP (f->menu_bar_window));
19076 menu_w = XWINDOW (f->menu_bar_window);
19077 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
19078 MENU_FACE_ID);
19079 it.first_visible_x = 0;
19080 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
19082 else
19084 /* This is a TTY frame, i.e. character hpos/vpos are used as
19085 pixel x/y. */
19086 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
19087 MENU_FACE_ID);
19088 it.first_visible_x = 0;
19089 it.last_visible_x = FRAME_COLS (f);
19091 #endif /* not USE_X_TOOLKIT */
19093 /* FIXME: This should be controlled by a user option. See the
19094 comments in redisplay_tool_bar and display_mode_line about
19095 this. */
19096 it.paragraph_embedding = L2R;
19098 if (! mode_line_inverse_video)
19099 /* Force the menu-bar to be displayed in the default face. */
19100 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
19102 /* Clear all rows of the menu bar. */
19103 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
19105 struct glyph_row *row = it.glyph_row + i;
19106 clear_glyph_row (row);
19107 row->enabled_p = 1;
19108 row->full_width_p = 1;
19111 /* Display all items of the menu bar. */
19112 items = FRAME_MENU_BAR_ITEMS (it.f);
19113 for (i = 0; i < ASIZE (items); i += 4)
19115 Lisp_Object string;
19117 /* Stop at nil string. */
19118 string = AREF (items, i + 1);
19119 if (NILP (string))
19120 break;
19122 /* Remember where item was displayed. */
19123 ASET (items, i + 3, make_number (it.hpos));
19125 /* Display the item, pad with one space. */
19126 if (it.current_x < it.last_visible_x)
19127 display_string (NULL, string, Qnil, 0, 0, &it,
19128 SCHARS (string) + 1, 0, 0, -1);
19131 /* Fill out the line with spaces. */
19132 if (it.current_x < it.last_visible_x)
19133 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
19135 /* Compute the total height of the lines. */
19136 compute_line_metrics (&it);
19141 /***********************************************************************
19142 Mode Line
19143 ***********************************************************************/
19145 /* Redisplay mode lines in the window tree whose root is WINDOW. If
19146 FORCE is non-zero, redisplay mode lines unconditionally.
19147 Otherwise, redisplay only mode lines that are garbaged. Value is
19148 the number of windows whose mode lines were redisplayed. */
19150 static int
19151 redisplay_mode_lines (Lisp_Object window, int force)
19153 int nwindows = 0;
19155 while (!NILP (window))
19157 struct window *w = XWINDOW (window);
19159 if (WINDOWP (w->hchild))
19160 nwindows += redisplay_mode_lines (w->hchild, force);
19161 else if (WINDOWP (w->vchild))
19162 nwindows += redisplay_mode_lines (w->vchild, force);
19163 else if (force
19164 || FRAME_GARBAGED_P (XFRAME (w->frame))
19165 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
19167 struct text_pos lpoint;
19168 struct buffer *old = current_buffer;
19170 /* Set the window's buffer for the mode line display. */
19171 SET_TEXT_POS (lpoint, PT, PT_BYTE);
19172 set_buffer_internal_1 (XBUFFER (w->buffer));
19174 /* Point refers normally to the selected window. For any
19175 other window, set up appropriate value. */
19176 if (!EQ (window, selected_window))
19178 struct text_pos pt;
19180 SET_TEXT_POS_FROM_MARKER (pt, w->pointm);
19181 if (CHARPOS (pt) < BEGV)
19182 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
19183 else if (CHARPOS (pt) > (ZV - 1))
19184 TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
19185 else
19186 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
19189 /* Display mode lines. */
19190 clear_glyph_matrix (w->desired_matrix);
19191 if (display_mode_lines (w))
19193 ++nwindows;
19194 w->must_be_updated_p = 1;
19197 /* Restore old settings. */
19198 set_buffer_internal_1 (old);
19199 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
19202 window = w->next;
19205 return nwindows;
19209 /* Display the mode and/or header line of window W. Value is the
19210 sum number of mode lines and header lines displayed. */
19212 static int
19213 display_mode_lines (struct window *w)
19215 Lisp_Object old_selected_window, old_selected_frame;
19216 int n = 0;
19218 old_selected_frame = selected_frame;
19219 selected_frame = w->frame;
19220 old_selected_window = selected_window;
19221 XSETWINDOW (selected_window, w);
19223 /* These will be set while the mode line specs are processed. */
19224 line_number_displayed = 0;
19225 w->column_number_displayed = Qnil;
19227 if (WINDOW_WANTS_MODELINE_P (w))
19229 struct window *sel_w = XWINDOW (old_selected_window);
19231 /* Select mode line face based on the real selected window. */
19232 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
19233 BVAR (current_buffer, mode_line_format));
19234 ++n;
19237 if (WINDOW_WANTS_HEADER_LINE_P (w))
19239 display_mode_line (w, HEADER_LINE_FACE_ID,
19240 BVAR (current_buffer, header_line_format));
19241 ++n;
19244 selected_frame = old_selected_frame;
19245 selected_window = old_selected_window;
19246 return n;
19250 /* Display mode or header line of window W. FACE_ID specifies which
19251 line to display; it is either MODE_LINE_FACE_ID or
19252 HEADER_LINE_FACE_ID. FORMAT is the mode/header line format to
19253 display. Value is the pixel height of the mode/header line
19254 displayed. */
19256 static int
19257 display_mode_line (struct window *w, enum face_id face_id, Lisp_Object format)
19259 struct it it;
19260 struct face *face;
19261 int count = SPECPDL_INDEX ();
19263 init_iterator (&it, w, -1, -1, NULL, face_id);
19264 /* Don't extend on a previously drawn mode-line.
19265 This may happen if called from pos_visible_p. */
19266 it.glyph_row->enabled_p = 0;
19267 prepare_desired_row (it.glyph_row);
19269 it.glyph_row->mode_line_p = 1;
19271 if (! mode_line_inverse_video)
19272 /* Force the mode-line to be displayed in the default face. */
19273 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
19275 /* FIXME: This should be controlled by a user option. But
19276 supporting such an option is not trivial, since the mode line is
19277 made up of many separate strings. */
19278 it.paragraph_embedding = L2R;
19280 record_unwind_protect (unwind_format_mode_line,
19281 format_mode_line_unwind_data (NULL, Qnil, 0));
19283 mode_line_target = MODE_LINE_DISPLAY;
19285 /* Temporarily make frame's keyboard the current kboard so that
19286 kboard-local variables in the mode_line_format will get the right
19287 values. */
19288 push_kboard (FRAME_KBOARD (it.f));
19289 record_unwind_save_match_data ();
19290 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
19291 pop_kboard ();
19293 unbind_to (count, Qnil);
19295 /* Fill up with spaces. */
19296 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
19298 compute_line_metrics (&it);
19299 it.glyph_row->full_width_p = 1;
19300 it.glyph_row->continued_p = 0;
19301 it.glyph_row->truncated_on_left_p = 0;
19302 it.glyph_row->truncated_on_right_p = 0;
19304 /* Make a 3D mode-line have a shadow at its right end. */
19305 face = FACE_FROM_ID (it.f, face_id);
19306 extend_face_to_end_of_line (&it);
19307 if (face->box != FACE_NO_BOX)
19309 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
19310 + it.glyph_row->used[TEXT_AREA] - 1);
19311 last->right_box_line_p = 1;
19314 return it.glyph_row->height;
19317 /* Move element ELT in LIST to the front of LIST.
19318 Return the updated list. */
19320 static Lisp_Object
19321 move_elt_to_front (Lisp_Object elt, Lisp_Object list)
19323 register Lisp_Object tail, prev;
19324 register Lisp_Object tem;
19326 tail = list;
19327 prev = Qnil;
19328 while (CONSP (tail))
19330 tem = XCAR (tail);
19332 if (EQ (elt, tem))
19334 /* Splice out the link TAIL. */
19335 if (NILP (prev))
19336 list = XCDR (tail);
19337 else
19338 Fsetcdr (prev, XCDR (tail));
19340 /* Now make it the first. */
19341 Fsetcdr (tail, list);
19342 return tail;
19344 else
19345 prev = tail;
19346 tail = XCDR (tail);
19347 QUIT;
19350 /* Not found--return unchanged LIST. */
19351 return list;
19354 /* Contribute ELT to the mode line for window IT->w. How it
19355 translates into text depends on its data type.
19357 IT describes the display environment in which we display, as usual.
19359 DEPTH is the depth in recursion. It is used to prevent
19360 infinite recursion here.
19362 FIELD_WIDTH is the number of characters the display of ELT should
19363 occupy in the mode line, and PRECISION is the maximum number of
19364 characters to display from ELT's representation. See
19365 display_string for details.
19367 Returns the hpos of the end of the text generated by ELT.
19369 PROPS is a property list to add to any string we encounter.
19371 If RISKY is nonzero, remove (disregard) any properties in any string
19372 we encounter, and ignore :eval and :propertize.
19374 The global variable `mode_line_target' determines whether the
19375 output is passed to `store_mode_line_noprop',
19376 `store_mode_line_string', or `display_string'. */
19378 static int
19379 display_mode_element (struct it *it, int depth, int field_width, int precision,
19380 Lisp_Object elt, Lisp_Object props, int risky)
19382 int n = 0, field, prec;
19383 int literal = 0;
19385 tail_recurse:
19386 if (depth > 100)
19387 elt = build_string ("*too-deep*");
19389 depth++;
19391 switch (SWITCH_ENUM_CAST (XTYPE (elt)))
19393 case Lisp_String:
19395 /* A string: output it and check for %-constructs within it. */
19396 unsigned char c;
19397 EMACS_INT offset = 0;
19399 if (SCHARS (elt) > 0
19400 && (!NILP (props) || risky))
19402 Lisp_Object oprops, aelt;
19403 oprops = Ftext_properties_at (make_number (0), elt);
19405 /* If the starting string's properties are not what
19406 we want, translate the string. Also, if the string
19407 is risky, do that anyway. */
19409 if (NILP (Fequal (props, oprops)) || risky)
19411 /* If the starting string has properties,
19412 merge the specified ones onto the existing ones. */
19413 if (! NILP (oprops) && !risky)
19415 Lisp_Object tem;
19417 oprops = Fcopy_sequence (oprops);
19418 tem = props;
19419 while (CONSP (tem))
19421 oprops = Fplist_put (oprops, XCAR (tem),
19422 XCAR (XCDR (tem)));
19423 tem = XCDR (XCDR (tem));
19425 props = oprops;
19428 aelt = Fassoc (elt, mode_line_proptrans_alist);
19429 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
19431 /* AELT is what we want. Move it to the front
19432 without consing. */
19433 elt = XCAR (aelt);
19434 mode_line_proptrans_alist
19435 = move_elt_to_front (aelt, mode_line_proptrans_alist);
19437 else
19439 Lisp_Object tem;
19441 /* If AELT has the wrong props, it is useless.
19442 so get rid of it. */
19443 if (! NILP (aelt))
19444 mode_line_proptrans_alist
19445 = Fdelq (aelt, mode_line_proptrans_alist);
19447 elt = Fcopy_sequence (elt);
19448 Fset_text_properties (make_number (0), Flength (elt),
19449 props, elt);
19450 /* Add this item to mode_line_proptrans_alist. */
19451 mode_line_proptrans_alist
19452 = Fcons (Fcons (elt, props),
19453 mode_line_proptrans_alist);
19454 /* Truncate mode_line_proptrans_alist
19455 to at most 50 elements. */
19456 tem = Fnthcdr (make_number (50),
19457 mode_line_proptrans_alist);
19458 if (! NILP (tem))
19459 XSETCDR (tem, Qnil);
19464 offset = 0;
19466 if (literal)
19468 prec = precision - n;
19469 switch (mode_line_target)
19471 case MODE_LINE_NOPROP:
19472 case MODE_LINE_TITLE:
19473 n += store_mode_line_noprop (SSDATA (elt), -1, prec);
19474 break;
19475 case MODE_LINE_STRING:
19476 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
19477 break;
19478 case MODE_LINE_DISPLAY:
19479 n += display_string (NULL, elt, Qnil, 0, 0, it,
19480 0, prec, 0, STRING_MULTIBYTE (elt));
19481 break;
19484 break;
19487 /* Handle the non-literal case. */
19489 while ((precision <= 0 || n < precision)
19490 && SREF (elt, offset) != 0
19491 && (mode_line_target != MODE_LINE_DISPLAY
19492 || it->current_x < it->last_visible_x))
19494 EMACS_INT last_offset = offset;
19496 /* Advance to end of string or next format specifier. */
19497 while ((c = SREF (elt, offset++)) != '\0' && c != '%')
19500 if (offset - 1 != last_offset)
19502 EMACS_INT nchars, nbytes;
19504 /* Output to end of string or up to '%'. Field width
19505 is length of string. Don't output more than
19506 PRECISION allows us. */
19507 offset--;
19509 prec = c_string_width (SDATA (elt) + last_offset,
19510 offset - last_offset, precision - n,
19511 &nchars, &nbytes);
19513 switch (mode_line_target)
19515 case MODE_LINE_NOPROP:
19516 case MODE_LINE_TITLE:
19517 n += store_mode_line_noprop (SSDATA (elt) + last_offset, 0, prec);
19518 break;
19519 case MODE_LINE_STRING:
19521 EMACS_INT bytepos = last_offset;
19522 EMACS_INT charpos = string_byte_to_char (elt, bytepos);
19523 EMACS_INT endpos = (precision <= 0
19524 ? string_byte_to_char (elt, offset)
19525 : charpos + nchars);
19527 n += store_mode_line_string (NULL,
19528 Fsubstring (elt, make_number (charpos),
19529 make_number (endpos)),
19530 0, 0, 0, Qnil);
19532 break;
19533 case MODE_LINE_DISPLAY:
19535 EMACS_INT bytepos = last_offset;
19536 EMACS_INT charpos = string_byte_to_char (elt, bytepos);
19538 if (precision <= 0)
19539 nchars = string_byte_to_char (elt, offset) - charpos;
19540 n += display_string (NULL, elt, Qnil, 0, charpos,
19541 it, 0, nchars, 0,
19542 STRING_MULTIBYTE (elt));
19544 break;
19547 else /* c == '%' */
19549 EMACS_INT percent_position = offset;
19551 /* Get the specified minimum width. Zero means
19552 don't pad. */
19553 field = 0;
19554 while ((c = SREF (elt, offset++)) >= '0' && c <= '9')
19555 field = field * 10 + c - '0';
19557 /* Don't pad beyond the total padding allowed. */
19558 if (field_width - n > 0 && field > field_width - n)
19559 field = field_width - n;
19561 /* Note that either PRECISION <= 0 or N < PRECISION. */
19562 prec = precision - n;
19564 if (c == 'M')
19565 n += display_mode_element (it, depth, field, prec,
19566 Vglobal_mode_string, props,
19567 risky);
19568 else if (c != 0)
19570 int multibyte;
19571 EMACS_INT bytepos, charpos;
19572 const char *spec;
19573 Lisp_Object string;
19575 bytepos = percent_position;
19576 charpos = (STRING_MULTIBYTE (elt)
19577 ? string_byte_to_char (elt, bytepos)
19578 : bytepos);
19579 spec = decode_mode_spec (it->w, c, field, &string);
19580 multibyte = STRINGP (string) && STRING_MULTIBYTE (string);
19582 switch (mode_line_target)
19584 case MODE_LINE_NOPROP:
19585 case MODE_LINE_TITLE:
19586 n += store_mode_line_noprop (spec, field, prec);
19587 break;
19588 case MODE_LINE_STRING:
19590 Lisp_Object tem = build_string (spec);
19591 props = Ftext_properties_at (make_number (charpos), elt);
19592 /* Should only keep face property in props */
19593 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
19595 break;
19596 case MODE_LINE_DISPLAY:
19598 int nglyphs_before, nwritten;
19600 nglyphs_before = it->glyph_row->used[TEXT_AREA];
19601 nwritten = display_string (spec, string, elt,
19602 charpos, 0, it,
19603 field, prec, 0,
19604 multibyte);
19606 /* Assign to the glyphs written above the
19607 string where the `%x' came from, position
19608 of the `%'. */
19609 if (nwritten > 0)
19611 struct glyph *glyph
19612 = (it->glyph_row->glyphs[TEXT_AREA]
19613 + nglyphs_before);
19614 int i;
19616 for (i = 0; i < nwritten; ++i)
19618 glyph[i].object = elt;
19619 glyph[i].charpos = charpos;
19622 n += nwritten;
19625 break;
19628 else /* c == 0 */
19629 break;
19633 break;
19635 case Lisp_Symbol:
19636 /* A symbol: process the value of the symbol recursively
19637 as if it appeared here directly. Avoid error if symbol void.
19638 Special case: if value of symbol is a string, output the string
19639 literally. */
19641 register Lisp_Object tem;
19643 /* If the variable is not marked as risky to set
19644 then its contents are risky to use. */
19645 if (NILP (Fget (elt, Qrisky_local_variable)))
19646 risky = 1;
19648 tem = Fboundp (elt);
19649 if (!NILP (tem))
19651 tem = Fsymbol_value (elt);
19652 /* If value is a string, output that string literally:
19653 don't check for % within it. */
19654 if (STRINGP (tem))
19655 literal = 1;
19657 if (!EQ (tem, elt))
19659 /* Give up right away for nil or t. */
19660 elt = tem;
19661 goto tail_recurse;
19665 break;
19667 case Lisp_Cons:
19669 register Lisp_Object car, tem;
19671 /* A cons cell: five distinct cases.
19672 If first element is :eval or :propertize, do something special.
19673 If first element is a string or a cons, process all the elements
19674 and effectively concatenate them.
19675 If first element is a negative number, truncate displaying cdr to
19676 at most that many characters. If positive, pad (with spaces)
19677 to at least that many characters.
19678 If first element is a symbol, process the cadr or caddr recursively
19679 according to whether the symbol's value is non-nil or nil. */
19680 car = XCAR (elt);
19681 if (EQ (car, QCeval))
19683 /* An element of the form (:eval FORM) means evaluate FORM
19684 and use the result as mode line elements. */
19686 if (risky)
19687 break;
19689 if (CONSP (XCDR (elt)))
19691 Lisp_Object spec;
19692 spec = safe_eval (XCAR (XCDR (elt)));
19693 n += display_mode_element (it, depth, field_width - n,
19694 precision - n, spec, props,
19695 risky);
19698 else if (EQ (car, QCpropertize))
19700 /* An element of the form (:propertize ELT PROPS...)
19701 means display ELT but applying properties PROPS. */
19703 if (risky)
19704 break;
19706 if (CONSP (XCDR (elt)))
19707 n += display_mode_element (it, depth, field_width - n,
19708 precision - n, XCAR (XCDR (elt)),
19709 XCDR (XCDR (elt)), risky);
19711 else if (SYMBOLP (car))
19713 tem = Fboundp (car);
19714 elt = XCDR (elt);
19715 if (!CONSP (elt))
19716 goto invalid;
19717 /* elt is now the cdr, and we know it is a cons cell.
19718 Use its car if CAR has a non-nil value. */
19719 if (!NILP (tem))
19721 tem = Fsymbol_value (car);
19722 if (!NILP (tem))
19724 elt = XCAR (elt);
19725 goto tail_recurse;
19728 /* Symbol's value is nil (or symbol is unbound)
19729 Get the cddr of the original list
19730 and if possible find the caddr and use that. */
19731 elt = XCDR (elt);
19732 if (NILP (elt))
19733 break;
19734 else if (!CONSP (elt))
19735 goto invalid;
19736 elt = XCAR (elt);
19737 goto tail_recurse;
19739 else if (INTEGERP (car))
19741 register int lim = XINT (car);
19742 elt = XCDR (elt);
19743 if (lim < 0)
19745 /* Negative int means reduce maximum width. */
19746 if (precision <= 0)
19747 precision = -lim;
19748 else
19749 precision = min (precision, -lim);
19751 else if (lim > 0)
19753 /* Padding specified. Don't let it be more than
19754 current maximum. */
19755 if (precision > 0)
19756 lim = min (precision, lim);
19758 /* If that's more padding than already wanted, queue it.
19759 But don't reduce padding already specified even if
19760 that is beyond the current truncation point. */
19761 field_width = max (lim, field_width);
19763 goto tail_recurse;
19765 else if (STRINGP (car) || CONSP (car))
19767 Lisp_Object halftail = elt;
19768 int len = 0;
19770 while (CONSP (elt)
19771 && (precision <= 0 || n < precision))
19773 n += display_mode_element (it, depth,
19774 /* Do padding only after the last
19775 element in the list. */
19776 (! CONSP (XCDR (elt))
19777 ? field_width - n
19778 : 0),
19779 precision - n, XCAR (elt),
19780 props, risky);
19781 elt = XCDR (elt);
19782 len++;
19783 if ((len & 1) == 0)
19784 halftail = XCDR (halftail);
19785 /* Check for cycle. */
19786 if (EQ (halftail, elt))
19787 break;
19791 break;
19793 default:
19794 invalid:
19795 elt = build_string ("*invalid*");
19796 goto tail_recurse;
19799 /* Pad to FIELD_WIDTH. */
19800 if (field_width > 0 && n < field_width)
19802 switch (mode_line_target)
19804 case MODE_LINE_NOPROP:
19805 case MODE_LINE_TITLE:
19806 n += store_mode_line_noprop ("", field_width - n, 0);
19807 break;
19808 case MODE_LINE_STRING:
19809 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
19810 break;
19811 case MODE_LINE_DISPLAY:
19812 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
19813 0, 0, 0);
19814 break;
19818 return n;
19821 /* Store a mode-line string element in mode_line_string_list.
19823 If STRING is non-null, display that C string. Otherwise, the Lisp
19824 string LISP_STRING is displayed.
19826 FIELD_WIDTH is the minimum number of output glyphs to produce.
19827 If STRING has fewer characters than FIELD_WIDTH, pad to the right
19828 with spaces. FIELD_WIDTH <= 0 means don't pad.
19830 PRECISION is the maximum number of characters to output from
19831 STRING. PRECISION <= 0 means don't truncate the string.
19833 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
19834 properties to the string.
19836 PROPS are the properties to add to the string.
19837 The mode_line_string_face face property is always added to the string.
19840 static int
19841 store_mode_line_string (const char *string, Lisp_Object lisp_string, int copy_string,
19842 int field_width, int precision, Lisp_Object props)
19844 EMACS_INT len;
19845 int n = 0;
19847 if (string != NULL)
19849 len = strlen (string);
19850 if (precision > 0 && len > precision)
19851 len = precision;
19852 lisp_string = make_string (string, len);
19853 if (NILP (props))
19854 props = mode_line_string_face_prop;
19855 else if (!NILP (mode_line_string_face))
19857 Lisp_Object face = Fplist_get (props, Qface);
19858 props = Fcopy_sequence (props);
19859 if (NILP (face))
19860 face = mode_line_string_face;
19861 else
19862 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
19863 props = Fplist_put (props, Qface, face);
19865 Fadd_text_properties (make_number (0), make_number (len),
19866 props, lisp_string);
19868 else
19870 len = XFASTINT (Flength (lisp_string));
19871 if (precision > 0 && len > precision)
19873 len = precision;
19874 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
19875 precision = -1;
19877 if (!NILP (mode_line_string_face))
19879 Lisp_Object face;
19880 if (NILP (props))
19881 props = Ftext_properties_at (make_number (0), lisp_string);
19882 face = Fplist_get (props, Qface);
19883 if (NILP (face))
19884 face = mode_line_string_face;
19885 else
19886 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
19887 props = Fcons (Qface, Fcons (face, Qnil));
19888 if (copy_string)
19889 lisp_string = Fcopy_sequence (lisp_string);
19891 if (!NILP (props))
19892 Fadd_text_properties (make_number (0), make_number (len),
19893 props, lisp_string);
19896 if (len > 0)
19898 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
19899 n += len;
19902 if (field_width > len)
19904 field_width -= len;
19905 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
19906 if (!NILP (props))
19907 Fadd_text_properties (make_number (0), make_number (field_width),
19908 props, lisp_string);
19909 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
19910 n += field_width;
19913 return n;
19917 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
19918 1, 4, 0,
19919 doc: /* Format a string out of a mode line format specification.
19920 First arg FORMAT specifies the mode line format (see `mode-line-format'
19921 for details) to use.
19923 By default, the format is evaluated for the currently selected window.
19925 Optional second arg FACE specifies the face property to put on all
19926 characters for which no face is specified. The value nil means the
19927 default face. The value t means whatever face the window's mode line
19928 currently uses (either `mode-line' or `mode-line-inactive',
19929 depending on whether the window is the selected window or not).
19930 An integer value means the value string has no text
19931 properties.
19933 Optional third and fourth args WINDOW and BUFFER specify the window
19934 and buffer to use as the context for the formatting (defaults
19935 are the selected window and the WINDOW's buffer). */)
19936 (Lisp_Object format, Lisp_Object face,
19937 Lisp_Object window, Lisp_Object buffer)
19939 struct it it;
19940 int len;
19941 struct window *w;
19942 struct buffer *old_buffer = NULL;
19943 int face_id;
19944 int no_props = INTEGERP (face);
19945 int count = SPECPDL_INDEX ();
19946 Lisp_Object str;
19947 int string_start = 0;
19949 if (NILP (window))
19950 window = selected_window;
19951 CHECK_WINDOW (window);
19952 w = XWINDOW (window);
19954 if (NILP (buffer))
19955 buffer = w->buffer;
19956 CHECK_BUFFER (buffer);
19958 /* Make formatting the modeline a non-op when noninteractive, otherwise
19959 there will be problems later caused by a partially initialized frame. */
19960 if (NILP (format) || noninteractive)
19961 return empty_unibyte_string;
19963 if (no_props)
19964 face = Qnil;
19966 face_id = (NILP (face) || EQ (face, Qdefault)) ? DEFAULT_FACE_ID
19967 : EQ (face, Qt) ? (EQ (window, selected_window)
19968 ? MODE_LINE_FACE_ID : MODE_LINE_INACTIVE_FACE_ID)
19969 : EQ (face, Qmode_line) ? MODE_LINE_FACE_ID
19970 : EQ (face, Qmode_line_inactive) ? MODE_LINE_INACTIVE_FACE_ID
19971 : EQ (face, Qheader_line) ? HEADER_LINE_FACE_ID
19972 : EQ (face, Qtool_bar) ? TOOL_BAR_FACE_ID
19973 : DEFAULT_FACE_ID;
19975 if (XBUFFER (buffer) != current_buffer)
19976 old_buffer = current_buffer;
19978 /* Save things including mode_line_proptrans_alist,
19979 and set that to nil so that we don't alter the outer value. */
19980 record_unwind_protect (unwind_format_mode_line,
19981 format_mode_line_unwind_data
19982 (old_buffer, selected_window, 1));
19983 mode_line_proptrans_alist = Qnil;
19985 Fselect_window (window, Qt);
19986 if (old_buffer)
19987 set_buffer_internal_1 (XBUFFER (buffer));
19989 init_iterator (&it, w, -1, -1, NULL, face_id);
19991 if (no_props)
19993 mode_line_target = MODE_LINE_NOPROP;
19994 mode_line_string_face_prop = Qnil;
19995 mode_line_string_list = Qnil;
19996 string_start = MODE_LINE_NOPROP_LEN (0);
19998 else
20000 mode_line_target = MODE_LINE_STRING;
20001 mode_line_string_list = Qnil;
20002 mode_line_string_face = face;
20003 mode_line_string_face_prop
20004 = (NILP (face) ? Qnil : Fcons (Qface, Fcons (face, Qnil)));
20007 push_kboard (FRAME_KBOARD (it.f));
20008 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
20009 pop_kboard ();
20011 if (no_props)
20013 len = MODE_LINE_NOPROP_LEN (string_start);
20014 str = make_string (mode_line_noprop_buf + string_start, len);
20016 else
20018 mode_line_string_list = Fnreverse (mode_line_string_list);
20019 str = Fmapconcat (intern ("identity"), mode_line_string_list,
20020 empty_unibyte_string);
20023 unbind_to (count, Qnil);
20024 return str;
20027 /* Write a null-terminated, right justified decimal representation of
20028 the positive integer D to BUF using a minimal field width WIDTH. */
20030 static void
20031 pint2str (register char *buf, register int width, register EMACS_INT d)
20033 register char *p = buf;
20035 if (d <= 0)
20036 *p++ = '0';
20037 else
20039 while (d > 0)
20041 *p++ = d % 10 + '0';
20042 d /= 10;
20046 for (width -= (int) (p - buf); width > 0; --width)
20047 *p++ = ' ';
20048 *p-- = '\0';
20049 while (p > buf)
20051 d = *buf;
20052 *buf++ = *p;
20053 *p-- = d;
20057 /* Write a null-terminated, right justified decimal and "human
20058 readable" representation of the nonnegative integer D to BUF using
20059 a minimal field width WIDTH. D should be smaller than 999.5e24. */
20061 static const char power_letter[] =
20063 0, /* no letter */
20064 'k', /* kilo */
20065 'M', /* mega */
20066 'G', /* giga */
20067 'T', /* tera */
20068 'P', /* peta */
20069 'E', /* exa */
20070 'Z', /* zetta */
20071 'Y' /* yotta */
20074 static void
20075 pint2hrstr (char *buf, int width, EMACS_INT d)
20077 /* We aim to represent the nonnegative integer D as
20078 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
20079 EMACS_INT quotient = d;
20080 int remainder = 0;
20081 /* -1 means: do not use TENTHS. */
20082 int tenths = -1;
20083 int exponent = 0;
20085 /* Length of QUOTIENT.TENTHS as a string. */
20086 int length;
20088 char * psuffix;
20089 char * p;
20091 if (1000 <= quotient)
20093 /* Scale to the appropriate EXPONENT. */
20096 remainder = quotient % 1000;
20097 quotient /= 1000;
20098 exponent++;
20100 while (1000 <= quotient);
20102 /* Round to nearest and decide whether to use TENTHS or not. */
20103 if (quotient <= 9)
20105 tenths = remainder / 100;
20106 if (50 <= remainder % 100)
20108 if (tenths < 9)
20109 tenths++;
20110 else
20112 quotient++;
20113 if (quotient == 10)
20114 tenths = -1;
20115 else
20116 tenths = 0;
20120 else
20121 if (500 <= remainder)
20123 if (quotient < 999)
20124 quotient++;
20125 else
20127 quotient = 1;
20128 exponent++;
20129 tenths = 0;
20134 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
20135 if (tenths == -1 && quotient <= 99)
20136 if (quotient <= 9)
20137 length = 1;
20138 else
20139 length = 2;
20140 else
20141 length = 3;
20142 p = psuffix = buf + max (width, length);
20144 /* Print EXPONENT. */
20145 *psuffix++ = power_letter[exponent];
20146 *psuffix = '\0';
20148 /* Print TENTHS. */
20149 if (tenths >= 0)
20151 *--p = '0' + tenths;
20152 *--p = '.';
20155 /* Print QUOTIENT. */
20158 int digit = quotient % 10;
20159 *--p = '0' + digit;
20161 while ((quotient /= 10) != 0);
20163 /* Print leading spaces. */
20164 while (buf < p)
20165 *--p = ' ';
20168 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
20169 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
20170 type of CODING_SYSTEM. Return updated pointer into BUF. */
20172 static unsigned char invalid_eol_type[] = "(*invalid*)";
20174 static char *
20175 decode_mode_spec_coding (Lisp_Object coding_system, register char *buf, int eol_flag)
20177 Lisp_Object val;
20178 int multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters));
20179 const unsigned char *eol_str;
20180 int eol_str_len;
20181 /* The EOL conversion we are using. */
20182 Lisp_Object eoltype;
20184 val = CODING_SYSTEM_SPEC (coding_system);
20185 eoltype = Qnil;
20187 if (!VECTORP (val)) /* Not yet decided. */
20189 if (multibyte)
20190 *buf++ = '-';
20191 if (eol_flag)
20192 eoltype = eol_mnemonic_undecided;
20193 /* Don't mention EOL conversion if it isn't decided. */
20195 else
20197 Lisp_Object attrs;
20198 Lisp_Object eolvalue;
20200 attrs = AREF (val, 0);
20201 eolvalue = AREF (val, 2);
20203 if (multibyte)
20204 *buf++ = XFASTINT (CODING_ATTR_MNEMONIC (attrs));
20206 if (eol_flag)
20208 /* The EOL conversion that is normal on this system. */
20210 if (NILP (eolvalue)) /* Not yet decided. */
20211 eoltype = eol_mnemonic_undecided;
20212 else if (VECTORP (eolvalue)) /* Not yet decided. */
20213 eoltype = eol_mnemonic_undecided;
20214 else /* eolvalue is Qunix, Qdos, or Qmac. */
20215 eoltype = (EQ (eolvalue, Qunix)
20216 ? eol_mnemonic_unix
20217 : (EQ (eolvalue, Qdos) == 1
20218 ? eol_mnemonic_dos : eol_mnemonic_mac));
20222 if (eol_flag)
20224 /* Mention the EOL conversion if it is not the usual one. */
20225 if (STRINGP (eoltype))
20227 eol_str = SDATA (eoltype);
20228 eol_str_len = SBYTES (eoltype);
20230 else if (CHARACTERP (eoltype))
20232 unsigned char *tmp = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
20233 int c = XFASTINT (eoltype);
20234 eol_str_len = CHAR_STRING (c, tmp);
20235 eol_str = tmp;
20237 else
20239 eol_str = invalid_eol_type;
20240 eol_str_len = sizeof (invalid_eol_type) - 1;
20242 memcpy (buf, eol_str, eol_str_len);
20243 buf += eol_str_len;
20246 return buf;
20249 /* Return a string for the output of a mode line %-spec for window W,
20250 generated by character C. FIELD_WIDTH > 0 means pad the string
20251 returned with spaces to that value. Return a Lisp string in
20252 *STRING if the resulting string is taken from that Lisp string.
20254 Note we operate on the current buffer for most purposes,
20255 the exception being w->base_line_pos. */
20257 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
20259 static const char *
20260 decode_mode_spec (struct window *w, register int c, int field_width,
20261 Lisp_Object *string)
20263 Lisp_Object obj;
20264 struct frame *f = XFRAME (WINDOW_FRAME (w));
20265 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
20266 struct buffer *b = current_buffer;
20268 obj = Qnil;
20269 *string = Qnil;
20271 switch (c)
20273 case '*':
20274 if (!NILP (BVAR (b, read_only)))
20275 return "%";
20276 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
20277 return "*";
20278 return "-";
20280 case '+':
20281 /* This differs from %* only for a modified read-only buffer. */
20282 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
20283 return "*";
20284 if (!NILP (BVAR (b, read_only)))
20285 return "%";
20286 return "-";
20288 case '&':
20289 /* This differs from %* in ignoring read-only-ness. */
20290 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
20291 return "*";
20292 return "-";
20294 case '%':
20295 return "%";
20297 case '[':
20299 int i;
20300 char *p;
20302 if (command_loop_level > 5)
20303 return "[[[... ";
20304 p = decode_mode_spec_buf;
20305 for (i = 0; i < command_loop_level; i++)
20306 *p++ = '[';
20307 *p = 0;
20308 return decode_mode_spec_buf;
20311 case ']':
20313 int i;
20314 char *p;
20316 if (command_loop_level > 5)
20317 return " ...]]]";
20318 p = decode_mode_spec_buf;
20319 for (i = 0; i < command_loop_level; i++)
20320 *p++ = ']';
20321 *p = 0;
20322 return decode_mode_spec_buf;
20325 case '-':
20327 register int i;
20329 /* Let lots_of_dashes be a string of infinite length. */
20330 if (mode_line_target == MODE_LINE_NOPROP ||
20331 mode_line_target == MODE_LINE_STRING)
20332 return "--";
20333 if (field_width <= 0
20334 || field_width > sizeof (lots_of_dashes))
20336 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
20337 decode_mode_spec_buf[i] = '-';
20338 decode_mode_spec_buf[i] = '\0';
20339 return decode_mode_spec_buf;
20341 else
20342 return lots_of_dashes;
20345 case 'b':
20346 obj = BVAR (b, name);
20347 break;
20349 case 'c':
20350 /* %c and %l are ignored in `frame-title-format'.
20351 (In redisplay_internal, the frame title is drawn _before_ the
20352 windows are updated, so the stuff which depends on actual
20353 window contents (such as %l) may fail to render properly, or
20354 even crash emacs.) */
20355 if (mode_line_target == MODE_LINE_TITLE)
20356 return "";
20357 else
20359 EMACS_INT col = current_column ();
20360 w->column_number_displayed = make_number (col);
20361 pint2str (decode_mode_spec_buf, field_width, col);
20362 return decode_mode_spec_buf;
20365 case 'e':
20366 #ifndef SYSTEM_MALLOC
20368 if (NILP (Vmemory_full))
20369 return "";
20370 else
20371 return "!MEM FULL! ";
20373 #else
20374 return "";
20375 #endif
20377 case 'F':
20378 /* %F displays the frame name. */
20379 if (!NILP (f->title))
20380 return SSDATA (f->title);
20381 if (f->explicit_name || ! FRAME_WINDOW_P (f))
20382 return SSDATA (f->name);
20383 return "Emacs";
20385 case 'f':
20386 obj = BVAR (b, filename);
20387 break;
20389 case 'i':
20391 EMACS_INT size = ZV - BEGV;
20392 pint2str (decode_mode_spec_buf, field_width, size);
20393 return decode_mode_spec_buf;
20396 case 'I':
20398 EMACS_INT size = ZV - BEGV;
20399 pint2hrstr (decode_mode_spec_buf, field_width, size);
20400 return decode_mode_spec_buf;
20403 case 'l':
20405 EMACS_INT startpos, startpos_byte, line, linepos, linepos_byte;
20406 EMACS_INT topline, nlines, height;
20407 EMACS_INT junk;
20409 /* %c and %l are ignored in `frame-title-format'. */
20410 if (mode_line_target == MODE_LINE_TITLE)
20411 return "";
20413 startpos = XMARKER (w->start)->charpos;
20414 startpos_byte = marker_byte_position (w->start);
20415 height = WINDOW_TOTAL_LINES (w);
20417 /* If we decided that this buffer isn't suitable for line numbers,
20418 don't forget that too fast. */
20419 if (EQ (w->base_line_pos, w->buffer))
20420 goto no_value;
20421 /* But do forget it, if the window shows a different buffer now. */
20422 else if (BUFFERP (w->base_line_pos))
20423 w->base_line_pos = Qnil;
20425 /* If the buffer is very big, don't waste time. */
20426 if (INTEGERP (Vline_number_display_limit)
20427 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
20429 w->base_line_pos = Qnil;
20430 w->base_line_number = Qnil;
20431 goto no_value;
20434 if (INTEGERP (w->base_line_number)
20435 && INTEGERP (w->base_line_pos)
20436 && XFASTINT (w->base_line_pos) <= startpos)
20438 line = XFASTINT (w->base_line_number);
20439 linepos = XFASTINT (w->base_line_pos);
20440 linepos_byte = buf_charpos_to_bytepos (b, linepos);
20442 else
20444 line = 1;
20445 linepos = BUF_BEGV (b);
20446 linepos_byte = BUF_BEGV_BYTE (b);
20449 /* Count lines from base line to window start position. */
20450 nlines = display_count_lines (linepos_byte,
20451 startpos_byte,
20452 startpos, &junk);
20454 topline = nlines + line;
20456 /* Determine a new base line, if the old one is too close
20457 or too far away, or if we did not have one.
20458 "Too close" means it's plausible a scroll-down would
20459 go back past it. */
20460 if (startpos == BUF_BEGV (b))
20462 w->base_line_number = make_number (topline);
20463 w->base_line_pos = make_number (BUF_BEGV (b));
20465 else if (nlines < height + 25 || nlines > height * 3 + 50
20466 || linepos == BUF_BEGV (b))
20468 EMACS_INT limit = BUF_BEGV (b);
20469 EMACS_INT limit_byte = BUF_BEGV_BYTE (b);
20470 EMACS_INT position;
20471 EMACS_INT distance =
20472 (height * 2 + 30) * line_number_display_limit_width;
20474 if (startpos - distance > limit)
20476 limit = startpos - distance;
20477 limit_byte = CHAR_TO_BYTE (limit);
20480 nlines = display_count_lines (startpos_byte,
20481 limit_byte,
20482 - (height * 2 + 30),
20483 &position);
20484 /* If we couldn't find the lines we wanted within
20485 line_number_display_limit_width chars per line,
20486 give up on line numbers for this window. */
20487 if (position == limit_byte && limit == startpos - distance)
20489 w->base_line_pos = w->buffer;
20490 w->base_line_number = Qnil;
20491 goto no_value;
20494 w->base_line_number = make_number (topline - nlines);
20495 w->base_line_pos = make_number (BYTE_TO_CHAR (position));
20498 /* Now count lines from the start pos to point. */
20499 nlines = display_count_lines (startpos_byte,
20500 PT_BYTE, PT, &junk);
20502 /* Record that we did display the line number. */
20503 line_number_displayed = 1;
20505 /* Make the string to show. */
20506 pint2str (decode_mode_spec_buf, field_width, topline + nlines);
20507 return decode_mode_spec_buf;
20508 no_value:
20510 char* p = decode_mode_spec_buf;
20511 int pad = field_width - 2;
20512 while (pad-- > 0)
20513 *p++ = ' ';
20514 *p++ = '?';
20515 *p++ = '?';
20516 *p = '\0';
20517 return decode_mode_spec_buf;
20520 break;
20522 case 'm':
20523 obj = BVAR (b, mode_name);
20524 break;
20526 case 'n':
20527 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
20528 return " Narrow";
20529 break;
20531 case 'p':
20533 EMACS_INT pos = marker_position (w->start);
20534 EMACS_INT total = BUF_ZV (b) - BUF_BEGV (b);
20536 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
20538 if (pos <= BUF_BEGV (b))
20539 return "All";
20540 else
20541 return "Bottom";
20543 else if (pos <= BUF_BEGV (b))
20544 return "Top";
20545 else
20547 if (total > 1000000)
20548 /* Do it differently for a large value, to avoid overflow. */
20549 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
20550 else
20551 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
20552 /* We can't normally display a 3-digit number,
20553 so get us a 2-digit number that is close. */
20554 if (total == 100)
20555 total = 99;
20556 sprintf (decode_mode_spec_buf, "%2"pI"d%%", total);
20557 return decode_mode_spec_buf;
20561 /* Display percentage of size above the bottom of the screen. */
20562 case 'P':
20564 EMACS_INT toppos = marker_position (w->start);
20565 EMACS_INT botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
20566 EMACS_INT total = BUF_ZV (b) - BUF_BEGV (b);
20568 if (botpos >= BUF_ZV (b))
20570 if (toppos <= BUF_BEGV (b))
20571 return "All";
20572 else
20573 return "Bottom";
20575 else
20577 if (total > 1000000)
20578 /* Do it differently for a large value, to avoid overflow. */
20579 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
20580 else
20581 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
20582 /* We can't normally display a 3-digit number,
20583 so get us a 2-digit number that is close. */
20584 if (total == 100)
20585 total = 99;
20586 if (toppos <= BUF_BEGV (b))
20587 sprintf (decode_mode_spec_buf, "Top%2"pI"d%%", total);
20588 else
20589 sprintf (decode_mode_spec_buf, "%2"pI"d%%", total);
20590 return decode_mode_spec_buf;
20594 case 's':
20595 /* status of process */
20596 obj = Fget_buffer_process (Fcurrent_buffer ());
20597 if (NILP (obj))
20598 return "no process";
20599 #ifndef MSDOS
20600 obj = Fsymbol_name (Fprocess_status (obj));
20601 #endif
20602 break;
20604 case '@':
20606 int count = inhibit_garbage_collection ();
20607 Lisp_Object val = call1 (intern ("file-remote-p"),
20608 BVAR (current_buffer, directory));
20609 unbind_to (count, Qnil);
20611 if (NILP (val))
20612 return "-";
20613 else
20614 return "@";
20617 case 't': /* indicate TEXT or BINARY */
20618 return "T";
20620 case 'z':
20621 /* coding-system (not including end-of-line format) */
20622 case 'Z':
20623 /* coding-system (including end-of-line type) */
20625 int eol_flag = (c == 'Z');
20626 char *p = decode_mode_spec_buf;
20628 if (! FRAME_WINDOW_P (f))
20630 /* No need to mention EOL here--the terminal never needs
20631 to do EOL conversion. */
20632 p = decode_mode_spec_coding (CODING_ID_NAME
20633 (FRAME_KEYBOARD_CODING (f)->id),
20634 p, 0);
20635 p = decode_mode_spec_coding (CODING_ID_NAME
20636 (FRAME_TERMINAL_CODING (f)->id),
20637 p, 0);
20639 p = decode_mode_spec_coding (BVAR (b, buffer_file_coding_system),
20640 p, eol_flag);
20642 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
20643 #ifdef subprocesses
20644 obj = Fget_buffer_process (Fcurrent_buffer ());
20645 if (PROCESSP (obj))
20647 p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system,
20648 p, eol_flag);
20649 p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system,
20650 p, eol_flag);
20652 #endif /* subprocesses */
20653 #endif /* 0 */
20654 *p = 0;
20655 return decode_mode_spec_buf;
20659 if (STRINGP (obj))
20661 *string = obj;
20662 return SSDATA (obj);
20664 else
20665 return "";
20669 /* Count up to COUNT lines starting from START_BYTE.
20670 But don't go beyond LIMIT_BYTE.
20671 Return the number of lines thus found (always nonnegative).
20673 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
20675 static EMACS_INT
20676 display_count_lines (EMACS_INT start_byte,
20677 EMACS_INT limit_byte, EMACS_INT count,
20678 EMACS_INT *byte_pos_ptr)
20680 register unsigned char *cursor;
20681 unsigned char *base;
20683 register EMACS_INT ceiling;
20684 register unsigned char *ceiling_addr;
20685 EMACS_INT orig_count = count;
20687 /* If we are not in selective display mode,
20688 check only for newlines. */
20689 int selective_display = (!NILP (BVAR (current_buffer, selective_display))
20690 && !INTEGERP (BVAR (current_buffer, selective_display)));
20692 if (count > 0)
20694 while (start_byte < limit_byte)
20696 ceiling = BUFFER_CEILING_OF (start_byte);
20697 ceiling = min (limit_byte - 1, ceiling);
20698 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
20699 base = (cursor = BYTE_POS_ADDR (start_byte));
20700 while (1)
20702 if (selective_display)
20703 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
20705 else
20706 while (*cursor != '\n' && ++cursor != ceiling_addr)
20709 if (cursor != ceiling_addr)
20711 if (--count == 0)
20713 start_byte += cursor - base + 1;
20714 *byte_pos_ptr = start_byte;
20715 return orig_count;
20717 else
20718 if (++cursor == ceiling_addr)
20719 break;
20721 else
20722 break;
20724 start_byte += cursor - base;
20727 else
20729 while (start_byte > limit_byte)
20731 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
20732 ceiling = max (limit_byte, ceiling);
20733 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1;
20734 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
20735 while (1)
20737 if (selective_display)
20738 while (--cursor != ceiling_addr
20739 && *cursor != '\n' && *cursor != 015)
20741 else
20742 while (--cursor != ceiling_addr && *cursor != '\n')
20745 if (cursor != ceiling_addr)
20747 if (++count == 0)
20749 start_byte += cursor - base + 1;
20750 *byte_pos_ptr = start_byte;
20751 /* When scanning backwards, we should
20752 not count the newline posterior to which we stop. */
20753 return - orig_count - 1;
20756 else
20757 break;
20759 /* Here we add 1 to compensate for the last decrement
20760 of CURSOR, which took it past the valid range. */
20761 start_byte += cursor - base + 1;
20765 *byte_pos_ptr = limit_byte;
20767 if (count < 0)
20768 return - orig_count + count;
20769 return orig_count - count;
20775 /***********************************************************************
20776 Displaying strings
20777 ***********************************************************************/
20779 /* Display a NUL-terminated string, starting with index START.
20781 If STRING is non-null, display that C string. Otherwise, the Lisp
20782 string LISP_STRING is displayed. There's a case that STRING is
20783 non-null and LISP_STRING is not nil. It means STRING is a string
20784 data of LISP_STRING. In that case, we display LISP_STRING while
20785 ignoring its text properties.
20787 If FACE_STRING is not nil, FACE_STRING_POS is a position in
20788 FACE_STRING. Display STRING or LISP_STRING with the face at
20789 FACE_STRING_POS in FACE_STRING:
20791 Display the string in the environment given by IT, but use the
20792 standard display table, temporarily.
20794 FIELD_WIDTH is the minimum number of output glyphs to produce.
20795 If STRING has fewer characters than FIELD_WIDTH, pad to the right
20796 with spaces. If STRING has more characters, more than FIELD_WIDTH
20797 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
20799 PRECISION is the maximum number of characters to output from
20800 STRING. PRECISION < 0 means don't truncate the string.
20802 This is roughly equivalent to printf format specifiers:
20804 FIELD_WIDTH PRECISION PRINTF
20805 ----------------------------------------
20806 -1 -1 %s
20807 -1 10 %.10s
20808 10 -1 %10s
20809 20 10 %20.10s
20811 MULTIBYTE zero means do not display multibyte chars, > 0 means do
20812 display them, and < 0 means obey the current buffer's value of
20813 enable_multibyte_characters.
20815 Value is the number of columns displayed. */
20817 static int
20818 display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_string,
20819 EMACS_INT face_string_pos, EMACS_INT start, struct it *it,
20820 int field_width, int precision, int max_x, int multibyte)
20822 int hpos_at_start = it->hpos;
20823 int saved_face_id = it->face_id;
20824 struct glyph_row *row = it->glyph_row;
20825 EMACS_INT it_charpos;
20827 /* Initialize the iterator IT for iteration over STRING beginning
20828 with index START. */
20829 reseat_to_string (it, NILP (lisp_string) ? string : NULL, lisp_string, start,
20830 precision, field_width, multibyte);
20831 if (string && STRINGP (lisp_string))
20832 /* LISP_STRING is the one returned by decode_mode_spec. We should
20833 ignore its text properties. */
20834 it->stop_charpos = it->end_charpos;
20836 /* If displaying STRING, set up the face of the iterator from
20837 FACE_STRING, if that's given. */
20838 if (STRINGP (face_string))
20840 EMACS_INT endptr;
20841 struct face *face;
20843 it->face_id
20844 = face_at_string_position (it->w, face_string, face_string_pos,
20845 0, it->region_beg_charpos,
20846 it->region_end_charpos,
20847 &endptr, it->base_face_id, 0);
20848 face = FACE_FROM_ID (it->f, it->face_id);
20849 it->face_box_p = face->box != FACE_NO_BOX;
20852 /* Set max_x to the maximum allowed X position. Don't let it go
20853 beyond the right edge of the window. */
20854 if (max_x <= 0)
20855 max_x = it->last_visible_x;
20856 else
20857 max_x = min (max_x, it->last_visible_x);
20859 /* Skip over display elements that are not visible. because IT->w is
20860 hscrolled. */
20861 if (it->current_x < it->first_visible_x)
20862 move_it_in_display_line_to (it, 100000, it->first_visible_x,
20863 MOVE_TO_POS | MOVE_TO_X);
20865 row->ascent = it->max_ascent;
20866 row->height = it->max_ascent + it->max_descent;
20867 row->phys_ascent = it->max_phys_ascent;
20868 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
20869 row->extra_line_spacing = it->max_extra_line_spacing;
20871 if (STRINGP (it->string))
20872 it_charpos = IT_STRING_CHARPOS (*it);
20873 else
20874 it_charpos = IT_CHARPOS (*it);
20876 /* This condition is for the case that we are called with current_x
20877 past last_visible_x. */
20878 while (it->current_x < max_x)
20880 int x_before, x, n_glyphs_before, i, nglyphs;
20882 /* Get the next display element. */
20883 if (!get_next_display_element (it))
20884 break;
20886 /* Produce glyphs. */
20887 x_before = it->current_x;
20888 n_glyphs_before = row->used[TEXT_AREA];
20889 PRODUCE_GLYPHS (it);
20891 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
20892 i = 0;
20893 x = x_before;
20894 while (i < nglyphs)
20896 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
20898 if (it->line_wrap != TRUNCATE
20899 && x + glyph->pixel_width > max_x)
20901 /* End of continued line or max_x reached. */
20902 if (CHAR_GLYPH_PADDING_P (*glyph))
20904 /* A wide character is unbreakable. */
20905 if (row->reversed_p)
20906 unproduce_glyphs (it, row->used[TEXT_AREA]
20907 - n_glyphs_before);
20908 row->used[TEXT_AREA] = n_glyphs_before;
20909 it->current_x = x_before;
20911 else
20913 if (row->reversed_p)
20914 unproduce_glyphs (it, row->used[TEXT_AREA]
20915 - (n_glyphs_before + i));
20916 row->used[TEXT_AREA] = n_glyphs_before + i;
20917 it->current_x = x;
20919 break;
20921 else if (x + glyph->pixel_width >= it->first_visible_x)
20923 /* Glyph is at least partially visible. */
20924 ++it->hpos;
20925 if (x < it->first_visible_x)
20926 row->x = x - it->first_visible_x;
20928 else
20930 /* Glyph is off the left margin of the display area.
20931 Should not happen. */
20932 abort ();
20935 row->ascent = max (row->ascent, it->max_ascent);
20936 row->height = max (row->height, it->max_ascent + it->max_descent);
20937 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
20938 row->phys_height = max (row->phys_height,
20939 it->max_phys_ascent + it->max_phys_descent);
20940 row->extra_line_spacing = max (row->extra_line_spacing,
20941 it->max_extra_line_spacing);
20942 x += glyph->pixel_width;
20943 ++i;
20946 /* Stop if max_x reached. */
20947 if (i < nglyphs)
20948 break;
20950 /* Stop at line ends. */
20951 if (ITERATOR_AT_END_OF_LINE_P (it))
20953 it->continuation_lines_width = 0;
20954 break;
20957 set_iterator_to_next (it, 1);
20958 if (STRINGP (it->string))
20959 it_charpos = IT_STRING_CHARPOS (*it);
20960 else
20961 it_charpos = IT_CHARPOS (*it);
20963 /* Stop if truncating at the right edge. */
20964 if (it->line_wrap == TRUNCATE
20965 && it->current_x >= it->last_visible_x)
20967 /* Add truncation mark, but don't do it if the line is
20968 truncated at a padding space. */
20969 if (it_charpos < it->string_nchars)
20971 if (!FRAME_WINDOW_P (it->f))
20973 int ii, n;
20975 if (it->current_x > it->last_visible_x)
20977 if (!row->reversed_p)
20979 for (ii = row->used[TEXT_AREA] - 1; ii > 0; --ii)
20980 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
20981 break;
20983 else
20985 for (ii = 0; ii < row->used[TEXT_AREA]; ii++)
20986 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
20987 break;
20988 unproduce_glyphs (it, ii + 1);
20989 ii = row->used[TEXT_AREA] - (ii + 1);
20991 for (n = row->used[TEXT_AREA]; ii < n; ++ii)
20993 row->used[TEXT_AREA] = ii;
20994 produce_special_glyphs (it, IT_TRUNCATION);
20997 produce_special_glyphs (it, IT_TRUNCATION);
20999 row->truncated_on_right_p = 1;
21001 break;
21005 /* Maybe insert a truncation at the left. */
21006 if (it->first_visible_x
21007 && it_charpos > 0)
21009 if (!FRAME_WINDOW_P (it->f))
21010 insert_left_trunc_glyphs (it);
21011 row->truncated_on_left_p = 1;
21014 it->face_id = saved_face_id;
21016 /* Value is number of columns displayed. */
21017 return it->hpos - hpos_at_start;
21022 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
21023 appears as an element of LIST or as the car of an element of LIST.
21024 If PROPVAL is a list, compare each element against LIST in that
21025 way, and return 1/2 if any element of PROPVAL is found in LIST.
21026 Otherwise return 0. This function cannot quit.
21027 The return value is 2 if the text is invisible but with an ellipsis
21028 and 1 if it's invisible and without an ellipsis. */
21031 invisible_p (register Lisp_Object propval, Lisp_Object list)
21033 register Lisp_Object tail, proptail;
21035 for (tail = list; CONSP (tail); tail = XCDR (tail))
21037 register Lisp_Object tem;
21038 tem = XCAR (tail);
21039 if (EQ (propval, tem))
21040 return 1;
21041 if (CONSP (tem) && EQ (propval, XCAR (tem)))
21042 return NILP (XCDR (tem)) ? 1 : 2;
21045 if (CONSP (propval))
21047 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
21049 Lisp_Object propelt;
21050 propelt = XCAR (proptail);
21051 for (tail = list; CONSP (tail); tail = XCDR (tail))
21053 register Lisp_Object tem;
21054 tem = XCAR (tail);
21055 if (EQ (propelt, tem))
21056 return 1;
21057 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
21058 return NILP (XCDR (tem)) ? 1 : 2;
21063 return 0;
21066 DEFUN ("invisible-p", Finvisible_p, Sinvisible_p, 1, 1, 0,
21067 doc: /* Non-nil if the property makes the text invisible.
21068 POS-OR-PROP can be a marker or number, in which case it is taken to be
21069 a position in the current buffer and the value of the `invisible' property
21070 is checked; or it can be some other value, which is then presumed to be the
21071 value of the `invisible' property of the text of interest.
21072 The non-nil value returned can be t for truly invisible text or something
21073 else if the text is replaced by an ellipsis. */)
21074 (Lisp_Object pos_or_prop)
21076 Lisp_Object prop
21077 = (NATNUMP (pos_or_prop) || MARKERP (pos_or_prop)
21078 ? Fget_char_property (pos_or_prop, Qinvisible, Qnil)
21079 : pos_or_prop);
21080 int invis = TEXT_PROP_MEANS_INVISIBLE (prop);
21081 return (invis == 0 ? Qnil
21082 : invis == 1 ? Qt
21083 : make_number (invis));
21086 /* Calculate a width or height in pixels from a specification using
21087 the following elements:
21089 SPEC ::=
21090 NUM - a (fractional) multiple of the default font width/height
21091 (NUM) - specifies exactly NUM pixels
21092 UNIT - a fixed number of pixels, see below.
21093 ELEMENT - size of a display element in pixels, see below.
21094 (NUM . SPEC) - equals NUM * SPEC
21095 (+ SPEC SPEC ...) - add pixel values
21096 (- SPEC SPEC ...) - subtract pixel values
21097 (- SPEC) - negate pixel value
21099 NUM ::=
21100 INT or FLOAT - a number constant
21101 SYMBOL - use symbol's (buffer local) variable binding.
21103 UNIT ::=
21104 in - pixels per inch *)
21105 mm - pixels per 1/1000 meter *)
21106 cm - pixels per 1/100 meter *)
21107 width - width of current font in pixels.
21108 height - height of current font in pixels.
21110 *) using the ratio(s) defined in display-pixels-per-inch.
21112 ELEMENT ::=
21114 left-fringe - left fringe width in pixels
21115 right-fringe - right fringe width in pixels
21117 left-margin - left margin width in pixels
21118 right-margin - right margin width in pixels
21120 scroll-bar - scroll-bar area width in pixels
21122 Examples:
21124 Pixels corresponding to 5 inches:
21125 (5 . in)
21127 Total width of non-text areas on left side of window (if scroll-bar is on left):
21128 '(space :width (+ left-fringe left-margin scroll-bar))
21130 Align to first text column (in header line):
21131 '(space :align-to 0)
21133 Align to middle of text area minus half the width of variable `my-image'
21134 containing a loaded image:
21135 '(space :align-to (0.5 . (- text my-image)))
21137 Width of left margin minus width of 1 character in the default font:
21138 '(space :width (- left-margin 1))
21140 Width of left margin minus width of 2 characters in the current font:
21141 '(space :width (- left-margin (2 . width)))
21143 Center 1 character over left-margin (in header line):
21144 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
21146 Different ways to express width of left fringe plus left margin minus one pixel:
21147 '(space :width (- (+ left-fringe left-margin) (1)))
21148 '(space :width (+ left-fringe left-margin (- (1))))
21149 '(space :width (+ left-fringe left-margin (-1)))
21153 #define NUMVAL(X) \
21154 ((INTEGERP (X) || FLOATP (X)) \
21155 ? XFLOATINT (X) \
21156 : - 1)
21159 calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
21160 struct font *font, int width_p, int *align_to)
21162 double pixels;
21164 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
21165 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
21167 if (NILP (prop))
21168 return OK_PIXELS (0);
21170 xassert (FRAME_LIVE_P (it->f));
21172 if (SYMBOLP (prop))
21174 if (SCHARS (SYMBOL_NAME (prop)) == 2)
21176 char *unit = SSDATA (SYMBOL_NAME (prop));
21178 if (unit[0] == 'i' && unit[1] == 'n')
21179 pixels = 1.0;
21180 else if (unit[0] == 'm' && unit[1] == 'm')
21181 pixels = 25.4;
21182 else if (unit[0] == 'c' && unit[1] == 'm')
21183 pixels = 2.54;
21184 else
21185 pixels = 0;
21186 if (pixels > 0)
21188 double ppi;
21189 #ifdef HAVE_WINDOW_SYSTEM
21190 if (FRAME_WINDOW_P (it->f)
21191 && (ppi = (width_p
21192 ? FRAME_X_DISPLAY_INFO (it->f)->resx
21193 : FRAME_X_DISPLAY_INFO (it->f)->resy),
21194 ppi > 0))
21195 return OK_PIXELS (ppi / pixels);
21196 #endif
21198 if ((ppi = NUMVAL (Vdisplay_pixels_per_inch), ppi > 0)
21199 || (CONSP (Vdisplay_pixels_per_inch)
21200 && (ppi = (width_p
21201 ? NUMVAL (XCAR (Vdisplay_pixels_per_inch))
21202 : NUMVAL (XCDR (Vdisplay_pixels_per_inch))),
21203 ppi > 0)))
21204 return OK_PIXELS (ppi / pixels);
21206 return 0;
21210 #ifdef HAVE_WINDOW_SYSTEM
21211 if (EQ (prop, Qheight))
21212 return OK_PIXELS (font ? FONT_HEIGHT (font) : FRAME_LINE_HEIGHT (it->f));
21213 if (EQ (prop, Qwidth))
21214 return OK_PIXELS (font ? FONT_WIDTH (font) : FRAME_COLUMN_WIDTH (it->f));
21215 #else
21216 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
21217 return OK_PIXELS (1);
21218 #endif
21220 if (EQ (prop, Qtext))
21221 return OK_PIXELS (width_p
21222 ? window_box_width (it->w, TEXT_AREA)
21223 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
21225 if (align_to && *align_to < 0)
21227 *res = 0;
21228 if (EQ (prop, Qleft))
21229 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA));
21230 if (EQ (prop, Qright))
21231 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
21232 if (EQ (prop, Qcenter))
21233 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
21234 + window_box_width (it->w, TEXT_AREA) / 2);
21235 if (EQ (prop, Qleft_fringe))
21236 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
21237 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
21238 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
21239 if (EQ (prop, Qright_fringe))
21240 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
21241 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
21242 : window_box_right_offset (it->w, TEXT_AREA));
21243 if (EQ (prop, Qleft_margin))
21244 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
21245 if (EQ (prop, Qright_margin))
21246 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
21247 if (EQ (prop, Qscroll_bar))
21248 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
21250 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
21251 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
21252 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
21253 : 0)));
21255 else
21257 if (EQ (prop, Qleft_fringe))
21258 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
21259 if (EQ (prop, Qright_fringe))
21260 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
21261 if (EQ (prop, Qleft_margin))
21262 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
21263 if (EQ (prop, Qright_margin))
21264 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
21265 if (EQ (prop, Qscroll_bar))
21266 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
21269 prop = Fbuffer_local_value (prop, it->w->buffer);
21272 if (INTEGERP (prop) || FLOATP (prop))
21274 int base_unit = (width_p
21275 ? FRAME_COLUMN_WIDTH (it->f)
21276 : FRAME_LINE_HEIGHT (it->f));
21277 return OK_PIXELS (XFLOATINT (prop) * base_unit);
21280 if (CONSP (prop))
21282 Lisp_Object car = XCAR (prop);
21283 Lisp_Object cdr = XCDR (prop);
21285 if (SYMBOLP (car))
21287 #ifdef HAVE_WINDOW_SYSTEM
21288 if (FRAME_WINDOW_P (it->f)
21289 && valid_image_p (prop))
21291 int id = lookup_image (it->f, prop);
21292 struct image *img = IMAGE_FROM_ID (it->f, id);
21294 return OK_PIXELS (width_p ? img->width : img->height);
21296 #endif
21297 if (EQ (car, Qplus) || EQ (car, Qminus))
21299 int first = 1;
21300 double px;
21302 pixels = 0;
21303 while (CONSP (cdr))
21305 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
21306 font, width_p, align_to))
21307 return 0;
21308 if (first)
21309 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
21310 else
21311 pixels += px;
21312 cdr = XCDR (cdr);
21314 if (EQ (car, Qminus))
21315 pixels = -pixels;
21316 return OK_PIXELS (pixels);
21319 car = Fbuffer_local_value (car, it->w->buffer);
21322 if (INTEGERP (car) || FLOATP (car))
21324 double fact;
21325 pixels = XFLOATINT (car);
21326 if (NILP (cdr))
21327 return OK_PIXELS (pixels);
21328 if (calc_pixel_width_or_height (&fact, it, cdr,
21329 font, width_p, align_to))
21330 return OK_PIXELS (pixels * fact);
21331 return 0;
21334 return 0;
21337 return 0;
21341 /***********************************************************************
21342 Glyph Display
21343 ***********************************************************************/
21345 #ifdef HAVE_WINDOW_SYSTEM
21347 #if GLYPH_DEBUG
21349 void
21350 dump_glyph_string (struct glyph_string *s)
21352 fprintf (stderr, "glyph string\n");
21353 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
21354 s->x, s->y, s->width, s->height);
21355 fprintf (stderr, " ybase = %d\n", s->ybase);
21356 fprintf (stderr, " hl = %d\n", s->hl);
21357 fprintf (stderr, " left overhang = %d, right = %d\n",
21358 s->left_overhang, s->right_overhang);
21359 fprintf (stderr, " nchars = %d\n", s->nchars);
21360 fprintf (stderr, " extends to end of line = %d\n",
21361 s->extends_to_end_of_line_p);
21362 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
21363 fprintf (stderr, " bg width = %d\n", s->background_width);
21366 #endif /* GLYPH_DEBUG */
21368 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
21369 of XChar2b structures for S; it can't be allocated in
21370 init_glyph_string because it must be allocated via `alloca'. W
21371 is the window on which S is drawn. ROW and AREA are the glyph row
21372 and area within the row from which S is constructed. START is the
21373 index of the first glyph structure covered by S. HL is a
21374 face-override for drawing S. */
21376 #ifdef HAVE_NTGUI
21377 #define OPTIONAL_HDC(hdc) HDC hdc,
21378 #define DECLARE_HDC(hdc) HDC hdc;
21379 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
21380 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
21381 #endif
21383 #ifndef OPTIONAL_HDC
21384 #define OPTIONAL_HDC(hdc)
21385 #define DECLARE_HDC(hdc)
21386 #define ALLOCATE_HDC(hdc, f)
21387 #define RELEASE_HDC(hdc, f)
21388 #endif
21390 static void
21391 init_glyph_string (struct glyph_string *s,
21392 OPTIONAL_HDC (hdc)
21393 XChar2b *char2b, struct window *w, struct glyph_row *row,
21394 enum glyph_row_area area, int start, enum draw_glyphs_face hl)
21396 memset (s, 0, sizeof *s);
21397 s->w = w;
21398 s->f = XFRAME (w->frame);
21399 #ifdef HAVE_NTGUI
21400 s->hdc = hdc;
21401 #endif
21402 s->display = FRAME_X_DISPLAY (s->f);
21403 s->window = FRAME_X_WINDOW (s->f);
21404 s->char2b = char2b;
21405 s->hl = hl;
21406 s->row = row;
21407 s->area = area;
21408 s->first_glyph = row->glyphs[area] + start;
21409 s->height = row->height;
21410 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
21411 s->ybase = s->y + row->ascent;
21415 /* Append the list of glyph strings with head H and tail T to the list
21416 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
21418 static inline void
21419 append_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
21420 struct glyph_string *h, struct glyph_string *t)
21422 if (h)
21424 if (*head)
21425 (*tail)->next = h;
21426 else
21427 *head = h;
21428 h->prev = *tail;
21429 *tail = t;
21434 /* Prepend the list of glyph strings with head H and tail T to the
21435 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
21436 result. */
21438 static inline void
21439 prepend_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
21440 struct glyph_string *h, struct glyph_string *t)
21442 if (h)
21444 if (*head)
21445 (*head)->prev = t;
21446 else
21447 *tail = t;
21448 t->next = *head;
21449 *head = h;
21454 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
21455 Set *HEAD and *TAIL to the resulting list. */
21457 static inline void
21458 append_glyph_string (struct glyph_string **head, struct glyph_string **tail,
21459 struct glyph_string *s)
21461 s->next = s->prev = NULL;
21462 append_glyph_string_lists (head, tail, s, s);
21466 /* Get face and two-byte form of character C in face FACE_ID on frame F.
21467 The encoding of C is returned in *CHAR2B. DISPLAY_P non-zero means
21468 make sure that X resources for the face returned are allocated.
21469 Value is a pointer to a realized face that is ready for display if
21470 DISPLAY_P is non-zero. */
21472 static inline struct face *
21473 get_char_face_and_encoding (struct frame *f, int c, int face_id,
21474 XChar2b *char2b, int display_p)
21476 struct face *face = FACE_FROM_ID (f, face_id);
21478 if (face->font)
21480 unsigned code = face->font->driver->encode_char (face->font, c);
21482 if (code != FONT_INVALID_CODE)
21483 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
21484 else
21485 STORE_XCHAR2B (char2b, 0, 0);
21488 /* Make sure X resources of the face are allocated. */
21489 #ifdef HAVE_X_WINDOWS
21490 if (display_p)
21491 #endif
21493 xassert (face != NULL);
21494 PREPARE_FACE_FOR_DISPLAY (f, face);
21497 return face;
21501 /* Get face and two-byte form of character glyph GLYPH on frame F.
21502 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
21503 a pointer to a realized face that is ready for display. */
21505 static inline struct face *
21506 get_glyph_face_and_encoding (struct frame *f, struct glyph *glyph,
21507 XChar2b *char2b, int *two_byte_p)
21509 struct face *face;
21511 xassert (glyph->type == CHAR_GLYPH);
21512 face = FACE_FROM_ID (f, glyph->face_id);
21514 if (two_byte_p)
21515 *two_byte_p = 0;
21517 if (face->font)
21519 unsigned code;
21521 if (CHAR_BYTE8_P (glyph->u.ch))
21522 code = CHAR_TO_BYTE8 (glyph->u.ch);
21523 else
21524 code = face->font->driver->encode_char (face->font, glyph->u.ch);
21526 if (code != FONT_INVALID_CODE)
21527 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
21528 else
21529 STORE_XCHAR2B (char2b, 0, 0);
21532 /* Make sure X resources of the face are allocated. */
21533 xassert (face != NULL);
21534 PREPARE_FACE_FOR_DISPLAY (f, face);
21535 return face;
21539 /* Get glyph code of character C in FONT in the two-byte form CHAR2B.
21540 Retunr 1 if FONT has a glyph for C, otherwise return 0. */
21542 static inline int
21543 get_char_glyph_code (int c, struct font *font, XChar2b *char2b)
21545 unsigned code;
21547 if (CHAR_BYTE8_P (c))
21548 code = CHAR_TO_BYTE8 (c);
21549 else
21550 code = font->driver->encode_char (font, c);
21552 if (code == FONT_INVALID_CODE)
21553 return 0;
21554 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
21555 return 1;
21559 /* Fill glyph string S with composition components specified by S->cmp.
21561 BASE_FACE is the base face of the composition.
21562 S->cmp_from is the index of the first component for S.
21564 OVERLAPS non-zero means S should draw the foreground only, and use
21565 its physical height for clipping. See also draw_glyphs.
21567 Value is the index of a component not in S. */
21569 static int
21570 fill_composite_glyph_string (struct glyph_string *s, struct face *base_face,
21571 int overlaps)
21573 int i;
21574 /* For all glyphs of this composition, starting at the offset
21575 S->cmp_from, until we reach the end of the definition or encounter a
21576 glyph that requires the different face, add it to S. */
21577 struct face *face;
21579 xassert (s);
21581 s->for_overlaps = overlaps;
21582 s->face = NULL;
21583 s->font = NULL;
21584 for (i = s->cmp_from; i < s->cmp->glyph_len; i++)
21586 int c = COMPOSITION_GLYPH (s->cmp, i);
21588 if (c != '\t')
21590 int face_id = FACE_FOR_CHAR (s->f, base_face->ascii_face, c,
21591 -1, Qnil);
21593 face = get_char_face_and_encoding (s->f, c, face_id,
21594 s->char2b + i, 1);
21595 if (face)
21597 if (! s->face)
21599 s->face = face;
21600 s->font = s->face->font;
21602 else if (s->face != face)
21603 break;
21606 ++s->nchars;
21608 s->cmp_to = i;
21610 /* All glyph strings for the same composition has the same width,
21611 i.e. the width set for the first component of the composition. */
21612 s->width = s->first_glyph->pixel_width;
21614 /* If the specified font could not be loaded, use the frame's
21615 default font, but record the fact that we couldn't load it in
21616 the glyph string so that we can draw rectangles for the
21617 characters of the glyph string. */
21618 if (s->font == NULL)
21620 s->font_not_found_p = 1;
21621 s->font = FRAME_FONT (s->f);
21624 /* Adjust base line for subscript/superscript text. */
21625 s->ybase += s->first_glyph->voffset;
21627 /* This glyph string must always be drawn with 16-bit functions. */
21628 s->two_byte_p = 1;
21630 return s->cmp_to;
21633 static int
21634 fill_gstring_glyph_string (struct glyph_string *s, int face_id,
21635 int start, int end, int overlaps)
21637 struct glyph *glyph, *last;
21638 Lisp_Object lgstring;
21639 int i;
21641 s->for_overlaps = overlaps;
21642 glyph = s->row->glyphs[s->area] + start;
21643 last = s->row->glyphs[s->area] + end;
21644 s->cmp_id = glyph->u.cmp.id;
21645 s->cmp_from = glyph->slice.cmp.from;
21646 s->cmp_to = glyph->slice.cmp.to + 1;
21647 s->face = FACE_FROM_ID (s->f, face_id);
21648 lgstring = composition_gstring_from_id (s->cmp_id);
21649 s->font = XFONT_OBJECT (LGSTRING_FONT (lgstring));
21650 glyph++;
21651 while (glyph < last
21652 && glyph->u.cmp.automatic
21653 && glyph->u.cmp.id == s->cmp_id
21654 && s->cmp_to == glyph->slice.cmp.from)
21655 s->cmp_to = (glyph++)->slice.cmp.to + 1;
21657 for (i = s->cmp_from; i < s->cmp_to; i++)
21659 Lisp_Object lglyph = LGSTRING_GLYPH (lgstring, i);
21660 unsigned code = LGLYPH_CODE (lglyph);
21662 STORE_XCHAR2B ((s->char2b + i), code >> 8, code & 0xFF);
21664 s->width = composition_gstring_width (lgstring, s->cmp_from, s->cmp_to, NULL);
21665 return glyph - s->row->glyphs[s->area];
21669 /* Fill glyph string S from a sequence glyphs for glyphless characters.
21670 See the comment of fill_glyph_string for arguments.
21671 Value is the index of the first glyph not in S. */
21674 static int
21675 fill_glyphless_glyph_string (struct glyph_string *s, int face_id,
21676 int start, int end, int overlaps)
21678 struct glyph *glyph, *last;
21679 int voffset;
21681 xassert (s->first_glyph->type == GLYPHLESS_GLYPH);
21682 s->for_overlaps = overlaps;
21683 glyph = s->row->glyphs[s->area] + start;
21684 last = s->row->glyphs[s->area] + end;
21685 voffset = glyph->voffset;
21686 s->face = FACE_FROM_ID (s->f, face_id);
21687 s->font = s->face->font;
21688 s->nchars = 1;
21689 s->width = glyph->pixel_width;
21690 glyph++;
21691 while (glyph < last
21692 && glyph->type == GLYPHLESS_GLYPH
21693 && glyph->voffset == voffset
21694 && glyph->face_id == face_id)
21696 s->nchars++;
21697 s->width += glyph->pixel_width;
21698 glyph++;
21700 s->ybase += voffset;
21701 return glyph - s->row->glyphs[s->area];
21705 /* Fill glyph string S from a sequence of character glyphs.
21707 FACE_ID is the face id of the string. START is the index of the
21708 first glyph to consider, END is the index of the last + 1.
21709 OVERLAPS non-zero means S should draw the foreground only, and use
21710 its physical height for clipping. See also draw_glyphs.
21712 Value is the index of the first glyph not in S. */
21714 static int
21715 fill_glyph_string (struct glyph_string *s, int face_id,
21716 int start, int end, int overlaps)
21718 struct glyph *glyph, *last;
21719 int voffset;
21720 int glyph_not_available_p;
21722 xassert (s->f == XFRAME (s->w->frame));
21723 xassert (s->nchars == 0);
21724 xassert (start >= 0 && end > start);
21726 s->for_overlaps = overlaps;
21727 glyph = s->row->glyphs[s->area] + start;
21728 last = s->row->glyphs[s->area] + end;
21729 voffset = glyph->voffset;
21730 s->padding_p = glyph->padding_p;
21731 glyph_not_available_p = glyph->glyph_not_available_p;
21733 while (glyph < last
21734 && glyph->type == CHAR_GLYPH
21735 && glyph->voffset == voffset
21736 /* Same face id implies same font, nowadays. */
21737 && glyph->face_id == face_id
21738 && glyph->glyph_not_available_p == glyph_not_available_p)
21740 int two_byte_p;
21742 s->face = get_glyph_face_and_encoding (s->f, glyph,
21743 s->char2b + s->nchars,
21744 &two_byte_p);
21745 s->two_byte_p = two_byte_p;
21746 ++s->nchars;
21747 xassert (s->nchars <= end - start);
21748 s->width += glyph->pixel_width;
21749 if (glyph++->padding_p != s->padding_p)
21750 break;
21753 s->font = s->face->font;
21755 /* If the specified font could not be loaded, use the frame's font,
21756 but record the fact that we couldn't load it in
21757 S->font_not_found_p so that we can draw rectangles for the
21758 characters of the glyph string. */
21759 if (s->font == NULL || glyph_not_available_p)
21761 s->font_not_found_p = 1;
21762 s->font = FRAME_FONT (s->f);
21765 /* Adjust base line for subscript/superscript text. */
21766 s->ybase += voffset;
21768 xassert (s->face && s->face->gc);
21769 return glyph - s->row->glyphs[s->area];
21773 /* Fill glyph string S from image glyph S->first_glyph. */
21775 static void
21776 fill_image_glyph_string (struct glyph_string *s)
21778 xassert (s->first_glyph->type == IMAGE_GLYPH);
21779 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
21780 xassert (s->img);
21781 s->slice = s->first_glyph->slice.img;
21782 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
21783 s->font = s->face->font;
21784 s->width = s->first_glyph->pixel_width;
21786 /* Adjust base line for subscript/superscript text. */
21787 s->ybase += s->first_glyph->voffset;
21791 /* Fill glyph string S from a sequence of stretch glyphs.
21793 START is the index of the first glyph to consider,
21794 END is the index of the last + 1.
21796 Value is the index of the first glyph not in S. */
21798 static int
21799 fill_stretch_glyph_string (struct glyph_string *s, int start, int end)
21801 struct glyph *glyph, *last;
21802 int voffset, face_id;
21804 xassert (s->first_glyph->type == STRETCH_GLYPH);
21806 glyph = s->row->glyphs[s->area] + start;
21807 last = s->row->glyphs[s->area] + end;
21808 face_id = glyph->face_id;
21809 s->face = FACE_FROM_ID (s->f, face_id);
21810 s->font = s->face->font;
21811 s->width = glyph->pixel_width;
21812 s->nchars = 1;
21813 voffset = glyph->voffset;
21815 for (++glyph;
21816 (glyph < last
21817 && glyph->type == STRETCH_GLYPH
21818 && glyph->voffset == voffset
21819 && glyph->face_id == face_id);
21820 ++glyph)
21821 s->width += glyph->pixel_width;
21823 /* Adjust base line for subscript/superscript text. */
21824 s->ybase += voffset;
21826 /* The case that face->gc == 0 is handled when drawing the glyph
21827 string by calling PREPARE_FACE_FOR_DISPLAY. */
21828 xassert (s->face);
21829 return glyph - s->row->glyphs[s->area];
21832 static struct font_metrics *
21833 get_per_char_metric (struct font *font, XChar2b *char2b)
21835 static struct font_metrics metrics;
21836 unsigned code = (XCHAR2B_BYTE1 (char2b) << 8) | XCHAR2B_BYTE2 (char2b);
21838 if (! font || code == FONT_INVALID_CODE)
21839 return NULL;
21840 font->driver->text_extents (font, &code, 1, &metrics);
21841 return &metrics;
21844 /* EXPORT for RIF:
21845 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
21846 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
21847 assumed to be zero. */
21849 void
21850 x_get_glyph_overhangs (struct glyph *glyph, struct frame *f, int *left, int *right)
21852 *left = *right = 0;
21854 if (glyph->type == CHAR_GLYPH)
21856 struct face *face;
21857 XChar2b char2b;
21858 struct font_metrics *pcm;
21860 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
21861 if (face->font && (pcm = get_per_char_metric (face->font, &char2b)))
21863 if (pcm->rbearing > pcm->width)
21864 *right = pcm->rbearing - pcm->width;
21865 if (pcm->lbearing < 0)
21866 *left = -pcm->lbearing;
21869 else if (glyph->type == COMPOSITE_GLYPH)
21871 if (! glyph->u.cmp.automatic)
21873 struct composition *cmp = composition_table[glyph->u.cmp.id];
21875 if (cmp->rbearing > cmp->pixel_width)
21876 *right = cmp->rbearing - cmp->pixel_width;
21877 if (cmp->lbearing < 0)
21878 *left = - cmp->lbearing;
21880 else
21882 Lisp_Object gstring = composition_gstring_from_id (glyph->u.cmp.id);
21883 struct font_metrics metrics;
21885 composition_gstring_width (gstring, glyph->slice.cmp.from,
21886 glyph->slice.cmp.to + 1, &metrics);
21887 if (metrics.rbearing > metrics.width)
21888 *right = metrics.rbearing - metrics.width;
21889 if (metrics.lbearing < 0)
21890 *left = - metrics.lbearing;
21896 /* Return the index of the first glyph preceding glyph string S that
21897 is overwritten by S because of S's left overhang. Value is -1
21898 if no glyphs are overwritten. */
21900 static int
21901 left_overwritten (struct glyph_string *s)
21903 int k;
21905 if (s->left_overhang)
21907 int x = 0, i;
21908 struct glyph *glyphs = s->row->glyphs[s->area];
21909 int first = s->first_glyph - glyphs;
21911 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
21912 x -= glyphs[i].pixel_width;
21914 k = i + 1;
21916 else
21917 k = -1;
21919 return k;
21923 /* Return the index of the first glyph preceding glyph string S that
21924 is overwriting S because of its right overhang. Value is -1 if no
21925 glyph in front of S overwrites S. */
21927 static int
21928 left_overwriting (struct glyph_string *s)
21930 int i, k, x;
21931 struct glyph *glyphs = s->row->glyphs[s->area];
21932 int first = s->first_glyph - glyphs;
21934 k = -1;
21935 x = 0;
21936 for (i = first - 1; i >= 0; --i)
21938 int left, right;
21939 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
21940 if (x + right > 0)
21941 k = i;
21942 x -= glyphs[i].pixel_width;
21945 return k;
21949 /* Return the index of the last glyph following glyph string S that is
21950 overwritten by S because of S's right overhang. Value is -1 if
21951 no such glyph is found. */
21953 static int
21954 right_overwritten (struct glyph_string *s)
21956 int k = -1;
21958 if (s->right_overhang)
21960 int x = 0, i;
21961 struct glyph *glyphs = s->row->glyphs[s->area];
21962 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
21963 int end = s->row->used[s->area];
21965 for (i = first; i < end && s->right_overhang > x; ++i)
21966 x += glyphs[i].pixel_width;
21968 k = i;
21971 return k;
21975 /* Return the index of the last glyph following glyph string S that
21976 overwrites S because of its left overhang. Value is negative
21977 if no such glyph is found. */
21979 static int
21980 right_overwriting (struct glyph_string *s)
21982 int i, k, x;
21983 int end = s->row->used[s->area];
21984 struct glyph *glyphs = s->row->glyphs[s->area];
21985 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
21987 k = -1;
21988 x = 0;
21989 for (i = first; i < end; ++i)
21991 int left, right;
21992 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
21993 if (x - left < 0)
21994 k = i;
21995 x += glyphs[i].pixel_width;
21998 return k;
22002 /* Set background width of glyph string S. START is the index of the
22003 first glyph following S. LAST_X is the right-most x-position + 1
22004 in the drawing area. */
22006 static inline void
22007 set_glyph_string_background_width (struct glyph_string *s, int start, int last_x)
22009 /* If the face of this glyph string has to be drawn to the end of
22010 the drawing area, set S->extends_to_end_of_line_p. */
22012 if (start == s->row->used[s->area]
22013 && s->area == TEXT_AREA
22014 && ((s->row->fill_line_p
22015 && (s->hl == DRAW_NORMAL_TEXT
22016 || s->hl == DRAW_IMAGE_RAISED
22017 || s->hl == DRAW_IMAGE_SUNKEN))
22018 || s->hl == DRAW_MOUSE_FACE))
22019 s->extends_to_end_of_line_p = 1;
22021 /* If S extends its face to the end of the line, set its
22022 background_width to the distance to the right edge of the drawing
22023 area. */
22024 if (s->extends_to_end_of_line_p)
22025 s->background_width = last_x - s->x + 1;
22026 else
22027 s->background_width = s->width;
22031 /* Compute overhangs and x-positions for glyph string S and its
22032 predecessors, or successors. X is the starting x-position for S.
22033 BACKWARD_P non-zero means process predecessors. */
22035 static void
22036 compute_overhangs_and_x (struct glyph_string *s, int x, int backward_p)
22038 if (backward_p)
22040 while (s)
22042 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
22043 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
22044 x -= s->width;
22045 s->x = x;
22046 s = s->prev;
22049 else
22051 while (s)
22053 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
22054 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
22055 s->x = x;
22056 x += s->width;
22057 s = s->next;
22064 /* The following macros are only called from draw_glyphs below.
22065 They reference the following parameters of that function directly:
22066 `w', `row', `area', and `overlap_p'
22067 as well as the following local variables:
22068 `s', `f', and `hdc' (in W32) */
22070 #ifdef HAVE_NTGUI
22071 /* On W32, silently add local `hdc' variable to argument list of
22072 init_glyph_string. */
22073 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
22074 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
22075 #else
22076 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
22077 init_glyph_string (s, char2b, w, row, area, start, hl)
22078 #endif
22080 /* Add a glyph string for a stretch glyph to the list of strings
22081 between HEAD and TAIL. START is the index of the stretch glyph in
22082 row area AREA of glyph row ROW. END is the index of the last glyph
22083 in that glyph row area. X is the current output position assigned
22084 to the new glyph string constructed. HL overrides that face of the
22085 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
22086 is the right-most x-position of the drawing area. */
22088 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
22089 and below -- keep them on one line. */
22090 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
22091 do \
22093 s = (struct glyph_string *) alloca (sizeof *s); \
22094 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
22095 START = fill_stretch_glyph_string (s, START, END); \
22096 append_glyph_string (&HEAD, &TAIL, s); \
22097 s->x = (X); \
22099 while (0)
22102 /* Add a glyph string for an image glyph to the list of strings
22103 between HEAD and TAIL. START is the index of the image glyph in
22104 row area AREA of glyph row ROW. END is the index of the last glyph
22105 in that glyph row area. X is the current output position assigned
22106 to the new glyph string constructed. HL overrides that face of the
22107 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
22108 is the right-most x-position of the drawing area. */
22110 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
22111 do \
22113 s = (struct glyph_string *) alloca (sizeof *s); \
22114 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
22115 fill_image_glyph_string (s); \
22116 append_glyph_string (&HEAD, &TAIL, s); \
22117 ++START; \
22118 s->x = (X); \
22120 while (0)
22123 /* Add a glyph string for a sequence of character glyphs to the list
22124 of strings between HEAD and TAIL. START is the index of the first
22125 glyph in row area AREA of glyph row ROW that is part of the new
22126 glyph string. END is the index of the last glyph in that glyph row
22127 area. X is the current output position assigned to the new glyph
22128 string constructed. HL overrides that face of the glyph; e.g. it
22129 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
22130 right-most x-position of the drawing area. */
22132 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
22133 do \
22135 int face_id; \
22136 XChar2b *char2b; \
22138 face_id = (row)->glyphs[area][START].face_id; \
22140 s = (struct glyph_string *) alloca (sizeof *s); \
22141 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
22142 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
22143 append_glyph_string (&HEAD, &TAIL, s); \
22144 s->x = (X); \
22145 START = fill_glyph_string (s, face_id, START, END, overlaps); \
22147 while (0)
22150 /* Add a glyph string for a composite sequence to the list of strings
22151 between HEAD and TAIL. START is the index of the first glyph in
22152 row area AREA of glyph row ROW that is part of the new glyph
22153 string. END is the index of the last glyph in that glyph row area.
22154 X is the current output position assigned to the new glyph string
22155 constructed. HL overrides that face of the glyph; e.g. it is
22156 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
22157 x-position of the drawing area. */
22159 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
22160 do { \
22161 int face_id = (row)->glyphs[area][START].face_id; \
22162 struct face *base_face = FACE_FROM_ID (f, face_id); \
22163 int cmp_id = (row)->glyphs[area][START].u.cmp.id; \
22164 struct composition *cmp = composition_table[cmp_id]; \
22165 XChar2b *char2b; \
22166 struct glyph_string *first_s IF_LINT (= NULL); \
22167 int n; \
22169 char2b = (XChar2b *) alloca ((sizeof *char2b) * cmp->glyph_len); \
22171 /* Make glyph_strings for each glyph sequence that is drawable by \
22172 the same face, and append them to HEAD/TAIL. */ \
22173 for (n = 0; n < cmp->glyph_len;) \
22175 s = (struct glyph_string *) alloca (sizeof *s); \
22176 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
22177 append_glyph_string (&(HEAD), &(TAIL), s); \
22178 s->cmp = cmp; \
22179 s->cmp_from = n; \
22180 s->x = (X); \
22181 if (n == 0) \
22182 first_s = s; \
22183 n = fill_composite_glyph_string (s, base_face, overlaps); \
22186 ++START; \
22187 s = first_s; \
22188 } while (0)
22191 /* Add a glyph string for a glyph-string sequence to the list of strings
22192 between HEAD and TAIL. */
22194 #define BUILD_GSTRING_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
22195 do { \
22196 int face_id; \
22197 XChar2b *char2b; \
22198 Lisp_Object gstring; \
22200 face_id = (row)->glyphs[area][START].face_id; \
22201 gstring = (composition_gstring_from_id \
22202 ((row)->glyphs[area][START].u.cmp.id)); \
22203 s = (struct glyph_string *) alloca (sizeof *s); \
22204 char2b = (XChar2b *) alloca ((sizeof *char2b) \
22205 * LGSTRING_GLYPH_LEN (gstring)); \
22206 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
22207 append_glyph_string (&(HEAD), &(TAIL), s); \
22208 s->x = (X); \
22209 START = fill_gstring_glyph_string (s, face_id, START, END, overlaps); \
22210 } while (0)
22213 /* Add a glyph string for a sequence of glyphless character's glyphs
22214 to the list of strings between HEAD and TAIL. The meanings of
22215 arguments are the same as those of BUILD_CHAR_GLYPH_STRINGS. */
22217 #define BUILD_GLYPHLESS_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
22218 do \
22220 int face_id; \
22222 face_id = (row)->glyphs[area][START].face_id; \
22224 s = (struct glyph_string *) alloca (sizeof *s); \
22225 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
22226 append_glyph_string (&HEAD, &TAIL, s); \
22227 s->x = (X); \
22228 START = fill_glyphless_glyph_string (s, face_id, START, END, \
22229 overlaps); \
22231 while (0)
22234 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
22235 of AREA of glyph row ROW on window W between indices START and END.
22236 HL overrides the face for drawing glyph strings, e.g. it is
22237 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
22238 x-positions of the drawing area.
22240 This is an ugly monster macro construct because we must use alloca
22241 to allocate glyph strings (because draw_glyphs can be called
22242 asynchronously). */
22244 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
22245 do \
22247 HEAD = TAIL = NULL; \
22248 while (START < END) \
22250 struct glyph *first_glyph = (row)->glyphs[area] + START; \
22251 switch (first_glyph->type) \
22253 case CHAR_GLYPH: \
22254 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
22255 HL, X, LAST_X); \
22256 break; \
22258 case COMPOSITE_GLYPH: \
22259 if (first_glyph->u.cmp.automatic) \
22260 BUILD_GSTRING_GLYPH_STRING (START, END, HEAD, TAIL, \
22261 HL, X, LAST_X); \
22262 else \
22263 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
22264 HL, X, LAST_X); \
22265 break; \
22267 case STRETCH_GLYPH: \
22268 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
22269 HL, X, LAST_X); \
22270 break; \
22272 case IMAGE_GLYPH: \
22273 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
22274 HL, X, LAST_X); \
22275 break; \
22277 case GLYPHLESS_GLYPH: \
22278 BUILD_GLYPHLESS_GLYPH_STRING (START, END, HEAD, TAIL, \
22279 HL, X, LAST_X); \
22280 break; \
22282 default: \
22283 abort (); \
22286 if (s) \
22288 set_glyph_string_background_width (s, START, LAST_X); \
22289 (X) += s->width; \
22292 } while (0)
22295 /* Draw glyphs between START and END in AREA of ROW on window W,
22296 starting at x-position X. X is relative to AREA in W. HL is a
22297 face-override with the following meaning:
22299 DRAW_NORMAL_TEXT draw normally
22300 DRAW_CURSOR draw in cursor face
22301 DRAW_MOUSE_FACE draw in mouse face.
22302 DRAW_INVERSE_VIDEO draw in mode line face
22303 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
22304 DRAW_IMAGE_RAISED draw an image with a raised relief around it
22306 If OVERLAPS is non-zero, draw only the foreground of characters and
22307 clip to the physical height of ROW. Non-zero value also defines
22308 the overlapping part to be drawn:
22310 OVERLAPS_PRED overlap with preceding rows
22311 OVERLAPS_SUCC overlap with succeeding rows
22312 OVERLAPS_BOTH overlap with both preceding/succeeding rows
22313 OVERLAPS_ERASED_CURSOR overlap with erased cursor area
22315 Value is the x-position reached, relative to AREA of W. */
22317 static int
22318 draw_glyphs (struct window *w, int x, struct glyph_row *row,
22319 enum glyph_row_area area, EMACS_INT start, EMACS_INT end,
22320 enum draw_glyphs_face hl, int overlaps)
22322 struct glyph_string *head, *tail;
22323 struct glyph_string *s;
22324 struct glyph_string *clip_head = NULL, *clip_tail = NULL;
22325 int i, j, x_reached, last_x, area_left = 0;
22326 struct frame *f = XFRAME (WINDOW_FRAME (w));
22327 DECLARE_HDC (hdc);
22329 ALLOCATE_HDC (hdc, f);
22331 /* Let's rather be paranoid than getting a SEGV. */
22332 end = min (end, row->used[area]);
22333 start = max (0, start);
22334 start = min (end, start);
22336 /* Translate X to frame coordinates. Set last_x to the right
22337 end of the drawing area. */
22338 if (row->full_width_p)
22340 /* X is relative to the left edge of W, without scroll bars
22341 or fringes. */
22342 area_left = WINDOW_LEFT_EDGE_X (w);
22343 last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
22345 else
22347 area_left = window_box_left (w, area);
22348 last_x = area_left + window_box_width (w, area);
22350 x += area_left;
22352 /* Build a doubly-linked list of glyph_string structures between
22353 head and tail from what we have to draw. Note that the macro
22354 BUILD_GLYPH_STRINGS will modify its start parameter. That's
22355 the reason we use a separate variable `i'. */
22356 i = start;
22357 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
22358 if (tail)
22359 x_reached = tail->x + tail->background_width;
22360 else
22361 x_reached = x;
22363 /* If there are any glyphs with lbearing < 0 or rbearing > width in
22364 the row, redraw some glyphs in front or following the glyph
22365 strings built above. */
22366 if (head && !overlaps && row->contains_overlapping_glyphs_p)
22368 struct glyph_string *h, *t;
22369 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
22370 int mouse_beg_col IF_LINT (= 0), mouse_end_col IF_LINT (= 0);
22371 int check_mouse_face = 0;
22372 int dummy_x = 0;
22374 /* If mouse highlighting is on, we may need to draw adjacent
22375 glyphs using mouse-face highlighting. */
22376 if (area == TEXT_AREA && row->mouse_face_p)
22378 struct glyph_row *mouse_beg_row, *mouse_end_row;
22380 mouse_beg_row = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_beg_row);
22381 mouse_end_row = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_end_row);
22383 if (row >= mouse_beg_row && row <= mouse_end_row)
22385 check_mouse_face = 1;
22386 mouse_beg_col = (row == mouse_beg_row)
22387 ? hlinfo->mouse_face_beg_col : 0;
22388 mouse_end_col = (row == mouse_end_row)
22389 ? hlinfo->mouse_face_end_col
22390 : row->used[TEXT_AREA];
22394 /* Compute overhangs for all glyph strings. */
22395 if (FRAME_RIF (f)->compute_glyph_string_overhangs)
22396 for (s = head; s; s = s->next)
22397 FRAME_RIF (f)->compute_glyph_string_overhangs (s);
22399 /* Prepend glyph strings for glyphs in front of the first glyph
22400 string that are overwritten because of the first glyph
22401 string's left overhang. The background of all strings
22402 prepended must be drawn because the first glyph string
22403 draws over it. */
22404 i = left_overwritten (head);
22405 if (i >= 0)
22407 enum draw_glyphs_face overlap_hl;
22409 /* If this row contains mouse highlighting, attempt to draw
22410 the overlapped glyphs with the correct highlight. This
22411 code fails if the overlap encompasses more than one glyph
22412 and mouse-highlight spans only some of these glyphs.
22413 However, making it work perfectly involves a lot more
22414 code, and I don't know if the pathological case occurs in
22415 practice, so we'll stick to this for now. --- cyd */
22416 if (check_mouse_face
22417 && mouse_beg_col < start && mouse_end_col > i)
22418 overlap_hl = DRAW_MOUSE_FACE;
22419 else
22420 overlap_hl = DRAW_NORMAL_TEXT;
22422 j = i;
22423 BUILD_GLYPH_STRINGS (j, start, h, t,
22424 overlap_hl, dummy_x, last_x);
22425 start = i;
22426 compute_overhangs_and_x (t, head->x, 1);
22427 prepend_glyph_string_lists (&head, &tail, h, t);
22428 clip_head = head;
22431 /* Prepend glyph strings for glyphs in front of the first glyph
22432 string that overwrite that glyph string because of their
22433 right overhang. For these strings, only the foreground must
22434 be drawn, because it draws over the glyph string at `head'.
22435 The background must not be drawn because this would overwrite
22436 right overhangs of preceding glyphs for which no glyph
22437 strings exist. */
22438 i = left_overwriting (head);
22439 if (i >= 0)
22441 enum draw_glyphs_face overlap_hl;
22443 if (check_mouse_face
22444 && mouse_beg_col < start && mouse_end_col > i)
22445 overlap_hl = DRAW_MOUSE_FACE;
22446 else
22447 overlap_hl = DRAW_NORMAL_TEXT;
22449 clip_head = head;
22450 BUILD_GLYPH_STRINGS (i, start, h, t,
22451 overlap_hl, dummy_x, last_x);
22452 for (s = h; s; s = s->next)
22453 s->background_filled_p = 1;
22454 compute_overhangs_and_x (t, head->x, 1);
22455 prepend_glyph_string_lists (&head, &tail, h, t);
22458 /* Append glyphs strings for glyphs following the last glyph
22459 string tail that are overwritten by tail. The background of
22460 these strings has to be drawn because tail's foreground draws
22461 over it. */
22462 i = right_overwritten (tail);
22463 if (i >= 0)
22465 enum draw_glyphs_face overlap_hl;
22467 if (check_mouse_face
22468 && mouse_beg_col < i && mouse_end_col > end)
22469 overlap_hl = DRAW_MOUSE_FACE;
22470 else
22471 overlap_hl = DRAW_NORMAL_TEXT;
22473 BUILD_GLYPH_STRINGS (end, i, h, t,
22474 overlap_hl, x, last_x);
22475 /* Because BUILD_GLYPH_STRINGS updates the first argument,
22476 we don't have `end = i;' here. */
22477 compute_overhangs_and_x (h, tail->x + tail->width, 0);
22478 append_glyph_string_lists (&head, &tail, h, t);
22479 clip_tail = tail;
22482 /* Append glyph strings for glyphs following the last glyph
22483 string tail that overwrite tail. The foreground of such
22484 glyphs has to be drawn because it writes into the background
22485 of tail. The background must not be drawn because it could
22486 paint over the foreground of following glyphs. */
22487 i = right_overwriting (tail);
22488 if (i >= 0)
22490 enum draw_glyphs_face overlap_hl;
22491 if (check_mouse_face
22492 && mouse_beg_col < i && mouse_end_col > end)
22493 overlap_hl = DRAW_MOUSE_FACE;
22494 else
22495 overlap_hl = DRAW_NORMAL_TEXT;
22497 clip_tail = tail;
22498 i++; /* We must include the Ith glyph. */
22499 BUILD_GLYPH_STRINGS (end, i, h, t,
22500 overlap_hl, x, last_x);
22501 for (s = h; s; s = s->next)
22502 s->background_filled_p = 1;
22503 compute_overhangs_and_x (h, tail->x + tail->width, 0);
22504 append_glyph_string_lists (&head, &tail, h, t);
22506 if (clip_head || clip_tail)
22507 for (s = head; s; s = s->next)
22509 s->clip_head = clip_head;
22510 s->clip_tail = clip_tail;
22514 /* Draw all strings. */
22515 for (s = head; s; s = s->next)
22516 FRAME_RIF (f)->draw_glyph_string (s);
22518 #ifndef HAVE_NS
22519 /* When focus a sole frame and move horizontally, this sets on_p to 0
22520 causing a failure to erase prev cursor position. */
22521 if (area == TEXT_AREA
22522 && !row->full_width_p
22523 /* When drawing overlapping rows, only the glyph strings'
22524 foreground is drawn, which doesn't erase a cursor
22525 completely. */
22526 && !overlaps)
22528 int x0 = clip_head ? clip_head->x : (head ? head->x : x);
22529 int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width
22530 : (tail ? tail->x + tail->background_width : x));
22531 x0 -= area_left;
22532 x1 -= area_left;
22534 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
22535 row->y, MATRIX_ROW_BOTTOM_Y (row));
22537 #endif
22539 /* Value is the x-position up to which drawn, relative to AREA of W.
22540 This doesn't include parts drawn because of overhangs. */
22541 if (row->full_width_p)
22542 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
22543 else
22544 x_reached -= area_left;
22546 RELEASE_HDC (hdc, f);
22548 return x_reached;
22551 /* Expand row matrix if too narrow. Don't expand if area
22552 is not present. */
22554 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
22556 if (!fonts_changed_p \
22557 && (it->glyph_row->glyphs[area] \
22558 < it->glyph_row->glyphs[area + 1])) \
22560 it->w->ncols_scale_factor++; \
22561 fonts_changed_p = 1; \
22565 /* Store one glyph for IT->char_to_display in IT->glyph_row.
22566 Called from x_produce_glyphs when IT->glyph_row is non-null. */
22568 static inline void
22569 append_glyph (struct it *it)
22571 struct glyph *glyph;
22572 enum glyph_row_area area = it->area;
22574 xassert (it->glyph_row);
22575 xassert (it->char_to_display != '\n' && it->char_to_display != '\t');
22577 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
22578 if (glyph < it->glyph_row->glyphs[area + 1])
22580 /* If the glyph row is reversed, we need to prepend the glyph
22581 rather than append it. */
22582 if (it->glyph_row->reversed_p && area == TEXT_AREA)
22584 struct glyph *g;
22586 /* Make room for the additional glyph. */
22587 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
22588 g[1] = *g;
22589 glyph = it->glyph_row->glyphs[area];
22591 glyph->charpos = CHARPOS (it->position);
22592 glyph->object = it->object;
22593 if (it->pixel_width > 0)
22595 glyph->pixel_width = it->pixel_width;
22596 glyph->padding_p = 0;
22598 else
22600 /* Assure at least 1-pixel width. Otherwise, cursor can't
22601 be displayed correctly. */
22602 glyph->pixel_width = 1;
22603 glyph->padding_p = 1;
22605 glyph->ascent = it->ascent;
22606 glyph->descent = it->descent;
22607 glyph->voffset = it->voffset;
22608 glyph->type = CHAR_GLYPH;
22609 glyph->avoid_cursor_p = it->avoid_cursor_p;
22610 glyph->multibyte_p = it->multibyte_p;
22611 glyph->left_box_line_p = it->start_of_box_run_p;
22612 glyph->right_box_line_p = it->end_of_box_run_p;
22613 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
22614 || it->phys_descent > it->descent);
22615 glyph->glyph_not_available_p = it->glyph_not_available_p;
22616 glyph->face_id = it->face_id;
22617 glyph->u.ch = it->char_to_display;
22618 glyph->slice.img = null_glyph_slice;
22619 glyph->font_type = FONT_TYPE_UNKNOWN;
22620 if (it->bidi_p)
22622 glyph->resolved_level = it->bidi_it.resolved_level;
22623 if ((it->bidi_it.type & 7) != it->bidi_it.type)
22624 abort ();
22625 glyph->bidi_type = it->bidi_it.type;
22627 else
22629 glyph->resolved_level = 0;
22630 glyph->bidi_type = UNKNOWN_BT;
22632 ++it->glyph_row->used[area];
22634 else
22635 IT_EXPAND_MATRIX_WIDTH (it, area);
22638 /* Store one glyph for the composition IT->cmp_it.id in
22639 IT->glyph_row. Called from x_produce_glyphs when IT->glyph_row is
22640 non-null. */
22642 static inline void
22643 append_composite_glyph (struct it *it)
22645 struct glyph *glyph;
22646 enum glyph_row_area area = it->area;
22648 xassert (it->glyph_row);
22650 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
22651 if (glyph < it->glyph_row->glyphs[area + 1])
22653 /* If the glyph row is reversed, we need to prepend the glyph
22654 rather than append it. */
22655 if (it->glyph_row->reversed_p && it->area == TEXT_AREA)
22657 struct glyph *g;
22659 /* Make room for the new glyph. */
22660 for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
22661 g[1] = *g;
22662 glyph = it->glyph_row->glyphs[it->area];
22664 glyph->charpos = it->cmp_it.charpos;
22665 glyph->object = it->object;
22666 glyph->pixel_width = it->pixel_width;
22667 glyph->ascent = it->ascent;
22668 glyph->descent = it->descent;
22669 glyph->voffset = it->voffset;
22670 glyph->type = COMPOSITE_GLYPH;
22671 if (it->cmp_it.ch < 0)
22673 glyph->u.cmp.automatic = 0;
22674 glyph->u.cmp.id = it->cmp_it.id;
22675 glyph->slice.cmp.from = glyph->slice.cmp.to = 0;
22677 else
22679 glyph->u.cmp.automatic = 1;
22680 glyph->u.cmp.id = it->cmp_it.id;
22681 glyph->slice.cmp.from = it->cmp_it.from;
22682 glyph->slice.cmp.to = it->cmp_it.to - 1;
22684 glyph->avoid_cursor_p = it->avoid_cursor_p;
22685 glyph->multibyte_p = it->multibyte_p;
22686 glyph->left_box_line_p = it->start_of_box_run_p;
22687 glyph->right_box_line_p = it->end_of_box_run_p;
22688 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
22689 || it->phys_descent > it->descent);
22690 glyph->padding_p = 0;
22691 glyph->glyph_not_available_p = 0;
22692 glyph->face_id = it->face_id;
22693 glyph->font_type = FONT_TYPE_UNKNOWN;
22694 if (it->bidi_p)
22696 glyph->resolved_level = it->bidi_it.resolved_level;
22697 if ((it->bidi_it.type & 7) != it->bidi_it.type)
22698 abort ();
22699 glyph->bidi_type = it->bidi_it.type;
22701 ++it->glyph_row->used[area];
22703 else
22704 IT_EXPAND_MATRIX_WIDTH (it, area);
22708 /* Change IT->ascent and IT->height according to the setting of
22709 IT->voffset. */
22711 static inline void
22712 take_vertical_position_into_account (struct it *it)
22714 if (it->voffset)
22716 if (it->voffset < 0)
22717 /* Increase the ascent so that we can display the text higher
22718 in the line. */
22719 it->ascent -= it->voffset;
22720 else
22721 /* Increase the descent so that we can display the text lower
22722 in the line. */
22723 it->descent += it->voffset;
22728 /* Produce glyphs/get display metrics for the image IT is loaded with.
22729 See the description of struct display_iterator in dispextern.h for
22730 an overview of struct display_iterator. */
22732 static void
22733 produce_image_glyph (struct it *it)
22735 struct image *img;
22736 struct face *face;
22737 int glyph_ascent, crop;
22738 struct glyph_slice slice;
22740 xassert (it->what == IT_IMAGE);
22742 face = FACE_FROM_ID (it->f, it->face_id);
22743 xassert (face);
22744 /* Make sure X resources of the face is loaded. */
22745 PREPARE_FACE_FOR_DISPLAY (it->f, face);
22747 if (it->image_id < 0)
22749 /* Fringe bitmap. */
22750 it->ascent = it->phys_ascent = 0;
22751 it->descent = it->phys_descent = 0;
22752 it->pixel_width = 0;
22753 it->nglyphs = 0;
22754 return;
22757 img = IMAGE_FROM_ID (it->f, it->image_id);
22758 xassert (img);
22759 /* Make sure X resources of the image is loaded. */
22760 prepare_image_for_display (it->f, img);
22762 slice.x = slice.y = 0;
22763 slice.width = img->width;
22764 slice.height = img->height;
22766 if (INTEGERP (it->slice.x))
22767 slice.x = XINT (it->slice.x);
22768 else if (FLOATP (it->slice.x))
22769 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
22771 if (INTEGERP (it->slice.y))
22772 slice.y = XINT (it->slice.y);
22773 else if (FLOATP (it->slice.y))
22774 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
22776 if (INTEGERP (it->slice.width))
22777 slice.width = XINT (it->slice.width);
22778 else if (FLOATP (it->slice.width))
22779 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
22781 if (INTEGERP (it->slice.height))
22782 slice.height = XINT (it->slice.height);
22783 else if (FLOATP (it->slice.height))
22784 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
22786 if (slice.x >= img->width)
22787 slice.x = img->width;
22788 if (slice.y >= img->height)
22789 slice.y = img->height;
22790 if (slice.x + slice.width >= img->width)
22791 slice.width = img->width - slice.x;
22792 if (slice.y + slice.height > img->height)
22793 slice.height = img->height - slice.y;
22795 if (slice.width == 0 || slice.height == 0)
22796 return;
22798 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
22800 it->descent = slice.height - glyph_ascent;
22801 if (slice.y == 0)
22802 it->descent += img->vmargin;
22803 if (slice.y + slice.height == img->height)
22804 it->descent += img->vmargin;
22805 it->phys_descent = it->descent;
22807 it->pixel_width = slice.width;
22808 if (slice.x == 0)
22809 it->pixel_width += img->hmargin;
22810 if (slice.x + slice.width == img->width)
22811 it->pixel_width += img->hmargin;
22813 /* It's quite possible for images to have an ascent greater than
22814 their height, so don't get confused in that case. */
22815 if (it->descent < 0)
22816 it->descent = 0;
22818 it->nglyphs = 1;
22820 if (face->box != FACE_NO_BOX)
22822 if (face->box_line_width > 0)
22824 if (slice.y == 0)
22825 it->ascent += face->box_line_width;
22826 if (slice.y + slice.height == img->height)
22827 it->descent += face->box_line_width;
22830 if (it->start_of_box_run_p && slice.x == 0)
22831 it->pixel_width += eabs (face->box_line_width);
22832 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
22833 it->pixel_width += eabs (face->box_line_width);
22836 take_vertical_position_into_account (it);
22838 /* Automatically crop wide image glyphs at right edge so we can
22839 draw the cursor on same display row. */
22840 if ((crop = it->pixel_width - (it->last_visible_x - it->current_x), crop > 0)
22841 && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
22843 it->pixel_width -= crop;
22844 slice.width -= crop;
22847 if (it->glyph_row)
22849 struct glyph *glyph;
22850 enum glyph_row_area area = it->area;
22852 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
22853 if (glyph < it->glyph_row->glyphs[area + 1])
22855 glyph->charpos = CHARPOS (it->position);
22856 glyph->object = it->object;
22857 glyph->pixel_width = it->pixel_width;
22858 glyph->ascent = glyph_ascent;
22859 glyph->descent = it->descent;
22860 glyph->voffset = it->voffset;
22861 glyph->type = IMAGE_GLYPH;
22862 glyph->avoid_cursor_p = it->avoid_cursor_p;
22863 glyph->multibyte_p = it->multibyte_p;
22864 glyph->left_box_line_p = it->start_of_box_run_p;
22865 glyph->right_box_line_p = it->end_of_box_run_p;
22866 glyph->overlaps_vertically_p = 0;
22867 glyph->padding_p = 0;
22868 glyph->glyph_not_available_p = 0;
22869 glyph->face_id = it->face_id;
22870 glyph->u.img_id = img->id;
22871 glyph->slice.img = slice;
22872 glyph->font_type = FONT_TYPE_UNKNOWN;
22873 if (it->bidi_p)
22875 glyph->resolved_level = it->bidi_it.resolved_level;
22876 if ((it->bidi_it.type & 7) != it->bidi_it.type)
22877 abort ();
22878 glyph->bidi_type = it->bidi_it.type;
22880 ++it->glyph_row->used[area];
22882 else
22883 IT_EXPAND_MATRIX_WIDTH (it, area);
22888 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
22889 of the glyph, WIDTH and HEIGHT are the width and height of the
22890 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
22892 static void
22893 append_stretch_glyph (struct it *it, Lisp_Object object,
22894 int width, int height, int ascent)
22896 struct glyph *glyph;
22897 enum glyph_row_area area = it->area;
22899 xassert (ascent >= 0 && ascent <= height);
22901 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
22902 if (glyph < it->glyph_row->glyphs[area + 1])
22904 /* If the glyph row is reversed, we need to prepend the glyph
22905 rather than append it. */
22906 if (it->glyph_row->reversed_p && area == TEXT_AREA)
22908 struct glyph *g;
22910 /* Make room for the additional glyph. */
22911 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
22912 g[1] = *g;
22913 glyph = it->glyph_row->glyphs[area];
22915 glyph->charpos = CHARPOS (it->position);
22916 glyph->object = object;
22917 glyph->pixel_width = width;
22918 glyph->ascent = ascent;
22919 glyph->descent = height - ascent;
22920 glyph->voffset = it->voffset;
22921 glyph->type = STRETCH_GLYPH;
22922 glyph->avoid_cursor_p = it->avoid_cursor_p;
22923 glyph->multibyte_p = it->multibyte_p;
22924 glyph->left_box_line_p = it->start_of_box_run_p;
22925 glyph->right_box_line_p = it->end_of_box_run_p;
22926 glyph->overlaps_vertically_p = 0;
22927 glyph->padding_p = 0;
22928 glyph->glyph_not_available_p = 0;
22929 glyph->face_id = it->face_id;
22930 glyph->u.stretch.ascent = ascent;
22931 glyph->u.stretch.height = height;
22932 glyph->slice.img = null_glyph_slice;
22933 glyph->font_type = FONT_TYPE_UNKNOWN;
22934 if (it->bidi_p)
22936 glyph->resolved_level = it->bidi_it.resolved_level;
22937 if ((it->bidi_it.type & 7) != it->bidi_it.type)
22938 abort ();
22939 glyph->bidi_type = it->bidi_it.type;
22941 else
22943 glyph->resolved_level = 0;
22944 glyph->bidi_type = UNKNOWN_BT;
22946 ++it->glyph_row->used[area];
22948 else
22949 IT_EXPAND_MATRIX_WIDTH (it, area);
22953 /* Produce a stretch glyph for iterator IT. IT->object is the value
22954 of the glyph property displayed. The value must be a list
22955 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
22956 being recognized:
22958 1. `:width WIDTH' specifies that the space should be WIDTH *
22959 canonical char width wide. WIDTH may be an integer or floating
22960 point number.
22962 2. `:relative-width FACTOR' specifies that the width of the stretch
22963 should be computed from the width of the first character having the
22964 `glyph' property, and should be FACTOR times that width.
22966 3. `:align-to HPOS' specifies that the space should be wide enough
22967 to reach HPOS, a value in canonical character units.
22969 Exactly one of the above pairs must be present.
22971 4. `:height HEIGHT' specifies that the height of the stretch produced
22972 should be HEIGHT, measured in canonical character units.
22974 5. `:relative-height FACTOR' specifies that the height of the
22975 stretch should be FACTOR times the height of the characters having
22976 the glyph property.
22978 Either none or exactly one of 4 or 5 must be present.
22980 6. `:ascent ASCENT' specifies that ASCENT percent of the height
22981 of the stretch should be used for the ascent of the stretch.
22982 ASCENT must be in the range 0 <= ASCENT <= 100. */
22984 static void
22985 produce_stretch_glyph (struct it *it)
22987 /* (space :width WIDTH :height HEIGHT ...) */
22988 Lisp_Object prop, plist;
22989 int width = 0, height = 0, align_to = -1;
22990 int zero_width_ok_p = 0, zero_height_ok_p = 0;
22991 int ascent = 0;
22992 double tem;
22993 struct face *face = FACE_FROM_ID (it->f, it->face_id);
22994 struct font *font = face->font ? face->font : FRAME_FONT (it->f);
22996 PREPARE_FACE_FOR_DISPLAY (it->f, face);
22998 /* List should start with `space'. */
22999 xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
23000 plist = XCDR (it->object);
23002 /* Compute the width of the stretch. */
23003 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
23004 && calc_pixel_width_or_height (&tem, it, prop, font, 1, 0))
23006 /* Absolute width `:width WIDTH' specified and valid. */
23007 zero_width_ok_p = 1;
23008 width = (int)tem;
23010 else if (prop = Fplist_get (plist, QCrelative_width),
23011 NUMVAL (prop) > 0)
23013 /* Relative width `:relative-width FACTOR' specified and valid.
23014 Compute the width of the characters having the `glyph'
23015 property. */
23016 struct it it2;
23017 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
23019 it2 = *it;
23020 if (it->multibyte_p)
23021 it2.c = it2.char_to_display = STRING_CHAR_AND_LENGTH (p, it2.len);
23022 else
23024 it2.c = it2.char_to_display = *p, it2.len = 1;
23025 if (! ASCII_CHAR_P (it2.c))
23026 it2.char_to_display = BYTE8_TO_CHAR (it2.c);
23029 it2.glyph_row = NULL;
23030 it2.what = IT_CHARACTER;
23031 x_produce_glyphs (&it2);
23032 width = NUMVAL (prop) * it2.pixel_width;
23034 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
23035 && calc_pixel_width_or_height (&tem, it, prop, font, 1, &align_to))
23037 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
23038 align_to = (align_to < 0
23040 : align_to - window_box_left_offset (it->w, TEXT_AREA));
23041 else if (align_to < 0)
23042 align_to = window_box_left_offset (it->w, TEXT_AREA);
23043 width = max (0, (int)tem + align_to - it->current_x);
23044 zero_width_ok_p = 1;
23046 else
23047 /* Nothing specified -> width defaults to canonical char width. */
23048 width = FRAME_COLUMN_WIDTH (it->f);
23050 if (width <= 0 && (width < 0 || !zero_width_ok_p))
23051 width = 1;
23053 /* Compute height. */
23054 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
23055 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
23057 height = (int)tem;
23058 zero_height_ok_p = 1;
23060 else if (prop = Fplist_get (plist, QCrelative_height),
23061 NUMVAL (prop) > 0)
23062 height = FONT_HEIGHT (font) * NUMVAL (prop);
23063 else
23064 height = FONT_HEIGHT (font);
23066 if (height <= 0 && (height < 0 || !zero_height_ok_p))
23067 height = 1;
23069 /* Compute percentage of height used for ascent. If
23070 `:ascent ASCENT' is present and valid, use that. Otherwise,
23071 derive the ascent from the font in use. */
23072 if (prop = Fplist_get (plist, QCascent),
23073 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
23074 ascent = height * NUMVAL (prop) / 100.0;
23075 else if (!NILP (prop)
23076 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
23077 ascent = min (max (0, (int)tem), height);
23078 else
23079 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
23081 if (width > 0 && it->line_wrap != TRUNCATE
23082 && it->current_x + width > it->last_visible_x)
23083 width = it->last_visible_x - it->current_x - 1;
23085 if (width > 0 && height > 0 && it->glyph_row)
23087 Lisp_Object object = it->stack[it->sp - 1].string;
23088 if (!STRINGP (object))
23089 object = it->w->buffer;
23090 append_stretch_glyph (it, object, width, height, ascent);
23093 it->pixel_width = width;
23094 it->ascent = it->phys_ascent = ascent;
23095 it->descent = it->phys_descent = height - it->ascent;
23096 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
23098 take_vertical_position_into_account (it);
23101 /* Calculate line-height and line-spacing properties.
23102 An integer value specifies explicit pixel value.
23103 A float value specifies relative value to current face height.
23104 A cons (float . face-name) specifies relative value to
23105 height of specified face font.
23107 Returns height in pixels, or nil. */
23110 static Lisp_Object
23111 calc_line_height_property (struct it *it, Lisp_Object val, struct font *font,
23112 int boff, int override)
23114 Lisp_Object face_name = Qnil;
23115 int ascent, descent, height;
23117 if (NILP (val) || INTEGERP (val) || (override && EQ (val, Qt)))
23118 return val;
23120 if (CONSP (val))
23122 face_name = XCAR (val);
23123 val = XCDR (val);
23124 if (!NUMBERP (val))
23125 val = make_number (1);
23126 if (NILP (face_name))
23128 height = it->ascent + it->descent;
23129 goto scale;
23133 if (NILP (face_name))
23135 font = FRAME_FONT (it->f);
23136 boff = FRAME_BASELINE_OFFSET (it->f);
23138 else if (EQ (face_name, Qt))
23140 override = 0;
23142 else
23144 int face_id;
23145 struct face *face;
23147 face_id = lookup_named_face (it->f, face_name, 0);
23148 if (face_id < 0)
23149 return make_number (-1);
23151 face = FACE_FROM_ID (it->f, face_id);
23152 font = face->font;
23153 if (font == NULL)
23154 return make_number (-1);
23155 boff = font->baseline_offset;
23156 if (font->vertical_centering)
23157 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
23160 ascent = FONT_BASE (font) + boff;
23161 descent = FONT_DESCENT (font) - boff;
23163 if (override)
23165 it->override_ascent = ascent;
23166 it->override_descent = descent;
23167 it->override_boff = boff;
23170 height = ascent + descent;
23172 scale:
23173 if (FLOATP (val))
23174 height = (int)(XFLOAT_DATA (val) * height);
23175 else if (INTEGERP (val))
23176 height *= XINT (val);
23178 return make_number (height);
23182 /* Append a glyph for a glyphless character to IT->glyph_row. FACE_ID
23183 is a face ID to be used for the glyph. FOR_NO_FONT is nonzero if
23184 and only if this is for a character for which no font was found.
23186 If the display method (it->glyphless_method) is
23187 GLYPHLESS_DISPLAY_ACRONYM or GLYPHLESS_DISPLAY_HEX_CODE, LEN is a
23188 length of the acronym or the hexadecimal string, UPPER_XOFF and
23189 UPPER_YOFF are pixel offsets for the upper part of the string,
23190 LOWER_XOFF and LOWER_YOFF are for the lower part.
23192 For the other display methods, LEN through LOWER_YOFF are zero. */
23194 static void
23195 append_glyphless_glyph (struct it *it, int face_id, int for_no_font, int len,
23196 short upper_xoff, short upper_yoff,
23197 short lower_xoff, short lower_yoff)
23199 struct glyph *glyph;
23200 enum glyph_row_area area = it->area;
23202 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
23203 if (glyph < it->glyph_row->glyphs[area + 1])
23205 /* If the glyph row is reversed, we need to prepend the glyph
23206 rather than append it. */
23207 if (it->glyph_row->reversed_p && area == TEXT_AREA)
23209 struct glyph *g;
23211 /* Make room for the additional glyph. */
23212 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
23213 g[1] = *g;
23214 glyph = it->glyph_row->glyphs[area];
23216 glyph->charpos = CHARPOS (it->position);
23217 glyph->object = it->object;
23218 glyph->pixel_width = it->pixel_width;
23219 glyph->ascent = it->ascent;
23220 glyph->descent = it->descent;
23221 glyph->voffset = it->voffset;
23222 glyph->type = GLYPHLESS_GLYPH;
23223 glyph->u.glyphless.method = it->glyphless_method;
23224 glyph->u.glyphless.for_no_font = for_no_font;
23225 glyph->u.glyphless.len = len;
23226 glyph->u.glyphless.ch = it->c;
23227 glyph->slice.glyphless.upper_xoff = upper_xoff;
23228 glyph->slice.glyphless.upper_yoff = upper_yoff;
23229 glyph->slice.glyphless.lower_xoff = lower_xoff;
23230 glyph->slice.glyphless.lower_yoff = lower_yoff;
23231 glyph->avoid_cursor_p = it->avoid_cursor_p;
23232 glyph->multibyte_p = it->multibyte_p;
23233 glyph->left_box_line_p = it->start_of_box_run_p;
23234 glyph->right_box_line_p = it->end_of_box_run_p;
23235 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
23236 || it->phys_descent > it->descent);
23237 glyph->padding_p = 0;
23238 glyph->glyph_not_available_p = 0;
23239 glyph->face_id = face_id;
23240 glyph->font_type = FONT_TYPE_UNKNOWN;
23241 if (it->bidi_p)
23243 glyph->resolved_level = it->bidi_it.resolved_level;
23244 if ((it->bidi_it.type & 7) != it->bidi_it.type)
23245 abort ();
23246 glyph->bidi_type = it->bidi_it.type;
23248 ++it->glyph_row->used[area];
23250 else
23251 IT_EXPAND_MATRIX_WIDTH (it, area);
23255 /* Produce a glyph for a glyphless character for iterator IT.
23256 IT->glyphless_method specifies which method to use for displaying
23257 the character. See the description of enum
23258 glyphless_display_method in dispextern.h for the detail.
23260 FOR_NO_FONT is nonzero if and only if this is for a character for
23261 which no font was found. ACRONYM, if non-nil, is an acronym string
23262 for the character. */
23264 static void
23265 produce_glyphless_glyph (struct it *it, int for_no_font, Lisp_Object acronym)
23267 int face_id;
23268 struct face *face;
23269 struct font *font;
23270 int base_width, base_height, width, height;
23271 short upper_xoff, upper_yoff, lower_xoff, lower_yoff;
23272 int len;
23274 /* Get the metrics of the base font. We always refer to the current
23275 ASCII face. */
23276 face = FACE_FROM_ID (it->f, it->face_id)->ascii_face;
23277 font = face->font ? face->font : FRAME_FONT (it->f);
23278 it->ascent = FONT_BASE (font) + font->baseline_offset;
23279 it->descent = FONT_DESCENT (font) - font->baseline_offset;
23280 base_height = it->ascent + it->descent;
23281 base_width = font->average_width;
23283 /* Get a face ID for the glyph by utilizing a cache (the same way as
23284 done for `escape-glyph' in get_next_display_element). */
23285 if (it->f == last_glyphless_glyph_frame
23286 && it->face_id == last_glyphless_glyph_face_id)
23288 face_id = last_glyphless_glyph_merged_face_id;
23290 else
23292 /* Merge the `glyphless-char' face into the current face. */
23293 face_id = merge_faces (it->f, Qglyphless_char, 0, it->face_id);
23294 last_glyphless_glyph_frame = it->f;
23295 last_glyphless_glyph_face_id = it->face_id;
23296 last_glyphless_glyph_merged_face_id = face_id;
23299 if (it->glyphless_method == GLYPHLESS_DISPLAY_THIN_SPACE)
23301 it->pixel_width = THIN_SPACE_WIDTH;
23302 len = 0;
23303 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
23305 else if (it->glyphless_method == GLYPHLESS_DISPLAY_EMPTY_BOX)
23307 width = CHAR_WIDTH (it->c);
23308 if (width == 0)
23309 width = 1;
23310 else if (width > 4)
23311 width = 4;
23312 it->pixel_width = base_width * width;
23313 len = 0;
23314 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
23316 else
23318 char buf[7];
23319 const char *str;
23320 unsigned int code[6];
23321 int upper_len;
23322 int ascent, descent;
23323 struct font_metrics metrics_upper, metrics_lower;
23325 face = FACE_FROM_ID (it->f, face_id);
23326 font = face->font ? face->font : FRAME_FONT (it->f);
23327 PREPARE_FACE_FOR_DISPLAY (it->f, face);
23329 if (it->glyphless_method == GLYPHLESS_DISPLAY_ACRONYM)
23331 if (! STRINGP (acronym) && CHAR_TABLE_P (Vglyphless_char_display))
23332 acronym = CHAR_TABLE_REF (Vglyphless_char_display, it->c);
23333 if (CONSP (acronym))
23334 acronym = XCAR (acronym);
23335 str = STRINGP (acronym) ? SSDATA (acronym) : "";
23337 else
23339 xassert (it->glyphless_method == GLYPHLESS_DISPLAY_HEX_CODE);
23340 sprintf (buf, "%0*X", it->c < 0x10000 ? 4 : 6, it->c);
23341 str = buf;
23343 for (len = 0; str[len] && ASCII_BYTE_P (str[len]); len++)
23344 code[len] = font->driver->encode_char (font, str[len]);
23345 upper_len = (len + 1) / 2;
23346 font->driver->text_extents (font, code, upper_len,
23347 &metrics_upper);
23348 font->driver->text_extents (font, code + upper_len, len - upper_len,
23349 &metrics_lower);
23353 /* +4 is for vertical bars of a box plus 1-pixel spaces at both side. */
23354 width = max (metrics_upper.width, metrics_lower.width) + 4;
23355 upper_xoff = upper_yoff = 2; /* the typical case */
23356 if (base_width >= width)
23358 /* Align the upper to the left, the lower to the right. */
23359 it->pixel_width = base_width;
23360 lower_xoff = base_width - 2 - metrics_lower.width;
23362 else
23364 /* Center the shorter one. */
23365 it->pixel_width = width;
23366 if (metrics_upper.width >= metrics_lower.width)
23367 lower_xoff = (width - metrics_lower.width) / 2;
23368 else
23370 /* FIXME: This code doesn't look right. It formerly was
23371 missing the "lower_xoff = 0;", which couldn't have
23372 been right since it left lower_xoff uninitialized. */
23373 lower_xoff = 0;
23374 upper_xoff = (width - metrics_upper.width) / 2;
23378 /* +5 is for horizontal bars of a box plus 1-pixel spaces at
23379 top, bottom, and between upper and lower strings. */
23380 height = (metrics_upper.ascent + metrics_upper.descent
23381 + metrics_lower.ascent + metrics_lower.descent) + 5;
23382 /* Center vertically.
23383 H:base_height, D:base_descent
23384 h:height, ld:lower_descent, la:lower_ascent, ud:upper_descent
23386 ascent = - (D - H/2 - h/2 + 1); "+ 1" for rounding up
23387 descent = D - H/2 + h/2;
23388 lower_yoff = descent - 2 - ld;
23389 upper_yoff = lower_yoff - la - 1 - ud; */
23390 ascent = - (it->descent - (base_height + height + 1) / 2);
23391 descent = it->descent - (base_height - height) / 2;
23392 lower_yoff = descent - 2 - metrics_lower.descent;
23393 upper_yoff = (lower_yoff - metrics_lower.ascent - 1
23394 - metrics_upper.descent);
23395 /* Don't make the height shorter than the base height. */
23396 if (height > base_height)
23398 it->ascent = ascent;
23399 it->descent = descent;
23403 it->phys_ascent = it->ascent;
23404 it->phys_descent = it->descent;
23405 if (it->glyph_row)
23406 append_glyphless_glyph (it, face_id, for_no_font, len,
23407 upper_xoff, upper_yoff,
23408 lower_xoff, lower_yoff);
23409 it->nglyphs = 1;
23410 take_vertical_position_into_account (it);
23414 /* RIF:
23415 Produce glyphs/get display metrics for the display element IT is
23416 loaded with. See the description of struct it in dispextern.h
23417 for an overview of struct it. */
23419 void
23420 x_produce_glyphs (struct it *it)
23422 int extra_line_spacing = it->extra_line_spacing;
23424 it->glyph_not_available_p = 0;
23426 if (it->what == IT_CHARACTER)
23428 XChar2b char2b;
23429 struct face *face = FACE_FROM_ID (it->f, it->face_id);
23430 struct font *font = face->font;
23431 struct font_metrics *pcm = NULL;
23432 int boff; /* baseline offset */
23434 if (font == NULL)
23436 /* When no suitable font is found, display this character by
23437 the method specified in the first extra slot of
23438 Vglyphless_char_display. */
23439 Lisp_Object acronym = lookup_glyphless_char_display (-1, it);
23441 xassert (it->what == IT_GLYPHLESS);
23442 produce_glyphless_glyph (it, 1, STRINGP (acronym) ? acronym : Qnil);
23443 goto done;
23446 boff = font->baseline_offset;
23447 if (font->vertical_centering)
23448 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
23450 if (it->char_to_display != '\n' && it->char_to_display != '\t')
23452 int stretched_p;
23454 it->nglyphs = 1;
23456 if (it->override_ascent >= 0)
23458 it->ascent = it->override_ascent;
23459 it->descent = it->override_descent;
23460 boff = it->override_boff;
23462 else
23464 it->ascent = FONT_BASE (font) + boff;
23465 it->descent = FONT_DESCENT (font) - boff;
23468 if (get_char_glyph_code (it->char_to_display, font, &char2b))
23470 pcm = get_per_char_metric (font, &char2b);
23471 if (pcm->width == 0
23472 && pcm->rbearing == 0 && pcm->lbearing == 0)
23473 pcm = NULL;
23476 if (pcm)
23478 it->phys_ascent = pcm->ascent + boff;
23479 it->phys_descent = pcm->descent - boff;
23480 it->pixel_width = pcm->width;
23482 else
23484 it->glyph_not_available_p = 1;
23485 it->phys_ascent = it->ascent;
23486 it->phys_descent = it->descent;
23487 it->pixel_width = font->space_width;
23490 if (it->constrain_row_ascent_descent_p)
23492 if (it->descent > it->max_descent)
23494 it->ascent += it->descent - it->max_descent;
23495 it->descent = it->max_descent;
23497 if (it->ascent > it->max_ascent)
23499 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
23500 it->ascent = it->max_ascent;
23502 it->phys_ascent = min (it->phys_ascent, it->ascent);
23503 it->phys_descent = min (it->phys_descent, it->descent);
23504 extra_line_spacing = 0;
23507 /* If this is a space inside a region of text with
23508 `space-width' property, change its width. */
23509 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
23510 if (stretched_p)
23511 it->pixel_width *= XFLOATINT (it->space_width);
23513 /* If face has a box, add the box thickness to the character
23514 height. If character has a box line to the left and/or
23515 right, add the box line width to the character's width. */
23516 if (face->box != FACE_NO_BOX)
23518 int thick = face->box_line_width;
23520 if (thick > 0)
23522 it->ascent += thick;
23523 it->descent += thick;
23525 else
23526 thick = -thick;
23528 if (it->start_of_box_run_p)
23529 it->pixel_width += thick;
23530 if (it->end_of_box_run_p)
23531 it->pixel_width += thick;
23534 /* If face has an overline, add the height of the overline
23535 (1 pixel) and a 1 pixel margin to the character height. */
23536 if (face->overline_p)
23537 it->ascent += overline_margin;
23539 if (it->constrain_row_ascent_descent_p)
23541 if (it->ascent > it->max_ascent)
23542 it->ascent = it->max_ascent;
23543 if (it->descent > it->max_descent)
23544 it->descent = it->max_descent;
23547 take_vertical_position_into_account (it);
23549 /* If we have to actually produce glyphs, do it. */
23550 if (it->glyph_row)
23552 if (stretched_p)
23554 /* Translate a space with a `space-width' property
23555 into a stretch glyph. */
23556 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
23557 / FONT_HEIGHT (font));
23558 append_stretch_glyph (it, it->object, it->pixel_width,
23559 it->ascent + it->descent, ascent);
23561 else
23562 append_glyph (it);
23564 /* If characters with lbearing or rbearing are displayed
23565 in this line, record that fact in a flag of the
23566 glyph row. This is used to optimize X output code. */
23567 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
23568 it->glyph_row->contains_overlapping_glyphs_p = 1;
23570 if (! stretched_p && it->pixel_width == 0)
23571 /* We assure that all visible glyphs have at least 1-pixel
23572 width. */
23573 it->pixel_width = 1;
23575 else if (it->char_to_display == '\n')
23577 /* A newline has no width, but we need the height of the
23578 line. But if previous part of the line sets a height,
23579 don't increase that height */
23581 Lisp_Object height;
23582 Lisp_Object total_height = Qnil;
23584 it->override_ascent = -1;
23585 it->pixel_width = 0;
23586 it->nglyphs = 0;
23588 height = get_it_property (it, Qline_height);
23589 /* Split (line-height total-height) list */
23590 if (CONSP (height)
23591 && CONSP (XCDR (height))
23592 && NILP (XCDR (XCDR (height))))
23594 total_height = XCAR (XCDR (height));
23595 height = XCAR (height);
23597 height = calc_line_height_property (it, height, font, boff, 1);
23599 if (it->override_ascent >= 0)
23601 it->ascent = it->override_ascent;
23602 it->descent = it->override_descent;
23603 boff = it->override_boff;
23605 else
23607 it->ascent = FONT_BASE (font) + boff;
23608 it->descent = FONT_DESCENT (font) - boff;
23611 if (EQ (height, Qt))
23613 if (it->descent > it->max_descent)
23615 it->ascent += it->descent - it->max_descent;
23616 it->descent = it->max_descent;
23618 if (it->ascent > it->max_ascent)
23620 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
23621 it->ascent = it->max_ascent;
23623 it->phys_ascent = min (it->phys_ascent, it->ascent);
23624 it->phys_descent = min (it->phys_descent, it->descent);
23625 it->constrain_row_ascent_descent_p = 1;
23626 extra_line_spacing = 0;
23628 else
23630 Lisp_Object spacing;
23632 it->phys_ascent = it->ascent;
23633 it->phys_descent = it->descent;
23635 if ((it->max_ascent > 0 || it->max_descent > 0)
23636 && face->box != FACE_NO_BOX
23637 && face->box_line_width > 0)
23639 it->ascent += face->box_line_width;
23640 it->descent += face->box_line_width;
23642 if (!NILP (height)
23643 && XINT (height) > it->ascent + it->descent)
23644 it->ascent = XINT (height) - it->descent;
23646 if (!NILP (total_height))
23647 spacing = calc_line_height_property (it, total_height, font, boff, 0);
23648 else
23650 spacing = get_it_property (it, Qline_spacing);
23651 spacing = calc_line_height_property (it, spacing, font, boff, 0);
23653 if (INTEGERP (spacing))
23655 extra_line_spacing = XINT (spacing);
23656 if (!NILP (total_height))
23657 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
23661 else /* i.e. (it->char_to_display == '\t') */
23663 if (font->space_width > 0)
23665 int tab_width = it->tab_width * font->space_width;
23666 int x = it->current_x + it->continuation_lines_width;
23667 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
23669 /* If the distance from the current position to the next tab
23670 stop is less than a space character width, use the
23671 tab stop after that. */
23672 if (next_tab_x - x < font->space_width)
23673 next_tab_x += tab_width;
23675 it->pixel_width = next_tab_x - x;
23676 it->nglyphs = 1;
23677 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
23678 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
23680 if (it->glyph_row)
23682 append_stretch_glyph (it, it->object, it->pixel_width,
23683 it->ascent + it->descent, it->ascent);
23686 else
23688 it->pixel_width = 0;
23689 it->nglyphs = 1;
23693 else if (it->what == IT_COMPOSITION && it->cmp_it.ch < 0)
23695 /* A static composition.
23697 Note: A composition is represented as one glyph in the
23698 glyph matrix. There are no padding glyphs.
23700 Important note: pixel_width, ascent, and descent are the
23701 values of what is drawn by draw_glyphs (i.e. the values of
23702 the overall glyphs composed). */
23703 struct face *face = FACE_FROM_ID (it->f, it->face_id);
23704 int boff; /* baseline offset */
23705 struct composition *cmp = composition_table[it->cmp_it.id];
23706 int glyph_len = cmp->glyph_len;
23707 struct font *font = face->font;
23709 it->nglyphs = 1;
23711 /* If we have not yet calculated pixel size data of glyphs of
23712 the composition for the current face font, calculate them
23713 now. Theoretically, we have to check all fonts for the
23714 glyphs, but that requires much time and memory space. So,
23715 here we check only the font of the first glyph. This may
23716 lead to incorrect display, but it's very rare, and C-l
23717 (recenter-top-bottom) can correct the display anyway. */
23718 if (! cmp->font || cmp->font != font)
23720 /* Ascent and descent of the font of the first character
23721 of this composition (adjusted by baseline offset).
23722 Ascent and descent of overall glyphs should not be less
23723 than these, respectively. */
23724 int font_ascent, font_descent, font_height;
23725 /* Bounding box of the overall glyphs. */
23726 int leftmost, rightmost, lowest, highest;
23727 int lbearing, rbearing;
23728 int i, width, ascent, descent;
23729 int left_padded = 0, right_padded = 0;
23730 int c IF_LINT (= 0); /* cmp->glyph_len can't be zero; see Bug#8512 */
23731 XChar2b char2b;
23732 struct font_metrics *pcm;
23733 int font_not_found_p;
23734 EMACS_INT pos;
23736 for (glyph_len = cmp->glyph_len; glyph_len > 0; glyph_len--)
23737 if ((c = COMPOSITION_GLYPH (cmp, glyph_len - 1)) != '\t')
23738 break;
23739 if (glyph_len < cmp->glyph_len)
23740 right_padded = 1;
23741 for (i = 0; i < glyph_len; i++)
23743 if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
23744 break;
23745 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
23747 if (i > 0)
23748 left_padded = 1;
23750 pos = (STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
23751 : IT_CHARPOS (*it));
23752 /* If no suitable font is found, use the default font. */
23753 font_not_found_p = font == NULL;
23754 if (font_not_found_p)
23756 face = face->ascii_face;
23757 font = face->font;
23759 boff = font->baseline_offset;
23760 if (font->vertical_centering)
23761 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
23762 font_ascent = FONT_BASE (font) + boff;
23763 font_descent = FONT_DESCENT (font) - boff;
23764 font_height = FONT_HEIGHT (font);
23766 cmp->font = (void *) font;
23768 pcm = NULL;
23769 if (! font_not_found_p)
23771 get_char_face_and_encoding (it->f, c, it->face_id,
23772 &char2b, 0);
23773 pcm = get_per_char_metric (font, &char2b);
23776 /* Initialize the bounding box. */
23777 if (pcm)
23779 width = pcm->width;
23780 ascent = pcm->ascent;
23781 descent = pcm->descent;
23782 lbearing = pcm->lbearing;
23783 rbearing = pcm->rbearing;
23785 else
23787 width = font->space_width;
23788 ascent = FONT_BASE (font);
23789 descent = FONT_DESCENT (font);
23790 lbearing = 0;
23791 rbearing = width;
23794 rightmost = width;
23795 leftmost = 0;
23796 lowest = - descent + boff;
23797 highest = ascent + boff;
23799 if (! font_not_found_p
23800 && font->default_ascent
23801 && CHAR_TABLE_P (Vuse_default_ascent)
23802 && !NILP (Faref (Vuse_default_ascent,
23803 make_number (it->char_to_display))))
23804 highest = font->default_ascent + boff;
23806 /* Draw the first glyph at the normal position. It may be
23807 shifted to right later if some other glyphs are drawn
23808 at the left. */
23809 cmp->offsets[i * 2] = 0;
23810 cmp->offsets[i * 2 + 1] = boff;
23811 cmp->lbearing = lbearing;
23812 cmp->rbearing = rbearing;
23814 /* Set cmp->offsets for the remaining glyphs. */
23815 for (i++; i < glyph_len; i++)
23817 int left, right, btm, top;
23818 int ch = COMPOSITION_GLYPH (cmp, i);
23819 int face_id;
23820 struct face *this_face;
23822 if (ch == '\t')
23823 ch = ' ';
23824 face_id = FACE_FOR_CHAR (it->f, face, ch, pos, it->string);
23825 this_face = FACE_FROM_ID (it->f, face_id);
23826 font = this_face->font;
23828 if (font == NULL)
23829 pcm = NULL;
23830 else
23832 get_char_face_and_encoding (it->f, ch, face_id,
23833 &char2b, 0);
23834 pcm = get_per_char_metric (font, &char2b);
23836 if (! pcm)
23837 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
23838 else
23840 width = pcm->width;
23841 ascent = pcm->ascent;
23842 descent = pcm->descent;
23843 lbearing = pcm->lbearing;
23844 rbearing = pcm->rbearing;
23845 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
23847 /* Relative composition with or without
23848 alternate chars. */
23849 left = (leftmost + rightmost - width) / 2;
23850 btm = - descent + boff;
23851 if (font->relative_compose
23852 && (! CHAR_TABLE_P (Vignore_relative_composition)
23853 || NILP (Faref (Vignore_relative_composition,
23854 make_number (ch)))))
23857 if (- descent >= font->relative_compose)
23858 /* One extra pixel between two glyphs. */
23859 btm = highest + 1;
23860 else if (ascent <= 0)
23861 /* One extra pixel between two glyphs. */
23862 btm = lowest - 1 - ascent - descent;
23865 else
23867 /* A composition rule is specified by an integer
23868 value that encodes global and new reference
23869 points (GREF and NREF). GREF and NREF are
23870 specified by numbers as below:
23872 0---1---2 -- ascent
23876 9--10--11 -- center
23878 ---3---4---5--- baseline
23880 6---7---8 -- descent
23882 int rule = COMPOSITION_RULE (cmp, i);
23883 int gref, nref, grefx, grefy, nrefx, nrefy, xoff, yoff;
23885 COMPOSITION_DECODE_RULE (rule, gref, nref, xoff, yoff);
23886 grefx = gref % 3, nrefx = nref % 3;
23887 grefy = gref / 3, nrefy = nref / 3;
23888 if (xoff)
23889 xoff = font_height * (xoff - 128) / 256;
23890 if (yoff)
23891 yoff = font_height * (yoff - 128) / 256;
23893 left = (leftmost
23894 + grefx * (rightmost - leftmost) / 2
23895 - nrefx * width / 2
23896 + xoff);
23898 btm = ((grefy == 0 ? highest
23899 : grefy == 1 ? 0
23900 : grefy == 2 ? lowest
23901 : (highest + lowest) / 2)
23902 - (nrefy == 0 ? ascent + descent
23903 : nrefy == 1 ? descent - boff
23904 : nrefy == 2 ? 0
23905 : (ascent + descent) / 2)
23906 + yoff);
23909 cmp->offsets[i * 2] = left;
23910 cmp->offsets[i * 2 + 1] = btm + descent;
23912 /* Update the bounding box of the overall glyphs. */
23913 if (width > 0)
23915 right = left + width;
23916 if (left < leftmost)
23917 leftmost = left;
23918 if (right > rightmost)
23919 rightmost = right;
23921 top = btm + descent + ascent;
23922 if (top > highest)
23923 highest = top;
23924 if (btm < lowest)
23925 lowest = btm;
23927 if (cmp->lbearing > left + lbearing)
23928 cmp->lbearing = left + lbearing;
23929 if (cmp->rbearing < left + rbearing)
23930 cmp->rbearing = left + rbearing;
23934 /* If there are glyphs whose x-offsets are negative,
23935 shift all glyphs to the right and make all x-offsets
23936 non-negative. */
23937 if (leftmost < 0)
23939 for (i = 0; i < cmp->glyph_len; i++)
23940 cmp->offsets[i * 2] -= leftmost;
23941 rightmost -= leftmost;
23942 cmp->lbearing -= leftmost;
23943 cmp->rbearing -= leftmost;
23946 if (left_padded && cmp->lbearing < 0)
23948 for (i = 0; i < cmp->glyph_len; i++)
23949 cmp->offsets[i * 2] -= cmp->lbearing;
23950 rightmost -= cmp->lbearing;
23951 cmp->rbearing -= cmp->lbearing;
23952 cmp->lbearing = 0;
23954 if (right_padded && rightmost < cmp->rbearing)
23956 rightmost = cmp->rbearing;
23959 cmp->pixel_width = rightmost;
23960 cmp->ascent = highest;
23961 cmp->descent = - lowest;
23962 if (cmp->ascent < font_ascent)
23963 cmp->ascent = font_ascent;
23964 if (cmp->descent < font_descent)
23965 cmp->descent = font_descent;
23968 if (it->glyph_row
23969 && (cmp->lbearing < 0
23970 || cmp->rbearing > cmp->pixel_width))
23971 it->glyph_row->contains_overlapping_glyphs_p = 1;
23973 it->pixel_width = cmp->pixel_width;
23974 it->ascent = it->phys_ascent = cmp->ascent;
23975 it->descent = it->phys_descent = cmp->descent;
23976 if (face->box != FACE_NO_BOX)
23978 int thick = face->box_line_width;
23980 if (thick > 0)
23982 it->ascent += thick;
23983 it->descent += thick;
23985 else
23986 thick = - thick;
23988 if (it->start_of_box_run_p)
23989 it->pixel_width += thick;
23990 if (it->end_of_box_run_p)
23991 it->pixel_width += thick;
23994 /* If face has an overline, add the height of the overline
23995 (1 pixel) and a 1 pixel margin to the character height. */
23996 if (face->overline_p)
23997 it->ascent += overline_margin;
23999 take_vertical_position_into_account (it);
24000 if (it->ascent < 0)
24001 it->ascent = 0;
24002 if (it->descent < 0)
24003 it->descent = 0;
24005 if (it->glyph_row)
24006 append_composite_glyph (it);
24008 else if (it->what == IT_COMPOSITION)
24010 /* A dynamic (automatic) composition. */
24011 struct face *face = FACE_FROM_ID (it->f, it->face_id);
24012 Lisp_Object gstring;
24013 struct font_metrics metrics;
24015 gstring = composition_gstring_from_id (it->cmp_it.id);
24016 it->pixel_width
24017 = composition_gstring_width (gstring, it->cmp_it.from, it->cmp_it.to,
24018 &metrics);
24019 if (it->glyph_row
24020 && (metrics.lbearing < 0 || metrics.rbearing > metrics.width))
24021 it->glyph_row->contains_overlapping_glyphs_p = 1;
24022 it->ascent = it->phys_ascent = metrics.ascent;
24023 it->descent = it->phys_descent = metrics.descent;
24024 if (face->box != FACE_NO_BOX)
24026 int thick = face->box_line_width;
24028 if (thick > 0)
24030 it->ascent += thick;
24031 it->descent += thick;
24033 else
24034 thick = - thick;
24036 if (it->start_of_box_run_p)
24037 it->pixel_width += thick;
24038 if (it->end_of_box_run_p)
24039 it->pixel_width += thick;
24041 /* If face has an overline, add the height of the overline
24042 (1 pixel) and a 1 pixel margin to the character height. */
24043 if (face->overline_p)
24044 it->ascent += overline_margin;
24045 take_vertical_position_into_account (it);
24046 if (it->ascent < 0)
24047 it->ascent = 0;
24048 if (it->descent < 0)
24049 it->descent = 0;
24051 if (it->glyph_row)
24052 append_composite_glyph (it);
24054 else if (it->what == IT_GLYPHLESS)
24055 produce_glyphless_glyph (it, 0, Qnil);
24056 else if (it->what == IT_IMAGE)
24057 produce_image_glyph (it);
24058 else if (it->what == IT_STRETCH)
24059 produce_stretch_glyph (it);
24061 done:
24062 /* Accumulate dimensions. Note: can't assume that it->descent > 0
24063 because this isn't true for images with `:ascent 100'. */
24064 xassert (it->ascent >= 0 && it->descent >= 0);
24065 if (it->area == TEXT_AREA)
24066 it->current_x += it->pixel_width;
24068 if (extra_line_spacing > 0)
24070 it->descent += extra_line_spacing;
24071 if (extra_line_spacing > it->max_extra_line_spacing)
24072 it->max_extra_line_spacing = extra_line_spacing;
24075 it->max_ascent = max (it->max_ascent, it->ascent);
24076 it->max_descent = max (it->max_descent, it->descent);
24077 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
24078 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
24081 /* EXPORT for RIF:
24082 Output LEN glyphs starting at START at the nominal cursor position.
24083 Advance the nominal cursor over the text. The global variable
24084 updated_window contains the window being updated, updated_row is
24085 the glyph row being updated, and updated_area is the area of that
24086 row being updated. */
24088 void
24089 x_write_glyphs (struct glyph *start, int len)
24091 int x, hpos;
24093 xassert (updated_window && updated_row);
24094 BLOCK_INPUT;
24096 /* Write glyphs. */
24098 hpos = start - updated_row->glyphs[updated_area];
24099 x = draw_glyphs (updated_window, output_cursor.x,
24100 updated_row, updated_area,
24101 hpos, hpos + len,
24102 DRAW_NORMAL_TEXT, 0);
24104 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
24105 if (updated_area == TEXT_AREA
24106 && updated_window->phys_cursor_on_p
24107 && updated_window->phys_cursor.vpos == output_cursor.vpos
24108 && updated_window->phys_cursor.hpos >= hpos
24109 && updated_window->phys_cursor.hpos < hpos + len)
24110 updated_window->phys_cursor_on_p = 0;
24112 UNBLOCK_INPUT;
24114 /* Advance the output cursor. */
24115 output_cursor.hpos += len;
24116 output_cursor.x = x;
24120 /* EXPORT for RIF:
24121 Insert LEN glyphs from START at the nominal cursor position. */
24123 void
24124 x_insert_glyphs (struct glyph *start, int len)
24126 struct frame *f;
24127 struct window *w;
24128 int line_height, shift_by_width, shifted_region_width;
24129 struct glyph_row *row;
24130 struct glyph *glyph;
24131 int frame_x, frame_y;
24132 EMACS_INT hpos;
24134 xassert (updated_window && updated_row);
24135 BLOCK_INPUT;
24136 w = updated_window;
24137 f = XFRAME (WINDOW_FRAME (w));
24139 /* Get the height of the line we are in. */
24140 row = updated_row;
24141 line_height = row->height;
24143 /* Get the width of the glyphs to insert. */
24144 shift_by_width = 0;
24145 for (glyph = start; glyph < start + len; ++glyph)
24146 shift_by_width += glyph->pixel_width;
24148 /* Get the width of the region to shift right. */
24149 shifted_region_width = (window_box_width (w, updated_area)
24150 - output_cursor.x
24151 - shift_by_width);
24153 /* Shift right. */
24154 frame_x = window_box_left (w, updated_area) + output_cursor.x;
24155 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
24157 FRAME_RIF (f)->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
24158 line_height, shift_by_width);
24160 /* Write the glyphs. */
24161 hpos = start - row->glyphs[updated_area];
24162 draw_glyphs (w, output_cursor.x, row, updated_area,
24163 hpos, hpos + len,
24164 DRAW_NORMAL_TEXT, 0);
24166 /* Advance the output cursor. */
24167 output_cursor.hpos += len;
24168 output_cursor.x += shift_by_width;
24169 UNBLOCK_INPUT;
24173 /* EXPORT for RIF:
24174 Erase the current text line from the nominal cursor position
24175 (inclusive) to pixel column TO_X (exclusive). The idea is that
24176 everything from TO_X onward is already erased.
24178 TO_X is a pixel position relative to updated_area of
24179 updated_window. TO_X == -1 means clear to the end of this area. */
24181 void
24182 x_clear_end_of_line (int to_x)
24184 struct frame *f;
24185 struct window *w = updated_window;
24186 int max_x, min_y, max_y;
24187 int from_x, from_y, to_y;
24189 xassert (updated_window && updated_row);
24190 f = XFRAME (w->frame);
24192 if (updated_row->full_width_p)
24193 max_x = WINDOW_TOTAL_WIDTH (w);
24194 else
24195 max_x = window_box_width (w, updated_area);
24196 max_y = window_text_bottom_y (w);
24198 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
24199 of window. For TO_X > 0, truncate to end of drawing area. */
24200 if (to_x == 0)
24201 return;
24202 else if (to_x < 0)
24203 to_x = max_x;
24204 else
24205 to_x = min (to_x, max_x);
24207 to_y = min (max_y, output_cursor.y + updated_row->height);
24209 /* Notice if the cursor will be cleared by this operation. */
24210 if (!updated_row->full_width_p)
24211 notice_overwritten_cursor (w, updated_area,
24212 output_cursor.x, -1,
24213 updated_row->y,
24214 MATRIX_ROW_BOTTOM_Y (updated_row));
24216 from_x = output_cursor.x;
24218 /* Translate to frame coordinates. */
24219 if (updated_row->full_width_p)
24221 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
24222 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
24224 else
24226 int area_left = window_box_left (w, updated_area);
24227 from_x += area_left;
24228 to_x += area_left;
24231 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
24232 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
24233 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
24235 /* Prevent inadvertently clearing to end of the X window. */
24236 if (to_x > from_x && to_y > from_y)
24238 BLOCK_INPUT;
24239 FRAME_RIF (f)->clear_frame_area (f, from_x, from_y,
24240 to_x - from_x, to_y - from_y);
24241 UNBLOCK_INPUT;
24245 #endif /* HAVE_WINDOW_SYSTEM */
24249 /***********************************************************************
24250 Cursor types
24251 ***********************************************************************/
24253 /* Value is the internal representation of the specified cursor type
24254 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
24255 of the bar cursor. */
24257 static enum text_cursor_kinds
24258 get_specified_cursor_type (Lisp_Object arg, int *width)
24260 enum text_cursor_kinds type;
24262 if (NILP (arg))
24263 return NO_CURSOR;
24265 if (EQ (arg, Qbox))
24266 return FILLED_BOX_CURSOR;
24268 if (EQ (arg, Qhollow))
24269 return HOLLOW_BOX_CURSOR;
24271 if (EQ (arg, Qbar))
24273 *width = 2;
24274 return BAR_CURSOR;
24277 if (CONSP (arg)
24278 && EQ (XCAR (arg), Qbar)
24279 && INTEGERP (XCDR (arg))
24280 && XINT (XCDR (arg)) >= 0)
24282 *width = XINT (XCDR (arg));
24283 return BAR_CURSOR;
24286 if (EQ (arg, Qhbar))
24288 *width = 2;
24289 return HBAR_CURSOR;
24292 if (CONSP (arg)
24293 && EQ (XCAR (arg), Qhbar)
24294 && INTEGERP (XCDR (arg))
24295 && XINT (XCDR (arg)) >= 0)
24297 *width = XINT (XCDR (arg));
24298 return HBAR_CURSOR;
24301 /* Treat anything unknown as "hollow box cursor".
24302 It was bad to signal an error; people have trouble fixing
24303 .Xdefaults with Emacs, when it has something bad in it. */
24304 type = HOLLOW_BOX_CURSOR;
24306 return type;
24309 /* Set the default cursor types for specified frame. */
24310 void
24311 set_frame_cursor_types (struct frame *f, Lisp_Object arg)
24313 int width = 1;
24314 Lisp_Object tem;
24316 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
24317 FRAME_CURSOR_WIDTH (f) = width;
24319 /* By default, set up the blink-off state depending on the on-state. */
24321 tem = Fassoc (arg, Vblink_cursor_alist);
24322 if (!NILP (tem))
24324 FRAME_BLINK_OFF_CURSOR (f)
24325 = get_specified_cursor_type (XCDR (tem), &width);
24326 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
24328 else
24329 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
24333 #ifdef HAVE_WINDOW_SYSTEM
24335 /* Return the cursor we want to be displayed in window W. Return
24336 width of bar/hbar cursor through WIDTH arg. Return with
24337 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
24338 (i.e. if the `system caret' should track this cursor).
24340 In a mini-buffer window, we want the cursor only to appear if we
24341 are reading input from this window. For the selected window, we
24342 want the cursor type given by the frame parameter or buffer local
24343 setting of cursor-type. If explicitly marked off, draw no cursor.
24344 In all other cases, we want a hollow box cursor. */
24346 static enum text_cursor_kinds
24347 get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
24348 int *active_cursor)
24350 struct frame *f = XFRAME (w->frame);
24351 struct buffer *b = XBUFFER (w->buffer);
24352 int cursor_type = DEFAULT_CURSOR;
24353 Lisp_Object alt_cursor;
24354 int non_selected = 0;
24356 *active_cursor = 1;
24358 /* Echo area */
24359 if (cursor_in_echo_area
24360 && FRAME_HAS_MINIBUF_P (f)
24361 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
24363 if (w == XWINDOW (echo_area_window))
24365 if (EQ (BVAR (b, cursor_type), Qt) || NILP (BVAR (b, cursor_type)))
24367 *width = FRAME_CURSOR_WIDTH (f);
24368 return FRAME_DESIRED_CURSOR (f);
24370 else
24371 return get_specified_cursor_type (BVAR (b, cursor_type), width);
24374 *active_cursor = 0;
24375 non_selected = 1;
24378 /* Detect a nonselected window or nonselected frame. */
24379 else if (w != XWINDOW (f->selected_window)
24380 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame)
24382 *active_cursor = 0;
24384 if (MINI_WINDOW_P (w) && minibuf_level == 0)
24385 return NO_CURSOR;
24387 non_selected = 1;
24390 /* Never display a cursor in a window in which cursor-type is nil. */
24391 if (NILP (BVAR (b, cursor_type)))
24392 return NO_CURSOR;
24394 /* Get the normal cursor type for this window. */
24395 if (EQ (BVAR (b, cursor_type), Qt))
24397 cursor_type = FRAME_DESIRED_CURSOR (f);
24398 *width = FRAME_CURSOR_WIDTH (f);
24400 else
24401 cursor_type = get_specified_cursor_type (BVAR (b, cursor_type), width);
24403 /* Use cursor-in-non-selected-windows instead
24404 for non-selected window or frame. */
24405 if (non_selected)
24407 alt_cursor = BVAR (b, cursor_in_non_selected_windows);
24408 if (!EQ (Qt, alt_cursor))
24409 return get_specified_cursor_type (alt_cursor, width);
24410 /* t means modify the normal cursor type. */
24411 if (cursor_type == FILLED_BOX_CURSOR)
24412 cursor_type = HOLLOW_BOX_CURSOR;
24413 else if (cursor_type == BAR_CURSOR && *width > 1)
24414 --*width;
24415 return cursor_type;
24418 /* Use normal cursor if not blinked off. */
24419 if (!w->cursor_off_p)
24421 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
24423 if (cursor_type == FILLED_BOX_CURSOR)
24425 /* Using a block cursor on large images can be very annoying.
24426 So use a hollow cursor for "large" images.
24427 If image is not transparent (no mask), also use hollow cursor. */
24428 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
24429 if (img != NULL && IMAGEP (img->spec))
24431 /* Arbitrarily, interpret "Large" as >32x32 and >NxN
24432 where N = size of default frame font size.
24433 This should cover most of the "tiny" icons people may use. */
24434 if (!img->mask
24435 || img->width > max (32, WINDOW_FRAME_COLUMN_WIDTH (w))
24436 || img->height > max (32, WINDOW_FRAME_LINE_HEIGHT (w)))
24437 cursor_type = HOLLOW_BOX_CURSOR;
24440 else if (cursor_type != NO_CURSOR)
24442 /* Display current only supports BOX and HOLLOW cursors for images.
24443 So for now, unconditionally use a HOLLOW cursor when cursor is
24444 not a solid box cursor. */
24445 cursor_type = HOLLOW_BOX_CURSOR;
24448 return cursor_type;
24451 /* Cursor is blinked off, so determine how to "toggle" it. */
24453 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
24454 if ((alt_cursor = Fassoc (BVAR (b, cursor_type), Vblink_cursor_alist), !NILP (alt_cursor)))
24455 return get_specified_cursor_type (XCDR (alt_cursor), width);
24457 /* Then see if frame has specified a specific blink off cursor type. */
24458 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
24460 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
24461 return FRAME_BLINK_OFF_CURSOR (f);
24464 #if 0
24465 /* Some people liked having a permanently visible blinking cursor,
24466 while others had very strong opinions against it. So it was
24467 decided to remove it. KFS 2003-09-03 */
24469 /* Finally perform built-in cursor blinking:
24470 filled box <-> hollow box
24471 wide [h]bar <-> narrow [h]bar
24472 narrow [h]bar <-> no cursor
24473 other type <-> no cursor */
24475 if (cursor_type == FILLED_BOX_CURSOR)
24476 return HOLLOW_BOX_CURSOR;
24478 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
24480 *width = 1;
24481 return cursor_type;
24483 #endif
24485 return NO_CURSOR;
24489 /* Notice when the text cursor of window W has been completely
24490 overwritten by a drawing operation that outputs glyphs in AREA
24491 starting at X0 and ending at X1 in the line starting at Y0 and
24492 ending at Y1. X coordinates are area-relative. X1 < 0 means all
24493 the rest of the line after X0 has been written. Y coordinates
24494 are window-relative. */
24496 static void
24497 notice_overwritten_cursor (struct window *w, enum glyph_row_area area,
24498 int x0, int x1, int y0, int y1)
24500 int cx0, cx1, cy0, cy1;
24501 struct glyph_row *row;
24503 if (!w->phys_cursor_on_p)
24504 return;
24505 if (area != TEXT_AREA)
24506 return;
24508 if (w->phys_cursor.vpos < 0
24509 || w->phys_cursor.vpos >= w->current_matrix->nrows
24510 || (row = w->current_matrix->rows + w->phys_cursor.vpos,
24511 !(row->enabled_p && row->displays_text_p)))
24512 return;
24514 if (row->cursor_in_fringe_p)
24516 row->cursor_in_fringe_p = 0;
24517 draw_fringe_bitmap (w, row, row->reversed_p);
24518 w->phys_cursor_on_p = 0;
24519 return;
24522 cx0 = w->phys_cursor.x;
24523 cx1 = cx0 + w->phys_cursor_width;
24524 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
24525 return;
24527 /* The cursor image will be completely removed from the
24528 screen if the output area intersects the cursor area in
24529 y-direction. When we draw in [y0 y1[, and some part of
24530 the cursor is at y < y0, that part must have been drawn
24531 before. When scrolling, the cursor is erased before
24532 actually scrolling, so we don't come here. When not
24533 scrolling, the rows above the old cursor row must have
24534 changed, and in this case these rows must have written
24535 over the cursor image.
24537 Likewise if part of the cursor is below y1, with the
24538 exception of the cursor being in the first blank row at
24539 the buffer and window end because update_text_area
24540 doesn't draw that row. (Except when it does, but
24541 that's handled in update_text_area.) */
24543 cy0 = w->phys_cursor.y;
24544 cy1 = cy0 + w->phys_cursor_height;
24545 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
24546 return;
24548 w->phys_cursor_on_p = 0;
24551 #endif /* HAVE_WINDOW_SYSTEM */
24554 /************************************************************************
24555 Mouse Face
24556 ************************************************************************/
24558 #ifdef HAVE_WINDOW_SYSTEM
24560 /* EXPORT for RIF:
24561 Fix the display of area AREA of overlapping row ROW in window W
24562 with respect to the overlapping part OVERLAPS. */
24564 void
24565 x_fix_overlapping_area (struct window *w, struct glyph_row *row,
24566 enum glyph_row_area area, int overlaps)
24568 int i, x;
24570 BLOCK_INPUT;
24572 x = 0;
24573 for (i = 0; i < row->used[area];)
24575 if (row->glyphs[area][i].overlaps_vertically_p)
24577 int start = i, start_x = x;
24581 x += row->glyphs[area][i].pixel_width;
24582 ++i;
24584 while (i < row->used[area]
24585 && row->glyphs[area][i].overlaps_vertically_p);
24587 draw_glyphs (w, start_x, row, area,
24588 start, i,
24589 DRAW_NORMAL_TEXT, overlaps);
24591 else
24593 x += row->glyphs[area][i].pixel_width;
24594 ++i;
24598 UNBLOCK_INPUT;
24602 /* EXPORT:
24603 Draw the cursor glyph of window W in glyph row ROW. See the
24604 comment of draw_glyphs for the meaning of HL. */
24606 void
24607 draw_phys_cursor_glyph (struct window *w, struct glyph_row *row,
24608 enum draw_glyphs_face hl)
24610 /* If cursor hpos is out of bounds, don't draw garbage. This can
24611 happen in mini-buffer windows when switching between echo area
24612 glyphs and mini-buffer. */
24613 if ((row->reversed_p
24614 ? (w->phys_cursor.hpos >= 0)
24615 : (w->phys_cursor.hpos < row->used[TEXT_AREA])))
24617 int on_p = w->phys_cursor_on_p;
24618 int x1;
24619 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
24620 w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
24621 hl, 0);
24622 w->phys_cursor_on_p = on_p;
24624 if (hl == DRAW_CURSOR)
24625 w->phys_cursor_width = x1 - w->phys_cursor.x;
24626 /* When we erase the cursor, and ROW is overlapped by other
24627 rows, make sure that these overlapping parts of other rows
24628 are redrawn. */
24629 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
24631 w->phys_cursor_width = x1 - w->phys_cursor.x;
24633 if (row > w->current_matrix->rows
24634 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
24635 x_fix_overlapping_area (w, row - 1, TEXT_AREA,
24636 OVERLAPS_ERASED_CURSOR);
24638 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
24639 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
24640 x_fix_overlapping_area (w, row + 1, TEXT_AREA,
24641 OVERLAPS_ERASED_CURSOR);
24647 /* EXPORT:
24648 Erase the image of a cursor of window W from the screen. */
24650 void
24651 erase_phys_cursor (struct window *w)
24653 struct frame *f = XFRAME (w->frame);
24654 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
24655 int hpos = w->phys_cursor.hpos;
24656 int vpos = w->phys_cursor.vpos;
24657 int mouse_face_here_p = 0;
24658 struct glyph_matrix *active_glyphs = w->current_matrix;
24659 struct glyph_row *cursor_row;
24660 struct glyph *cursor_glyph;
24661 enum draw_glyphs_face hl;
24663 /* No cursor displayed or row invalidated => nothing to do on the
24664 screen. */
24665 if (w->phys_cursor_type == NO_CURSOR)
24666 goto mark_cursor_off;
24668 /* VPOS >= active_glyphs->nrows means that window has been resized.
24669 Don't bother to erase the cursor. */
24670 if (vpos >= active_glyphs->nrows)
24671 goto mark_cursor_off;
24673 /* If row containing cursor is marked invalid, there is nothing we
24674 can do. */
24675 cursor_row = MATRIX_ROW (active_glyphs, vpos);
24676 if (!cursor_row->enabled_p)
24677 goto mark_cursor_off;
24679 /* If line spacing is > 0, old cursor may only be partially visible in
24680 window after split-window. So adjust visible height. */
24681 cursor_row->visible_height = min (cursor_row->visible_height,
24682 window_text_bottom_y (w) - cursor_row->y);
24684 /* If row is completely invisible, don't attempt to delete a cursor which
24685 isn't there. This can happen if cursor is at top of a window, and
24686 we switch to a buffer with a header line in that window. */
24687 if (cursor_row->visible_height <= 0)
24688 goto mark_cursor_off;
24690 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
24691 if (cursor_row->cursor_in_fringe_p)
24693 cursor_row->cursor_in_fringe_p = 0;
24694 draw_fringe_bitmap (w, cursor_row, cursor_row->reversed_p);
24695 goto mark_cursor_off;
24698 /* This can happen when the new row is shorter than the old one.
24699 In this case, either draw_glyphs or clear_end_of_line
24700 should have cleared the cursor. Note that we wouldn't be
24701 able to erase the cursor in this case because we don't have a
24702 cursor glyph at hand. */
24703 if ((cursor_row->reversed_p
24704 ? (w->phys_cursor.hpos < 0)
24705 : (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])))
24706 goto mark_cursor_off;
24708 /* If the cursor is in the mouse face area, redisplay that when
24709 we clear the cursor. */
24710 if (! NILP (hlinfo->mouse_face_window)
24711 && coords_in_mouse_face_p (w, hpos, vpos)
24712 /* Don't redraw the cursor's spot in mouse face if it is at the
24713 end of a line (on a newline). The cursor appears there, but
24714 mouse highlighting does not. */
24715 && cursor_row->used[TEXT_AREA] > hpos && hpos >= 0)
24716 mouse_face_here_p = 1;
24718 /* Maybe clear the display under the cursor. */
24719 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
24721 int x, y, left_x;
24722 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
24723 int width;
24725 cursor_glyph = get_phys_cursor_glyph (w);
24726 if (cursor_glyph == NULL)
24727 goto mark_cursor_off;
24729 width = cursor_glyph->pixel_width;
24730 left_x = window_box_left_offset (w, TEXT_AREA);
24731 x = w->phys_cursor.x;
24732 if (x < left_x)
24733 width -= left_x - x;
24734 width = min (width, window_box_width (w, TEXT_AREA) - x);
24735 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
24736 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, max (x, left_x));
24738 if (width > 0)
24739 FRAME_RIF (f)->clear_frame_area (f, x, y, width, cursor_row->visible_height);
24742 /* Erase the cursor by redrawing the character underneath it. */
24743 if (mouse_face_here_p)
24744 hl = DRAW_MOUSE_FACE;
24745 else
24746 hl = DRAW_NORMAL_TEXT;
24747 draw_phys_cursor_glyph (w, cursor_row, hl);
24749 mark_cursor_off:
24750 w->phys_cursor_on_p = 0;
24751 w->phys_cursor_type = NO_CURSOR;
24755 /* EXPORT:
24756 Display or clear cursor of window W. If ON is zero, clear the
24757 cursor. If it is non-zero, display the cursor. If ON is nonzero,
24758 where to put the cursor is specified by HPOS, VPOS, X and Y. */
24760 void
24761 display_and_set_cursor (struct window *w, int on,
24762 int hpos, int vpos, int x, int y)
24764 struct frame *f = XFRAME (w->frame);
24765 int new_cursor_type;
24766 int new_cursor_width;
24767 int active_cursor;
24768 struct glyph_row *glyph_row;
24769 struct glyph *glyph;
24771 /* This is pointless on invisible frames, and dangerous on garbaged
24772 windows and frames; in the latter case, the frame or window may
24773 be in the midst of changing its size, and x and y may be off the
24774 window. */
24775 if (! FRAME_VISIBLE_P (f)
24776 || FRAME_GARBAGED_P (f)
24777 || vpos >= w->current_matrix->nrows
24778 || hpos >= w->current_matrix->matrix_w)
24779 return;
24781 /* If cursor is off and we want it off, return quickly. */
24782 if (!on && !w->phys_cursor_on_p)
24783 return;
24785 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
24786 /* If cursor row is not enabled, we don't really know where to
24787 display the cursor. */
24788 if (!glyph_row->enabled_p)
24790 w->phys_cursor_on_p = 0;
24791 return;
24794 glyph = NULL;
24795 if (!glyph_row->exact_window_width_line_p
24796 || (0 <= hpos && hpos < glyph_row->used[TEXT_AREA]))
24797 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
24799 xassert (interrupt_input_blocked);
24801 /* Set new_cursor_type to the cursor we want to be displayed. */
24802 new_cursor_type = get_window_cursor_type (w, glyph,
24803 &new_cursor_width, &active_cursor);
24805 /* If cursor is currently being shown and we don't want it to be or
24806 it is in the wrong place, or the cursor type is not what we want,
24807 erase it. */
24808 if (w->phys_cursor_on_p
24809 && (!on
24810 || w->phys_cursor.x != x
24811 || w->phys_cursor.y != y
24812 || new_cursor_type != w->phys_cursor_type
24813 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
24814 && new_cursor_width != w->phys_cursor_width)))
24815 erase_phys_cursor (w);
24817 /* Don't check phys_cursor_on_p here because that flag is only set
24818 to zero in some cases where we know that the cursor has been
24819 completely erased, to avoid the extra work of erasing the cursor
24820 twice. In other words, phys_cursor_on_p can be 1 and the cursor
24821 still not be visible, or it has only been partly erased. */
24822 if (on)
24824 w->phys_cursor_ascent = glyph_row->ascent;
24825 w->phys_cursor_height = glyph_row->height;
24827 /* Set phys_cursor_.* before x_draw_.* is called because some
24828 of them may need the information. */
24829 w->phys_cursor.x = x;
24830 w->phys_cursor.y = glyph_row->y;
24831 w->phys_cursor.hpos = hpos;
24832 w->phys_cursor.vpos = vpos;
24835 FRAME_RIF (f)->draw_window_cursor (w, glyph_row, x, y,
24836 new_cursor_type, new_cursor_width,
24837 on, active_cursor);
24841 /* Switch the display of W's cursor on or off, according to the value
24842 of ON. */
24844 static void
24845 update_window_cursor (struct window *w, int on)
24847 /* Don't update cursor in windows whose frame is in the process
24848 of being deleted. */
24849 if (w->current_matrix)
24851 BLOCK_INPUT;
24852 display_and_set_cursor (w, on, w->phys_cursor.hpos, w->phys_cursor.vpos,
24853 w->phys_cursor.x, w->phys_cursor.y);
24854 UNBLOCK_INPUT;
24859 /* Call update_window_cursor with parameter ON_P on all leaf windows
24860 in the window tree rooted at W. */
24862 static void
24863 update_cursor_in_window_tree (struct window *w, int on_p)
24865 while (w)
24867 if (!NILP (w->hchild))
24868 update_cursor_in_window_tree (XWINDOW (w->hchild), on_p);
24869 else if (!NILP (w->vchild))
24870 update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
24871 else
24872 update_window_cursor (w, on_p);
24874 w = NILP (w->next) ? 0 : XWINDOW (w->next);
24879 /* EXPORT:
24880 Display the cursor on window W, or clear it, according to ON_P.
24881 Don't change the cursor's position. */
24883 void
24884 x_update_cursor (struct frame *f, int on_p)
24886 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
24890 /* EXPORT:
24891 Clear the cursor of window W to background color, and mark the
24892 cursor as not shown. This is used when the text where the cursor
24893 is about to be rewritten. */
24895 void
24896 x_clear_cursor (struct window *w)
24898 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
24899 update_window_cursor (w, 0);
24902 #endif /* HAVE_WINDOW_SYSTEM */
24904 /* Implementation of draw_row_with_mouse_face for GUI sessions, GPM,
24905 and MSDOS. */
24906 static void
24907 draw_row_with_mouse_face (struct window *w, int start_x, struct glyph_row *row,
24908 int start_hpos, int end_hpos,
24909 enum draw_glyphs_face draw)
24911 #ifdef HAVE_WINDOW_SYSTEM
24912 if (FRAME_WINDOW_P (XFRAME (w->frame)))
24914 draw_glyphs (w, start_x, row, TEXT_AREA, start_hpos, end_hpos, draw, 0);
24915 return;
24917 #endif
24918 #if defined (HAVE_GPM) || defined (MSDOS)
24919 tty_draw_row_with_mouse_face (w, row, start_hpos, end_hpos, draw);
24920 #endif
24923 /* Display the active region described by mouse_face_* according to DRAW. */
24925 static void
24926 show_mouse_face (Mouse_HLInfo *hlinfo, enum draw_glyphs_face draw)
24928 struct window *w = XWINDOW (hlinfo->mouse_face_window);
24929 struct frame *f = XFRAME (WINDOW_FRAME (w));
24931 if (/* If window is in the process of being destroyed, don't bother
24932 to do anything. */
24933 w->current_matrix != NULL
24934 /* Don't update mouse highlight if hidden */
24935 && (draw != DRAW_MOUSE_FACE || !hlinfo->mouse_face_hidden)
24936 /* Recognize when we are called to operate on rows that don't exist
24937 anymore. This can happen when a window is split. */
24938 && hlinfo->mouse_face_end_row < w->current_matrix->nrows)
24940 int phys_cursor_on_p = w->phys_cursor_on_p;
24941 struct glyph_row *row, *first, *last;
24943 first = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_beg_row);
24944 last = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_end_row);
24946 for (row = first; row <= last && row->enabled_p; ++row)
24948 int start_hpos, end_hpos, start_x;
24950 /* For all but the first row, the highlight starts at column 0. */
24951 if (row == first)
24953 /* R2L rows have BEG and END in reversed order, but the
24954 screen drawing geometry is always left to right. So
24955 we need to mirror the beginning and end of the
24956 highlighted area in R2L rows. */
24957 if (!row->reversed_p)
24959 start_hpos = hlinfo->mouse_face_beg_col;
24960 start_x = hlinfo->mouse_face_beg_x;
24962 else if (row == last)
24964 start_hpos = hlinfo->mouse_face_end_col;
24965 start_x = hlinfo->mouse_face_end_x;
24967 else
24969 start_hpos = 0;
24970 start_x = 0;
24973 else if (row->reversed_p && row == last)
24975 start_hpos = hlinfo->mouse_face_end_col;
24976 start_x = hlinfo->mouse_face_end_x;
24978 else
24980 start_hpos = 0;
24981 start_x = 0;
24984 if (row == last)
24986 if (!row->reversed_p)
24987 end_hpos = hlinfo->mouse_face_end_col;
24988 else if (row == first)
24989 end_hpos = hlinfo->mouse_face_beg_col;
24990 else
24992 end_hpos = row->used[TEXT_AREA];
24993 if (draw == DRAW_NORMAL_TEXT)
24994 row->fill_line_p = 1; /* Clear to end of line */
24997 else if (row->reversed_p && row == first)
24998 end_hpos = hlinfo->mouse_face_beg_col;
24999 else
25001 end_hpos = row->used[TEXT_AREA];
25002 if (draw == DRAW_NORMAL_TEXT)
25003 row->fill_line_p = 1; /* Clear to end of line */
25006 if (end_hpos > start_hpos)
25008 draw_row_with_mouse_face (w, start_x, row,
25009 start_hpos, end_hpos, draw);
25011 row->mouse_face_p
25012 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
25016 #ifdef HAVE_WINDOW_SYSTEM
25017 /* When we've written over the cursor, arrange for it to
25018 be displayed again. */
25019 if (FRAME_WINDOW_P (f)
25020 && phys_cursor_on_p && !w->phys_cursor_on_p)
25022 BLOCK_INPUT;
25023 display_and_set_cursor (w, 1,
25024 w->phys_cursor.hpos, w->phys_cursor.vpos,
25025 w->phys_cursor.x, w->phys_cursor.y);
25026 UNBLOCK_INPUT;
25028 #endif /* HAVE_WINDOW_SYSTEM */
25031 #ifdef HAVE_WINDOW_SYSTEM
25032 /* Change the mouse cursor. */
25033 if (FRAME_WINDOW_P (f))
25035 if (draw == DRAW_NORMAL_TEXT
25036 && !EQ (hlinfo->mouse_face_window, f->tool_bar_window))
25037 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
25038 else if (draw == DRAW_MOUSE_FACE)
25039 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
25040 else
25041 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
25043 #endif /* HAVE_WINDOW_SYSTEM */
25046 /* EXPORT:
25047 Clear out the mouse-highlighted active region.
25048 Redraw it un-highlighted first. Value is non-zero if mouse
25049 face was actually drawn unhighlighted. */
25052 clear_mouse_face (Mouse_HLInfo *hlinfo)
25054 int cleared = 0;
25056 if (!hlinfo->mouse_face_hidden && !NILP (hlinfo->mouse_face_window))
25058 show_mouse_face (hlinfo, DRAW_NORMAL_TEXT);
25059 cleared = 1;
25062 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
25063 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
25064 hlinfo->mouse_face_window = Qnil;
25065 hlinfo->mouse_face_overlay = Qnil;
25066 return cleared;
25069 /* Return non-zero if the coordinates HPOS and VPOS on windows W are
25070 within the mouse face on that window. */
25071 static int
25072 coords_in_mouse_face_p (struct window *w, int hpos, int vpos)
25074 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
25076 /* Quickly resolve the easy cases. */
25077 if (!(WINDOWP (hlinfo->mouse_face_window)
25078 && XWINDOW (hlinfo->mouse_face_window) == w))
25079 return 0;
25080 if (vpos < hlinfo->mouse_face_beg_row
25081 || vpos > hlinfo->mouse_face_end_row)
25082 return 0;
25083 if (vpos > hlinfo->mouse_face_beg_row
25084 && vpos < hlinfo->mouse_face_end_row)
25085 return 1;
25087 if (!MATRIX_ROW (w->current_matrix, vpos)->reversed_p)
25089 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
25091 if (hlinfo->mouse_face_beg_col <= hpos && hpos < hlinfo->mouse_face_end_col)
25092 return 1;
25094 else if ((vpos == hlinfo->mouse_face_beg_row
25095 && hpos >= hlinfo->mouse_face_beg_col)
25096 || (vpos == hlinfo->mouse_face_end_row
25097 && hpos < hlinfo->mouse_face_end_col))
25098 return 1;
25100 else
25102 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
25104 if (hlinfo->mouse_face_end_col < hpos && hpos <= hlinfo->mouse_face_beg_col)
25105 return 1;
25107 else if ((vpos == hlinfo->mouse_face_beg_row
25108 && hpos <= hlinfo->mouse_face_beg_col)
25109 || (vpos == hlinfo->mouse_face_end_row
25110 && hpos > hlinfo->mouse_face_end_col))
25111 return 1;
25113 return 0;
25117 /* EXPORT:
25118 Non-zero if physical cursor of window W is within mouse face. */
25121 cursor_in_mouse_face_p (struct window *w)
25123 return coords_in_mouse_face_p (w, w->phys_cursor.hpos, w->phys_cursor.vpos);
25128 /* Find the glyph rows START_ROW and END_ROW of window W that display
25129 characters between buffer positions START_CHARPOS and END_CHARPOS
25130 (excluding END_CHARPOS). This is similar to row_containing_pos,
25131 but is more accurate when bidi reordering makes buffer positions
25132 change non-linearly with glyph rows. */
25133 static void
25134 rows_from_pos_range (struct window *w,
25135 EMACS_INT start_charpos, EMACS_INT end_charpos,
25136 struct glyph_row **start, struct glyph_row **end)
25138 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
25139 int last_y = window_text_bottom_y (w);
25140 struct glyph_row *row;
25142 *start = NULL;
25143 *end = NULL;
25145 while (!first->enabled_p
25146 && first < MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w))
25147 first++;
25149 /* Find the START row. */
25150 for (row = first;
25151 row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y;
25152 row++)
25154 /* A row can potentially be the START row if the range of the
25155 characters it displays intersects the range
25156 [START_CHARPOS..END_CHARPOS). */
25157 if (! ((start_charpos < MATRIX_ROW_START_CHARPOS (row)
25158 && end_charpos < MATRIX_ROW_START_CHARPOS (row))
25159 /* See the commentary in row_containing_pos, for the
25160 explanation of the complicated way to check whether
25161 some position is beyond the end of the characters
25162 displayed by a row. */
25163 || ((start_charpos > MATRIX_ROW_END_CHARPOS (row)
25164 || (start_charpos == MATRIX_ROW_END_CHARPOS (row)
25165 && !row->ends_at_zv_p
25166 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
25167 && (end_charpos > MATRIX_ROW_END_CHARPOS (row)
25168 || (end_charpos == MATRIX_ROW_END_CHARPOS (row)
25169 && !row->ends_at_zv_p
25170 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))))))
25172 /* Found a candidate row. Now make sure at least one of the
25173 glyphs it displays has a charpos from the range
25174 [START_CHARPOS..END_CHARPOS).
25176 This is not obvious because bidi reordering could make
25177 buffer positions of a row be 1,2,3,102,101,100, and if we
25178 want to highlight characters in [50..60), we don't want
25179 this row, even though [50..60) does intersect [1..103),
25180 the range of character positions given by the row's start
25181 and end positions. */
25182 struct glyph *g = row->glyphs[TEXT_AREA];
25183 struct glyph *e = g + row->used[TEXT_AREA];
25185 while (g < e)
25187 if ((BUFFERP (g->object) || INTEGERP (g->object))
25188 && start_charpos <= g->charpos && g->charpos < end_charpos)
25189 *start = row;
25190 g++;
25192 if (*start)
25193 break;
25197 /* Find the END row. */
25198 if (!*start
25199 /* If the last row is partially visible, start looking for END
25200 from that row, instead of starting from FIRST. */
25201 && !(row->enabled_p
25202 && row->y < last_y && MATRIX_ROW_BOTTOM_Y (row) > last_y))
25203 row = first;
25204 for ( ; row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y; row++)
25206 struct glyph_row *next = row + 1;
25208 if (!next->enabled_p
25209 || next >= MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w)
25210 /* The first row >= START whose range of displayed characters
25211 does NOT intersect the range [START_CHARPOS..END_CHARPOS]
25212 is the row END + 1. */
25213 || (start_charpos < MATRIX_ROW_START_CHARPOS (next)
25214 && end_charpos < MATRIX_ROW_START_CHARPOS (next))
25215 || ((start_charpos > MATRIX_ROW_END_CHARPOS (next)
25216 || (start_charpos == MATRIX_ROW_END_CHARPOS (next)
25217 && !next->ends_at_zv_p
25218 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))
25219 && (end_charpos > MATRIX_ROW_END_CHARPOS (next)
25220 || (end_charpos == MATRIX_ROW_END_CHARPOS (next)
25221 && !next->ends_at_zv_p
25222 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))))
25224 *end = row;
25225 break;
25227 else
25229 /* If the next row's edges intersect [START_CHARPOS..END_CHARPOS],
25230 but none of the characters it displays are in the range, it is
25231 also END + 1. */
25232 struct glyph *g = next->glyphs[TEXT_AREA];
25233 struct glyph *e = g + next->used[TEXT_AREA];
25235 while (g < e)
25237 if ((BUFFERP (g->object) || INTEGERP (g->object))
25238 && start_charpos <= g->charpos && g->charpos < end_charpos)
25239 break;
25240 g++;
25242 if (g == e)
25244 *end = row;
25245 break;
25251 /* This function sets the mouse_face_* elements of HLINFO, assuming
25252 the mouse cursor is on a glyph with buffer charpos MOUSE_CHARPOS in
25253 window WINDOW. START_CHARPOS and END_CHARPOS are buffer positions
25254 for the overlay or run of text properties specifying the mouse
25255 face. BEFORE_STRING and AFTER_STRING, if non-nil, are a
25256 before-string and after-string that must also be highlighted.
25257 COVER_STRING, if non-nil, is a display string that may cover some
25258 or all of the highlighted text. */
25260 static void
25261 mouse_face_from_buffer_pos (Lisp_Object window,
25262 Mouse_HLInfo *hlinfo,
25263 EMACS_INT mouse_charpos,
25264 EMACS_INT start_charpos,
25265 EMACS_INT end_charpos,
25266 Lisp_Object before_string,
25267 Lisp_Object after_string,
25268 Lisp_Object cover_string)
25270 struct window *w = XWINDOW (window);
25271 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
25272 struct glyph_row *r1, *r2;
25273 struct glyph *glyph, *end;
25274 EMACS_INT ignore, pos;
25275 int x;
25277 xassert (NILP (cover_string) || STRINGP (cover_string));
25278 xassert (NILP (before_string) || STRINGP (before_string));
25279 xassert (NILP (after_string) || STRINGP (after_string));
25281 /* Find the rows corresponding to START_CHARPOS and END_CHARPOS. */
25282 rows_from_pos_range (w, start_charpos, end_charpos, &r1, &r2);
25283 if (r1 == NULL)
25284 r1 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
25285 /* If the before-string or display-string contains newlines,
25286 rows_from_pos_range skips to its last row. Move back. */
25287 if (!NILP (before_string) || !NILP (cover_string))
25289 struct glyph_row *prev;
25290 while ((prev = r1 - 1, prev >= first)
25291 && MATRIX_ROW_END_CHARPOS (prev) == start_charpos
25292 && prev->used[TEXT_AREA] > 0)
25294 struct glyph *beg = prev->glyphs[TEXT_AREA];
25295 glyph = beg + prev->used[TEXT_AREA];
25296 while (--glyph >= beg && INTEGERP (glyph->object));
25297 if (glyph < beg
25298 || !(EQ (glyph->object, before_string)
25299 || EQ (glyph->object, cover_string)))
25300 break;
25301 r1 = prev;
25304 if (r2 == NULL)
25306 r2 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
25307 hlinfo->mouse_face_past_end = 1;
25309 else if (!NILP (after_string))
25311 /* If the after-string has newlines, advance to its last row. */
25312 struct glyph_row *next;
25313 struct glyph_row *last
25314 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
25316 for (next = r2 + 1;
25317 next <= last
25318 && next->used[TEXT_AREA] > 0
25319 && EQ (next->glyphs[TEXT_AREA]->object, after_string);
25320 ++next)
25321 r2 = next;
25323 /* The rest of the display engine assumes that mouse_face_beg_row is
25324 either above below mouse_face_end_row or identical to it. But
25325 with bidi-reordered continued lines, the row for START_CHARPOS
25326 could be below the row for END_CHARPOS. If so, swap the rows and
25327 store them in correct order. */
25328 if (r1->y > r2->y)
25330 struct glyph_row *tem = r2;
25332 r2 = r1;
25333 r1 = tem;
25336 hlinfo->mouse_face_beg_y = r1->y;
25337 hlinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (r1, w->current_matrix);
25338 hlinfo->mouse_face_end_y = r2->y;
25339 hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r2, w->current_matrix);
25341 /* For a bidi-reordered row, the positions of BEFORE_STRING,
25342 AFTER_STRING, COVER_STRING, START_CHARPOS, and END_CHARPOS
25343 could be anywhere in the row and in any order. The strategy
25344 below is to find the leftmost and the rightmost glyph that
25345 belongs to either of these 3 strings, or whose position is
25346 between START_CHARPOS and END_CHARPOS, and highlight all the
25347 glyphs between those two. This may cover more than just the text
25348 between START_CHARPOS and END_CHARPOS if the range of characters
25349 strides the bidi level boundary, e.g. if the beginning is in R2L
25350 text while the end is in L2R text or vice versa. */
25351 if (!r1->reversed_p)
25353 /* This row is in a left to right paragraph. Scan it left to
25354 right. */
25355 glyph = r1->glyphs[TEXT_AREA];
25356 end = glyph + r1->used[TEXT_AREA];
25357 x = r1->x;
25359 /* Skip truncation glyphs at the start of the glyph row. */
25360 if (r1->displays_text_p)
25361 for (; glyph < end
25362 && INTEGERP (glyph->object)
25363 && glyph->charpos < 0;
25364 ++glyph)
25365 x += glyph->pixel_width;
25367 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
25368 or COVER_STRING, and the first glyph from buffer whose
25369 position is between START_CHARPOS and END_CHARPOS. */
25370 for (; glyph < end
25371 && !INTEGERP (glyph->object)
25372 && !EQ (glyph->object, cover_string)
25373 && !(BUFFERP (glyph->object)
25374 && (glyph->charpos >= start_charpos
25375 && glyph->charpos < end_charpos));
25376 ++glyph)
25378 /* BEFORE_STRING or AFTER_STRING are only relevant if they
25379 are present at buffer positions between START_CHARPOS and
25380 END_CHARPOS, or if they come from an overlay. */
25381 if (EQ (glyph->object, before_string))
25383 pos = string_buffer_position (before_string,
25384 start_charpos);
25385 /* If pos == 0, it means before_string came from an
25386 overlay, not from a buffer position. */
25387 if (!pos || (pos >= start_charpos && pos < end_charpos))
25388 break;
25390 else if (EQ (glyph->object, after_string))
25392 pos = string_buffer_position (after_string, end_charpos);
25393 if (!pos || (pos >= start_charpos && pos < end_charpos))
25394 break;
25396 x += glyph->pixel_width;
25398 hlinfo->mouse_face_beg_x = x;
25399 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
25401 else
25403 /* This row is in a right to left paragraph. Scan it right to
25404 left. */
25405 struct glyph *g;
25407 end = r1->glyphs[TEXT_AREA] - 1;
25408 glyph = end + r1->used[TEXT_AREA];
25410 /* Skip truncation glyphs at the start of the glyph row. */
25411 if (r1->displays_text_p)
25412 for (; glyph > end
25413 && INTEGERP (glyph->object)
25414 && glyph->charpos < 0;
25415 --glyph)
25418 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
25419 or COVER_STRING, and the first glyph from buffer whose
25420 position is between START_CHARPOS and END_CHARPOS. */
25421 for (; glyph > end
25422 && !INTEGERP (glyph->object)
25423 && !EQ (glyph->object, cover_string)
25424 && !(BUFFERP (glyph->object)
25425 && (glyph->charpos >= start_charpos
25426 && glyph->charpos < end_charpos));
25427 --glyph)
25429 /* BEFORE_STRING or AFTER_STRING are only relevant if they
25430 are present at buffer positions between START_CHARPOS and
25431 END_CHARPOS, or if they come from an overlay. */
25432 if (EQ (glyph->object, before_string))
25434 pos = string_buffer_position (before_string, start_charpos);
25435 /* If pos == 0, it means before_string came from an
25436 overlay, not from a buffer position. */
25437 if (!pos || (pos >= start_charpos && pos < end_charpos))
25438 break;
25440 else if (EQ (glyph->object, after_string))
25442 pos = string_buffer_position (after_string, end_charpos);
25443 if (!pos || (pos >= start_charpos && pos < end_charpos))
25444 break;
25448 glyph++; /* first glyph to the right of the highlighted area */
25449 for (g = r1->glyphs[TEXT_AREA], x = r1->x; g < glyph; g++)
25450 x += g->pixel_width;
25451 hlinfo->mouse_face_beg_x = x;
25452 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
25455 /* If the highlight ends in a different row, compute GLYPH and END
25456 for the end row. Otherwise, reuse the values computed above for
25457 the row where the highlight begins. */
25458 if (r2 != r1)
25460 if (!r2->reversed_p)
25462 glyph = r2->glyphs[TEXT_AREA];
25463 end = glyph + r2->used[TEXT_AREA];
25464 x = r2->x;
25466 else
25468 end = r2->glyphs[TEXT_AREA] - 1;
25469 glyph = end + r2->used[TEXT_AREA];
25473 if (!r2->reversed_p)
25475 /* Skip truncation and continuation glyphs near the end of the
25476 row, and also blanks and stretch glyphs inserted by
25477 extend_face_to_end_of_line. */
25478 while (end > glyph
25479 && INTEGERP ((end - 1)->object)
25480 && (end - 1)->charpos <= 0)
25481 --end;
25482 /* Scan the rest of the glyph row from the end, looking for the
25483 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
25484 COVER_STRING, or whose position is between START_CHARPOS
25485 and END_CHARPOS */
25486 for (--end;
25487 end > glyph
25488 && !INTEGERP (end->object)
25489 && !EQ (end->object, cover_string)
25490 && !(BUFFERP (end->object)
25491 && (end->charpos >= start_charpos
25492 && end->charpos < end_charpos));
25493 --end)
25495 /* BEFORE_STRING or AFTER_STRING are only relevant if they
25496 are present at buffer positions between START_CHARPOS and
25497 END_CHARPOS, or if they come from an overlay. */
25498 if (EQ (end->object, before_string))
25500 pos = string_buffer_position (before_string, start_charpos);
25501 if (!pos || (pos >= start_charpos && pos < end_charpos))
25502 break;
25504 else if (EQ (end->object, after_string))
25506 pos = string_buffer_position (after_string, end_charpos);
25507 if (!pos || (pos >= start_charpos && pos < end_charpos))
25508 break;
25511 /* Find the X coordinate of the last glyph to be highlighted. */
25512 for (; glyph <= end; ++glyph)
25513 x += glyph->pixel_width;
25515 hlinfo->mouse_face_end_x = x;
25516 hlinfo->mouse_face_end_col = glyph - r2->glyphs[TEXT_AREA];
25518 else
25520 /* Skip truncation and continuation glyphs near the end of the
25521 row, and also blanks and stretch glyphs inserted by
25522 extend_face_to_end_of_line. */
25523 x = r2->x;
25524 end++;
25525 while (end < glyph
25526 && INTEGERP (end->object)
25527 && end->charpos <= 0)
25529 x += end->pixel_width;
25530 ++end;
25532 /* Scan the rest of the glyph row from the end, looking for the
25533 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
25534 COVER_STRING, or whose position is between START_CHARPOS
25535 and END_CHARPOS */
25536 for ( ;
25537 end < glyph
25538 && !INTEGERP (end->object)
25539 && !EQ (end->object, cover_string)
25540 && !(BUFFERP (end->object)
25541 && (end->charpos >= start_charpos
25542 && end->charpos < end_charpos));
25543 ++end)
25545 /* BEFORE_STRING or AFTER_STRING are only relevant if they
25546 are present at buffer positions between START_CHARPOS and
25547 END_CHARPOS, or if they come from an overlay. */
25548 if (EQ (end->object, before_string))
25550 pos = string_buffer_position (before_string, start_charpos);
25551 if (!pos || (pos >= start_charpos && pos < end_charpos))
25552 break;
25554 else if (EQ (end->object, after_string))
25556 pos = string_buffer_position (after_string, end_charpos);
25557 if (!pos || (pos >= start_charpos && pos < end_charpos))
25558 break;
25560 x += end->pixel_width;
25562 hlinfo->mouse_face_end_x = x;
25563 hlinfo->mouse_face_end_col = end - r2->glyphs[TEXT_AREA];
25566 hlinfo->mouse_face_window = window;
25567 hlinfo->mouse_face_face_id
25568 = face_at_buffer_position (w, mouse_charpos, 0, 0, &ignore,
25569 mouse_charpos + 1,
25570 !hlinfo->mouse_face_hidden, -1);
25571 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
25574 /* The following function is not used anymore (replaced with
25575 mouse_face_from_string_pos), but I leave it here for the time
25576 being, in case someone would. */
25578 #if 0 /* not used */
25580 /* Find the position of the glyph for position POS in OBJECT in
25581 window W's current matrix, and return in *X, *Y the pixel
25582 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
25584 RIGHT_P non-zero means return the position of the right edge of the
25585 glyph, RIGHT_P zero means return the left edge position.
25587 If no glyph for POS exists in the matrix, return the position of
25588 the glyph with the next smaller position that is in the matrix, if
25589 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
25590 exists in the matrix, return the position of the glyph with the
25591 next larger position in OBJECT.
25593 Value is non-zero if a glyph was found. */
25595 static int
25596 fast_find_string_pos (struct window *w, EMACS_INT pos, Lisp_Object object,
25597 int *hpos, int *vpos, int *x, int *y, int right_p)
25599 int yb = window_text_bottom_y (w);
25600 struct glyph_row *r;
25601 struct glyph *best_glyph = NULL;
25602 struct glyph_row *best_row = NULL;
25603 int best_x = 0;
25605 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
25606 r->enabled_p && r->y < yb;
25607 ++r)
25609 struct glyph *g = r->glyphs[TEXT_AREA];
25610 struct glyph *e = g + r->used[TEXT_AREA];
25611 int gx;
25613 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
25614 if (EQ (g->object, object))
25616 if (g->charpos == pos)
25618 best_glyph = g;
25619 best_x = gx;
25620 best_row = r;
25621 goto found;
25623 else if (best_glyph == NULL
25624 || ((eabs (g->charpos - pos)
25625 < eabs (best_glyph->charpos - pos))
25626 && (right_p
25627 ? g->charpos < pos
25628 : g->charpos > pos)))
25630 best_glyph = g;
25631 best_x = gx;
25632 best_row = r;
25637 found:
25639 if (best_glyph)
25641 *x = best_x;
25642 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
25644 if (right_p)
25646 *x += best_glyph->pixel_width;
25647 ++*hpos;
25650 *y = best_row->y;
25651 *vpos = best_row - w->current_matrix->rows;
25654 return best_glyph != NULL;
25656 #endif /* not used */
25658 /* Find the positions of the first and the last glyphs in window W's
25659 current matrix that occlude positions [STARTPOS..ENDPOS] in OBJECT
25660 (assumed to be a string), and return in HLINFO's mouse_face_*
25661 members the pixel and column/row coordinates of those glyphs. */
25663 static void
25664 mouse_face_from_string_pos (struct window *w, Mouse_HLInfo *hlinfo,
25665 Lisp_Object object,
25666 EMACS_INT startpos, EMACS_INT endpos)
25668 int yb = window_text_bottom_y (w);
25669 struct glyph_row *r;
25670 struct glyph *g, *e;
25671 int gx;
25672 int found = 0;
25674 /* Find the glyph row with at least one position in the range
25675 [STARTPOS..ENDPOS], and the first glyph in that row whose
25676 position belongs to that range. */
25677 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
25678 r->enabled_p && r->y < yb;
25679 ++r)
25681 if (!r->reversed_p)
25683 g = r->glyphs[TEXT_AREA];
25684 e = g + r->used[TEXT_AREA];
25685 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
25686 if (EQ (g->object, object)
25687 && startpos <= g->charpos && g->charpos <= endpos)
25689 hlinfo->mouse_face_beg_row = r - w->current_matrix->rows;
25690 hlinfo->mouse_face_beg_y = r->y;
25691 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
25692 hlinfo->mouse_face_beg_x = gx;
25693 found = 1;
25694 break;
25697 else
25699 struct glyph *g1;
25701 e = r->glyphs[TEXT_AREA];
25702 g = e + r->used[TEXT_AREA];
25703 for ( ; g > e; --g)
25704 if (EQ ((g-1)->object, object)
25705 && startpos <= (g-1)->charpos && (g-1)->charpos <= endpos)
25707 hlinfo->mouse_face_beg_row = r - w->current_matrix->rows;
25708 hlinfo->mouse_face_beg_y = r->y;
25709 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
25710 for (gx = r->x, g1 = r->glyphs[TEXT_AREA]; g1 < g; ++g1)
25711 gx += g1->pixel_width;
25712 hlinfo->mouse_face_beg_x = gx;
25713 found = 1;
25714 break;
25717 if (found)
25718 break;
25721 if (!found)
25722 return;
25724 /* Starting with the next row, look for the first row which does NOT
25725 include any glyphs whose positions are in the range. */
25726 for (++r; r->enabled_p && r->y < yb; ++r)
25728 g = r->glyphs[TEXT_AREA];
25729 e = g + r->used[TEXT_AREA];
25730 found = 0;
25731 for ( ; g < e; ++g)
25732 if (EQ (g->object, object)
25733 && startpos <= g->charpos && g->charpos <= endpos)
25735 found = 1;
25736 break;
25738 if (!found)
25739 break;
25742 /* The highlighted region ends on the previous row. */
25743 r--;
25745 /* Set the end row and its vertical pixel coordinate. */
25746 hlinfo->mouse_face_end_row = r - w->current_matrix->rows;
25747 hlinfo->mouse_face_end_y = r->y;
25749 /* Compute and set the end column and the end column's horizontal
25750 pixel coordinate. */
25751 if (!r->reversed_p)
25753 g = r->glyphs[TEXT_AREA];
25754 e = g + r->used[TEXT_AREA];
25755 for ( ; e > g; --e)
25756 if (EQ ((e-1)->object, object)
25757 && startpos <= (e-1)->charpos && (e-1)->charpos <= endpos)
25758 break;
25759 hlinfo->mouse_face_end_col = e - g;
25761 for (gx = r->x; g < e; ++g)
25762 gx += g->pixel_width;
25763 hlinfo->mouse_face_end_x = gx;
25765 else
25767 e = r->glyphs[TEXT_AREA];
25768 g = e + r->used[TEXT_AREA];
25769 for (gx = r->x ; e < g; ++e)
25771 if (EQ (e->object, object)
25772 && startpos <= e->charpos && e->charpos <= endpos)
25773 break;
25774 gx += e->pixel_width;
25776 hlinfo->mouse_face_end_col = e - r->glyphs[TEXT_AREA];
25777 hlinfo->mouse_face_end_x = gx;
25781 #ifdef HAVE_WINDOW_SYSTEM
25783 /* See if position X, Y is within a hot-spot of an image. */
25785 static int
25786 on_hot_spot_p (Lisp_Object hot_spot, int x, int y)
25788 if (!CONSP (hot_spot))
25789 return 0;
25791 if (EQ (XCAR (hot_spot), Qrect))
25793 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
25794 Lisp_Object rect = XCDR (hot_spot);
25795 Lisp_Object tem;
25796 if (!CONSP (rect))
25797 return 0;
25798 if (!CONSP (XCAR (rect)))
25799 return 0;
25800 if (!CONSP (XCDR (rect)))
25801 return 0;
25802 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
25803 return 0;
25804 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
25805 return 0;
25806 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
25807 return 0;
25808 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
25809 return 0;
25810 return 1;
25812 else if (EQ (XCAR (hot_spot), Qcircle))
25814 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
25815 Lisp_Object circ = XCDR (hot_spot);
25816 Lisp_Object lr, lx0, ly0;
25817 if (CONSP (circ)
25818 && CONSP (XCAR (circ))
25819 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
25820 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
25821 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
25823 double r = XFLOATINT (lr);
25824 double dx = XINT (lx0) - x;
25825 double dy = XINT (ly0) - y;
25826 return (dx * dx + dy * dy <= r * r);
25829 else if (EQ (XCAR (hot_spot), Qpoly))
25831 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
25832 if (VECTORP (XCDR (hot_spot)))
25834 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
25835 Lisp_Object *poly = v->contents;
25836 int n = v->header.size;
25837 int i;
25838 int inside = 0;
25839 Lisp_Object lx, ly;
25840 int x0, y0;
25842 /* Need an even number of coordinates, and at least 3 edges. */
25843 if (n < 6 || n & 1)
25844 return 0;
25846 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
25847 If count is odd, we are inside polygon. Pixels on edges
25848 may or may not be included depending on actual geometry of the
25849 polygon. */
25850 if ((lx = poly[n-2], !INTEGERP (lx))
25851 || (ly = poly[n-1], !INTEGERP (lx)))
25852 return 0;
25853 x0 = XINT (lx), y0 = XINT (ly);
25854 for (i = 0; i < n; i += 2)
25856 int x1 = x0, y1 = y0;
25857 if ((lx = poly[i], !INTEGERP (lx))
25858 || (ly = poly[i+1], !INTEGERP (ly)))
25859 return 0;
25860 x0 = XINT (lx), y0 = XINT (ly);
25862 /* Does this segment cross the X line? */
25863 if (x0 >= x)
25865 if (x1 >= x)
25866 continue;
25868 else if (x1 < x)
25869 continue;
25870 if (y > y0 && y > y1)
25871 continue;
25872 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
25873 inside = !inside;
25875 return inside;
25878 return 0;
25881 Lisp_Object
25882 find_hot_spot (Lisp_Object map, int x, int y)
25884 while (CONSP (map))
25886 if (CONSP (XCAR (map))
25887 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
25888 return XCAR (map);
25889 map = XCDR (map);
25892 return Qnil;
25895 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
25896 3, 3, 0,
25897 doc: /* Lookup in image map MAP coordinates X and Y.
25898 An image map is an alist where each element has the format (AREA ID PLIST).
25899 An AREA is specified as either a rectangle, a circle, or a polygon:
25900 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
25901 pixel coordinates of the upper left and bottom right corners.
25902 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
25903 and the radius of the circle; r may be a float or integer.
25904 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
25905 vector describes one corner in the polygon.
25906 Returns the alist element for the first matching AREA in MAP. */)
25907 (Lisp_Object map, Lisp_Object x, Lisp_Object y)
25909 if (NILP (map))
25910 return Qnil;
25912 CHECK_NUMBER (x);
25913 CHECK_NUMBER (y);
25915 return find_hot_spot (map, XINT (x), XINT (y));
25919 /* Display frame CURSOR, optionally using shape defined by POINTER. */
25920 static void
25921 define_frame_cursor1 (struct frame *f, Cursor cursor, Lisp_Object pointer)
25923 /* Do not change cursor shape while dragging mouse. */
25924 if (!NILP (do_mouse_tracking))
25925 return;
25927 if (!NILP (pointer))
25929 if (EQ (pointer, Qarrow))
25930 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
25931 else if (EQ (pointer, Qhand))
25932 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
25933 else if (EQ (pointer, Qtext))
25934 cursor = FRAME_X_OUTPUT (f)->text_cursor;
25935 else if (EQ (pointer, intern ("hdrag")))
25936 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
25937 #ifdef HAVE_X_WINDOWS
25938 else if (EQ (pointer, intern ("vdrag")))
25939 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
25940 #endif
25941 else if (EQ (pointer, intern ("hourglass")))
25942 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
25943 else if (EQ (pointer, Qmodeline))
25944 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
25945 else
25946 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
25949 if (cursor != No_Cursor)
25950 FRAME_RIF (f)->define_frame_cursor (f, cursor);
25953 #endif /* HAVE_WINDOW_SYSTEM */
25955 /* Take proper action when mouse has moved to the mode or header line
25956 or marginal area AREA of window W, x-position X and y-position Y.
25957 X is relative to the start of the text display area of W, so the
25958 width of bitmap areas and scroll bars must be subtracted to get a
25959 position relative to the start of the mode line. */
25961 static void
25962 note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
25963 enum window_part area)
25965 struct window *w = XWINDOW (window);
25966 struct frame *f = XFRAME (w->frame);
25967 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
25968 #ifdef HAVE_WINDOW_SYSTEM
25969 Display_Info *dpyinfo;
25970 #endif
25971 Cursor cursor = No_Cursor;
25972 Lisp_Object pointer = Qnil;
25973 int dx, dy, width, height;
25974 EMACS_INT charpos;
25975 Lisp_Object string, object = Qnil;
25976 Lisp_Object pos, help;
25978 Lisp_Object mouse_face;
25979 int original_x_pixel = x;
25980 struct glyph * glyph = NULL, * row_start_glyph = NULL;
25981 struct glyph_row *row;
25983 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
25985 int x0;
25986 struct glyph *end;
25988 /* Kludge alert: mode_line_string takes X/Y in pixels, but
25989 returns them in row/column units! */
25990 string = mode_line_string (w, area, &x, &y, &charpos,
25991 &object, &dx, &dy, &width, &height);
25993 row = (area == ON_MODE_LINE
25994 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
25995 : MATRIX_HEADER_LINE_ROW (w->current_matrix));
25997 /* Find the glyph under the mouse pointer. */
25998 if (row->mode_line_p && row->enabled_p)
26000 glyph = row_start_glyph = row->glyphs[TEXT_AREA];
26001 end = glyph + row->used[TEXT_AREA];
26003 for (x0 = original_x_pixel;
26004 glyph < end && x0 >= glyph->pixel_width;
26005 ++glyph)
26006 x0 -= glyph->pixel_width;
26008 if (glyph >= end)
26009 glyph = NULL;
26012 else
26014 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
26015 /* Kludge alert: marginal_area_string takes X/Y in pixels, but
26016 returns them in row/column units! */
26017 string = marginal_area_string (w, area, &x, &y, &charpos,
26018 &object, &dx, &dy, &width, &height);
26021 help = Qnil;
26023 #ifdef HAVE_WINDOW_SYSTEM
26024 if (IMAGEP (object))
26026 Lisp_Object image_map, hotspot;
26027 if ((image_map = Fplist_get (XCDR (object), QCmap),
26028 !NILP (image_map))
26029 && (hotspot = find_hot_spot (image_map, dx, dy),
26030 CONSP (hotspot))
26031 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
26033 Lisp_Object plist;
26035 /* Could check XCAR (hotspot) to see if we enter/leave this hot-spot.
26036 If so, we could look for mouse-enter, mouse-leave
26037 properties in PLIST (and do something...). */
26038 hotspot = XCDR (hotspot);
26039 if (CONSP (hotspot)
26040 && (plist = XCAR (hotspot), CONSP (plist)))
26042 pointer = Fplist_get (plist, Qpointer);
26043 if (NILP (pointer))
26044 pointer = Qhand;
26045 help = Fplist_get (plist, Qhelp_echo);
26046 if (!NILP (help))
26048 help_echo_string = help;
26049 /* Is this correct? ++kfs */
26050 XSETWINDOW (help_echo_window, w);
26051 help_echo_object = w->buffer;
26052 help_echo_pos = charpos;
26056 if (NILP (pointer))
26057 pointer = Fplist_get (XCDR (object), QCpointer);
26059 #endif /* HAVE_WINDOW_SYSTEM */
26061 if (STRINGP (string))
26063 pos = make_number (charpos);
26064 /* If we're on a string with `help-echo' text property, arrange
26065 for the help to be displayed. This is done by setting the
26066 global variable help_echo_string to the help string. */
26067 if (NILP (help))
26069 help = Fget_text_property (pos, Qhelp_echo, string);
26070 if (!NILP (help))
26072 help_echo_string = help;
26073 XSETWINDOW (help_echo_window, w);
26074 help_echo_object = string;
26075 help_echo_pos = charpos;
26079 #ifdef HAVE_WINDOW_SYSTEM
26080 if (FRAME_WINDOW_P (f))
26082 dpyinfo = FRAME_X_DISPLAY_INFO (f);
26083 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
26084 if (NILP (pointer))
26085 pointer = Fget_text_property (pos, Qpointer, string);
26087 /* Change the mouse pointer according to what is under X/Y. */
26088 if (NILP (pointer)
26089 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
26091 Lisp_Object map;
26092 map = Fget_text_property (pos, Qlocal_map, string);
26093 if (!KEYMAPP (map))
26094 map = Fget_text_property (pos, Qkeymap, string);
26095 if (!KEYMAPP (map))
26096 cursor = dpyinfo->vertical_scroll_bar_cursor;
26099 #endif
26101 /* Change the mouse face according to what is under X/Y. */
26102 mouse_face = Fget_text_property (pos, Qmouse_face, string);
26103 if (!NILP (mouse_face)
26104 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
26105 && glyph)
26107 Lisp_Object b, e;
26109 struct glyph * tmp_glyph;
26111 int gpos;
26112 int gseq_length;
26113 int total_pixel_width;
26114 EMACS_INT begpos, endpos, ignore;
26116 int vpos, hpos;
26118 b = Fprevious_single_property_change (make_number (charpos + 1),
26119 Qmouse_face, string, Qnil);
26120 if (NILP (b))
26121 begpos = 0;
26122 else
26123 begpos = XINT (b);
26125 e = Fnext_single_property_change (pos, Qmouse_face, string, Qnil);
26126 if (NILP (e))
26127 endpos = SCHARS (string);
26128 else
26129 endpos = XINT (e);
26131 /* Calculate the glyph position GPOS of GLYPH in the
26132 displayed string, relative to the beginning of the
26133 highlighted part of the string.
26135 Note: GPOS is different from CHARPOS. CHARPOS is the
26136 position of GLYPH in the internal string object. A mode
26137 line string format has structures which are converted to
26138 a flattened string by the Emacs Lisp interpreter. The
26139 internal string is an element of those structures. The
26140 displayed string is the flattened string. */
26141 tmp_glyph = row_start_glyph;
26142 while (tmp_glyph < glyph
26143 && (!(EQ (tmp_glyph->object, glyph->object)
26144 && begpos <= tmp_glyph->charpos
26145 && tmp_glyph->charpos < endpos)))
26146 tmp_glyph++;
26147 gpos = glyph - tmp_glyph;
26149 /* Calculate the length GSEQ_LENGTH of the glyph sequence of
26150 the highlighted part of the displayed string to which
26151 GLYPH belongs. Note: GSEQ_LENGTH is different from
26152 SCHARS (STRING), because the latter returns the length of
26153 the internal string. */
26154 for (tmp_glyph = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
26155 tmp_glyph > glyph
26156 && (!(EQ (tmp_glyph->object, glyph->object)
26157 && begpos <= tmp_glyph->charpos
26158 && tmp_glyph->charpos < endpos));
26159 tmp_glyph--)
26161 gseq_length = gpos + (tmp_glyph - glyph) + 1;
26163 /* Calculate the total pixel width of all the glyphs between
26164 the beginning of the highlighted area and GLYPH. */
26165 total_pixel_width = 0;
26166 for (tmp_glyph = glyph - gpos; tmp_glyph != glyph; tmp_glyph++)
26167 total_pixel_width += tmp_glyph->pixel_width;
26169 /* Pre calculation of re-rendering position. Note: X is in
26170 column units here, after the call to mode_line_string or
26171 marginal_area_string. */
26172 hpos = x - gpos;
26173 vpos = (area == ON_MODE_LINE
26174 ? (w->current_matrix)->nrows - 1
26175 : 0);
26177 /* If GLYPH's position is included in the region that is
26178 already drawn in mouse face, we have nothing to do. */
26179 if ( EQ (window, hlinfo->mouse_face_window)
26180 && (!row->reversed_p
26181 ? (hlinfo->mouse_face_beg_col <= hpos
26182 && hpos < hlinfo->mouse_face_end_col)
26183 /* In R2L rows we swap BEG and END, see below. */
26184 : (hlinfo->mouse_face_end_col <= hpos
26185 && hpos < hlinfo->mouse_face_beg_col))
26186 && hlinfo->mouse_face_beg_row == vpos )
26187 return;
26189 if (clear_mouse_face (hlinfo))
26190 cursor = No_Cursor;
26192 if (!row->reversed_p)
26194 hlinfo->mouse_face_beg_col = hpos;
26195 hlinfo->mouse_face_beg_x = original_x_pixel
26196 - (total_pixel_width + dx);
26197 hlinfo->mouse_face_end_col = hpos + gseq_length;
26198 hlinfo->mouse_face_end_x = 0;
26200 else
26202 /* In R2L rows, show_mouse_face expects BEG and END
26203 coordinates to be swapped. */
26204 hlinfo->mouse_face_end_col = hpos;
26205 hlinfo->mouse_face_end_x = original_x_pixel
26206 - (total_pixel_width + dx);
26207 hlinfo->mouse_face_beg_col = hpos + gseq_length;
26208 hlinfo->mouse_face_beg_x = 0;
26211 hlinfo->mouse_face_beg_row = vpos;
26212 hlinfo->mouse_face_end_row = hlinfo->mouse_face_beg_row;
26213 hlinfo->mouse_face_beg_y = 0;
26214 hlinfo->mouse_face_end_y = 0;
26215 hlinfo->mouse_face_past_end = 0;
26216 hlinfo->mouse_face_window = window;
26218 hlinfo->mouse_face_face_id = face_at_string_position (w, string,
26219 charpos,
26220 0, 0, 0,
26221 &ignore,
26222 glyph->face_id,
26224 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
26226 if (NILP (pointer))
26227 pointer = Qhand;
26229 else if ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
26230 clear_mouse_face (hlinfo);
26232 #ifdef HAVE_WINDOW_SYSTEM
26233 if (FRAME_WINDOW_P (f))
26234 define_frame_cursor1 (f, cursor, pointer);
26235 #endif
26239 /* EXPORT:
26240 Take proper action when the mouse has moved to position X, Y on
26241 frame F as regards highlighting characters that have mouse-face
26242 properties. Also de-highlighting chars where the mouse was before.
26243 X and Y can be negative or out of range. */
26245 void
26246 note_mouse_highlight (struct frame *f, int x, int y)
26248 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
26249 enum window_part part;
26250 Lisp_Object window;
26251 struct window *w;
26252 Cursor cursor = No_Cursor;
26253 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
26254 struct buffer *b;
26256 /* When a menu is active, don't highlight because this looks odd. */
26257 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) || defined (MSDOS)
26258 if (popup_activated ())
26259 return;
26260 #endif
26262 if (NILP (Vmouse_highlight)
26263 || !f->glyphs_initialized_p
26264 || f->pointer_invisible)
26265 return;
26267 hlinfo->mouse_face_mouse_x = x;
26268 hlinfo->mouse_face_mouse_y = y;
26269 hlinfo->mouse_face_mouse_frame = f;
26271 if (hlinfo->mouse_face_defer)
26272 return;
26274 if (gc_in_progress)
26276 hlinfo->mouse_face_deferred_gc = 1;
26277 return;
26280 /* Which window is that in? */
26281 window = window_from_coordinates (f, x, y, &part, 1);
26283 /* If we were displaying active text in another window, clear that.
26284 Also clear if we move out of text area in same window. */
26285 if (! EQ (window, hlinfo->mouse_face_window)
26286 || (part != ON_TEXT && part != ON_MODE_LINE && part != ON_HEADER_LINE
26287 && !NILP (hlinfo->mouse_face_window)))
26288 clear_mouse_face (hlinfo);
26290 /* Not on a window -> return. */
26291 if (!WINDOWP (window))
26292 return;
26294 /* Reset help_echo_string. It will get recomputed below. */
26295 help_echo_string = Qnil;
26297 /* Convert to window-relative pixel coordinates. */
26298 w = XWINDOW (window);
26299 frame_to_window_pixel_xy (w, &x, &y);
26301 #ifdef HAVE_WINDOW_SYSTEM
26302 /* Handle tool-bar window differently since it doesn't display a
26303 buffer. */
26304 if (EQ (window, f->tool_bar_window))
26306 note_tool_bar_highlight (f, x, y);
26307 return;
26309 #endif
26311 /* Mouse is on the mode, header line or margin? */
26312 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
26313 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
26315 note_mode_line_or_margin_highlight (window, x, y, part);
26316 return;
26319 #ifdef HAVE_WINDOW_SYSTEM
26320 if (part == ON_VERTICAL_BORDER)
26322 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
26323 help_echo_string = build_string ("drag-mouse-1: resize");
26325 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
26326 || part == ON_SCROLL_BAR)
26327 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
26328 else
26329 cursor = FRAME_X_OUTPUT (f)->text_cursor;
26330 #endif
26332 /* Are we in a window whose display is up to date?
26333 And verify the buffer's text has not changed. */
26334 b = XBUFFER (w->buffer);
26335 if (part == ON_TEXT
26336 && EQ (w->window_end_valid, w->buffer)
26337 && XFASTINT (w->last_modified) == BUF_MODIFF (b)
26338 && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
26340 int hpos, vpos, dx, dy, area;
26341 EMACS_INT pos;
26342 struct glyph *glyph;
26343 Lisp_Object object;
26344 Lisp_Object mouse_face = Qnil, position;
26345 Lisp_Object *overlay_vec = NULL;
26346 ptrdiff_t i, noverlays;
26347 struct buffer *obuf;
26348 EMACS_INT obegv, ozv;
26349 int same_region;
26351 /* Find the glyph under X/Y. */
26352 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
26354 #ifdef HAVE_WINDOW_SYSTEM
26355 /* Look for :pointer property on image. */
26356 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
26358 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
26359 if (img != NULL && IMAGEP (img->spec))
26361 Lisp_Object image_map, hotspot;
26362 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
26363 !NILP (image_map))
26364 && (hotspot = find_hot_spot (image_map,
26365 glyph->slice.img.x + dx,
26366 glyph->slice.img.y + dy),
26367 CONSP (hotspot))
26368 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
26370 Lisp_Object plist;
26372 /* Could check XCAR (hotspot) to see if we enter/leave
26373 this hot-spot.
26374 If so, we could look for mouse-enter, mouse-leave
26375 properties in PLIST (and do something...). */
26376 hotspot = XCDR (hotspot);
26377 if (CONSP (hotspot)
26378 && (plist = XCAR (hotspot), CONSP (plist)))
26380 pointer = Fplist_get (plist, Qpointer);
26381 if (NILP (pointer))
26382 pointer = Qhand;
26383 help_echo_string = Fplist_get (plist, Qhelp_echo);
26384 if (!NILP (help_echo_string))
26386 help_echo_window = window;
26387 help_echo_object = glyph->object;
26388 help_echo_pos = glyph->charpos;
26392 if (NILP (pointer))
26393 pointer = Fplist_get (XCDR (img->spec), QCpointer);
26396 #endif /* HAVE_WINDOW_SYSTEM */
26398 /* Clear mouse face if X/Y not over text. */
26399 if (glyph == NULL
26400 || area != TEXT_AREA
26401 || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p
26402 /* Glyph's OBJECT is an integer for glyphs inserted by the
26403 display engine for its internal purposes, like truncation
26404 and continuation glyphs and blanks beyond the end of
26405 line's text on text terminals. If we are over such a
26406 glyph, we are not over any text. */
26407 || INTEGERP (glyph->object)
26408 /* R2L rows have a stretch glyph at their front, which
26409 stands for no text, whereas L2R rows have no glyphs at
26410 all beyond the end of text. Treat such stretch glyphs
26411 like we do with NULL glyphs in L2R rows. */
26412 || (MATRIX_ROW (w->current_matrix, vpos)->reversed_p
26413 && glyph == MATRIX_ROW (w->current_matrix, vpos)->glyphs[TEXT_AREA]
26414 && glyph->type == STRETCH_GLYPH
26415 && glyph->avoid_cursor_p))
26417 if (clear_mouse_face (hlinfo))
26418 cursor = No_Cursor;
26419 #ifdef HAVE_WINDOW_SYSTEM
26420 if (FRAME_WINDOW_P (f) && NILP (pointer))
26422 if (area != TEXT_AREA)
26423 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
26424 else
26425 pointer = Vvoid_text_area_pointer;
26427 #endif
26428 goto set_cursor;
26431 pos = glyph->charpos;
26432 object = glyph->object;
26433 if (!STRINGP (object) && !BUFFERP (object))
26434 goto set_cursor;
26436 /* If we get an out-of-range value, return now; avoid an error. */
26437 if (BUFFERP (object) && pos > BUF_Z (b))
26438 goto set_cursor;
26440 /* Make the window's buffer temporarily current for
26441 overlays_at and compute_char_face. */
26442 obuf = current_buffer;
26443 current_buffer = b;
26444 obegv = BEGV;
26445 ozv = ZV;
26446 BEGV = BEG;
26447 ZV = Z;
26449 /* Is this char mouse-active or does it have help-echo? */
26450 position = make_number (pos);
26452 if (BUFFERP (object))
26454 /* Put all the overlays we want in a vector in overlay_vec. */
26455 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
26456 /* Sort overlays into increasing priority order. */
26457 noverlays = sort_overlays (overlay_vec, noverlays, w);
26459 else
26460 noverlays = 0;
26462 same_region = coords_in_mouse_face_p (w, hpos, vpos);
26464 if (same_region)
26465 cursor = No_Cursor;
26467 /* Check mouse-face highlighting. */
26468 if (! same_region
26469 /* If there exists an overlay with mouse-face overlapping
26470 the one we are currently highlighting, we have to
26471 check if we enter the overlapping overlay, and then
26472 highlight only that. */
26473 || (OVERLAYP (hlinfo->mouse_face_overlay)
26474 && mouse_face_overlay_overlaps (hlinfo->mouse_face_overlay)))
26476 /* Find the highest priority overlay with a mouse-face. */
26477 Lisp_Object overlay = Qnil;
26478 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
26480 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
26481 if (!NILP (mouse_face))
26482 overlay = overlay_vec[i];
26485 /* If we're highlighting the same overlay as before, there's
26486 no need to do that again. */
26487 if (!NILP (overlay) && EQ (overlay, hlinfo->mouse_face_overlay))
26488 goto check_help_echo;
26489 hlinfo->mouse_face_overlay = overlay;
26491 /* Clear the display of the old active region, if any. */
26492 if (clear_mouse_face (hlinfo))
26493 cursor = No_Cursor;
26495 /* If no overlay applies, get a text property. */
26496 if (NILP (overlay))
26497 mouse_face = Fget_text_property (position, Qmouse_face, object);
26499 /* Next, compute the bounds of the mouse highlighting and
26500 display it. */
26501 if (!NILP (mouse_face) && STRINGP (object))
26503 /* The mouse-highlighting comes from a display string
26504 with a mouse-face. */
26505 Lisp_Object s, e;
26506 EMACS_INT ignore;
26508 s = Fprevious_single_property_change
26509 (make_number (pos + 1), Qmouse_face, object, Qnil);
26510 e = Fnext_single_property_change
26511 (position, Qmouse_face, object, Qnil);
26512 if (NILP (s))
26513 s = make_number (0);
26514 if (NILP (e))
26515 e = make_number (SCHARS (object) - 1);
26516 mouse_face_from_string_pos (w, hlinfo, object,
26517 XINT (s), XINT (e));
26518 hlinfo->mouse_face_past_end = 0;
26519 hlinfo->mouse_face_window = window;
26520 hlinfo->mouse_face_face_id
26521 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
26522 glyph->face_id, 1);
26523 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
26524 cursor = No_Cursor;
26526 else
26528 /* The mouse-highlighting, if any, comes from an overlay
26529 or text property in the buffer. */
26530 Lisp_Object buffer IF_LINT (= Qnil);
26531 Lisp_Object cover_string IF_LINT (= Qnil);
26533 if (STRINGP (object))
26535 /* If we are on a display string with no mouse-face,
26536 check if the text under it has one. */
26537 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
26538 EMACS_INT start = MATRIX_ROW_START_CHARPOS (r);
26539 pos = string_buffer_position (object, start);
26540 if (pos > 0)
26542 mouse_face = get_char_property_and_overlay
26543 (make_number (pos), Qmouse_face, w->buffer, &overlay);
26544 buffer = w->buffer;
26545 cover_string = object;
26548 else
26550 buffer = object;
26551 cover_string = Qnil;
26554 if (!NILP (mouse_face))
26556 Lisp_Object before, after;
26557 Lisp_Object before_string, after_string;
26558 /* To correctly find the limits of mouse highlight
26559 in a bidi-reordered buffer, we must not use the
26560 optimization of limiting the search in
26561 previous-single-property-change and
26562 next-single-property-change, because
26563 rows_from_pos_range needs the real start and end
26564 positions to DTRT in this case. That's because
26565 the first row visible in a window does not
26566 necessarily display the character whose position
26567 is the smallest. */
26568 Lisp_Object lim1 =
26569 NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
26570 ? Fmarker_position (w->start)
26571 : Qnil;
26572 Lisp_Object lim2 =
26573 NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
26574 ? make_number (BUF_Z (XBUFFER (buffer))
26575 - XFASTINT (w->window_end_pos))
26576 : Qnil;
26578 if (NILP (overlay))
26580 /* Handle the text property case. */
26581 before = Fprevious_single_property_change
26582 (make_number (pos + 1), Qmouse_face, buffer, lim1);
26583 after = Fnext_single_property_change
26584 (make_number (pos), Qmouse_face, buffer, lim2);
26585 before_string = after_string = Qnil;
26587 else
26589 /* Handle the overlay case. */
26590 before = Foverlay_start (overlay);
26591 after = Foverlay_end (overlay);
26592 before_string = Foverlay_get (overlay, Qbefore_string);
26593 after_string = Foverlay_get (overlay, Qafter_string);
26595 if (!STRINGP (before_string)) before_string = Qnil;
26596 if (!STRINGP (after_string)) after_string = Qnil;
26599 mouse_face_from_buffer_pos (window, hlinfo, pos,
26600 XFASTINT (before),
26601 XFASTINT (after),
26602 before_string, after_string,
26603 cover_string);
26604 cursor = No_Cursor;
26609 check_help_echo:
26611 /* Look for a `help-echo' property. */
26612 if (NILP (help_echo_string)) {
26613 Lisp_Object help, overlay;
26615 /* Check overlays first. */
26616 help = overlay = Qnil;
26617 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
26619 overlay = overlay_vec[i];
26620 help = Foverlay_get (overlay, Qhelp_echo);
26623 if (!NILP (help))
26625 help_echo_string = help;
26626 help_echo_window = window;
26627 help_echo_object = overlay;
26628 help_echo_pos = pos;
26630 else
26632 Lisp_Object obj = glyph->object;
26633 EMACS_INT charpos = glyph->charpos;
26635 /* Try text properties. */
26636 if (STRINGP (obj)
26637 && charpos >= 0
26638 && charpos < SCHARS (obj))
26640 help = Fget_text_property (make_number (charpos),
26641 Qhelp_echo, obj);
26642 if (NILP (help))
26644 /* If the string itself doesn't specify a help-echo,
26645 see if the buffer text ``under'' it does. */
26646 struct glyph_row *r
26647 = MATRIX_ROW (w->current_matrix, vpos);
26648 EMACS_INT start = MATRIX_ROW_START_CHARPOS (r);
26649 EMACS_INT p = string_buffer_position (obj, start);
26650 if (p > 0)
26652 help = Fget_char_property (make_number (p),
26653 Qhelp_echo, w->buffer);
26654 if (!NILP (help))
26656 charpos = p;
26657 obj = w->buffer;
26662 else if (BUFFERP (obj)
26663 && charpos >= BEGV
26664 && charpos < ZV)
26665 help = Fget_text_property (make_number (charpos), Qhelp_echo,
26666 obj);
26668 if (!NILP (help))
26670 help_echo_string = help;
26671 help_echo_window = window;
26672 help_echo_object = obj;
26673 help_echo_pos = charpos;
26678 #ifdef HAVE_WINDOW_SYSTEM
26679 /* Look for a `pointer' property. */
26680 if (FRAME_WINDOW_P (f) && NILP (pointer))
26682 /* Check overlays first. */
26683 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
26684 pointer = Foverlay_get (overlay_vec[i], Qpointer);
26686 if (NILP (pointer))
26688 Lisp_Object obj = glyph->object;
26689 EMACS_INT charpos = glyph->charpos;
26691 /* Try text properties. */
26692 if (STRINGP (obj)
26693 && charpos >= 0
26694 && charpos < SCHARS (obj))
26696 pointer = Fget_text_property (make_number (charpos),
26697 Qpointer, obj);
26698 if (NILP (pointer))
26700 /* If the string itself doesn't specify a pointer,
26701 see if the buffer text ``under'' it does. */
26702 struct glyph_row *r
26703 = MATRIX_ROW (w->current_matrix, vpos);
26704 EMACS_INT start = MATRIX_ROW_START_CHARPOS (r);
26705 EMACS_INT p = string_buffer_position (obj, start);
26706 if (p > 0)
26707 pointer = Fget_char_property (make_number (p),
26708 Qpointer, w->buffer);
26711 else if (BUFFERP (obj)
26712 && charpos >= BEGV
26713 && charpos < ZV)
26714 pointer = Fget_text_property (make_number (charpos),
26715 Qpointer, obj);
26718 #endif /* HAVE_WINDOW_SYSTEM */
26720 BEGV = obegv;
26721 ZV = ozv;
26722 current_buffer = obuf;
26725 set_cursor:
26727 #ifdef HAVE_WINDOW_SYSTEM
26728 if (FRAME_WINDOW_P (f))
26729 define_frame_cursor1 (f, cursor, pointer);
26730 #else
26731 /* This is here to prevent a compiler error, about "label at end of
26732 compound statement". */
26733 return;
26734 #endif
26738 /* EXPORT for RIF:
26739 Clear any mouse-face on window W. This function is part of the
26740 redisplay interface, and is called from try_window_id and similar
26741 functions to ensure the mouse-highlight is off. */
26743 void
26744 x_clear_window_mouse_face (struct window *w)
26746 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
26747 Lisp_Object window;
26749 BLOCK_INPUT;
26750 XSETWINDOW (window, w);
26751 if (EQ (window, hlinfo->mouse_face_window))
26752 clear_mouse_face (hlinfo);
26753 UNBLOCK_INPUT;
26757 /* EXPORT:
26758 Just discard the mouse face information for frame F, if any.
26759 This is used when the size of F is changed. */
26761 void
26762 cancel_mouse_face (struct frame *f)
26764 Lisp_Object window;
26765 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
26767 window = hlinfo->mouse_face_window;
26768 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
26770 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
26771 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
26772 hlinfo->mouse_face_window = Qnil;
26778 /***********************************************************************
26779 Exposure Events
26780 ***********************************************************************/
26782 #ifdef HAVE_WINDOW_SYSTEM
26784 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
26785 which intersects rectangle R. R is in window-relative coordinates. */
26787 static void
26788 expose_area (struct window *w, struct glyph_row *row, XRectangle *r,
26789 enum glyph_row_area area)
26791 struct glyph *first = row->glyphs[area];
26792 struct glyph *end = row->glyphs[area] + row->used[area];
26793 struct glyph *last;
26794 int first_x, start_x, x;
26796 if (area == TEXT_AREA && row->fill_line_p)
26797 /* If row extends face to end of line write the whole line. */
26798 draw_glyphs (w, 0, row, area,
26799 0, row->used[area],
26800 DRAW_NORMAL_TEXT, 0);
26801 else
26803 /* Set START_X to the window-relative start position for drawing glyphs of
26804 AREA. The first glyph of the text area can be partially visible.
26805 The first glyphs of other areas cannot. */
26806 start_x = window_box_left_offset (w, area);
26807 x = start_x;
26808 if (area == TEXT_AREA)
26809 x += row->x;
26811 /* Find the first glyph that must be redrawn. */
26812 while (first < end
26813 && x + first->pixel_width < r->x)
26815 x += first->pixel_width;
26816 ++first;
26819 /* Find the last one. */
26820 last = first;
26821 first_x = x;
26822 while (last < end
26823 && x < r->x + r->width)
26825 x += last->pixel_width;
26826 ++last;
26829 /* Repaint. */
26830 if (last > first)
26831 draw_glyphs (w, first_x - start_x, row, area,
26832 first - row->glyphs[area], last - row->glyphs[area],
26833 DRAW_NORMAL_TEXT, 0);
26838 /* Redraw the parts of the glyph row ROW on window W intersecting
26839 rectangle R. R is in window-relative coordinates. Value is
26840 non-zero if mouse-face was overwritten. */
26842 static int
26843 expose_line (struct window *w, struct glyph_row *row, XRectangle *r)
26845 xassert (row->enabled_p);
26847 if (row->mode_line_p || w->pseudo_window_p)
26848 draw_glyphs (w, 0, row, TEXT_AREA,
26849 0, row->used[TEXT_AREA],
26850 DRAW_NORMAL_TEXT, 0);
26851 else
26853 if (row->used[LEFT_MARGIN_AREA])
26854 expose_area (w, row, r, LEFT_MARGIN_AREA);
26855 if (row->used[TEXT_AREA])
26856 expose_area (w, row, r, TEXT_AREA);
26857 if (row->used[RIGHT_MARGIN_AREA])
26858 expose_area (w, row, r, RIGHT_MARGIN_AREA);
26859 draw_row_fringe_bitmaps (w, row);
26862 return row->mouse_face_p;
26866 /* Redraw those parts of glyphs rows during expose event handling that
26867 overlap other rows. Redrawing of an exposed line writes over parts
26868 of lines overlapping that exposed line; this function fixes that.
26870 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
26871 row in W's current matrix that is exposed and overlaps other rows.
26872 LAST_OVERLAPPING_ROW is the last such row. */
26874 static void
26875 expose_overlaps (struct window *w,
26876 struct glyph_row *first_overlapping_row,
26877 struct glyph_row *last_overlapping_row,
26878 XRectangle *r)
26880 struct glyph_row *row;
26882 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
26883 if (row->overlapping_p)
26885 xassert (row->enabled_p && !row->mode_line_p);
26887 row->clip = r;
26888 if (row->used[LEFT_MARGIN_AREA])
26889 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA, OVERLAPS_BOTH);
26891 if (row->used[TEXT_AREA])
26892 x_fix_overlapping_area (w, row, TEXT_AREA, OVERLAPS_BOTH);
26894 if (row->used[RIGHT_MARGIN_AREA])
26895 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, OVERLAPS_BOTH);
26896 row->clip = NULL;
26901 /* Return non-zero if W's cursor intersects rectangle R. */
26903 static int
26904 phys_cursor_in_rect_p (struct window *w, XRectangle *r)
26906 XRectangle cr, result;
26907 struct glyph *cursor_glyph;
26908 struct glyph_row *row;
26910 if (w->phys_cursor.vpos >= 0
26911 && w->phys_cursor.vpos < w->current_matrix->nrows
26912 && (row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos),
26913 row->enabled_p)
26914 && row->cursor_in_fringe_p)
26916 /* Cursor is in the fringe. */
26917 cr.x = window_box_right_offset (w,
26918 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
26919 ? RIGHT_MARGIN_AREA
26920 : TEXT_AREA));
26921 cr.y = row->y;
26922 cr.width = WINDOW_RIGHT_FRINGE_WIDTH (w);
26923 cr.height = row->height;
26924 return x_intersect_rectangles (&cr, r, &result);
26927 cursor_glyph = get_phys_cursor_glyph (w);
26928 if (cursor_glyph)
26930 /* r is relative to W's box, but w->phys_cursor.x is relative
26931 to left edge of W's TEXT area. Adjust it. */
26932 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
26933 cr.y = w->phys_cursor.y;
26934 cr.width = cursor_glyph->pixel_width;
26935 cr.height = w->phys_cursor_height;
26936 /* ++KFS: W32 version used W32-specific IntersectRect here, but
26937 I assume the effect is the same -- and this is portable. */
26938 return x_intersect_rectangles (&cr, r, &result);
26940 /* If we don't understand the format, pretend we're not in the hot-spot. */
26941 return 0;
26945 /* EXPORT:
26946 Draw a vertical window border to the right of window W if W doesn't
26947 have vertical scroll bars. */
26949 void
26950 x_draw_vertical_border (struct window *w)
26952 struct frame *f = XFRAME (WINDOW_FRAME (w));
26954 /* We could do better, if we knew what type of scroll-bar the adjacent
26955 windows (on either side) have... But we don't :-(
26956 However, I think this works ok. ++KFS 2003-04-25 */
26958 /* Redraw borders between horizontally adjacent windows. Don't
26959 do it for frames with vertical scroll bars because either the
26960 right scroll bar of a window, or the left scroll bar of its
26961 neighbor will suffice as a border. */
26962 if (FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (w->frame)))
26963 return;
26965 if (!WINDOW_RIGHTMOST_P (w)
26966 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
26968 int x0, x1, y0, y1;
26970 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
26971 y1 -= 1;
26973 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
26974 x1 -= 1;
26976 FRAME_RIF (f)->draw_vertical_window_border (w, x1, y0, y1);
26978 else if (!WINDOW_LEFTMOST_P (w)
26979 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
26981 int x0, x1, y0, y1;
26983 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
26984 y1 -= 1;
26986 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
26987 x0 -= 1;
26989 FRAME_RIF (f)->draw_vertical_window_border (w, x0, y0, y1);
26994 /* Redraw the part of window W intersection rectangle FR. Pixel
26995 coordinates in FR are frame-relative. Call this function with
26996 input blocked. Value is non-zero if the exposure overwrites
26997 mouse-face. */
26999 static int
27000 expose_window (struct window *w, XRectangle *fr)
27002 struct frame *f = XFRAME (w->frame);
27003 XRectangle wr, r;
27004 int mouse_face_overwritten_p = 0;
27006 /* If window is not yet fully initialized, do nothing. This can
27007 happen when toolkit scroll bars are used and a window is split.
27008 Reconfiguring the scroll bar will generate an expose for a newly
27009 created window. */
27010 if (w->current_matrix == NULL)
27011 return 0;
27013 /* When we're currently updating the window, display and current
27014 matrix usually don't agree. Arrange for a thorough display
27015 later. */
27016 if (w == updated_window)
27018 SET_FRAME_GARBAGED (f);
27019 return 0;
27022 /* Frame-relative pixel rectangle of W. */
27023 wr.x = WINDOW_LEFT_EDGE_X (w);
27024 wr.y = WINDOW_TOP_EDGE_Y (w);
27025 wr.width = WINDOW_TOTAL_WIDTH (w);
27026 wr.height = WINDOW_TOTAL_HEIGHT (w);
27028 if (x_intersect_rectangles (fr, &wr, &r))
27030 int yb = window_text_bottom_y (w);
27031 struct glyph_row *row;
27032 int cursor_cleared_p;
27033 struct glyph_row *first_overlapping_row, *last_overlapping_row;
27035 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
27036 r.x, r.y, r.width, r.height));
27038 /* Convert to window coordinates. */
27039 r.x -= WINDOW_LEFT_EDGE_X (w);
27040 r.y -= WINDOW_TOP_EDGE_Y (w);
27042 /* Turn off the cursor. */
27043 if (!w->pseudo_window_p
27044 && phys_cursor_in_rect_p (w, &r))
27046 x_clear_cursor (w);
27047 cursor_cleared_p = 1;
27049 else
27050 cursor_cleared_p = 0;
27052 /* Update lines intersecting rectangle R. */
27053 first_overlapping_row = last_overlapping_row = NULL;
27054 for (row = w->current_matrix->rows;
27055 row->enabled_p;
27056 ++row)
27058 int y0 = row->y;
27059 int y1 = MATRIX_ROW_BOTTOM_Y (row);
27061 if ((y0 >= r.y && y0 < r.y + r.height)
27062 || (y1 > r.y && y1 < r.y + r.height)
27063 || (r.y >= y0 && r.y < y1)
27064 || (r.y + r.height > y0 && r.y + r.height < y1))
27066 /* A header line may be overlapping, but there is no need
27067 to fix overlapping areas for them. KFS 2005-02-12 */
27068 if (row->overlapping_p && !row->mode_line_p)
27070 if (first_overlapping_row == NULL)
27071 first_overlapping_row = row;
27072 last_overlapping_row = row;
27075 row->clip = fr;
27076 if (expose_line (w, row, &r))
27077 mouse_face_overwritten_p = 1;
27078 row->clip = NULL;
27080 else if (row->overlapping_p)
27082 /* We must redraw a row overlapping the exposed area. */
27083 if (y0 < r.y
27084 ? y0 + row->phys_height > r.y
27085 : y0 + row->ascent - row->phys_ascent < r.y +r.height)
27087 if (first_overlapping_row == NULL)
27088 first_overlapping_row = row;
27089 last_overlapping_row = row;
27093 if (y1 >= yb)
27094 break;
27097 /* Display the mode line if there is one. */
27098 if (WINDOW_WANTS_MODELINE_P (w)
27099 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
27100 row->enabled_p)
27101 && row->y < r.y + r.height)
27103 if (expose_line (w, row, &r))
27104 mouse_face_overwritten_p = 1;
27107 if (!w->pseudo_window_p)
27109 /* Fix the display of overlapping rows. */
27110 if (first_overlapping_row)
27111 expose_overlaps (w, first_overlapping_row, last_overlapping_row,
27112 fr);
27114 /* Draw border between windows. */
27115 x_draw_vertical_border (w);
27117 /* Turn the cursor on again. */
27118 if (cursor_cleared_p)
27119 update_window_cursor (w, 1);
27123 return mouse_face_overwritten_p;
27128 /* Redraw (parts) of all windows in the window tree rooted at W that
27129 intersect R. R contains frame pixel coordinates. Value is
27130 non-zero if the exposure overwrites mouse-face. */
27132 static int
27133 expose_window_tree (struct window *w, XRectangle *r)
27135 struct frame *f = XFRAME (w->frame);
27136 int mouse_face_overwritten_p = 0;
27138 while (w && !FRAME_GARBAGED_P (f))
27140 if (!NILP (w->hchild))
27141 mouse_face_overwritten_p
27142 |= expose_window_tree (XWINDOW (w->hchild), r);
27143 else if (!NILP (w->vchild))
27144 mouse_face_overwritten_p
27145 |= expose_window_tree (XWINDOW (w->vchild), r);
27146 else
27147 mouse_face_overwritten_p |= expose_window (w, r);
27149 w = NILP (w->next) ? NULL : XWINDOW (w->next);
27152 return mouse_face_overwritten_p;
27156 /* EXPORT:
27157 Redisplay an exposed area of frame F. X and Y are the upper-left
27158 corner of the exposed rectangle. W and H are width and height of
27159 the exposed area. All are pixel values. W or H zero means redraw
27160 the entire frame. */
27162 void
27163 expose_frame (struct frame *f, int x, int y, int w, int h)
27165 XRectangle r;
27166 int mouse_face_overwritten_p = 0;
27168 TRACE ((stderr, "expose_frame "));
27170 /* No need to redraw if frame will be redrawn soon. */
27171 if (FRAME_GARBAGED_P (f))
27173 TRACE ((stderr, " garbaged\n"));
27174 return;
27177 /* If basic faces haven't been realized yet, there is no point in
27178 trying to redraw anything. This can happen when we get an expose
27179 event while Emacs is starting, e.g. by moving another window. */
27180 if (FRAME_FACE_CACHE (f) == NULL
27181 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
27183 TRACE ((stderr, " no faces\n"));
27184 return;
27187 if (w == 0 || h == 0)
27189 r.x = r.y = 0;
27190 r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f);
27191 r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f);
27193 else
27195 r.x = x;
27196 r.y = y;
27197 r.width = w;
27198 r.height = h;
27201 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
27202 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
27204 if (WINDOWP (f->tool_bar_window))
27205 mouse_face_overwritten_p
27206 |= expose_window (XWINDOW (f->tool_bar_window), &r);
27208 #ifdef HAVE_X_WINDOWS
27209 #ifndef MSDOS
27210 #ifndef USE_X_TOOLKIT
27211 if (WINDOWP (f->menu_bar_window))
27212 mouse_face_overwritten_p
27213 |= expose_window (XWINDOW (f->menu_bar_window), &r);
27214 #endif /* not USE_X_TOOLKIT */
27215 #endif
27216 #endif
27218 /* Some window managers support a focus-follows-mouse style with
27219 delayed raising of frames. Imagine a partially obscured frame,
27220 and moving the mouse into partially obscured mouse-face on that
27221 frame. The visible part of the mouse-face will be highlighted,
27222 then the WM raises the obscured frame. With at least one WM, KDE
27223 2.1, Emacs is not getting any event for the raising of the frame
27224 (even tried with SubstructureRedirectMask), only Expose events.
27225 These expose events will draw text normally, i.e. not
27226 highlighted. Which means we must redo the highlight here.
27227 Subsume it under ``we love X''. --gerd 2001-08-15 */
27228 /* Included in Windows version because Windows most likely does not
27229 do the right thing if any third party tool offers
27230 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
27231 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
27233 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
27234 if (f == hlinfo->mouse_face_mouse_frame)
27236 int mouse_x = hlinfo->mouse_face_mouse_x;
27237 int mouse_y = hlinfo->mouse_face_mouse_y;
27238 clear_mouse_face (hlinfo);
27239 note_mouse_highlight (f, mouse_x, mouse_y);
27245 /* EXPORT:
27246 Determine the intersection of two rectangles R1 and R2. Return
27247 the intersection in *RESULT. Value is non-zero if RESULT is not
27248 empty. */
27251 x_intersect_rectangles (XRectangle *r1, XRectangle *r2, XRectangle *result)
27253 XRectangle *left, *right;
27254 XRectangle *upper, *lower;
27255 int intersection_p = 0;
27257 /* Rearrange so that R1 is the left-most rectangle. */
27258 if (r1->x < r2->x)
27259 left = r1, right = r2;
27260 else
27261 left = r2, right = r1;
27263 /* X0 of the intersection is right.x0, if this is inside R1,
27264 otherwise there is no intersection. */
27265 if (right->x <= left->x + left->width)
27267 result->x = right->x;
27269 /* The right end of the intersection is the minimum of
27270 the right ends of left and right. */
27271 result->width = (min (left->x + left->width, right->x + right->width)
27272 - result->x);
27274 /* Same game for Y. */
27275 if (r1->y < r2->y)
27276 upper = r1, lower = r2;
27277 else
27278 upper = r2, lower = r1;
27280 /* The upper end of the intersection is lower.y0, if this is inside
27281 of upper. Otherwise, there is no intersection. */
27282 if (lower->y <= upper->y + upper->height)
27284 result->y = lower->y;
27286 /* The lower end of the intersection is the minimum of the lower
27287 ends of upper and lower. */
27288 result->height = (min (lower->y + lower->height,
27289 upper->y + upper->height)
27290 - result->y);
27291 intersection_p = 1;
27295 return intersection_p;
27298 #endif /* HAVE_WINDOW_SYSTEM */
27301 /***********************************************************************
27302 Initialization
27303 ***********************************************************************/
27305 void
27306 syms_of_xdisp (void)
27308 Vwith_echo_area_save_vector = Qnil;
27309 staticpro (&Vwith_echo_area_save_vector);
27311 Vmessage_stack = Qnil;
27312 staticpro (&Vmessage_stack);
27314 DEFSYM (Qinhibit_redisplay, "inhibit-redisplay");
27316 message_dolog_marker1 = Fmake_marker ();
27317 staticpro (&message_dolog_marker1);
27318 message_dolog_marker2 = Fmake_marker ();
27319 staticpro (&message_dolog_marker2);
27320 message_dolog_marker3 = Fmake_marker ();
27321 staticpro (&message_dolog_marker3);
27323 #if GLYPH_DEBUG
27324 defsubr (&Sdump_frame_glyph_matrix);
27325 defsubr (&Sdump_glyph_matrix);
27326 defsubr (&Sdump_glyph_row);
27327 defsubr (&Sdump_tool_bar_row);
27328 defsubr (&Strace_redisplay);
27329 defsubr (&Strace_to_stderr);
27330 #endif
27331 #ifdef HAVE_WINDOW_SYSTEM
27332 defsubr (&Stool_bar_lines_needed);
27333 defsubr (&Slookup_image_map);
27334 #endif
27335 defsubr (&Sformat_mode_line);
27336 defsubr (&Sinvisible_p);
27337 defsubr (&Scurrent_bidi_paragraph_direction);
27339 DEFSYM (Qmenu_bar_update_hook, "menu-bar-update-hook");
27340 DEFSYM (Qoverriding_terminal_local_map, "overriding-terminal-local-map");
27341 DEFSYM (Qoverriding_local_map, "overriding-local-map");
27342 DEFSYM (Qwindow_scroll_functions, "window-scroll-functions");
27343 DEFSYM (Qwindow_text_change_functions, "window-text-change-functions");
27344 DEFSYM (Qredisplay_end_trigger_functions, "redisplay-end-trigger-functions");
27345 DEFSYM (Qinhibit_point_motion_hooks, "inhibit-point-motion-hooks");
27346 DEFSYM (Qeval, "eval");
27347 DEFSYM (QCdata, ":data");
27348 DEFSYM (Qdisplay, "display");
27349 DEFSYM (Qspace_width, "space-width");
27350 DEFSYM (Qraise, "raise");
27351 DEFSYM (Qslice, "slice");
27352 DEFSYM (Qspace, "space");
27353 DEFSYM (Qmargin, "margin");
27354 DEFSYM (Qpointer, "pointer");
27355 DEFSYM (Qleft_margin, "left-margin");
27356 DEFSYM (Qright_margin, "right-margin");
27357 DEFSYM (Qcenter, "center");
27358 DEFSYM (Qline_height, "line-height");
27359 DEFSYM (QCalign_to, ":align-to");
27360 DEFSYM (QCrelative_width, ":relative-width");
27361 DEFSYM (QCrelative_height, ":relative-height");
27362 DEFSYM (QCeval, ":eval");
27363 DEFSYM (QCpropertize, ":propertize");
27364 DEFSYM (QCfile, ":file");
27365 DEFSYM (Qfontified, "fontified");
27366 DEFSYM (Qfontification_functions, "fontification-functions");
27367 DEFSYM (Qtrailing_whitespace, "trailing-whitespace");
27368 DEFSYM (Qescape_glyph, "escape-glyph");
27369 DEFSYM (Qnobreak_space, "nobreak-space");
27370 DEFSYM (Qimage, "image");
27371 DEFSYM (Qtext, "text");
27372 DEFSYM (Qboth, "both");
27373 DEFSYM (Qboth_horiz, "both-horiz");
27374 DEFSYM (Qtext_image_horiz, "text-image-horiz");
27375 DEFSYM (QCmap, ":map");
27376 DEFSYM (QCpointer, ":pointer");
27377 DEFSYM (Qrect, "rect");
27378 DEFSYM (Qcircle, "circle");
27379 DEFSYM (Qpoly, "poly");
27380 DEFSYM (Qmessage_truncate_lines, "message-truncate-lines");
27381 DEFSYM (Qgrow_only, "grow-only");
27382 DEFSYM (Qinhibit_menubar_update, "inhibit-menubar-update");
27383 DEFSYM (Qinhibit_eval_during_redisplay, "inhibit-eval-during-redisplay");
27384 DEFSYM (Qposition, "position");
27385 DEFSYM (Qbuffer_position, "buffer-position");
27386 DEFSYM (Qobject, "object");
27387 DEFSYM (Qbar, "bar");
27388 DEFSYM (Qhbar, "hbar");
27389 DEFSYM (Qbox, "box");
27390 DEFSYM (Qhollow, "hollow");
27391 DEFSYM (Qhand, "hand");
27392 DEFSYM (Qarrow, "arrow");
27393 DEFSYM (Qtext, "text");
27394 DEFSYM (Qinhibit_free_realized_faces, "inhibit-free-realized-faces");
27396 list_of_error = Fcons (Fcons (intern_c_string ("error"),
27397 Fcons (intern_c_string ("void-variable"), Qnil)),
27398 Qnil);
27399 staticpro (&list_of_error);
27401 DEFSYM (Qlast_arrow_position, "last-arrow-position");
27402 DEFSYM (Qlast_arrow_string, "last-arrow-string");
27403 DEFSYM (Qoverlay_arrow_string, "overlay-arrow-string");
27404 DEFSYM (Qoverlay_arrow_bitmap, "overlay-arrow-bitmap");
27406 echo_buffer[0] = echo_buffer[1] = Qnil;
27407 staticpro (&echo_buffer[0]);
27408 staticpro (&echo_buffer[1]);
27410 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
27411 staticpro (&echo_area_buffer[0]);
27412 staticpro (&echo_area_buffer[1]);
27414 Vmessages_buffer_name = make_pure_c_string ("*Messages*");
27415 staticpro (&Vmessages_buffer_name);
27417 mode_line_proptrans_alist = Qnil;
27418 staticpro (&mode_line_proptrans_alist);
27419 mode_line_string_list = Qnil;
27420 staticpro (&mode_line_string_list);
27421 mode_line_string_face = Qnil;
27422 staticpro (&mode_line_string_face);
27423 mode_line_string_face_prop = Qnil;
27424 staticpro (&mode_line_string_face_prop);
27425 Vmode_line_unwind_vector = Qnil;
27426 staticpro (&Vmode_line_unwind_vector);
27428 help_echo_string = Qnil;
27429 staticpro (&help_echo_string);
27430 help_echo_object = Qnil;
27431 staticpro (&help_echo_object);
27432 help_echo_window = Qnil;
27433 staticpro (&help_echo_window);
27434 previous_help_echo_string = Qnil;
27435 staticpro (&previous_help_echo_string);
27436 help_echo_pos = -1;
27438 DEFSYM (Qright_to_left, "right-to-left");
27439 DEFSYM (Qleft_to_right, "left-to-right");
27441 #ifdef HAVE_WINDOW_SYSTEM
27442 DEFVAR_BOOL ("x-stretch-cursor", x_stretch_cursor_p,
27443 doc: /* *Non-nil means draw block cursor as wide as the glyph under it.
27444 For example, if a block cursor is over a tab, it will be drawn as
27445 wide as that tab on the display. */);
27446 x_stretch_cursor_p = 0;
27447 #endif
27449 DEFVAR_LISP ("show-trailing-whitespace", Vshow_trailing_whitespace,
27450 doc: /* *Non-nil means highlight trailing whitespace.
27451 The face used for trailing whitespace is `trailing-whitespace'. */);
27452 Vshow_trailing_whitespace = Qnil;
27454 DEFVAR_LISP ("nobreak-char-display", Vnobreak_char_display,
27455 doc: /* *Control highlighting of nobreak space and soft hyphen.
27456 A value of t means highlight the character itself (for nobreak space,
27457 use face `nobreak-space').
27458 A value of nil means no highlighting.
27459 Other values mean display the escape glyph followed by an ordinary
27460 space or ordinary hyphen. */);
27461 Vnobreak_char_display = Qt;
27463 DEFVAR_LISP ("void-text-area-pointer", Vvoid_text_area_pointer,
27464 doc: /* *The pointer shape to show in void text areas.
27465 A value of nil means to show the text pointer. Other options are `arrow',
27466 `text', `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
27467 Vvoid_text_area_pointer = Qarrow;
27469 DEFVAR_LISP ("inhibit-redisplay", Vinhibit_redisplay,
27470 doc: /* Non-nil means don't actually do any redisplay.
27471 This is used for internal purposes. */);
27472 Vinhibit_redisplay = Qnil;
27474 DEFVAR_LISP ("global-mode-string", Vglobal_mode_string,
27475 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
27476 Vglobal_mode_string = Qnil;
27478 DEFVAR_LISP ("overlay-arrow-position", Voverlay_arrow_position,
27479 doc: /* Marker for where to display an arrow on top of the buffer text.
27480 This must be the beginning of a line in order to work.
27481 See also `overlay-arrow-string'. */);
27482 Voverlay_arrow_position = Qnil;
27484 DEFVAR_LISP ("overlay-arrow-string", Voverlay_arrow_string,
27485 doc: /* String to display as an arrow in non-window frames.
27486 See also `overlay-arrow-position'. */);
27487 Voverlay_arrow_string = make_pure_c_string ("=>");
27489 DEFVAR_LISP ("overlay-arrow-variable-list", Voverlay_arrow_variable_list,
27490 doc: /* List of variables (symbols) which hold markers for overlay arrows.
27491 The symbols on this list are examined during redisplay to determine
27492 where to display overlay arrows. */);
27493 Voverlay_arrow_variable_list
27494 = Fcons (intern_c_string ("overlay-arrow-position"), Qnil);
27496 DEFVAR_INT ("scroll-step", emacs_scroll_step,
27497 doc: /* *The number of lines to try scrolling a window by when point moves out.
27498 If that fails to bring point back on frame, point is centered instead.
27499 If this is zero, point is always centered after it moves off frame.
27500 If you want scrolling to always be a line at a time, you should set
27501 `scroll-conservatively' to a large value rather than set this to 1. */);
27503 DEFVAR_INT ("scroll-conservatively", scroll_conservatively,
27504 doc: /* *Scroll up to this many lines, to bring point back on screen.
27505 If point moves off-screen, redisplay will scroll by up to
27506 `scroll-conservatively' lines in order to bring point just barely
27507 onto the screen again. If that cannot be done, then redisplay
27508 recenters point as usual.
27510 If the value is greater than 100, redisplay will never recenter point,
27511 but will always scroll just enough text to bring point into view, even
27512 if you move far away.
27514 A value of zero means always recenter point if it moves off screen. */);
27515 scroll_conservatively = 0;
27517 DEFVAR_INT ("scroll-margin", scroll_margin,
27518 doc: /* *Number of lines of margin at the top and bottom of a window.
27519 Recenter the window whenever point gets within this many lines
27520 of the top or bottom of the window. */);
27521 scroll_margin = 0;
27523 DEFVAR_LISP ("display-pixels-per-inch", Vdisplay_pixels_per_inch,
27524 doc: /* Pixels per inch value for non-window system displays.
27525 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
27526 Vdisplay_pixels_per_inch = make_float (72.0);
27528 #if GLYPH_DEBUG
27529 DEFVAR_INT ("debug-end-pos", debug_end_pos, doc: /* Don't ask. */);
27530 #endif
27532 DEFVAR_LISP ("truncate-partial-width-windows",
27533 Vtruncate_partial_width_windows,
27534 doc: /* Non-nil means truncate lines in windows narrower than the frame.
27535 For an integer value, truncate lines in each window narrower than the
27536 full frame width, provided the window width is less than that integer;
27537 otherwise, respect the value of `truncate-lines'.
27539 For any other non-nil value, truncate lines in all windows that do
27540 not span the full frame width.
27542 A value of nil means to respect the value of `truncate-lines'.
27544 If `word-wrap' is enabled, you might want to reduce this. */);
27545 Vtruncate_partial_width_windows = make_number (50);
27547 DEFVAR_BOOL ("mode-line-inverse-video", mode_line_inverse_video,
27548 doc: /* When nil, display the mode-line/header-line/menu-bar in the default face.
27549 Any other value means to use the appropriate face, `mode-line',
27550 `header-line', or `menu' respectively. */);
27551 mode_line_inverse_video = 1;
27553 DEFVAR_LISP ("line-number-display-limit", Vline_number_display_limit,
27554 doc: /* *Maximum buffer size for which line number should be displayed.
27555 If the buffer is bigger than this, the line number does not appear
27556 in the mode line. A value of nil means no limit. */);
27557 Vline_number_display_limit = Qnil;
27559 DEFVAR_INT ("line-number-display-limit-width",
27560 line_number_display_limit_width,
27561 doc: /* *Maximum line width (in characters) for line number display.
27562 If the average length of the lines near point is bigger than this, then the
27563 line number may be omitted from the mode line. */);
27564 line_number_display_limit_width = 200;
27566 DEFVAR_BOOL ("highlight-nonselected-windows", highlight_nonselected_windows,
27567 doc: /* *Non-nil means highlight region even in nonselected windows. */);
27568 highlight_nonselected_windows = 0;
27570 DEFVAR_BOOL ("multiple-frames", multiple_frames,
27571 doc: /* Non-nil if more than one frame is visible on this display.
27572 Minibuffer-only frames don't count, but iconified frames do.
27573 This variable is not guaranteed to be accurate except while processing
27574 `frame-title-format' and `icon-title-format'. */);
27576 DEFVAR_LISP ("frame-title-format", Vframe_title_format,
27577 doc: /* Template for displaying the title bar of visible frames.
27578 \(Assuming the window manager supports this feature.)
27580 This variable has the same structure as `mode-line-format', except that
27581 the %c and %l constructs are ignored. It is used only on frames for
27582 which no explicit name has been set \(see `modify-frame-parameters'). */);
27584 DEFVAR_LISP ("icon-title-format", Vicon_title_format,
27585 doc: /* Template for displaying the title bar of an iconified frame.
27586 \(Assuming the window manager supports this feature.)
27587 This variable has the same structure as `mode-line-format' (which see),
27588 and is used only on frames for which no explicit name has been set
27589 \(see `modify-frame-parameters'). */);
27590 Vicon_title_format
27591 = Vframe_title_format
27592 = pure_cons (intern_c_string ("multiple-frames"),
27593 pure_cons (make_pure_c_string ("%b"),
27594 pure_cons (pure_cons (empty_unibyte_string,
27595 pure_cons (intern_c_string ("invocation-name"),
27596 pure_cons (make_pure_c_string ("@"),
27597 pure_cons (intern_c_string ("system-name"),
27598 Qnil)))),
27599 Qnil)));
27601 DEFVAR_LISP ("message-log-max", Vmessage_log_max,
27602 doc: /* Maximum number of lines to keep in the message log buffer.
27603 If nil, disable message logging. If t, log messages but don't truncate
27604 the buffer when it becomes large. */);
27605 Vmessage_log_max = make_number (100);
27607 DEFVAR_LISP ("window-size-change-functions", Vwindow_size_change_functions,
27608 doc: /* Functions called before redisplay, if window sizes have changed.
27609 The value should be a list of functions that take one argument.
27610 Just before redisplay, for each frame, if any of its windows have changed
27611 size since the last redisplay, or have been split or deleted,
27612 all the functions in the list are called, with the frame as argument. */);
27613 Vwindow_size_change_functions = Qnil;
27615 DEFVAR_LISP ("window-scroll-functions", Vwindow_scroll_functions,
27616 doc: /* List of functions to call before redisplaying a window with scrolling.
27617 Each function is called with two arguments, the window and its new
27618 display-start position. Note that these functions are also called by
27619 `set-window-buffer'. Also note that the value of `window-end' is not
27620 valid when these functions are called. */);
27621 Vwindow_scroll_functions = Qnil;
27623 DEFVAR_LISP ("window-text-change-functions",
27624 Vwindow_text_change_functions,
27625 doc: /* Functions to call in redisplay when text in the window might change. */);
27626 Vwindow_text_change_functions = Qnil;
27628 DEFVAR_LISP ("redisplay-end-trigger-functions", Vredisplay_end_trigger_functions,
27629 doc: /* Functions called when redisplay of a window reaches the end trigger.
27630 Each function is called with two arguments, the window and the end trigger value.
27631 See `set-window-redisplay-end-trigger'. */);
27632 Vredisplay_end_trigger_functions = Qnil;
27634 DEFVAR_LISP ("mouse-autoselect-window", Vmouse_autoselect_window,
27635 doc: /* *Non-nil means autoselect window with mouse pointer.
27636 If nil, do not autoselect windows.
27637 A positive number means delay autoselection by that many seconds: a
27638 window is autoselected only after the mouse has remained in that
27639 window for the duration of the delay.
27640 A negative number has a similar effect, but causes windows to be
27641 autoselected only after the mouse has stopped moving. \(Because of
27642 the way Emacs compares mouse events, you will occasionally wait twice
27643 that time before the window gets selected.\)
27644 Any other value means to autoselect window instantaneously when the
27645 mouse pointer enters it.
27647 Autoselection selects the minibuffer only if it is active, and never
27648 unselects the minibuffer if it is active.
27650 When customizing this variable make sure that the actual value of
27651 `focus-follows-mouse' matches the behavior of your window manager. */);
27652 Vmouse_autoselect_window = Qnil;
27654 DEFVAR_LISP ("auto-resize-tool-bars", Vauto_resize_tool_bars,
27655 doc: /* *Non-nil means automatically resize tool-bars.
27656 This dynamically changes the tool-bar's height to the minimum height
27657 that is needed to make all tool-bar items visible.
27658 If value is `grow-only', the tool-bar's height is only increased
27659 automatically; to decrease the tool-bar height, use \\[recenter]. */);
27660 Vauto_resize_tool_bars = Qt;
27662 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", auto_raise_tool_bar_buttons_p,
27663 doc: /* *Non-nil means raise tool-bar buttons when the mouse moves over them. */);
27664 auto_raise_tool_bar_buttons_p = 1;
27666 DEFVAR_BOOL ("make-cursor-line-fully-visible", make_cursor_line_fully_visible_p,
27667 doc: /* *Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
27668 make_cursor_line_fully_visible_p = 1;
27670 DEFVAR_LISP ("tool-bar-border", Vtool_bar_border,
27671 doc: /* *Border below tool-bar in pixels.
27672 If an integer, use it as the height of the border.
27673 If it is one of `internal-border-width' or `border-width', use the
27674 value of the corresponding frame parameter.
27675 Otherwise, no border is added below the tool-bar. */);
27676 Vtool_bar_border = Qinternal_border_width;
27678 DEFVAR_LISP ("tool-bar-button-margin", Vtool_bar_button_margin,
27679 doc: /* *Margin around tool-bar buttons in pixels.
27680 If an integer, use that for both horizontal and vertical margins.
27681 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
27682 HORZ specifying the horizontal margin, and VERT specifying the
27683 vertical margin. */);
27684 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
27686 DEFVAR_INT ("tool-bar-button-relief", tool_bar_button_relief,
27687 doc: /* *Relief thickness of tool-bar buttons. */);
27688 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
27690 DEFVAR_LISP ("tool-bar-style", Vtool_bar_style,
27691 doc: /* Tool bar style to use.
27692 It can be one of
27693 image - show images only
27694 text - show text only
27695 both - show both, text below image
27696 both-horiz - show text to the right of the image
27697 text-image-horiz - show text to the left of the image
27698 any other - use system default or image if no system default. */);
27699 Vtool_bar_style = Qnil;
27701 DEFVAR_INT ("tool-bar-max-label-size", tool_bar_max_label_size,
27702 doc: /* *Maximum number of characters a label can have to be shown.
27703 The tool bar style must also show labels for this to have any effect, see
27704 `tool-bar-style'. */);
27705 tool_bar_max_label_size = DEFAULT_TOOL_BAR_LABEL_SIZE;
27707 DEFVAR_LISP ("fontification-functions", Vfontification_functions,
27708 doc: /* List of functions to call to fontify regions of text.
27709 Each function is called with one argument POS. Functions must
27710 fontify a region starting at POS in the current buffer, and give
27711 fontified regions the property `fontified'. */);
27712 Vfontification_functions = Qnil;
27713 Fmake_variable_buffer_local (Qfontification_functions);
27715 DEFVAR_BOOL ("unibyte-display-via-language-environment",
27716 unibyte_display_via_language_environment,
27717 doc: /* *Non-nil means display unibyte text according to language environment.
27718 Specifically, this means that raw bytes in the range 160-255 decimal
27719 are displayed by converting them to the equivalent multibyte characters
27720 according to the current language environment. As a result, they are
27721 displayed according to the current fontset.
27723 Note that this variable affects only how these bytes are displayed,
27724 but does not change the fact they are interpreted as raw bytes. */);
27725 unibyte_display_via_language_environment = 0;
27727 DEFVAR_LISP ("max-mini-window-height", Vmax_mini_window_height,
27728 doc: /* *Maximum height for resizing mini-windows (the minibuffer and the echo area).
27729 If a float, it specifies a fraction of the mini-window frame's height.
27730 If an integer, it specifies a number of lines. */);
27731 Vmax_mini_window_height = make_float (0.25);
27733 DEFVAR_LISP ("resize-mini-windows", Vresize_mini_windows,
27734 doc: /* How to resize mini-windows (the minibuffer and the echo area).
27735 A value of nil means don't automatically resize mini-windows.
27736 A value of t means resize them to fit the text displayed in them.
27737 A value of `grow-only', the default, means let mini-windows grow only;
27738 they return to their normal size when the minibuffer is closed, or the
27739 echo area becomes empty. */);
27740 Vresize_mini_windows = Qgrow_only;
27742 DEFVAR_LISP ("blink-cursor-alist", Vblink_cursor_alist,
27743 doc: /* Alist specifying how to blink the cursor off.
27744 Each element has the form (ON-STATE . OFF-STATE). Whenever the
27745 `cursor-type' frame-parameter or variable equals ON-STATE,
27746 comparing using `equal', Emacs uses OFF-STATE to specify
27747 how to blink it off. ON-STATE and OFF-STATE are values for
27748 the `cursor-type' frame parameter.
27750 If a frame's ON-STATE has no entry in this list,
27751 the frame's other specifications determine how to blink the cursor off. */);
27752 Vblink_cursor_alist = Qnil;
27754 DEFVAR_BOOL ("auto-hscroll-mode", automatic_hscrolling_p,
27755 doc: /* Allow or disallow automatic horizontal scrolling of windows.
27756 If non-nil, windows are automatically scrolled horizontally to make
27757 point visible. */);
27758 automatic_hscrolling_p = 1;
27759 DEFSYM (Qauto_hscroll_mode, "auto-hscroll-mode");
27761 DEFVAR_INT ("hscroll-margin", hscroll_margin,
27762 doc: /* *How many columns away from the window edge point is allowed to get
27763 before automatic hscrolling will horizontally scroll the window. */);
27764 hscroll_margin = 5;
27766 DEFVAR_LISP ("hscroll-step", Vhscroll_step,
27767 doc: /* *How many columns to scroll the window when point gets too close to the edge.
27768 When point is less than `hscroll-margin' columns from the window
27769 edge, automatic hscrolling will scroll the window by the amount of columns
27770 determined by this variable. If its value is a positive integer, scroll that
27771 many columns. If it's a positive floating-point number, it specifies the
27772 fraction of the window's width to scroll. If it's nil or zero, point will be
27773 centered horizontally after the scroll. Any other value, including negative
27774 numbers, are treated as if the value were zero.
27776 Automatic hscrolling always moves point outside the scroll margin, so if
27777 point was more than scroll step columns inside the margin, the window will
27778 scroll more than the value given by the scroll step.
27780 Note that the lower bound for automatic hscrolling specified by `scroll-left'
27781 and `scroll-right' overrides this variable's effect. */);
27782 Vhscroll_step = make_number (0);
27784 DEFVAR_BOOL ("message-truncate-lines", message_truncate_lines,
27785 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
27786 Bind this around calls to `message' to let it take effect. */);
27787 message_truncate_lines = 0;
27789 DEFVAR_LISP ("menu-bar-update-hook", Vmenu_bar_update_hook,
27790 doc: /* Normal hook run to update the menu bar definitions.
27791 Redisplay runs this hook before it redisplays the menu bar.
27792 This is used to update submenus such as Buffers,
27793 whose contents depend on various data. */);
27794 Vmenu_bar_update_hook = Qnil;
27796 DEFVAR_LISP ("menu-updating-frame", Vmenu_updating_frame,
27797 doc: /* Frame for which we are updating a menu.
27798 The enable predicate for a menu binding should check this variable. */);
27799 Vmenu_updating_frame = Qnil;
27801 DEFVAR_BOOL ("inhibit-menubar-update", inhibit_menubar_update,
27802 doc: /* Non-nil means don't update menu bars. Internal use only. */);
27803 inhibit_menubar_update = 0;
27805 DEFVAR_LISP ("wrap-prefix", Vwrap_prefix,
27806 doc: /* Prefix prepended to all continuation lines at display time.
27807 The value may be a string, an image, or a stretch-glyph; it is
27808 interpreted in the same way as the value of a `display' text property.
27810 This variable is overridden by any `wrap-prefix' text or overlay
27811 property.
27813 To add a prefix to non-continuation lines, use `line-prefix'. */);
27814 Vwrap_prefix = Qnil;
27815 DEFSYM (Qwrap_prefix, "wrap-prefix");
27816 Fmake_variable_buffer_local (Qwrap_prefix);
27818 DEFVAR_LISP ("line-prefix", Vline_prefix,
27819 doc: /* Prefix prepended to all non-continuation lines at display time.
27820 The value may be a string, an image, or a stretch-glyph; it is
27821 interpreted in the same way as the value of a `display' text property.
27823 This variable is overridden by any `line-prefix' text or overlay
27824 property.
27826 To add a prefix to continuation lines, use `wrap-prefix'. */);
27827 Vline_prefix = Qnil;
27828 DEFSYM (Qline_prefix, "line-prefix");
27829 Fmake_variable_buffer_local (Qline_prefix);
27831 DEFVAR_BOOL ("inhibit-eval-during-redisplay", inhibit_eval_during_redisplay,
27832 doc: /* Non-nil means don't eval Lisp during redisplay. */);
27833 inhibit_eval_during_redisplay = 0;
27835 DEFVAR_BOOL ("inhibit-free-realized-faces", inhibit_free_realized_faces,
27836 doc: /* Non-nil means don't free realized faces. Internal use only. */);
27837 inhibit_free_realized_faces = 0;
27839 #if GLYPH_DEBUG
27840 DEFVAR_BOOL ("inhibit-try-window-id", inhibit_try_window_id,
27841 doc: /* Inhibit try_window_id display optimization. */);
27842 inhibit_try_window_id = 0;
27844 DEFVAR_BOOL ("inhibit-try-window-reusing", inhibit_try_window_reusing,
27845 doc: /* Inhibit try_window_reusing display optimization. */);
27846 inhibit_try_window_reusing = 0;
27848 DEFVAR_BOOL ("inhibit-try-cursor-movement", inhibit_try_cursor_movement,
27849 doc: /* Inhibit try_cursor_movement display optimization. */);
27850 inhibit_try_cursor_movement = 0;
27851 #endif /* GLYPH_DEBUG */
27853 DEFVAR_INT ("overline-margin", overline_margin,
27854 doc: /* *Space between overline and text, in pixels.
27855 The default value is 2: the height of the overline (1 pixel) plus 1 pixel
27856 margin to the caracter height. */);
27857 overline_margin = 2;
27859 DEFVAR_INT ("underline-minimum-offset",
27860 underline_minimum_offset,
27861 doc: /* Minimum distance between baseline and underline.
27862 This can improve legibility of underlined text at small font sizes,
27863 particularly when using variable `x-use-underline-position-properties'
27864 with fonts that specify an UNDERLINE_POSITION relatively close to the
27865 baseline. The default value is 1. */);
27866 underline_minimum_offset = 1;
27868 DEFVAR_BOOL ("display-hourglass", display_hourglass_p,
27869 doc: /* Non-nil means show an hourglass pointer, when Emacs is busy.
27870 This feature only works when on a window system that can change
27871 cursor shapes. */);
27872 display_hourglass_p = 1;
27874 DEFVAR_LISP ("hourglass-delay", Vhourglass_delay,
27875 doc: /* *Seconds to wait before displaying an hourglass pointer when Emacs is busy. */);
27876 Vhourglass_delay = make_number (DEFAULT_HOURGLASS_DELAY);
27878 hourglass_atimer = NULL;
27879 hourglass_shown_p = 0;
27881 DEFSYM (Qglyphless_char, "glyphless-char");
27882 DEFSYM (Qhex_code, "hex-code");
27883 DEFSYM (Qempty_box, "empty-box");
27884 DEFSYM (Qthin_space, "thin-space");
27885 DEFSYM (Qzero_width, "zero-width");
27887 DEFSYM (Qglyphless_char_display, "glyphless-char-display");
27888 /* Intern this now in case it isn't already done.
27889 Setting this variable twice is harmless.
27890 But don't staticpro it here--that is done in alloc.c. */
27891 Qchar_table_extra_slots = intern_c_string ("char-table-extra-slots");
27892 Fput (Qglyphless_char_display, Qchar_table_extra_slots, make_number (1));
27894 DEFVAR_LISP ("glyphless-char-display", Vglyphless_char_display,
27895 doc: /* Char-table defining glyphless characters.
27896 Each element, if non-nil, should be one of the following:
27897 an ASCII acronym string: display this string in a box
27898 `hex-code': display the hexadecimal code of a character in a box
27899 `empty-box': display as an empty box
27900 `thin-space': display as 1-pixel width space
27901 `zero-width': don't display
27902 An element may also be a cons cell (GRAPHICAL . TEXT), which specifies the
27903 display method for graphical terminals and text terminals respectively.
27904 GRAPHICAL and TEXT should each have one of the values listed above.
27906 The char-table has one extra slot to control the display of a character for
27907 which no font is found. This slot only takes effect on graphical terminals.
27908 Its value should be an ASCII acronym string, `hex-code', `empty-box', or
27909 `thin-space'. The default is `empty-box'. */);
27910 Vglyphless_char_display = Fmake_char_table (Qglyphless_char_display, Qnil);
27911 Fset_char_table_extra_slot (Vglyphless_char_display, make_number (0),
27912 Qempty_box);
27916 /* Initialize this module when Emacs starts. */
27918 void
27919 init_xdisp (void)
27921 current_header_line_height = current_mode_line_height = -1;
27923 CHARPOS (this_line_start_pos) = 0;
27925 if (!noninteractive)
27927 struct window *m = XWINDOW (minibuf_window);
27928 Lisp_Object frame = m->frame;
27929 struct frame *f = XFRAME (frame);
27930 Lisp_Object root = FRAME_ROOT_WINDOW (f);
27931 struct window *r = XWINDOW (root);
27932 int i;
27934 echo_area_window = minibuf_window;
27936 XSETFASTINT (r->top_line, FRAME_TOP_MARGIN (f));
27937 XSETFASTINT (r->total_lines, FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f));
27938 XSETFASTINT (r->total_cols, FRAME_COLS (f));
27939 XSETFASTINT (m->top_line, FRAME_LINES (f) - 1);
27940 XSETFASTINT (m->total_lines, 1);
27941 XSETFASTINT (m->total_cols, FRAME_COLS (f));
27943 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
27944 scratch_glyph_row.glyphs[TEXT_AREA + 1]
27945 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
27947 /* The default ellipsis glyphs `...'. */
27948 for (i = 0; i < 3; ++i)
27949 default_invis_vector[i] = make_number ('.');
27953 /* Allocate the buffer for frame titles.
27954 Also used for `format-mode-line'. */
27955 int size = 100;
27956 mode_line_noprop_buf = (char *) xmalloc (size);
27957 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
27958 mode_line_noprop_ptr = mode_line_noprop_buf;
27959 mode_line_target = MODE_LINE_DISPLAY;
27962 help_echo_showing_p = 0;
27965 /* Since w32 does not support atimers, it defines its own implementation of
27966 the following three functions in w32fns.c. */
27967 #ifndef WINDOWSNT
27969 /* Platform-independent portion of hourglass implementation. */
27971 /* Return non-zero if houglass timer has been started or hourglass is shown. */
27973 hourglass_started (void)
27975 return hourglass_shown_p || hourglass_atimer != NULL;
27978 /* Cancel a currently active hourglass timer, and start a new one. */
27979 void
27980 start_hourglass (void)
27982 #if defined (HAVE_WINDOW_SYSTEM)
27983 EMACS_TIME delay;
27984 int secs, usecs = 0;
27986 cancel_hourglass ();
27988 if (INTEGERP (Vhourglass_delay)
27989 && XINT (Vhourglass_delay) > 0)
27990 secs = XFASTINT (Vhourglass_delay);
27991 else if (FLOATP (Vhourglass_delay)
27992 && XFLOAT_DATA (Vhourglass_delay) > 0)
27994 Lisp_Object tem;
27995 tem = Ftruncate (Vhourglass_delay, Qnil);
27996 secs = XFASTINT (tem);
27997 usecs = (XFLOAT_DATA (Vhourglass_delay) - secs) * 1000000;
27999 else
28000 secs = DEFAULT_HOURGLASS_DELAY;
28002 EMACS_SET_SECS_USECS (delay, secs, usecs);
28003 hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
28004 show_hourglass, NULL);
28005 #endif
28009 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
28010 shown. */
28011 void
28012 cancel_hourglass (void)
28014 #if defined (HAVE_WINDOW_SYSTEM)
28015 if (hourglass_atimer)
28017 cancel_atimer (hourglass_atimer);
28018 hourglass_atimer = NULL;
28021 if (hourglass_shown_p)
28022 hide_hourglass ();
28023 #endif
28025 #endif /* ! WINDOWSNT */