Fix bug#7750.
[emacs.git] / src / xdisp.c
blobf7df35d059d0ad1c3c65353db1e7ee059d56d3e0
1 /* Display generation from window structure and buffer text.
3 Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995, 1997, 1998,
4 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
5 2010, 2011 Free Software Foundation, Inc.
7 This file is part of GNU Emacs.
9 GNU Emacs is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
14 GNU Emacs is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
22 /* New redisplay written by Gerd Moellmann <gerd@gnu.org>.
24 Redisplay.
26 Emacs separates the task of updating the display from code
27 modifying global state, e.g. buffer text. This way functions
28 operating on buffers don't also have to be concerned with updating
29 the display.
31 Updating the display is triggered by the Lisp interpreter when it
32 decides it's time to do it. This is done either automatically for
33 you as part of the interpreter's command loop or as the result of
34 calling Lisp functions like `sit-for'. The C function `redisplay'
35 in xdisp.c is the only entry into the inner redisplay code.
37 The following diagram shows how redisplay code is invoked. As you
38 can see, Lisp calls redisplay and vice versa. Under window systems
39 like X, some portions of the redisplay code are also called
40 asynchronously during mouse movement or expose events. It is very
41 important that these code parts do NOT use the C library (malloc,
42 free) because many C libraries under Unix are not reentrant. They
43 may also NOT call functions of the Lisp interpreter which could
44 change the interpreter's state. If you don't follow these rules,
45 you will encounter bugs which are very hard to explain.
47 +--------------+ redisplay +----------------+
48 | Lisp machine |---------------->| Redisplay code |<--+
49 +--------------+ (xdisp.c) +----------------+ |
50 ^ | |
51 +----------------------------------+ |
52 Don't use this path when called |
53 asynchronously! |
55 expose_window (asynchronous) |
57 X expose events -----+
59 What does redisplay do? Obviously, it has to figure out somehow what
60 has been changed since the last time the display has been updated,
61 and to make these changes visible. Preferably it would do that in
62 a moderately intelligent way, i.e. fast.
64 Changes in buffer text can be deduced from window and buffer
65 structures, and from some global variables like `beg_unchanged' and
66 `end_unchanged'. The contents of the display are additionally
67 recorded in a `glyph matrix', a two-dimensional matrix of glyph
68 structures. Each row in such a matrix corresponds to a line on the
69 display, and each glyph in a row corresponds to a column displaying
70 a character, an image, or what else. This matrix is called the
71 `current glyph matrix' or `current matrix' in redisplay
72 terminology.
74 For buffer parts that have been changed since the last update, a
75 second glyph matrix is constructed, the so called `desired glyph
76 matrix' or short `desired matrix'. Current and desired matrix are
77 then compared to find a cheap way to update the display, e.g. by
78 reusing part of the display by scrolling lines.
80 You will find a lot of redisplay optimizations when you start
81 looking at the innards of redisplay. The overall goal of all these
82 optimizations is to make redisplay fast because it is done
83 frequently. Some of these optimizations are implemented by the
84 following functions:
86 . try_cursor_movement
88 This function tries to update the display if the text in the
89 window did not change and did not scroll, only point moved, and
90 it did not move off the displayed portion of the text.
92 . try_window_reusing_current_matrix
94 This function reuses the current matrix of a window when text
95 has not changed, but the window start changed (e.g., due to
96 scrolling).
98 . try_window_id
100 This function attempts to redisplay a window by reusing parts of
101 its existing display. It finds and reuses the part that was not
102 changed, and redraws the rest.
104 . try_window
106 This function performs the full redisplay of a single window
107 assuming that its fonts were not changed and that the cursor
108 will not end up in the scroll margins. (Loading fonts requires
109 re-adjustment of dimensions of glyph matrices, which makes this
110 method impossible to use.)
112 These optimizations are tried in sequence (some can be skipped if
113 it is known that they are not applicable). If none of the
114 optimizations were successful, redisplay calls redisplay_windows,
115 which performs a full redisplay of all windows.
117 Desired matrices.
119 Desired matrices are always built per Emacs window. The function
120 `display_line' is the central function to look at if you are
121 interested. It constructs one row in a desired matrix given an
122 iterator structure containing both a buffer position and a
123 description of the environment in which the text is to be
124 displayed. But this is too early, read on.
126 Characters and pixmaps displayed for a range of buffer text depend
127 on various settings of buffers and windows, on overlays and text
128 properties, on display tables, on selective display. The good news
129 is that all this hairy stuff is hidden behind a small set of
130 interface functions taking an iterator structure (struct it)
131 argument.
133 Iteration over things to be displayed is then simple. It is
134 started by initializing an iterator with a call to init_iterator.
135 Calls to get_next_display_element fill the iterator structure with
136 relevant information about the next thing to display. Calls to
137 set_iterator_to_next move the iterator to the next thing.
139 Besides this, an iterator also contains information about the
140 display environment in which glyphs for display elements are to be
141 produced. It has fields for the width and height of the display,
142 the information whether long lines are truncated or continued, a
143 current X and Y position, and lots of other stuff you can better
144 see in dispextern.h.
146 Glyphs in a desired matrix are normally constructed in a loop
147 calling get_next_display_element and then PRODUCE_GLYPHS. The call
148 to PRODUCE_GLYPHS will fill the iterator structure with pixel
149 information about the element being displayed and at the same time
150 produce glyphs for it. If the display element fits on the line
151 being displayed, set_iterator_to_next is called next, otherwise the
152 glyphs produced are discarded. The function display_line is the
153 workhorse of filling glyph rows in the desired matrix with glyphs.
154 In addition to producing glyphs, it also handles line truncation
155 and continuation, word wrap, and cursor positioning (for the
156 latter, see also set_cursor_from_row).
158 Frame matrices.
160 That just couldn't be all, could it? What about terminal types not
161 supporting operations on sub-windows of the screen? To update the
162 display on such a terminal, window-based glyph matrices are not
163 well suited. To be able to reuse part of the display (scrolling
164 lines up and down), we must instead have a view of the whole
165 screen. This is what `frame matrices' are for. They are a trick.
167 Frames on terminals like above have a glyph pool. Windows on such
168 a frame sub-allocate their glyph memory from their frame's glyph
169 pool. The frame itself is given its own glyph matrices. By
170 coincidence---or maybe something else---rows in window glyph
171 matrices are slices of corresponding rows in frame matrices. Thus
172 writing to window matrices implicitly updates a frame matrix which
173 provides us with the view of the whole screen that we originally
174 wanted to have without having to move many bytes around. To be
175 honest, there is a little bit more done, but not much more. If you
176 plan to extend that code, take a look at dispnew.c. The function
177 build_frame_matrix is a good starting point.
179 Bidirectional display.
181 Bidirectional display adds quite some hair to this already complex
182 design. The good news are that a large portion of that hairy stuff
183 is hidden in bidi.c behind only 3 interfaces. bidi.c implements a
184 reordering engine which is called by set_iterator_to_next and
185 returns the next character to display in the visual order. See
186 commentary on bidi.c for more details. As far as redisplay is
187 concerned, the effect of calling bidi_move_to_visually_next, the
188 main interface of the reordering engine, is that the iterator gets
189 magically placed on the buffer or string position that is to be
190 displayed next. In other words, a linear iteration through the
191 buffer/string is replaced with a non-linear one. All the rest of
192 the redisplay is oblivious to the bidi reordering.
194 Well, almost oblivious---there are still complications, most of
195 them due to the fact that buffer and string positions no longer
196 change monotonously with glyph indices in a glyph row. Moreover,
197 for continued lines, the buffer positions may not even be
198 monotonously changing with vertical positions. Also, accounting
199 for face changes, overlays, etc. becomes more complex because
200 non-linear iteration could potentially skip many positions with
201 changes, and then cross them again on the way back...
203 One other prominent effect of bidirectional display is that some
204 paragraphs of text need to be displayed starting at the right
205 margin of the window---the so-called right-to-left, or R2L
206 paragraphs. R2L paragraphs are displayed with R2L glyph rows,
207 which have their reversed_p flag set. The bidi reordering engine
208 produces characters in such rows starting from the character which
209 should be the rightmost on display. PRODUCE_GLYPHS then reverses
210 the order, when it fills up the glyph row whose reversed_p flag is
211 set, by prepending each new glyph to what is already there, instead
212 of appending it. When the glyph row is complete, the function
213 extend_face_to_end_of_line fills the empty space to the left of the
214 leftmost character with special glyphs, which will display as,
215 well, empty. On text terminals, these special glyphs are simply
216 blank characters. On graphics terminals, there's a single stretch
217 glyph of a suitably computed width. Both the blanks and the
218 stretch glyph are given the face of the background of the line.
219 This way, the terminal-specific back-end can still draw the glyphs
220 left to right, even for R2L lines.
222 Bidirectional display and character compositions
224 Some scripts cannot be displayed by drawing each character
225 individually, because adjacent characters change each other's shape
226 on display. For example, Arabic and Indic scripts belong to this
227 category.
229 Emacs display supports this by providing "character compositions",
230 most of which is implemented in composite.c. During the buffer
231 scan that delivers characters to PRODUCE_GLYPHS, if the next
232 character to be delivered is a composed character, the iteration
233 calls composition_reseat_it and next_element_from_composition. If
234 they succeed to compose the character with one or more of the
235 following characters, the whole sequence of characters that where
236 composed is recorded in the `struct composition_it' object that is
237 part of the buffer iterator. The composed sequence could produce
238 one or more font glyphs (called "grapheme clusters") on the screen.
239 Each of these grapheme clusters is then delivered to PRODUCE_GLYPHS
240 in the direction corresponding to the current bidi scan direction
241 (recorded in the scan_dir member of the `struct bidi_it' object
242 that is part of the buffer iterator). In particular, if the bidi
243 iterator currently scans the buffer backwards, the grapheme
244 clusters are delivered back to front. This reorders the grapheme
245 clusters as appropriate for the current bidi context. Note that
246 this means that the grapheme clusters are always stored in the
247 LGSTRING object (see composite.c) in the logical order.
249 Moving an iterator in bidirectional text
250 without producing glyphs
252 Note one important detail mentioned above: that the bidi reordering
253 engine, driven by the iterator, produces characters in R2L rows
254 starting at the character that will be the rightmost on display.
255 As far as the iterator is concerned, the geometry of such rows is
256 still left to right, i.e. the iterator "thinks" the first character
257 is at the leftmost pixel position. The iterator does not know that
258 PRODUCE_GLYPHS reverses the order of the glyphs that the iterator
259 delivers. This is important when functions from the the move_it_*
260 family are used to get to certain screen position or to match
261 screen coordinates with buffer coordinates: these functions use the
262 iterator geometry, which is left to right even in R2L paragraphs.
263 This works well with most callers of move_it_*, because they need
264 to get to a specific column, and columns are still numbered in the
265 reading order, i.e. the rightmost character in a R2L paragraph is
266 still column zero. But some callers do not get well with this; a
267 notable example is mouse clicks that need to find the character
268 that corresponds to certain pixel coordinates. See
269 buffer_posn_from_coords in dispnew.c for how this is handled. */
271 #include <config.h>
272 #include <stdio.h>
273 #include <limits.h>
274 #include <setjmp.h>
276 #include "lisp.h"
277 #include "keyboard.h"
278 #include "frame.h"
279 #include "window.h"
280 #include "termchar.h"
281 #include "dispextern.h"
282 #include "buffer.h"
283 #include "character.h"
284 #include "charset.h"
285 #include "indent.h"
286 #include "commands.h"
287 #include "keymap.h"
288 #include "macros.h"
289 #include "disptab.h"
290 #include "termhooks.h"
291 #include "termopts.h"
292 #include "intervals.h"
293 #include "coding.h"
294 #include "process.h"
295 #include "region-cache.h"
296 #include "font.h"
297 #include "fontset.h"
298 #include "blockinput.h"
300 #ifdef HAVE_X_WINDOWS
301 #include "xterm.h"
302 #endif
303 #ifdef WINDOWSNT
304 #include "w32term.h"
305 #endif
306 #ifdef HAVE_NS
307 #include "nsterm.h"
308 #endif
309 #ifdef USE_GTK
310 #include "gtkutil.h"
311 #endif
313 #include "font.h"
315 #ifndef FRAME_X_OUTPUT
316 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
317 #endif
319 #define INFINITY 10000000
321 Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
322 Lisp_Object Qwindow_scroll_functions, Vwindow_scroll_functions;
323 Lisp_Object Qwindow_text_change_functions, Vwindow_text_change_functions;
324 Lisp_Object Qredisplay_end_trigger_functions, Vredisplay_end_trigger_functions;
325 Lisp_Object Qinhibit_point_motion_hooks;
326 Lisp_Object QCeval, QCfile, QCdata, QCpropertize;
327 Lisp_Object Qfontified;
328 Lisp_Object Qgrow_only;
329 Lisp_Object Qinhibit_eval_during_redisplay;
330 Lisp_Object Qbuffer_position, Qposition, Qobject;
331 Lisp_Object Qright_to_left, Qleft_to_right;
333 /* Cursor shapes */
334 Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
336 /* Pointer shapes */
337 Lisp_Object Qarrow, Qhand, Qtext;
339 /* Holds the list (error). */
340 Lisp_Object list_of_error;
342 /* Functions called to fontify regions of text. */
344 Lisp_Object Vfontification_functions;
345 Lisp_Object Qfontification_functions;
347 /* Non-nil means automatically select any window when the mouse
348 cursor moves into it. */
349 Lisp_Object Vmouse_autoselect_window;
351 Lisp_Object Vwrap_prefix, Qwrap_prefix;
352 Lisp_Object Vline_prefix, Qline_prefix;
354 /* Non-zero means draw tool bar buttons raised when the mouse moves
355 over them. */
357 int auto_raise_tool_bar_buttons_p;
359 /* Non-zero means to reposition window if cursor line is only partially visible. */
361 int make_cursor_line_fully_visible_p;
363 /* Margin below tool bar in pixels. 0 or nil means no margin.
364 If value is `internal-border-width' or `border-width',
365 the corresponding frame parameter is used. */
367 Lisp_Object Vtool_bar_border;
369 /* Margin around tool bar buttons in pixels. */
371 Lisp_Object Vtool_bar_button_margin;
373 /* Thickness of shadow to draw around tool bar buttons. */
375 EMACS_INT tool_bar_button_relief;
377 /* Non-nil means automatically resize tool-bars so that all tool-bar
378 items are visible, and no blank lines remain.
380 If value is `grow-only', only make tool-bar bigger. */
382 Lisp_Object Vauto_resize_tool_bars;
384 /* Type of tool bar. Can be symbols image, text, both or both-hroiz. */
386 Lisp_Object Vtool_bar_style;
388 /* Maximum number of characters a label can have to be shown. */
390 EMACS_INT tool_bar_max_label_size;
392 /* Non-zero means draw block and hollow cursor as wide as the glyph
393 under it. For example, if a block cursor is over a tab, it will be
394 drawn as wide as that tab on the display. */
396 int x_stretch_cursor_p;
398 /* Non-nil means don't actually do any redisplay. */
400 Lisp_Object Vinhibit_redisplay, Qinhibit_redisplay;
402 /* Non-zero means Lisp evaluation during redisplay is inhibited. */
404 int inhibit_eval_during_redisplay;
406 /* Names of text properties relevant for redisplay. */
408 Lisp_Object Qdisplay;
410 /* Symbols used in text property values. */
412 Lisp_Object Vdisplay_pixels_per_inch;
413 Lisp_Object Qspace, QCalign_to, QCrelative_width, QCrelative_height;
414 Lisp_Object Qleft_margin, Qright_margin, Qspace_width, Qraise;
415 Lisp_Object Qslice;
416 Lisp_Object Qcenter;
417 Lisp_Object Qmargin, Qpointer;
418 Lisp_Object Qline_height;
420 /* Non-nil means highlight trailing whitespace. */
422 Lisp_Object Vshow_trailing_whitespace;
424 /* Non-nil means escape non-break space and hyphens. */
426 Lisp_Object Vnobreak_char_display;
428 #ifdef HAVE_WINDOW_SYSTEM
430 /* Test if overflow newline into fringe. Called with iterator IT
431 at or past right window margin, and with IT->current_x set. */
433 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(IT) \
434 (!NILP (Voverflow_newline_into_fringe) \
435 && FRAME_WINDOW_P ((IT)->f) \
436 && ((IT)->bidi_it.paragraph_dir == R2L \
437 ? (WINDOW_LEFT_FRINGE_WIDTH ((IT)->w) > 0) \
438 : (WINDOW_RIGHT_FRINGE_WIDTH ((IT)->w) > 0)) \
439 && (IT)->current_x == (IT)->last_visible_x \
440 && (IT)->line_wrap != WORD_WRAP)
442 #else /* !HAVE_WINDOW_SYSTEM */
443 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) 0
444 #endif /* HAVE_WINDOW_SYSTEM */
446 /* Test if the display element loaded in IT is a space or tab
447 character. This is used to determine word wrapping. */
449 #define IT_DISPLAYING_WHITESPACE(it) \
450 (it->what == IT_CHARACTER && (it->c == ' ' || it->c == '\t'))
452 /* Non-nil means show the text cursor in void text areas
453 i.e. in blank areas after eol and eob. This used to be
454 the default in 21.3. */
456 Lisp_Object Vvoid_text_area_pointer;
458 /* Name of the face used to highlight trailing whitespace. */
460 Lisp_Object Qtrailing_whitespace;
462 /* Name and number of the face used to highlight escape glyphs. */
464 Lisp_Object Qescape_glyph;
466 /* Name and number of the face used to highlight non-breaking spaces. */
468 Lisp_Object Qnobreak_space;
470 /* The symbol `image' which is the car of the lists used to represent
471 images in Lisp. Also a tool bar style. */
473 Lisp_Object Qimage;
475 /* The image map types. */
476 Lisp_Object QCmap, QCpointer;
477 Lisp_Object Qrect, Qcircle, Qpoly;
479 /* Tool bar styles */
480 Lisp_Object Qboth, Qboth_horiz, Qtext_image_horiz;
482 /* Non-zero means print newline to stdout before next mini-buffer
483 message. */
485 int noninteractive_need_newline;
487 /* Non-zero means print newline to message log before next message. */
489 static int message_log_need_newline;
491 /* Three markers that message_dolog uses.
492 It could allocate them itself, but that causes trouble
493 in handling memory-full errors. */
494 static Lisp_Object message_dolog_marker1;
495 static Lisp_Object message_dolog_marker2;
496 static Lisp_Object message_dolog_marker3;
498 /* The buffer position of the first character appearing entirely or
499 partially on the line of the selected window which contains the
500 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
501 redisplay optimization in redisplay_internal. */
503 static struct text_pos this_line_start_pos;
505 /* Number of characters past the end of the line above, including the
506 terminating newline. */
508 static struct text_pos this_line_end_pos;
510 /* The vertical positions and the height of this line. */
512 static int this_line_vpos;
513 static int this_line_y;
514 static int this_line_pixel_height;
516 /* X position at which this display line starts. Usually zero;
517 negative if first character is partially visible. */
519 static int this_line_start_x;
521 /* Buffer that this_line_.* variables are referring to. */
523 static struct buffer *this_line_buffer;
525 /* Nonzero means truncate lines in all windows less wide than the
526 frame. */
528 Lisp_Object Vtruncate_partial_width_windows;
530 /* A flag to control how to display unibyte 8-bit character. */
532 int unibyte_display_via_language_environment;
534 /* Nonzero means we have more than one non-mini-buffer-only frame.
535 Not guaranteed to be accurate except while parsing
536 frame-title-format. */
538 int multiple_frames;
540 Lisp_Object Vglobal_mode_string;
543 /* List of variables (symbols) which hold markers for overlay arrows.
544 The symbols on this list are examined during redisplay to determine
545 where to display overlay arrows. */
547 Lisp_Object Voverlay_arrow_variable_list;
549 /* Marker for where to display an arrow on top of the buffer text. */
551 Lisp_Object Voverlay_arrow_position;
553 /* String to display for the arrow. Only used on terminal frames. */
555 Lisp_Object Voverlay_arrow_string;
557 /* Values of those variables at last redisplay are stored as
558 properties on `overlay-arrow-position' symbol. However, if
559 Voverlay_arrow_position is a marker, last-arrow-position is its
560 numerical position. */
562 Lisp_Object Qlast_arrow_position, Qlast_arrow_string;
564 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
565 properties on a symbol in overlay-arrow-variable-list. */
567 Lisp_Object Qoverlay_arrow_string, Qoverlay_arrow_bitmap;
569 /* Like mode-line-format, but for the title bar on a visible frame. */
571 Lisp_Object Vframe_title_format;
573 /* Like mode-line-format, but for the title bar on an iconified frame. */
575 Lisp_Object Vicon_title_format;
577 /* List of functions to call when a window's size changes. These
578 functions get one arg, a frame on which one or more windows' sizes
579 have changed. */
581 static Lisp_Object Vwindow_size_change_functions;
583 Lisp_Object Qmenu_bar_update_hook, Vmenu_bar_update_hook;
585 /* Nonzero if an overlay arrow has been displayed in this window. */
587 static int overlay_arrow_seen;
589 /* Nonzero means highlight the region even in nonselected windows. */
591 int highlight_nonselected_windows;
593 /* If cursor motion alone moves point off frame, try scrolling this
594 many lines up or down if that will bring it back. */
596 static EMACS_INT scroll_step;
598 /* Nonzero means scroll just far enough to bring point back on the
599 screen, when appropriate. */
601 static EMACS_INT scroll_conservatively;
603 /* Recenter the window whenever point gets within this many lines of
604 the top or bottom of the window. This value is translated into a
605 pixel value by multiplying it with FRAME_LINE_HEIGHT, which means
606 that there is really a fixed pixel height scroll margin. */
608 EMACS_INT scroll_margin;
610 /* Number of windows showing the buffer of the selected window (or
611 another buffer with the same base buffer). keyboard.c refers to
612 this. */
614 int buffer_shared;
616 /* Vector containing glyphs for an ellipsis `...'. */
618 static Lisp_Object default_invis_vector[3];
620 /* Zero means display the mode-line/header-line/menu-bar in the default face
621 (this slightly odd definition is for compatibility with previous versions
622 of emacs), non-zero means display them using their respective faces.
624 This variable is deprecated. */
626 int mode_line_inverse_video;
628 /* Prompt to display in front of the mini-buffer contents. */
630 Lisp_Object minibuf_prompt;
632 /* Width of current mini-buffer prompt. Only set after display_line
633 of the line that contains the prompt. */
635 int minibuf_prompt_width;
637 /* This is the window where the echo area message was displayed. It
638 is always a mini-buffer window, but it may not be the same window
639 currently active as a mini-buffer. */
641 Lisp_Object echo_area_window;
643 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
644 pushes the current message and the value of
645 message_enable_multibyte on the stack, the function restore_message
646 pops the stack and displays MESSAGE again. */
648 Lisp_Object Vmessage_stack;
650 /* Nonzero means multibyte characters were enabled when the echo area
651 message was specified. */
653 int message_enable_multibyte;
655 /* Nonzero if we should redraw the mode lines on the next redisplay. */
657 int update_mode_lines;
659 /* Nonzero if window sizes or contents have changed since last
660 redisplay that finished. */
662 int windows_or_buffers_changed;
664 /* Nonzero means a frame's cursor type has been changed. */
666 int cursor_type_changed;
668 /* Nonzero after display_mode_line if %l was used and it displayed a
669 line number. */
671 int line_number_displayed;
673 /* Maximum buffer size for which to display line numbers. */
675 Lisp_Object Vline_number_display_limit;
677 /* Line width to consider when repositioning for line number display. */
679 static EMACS_INT line_number_display_limit_width;
681 /* Number of lines to keep in the message log buffer. t means
682 infinite. nil means don't log at all. */
684 Lisp_Object Vmessage_log_max;
686 /* The name of the *Messages* buffer, a string. */
688 static Lisp_Object Vmessages_buffer_name;
690 /* Current, index 0, and last displayed echo area message. Either
691 buffers from echo_buffers, or nil to indicate no message. */
693 Lisp_Object echo_area_buffer[2];
695 /* The buffers referenced from echo_area_buffer. */
697 static Lisp_Object echo_buffer[2];
699 /* A vector saved used in with_area_buffer to reduce consing. */
701 static Lisp_Object Vwith_echo_area_save_vector;
703 /* Non-zero means display_echo_area should display the last echo area
704 message again. Set by redisplay_preserve_echo_area. */
706 static int display_last_displayed_message_p;
708 /* Nonzero if echo area is being used by print; zero if being used by
709 message. */
711 int message_buf_print;
713 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
715 Lisp_Object Qinhibit_menubar_update;
716 int inhibit_menubar_update;
718 /* When evaluating expressions from menu bar items (enable conditions,
719 for instance), this is the frame they are being processed for. */
721 Lisp_Object Vmenu_updating_frame;
723 /* Maximum height for resizing mini-windows. Either a float
724 specifying a fraction of the available height, or an integer
725 specifying a number of lines. */
727 Lisp_Object Vmax_mini_window_height;
729 /* Non-zero means messages should be displayed with truncated
730 lines instead of being continued. */
732 int message_truncate_lines;
733 Lisp_Object Qmessage_truncate_lines;
735 /* Set to 1 in clear_message to make redisplay_internal aware
736 of an emptied echo area. */
738 static int message_cleared_p;
740 /* How to blink the default frame cursor off. */
741 Lisp_Object Vblink_cursor_alist;
743 /* A scratch glyph row with contents used for generating truncation
744 glyphs. Also used in direct_output_for_insert. */
746 #define MAX_SCRATCH_GLYPHS 100
747 struct glyph_row scratch_glyph_row;
748 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
750 /* Ascent and height of the last line processed by move_it_to. */
752 static int last_max_ascent, last_height;
754 /* Non-zero if there's a help-echo in the echo area. */
756 int help_echo_showing_p;
758 /* If >= 0, computed, exact values of mode-line and header-line height
759 to use in the macros CURRENT_MODE_LINE_HEIGHT and
760 CURRENT_HEADER_LINE_HEIGHT. */
762 int current_mode_line_height, current_header_line_height;
764 /* The maximum distance to look ahead for text properties. Values
765 that are too small let us call compute_char_face and similar
766 functions too often which is expensive. Values that are too large
767 let us call compute_char_face and alike too often because we
768 might not be interested in text properties that far away. */
770 #define TEXT_PROP_DISTANCE_LIMIT 100
772 #if GLYPH_DEBUG
774 /* Variables to turn off display optimizations from Lisp. */
776 int inhibit_try_window_id, inhibit_try_window_reusing;
777 int inhibit_try_cursor_movement;
779 /* Non-zero means print traces of redisplay if compiled with
780 GLYPH_DEBUG != 0. */
782 int trace_redisplay_p;
784 #endif /* GLYPH_DEBUG */
786 #ifdef DEBUG_TRACE_MOVE
787 /* Non-zero means trace with TRACE_MOVE to stderr. */
788 int trace_move;
790 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
791 #else
792 #define TRACE_MOVE(x) (void) 0
793 #endif
795 /* Non-zero means automatically scroll windows horizontally to make
796 point visible. */
798 int automatic_hscrolling_p;
799 Lisp_Object Qauto_hscroll_mode;
801 /* How close to the margin can point get before the window is scrolled
802 horizontally. */
803 EMACS_INT hscroll_margin;
805 /* How much to scroll horizontally when point is inside the above margin. */
806 Lisp_Object Vhscroll_step;
808 /* The variable `resize-mini-windows'. If nil, don't resize
809 mini-windows. If t, always resize them to fit the text they
810 display. If `grow-only', let mini-windows grow only until they
811 become empty. */
813 Lisp_Object Vresize_mini_windows;
815 /* Buffer being redisplayed -- for redisplay_window_error. */
817 struct buffer *displayed_buffer;
819 /* Space between overline and text. */
821 EMACS_INT overline_margin;
823 /* Require underline to be at least this many screen pixels below baseline
824 This to avoid underline "merging" with the base of letters at small
825 font sizes, particularly when x_use_underline_position_properties is on. */
827 EMACS_INT underline_minimum_offset;
829 /* Value returned from text property handlers (see below). */
831 enum prop_handled
833 HANDLED_NORMALLY,
834 HANDLED_RECOMPUTE_PROPS,
835 HANDLED_OVERLAY_STRING_CONSUMED,
836 HANDLED_RETURN
839 /* A description of text properties that redisplay is interested
840 in. */
842 struct props
844 /* The name of the property. */
845 Lisp_Object *name;
847 /* A unique index for the property. */
848 enum prop_idx idx;
850 /* A handler function called to set up iterator IT from the property
851 at IT's current position. Value is used to steer handle_stop. */
852 enum prop_handled (*handler) (struct it *it);
855 static enum prop_handled handle_face_prop (struct it *);
856 static enum prop_handled handle_invisible_prop (struct it *);
857 static enum prop_handled handle_display_prop (struct it *);
858 static enum prop_handled handle_composition_prop (struct it *);
859 static enum prop_handled handle_overlay_change (struct it *);
860 static enum prop_handled handle_fontified_prop (struct it *);
862 /* Properties handled by iterators. */
864 static struct props it_props[] =
866 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
867 /* Handle `face' before `display' because some sub-properties of
868 `display' need to know the face. */
869 {&Qface, FACE_PROP_IDX, handle_face_prop},
870 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
871 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
872 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
873 {NULL, 0, NULL}
876 /* Value is the position described by X. If X is a marker, value is
877 the marker_position of X. Otherwise, value is X. */
879 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
881 /* Enumeration returned by some move_it_.* functions internally. */
883 enum move_it_result
885 /* Not used. Undefined value. */
886 MOVE_UNDEFINED,
888 /* Move ended at the requested buffer position or ZV. */
889 MOVE_POS_MATCH_OR_ZV,
891 /* Move ended at the requested X pixel position. */
892 MOVE_X_REACHED,
894 /* Move within a line ended at the end of a line that must be
895 continued. */
896 MOVE_LINE_CONTINUED,
898 /* Move within a line ended at the end of a line that would
899 be displayed truncated. */
900 MOVE_LINE_TRUNCATED,
902 /* Move within a line ended at a line end. */
903 MOVE_NEWLINE_OR_CR
906 /* This counter is used to clear the face cache every once in a while
907 in redisplay_internal. It is incremented for each redisplay.
908 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
909 cleared. */
911 #define CLEAR_FACE_CACHE_COUNT 500
912 static int clear_face_cache_count;
914 /* Similarly for the image cache. */
916 #ifdef HAVE_WINDOW_SYSTEM
917 #define CLEAR_IMAGE_CACHE_COUNT 101
918 static int clear_image_cache_count;
920 /* Null glyph slice */
921 static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 };
922 #endif
924 /* Non-zero while redisplay_internal is in progress. */
926 int redisplaying_p;
928 /* Non-zero means don't free realized faces. Bound while freeing
929 realized faces is dangerous because glyph matrices might still
930 reference them. */
932 int inhibit_free_realized_faces;
933 Lisp_Object Qinhibit_free_realized_faces;
935 /* If a string, XTread_socket generates an event to display that string.
936 (The display is done in read_char.) */
938 Lisp_Object help_echo_string;
939 Lisp_Object help_echo_window;
940 Lisp_Object help_echo_object;
941 EMACS_INT help_echo_pos;
943 /* Temporary variable for XTread_socket. */
945 Lisp_Object previous_help_echo_string;
947 /* Platform-independent portion of hourglass implementation. */
949 /* Non-zero means we're allowed to display a hourglass pointer. */
950 int display_hourglass_p;
952 /* Non-zero means an hourglass cursor is currently shown. */
953 int hourglass_shown_p;
955 /* If non-null, an asynchronous timer that, when it expires, displays
956 an hourglass cursor on all frames. */
957 struct atimer *hourglass_atimer;
959 /* Number of seconds to wait before displaying an hourglass cursor. */
960 Lisp_Object Vhourglass_delay;
962 /* Name of the face used to display glyphless characters. */
963 Lisp_Object Qglyphless_char;
965 /* Char-table to control the display of glyphless characters. */
966 Lisp_Object Vglyphless_char_display;
968 /* Symbol for the purpose of Vglyphless_char_display. */
969 Lisp_Object Qglyphless_char_display;
971 /* Method symbols for Vglyphless_char_display. */
972 static Lisp_Object Qhex_code, Qempty_box, Qthin_space, Qzero_width;
974 /* Default pixel width of `thin-space' display method. */
975 #define THIN_SPACE_WIDTH 1
977 /* Default number of seconds to wait before displaying an hourglass
978 cursor. */
979 #define DEFAULT_HOURGLASS_DELAY 1
982 /* Function prototypes. */
984 static void setup_for_ellipsis (struct it *, int);
985 static void mark_window_display_accurate_1 (struct window *, int);
986 static int single_display_spec_string_p (Lisp_Object, Lisp_Object);
987 static int display_prop_string_p (Lisp_Object, Lisp_Object);
988 static int cursor_row_p (struct window *, struct glyph_row *);
989 static int redisplay_mode_lines (Lisp_Object, int);
990 static char *decode_mode_spec_coding (Lisp_Object, char *, int);
992 static Lisp_Object get_it_property (struct it *it, Lisp_Object prop);
994 static void handle_line_prefix (struct it *);
996 static void pint2str (char *, int, int);
997 static void pint2hrstr (char *, int, int);
998 static struct text_pos run_window_scroll_functions (Lisp_Object,
999 struct text_pos);
1000 static void reconsider_clip_changes (struct window *, struct buffer *);
1001 static int text_outside_line_unchanged_p (struct window *,
1002 EMACS_INT, EMACS_INT);
1003 static void store_mode_line_noprop_char (char);
1004 static int store_mode_line_noprop (const unsigned char *, int, int);
1005 static void handle_stop (struct it *);
1006 static void handle_stop_backwards (struct it *, EMACS_INT);
1007 static int single_display_spec_intangible_p (Lisp_Object);
1008 static void ensure_echo_area_buffers (void);
1009 static Lisp_Object unwind_with_echo_area_buffer (Lisp_Object);
1010 static Lisp_Object with_echo_area_buffer_unwind_data (struct window *);
1011 static int with_echo_area_buffer (struct window *, int,
1012 int (*) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
1013 EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
1014 static void clear_garbaged_frames (void);
1015 static int current_message_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
1016 static int truncate_message_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
1017 static int set_message_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
1018 static int display_echo_area (struct window *);
1019 static int display_echo_area_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
1020 static int resize_mini_window_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
1021 static Lisp_Object unwind_redisplay (Lisp_Object);
1022 static int string_char_and_length (const unsigned char *, int *);
1023 static struct text_pos display_prop_end (struct it *, Lisp_Object,
1024 struct text_pos);
1025 static int compute_window_start_on_continuation_line (struct window *);
1026 static Lisp_Object safe_eval_handler (Lisp_Object);
1027 static void insert_left_trunc_glyphs (struct it *);
1028 static struct glyph_row *get_overlay_arrow_glyph_row (struct window *,
1029 Lisp_Object);
1030 static void extend_face_to_end_of_line (struct it *);
1031 static int append_space_for_newline (struct it *, int);
1032 static int cursor_row_fully_visible_p (struct window *, int, int);
1033 static int try_scrolling (Lisp_Object, int, EMACS_INT, EMACS_INT, int, int);
1034 static int try_cursor_movement (Lisp_Object, struct text_pos, int *);
1035 static int trailing_whitespace_p (EMACS_INT);
1036 static int message_log_check_duplicate (EMACS_INT, EMACS_INT,
1037 EMACS_INT, EMACS_INT);
1038 static void push_it (struct it *);
1039 static void pop_it (struct it *);
1040 static void sync_frame_with_window_matrix_rows (struct window *);
1041 static void select_frame_for_redisplay (Lisp_Object);
1042 static void redisplay_internal (int);
1043 static int echo_area_display (int);
1044 static void redisplay_windows (Lisp_Object);
1045 static void redisplay_window (Lisp_Object, int);
1046 static Lisp_Object redisplay_window_error (Lisp_Object);
1047 static Lisp_Object redisplay_window_0 (Lisp_Object);
1048 static Lisp_Object redisplay_window_1 (Lisp_Object);
1049 static int update_menu_bar (struct frame *, int, int);
1050 static int try_window_reusing_current_matrix (struct window *);
1051 static int try_window_id (struct window *);
1052 static int display_line (struct it *);
1053 static int display_mode_lines (struct window *);
1054 static int display_mode_line (struct window *, enum face_id, Lisp_Object);
1055 static int display_mode_element (struct it *, int, int, int, Lisp_Object, Lisp_Object, int);
1056 static int store_mode_line_string (const char *, Lisp_Object, int, int, int, Lisp_Object);
1057 static const char *decode_mode_spec (struct window *, int, int, int,
1058 Lisp_Object *);
1059 static void display_menu_bar (struct window *);
1060 static int display_count_lines (EMACS_INT, EMACS_INT, EMACS_INT, int,
1061 EMACS_INT *);
1062 static int display_string (const unsigned char *, Lisp_Object, Lisp_Object,
1063 EMACS_INT, EMACS_INT, struct it *, int, int, int, int);
1064 static void compute_line_metrics (struct it *);
1065 static void run_redisplay_end_trigger_hook (struct it *);
1066 static int get_overlay_strings (struct it *, EMACS_INT);
1067 static int get_overlay_strings_1 (struct it *, EMACS_INT, int);
1068 static void next_overlay_string (struct it *);
1069 static void reseat (struct it *, struct text_pos, int);
1070 static void reseat_1 (struct it *, struct text_pos, int);
1071 static void back_to_previous_visible_line_start (struct it *);
1072 void reseat_at_previous_visible_line_start (struct it *);
1073 static void reseat_at_next_visible_line_start (struct it *, int);
1074 static int next_element_from_ellipsis (struct it *);
1075 static int next_element_from_display_vector (struct it *);
1076 static int next_element_from_string (struct it *);
1077 static int next_element_from_c_string (struct it *);
1078 static int next_element_from_buffer (struct it *);
1079 static int next_element_from_composition (struct it *);
1080 static int next_element_from_image (struct it *);
1081 static int next_element_from_stretch (struct it *);
1082 static void load_overlay_strings (struct it *, EMACS_INT);
1083 static int init_from_display_pos (struct it *, struct window *,
1084 struct display_pos *);
1085 static void reseat_to_string (struct it *, const unsigned char *,
1086 Lisp_Object, EMACS_INT, EMACS_INT, int, int);
1087 static enum move_it_result
1088 move_it_in_display_line_to (struct it *, EMACS_INT, int,
1089 enum move_operation_enum);
1090 void move_it_vertically_backward (struct it *, int);
1091 static void init_to_row_start (struct it *, struct window *,
1092 struct glyph_row *);
1093 static int init_to_row_end (struct it *, struct window *,
1094 struct glyph_row *);
1095 static void back_to_previous_line_start (struct it *);
1096 static int forward_to_next_line_start (struct it *, int *);
1097 static struct text_pos string_pos_nchars_ahead (struct text_pos,
1098 Lisp_Object, EMACS_INT);
1099 static struct text_pos string_pos (EMACS_INT, Lisp_Object);
1100 static struct text_pos c_string_pos (EMACS_INT, const unsigned char *, int);
1101 static EMACS_INT number_of_chars (const unsigned char *, int);
1102 static void compute_stop_pos (struct it *);
1103 static void compute_string_pos (struct text_pos *, struct text_pos,
1104 Lisp_Object);
1105 static int face_before_or_after_it_pos (struct it *, int);
1106 static EMACS_INT next_overlay_change (EMACS_INT);
1107 static int handle_single_display_spec (struct it *, Lisp_Object,
1108 Lisp_Object, Lisp_Object,
1109 struct text_pos *, int);
1110 static int underlying_face_id (struct it *);
1111 static int in_ellipses_for_invisible_text_p (struct display_pos *,
1112 struct window *);
1114 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
1115 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
1117 #ifdef HAVE_WINDOW_SYSTEM
1119 static void x_consider_frame_title (Lisp_Object);
1120 static int tool_bar_lines_needed (struct frame *, int *);
1121 static void update_tool_bar (struct frame *, int);
1122 static void build_desired_tool_bar_string (struct frame *f);
1123 static int redisplay_tool_bar (struct frame *);
1124 static void display_tool_bar_line (struct it *, int);
1125 static void notice_overwritten_cursor (struct window *,
1126 enum glyph_row_area,
1127 int, int, int, int);
1128 static void append_stretch_glyph (struct it *, Lisp_Object,
1129 int, int, int);
1132 #endif /* HAVE_WINDOW_SYSTEM */
1134 static int coords_in_mouse_face_p (struct window *, int, int);
1138 /***********************************************************************
1139 Window display dimensions
1140 ***********************************************************************/
1142 /* Return the bottom boundary y-position for text lines in window W.
1143 This is the first y position at which a line cannot start.
1144 It is relative to the top of the window.
1146 This is the height of W minus the height of a mode line, if any. */
1148 INLINE int
1149 window_text_bottom_y (struct window *w)
1151 int height = WINDOW_TOTAL_HEIGHT (w);
1153 if (WINDOW_WANTS_MODELINE_P (w))
1154 height -= CURRENT_MODE_LINE_HEIGHT (w);
1155 return height;
1158 /* Return the pixel width of display area AREA of window W. AREA < 0
1159 means return the total width of W, not including fringes to
1160 the left and right of the window. */
1162 INLINE int
1163 window_box_width (struct window *w, int area)
1165 int cols = XFASTINT (w->total_cols);
1166 int pixels = 0;
1168 if (!w->pseudo_window_p)
1170 cols -= WINDOW_SCROLL_BAR_COLS (w);
1172 if (area == TEXT_AREA)
1174 if (INTEGERP (w->left_margin_cols))
1175 cols -= XFASTINT (w->left_margin_cols);
1176 if (INTEGERP (w->right_margin_cols))
1177 cols -= XFASTINT (w->right_margin_cols);
1178 pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w);
1180 else if (area == LEFT_MARGIN_AREA)
1182 cols = (INTEGERP (w->left_margin_cols)
1183 ? XFASTINT (w->left_margin_cols) : 0);
1184 pixels = 0;
1186 else if (area == RIGHT_MARGIN_AREA)
1188 cols = (INTEGERP (w->right_margin_cols)
1189 ? XFASTINT (w->right_margin_cols) : 0);
1190 pixels = 0;
1194 return cols * WINDOW_FRAME_COLUMN_WIDTH (w) + pixels;
1198 /* Return the pixel height of the display area of window W, not
1199 including mode lines of W, if any. */
1201 INLINE int
1202 window_box_height (struct window *w)
1204 struct frame *f = XFRAME (w->frame);
1205 int height = WINDOW_TOTAL_HEIGHT (w);
1207 xassert (height >= 0);
1209 /* Note: the code below that determines the mode-line/header-line
1210 height is essentially the same as that contained in the macro
1211 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1212 the appropriate glyph row has its `mode_line_p' flag set,
1213 and if it doesn't, uses estimate_mode_line_height instead. */
1215 if (WINDOW_WANTS_MODELINE_P (w))
1217 struct glyph_row *ml_row
1218 = (w->current_matrix && w->current_matrix->rows
1219 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
1220 : 0);
1221 if (ml_row && ml_row->mode_line_p)
1222 height -= ml_row->height;
1223 else
1224 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
1227 if (WINDOW_WANTS_HEADER_LINE_P (w))
1229 struct glyph_row *hl_row
1230 = (w->current_matrix && w->current_matrix->rows
1231 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
1232 : 0);
1233 if (hl_row && hl_row->mode_line_p)
1234 height -= hl_row->height;
1235 else
1236 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1239 /* With a very small font and a mode-line that's taller than
1240 default, we might end up with a negative height. */
1241 return max (0, height);
1244 /* Return the window-relative coordinate of the left edge of display
1245 area AREA of window W. AREA < 0 means return the left edge of the
1246 whole window, to the right of the left fringe of W. */
1248 INLINE int
1249 window_box_left_offset (struct window *w, int area)
1251 int x;
1253 if (w->pseudo_window_p)
1254 return 0;
1256 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
1258 if (area == TEXT_AREA)
1259 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1260 + window_box_width (w, LEFT_MARGIN_AREA));
1261 else if (area == RIGHT_MARGIN_AREA)
1262 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1263 + window_box_width (w, LEFT_MARGIN_AREA)
1264 + window_box_width (w, TEXT_AREA)
1265 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1267 : WINDOW_RIGHT_FRINGE_WIDTH (w)));
1268 else if (area == LEFT_MARGIN_AREA
1269 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1270 x += WINDOW_LEFT_FRINGE_WIDTH (w);
1272 return x;
1276 /* Return the window-relative coordinate of the right edge of display
1277 area AREA of window W. AREA < 0 means return the right edge of the
1278 whole window, to the left of the right fringe of W. */
1280 INLINE int
1281 window_box_right_offset (struct window *w, int area)
1283 return window_box_left_offset (w, area) + window_box_width (w, area);
1286 /* Return the frame-relative coordinate of the left edge of display
1287 area AREA of window W. AREA < 0 means return the left edge of the
1288 whole window, to the right of the left fringe of W. */
1290 INLINE int
1291 window_box_left (struct window *w, int area)
1293 struct frame *f = XFRAME (w->frame);
1294 int x;
1296 if (w->pseudo_window_p)
1297 return FRAME_INTERNAL_BORDER_WIDTH (f);
1299 x = (WINDOW_LEFT_EDGE_X (w)
1300 + window_box_left_offset (w, area));
1302 return x;
1306 /* Return the frame-relative coordinate of the right edge of display
1307 area AREA of window W. AREA < 0 means return the right edge of the
1308 whole window, to the left of the right fringe of W. */
1310 INLINE int
1311 window_box_right (struct window *w, int area)
1313 return window_box_left (w, area) + window_box_width (w, area);
1316 /* Get the bounding box of the display area AREA of window W, without
1317 mode lines, in frame-relative coordinates. AREA < 0 means the
1318 whole window, not including the left and right fringes of
1319 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1320 coordinates of the upper-left corner of the box. Return in
1321 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1323 INLINE void
1324 window_box (struct window *w, int area, int *box_x, int *box_y,
1325 int *box_width, int *box_height)
1327 if (box_width)
1328 *box_width = window_box_width (w, area);
1329 if (box_height)
1330 *box_height = window_box_height (w);
1331 if (box_x)
1332 *box_x = window_box_left (w, area);
1333 if (box_y)
1335 *box_y = WINDOW_TOP_EDGE_Y (w);
1336 if (WINDOW_WANTS_HEADER_LINE_P (w))
1337 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1342 /* Get the bounding box of the display area AREA of window W, without
1343 mode lines. AREA < 0 means the whole window, not including the
1344 left and right fringe of the window. Return in *TOP_LEFT_X
1345 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1346 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1347 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1348 box. */
1350 INLINE void
1351 window_box_edges (struct window *w, int area, int *top_left_x, int *top_left_y,
1352 int *bottom_right_x, int *bottom_right_y)
1354 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
1355 bottom_right_y);
1356 *bottom_right_x += *top_left_x;
1357 *bottom_right_y += *top_left_y;
1362 /***********************************************************************
1363 Utilities
1364 ***********************************************************************/
1366 /* Return the bottom y-position of the line the iterator IT is in.
1367 This can modify IT's settings. */
1370 line_bottom_y (struct it *it)
1372 int line_height = it->max_ascent + it->max_descent;
1373 int line_top_y = it->current_y;
1375 if (line_height == 0)
1377 if (last_height)
1378 line_height = last_height;
1379 else if (IT_CHARPOS (*it) < ZV)
1381 move_it_by_lines (it, 1, 1);
1382 line_height = (it->max_ascent || it->max_descent
1383 ? it->max_ascent + it->max_descent
1384 : last_height);
1386 else
1388 struct glyph_row *row = it->glyph_row;
1390 /* Use the default character height. */
1391 it->glyph_row = NULL;
1392 it->what = IT_CHARACTER;
1393 it->c = ' ';
1394 it->len = 1;
1395 PRODUCE_GLYPHS (it);
1396 line_height = it->ascent + it->descent;
1397 it->glyph_row = row;
1401 return line_top_y + line_height;
1405 /* Return 1 if position CHARPOS is visible in window W.
1406 CHARPOS < 0 means return info about WINDOW_END position.
1407 If visible, set *X and *Y to pixel coordinates of top left corner.
1408 Set *RTOP and *RBOT to pixel height of an invisible area of glyph at POS.
1409 Set *ROWH and *VPOS to row's visible height and VPOS (row number). */
1412 pos_visible_p (struct window *w, EMACS_INT charpos, int *x, int *y,
1413 int *rtop, int *rbot, int *rowh, int *vpos)
1415 struct it it;
1416 struct text_pos top;
1417 int visible_p = 0;
1418 struct buffer *old_buffer = NULL;
1420 if (FRAME_INITIAL_P (XFRAME (WINDOW_FRAME (w))))
1421 return visible_p;
1423 if (XBUFFER (w->buffer) != current_buffer)
1425 old_buffer = current_buffer;
1426 set_buffer_internal_1 (XBUFFER (w->buffer));
1429 SET_TEXT_POS_FROM_MARKER (top, w->start);
1431 /* Compute exact mode line heights. */
1432 if (WINDOW_WANTS_MODELINE_P (w))
1433 current_mode_line_height
1434 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1435 current_buffer->mode_line_format);
1437 if (WINDOW_WANTS_HEADER_LINE_P (w))
1438 current_header_line_height
1439 = display_mode_line (w, HEADER_LINE_FACE_ID,
1440 current_buffer->header_line_format);
1442 start_display (&it, w, top);
1443 move_it_to (&it, charpos, -1, it.last_visible_y-1, -1,
1444 (charpos >= 0 ? MOVE_TO_POS : 0) | MOVE_TO_Y);
1446 if (charpos >= 0 && IT_CHARPOS (it) >= charpos)
1448 /* We have reached CHARPOS, or passed it. How the call to
1449 move_it_to can overshoot: (i) If CHARPOS is on invisible
1450 text, move_it_to stops at the end of the invisible text,
1451 after CHARPOS. (ii) If CHARPOS is in a display vector,
1452 move_it_to stops on its last glyph. */
1453 int top_x = it.current_x;
1454 int top_y = it.current_y;
1455 enum it_method it_method = it.method;
1456 /* Calling line_bottom_y may change it.method, it.position, etc. */
1457 int bottom_y = (last_height = 0, line_bottom_y (&it));
1458 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1460 if (top_y < window_top_y)
1461 visible_p = bottom_y > window_top_y;
1462 else if (top_y < it.last_visible_y)
1463 visible_p = 1;
1464 if (visible_p)
1466 if (it_method == GET_FROM_DISPLAY_VECTOR)
1468 /* We stopped on the last glyph of a display vector.
1469 Try and recompute. Hack alert! */
1470 if (charpos < 2 || top.charpos >= charpos)
1471 top_x = it.glyph_row->x;
1472 else
1474 struct it it2;
1475 start_display (&it2, w, top);
1476 move_it_to (&it2, charpos - 1, -1, -1, -1, MOVE_TO_POS);
1477 get_next_display_element (&it2);
1478 PRODUCE_GLYPHS (&it2);
1479 if (ITERATOR_AT_END_OF_LINE_P (&it2)
1480 || it2.current_x > it2.last_visible_x)
1481 top_x = it.glyph_row->x;
1482 else
1484 top_x = it2.current_x;
1485 top_y = it2.current_y;
1490 *x = top_x;
1491 *y = max (top_y + max (0, it.max_ascent - it.ascent), window_top_y);
1492 *rtop = max (0, window_top_y - top_y);
1493 *rbot = max (0, bottom_y - it.last_visible_y);
1494 *rowh = max (0, (min (bottom_y, it.last_visible_y)
1495 - max (top_y, window_top_y)));
1496 *vpos = it.vpos;
1499 else
1501 struct it it2;
1503 it2 = it;
1504 if (IT_CHARPOS (it) < ZV && FETCH_BYTE (IT_BYTEPOS (it)) != '\n')
1505 move_it_by_lines (&it, 1, 0);
1506 if (charpos < IT_CHARPOS (it)
1507 || (it.what == IT_EOB && charpos == IT_CHARPOS (it)))
1509 visible_p = 1;
1510 move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
1511 *x = it2.current_x;
1512 *y = it2.current_y + it2.max_ascent - it2.ascent;
1513 *rtop = max (0, -it2.current_y);
1514 *rbot = max (0, ((it2.current_y + it2.max_ascent + it2.max_descent)
1515 - it.last_visible_y));
1516 *rowh = max (0, (min (it2.current_y + it2.max_ascent + it2.max_descent,
1517 it.last_visible_y)
1518 - max (it2.current_y,
1519 WINDOW_HEADER_LINE_HEIGHT (w))));
1520 *vpos = it2.vpos;
1524 if (old_buffer)
1525 set_buffer_internal_1 (old_buffer);
1527 current_header_line_height = current_mode_line_height = -1;
1529 if (visible_p && XFASTINT (w->hscroll) > 0)
1530 *x -= XFASTINT (w->hscroll) * WINDOW_FRAME_COLUMN_WIDTH (w);
1532 #if 0
1533 /* Debugging code. */
1534 if (visible_p)
1535 fprintf (stderr, "+pv pt=%d vs=%d --> x=%d y=%d rt=%d rb=%d rh=%d vp=%d\n",
1536 charpos, w->vscroll, *x, *y, *rtop, *rbot, *rowh, *vpos);
1537 else
1538 fprintf (stderr, "-pv pt=%d vs=%d\n", charpos, w->vscroll);
1539 #endif
1541 return visible_p;
1545 /* Return the next character from STR. Return in *LEN the length of
1546 the character. This is like STRING_CHAR_AND_LENGTH but never
1547 returns an invalid character. If we find one, we return a `?', but
1548 with the length of the invalid character. */
1550 static INLINE int
1551 string_char_and_length (const unsigned char *str, int *len)
1553 int c;
1555 c = STRING_CHAR_AND_LENGTH (str, *len);
1556 if (!CHAR_VALID_P (c, 1))
1557 /* We may not change the length here because other places in Emacs
1558 don't use this function, i.e. they silently accept invalid
1559 characters. */
1560 c = '?';
1562 return c;
1567 /* Given a position POS containing a valid character and byte position
1568 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1570 static struct text_pos
1571 string_pos_nchars_ahead (struct text_pos pos, Lisp_Object string, EMACS_INT nchars)
1573 xassert (STRINGP (string) && nchars >= 0);
1575 if (STRING_MULTIBYTE (string))
1577 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1578 int len;
1580 while (nchars--)
1582 string_char_and_length (p, &len);
1583 p += len;
1584 CHARPOS (pos) += 1;
1585 BYTEPOS (pos) += len;
1588 else
1589 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1591 return pos;
1595 /* Value is the text position, i.e. character and byte position,
1596 for character position CHARPOS in STRING. */
1598 static INLINE struct text_pos
1599 string_pos (EMACS_INT charpos, Lisp_Object string)
1601 struct text_pos pos;
1602 xassert (STRINGP (string));
1603 xassert (charpos >= 0);
1604 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1605 return pos;
1609 /* Value is a text position, i.e. character and byte position, for
1610 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1611 means recognize multibyte characters. */
1613 static struct text_pos
1614 c_string_pos (EMACS_INT charpos, const unsigned char *s, int multibyte_p)
1616 struct text_pos pos;
1618 xassert (s != NULL);
1619 xassert (charpos >= 0);
1621 if (multibyte_p)
1623 int len;
1625 SET_TEXT_POS (pos, 0, 0);
1626 while (charpos--)
1628 string_char_and_length (s, &len);
1629 s += len;
1630 CHARPOS (pos) += 1;
1631 BYTEPOS (pos) += len;
1634 else
1635 SET_TEXT_POS (pos, charpos, charpos);
1637 return pos;
1641 /* Value is the number of characters in C string S. MULTIBYTE_P
1642 non-zero means recognize multibyte characters. */
1644 static EMACS_INT
1645 number_of_chars (const unsigned char *s, int multibyte_p)
1647 EMACS_INT nchars;
1649 if (multibyte_p)
1651 EMACS_INT rest = strlen (s);
1652 int len;
1653 unsigned char *p = (unsigned char *) s;
1655 for (nchars = 0; rest > 0; ++nchars)
1657 string_char_and_length (p, &len);
1658 rest -= len, p += len;
1661 else
1662 nchars = strlen (s);
1664 return nchars;
1668 /* Compute byte position NEWPOS->bytepos corresponding to
1669 NEWPOS->charpos. POS is a known position in string STRING.
1670 NEWPOS->charpos must be >= POS.charpos. */
1672 static void
1673 compute_string_pos (struct text_pos *newpos, struct text_pos pos, Lisp_Object string)
1675 xassert (STRINGP (string));
1676 xassert (CHARPOS (*newpos) >= CHARPOS (pos));
1678 if (STRING_MULTIBYTE (string))
1679 *newpos = string_pos_nchars_ahead (pos, string,
1680 CHARPOS (*newpos) - CHARPOS (pos));
1681 else
1682 BYTEPOS (*newpos) = CHARPOS (*newpos);
1685 /* EXPORT:
1686 Return an estimation of the pixel height of mode or header lines on
1687 frame F. FACE_ID specifies what line's height to estimate. */
1690 estimate_mode_line_height (struct frame *f, enum face_id face_id)
1692 #ifdef HAVE_WINDOW_SYSTEM
1693 if (FRAME_WINDOW_P (f))
1695 int height = FONT_HEIGHT (FRAME_FONT (f));
1697 /* This function is called so early when Emacs starts that the face
1698 cache and mode line face are not yet initialized. */
1699 if (FRAME_FACE_CACHE (f))
1701 struct face *face = FACE_FROM_ID (f, face_id);
1702 if (face)
1704 if (face->font)
1705 height = FONT_HEIGHT (face->font);
1706 if (face->box_line_width > 0)
1707 height += 2 * face->box_line_width;
1711 return height;
1713 #endif
1715 return 1;
1718 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1719 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1720 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1721 not force the value into range. */
1723 void
1724 pixel_to_glyph_coords (FRAME_PTR f, register int pix_x, register int pix_y,
1725 int *x, int *y, NativeRectangle *bounds, int noclip)
1728 #ifdef HAVE_WINDOW_SYSTEM
1729 if (FRAME_WINDOW_P (f))
1731 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1732 even for negative values. */
1733 if (pix_x < 0)
1734 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1735 if (pix_y < 0)
1736 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1738 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1739 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1741 if (bounds)
1742 STORE_NATIVE_RECT (*bounds,
1743 FRAME_COL_TO_PIXEL_X (f, pix_x),
1744 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1745 FRAME_COLUMN_WIDTH (f) - 1,
1746 FRAME_LINE_HEIGHT (f) - 1);
1748 if (!noclip)
1750 if (pix_x < 0)
1751 pix_x = 0;
1752 else if (pix_x > FRAME_TOTAL_COLS (f))
1753 pix_x = FRAME_TOTAL_COLS (f);
1755 if (pix_y < 0)
1756 pix_y = 0;
1757 else if (pix_y > FRAME_LINES (f))
1758 pix_y = FRAME_LINES (f);
1761 #endif
1763 *x = pix_x;
1764 *y = pix_y;
1768 /* Given HPOS/VPOS in the current matrix of W, return corresponding
1769 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
1770 can't tell the positions because W's display is not up to date,
1771 return 0. */
1774 glyph_to_pixel_coords (struct window *w, int hpos, int vpos,
1775 int *frame_x, int *frame_y)
1777 #ifdef HAVE_WINDOW_SYSTEM
1778 if (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w))))
1780 int success_p;
1782 xassert (hpos >= 0 && hpos < w->current_matrix->matrix_w);
1783 xassert (vpos >= 0 && vpos < w->current_matrix->matrix_h);
1785 if (display_completed)
1787 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
1788 struct glyph *glyph = row->glyphs[TEXT_AREA];
1789 struct glyph *end = glyph + min (hpos, row->used[TEXT_AREA]);
1791 hpos = row->x;
1792 vpos = row->y;
1793 while (glyph < end)
1795 hpos += glyph->pixel_width;
1796 ++glyph;
1799 /* If first glyph is partially visible, its first visible position is still 0. */
1800 if (hpos < 0)
1801 hpos = 0;
1803 success_p = 1;
1805 else
1807 hpos = vpos = 0;
1808 success_p = 0;
1811 *frame_x = WINDOW_TO_FRAME_PIXEL_X (w, hpos);
1812 *frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, vpos);
1813 return success_p;
1815 #endif
1817 *frame_x = hpos;
1818 *frame_y = vpos;
1819 return 1;
1823 /* Find the glyph under window-relative coordinates X/Y in window W.
1824 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1825 strings. Return in *HPOS and *VPOS the row and column number of
1826 the glyph found. Return in *AREA the glyph area containing X.
1827 Value is a pointer to the glyph found or null if X/Y is not on
1828 text, or we can't tell because W's current matrix is not up to
1829 date. */
1831 static
1832 struct glyph *
1833 x_y_to_hpos_vpos (struct window *w, int x, int y, int *hpos, int *vpos,
1834 int *dx, int *dy, int *area)
1836 struct glyph *glyph, *end;
1837 struct glyph_row *row = NULL;
1838 int x0, i;
1840 /* Find row containing Y. Give up if some row is not enabled. */
1841 for (i = 0; i < w->current_matrix->nrows; ++i)
1843 row = MATRIX_ROW (w->current_matrix, i);
1844 if (!row->enabled_p)
1845 return NULL;
1846 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1847 break;
1850 *vpos = i;
1851 *hpos = 0;
1853 /* Give up if Y is not in the window. */
1854 if (i == w->current_matrix->nrows)
1855 return NULL;
1857 /* Get the glyph area containing X. */
1858 if (w->pseudo_window_p)
1860 *area = TEXT_AREA;
1861 x0 = 0;
1863 else
1865 if (x < window_box_left_offset (w, TEXT_AREA))
1867 *area = LEFT_MARGIN_AREA;
1868 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
1870 else if (x < window_box_right_offset (w, TEXT_AREA))
1872 *area = TEXT_AREA;
1873 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
1875 else
1877 *area = RIGHT_MARGIN_AREA;
1878 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
1882 /* Find glyph containing X. */
1883 glyph = row->glyphs[*area];
1884 end = glyph + row->used[*area];
1885 x -= x0;
1886 while (glyph < end && x >= glyph->pixel_width)
1888 x -= glyph->pixel_width;
1889 ++glyph;
1892 if (glyph == end)
1893 return NULL;
1895 if (dx)
1897 *dx = x;
1898 *dy = y - (row->y + row->ascent - glyph->ascent);
1901 *hpos = glyph - row->glyphs[*area];
1902 return glyph;
1905 /* EXPORT:
1906 Convert frame-relative x/y to coordinates relative to window W.
1907 Takes pseudo-windows into account. */
1909 void
1910 frame_to_window_pixel_xy (struct window *w, int *x, int *y)
1912 if (w->pseudo_window_p)
1914 /* A pseudo-window is always full-width, and starts at the
1915 left edge of the frame, plus a frame border. */
1916 struct frame *f = XFRAME (w->frame);
1917 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
1918 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1920 else
1922 *x -= WINDOW_LEFT_EDGE_X (w);
1923 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1927 #ifdef HAVE_WINDOW_SYSTEM
1929 /* EXPORT:
1930 Return in RECTS[] at most N clipping rectangles for glyph string S.
1931 Return the number of stored rectangles. */
1934 get_glyph_string_clip_rects (struct glyph_string *s, NativeRectangle *rects, int n)
1936 XRectangle r;
1938 if (n <= 0)
1939 return 0;
1941 if (s->row->full_width_p)
1943 /* Draw full-width. X coordinates are relative to S->w->left_col. */
1944 r.x = WINDOW_LEFT_EDGE_X (s->w);
1945 r.width = WINDOW_TOTAL_WIDTH (s->w);
1947 /* Unless displaying a mode or menu bar line, which are always
1948 fully visible, clip to the visible part of the row. */
1949 if (s->w->pseudo_window_p)
1950 r.height = s->row->visible_height;
1951 else
1952 r.height = s->height;
1954 else
1956 /* This is a text line that may be partially visible. */
1957 r.x = window_box_left (s->w, s->area);
1958 r.width = window_box_width (s->w, s->area);
1959 r.height = s->row->visible_height;
1962 if (s->clip_head)
1963 if (r.x < s->clip_head->x)
1965 if (r.width >= s->clip_head->x - r.x)
1966 r.width -= s->clip_head->x - r.x;
1967 else
1968 r.width = 0;
1969 r.x = s->clip_head->x;
1971 if (s->clip_tail)
1972 if (r.x + r.width > s->clip_tail->x + s->clip_tail->background_width)
1974 if (s->clip_tail->x + s->clip_tail->background_width >= r.x)
1975 r.width = s->clip_tail->x + s->clip_tail->background_width - r.x;
1976 else
1977 r.width = 0;
1980 /* If S draws overlapping rows, it's sufficient to use the top and
1981 bottom of the window for clipping because this glyph string
1982 intentionally draws over other lines. */
1983 if (s->for_overlaps)
1985 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1986 r.height = window_text_bottom_y (s->w) - r.y;
1988 /* Alas, the above simple strategy does not work for the
1989 environments with anti-aliased text: if the same text is
1990 drawn onto the same place multiple times, it gets thicker.
1991 If the overlap we are processing is for the erased cursor, we
1992 take the intersection with the rectagle of the cursor. */
1993 if (s->for_overlaps & OVERLAPS_ERASED_CURSOR)
1995 XRectangle rc, r_save = r;
1997 rc.x = WINDOW_TEXT_TO_FRAME_PIXEL_X (s->w, s->w->phys_cursor.x);
1998 rc.y = s->w->phys_cursor.y;
1999 rc.width = s->w->phys_cursor_width;
2000 rc.height = s->w->phys_cursor_height;
2002 x_intersect_rectangles (&r_save, &rc, &r);
2005 else
2007 /* Don't use S->y for clipping because it doesn't take partially
2008 visible lines into account. For example, it can be negative for
2009 partially visible lines at the top of a window. */
2010 if (!s->row->full_width_p
2011 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
2012 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
2013 else
2014 r.y = max (0, s->row->y);
2017 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
2019 /* If drawing the cursor, don't let glyph draw outside its
2020 advertised boundaries. Cleartype does this under some circumstances. */
2021 if (s->hl == DRAW_CURSOR)
2023 struct glyph *glyph = s->first_glyph;
2024 int height, max_y;
2026 if (s->x > r.x)
2028 r.width -= s->x - r.x;
2029 r.x = s->x;
2031 r.width = min (r.width, glyph->pixel_width);
2033 /* If r.y is below window bottom, ensure that we still see a cursor. */
2034 height = min (glyph->ascent + glyph->descent,
2035 min (FRAME_LINE_HEIGHT (s->f), s->row->visible_height));
2036 max_y = window_text_bottom_y (s->w) - height;
2037 max_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, max_y);
2038 if (s->ybase - glyph->ascent > max_y)
2040 r.y = max_y;
2041 r.height = height;
2043 else
2045 /* Don't draw cursor glyph taller than our actual glyph. */
2046 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
2047 if (height < r.height)
2049 max_y = r.y + r.height;
2050 r.y = min (max_y, max (r.y, s->ybase + glyph->descent - height));
2051 r.height = min (max_y - r.y, height);
2056 if (s->row->clip)
2058 XRectangle r_save = r;
2060 if (! x_intersect_rectangles (&r_save, s->row->clip, &r))
2061 r.width = 0;
2064 if ((s->for_overlaps & OVERLAPS_BOTH) == 0
2065 || ((s->for_overlaps & OVERLAPS_BOTH) == OVERLAPS_BOTH && n == 1))
2067 #ifdef CONVERT_FROM_XRECT
2068 CONVERT_FROM_XRECT (r, *rects);
2069 #else
2070 *rects = r;
2071 #endif
2072 return 1;
2074 else
2076 /* If we are processing overlapping and allowed to return
2077 multiple clipping rectangles, we exclude the row of the glyph
2078 string from the clipping rectangle. This is to avoid drawing
2079 the same text on the environment with anti-aliasing. */
2080 #ifdef CONVERT_FROM_XRECT
2081 XRectangle rs[2];
2082 #else
2083 XRectangle *rs = rects;
2084 #endif
2085 int i = 0, row_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, s->row->y);
2087 if (s->for_overlaps & OVERLAPS_PRED)
2089 rs[i] = r;
2090 if (r.y + r.height > row_y)
2092 if (r.y < row_y)
2093 rs[i].height = row_y - r.y;
2094 else
2095 rs[i].height = 0;
2097 i++;
2099 if (s->for_overlaps & OVERLAPS_SUCC)
2101 rs[i] = r;
2102 if (r.y < row_y + s->row->visible_height)
2104 if (r.y + r.height > row_y + s->row->visible_height)
2106 rs[i].y = row_y + s->row->visible_height;
2107 rs[i].height = r.y + r.height - rs[i].y;
2109 else
2110 rs[i].height = 0;
2112 i++;
2115 n = i;
2116 #ifdef CONVERT_FROM_XRECT
2117 for (i = 0; i < n; i++)
2118 CONVERT_FROM_XRECT (rs[i], rects[i]);
2119 #endif
2120 return n;
2124 /* EXPORT:
2125 Return in *NR the clipping rectangle for glyph string S. */
2127 void
2128 get_glyph_string_clip_rect (struct glyph_string *s, NativeRectangle *nr)
2130 get_glyph_string_clip_rects (s, nr, 1);
2134 /* EXPORT:
2135 Return the position and height of the phys cursor in window W.
2136 Set w->phys_cursor_width to width of phys cursor.
2139 void
2140 get_phys_cursor_geometry (struct window *w, struct glyph_row *row,
2141 struct glyph *glyph, int *xp, int *yp, int *heightp)
2143 struct frame *f = XFRAME (WINDOW_FRAME (w));
2144 int x, y, wd, h, h0, y0;
2146 /* Compute the width of the rectangle to draw. If on a stretch
2147 glyph, and `x-stretch-block-cursor' is nil, don't draw a
2148 rectangle as wide as the glyph, but use a canonical character
2149 width instead. */
2150 wd = glyph->pixel_width - 1;
2151 #if defined(HAVE_NTGUI) || defined(HAVE_NS)
2152 wd++; /* Why? */
2153 #endif
2155 x = w->phys_cursor.x;
2156 if (x < 0)
2158 wd += x;
2159 x = 0;
2162 if (glyph->type == STRETCH_GLYPH
2163 && !x_stretch_cursor_p)
2164 wd = min (FRAME_COLUMN_WIDTH (f), wd);
2165 w->phys_cursor_width = wd;
2167 y = w->phys_cursor.y + row->ascent - glyph->ascent;
2169 /* If y is below window bottom, ensure that we still see a cursor. */
2170 h0 = min (FRAME_LINE_HEIGHT (f), row->visible_height);
2172 h = max (h0, glyph->ascent + glyph->descent);
2173 h0 = min (h0, glyph->ascent + glyph->descent);
2175 y0 = WINDOW_HEADER_LINE_HEIGHT (w);
2176 if (y < y0)
2178 h = max (h - (y0 - y) + 1, h0);
2179 y = y0 - 1;
2181 else
2183 y0 = window_text_bottom_y (w) - h0;
2184 if (y > y0)
2186 h += y - y0;
2187 y = y0;
2191 *xp = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x);
2192 *yp = WINDOW_TO_FRAME_PIXEL_Y (w, y);
2193 *heightp = h;
2197 * Remember which glyph the mouse is over.
2200 void
2201 remember_mouse_glyph (struct frame *f, int gx, int gy, NativeRectangle *rect)
2203 Lisp_Object window;
2204 struct window *w;
2205 struct glyph_row *r, *gr, *end_row;
2206 enum window_part part;
2207 enum glyph_row_area area;
2208 int x, y, width, height;
2210 /* Try to determine frame pixel position and size of the glyph under
2211 frame pixel coordinates X/Y on frame F. */
2213 if (!f->glyphs_initialized_p
2214 || (window = window_from_coordinates (f, gx, gy, &part, 0),
2215 NILP (window)))
2217 width = FRAME_SMALLEST_CHAR_WIDTH (f);
2218 height = FRAME_SMALLEST_FONT_HEIGHT (f);
2219 goto virtual_glyph;
2222 w = XWINDOW (window);
2223 width = WINDOW_FRAME_COLUMN_WIDTH (w);
2224 height = WINDOW_FRAME_LINE_HEIGHT (w);
2226 x = window_relative_x_coord (w, part, gx);
2227 y = gy - WINDOW_TOP_EDGE_Y (w);
2229 r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
2230 end_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
2232 if (w->pseudo_window_p)
2234 area = TEXT_AREA;
2235 part = ON_MODE_LINE; /* Don't adjust margin. */
2236 goto text_glyph;
2239 switch (part)
2241 case ON_LEFT_MARGIN:
2242 area = LEFT_MARGIN_AREA;
2243 goto text_glyph;
2245 case ON_RIGHT_MARGIN:
2246 area = RIGHT_MARGIN_AREA;
2247 goto text_glyph;
2249 case ON_HEADER_LINE:
2250 case ON_MODE_LINE:
2251 gr = (part == ON_HEADER_LINE
2252 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
2253 : MATRIX_MODE_LINE_ROW (w->current_matrix));
2254 gy = gr->y;
2255 area = TEXT_AREA;
2256 goto text_glyph_row_found;
2258 case ON_TEXT:
2259 area = TEXT_AREA;
2261 text_glyph:
2262 gr = 0; gy = 0;
2263 for (; r <= end_row && r->enabled_p; ++r)
2264 if (r->y + r->height > y)
2266 gr = r; gy = r->y;
2267 break;
2270 text_glyph_row_found:
2271 if (gr && gy <= y)
2273 struct glyph *g = gr->glyphs[area];
2274 struct glyph *end = g + gr->used[area];
2276 height = gr->height;
2277 for (gx = gr->x; g < end; gx += g->pixel_width, ++g)
2278 if (gx + g->pixel_width > x)
2279 break;
2281 if (g < end)
2283 if (g->type == IMAGE_GLYPH)
2285 /* Don't remember when mouse is over image, as
2286 image may have hot-spots. */
2287 STORE_NATIVE_RECT (*rect, 0, 0, 0, 0);
2288 return;
2290 width = g->pixel_width;
2292 else
2294 /* Use nominal char spacing at end of line. */
2295 x -= gx;
2296 gx += (x / width) * width;
2299 if (part != ON_MODE_LINE && part != ON_HEADER_LINE)
2300 gx += window_box_left_offset (w, area);
2302 else
2304 /* Use nominal line height at end of window. */
2305 gx = (x / width) * width;
2306 y -= gy;
2307 gy += (y / height) * height;
2309 break;
2311 case ON_LEFT_FRINGE:
2312 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2313 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w)
2314 : window_box_right_offset (w, LEFT_MARGIN_AREA));
2315 width = WINDOW_LEFT_FRINGE_WIDTH (w);
2316 goto row_glyph;
2318 case ON_RIGHT_FRINGE:
2319 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2320 ? window_box_right_offset (w, RIGHT_MARGIN_AREA)
2321 : window_box_right_offset (w, TEXT_AREA));
2322 width = WINDOW_RIGHT_FRINGE_WIDTH (w);
2323 goto row_glyph;
2325 case ON_SCROLL_BAR:
2326 gx = (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)
2328 : (window_box_right_offset (w, RIGHT_MARGIN_AREA)
2329 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2330 ? WINDOW_RIGHT_FRINGE_WIDTH (w)
2331 : 0)));
2332 width = WINDOW_SCROLL_BAR_AREA_WIDTH (w);
2334 row_glyph:
2335 gr = 0, gy = 0;
2336 for (; r <= end_row && r->enabled_p; ++r)
2337 if (r->y + r->height > y)
2339 gr = r; gy = r->y;
2340 break;
2343 if (gr && gy <= y)
2344 height = gr->height;
2345 else
2347 /* Use nominal line height at end of window. */
2348 y -= gy;
2349 gy += (y / height) * height;
2351 break;
2353 default:
2355 virtual_glyph:
2356 /* If there is no glyph under the mouse, then we divide the screen
2357 into a grid of the smallest glyph in the frame, and use that
2358 as our "glyph". */
2360 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to
2361 round down even for negative values. */
2362 if (gx < 0)
2363 gx -= width - 1;
2364 if (gy < 0)
2365 gy -= height - 1;
2367 gx = (gx / width) * width;
2368 gy = (gy / height) * height;
2370 goto store_rect;
2373 gx += WINDOW_LEFT_EDGE_X (w);
2374 gy += WINDOW_TOP_EDGE_Y (w);
2376 store_rect:
2377 STORE_NATIVE_RECT (*rect, gx, gy, width, height);
2379 /* Visible feedback for debugging. */
2380 #if 0
2381 #if HAVE_X_WINDOWS
2382 XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2383 f->output_data.x->normal_gc,
2384 gx, gy, width, height);
2385 #endif
2386 #endif
2390 #endif /* HAVE_WINDOW_SYSTEM */
2393 /***********************************************************************
2394 Lisp form evaluation
2395 ***********************************************************************/
2397 /* Error handler for safe_eval and safe_call. */
2399 static Lisp_Object
2400 safe_eval_handler (Lisp_Object arg)
2402 add_to_log ("Error during redisplay: %s", arg, Qnil);
2403 return Qnil;
2407 /* Evaluate SEXPR and return the result, or nil if something went
2408 wrong. Prevent redisplay during the evaluation. */
2410 /* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1].
2411 Return the result, or nil if something went wrong. Prevent
2412 redisplay during the evaluation. */
2414 Lisp_Object
2415 safe_call (int nargs, Lisp_Object *args)
2417 Lisp_Object val;
2419 if (inhibit_eval_during_redisplay)
2420 val = Qnil;
2421 else
2423 int count = SPECPDL_INDEX ();
2424 struct gcpro gcpro1;
2426 GCPRO1 (args[0]);
2427 gcpro1.nvars = nargs;
2428 specbind (Qinhibit_redisplay, Qt);
2429 /* Use Qt to ensure debugger does not run,
2430 so there is no possibility of wanting to redisplay. */
2431 val = internal_condition_case_n (Ffuncall, nargs, args, Qt,
2432 safe_eval_handler);
2433 UNGCPRO;
2434 val = unbind_to (count, val);
2437 return val;
2441 /* Call function FN with one argument ARG.
2442 Return the result, or nil if something went wrong. */
2444 Lisp_Object
2445 safe_call1 (Lisp_Object fn, Lisp_Object arg)
2447 Lisp_Object args[2];
2448 args[0] = fn;
2449 args[1] = arg;
2450 return safe_call (2, args);
2453 static Lisp_Object Qeval;
2455 Lisp_Object
2456 safe_eval (Lisp_Object sexpr)
2458 return safe_call1 (Qeval, sexpr);
2461 /* Call function FN with one argument ARG.
2462 Return the result, or nil if something went wrong. */
2464 Lisp_Object
2465 safe_call2 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2)
2467 Lisp_Object args[3];
2468 args[0] = fn;
2469 args[1] = arg1;
2470 args[2] = arg2;
2471 return safe_call (3, args);
2476 /***********************************************************************
2477 Debugging
2478 ***********************************************************************/
2480 #if 0
2482 /* Define CHECK_IT to perform sanity checks on iterators.
2483 This is for debugging. It is too slow to do unconditionally. */
2485 static void
2486 check_it (it)
2487 struct it *it;
2489 if (it->method == GET_FROM_STRING)
2491 xassert (STRINGP (it->string));
2492 xassert (IT_STRING_CHARPOS (*it) >= 0);
2494 else
2496 xassert (IT_STRING_CHARPOS (*it) < 0);
2497 if (it->method == GET_FROM_BUFFER)
2499 /* Check that character and byte positions agree. */
2500 xassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
2504 if (it->dpvec)
2505 xassert (it->current.dpvec_index >= 0);
2506 else
2507 xassert (it->current.dpvec_index < 0);
2510 #define CHECK_IT(IT) check_it ((IT))
2512 #else /* not 0 */
2514 #define CHECK_IT(IT) (void) 0
2516 #endif /* not 0 */
2519 #if GLYPH_DEBUG
2521 /* Check that the window end of window W is what we expect it
2522 to be---the last row in the current matrix displaying text. */
2524 static void
2525 check_window_end (w)
2526 struct window *w;
2528 if (!MINI_WINDOW_P (w)
2529 && !NILP (w->window_end_valid))
2531 struct glyph_row *row;
2532 xassert ((row = MATRIX_ROW (w->current_matrix,
2533 XFASTINT (w->window_end_vpos)),
2534 !row->enabled_p
2535 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
2536 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
2540 #define CHECK_WINDOW_END(W) check_window_end ((W))
2542 #else /* not GLYPH_DEBUG */
2544 #define CHECK_WINDOW_END(W) (void) 0
2546 #endif /* not GLYPH_DEBUG */
2550 /***********************************************************************
2551 Iterator initialization
2552 ***********************************************************************/
2554 /* Initialize IT for displaying current_buffer in window W, starting
2555 at character position CHARPOS. CHARPOS < 0 means that no buffer
2556 position is specified which is useful when the iterator is assigned
2557 a position later. BYTEPOS is the byte position corresponding to
2558 CHARPOS. BYTEPOS < 0 means compute it from CHARPOS.
2560 If ROW is not null, calls to produce_glyphs with IT as parameter
2561 will produce glyphs in that row.
2563 BASE_FACE_ID is the id of a base face to use. It must be one of
2564 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2565 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2566 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2568 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2569 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2570 will be initialized to use the corresponding mode line glyph row of
2571 the desired matrix of W. */
2573 void
2574 init_iterator (struct it *it, struct window *w,
2575 EMACS_INT charpos, EMACS_INT bytepos,
2576 struct glyph_row *row, enum face_id base_face_id)
2578 int highlight_region_p;
2579 enum face_id remapped_base_face_id = base_face_id;
2581 /* Some precondition checks. */
2582 xassert (w != NULL && it != NULL);
2583 xassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
2584 && charpos <= ZV));
2586 /* If face attributes have been changed since the last redisplay,
2587 free realized faces now because they depend on face definitions
2588 that might have changed. Don't free faces while there might be
2589 desired matrices pending which reference these faces. */
2590 if (face_change_count && !inhibit_free_realized_faces)
2592 face_change_count = 0;
2593 free_all_realized_faces (Qnil);
2596 /* Perhaps remap BASE_FACE_ID to a user-specified alternative. */
2597 if (! NILP (Vface_remapping_alist))
2598 remapped_base_face_id = lookup_basic_face (XFRAME (w->frame), base_face_id);
2600 /* Use one of the mode line rows of W's desired matrix if
2601 appropriate. */
2602 if (row == NULL)
2604 if (base_face_id == MODE_LINE_FACE_ID
2605 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
2606 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
2607 else if (base_face_id == HEADER_LINE_FACE_ID)
2608 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
2611 /* Clear IT. */
2612 memset (it, 0, sizeof *it);
2613 it->current.overlay_string_index = -1;
2614 it->current.dpvec_index = -1;
2615 it->base_face_id = remapped_base_face_id;
2616 it->string = Qnil;
2617 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
2619 /* The window in which we iterate over current_buffer: */
2620 XSETWINDOW (it->window, w);
2621 it->w = w;
2622 it->f = XFRAME (w->frame);
2624 it->cmp_it.id = -1;
2626 /* Extra space between lines (on window systems only). */
2627 if (base_face_id == DEFAULT_FACE_ID
2628 && FRAME_WINDOW_P (it->f))
2630 if (NATNUMP (current_buffer->extra_line_spacing))
2631 it->extra_line_spacing = XFASTINT (current_buffer->extra_line_spacing);
2632 else if (FLOATP (current_buffer->extra_line_spacing))
2633 it->extra_line_spacing = (XFLOAT_DATA (current_buffer->extra_line_spacing)
2634 * FRAME_LINE_HEIGHT (it->f));
2635 else if (it->f->extra_line_spacing > 0)
2636 it->extra_line_spacing = it->f->extra_line_spacing;
2637 it->max_extra_line_spacing = 0;
2640 /* If realized faces have been removed, e.g. because of face
2641 attribute changes of named faces, recompute them. When running
2642 in batch mode, the face cache of the initial frame is null. If
2643 we happen to get called, make a dummy face cache. */
2644 if (FRAME_FACE_CACHE (it->f) == NULL)
2645 init_frame_faces (it->f);
2646 if (FRAME_FACE_CACHE (it->f)->used == 0)
2647 recompute_basic_faces (it->f);
2649 /* Current value of the `slice', `space-width', and 'height' properties. */
2650 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
2651 it->space_width = Qnil;
2652 it->font_height = Qnil;
2653 it->override_ascent = -1;
2655 /* Are control characters displayed as `^C'? */
2656 it->ctl_arrow_p = !NILP (current_buffer->ctl_arrow);
2658 /* -1 means everything between a CR and the following line end
2659 is invisible. >0 means lines indented more than this value are
2660 invisible. */
2661 it->selective = (INTEGERP (current_buffer->selective_display)
2662 ? XFASTINT (current_buffer->selective_display)
2663 : (!NILP (current_buffer->selective_display)
2664 ? -1 : 0));
2665 it->selective_display_ellipsis_p
2666 = !NILP (current_buffer->selective_display_ellipses);
2668 /* Display table to use. */
2669 it->dp = window_display_table (w);
2671 /* Are multibyte characters enabled in current_buffer? */
2672 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
2674 /* Do we need to reorder bidirectional text? Not if this is a
2675 unibyte buffer: by definition, none of the single-byte characters
2676 are strong R2L, so no reordering is needed. And bidi.c doesn't
2677 support unibyte buffers anyway. */
2678 it->bidi_p
2679 = !NILP (current_buffer->bidi_display_reordering) && it->multibyte_p;
2681 /* Non-zero if we should highlight the region. */
2682 highlight_region_p
2683 = (!NILP (Vtransient_mark_mode)
2684 && !NILP (current_buffer->mark_active)
2685 && XMARKER (current_buffer->mark)->buffer != 0);
2687 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
2688 start and end of a visible region in window IT->w. Set both to
2689 -1 to indicate no region. */
2690 if (highlight_region_p
2691 /* Maybe highlight only in selected window. */
2692 && (/* Either show region everywhere. */
2693 highlight_nonselected_windows
2694 /* Or show region in the selected window. */
2695 || w == XWINDOW (selected_window)
2696 /* Or show the region if we are in the mini-buffer and W is
2697 the window the mini-buffer refers to. */
2698 || (MINI_WINDOW_P (XWINDOW (selected_window))
2699 && WINDOWP (minibuf_selected_window)
2700 && w == XWINDOW (minibuf_selected_window))))
2702 EMACS_INT charpos = marker_position (current_buffer->mark);
2703 it->region_beg_charpos = min (PT, charpos);
2704 it->region_end_charpos = max (PT, charpos);
2706 else
2707 it->region_beg_charpos = it->region_end_charpos = -1;
2709 /* Get the position at which the redisplay_end_trigger hook should
2710 be run, if it is to be run at all. */
2711 if (MARKERP (w->redisplay_end_trigger)
2712 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2713 it->redisplay_end_trigger_charpos
2714 = marker_position (w->redisplay_end_trigger);
2715 else if (INTEGERP (w->redisplay_end_trigger))
2716 it->redisplay_end_trigger_charpos = XINT (w->redisplay_end_trigger);
2718 /* Correct bogus values of tab_width. */
2719 it->tab_width = XINT (current_buffer->tab_width);
2720 if (it->tab_width <= 0 || it->tab_width > 1000)
2721 it->tab_width = 8;
2723 /* Are lines in the display truncated? */
2724 if (base_face_id != DEFAULT_FACE_ID
2725 || XINT (it->w->hscroll)
2726 || (! WINDOW_FULL_WIDTH_P (it->w)
2727 && ((!NILP (Vtruncate_partial_width_windows)
2728 && !INTEGERP (Vtruncate_partial_width_windows))
2729 || (INTEGERP (Vtruncate_partial_width_windows)
2730 && (WINDOW_TOTAL_COLS (it->w)
2731 < XINT (Vtruncate_partial_width_windows))))))
2732 it->line_wrap = TRUNCATE;
2733 else if (NILP (current_buffer->truncate_lines))
2734 it->line_wrap = NILP (current_buffer->word_wrap)
2735 ? WINDOW_WRAP : WORD_WRAP;
2736 else
2737 it->line_wrap = TRUNCATE;
2739 /* Get dimensions of truncation and continuation glyphs. These are
2740 displayed as fringe bitmaps under X, so we don't need them for such
2741 frames. */
2742 if (!FRAME_WINDOW_P (it->f))
2744 if (it->line_wrap == TRUNCATE)
2746 /* We will need the truncation glyph. */
2747 xassert (it->glyph_row == NULL);
2748 produce_special_glyphs (it, IT_TRUNCATION);
2749 it->truncation_pixel_width = it->pixel_width;
2751 else
2753 /* We will need the continuation glyph. */
2754 xassert (it->glyph_row == NULL);
2755 produce_special_glyphs (it, IT_CONTINUATION);
2756 it->continuation_pixel_width = it->pixel_width;
2759 /* Reset these values to zero because the produce_special_glyphs
2760 above has changed them. */
2761 it->pixel_width = it->ascent = it->descent = 0;
2762 it->phys_ascent = it->phys_descent = 0;
2765 /* Set this after getting the dimensions of truncation and
2766 continuation glyphs, so that we don't produce glyphs when calling
2767 produce_special_glyphs, above. */
2768 it->glyph_row = row;
2769 it->area = TEXT_AREA;
2771 /* Forget any previous info about this row being reversed. */
2772 if (it->glyph_row)
2773 it->glyph_row->reversed_p = 0;
2775 /* Get the dimensions of the display area. The display area
2776 consists of the visible window area plus a horizontally scrolled
2777 part to the left of the window. All x-values are relative to the
2778 start of this total display area. */
2779 if (base_face_id != DEFAULT_FACE_ID)
2781 /* Mode lines, menu bar in terminal frames. */
2782 it->first_visible_x = 0;
2783 it->last_visible_x = WINDOW_TOTAL_WIDTH (w);
2785 else
2787 it->first_visible_x
2788 = XFASTINT (it->w->hscroll) * FRAME_COLUMN_WIDTH (it->f);
2789 it->last_visible_x = (it->first_visible_x
2790 + window_box_width (w, TEXT_AREA));
2792 /* If we truncate lines, leave room for the truncator glyph(s) at
2793 the right margin. Otherwise, leave room for the continuation
2794 glyph(s). Truncation and continuation glyphs are not inserted
2795 for window-based redisplay. */
2796 if (!FRAME_WINDOW_P (it->f))
2798 if (it->line_wrap == TRUNCATE)
2799 it->last_visible_x -= it->truncation_pixel_width;
2800 else
2801 it->last_visible_x -= it->continuation_pixel_width;
2804 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
2805 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
2808 /* Leave room for a border glyph. */
2809 if (!FRAME_WINDOW_P (it->f)
2810 && !WINDOW_RIGHTMOST_P (it->w))
2811 it->last_visible_x -= 1;
2813 it->last_visible_y = window_text_bottom_y (w);
2815 /* For mode lines and alike, arrange for the first glyph having a
2816 left box line if the face specifies a box. */
2817 if (base_face_id != DEFAULT_FACE_ID)
2819 struct face *face;
2821 it->face_id = remapped_base_face_id;
2823 /* If we have a boxed mode line, make the first character appear
2824 with a left box line. */
2825 face = FACE_FROM_ID (it->f, remapped_base_face_id);
2826 if (face->box != FACE_NO_BOX)
2827 it->start_of_box_run_p = 1;
2830 /* If we are to reorder bidirectional text, init the bidi
2831 iterator. */
2832 if (it->bidi_p)
2834 /* Note the paragraph direction that this buffer wants to
2835 use. */
2836 if (EQ (current_buffer->bidi_paragraph_direction, Qleft_to_right))
2837 it->paragraph_embedding = L2R;
2838 else if (EQ (current_buffer->bidi_paragraph_direction, Qright_to_left))
2839 it->paragraph_embedding = R2L;
2840 else
2841 it->paragraph_embedding = NEUTRAL_DIR;
2842 bidi_init_it (charpos, bytepos, &it->bidi_it);
2845 /* If a buffer position was specified, set the iterator there,
2846 getting overlays and face properties from that position. */
2847 if (charpos >= BUF_BEG (current_buffer))
2849 it->end_charpos = ZV;
2850 it->face_id = -1;
2851 IT_CHARPOS (*it) = charpos;
2853 /* Compute byte position if not specified. */
2854 if (bytepos < charpos)
2855 IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos);
2856 else
2857 IT_BYTEPOS (*it) = bytepos;
2859 it->start = it->current;
2861 /* Compute faces etc. */
2862 reseat (it, it->current.pos, 1);
2865 CHECK_IT (it);
2869 /* Initialize IT for the display of window W with window start POS. */
2871 void
2872 start_display (struct it *it, struct window *w, struct text_pos pos)
2874 struct glyph_row *row;
2875 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
2877 row = w->desired_matrix->rows + first_vpos;
2878 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
2879 it->first_vpos = first_vpos;
2881 /* Don't reseat to previous visible line start if current start
2882 position is in a string or image. */
2883 if (it->method == GET_FROM_BUFFER && it->line_wrap != TRUNCATE)
2885 int start_at_line_beg_p;
2886 int first_y = it->current_y;
2888 /* If window start is not at a line start, skip forward to POS to
2889 get the correct continuation lines width. */
2890 start_at_line_beg_p = (CHARPOS (pos) == BEGV
2891 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
2892 if (!start_at_line_beg_p)
2894 int new_x;
2896 reseat_at_previous_visible_line_start (it);
2897 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
2899 new_x = it->current_x + it->pixel_width;
2901 /* If lines are continued, this line may end in the middle
2902 of a multi-glyph character (e.g. a control character
2903 displayed as \003, or in the middle of an overlay
2904 string). In this case move_it_to above will not have
2905 taken us to the start of the continuation line but to the
2906 end of the continued line. */
2907 if (it->current_x > 0
2908 && it->line_wrap != TRUNCATE /* Lines are continued. */
2909 && (/* And glyph doesn't fit on the line. */
2910 new_x > it->last_visible_x
2911 /* Or it fits exactly and we're on a window
2912 system frame. */
2913 || (new_x == it->last_visible_x
2914 && FRAME_WINDOW_P (it->f))))
2916 if (it->current.dpvec_index >= 0
2917 || it->current.overlay_string_index >= 0)
2919 set_iterator_to_next (it, 1);
2920 move_it_in_display_line_to (it, -1, -1, 0);
2923 it->continuation_lines_width += it->current_x;
2926 /* We're starting a new display line, not affected by the
2927 height of the continued line, so clear the appropriate
2928 fields in the iterator structure. */
2929 it->max_ascent = it->max_descent = 0;
2930 it->max_phys_ascent = it->max_phys_descent = 0;
2932 it->current_y = first_y;
2933 it->vpos = 0;
2934 it->current_x = it->hpos = 0;
2940 /* Return 1 if POS is a position in ellipses displayed for invisible
2941 text. W is the window we display, for text property lookup. */
2943 static int
2944 in_ellipses_for_invisible_text_p (struct display_pos *pos, struct window *w)
2946 Lisp_Object prop, window;
2947 int ellipses_p = 0;
2948 EMACS_INT charpos = CHARPOS (pos->pos);
2950 /* If POS specifies a position in a display vector, this might
2951 be for an ellipsis displayed for invisible text. We won't
2952 get the iterator set up for delivering that ellipsis unless
2953 we make sure that it gets aware of the invisible text. */
2954 if (pos->dpvec_index >= 0
2955 && pos->overlay_string_index < 0
2956 && CHARPOS (pos->string_pos) < 0
2957 && charpos > BEGV
2958 && (XSETWINDOW (window, w),
2959 prop = Fget_char_property (make_number (charpos),
2960 Qinvisible, window),
2961 !TEXT_PROP_MEANS_INVISIBLE (prop)))
2963 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
2964 window);
2965 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
2968 return ellipses_p;
2972 /* Initialize IT for stepping through current_buffer in window W,
2973 starting at position POS that includes overlay string and display
2974 vector/ control character translation position information. Value
2975 is zero if there are overlay strings with newlines at POS. */
2977 static int
2978 init_from_display_pos (struct it *it, struct window *w, struct display_pos *pos)
2980 EMACS_INT charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
2981 int i, overlay_strings_with_newlines = 0;
2983 /* If POS specifies a position in a display vector, this might
2984 be for an ellipsis displayed for invisible text. We won't
2985 get the iterator set up for delivering that ellipsis unless
2986 we make sure that it gets aware of the invisible text. */
2987 if (in_ellipses_for_invisible_text_p (pos, w))
2989 --charpos;
2990 bytepos = 0;
2993 /* Keep in mind: the call to reseat in init_iterator skips invisible
2994 text, so we might end up at a position different from POS. This
2995 is only a problem when POS is a row start after a newline and an
2996 overlay starts there with an after-string, and the overlay has an
2997 invisible property. Since we don't skip invisible text in
2998 display_line and elsewhere immediately after consuming the
2999 newline before the row start, such a POS will not be in a string,
3000 but the call to init_iterator below will move us to the
3001 after-string. */
3002 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
3004 /* This only scans the current chunk -- it should scan all chunks.
3005 However, OVERLAY_STRING_CHUNK_SIZE has been increased from 3 in 21.1
3006 to 16 in 22.1 to make this a lesser problem. */
3007 for (i = 0; i < it->n_overlay_strings && i < OVERLAY_STRING_CHUNK_SIZE; ++i)
3009 const char *s = SDATA (it->overlay_strings[i]);
3010 const char *e = s + SBYTES (it->overlay_strings[i]);
3012 while (s < e && *s != '\n')
3013 ++s;
3015 if (s < e)
3017 overlay_strings_with_newlines = 1;
3018 break;
3022 /* If position is within an overlay string, set up IT to the right
3023 overlay string. */
3024 if (pos->overlay_string_index >= 0)
3026 int relative_index;
3028 /* If the first overlay string happens to have a `display'
3029 property for an image, the iterator will be set up for that
3030 image, and we have to undo that setup first before we can
3031 correct the overlay string index. */
3032 if (it->method == GET_FROM_IMAGE)
3033 pop_it (it);
3035 /* We already have the first chunk of overlay strings in
3036 IT->overlay_strings. Load more until the one for
3037 pos->overlay_string_index is in IT->overlay_strings. */
3038 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
3040 int n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
3041 it->current.overlay_string_index = 0;
3042 while (n--)
3044 load_overlay_strings (it, 0);
3045 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
3049 it->current.overlay_string_index = pos->overlay_string_index;
3050 relative_index = (it->current.overlay_string_index
3051 % OVERLAY_STRING_CHUNK_SIZE);
3052 it->string = it->overlay_strings[relative_index];
3053 xassert (STRINGP (it->string));
3054 it->current.string_pos = pos->string_pos;
3055 it->method = GET_FROM_STRING;
3058 if (CHARPOS (pos->string_pos) >= 0)
3060 /* Recorded position is not in an overlay string, but in another
3061 string. This can only be a string from a `display' property.
3062 IT should already be filled with that string. */
3063 it->current.string_pos = pos->string_pos;
3064 xassert (STRINGP (it->string));
3067 /* Restore position in display vector translations, control
3068 character translations or ellipses. */
3069 if (pos->dpvec_index >= 0)
3071 if (it->dpvec == NULL)
3072 get_next_display_element (it);
3073 xassert (it->dpvec && it->current.dpvec_index == 0);
3074 it->current.dpvec_index = pos->dpvec_index;
3077 CHECK_IT (it);
3078 return !overlay_strings_with_newlines;
3082 /* Initialize IT for stepping through current_buffer in window W
3083 starting at ROW->start. */
3085 static void
3086 init_to_row_start (struct it *it, struct window *w, struct glyph_row *row)
3088 init_from_display_pos (it, w, &row->start);
3089 it->start = row->start;
3090 it->continuation_lines_width = row->continuation_lines_width;
3091 CHECK_IT (it);
3095 /* Initialize IT for stepping through current_buffer in window W
3096 starting in the line following ROW, i.e. starting at ROW->end.
3097 Value is zero if there are overlay strings with newlines at ROW's
3098 end position. */
3100 static int
3101 init_to_row_end (struct it *it, struct window *w, struct glyph_row *row)
3103 int success = 0;
3105 if (init_from_display_pos (it, w, &row->end))
3107 if (row->continued_p)
3108 it->continuation_lines_width
3109 = row->continuation_lines_width + row->pixel_width;
3110 CHECK_IT (it);
3111 success = 1;
3114 return success;
3120 /***********************************************************************
3121 Text properties
3122 ***********************************************************************/
3124 /* Called when IT reaches IT->stop_charpos. Handle text property and
3125 overlay changes. Set IT->stop_charpos to the next position where
3126 to stop. */
3128 static void
3129 handle_stop (struct it *it)
3131 enum prop_handled handled;
3132 int handle_overlay_change_p;
3133 struct props *p;
3135 it->dpvec = NULL;
3136 it->current.dpvec_index = -1;
3137 handle_overlay_change_p = !it->ignore_overlay_strings_at_pos_p;
3138 it->ignore_overlay_strings_at_pos_p = 0;
3139 it->ellipsis_p = 0;
3141 /* Use face of preceding text for ellipsis (if invisible) */
3142 if (it->selective_display_ellipsis_p)
3143 it->saved_face_id = it->face_id;
3147 handled = HANDLED_NORMALLY;
3149 /* Call text property handlers. */
3150 for (p = it_props; p->handler; ++p)
3152 handled = p->handler (it);
3154 if (handled == HANDLED_RECOMPUTE_PROPS)
3155 break;
3156 else if (handled == HANDLED_RETURN)
3158 /* We still want to show before and after strings from
3159 overlays even if the actual buffer text is replaced. */
3160 if (!handle_overlay_change_p
3161 || it->sp > 1
3162 || !get_overlay_strings_1 (it, 0, 0))
3164 if (it->ellipsis_p)
3165 setup_for_ellipsis (it, 0);
3166 /* When handling a display spec, we might load an
3167 empty string. In that case, discard it here. We
3168 used to discard it in handle_single_display_spec,
3169 but that causes get_overlay_strings_1, above, to
3170 ignore overlay strings that we must check. */
3171 if (STRINGP (it->string) && !SCHARS (it->string))
3172 pop_it (it);
3173 return;
3175 else if (STRINGP (it->string) && !SCHARS (it->string))
3176 pop_it (it);
3177 else
3179 it->ignore_overlay_strings_at_pos_p = 1;
3180 it->string_from_display_prop_p = 0;
3181 handle_overlay_change_p = 0;
3183 handled = HANDLED_RECOMPUTE_PROPS;
3184 break;
3186 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
3187 handle_overlay_change_p = 0;
3190 if (handled != HANDLED_RECOMPUTE_PROPS)
3192 /* Don't check for overlay strings below when set to deliver
3193 characters from a display vector. */
3194 if (it->method == GET_FROM_DISPLAY_VECTOR)
3195 handle_overlay_change_p = 0;
3197 /* Handle overlay changes.
3198 This sets HANDLED to HANDLED_RECOMPUTE_PROPS
3199 if it finds overlays. */
3200 if (handle_overlay_change_p)
3201 handled = handle_overlay_change (it);
3204 if (it->ellipsis_p)
3206 setup_for_ellipsis (it, 0);
3207 break;
3210 while (handled == HANDLED_RECOMPUTE_PROPS);
3212 /* Determine where to stop next. */
3213 if (handled == HANDLED_NORMALLY)
3214 compute_stop_pos (it);
3218 /* Compute IT->stop_charpos from text property and overlay change
3219 information for IT's current position. */
3221 static void
3222 compute_stop_pos (struct it *it)
3224 register INTERVAL iv, next_iv;
3225 Lisp_Object object, limit, position;
3226 EMACS_INT charpos, bytepos;
3228 /* If nowhere else, stop at the end. */
3229 it->stop_charpos = it->end_charpos;
3231 if (STRINGP (it->string))
3233 /* Strings are usually short, so don't limit the search for
3234 properties. */
3235 object = it->string;
3236 limit = Qnil;
3237 charpos = IT_STRING_CHARPOS (*it);
3238 bytepos = IT_STRING_BYTEPOS (*it);
3240 else
3242 EMACS_INT pos;
3244 /* If next overlay change is in front of the current stop pos
3245 (which is IT->end_charpos), stop there. Note: value of
3246 next_overlay_change is point-max if no overlay change
3247 follows. */
3248 charpos = IT_CHARPOS (*it);
3249 bytepos = IT_BYTEPOS (*it);
3250 pos = next_overlay_change (charpos);
3251 if (pos < it->stop_charpos)
3252 it->stop_charpos = pos;
3254 /* If showing the region, we have to stop at the region
3255 start or end because the face might change there. */
3256 if (it->region_beg_charpos > 0)
3258 if (IT_CHARPOS (*it) < it->region_beg_charpos)
3259 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
3260 else if (IT_CHARPOS (*it) < it->region_end_charpos)
3261 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
3264 /* Set up variables for computing the stop position from text
3265 property changes. */
3266 XSETBUFFER (object, current_buffer);
3267 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
3270 /* Get the interval containing IT's position. Value is a null
3271 interval if there isn't such an interval. */
3272 position = make_number (charpos);
3273 iv = validate_interval_range (object, &position, &position, 0);
3274 if (!NULL_INTERVAL_P (iv))
3276 Lisp_Object values_here[LAST_PROP_IDX];
3277 struct props *p;
3279 /* Get properties here. */
3280 for (p = it_props; p->handler; ++p)
3281 values_here[p->idx] = textget (iv->plist, *p->name);
3283 /* Look for an interval following iv that has different
3284 properties. */
3285 for (next_iv = next_interval (iv);
3286 (!NULL_INTERVAL_P (next_iv)
3287 && (NILP (limit)
3288 || XFASTINT (limit) > next_iv->position));
3289 next_iv = next_interval (next_iv))
3291 for (p = it_props; p->handler; ++p)
3293 Lisp_Object new_value;
3295 new_value = textget (next_iv->plist, *p->name);
3296 if (!EQ (values_here[p->idx], new_value))
3297 break;
3300 if (p->handler)
3301 break;
3304 if (!NULL_INTERVAL_P (next_iv))
3306 if (INTEGERP (limit)
3307 && next_iv->position >= XFASTINT (limit))
3308 /* No text property change up to limit. */
3309 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
3310 else
3311 /* Text properties change in next_iv. */
3312 it->stop_charpos = min (it->stop_charpos, next_iv->position);
3316 if (it->cmp_it.id < 0)
3318 EMACS_INT stoppos = it->end_charpos;
3320 if (it->bidi_p && it->bidi_it.scan_dir < 0)
3321 stoppos = -1;
3322 composition_compute_stop_pos (&it->cmp_it, charpos, bytepos,
3323 stoppos, it->string);
3326 xassert (STRINGP (it->string)
3327 || (it->stop_charpos >= BEGV
3328 && it->stop_charpos >= IT_CHARPOS (*it)));
3332 /* Return the position of the next overlay change after POS in
3333 current_buffer. Value is point-max if no overlay change
3334 follows. This is like `next-overlay-change' but doesn't use
3335 xmalloc. */
3337 static EMACS_INT
3338 next_overlay_change (EMACS_INT pos)
3340 int noverlays;
3341 EMACS_INT endpos;
3342 Lisp_Object *overlays;
3343 int i;
3345 /* Get all overlays at the given position. */
3346 GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, 1);
3348 /* If any of these overlays ends before endpos,
3349 use its ending point instead. */
3350 for (i = 0; i < noverlays; ++i)
3352 Lisp_Object oend;
3353 EMACS_INT oendpos;
3355 oend = OVERLAY_END (overlays[i]);
3356 oendpos = OVERLAY_POSITION (oend);
3357 endpos = min (endpos, oendpos);
3360 return endpos;
3365 /***********************************************************************
3366 Fontification
3367 ***********************************************************************/
3369 /* Handle changes in the `fontified' property of the current buffer by
3370 calling hook functions from Qfontification_functions to fontify
3371 regions of text. */
3373 static enum prop_handled
3374 handle_fontified_prop (struct it *it)
3376 Lisp_Object prop, pos;
3377 enum prop_handled handled = HANDLED_NORMALLY;
3379 if (!NILP (Vmemory_full))
3380 return handled;
3382 /* Get the value of the `fontified' property at IT's current buffer
3383 position. (The `fontified' property doesn't have a special
3384 meaning in strings.) If the value is nil, call functions from
3385 Qfontification_functions. */
3386 if (!STRINGP (it->string)
3387 && it->s == NULL
3388 && !NILP (Vfontification_functions)
3389 && !NILP (Vrun_hooks)
3390 && (pos = make_number (IT_CHARPOS (*it)),
3391 prop = Fget_char_property (pos, Qfontified, Qnil),
3392 /* Ignore the special cased nil value always present at EOB since
3393 no amount of fontifying will be able to change it. */
3394 NILP (prop) && IT_CHARPOS (*it) < Z))
3396 int count = SPECPDL_INDEX ();
3397 Lisp_Object val;
3399 val = Vfontification_functions;
3400 specbind (Qfontification_functions, Qnil);
3402 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
3403 safe_call1 (val, pos);
3404 else
3406 Lisp_Object globals, fn;
3407 struct gcpro gcpro1, gcpro2;
3409 globals = Qnil;
3410 GCPRO2 (val, globals);
3412 for (; CONSP (val); val = XCDR (val))
3414 fn = XCAR (val);
3416 if (EQ (fn, Qt))
3418 /* A value of t indicates this hook has a local
3419 binding; it means to run the global binding too.
3420 In a global value, t should not occur. If it
3421 does, we must ignore it to avoid an endless
3422 loop. */
3423 for (globals = Fdefault_value (Qfontification_functions);
3424 CONSP (globals);
3425 globals = XCDR (globals))
3427 fn = XCAR (globals);
3428 if (!EQ (fn, Qt))
3429 safe_call1 (fn, pos);
3432 else
3433 safe_call1 (fn, pos);
3436 UNGCPRO;
3439 unbind_to (count, Qnil);
3441 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
3442 something. This avoids an endless loop if they failed to
3443 fontify the text for which reason ever. */
3444 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
3445 handled = HANDLED_RECOMPUTE_PROPS;
3448 return handled;
3453 /***********************************************************************
3454 Faces
3455 ***********************************************************************/
3457 /* Set up iterator IT from face properties at its current position.
3458 Called from handle_stop. */
3460 static enum prop_handled
3461 handle_face_prop (struct it *it)
3463 int new_face_id;
3464 EMACS_INT next_stop;
3466 if (!STRINGP (it->string))
3468 new_face_id
3469 = face_at_buffer_position (it->w,
3470 IT_CHARPOS (*it),
3471 it->region_beg_charpos,
3472 it->region_end_charpos,
3473 &next_stop,
3474 (IT_CHARPOS (*it)
3475 + TEXT_PROP_DISTANCE_LIMIT),
3476 0, it->base_face_id);
3478 /* Is this a start of a run of characters with box face?
3479 Caveat: this can be called for a freshly initialized
3480 iterator; face_id is -1 in this case. We know that the new
3481 face will not change until limit, i.e. if the new face has a
3482 box, all characters up to limit will have one. But, as
3483 usual, we don't know whether limit is really the end. */
3484 if (new_face_id != it->face_id)
3486 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3488 /* If new face has a box but old face has not, this is
3489 the start of a run of characters with box, i.e. it has
3490 a shadow on the left side. The value of face_id of the
3491 iterator will be -1 if this is the initial call that gets
3492 the face. In this case, we have to look in front of IT's
3493 position and see whether there is a face != new_face_id. */
3494 it->start_of_box_run_p
3495 = (new_face->box != FACE_NO_BOX
3496 && (it->face_id >= 0
3497 || IT_CHARPOS (*it) == BEG
3498 || new_face_id != face_before_it_pos (it)));
3499 it->face_box_p = new_face->box != FACE_NO_BOX;
3502 else
3504 int base_face_id;
3505 EMACS_INT bufpos;
3506 int i;
3507 Lisp_Object from_overlay
3508 = (it->current.overlay_string_index >= 0
3509 ? it->string_overlays[it->current.overlay_string_index]
3510 : Qnil);
3512 /* See if we got to this string directly or indirectly from
3513 an overlay property. That includes the before-string or
3514 after-string of an overlay, strings in display properties
3515 provided by an overlay, their text properties, etc.
3517 FROM_OVERLAY is the overlay that brought us here, or nil if none. */
3518 if (! NILP (from_overlay))
3519 for (i = it->sp - 1; i >= 0; i--)
3521 if (it->stack[i].current.overlay_string_index >= 0)
3522 from_overlay
3523 = it->string_overlays[it->stack[i].current.overlay_string_index];
3524 else if (! NILP (it->stack[i].from_overlay))
3525 from_overlay = it->stack[i].from_overlay;
3527 if (!NILP (from_overlay))
3528 break;
3531 if (! NILP (from_overlay))
3533 bufpos = IT_CHARPOS (*it);
3534 /* For a string from an overlay, the base face depends
3535 only on text properties and ignores overlays. */
3536 base_face_id
3537 = face_for_overlay_string (it->w,
3538 IT_CHARPOS (*it),
3539 it->region_beg_charpos,
3540 it->region_end_charpos,
3541 &next_stop,
3542 (IT_CHARPOS (*it)
3543 + TEXT_PROP_DISTANCE_LIMIT),
3545 from_overlay);
3547 else
3549 bufpos = 0;
3551 /* For strings from a `display' property, use the face at
3552 IT's current buffer position as the base face to merge
3553 with, so that overlay strings appear in the same face as
3554 surrounding text, unless they specify their own
3555 faces. */
3556 base_face_id = underlying_face_id (it);
3559 new_face_id = face_at_string_position (it->w,
3560 it->string,
3561 IT_STRING_CHARPOS (*it),
3562 bufpos,
3563 it->region_beg_charpos,
3564 it->region_end_charpos,
3565 &next_stop,
3566 base_face_id, 0);
3568 /* Is this a start of a run of characters with box? Caveat:
3569 this can be called for a freshly allocated iterator; face_id
3570 is -1 is this case. We know that the new face will not
3571 change until the next check pos, i.e. if the new face has a
3572 box, all characters up to that position will have a
3573 box. But, as usual, we don't know whether that position
3574 is really the end. */
3575 if (new_face_id != it->face_id)
3577 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3578 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
3580 /* If new face has a box but old face hasn't, this is the
3581 start of a run of characters with box, i.e. it has a
3582 shadow on the left side. */
3583 it->start_of_box_run_p
3584 = new_face->box && (old_face == NULL || !old_face->box);
3585 it->face_box_p = new_face->box != FACE_NO_BOX;
3589 it->face_id = new_face_id;
3590 return HANDLED_NORMALLY;
3594 /* Return the ID of the face ``underlying'' IT's current position,
3595 which is in a string. If the iterator is associated with a
3596 buffer, return the face at IT's current buffer position.
3597 Otherwise, use the iterator's base_face_id. */
3599 static int
3600 underlying_face_id (struct it *it)
3602 int face_id = it->base_face_id, i;
3604 xassert (STRINGP (it->string));
3606 for (i = it->sp - 1; i >= 0; --i)
3607 if (NILP (it->stack[i].string))
3608 face_id = it->stack[i].face_id;
3610 return face_id;
3614 /* Compute the face one character before or after the current position
3615 of IT. BEFORE_P non-zero means get the face in front of IT's
3616 position. Value is the id of the face. */
3618 static int
3619 face_before_or_after_it_pos (struct it *it, int before_p)
3621 int face_id, limit;
3622 EMACS_INT next_check_charpos;
3623 struct text_pos pos;
3625 xassert (it->s == NULL);
3627 if (STRINGP (it->string))
3629 EMACS_INT bufpos;
3630 int base_face_id;
3632 /* No face change past the end of the string (for the case
3633 we are padding with spaces). No face change before the
3634 string start. */
3635 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
3636 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
3637 return it->face_id;
3639 /* Set pos to the position before or after IT's current position. */
3640 if (before_p)
3641 pos = string_pos (IT_STRING_CHARPOS (*it) - 1, it->string);
3642 else
3643 /* For composition, we must check the character after the
3644 composition. */
3645 pos = (it->what == IT_COMPOSITION
3646 ? string_pos (IT_STRING_CHARPOS (*it)
3647 + it->cmp_it.nchars, it->string)
3648 : string_pos (IT_STRING_CHARPOS (*it) + 1, it->string));
3650 if (it->current.overlay_string_index >= 0)
3651 bufpos = IT_CHARPOS (*it);
3652 else
3653 bufpos = 0;
3655 base_face_id = underlying_face_id (it);
3657 /* Get the face for ASCII, or unibyte. */
3658 face_id = face_at_string_position (it->w,
3659 it->string,
3660 CHARPOS (pos),
3661 bufpos,
3662 it->region_beg_charpos,
3663 it->region_end_charpos,
3664 &next_check_charpos,
3665 base_face_id, 0);
3667 /* Correct the face for charsets different from ASCII. Do it
3668 for the multibyte case only. The face returned above is
3669 suitable for unibyte text if IT->string is unibyte. */
3670 if (STRING_MULTIBYTE (it->string))
3672 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos);
3673 int c, len;
3674 struct face *face = FACE_FROM_ID (it->f, face_id);
3676 c = string_char_and_length (p, &len);
3677 face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), it->string);
3680 else
3682 if ((IT_CHARPOS (*it) >= ZV && !before_p)
3683 || (IT_CHARPOS (*it) <= BEGV && before_p))
3684 return it->face_id;
3686 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
3687 pos = it->current.pos;
3689 if (before_p)
3690 DEC_TEXT_POS (pos, it->multibyte_p);
3691 else
3693 if (it->what == IT_COMPOSITION)
3694 /* For composition, we must check the position after the
3695 composition. */
3696 pos.charpos += it->cmp_it.nchars, pos.bytepos += it->len;
3697 else
3698 INC_TEXT_POS (pos, it->multibyte_p);
3701 /* Determine face for CHARSET_ASCII, or unibyte. */
3702 face_id = face_at_buffer_position (it->w,
3703 CHARPOS (pos),
3704 it->region_beg_charpos,
3705 it->region_end_charpos,
3706 &next_check_charpos,
3707 limit, 0, -1);
3709 /* Correct the face for charsets different from ASCII. Do it
3710 for the multibyte case only. The face returned above is
3711 suitable for unibyte text if current_buffer is unibyte. */
3712 if (it->multibyte_p)
3714 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
3715 struct face *face = FACE_FROM_ID (it->f, face_id);
3716 face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), Qnil);
3720 return face_id;
3725 /***********************************************************************
3726 Invisible text
3727 ***********************************************************************/
3729 /* Set up iterator IT from invisible properties at its current
3730 position. Called from handle_stop. */
3732 static enum prop_handled
3733 handle_invisible_prop (struct it *it)
3735 enum prop_handled handled = HANDLED_NORMALLY;
3737 if (STRINGP (it->string))
3739 Lisp_Object prop, end_charpos, limit, charpos;
3741 /* Get the value of the invisible text property at the
3742 current position. Value will be nil if there is no such
3743 property. */
3744 charpos = make_number (IT_STRING_CHARPOS (*it));
3745 prop = Fget_text_property (charpos, Qinvisible, it->string);
3747 if (!NILP (prop)
3748 && IT_STRING_CHARPOS (*it) < it->end_charpos)
3750 handled = HANDLED_RECOMPUTE_PROPS;
3752 /* Get the position at which the next change of the
3753 invisible text property can be found in IT->string.
3754 Value will be nil if the property value is the same for
3755 all the rest of IT->string. */
3756 XSETINT (limit, SCHARS (it->string));
3757 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
3758 it->string, limit);
3760 /* Text at current position is invisible. The next
3761 change in the property is at position end_charpos.
3762 Move IT's current position to that position. */
3763 if (INTEGERP (end_charpos)
3764 && XFASTINT (end_charpos) < XFASTINT (limit))
3766 struct text_pos old;
3767 old = it->current.string_pos;
3768 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
3769 compute_string_pos (&it->current.string_pos, old, it->string);
3771 else
3773 /* The rest of the string is invisible. If this is an
3774 overlay string, proceed with the next overlay string
3775 or whatever comes and return a character from there. */
3776 if (it->current.overlay_string_index >= 0)
3778 next_overlay_string (it);
3779 /* Don't check for overlay strings when we just
3780 finished processing them. */
3781 handled = HANDLED_OVERLAY_STRING_CONSUMED;
3783 else
3785 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
3786 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
3791 else
3793 int invis_p;
3794 EMACS_INT newpos, next_stop, start_charpos, tem;
3795 Lisp_Object pos, prop, overlay;
3797 /* First of all, is there invisible text at this position? */
3798 tem = start_charpos = IT_CHARPOS (*it);
3799 pos = make_number (tem);
3800 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
3801 &overlay);
3802 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3804 /* If we are on invisible text, skip over it. */
3805 if (invis_p && start_charpos < it->end_charpos)
3807 /* Record whether we have to display an ellipsis for the
3808 invisible text. */
3809 int display_ellipsis_p = invis_p == 2;
3811 handled = HANDLED_RECOMPUTE_PROPS;
3813 /* Loop skipping over invisible text. The loop is left at
3814 ZV or with IT on the first char being visible again. */
3817 /* Try to skip some invisible text. Return value is the
3818 position reached which can be equal to where we start
3819 if there is nothing invisible there. This skips both
3820 over invisible text properties and overlays with
3821 invisible property. */
3822 newpos = skip_invisible (tem, &next_stop, ZV, it->window);
3824 /* If we skipped nothing at all we weren't at invisible
3825 text in the first place. If everything to the end of
3826 the buffer was skipped, end the loop. */
3827 if (newpos == tem || newpos >= ZV)
3828 invis_p = 0;
3829 else
3831 /* We skipped some characters but not necessarily
3832 all there are. Check if we ended up on visible
3833 text. Fget_char_property returns the property of
3834 the char before the given position, i.e. if we
3835 get invis_p = 0, this means that the char at
3836 newpos is visible. */
3837 pos = make_number (newpos);
3838 prop = Fget_char_property (pos, Qinvisible, it->window);
3839 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3842 /* If we ended up on invisible text, proceed to
3843 skip starting with next_stop. */
3844 if (invis_p)
3845 tem = next_stop;
3847 /* If there are adjacent invisible texts, don't lose the
3848 second one's ellipsis. */
3849 if (invis_p == 2)
3850 display_ellipsis_p = 1;
3852 while (invis_p);
3854 /* The position newpos is now either ZV or on visible text. */
3855 if (it->bidi_p && newpos < ZV)
3857 /* With bidi iteration, the region of invisible text
3858 could start and/or end in the middle of a non-base
3859 embedding level. Therefore, we need to skip
3860 invisible text using the bidi iterator, starting at
3861 IT's current position, until we find ourselves
3862 outside the invisible text. Skipping invisible text
3863 _after_ bidi iteration avoids affecting the visual
3864 order of the displayed text when invisible properties
3865 are added or removed. */
3866 if (it->bidi_it.first_elt)
3868 /* If we were `reseat'ed to a new paragraph,
3869 determine the paragraph base direction. We need
3870 to do it now because next_element_from_buffer may
3871 not have a chance to do it, if we are going to
3872 skip any text at the beginning, which resets the
3873 FIRST_ELT flag. */
3874 bidi_paragraph_init (it->paragraph_embedding,
3875 &it->bidi_it, 1);
3879 bidi_move_to_visually_next (&it->bidi_it);
3881 while (it->stop_charpos <= it->bidi_it.charpos
3882 && it->bidi_it.charpos < newpos);
3883 IT_CHARPOS (*it) = it->bidi_it.charpos;
3884 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
3885 /* If we overstepped NEWPOS, record its position in the
3886 iterator, so that we skip invisible text if later the
3887 bidi iteration lands us in the invisible region
3888 again. */
3889 if (IT_CHARPOS (*it) >= newpos)
3890 it->prev_stop = newpos;
3892 else
3894 IT_CHARPOS (*it) = newpos;
3895 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
3898 /* If there are before-strings at the start of invisible
3899 text, and the text is invisible because of a text
3900 property, arrange to show before-strings because 20.x did
3901 it that way. (If the text is invisible because of an
3902 overlay property instead of a text property, this is
3903 already handled in the overlay code.) */
3904 if (NILP (overlay)
3905 && get_overlay_strings (it, it->stop_charpos))
3907 handled = HANDLED_RECOMPUTE_PROPS;
3908 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
3910 else if (display_ellipsis_p)
3912 /* Make sure that the glyphs of the ellipsis will get
3913 correct `charpos' values. If we would not update
3914 it->position here, the glyphs would belong to the
3915 last visible character _before_ the invisible
3916 text, which confuses `set_cursor_from_row'.
3918 We use the last invisible position instead of the
3919 first because this way the cursor is always drawn on
3920 the first "." of the ellipsis, whenever PT is inside
3921 the invisible text. Otherwise the cursor would be
3922 placed _after_ the ellipsis when the point is after the
3923 first invisible character. */
3924 if (!STRINGP (it->object))
3926 it->position.charpos = newpos - 1;
3927 it->position.bytepos = CHAR_TO_BYTE (it->position.charpos);
3929 it->ellipsis_p = 1;
3930 /* Let the ellipsis display before
3931 considering any properties of the following char.
3932 Fixes jasonr@gnu.org 01 Oct 07 bug. */
3933 handled = HANDLED_RETURN;
3938 return handled;
3942 /* Make iterator IT return `...' next.
3943 Replaces LEN characters from buffer. */
3945 static void
3946 setup_for_ellipsis (struct it *it, int len)
3948 /* Use the display table definition for `...'. Invalid glyphs
3949 will be handled by the method returning elements from dpvec. */
3950 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
3952 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
3953 it->dpvec = v->contents;
3954 it->dpend = v->contents + v->size;
3956 else
3958 /* Default `...'. */
3959 it->dpvec = default_invis_vector;
3960 it->dpend = default_invis_vector + 3;
3963 it->dpvec_char_len = len;
3964 it->current.dpvec_index = 0;
3965 it->dpvec_face_id = -1;
3967 /* Remember the current face id in case glyphs specify faces.
3968 IT's face is restored in set_iterator_to_next.
3969 saved_face_id was set to preceding char's face in handle_stop. */
3970 if (it->saved_face_id < 0 || it->saved_face_id != it->face_id)
3971 it->saved_face_id = it->face_id = DEFAULT_FACE_ID;
3973 it->method = GET_FROM_DISPLAY_VECTOR;
3974 it->ellipsis_p = 1;
3979 /***********************************************************************
3980 'display' property
3981 ***********************************************************************/
3983 /* Set up iterator IT from `display' property at its current position.
3984 Called from handle_stop.
3985 We return HANDLED_RETURN if some part of the display property
3986 overrides the display of the buffer text itself.
3987 Otherwise we return HANDLED_NORMALLY. */
3989 static enum prop_handled
3990 handle_display_prop (struct it *it)
3992 Lisp_Object prop, object, overlay;
3993 struct text_pos *position;
3994 /* Nonzero if some property replaces the display of the text itself. */
3995 int display_replaced_p = 0;
3997 if (STRINGP (it->string))
3999 object = it->string;
4000 position = &it->current.string_pos;
4002 else
4004 XSETWINDOW (object, it->w);
4005 position = &it->current.pos;
4008 /* Reset those iterator values set from display property values. */
4009 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
4010 it->space_width = Qnil;
4011 it->font_height = Qnil;
4012 it->voffset = 0;
4014 /* We don't support recursive `display' properties, i.e. string
4015 values that have a string `display' property, that have a string
4016 `display' property etc. */
4017 if (!it->string_from_display_prop_p)
4018 it->area = TEXT_AREA;
4020 prop = get_char_property_and_overlay (make_number (position->charpos),
4021 Qdisplay, object, &overlay);
4022 if (NILP (prop))
4023 return HANDLED_NORMALLY;
4024 /* Now OVERLAY is the overlay that gave us this property, or nil
4025 if it was a text property. */
4027 if (!STRINGP (it->string))
4028 object = it->w->buffer;
4030 if (CONSP (prop)
4031 /* Simple properties. */
4032 && !EQ (XCAR (prop), Qimage)
4033 && !EQ (XCAR (prop), Qspace)
4034 && !EQ (XCAR (prop), Qwhen)
4035 && !EQ (XCAR (prop), Qslice)
4036 && !EQ (XCAR (prop), Qspace_width)
4037 && !EQ (XCAR (prop), Qheight)
4038 && !EQ (XCAR (prop), Qraise)
4039 /* Marginal area specifications. */
4040 && !(CONSP (XCAR (prop)) && EQ (XCAR (XCAR (prop)), Qmargin))
4041 && !EQ (XCAR (prop), Qleft_fringe)
4042 && !EQ (XCAR (prop), Qright_fringe)
4043 && !NILP (XCAR (prop)))
4045 for (; CONSP (prop); prop = XCDR (prop))
4047 if (handle_single_display_spec (it, XCAR (prop), object, overlay,
4048 position, display_replaced_p))
4050 display_replaced_p = 1;
4051 /* If some text in a string is replaced, `position' no
4052 longer points to the position of `object'. */
4053 if (STRINGP (object))
4054 break;
4058 else if (VECTORP (prop))
4060 int i;
4061 for (i = 0; i < ASIZE (prop); ++i)
4062 if (handle_single_display_spec (it, AREF (prop, i), object, overlay,
4063 position, display_replaced_p))
4065 display_replaced_p = 1;
4066 /* If some text in a string is replaced, `position' no
4067 longer points to the position of `object'. */
4068 if (STRINGP (object))
4069 break;
4072 else
4074 if (handle_single_display_spec (it, prop, object, overlay,
4075 position, 0))
4076 display_replaced_p = 1;
4079 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
4083 /* Value is the position of the end of the `display' property starting
4084 at START_POS in OBJECT. */
4086 static struct text_pos
4087 display_prop_end (struct it *it, Lisp_Object object, struct text_pos start_pos)
4089 Lisp_Object end;
4090 struct text_pos end_pos;
4092 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
4093 Qdisplay, object, Qnil);
4094 CHARPOS (end_pos) = XFASTINT (end);
4095 if (STRINGP (object))
4096 compute_string_pos (&end_pos, start_pos, it->string);
4097 else
4098 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
4100 return end_pos;
4104 /* Set up IT from a single `display' specification PROP. OBJECT
4105 is the object in which the `display' property was found. *POSITION
4106 is the position at which it was found. DISPLAY_REPLACED_P non-zero
4107 means that we previously saw a display specification which already
4108 replaced text display with something else, for example an image;
4109 we ignore such properties after the first one has been processed.
4111 OVERLAY is the overlay this `display' property came from,
4112 or nil if it was a text property.
4114 If PROP is a `space' or `image' specification, and in some other
4115 cases too, set *POSITION to the position where the `display'
4116 property ends.
4118 Value is non-zero if something was found which replaces the display
4119 of buffer or string text. */
4121 static int
4122 handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4123 Lisp_Object overlay, struct text_pos *position,
4124 int display_replaced_before_p)
4126 Lisp_Object form;
4127 Lisp_Object location, value;
4128 struct text_pos start_pos, save_pos;
4129 int valid_p;
4131 /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
4132 If the result is non-nil, use VALUE instead of SPEC. */
4133 form = Qt;
4134 if (CONSP (spec) && EQ (XCAR (spec), Qwhen))
4136 spec = XCDR (spec);
4137 if (!CONSP (spec))
4138 return 0;
4139 form = XCAR (spec);
4140 spec = XCDR (spec);
4143 if (!NILP (form) && !EQ (form, Qt))
4145 int count = SPECPDL_INDEX ();
4146 struct gcpro gcpro1;
4148 /* Bind `object' to the object having the `display' property, a
4149 buffer or string. Bind `position' to the position in the
4150 object where the property was found, and `buffer-position'
4151 to the current position in the buffer. */
4152 specbind (Qobject, object);
4153 specbind (Qposition, make_number (CHARPOS (*position)));
4154 specbind (Qbuffer_position,
4155 make_number (STRINGP (object)
4156 ? IT_CHARPOS (*it) : CHARPOS (*position)));
4157 GCPRO1 (form);
4158 form = safe_eval (form);
4159 UNGCPRO;
4160 unbind_to (count, Qnil);
4163 if (NILP (form))
4164 return 0;
4166 /* Handle `(height HEIGHT)' specifications. */
4167 if (CONSP (spec)
4168 && EQ (XCAR (spec), Qheight)
4169 && CONSP (XCDR (spec)))
4171 if (!FRAME_WINDOW_P (it->f))
4172 return 0;
4174 it->font_height = XCAR (XCDR (spec));
4175 if (!NILP (it->font_height))
4177 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4178 int new_height = -1;
4180 if (CONSP (it->font_height)
4181 && (EQ (XCAR (it->font_height), Qplus)
4182 || EQ (XCAR (it->font_height), Qminus))
4183 && CONSP (XCDR (it->font_height))
4184 && INTEGERP (XCAR (XCDR (it->font_height))))
4186 /* `(+ N)' or `(- N)' where N is an integer. */
4187 int steps = XINT (XCAR (XCDR (it->font_height)));
4188 if (EQ (XCAR (it->font_height), Qplus))
4189 steps = - steps;
4190 it->face_id = smaller_face (it->f, it->face_id, steps);
4192 else if (FUNCTIONP (it->font_height))
4194 /* Call function with current height as argument.
4195 Value is the new height. */
4196 Lisp_Object height;
4197 height = safe_call1 (it->font_height,
4198 face->lface[LFACE_HEIGHT_INDEX]);
4199 if (NUMBERP (height))
4200 new_height = XFLOATINT (height);
4202 else if (NUMBERP (it->font_height))
4204 /* Value is a multiple of the canonical char height. */
4205 struct face *face;
4207 face = FACE_FROM_ID (it->f,
4208 lookup_basic_face (it->f, DEFAULT_FACE_ID));
4209 new_height = (XFLOATINT (it->font_height)
4210 * XINT (face->lface[LFACE_HEIGHT_INDEX]));
4212 else
4214 /* Evaluate IT->font_height with `height' bound to the
4215 current specified height to get the new height. */
4216 int count = SPECPDL_INDEX ();
4218 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
4219 value = safe_eval (it->font_height);
4220 unbind_to (count, Qnil);
4222 if (NUMBERP (value))
4223 new_height = XFLOATINT (value);
4226 if (new_height > 0)
4227 it->face_id = face_with_height (it->f, it->face_id, new_height);
4230 return 0;
4233 /* Handle `(space-width WIDTH)'. */
4234 if (CONSP (spec)
4235 && EQ (XCAR (spec), Qspace_width)
4236 && CONSP (XCDR (spec)))
4238 if (!FRAME_WINDOW_P (it->f))
4239 return 0;
4241 value = XCAR (XCDR (spec));
4242 if (NUMBERP (value) && XFLOATINT (value) > 0)
4243 it->space_width = value;
4245 return 0;
4248 /* Handle `(slice X Y WIDTH HEIGHT)'. */
4249 if (CONSP (spec)
4250 && EQ (XCAR (spec), Qslice))
4252 Lisp_Object tem;
4254 if (!FRAME_WINDOW_P (it->f))
4255 return 0;
4257 if (tem = XCDR (spec), CONSP (tem))
4259 it->slice.x = XCAR (tem);
4260 if (tem = XCDR (tem), CONSP (tem))
4262 it->slice.y = XCAR (tem);
4263 if (tem = XCDR (tem), CONSP (tem))
4265 it->slice.width = XCAR (tem);
4266 if (tem = XCDR (tem), CONSP (tem))
4267 it->slice.height = XCAR (tem);
4272 return 0;
4275 /* Handle `(raise FACTOR)'. */
4276 if (CONSP (spec)
4277 && EQ (XCAR (spec), Qraise)
4278 && CONSP (XCDR (spec)))
4280 if (!FRAME_WINDOW_P (it->f))
4281 return 0;
4283 #ifdef HAVE_WINDOW_SYSTEM
4284 value = XCAR (XCDR (spec));
4285 if (NUMBERP (value))
4287 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4288 it->voffset = - (XFLOATINT (value)
4289 * (FONT_HEIGHT (face->font)));
4291 #endif /* HAVE_WINDOW_SYSTEM */
4293 return 0;
4296 /* Don't handle the other kinds of display specifications
4297 inside a string that we got from a `display' property. */
4298 if (it->string_from_display_prop_p)
4299 return 0;
4301 /* Characters having this form of property are not displayed, so
4302 we have to find the end of the property. */
4303 start_pos = *position;
4304 *position = display_prop_end (it, object, start_pos);
4305 value = Qnil;
4307 /* Stop the scan at that end position--we assume that all
4308 text properties change there. */
4309 it->stop_charpos = position->charpos;
4311 /* Handle `(left-fringe BITMAP [FACE])'
4312 and `(right-fringe BITMAP [FACE])'. */
4313 if (CONSP (spec)
4314 && (EQ (XCAR (spec), Qleft_fringe)
4315 || EQ (XCAR (spec), Qright_fringe))
4316 && CONSP (XCDR (spec)))
4318 int face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);
4319 int fringe_bitmap;
4321 if (!FRAME_WINDOW_P (it->f))
4322 /* If we return here, POSITION has been advanced
4323 across the text with this property. */
4324 return 0;
4326 #ifdef HAVE_WINDOW_SYSTEM
4327 value = XCAR (XCDR (spec));
4328 if (!SYMBOLP (value)
4329 || !(fringe_bitmap = lookup_fringe_bitmap (value)))
4330 /* If we return here, POSITION has been advanced
4331 across the text with this property. */
4332 return 0;
4334 if (CONSP (XCDR (XCDR (spec))))
4336 Lisp_Object face_name = XCAR (XCDR (XCDR (spec)));
4337 int face_id2 = lookup_derived_face (it->f, face_name,
4338 FRINGE_FACE_ID, 0);
4339 if (face_id2 >= 0)
4340 face_id = face_id2;
4343 /* Save current settings of IT so that we can restore them
4344 when we are finished with the glyph property value. */
4346 save_pos = it->position;
4347 it->position = *position;
4348 push_it (it);
4349 it->position = save_pos;
4351 it->area = TEXT_AREA;
4352 it->what = IT_IMAGE;
4353 it->image_id = -1; /* no image */
4354 it->position = start_pos;
4355 it->object = NILP (object) ? it->w->buffer : object;
4356 it->method = GET_FROM_IMAGE;
4357 it->from_overlay = Qnil;
4358 it->face_id = face_id;
4360 /* Say that we haven't consumed the characters with
4361 `display' property yet. The call to pop_it in
4362 set_iterator_to_next will clean this up. */
4363 *position = start_pos;
4365 if (EQ (XCAR (spec), Qleft_fringe))
4367 it->left_user_fringe_bitmap = fringe_bitmap;
4368 it->left_user_fringe_face_id = face_id;
4370 else
4372 it->right_user_fringe_bitmap = fringe_bitmap;
4373 it->right_user_fringe_face_id = face_id;
4375 #endif /* HAVE_WINDOW_SYSTEM */
4376 return 1;
4379 /* Prepare to handle `((margin left-margin) ...)',
4380 `((margin right-margin) ...)' and `((margin nil) ...)'
4381 prefixes for display specifications. */
4382 location = Qunbound;
4383 if (CONSP (spec) && CONSP (XCAR (spec)))
4385 Lisp_Object tem;
4387 value = XCDR (spec);
4388 if (CONSP (value))
4389 value = XCAR (value);
4391 tem = XCAR (spec);
4392 if (EQ (XCAR (tem), Qmargin)
4393 && (tem = XCDR (tem),
4394 tem = CONSP (tem) ? XCAR (tem) : Qnil,
4395 (NILP (tem)
4396 || EQ (tem, Qleft_margin)
4397 || EQ (tem, Qright_margin))))
4398 location = tem;
4401 if (EQ (location, Qunbound))
4403 location = Qnil;
4404 value = spec;
4407 /* After this point, VALUE is the property after any
4408 margin prefix has been stripped. It must be a string,
4409 an image specification, or `(space ...)'.
4411 LOCATION specifies where to display: `left-margin',
4412 `right-margin' or nil. */
4414 valid_p = (STRINGP (value)
4415 #ifdef HAVE_WINDOW_SYSTEM
4416 || (FRAME_WINDOW_P (it->f) && valid_image_p (value))
4417 #endif /* not HAVE_WINDOW_SYSTEM */
4418 || (CONSP (value) && EQ (XCAR (value), Qspace)));
4420 if (valid_p && !display_replaced_before_p)
4422 /* Save current settings of IT so that we can restore them
4423 when we are finished with the glyph property value. */
4424 save_pos = it->position;
4425 it->position = *position;
4426 push_it (it);
4427 it->position = save_pos;
4428 it->from_overlay = overlay;
4430 if (NILP (location))
4431 it->area = TEXT_AREA;
4432 else if (EQ (location, Qleft_margin))
4433 it->area = LEFT_MARGIN_AREA;
4434 else
4435 it->area = RIGHT_MARGIN_AREA;
4437 if (STRINGP (value))
4439 it->string = value;
4440 it->multibyte_p = STRING_MULTIBYTE (it->string);
4441 it->current.overlay_string_index = -1;
4442 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
4443 it->end_charpos = it->string_nchars = SCHARS (it->string);
4444 it->method = GET_FROM_STRING;
4445 it->stop_charpos = 0;
4446 it->string_from_display_prop_p = 1;
4447 /* Say that we haven't consumed the characters with
4448 `display' property yet. The call to pop_it in
4449 set_iterator_to_next will clean this up. */
4450 if (BUFFERP (object))
4451 *position = start_pos;
4453 else if (CONSP (value) && EQ (XCAR (value), Qspace))
4455 it->method = GET_FROM_STRETCH;
4456 it->object = value;
4457 *position = it->position = start_pos;
4459 #ifdef HAVE_WINDOW_SYSTEM
4460 else
4462 it->what = IT_IMAGE;
4463 it->image_id = lookup_image (it->f, value);
4464 it->position = start_pos;
4465 it->object = NILP (object) ? it->w->buffer : object;
4466 it->method = GET_FROM_IMAGE;
4468 /* Say that we haven't consumed the characters with
4469 `display' property yet. The call to pop_it in
4470 set_iterator_to_next will clean this up. */
4471 *position = start_pos;
4473 #endif /* HAVE_WINDOW_SYSTEM */
4475 return 1;
4478 /* Invalid property or property not supported. Restore
4479 POSITION to what it was before. */
4480 *position = start_pos;
4481 return 0;
4485 /* Check if SPEC is a display sub-property value whose text should be
4486 treated as intangible. */
4488 static int
4489 single_display_spec_intangible_p (Lisp_Object prop)
4491 /* Skip over `when FORM'. */
4492 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
4494 prop = XCDR (prop);
4495 if (!CONSP (prop))
4496 return 0;
4497 prop = XCDR (prop);
4500 if (STRINGP (prop))
4501 return 1;
4503 if (!CONSP (prop))
4504 return 0;
4506 /* Skip over `margin LOCATION'. If LOCATION is in the margins,
4507 we don't need to treat text as intangible. */
4508 if (EQ (XCAR (prop), Qmargin))
4510 prop = XCDR (prop);
4511 if (!CONSP (prop))
4512 return 0;
4514 prop = XCDR (prop);
4515 if (!CONSP (prop)
4516 || EQ (XCAR (prop), Qleft_margin)
4517 || EQ (XCAR (prop), Qright_margin))
4518 return 0;
4521 return (CONSP (prop)
4522 && (EQ (XCAR (prop), Qimage)
4523 || EQ (XCAR (prop), Qspace)));
4527 /* Check if PROP is a display property value whose text should be
4528 treated as intangible. */
4531 display_prop_intangible_p (Lisp_Object prop)
4533 if (CONSP (prop)
4534 && CONSP (XCAR (prop))
4535 && !EQ (Qmargin, XCAR (XCAR (prop))))
4537 /* A list of sub-properties. */
4538 while (CONSP (prop))
4540 if (single_display_spec_intangible_p (XCAR (prop)))
4541 return 1;
4542 prop = XCDR (prop);
4545 else if (VECTORP (prop))
4547 /* A vector of sub-properties. */
4548 int i;
4549 for (i = 0; i < ASIZE (prop); ++i)
4550 if (single_display_spec_intangible_p (AREF (prop, i)))
4551 return 1;
4553 else
4554 return single_display_spec_intangible_p (prop);
4556 return 0;
4560 /* Return 1 if PROP is a display sub-property value containing STRING. */
4562 static int
4563 single_display_spec_string_p (Lisp_Object prop, Lisp_Object string)
4565 if (EQ (string, prop))
4566 return 1;
4568 /* Skip over `when FORM'. */
4569 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
4571 prop = XCDR (prop);
4572 if (!CONSP (prop))
4573 return 0;
4574 prop = XCDR (prop);
4577 if (CONSP (prop))
4578 /* Skip over `margin LOCATION'. */
4579 if (EQ (XCAR (prop), Qmargin))
4581 prop = XCDR (prop);
4582 if (!CONSP (prop))
4583 return 0;
4585 prop = XCDR (prop);
4586 if (!CONSP (prop))
4587 return 0;
4590 return CONSP (prop) && EQ (XCAR (prop), string);
4594 /* Return 1 if STRING appears in the `display' property PROP. */
4596 static int
4597 display_prop_string_p (Lisp_Object prop, Lisp_Object string)
4599 if (CONSP (prop)
4600 && CONSP (XCAR (prop))
4601 && !EQ (Qmargin, XCAR (XCAR (prop))))
4603 /* A list of sub-properties. */
4604 while (CONSP (prop))
4606 if (single_display_spec_string_p (XCAR (prop), string))
4607 return 1;
4608 prop = XCDR (prop);
4611 else if (VECTORP (prop))
4613 /* A vector of sub-properties. */
4614 int i;
4615 for (i = 0; i < ASIZE (prop); ++i)
4616 if (single_display_spec_string_p (AREF (prop, i), string))
4617 return 1;
4619 else
4620 return single_display_spec_string_p (prop, string);
4622 return 0;
4625 /* Look for STRING in overlays and text properties in W's buffer,
4626 between character positions FROM and TO (excluding TO).
4627 BACK_P non-zero means look back (in this case, TO is supposed to be
4628 less than FROM).
4629 Value is the first character position where STRING was found, or
4630 zero if it wasn't found before hitting TO.
4632 W's buffer must be current.
4634 This function may only use code that doesn't eval because it is
4635 called asynchronously from note_mouse_highlight. */
4637 static EMACS_INT
4638 string_buffer_position_lim (struct window *w, Lisp_Object string,
4639 EMACS_INT from, EMACS_INT to, int back_p)
4641 Lisp_Object limit, prop, pos;
4642 int found = 0;
4644 pos = make_number (from);
4646 if (!back_p) /* looking forward */
4648 limit = make_number (min (to, ZV));
4649 while (!found && !EQ (pos, limit))
4651 prop = Fget_char_property (pos, Qdisplay, Qnil);
4652 if (!NILP (prop) && display_prop_string_p (prop, string))
4653 found = 1;
4654 else
4655 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil,
4656 limit);
4659 else /* looking back */
4661 limit = make_number (max (to, BEGV));
4662 while (!found && !EQ (pos, limit))
4664 prop = Fget_char_property (pos, Qdisplay, Qnil);
4665 if (!NILP (prop) && display_prop_string_p (prop, string))
4666 found = 1;
4667 else
4668 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
4669 limit);
4673 return found ? XINT (pos) : 0;
4676 /* Determine which buffer position in W's buffer STRING comes from.
4677 AROUND_CHARPOS is an approximate position where it could come from.
4678 Value is the buffer position or 0 if it couldn't be determined.
4680 W's buffer must be current.
4682 This function is necessary because we don't record buffer positions
4683 in glyphs generated from strings (to keep struct glyph small).
4684 This function may only use code that doesn't eval because it is
4685 called asynchronously from note_mouse_highlight. */
4687 EMACS_INT
4688 string_buffer_position (struct window *w, Lisp_Object string, EMACS_INT around_charpos)
4690 const int MAX_DISTANCE = 1000;
4691 EMACS_INT found = string_buffer_position_lim (w, string, around_charpos,
4692 around_charpos + MAX_DISTANCE,
4695 if (!found)
4696 found = string_buffer_position_lim (w, string, around_charpos,
4697 around_charpos - MAX_DISTANCE, 1);
4698 return found;
4703 /***********************************************************************
4704 `composition' property
4705 ***********************************************************************/
4707 /* Set up iterator IT from `composition' property at its current
4708 position. Called from handle_stop. */
4710 static enum prop_handled
4711 handle_composition_prop (struct it *it)
4713 Lisp_Object prop, string;
4714 EMACS_INT pos, pos_byte, start, end;
4716 if (STRINGP (it->string))
4718 unsigned char *s;
4720 pos = IT_STRING_CHARPOS (*it);
4721 pos_byte = IT_STRING_BYTEPOS (*it);
4722 string = it->string;
4723 s = SDATA (string) + pos_byte;
4724 it->c = STRING_CHAR (s);
4726 else
4728 pos = IT_CHARPOS (*it);
4729 pos_byte = IT_BYTEPOS (*it);
4730 string = Qnil;
4731 it->c = FETCH_CHAR (pos_byte);
4734 /* If there's a valid composition and point is not inside of the
4735 composition (in the case that the composition is from the current
4736 buffer), draw a glyph composed from the composition components. */
4737 if (find_composition (pos, -1, &start, &end, &prop, string)
4738 && COMPOSITION_VALID_P (start, end, prop)
4739 && (STRINGP (it->string) || (PT <= start || PT >= end)))
4741 if (start != pos)
4743 if (STRINGP (it->string))
4744 pos_byte = string_char_to_byte (it->string, start);
4745 else
4746 pos_byte = CHAR_TO_BYTE (start);
4748 it->cmp_it.id = get_composition_id (start, pos_byte, end - start,
4749 prop, string);
4751 if (it->cmp_it.id >= 0)
4753 it->cmp_it.ch = -1;
4754 it->cmp_it.nchars = COMPOSITION_LENGTH (prop);
4755 it->cmp_it.nglyphs = -1;
4759 return HANDLED_NORMALLY;
4764 /***********************************************************************
4765 Overlay strings
4766 ***********************************************************************/
4768 /* The following structure is used to record overlay strings for
4769 later sorting in load_overlay_strings. */
4771 struct overlay_entry
4773 Lisp_Object overlay;
4774 Lisp_Object string;
4775 int priority;
4776 int after_string_p;
4780 /* Set up iterator IT from overlay strings at its current position.
4781 Called from handle_stop. */
4783 static enum prop_handled
4784 handle_overlay_change (struct it *it)
4786 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
4787 return HANDLED_RECOMPUTE_PROPS;
4788 else
4789 return HANDLED_NORMALLY;
4793 /* Set up the next overlay string for delivery by IT, if there is an
4794 overlay string to deliver. Called by set_iterator_to_next when the
4795 end of the current overlay string is reached. If there are more
4796 overlay strings to display, IT->string and
4797 IT->current.overlay_string_index are set appropriately here.
4798 Otherwise IT->string is set to nil. */
4800 static void
4801 next_overlay_string (struct it *it)
4803 ++it->current.overlay_string_index;
4804 if (it->current.overlay_string_index == it->n_overlay_strings)
4806 /* No more overlay strings. Restore IT's settings to what
4807 they were before overlay strings were processed, and
4808 continue to deliver from current_buffer. */
4810 it->ellipsis_p = (it->stack[it->sp - 1].display_ellipsis_p != 0);
4811 pop_it (it);
4812 xassert (it->sp > 0
4813 || (NILP (it->string)
4814 && it->method == GET_FROM_BUFFER
4815 && it->stop_charpos >= BEGV
4816 && it->stop_charpos <= it->end_charpos));
4817 it->current.overlay_string_index = -1;
4818 it->n_overlay_strings = 0;
4819 it->overlay_strings_charpos = -1;
4821 /* If we're at the end of the buffer, record that we have
4822 processed the overlay strings there already, so that
4823 next_element_from_buffer doesn't try it again. */
4824 if (NILP (it->string) && IT_CHARPOS (*it) >= it->end_charpos)
4825 it->overlay_strings_at_end_processed_p = 1;
4827 else
4829 /* There are more overlay strings to process. If
4830 IT->current.overlay_string_index has advanced to a position
4831 where we must load IT->overlay_strings with more strings, do
4832 it. We must load at the IT->overlay_strings_charpos where
4833 IT->n_overlay_strings was originally computed; when invisible
4834 text is present, this might not be IT_CHARPOS (Bug#7016). */
4835 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
4837 if (it->current.overlay_string_index && i == 0)
4838 load_overlay_strings (it, it->overlay_strings_charpos);
4840 /* Initialize IT to deliver display elements from the overlay
4841 string. */
4842 it->string = it->overlay_strings[i];
4843 it->multibyte_p = STRING_MULTIBYTE (it->string);
4844 SET_TEXT_POS (it->current.string_pos, 0, 0);
4845 it->method = GET_FROM_STRING;
4846 it->stop_charpos = 0;
4847 if (it->cmp_it.stop_pos >= 0)
4848 it->cmp_it.stop_pos = 0;
4851 CHECK_IT (it);
4855 /* Compare two overlay_entry structures E1 and E2. Used as a
4856 comparison function for qsort in load_overlay_strings. Overlay
4857 strings for the same position are sorted so that
4859 1. All after-strings come in front of before-strings, except
4860 when they come from the same overlay.
4862 2. Within after-strings, strings are sorted so that overlay strings
4863 from overlays with higher priorities come first.
4865 2. Within before-strings, strings are sorted so that overlay
4866 strings from overlays with higher priorities come last.
4868 Value is analogous to strcmp. */
4871 static int
4872 compare_overlay_entries (const void *e1, const void *e2)
4874 struct overlay_entry *entry1 = (struct overlay_entry *) e1;
4875 struct overlay_entry *entry2 = (struct overlay_entry *) e2;
4876 int result;
4878 if (entry1->after_string_p != entry2->after_string_p)
4880 /* Let after-strings appear in front of before-strings if
4881 they come from different overlays. */
4882 if (EQ (entry1->overlay, entry2->overlay))
4883 result = entry1->after_string_p ? 1 : -1;
4884 else
4885 result = entry1->after_string_p ? -1 : 1;
4887 else if (entry1->after_string_p)
4888 /* After-strings sorted in order of decreasing priority. */
4889 result = entry2->priority - entry1->priority;
4890 else
4891 /* Before-strings sorted in order of increasing priority. */
4892 result = entry1->priority - entry2->priority;
4894 return result;
4898 /* Load the vector IT->overlay_strings with overlay strings from IT's
4899 current buffer position, or from CHARPOS if that is > 0. Set
4900 IT->n_overlays to the total number of overlay strings found.
4902 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
4903 a time. On entry into load_overlay_strings,
4904 IT->current.overlay_string_index gives the number of overlay
4905 strings that have already been loaded by previous calls to this
4906 function.
4908 IT->add_overlay_start contains an additional overlay start
4909 position to consider for taking overlay strings from, if non-zero.
4910 This position comes into play when the overlay has an `invisible'
4911 property, and both before and after-strings. When we've skipped to
4912 the end of the overlay, because of its `invisible' property, we
4913 nevertheless want its before-string to appear.
4914 IT->add_overlay_start will contain the overlay start position
4915 in this case.
4917 Overlay strings are sorted so that after-string strings come in
4918 front of before-string strings. Within before and after-strings,
4919 strings are sorted by overlay priority. See also function
4920 compare_overlay_entries. */
4922 static void
4923 load_overlay_strings (struct it *it, EMACS_INT charpos)
4925 Lisp_Object overlay, window, str, invisible;
4926 struct Lisp_Overlay *ov;
4927 EMACS_INT start, end;
4928 int size = 20;
4929 int n = 0, i, j, invis_p;
4930 struct overlay_entry *entries
4931 = (struct overlay_entry *) alloca (size * sizeof *entries);
4933 if (charpos <= 0)
4934 charpos = IT_CHARPOS (*it);
4936 /* Append the overlay string STRING of overlay OVERLAY to vector
4937 `entries' which has size `size' and currently contains `n'
4938 elements. AFTER_P non-zero means STRING is an after-string of
4939 OVERLAY. */
4940 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
4941 do \
4943 Lisp_Object priority; \
4945 if (n == size) \
4947 int new_size = 2 * size; \
4948 struct overlay_entry *old = entries; \
4949 entries = \
4950 (struct overlay_entry *) alloca (new_size \
4951 * sizeof *entries); \
4952 memcpy (entries, old, size * sizeof *entries); \
4953 size = new_size; \
4956 entries[n].string = (STRING); \
4957 entries[n].overlay = (OVERLAY); \
4958 priority = Foverlay_get ((OVERLAY), Qpriority); \
4959 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
4960 entries[n].after_string_p = (AFTER_P); \
4961 ++n; \
4963 while (0)
4965 /* Process overlay before the overlay center. */
4966 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
4968 XSETMISC (overlay, ov);
4969 xassert (OVERLAYP (overlay));
4970 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4971 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4973 if (end < charpos)
4974 break;
4976 /* Skip this overlay if it doesn't start or end at IT's current
4977 position. */
4978 if (end != charpos && start != charpos)
4979 continue;
4981 /* Skip this overlay if it doesn't apply to IT->w. */
4982 window = Foverlay_get (overlay, Qwindow);
4983 if (WINDOWP (window) && XWINDOW (window) != it->w)
4984 continue;
4986 /* If the text ``under'' the overlay is invisible, both before-
4987 and after-strings from this overlay are visible; start and
4988 end position are indistinguishable. */
4989 invisible = Foverlay_get (overlay, Qinvisible);
4990 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4992 /* If overlay has a non-empty before-string, record it. */
4993 if ((start == charpos || (end == charpos && invis_p))
4994 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4995 && SCHARS (str))
4996 RECORD_OVERLAY_STRING (overlay, str, 0);
4998 /* If overlay has a non-empty after-string, record it. */
4999 if ((end == charpos || (start == charpos && invis_p))
5000 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
5001 && SCHARS (str))
5002 RECORD_OVERLAY_STRING (overlay, str, 1);
5005 /* Process overlays after the overlay center. */
5006 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
5008 XSETMISC (overlay, ov);
5009 xassert (OVERLAYP (overlay));
5010 start = OVERLAY_POSITION (OVERLAY_START (overlay));
5011 end = OVERLAY_POSITION (OVERLAY_END (overlay));
5013 if (start > charpos)
5014 break;
5016 /* Skip this overlay if it doesn't start or end at IT's current
5017 position. */
5018 if (end != charpos && start != charpos)
5019 continue;
5021 /* Skip this overlay if it doesn't apply to IT->w. */
5022 window = Foverlay_get (overlay, Qwindow);
5023 if (WINDOWP (window) && XWINDOW (window) != it->w)
5024 continue;
5026 /* If the text ``under'' the overlay is invisible, it has a zero
5027 dimension, and both before- and after-strings apply. */
5028 invisible = Foverlay_get (overlay, Qinvisible);
5029 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
5031 /* If overlay has a non-empty before-string, record it. */
5032 if ((start == charpos || (end == charpos && invis_p))
5033 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
5034 && SCHARS (str))
5035 RECORD_OVERLAY_STRING (overlay, str, 0);
5037 /* If overlay has a non-empty after-string, record it. */
5038 if ((end == charpos || (start == charpos && invis_p))
5039 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
5040 && SCHARS (str))
5041 RECORD_OVERLAY_STRING (overlay, str, 1);
5044 #undef RECORD_OVERLAY_STRING
5046 /* Sort entries. */
5047 if (n > 1)
5048 qsort (entries, n, sizeof *entries, compare_overlay_entries);
5050 /* Record number of overlay strings, and where we computed it. */
5051 it->n_overlay_strings = n;
5052 it->overlay_strings_charpos = charpos;
5054 /* IT->current.overlay_string_index is the number of overlay strings
5055 that have already been consumed by IT. Copy some of the
5056 remaining overlay strings to IT->overlay_strings. */
5057 i = 0;
5058 j = it->current.overlay_string_index;
5059 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
5061 it->overlay_strings[i] = entries[j].string;
5062 it->string_overlays[i++] = entries[j++].overlay;
5065 CHECK_IT (it);
5069 /* Get the first chunk of overlay strings at IT's current buffer
5070 position, or at CHARPOS if that is > 0. Value is non-zero if at
5071 least one overlay string was found. */
5073 static int
5074 get_overlay_strings_1 (struct it *it, EMACS_INT charpos, int compute_stop_p)
5076 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
5077 process. This fills IT->overlay_strings with strings, and sets
5078 IT->n_overlay_strings to the total number of strings to process.
5079 IT->pos.overlay_string_index has to be set temporarily to zero
5080 because load_overlay_strings needs this; it must be set to -1
5081 when no overlay strings are found because a zero value would
5082 indicate a position in the first overlay string. */
5083 it->current.overlay_string_index = 0;
5084 load_overlay_strings (it, charpos);
5086 /* If we found overlay strings, set up IT to deliver display
5087 elements from the first one. Otherwise set up IT to deliver
5088 from current_buffer. */
5089 if (it->n_overlay_strings)
5091 /* Make sure we know settings in current_buffer, so that we can
5092 restore meaningful values when we're done with the overlay
5093 strings. */
5094 if (compute_stop_p)
5095 compute_stop_pos (it);
5096 xassert (it->face_id >= 0);
5098 /* Save IT's settings. They are restored after all overlay
5099 strings have been processed. */
5100 xassert (!compute_stop_p || it->sp == 0);
5102 /* When called from handle_stop, there might be an empty display
5103 string loaded. In that case, don't bother saving it. */
5104 if (!STRINGP (it->string) || SCHARS (it->string))
5105 push_it (it);
5107 /* Set up IT to deliver display elements from the first overlay
5108 string. */
5109 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
5110 it->string = it->overlay_strings[0];
5111 it->from_overlay = Qnil;
5112 it->stop_charpos = 0;
5113 xassert (STRINGP (it->string));
5114 it->end_charpos = SCHARS (it->string);
5115 it->multibyte_p = STRING_MULTIBYTE (it->string);
5116 it->method = GET_FROM_STRING;
5117 return 1;
5120 it->current.overlay_string_index = -1;
5121 return 0;
5124 static int
5125 get_overlay_strings (struct it *it, EMACS_INT charpos)
5127 it->string = Qnil;
5128 it->method = GET_FROM_BUFFER;
5130 (void) get_overlay_strings_1 (it, charpos, 1);
5132 CHECK_IT (it);
5134 /* Value is non-zero if we found at least one overlay string. */
5135 return STRINGP (it->string);
5140 /***********************************************************************
5141 Saving and restoring state
5142 ***********************************************************************/
5144 /* Save current settings of IT on IT->stack. Called, for example,
5145 before setting up IT for an overlay string, to be able to restore
5146 IT's settings to what they were after the overlay string has been
5147 processed. */
5149 static void
5150 push_it (struct it *it)
5152 struct iterator_stack_entry *p;
5154 xassert (it->sp < IT_STACK_SIZE);
5155 p = it->stack + it->sp;
5157 p->stop_charpos = it->stop_charpos;
5158 p->prev_stop = it->prev_stop;
5159 p->base_level_stop = it->base_level_stop;
5160 p->cmp_it = it->cmp_it;
5161 xassert (it->face_id >= 0);
5162 p->face_id = it->face_id;
5163 p->string = it->string;
5164 p->method = it->method;
5165 p->from_overlay = it->from_overlay;
5166 switch (p->method)
5168 case GET_FROM_IMAGE:
5169 p->u.image.object = it->object;
5170 p->u.image.image_id = it->image_id;
5171 p->u.image.slice = it->slice;
5172 break;
5173 case GET_FROM_STRETCH:
5174 p->u.stretch.object = it->object;
5175 break;
5177 p->position = it->position;
5178 p->current = it->current;
5179 p->end_charpos = it->end_charpos;
5180 p->string_nchars = it->string_nchars;
5181 p->area = it->area;
5182 p->multibyte_p = it->multibyte_p;
5183 p->avoid_cursor_p = it->avoid_cursor_p;
5184 p->space_width = it->space_width;
5185 p->font_height = it->font_height;
5186 p->voffset = it->voffset;
5187 p->string_from_display_prop_p = it->string_from_display_prop_p;
5188 p->display_ellipsis_p = 0;
5189 p->line_wrap = it->line_wrap;
5190 ++it->sp;
5193 static void
5194 iterate_out_of_display_property (struct it *it)
5196 /* Maybe initialize paragraph direction. If we are at the beginning
5197 of a new paragraph, next_element_from_buffer may not have a
5198 chance to do that. */
5199 if (it->bidi_it.first_elt && it->bidi_it.charpos < ZV)
5200 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
5201 /* prev_stop can be zero, so check against BEGV as well. */
5202 while (it->bidi_it.charpos >= BEGV
5203 && it->prev_stop <= it->bidi_it.charpos
5204 && it->bidi_it.charpos < CHARPOS (it->position))
5205 bidi_move_to_visually_next (&it->bidi_it);
5206 /* Record the stop_pos we just crossed, for when we cross it
5207 back, maybe. */
5208 if (it->bidi_it.charpos > CHARPOS (it->position))
5209 it->prev_stop = CHARPOS (it->position);
5210 /* If we ended up not where pop_it put us, resync IT's
5211 positional members with the bidi iterator. */
5212 if (it->bidi_it.charpos != CHARPOS (it->position))
5214 SET_TEXT_POS (it->position,
5215 it->bidi_it.charpos, it->bidi_it.bytepos);
5216 it->current.pos = it->position;
5220 /* Restore IT's settings from IT->stack. Called, for example, when no
5221 more overlay strings must be processed, and we return to delivering
5222 display elements from a buffer, or when the end of a string from a
5223 `display' property is reached and we return to delivering display
5224 elements from an overlay string, or from a buffer. */
5226 static void
5227 pop_it (struct it *it)
5229 struct iterator_stack_entry *p;
5231 xassert (it->sp > 0);
5232 --it->sp;
5233 p = it->stack + it->sp;
5234 it->stop_charpos = p->stop_charpos;
5235 it->prev_stop = p->prev_stop;
5236 it->base_level_stop = p->base_level_stop;
5237 it->cmp_it = p->cmp_it;
5238 it->face_id = p->face_id;
5239 it->current = p->current;
5240 it->position = p->position;
5241 it->string = p->string;
5242 it->from_overlay = p->from_overlay;
5243 if (NILP (it->string))
5244 SET_TEXT_POS (it->current.string_pos, -1, -1);
5245 it->method = p->method;
5246 switch (it->method)
5248 case GET_FROM_IMAGE:
5249 it->image_id = p->u.image.image_id;
5250 it->object = p->u.image.object;
5251 it->slice = p->u.image.slice;
5252 break;
5253 case GET_FROM_STRETCH:
5254 it->object = p->u.comp.object;
5255 break;
5256 case GET_FROM_BUFFER:
5257 it->object = it->w->buffer;
5258 if (it->bidi_p)
5260 /* Bidi-iterate until we get out of the portion of text, if
5261 any, covered by a `display' text property or an overlay
5262 with `display' property. (We cannot just jump there,
5263 because the internal coherency of the bidi iterator state
5264 can not be preserved across such jumps.) We also must
5265 determine the paragraph base direction if the overlay we
5266 just processed is at the beginning of a new
5267 paragraph. */
5268 iterate_out_of_display_property (it);
5270 break;
5271 case GET_FROM_STRING:
5272 it->object = it->string;
5273 break;
5274 case GET_FROM_DISPLAY_VECTOR:
5275 if (it->s)
5276 it->method = GET_FROM_C_STRING;
5277 else if (STRINGP (it->string))
5278 it->method = GET_FROM_STRING;
5279 else
5281 it->method = GET_FROM_BUFFER;
5282 it->object = it->w->buffer;
5285 it->end_charpos = p->end_charpos;
5286 it->string_nchars = p->string_nchars;
5287 it->area = p->area;
5288 it->multibyte_p = p->multibyte_p;
5289 it->avoid_cursor_p = p->avoid_cursor_p;
5290 it->space_width = p->space_width;
5291 it->font_height = p->font_height;
5292 it->voffset = p->voffset;
5293 it->string_from_display_prop_p = p->string_from_display_prop_p;
5294 it->line_wrap = p->line_wrap;
5299 /***********************************************************************
5300 Moving over lines
5301 ***********************************************************************/
5303 /* Set IT's current position to the previous line start. */
5305 static void
5306 back_to_previous_line_start (struct it *it)
5308 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
5309 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
5313 /* Move IT to the next line start.
5315 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
5316 we skipped over part of the text (as opposed to moving the iterator
5317 continuously over the text). Otherwise, don't change the value
5318 of *SKIPPED_P.
5320 Newlines may come from buffer text, overlay strings, or strings
5321 displayed via the `display' property. That's the reason we can't
5322 simply use find_next_newline_no_quit.
5324 Note that this function may not skip over invisible text that is so
5325 because of text properties and immediately follows a newline. If
5326 it would, function reseat_at_next_visible_line_start, when called
5327 from set_iterator_to_next, would effectively make invisible
5328 characters following a newline part of the wrong glyph row, which
5329 leads to wrong cursor motion. */
5331 static int
5332 forward_to_next_line_start (struct it *it, int *skipped_p)
5334 int old_selective, newline_found_p, n;
5335 const int MAX_NEWLINE_DISTANCE = 500;
5337 /* If already on a newline, just consume it to avoid unintended
5338 skipping over invisible text below. */
5339 if (it->what == IT_CHARACTER
5340 && it->c == '\n'
5341 && CHARPOS (it->position) == IT_CHARPOS (*it))
5343 set_iterator_to_next (it, 0);
5344 it->c = 0;
5345 return 1;
5348 /* Don't handle selective display in the following. It's (a)
5349 unnecessary because it's done by the caller, and (b) leads to an
5350 infinite recursion because next_element_from_ellipsis indirectly
5351 calls this function. */
5352 old_selective = it->selective;
5353 it->selective = 0;
5355 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
5356 from buffer text. */
5357 for (n = newline_found_p = 0;
5358 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
5359 n += STRINGP (it->string) ? 0 : 1)
5361 if (!get_next_display_element (it))
5362 return 0;
5363 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
5364 set_iterator_to_next (it, 0);
5367 /* If we didn't find a newline near enough, see if we can use a
5368 short-cut. */
5369 if (!newline_found_p)
5371 EMACS_INT start = IT_CHARPOS (*it);
5372 EMACS_INT limit = find_next_newline_no_quit (start, 1);
5373 Lisp_Object pos;
5375 xassert (!STRINGP (it->string));
5377 /* If there isn't any `display' property in sight, and no
5378 overlays, we can just use the position of the newline in
5379 buffer text. */
5380 if (it->stop_charpos >= limit
5381 || ((pos = Fnext_single_property_change (make_number (start),
5382 Qdisplay,
5383 Qnil, make_number (limit)),
5384 NILP (pos))
5385 && next_overlay_change (start) == ZV))
5387 IT_CHARPOS (*it) = limit;
5388 IT_BYTEPOS (*it) = CHAR_TO_BYTE (limit);
5389 *skipped_p = newline_found_p = 1;
5391 else
5393 while (get_next_display_element (it)
5394 && !newline_found_p)
5396 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
5397 set_iterator_to_next (it, 0);
5402 it->selective = old_selective;
5403 return newline_found_p;
5407 /* Set IT's current position to the previous visible line start. Skip
5408 invisible text that is so either due to text properties or due to
5409 selective display. Caution: this does not change IT->current_x and
5410 IT->hpos. */
5412 static void
5413 back_to_previous_visible_line_start (struct it *it)
5415 while (IT_CHARPOS (*it) > BEGV)
5417 back_to_previous_line_start (it);
5419 if (IT_CHARPOS (*it) <= BEGV)
5420 break;
5422 /* If selective > 0, then lines indented more than its value are
5423 invisible. */
5424 if (it->selective > 0
5425 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
5426 (double) it->selective)) /* iftc */
5427 continue;
5429 /* Check the newline before point for invisibility. */
5431 Lisp_Object prop;
5432 prop = Fget_char_property (make_number (IT_CHARPOS (*it) - 1),
5433 Qinvisible, it->window);
5434 if (TEXT_PROP_MEANS_INVISIBLE (prop))
5435 continue;
5438 if (IT_CHARPOS (*it) <= BEGV)
5439 break;
5442 struct it it2;
5443 EMACS_INT pos;
5444 EMACS_INT beg, end;
5445 Lisp_Object val, overlay;
5447 /* If newline is part of a composition, continue from start of composition */
5448 if (find_composition (IT_CHARPOS (*it), -1, &beg, &end, &val, Qnil)
5449 && beg < IT_CHARPOS (*it))
5450 goto replaced;
5452 /* If newline is replaced by a display property, find start of overlay
5453 or interval and continue search from that point. */
5454 it2 = *it;
5455 pos = --IT_CHARPOS (it2);
5456 --IT_BYTEPOS (it2);
5457 it2.sp = 0;
5458 it2.string_from_display_prop_p = 0;
5459 if (handle_display_prop (&it2) == HANDLED_RETURN
5460 && !NILP (val = get_char_property_and_overlay
5461 (make_number (pos), Qdisplay, Qnil, &overlay))
5462 && (OVERLAYP (overlay)
5463 ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
5464 : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
5465 goto replaced;
5467 /* Newline is not replaced by anything -- so we are done. */
5468 break;
5470 replaced:
5471 if (beg < BEGV)
5472 beg = BEGV;
5473 IT_CHARPOS (*it) = beg;
5474 IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg);
5478 it->continuation_lines_width = 0;
5480 xassert (IT_CHARPOS (*it) >= BEGV);
5481 xassert (IT_CHARPOS (*it) == BEGV
5482 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
5483 CHECK_IT (it);
5487 /* Reseat iterator IT at the previous visible line start. Skip
5488 invisible text that is so either due to text properties or due to
5489 selective display. At the end, update IT's overlay information,
5490 face information etc. */
5492 void
5493 reseat_at_previous_visible_line_start (struct it *it)
5495 back_to_previous_visible_line_start (it);
5496 reseat (it, it->current.pos, 1);
5497 CHECK_IT (it);
5501 /* Reseat iterator IT on the next visible line start in the current
5502 buffer. ON_NEWLINE_P non-zero means position IT on the newline
5503 preceding the line start. Skip over invisible text that is so
5504 because of selective display. Compute faces, overlays etc at the
5505 new position. Note that this function does not skip over text that
5506 is invisible because of text properties. */
5508 static void
5509 reseat_at_next_visible_line_start (struct it *it, int on_newline_p)
5511 int newline_found_p, skipped_p = 0;
5513 newline_found_p = forward_to_next_line_start (it, &skipped_p);
5515 /* Skip over lines that are invisible because they are indented
5516 more than the value of IT->selective. */
5517 if (it->selective > 0)
5518 while (IT_CHARPOS (*it) < ZV
5519 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
5520 (double) it->selective)) /* iftc */
5522 xassert (IT_BYTEPOS (*it) == BEGV
5523 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
5524 newline_found_p = forward_to_next_line_start (it, &skipped_p);
5527 /* Position on the newline if that's what's requested. */
5528 if (on_newline_p && newline_found_p)
5530 if (STRINGP (it->string))
5532 if (IT_STRING_CHARPOS (*it) > 0)
5534 --IT_STRING_CHARPOS (*it);
5535 --IT_STRING_BYTEPOS (*it);
5538 else if (IT_CHARPOS (*it) > BEGV)
5540 --IT_CHARPOS (*it);
5541 --IT_BYTEPOS (*it);
5542 reseat (it, it->current.pos, 0);
5545 else if (skipped_p)
5546 reseat (it, it->current.pos, 0);
5548 CHECK_IT (it);
5553 /***********************************************************************
5554 Changing an iterator's position
5555 ***********************************************************************/
5557 /* Change IT's current position to POS in current_buffer. If FORCE_P
5558 is non-zero, always check for text properties at the new position.
5559 Otherwise, text properties are only looked up if POS >=
5560 IT->check_charpos of a property. */
5562 static void
5563 reseat (struct it *it, struct text_pos pos, int force_p)
5565 EMACS_INT original_pos = IT_CHARPOS (*it);
5567 reseat_1 (it, pos, 0);
5569 /* Determine where to check text properties. Avoid doing it
5570 where possible because text property lookup is very expensive. */
5571 if (force_p
5572 || CHARPOS (pos) > it->stop_charpos
5573 || CHARPOS (pos) < original_pos)
5575 if (it->bidi_p)
5577 /* For bidi iteration, we need to prime prev_stop and
5578 base_level_stop with our best estimations. */
5579 if (CHARPOS (pos) < it->prev_stop)
5581 handle_stop_backwards (it, BEGV);
5582 if (CHARPOS (pos) < it->base_level_stop)
5583 it->base_level_stop = 0;
5585 else if (CHARPOS (pos) > it->stop_charpos
5586 && it->stop_charpos >= BEGV)
5587 handle_stop_backwards (it, it->stop_charpos);
5588 else /* force_p */
5589 handle_stop (it);
5591 else
5593 handle_stop (it);
5594 it->prev_stop = it->base_level_stop = 0;
5599 CHECK_IT (it);
5603 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
5604 IT->stop_pos to POS, also. */
5606 static void
5607 reseat_1 (struct it *it, struct text_pos pos, int set_stop_p)
5609 /* Don't call this function when scanning a C string. */
5610 xassert (it->s == NULL);
5612 /* POS must be a reasonable value. */
5613 xassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
5615 it->current.pos = it->position = pos;
5616 it->end_charpos = ZV;
5617 it->dpvec = NULL;
5618 it->current.dpvec_index = -1;
5619 it->current.overlay_string_index = -1;
5620 IT_STRING_CHARPOS (*it) = -1;
5621 IT_STRING_BYTEPOS (*it) = -1;
5622 it->string = Qnil;
5623 it->string_from_display_prop_p = 0;
5624 it->method = GET_FROM_BUFFER;
5625 it->object = it->w->buffer;
5626 it->area = TEXT_AREA;
5627 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
5628 it->sp = 0;
5629 it->string_from_display_prop_p = 0;
5630 it->face_before_selective_p = 0;
5631 if (it->bidi_p)
5633 it->bidi_it.first_elt = 1;
5634 it->bidi_it.paragraph_dir = NEUTRAL_DIR;
5637 if (set_stop_p)
5639 it->stop_charpos = CHARPOS (pos);
5640 it->base_level_stop = CHARPOS (pos);
5645 /* Set up IT for displaying a string, starting at CHARPOS in window W.
5646 If S is non-null, it is a C string to iterate over. Otherwise,
5647 STRING gives a Lisp string to iterate over.
5649 If PRECISION > 0, don't return more then PRECISION number of
5650 characters from the string.
5652 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
5653 characters have been returned. FIELD_WIDTH < 0 means an infinite
5654 field width.
5656 MULTIBYTE = 0 means disable processing of multibyte characters,
5657 MULTIBYTE > 0 means enable it,
5658 MULTIBYTE < 0 means use IT->multibyte_p.
5660 IT must be initialized via a prior call to init_iterator before
5661 calling this function. */
5663 static void
5664 reseat_to_string (struct it *it, const unsigned char *s, Lisp_Object string,
5665 EMACS_INT charpos, EMACS_INT precision, int field_width,
5666 int multibyte)
5668 /* No region in strings. */
5669 it->region_beg_charpos = it->region_end_charpos = -1;
5671 /* No text property checks performed by default, but see below. */
5672 it->stop_charpos = -1;
5674 /* Set iterator position and end position. */
5675 memset (&it->current, 0, sizeof it->current);
5676 it->current.overlay_string_index = -1;
5677 it->current.dpvec_index = -1;
5678 xassert (charpos >= 0);
5680 /* If STRING is specified, use its multibyteness, otherwise use the
5681 setting of MULTIBYTE, if specified. */
5682 if (multibyte >= 0)
5683 it->multibyte_p = multibyte > 0;
5685 if (s == NULL)
5687 xassert (STRINGP (string));
5688 it->string = string;
5689 it->s = NULL;
5690 it->end_charpos = it->string_nchars = SCHARS (string);
5691 it->method = GET_FROM_STRING;
5692 it->current.string_pos = string_pos (charpos, string);
5694 else
5696 it->s = s;
5697 it->string = Qnil;
5699 /* Note that we use IT->current.pos, not it->current.string_pos,
5700 for displaying C strings. */
5701 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
5702 if (it->multibyte_p)
5704 it->current.pos = c_string_pos (charpos, s, 1);
5705 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
5707 else
5709 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
5710 it->end_charpos = it->string_nchars = strlen (s);
5713 it->method = GET_FROM_C_STRING;
5716 /* PRECISION > 0 means don't return more than PRECISION characters
5717 from the string. */
5718 if (precision > 0 && it->end_charpos - charpos > precision)
5719 it->end_charpos = it->string_nchars = charpos + precision;
5721 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
5722 characters have been returned. FIELD_WIDTH == 0 means don't pad,
5723 FIELD_WIDTH < 0 means infinite field width. This is useful for
5724 padding with `-' at the end of a mode line. */
5725 if (field_width < 0)
5726 field_width = INFINITY;
5727 if (field_width > it->end_charpos - charpos)
5728 it->end_charpos = charpos + field_width;
5730 /* Use the standard display table for displaying strings. */
5731 if (DISP_TABLE_P (Vstandard_display_table))
5732 it->dp = XCHAR_TABLE (Vstandard_display_table);
5734 it->stop_charpos = charpos;
5735 if (s == NULL && it->multibyte_p)
5737 EMACS_INT endpos = SCHARS (it->string);
5738 if (endpos > it->end_charpos)
5739 endpos = it->end_charpos;
5740 composition_compute_stop_pos (&it->cmp_it, charpos, -1, endpos,
5741 it->string);
5743 CHECK_IT (it);
5748 /***********************************************************************
5749 Iteration
5750 ***********************************************************************/
5752 /* Map enum it_method value to corresponding next_element_from_* function. */
5754 static int (* get_next_element[NUM_IT_METHODS]) (struct it *it) =
5756 next_element_from_buffer,
5757 next_element_from_display_vector,
5758 next_element_from_string,
5759 next_element_from_c_string,
5760 next_element_from_image,
5761 next_element_from_stretch
5764 #define GET_NEXT_DISPLAY_ELEMENT(it) (*get_next_element[(it)->method]) (it)
5767 /* Return 1 iff a character at CHARPOS (and BYTEPOS) is composed
5768 (possibly with the following characters). */
5770 #define CHAR_COMPOSED_P(IT,CHARPOS,BYTEPOS,END_CHARPOS) \
5771 ((IT)->cmp_it.id >= 0 \
5772 || ((IT)->cmp_it.stop_pos == (CHARPOS) \
5773 && composition_reseat_it (&(IT)->cmp_it, CHARPOS, BYTEPOS, \
5774 END_CHARPOS, (IT)->w, \
5775 FACE_FROM_ID ((IT)->f, (IT)->face_id), \
5776 (IT)->string)))
5779 /* Lookup the char-table Vglyphless_char_display for character C (-1
5780 if we want information for no-font case), and return the display
5781 method symbol. By side-effect, update it->what and
5782 it->glyphless_method. This function is called from
5783 get_next_display_element for each character element, and from
5784 x_produce_glyphs when no suitable font was found. */
5786 Lisp_Object
5787 lookup_glyphless_char_display (int c, struct it *it)
5789 Lisp_Object glyphless_method = Qnil;
5791 if (CHAR_TABLE_P (Vglyphless_char_display)
5792 && CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display)) >= 1)
5793 glyphless_method = (c >= 0
5794 ? CHAR_TABLE_REF (Vglyphless_char_display, c)
5795 : XCHAR_TABLE (Vglyphless_char_display)->extras[0]);
5796 retry:
5797 if (NILP (glyphless_method))
5799 if (c >= 0)
5800 /* The default is to display the character by a proper font. */
5801 return Qnil;
5802 /* The default for the no-font case is to display an empty box. */
5803 glyphless_method = Qempty_box;
5805 if (EQ (glyphless_method, Qzero_width))
5807 if (c >= 0)
5808 return glyphless_method;
5809 /* This method can't be used for the no-font case. */
5810 glyphless_method = Qempty_box;
5812 if (EQ (glyphless_method, Qthin_space))
5813 it->glyphless_method = GLYPHLESS_DISPLAY_THIN_SPACE;
5814 else if (EQ (glyphless_method, Qempty_box))
5815 it->glyphless_method = GLYPHLESS_DISPLAY_EMPTY_BOX;
5816 else if (EQ (glyphless_method, Qhex_code))
5817 it->glyphless_method = GLYPHLESS_DISPLAY_HEX_CODE;
5818 else if (STRINGP (glyphless_method))
5819 it->glyphless_method = GLYPHLESS_DISPLAY_ACRONYM;
5820 else
5822 /* Invalid value. We use the default method. */
5823 glyphless_method = Qnil;
5824 goto retry;
5826 it->what = IT_GLYPHLESS;
5827 return glyphless_method;
5830 /* Load IT's display element fields with information about the next
5831 display element from the current position of IT. Value is zero if
5832 end of buffer (or C string) is reached. */
5834 static struct frame *last_escape_glyph_frame = NULL;
5835 static unsigned last_escape_glyph_face_id = (1 << FACE_ID_BITS);
5836 static int last_escape_glyph_merged_face_id = 0;
5838 struct frame *last_glyphless_glyph_frame = NULL;
5839 unsigned last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
5840 int last_glyphless_glyph_merged_face_id = 0;
5843 get_next_display_element (struct it *it)
5845 /* Non-zero means that we found a display element. Zero means that
5846 we hit the end of what we iterate over. Performance note: the
5847 function pointer `method' used here turns out to be faster than
5848 using a sequence of if-statements. */
5849 int success_p;
5851 get_next:
5852 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
5854 if (it->what == IT_CHARACTER)
5856 /* UAX#9, L4: "A character is depicted by a mirrored glyph if
5857 and only if (a) the resolved directionality of that character
5858 is R..." */
5859 /* FIXME: Do we need an exception for characters from display
5860 tables? */
5861 if (it->bidi_p && it->bidi_it.type == STRONG_R)
5862 it->c = bidi_mirror_char (it->c);
5863 /* Map via display table or translate control characters.
5864 IT->c, IT->len etc. have been set to the next character by
5865 the function call above. If we have a display table, and it
5866 contains an entry for IT->c, translate it. Don't do this if
5867 IT->c itself comes from a display table, otherwise we could
5868 end up in an infinite recursion. (An alternative could be to
5869 count the recursion depth of this function and signal an
5870 error when a certain maximum depth is reached.) Is it worth
5871 it? */
5872 if (success_p && it->dpvec == NULL)
5874 Lisp_Object dv;
5875 struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte);
5876 enum { char_is_other = 0, char_is_nbsp, char_is_soft_hyphen }
5877 nbsp_or_shy = char_is_other;
5878 int c = it->c; /* This is the character to display. */
5880 if (! it->multibyte_p && ! ASCII_CHAR_P (c))
5882 xassert (SINGLE_BYTE_CHAR_P (c));
5883 if (unibyte_display_via_language_environment)
5885 c = DECODE_CHAR (unibyte, c);
5886 if (c < 0)
5887 c = BYTE8_TO_CHAR (it->c);
5889 else
5890 c = BYTE8_TO_CHAR (it->c);
5893 if (it->dp
5894 && (dv = DISP_CHAR_VECTOR (it->dp, c),
5895 VECTORP (dv)))
5897 struct Lisp_Vector *v = XVECTOR (dv);
5899 /* Return the first character from the display table
5900 entry, if not empty. If empty, don't display the
5901 current character. */
5902 if (v->size)
5904 it->dpvec_char_len = it->len;
5905 it->dpvec = v->contents;
5906 it->dpend = v->contents + v->size;
5907 it->current.dpvec_index = 0;
5908 it->dpvec_face_id = -1;
5909 it->saved_face_id = it->face_id;
5910 it->method = GET_FROM_DISPLAY_VECTOR;
5911 it->ellipsis_p = 0;
5913 else
5915 set_iterator_to_next (it, 0);
5917 goto get_next;
5920 if (! NILP (lookup_glyphless_char_display (c, it)))
5922 if (it->what == IT_GLYPHLESS)
5923 goto done;
5924 /* Don't display this character. */
5925 set_iterator_to_next (it, 0);
5926 goto get_next;
5929 if (! ASCII_CHAR_P (c) && ! NILP (Vnobreak_char_display))
5930 nbsp_or_shy = (c == 0xA0 ? char_is_nbsp
5931 : c == 0xAD ? char_is_soft_hyphen
5932 : char_is_other);
5934 /* Translate control characters into `\003' or `^C' form.
5935 Control characters coming from a display table entry are
5936 currently not translated because we use IT->dpvec to hold
5937 the translation. This could easily be changed but I
5938 don't believe that it is worth doing.
5940 NBSP and SOFT-HYPEN are property translated too.
5942 Non-printable characters and raw-byte characters are also
5943 translated to octal form. */
5944 if (((c < ' ' || c == 127) /* ASCII control chars */
5945 ? (it->area != TEXT_AREA
5946 /* In mode line, treat \n, \t like other crl chars. */
5947 || (c != '\t'
5948 && it->glyph_row
5949 && (it->glyph_row->mode_line_p || it->avoid_cursor_p))
5950 || (c != '\n' && c != '\t'))
5951 : (nbsp_or_shy
5952 || CHAR_BYTE8_P (c)
5953 || ! CHAR_PRINTABLE_P (c))))
5955 /* C is a control character, NBSP, SOFT-HYPEN, raw-byte,
5956 or a non-printable character which must be displayed
5957 either as '\003' or as `^C' where the '\\' and '^'
5958 can be defined in the display table. Fill
5959 IT->ctl_chars with glyphs for what we have to
5960 display. Then, set IT->dpvec to these glyphs. */
5961 Lisp_Object gc;
5962 int ctl_len;
5963 int face_id, lface_id = 0 ;
5964 int escape_glyph;
5966 /* Handle control characters with ^. */
5968 if (ASCII_CHAR_P (c) && it->ctl_arrow_p)
5970 int g;
5972 g = '^'; /* default glyph for Control */
5973 /* Set IT->ctl_chars[0] to the glyph for `^'. */
5974 if (it->dp
5975 && (gc = DISP_CTRL_GLYPH (it->dp), GLYPH_CODE_P (gc))
5976 && GLYPH_CODE_CHAR_VALID_P (gc))
5978 g = GLYPH_CODE_CHAR (gc);
5979 lface_id = GLYPH_CODE_FACE (gc);
5981 if (lface_id)
5983 face_id = merge_faces (it->f, Qt, lface_id, it->face_id);
5985 else if (it->f == last_escape_glyph_frame
5986 && it->face_id == last_escape_glyph_face_id)
5988 face_id = last_escape_glyph_merged_face_id;
5990 else
5992 /* Merge the escape-glyph face into the current face. */
5993 face_id = merge_faces (it->f, Qescape_glyph, 0,
5994 it->face_id);
5995 last_escape_glyph_frame = it->f;
5996 last_escape_glyph_face_id = it->face_id;
5997 last_escape_glyph_merged_face_id = face_id;
6000 XSETINT (it->ctl_chars[0], g);
6001 XSETINT (it->ctl_chars[1], c ^ 0100);
6002 ctl_len = 2;
6003 goto display_control;
6006 /* Handle non-break space in the mode where it only gets
6007 highlighting. */
6009 if (EQ (Vnobreak_char_display, Qt)
6010 && nbsp_or_shy == char_is_nbsp)
6012 /* Merge the no-break-space face into the current face. */
6013 face_id = merge_faces (it->f, Qnobreak_space, 0,
6014 it->face_id);
6016 c = ' ';
6017 XSETINT (it->ctl_chars[0], ' ');
6018 ctl_len = 1;
6019 goto display_control;
6022 /* Handle sequences that start with the "escape glyph". */
6024 /* the default escape glyph is \. */
6025 escape_glyph = '\\';
6027 if (it->dp
6028 && (gc = DISP_ESCAPE_GLYPH (it->dp), GLYPH_CODE_P (gc))
6029 && GLYPH_CODE_CHAR_VALID_P (gc))
6031 escape_glyph = GLYPH_CODE_CHAR (gc);
6032 lface_id = GLYPH_CODE_FACE (gc);
6034 if (lface_id)
6036 /* The display table specified a face.
6037 Merge it into face_id and also into escape_glyph. */
6038 face_id = merge_faces (it->f, Qt, lface_id,
6039 it->face_id);
6041 else if (it->f == last_escape_glyph_frame
6042 && it->face_id == last_escape_glyph_face_id)
6044 face_id = last_escape_glyph_merged_face_id;
6046 else
6048 /* Merge the escape-glyph face into the current face. */
6049 face_id = merge_faces (it->f, Qescape_glyph, 0,
6050 it->face_id);
6051 last_escape_glyph_frame = it->f;
6052 last_escape_glyph_face_id = it->face_id;
6053 last_escape_glyph_merged_face_id = face_id;
6056 /* Handle soft hyphens in the mode where they only get
6057 highlighting. */
6059 if (EQ (Vnobreak_char_display, Qt)
6060 && nbsp_or_shy == char_is_soft_hyphen)
6062 XSETINT (it->ctl_chars[0], '-');
6063 ctl_len = 1;
6064 goto display_control;
6067 /* Handle non-break space and soft hyphen
6068 with the escape glyph. */
6070 if (nbsp_or_shy)
6072 XSETINT (it->ctl_chars[0], escape_glyph);
6073 c = (nbsp_or_shy == char_is_nbsp ? ' ' : '-');
6074 XSETINT (it->ctl_chars[1], c);
6075 ctl_len = 2;
6076 goto display_control;
6080 char str[10];
6081 int len, i;
6083 if (CHAR_BYTE8_P (c))
6084 /* Display \200 instead of \17777600. */
6085 c = CHAR_TO_BYTE8 (c);
6086 len = sprintf (str, "%03o", c);
6088 XSETINT (it->ctl_chars[0], escape_glyph);
6089 for (i = 0; i < len; i++)
6090 XSETINT (it->ctl_chars[i + 1], str[i]);
6091 ctl_len = len + 1;
6094 display_control:
6095 /* Set up IT->dpvec and return first character from it. */
6096 it->dpvec_char_len = it->len;
6097 it->dpvec = it->ctl_chars;
6098 it->dpend = it->dpvec + ctl_len;
6099 it->current.dpvec_index = 0;
6100 it->dpvec_face_id = face_id;
6101 it->saved_face_id = it->face_id;
6102 it->method = GET_FROM_DISPLAY_VECTOR;
6103 it->ellipsis_p = 0;
6104 goto get_next;
6106 it->char_to_display = c;
6108 else if (success_p)
6110 it->char_to_display = it->c;
6114 #ifdef HAVE_WINDOW_SYSTEM
6115 /* Adjust face id for a multibyte character. There are no multibyte
6116 character in unibyte text. */
6117 if ((it->what == IT_CHARACTER || it->what == IT_COMPOSITION)
6118 && it->multibyte_p
6119 && success_p
6120 && FRAME_WINDOW_P (it->f))
6122 struct face *face = FACE_FROM_ID (it->f, it->face_id);
6124 if (it->what == IT_COMPOSITION && it->cmp_it.ch >= 0)
6126 /* Automatic composition with glyph-string. */
6127 Lisp_Object gstring = composition_gstring_from_id (it->cmp_it.id);
6129 it->face_id = face_for_font (it->f, LGSTRING_FONT (gstring), face);
6131 else
6133 EMACS_INT pos = (it->s ? -1
6134 : STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
6135 : IT_CHARPOS (*it));
6137 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display, pos,
6138 it->string);
6141 #endif
6143 done:
6144 /* Is this character the last one of a run of characters with
6145 box? If yes, set IT->end_of_box_run_p to 1. */
6146 if (it->face_box_p
6147 && it->s == NULL)
6149 if (it->method == GET_FROM_STRING && it->sp)
6151 int face_id = underlying_face_id (it);
6152 struct face *face = FACE_FROM_ID (it->f, face_id);
6154 if (face)
6156 if (face->box == FACE_NO_BOX)
6158 /* If the box comes from face properties in a
6159 display string, check faces in that string. */
6160 int string_face_id = face_after_it_pos (it);
6161 it->end_of_box_run_p
6162 = (FACE_FROM_ID (it->f, string_face_id)->box
6163 == FACE_NO_BOX);
6165 /* Otherwise, the box comes from the underlying face.
6166 If this is the last string character displayed, check
6167 the next buffer location. */
6168 else if ((IT_STRING_CHARPOS (*it) >= SCHARS (it->string) - 1)
6169 && (it->current.overlay_string_index
6170 == it->n_overlay_strings - 1))
6172 EMACS_INT ignore;
6173 int next_face_id;
6174 struct text_pos pos = it->current.pos;
6175 INC_TEXT_POS (pos, it->multibyte_p);
6177 next_face_id = face_at_buffer_position
6178 (it->w, CHARPOS (pos), it->region_beg_charpos,
6179 it->region_end_charpos, &ignore,
6180 (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT), 0,
6181 -1);
6182 it->end_of_box_run_p
6183 = (FACE_FROM_ID (it->f, next_face_id)->box
6184 == FACE_NO_BOX);
6188 else
6190 int face_id = face_after_it_pos (it);
6191 it->end_of_box_run_p
6192 = (face_id != it->face_id
6193 && FACE_FROM_ID (it->f, face_id)->box == FACE_NO_BOX);
6197 /* Value is 0 if end of buffer or string reached. */
6198 return success_p;
6202 /* Move IT to the next display element.
6204 RESEAT_P non-zero means if called on a newline in buffer text,
6205 skip to the next visible line start.
6207 Functions get_next_display_element and set_iterator_to_next are
6208 separate because I find this arrangement easier to handle than a
6209 get_next_display_element function that also increments IT's
6210 position. The way it is we can first look at an iterator's current
6211 display element, decide whether it fits on a line, and if it does,
6212 increment the iterator position. The other way around we probably
6213 would either need a flag indicating whether the iterator has to be
6214 incremented the next time, or we would have to implement a
6215 decrement position function which would not be easy to write. */
6217 void
6218 set_iterator_to_next (struct it *it, int reseat_p)
6220 /* Reset flags indicating start and end of a sequence of characters
6221 with box. Reset them at the start of this function because
6222 moving the iterator to a new position might set them. */
6223 it->start_of_box_run_p = it->end_of_box_run_p = 0;
6225 switch (it->method)
6227 case GET_FROM_BUFFER:
6228 /* The current display element of IT is a character from
6229 current_buffer. Advance in the buffer, and maybe skip over
6230 invisible lines that are so because of selective display. */
6231 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
6232 reseat_at_next_visible_line_start (it, 0);
6233 else if (it->cmp_it.id >= 0)
6235 /* We are currently getting glyphs from a composition. */
6236 int i;
6238 if (! it->bidi_p)
6240 IT_CHARPOS (*it) += it->cmp_it.nchars;
6241 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
6242 if (it->cmp_it.to < it->cmp_it.nglyphs)
6244 it->cmp_it.from = it->cmp_it.to;
6246 else
6248 it->cmp_it.id = -1;
6249 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
6250 IT_BYTEPOS (*it),
6251 it->end_charpos, Qnil);
6254 else if (! it->cmp_it.reversed_p)
6256 /* Composition created while scanning forward. */
6257 /* Update IT's char/byte positions to point to the first
6258 character of the next grapheme cluster, or to the
6259 character visually after the current composition. */
6260 for (i = 0; i < it->cmp_it.nchars; i++)
6261 bidi_move_to_visually_next (&it->bidi_it);
6262 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6263 IT_CHARPOS (*it) = it->bidi_it.charpos;
6265 if (it->cmp_it.to < it->cmp_it.nglyphs)
6267 /* Proceed to the next grapheme cluster. */
6268 it->cmp_it.from = it->cmp_it.to;
6270 else
6272 /* No more grapheme clusters in this composition.
6273 Find the next stop position. */
6274 EMACS_INT stop = it->end_charpos;
6275 if (it->bidi_it.scan_dir < 0)
6276 /* Now we are scanning backward and don't know
6277 where to stop. */
6278 stop = -1;
6279 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
6280 IT_BYTEPOS (*it), stop, Qnil);
6283 else
6285 /* Composition created while scanning backward. */
6286 /* Update IT's char/byte positions to point to the last
6287 character of the previous grapheme cluster, or the
6288 character visually after the current composition. */
6289 for (i = 0; i < it->cmp_it.nchars; i++)
6290 bidi_move_to_visually_next (&it->bidi_it);
6291 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6292 IT_CHARPOS (*it) = it->bidi_it.charpos;
6293 if (it->cmp_it.from > 0)
6295 /* Proceed to the previous grapheme cluster. */
6296 it->cmp_it.to = it->cmp_it.from;
6298 else
6300 /* No more grapheme clusters in this composition.
6301 Find the next stop position. */
6302 EMACS_INT stop = it->end_charpos;
6303 if (it->bidi_it.scan_dir < 0)
6304 /* Now we are scanning backward and don't know
6305 where to stop. */
6306 stop = -1;
6307 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
6308 IT_BYTEPOS (*it), stop, Qnil);
6312 else
6314 xassert (it->len != 0);
6316 if (!it->bidi_p)
6318 IT_BYTEPOS (*it) += it->len;
6319 IT_CHARPOS (*it) += 1;
6321 else
6323 int prev_scan_dir = it->bidi_it.scan_dir;
6324 /* If this is a new paragraph, determine its base
6325 direction (a.k.a. its base embedding level). */
6326 if (it->bidi_it.new_paragraph)
6327 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 0);
6328 bidi_move_to_visually_next (&it->bidi_it);
6329 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6330 IT_CHARPOS (*it) = it->bidi_it.charpos;
6331 if (prev_scan_dir != it->bidi_it.scan_dir)
6333 /* As the scan direction was changed, we must
6334 re-compute the stop position for composition. */
6335 EMACS_INT stop = it->end_charpos;
6336 if (it->bidi_it.scan_dir < 0)
6337 stop = -1;
6338 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
6339 IT_BYTEPOS (*it), stop, Qnil);
6342 xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
6344 break;
6346 case GET_FROM_C_STRING:
6347 /* Current display element of IT is from a C string. */
6348 IT_BYTEPOS (*it) += it->len;
6349 IT_CHARPOS (*it) += 1;
6350 break;
6352 case GET_FROM_DISPLAY_VECTOR:
6353 /* Current display element of IT is from a display table entry.
6354 Advance in the display table definition. Reset it to null if
6355 end reached, and continue with characters from buffers/
6356 strings. */
6357 ++it->current.dpvec_index;
6359 /* Restore face of the iterator to what they were before the
6360 display vector entry (these entries may contain faces). */
6361 it->face_id = it->saved_face_id;
6363 if (it->dpvec + it->current.dpvec_index == it->dpend)
6365 int recheck_faces = it->ellipsis_p;
6367 if (it->s)
6368 it->method = GET_FROM_C_STRING;
6369 else if (STRINGP (it->string))
6370 it->method = GET_FROM_STRING;
6371 else
6373 it->method = GET_FROM_BUFFER;
6374 it->object = it->w->buffer;
6377 it->dpvec = NULL;
6378 it->current.dpvec_index = -1;
6380 /* Skip over characters which were displayed via IT->dpvec. */
6381 if (it->dpvec_char_len < 0)
6382 reseat_at_next_visible_line_start (it, 1);
6383 else if (it->dpvec_char_len > 0)
6385 if (it->method == GET_FROM_STRING
6386 && it->n_overlay_strings > 0)
6387 it->ignore_overlay_strings_at_pos_p = 1;
6388 it->len = it->dpvec_char_len;
6389 set_iterator_to_next (it, reseat_p);
6392 /* Maybe recheck faces after display vector */
6393 if (recheck_faces)
6394 it->stop_charpos = IT_CHARPOS (*it);
6396 break;
6398 case GET_FROM_STRING:
6399 /* Current display element is a character from a Lisp string. */
6400 xassert (it->s == NULL && STRINGP (it->string));
6401 if (it->cmp_it.id >= 0)
6403 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
6404 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
6405 if (it->cmp_it.to < it->cmp_it.nglyphs)
6406 it->cmp_it.from = it->cmp_it.to;
6407 else
6409 it->cmp_it.id = -1;
6410 composition_compute_stop_pos (&it->cmp_it,
6411 IT_STRING_CHARPOS (*it),
6412 IT_STRING_BYTEPOS (*it),
6413 it->end_charpos, it->string);
6416 else
6418 IT_STRING_BYTEPOS (*it) += it->len;
6419 IT_STRING_CHARPOS (*it) += 1;
6422 consider_string_end:
6424 if (it->current.overlay_string_index >= 0)
6426 /* IT->string is an overlay string. Advance to the
6427 next, if there is one. */
6428 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
6430 it->ellipsis_p = 0;
6431 next_overlay_string (it);
6432 if (it->ellipsis_p)
6433 setup_for_ellipsis (it, 0);
6436 else
6438 /* IT->string is not an overlay string. If we reached
6439 its end, and there is something on IT->stack, proceed
6440 with what is on the stack. This can be either another
6441 string, this time an overlay string, or a buffer. */
6442 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
6443 && it->sp > 0)
6445 pop_it (it);
6446 if (it->method == GET_FROM_STRING)
6447 goto consider_string_end;
6450 break;
6452 case GET_FROM_IMAGE:
6453 case GET_FROM_STRETCH:
6454 /* The position etc with which we have to proceed are on
6455 the stack. The position may be at the end of a string,
6456 if the `display' property takes up the whole string. */
6457 xassert (it->sp > 0);
6458 pop_it (it);
6459 if (it->method == GET_FROM_STRING)
6460 goto consider_string_end;
6461 break;
6463 default:
6464 /* There are no other methods defined, so this should be a bug. */
6465 abort ();
6468 xassert (it->method != GET_FROM_STRING
6469 || (STRINGP (it->string)
6470 && IT_STRING_CHARPOS (*it) >= 0));
6473 /* Load IT's display element fields with information about the next
6474 display element which comes from a display table entry or from the
6475 result of translating a control character to one of the forms `^C'
6476 or `\003'.
6478 IT->dpvec holds the glyphs to return as characters.
6479 IT->saved_face_id holds the face id before the display vector--it
6480 is restored into IT->face_id in set_iterator_to_next. */
6482 static int
6483 next_element_from_display_vector (struct it *it)
6485 Lisp_Object gc;
6487 /* Precondition. */
6488 xassert (it->dpvec && it->current.dpvec_index >= 0);
6490 it->face_id = it->saved_face_id;
6492 /* KFS: This code used to check ip->dpvec[0] instead of the current element.
6493 That seemed totally bogus - so I changed it... */
6494 gc = it->dpvec[it->current.dpvec_index];
6496 if (GLYPH_CODE_P (gc) && GLYPH_CODE_CHAR_VALID_P (gc))
6498 it->c = GLYPH_CODE_CHAR (gc);
6499 it->len = CHAR_BYTES (it->c);
6501 /* The entry may contain a face id to use. Such a face id is
6502 the id of a Lisp face, not a realized face. A face id of
6503 zero means no face is specified. */
6504 if (it->dpvec_face_id >= 0)
6505 it->face_id = it->dpvec_face_id;
6506 else
6508 int lface_id = GLYPH_CODE_FACE (gc);
6509 if (lface_id > 0)
6510 it->face_id = merge_faces (it->f, Qt, lface_id,
6511 it->saved_face_id);
6514 else
6515 /* Display table entry is invalid. Return a space. */
6516 it->c = ' ', it->len = 1;
6518 /* Don't change position and object of the iterator here. They are
6519 still the values of the character that had this display table
6520 entry or was translated, and that's what we want. */
6521 it->what = IT_CHARACTER;
6522 return 1;
6526 /* Load IT with the next display element from Lisp string IT->string.
6527 IT->current.string_pos is the current position within the string.
6528 If IT->current.overlay_string_index >= 0, the Lisp string is an
6529 overlay string. */
6531 static int
6532 next_element_from_string (struct it *it)
6534 struct text_pos position;
6536 xassert (STRINGP (it->string));
6537 xassert (IT_STRING_CHARPOS (*it) >= 0);
6538 position = it->current.string_pos;
6540 /* Time to check for invisible text? */
6541 if (IT_STRING_CHARPOS (*it) < it->end_charpos
6542 && IT_STRING_CHARPOS (*it) == it->stop_charpos)
6544 handle_stop (it);
6546 /* Since a handler may have changed IT->method, we must
6547 recurse here. */
6548 return GET_NEXT_DISPLAY_ELEMENT (it);
6551 if (it->current.overlay_string_index >= 0)
6553 /* Get the next character from an overlay string. In overlay
6554 strings, There is no field width or padding with spaces to
6555 do. */
6556 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
6558 it->what = IT_EOB;
6559 return 0;
6561 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
6562 IT_STRING_BYTEPOS (*it), SCHARS (it->string))
6563 && next_element_from_composition (it))
6565 return 1;
6567 else if (STRING_MULTIBYTE (it->string))
6569 const unsigned char *s = (SDATA (it->string)
6570 + IT_STRING_BYTEPOS (*it));
6571 it->c = string_char_and_length (s, &it->len);
6573 else
6575 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
6576 it->len = 1;
6579 else
6581 /* Get the next character from a Lisp string that is not an
6582 overlay string. Such strings come from the mode line, for
6583 example. We may have to pad with spaces, or truncate the
6584 string. See also next_element_from_c_string. */
6585 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
6587 it->what = IT_EOB;
6588 return 0;
6590 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
6592 /* Pad with spaces. */
6593 it->c = ' ', it->len = 1;
6594 CHARPOS (position) = BYTEPOS (position) = -1;
6596 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
6597 IT_STRING_BYTEPOS (*it), it->string_nchars)
6598 && next_element_from_composition (it))
6600 return 1;
6602 else if (STRING_MULTIBYTE (it->string))
6604 const unsigned char *s = (SDATA (it->string)
6605 + IT_STRING_BYTEPOS (*it));
6606 it->c = string_char_and_length (s, &it->len);
6608 else
6610 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
6611 it->len = 1;
6615 /* Record what we have and where it came from. */
6616 it->what = IT_CHARACTER;
6617 it->object = it->string;
6618 it->position = position;
6619 return 1;
6623 /* Load IT with next display element from C string IT->s.
6624 IT->string_nchars is the maximum number of characters to return
6625 from the string. IT->end_charpos may be greater than
6626 IT->string_nchars when this function is called, in which case we
6627 may have to return padding spaces. Value is zero if end of string
6628 reached, including padding spaces. */
6630 static int
6631 next_element_from_c_string (struct it *it)
6633 int success_p = 1;
6635 xassert (it->s);
6636 it->what = IT_CHARACTER;
6637 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
6638 it->object = Qnil;
6640 /* IT's position can be greater IT->string_nchars in case a field
6641 width or precision has been specified when the iterator was
6642 initialized. */
6643 if (IT_CHARPOS (*it) >= it->end_charpos)
6645 /* End of the game. */
6646 it->what = IT_EOB;
6647 success_p = 0;
6649 else if (IT_CHARPOS (*it) >= it->string_nchars)
6651 /* Pad with spaces. */
6652 it->c = ' ', it->len = 1;
6653 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
6655 else if (it->multibyte_p)
6656 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it), &it->len);
6657 else
6658 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
6660 return success_p;
6664 /* Set up IT to return characters from an ellipsis, if appropriate.
6665 The definition of the ellipsis glyphs may come from a display table
6666 entry. This function fills IT with the first glyph from the
6667 ellipsis if an ellipsis is to be displayed. */
6669 static int
6670 next_element_from_ellipsis (struct it *it)
6672 if (it->selective_display_ellipsis_p)
6673 setup_for_ellipsis (it, it->len);
6674 else
6676 /* The face at the current position may be different from the
6677 face we find after the invisible text. Remember what it
6678 was in IT->saved_face_id, and signal that it's there by
6679 setting face_before_selective_p. */
6680 it->saved_face_id = it->face_id;
6681 it->method = GET_FROM_BUFFER;
6682 it->object = it->w->buffer;
6683 reseat_at_next_visible_line_start (it, 1);
6684 it->face_before_selective_p = 1;
6687 return GET_NEXT_DISPLAY_ELEMENT (it);
6691 /* Deliver an image display element. The iterator IT is already
6692 filled with image information (done in handle_display_prop). Value
6693 is always 1. */
6696 static int
6697 next_element_from_image (struct it *it)
6699 it->what = IT_IMAGE;
6700 it->ignore_overlay_strings_at_pos_p = 0;
6701 return 1;
6705 /* Fill iterator IT with next display element from a stretch glyph
6706 property. IT->object is the value of the text property. Value is
6707 always 1. */
6709 static int
6710 next_element_from_stretch (struct it *it)
6712 it->what = IT_STRETCH;
6713 return 1;
6716 /* Scan forward from CHARPOS in the current buffer, until we find a
6717 stop position > current IT's position. Then handle the stop
6718 position before that. This is called when we bump into a stop
6719 position while reordering bidirectional text. CHARPOS should be
6720 the last previously processed stop_pos (or BEGV, if none were
6721 processed yet) whose position is less that IT's current
6722 position. */
6724 static void
6725 handle_stop_backwards (struct it *it, EMACS_INT charpos)
6727 EMACS_INT where_we_are = IT_CHARPOS (*it);
6728 struct display_pos save_current = it->current;
6729 struct text_pos save_position = it->position;
6730 struct text_pos pos1;
6731 EMACS_INT next_stop;
6733 /* Scan in strict logical order. */
6734 it->bidi_p = 0;
6737 it->prev_stop = charpos;
6738 SET_TEXT_POS (pos1, charpos, CHAR_TO_BYTE (charpos));
6739 reseat_1 (it, pos1, 0);
6740 compute_stop_pos (it);
6741 /* We must advance forward, right? */
6742 if (it->stop_charpos <= it->prev_stop)
6743 abort ();
6744 charpos = it->stop_charpos;
6746 while (charpos <= where_we_are);
6748 next_stop = it->stop_charpos;
6749 it->stop_charpos = it->prev_stop;
6750 it->bidi_p = 1;
6751 it->current = save_current;
6752 it->position = save_position;
6753 handle_stop (it);
6754 it->stop_charpos = next_stop;
6757 /* Load IT with the next display element from current_buffer. Value
6758 is zero if end of buffer reached. IT->stop_charpos is the next
6759 position at which to stop and check for text properties or buffer
6760 end. */
6762 static int
6763 next_element_from_buffer (struct it *it)
6765 int success_p = 1;
6767 xassert (IT_CHARPOS (*it) >= BEGV);
6769 /* With bidi reordering, the character to display might not be the
6770 character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that
6771 we were reseat()ed to a new buffer position, which is potentially
6772 a different paragraph. */
6773 if (it->bidi_p && it->bidi_it.first_elt)
6775 it->bidi_it.charpos = IT_CHARPOS (*it);
6776 it->bidi_it.bytepos = IT_BYTEPOS (*it);
6777 if (it->bidi_it.bytepos == ZV_BYTE)
6779 /* Nothing to do, but reset the FIRST_ELT flag, like
6780 bidi_paragraph_init does, because we are not going to
6781 call it. */
6782 it->bidi_it.first_elt = 0;
6784 else if (it->bidi_it.bytepos == BEGV_BYTE
6785 /* FIXME: Should support all Unicode line separators. */
6786 || FETCH_CHAR (it->bidi_it.bytepos - 1) == '\n'
6787 || FETCH_CHAR (it->bidi_it.bytepos) == '\n')
6789 /* If we are at the beginning of a line, we can produce the
6790 next element right away. */
6791 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
6792 bidi_move_to_visually_next (&it->bidi_it);
6794 else
6796 EMACS_INT orig_bytepos = IT_BYTEPOS (*it);
6798 /* We need to prime the bidi iterator starting at the line's
6799 beginning, before we will be able to produce the next
6800 element. */
6801 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it), -1);
6802 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
6803 it->bidi_it.charpos = IT_CHARPOS (*it);
6804 it->bidi_it.bytepos = IT_BYTEPOS (*it);
6805 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
6808 /* Now return to buffer position where we were asked to
6809 get the next display element, and produce that. */
6810 bidi_move_to_visually_next (&it->bidi_it);
6812 while (it->bidi_it.bytepos != orig_bytepos
6813 && it->bidi_it.bytepos < ZV_BYTE);
6816 it->bidi_it.first_elt = 0; /* paranoia: bidi.c does this */
6817 /* Adjust IT's position information to where we ended up. */
6818 IT_CHARPOS (*it) = it->bidi_it.charpos;
6819 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6820 SET_TEXT_POS (it->position, IT_CHARPOS (*it), IT_BYTEPOS (*it));
6822 EMACS_INT stop = it->end_charpos;
6823 if (it->bidi_it.scan_dir < 0)
6824 stop = -1;
6825 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
6826 IT_BYTEPOS (*it), stop, Qnil);
6830 if (IT_CHARPOS (*it) >= it->stop_charpos)
6832 if (IT_CHARPOS (*it) >= it->end_charpos)
6834 int overlay_strings_follow_p;
6836 /* End of the game, except when overlay strings follow that
6837 haven't been returned yet. */
6838 if (it->overlay_strings_at_end_processed_p)
6839 overlay_strings_follow_p = 0;
6840 else
6842 it->overlay_strings_at_end_processed_p = 1;
6843 overlay_strings_follow_p = get_overlay_strings (it, 0);
6846 if (overlay_strings_follow_p)
6847 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
6848 else
6850 it->what = IT_EOB;
6851 it->position = it->current.pos;
6852 success_p = 0;
6855 else if (!(!it->bidi_p
6856 || BIDI_AT_BASE_LEVEL (it->bidi_it)
6857 || IT_CHARPOS (*it) == it->stop_charpos))
6859 /* With bidi non-linear iteration, we could find ourselves
6860 far beyond the last computed stop_charpos, with several
6861 other stop positions in between that we missed. Scan
6862 them all now, in buffer's logical order, until we find
6863 and handle the last stop_charpos that precedes our
6864 current position. */
6865 handle_stop_backwards (it, it->stop_charpos);
6866 return GET_NEXT_DISPLAY_ELEMENT (it);
6868 else
6870 if (it->bidi_p)
6872 /* Take note of the stop position we just moved across,
6873 for when we will move back across it. */
6874 it->prev_stop = it->stop_charpos;
6875 /* If we are at base paragraph embedding level, take
6876 note of the last stop position seen at this
6877 level. */
6878 if (BIDI_AT_BASE_LEVEL (it->bidi_it))
6879 it->base_level_stop = it->stop_charpos;
6881 handle_stop (it);
6882 return GET_NEXT_DISPLAY_ELEMENT (it);
6885 else if (it->bidi_p
6886 /* We can sometimes back up for reasons that have nothing
6887 to do with bidi reordering. E.g., compositions. The
6888 code below is only needed when we are above the base
6889 embedding level, so test for that explicitly. */
6890 && !BIDI_AT_BASE_LEVEL (it->bidi_it)
6891 && IT_CHARPOS (*it) < it->prev_stop)
6893 if (it->base_level_stop <= 0)
6894 it->base_level_stop = BEGV;
6895 if (IT_CHARPOS (*it) < it->base_level_stop)
6896 abort ();
6897 handle_stop_backwards (it, it->base_level_stop);
6898 return GET_NEXT_DISPLAY_ELEMENT (it);
6900 else
6902 /* No face changes, overlays etc. in sight, so just return a
6903 character from current_buffer. */
6904 unsigned char *p;
6905 EMACS_INT stop;
6907 /* Maybe run the redisplay end trigger hook. Performance note:
6908 This doesn't seem to cost measurable time. */
6909 if (it->redisplay_end_trigger_charpos
6910 && it->glyph_row
6911 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
6912 run_redisplay_end_trigger_hook (it);
6914 stop = it->bidi_it.scan_dir < 0 ? -1 : it->end_charpos;
6915 if (CHAR_COMPOSED_P (it, IT_CHARPOS (*it), IT_BYTEPOS (*it),
6916 stop)
6917 && next_element_from_composition (it))
6919 return 1;
6922 /* Get the next character, maybe multibyte. */
6923 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
6924 if (it->multibyte_p && !ASCII_BYTE_P (*p))
6925 it->c = STRING_CHAR_AND_LENGTH (p, it->len);
6926 else
6927 it->c = *p, it->len = 1;
6929 /* Record what we have and where it came from. */
6930 it->what = IT_CHARACTER;
6931 it->object = it->w->buffer;
6932 it->position = it->current.pos;
6934 /* Normally we return the character found above, except when we
6935 really want to return an ellipsis for selective display. */
6936 if (it->selective)
6938 if (it->c == '\n')
6940 /* A value of selective > 0 means hide lines indented more
6941 than that number of columns. */
6942 if (it->selective > 0
6943 && IT_CHARPOS (*it) + 1 < ZV
6944 && indented_beyond_p (IT_CHARPOS (*it) + 1,
6945 IT_BYTEPOS (*it) + 1,
6946 (double) it->selective)) /* iftc */
6948 success_p = next_element_from_ellipsis (it);
6949 it->dpvec_char_len = -1;
6952 else if (it->c == '\r' && it->selective == -1)
6954 /* A value of selective == -1 means that everything from the
6955 CR to the end of the line is invisible, with maybe an
6956 ellipsis displayed for it. */
6957 success_p = next_element_from_ellipsis (it);
6958 it->dpvec_char_len = -1;
6963 /* Value is zero if end of buffer reached. */
6964 xassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
6965 return success_p;
6969 /* Run the redisplay end trigger hook for IT. */
6971 static void
6972 run_redisplay_end_trigger_hook (struct it *it)
6974 Lisp_Object args[3];
6976 /* IT->glyph_row should be non-null, i.e. we should be actually
6977 displaying something, or otherwise we should not run the hook. */
6978 xassert (it->glyph_row);
6980 /* Set up hook arguments. */
6981 args[0] = Qredisplay_end_trigger_functions;
6982 args[1] = it->window;
6983 XSETINT (args[2], it->redisplay_end_trigger_charpos);
6984 it->redisplay_end_trigger_charpos = 0;
6986 /* Since we are *trying* to run these functions, don't try to run
6987 them again, even if they get an error. */
6988 it->w->redisplay_end_trigger = Qnil;
6989 Frun_hook_with_args (3, args);
6991 /* Notice if it changed the face of the character we are on. */
6992 handle_face_prop (it);
6996 /* Deliver a composition display element. Unlike the other
6997 next_element_from_XXX, this function is not registered in the array
6998 get_next_element[]. It is called from next_element_from_buffer and
6999 next_element_from_string when necessary. */
7001 static int
7002 next_element_from_composition (struct it *it)
7004 it->what = IT_COMPOSITION;
7005 it->len = it->cmp_it.nbytes;
7006 if (STRINGP (it->string))
7008 if (it->c < 0)
7010 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
7011 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
7012 return 0;
7014 it->position = it->current.string_pos;
7015 it->object = it->string;
7016 it->c = composition_update_it (&it->cmp_it, IT_STRING_CHARPOS (*it),
7017 IT_STRING_BYTEPOS (*it), it->string);
7019 else
7021 if (it->c < 0)
7023 IT_CHARPOS (*it) += it->cmp_it.nchars;
7024 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
7025 if (it->bidi_p)
7027 if (it->bidi_it.new_paragraph)
7028 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 0);
7029 /* Resync the bidi iterator with IT's new position.
7030 FIXME: this doesn't support bidirectional text. */
7031 while (it->bidi_it.charpos < IT_CHARPOS (*it))
7032 bidi_move_to_visually_next (&it->bidi_it);
7034 return 0;
7036 it->position = it->current.pos;
7037 it->object = it->w->buffer;
7038 it->c = composition_update_it (&it->cmp_it, IT_CHARPOS (*it),
7039 IT_BYTEPOS (*it), Qnil);
7041 return 1;
7046 /***********************************************************************
7047 Moving an iterator without producing glyphs
7048 ***********************************************************************/
7050 /* Check if iterator is at a position corresponding to a valid buffer
7051 position after some move_it_ call. */
7053 #define IT_POS_VALID_AFTER_MOVE_P(it) \
7054 ((it)->method == GET_FROM_STRING \
7055 ? IT_STRING_CHARPOS (*it) == 0 \
7056 : 1)
7059 /* Move iterator IT to a specified buffer or X position within one
7060 line on the display without producing glyphs.
7062 OP should be a bit mask including some or all of these bits:
7063 MOVE_TO_X: Stop upon reaching x-position TO_X.
7064 MOVE_TO_POS: Stop upon reaching buffer or string position TO_CHARPOS.
7065 Regardless of OP's value, stop upon reaching the end of the display line.
7067 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
7068 This means, in particular, that TO_X includes window's horizontal
7069 scroll amount.
7071 The return value has several possible values that
7072 say what condition caused the scan to stop:
7074 MOVE_POS_MATCH_OR_ZV
7075 - when TO_POS or ZV was reached.
7077 MOVE_X_REACHED
7078 -when TO_X was reached before TO_POS or ZV were reached.
7080 MOVE_LINE_CONTINUED
7081 - when we reached the end of the display area and the line must
7082 be continued.
7084 MOVE_LINE_TRUNCATED
7085 - when we reached the end of the display area and the line is
7086 truncated.
7088 MOVE_NEWLINE_OR_CR
7089 - when we stopped at a line end, i.e. a newline or a CR and selective
7090 display is on. */
7092 static enum move_it_result
7093 move_it_in_display_line_to (struct it *it,
7094 EMACS_INT to_charpos, int to_x,
7095 enum move_operation_enum op)
7097 enum move_it_result result = MOVE_UNDEFINED;
7098 struct glyph_row *saved_glyph_row;
7099 struct it wrap_it, atpos_it, atx_it;
7100 int may_wrap = 0;
7101 enum it_method prev_method = it->method;
7102 EMACS_INT prev_pos = IT_CHARPOS (*it);
7104 /* Don't produce glyphs in produce_glyphs. */
7105 saved_glyph_row = it->glyph_row;
7106 it->glyph_row = NULL;
7108 /* Use wrap_it to save a copy of IT wherever a word wrap could
7109 occur. Use atpos_it to save a copy of IT at the desired buffer
7110 position, if found, so that we can scan ahead and check if the
7111 word later overshoots the window edge. Use atx_it similarly, for
7112 pixel positions. */
7113 wrap_it.sp = -1;
7114 atpos_it.sp = -1;
7115 atx_it.sp = -1;
7117 #define BUFFER_POS_REACHED_P() \
7118 ((op & MOVE_TO_POS) != 0 \
7119 && BUFFERP (it->object) \
7120 && (IT_CHARPOS (*it) == to_charpos \
7121 || (!it->bidi_p && IT_CHARPOS (*it) > to_charpos)) \
7122 && (it->method == GET_FROM_BUFFER \
7123 || (it->method == GET_FROM_DISPLAY_VECTOR \
7124 && it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
7126 /* If there's a line-/wrap-prefix, handle it. */
7127 if (it->hpos == 0 && it->method == GET_FROM_BUFFER
7128 && it->current_y < it->last_visible_y)
7129 handle_line_prefix (it);
7131 while (1)
7133 int x, i, ascent = 0, descent = 0;
7135 /* Utility macro to reset an iterator with x, ascent, and descent. */
7136 #define IT_RESET_X_ASCENT_DESCENT(IT) \
7137 ((IT)->current_x = x, (IT)->max_ascent = ascent, \
7138 (IT)->max_descent = descent)
7140 /* Stop if we move beyond TO_CHARPOS (after an image or stretch
7141 glyph). */
7142 if ((op & MOVE_TO_POS) != 0
7143 && BUFFERP (it->object)
7144 && it->method == GET_FROM_BUFFER
7145 && ((!it->bidi_p && IT_CHARPOS (*it) > to_charpos)
7146 || (it->bidi_p
7147 && (prev_method == GET_FROM_IMAGE
7148 || prev_method == GET_FROM_STRETCH)
7149 /* Passed TO_CHARPOS from left to right. */
7150 && ((prev_pos < to_charpos
7151 && IT_CHARPOS (*it) > to_charpos)
7152 /* Passed TO_CHARPOS from right to left. */
7153 || (prev_pos > to_charpos
7154 && IT_CHARPOS (*it) < to_charpos)))))
7156 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
7158 result = MOVE_POS_MATCH_OR_ZV;
7159 break;
7161 else if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
7162 /* If wrap_it is valid, the current position might be in a
7163 word that is wrapped. So, save the iterator in
7164 atpos_it and continue to see if wrapping happens. */
7165 atpos_it = *it;
7168 prev_method = it->method;
7169 if (it->method == GET_FROM_BUFFER)
7170 prev_pos = IT_CHARPOS (*it);
7171 /* Stop when ZV reached.
7172 We used to stop here when TO_CHARPOS reached as well, but that is
7173 too soon if this glyph does not fit on this line. So we handle it
7174 explicitly below. */
7175 if (!get_next_display_element (it))
7177 result = MOVE_POS_MATCH_OR_ZV;
7178 break;
7181 if (it->line_wrap == TRUNCATE)
7183 if (BUFFER_POS_REACHED_P ())
7185 result = MOVE_POS_MATCH_OR_ZV;
7186 break;
7189 else
7191 if (it->line_wrap == WORD_WRAP)
7193 if (IT_DISPLAYING_WHITESPACE (it))
7194 may_wrap = 1;
7195 else if (may_wrap)
7197 /* We have reached a glyph that follows one or more
7198 whitespace characters. If the position is
7199 already found, we are done. */
7200 if (atpos_it.sp >= 0)
7202 *it = atpos_it;
7203 result = MOVE_POS_MATCH_OR_ZV;
7204 goto done;
7206 if (atx_it.sp >= 0)
7208 *it = atx_it;
7209 result = MOVE_X_REACHED;
7210 goto done;
7212 /* Otherwise, we can wrap here. */
7213 wrap_it = *it;
7214 may_wrap = 0;
7219 /* Remember the line height for the current line, in case
7220 the next element doesn't fit on the line. */
7221 ascent = it->max_ascent;
7222 descent = it->max_descent;
7224 /* The call to produce_glyphs will get the metrics of the
7225 display element IT is loaded with. Record the x-position
7226 before this display element, in case it doesn't fit on the
7227 line. */
7228 x = it->current_x;
7230 PRODUCE_GLYPHS (it);
7232 if (it->area != TEXT_AREA)
7234 set_iterator_to_next (it, 1);
7235 continue;
7238 /* The number of glyphs we get back in IT->nglyphs will normally
7239 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
7240 character on a terminal frame, or (iii) a line end. For the
7241 second case, IT->nglyphs - 1 padding glyphs will be present.
7242 (On X frames, there is only one glyph produced for a
7243 composite character.)
7245 The behavior implemented below means, for continuation lines,
7246 that as many spaces of a TAB as fit on the current line are
7247 displayed there. For terminal frames, as many glyphs of a
7248 multi-glyph character are displayed in the current line, too.
7249 This is what the old redisplay code did, and we keep it that
7250 way. Under X, the whole shape of a complex character must
7251 fit on the line or it will be completely displayed in the
7252 next line.
7254 Note that both for tabs and padding glyphs, all glyphs have
7255 the same width. */
7256 if (it->nglyphs)
7258 /* More than one glyph or glyph doesn't fit on line. All
7259 glyphs have the same width. */
7260 int single_glyph_width = it->pixel_width / it->nglyphs;
7261 int new_x;
7262 int x_before_this_char = x;
7263 int hpos_before_this_char = it->hpos;
7265 for (i = 0; i < it->nglyphs; ++i, x = new_x)
7267 new_x = x + single_glyph_width;
7269 /* We want to leave anything reaching TO_X to the caller. */
7270 if ((op & MOVE_TO_X) && new_x > to_x)
7272 if (BUFFER_POS_REACHED_P ())
7274 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
7275 goto buffer_pos_reached;
7276 if (atpos_it.sp < 0)
7278 atpos_it = *it;
7279 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
7282 else
7284 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
7286 it->current_x = x;
7287 result = MOVE_X_REACHED;
7288 break;
7290 if (atx_it.sp < 0)
7292 atx_it = *it;
7293 IT_RESET_X_ASCENT_DESCENT (&atx_it);
7298 if (/* Lines are continued. */
7299 it->line_wrap != TRUNCATE
7300 && (/* And glyph doesn't fit on the line. */
7301 new_x > it->last_visible_x
7302 /* Or it fits exactly and we're on a window
7303 system frame. */
7304 || (new_x == it->last_visible_x
7305 && FRAME_WINDOW_P (it->f))))
7307 if (/* IT->hpos == 0 means the very first glyph
7308 doesn't fit on the line, e.g. a wide image. */
7309 it->hpos == 0
7310 || (new_x == it->last_visible_x
7311 && FRAME_WINDOW_P (it->f)))
7313 ++it->hpos;
7314 it->current_x = new_x;
7316 /* The character's last glyph just barely fits
7317 in this row. */
7318 if (i == it->nglyphs - 1)
7320 /* If this is the destination position,
7321 return a position *before* it in this row,
7322 now that we know it fits in this row. */
7323 if (BUFFER_POS_REACHED_P ())
7325 if (it->line_wrap != WORD_WRAP
7326 || wrap_it.sp < 0)
7328 it->hpos = hpos_before_this_char;
7329 it->current_x = x_before_this_char;
7330 result = MOVE_POS_MATCH_OR_ZV;
7331 break;
7333 if (it->line_wrap == WORD_WRAP
7334 && atpos_it.sp < 0)
7336 atpos_it = *it;
7337 atpos_it.current_x = x_before_this_char;
7338 atpos_it.hpos = hpos_before_this_char;
7342 set_iterator_to_next (it, 1);
7343 /* On graphical terminals, newlines may
7344 "overflow" into the fringe if
7345 overflow-newline-into-fringe is non-nil.
7346 On text-only terminals, newlines may
7347 overflow into the last glyph on the
7348 display line.*/
7349 if (!FRAME_WINDOW_P (it->f)
7350 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
7352 if (!get_next_display_element (it))
7354 result = MOVE_POS_MATCH_OR_ZV;
7355 break;
7357 if (BUFFER_POS_REACHED_P ())
7359 if (ITERATOR_AT_END_OF_LINE_P (it))
7360 result = MOVE_POS_MATCH_OR_ZV;
7361 else
7362 result = MOVE_LINE_CONTINUED;
7363 break;
7365 if (ITERATOR_AT_END_OF_LINE_P (it))
7367 result = MOVE_NEWLINE_OR_CR;
7368 break;
7373 else
7374 IT_RESET_X_ASCENT_DESCENT (it);
7376 if (wrap_it.sp >= 0)
7378 *it = wrap_it;
7379 atpos_it.sp = -1;
7380 atx_it.sp = -1;
7383 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
7384 IT_CHARPOS (*it)));
7385 result = MOVE_LINE_CONTINUED;
7386 break;
7389 if (BUFFER_POS_REACHED_P ())
7391 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
7392 goto buffer_pos_reached;
7393 if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
7395 atpos_it = *it;
7396 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
7400 if (new_x > it->first_visible_x)
7402 /* Glyph is visible. Increment number of glyphs that
7403 would be displayed. */
7404 ++it->hpos;
7408 if (result != MOVE_UNDEFINED)
7409 break;
7411 else if (BUFFER_POS_REACHED_P ())
7413 buffer_pos_reached:
7414 IT_RESET_X_ASCENT_DESCENT (it);
7415 result = MOVE_POS_MATCH_OR_ZV;
7416 break;
7418 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
7420 /* Stop when TO_X specified and reached. This check is
7421 necessary here because of lines consisting of a line end,
7422 only. The line end will not produce any glyphs and we
7423 would never get MOVE_X_REACHED. */
7424 xassert (it->nglyphs == 0);
7425 result = MOVE_X_REACHED;
7426 break;
7429 /* Is this a line end? If yes, we're done. */
7430 if (ITERATOR_AT_END_OF_LINE_P (it))
7432 result = MOVE_NEWLINE_OR_CR;
7433 break;
7436 if (it->method == GET_FROM_BUFFER)
7437 prev_pos = IT_CHARPOS (*it);
7438 /* The current display element has been consumed. Advance
7439 to the next. */
7440 set_iterator_to_next (it, 1);
7442 /* Stop if lines are truncated and IT's current x-position is
7443 past the right edge of the window now. */
7444 if (it->line_wrap == TRUNCATE
7445 && it->current_x >= it->last_visible_x)
7447 if (!FRAME_WINDOW_P (it->f)
7448 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
7450 if (!get_next_display_element (it)
7451 || BUFFER_POS_REACHED_P ())
7453 result = MOVE_POS_MATCH_OR_ZV;
7454 break;
7456 if (ITERATOR_AT_END_OF_LINE_P (it))
7458 result = MOVE_NEWLINE_OR_CR;
7459 break;
7462 result = MOVE_LINE_TRUNCATED;
7463 break;
7465 #undef IT_RESET_X_ASCENT_DESCENT
7468 #undef BUFFER_POS_REACHED_P
7470 /* If we scanned beyond to_pos and didn't find a point to wrap at,
7471 restore the saved iterator. */
7472 if (atpos_it.sp >= 0)
7473 *it = atpos_it;
7474 else if (atx_it.sp >= 0)
7475 *it = atx_it;
7477 done:
7479 /* Restore the iterator settings altered at the beginning of this
7480 function. */
7481 it->glyph_row = saved_glyph_row;
7482 return result;
7485 /* For external use. */
7486 void
7487 move_it_in_display_line (struct it *it,
7488 EMACS_INT to_charpos, int to_x,
7489 enum move_operation_enum op)
7491 if (it->line_wrap == WORD_WRAP
7492 && (op & MOVE_TO_X))
7494 struct it save_it = *it;
7495 int skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
7496 /* When word-wrap is on, TO_X may lie past the end
7497 of a wrapped line. Then it->current is the
7498 character on the next line, so backtrack to the
7499 space before the wrap point. */
7500 if (skip == MOVE_LINE_CONTINUED)
7502 int prev_x = max (it->current_x - 1, 0);
7503 *it = save_it;
7504 move_it_in_display_line_to
7505 (it, -1, prev_x, MOVE_TO_X);
7508 else
7509 move_it_in_display_line_to (it, to_charpos, to_x, op);
7513 /* Move IT forward until it satisfies one or more of the criteria in
7514 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
7516 OP is a bit-mask that specifies where to stop, and in particular,
7517 which of those four position arguments makes a difference. See the
7518 description of enum move_operation_enum.
7520 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
7521 screen line, this function will set IT to the next position >
7522 TO_CHARPOS. */
7524 void
7525 move_it_to (struct it *it, EMACS_INT to_charpos, int to_x, int to_y, int to_vpos, int op)
7527 enum move_it_result skip, skip2 = MOVE_X_REACHED;
7528 int line_height, line_start_x = 0, reached = 0;
7530 for (;;)
7532 if (op & MOVE_TO_VPOS)
7534 /* If no TO_CHARPOS and no TO_X specified, stop at the
7535 start of the line TO_VPOS. */
7536 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
7538 if (it->vpos == to_vpos)
7540 reached = 1;
7541 break;
7543 else
7544 skip = move_it_in_display_line_to (it, -1, -1, 0);
7546 else
7548 /* TO_VPOS >= 0 means stop at TO_X in the line at
7549 TO_VPOS, or at TO_POS, whichever comes first. */
7550 if (it->vpos == to_vpos)
7552 reached = 2;
7553 break;
7556 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
7558 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
7560 reached = 3;
7561 break;
7563 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
7565 /* We have reached TO_X but not in the line we want. */
7566 skip = move_it_in_display_line_to (it, to_charpos,
7567 -1, MOVE_TO_POS);
7568 if (skip == MOVE_POS_MATCH_OR_ZV)
7570 reached = 4;
7571 break;
7576 else if (op & MOVE_TO_Y)
7578 struct it it_backup;
7580 if (it->line_wrap == WORD_WRAP)
7581 it_backup = *it;
7583 /* TO_Y specified means stop at TO_X in the line containing
7584 TO_Y---or at TO_CHARPOS if this is reached first. The
7585 problem is that we can't really tell whether the line
7586 contains TO_Y before we have completely scanned it, and
7587 this may skip past TO_X. What we do is to first scan to
7588 TO_X.
7590 If TO_X is not specified, use a TO_X of zero. The reason
7591 is to make the outcome of this function more predictable.
7592 If we didn't use TO_X == 0, we would stop at the end of
7593 the line which is probably not what a caller would expect
7594 to happen. */
7595 skip = move_it_in_display_line_to
7596 (it, to_charpos, ((op & MOVE_TO_X) ? to_x : 0),
7597 (MOVE_TO_X | (op & MOVE_TO_POS)));
7599 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
7600 if (skip == MOVE_POS_MATCH_OR_ZV)
7601 reached = 5;
7602 else if (skip == MOVE_X_REACHED)
7604 /* If TO_X was reached, we want to know whether TO_Y is
7605 in the line. We know this is the case if the already
7606 scanned glyphs make the line tall enough. Otherwise,
7607 we must check by scanning the rest of the line. */
7608 line_height = it->max_ascent + it->max_descent;
7609 if (to_y >= it->current_y
7610 && to_y < it->current_y + line_height)
7612 reached = 6;
7613 break;
7615 it_backup = *it;
7616 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
7617 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
7618 op & MOVE_TO_POS);
7619 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
7620 line_height = it->max_ascent + it->max_descent;
7621 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
7623 if (to_y >= it->current_y
7624 && to_y < it->current_y + line_height)
7626 /* If TO_Y is in this line and TO_X was reached
7627 above, we scanned too far. We have to restore
7628 IT's settings to the ones before skipping. */
7629 *it = it_backup;
7630 reached = 6;
7632 else
7634 skip = skip2;
7635 if (skip == MOVE_POS_MATCH_OR_ZV)
7636 reached = 7;
7639 else
7641 /* Check whether TO_Y is in this line. */
7642 line_height = it->max_ascent + it->max_descent;
7643 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
7645 if (to_y >= it->current_y
7646 && to_y < it->current_y + line_height)
7648 /* When word-wrap is on, TO_X may lie past the end
7649 of a wrapped line. Then it->current is the
7650 character on the next line, so backtrack to the
7651 space before the wrap point. */
7652 if (skip == MOVE_LINE_CONTINUED
7653 && it->line_wrap == WORD_WRAP)
7655 int prev_x = max (it->current_x - 1, 0);
7656 *it = it_backup;
7657 skip = move_it_in_display_line_to
7658 (it, -1, prev_x, MOVE_TO_X);
7660 reached = 6;
7664 if (reached)
7665 break;
7667 else if (BUFFERP (it->object)
7668 && (it->method == GET_FROM_BUFFER
7669 || it->method == GET_FROM_STRETCH)
7670 && IT_CHARPOS (*it) >= to_charpos)
7671 skip = MOVE_POS_MATCH_OR_ZV;
7672 else
7673 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
7675 switch (skip)
7677 case MOVE_POS_MATCH_OR_ZV:
7678 reached = 8;
7679 goto out;
7681 case MOVE_NEWLINE_OR_CR:
7682 set_iterator_to_next (it, 1);
7683 it->continuation_lines_width = 0;
7684 break;
7686 case MOVE_LINE_TRUNCATED:
7687 it->continuation_lines_width = 0;
7688 reseat_at_next_visible_line_start (it, 0);
7689 if ((op & MOVE_TO_POS) != 0
7690 && IT_CHARPOS (*it) > to_charpos)
7692 reached = 9;
7693 goto out;
7695 break;
7697 case MOVE_LINE_CONTINUED:
7698 /* For continued lines ending in a tab, some of the glyphs
7699 associated with the tab are displayed on the current
7700 line. Since it->current_x does not include these glyphs,
7701 we use it->last_visible_x instead. */
7702 if (it->c == '\t')
7704 it->continuation_lines_width += it->last_visible_x;
7705 /* When moving by vpos, ensure that the iterator really
7706 advances to the next line (bug#847, bug#969). Fixme:
7707 do we need to do this in other circumstances? */
7708 if (it->current_x != it->last_visible_x
7709 && (op & MOVE_TO_VPOS)
7710 && !(op & (MOVE_TO_X | MOVE_TO_POS)))
7712 line_start_x = it->current_x + it->pixel_width
7713 - it->last_visible_x;
7714 set_iterator_to_next (it, 0);
7717 else
7718 it->continuation_lines_width += it->current_x;
7719 break;
7721 default:
7722 abort ();
7725 /* Reset/increment for the next run. */
7726 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
7727 it->current_x = line_start_x;
7728 line_start_x = 0;
7729 it->hpos = 0;
7730 it->current_y += it->max_ascent + it->max_descent;
7731 ++it->vpos;
7732 last_height = it->max_ascent + it->max_descent;
7733 last_max_ascent = it->max_ascent;
7734 it->max_ascent = it->max_descent = 0;
7737 out:
7739 /* On text terminals, we may stop at the end of a line in the middle
7740 of a multi-character glyph. If the glyph itself is continued,
7741 i.e. it is actually displayed on the next line, don't treat this
7742 stopping point as valid; move to the next line instead (unless
7743 that brings us offscreen). */
7744 if (!FRAME_WINDOW_P (it->f)
7745 && op & MOVE_TO_POS
7746 && IT_CHARPOS (*it) == to_charpos
7747 && it->what == IT_CHARACTER
7748 && it->nglyphs > 1
7749 && it->line_wrap == WINDOW_WRAP
7750 && it->current_x == it->last_visible_x - 1
7751 && it->c != '\n'
7752 && it->c != '\t'
7753 && it->vpos < XFASTINT (it->w->window_end_vpos))
7755 it->continuation_lines_width += it->current_x;
7756 it->current_x = it->hpos = it->max_ascent = it->max_descent = 0;
7757 it->current_y += it->max_ascent + it->max_descent;
7758 ++it->vpos;
7759 last_height = it->max_ascent + it->max_descent;
7760 last_max_ascent = it->max_ascent;
7763 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
7767 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
7769 If DY > 0, move IT backward at least that many pixels. DY = 0
7770 means move IT backward to the preceding line start or BEGV. This
7771 function may move over more than DY pixels if IT->current_y - DY
7772 ends up in the middle of a line; in this case IT->current_y will be
7773 set to the top of the line moved to. */
7775 void
7776 move_it_vertically_backward (struct it *it, int dy)
7778 int nlines, h;
7779 struct it it2, it3;
7780 EMACS_INT start_pos;
7782 move_further_back:
7783 xassert (dy >= 0);
7785 start_pos = IT_CHARPOS (*it);
7787 /* Estimate how many newlines we must move back. */
7788 nlines = max (1, dy / FRAME_LINE_HEIGHT (it->f));
7790 /* Set the iterator's position that many lines back. */
7791 while (nlines-- && IT_CHARPOS (*it) > BEGV)
7792 back_to_previous_visible_line_start (it);
7794 /* Reseat the iterator here. When moving backward, we don't want
7795 reseat to skip forward over invisible text, set up the iterator
7796 to deliver from overlay strings at the new position etc. So,
7797 use reseat_1 here. */
7798 reseat_1 (it, it->current.pos, 1);
7800 /* We are now surely at a line start. */
7801 it->current_x = it->hpos = 0;
7802 it->continuation_lines_width = 0;
7804 /* Move forward and see what y-distance we moved. First move to the
7805 start of the next line so that we get its height. We need this
7806 height to be able to tell whether we reached the specified
7807 y-distance. */
7808 it2 = *it;
7809 it2.max_ascent = it2.max_descent = 0;
7812 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
7813 MOVE_TO_POS | MOVE_TO_VPOS);
7815 while (!IT_POS_VALID_AFTER_MOVE_P (&it2));
7816 xassert (IT_CHARPOS (*it) >= BEGV);
7817 it3 = it2;
7819 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
7820 xassert (IT_CHARPOS (*it) >= BEGV);
7821 /* H is the actual vertical distance from the position in *IT
7822 and the starting position. */
7823 h = it2.current_y - it->current_y;
7824 /* NLINES is the distance in number of lines. */
7825 nlines = it2.vpos - it->vpos;
7827 /* Correct IT's y and vpos position
7828 so that they are relative to the starting point. */
7829 it->vpos -= nlines;
7830 it->current_y -= h;
7832 if (dy == 0)
7834 /* DY == 0 means move to the start of the screen line. The
7835 value of nlines is > 0 if continuation lines were involved. */
7836 if (nlines > 0)
7837 move_it_by_lines (it, nlines, 1);
7839 else
7841 /* The y-position we try to reach, relative to *IT.
7842 Note that H has been subtracted in front of the if-statement. */
7843 int target_y = it->current_y + h - dy;
7844 int y0 = it3.current_y;
7845 int y1 = line_bottom_y (&it3);
7846 int line_height = y1 - y0;
7848 /* If we did not reach target_y, try to move further backward if
7849 we can. If we moved too far backward, try to move forward. */
7850 if (target_y < it->current_y
7851 /* This is heuristic. In a window that's 3 lines high, with
7852 a line height of 13 pixels each, recentering with point
7853 on the bottom line will try to move -39/2 = 19 pixels
7854 backward. Try to avoid moving into the first line. */
7855 && (it->current_y - target_y
7856 > min (window_box_height (it->w), line_height * 2 / 3))
7857 && IT_CHARPOS (*it) > BEGV)
7859 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
7860 target_y - it->current_y));
7861 dy = it->current_y - target_y;
7862 goto move_further_back;
7864 else if (target_y >= it->current_y + line_height
7865 && IT_CHARPOS (*it) < ZV)
7867 /* Should move forward by at least one line, maybe more.
7869 Note: Calling move_it_by_lines can be expensive on
7870 terminal frames, where compute_motion is used (via
7871 vmotion) to do the job, when there are very long lines
7872 and truncate-lines is nil. That's the reason for
7873 treating terminal frames specially here. */
7875 if (!FRAME_WINDOW_P (it->f))
7876 move_it_vertically (it, target_y - (it->current_y + line_height));
7877 else
7881 move_it_by_lines (it, 1, 1);
7883 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
7890 /* Move IT by a specified amount of pixel lines DY. DY negative means
7891 move backwards. DY = 0 means move to start of screen line. At the
7892 end, IT will be on the start of a screen line. */
7894 void
7895 move_it_vertically (struct it *it, int dy)
7897 if (dy <= 0)
7898 move_it_vertically_backward (it, -dy);
7899 else
7901 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
7902 move_it_to (it, ZV, -1, it->current_y + dy, -1,
7903 MOVE_TO_POS | MOVE_TO_Y);
7904 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
7906 /* If buffer ends in ZV without a newline, move to the start of
7907 the line to satisfy the post-condition. */
7908 if (IT_CHARPOS (*it) == ZV
7909 && ZV > BEGV
7910 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
7911 move_it_by_lines (it, 0, 0);
7916 /* Move iterator IT past the end of the text line it is in. */
7918 void
7919 move_it_past_eol (struct it *it)
7921 enum move_it_result rc;
7923 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
7924 if (rc == MOVE_NEWLINE_OR_CR)
7925 set_iterator_to_next (it, 0);
7929 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
7930 negative means move up. DVPOS == 0 means move to the start of the
7931 screen line. NEED_Y_P non-zero means calculate IT->current_y. If
7932 NEED_Y_P is zero, IT->current_y will be left unchanged.
7934 Further optimization ideas: If we would know that IT->f doesn't use
7935 a face with proportional font, we could be faster for
7936 truncate-lines nil. */
7938 void
7939 move_it_by_lines (struct it *it, int dvpos, int need_y_p)
7942 /* The commented-out optimization uses vmotion on terminals. This
7943 gives bad results, because elements like it->what, on which
7944 callers such as pos_visible_p rely, aren't updated. */
7945 /* struct position pos;
7946 if (!FRAME_WINDOW_P (it->f))
7948 struct text_pos textpos;
7950 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
7951 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
7952 reseat (it, textpos, 1);
7953 it->vpos += pos.vpos;
7954 it->current_y += pos.vpos;
7956 else */
7958 if (dvpos == 0)
7960 /* DVPOS == 0 means move to the start of the screen line. */
7961 move_it_vertically_backward (it, 0);
7962 xassert (it->current_x == 0 && it->hpos == 0);
7963 /* Let next call to line_bottom_y calculate real line height */
7964 last_height = 0;
7966 else if (dvpos > 0)
7968 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
7969 if (!IT_POS_VALID_AFTER_MOVE_P (it))
7970 move_it_to (it, IT_CHARPOS (*it) + 1, -1, -1, -1, MOVE_TO_POS);
7972 else
7974 struct it it2;
7975 EMACS_INT start_charpos, i;
7977 /* Start at the beginning of the screen line containing IT's
7978 position. This may actually move vertically backwards,
7979 in case of overlays, so adjust dvpos accordingly. */
7980 dvpos += it->vpos;
7981 move_it_vertically_backward (it, 0);
7982 dvpos -= it->vpos;
7984 /* Go back -DVPOS visible lines and reseat the iterator there. */
7985 start_charpos = IT_CHARPOS (*it);
7986 for (i = -dvpos; i > 0 && IT_CHARPOS (*it) > BEGV; --i)
7987 back_to_previous_visible_line_start (it);
7988 reseat (it, it->current.pos, 1);
7990 /* Move further back if we end up in a string or an image. */
7991 while (!IT_POS_VALID_AFTER_MOVE_P (it))
7993 /* First try to move to start of display line. */
7994 dvpos += it->vpos;
7995 move_it_vertically_backward (it, 0);
7996 dvpos -= it->vpos;
7997 if (IT_POS_VALID_AFTER_MOVE_P (it))
7998 break;
7999 /* If start of line is still in string or image,
8000 move further back. */
8001 back_to_previous_visible_line_start (it);
8002 reseat (it, it->current.pos, 1);
8003 dvpos--;
8006 it->current_x = it->hpos = 0;
8008 /* Above call may have moved too far if continuation lines
8009 are involved. Scan forward and see if it did. */
8010 it2 = *it;
8011 it2.vpos = it2.current_y = 0;
8012 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
8013 it->vpos -= it2.vpos;
8014 it->current_y -= it2.current_y;
8015 it->current_x = it->hpos = 0;
8017 /* If we moved too far back, move IT some lines forward. */
8018 if (it2.vpos > -dvpos)
8020 int delta = it2.vpos + dvpos;
8021 it2 = *it;
8022 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
8023 /* Move back again if we got too far ahead. */
8024 if (IT_CHARPOS (*it) >= start_charpos)
8025 *it = it2;
8030 /* Return 1 if IT points into the middle of a display vector. */
8033 in_display_vector_p (struct it *it)
8035 return (it->method == GET_FROM_DISPLAY_VECTOR
8036 && it->current.dpvec_index > 0
8037 && it->dpvec + it->current.dpvec_index != it->dpend);
8041 /***********************************************************************
8042 Messages
8043 ***********************************************************************/
8046 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
8047 to *Messages*. */
8049 void
8050 add_to_log (const char *format, Lisp_Object arg1, Lisp_Object arg2)
8052 Lisp_Object args[3];
8053 Lisp_Object msg, fmt;
8054 char *buffer;
8055 EMACS_INT len;
8056 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
8057 USE_SAFE_ALLOCA;
8059 /* Do nothing if called asynchronously. Inserting text into
8060 a buffer may call after-change-functions and alike and
8061 that would means running Lisp asynchronously. */
8062 if (handling_signal)
8063 return;
8065 fmt = msg = Qnil;
8066 GCPRO4 (fmt, msg, arg1, arg2);
8068 args[0] = fmt = build_string (format);
8069 args[1] = arg1;
8070 args[2] = arg2;
8071 msg = Fformat (3, args);
8073 len = SBYTES (msg) + 1;
8074 SAFE_ALLOCA (buffer, char *, len);
8075 memcpy (buffer, SDATA (msg), len);
8077 message_dolog (buffer, len - 1, 1, 0);
8078 SAFE_FREE ();
8080 UNGCPRO;
8084 /* Output a newline in the *Messages* buffer if "needs" one. */
8086 void
8087 message_log_maybe_newline (void)
8089 if (message_log_need_newline)
8090 message_dolog ("", 0, 1, 0);
8094 /* Add a string M of length NBYTES to the message log, optionally
8095 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
8096 nonzero, means interpret the contents of M as multibyte. This
8097 function calls low-level routines in order to bypass text property
8098 hooks, etc. which might not be safe to run.
8100 This may GC (insert may run before/after change hooks),
8101 so the buffer M must NOT point to a Lisp string. */
8103 void
8104 message_dolog (const char *m, EMACS_INT nbytes, int nlflag, int multibyte)
8106 if (!NILP (Vmemory_full))
8107 return;
8109 if (!NILP (Vmessage_log_max))
8111 struct buffer *oldbuf;
8112 Lisp_Object oldpoint, oldbegv, oldzv;
8113 int old_windows_or_buffers_changed = windows_or_buffers_changed;
8114 EMACS_INT point_at_end = 0;
8115 EMACS_INT zv_at_end = 0;
8116 Lisp_Object old_deactivate_mark, tem;
8117 struct gcpro gcpro1;
8119 old_deactivate_mark = Vdeactivate_mark;
8120 oldbuf = current_buffer;
8121 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
8122 current_buffer->undo_list = Qt;
8124 oldpoint = message_dolog_marker1;
8125 set_marker_restricted (oldpoint, make_number (PT), Qnil);
8126 oldbegv = message_dolog_marker2;
8127 set_marker_restricted (oldbegv, make_number (BEGV), Qnil);
8128 oldzv = message_dolog_marker3;
8129 set_marker_restricted (oldzv, make_number (ZV), Qnil);
8130 GCPRO1 (old_deactivate_mark);
8132 if (PT == Z)
8133 point_at_end = 1;
8134 if (ZV == Z)
8135 zv_at_end = 1;
8137 BEGV = BEG;
8138 BEGV_BYTE = BEG_BYTE;
8139 ZV = Z;
8140 ZV_BYTE = Z_BYTE;
8141 TEMP_SET_PT_BOTH (Z, Z_BYTE);
8143 /* Insert the string--maybe converting multibyte to single byte
8144 or vice versa, so that all the text fits the buffer. */
8145 if (multibyte
8146 && NILP (current_buffer->enable_multibyte_characters))
8148 EMACS_INT i;
8149 int c, char_bytes;
8150 unsigned char work[1];
8152 /* Convert a multibyte string to single-byte
8153 for the *Message* buffer. */
8154 for (i = 0; i < nbytes; i += char_bytes)
8156 c = string_char_and_length (m + i, &char_bytes);
8157 work[0] = (ASCII_CHAR_P (c)
8159 : multibyte_char_to_unibyte (c, Qnil));
8160 insert_1_both (work, 1, 1, 1, 0, 0);
8163 else if (! multibyte
8164 && ! NILP (current_buffer->enable_multibyte_characters))
8166 EMACS_INT i;
8167 int c, char_bytes;
8168 unsigned char *msg = (unsigned char *) m;
8169 unsigned char str[MAX_MULTIBYTE_LENGTH];
8170 /* Convert a single-byte string to multibyte
8171 for the *Message* buffer. */
8172 for (i = 0; i < nbytes; i++)
8174 c = msg[i];
8175 MAKE_CHAR_MULTIBYTE (c);
8176 char_bytes = CHAR_STRING (c, str);
8177 insert_1_both (str, 1, char_bytes, 1, 0, 0);
8180 else if (nbytes)
8181 insert_1 (m, nbytes, 1, 0, 0);
8183 if (nlflag)
8185 EMACS_INT this_bol, this_bol_byte, prev_bol, prev_bol_byte;
8186 int dup;
8187 insert_1 ("\n", 1, 1, 0, 0);
8189 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
8190 this_bol = PT;
8191 this_bol_byte = PT_BYTE;
8193 /* See if this line duplicates the previous one.
8194 If so, combine duplicates. */
8195 if (this_bol > BEG)
8197 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
8198 prev_bol = PT;
8199 prev_bol_byte = PT_BYTE;
8201 dup = message_log_check_duplicate (prev_bol, prev_bol_byte,
8202 this_bol, this_bol_byte);
8203 if (dup)
8205 del_range_both (prev_bol, prev_bol_byte,
8206 this_bol, this_bol_byte, 0);
8207 if (dup > 1)
8209 char dupstr[40];
8210 int duplen;
8212 /* If you change this format, don't forget to also
8213 change message_log_check_duplicate. */
8214 sprintf (dupstr, " [%d times]", dup);
8215 duplen = strlen (dupstr);
8216 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
8217 insert_1 (dupstr, duplen, 1, 0, 1);
8222 /* If we have more than the desired maximum number of lines
8223 in the *Messages* buffer now, delete the oldest ones.
8224 This is safe because we don't have undo in this buffer. */
8226 if (NATNUMP (Vmessage_log_max))
8228 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
8229 -XFASTINT (Vmessage_log_max) - 1, 0);
8230 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
8233 BEGV = XMARKER (oldbegv)->charpos;
8234 BEGV_BYTE = marker_byte_position (oldbegv);
8236 if (zv_at_end)
8238 ZV = Z;
8239 ZV_BYTE = Z_BYTE;
8241 else
8243 ZV = XMARKER (oldzv)->charpos;
8244 ZV_BYTE = marker_byte_position (oldzv);
8247 if (point_at_end)
8248 TEMP_SET_PT_BOTH (Z, Z_BYTE);
8249 else
8250 /* We can't do Fgoto_char (oldpoint) because it will run some
8251 Lisp code. */
8252 TEMP_SET_PT_BOTH (XMARKER (oldpoint)->charpos,
8253 XMARKER (oldpoint)->bytepos);
8255 UNGCPRO;
8256 unchain_marker (XMARKER (oldpoint));
8257 unchain_marker (XMARKER (oldbegv));
8258 unchain_marker (XMARKER (oldzv));
8260 tem = Fget_buffer_window (Fcurrent_buffer (), Qt);
8261 set_buffer_internal (oldbuf);
8262 if (NILP (tem))
8263 windows_or_buffers_changed = old_windows_or_buffers_changed;
8264 message_log_need_newline = !nlflag;
8265 Vdeactivate_mark = old_deactivate_mark;
8270 /* We are at the end of the buffer after just having inserted a newline.
8271 (Note: We depend on the fact we won't be crossing the gap.)
8272 Check to see if the most recent message looks a lot like the previous one.
8273 Return 0 if different, 1 if the new one should just replace it, or a
8274 value N > 1 if we should also append " [N times]". */
8276 static int
8277 message_log_check_duplicate (EMACS_INT prev_bol, EMACS_INT prev_bol_byte,
8278 EMACS_INT this_bol, EMACS_INT this_bol_byte)
8280 EMACS_INT i;
8281 EMACS_INT len = Z_BYTE - 1 - this_bol_byte;
8282 int seen_dots = 0;
8283 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
8284 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
8286 for (i = 0; i < len; i++)
8288 if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.')
8289 seen_dots = 1;
8290 if (p1[i] != p2[i])
8291 return seen_dots;
8293 p1 += len;
8294 if (*p1 == '\n')
8295 return 2;
8296 if (*p1++ == ' ' && *p1++ == '[')
8298 int n = 0;
8299 while (*p1 >= '0' && *p1 <= '9')
8300 n = n * 10 + *p1++ - '0';
8301 if (strncmp (p1, " times]\n", 8) == 0)
8302 return n+1;
8304 return 0;
8308 /* Display an echo area message M with a specified length of NBYTES
8309 bytes. The string may include null characters. If M is 0, clear
8310 out any existing message, and let the mini-buffer text show
8311 through.
8313 This may GC, so the buffer M must NOT point to a Lisp string. */
8315 void
8316 message2 (const char *m, EMACS_INT nbytes, int multibyte)
8318 /* First flush out any partial line written with print. */
8319 message_log_maybe_newline ();
8320 if (m)
8321 message_dolog (m, nbytes, 1, multibyte);
8322 message2_nolog (m, nbytes, multibyte);
8326 /* The non-logging counterpart of message2. */
8328 void
8329 message2_nolog (const char *m, EMACS_INT nbytes, int multibyte)
8331 struct frame *sf = SELECTED_FRAME ();
8332 message_enable_multibyte = multibyte;
8334 if (FRAME_INITIAL_P (sf))
8336 if (noninteractive_need_newline)
8337 putc ('\n', stderr);
8338 noninteractive_need_newline = 0;
8339 if (m)
8340 fwrite (m, nbytes, 1, stderr);
8341 if (cursor_in_echo_area == 0)
8342 fprintf (stderr, "\n");
8343 fflush (stderr);
8345 /* A null message buffer means that the frame hasn't really been
8346 initialized yet. Error messages get reported properly by
8347 cmd_error, so this must be just an informative message; toss it. */
8348 else if (INTERACTIVE
8349 && sf->glyphs_initialized_p
8350 && FRAME_MESSAGE_BUF (sf))
8352 Lisp_Object mini_window;
8353 struct frame *f;
8355 /* Get the frame containing the mini-buffer
8356 that the selected frame is using. */
8357 mini_window = FRAME_MINIBUF_WINDOW (sf);
8358 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
8360 FRAME_SAMPLE_VISIBILITY (f);
8361 if (FRAME_VISIBLE_P (sf)
8362 && ! FRAME_VISIBLE_P (f))
8363 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
8365 if (m)
8367 set_message (m, Qnil, nbytes, multibyte);
8368 if (minibuffer_auto_raise)
8369 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
8371 else
8372 clear_message (1, 1);
8374 do_pending_window_change (0);
8375 echo_area_display (1);
8376 do_pending_window_change (0);
8377 if (FRAME_TERMINAL (f)->frame_up_to_date_hook != 0 && ! gc_in_progress)
8378 (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
8383 /* Display an echo area message M with a specified length of NBYTES
8384 bytes. The string may include null characters. If M is not a
8385 string, clear out any existing message, and let the mini-buffer
8386 text show through.
8388 This function cancels echoing. */
8390 void
8391 message3 (Lisp_Object m, EMACS_INT nbytes, int multibyte)
8393 struct gcpro gcpro1;
8395 GCPRO1 (m);
8396 clear_message (1,1);
8397 cancel_echoing ();
8399 /* First flush out any partial line written with print. */
8400 message_log_maybe_newline ();
8401 if (STRINGP (m))
8403 char *buffer;
8404 USE_SAFE_ALLOCA;
8406 SAFE_ALLOCA (buffer, char *, nbytes);
8407 memcpy (buffer, SDATA (m), nbytes);
8408 message_dolog (buffer, nbytes, 1, multibyte);
8409 SAFE_FREE ();
8411 message3_nolog (m, nbytes, multibyte);
8413 UNGCPRO;
8417 /* The non-logging version of message3.
8418 This does not cancel echoing, because it is used for echoing.
8419 Perhaps we need to make a separate function for echoing
8420 and make this cancel echoing. */
8422 void
8423 message3_nolog (Lisp_Object m, EMACS_INT nbytes, int multibyte)
8425 struct frame *sf = SELECTED_FRAME ();
8426 message_enable_multibyte = multibyte;
8428 if (FRAME_INITIAL_P (sf))
8430 if (noninteractive_need_newline)
8431 putc ('\n', stderr);
8432 noninteractive_need_newline = 0;
8433 if (STRINGP (m))
8434 fwrite (SDATA (m), nbytes, 1, stderr);
8435 if (cursor_in_echo_area == 0)
8436 fprintf (stderr, "\n");
8437 fflush (stderr);
8439 /* A null message buffer means that the frame hasn't really been
8440 initialized yet. Error messages get reported properly by
8441 cmd_error, so this must be just an informative message; toss it. */
8442 else if (INTERACTIVE
8443 && sf->glyphs_initialized_p
8444 && FRAME_MESSAGE_BUF (sf))
8446 Lisp_Object mini_window;
8447 Lisp_Object frame;
8448 struct frame *f;
8450 /* Get the frame containing the mini-buffer
8451 that the selected frame is using. */
8452 mini_window = FRAME_MINIBUF_WINDOW (sf);
8453 frame = XWINDOW (mini_window)->frame;
8454 f = XFRAME (frame);
8456 FRAME_SAMPLE_VISIBILITY (f);
8457 if (FRAME_VISIBLE_P (sf)
8458 && !FRAME_VISIBLE_P (f))
8459 Fmake_frame_visible (frame);
8461 if (STRINGP (m) && SCHARS (m) > 0)
8463 set_message (NULL, m, nbytes, multibyte);
8464 if (minibuffer_auto_raise)
8465 Fraise_frame (frame);
8466 /* Assume we are not echoing.
8467 (If we are, echo_now will override this.) */
8468 echo_message_buffer = Qnil;
8470 else
8471 clear_message (1, 1);
8473 do_pending_window_change (0);
8474 echo_area_display (1);
8475 do_pending_window_change (0);
8476 if (FRAME_TERMINAL (f)->frame_up_to_date_hook != 0 && ! gc_in_progress)
8477 (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
8482 /* Display a null-terminated echo area message M. If M is 0, clear
8483 out any existing message, and let the mini-buffer text show through.
8485 The buffer M must continue to exist until after the echo area gets
8486 cleared or some other message gets displayed there. Do not pass
8487 text that is stored in a Lisp string. Do not pass text in a buffer
8488 that was alloca'd. */
8490 void
8491 message1 (const char *m)
8493 message2 (m, (m ? strlen (m) : 0), 0);
8497 /* The non-logging counterpart of message1. */
8499 void
8500 message1_nolog (const char *m)
8502 message2_nolog (m, (m ? strlen (m) : 0), 0);
8505 /* Display a message M which contains a single %s
8506 which gets replaced with STRING. */
8508 void
8509 message_with_string (const char *m, Lisp_Object string, int log)
8511 CHECK_STRING (string);
8513 if (noninteractive)
8515 if (m)
8517 if (noninteractive_need_newline)
8518 putc ('\n', stderr);
8519 noninteractive_need_newline = 0;
8520 fprintf (stderr, m, SDATA (string));
8521 if (!cursor_in_echo_area)
8522 fprintf (stderr, "\n");
8523 fflush (stderr);
8526 else if (INTERACTIVE)
8528 /* The frame whose minibuffer we're going to display the message on.
8529 It may be larger than the selected frame, so we need
8530 to use its buffer, not the selected frame's buffer. */
8531 Lisp_Object mini_window;
8532 struct frame *f, *sf = SELECTED_FRAME ();
8534 /* Get the frame containing the minibuffer
8535 that the selected frame is using. */
8536 mini_window = FRAME_MINIBUF_WINDOW (sf);
8537 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
8539 /* A null message buffer means that the frame hasn't really been
8540 initialized yet. Error messages get reported properly by
8541 cmd_error, so this must be just an informative message; toss it. */
8542 if (FRAME_MESSAGE_BUF (f))
8544 Lisp_Object args[2], message;
8545 struct gcpro gcpro1, gcpro2;
8547 args[0] = build_string (m);
8548 args[1] = message = string;
8549 GCPRO2 (args[0], message);
8550 gcpro1.nvars = 2;
8552 message = Fformat (2, args);
8554 if (log)
8555 message3 (message, SBYTES (message), STRING_MULTIBYTE (message));
8556 else
8557 message3_nolog (message, SBYTES (message), STRING_MULTIBYTE (message));
8559 UNGCPRO;
8561 /* Print should start at the beginning of the message
8562 buffer next time. */
8563 message_buf_print = 0;
8569 /* Dump an informative message to the minibuf. If M is 0, clear out
8570 any existing message, and let the mini-buffer text show through. */
8572 static void
8573 vmessage (const char *m, va_list ap)
8575 if (noninteractive)
8577 if (m)
8579 if (noninteractive_need_newline)
8580 putc ('\n', stderr);
8581 noninteractive_need_newline = 0;
8582 vfprintf (stderr, m, ap);
8583 if (cursor_in_echo_area == 0)
8584 fprintf (stderr, "\n");
8585 fflush (stderr);
8588 else if (INTERACTIVE)
8590 /* The frame whose mini-buffer we're going to display the message
8591 on. It may be larger than the selected frame, so we need to
8592 use its buffer, not the selected frame's buffer. */
8593 Lisp_Object mini_window;
8594 struct frame *f, *sf = SELECTED_FRAME ();
8596 /* Get the frame containing the mini-buffer
8597 that the selected frame is using. */
8598 mini_window = FRAME_MINIBUF_WINDOW (sf);
8599 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
8601 /* A null message buffer means that the frame hasn't really been
8602 initialized yet. Error messages get reported properly by
8603 cmd_error, so this must be just an informative message; toss
8604 it. */
8605 if (FRAME_MESSAGE_BUF (f))
8607 if (m)
8609 EMACS_INT len;
8611 len = doprnt (FRAME_MESSAGE_BUF (f),
8612 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, ap);
8614 message2 (FRAME_MESSAGE_BUF (f), len, 0);
8616 else
8617 message1 (0);
8619 /* Print should start at the beginning of the message
8620 buffer next time. */
8621 message_buf_print = 0;
8626 void
8627 message (const char *m, ...)
8629 va_list ap;
8630 va_start (ap, m);
8631 vmessage (m, ap);
8632 va_end (ap);
8636 /* The non-logging version of message. */
8638 void
8639 message_nolog (const char *m, ...)
8641 Lisp_Object old_log_max;
8642 va_list ap;
8643 va_start (ap, m);
8644 old_log_max = Vmessage_log_max;
8645 Vmessage_log_max = Qnil;
8646 vmessage (m, ap);
8647 Vmessage_log_max = old_log_max;
8648 va_end (ap);
8652 /* Display the current message in the current mini-buffer. This is
8653 only called from error handlers in process.c, and is not time
8654 critical. */
8656 void
8657 update_echo_area (void)
8659 if (!NILP (echo_area_buffer[0]))
8661 Lisp_Object string;
8662 string = Fcurrent_message ();
8663 message3 (string, SBYTES (string),
8664 !NILP (current_buffer->enable_multibyte_characters));
8669 /* Make sure echo area buffers in `echo_buffers' are live.
8670 If they aren't, make new ones. */
8672 static void
8673 ensure_echo_area_buffers (void)
8675 int i;
8677 for (i = 0; i < 2; ++i)
8678 if (!BUFFERP (echo_buffer[i])
8679 || NILP (XBUFFER (echo_buffer[i])->name))
8681 char name[30];
8682 Lisp_Object old_buffer;
8683 int j;
8685 old_buffer = echo_buffer[i];
8686 sprintf (name, " *Echo Area %d*", i);
8687 echo_buffer[i] = Fget_buffer_create (build_string (name));
8688 XBUFFER (echo_buffer[i])->truncate_lines = Qnil;
8689 /* to force word wrap in echo area -
8690 it was decided to postpone this*/
8691 /* XBUFFER (echo_buffer[i])->word_wrap = Qt; */
8693 for (j = 0; j < 2; ++j)
8694 if (EQ (old_buffer, echo_area_buffer[j]))
8695 echo_area_buffer[j] = echo_buffer[i];
8700 /* Call FN with args A1..A4 with either the current or last displayed
8701 echo_area_buffer as current buffer.
8703 WHICH zero means use the current message buffer
8704 echo_area_buffer[0]. If that is nil, choose a suitable buffer
8705 from echo_buffer[] and clear it.
8707 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
8708 suitable buffer from echo_buffer[] and clear it.
8710 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
8711 that the current message becomes the last displayed one, make
8712 choose a suitable buffer for echo_area_buffer[0], and clear it.
8714 Value is what FN returns. */
8716 static int
8717 with_echo_area_buffer (struct window *w, int which,
8718 int (*fn) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
8719 EMACS_INT a1, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4)
8721 Lisp_Object buffer;
8722 int this_one, the_other, clear_buffer_p, rc;
8723 int count = SPECPDL_INDEX ();
8725 /* If buffers aren't live, make new ones. */
8726 ensure_echo_area_buffers ();
8728 clear_buffer_p = 0;
8730 if (which == 0)
8731 this_one = 0, the_other = 1;
8732 else if (which > 0)
8733 this_one = 1, the_other = 0;
8734 else
8736 this_one = 0, the_other = 1;
8737 clear_buffer_p = 1;
8739 /* We need a fresh one in case the current echo buffer equals
8740 the one containing the last displayed echo area message. */
8741 if (!NILP (echo_area_buffer[this_one])
8742 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
8743 echo_area_buffer[this_one] = Qnil;
8746 /* Choose a suitable buffer from echo_buffer[] is we don't
8747 have one. */
8748 if (NILP (echo_area_buffer[this_one]))
8750 echo_area_buffer[this_one]
8751 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
8752 ? echo_buffer[the_other]
8753 : echo_buffer[this_one]);
8754 clear_buffer_p = 1;
8757 buffer = echo_area_buffer[this_one];
8759 /* Don't get confused by reusing the buffer used for echoing
8760 for a different purpose. */
8761 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
8762 cancel_echoing ();
8764 record_unwind_protect (unwind_with_echo_area_buffer,
8765 with_echo_area_buffer_unwind_data (w));
8767 /* Make the echo area buffer current. Note that for display
8768 purposes, it is not necessary that the displayed window's buffer
8769 == current_buffer, except for text property lookup. So, let's
8770 only set that buffer temporarily here without doing a full
8771 Fset_window_buffer. We must also change w->pointm, though,
8772 because otherwise an assertions in unshow_buffer fails, and Emacs
8773 aborts. */
8774 set_buffer_internal_1 (XBUFFER (buffer));
8775 if (w)
8777 w->buffer = buffer;
8778 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
8781 current_buffer->undo_list = Qt;
8782 current_buffer->read_only = Qnil;
8783 specbind (Qinhibit_read_only, Qt);
8784 specbind (Qinhibit_modification_hooks, Qt);
8786 if (clear_buffer_p && Z > BEG)
8787 del_range (BEG, Z);
8789 xassert (BEGV >= BEG);
8790 xassert (ZV <= Z && ZV >= BEGV);
8792 rc = fn (a1, a2, a3, a4);
8794 xassert (BEGV >= BEG);
8795 xassert (ZV <= Z && ZV >= BEGV);
8797 unbind_to (count, Qnil);
8798 return rc;
8802 /* Save state that should be preserved around the call to the function
8803 FN called in with_echo_area_buffer. */
8805 static Lisp_Object
8806 with_echo_area_buffer_unwind_data (struct window *w)
8808 int i = 0;
8809 Lisp_Object vector, tmp;
8811 /* Reduce consing by keeping one vector in
8812 Vwith_echo_area_save_vector. */
8813 vector = Vwith_echo_area_save_vector;
8814 Vwith_echo_area_save_vector = Qnil;
8816 if (NILP (vector))
8817 vector = Fmake_vector (make_number (7), Qnil);
8819 XSETBUFFER (tmp, current_buffer); ASET (vector, i, tmp); ++i;
8820 ASET (vector, i, Vdeactivate_mark); ++i;
8821 ASET (vector, i, make_number (windows_or_buffers_changed)); ++i;
8823 if (w)
8825 XSETWINDOW (tmp, w); ASET (vector, i, tmp); ++i;
8826 ASET (vector, i, w->buffer); ++i;
8827 ASET (vector, i, make_number (XMARKER (w->pointm)->charpos)); ++i;
8828 ASET (vector, i, make_number (XMARKER (w->pointm)->bytepos)); ++i;
8830 else
8832 int end = i + 4;
8833 for (; i < end; ++i)
8834 ASET (vector, i, Qnil);
8837 xassert (i == ASIZE (vector));
8838 return vector;
8842 /* Restore global state from VECTOR which was created by
8843 with_echo_area_buffer_unwind_data. */
8845 static Lisp_Object
8846 unwind_with_echo_area_buffer (Lisp_Object vector)
8848 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
8849 Vdeactivate_mark = AREF (vector, 1);
8850 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
8852 if (WINDOWP (AREF (vector, 3)))
8854 struct window *w;
8855 Lisp_Object buffer, charpos, bytepos;
8857 w = XWINDOW (AREF (vector, 3));
8858 buffer = AREF (vector, 4);
8859 charpos = AREF (vector, 5);
8860 bytepos = AREF (vector, 6);
8862 w->buffer = buffer;
8863 set_marker_both (w->pointm, buffer,
8864 XFASTINT (charpos), XFASTINT (bytepos));
8867 Vwith_echo_area_save_vector = vector;
8868 return Qnil;
8872 /* Set up the echo area for use by print functions. MULTIBYTE_P
8873 non-zero means we will print multibyte. */
8875 void
8876 setup_echo_area_for_printing (int multibyte_p)
8878 /* If we can't find an echo area any more, exit. */
8879 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
8880 Fkill_emacs (Qnil);
8882 ensure_echo_area_buffers ();
8884 if (!message_buf_print)
8886 /* A message has been output since the last time we printed.
8887 Choose a fresh echo area buffer. */
8888 if (EQ (echo_area_buffer[1], echo_buffer[0]))
8889 echo_area_buffer[0] = echo_buffer[1];
8890 else
8891 echo_area_buffer[0] = echo_buffer[0];
8893 /* Switch to that buffer and clear it. */
8894 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
8895 current_buffer->truncate_lines = Qnil;
8897 if (Z > BEG)
8899 int count = SPECPDL_INDEX ();
8900 specbind (Qinhibit_read_only, Qt);
8901 /* Note that undo recording is always disabled. */
8902 del_range (BEG, Z);
8903 unbind_to (count, Qnil);
8905 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
8907 /* Set up the buffer for the multibyteness we need. */
8908 if (multibyte_p
8909 != !NILP (current_buffer->enable_multibyte_characters))
8910 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
8912 /* Raise the frame containing the echo area. */
8913 if (minibuffer_auto_raise)
8915 struct frame *sf = SELECTED_FRAME ();
8916 Lisp_Object mini_window;
8917 mini_window = FRAME_MINIBUF_WINDOW (sf);
8918 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
8921 message_log_maybe_newline ();
8922 message_buf_print = 1;
8924 else
8926 if (NILP (echo_area_buffer[0]))
8928 if (EQ (echo_area_buffer[1], echo_buffer[0]))
8929 echo_area_buffer[0] = echo_buffer[1];
8930 else
8931 echo_area_buffer[0] = echo_buffer[0];
8934 if (current_buffer != XBUFFER (echo_area_buffer[0]))
8936 /* Someone switched buffers between print requests. */
8937 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
8938 current_buffer->truncate_lines = Qnil;
8944 /* Display an echo area message in window W. Value is non-zero if W's
8945 height is changed. If display_last_displayed_message_p is
8946 non-zero, display the message that was last displayed, otherwise
8947 display the current message. */
8949 static int
8950 display_echo_area (struct window *w)
8952 int i, no_message_p, window_height_changed_p, count;
8954 /* Temporarily disable garbage collections while displaying the echo
8955 area. This is done because a GC can print a message itself.
8956 That message would modify the echo area buffer's contents while a
8957 redisplay of the buffer is going on, and seriously confuse
8958 redisplay. */
8959 count = inhibit_garbage_collection ();
8961 /* If there is no message, we must call display_echo_area_1
8962 nevertheless because it resizes the window. But we will have to
8963 reset the echo_area_buffer in question to nil at the end because
8964 with_echo_area_buffer will sets it to an empty buffer. */
8965 i = display_last_displayed_message_p ? 1 : 0;
8966 no_message_p = NILP (echo_area_buffer[i]);
8968 window_height_changed_p
8969 = with_echo_area_buffer (w, display_last_displayed_message_p,
8970 display_echo_area_1,
8971 (EMACS_INT) w, Qnil, 0, 0);
8973 if (no_message_p)
8974 echo_area_buffer[i] = Qnil;
8976 unbind_to (count, Qnil);
8977 return window_height_changed_p;
8981 /* Helper for display_echo_area. Display the current buffer which
8982 contains the current echo area message in window W, a mini-window,
8983 a pointer to which is passed in A1. A2..A4 are currently not used.
8984 Change the height of W so that all of the message is displayed.
8985 Value is non-zero if height of W was changed. */
8987 static int
8988 display_echo_area_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4)
8990 struct window *w = (struct window *) a1;
8991 Lisp_Object window;
8992 struct text_pos start;
8993 int window_height_changed_p = 0;
8995 /* Do this before displaying, so that we have a large enough glyph
8996 matrix for the display. If we can't get enough space for the
8997 whole text, display the last N lines. That works by setting w->start. */
8998 window_height_changed_p = resize_mini_window (w, 0);
9000 /* Use the starting position chosen by resize_mini_window. */
9001 SET_TEXT_POS_FROM_MARKER (start, w->start);
9003 /* Display. */
9004 clear_glyph_matrix (w->desired_matrix);
9005 XSETWINDOW (window, w);
9006 try_window (window, start, 0);
9008 return window_height_changed_p;
9012 /* Resize the echo area window to exactly the size needed for the
9013 currently displayed message, if there is one. If a mini-buffer
9014 is active, don't shrink it. */
9016 void
9017 resize_echo_area_exactly (void)
9019 if (BUFFERP (echo_area_buffer[0])
9020 && WINDOWP (echo_area_window))
9022 struct window *w = XWINDOW (echo_area_window);
9023 int resized_p;
9024 Lisp_Object resize_exactly;
9026 if (minibuf_level == 0)
9027 resize_exactly = Qt;
9028 else
9029 resize_exactly = Qnil;
9031 resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
9032 (EMACS_INT) w, resize_exactly, 0, 0);
9033 if (resized_p)
9035 ++windows_or_buffers_changed;
9036 ++update_mode_lines;
9037 redisplay_internal (0);
9043 /* Callback function for with_echo_area_buffer, when used from
9044 resize_echo_area_exactly. A1 contains a pointer to the window to
9045 resize, EXACTLY non-nil means resize the mini-window exactly to the
9046 size of the text displayed. A3 and A4 are not used. Value is what
9047 resize_mini_window returns. */
9049 static int
9050 resize_mini_window_1 (EMACS_INT a1, Lisp_Object exactly, EMACS_INT a3, EMACS_INT a4)
9052 return resize_mini_window ((struct window *) a1, !NILP (exactly));
9056 /* Resize mini-window W to fit the size of its contents. EXACT_P
9057 means size the window exactly to the size needed. Otherwise, it's
9058 only enlarged until W's buffer is empty.
9060 Set W->start to the right place to begin display. If the whole
9061 contents fit, start at the beginning. Otherwise, start so as
9062 to make the end of the contents appear. This is particularly
9063 important for y-or-n-p, but seems desirable generally.
9065 Value is non-zero if the window height has been changed. */
9068 resize_mini_window (struct window *w, int exact_p)
9070 struct frame *f = XFRAME (w->frame);
9071 int window_height_changed_p = 0;
9073 xassert (MINI_WINDOW_P (w));
9075 /* By default, start display at the beginning. */
9076 set_marker_both (w->start, w->buffer,
9077 BUF_BEGV (XBUFFER (w->buffer)),
9078 BUF_BEGV_BYTE (XBUFFER (w->buffer)));
9080 /* Don't resize windows while redisplaying a window; it would
9081 confuse redisplay functions when the size of the window they are
9082 displaying changes from under them. Such a resizing can happen,
9083 for instance, when which-func prints a long message while
9084 we are running fontification-functions. We're running these
9085 functions with safe_call which binds inhibit-redisplay to t. */
9086 if (!NILP (Vinhibit_redisplay))
9087 return 0;
9089 /* Nil means don't try to resize. */
9090 if (NILP (Vresize_mini_windows)
9091 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
9092 return 0;
9094 if (!FRAME_MINIBUF_ONLY_P (f))
9096 struct it it;
9097 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
9098 int total_height = WINDOW_TOTAL_LINES (root) + WINDOW_TOTAL_LINES (w);
9099 int height, max_height;
9100 int unit = FRAME_LINE_HEIGHT (f);
9101 struct text_pos start;
9102 struct buffer *old_current_buffer = NULL;
9104 if (current_buffer != XBUFFER (w->buffer))
9106 old_current_buffer = current_buffer;
9107 set_buffer_internal (XBUFFER (w->buffer));
9110 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
9112 /* Compute the max. number of lines specified by the user. */
9113 if (FLOATP (Vmax_mini_window_height))
9114 max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_LINES (f);
9115 else if (INTEGERP (Vmax_mini_window_height))
9116 max_height = XINT (Vmax_mini_window_height);
9117 else
9118 max_height = total_height / 4;
9120 /* Correct that max. height if it's bogus. */
9121 max_height = max (1, max_height);
9122 max_height = min (total_height, max_height);
9124 /* Find out the height of the text in the window. */
9125 if (it.line_wrap == TRUNCATE)
9126 height = 1;
9127 else
9129 last_height = 0;
9130 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
9131 if (it.max_ascent == 0 && it.max_descent == 0)
9132 height = it.current_y + last_height;
9133 else
9134 height = it.current_y + it.max_ascent + it.max_descent;
9135 height -= min (it.extra_line_spacing, it.max_extra_line_spacing);
9136 height = (height + unit - 1) / unit;
9139 /* Compute a suitable window start. */
9140 if (height > max_height)
9142 height = max_height;
9143 init_iterator (&it, w, ZV, ZV_BYTE, NULL, DEFAULT_FACE_ID);
9144 move_it_vertically_backward (&it, (height - 1) * unit);
9145 start = it.current.pos;
9147 else
9148 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
9149 SET_MARKER_FROM_TEXT_POS (w->start, start);
9151 if (EQ (Vresize_mini_windows, Qgrow_only))
9153 /* Let it grow only, until we display an empty message, in which
9154 case the window shrinks again. */
9155 if (height > WINDOW_TOTAL_LINES (w))
9157 int old_height = WINDOW_TOTAL_LINES (w);
9158 freeze_window_starts (f, 1);
9159 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
9160 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
9162 else if (height < WINDOW_TOTAL_LINES (w)
9163 && (exact_p || BEGV == ZV))
9165 int old_height = WINDOW_TOTAL_LINES (w);
9166 freeze_window_starts (f, 0);
9167 shrink_mini_window (w);
9168 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
9171 else
9173 /* Always resize to exact size needed. */
9174 if (height > WINDOW_TOTAL_LINES (w))
9176 int old_height = WINDOW_TOTAL_LINES (w);
9177 freeze_window_starts (f, 1);
9178 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
9179 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
9181 else if (height < WINDOW_TOTAL_LINES (w))
9183 int old_height = WINDOW_TOTAL_LINES (w);
9184 freeze_window_starts (f, 0);
9185 shrink_mini_window (w);
9187 if (height)
9189 freeze_window_starts (f, 1);
9190 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
9193 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
9197 if (old_current_buffer)
9198 set_buffer_internal (old_current_buffer);
9201 return window_height_changed_p;
9205 /* Value is the current message, a string, or nil if there is no
9206 current message. */
9208 Lisp_Object
9209 current_message (void)
9211 Lisp_Object msg;
9213 if (!BUFFERP (echo_area_buffer[0]))
9214 msg = Qnil;
9215 else
9217 with_echo_area_buffer (0, 0, current_message_1,
9218 (EMACS_INT) &msg, Qnil, 0, 0);
9219 if (NILP (msg))
9220 echo_area_buffer[0] = Qnil;
9223 return msg;
9227 static int
9228 current_message_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4)
9230 Lisp_Object *msg = (Lisp_Object *) a1;
9232 if (Z > BEG)
9233 *msg = make_buffer_string (BEG, Z, 1);
9234 else
9235 *msg = Qnil;
9236 return 0;
9240 /* Push the current message on Vmessage_stack for later restauration
9241 by restore_message. Value is non-zero if the current message isn't
9242 empty. This is a relatively infrequent operation, so it's not
9243 worth optimizing. */
9246 push_message (void)
9248 Lisp_Object msg;
9249 msg = current_message ();
9250 Vmessage_stack = Fcons (msg, Vmessage_stack);
9251 return STRINGP (msg);
9255 /* Restore message display from the top of Vmessage_stack. */
9257 void
9258 restore_message (void)
9260 Lisp_Object msg;
9262 xassert (CONSP (Vmessage_stack));
9263 msg = XCAR (Vmessage_stack);
9264 if (STRINGP (msg))
9265 message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
9266 else
9267 message3_nolog (msg, 0, 0);
9271 /* Handler for record_unwind_protect calling pop_message. */
9273 Lisp_Object
9274 pop_message_unwind (Lisp_Object dummy)
9276 pop_message ();
9277 return Qnil;
9280 /* Pop the top-most entry off Vmessage_stack. */
9282 void
9283 pop_message (void)
9285 xassert (CONSP (Vmessage_stack));
9286 Vmessage_stack = XCDR (Vmessage_stack);
9290 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
9291 exits. If the stack is not empty, we have a missing pop_message
9292 somewhere. */
9294 void
9295 check_message_stack (void)
9297 if (!NILP (Vmessage_stack))
9298 abort ();
9302 /* Truncate to NCHARS what will be displayed in the echo area the next
9303 time we display it---but don't redisplay it now. */
9305 void
9306 truncate_echo_area (EMACS_INT nchars)
9308 if (nchars == 0)
9309 echo_area_buffer[0] = Qnil;
9310 /* A null message buffer means that the frame hasn't really been
9311 initialized yet. Error messages get reported properly by
9312 cmd_error, so this must be just an informative message; toss it. */
9313 else if (!noninteractive
9314 && INTERACTIVE
9315 && !NILP (echo_area_buffer[0]))
9317 struct frame *sf = SELECTED_FRAME ();
9318 if (FRAME_MESSAGE_BUF (sf))
9319 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil, 0, 0);
9324 /* Helper function for truncate_echo_area. Truncate the current
9325 message to at most NCHARS characters. */
9327 static int
9328 truncate_message_1 (EMACS_INT nchars, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4)
9330 if (BEG + nchars < Z)
9331 del_range (BEG + nchars, Z);
9332 if (Z == BEG)
9333 echo_area_buffer[0] = Qnil;
9334 return 0;
9338 /* Set the current message to a substring of S or STRING.
9340 If STRING is a Lisp string, set the message to the first NBYTES
9341 bytes from STRING. NBYTES zero means use the whole string. If
9342 STRING is multibyte, the message will be displayed multibyte.
9344 If S is not null, set the message to the first LEN bytes of S. LEN
9345 zero means use the whole string. MULTIBYTE_P non-zero means S is
9346 multibyte. Display the message multibyte in that case.
9348 Doesn't GC, as with_echo_area_buffer binds Qinhibit_modification_hooks
9349 to t before calling set_message_1 (which calls insert).
9352 void
9353 set_message (const char *s, Lisp_Object string,
9354 EMACS_INT nbytes, int multibyte_p)
9356 message_enable_multibyte
9357 = ((s && multibyte_p)
9358 || (STRINGP (string) && STRING_MULTIBYTE (string)));
9360 with_echo_area_buffer (0, -1, set_message_1,
9361 (EMACS_INT) s, string, nbytes, multibyte_p);
9362 message_buf_print = 0;
9363 help_echo_showing_p = 0;
9367 /* Helper function for set_message. Arguments have the same meaning
9368 as there, with A1 corresponding to S and A2 corresponding to STRING
9369 This function is called with the echo area buffer being
9370 current. */
9372 static int
9373 set_message_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT nbytes, EMACS_INT multibyte_p)
9375 const char *s = (const char *) a1;
9376 Lisp_Object string = a2;
9378 /* Change multibyteness of the echo buffer appropriately. */
9379 if (message_enable_multibyte
9380 != !NILP (current_buffer->enable_multibyte_characters))
9381 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
9383 current_buffer->truncate_lines = message_truncate_lines ? Qt : Qnil;
9384 if (!NILP (current_buffer->bidi_display_reordering))
9385 current_buffer->bidi_paragraph_direction = Qleft_to_right;
9387 /* Insert new message at BEG. */
9388 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
9390 if (STRINGP (string))
9392 EMACS_INT nchars;
9394 if (nbytes == 0)
9395 nbytes = SBYTES (string);
9396 nchars = string_byte_to_char (string, nbytes);
9398 /* This function takes care of single/multibyte conversion. We
9399 just have to ensure that the echo area buffer has the right
9400 setting of enable_multibyte_characters. */
9401 insert_from_string (string, 0, 0, nchars, nbytes, 1);
9403 else if (s)
9405 if (nbytes == 0)
9406 nbytes = strlen (s);
9408 if (multibyte_p && NILP (current_buffer->enable_multibyte_characters))
9410 /* Convert from multi-byte to single-byte. */
9411 EMACS_INT i;
9412 int c, n;
9413 unsigned char work[1];
9415 /* Convert a multibyte string to single-byte. */
9416 for (i = 0; i < nbytes; i += n)
9418 c = string_char_and_length (s + i, &n);
9419 work[0] = (ASCII_CHAR_P (c)
9421 : multibyte_char_to_unibyte (c, Qnil));
9422 insert_1_both (work, 1, 1, 1, 0, 0);
9425 else if (!multibyte_p
9426 && !NILP (current_buffer->enable_multibyte_characters))
9428 /* Convert from single-byte to multi-byte. */
9429 EMACS_INT i;
9430 int c, n;
9431 const unsigned char *msg = (const unsigned char *) s;
9432 unsigned char str[MAX_MULTIBYTE_LENGTH];
9434 /* Convert a single-byte string to multibyte. */
9435 for (i = 0; i < nbytes; i++)
9437 c = msg[i];
9438 MAKE_CHAR_MULTIBYTE (c);
9439 n = CHAR_STRING (c, str);
9440 insert_1_both (str, 1, n, 1, 0, 0);
9443 else
9444 insert_1 (s, nbytes, 1, 0, 0);
9447 return 0;
9451 /* Clear messages. CURRENT_P non-zero means clear the current
9452 message. LAST_DISPLAYED_P non-zero means clear the message
9453 last displayed. */
9455 void
9456 clear_message (int current_p, int last_displayed_p)
9458 if (current_p)
9460 echo_area_buffer[0] = Qnil;
9461 message_cleared_p = 1;
9464 if (last_displayed_p)
9465 echo_area_buffer[1] = Qnil;
9467 message_buf_print = 0;
9470 /* Clear garbaged frames.
9472 This function is used where the old redisplay called
9473 redraw_garbaged_frames which in turn called redraw_frame which in
9474 turn called clear_frame. The call to clear_frame was a source of
9475 flickering. I believe a clear_frame is not necessary. It should
9476 suffice in the new redisplay to invalidate all current matrices,
9477 and ensure a complete redisplay of all windows. */
9479 static void
9480 clear_garbaged_frames (void)
9482 if (frame_garbaged)
9484 Lisp_Object tail, frame;
9485 int changed_count = 0;
9487 FOR_EACH_FRAME (tail, frame)
9489 struct frame *f = XFRAME (frame);
9491 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
9493 if (f->resized_p)
9495 Fredraw_frame (frame);
9496 f->force_flush_display_p = 1;
9498 clear_current_matrices (f);
9499 changed_count++;
9500 f->garbaged = 0;
9501 f->resized_p = 0;
9505 frame_garbaged = 0;
9506 if (changed_count)
9507 ++windows_or_buffers_changed;
9512 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
9513 is non-zero update selected_frame. Value is non-zero if the
9514 mini-windows height has been changed. */
9516 static int
9517 echo_area_display (int update_frame_p)
9519 Lisp_Object mini_window;
9520 struct window *w;
9521 struct frame *f;
9522 int window_height_changed_p = 0;
9523 struct frame *sf = SELECTED_FRAME ();
9525 mini_window = FRAME_MINIBUF_WINDOW (sf);
9526 w = XWINDOW (mini_window);
9527 f = XFRAME (WINDOW_FRAME (w));
9529 /* Don't display if frame is invisible or not yet initialized. */
9530 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
9531 return 0;
9533 #ifdef HAVE_WINDOW_SYSTEM
9534 /* When Emacs starts, selected_frame may be the initial terminal
9535 frame. If we let this through, a message would be displayed on
9536 the terminal. */
9537 if (FRAME_INITIAL_P (XFRAME (selected_frame)))
9538 return 0;
9539 #endif /* HAVE_WINDOW_SYSTEM */
9541 /* Redraw garbaged frames. */
9542 if (frame_garbaged)
9543 clear_garbaged_frames ();
9545 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
9547 echo_area_window = mini_window;
9548 window_height_changed_p = display_echo_area (w);
9549 w->must_be_updated_p = 1;
9551 /* Update the display, unless called from redisplay_internal.
9552 Also don't update the screen during redisplay itself. The
9553 update will happen at the end of redisplay, and an update
9554 here could cause confusion. */
9555 if (update_frame_p && !redisplaying_p)
9557 int n = 0;
9559 /* If the display update has been interrupted by pending
9560 input, update mode lines in the frame. Due to the
9561 pending input, it might have been that redisplay hasn't
9562 been called, so that mode lines above the echo area are
9563 garbaged. This looks odd, so we prevent it here. */
9564 if (!display_completed)
9565 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), 0);
9567 if (window_height_changed_p
9568 /* Don't do this if Emacs is shutting down. Redisplay
9569 needs to run hooks. */
9570 && !NILP (Vrun_hooks))
9572 /* Must update other windows. Likewise as in other
9573 cases, don't let this update be interrupted by
9574 pending input. */
9575 int count = SPECPDL_INDEX ();
9576 specbind (Qredisplay_dont_pause, Qt);
9577 windows_or_buffers_changed = 1;
9578 redisplay_internal (0);
9579 unbind_to (count, Qnil);
9581 else if (FRAME_WINDOW_P (f) && n == 0)
9583 /* Window configuration is the same as before.
9584 Can do with a display update of the echo area,
9585 unless we displayed some mode lines. */
9586 update_single_window (w, 1);
9587 FRAME_RIF (f)->flush_display (f);
9589 else
9590 update_frame (f, 1, 1);
9592 /* If cursor is in the echo area, make sure that the next
9593 redisplay displays the minibuffer, so that the cursor will
9594 be replaced with what the minibuffer wants. */
9595 if (cursor_in_echo_area)
9596 ++windows_or_buffers_changed;
9599 else if (!EQ (mini_window, selected_window))
9600 windows_or_buffers_changed++;
9602 /* Last displayed message is now the current message. */
9603 echo_area_buffer[1] = echo_area_buffer[0];
9604 /* Inform read_char that we're not echoing. */
9605 echo_message_buffer = Qnil;
9607 /* Prevent redisplay optimization in redisplay_internal by resetting
9608 this_line_start_pos. This is done because the mini-buffer now
9609 displays the message instead of its buffer text. */
9610 if (EQ (mini_window, selected_window))
9611 CHARPOS (this_line_start_pos) = 0;
9613 return window_height_changed_p;
9618 /***********************************************************************
9619 Mode Lines and Frame Titles
9620 ***********************************************************************/
9622 /* A buffer for constructing non-propertized mode-line strings and
9623 frame titles in it; allocated from the heap in init_xdisp and
9624 resized as needed in store_mode_line_noprop_char. */
9626 static char *mode_line_noprop_buf;
9628 /* The buffer's end, and a current output position in it. */
9630 static char *mode_line_noprop_buf_end;
9631 static char *mode_line_noprop_ptr;
9633 #define MODE_LINE_NOPROP_LEN(start) \
9634 ((mode_line_noprop_ptr - mode_line_noprop_buf) - start)
9636 static enum {
9637 MODE_LINE_DISPLAY = 0,
9638 MODE_LINE_TITLE,
9639 MODE_LINE_NOPROP,
9640 MODE_LINE_STRING
9641 } mode_line_target;
9643 /* Alist that caches the results of :propertize.
9644 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
9645 static Lisp_Object mode_line_proptrans_alist;
9647 /* List of strings making up the mode-line. */
9648 static Lisp_Object mode_line_string_list;
9650 /* Base face property when building propertized mode line string. */
9651 static Lisp_Object mode_line_string_face;
9652 static Lisp_Object mode_line_string_face_prop;
9655 /* Unwind data for mode line strings */
9657 static Lisp_Object Vmode_line_unwind_vector;
9659 static Lisp_Object
9660 format_mode_line_unwind_data (struct buffer *obuf,
9661 Lisp_Object owin,
9662 int save_proptrans)
9664 Lisp_Object vector, tmp;
9666 /* Reduce consing by keeping one vector in
9667 Vwith_echo_area_save_vector. */
9668 vector = Vmode_line_unwind_vector;
9669 Vmode_line_unwind_vector = Qnil;
9671 if (NILP (vector))
9672 vector = Fmake_vector (make_number (8), Qnil);
9674 ASET (vector, 0, make_number (mode_line_target));
9675 ASET (vector, 1, make_number (MODE_LINE_NOPROP_LEN (0)));
9676 ASET (vector, 2, mode_line_string_list);
9677 ASET (vector, 3, save_proptrans ? mode_line_proptrans_alist : Qt);
9678 ASET (vector, 4, mode_line_string_face);
9679 ASET (vector, 5, mode_line_string_face_prop);
9681 if (obuf)
9682 XSETBUFFER (tmp, obuf);
9683 else
9684 tmp = Qnil;
9685 ASET (vector, 6, tmp);
9686 ASET (vector, 7, owin);
9688 return vector;
9691 static Lisp_Object
9692 unwind_format_mode_line (Lisp_Object vector)
9694 mode_line_target = XINT (AREF (vector, 0));
9695 mode_line_noprop_ptr = mode_line_noprop_buf + XINT (AREF (vector, 1));
9696 mode_line_string_list = AREF (vector, 2);
9697 if (! EQ (AREF (vector, 3), Qt))
9698 mode_line_proptrans_alist = AREF (vector, 3);
9699 mode_line_string_face = AREF (vector, 4);
9700 mode_line_string_face_prop = AREF (vector, 5);
9702 if (!NILP (AREF (vector, 7)))
9703 /* Select window before buffer, since it may change the buffer. */
9704 Fselect_window (AREF (vector, 7), Qt);
9706 if (!NILP (AREF (vector, 6)))
9708 set_buffer_internal_1 (XBUFFER (AREF (vector, 6)));
9709 ASET (vector, 6, Qnil);
9712 Vmode_line_unwind_vector = vector;
9713 return Qnil;
9717 /* Store a single character C for the frame title in mode_line_noprop_buf.
9718 Re-allocate mode_line_noprop_buf if necessary. */
9720 static void
9721 store_mode_line_noprop_char (char c)
9723 /* If output position has reached the end of the allocated buffer,
9724 double the buffer's size. */
9725 if (mode_line_noprop_ptr == mode_line_noprop_buf_end)
9727 int len = MODE_LINE_NOPROP_LEN (0);
9728 int new_size = 2 * len * sizeof *mode_line_noprop_buf;
9729 mode_line_noprop_buf = (char *) xrealloc (mode_line_noprop_buf, new_size);
9730 mode_line_noprop_buf_end = mode_line_noprop_buf + new_size;
9731 mode_line_noprop_ptr = mode_line_noprop_buf + len;
9734 *mode_line_noprop_ptr++ = c;
9738 /* Store part of a frame title in mode_line_noprop_buf, beginning at
9739 mode_line_noprop_ptr. STR is the string to store. Do not copy
9740 characters that yield more columns than PRECISION; PRECISION <= 0
9741 means copy the whole string. Pad with spaces until FIELD_WIDTH
9742 number of characters have been copied; FIELD_WIDTH <= 0 means don't
9743 pad. Called from display_mode_element when it is used to build a
9744 frame title. */
9746 static int
9747 store_mode_line_noprop (const unsigned char *str, int field_width, int precision)
9749 int n = 0;
9750 EMACS_INT dummy, nbytes;
9752 /* Copy at most PRECISION chars from STR. */
9753 nbytes = strlen (str);
9754 n += c_string_width (str, nbytes, precision, &dummy, &nbytes);
9755 while (nbytes--)
9756 store_mode_line_noprop_char (*str++);
9758 /* Fill up with spaces until FIELD_WIDTH reached. */
9759 while (field_width > 0
9760 && n < field_width)
9762 store_mode_line_noprop_char (' ');
9763 ++n;
9766 return n;
9769 /***********************************************************************
9770 Frame Titles
9771 ***********************************************************************/
9773 #ifdef HAVE_WINDOW_SYSTEM
9775 /* Set the title of FRAME, if it has changed. The title format is
9776 Vicon_title_format if FRAME is iconified, otherwise it is
9777 frame_title_format. */
9779 static void
9780 x_consider_frame_title (Lisp_Object frame)
9782 struct frame *f = XFRAME (frame);
9784 if (FRAME_WINDOW_P (f)
9785 || FRAME_MINIBUF_ONLY_P (f)
9786 || f->explicit_name)
9788 /* Do we have more than one visible frame on this X display? */
9789 Lisp_Object tail;
9790 Lisp_Object fmt;
9791 int title_start;
9792 char *title;
9793 int len;
9794 struct it it;
9795 int count = SPECPDL_INDEX ();
9797 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
9799 Lisp_Object other_frame = XCAR (tail);
9800 struct frame *tf = XFRAME (other_frame);
9802 if (tf != f
9803 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
9804 && !FRAME_MINIBUF_ONLY_P (tf)
9805 && !EQ (other_frame, tip_frame)
9806 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
9807 break;
9810 /* Set global variable indicating that multiple frames exist. */
9811 multiple_frames = CONSP (tail);
9813 /* Switch to the buffer of selected window of the frame. Set up
9814 mode_line_target so that display_mode_element will output into
9815 mode_line_noprop_buf; then display the title. */
9816 record_unwind_protect (unwind_format_mode_line,
9817 format_mode_line_unwind_data
9818 (current_buffer, selected_window, 0));
9820 Fselect_window (f->selected_window, Qt);
9821 set_buffer_internal_1 (XBUFFER (XWINDOW (f->selected_window)->buffer));
9822 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
9824 mode_line_target = MODE_LINE_TITLE;
9825 title_start = MODE_LINE_NOPROP_LEN (0);
9826 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
9827 NULL, DEFAULT_FACE_ID);
9828 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
9829 len = MODE_LINE_NOPROP_LEN (title_start);
9830 title = mode_line_noprop_buf + title_start;
9831 unbind_to (count, Qnil);
9833 /* Set the title only if it's changed. This avoids consing in
9834 the common case where it hasn't. (If it turns out that we've
9835 already wasted too much time by walking through the list with
9836 display_mode_element, then we might need to optimize at a
9837 higher level than this.) */
9838 if (! STRINGP (f->name)
9839 || SBYTES (f->name) != len
9840 || memcmp (title, SDATA (f->name), len) != 0)
9841 x_implicitly_set_name (f, make_string (title, len), Qnil);
9845 #endif /* not HAVE_WINDOW_SYSTEM */
9850 /***********************************************************************
9851 Menu Bars
9852 ***********************************************************************/
9855 /* Prepare for redisplay by updating menu-bar item lists when
9856 appropriate. This can call eval. */
9858 void
9859 prepare_menu_bars (void)
9861 int all_windows;
9862 struct gcpro gcpro1, gcpro2;
9863 struct frame *f;
9864 Lisp_Object tooltip_frame;
9866 #ifdef HAVE_WINDOW_SYSTEM
9867 tooltip_frame = tip_frame;
9868 #else
9869 tooltip_frame = Qnil;
9870 #endif
9872 /* Update all frame titles based on their buffer names, etc. We do
9873 this before the menu bars so that the buffer-menu will show the
9874 up-to-date frame titles. */
9875 #ifdef HAVE_WINDOW_SYSTEM
9876 if (windows_or_buffers_changed || update_mode_lines)
9878 Lisp_Object tail, frame;
9880 FOR_EACH_FRAME (tail, frame)
9882 f = XFRAME (frame);
9883 if (!EQ (frame, tooltip_frame)
9884 && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)))
9885 x_consider_frame_title (frame);
9888 #endif /* HAVE_WINDOW_SYSTEM */
9890 /* Update the menu bar item lists, if appropriate. This has to be
9891 done before any actual redisplay or generation of display lines. */
9892 all_windows = (update_mode_lines
9893 || buffer_shared > 1
9894 || windows_or_buffers_changed);
9895 if (all_windows)
9897 Lisp_Object tail, frame;
9898 int count = SPECPDL_INDEX ();
9899 /* 1 means that update_menu_bar has run its hooks
9900 so any further calls to update_menu_bar shouldn't do so again. */
9901 int menu_bar_hooks_run = 0;
9903 record_unwind_save_match_data ();
9905 FOR_EACH_FRAME (tail, frame)
9907 f = XFRAME (frame);
9909 /* Ignore tooltip frame. */
9910 if (EQ (frame, tooltip_frame))
9911 continue;
9913 /* If a window on this frame changed size, report that to
9914 the user and clear the size-change flag. */
9915 if (FRAME_WINDOW_SIZES_CHANGED (f))
9917 Lisp_Object functions;
9919 /* Clear flag first in case we get an error below. */
9920 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
9921 functions = Vwindow_size_change_functions;
9922 GCPRO2 (tail, functions);
9924 while (CONSP (functions))
9926 if (!EQ (XCAR (functions), Qt))
9927 call1 (XCAR (functions), frame);
9928 functions = XCDR (functions);
9930 UNGCPRO;
9933 GCPRO1 (tail);
9934 menu_bar_hooks_run = update_menu_bar (f, 0, menu_bar_hooks_run);
9935 #ifdef HAVE_WINDOW_SYSTEM
9936 update_tool_bar (f, 0);
9937 #endif
9938 #ifdef HAVE_NS
9939 if (windows_or_buffers_changed
9940 && FRAME_NS_P (f))
9941 ns_set_doc_edited (f, Fbuffer_modified_p
9942 (XWINDOW (f->selected_window)->buffer));
9943 #endif
9944 UNGCPRO;
9947 unbind_to (count, Qnil);
9949 else
9951 struct frame *sf = SELECTED_FRAME ();
9952 update_menu_bar (sf, 1, 0);
9953 #ifdef HAVE_WINDOW_SYSTEM
9954 update_tool_bar (sf, 1);
9955 #endif
9960 /* Update the menu bar item list for frame F. This has to be done
9961 before we start to fill in any display lines, because it can call
9962 eval.
9964 If SAVE_MATCH_DATA is non-zero, we must save and restore it here.
9966 If HOOKS_RUN is 1, that means a previous call to update_menu_bar
9967 already ran the menu bar hooks for this redisplay, so there
9968 is no need to run them again. The return value is the
9969 updated value of this flag, to pass to the next call. */
9971 static int
9972 update_menu_bar (struct frame *f, int save_match_data, int hooks_run)
9974 Lisp_Object window;
9975 register struct window *w;
9977 /* If called recursively during a menu update, do nothing. This can
9978 happen when, for instance, an activate-menubar-hook causes a
9979 redisplay. */
9980 if (inhibit_menubar_update)
9981 return hooks_run;
9983 window = FRAME_SELECTED_WINDOW (f);
9984 w = XWINDOW (window);
9986 if (FRAME_WINDOW_P (f)
9988 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
9989 || defined (HAVE_NS) || defined (USE_GTK)
9990 FRAME_EXTERNAL_MENU_BAR (f)
9991 #else
9992 FRAME_MENU_BAR_LINES (f) > 0
9993 #endif
9994 : FRAME_MENU_BAR_LINES (f) > 0)
9996 /* If the user has switched buffers or windows, we need to
9997 recompute to reflect the new bindings. But we'll
9998 recompute when update_mode_lines is set too; that means
9999 that people can use force-mode-line-update to request
10000 that the menu bar be recomputed. The adverse effect on
10001 the rest of the redisplay algorithm is about the same as
10002 windows_or_buffers_changed anyway. */
10003 if (windows_or_buffers_changed
10004 /* This used to test w->update_mode_line, but we believe
10005 there is no need to recompute the menu in that case. */
10006 || update_mode_lines
10007 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
10008 < BUF_MODIFF (XBUFFER (w->buffer)))
10009 != !NILP (w->last_had_star))
10010 || ((!NILP (Vtransient_mark_mode)
10011 && !NILP (XBUFFER (w->buffer)->mark_active))
10012 != !NILP (w->region_showing)))
10014 struct buffer *prev = current_buffer;
10015 int count = SPECPDL_INDEX ();
10017 specbind (Qinhibit_menubar_update, Qt);
10019 set_buffer_internal_1 (XBUFFER (w->buffer));
10020 if (save_match_data)
10021 record_unwind_save_match_data ();
10022 if (NILP (Voverriding_local_map_menu_flag))
10024 specbind (Qoverriding_terminal_local_map, Qnil);
10025 specbind (Qoverriding_local_map, Qnil);
10028 if (!hooks_run)
10030 /* Run the Lucid hook. */
10031 safe_run_hooks (Qactivate_menubar_hook);
10033 /* If it has changed current-menubar from previous value,
10034 really recompute the menu-bar from the value. */
10035 if (! NILP (Vlucid_menu_bar_dirty_flag))
10036 call0 (Qrecompute_lucid_menubar);
10038 safe_run_hooks (Qmenu_bar_update_hook);
10040 hooks_run = 1;
10043 XSETFRAME (Vmenu_updating_frame, f);
10044 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
10046 /* Redisplay the menu bar in case we changed it. */
10047 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
10048 || defined (HAVE_NS) || defined (USE_GTK)
10049 if (FRAME_WINDOW_P (f))
10051 #if defined (HAVE_NS)
10052 /* All frames on Mac OS share the same menubar. So only
10053 the selected frame should be allowed to set it. */
10054 if (f == SELECTED_FRAME ())
10055 #endif
10056 set_frame_menubar (f, 0, 0);
10058 else
10059 /* On a terminal screen, the menu bar is an ordinary screen
10060 line, and this makes it get updated. */
10061 w->update_mode_line = Qt;
10062 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
10063 /* In the non-toolkit version, the menu bar is an ordinary screen
10064 line, and this makes it get updated. */
10065 w->update_mode_line = Qt;
10066 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
10068 unbind_to (count, Qnil);
10069 set_buffer_internal_1 (prev);
10073 return hooks_run;
10078 /***********************************************************************
10079 Output Cursor
10080 ***********************************************************************/
10082 #ifdef HAVE_WINDOW_SYSTEM
10084 /* EXPORT:
10085 Nominal cursor position -- where to draw output.
10086 HPOS and VPOS are window relative glyph matrix coordinates.
10087 X and Y are window relative pixel coordinates. */
10089 struct cursor_pos output_cursor;
10092 /* EXPORT:
10093 Set the global variable output_cursor to CURSOR. All cursor
10094 positions are relative to updated_window. */
10096 void
10097 set_output_cursor (struct cursor_pos *cursor)
10099 output_cursor.hpos = cursor->hpos;
10100 output_cursor.vpos = cursor->vpos;
10101 output_cursor.x = cursor->x;
10102 output_cursor.y = cursor->y;
10106 /* EXPORT for RIF:
10107 Set a nominal cursor position.
10109 HPOS and VPOS are column/row positions in a window glyph matrix. X
10110 and Y are window text area relative pixel positions.
10112 If this is done during an update, updated_window will contain the
10113 window that is being updated and the position is the future output
10114 cursor position for that window. If updated_window is null, use
10115 selected_window and display the cursor at the given position. */
10117 void
10118 x_cursor_to (int vpos, int hpos, int y, int x)
10120 struct window *w;
10122 /* If updated_window is not set, work on selected_window. */
10123 if (updated_window)
10124 w = updated_window;
10125 else
10126 w = XWINDOW (selected_window);
10128 /* Set the output cursor. */
10129 output_cursor.hpos = hpos;
10130 output_cursor.vpos = vpos;
10131 output_cursor.x = x;
10132 output_cursor.y = y;
10134 /* If not called as part of an update, really display the cursor.
10135 This will also set the cursor position of W. */
10136 if (updated_window == NULL)
10138 BLOCK_INPUT;
10139 display_and_set_cursor (w, 1, hpos, vpos, x, y);
10140 if (FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
10141 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (SELECTED_FRAME ());
10142 UNBLOCK_INPUT;
10146 #endif /* HAVE_WINDOW_SYSTEM */
10149 /***********************************************************************
10150 Tool-bars
10151 ***********************************************************************/
10153 #ifdef HAVE_WINDOW_SYSTEM
10155 /* Where the mouse was last time we reported a mouse event. */
10157 FRAME_PTR last_mouse_frame;
10159 /* Tool-bar item index of the item on which a mouse button was pressed
10160 or -1. */
10162 int last_tool_bar_item;
10165 static Lisp_Object
10166 update_tool_bar_unwind (Lisp_Object frame)
10168 selected_frame = frame;
10169 return Qnil;
10172 /* Update the tool-bar item list for frame F. This has to be done
10173 before we start to fill in any display lines. Called from
10174 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
10175 and restore it here. */
10177 static void
10178 update_tool_bar (struct frame *f, int save_match_data)
10180 #if defined (USE_GTK) || defined (HAVE_NS)
10181 int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
10182 #else
10183 int do_update = WINDOWP (f->tool_bar_window)
10184 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0;
10185 #endif
10187 if (do_update)
10189 Lisp_Object window;
10190 struct window *w;
10192 window = FRAME_SELECTED_WINDOW (f);
10193 w = XWINDOW (window);
10195 /* If the user has switched buffers or windows, we need to
10196 recompute to reflect the new bindings. But we'll
10197 recompute when update_mode_lines is set too; that means
10198 that people can use force-mode-line-update to request
10199 that the menu bar be recomputed. The adverse effect on
10200 the rest of the redisplay algorithm is about the same as
10201 windows_or_buffers_changed anyway. */
10202 if (windows_or_buffers_changed
10203 || !NILP (w->update_mode_line)
10204 || update_mode_lines
10205 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
10206 < BUF_MODIFF (XBUFFER (w->buffer)))
10207 != !NILP (w->last_had_star))
10208 || ((!NILP (Vtransient_mark_mode)
10209 && !NILP (XBUFFER (w->buffer)->mark_active))
10210 != !NILP (w->region_showing)))
10212 struct buffer *prev = current_buffer;
10213 int count = SPECPDL_INDEX ();
10214 Lisp_Object frame, new_tool_bar;
10215 int new_n_tool_bar;
10216 struct gcpro gcpro1;
10218 /* Set current_buffer to the buffer of the selected
10219 window of the frame, so that we get the right local
10220 keymaps. */
10221 set_buffer_internal_1 (XBUFFER (w->buffer));
10223 /* Save match data, if we must. */
10224 if (save_match_data)
10225 record_unwind_save_match_data ();
10227 /* Make sure that we don't accidentally use bogus keymaps. */
10228 if (NILP (Voverriding_local_map_menu_flag))
10230 specbind (Qoverriding_terminal_local_map, Qnil);
10231 specbind (Qoverriding_local_map, Qnil);
10234 GCPRO1 (new_tool_bar);
10236 /* We must temporarily set the selected frame to this frame
10237 before calling tool_bar_items, because the calculation of
10238 the tool-bar keymap uses the selected frame (see
10239 `tool-bar-make-keymap' in tool-bar.el). */
10240 record_unwind_protect (update_tool_bar_unwind, selected_frame);
10241 XSETFRAME (frame, f);
10242 selected_frame = frame;
10244 /* Build desired tool-bar items from keymaps. */
10245 new_tool_bar = tool_bar_items (Fcopy_sequence (f->tool_bar_items),
10246 &new_n_tool_bar);
10248 /* Redisplay the tool-bar if we changed it. */
10249 if (new_n_tool_bar != f->n_tool_bar_items
10250 || NILP (Fequal (new_tool_bar, f->tool_bar_items)))
10252 /* Redisplay that happens asynchronously due to an expose event
10253 may access f->tool_bar_items. Make sure we update both
10254 variables within BLOCK_INPUT so no such event interrupts. */
10255 BLOCK_INPUT;
10256 f->tool_bar_items = new_tool_bar;
10257 f->n_tool_bar_items = new_n_tool_bar;
10258 w->update_mode_line = Qt;
10259 UNBLOCK_INPUT;
10262 UNGCPRO;
10264 unbind_to (count, Qnil);
10265 set_buffer_internal_1 (prev);
10271 /* Set F->desired_tool_bar_string to a Lisp string representing frame
10272 F's desired tool-bar contents. F->tool_bar_items must have
10273 been set up previously by calling prepare_menu_bars. */
10275 static void
10276 build_desired_tool_bar_string (struct frame *f)
10278 int i, size, size_needed;
10279 struct gcpro gcpro1, gcpro2, gcpro3;
10280 Lisp_Object image, plist, props;
10282 image = plist = props = Qnil;
10283 GCPRO3 (image, plist, props);
10285 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
10286 Otherwise, make a new string. */
10288 /* The size of the string we might be able to reuse. */
10289 size = (STRINGP (f->desired_tool_bar_string)
10290 ? SCHARS (f->desired_tool_bar_string)
10291 : 0);
10293 /* We need one space in the string for each image. */
10294 size_needed = f->n_tool_bar_items;
10296 /* Reuse f->desired_tool_bar_string, if possible. */
10297 if (size < size_needed || NILP (f->desired_tool_bar_string))
10298 f->desired_tool_bar_string = Fmake_string (make_number (size_needed),
10299 make_number (' '));
10300 else
10302 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
10303 Fremove_text_properties (make_number (0), make_number (size),
10304 props, f->desired_tool_bar_string);
10307 /* Put a `display' property on the string for the images to display,
10308 put a `menu_item' property on tool-bar items with a value that
10309 is the index of the item in F's tool-bar item vector. */
10310 for (i = 0; i < f->n_tool_bar_items; ++i)
10312 #define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
10314 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
10315 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
10316 int hmargin, vmargin, relief, idx, end;
10318 /* If image is a vector, choose the image according to the
10319 button state. */
10320 image = PROP (TOOL_BAR_ITEM_IMAGES);
10321 if (VECTORP (image))
10323 if (enabled_p)
10324 idx = (selected_p
10325 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
10326 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
10327 else
10328 idx = (selected_p
10329 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
10330 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
10332 xassert (ASIZE (image) >= idx);
10333 image = AREF (image, idx);
10335 else
10336 idx = -1;
10338 /* Ignore invalid image specifications. */
10339 if (!valid_image_p (image))
10340 continue;
10342 /* Display the tool-bar button pressed, or depressed. */
10343 plist = Fcopy_sequence (XCDR (image));
10345 /* Compute margin and relief to draw. */
10346 relief = (tool_bar_button_relief >= 0
10347 ? tool_bar_button_relief
10348 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
10349 hmargin = vmargin = relief;
10351 if (INTEGERP (Vtool_bar_button_margin)
10352 && XINT (Vtool_bar_button_margin) > 0)
10354 hmargin += XFASTINT (Vtool_bar_button_margin);
10355 vmargin += XFASTINT (Vtool_bar_button_margin);
10357 else if (CONSP (Vtool_bar_button_margin))
10359 if (INTEGERP (XCAR (Vtool_bar_button_margin))
10360 && XINT (XCAR (Vtool_bar_button_margin)) > 0)
10361 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
10363 if (INTEGERP (XCDR (Vtool_bar_button_margin))
10364 && XINT (XCDR (Vtool_bar_button_margin)) > 0)
10365 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
10368 if (auto_raise_tool_bar_buttons_p)
10370 /* Add a `:relief' property to the image spec if the item is
10371 selected. */
10372 if (selected_p)
10374 plist = Fplist_put (plist, QCrelief, make_number (-relief));
10375 hmargin -= relief;
10376 vmargin -= relief;
10379 else
10381 /* If image is selected, display it pressed, i.e. with a
10382 negative relief. If it's not selected, display it with a
10383 raised relief. */
10384 plist = Fplist_put (plist, QCrelief,
10385 (selected_p
10386 ? make_number (-relief)
10387 : make_number (relief)));
10388 hmargin -= relief;
10389 vmargin -= relief;
10392 /* Put a margin around the image. */
10393 if (hmargin || vmargin)
10395 if (hmargin == vmargin)
10396 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
10397 else
10398 plist = Fplist_put (plist, QCmargin,
10399 Fcons (make_number (hmargin),
10400 make_number (vmargin)));
10403 /* If button is not enabled, and we don't have special images
10404 for the disabled state, make the image appear disabled by
10405 applying an appropriate algorithm to it. */
10406 if (!enabled_p && idx < 0)
10407 plist = Fplist_put (plist, QCconversion, Qdisabled);
10409 /* Put a `display' text property on the string for the image to
10410 display. Put a `menu-item' property on the string that gives
10411 the start of this item's properties in the tool-bar items
10412 vector. */
10413 image = Fcons (Qimage, plist);
10414 props = list4 (Qdisplay, image,
10415 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS));
10417 /* Let the last image hide all remaining spaces in the tool bar
10418 string. The string can be longer than needed when we reuse a
10419 previous string. */
10420 if (i + 1 == f->n_tool_bar_items)
10421 end = SCHARS (f->desired_tool_bar_string);
10422 else
10423 end = i + 1;
10424 Fadd_text_properties (make_number (i), make_number (end),
10425 props, f->desired_tool_bar_string);
10426 #undef PROP
10429 UNGCPRO;
10433 /* Display one line of the tool-bar of frame IT->f.
10435 HEIGHT specifies the desired height of the tool-bar line.
10436 If the actual height of the glyph row is less than HEIGHT, the
10437 row's height is increased to HEIGHT, and the icons are centered
10438 vertically in the new height.
10440 If HEIGHT is -1, we are counting needed tool-bar lines, so don't
10441 count a final empty row in case the tool-bar width exactly matches
10442 the window width.
10445 static void
10446 display_tool_bar_line (struct it *it, int height)
10448 struct glyph_row *row = it->glyph_row;
10449 int max_x = it->last_visible_x;
10450 struct glyph *last;
10452 prepare_desired_row (row);
10453 row->y = it->current_y;
10455 /* Note that this isn't made use of if the face hasn't a box,
10456 so there's no need to check the face here. */
10457 it->start_of_box_run_p = 1;
10459 while (it->current_x < max_x)
10461 int x, n_glyphs_before, i, nglyphs;
10462 struct it it_before;
10464 /* Get the next display element. */
10465 if (!get_next_display_element (it))
10467 /* Don't count empty row if we are counting needed tool-bar lines. */
10468 if (height < 0 && !it->hpos)
10469 return;
10470 break;
10473 /* Produce glyphs. */
10474 n_glyphs_before = row->used[TEXT_AREA];
10475 it_before = *it;
10477 PRODUCE_GLYPHS (it);
10479 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
10480 i = 0;
10481 x = it_before.current_x;
10482 while (i < nglyphs)
10484 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
10486 if (x + glyph->pixel_width > max_x)
10488 /* Glyph doesn't fit on line. Backtrack. */
10489 row->used[TEXT_AREA] = n_glyphs_before;
10490 *it = it_before;
10491 /* If this is the only glyph on this line, it will never fit on the
10492 tool-bar, so skip it. But ensure there is at least one glyph,
10493 so we don't accidentally disable the tool-bar. */
10494 if (n_glyphs_before == 0
10495 && (it->vpos > 0 || IT_STRING_CHARPOS (*it) < it->end_charpos-1))
10496 break;
10497 goto out;
10500 ++it->hpos;
10501 x += glyph->pixel_width;
10502 ++i;
10505 /* Stop at line ends. */
10506 if (ITERATOR_AT_END_OF_LINE_P (it))
10507 break;
10509 set_iterator_to_next (it, 1);
10512 out:;
10514 row->displays_text_p = row->used[TEXT_AREA] != 0;
10516 /* Use default face for the border below the tool bar.
10518 FIXME: When auto-resize-tool-bars is grow-only, there is
10519 no additional border below the possibly empty tool-bar lines.
10520 So to make the extra empty lines look "normal", we have to
10521 use the tool-bar face for the border too. */
10522 if (!row->displays_text_p && !EQ (Vauto_resize_tool_bars, Qgrow_only))
10523 it->face_id = DEFAULT_FACE_ID;
10525 extend_face_to_end_of_line (it);
10526 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
10527 last->right_box_line_p = 1;
10528 if (last == row->glyphs[TEXT_AREA])
10529 last->left_box_line_p = 1;
10531 /* Make line the desired height and center it vertically. */
10532 if ((height -= it->max_ascent + it->max_descent) > 0)
10534 /* Don't add more than one line height. */
10535 height %= FRAME_LINE_HEIGHT (it->f);
10536 it->max_ascent += height / 2;
10537 it->max_descent += (height + 1) / 2;
10540 compute_line_metrics (it);
10542 /* If line is empty, make it occupy the rest of the tool-bar. */
10543 if (!row->displays_text_p)
10545 row->height = row->phys_height = it->last_visible_y - row->y;
10546 row->visible_height = row->height;
10547 row->ascent = row->phys_ascent = 0;
10548 row->extra_line_spacing = 0;
10551 row->full_width_p = 1;
10552 row->continued_p = 0;
10553 row->truncated_on_left_p = 0;
10554 row->truncated_on_right_p = 0;
10556 it->current_x = it->hpos = 0;
10557 it->current_y += row->height;
10558 ++it->vpos;
10559 ++it->glyph_row;
10563 /* Max tool-bar height. */
10565 #define MAX_FRAME_TOOL_BAR_HEIGHT(f) \
10566 ((FRAME_LINE_HEIGHT (f) * FRAME_LINES (f)))
10568 /* Value is the number of screen lines needed to make all tool-bar
10569 items of frame F visible. The number of actual rows needed is
10570 returned in *N_ROWS if non-NULL. */
10572 static int
10573 tool_bar_lines_needed (struct frame *f, int *n_rows)
10575 struct window *w = XWINDOW (f->tool_bar_window);
10576 struct it it;
10577 /* tool_bar_lines_needed is called from redisplay_tool_bar after building
10578 the desired matrix, so use (unused) mode-line row as temporary row to
10579 avoid destroying the first tool-bar row. */
10580 struct glyph_row *temp_row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
10582 /* Initialize an iterator for iteration over
10583 F->desired_tool_bar_string in the tool-bar window of frame F. */
10584 init_iterator (&it, w, -1, -1, temp_row, TOOL_BAR_FACE_ID);
10585 it.first_visible_x = 0;
10586 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
10587 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
10589 while (!ITERATOR_AT_END_P (&it))
10591 clear_glyph_row (temp_row);
10592 it.glyph_row = temp_row;
10593 display_tool_bar_line (&it, -1);
10595 clear_glyph_row (temp_row);
10597 /* f->n_tool_bar_rows == 0 means "unknown"; -1 means no tool-bar. */
10598 if (n_rows)
10599 *n_rows = it.vpos > 0 ? it.vpos : -1;
10601 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
10605 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
10606 0, 1, 0,
10607 doc: /* Return the number of lines occupied by the tool bar of FRAME. */)
10608 (Lisp_Object frame)
10610 struct frame *f;
10611 struct window *w;
10612 int nlines = 0;
10614 if (NILP (frame))
10615 frame = selected_frame;
10616 else
10617 CHECK_FRAME (frame);
10618 f = XFRAME (frame);
10620 if (WINDOWP (f->tool_bar_window)
10621 || (w = XWINDOW (f->tool_bar_window),
10622 WINDOW_TOTAL_LINES (w) > 0))
10624 update_tool_bar (f, 1);
10625 if (f->n_tool_bar_items)
10627 build_desired_tool_bar_string (f);
10628 nlines = tool_bar_lines_needed (f, NULL);
10632 return make_number (nlines);
10636 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
10637 height should be changed. */
10639 static int
10640 redisplay_tool_bar (struct frame *f)
10642 struct window *w;
10643 struct it it;
10644 struct glyph_row *row;
10646 #if defined (USE_GTK) || defined (HAVE_NS)
10647 if (FRAME_EXTERNAL_TOOL_BAR (f))
10648 update_frame_tool_bar (f);
10649 return 0;
10650 #endif
10652 /* If frame hasn't a tool-bar window or if it is zero-height, don't
10653 do anything. This means you must start with tool-bar-lines
10654 non-zero to get the auto-sizing effect. Or in other words, you
10655 can turn off tool-bars by specifying tool-bar-lines zero. */
10656 if (!WINDOWP (f->tool_bar_window)
10657 || (w = XWINDOW (f->tool_bar_window),
10658 WINDOW_TOTAL_LINES (w) == 0))
10659 return 0;
10661 /* Set up an iterator for the tool-bar window. */
10662 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
10663 it.first_visible_x = 0;
10664 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
10665 row = it.glyph_row;
10667 /* Build a string that represents the contents of the tool-bar. */
10668 build_desired_tool_bar_string (f);
10669 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
10671 if (f->n_tool_bar_rows == 0)
10673 int nlines;
10675 if ((nlines = tool_bar_lines_needed (f, &f->n_tool_bar_rows),
10676 nlines != WINDOW_TOTAL_LINES (w)))
10678 Lisp_Object frame;
10679 int old_height = WINDOW_TOTAL_LINES (w);
10681 XSETFRAME (frame, f);
10682 Fmodify_frame_parameters (frame,
10683 Fcons (Fcons (Qtool_bar_lines,
10684 make_number (nlines)),
10685 Qnil));
10686 if (WINDOW_TOTAL_LINES (w) != old_height)
10688 clear_glyph_matrix (w->desired_matrix);
10689 fonts_changed_p = 1;
10690 return 1;
10695 /* Display as many lines as needed to display all tool-bar items. */
10697 if (f->n_tool_bar_rows > 0)
10699 int border, rows, height, extra;
10701 if (INTEGERP (Vtool_bar_border))
10702 border = XINT (Vtool_bar_border);
10703 else if (EQ (Vtool_bar_border, Qinternal_border_width))
10704 border = FRAME_INTERNAL_BORDER_WIDTH (f);
10705 else if (EQ (Vtool_bar_border, Qborder_width))
10706 border = f->border_width;
10707 else
10708 border = 0;
10709 if (border < 0)
10710 border = 0;
10712 rows = f->n_tool_bar_rows;
10713 height = max (1, (it.last_visible_y - border) / rows);
10714 extra = it.last_visible_y - border - height * rows;
10716 while (it.current_y < it.last_visible_y)
10718 int h = 0;
10719 if (extra > 0 && rows-- > 0)
10721 h = (extra + rows - 1) / rows;
10722 extra -= h;
10724 display_tool_bar_line (&it, height + h);
10727 else
10729 while (it.current_y < it.last_visible_y)
10730 display_tool_bar_line (&it, 0);
10733 /* It doesn't make much sense to try scrolling in the tool-bar
10734 window, so don't do it. */
10735 w->desired_matrix->no_scrolling_p = 1;
10736 w->must_be_updated_p = 1;
10738 if (!NILP (Vauto_resize_tool_bars))
10740 int max_tool_bar_height = MAX_FRAME_TOOL_BAR_HEIGHT (f);
10741 int change_height_p = 0;
10743 /* If we couldn't display everything, change the tool-bar's
10744 height if there is room for more. */
10745 if (IT_STRING_CHARPOS (it) < it.end_charpos
10746 && it.current_y < max_tool_bar_height)
10747 change_height_p = 1;
10749 row = it.glyph_row - 1;
10751 /* If there are blank lines at the end, except for a partially
10752 visible blank line at the end that is smaller than
10753 FRAME_LINE_HEIGHT, change the tool-bar's height. */
10754 if (!row->displays_text_p
10755 && row->height >= FRAME_LINE_HEIGHT (f))
10756 change_height_p = 1;
10758 /* If row displays tool-bar items, but is partially visible,
10759 change the tool-bar's height. */
10760 if (row->displays_text_p
10761 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y
10762 && MATRIX_ROW_BOTTOM_Y (row) < max_tool_bar_height)
10763 change_height_p = 1;
10765 /* Resize windows as needed by changing the `tool-bar-lines'
10766 frame parameter. */
10767 if (change_height_p)
10769 Lisp_Object frame;
10770 int old_height = WINDOW_TOTAL_LINES (w);
10771 int nrows;
10772 int nlines = tool_bar_lines_needed (f, &nrows);
10774 change_height_p = ((EQ (Vauto_resize_tool_bars, Qgrow_only)
10775 && !f->minimize_tool_bar_window_p)
10776 ? (nlines > old_height)
10777 : (nlines != old_height));
10778 f->minimize_tool_bar_window_p = 0;
10780 if (change_height_p)
10782 XSETFRAME (frame, f);
10783 Fmodify_frame_parameters (frame,
10784 Fcons (Fcons (Qtool_bar_lines,
10785 make_number (nlines)),
10786 Qnil));
10787 if (WINDOW_TOTAL_LINES (w) != old_height)
10789 clear_glyph_matrix (w->desired_matrix);
10790 f->n_tool_bar_rows = nrows;
10791 fonts_changed_p = 1;
10792 return 1;
10798 f->minimize_tool_bar_window_p = 0;
10799 return 0;
10803 /* Get information about the tool-bar item which is displayed in GLYPH
10804 on frame F. Return in *PROP_IDX the index where tool-bar item
10805 properties start in F->tool_bar_items. Value is zero if
10806 GLYPH doesn't display a tool-bar item. */
10808 static int
10809 tool_bar_item_info (struct frame *f, struct glyph *glyph, int *prop_idx)
10811 Lisp_Object prop;
10812 int success_p;
10813 int charpos;
10815 /* This function can be called asynchronously, which means we must
10816 exclude any possibility that Fget_text_property signals an
10817 error. */
10818 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
10819 charpos = max (0, charpos);
10821 /* Get the text property `menu-item' at pos. The value of that
10822 property is the start index of this item's properties in
10823 F->tool_bar_items. */
10824 prop = Fget_text_property (make_number (charpos),
10825 Qmenu_item, f->current_tool_bar_string);
10826 if (INTEGERP (prop))
10828 *prop_idx = XINT (prop);
10829 success_p = 1;
10831 else
10832 success_p = 0;
10834 return success_p;
10838 /* Get information about the tool-bar item at position X/Y on frame F.
10839 Return in *GLYPH a pointer to the glyph of the tool-bar item in
10840 the current matrix of the tool-bar window of F, or NULL if not
10841 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
10842 item in F->tool_bar_items. Value is
10844 -1 if X/Y is not on a tool-bar item
10845 0 if X/Y is on the same item that was highlighted before.
10846 1 otherwise. */
10848 static int
10849 get_tool_bar_item (struct frame *f, int x, int y, struct glyph **glyph,
10850 int *hpos, int *vpos, int *prop_idx)
10852 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
10853 struct window *w = XWINDOW (f->tool_bar_window);
10854 int area;
10856 /* Find the glyph under X/Y. */
10857 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
10858 if (*glyph == NULL)
10859 return -1;
10861 /* Get the start of this tool-bar item's properties in
10862 f->tool_bar_items. */
10863 if (!tool_bar_item_info (f, *glyph, prop_idx))
10864 return -1;
10866 /* Is mouse on the highlighted item? */
10867 if (EQ (f->tool_bar_window, hlinfo->mouse_face_window)
10868 && *vpos >= hlinfo->mouse_face_beg_row
10869 && *vpos <= hlinfo->mouse_face_end_row
10870 && (*vpos > hlinfo->mouse_face_beg_row
10871 || *hpos >= hlinfo->mouse_face_beg_col)
10872 && (*vpos < hlinfo->mouse_face_end_row
10873 || *hpos < hlinfo->mouse_face_end_col
10874 || hlinfo->mouse_face_past_end))
10875 return 0;
10877 return 1;
10881 /* EXPORT:
10882 Handle mouse button event on the tool-bar of frame F, at
10883 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
10884 0 for button release. MODIFIERS is event modifiers for button
10885 release. */
10887 void
10888 handle_tool_bar_click (struct frame *f, int x, int y, int down_p,
10889 unsigned int modifiers)
10891 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
10892 struct window *w = XWINDOW (f->tool_bar_window);
10893 int hpos, vpos, prop_idx;
10894 struct glyph *glyph;
10895 Lisp_Object enabled_p;
10897 /* If not on the highlighted tool-bar item, return. */
10898 frame_to_window_pixel_xy (w, &x, &y);
10899 if (get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0)
10900 return;
10902 /* If item is disabled, do nothing. */
10903 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
10904 if (NILP (enabled_p))
10905 return;
10907 if (down_p)
10909 /* Show item in pressed state. */
10910 show_mouse_face (hlinfo, DRAW_IMAGE_SUNKEN);
10911 hlinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN;
10912 last_tool_bar_item = prop_idx;
10914 else
10916 Lisp_Object key, frame;
10917 struct input_event event;
10918 EVENT_INIT (event);
10920 /* Show item in released state. */
10921 show_mouse_face (hlinfo, DRAW_IMAGE_RAISED);
10922 hlinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
10924 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
10926 XSETFRAME (frame, f);
10927 event.kind = TOOL_BAR_EVENT;
10928 event.frame_or_window = frame;
10929 event.arg = frame;
10930 kbd_buffer_store_event (&event);
10932 event.kind = TOOL_BAR_EVENT;
10933 event.frame_or_window = frame;
10934 event.arg = key;
10935 event.modifiers = modifiers;
10936 kbd_buffer_store_event (&event);
10937 last_tool_bar_item = -1;
10942 /* Possibly highlight a tool-bar item on frame F when mouse moves to
10943 tool-bar window-relative coordinates X/Y. Called from
10944 note_mouse_highlight. */
10946 static void
10947 note_tool_bar_highlight (struct frame *f, int x, int y)
10949 Lisp_Object window = f->tool_bar_window;
10950 struct window *w = XWINDOW (window);
10951 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
10952 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
10953 int hpos, vpos;
10954 struct glyph *glyph;
10955 struct glyph_row *row;
10956 int i;
10957 Lisp_Object enabled_p;
10958 int prop_idx;
10959 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
10960 int mouse_down_p, rc;
10962 /* Function note_mouse_highlight is called with negative X/Y
10963 values when mouse moves outside of the frame. */
10964 if (x <= 0 || y <= 0)
10966 clear_mouse_face (hlinfo);
10967 return;
10970 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
10971 if (rc < 0)
10973 /* Not on tool-bar item. */
10974 clear_mouse_face (hlinfo);
10975 return;
10977 else if (rc == 0)
10978 /* On same tool-bar item as before. */
10979 goto set_help_echo;
10981 clear_mouse_face (hlinfo);
10983 /* Mouse is down, but on different tool-bar item? */
10984 mouse_down_p = (dpyinfo->grabbed
10985 && f == last_mouse_frame
10986 && FRAME_LIVE_P (f));
10987 if (mouse_down_p
10988 && last_tool_bar_item != prop_idx)
10989 return;
10991 hlinfo->mouse_face_image_state = DRAW_NORMAL_TEXT;
10992 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
10994 /* If tool-bar item is not enabled, don't highlight it. */
10995 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
10996 if (!NILP (enabled_p))
10998 /* Compute the x-position of the glyph. In front and past the
10999 image is a space. We include this in the highlighted area. */
11000 row = MATRIX_ROW (w->current_matrix, vpos);
11001 for (i = x = 0; i < hpos; ++i)
11002 x += row->glyphs[TEXT_AREA][i].pixel_width;
11004 /* Record this as the current active region. */
11005 hlinfo->mouse_face_beg_col = hpos;
11006 hlinfo->mouse_face_beg_row = vpos;
11007 hlinfo->mouse_face_beg_x = x;
11008 hlinfo->mouse_face_beg_y = row->y;
11009 hlinfo->mouse_face_past_end = 0;
11011 hlinfo->mouse_face_end_col = hpos + 1;
11012 hlinfo->mouse_face_end_row = vpos;
11013 hlinfo->mouse_face_end_x = x + glyph->pixel_width;
11014 hlinfo->mouse_face_end_y = row->y;
11015 hlinfo->mouse_face_window = window;
11016 hlinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
11018 /* Display it as active. */
11019 show_mouse_face (hlinfo, draw);
11020 hlinfo->mouse_face_image_state = draw;
11023 set_help_echo:
11025 /* Set help_echo_string to a help string to display for this tool-bar item.
11026 XTread_socket does the rest. */
11027 help_echo_object = help_echo_window = Qnil;
11028 help_echo_pos = -1;
11029 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
11030 if (NILP (help_echo_string))
11031 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
11034 #endif /* HAVE_WINDOW_SYSTEM */
11038 /************************************************************************
11039 Horizontal scrolling
11040 ************************************************************************/
11042 static int hscroll_window_tree (Lisp_Object);
11043 static int hscroll_windows (Lisp_Object);
11045 /* For all leaf windows in the window tree rooted at WINDOW, set their
11046 hscroll value so that PT is (i) visible in the window, and (ii) so
11047 that it is not within a certain margin at the window's left and
11048 right border. Value is non-zero if any window's hscroll has been
11049 changed. */
11051 static int
11052 hscroll_window_tree (Lisp_Object window)
11054 int hscrolled_p = 0;
11055 int hscroll_relative_p = FLOATP (Vhscroll_step);
11056 int hscroll_step_abs = 0;
11057 double hscroll_step_rel = 0;
11059 if (hscroll_relative_p)
11061 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
11062 if (hscroll_step_rel < 0)
11064 hscroll_relative_p = 0;
11065 hscroll_step_abs = 0;
11068 else if (INTEGERP (Vhscroll_step))
11070 hscroll_step_abs = XINT (Vhscroll_step);
11071 if (hscroll_step_abs < 0)
11072 hscroll_step_abs = 0;
11074 else
11075 hscroll_step_abs = 0;
11077 while (WINDOWP (window))
11079 struct window *w = XWINDOW (window);
11081 if (WINDOWP (w->hchild))
11082 hscrolled_p |= hscroll_window_tree (w->hchild);
11083 else if (WINDOWP (w->vchild))
11084 hscrolled_p |= hscroll_window_tree (w->vchild);
11085 else if (w->cursor.vpos >= 0)
11087 int h_margin;
11088 int text_area_width;
11089 struct glyph_row *current_cursor_row
11090 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
11091 struct glyph_row *desired_cursor_row
11092 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
11093 struct glyph_row *cursor_row
11094 = (desired_cursor_row->enabled_p
11095 ? desired_cursor_row
11096 : current_cursor_row);
11098 text_area_width = window_box_width (w, TEXT_AREA);
11100 /* Scroll when cursor is inside this scroll margin. */
11101 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
11103 if (!NILP (Fbuffer_local_value (Qauto_hscroll_mode, w->buffer))
11104 && ((XFASTINT (w->hscroll)
11105 && w->cursor.x <= h_margin)
11106 || (cursor_row->enabled_p
11107 && cursor_row->truncated_on_right_p
11108 && (w->cursor.x >= text_area_width - h_margin))))
11110 struct it it;
11111 int hscroll;
11112 struct buffer *saved_current_buffer;
11113 EMACS_INT pt;
11114 int wanted_x;
11116 /* Find point in a display of infinite width. */
11117 saved_current_buffer = current_buffer;
11118 current_buffer = XBUFFER (w->buffer);
11120 if (w == XWINDOW (selected_window))
11121 pt = BUF_PT (current_buffer);
11122 else
11124 pt = marker_position (w->pointm);
11125 pt = max (BEGV, pt);
11126 pt = min (ZV, pt);
11129 /* Move iterator to pt starting at cursor_row->start in
11130 a line with infinite width. */
11131 init_to_row_start (&it, w, cursor_row);
11132 it.last_visible_x = INFINITY;
11133 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
11134 current_buffer = saved_current_buffer;
11136 /* Position cursor in window. */
11137 if (!hscroll_relative_p && hscroll_step_abs == 0)
11138 hscroll = max (0, (it.current_x
11139 - (ITERATOR_AT_END_OF_LINE_P (&it)
11140 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
11141 : (text_area_width / 2))))
11142 / FRAME_COLUMN_WIDTH (it.f);
11143 else if (w->cursor.x >= text_area_width - h_margin)
11145 if (hscroll_relative_p)
11146 wanted_x = text_area_width * (1 - hscroll_step_rel)
11147 - h_margin;
11148 else
11149 wanted_x = text_area_width
11150 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
11151 - h_margin;
11152 hscroll
11153 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
11155 else
11157 if (hscroll_relative_p)
11158 wanted_x = text_area_width * hscroll_step_rel
11159 + h_margin;
11160 else
11161 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
11162 + h_margin;
11163 hscroll
11164 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
11166 hscroll = max (hscroll, XFASTINT (w->min_hscroll));
11168 /* Don't call Fset_window_hscroll if value hasn't
11169 changed because it will prevent redisplay
11170 optimizations. */
11171 if (XFASTINT (w->hscroll) != hscroll)
11173 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
11174 w->hscroll = make_number (hscroll);
11175 hscrolled_p = 1;
11180 window = w->next;
11183 /* Value is non-zero if hscroll of any leaf window has been changed. */
11184 return hscrolled_p;
11188 /* Set hscroll so that cursor is visible and not inside horizontal
11189 scroll margins for all windows in the tree rooted at WINDOW. See
11190 also hscroll_window_tree above. Value is non-zero if any window's
11191 hscroll has been changed. If it has, desired matrices on the frame
11192 of WINDOW are cleared. */
11194 static int
11195 hscroll_windows (Lisp_Object window)
11197 int hscrolled_p = hscroll_window_tree (window);
11198 if (hscrolled_p)
11199 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
11200 return hscrolled_p;
11205 /************************************************************************
11206 Redisplay
11207 ************************************************************************/
11209 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
11210 to a non-zero value. This is sometimes handy to have in a debugger
11211 session. */
11213 #if GLYPH_DEBUG
11215 /* First and last unchanged row for try_window_id. */
11217 int debug_first_unchanged_at_end_vpos;
11218 int debug_last_unchanged_at_beg_vpos;
11220 /* Delta vpos and y. */
11222 int debug_dvpos, debug_dy;
11224 /* Delta in characters and bytes for try_window_id. */
11226 EMACS_INT debug_delta, debug_delta_bytes;
11228 /* Values of window_end_pos and window_end_vpos at the end of
11229 try_window_id. */
11231 EMACS_INT debug_end_pos, debug_end_vpos;
11233 /* Append a string to W->desired_matrix->method. FMT is a printf
11234 format string. A1...A9 are a supplement for a variable-length
11235 argument list. If trace_redisplay_p is non-zero also printf the
11236 resulting string to stderr. */
11238 static void
11239 debug_method_add (w, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
11240 struct window *w;
11241 char *fmt;
11242 int a1, a2, a3, a4, a5, a6, a7, a8, a9;
11244 char buffer[512];
11245 char *method = w->desired_matrix->method;
11246 int len = strlen (method);
11247 int size = sizeof w->desired_matrix->method;
11248 int remaining = size - len - 1;
11250 sprintf (buffer, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
11251 if (len && remaining)
11253 method[len] = '|';
11254 --remaining, ++len;
11257 strncpy (method + len, buffer, remaining);
11259 if (trace_redisplay_p)
11260 fprintf (stderr, "%p (%s): %s\n",
11262 ((BUFFERP (w->buffer)
11263 && STRINGP (XBUFFER (w->buffer)->name))
11264 ? (char *) SDATA (XBUFFER (w->buffer)->name)
11265 : "no buffer"),
11266 buffer);
11269 #endif /* GLYPH_DEBUG */
11272 /* Value is non-zero if all changes in window W, which displays
11273 current_buffer, are in the text between START and END. START is a
11274 buffer position, END is given as a distance from Z. Used in
11275 redisplay_internal for display optimization. */
11277 static INLINE int
11278 text_outside_line_unchanged_p (struct window *w,
11279 EMACS_INT start, EMACS_INT end)
11281 int unchanged_p = 1;
11283 /* If text or overlays have changed, see where. */
11284 if (XFASTINT (w->last_modified) < MODIFF
11285 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
11287 /* Gap in the line? */
11288 if (GPT < start || Z - GPT < end)
11289 unchanged_p = 0;
11291 /* Changes start in front of the line, or end after it? */
11292 if (unchanged_p
11293 && (BEG_UNCHANGED < start - 1
11294 || END_UNCHANGED < end))
11295 unchanged_p = 0;
11297 /* If selective display, can't optimize if changes start at the
11298 beginning of the line. */
11299 if (unchanged_p
11300 && INTEGERP (current_buffer->selective_display)
11301 && XINT (current_buffer->selective_display) > 0
11302 && (BEG_UNCHANGED < start || GPT <= start))
11303 unchanged_p = 0;
11305 /* If there are overlays at the start or end of the line, these
11306 may have overlay strings with newlines in them. A change at
11307 START, for instance, may actually concern the display of such
11308 overlay strings as well, and they are displayed on different
11309 lines. So, quickly rule out this case. (For the future, it
11310 might be desirable to implement something more telling than
11311 just BEG/END_UNCHANGED.) */
11312 if (unchanged_p)
11314 if (BEG + BEG_UNCHANGED == start
11315 && overlay_touches_p (start))
11316 unchanged_p = 0;
11317 if (END_UNCHANGED == end
11318 && overlay_touches_p (Z - end))
11319 unchanged_p = 0;
11322 /* Under bidi reordering, adding or deleting a character in the
11323 beginning of a paragraph, before the first strong directional
11324 character, can change the base direction of the paragraph (unless
11325 the buffer specifies a fixed paragraph direction), which will
11326 require to redisplay the whole paragraph. It might be worthwhile
11327 to find the paragraph limits and widen the range of redisplayed
11328 lines to that, but for now just give up this optimization. */
11329 if (!NILP (XBUFFER (w->buffer)->bidi_display_reordering)
11330 && NILP (XBUFFER (w->buffer)->bidi_paragraph_direction))
11331 unchanged_p = 0;
11334 return unchanged_p;
11338 /* Do a frame update, taking possible shortcuts into account. This is
11339 the main external entry point for redisplay.
11341 If the last redisplay displayed an echo area message and that message
11342 is no longer requested, we clear the echo area or bring back the
11343 mini-buffer if that is in use. */
11345 void
11346 redisplay (void)
11348 redisplay_internal (0);
11352 static Lisp_Object
11353 overlay_arrow_string_or_property (Lisp_Object var)
11355 Lisp_Object val;
11357 if (val = Fget (var, Qoverlay_arrow_string), STRINGP (val))
11358 return val;
11360 return Voverlay_arrow_string;
11363 /* Return 1 if there are any overlay-arrows in current_buffer. */
11364 static int
11365 overlay_arrow_in_current_buffer_p (void)
11367 Lisp_Object vlist;
11369 for (vlist = Voverlay_arrow_variable_list;
11370 CONSP (vlist);
11371 vlist = XCDR (vlist))
11373 Lisp_Object var = XCAR (vlist);
11374 Lisp_Object val;
11376 if (!SYMBOLP (var))
11377 continue;
11378 val = find_symbol_value (var);
11379 if (MARKERP (val)
11380 && current_buffer == XMARKER (val)->buffer)
11381 return 1;
11383 return 0;
11387 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
11388 has changed. */
11390 static int
11391 overlay_arrows_changed_p (void)
11393 Lisp_Object vlist;
11395 for (vlist = Voverlay_arrow_variable_list;
11396 CONSP (vlist);
11397 vlist = XCDR (vlist))
11399 Lisp_Object var = XCAR (vlist);
11400 Lisp_Object val, pstr;
11402 if (!SYMBOLP (var))
11403 continue;
11404 val = find_symbol_value (var);
11405 if (!MARKERP (val))
11406 continue;
11407 if (! EQ (COERCE_MARKER (val),
11408 Fget (var, Qlast_arrow_position))
11409 || ! (pstr = overlay_arrow_string_or_property (var),
11410 EQ (pstr, Fget (var, Qlast_arrow_string))))
11411 return 1;
11413 return 0;
11416 /* Mark overlay arrows to be updated on next redisplay. */
11418 static void
11419 update_overlay_arrows (int up_to_date)
11421 Lisp_Object vlist;
11423 for (vlist = Voverlay_arrow_variable_list;
11424 CONSP (vlist);
11425 vlist = XCDR (vlist))
11427 Lisp_Object var = XCAR (vlist);
11429 if (!SYMBOLP (var))
11430 continue;
11432 if (up_to_date > 0)
11434 Lisp_Object val = find_symbol_value (var);
11435 Fput (var, Qlast_arrow_position,
11436 COERCE_MARKER (val));
11437 Fput (var, Qlast_arrow_string,
11438 overlay_arrow_string_or_property (var));
11440 else if (up_to_date < 0
11441 || !NILP (Fget (var, Qlast_arrow_position)))
11443 Fput (var, Qlast_arrow_position, Qt);
11444 Fput (var, Qlast_arrow_string, Qt);
11450 /* Return overlay arrow string to display at row.
11451 Return integer (bitmap number) for arrow bitmap in left fringe.
11452 Return nil if no overlay arrow. */
11454 static Lisp_Object
11455 overlay_arrow_at_row (struct it *it, struct glyph_row *row)
11457 Lisp_Object vlist;
11459 for (vlist = Voverlay_arrow_variable_list;
11460 CONSP (vlist);
11461 vlist = XCDR (vlist))
11463 Lisp_Object var = XCAR (vlist);
11464 Lisp_Object val;
11466 if (!SYMBOLP (var))
11467 continue;
11469 val = find_symbol_value (var);
11471 if (MARKERP (val)
11472 && current_buffer == XMARKER (val)->buffer
11473 && (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
11475 if (FRAME_WINDOW_P (it->f)
11476 /* FIXME: if ROW->reversed_p is set, this should test
11477 the right fringe, not the left one. */
11478 && WINDOW_LEFT_FRINGE_WIDTH (it->w) > 0)
11480 #ifdef HAVE_WINDOW_SYSTEM
11481 if (val = Fget (var, Qoverlay_arrow_bitmap), SYMBOLP (val))
11483 int fringe_bitmap;
11484 if ((fringe_bitmap = lookup_fringe_bitmap (val)) != 0)
11485 return make_number (fringe_bitmap);
11487 #endif
11488 return make_number (-1); /* Use default arrow bitmap */
11490 return overlay_arrow_string_or_property (var);
11494 return Qnil;
11497 /* Return 1 if point moved out of or into a composition. Otherwise
11498 return 0. PREV_BUF and PREV_PT are the last point buffer and
11499 position. BUF and PT are the current point buffer and position. */
11502 check_point_in_composition (struct buffer *prev_buf, EMACS_INT prev_pt,
11503 struct buffer *buf, EMACS_INT pt)
11505 EMACS_INT start, end;
11506 Lisp_Object prop;
11507 Lisp_Object buffer;
11509 XSETBUFFER (buffer, buf);
11510 /* Check a composition at the last point if point moved within the
11511 same buffer. */
11512 if (prev_buf == buf)
11514 if (prev_pt == pt)
11515 /* Point didn't move. */
11516 return 0;
11518 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
11519 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
11520 && COMPOSITION_VALID_P (start, end, prop)
11521 && start < prev_pt && end > prev_pt)
11522 /* The last point was within the composition. Return 1 iff
11523 point moved out of the composition. */
11524 return (pt <= start || pt >= end);
11527 /* Check a composition at the current point. */
11528 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
11529 && find_composition (pt, -1, &start, &end, &prop, buffer)
11530 && COMPOSITION_VALID_P (start, end, prop)
11531 && start < pt && end > pt);
11535 /* Reconsider the setting of B->clip_changed which is displayed
11536 in window W. */
11538 static INLINE void
11539 reconsider_clip_changes (struct window *w, struct buffer *b)
11541 if (b->clip_changed
11542 && !NILP (w->window_end_valid)
11543 && w->current_matrix->buffer == b
11544 && w->current_matrix->zv == BUF_ZV (b)
11545 && w->current_matrix->begv == BUF_BEGV (b))
11546 b->clip_changed = 0;
11548 /* If display wasn't paused, and W is not a tool bar window, see if
11549 point has been moved into or out of a composition. In that case,
11550 we set b->clip_changed to 1 to force updating the screen. If
11551 b->clip_changed has already been set to 1, we can skip this
11552 check. */
11553 if (!b->clip_changed
11554 && BUFFERP (w->buffer) && !NILP (w->window_end_valid))
11556 EMACS_INT pt;
11558 if (w == XWINDOW (selected_window))
11559 pt = BUF_PT (current_buffer);
11560 else
11561 pt = marker_position (w->pointm);
11563 if ((w->current_matrix->buffer != XBUFFER (w->buffer)
11564 || pt != XINT (w->last_point))
11565 && check_point_in_composition (w->current_matrix->buffer,
11566 XINT (w->last_point),
11567 XBUFFER (w->buffer), pt))
11568 b->clip_changed = 1;
11573 /* Select FRAME to forward the values of frame-local variables into C
11574 variables so that the redisplay routines can access those values
11575 directly. */
11577 static void
11578 select_frame_for_redisplay (Lisp_Object frame)
11580 Lisp_Object tail, tem;
11581 Lisp_Object old = selected_frame;
11582 struct Lisp_Symbol *sym;
11584 xassert (FRAMEP (frame) && FRAME_LIVE_P (XFRAME (frame)));
11586 selected_frame = frame;
11588 do {
11589 for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail))
11590 if (CONSP (XCAR (tail))
11591 && (tem = XCAR (XCAR (tail)),
11592 SYMBOLP (tem))
11593 && (sym = indirect_variable (XSYMBOL (tem)),
11594 sym->redirect == SYMBOL_LOCALIZED)
11595 && sym->val.blv->frame_local)
11596 /* Use find_symbol_value rather than Fsymbol_value
11597 to avoid an error if it is void. */
11598 find_symbol_value (tem);
11599 } while (!EQ (frame, old) && (frame = old, 1));
11603 #define STOP_POLLING \
11604 do { if (! polling_stopped_here) stop_polling (); \
11605 polling_stopped_here = 1; } while (0)
11607 #define RESUME_POLLING \
11608 do { if (polling_stopped_here) start_polling (); \
11609 polling_stopped_here = 0; } while (0)
11612 /* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
11613 response to any user action; therefore, we should preserve the echo
11614 area. (Actually, our caller does that job.) Perhaps in the future
11615 avoid recentering windows if it is not necessary; currently that
11616 causes some problems. */
11618 static void
11619 redisplay_internal (int preserve_echo_area)
11621 struct window *w = XWINDOW (selected_window);
11622 struct frame *f;
11623 int pause;
11624 int must_finish = 0;
11625 struct text_pos tlbufpos, tlendpos;
11626 int number_of_visible_frames;
11627 int count, count1;
11628 struct frame *sf;
11629 int polling_stopped_here = 0;
11630 Lisp_Object old_frame = selected_frame;
11632 /* Non-zero means redisplay has to consider all windows on all
11633 frames. Zero means, only selected_window is considered. */
11634 int consider_all_windows_p;
11636 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
11638 /* No redisplay if running in batch mode or frame is not yet fully
11639 initialized, or redisplay is explicitly turned off by setting
11640 Vinhibit_redisplay. */
11641 if (FRAME_INITIAL_P (SELECTED_FRAME ())
11642 || !NILP (Vinhibit_redisplay))
11643 return;
11645 /* Don't examine these until after testing Vinhibit_redisplay.
11646 When Emacs is shutting down, perhaps because its connection to
11647 X has dropped, we should not look at them at all. */
11648 f = XFRAME (w->frame);
11649 sf = SELECTED_FRAME ();
11651 if (!f->glyphs_initialized_p)
11652 return;
11654 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS)
11655 if (popup_activated ())
11656 return;
11657 #endif
11659 /* I don't think this happens but let's be paranoid. */
11660 if (redisplaying_p)
11661 return;
11663 /* Record a function that resets redisplaying_p to its old value
11664 when we leave this function. */
11665 count = SPECPDL_INDEX ();
11666 record_unwind_protect (unwind_redisplay,
11667 Fcons (make_number (redisplaying_p), selected_frame));
11668 ++redisplaying_p;
11669 specbind (Qinhibit_free_realized_faces, Qnil);
11672 Lisp_Object tail, frame;
11674 FOR_EACH_FRAME (tail, frame)
11676 struct frame *f = XFRAME (frame);
11677 f->already_hscrolled_p = 0;
11681 retry:
11682 if (!EQ (old_frame, selected_frame)
11683 && FRAME_LIVE_P (XFRAME (old_frame)))
11684 /* When running redisplay, we play a bit fast-and-loose and allow e.g.
11685 selected_frame and selected_window to be temporarily out-of-sync so
11686 when we come back here via `goto retry', we need to resync because we
11687 may need to run Elisp code (via prepare_menu_bars). */
11688 select_frame_for_redisplay (old_frame);
11690 pause = 0;
11691 reconsider_clip_changes (w, current_buffer);
11692 last_escape_glyph_frame = NULL;
11693 last_escape_glyph_face_id = (1 << FACE_ID_BITS);
11694 last_glyphless_glyph_frame = NULL;
11695 last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
11697 /* If new fonts have been loaded that make a glyph matrix adjustment
11698 necessary, do it. */
11699 if (fonts_changed_p)
11701 adjust_glyphs (NULL);
11702 ++windows_or_buffers_changed;
11703 fonts_changed_p = 0;
11706 /* If face_change_count is non-zero, init_iterator will free all
11707 realized faces, which includes the faces referenced from current
11708 matrices. So, we can't reuse current matrices in this case. */
11709 if (face_change_count)
11710 ++windows_or_buffers_changed;
11712 if ((FRAME_TERMCAP_P (sf) || FRAME_MSDOS_P (sf))
11713 && FRAME_TTY (sf)->previous_frame != sf)
11715 /* Since frames on a single ASCII terminal share the same
11716 display area, displaying a different frame means redisplay
11717 the whole thing. */
11718 windows_or_buffers_changed++;
11719 SET_FRAME_GARBAGED (sf);
11720 #ifndef DOS_NT
11721 set_tty_color_mode (FRAME_TTY (sf), sf);
11722 #endif
11723 FRAME_TTY (sf)->previous_frame = sf;
11726 /* Set the visible flags for all frames. Do this before checking
11727 for resized or garbaged frames; they want to know if their frames
11728 are visible. See the comment in frame.h for
11729 FRAME_SAMPLE_VISIBILITY. */
11731 Lisp_Object tail, frame;
11733 number_of_visible_frames = 0;
11735 FOR_EACH_FRAME (tail, frame)
11737 struct frame *f = XFRAME (frame);
11739 FRAME_SAMPLE_VISIBILITY (f);
11740 if (FRAME_VISIBLE_P (f))
11741 ++number_of_visible_frames;
11742 clear_desired_matrices (f);
11746 /* Notice any pending interrupt request to change frame size. */
11747 do_pending_window_change (1);
11749 /* Clear frames marked as garbaged. */
11750 if (frame_garbaged)
11751 clear_garbaged_frames ();
11753 /* Build menubar and tool-bar items. */
11754 if (NILP (Vmemory_full))
11755 prepare_menu_bars ();
11757 if (windows_or_buffers_changed)
11758 update_mode_lines++;
11760 /* Detect case that we need to write or remove a star in the mode line. */
11761 if ((SAVE_MODIFF < MODIFF) != !NILP (w->last_had_star))
11763 w->update_mode_line = Qt;
11764 if (buffer_shared > 1)
11765 update_mode_lines++;
11768 /* Avoid invocation of point motion hooks by `current_column' below. */
11769 count1 = SPECPDL_INDEX ();
11770 specbind (Qinhibit_point_motion_hooks, Qt);
11772 /* If %c is in the mode line, update it if needed. */
11773 if (!NILP (w->column_number_displayed)
11774 /* This alternative quickly identifies a common case
11775 where no change is needed. */
11776 && !(PT == XFASTINT (w->last_point)
11777 && XFASTINT (w->last_modified) >= MODIFF
11778 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
11779 && (XFASTINT (w->column_number_displayed)
11780 != (int) current_column ())) /* iftc */
11781 w->update_mode_line = Qt;
11783 unbind_to (count1, Qnil);
11785 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
11787 /* The variable buffer_shared is set in redisplay_window and
11788 indicates that we redisplay a buffer in different windows. See
11789 there. */
11790 consider_all_windows_p = (update_mode_lines || buffer_shared > 1
11791 || cursor_type_changed);
11793 /* If specs for an arrow have changed, do thorough redisplay
11794 to ensure we remove any arrow that should no longer exist. */
11795 if (overlay_arrows_changed_p ())
11796 consider_all_windows_p = windows_or_buffers_changed = 1;
11798 /* Normally the message* functions will have already displayed and
11799 updated the echo area, but the frame may have been trashed, or
11800 the update may have been preempted, so display the echo area
11801 again here. Checking message_cleared_p captures the case that
11802 the echo area should be cleared. */
11803 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
11804 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
11805 || (message_cleared_p
11806 && minibuf_level == 0
11807 /* If the mini-window is currently selected, this means the
11808 echo-area doesn't show through. */
11809 && !MINI_WINDOW_P (XWINDOW (selected_window))))
11811 int window_height_changed_p = echo_area_display (0);
11812 must_finish = 1;
11814 /* If we don't display the current message, don't clear the
11815 message_cleared_p flag, because, if we did, we wouldn't clear
11816 the echo area in the next redisplay which doesn't preserve
11817 the echo area. */
11818 if (!display_last_displayed_message_p)
11819 message_cleared_p = 0;
11821 if (fonts_changed_p)
11822 goto retry;
11823 else if (window_height_changed_p)
11825 consider_all_windows_p = 1;
11826 ++update_mode_lines;
11827 ++windows_or_buffers_changed;
11829 /* If window configuration was changed, frames may have been
11830 marked garbaged. Clear them or we will experience
11831 surprises wrt scrolling. */
11832 if (frame_garbaged)
11833 clear_garbaged_frames ();
11836 else if (EQ (selected_window, minibuf_window)
11837 && (current_buffer->clip_changed
11838 || XFASTINT (w->last_modified) < MODIFF
11839 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
11840 && resize_mini_window (w, 0))
11842 /* Resized active mini-window to fit the size of what it is
11843 showing if its contents might have changed. */
11844 must_finish = 1;
11845 /* FIXME: this causes all frames to be updated, which seems unnecessary
11846 since only the current frame needs to be considered. This function needs
11847 to be rewritten with two variables, consider_all_windows and
11848 consider_all_frames. */
11849 consider_all_windows_p = 1;
11850 ++windows_or_buffers_changed;
11851 ++update_mode_lines;
11853 /* If window configuration was changed, frames may have been
11854 marked garbaged. Clear them or we will experience
11855 surprises wrt scrolling. */
11856 if (frame_garbaged)
11857 clear_garbaged_frames ();
11861 /* If showing the region, and mark has changed, we must redisplay
11862 the whole window. The assignment to this_line_start_pos prevents
11863 the optimization directly below this if-statement. */
11864 if (((!NILP (Vtransient_mark_mode)
11865 && !NILP (XBUFFER (w->buffer)->mark_active))
11866 != !NILP (w->region_showing))
11867 || (!NILP (w->region_showing)
11868 && !EQ (w->region_showing,
11869 Fmarker_position (XBUFFER (w->buffer)->mark))))
11870 CHARPOS (this_line_start_pos) = 0;
11872 /* Optimize the case that only the line containing the cursor in the
11873 selected window has changed. Variables starting with this_ are
11874 set in display_line and record information about the line
11875 containing the cursor. */
11876 tlbufpos = this_line_start_pos;
11877 tlendpos = this_line_end_pos;
11878 if (!consider_all_windows_p
11879 && CHARPOS (tlbufpos) > 0
11880 && NILP (w->update_mode_line)
11881 && !current_buffer->clip_changed
11882 && !current_buffer->prevent_redisplay_optimizations_p
11883 && FRAME_VISIBLE_P (XFRAME (w->frame))
11884 && !FRAME_OBSCURED_P (XFRAME (w->frame))
11885 /* Make sure recorded data applies to current buffer, etc. */
11886 && this_line_buffer == current_buffer
11887 && current_buffer == XBUFFER (w->buffer)
11888 && NILP (w->force_start)
11889 && NILP (w->optional_new_start)
11890 /* Point must be on the line that we have info recorded about. */
11891 && PT >= CHARPOS (tlbufpos)
11892 && PT <= Z - CHARPOS (tlendpos)
11893 /* All text outside that line, including its final newline,
11894 must be unchanged. */
11895 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
11896 CHARPOS (tlendpos)))
11898 if (CHARPOS (tlbufpos) > BEGV
11899 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
11900 && (CHARPOS (tlbufpos) == ZV
11901 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
11902 /* Former continuation line has disappeared by becoming empty. */
11903 goto cancel;
11904 else if (XFASTINT (w->last_modified) < MODIFF
11905 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF
11906 || MINI_WINDOW_P (w))
11908 /* We have to handle the case of continuation around a
11909 wide-column character (see the comment in indent.c around
11910 line 1340).
11912 For instance, in the following case:
11914 -------- Insert --------
11915 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
11916 J_I_ ==> J_I_ `^^' are cursors.
11917 ^^ ^^
11918 -------- --------
11920 As we have to redraw the line above, we cannot use this
11921 optimization. */
11923 struct it it;
11924 int line_height_before = this_line_pixel_height;
11926 /* Note that start_display will handle the case that the
11927 line starting at tlbufpos is a continuation line. */
11928 start_display (&it, w, tlbufpos);
11930 /* Implementation note: It this still necessary? */
11931 if (it.current_x != this_line_start_x)
11932 goto cancel;
11934 TRACE ((stderr, "trying display optimization 1\n"));
11935 w->cursor.vpos = -1;
11936 overlay_arrow_seen = 0;
11937 it.vpos = this_line_vpos;
11938 it.current_y = this_line_y;
11939 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
11940 display_line (&it);
11942 /* If line contains point, is not continued,
11943 and ends at same distance from eob as before, we win. */
11944 if (w->cursor.vpos >= 0
11945 /* Line is not continued, otherwise this_line_start_pos
11946 would have been set to 0 in display_line. */
11947 && CHARPOS (this_line_start_pos)
11948 /* Line ends as before. */
11949 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
11950 /* Line has same height as before. Otherwise other lines
11951 would have to be shifted up or down. */
11952 && this_line_pixel_height == line_height_before)
11954 /* If this is not the window's last line, we must adjust
11955 the charstarts of the lines below. */
11956 if (it.current_y < it.last_visible_y)
11958 struct glyph_row *row
11959 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
11960 EMACS_INT delta, delta_bytes;
11962 /* We used to distinguish between two cases here,
11963 conditioned by Z - CHARPOS (tlendpos) == ZV, for
11964 when the line ends in a newline or the end of the
11965 buffer's accessible portion. But both cases did
11966 the same, so they were collapsed. */
11967 delta = (Z
11968 - CHARPOS (tlendpos)
11969 - MATRIX_ROW_START_CHARPOS (row));
11970 delta_bytes = (Z_BYTE
11971 - BYTEPOS (tlendpos)
11972 - MATRIX_ROW_START_BYTEPOS (row));
11974 increment_matrix_positions (w->current_matrix,
11975 this_line_vpos + 1,
11976 w->current_matrix->nrows,
11977 delta, delta_bytes);
11980 /* If this row displays text now but previously didn't,
11981 or vice versa, w->window_end_vpos may have to be
11982 adjusted. */
11983 if ((it.glyph_row - 1)->displays_text_p)
11985 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
11986 XSETINT (w->window_end_vpos, this_line_vpos);
11988 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
11989 && this_line_vpos > 0)
11990 XSETINT (w->window_end_vpos, this_line_vpos - 1);
11991 w->window_end_valid = Qnil;
11993 /* Update hint: No need to try to scroll in update_window. */
11994 w->desired_matrix->no_scrolling_p = 1;
11996 #if GLYPH_DEBUG
11997 *w->desired_matrix->method = 0;
11998 debug_method_add (w, "optimization 1");
11999 #endif
12000 #ifdef HAVE_WINDOW_SYSTEM
12001 update_window_fringes (w, 0);
12002 #endif
12003 goto update;
12005 else
12006 goto cancel;
12008 else if (/* Cursor position hasn't changed. */
12009 PT == XFASTINT (w->last_point)
12010 /* Make sure the cursor was last displayed
12011 in this window. Otherwise we have to reposition it. */
12012 && 0 <= w->cursor.vpos
12013 && WINDOW_TOTAL_LINES (w) > w->cursor.vpos)
12015 if (!must_finish)
12017 do_pending_window_change (1);
12019 /* We used to always goto end_of_redisplay here, but this
12020 isn't enough if we have a blinking cursor. */
12021 if (w->cursor_off_p == w->last_cursor_off_p)
12022 goto end_of_redisplay;
12024 goto update;
12026 /* If highlighting the region, or if the cursor is in the echo area,
12027 then we can't just move the cursor. */
12028 else if (! (!NILP (Vtransient_mark_mode)
12029 && !NILP (current_buffer->mark_active))
12030 && (EQ (selected_window, current_buffer->last_selected_window)
12031 || highlight_nonselected_windows)
12032 && NILP (w->region_showing)
12033 && NILP (Vshow_trailing_whitespace)
12034 && !cursor_in_echo_area)
12036 struct it it;
12037 struct glyph_row *row;
12039 /* Skip from tlbufpos to PT and see where it is. Note that
12040 PT may be in invisible text. If so, we will end at the
12041 next visible position. */
12042 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
12043 NULL, DEFAULT_FACE_ID);
12044 it.current_x = this_line_start_x;
12045 it.current_y = this_line_y;
12046 it.vpos = this_line_vpos;
12048 /* The call to move_it_to stops in front of PT, but
12049 moves over before-strings. */
12050 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
12052 if (it.vpos == this_line_vpos
12053 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
12054 row->enabled_p))
12056 xassert (this_line_vpos == it.vpos);
12057 xassert (this_line_y == it.current_y);
12058 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
12059 #if GLYPH_DEBUG
12060 *w->desired_matrix->method = 0;
12061 debug_method_add (w, "optimization 3");
12062 #endif
12063 goto update;
12065 else
12066 goto cancel;
12069 cancel:
12070 /* Text changed drastically or point moved off of line. */
12071 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
12074 CHARPOS (this_line_start_pos) = 0;
12075 consider_all_windows_p |= buffer_shared > 1;
12076 ++clear_face_cache_count;
12077 #ifdef HAVE_WINDOW_SYSTEM
12078 ++clear_image_cache_count;
12079 #endif
12081 /* Build desired matrices, and update the display. If
12082 consider_all_windows_p is non-zero, do it for all windows on all
12083 frames. Otherwise do it for selected_window, only. */
12085 if (consider_all_windows_p)
12087 Lisp_Object tail, frame;
12089 FOR_EACH_FRAME (tail, frame)
12090 XFRAME (frame)->updated_p = 0;
12092 /* Recompute # windows showing selected buffer. This will be
12093 incremented each time such a window is displayed. */
12094 buffer_shared = 0;
12096 FOR_EACH_FRAME (tail, frame)
12098 struct frame *f = XFRAME (frame);
12100 if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf)
12102 if (! EQ (frame, selected_frame))
12103 /* Select the frame, for the sake of frame-local
12104 variables. */
12105 select_frame_for_redisplay (frame);
12107 /* Mark all the scroll bars to be removed; we'll redeem
12108 the ones we want when we redisplay their windows. */
12109 if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
12110 FRAME_TERMINAL (f)->condemn_scroll_bars_hook (f);
12112 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
12113 redisplay_windows (FRAME_ROOT_WINDOW (f));
12115 /* The X error handler may have deleted that frame. */
12116 if (!FRAME_LIVE_P (f))
12117 continue;
12119 /* Any scroll bars which redisplay_windows should have
12120 nuked should now go away. */
12121 if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
12122 FRAME_TERMINAL (f)->judge_scroll_bars_hook (f);
12124 /* If fonts changed, display again. */
12125 /* ??? rms: I suspect it is a mistake to jump all the way
12126 back to retry here. It should just retry this frame. */
12127 if (fonts_changed_p)
12128 goto retry;
12130 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
12132 /* See if we have to hscroll. */
12133 if (!f->already_hscrolled_p)
12135 f->already_hscrolled_p = 1;
12136 if (hscroll_windows (f->root_window))
12137 goto retry;
12140 /* Prevent various kinds of signals during display
12141 update. stdio is not robust about handling
12142 signals, which can cause an apparent I/O
12143 error. */
12144 if (interrupt_input)
12145 unrequest_sigio ();
12146 STOP_POLLING;
12148 /* Update the display. */
12149 set_window_update_flags (XWINDOW (f->root_window), 1);
12150 pause |= update_frame (f, 0, 0);
12151 f->updated_p = 1;
12156 if (!EQ (old_frame, selected_frame)
12157 && FRAME_LIVE_P (XFRAME (old_frame)))
12158 /* We played a bit fast-and-loose above and allowed selected_frame
12159 and selected_window to be temporarily out-of-sync but let's make
12160 sure this stays contained. */
12161 select_frame_for_redisplay (old_frame);
12162 eassert (EQ (XFRAME (selected_frame)->selected_window, selected_window));
12164 if (!pause)
12166 /* Do the mark_window_display_accurate after all windows have
12167 been redisplayed because this call resets flags in buffers
12168 which are needed for proper redisplay. */
12169 FOR_EACH_FRAME (tail, frame)
12171 struct frame *f = XFRAME (frame);
12172 if (f->updated_p)
12174 mark_window_display_accurate (f->root_window, 1);
12175 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
12176 FRAME_TERMINAL (f)->frame_up_to_date_hook (f);
12181 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
12183 Lisp_Object mini_window;
12184 struct frame *mini_frame;
12186 displayed_buffer = XBUFFER (XWINDOW (selected_window)->buffer);
12187 /* Use list_of_error, not Qerror, so that
12188 we catch only errors and don't run the debugger. */
12189 internal_condition_case_1 (redisplay_window_1, selected_window,
12190 list_of_error,
12191 redisplay_window_error);
12193 /* Compare desired and current matrices, perform output. */
12195 update:
12196 /* If fonts changed, display again. */
12197 if (fonts_changed_p)
12198 goto retry;
12200 /* Prevent various kinds of signals during display update.
12201 stdio is not robust about handling signals,
12202 which can cause an apparent I/O error. */
12203 if (interrupt_input)
12204 unrequest_sigio ();
12205 STOP_POLLING;
12207 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
12209 if (hscroll_windows (selected_window))
12210 goto retry;
12212 XWINDOW (selected_window)->must_be_updated_p = 1;
12213 pause = update_frame (sf, 0, 0);
12216 /* We may have called echo_area_display at the top of this
12217 function. If the echo area is on another frame, that may
12218 have put text on a frame other than the selected one, so the
12219 above call to update_frame would not have caught it. Catch
12220 it here. */
12221 mini_window = FRAME_MINIBUF_WINDOW (sf);
12222 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
12224 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
12226 XWINDOW (mini_window)->must_be_updated_p = 1;
12227 pause |= update_frame (mini_frame, 0, 0);
12228 if (!pause && hscroll_windows (mini_window))
12229 goto retry;
12233 /* If display was paused because of pending input, make sure we do a
12234 thorough update the next time. */
12235 if (pause)
12237 /* Prevent the optimization at the beginning of
12238 redisplay_internal that tries a single-line update of the
12239 line containing the cursor in the selected window. */
12240 CHARPOS (this_line_start_pos) = 0;
12242 /* Let the overlay arrow be updated the next time. */
12243 update_overlay_arrows (0);
12245 /* If we pause after scrolling, some rows in the current
12246 matrices of some windows are not valid. */
12247 if (!WINDOW_FULL_WIDTH_P (w)
12248 && !FRAME_WINDOW_P (XFRAME (w->frame)))
12249 update_mode_lines = 1;
12251 else
12253 if (!consider_all_windows_p)
12255 /* This has already been done above if
12256 consider_all_windows_p is set. */
12257 mark_window_display_accurate_1 (w, 1);
12259 /* Say overlay arrows are up to date. */
12260 update_overlay_arrows (1);
12262 if (FRAME_TERMINAL (sf)->frame_up_to_date_hook != 0)
12263 FRAME_TERMINAL (sf)->frame_up_to_date_hook (sf);
12266 update_mode_lines = 0;
12267 windows_or_buffers_changed = 0;
12268 cursor_type_changed = 0;
12271 /* Start SIGIO interrupts coming again. Having them off during the
12272 code above makes it less likely one will discard output, but not
12273 impossible, since there might be stuff in the system buffer here.
12274 But it is much hairier to try to do anything about that. */
12275 if (interrupt_input)
12276 request_sigio ();
12277 RESUME_POLLING;
12279 /* If a frame has become visible which was not before, redisplay
12280 again, so that we display it. Expose events for such a frame
12281 (which it gets when becoming visible) don't call the parts of
12282 redisplay constructing glyphs, so simply exposing a frame won't
12283 display anything in this case. So, we have to display these
12284 frames here explicitly. */
12285 if (!pause)
12287 Lisp_Object tail, frame;
12288 int new_count = 0;
12290 FOR_EACH_FRAME (tail, frame)
12292 int this_is_visible = 0;
12294 if (XFRAME (frame)->visible)
12295 this_is_visible = 1;
12296 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
12297 if (XFRAME (frame)->visible)
12298 this_is_visible = 1;
12300 if (this_is_visible)
12301 new_count++;
12304 if (new_count != number_of_visible_frames)
12305 windows_or_buffers_changed++;
12308 /* Change frame size now if a change is pending. */
12309 do_pending_window_change (1);
12311 /* If we just did a pending size change, or have additional
12312 visible frames, redisplay again. */
12313 if (windows_or_buffers_changed && !pause)
12314 goto retry;
12316 /* Clear the face and image caches.
12318 We used to do this only if consider_all_windows_p. But the cache
12319 needs to be cleared if a timer creates images in the current
12320 buffer (e.g. the test case in Bug#6230). */
12322 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
12324 clear_face_cache (0);
12325 clear_face_cache_count = 0;
12328 #ifdef HAVE_WINDOW_SYSTEM
12329 if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT)
12331 clear_image_caches (Qnil);
12332 clear_image_cache_count = 0;
12334 #endif /* HAVE_WINDOW_SYSTEM */
12336 end_of_redisplay:
12337 unbind_to (count, Qnil);
12338 RESUME_POLLING;
12342 /* Redisplay, but leave alone any recent echo area message unless
12343 another message has been requested in its place.
12345 This is useful in situations where you need to redisplay but no
12346 user action has occurred, making it inappropriate for the message
12347 area to be cleared. See tracking_off and
12348 wait_reading_process_output for examples of these situations.
12350 FROM_WHERE is an integer saying from where this function was
12351 called. This is useful for debugging. */
12353 void
12354 redisplay_preserve_echo_area (int from_where)
12356 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
12358 if (!NILP (echo_area_buffer[1]))
12360 /* We have a previously displayed message, but no current
12361 message. Redisplay the previous message. */
12362 display_last_displayed_message_p = 1;
12363 redisplay_internal (1);
12364 display_last_displayed_message_p = 0;
12366 else
12367 redisplay_internal (1);
12369 if (FRAME_RIF (SELECTED_FRAME ()) != NULL
12370 && FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
12371 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (NULL);
12375 /* Function registered with record_unwind_protect in
12376 redisplay_internal. Reset redisplaying_p to the value it had
12377 before redisplay_internal was called, and clear
12378 prevent_freeing_realized_faces_p. It also selects the previously
12379 selected frame, unless it has been deleted (by an X connection
12380 failure during redisplay, for example). */
12382 static Lisp_Object
12383 unwind_redisplay (Lisp_Object val)
12385 Lisp_Object old_redisplaying_p, old_frame;
12387 old_redisplaying_p = XCAR (val);
12388 redisplaying_p = XFASTINT (old_redisplaying_p);
12389 old_frame = XCDR (val);
12390 if (! EQ (old_frame, selected_frame)
12391 && FRAME_LIVE_P (XFRAME (old_frame)))
12392 select_frame_for_redisplay (old_frame);
12393 return Qnil;
12397 /* Mark the display of window W as accurate or inaccurate. If
12398 ACCURATE_P is non-zero mark display of W as accurate. If
12399 ACCURATE_P is zero, arrange for W to be redisplayed the next time
12400 redisplay_internal is called. */
12402 static void
12403 mark_window_display_accurate_1 (struct window *w, int accurate_p)
12405 if (BUFFERP (w->buffer))
12407 struct buffer *b = XBUFFER (w->buffer);
12409 w->last_modified
12410 = make_number (accurate_p ? BUF_MODIFF (b) : 0);
12411 w->last_overlay_modified
12412 = make_number (accurate_p ? BUF_OVERLAY_MODIFF (b) : 0);
12413 w->last_had_star
12414 = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b) ? Qt : Qnil;
12416 if (accurate_p)
12418 b->clip_changed = 0;
12419 b->prevent_redisplay_optimizations_p = 0;
12421 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
12422 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
12423 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
12424 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
12426 w->current_matrix->buffer = b;
12427 w->current_matrix->begv = BUF_BEGV (b);
12428 w->current_matrix->zv = BUF_ZV (b);
12430 w->last_cursor = w->cursor;
12431 w->last_cursor_off_p = w->cursor_off_p;
12433 if (w == XWINDOW (selected_window))
12434 w->last_point = make_number (BUF_PT (b));
12435 else
12436 w->last_point = make_number (XMARKER (w->pointm)->charpos);
12440 if (accurate_p)
12442 w->window_end_valid = w->buffer;
12443 w->update_mode_line = Qnil;
12448 /* Mark the display of windows in the window tree rooted at WINDOW as
12449 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
12450 windows as accurate. If ACCURATE_P is zero, arrange for windows to
12451 be redisplayed the next time redisplay_internal is called. */
12453 void
12454 mark_window_display_accurate (Lisp_Object window, int accurate_p)
12456 struct window *w;
12458 for (; !NILP (window); window = w->next)
12460 w = XWINDOW (window);
12461 mark_window_display_accurate_1 (w, accurate_p);
12463 if (!NILP (w->vchild))
12464 mark_window_display_accurate (w->vchild, accurate_p);
12465 if (!NILP (w->hchild))
12466 mark_window_display_accurate (w->hchild, accurate_p);
12469 if (accurate_p)
12471 update_overlay_arrows (1);
12473 else
12475 /* Force a thorough redisplay the next time by setting
12476 last_arrow_position and last_arrow_string to t, which is
12477 unequal to any useful value of Voverlay_arrow_... */
12478 update_overlay_arrows (-1);
12483 /* Return value in display table DP (Lisp_Char_Table *) for character
12484 C. Since a display table doesn't have any parent, we don't have to
12485 follow parent. Do not call this function directly but use the
12486 macro DISP_CHAR_VECTOR. */
12488 Lisp_Object
12489 disp_char_vector (struct Lisp_Char_Table *dp, int c)
12491 Lisp_Object val;
12493 if (ASCII_CHAR_P (c))
12495 val = dp->ascii;
12496 if (SUB_CHAR_TABLE_P (val))
12497 val = XSUB_CHAR_TABLE (val)->contents[c];
12499 else
12501 Lisp_Object table;
12503 XSETCHAR_TABLE (table, dp);
12504 val = char_table_ref (table, c);
12506 if (NILP (val))
12507 val = dp->defalt;
12508 return val;
12513 /***********************************************************************
12514 Window Redisplay
12515 ***********************************************************************/
12517 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
12519 static void
12520 redisplay_windows (Lisp_Object window)
12522 while (!NILP (window))
12524 struct window *w = XWINDOW (window);
12526 if (!NILP (w->hchild))
12527 redisplay_windows (w->hchild);
12528 else if (!NILP (w->vchild))
12529 redisplay_windows (w->vchild);
12530 else if (!NILP (w->buffer))
12532 displayed_buffer = XBUFFER (w->buffer);
12533 /* Use list_of_error, not Qerror, so that
12534 we catch only errors and don't run the debugger. */
12535 internal_condition_case_1 (redisplay_window_0, window,
12536 list_of_error,
12537 redisplay_window_error);
12540 window = w->next;
12544 static Lisp_Object
12545 redisplay_window_error (Lisp_Object ignore)
12547 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
12548 return Qnil;
12551 static Lisp_Object
12552 redisplay_window_0 (Lisp_Object window)
12554 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
12555 redisplay_window (window, 0);
12556 return Qnil;
12559 static Lisp_Object
12560 redisplay_window_1 (Lisp_Object window)
12562 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
12563 redisplay_window (window, 1);
12564 return Qnil;
12568 /* Increment GLYPH until it reaches END or CONDITION fails while
12569 adding (GLYPH)->pixel_width to X. */
12571 #define SKIP_GLYPHS(glyph, end, x, condition) \
12572 do \
12574 (x) += (glyph)->pixel_width; \
12575 ++(glyph); \
12577 while ((glyph) < (end) && (condition))
12580 /* Set cursor position of W. PT is assumed to be displayed in ROW.
12581 DELTA and DELTA_BYTES are the numbers of characters and bytes by
12582 which positions recorded in ROW differ from current buffer
12583 positions.
12585 Return 0 if cursor is not on this row, 1 otherwise. */
12588 set_cursor_from_row (struct window *w, struct glyph_row *row,
12589 struct glyph_matrix *matrix,
12590 EMACS_INT delta, EMACS_INT delta_bytes,
12591 int dy, int dvpos)
12593 struct glyph *glyph = row->glyphs[TEXT_AREA];
12594 struct glyph *end = glyph + row->used[TEXT_AREA];
12595 struct glyph *cursor = NULL;
12596 /* The last known character position in row. */
12597 EMACS_INT last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
12598 int x = row->x;
12599 EMACS_INT pt_old = PT - delta;
12600 EMACS_INT pos_before = MATRIX_ROW_START_CHARPOS (row) + delta;
12601 EMACS_INT pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
12602 struct glyph *glyph_before = glyph - 1, *glyph_after = end;
12603 /* A glyph beyond the edge of TEXT_AREA which we should never
12604 touch. */
12605 struct glyph *glyphs_end = end;
12606 /* Non-zero means we've found a match for cursor position, but that
12607 glyph has the avoid_cursor_p flag set. */
12608 int match_with_avoid_cursor = 0;
12609 /* Non-zero means we've seen at least one glyph that came from a
12610 display string. */
12611 int string_seen = 0;
12612 /* Largest and smalles buffer positions seen so far during scan of
12613 glyph row. */
12614 EMACS_INT bpos_max = pos_before;
12615 EMACS_INT bpos_min = pos_after;
12616 /* Last buffer position covered by an overlay string with an integer
12617 `cursor' property. */
12618 EMACS_INT bpos_covered = 0;
12620 /* Skip over glyphs not having an object at the start and the end of
12621 the row. These are special glyphs like truncation marks on
12622 terminal frames. */
12623 if (row->displays_text_p)
12625 if (!row->reversed_p)
12627 while (glyph < end
12628 && INTEGERP (glyph->object)
12629 && glyph->charpos < 0)
12631 x += glyph->pixel_width;
12632 ++glyph;
12634 while (end > glyph
12635 && INTEGERP ((end - 1)->object)
12636 /* CHARPOS is zero for blanks and stretch glyphs
12637 inserted by extend_face_to_end_of_line. */
12638 && (end - 1)->charpos <= 0)
12639 --end;
12640 glyph_before = glyph - 1;
12641 glyph_after = end;
12643 else
12645 struct glyph *g;
12647 /* If the glyph row is reversed, we need to process it from back
12648 to front, so swap the edge pointers. */
12649 glyphs_end = end = glyph - 1;
12650 glyph += row->used[TEXT_AREA] - 1;
12652 while (glyph > end + 1
12653 && INTEGERP (glyph->object)
12654 && glyph->charpos < 0)
12656 --glyph;
12657 x -= glyph->pixel_width;
12659 if (INTEGERP (glyph->object) && glyph->charpos < 0)
12660 --glyph;
12661 /* By default, in reversed rows we put the cursor on the
12662 rightmost (first in the reading order) glyph. */
12663 for (g = end + 1; g < glyph; g++)
12664 x += g->pixel_width;
12665 while (end < glyph
12666 && INTEGERP ((end + 1)->object)
12667 && (end + 1)->charpos <= 0)
12668 ++end;
12669 glyph_before = glyph + 1;
12670 glyph_after = end;
12673 else if (row->reversed_p)
12675 /* In R2L rows that don't display text, put the cursor on the
12676 rightmost glyph. Case in point: an empty last line that is
12677 part of an R2L paragraph. */
12678 cursor = end - 1;
12679 /* Avoid placing the cursor on the last glyph of the row, where
12680 on terminal frames we hold the vertical border between
12681 adjacent windows. */
12682 if (!FRAME_WINDOW_P (WINDOW_XFRAME (w))
12683 && !WINDOW_RIGHTMOST_P (w)
12684 && cursor == row->glyphs[LAST_AREA] - 1)
12685 cursor--;
12686 x = -1; /* will be computed below, at label compute_x */
12689 /* Step 1: Try to find the glyph whose character position
12690 corresponds to point. If that's not possible, find 2 glyphs
12691 whose character positions are the closest to point, one before
12692 point, the other after it. */
12693 if (!row->reversed_p)
12694 while (/* not marched to end of glyph row */
12695 glyph < end
12696 /* glyph was not inserted by redisplay for internal purposes */
12697 && !INTEGERP (glyph->object))
12699 if (BUFFERP (glyph->object))
12701 EMACS_INT dpos = glyph->charpos - pt_old;
12703 if (glyph->charpos > bpos_max)
12704 bpos_max = glyph->charpos;
12705 if (glyph->charpos < bpos_min)
12706 bpos_min = glyph->charpos;
12707 if (!glyph->avoid_cursor_p)
12709 /* If we hit point, we've found the glyph on which to
12710 display the cursor. */
12711 if (dpos == 0)
12713 match_with_avoid_cursor = 0;
12714 break;
12716 /* See if we've found a better approximation to
12717 POS_BEFORE or to POS_AFTER. Note that we want the
12718 first (leftmost) glyph of all those that are the
12719 closest from below, and the last (rightmost) of all
12720 those from above. */
12721 if (0 > dpos && dpos > pos_before - pt_old)
12723 pos_before = glyph->charpos;
12724 glyph_before = glyph;
12726 else if (0 < dpos && dpos <= pos_after - pt_old)
12728 pos_after = glyph->charpos;
12729 glyph_after = glyph;
12732 else if (dpos == 0)
12733 match_with_avoid_cursor = 1;
12735 else if (STRINGP (glyph->object))
12737 Lisp_Object chprop;
12738 EMACS_INT glyph_pos = glyph->charpos;
12740 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
12741 glyph->object);
12742 if (INTEGERP (chprop))
12744 bpos_covered = bpos_max + XINT (chprop);
12745 /* If the `cursor' property covers buffer positions up
12746 to and including point, we should display cursor on
12747 this glyph. Note that overlays and text properties
12748 with string values stop bidi reordering, so every
12749 buffer position to the left of the string is always
12750 smaller than any position to the right of the
12751 string. Therefore, if a `cursor' property on one
12752 of the string's characters has an integer value, we
12753 will break out of the loop below _before_ we get to
12754 the position match above. IOW, integer values of
12755 the `cursor' property override the "exact match for
12756 point" strategy of positioning the cursor. */
12757 /* Implementation note: bpos_max == pt_old when, e.g.,
12758 we are in an empty line, where bpos_max is set to
12759 MATRIX_ROW_START_CHARPOS, see above. */
12760 if (bpos_max <= pt_old && bpos_covered >= pt_old)
12762 cursor = glyph;
12763 break;
12767 string_seen = 1;
12769 x += glyph->pixel_width;
12770 ++glyph;
12772 else if (glyph > end) /* row is reversed */
12773 while (!INTEGERP (glyph->object))
12775 if (BUFFERP (glyph->object))
12777 EMACS_INT dpos = glyph->charpos - pt_old;
12779 if (glyph->charpos > bpos_max)
12780 bpos_max = glyph->charpos;
12781 if (glyph->charpos < bpos_min)
12782 bpos_min = glyph->charpos;
12783 if (!glyph->avoid_cursor_p)
12785 if (dpos == 0)
12787 match_with_avoid_cursor = 0;
12788 break;
12790 if (0 > dpos && dpos > pos_before - pt_old)
12792 pos_before = glyph->charpos;
12793 glyph_before = glyph;
12795 else if (0 < dpos && dpos <= pos_after - pt_old)
12797 pos_after = glyph->charpos;
12798 glyph_after = glyph;
12801 else if (dpos == 0)
12802 match_with_avoid_cursor = 1;
12804 else if (STRINGP (glyph->object))
12806 Lisp_Object chprop;
12807 EMACS_INT glyph_pos = glyph->charpos;
12809 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
12810 glyph->object);
12811 if (INTEGERP (chprop))
12813 bpos_covered = bpos_max + XINT (chprop);
12814 /* If the `cursor' property covers buffer positions up
12815 to and including point, we should display cursor on
12816 this glyph. */
12817 if (bpos_max <= pt_old && bpos_covered >= pt_old)
12819 cursor = glyph;
12820 break;
12823 string_seen = 1;
12825 --glyph;
12826 if (glyph == glyphs_end) /* don't dereference outside TEXT_AREA */
12828 x--; /* can't use any pixel_width */
12829 break;
12831 x -= glyph->pixel_width;
12834 /* Step 2: If we didn't find an exact match for point, we need to
12835 look for a proper place to put the cursor among glyphs between
12836 GLYPH_BEFORE and GLYPH_AFTER. */
12837 if (!((row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
12838 && BUFFERP (glyph->object) && glyph->charpos == pt_old)
12839 && bpos_covered < pt_old)
12841 /* An empty line has a single glyph whose OBJECT is zero and
12842 whose CHARPOS is the position of a newline on that line.
12843 Note that on a TTY, there are more glyphs after that, which
12844 were produced by extend_face_to_end_of_line, but their
12845 CHARPOS is zero or negative. */
12846 int empty_line_p =
12847 (row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
12848 && INTEGERP (glyph->object) && glyph->charpos > 0;
12850 if (row->ends_in_ellipsis_p && pos_after == last_pos)
12852 EMACS_INT ellipsis_pos;
12854 /* Scan back over the ellipsis glyphs. */
12855 if (!row->reversed_p)
12857 ellipsis_pos = (glyph - 1)->charpos;
12858 while (glyph > row->glyphs[TEXT_AREA]
12859 && (glyph - 1)->charpos == ellipsis_pos)
12860 glyph--, x -= glyph->pixel_width;
12861 /* That loop always goes one position too far, including
12862 the glyph before the ellipsis. So scan forward over
12863 that one. */
12864 x += glyph->pixel_width;
12865 glyph++;
12867 else /* row is reversed */
12869 ellipsis_pos = (glyph + 1)->charpos;
12870 while (glyph < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
12871 && (glyph + 1)->charpos == ellipsis_pos)
12872 glyph++, x += glyph->pixel_width;
12873 x -= glyph->pixel_width;
12874 glyph--;
12877 else if (match_with_avoid_cursor
12878 /* A truncated row may not include PT among its
12879 character positions. Setting the cursor inside the
12880 scroll margin will trigger recalculation of hscroll
12881 in hscroll_window_tree. */
12882 || (row->truncated_on_left_p && pt_old < bpos_min)
12883 || (row->truncated_on_right_p && pt_old > bpos_max)
12884 /* Zero-width characters produce no glyphs. */
12885 || (!string_seen
12886 && !empty_line_p
12887 && (row->reversed_p
12888 ? glyph_after > glyphs_end
12889 : glyph_after < glyphs_end)))
12891 cursor = glyph_after;
12892 x = -1;
12894 else if (string_seen)
12896 int incr = row->reversed_p ? -1 : +1;
12898 /* Need to find the glyph that came out of a string which is
12899 present at point. That glyph is somewhere between
12900 GLYPH_BEFORE and GLYPH_AFTER, and it came from a string
12901 positioned between POS_BEFORE and POS_AFTER in the
12902 buffer. */
12903 struct glyph *stop = glyph_after;
12904 EMACS_INT pos = pos_before;
12906 x = -1;
12907 for (glyph = glyph_before + incr;
12908 row->reversed_p ? glyph > stop : glyph < stop; )
12911 /* Any glyphs that come from the buffer are here because
12912 of bidi reordering. Skip them, and only pay
12913 attention to glyphs that came from some string. */
12914 if (STRINGP (glyph->object))
12916 Lisp_Object str;
12917 EMACS_INT tem;
12919 str = glyph->object;
12920 tem = string_buffer_position_lim (w, str, pos, pos_after, 0);
12921 if (tem == 0 /* from overlay */
12922 || pos <= tem)
12924 /* If the string from which this glyph came is
12925 found in the buffer at point, then we've
12926 found the glyph we've been looking for. If
12927 it comes from an overlay (tem == 0), and it
12928 has the `cursor' property on one of its
12929 glyphs, record that glyph as a candidate for
12930 displaying the cursor. (As in the
12931 unidirectional version, we will display the
12932 cursor on the last candidate we find.) */
12933 if (tem == 0 || tem == pt_old)
12935 /* The glyphs from this string could have
12936 been reordered. Find the one with the
12937 smallest string position. Or there could
12938 be a character in the string with the
12939 `cursor' property, which means display
12940 cursor on that character's glyph. */
12941 EMACS_INT strpos = glyph->charpos;
12943 if (tem)
12944 cursor = glyph;
12945 for ( ;
12946 (row->reversed_p ? glyph > stop : glyph < stop)
12947 && EQ (glyph->object, str);
12948 glyph += incr)
12950 Lisp_Object cprop;
12951 EMACS_INT gpos = glyph->charpos;
12953 cprop = Fget_char_property (make_number (gpos),
12954 Qcursor,
12955 glyph->object);
12956 if (!NILP (cprop))
12958 cursor = glyph;
12959 break;
12961 if (tem && glyph->charpos < strpos)
12963 strpos = glyph->charpos;
12964 cursor = glyph;
12968 if (tem == pt_old)
12969 goto compute_x;
12971 if (tem)
12972 pos = tem + 1; /* don't find previous instances */
12974 /* This string is not what we want; skip all of the
12975 glyphs that came from it. */
12976 while ((row->reversed_p ? glyph > stop : glyph < stop)
12977 && EQ (glyph->object, str))
12978 glyph += incr;
12980 else
12981 glyph += incr;
12984 /* If we reached the end of the line, and END was from a string,
12985 the cursor is not on this line. */
12986 if (cursor == NULL
12987 && (row->reversed_p ? glyph <= end : glyph >= end)
12988 && STRINGP (end->object)
12989 && row->continued_p)
12990 return 0;
12994 compute_x:
12995 if (cursor != NULL)
12996 glyph = cursor;
12997 if (x < 0)
12999 struct glyph *g;
13001 /* Need to compute x that corresponds to GLYPH. */
13002 for (g = row->glyphs[TEXT_AREA], x = row->x; g < glyph; g++)
13004 if (g >= row->glyphs[TEXT_AREA] + row->used[TEXT_AREA])
13005 abort ();
13006 x += g->pixel_width;
13010 /* ROW could be part of a continued line, which, under bidi
13011 reordering, might have other rows whose start and end charpos
13012 occlude point. Only set w->cursor if we found a better
13013 approximation to the cursor position than we have from previously
13014 examined candidate rows belonging to the same continued line. */
13015 if (/* we already have a candidate row */
13016 w->cursor.vpos >= 0
13017 /* that candidate is not the row we are processing */
13018 && MATRIX_ROW (matrix, w->cursor.vpos) != row
13019 /* the row we are processing is part of a continued line */
13020 && (row->continued_p || MATRIX_ROW_CONTINUATION_LINE_P (row))
13021 /* Make sure cursor.vpos specifies a row whose start and end
13022 charpos occlude point. This is because some callers of this
13023 function leave cursor.vpos at the row where the cursor was
13024 displayed during the last redisplay cycle. */
13025 && MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos)) <= pt_old
13026 && pt_old < MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos)))
13028 struct glyph *g1 =
13029 MATRIX_ROW_GLYPH_START (matrix, w->cursor.vpos) + w->cursor.hpos;
13031 /* Don't consider glyphs that are outside TEXT_AREA. */
13032 if (!(row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end))
13033 return 0;
13034 /* Keep the candidate whose buffer position is the closest to
13035 point. */
13036 if (/* previous candidate is a glyph in TEXT_AREA of that row */
13037 w->cursor.hpos >= 0
13038 && w->cursor.hpos < MATRIX_ROW_USED (matrix, w->cursor.vpos)
13039 && BUFFERP (g1->object)
13040 && (g1->charpos == pt_old /* an exact match always wins */
13041 || (BUFFERP (glyph->object)
13042 && eabs (g1->charpos - pt_old)
13043 < eabs (glyph->charpos - pt_old))))
13044 return 0;
13045 /* If this candidate gives an exact match, use that. */
13046 if (!(BUFFERP (glyph->object) && glyph->charpos == pt_old)
13047 /* Otherwise, keep the candidate that comes from a row
13048 spanning less buffer positions. This may win when one or
13049 both candidate positions are on glyphs that came from
13050 display strings, for which we cannot compare buffer
13051 positions. */
13052 && MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
13053 - MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
13054 < MATRIX_ROW_END_CHARPOS (row) - MATRIX_ROW_START_CHARPOS (row))
13055 return 0;
13057 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
13058 w->cursor.x = x;
13059 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
13060 w->cursor.y = row->y + dy;
13062 if (w == XWINDOW (selected_window))
13064 if (!row->continued_p
13065 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
13066 && row->x == 0)
13068 this_line_buffer = XBUFFER (w->buffer);
13070 CHARPOS (this_line_start_pos)
13071 = MATRIX_ROW_START_CHARPOS (row) + delta;
13072 BYTEPOS (this_line_start_pos)
13073 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
13075 CHARPOS (this_line_end_pos)
13076 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
13077 BYTEPOS (this_line_end_pos)
13078 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
13080 this_line_y = w->cursor.y;
13081 this_line_pixel_height = row->height;
13082 this_line_vpos = w->cursor.vpos;
13083 this_line_start_x = row->x;
13085 else
13086 CHARPOS (this_line_start_pos) = 0;
13089 return 1;
13093 /* Run window scroll functions, if any, for WINDOW with new window
13094 start STARTP. Sets the window start of WINDOW to that position.
13096 We assume that the window's buffer is really current. */
13098 static INLINE struct text_pos
13099 run_window_scroll_functions (Lisp_Object window, struct text_pos startp)
13101 struct window *w = XWINDOW (window);
13102 SET_MARKER_FROM_TEXT_POS (w->start, startp);
13104 if (current_buffer != XBUFFER (w->buffer))
13105 abort ();
13107 if (!NILP (Vwindow_scroll_functions))
13109 run_hook_with_args_2 (Qwindow_scroll_functions, window,
13110 make_number (CHARPOS (startp)));
13111 SET_TEXT_POS_FROM_MARKER (startp, w->start);
13112 /* In case the hook functions switch buffers. */
13113 if (current_buffer != XBUFFER (w->buffer))
13114 set_buffer_internal_1 (XBUFFER (w->buffer));
13117 return startp;
13121 /* Make sure the line containing the cursor is fully visible.
13122 A value of 1 means there is nothing to be done.
13123 (Either the line is fully visible, or it cannot be made so,
13124 or we cannot tell.)
13126 If FORCE_P is non-zero, return 0 even if partial visible cursor row
13127 is higher than window.
13129 A value of 0 means the caller should do scrolling
13130 as if point had gone off the screen. */
13132 static int
13133 cursor_row_fully_visible_p (struct window *w, int force_p, int current_matrix_p)
13135 struct glyph_matrix *matrix;
13136 struct glyph_row *row;
13137 int window_height;
13139 if (!make_cursor_line_fully_visible_p)
13140 return 1;
13142 /* It's not always possible to find the cursor, e.g, when a window
13143 is full of overlay strings. Don't do anything in that case. */
13144 if (w->cursor.vpos < 0)
13145 return 1;
13147 matrix = current_matrix_p ? w->current_matrix : w->desired_matrix;
13148 row = MATRIX_ROW (matrix, w->cursor.vpos);
13150 /* If the cursor row is not partially visible, there's nothing to do. */
13151 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row))
13152 return 1;
13154 /* If the row the cursor is in is taller than the window's height,
13155 it's not clear what to do, so do nothing. */
13156 window_height = window_box_height (w);
13157 if (row->height >= window_height)
13159 if (!force_p || MINI_WINDOW_P (w)
13160 || w->vscroll || w->cursor.vpos == 0)
13161 return 1;
13163 return 0;
13167 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
13168 non-zero means only WINDOW is redisplayed in redisplay_internal.
13169 TEMP_SCROLL_STEP has the same meaning as scroll_step, and is used
13170 in redisplay_window to bring a partially visible line into view in
13171 the case that only the cursor has moved.
13173 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
13174 last screen line's vertical height extends past the end of the screen.
13176 Value is
13178 1 if scrolling succeeded
13180 0 if scrolling didn't find point.
13182 -1 if new fonts have been loaded so that we must interrupt
13183 redisplay, adjust glyph matrices, and try again. */
13185 enum
13187 SCROLLING_SUCCESS,
13188 SCROLLING_FAILED,
13189 SCROLLING_NEED_LARGER_MATRICES
13192 static int
13193 try_scrolling (Lisp_Object window, int just_this_one_p,
13194 EMACS_INT scroll_conservatively, EMACS_INT scroll_step,
13195 int temp_scroll_step, int last_line_misfit)
13197 struct window *w = XWINDOW (window);
13198 struct frame *f = XFRAME (w->frame);
13199 struct text_pos pos, startp;
13200 struct it it;
13201 int this_scroll_margin, scroll_max, rc, height;
13202 int dy = 0, amount_to_scroll = 0, scroll_down_p = 0;
13203 int extra_scroll_margin_lines = last_line_misfit ? 1 : 0;
13204 Lisp_Object aggressive;
13205 int scroll_limit = INT_MAX / FRAME_LINE_HEIGHT (f);
13207 #if GLYPH_DEBUG
13208 debug_method_add (w, "try_scrolling");
13209 #endif
13211 SET_TEXT_POS_FROM_MARKER (startp, w->start);
13213 /* Compute scroll margin height in pixels. We scroll when point is
13214 within this distance from the top or bottom of the window. */
13215 if (scroll_margin > 0)
13216 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4)
13217 * FRAME_LINE_HEIGHT (f);
13218 else
13219 this_scroll_margin = 0;
13221 /* Force scroll_conservatively to have a reasonable value, to avoid
13222 overflow while computing how much to scroll. Note that the user
13223 can supply scroll-conservatively equal to `most-positive-fixnum',
13224 which can be larger than INT_MAX. */
13225 if (scroll_conservatively > scroll_limit)
13227 scroll_conservatively = scroll_limit;
13228 scroll_max = INT_MAX;
13230 else if (scroll_step || scroll_conservatively || temp_scroll_step)
13231 /* Compute how much we should try to scroll maximally to bring
13232 point into view. */
13233 scroll_max = (max (scroll_step,
13234 max (scroll_conservatively, temp_scroll_step))
13235 * FRAME_LINE_HEIGHT (f));
13236 else if (NUMBERP (current_buffer->scroll_down_aggressively)
13237 || NUMBERP (current_buffer->scroll_up_aggressively))
13238 /* We're trying to scroll because of aggressive scrolling but no
13239 scroll_step is set. Choose an arbitrary one. */
13240 scroll_max = 10 * FRAME_LINE_HEIGHT (f);
13241 else
13242 scroll_max = 0;
13244 too_near_end:
13246 /* Decide whether to scroll down. */
13247 if (PT > CHARPOS (startp))
13249 int scroll_margin_y;
13251 /* Compute the pixel ypos of the scroll margin, then move it to
13252 either that ypos or PT, whichever comes first. */
13253 start_display (&it, w, startp);
13254 scroll_margin_y = it.last_visible_y - this_scroll_margin
13255 - FRAME_LINE_HEIGHT (f) * extra_scroll_margin_lines;
13256 move_it_to (&it, PT, -1, scroll_margin_y - 1, -1,
13257 (MOVE_TO_POS | MOVE_TO_Y));
13259 if (PT > CHARPOS (it.current.pos))
13261 int y0 = line_bottom_y (&it);
13262 /* Compute how many pixels below window bottom to stop searching
13263 for PT. This avoids costly search for PT that is far away if
13264 the user limited scrolling by a small number of lines, but
13265 always finds PT if scroll_conservatively is set to a large
13266 number, such as most-positive-fixnum. */
13267 int slack = max (scroll_max, 10 * FRAME_LINE_HEIGHT (f));
13268 int y_to_move =
13269 slack >= INT_MAX - it.last_visible_y
13270 ? INT_MAX
13271 : it.last_visible_y + slack;
13273 /* Compute the distance from the scroll margin to PT or to
13274 the scroll limit, whichever comes first. This should
13275 include the height of the cursor line, to make that line
13276 fully visible. */
13277 move_it_to (&it, PT, -1, y_to_move,
13278 -1, MOVE_TO_POS | MOVE_TO_Y);
13279 dy = line_bottom_y (&it) - y0;
13281 if (dy > scroll_max)
13282 return SCROLLING_FAILED;
13284 scroll_down_p = 1;
13288 if (scroll_down_p)
13290 /* Point is in or below the bottom scroll margin, so move the
13291 window start down. If scrolling conservatively, move it just
13292 enough down to make point visible. If scroll_step is set,
13293 move it down by scroll_step. */
13294 if (scroll_conservatively)
13295 amount_to_scroll
13296 = min (max (dy, FRAME_LINE_HEIGHT (f)),
13297 FRAME_LINE_HEIGHT (f) * scroll_conservatively);
13298 else if (scroll_step || temp_scroll_step)
13299 amount_to_scroll = scroll_max;
13300 else
13302 aggressive = current_buffer->scroll_up_aggressively;
13303 height = WINDOW_BOX_TEXT_HEIGHT (w);
13304 if (NUMBERP (aggressive))
13306 double float_amount = XFLOATINT (aggressive) * height;
13307 amount_to_scroll = float_amount;
13308 if (amount_to_scroll == 0 && float_amount > 0)
13309 amount_to_scroll = 1;
13313 if (amount_to_scroll <= 0)
13314 return SCROLLING_FAILED;
13316 start_display (&it, w, startp);
13317 if (scroll_max < INT_MAX)
13318 move_it_vertically (&it, amount_to_scroll);
13319 else
13321 /* Extra precision for users who set scroll-conservatively
13322 to most-positive-fixnum: make sure the amount we scroll
13323 the window start is never less than amount_to_scroll,
13324 which was computed as distance from window bottom to
13325 point. This matters when lines at window top and lines
13326 below window bottom have different height. */
13327 struct it it1 = it;
13328 /* We use a temporary it1 because line_bottom_y can modify
13329 its argument, if it moves one line down; see there. */
13330 int start_y = line_bottom_y (&it1);
13332 do {
13333 move_it_by_lines (&it, 1, 1);
13334 it1 = it;
13335 } while (line_bottom_y (&it1) - start_y < amount_to_scroll);
13338 /* If STARTP is unchanged, move it down another screen line. */
13339 if (CHARPOS (it.current.pos) == CHARPOS (startp))
13340 move_it_by_lines (&it, 1, 1);
13341 startp = it.current.pos;
13343 else
13345 struct text_pos scroll_margin_pos = startp;
13347 /* See if point is inside the scroll margin at the top of the
13348 window. */
13349 if (this_scroll_margin)
13351 start_display (&it, w, startp);
13352 move_it_vertically (&it, this_scroll_margin);
13353 scroll_margin_pos = it.current.pos;
13356 if (PT < CHARPOS (scroll_margin_pos))
13358 /* Point is in the scroll margin at the top of the window or
13359 above what is displayed in the window. */
13360 int y0;
13362 /* Compute the vertical distance from PT to the scroll
13363 margin position. Give up if distance is greater than
13364 scroll_max. */
13365 SET_TEXT_POS (pos, PT, PT_BYTE);
13366 start_display (&it, w, pos);
13367 y0 = it.current_y;
13368 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
13369 it.last_visible_y, -1,
13370 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
13371 dy = it.current_y - y0;
13372 if (dy > scroll_max)
13373 return SCROLLING_FAILED;
13375 /* Compute new window start. */
13376 start_display (&it, w, startp);
13378 if (scroll_conservatively)
13379 amount_to_scroll
13380 = max (dy, FRAME_LINE_HEIGHT (f) * max (scroll_step, temp_scroll_step));
13381 else if (scroll_step || temp_scroll_step)
13382 amount_to_scroll = scroll_max;
13383 else
13385 aggressive = current_buffer->scroll_down_aggressively;
13386 height = WINDOW_BOX_TEXT_HEIGHT (w);
13387 if (NUMBERP (aggressive))
13389 double float_amount = XFLOATINT (aggressive) * height;
13390 amount_to_scroll = float_amount;
13391 if (amount_to_scroll == 0 && float_amount > 0)
13392 amount_to_scroll = 1;
13396 if (amount_to_scroll <= 0)
13397 return SCROLLING_FAILED;
13399 move_it_vertically_backward (&it, amount_to_scroll);
13400 startp = it.current.pos;
13404 /* Run window scroll functions. */
13405 startp = run_window_scroll_functions (window, startp);
13407 /* Display the window. Give up if new fonts are loaded, or if point
13408 doesn't appear. */
13409 if (!try_window (window, startp, 0))
13410 rc = SCROLLING_NEED_LARGER_MATRICES;
13411 else if (w->cursor.vpos < 0)
13413 clear_glyph_matrix (w->desired_matrix);
13414 rc = SCROLLING_FAILED;
13416 else
13418 /* Maybe forget recorded base line for line number display. */
13419 if (!just_this_one_p
13420 || current_buffer->clip_changed
13421 || BEG_UNCHANGED < CHARPOS (startp))
13422 w->base_line_number = Qnil;
13424 /* If cursor ends up on a partially visible line,
13425 treat that as being off the bottom of the screen. */
13426 if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1, 0)
13427 /* It's possible that the cursor is on the first line of the
13428 buffer, which is partially obscured due to a vscroll
13429 (Bug#7537). In that case, avoid looping forever . */
13430 && extra_scroll_margin_lines < w->desired_matrix->nrows - 1)
13432 clear_glyph_matrix (w->desired_matrix);
13433 ++extra_scroll_margin_lines;
13434 goto too_near_end;
13436 rc = SCROLLING_SUCCESS;
13439 return rc;
13443 /* Compute a suitable window start for window W if display of W starts
13444 on a continuation line. Value is non-zero if a new window start
13445 was computed.
13447 The new window start will be computed, based on W's width, starting
13448 from the start of the continued line. It is the start of the
13449 screen line with the minimum distance from the old start W->start. */
13451 static int
13452 compute_window_start_on_continuation_line (struct window *w)
13454 struct text_pos pos, start_pos;
13455 int window_start_changed_p = 0;
13457 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
13459 /* If window start is on a continuation line... Window start may be
13460 < BEGV in case there's invisible text at the start of the
13461 buffer (M-x rmail, for example). */
13462 if (CHARPOS (start_pos) > BEGV
13463 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
13465 struct it it;
13466 struct glyph_row *row;
13468 /* Handle the case that the window start is out of range. */
13469 if (CHARPOS (start_pos) < BEGV)
13470 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
13471 else if (CHARPOS (start_pos) > ZV)
13472 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
13474 /* Find the start of the continued line. This should be fast
13475 because scan_buffer is fast (newline cache). */
13476 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
13477 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
13478 row, DEFAULT_FACE_ID);
13479 reseat_at_previous_visible_line_start (&it);
13481 /* If the line start is "too far" away from the window start,
13482 say it takes too much time to compute a new window start. */
13483 if (CHARPOS (start_pos) - IT_CHARPOS (it)
13484 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
13486 int min_distance, distance;
13488 /* Move forward by display lines to find the new window
13489 start. If window width was enlarged, the new start can
13490 be expected to be > the old start. If window width was
13491 decreased, the new window start will be < the old start.
13492 So, we're looking for the display line start with the
13493 minimum distance from the old window start. */
13494 pos = it.current.pos;
13495 min_distance = INFINITY;
13496 while ((distance = eabs (CHARPOS (start_pos) - IT_CHARPOS (it))),
13497 distance < min_distance)
13499 min_distance = distance;
13500 pos = it.current.pos;
13501 move_it_by_lines (&it, 1, 0);
13504 /* Set the window start there. */
13505 SET_MARKER_FROM_TEXT_POS (w->start, pos);
13506 window_start_changed_p = 1;
13510 return window_start_changed_p;
13514 /* Try cursor movement in case text has not changed in window WINDOW,
13515 with window start STARTP. Value is
13517 CURSOR_MOVEMENT_SUCCESS if successful
13519 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
13521 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
13522 display. *SCROLL_STEP is set to 1, under certain circumstances, if
13523 we want to scroll as if scroll-step were set to 1. See the code.
13525 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
13526 which case we have to abort this redisplay, and adjust matrices
13527 first. */
13529 enum
13531 CURSOR_MOVEMENT_SUCCESS,
13532 CURSOR_MOVEMENT_CANNOT_BE_USED,
13533 CURSOR_MOVEMENT_MUST_SCROLL,
13534 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
13537 static int
13538 try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_step)
13540 struct window *w = XWINDOW (window);
13541 struct frame *f = XFRAME (w->frame);
13542 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
13544 #if GLYPH_DEBUG
13545 if (inhibit_try_cursor_movement)
13546 return rc;
13547 #endif
13549 /* Handle case where text has not changed, only point, and it has
13550 not moved off the frame. */
13551 if (/* Point may be in this window. */
13552 PT >= CHARPOS (startp)
13553 /* Selective display hasn't changed. */
13554 && !current_buffer->clip_changed
13555 /* Function force-mode-line-update is used to force a thorough
13556 redisplay. It sets either windows_or_buffers_changed or
13557 update_mode_lines. So don't take a shortcut here for these
13558 cases. */
13559 && !update_mode_lines
13560 && !windows_or_buffers_changed
13561 && !cursor_type_changed
13562 /* Can't use this case if highlighting a region. When a
13563 region exists, cursor movement has to do more than just
13564 set the cursor. */
13565 && !(!NILP (Vtransient_mark_mode)
13566 && !NILP (current_buffer->mark_active))
13567 && NILP (w->region_showing)
13568 && NILP (Vshow_trailing_whitespace)
13569 /* Right after splitting windows, last_point may be nil. */
13570 && INTEGERP (w->last_point)
13571 /* This code is not used for mini-buffer for the sake of the case
13572 of redisplaying to replace an echo area message; since in
13573 that case the mini-buffer contents per se are usually
13574 unchanged. This code is of no real use in the mini-buffer
13575 since the handling of this_line_start_pos, etc., in redisplay
13576 handles the same cases. */
13577 && !EQ (window, minibuf_window)
13578 /* When splitting windows or for new windows, it happens that
13579 redisplay is called with a nil window_end_vpos or one being
13580 larger than the window. This should really be fixed in
13581 window.c. I don't have this on my list, now, so we do
13582 approximately the same as the old redisplay code. --gerd. */
13583 && INTEGERP (w->window_end_vpos)
13584 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
13585 && (FRAME_WINDOW_P (f)
13586 || !overlay_arrow_in_current_buffer_p ()))
13588 int this_scroll_margin, top_scroll_margin;
13589 struct glyph_row *row = NULL;
13591 #if GLYPH_DEBUG
13592 debug_method_add (w, "cursor movement");
13593 #endif
13595 /* Scroll if point within this distance from the top or bottom
13596 of the window. This is a pixel value. */
13597 if (scroll_margin > 0)
13599 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
13600 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
13602 else
13603 this_scroll_margin = 0;
13605 top_scroll_margin = this_scroll_margin;
13606 if (WINDOW_WANTS_HEADER_LINE_P (w))
13607 top_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w);
13609 /* Start with the row the cursor was displayed during the last
13610 not paused redisplay. Give up if that row is not valid. */
13611 if (w->last_cursor.vpos < 0
13612 || w->last_cursor.vpos >= w->current_matrix->nrows)
13613 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13614 else
13616 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
13617 if (row->mode_line_p)
13618 ++row;
13619 if (!row->enabled_p)
13620 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13623 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
13625 int scroll_p = 0, must_scroll = 0;
13626 int last_y = window_text_bottom_y (w) - this_scroll_margin;
13628 if (PT > XFASTINT (w->last_point))
13630 /* Point has moved forward. */
13631 while (MATRIX_ROW_END_CHARPOS (row) < PT
13632 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
13634 xassert (row->enabled_p);
13635 ++row;
13638 /* If the end position of a row equals the start
13639 position of the next row, and PT is at that position,
13640 we would rather display cursor in the next line. */
13641 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
13642 && MATRIX_ROW_END_CHARPOS (row) == PT
13643 && row < w->current_matrix->rows
13644 + w->current_matrix->nrows - 1
13645 && MATRIX_ROW_START_CHARPOS (row+1) == PT
13646 && !cursor_row_p (w, row))
13647 ++row;
13649 /* If within the scroll margin, scroll. Note that
13650 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
13651 the next line would be drawn, and that
13652 this_scroll_margin can be zero. */
13653 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
13654 || PT > MATRIX_ROW_END_CHARPOS (row)
13655 /* Line is completely visible last line in window
13656 and PT is to be set in the next line. */
13657 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
13658 && PT == MATRIX_ROW_END_CHARPOS (row)
13659 && !row->ends_at_zv_p
13660 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
13661 scroll_p = 1;
13663 else if (PT < XFASTINT (w->last_point))
13665 /* Cursor has to be moved backward. Note that PT >=
13666 CHARPOS (startp) because of the outer if-statement. */
13667 while (!row->mode_line_p
13668 && (MATRIX_ROW_START_CHARPOS (row) > PT
13669 || (MATRIX_ROW_START_CHARPOS (row) == PT
13670 && (MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)
13671 || (/* STARTS_IN_MIDDLE_OF_STRING_P (row) */
13672 row > w->current_matrix->rows
13673 && (row-1)->ends_in_newline_from_string_p))))
13674 && (row->y > top_scroll_margin
13675 || CHARPOS (startp) == BEGV))
13677 xassert (row->enabled_p);
13678 --row;
13681 /* Consider the following case: Window starts at BEGV,
13682 there is invisible, intangible text at BEGV, so that
13683 display starts at some point START > BEGV. It can
13684 happen that we are called with PT somewhere between
13685 BEGV and START. Try to handle that case. */
13686 if (row < w->current_matrix->rows
13687 || row->mode_line_p)
13689 row = w->current_matrix->rows;
13690 if (row->mode_line_p)
13691 ++row;
13694 /* Due to newlines in overlay strings, we may have to
13695 skip forward over overlay strings. */
13696 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
13697 && MATRIX_ROW_END_CHARPOS (row) == PT
13698 && !cursor_row_p (w, row))
13699 ++row;
13701 /* If within the scroll margin, scroll. */
13702 if (row->y < top_scroll_margin
13703 && CHARPOS (startp) != BEGV)
13704 scroll_p = 1;
13706 else
13708 /* Cursor did not move. So don't scroll even if cursor line
13709 is partially visible, as it was so before. */
13710 rc = CURSOR_MOVEMENT_SUCCESS;
13713 if (PT < MATRIX_ROW_START_CHARPOS (row)
13714 || PT > MATRIX_ROW_END_CHARPOS (row))
13716 /* if PT is not in the glyph row, give up. */
13717 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13718 must_scroll = 1;
13720 else if (rc != CURSOR_MOVEMENT_SUCCESS
13721 && !NILP (XBUFFER (w->buffer)->bidi_display_reordering))
13723 /* If rows are bidi-reordered and point moved, back up
13724 until we find a row that does not belong to a
13725 continuation line. This is because we must consider
13726 all rows of a continued line as candidates for the
13727 new cursor positioning, since row start and end
13728 positions change non-linearly with vertical position
13729 in such rows. */
13730 /* FIXME: Revisit this when glyph ``spilling'' in
13731 continuation lines' rows is implemented for
13732 bidi-reordered rows. */
13733 while (MATRIX_ROW_CONTINUATION_LINE_P (row))
13735 xassert (row->enabled_p);
13736 --row;
13737 /* If we hit the beginning of the displayed portion
13738 without finding the first row of a continued
13739 line, give up. */
13740 if (row <= w->current_matrix->rows)
13742 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13743 break;
13748 if (must_scroll)
13750 else if (rc != CURSOR_MOVEMENT_SUCCESS
13751 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
13752 && make_cursor_line_fully_visible_p)
13754 if (PT == MATRIX_ROW_END_CHARPOS (row)
13755 && !row->ends_at_zv_p
13756 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
13757 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13758 else if (row->height > window_box_height (w))
13760 /* If we end up in a partially visible line, let's
13761 make it fully visible, except when it's taller
13762 than the window, in which case we can't do much
13763 about it. */
13764 *scroll_step = 1;
13765 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13767 else
13769 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
13770 if (!cursor_row_fully_visible_p (w, 0, 1))
13771 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13772 else
13773 rc = CURSOR_MOVEMENT_SUCCESS;
13776 else if (scroll_p)
13777 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13778 else if (rc != CURSOR_MOVEMENT_SUCCESS
13779 && !NILP (XBUFFER (w->buffer)->bidi_display_reordering))
13781 /* With bidi-reordered rows, there could be more than
13782 one candidate row whose start and end positions
13783 occlude point. We need to let set_cursor_from_row
13784 find the best candidate. */
13785 /* FIXME: Revisit this when glyph ``spilling'' in
13786 continuation lines' rows is implemented for
13787 bidi-reordered rows. */
13788 int rv = 0;
13792 if (MATRIX_ROW_START_CHARPOS (row) <= PT
13793 && PT <= MATRIX_ROW_END_CHARPOS (row)
13794 && cursor_row_p (w, row))
13795 rv |= set_cursor_from_row (w, row, w->current_matrix,
13796 0, 0, 0, 0);
13797 /* As soon as we've found the first suitable row
13798 whose ends_at_zv_p flag is set, we are done. */
13799 if (rv
13800 && MATRIX_ROW (w->current_matrix, w->cursor.vpos)->ends_at_zv_p)
13802 rc = CURSOR_MOVEMENT_SUCCESS;
13803 break;
13805 ++row;
13807 while ((MATRIX_ROW_CONTINUATION_LINE_P (row)
13808 && MATRIX_ROW_BOTTOM_Y (row) <= last_y)
13809 || (MATRIX_ROW_START_CHARPOS (row) == PT
13810 && MATRIX_ROW_BOTTOM_Y (row) < last_y));
13811 /* If we didn't find any candidate rows, or exited the
13812 loop before all the candidates were examined, signal
13813 to the caller that this method failed. */
13814 if (rc != CURSOR_MOVEMENT_SUCCESS
13815 && (!rv || MATRIX_ROW_CONTINUATION_LINE_P (row)))
13816 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13817 else if (rv)
13818 rc = CURSOR_MOVEMENT_SUCCESS;
13820 else
13824 if (set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0))
13826 rc = CURSOR_MOVEMENT_SUCCESS;
13827 break;
13829 ++row;
13831 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
13832 && MATRIX_ROW_START_CHARPOS (row) == PT
13833 && cursor_row_p (w, row));
13838 return rc;
13841 void
13842 set_vertical_scroll_bar (struct window *w)
13844 EMACS_INT start, end, whole;
13846 /* Calculate the start and end positions for the current window.
13847 At some point, it would be nice to choose between scrollbars
13848 which reflect the whole buffer size, with special markers
13849 indicating narrowing, and scrollbars which reflect only the
13850 visible region.
13852 Note that mini-buffers sometimes aren't displaying any text. */
13853 if (!MINI_WINDOW_P (w)
13854 || (w == XWINDOW (minibuf_window)
13855 && NILP (echo_area_buffer[0])))
13857 struct buffer *buf = XBUFFER (w->buffer);
13858 whole = BUF_ZV (buf) - BUF_BEGV (buf);
13859 start = marker_position (w->start) - BUF_BEGV (buf);
13860 /* I don't think this is guaranteed to be right. For the
13861 moment, we'll pretend it is. */
13862 end = BUF_Z (buf) - XFASTINT (w->window_end_pos) - BUF_BEGV (buf);
13864 if (end < start)
13865 end = start;
13866 if (whole < (end - start))
13867 whole = end - start;
13869 else
13870 start = end = whole = 0;
13872 /* Indicate what this scroll bar ought to be displaying now. */
13873 if (FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
13874 (*FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
13875 (w, end - start, whole, start);
13879 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
13880 selected_window is redisplayed.
13882 We can return without actually redisplaying the window if
13883 fonts_changed_p is nonzero. In that case, redisplay_internal will
13884 retry. */
13886 static void
13887 redisplay_window (Lisp_Object window, int just_this_one_p)
13889 struct window *w = XWINDOW (window);
13890 struct frame *f = XFRAME (w->frame);
13891 struct buffer *buffer = XBUFFER (w->buffer);
13892 struct buffer *old = current_buffer;
13893 struct text_pos lpoint, opoint, startp;
13894 int update_mode_line;
13895 int tem;
13896 struct it it;
13897 /* Record it now because it's overwritten. */
13898 int current_matrix_up_to_date_p = 0;
13899 int used_current_matrix_p = 0;
13900 /* This is less strict than current_matrix_up_to_date_p.
13901 It indictes that the buffer contents and narrowing are unchanged. */
13902 int buffer_unchanged_p = 0;
13903 int temp_scroll_step = 0;
13904 int count = SPECPDL_INDEX ();
13905 int rc;
13906 int centering_position = -1;
13907 int last_line_misfit = 0;
13908 EMACS_INT beg_unchanged, end_unchanged;
13910 SET_TEXT_POS (lpoint, PT, PT_BYTE);
13911 opoint = lpoint;
13913 /* W must be a leaf window here. */
13914 xassert (!NILP (w->buffer));
13915 #if GLYPH_DEBUG
13916 *w->desired_matrix->method = 0;
13917 #endif
13919 restart:
13920 reconsider_clip_changes (w, buffer);
13922 /* Has the mode line to be updated? */
13923 update_mode_line = (!NILP (w->update_mode_line)
13924 || update_mode_lines
13925 || buffer->clip_changed
13926 || buffer->prevent_redisplay_optimizations_p);
13928 if (MINI_WINDOW_P (w))
13930 if (w == XWINDOW (echo_area_window)
13931 && !NILP (echo_area_buffer[0]))
13933 if (update_mode_line)
13934 /* We may have to update a tty frame's menu bar or a
13935 tool-bar. Example `M-x C-h C-h C-g'. */
13936 goto finish_menu_bars;
13937 else
13938 /* We've already displayed the echo area glyphs in this window. */
13939 goto finish_scroll_bars;
13941 else if ((w != XWINDOW (minibuf_window)
13942 || minibuf_level == 0)
13943 /* When buffer is nonempty, redisplay window normally. */
13944 && BUF_Z (XBUFFER (w->buffer)) == BUF_BEG (XBUFFER (w->buffer))
13945 /* Quail displays non-mini buffers in minibuffer window.
13946 In that case, redisplay the window normally. */
13947 && !NILP (Fmemq (w->buffer, Vminibuffer_list)))
13949 /* W is a mini-buffer window, but it's not active, so clear
13950 it. */
13951 int yb = window_text_bottom_y (w);
13952 struct glyph_row *row;
13953 int y;
13955 for (y = 0, row = w->desired_matrix->rows;
13956 y < yb;
13957 y += row->height, ++row)
13958 blank_row (w, row, y);
13959 goto finish_scroll_bars;
13962 clear_glyph_matrix (w->desired_matrix);
13965 /* Otherwise set up data on this window; select its buffer and point
13966 value. */
13967 /* Really select the buffer, for the sake of buffer-local
13968 variables. */
13969 set_buffer_internal_1 (XBUFFER (w->buffer));
13971 current_matrix_up_to_date_p
13972 = (!NILP (w->window_end_valid)
13973 && !current_buffer->clip_changed
13974 && !current_buffer->prevent_redisplay_optimizations_p
13975 && XFASTINT (w->last_modified) >= MODIFF
13976 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
13978 /* Run the window-bottom-change-functions
13979 if it is possible that the text on the screen has changed
13980 (either due to modification of the text, or any other reason). */
13981 if (!current_matrix_up_to_date_p
13982 && !NILP (Vwindow_text_change_functions))
13984 safe_run_hooks (Qwindow_text_change_functions);
13985 goto restart;
13988 beg_unchanged = BEG_UNCHANGED;
13989 end_unchanged = END_UNCHANGED;
13991 SET_TEXT_POS (opoint, PT, PT_BYTE);
13993 specbind (Qinhibit_point_motion_hooks, Qt);
13995 buffer_unchanged_p
13996 = (!NILP (w->window_end_valid)
13997 && !current_buffer->clip_changed
13998 && XFASTINT (w->last_modified) >= MODIFF
13999 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
14001 /* When windows_or_buffers_changed is non-zero, we can't rely on
14002 the window end being valid, so set it to nil there. */
14003 if (windows_or_buffers_changed)
14005 /* If window starts on a continuation line, maybe adjust the
14006 window start in case the window's width changed. */
14007 if (XMARKER (w->start)->buffer == current_buffer)
14008 compute_window_start_on_continuation_line (w);
14010 w->window_end_valid = Qnil;
14013 /* Some sanity checks. */
14014 CHECK_WINDOW_END (w);
14015 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
14016 abort ();
14017 if (BYTEPOS (opoint) < CHARPOS (opoint))
14018 abort ();
14020 /* If %c is in mode line, update it if needed. */
14021 if (!NILP (w->column_number_displayed)
14022 /* This alternative quickly identifies a common case
14023 where no change is needed. */
14024 && !(PT == XFASTINT (w->last_point)
14025 && XFASTINT (w->last_modified) >= MODIFF
14026 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
14027 && (XFASTINT (w->column_number_displayed)
14028 != (int) current_column ())) /* iftc */
14029 update_mode_line = 1;
14031 /* Count number of windows showing the selected buffer. An indirect
14032 buffer counts as its base buffer. */
14033 if (!just_this_one_p)
14035 struct buffer *current_base, *window_base;
14036 current_base = current_buffer;
14037 window_base = XBUFFER (XWINDOW (selected_window)->buffer);
14038 if (current_base->base_buffer)
14039 current_base = current_base->base_buffer;
14040 if (window_base->base_buffer)
14041 window_base = window_base->base_buffer;
14042 if (current_base == window_base)
14043 buffer_shared++;
14046 /* Point refers normally to the selected window. For any other
14047 window, set up appropriate value. */
14048 if (!EQ (window, selected_window))
14050 EMACS_INT new_pt = XMARKER (w->pointm)->charpos;
14051 EMACS_INT new_pt_byte = marker_byte_position (w->pointm);
14052 if (new_pt < BEGV)
14054 new_pt = BEGV;
14055 new_pt_byte = BEGV_BYTE;
14056 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
14058 else if (new_pt > (ZV - 1))
14060 new_pt = ZV;
14061 new_pt_byte = ZV_BYTE;
14062 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
14065 /* We don't use SET_PT so that the point-motion hooks don't run. */
14066 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
14069 /* If any of the character widths specified in the display table
14070 have changed, invalidate the width run cache. It's true that
14071 this may be a bit late to catch such changes, but the rest of
14072 redisplay goes (non-fatally) haywire when the display table is
14073 changed, so why should we worry about doing any better? */
14074 if (current_buffer->width_run_cache)
14076 struct Lisp_Char_Table *disptab = buffer_display_table ();
14078 if (! disptab_matches_widthtab (disptab,
14079 XVECTOR (current_buffer->width_table)))
14081 invalidate_region_cache (current_buffer,
14082 current_buffer->width_run_cache,
14083 BEG, Z);
14084 recompute_width_table (current_buffer, disptab);
14088 /* If window-start is screwed up, choose a new one. */
14089 if (XMARKER (w->start)->buffer != current_buffer)
14090 goto recenter;
14092 SET_TEXT_POS_FROM_MARKER (startp, w->start);
14094 /* If someone specified a new starting point but did not insist,
14095 check whether it can be used. */
14096 if (!NILP (w->optional_new_start)
14097 && CHARPOS (startp) >= BEGV
14098 && CHARPOS (startp) <= ZV)
14100 w->optional_new_start = Qnil;
14101 start_display (&it, w, startp);
14102 move_it_to (&it, PT, 0, it.last_visible_y, -1,
14103 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
14104 if (IT_CHARPOS (it) == PT)
14105 w->force_start = Qt;
14106 /* IT may overshoot PT if text at PT is invisible. */
14107 else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT)
14108 w->force_start = Qt;
14111 force_start:
14113 /* Handle case where place to start displaying has been specified,
14114 unless the specified location is outside the accessible range. */
14115 if (!NILP (w->force_start)
14116 || w->frozen_window_start_p)
14118 /* We set this later on if we have to adjust point. */
14119 int new_vpos = -1;
14121 w->force_start = Qnil;
14122 w->vscroll = 0;
14123 w->window_end_valid = Qnil;
14125 /* Forget any recorded base line for line number display. */
14126 if (!buffer_unchanged_p)
14127 w->base_line_number = Qnil;
14129 /* Redisplay the mode line. Select the buffer properly for that.
14130 Also, run the hook window-scroll-functions
14131 because we have scrolled. */
14132 /* Note, we do this after clearing force_start because
14133 if there's an error, it is better to forget about force_start
14134 than to get into an infinite loop calling the hook functions
14135 and having them get more errors. */
14136 if (!update_mode_line
14137 || ! NILP (Vwindow_scroll_functions))
14139 update_mode_line = 1;
14140 w->update_mode_line = Qt;
14141 startp = run_window_scroll_functions (window, startp);
14144 w->last_modified = make_number (0);
14145 w->last_overlay_modified = make_number (0);
14146 if (CHARPOS (startp) < BEGV)
14147 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
14148 else if (CHARPOS (startp) > ZV)
14149 SET_TEXT_POS (startp, ZV, ZV_BYTE);
14151 /* Redisplay, then check if cursor has been set during the
14152 redisplay. Give up if new fonts were loaded. */
14153 /* We used to issue a CHECK_MARGINS argument to try_window here,
14154 but this causes scrolling to fail when point begins inside
14155 the scroll margin (bug#148) -- cyd */
14156 if (!try_window (window, startp, 0))
14158 w->force_start = Qt;
14159 clear_glyph_matrix (w->desired_matrix);
14160 goto need_larger_matrices;
14163 if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
14165 /* If point does not appear, try to move point so it does
14166 appear. The desired matrix has been built above, so we
14167 can use it here. */
14168 new_vpos = window_box_height (w) / 2;
14171 if (!cursor_row_fully_visible_p (w, 0, 0))
14173 /* Point does appear, but on a line partly visible at end of window.
14174 Move it back to a fully-visible line. */
14175 new_vpos = window_box_height (w);
14178 /* If we need to move point for either of the above reasons,
14179 now actually do it. */
14180 if (new_vpos >= 0)
14182 struct glyph_row *row;
14184 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
14185 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
14186 ++row;
14188 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
14189 MATRIX_ROW_START_BYTEPOS (row));
14191 if (w != XWINDOW (selected_window))
14192 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
14193 else if (current_buffer == old)
14194 SET_TEXT_POS (lpoint, PT, PT_BYTE);
14196 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
14198 /* If we are highlighting the region, then we just changed
14199 the region, so redisplay to show it. */
14200 if (!NILP (Vtransient_mark_mode)
14201 && !NILP (current_buffer->mark_active))
14203 clear_glyph_matrix (w->desired_matrix);
14204 if (!try_window (window, startp, 0))
14205 goto need_larger_matrices;
14209 #if GLYPH_DEBUG
14210 debug_method_add (w, "forced window start");
14211 #endif
14212 goto done;
14215 /* Handle case where text has not changed, only point, and it has
14216 not moved off the frame, and we are not retrying after hscroll.
14217 (current_matrix_up_to_date_p is nonzero when retrying.) */
14218 if (current_matrix_up_to_date_p
14219 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
14220 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
14222 switch (rc)
14224 case CURSOR_MOVEMENT_SUCCESS:
14225 used_current_matrix_p = 1;
14226 goto done;
14228 case CURSOR_MOVEMENT_MUST_SCROLL:
14229 goto try_to_scroll;
14231 default:
14232 abort ();
14235 /* If current starting point was originally the beginning of a line
14236 but no longer is, find a new starting point. */
14237 else if (!NILP (w->start_at_line_beg)
14238 && !(CHARPOS (startp) <= BEGV
14239 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
14241 #if GLYPH_DEBUG
14242 debug_method_add (w, "recenter 1");
14243 #endif
14244 goto recenter;
14247 /* Try scrolling with try_window_id. Value is > 0 if update has
14248 been done, it is -1 if we know that the same window start will
14249 not work. It is 0 if unsuccessful for some other reason. */
14250 else if ((tem = try_window_id (w)) != 0)
14252 #if GLYPH_DEBUG
14253 debug_method_add (w, "try_window_id %d", tem);
14254 #endif
14256 if (fonts_changed_p)
14257 goto need_larger_matrices;
14258 if (tem > 0)
14259 goto done;
14261 /* Otherwise try_window_id has returned -1 which means that we
14262 don't want the alternative below this comment to execute. */
14264 else if (CHARPOS (startp) >= BEGV
14265 && CHARPOS (startp) <= ZV
14266 && PT >= CHARPOS (startp)
14267 && (CHARPOS (startp) < ZV
14268 /* Avoid starting at end of buffer. */
14269 || CHARPOS (startp) == BEGV
14270 || (XFASTINT (w->last_modified) >= MODIFF
14271 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)))
14274 /* If first window line is a continuation line, and window start
14275 is inside the modified region, but the first change is before
14276 current window start, we must select a new window start.
14278 However, if this is the result of a down-mouse event (e.g. by
14279 extending the mouse-drag-overlay), we don't want to select a
14280 new window start, since that would change the position under
14281 the mouse, resulting in an unwanted mouse-movement rather
14282 than a simple mouse-click. */
14283 if (NILP (w->start_at_line_beg)
14284 && NILP (do_mouse_tracking)
14285 && CHARPOS (startp) > BEGV
14286 && CHARPOS (startp) > BEG + beg_unchanged
14287 && CHARPOS (startp) <= Z - end_unchanged
14288 /* Even if w->start_at_line_beg is nil, a new window may
14289 start at a line_beg, since that's how set_buffer_window
14290 sets it. So, we need to check the return value of
14291 compute_window_start_on_continuation_line. (See also
14292 bug#197). */
14293 && XMARKER (w->start)->buffer == current_buffer
14294 && compute_window_start_on_continuation_line (w))
14296 w->force_start = Qt;
14297 SET_TEXT_POS_FROM_MARKER (startp, w->start);
14298 goto force_start;
14301 #if GLYPH_DEBUG
14302 debug_method_add (w, "same window start");
14303 #endif
14305 /* Try to redisplay starting at same place as before.
14306 If point has not moved off frame, accept the results. */
14307 if (!current_matrix_up_to_date_p
14308 /* Don't use try_window_reusing_current_matrix in this case
14309 because a window scroll function can have changed the
14310 buffer. */
14311 || !NILP (Vwindow_scroll_functions)
14312 || MINI_WINDOW_P (w)
14313 || !(used_current_matrix_p
14314 = try_window_reusing_current_matrix (w)))
14316 IF_DEBUG (debug_method_add (w, "1"));
14317 if (try_window (window, startp, TRY_WINDOW_CHECK_MARGINS) < 0)
14318 /* -1 means we need to scroll.
14319 0 means we need new matrices, but fonts_changed_p
14320 is set in that case, so we will detect it below. */
14321 goto try_to_scroll;
14324 if (fonts_changed_p)
14325 goto need_larger_matrices;
14327 if (w->cursor.vpos >= 0)
14329 if (!just_this_one_p
14330 || current_buffer->clip_changed
14331 || BEG_UNCHANGED < CHARPOS (startp))
14332 /* Forget any recorded base line for line number display. */
14333 w->base_line_number = Qnil;
14335 if (!cursor_row_fully_visible_p (w, 1, 0))
14337 clear_glyph_matrix (w->desired_matrix);
14338 last_line_misfit = 1;
14340 /* Drop through and scroll. */
14341 else
14342 goto done;
14344 else
14345 clear_glyph_matrix (w->desired_matrix);
14348 try_to_scroll:
14350 w->last_modified = make_number (0);
14351 w->last_overlay_modified = make_number (0);
14353 /* Redisplay the mode line. Select the buffer properly for that. */
14354 if (!update_mode_line)
14356 update_mode_line = 1;
14357 w->update_mode_line = Qt;
14360 /* Try to scroll by specified few lines. */
14361 if ((scroll_conservatively
14362 || scroll_step
14363 || temp_scroll_step
14364 || NUMBERP (current_buffer->scroll_up_aggressively)
14365 || NUMBERP (current_buffer->scroll_down_aggressively))
14366 && !current_buffer->clip_changed
14367 && CHARPOS (startp) >= BEGV
14368 && CHARPOS (startp) <= ZV)
14370 /* The function returns -1 if new fonts were loaded, 1 if
14371 successful, 0 if not successful. */
14372 int rc = try_scrolling (window, just_this_one_p,
14373 scroll_conservatively,
14374 scroll_step,
14375 temp_scroll_step, last_line_misfit);
14376 switch (rc)
14378 case SCROLLING_SUCCESS:
14379 goto done;
14381 case SCROLLING_NEED_LARGER_MATRICES:
14382 goto need_larger_matrices;
14384 case SCROLLING_FAILED:
14385 break;
14387 default:
14388 abort ();
14392 /* Finally, just choose place to start which centers point */
14394 recenter:
14395 if (centering_position < 0)
14396 centering_position = window_box_height (w) / 2;
14398 #if GLYPH_DEBUG
14399 debug_method_add (w, "recenter");
14400 #endif
14402 /* w->vscroll = 0; */
14404 /* Forget any previously recorded base line for line number display. */
14405 if (!buffer_unchanged_p)
14406 w->base_line_number = Qnil;
14408 /* Move backward half the height of the window. */
14409 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
14410 it.current_y = it.last_visible_y;
14411 move_it_vertically_backward (&it, centering_position);
14412 xassert (IT_CHARPOS (it) >= BEGV);
14414 /* The function move_it_vertically_backward may move over more
14415 than the specified y-distance. If it->w is small, e.g. a
14416 mini-buffer window, we may end up in front of the window's
14417 display area. Start displaying at the start of the line
14418 containing PT in this case. */
14419 if (it.current_y <= 0)
14421 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
14422 move_it_vertically_backward (&it, 0);
14423 it.current_y = 0;
14426 it.current_x = it.hpos = 0;
14428 /* Set startp here explicitly in case that helps avoid an infinite loop
14429 in case the window-scroll-functions functions get errors. */
14430 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
14432 /* Run scroll hooks. */
14433 startp = run_window_scroll_functions (window, it.current.pos);
14435 /* Redisplay the window. */
14436 if (!current_matrix_up_to_date_p
14437 || windows_or_buffers_changed
14438 || cursor_type_changed
14439 /* Don't use try_window_reusing_current_matrix in this case
14440 because it can have changed the buffer. */
14441 || !NILP (Vwindow_scroll_functions)
14442 || !just_this_one_p
14443 || MINI_WINDOW_P (w)
14444 || !(used_current_matrix_p
14445 = try_window_reusing_current_matrix (w)))
14446 try_window (window, startp, 0);
14448 /* If new fonts have been loaded (due to fontsets), give up. We
14449 have to start a new redisplay since we need to re-adjust glyph
14450 matrices. */
14451 if (fonts_changed_p)
14452 goto need_larger_matrices;
14454 /* If cursor did not appear assume that the middle of the window is
14455 in the first line of the window. Do it again with the next line.
14456 (Imagine a window of height 100, displaying two lines of height
14457 60. Moving back 50 from it->last_visible_y will end in the first
14458 line.) */
14459 if (w->cursor.vpos < 0)
14461 if (!NILP (w->window_end_valid)
14462 && PT >= Z - XFASTINT (w->window_end_pos))
14464 clear_glyph_matrix (w->desired_matrix);
14465 move_it_by_lines (&it, 1, 0);
14466 try_window (window, it.current.pos, 0);
14468 else if (PT < IT_CHARPOS (it))
14470 clear_glyph_matrix (w->desired_matrix);
14471 move_it_by_lines (&it, -1, 0);
14472 try_window (window, it.current.pos, 0);
14474 else
14476 /* Not much we can do about it. */
14480 /* Consider the following case: Window starts at BEGV, there is
14481 invisible, intangible text at BEGV, so that display starts at
14482 some point START > BEGV. It can happen that we are called with
14483 PT somewhere between BEGV and START. Try to handle that case. */
14484 if (w->cursor.vpos < 0)
14486 struct glyph_row *row = w->current_matrix->rows;
14487 if (row->mode_line_p)
14488 ++row;
14489 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
14492 if (!cursor_row_fully_visible_p (w, 0, 0))
14494 /* If vscroll is enabled, disable it and try again. */
14495 if (w->vscroll)
14497 w->vscroll = 0;
14498 clear_glyph_matrix (w->desired_matrix);
14499 goto recenter;
14502 /* If centering point failed to make the whole line visible,
14503 put point at the top instead. That has to make the whole line
14504 visible, if it can be done. */
14505 if (centering_position == 0)
14506 goto done;
14508 clear_glyph_matrix (w->desired_matrix);
14509 centering_position = 0;
14510 goto recenter;
14513 done:
14515 SET_TEXT_POS_FROM_MARKER (startp, w->start);
14516 w->start_at_line_beg = ((CHARPOS (startp) == BEGV
14517 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n')
14518 ? Qt : Qnil);
14520 /* Display the mode line, if we must. */
14521 if ((update_mode_line
14522 /* If window not full width, must redo its mode line
14523 if (a) the window to its side is being redone and
14524 (b) we do a frame-based redisplay. This is a consequence
14525 of how inverted lines are drawn in frame-based redisplay. */
14526 || (!just_this_one_p
14527 && !FRAME_WINDOW_P (f)
14528 && !WINDOW_FULL_WIDTH_P (w))
14529 /* Line number to display. */
14530 || INTEGERP (w->base_line_pos)
14531 /* Column number is displayed and different from the one displayed. */
14532 || (!NILP (w->column_number_displayed)
14533 && (XFASTINT (w->column_number_displayed)
14534 != (int) current_column ()))) /* iftc */
14535 /* This means that the window has a mode line. */
14536 && (WINDOW_WANTS_MODELINE_P (w)
14537 || WINDOW_WANTS_HEADER_LINE_P (w)))
14539 display_mode_lines (w);
14541 /* If mode line height has changed, arrange for a thorough
14542 immediate redisplay using the correct mode line height. */
14543 if (WINDOW_WANTS_MODELINE_P (w)
14544 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
14546 fonts_changed_p = 1;
14547 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
14548 = DESIRED_MODE_LINE_HEIGHT (w);
14551 /* If header line height has changed, arrange for a thorough
14552 immediate redisplay using the correct header line height. */
14553 if (WINDOW_WANTS_HEADER_LINE_P (w)
14554 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
14556 fonts_changed_p = 1;
14557 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
14558 = DESIRED_HEADER_LINE_HEIGHT (w);
14561 if (fonts_changed_p)
14562 goto need_larger_matrices;
14565 if (!line_number_displayed
14566 && !BUFFERP (w->base_line_pos))
14568 w->base_line_pos = Qnil;
14569 w->base_line_number = Qnil;
14572 finish_menu_bars:
14574 /* When we reach a frame's selected window, redo the frame's menu bar. */
14575 if (update_mode_line
14576 && EQ (FRAME_SELECTED_WINDOW (f), window))
14578 int redisplay_menu_p = 0;
14579 int redisplay_tool_bar_p = 0;
14581 if (FRAME_WINDOW_P (f))
14583 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
14584 || defined (HAVE_NS) || defined (USE_GTK)
14585 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
14586 #else
14587 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
14588 #endif
14590 else
14591 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
14593 if (redisplay_menu_p)
14594 display_menu_bar (w);
14596 #ifdef HAVE_WINDOW_SYSTEM
14597 if (FRAME_WINDOW_P (f))
14599 #if defined (USE_GTK) || defined (HAVE_NS)
14600 redisplay_tool_bar_p = FRAME_EXTERNAL_TOOL_BAR (f);
14601 #else
14602 redisplay_tool_bar_p = WINDOWP (f->tool_bar_window)
14603 && (FRAME_TOOL_BAR_LINES (f) > 0
14604 || !NILP (Vauto_resize_tool_bars));
14605 #endif
14607 if (redisplay_tool_bar_p && redisplay_tool_bar (f))
14609 ignore_mouse_drag_p = 1;
14612 #endif
14615 #ifdef HAVE_WINDOW_SYSTEM
14616 if (FRAME_WINDOW_P (f)
14617 && update_window_fringes (w, (just_this_one_p
14618 || (!used_current_matrix_p && !overlay_arrow_seen)
14619 || w->pseudo_window_p)))
14621 update_begin (f);
14622 BLOCK_INPUT;
14623 if (draw_window_fringes (w, 1))
14624 x_draw_vertical_border (w);
14625 UNBLOCK_INPUT;
14626 update_end (f);
14628 #endif /* HAVE_WINDOW_SYSTEM */
14630 /* We go to this label, with fonts_changed_p nonzero,
14631 if it is necessary to try again using larger glyph matrices.
14632 We have to redeem the scroll bar even in this case,
14633 because the loop in redisplay_internal expects that. */
14634 need_larger_matrices:
14636 finish_scroll_bars:
14638 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
14640 /* Set the thumb's position and size. */
14641 set_vertical_scroll_bar (w);
14643 /* Note that we actually used the scroll bar attached to this
14644 window, so it shouldn't be deleted at the end of redisplay. */
14645 if (FRAME_TERMINAL (f)->redeem_scroll_bar_hook)
14646 (*FRAME_TERMINAL (f)->redeem_scroll_bar_hook) (w);
14649 /* Restore current_buffer and value of point in it. The window
14650 update may have changed the buffer, so first make sure `opoint'
14651 is still valid (Bug#6177). */
14652 if (CHARPOS (opoint) < BEGV)
14653 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
14654 else if (CHARPOS (opoint) > ZV)
14655 TEMP_SET_PT_BOTH (Z, Z_BYTE);
14656 else
14657 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
14659 set_buffer_internal_1 (old);
14660 /* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become
14661 shorter. This can be caused by log truncation in *Messages*. */
14662 if (CHARPOS (lpoint) <= ZV)
14663 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
14665 unbind_to (count, Qnil);
14669 /* Build the complete desired matrix of WINDOW with a window start
14670 buffer position POS.
14672 Value is 1 if successful. It is zero if fonts were loaded during
14673 redisplay which makes re-adjusting glyph matrices necessary, and -1
14674 if point would appear in the scroll margins.
14675 (We check the former only if TRY_WINDOW_IGNORE_FONTS_CHANGE is
14676 unset in FLAGS, and the latter only if TRY_WINDOW_CHECK_MARGINS is
14677 set in FLAGS.) */
14680 try_window (Lisp_Object window, struct text_pos pos, int flags)
14682 struct window *w = XWINDOW (window);
14683 struct it it;
14684 struct glyph_row *last_text_row = NULL;
14685 struct frame *f = XFRAME (w->frame);
14687 /* Make POS the new window start. */
14688 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
14690 /* Mark cursor position as unknown. No overlay arrow seen. */
14691 w->cursor.vpos = -1;
14692 overlay_arrow_seen = 0;
14694 /* Initialize iterator and info to start at POS. */
14695 start_display (&it, w, pos);
14697 /* Display all lines of W. */
14698 while (it.current_y < it.last_visible_y)
14700 if (display_line (&it))
14701 last_text_row = it.glyph_row - 1;
14702 if (fonts_changed_p && !(flags & TRY_WINDOW_IGNORE_FONTS_CHANGE))
14703 return 0;
14706 /* Don't let the cursor end in the scroll margins. */
14707 if ((flags & TRY_WINDOW_CHECK_MARGINS)
14708 && !MINI_WINDOW_P (w))
14710 int this_scroll_margin;
14712 if (scroll_margin > 0)
14714 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
14715 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
14717 else
14718 this_scroll_margin = 0;
14720 if ((w->cursor.y >= 0 /* not vscrolled */
14721 && w->cursor.y < this_scroll_margin
14722 && CHARPOS (pos) > BEGV
14723 && IT_CHARPOS (it) < ZV)
14724 /* rms: considering make_cursor_line_fully_visible_p here
14725 seems to give wrong results. We don't want to recenter
14726 when the last line is partly visible, we want to allow
14727 that case to be handled in the usual way. */
14728 || w->cursor.y > it.last_visible_y - this_scroll_margin - 1)
14730 w->cursor.vpos = -1;
14731 clear_glyph_matrix (w->desired_matrix);
14732 return -1;
14736 /* If bottom moved off end of frame, change mode line percentage. */
14737 if (XFASTINT (w->window_end_pos) <= 0
14738 && Z != IT_CHARPOS (it))
14739 w->update_mode_line = Qt;
14741 /* Set window_end_pos to the offset of the last character displayed
14742 on the window from the end of current_buffer. Set
14743 window_end_vpos to its row number. */
14744 if (last_text_row)
14746 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
14747 w->window_end_bytepos
14748 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
14749 w->window_end_pos
14750 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
14751 w->window_end_vpos
14752 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
14753 xassert (MATRIX_ROW (w->desired_matrix, XFASTINT (w->window_end_vpos))
14754 ->displays_text_p);
14756 else
14758 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
14759 w->window_end_pos = make_number (Z - ZV);
14760 w->window_end_vpos = make_number (0);
14763 /* But that is not valid info until redisplay finishes. */
14764 w->window_end_valid = Qnil;
14765 return 1;
14770 /************************************************************************
14771 Window redisplay reusing current matrix when buffer has not changed
14772 ************************************************************************/
14774 /* Try redisplay of window W showing an unchanged buffer with a
14775 different window start than the last time it was displayed by
14776 reusing its current matrix. Value is non-zero if successful.
14777 W->start is the new window start. */
14779 static int
14780 try_window_reusing_current_matrix (struct window *w)
14782 struct frame *f = XFRAME (w->frame);
14783 struct glyph_row *row, *bottom_row;
14784 struct it it;
14785 struct run run;
14786 struct text_pos start, new_start;
14787 int nrows_scrolled, i;
14788 struct glyph_row *last_text_row;
14789 struct glyph_row *last_reused_text_row;
14790 struct glyph_row *start_row;
14791 int start_vpos, min_y, max_y;
14793 #if GLYPH_DEBUG
14794 if (inhibit_try_window_reusing)
14795 return 0;
14796 #endif
14798 if (/* This function doesn't handle terminal frames. */
14799 !FRAME_WINDOW_P (f)
14800 /* Don't try to reuse the display if windows have been split
14801 or such. */
14802 || windows_or_buffers_changed
14803 || cursor_type_changed)
14804 return 0;
14806 /* Can't do this if region may have changed. */
14807 if ((!NILP (Vtransient_mark_mode)
14808 && !NILP (current_buffer->mark_active))
14809 || !NILP (w->region_showing)
14810 || !NILP (Vshow_trailing_whitespace))
14811 return 0;
14813 /* If top-line visibility has changed, give up. */
14814 if (WINDOW_WANTS_HEADER_LINE_P (w)
14815 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
14816 return 0;
14818 /* Give up if old or new display is scrolled vertically. We could
14819 make this function handle this, but right now it doesn't. */
14820 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
14821 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row))
14822 return 0;
14824 /* The variable new_start now holds the new window start. The old
14825 start `start' can be determined from the current matrix. */
14826 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
14827 start = start_row->minpos;
14828 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
14830 /* Clear the desired matrix for the display below. */
14831 clear_glyph_matrix (w->desired_matrix);
14833 if (CHARPOS (new_start) <= CHARPOS (start))
14835 int first_row_y;
14837 /* Don't use this method if the display starts with an ellipsis
14838 displayed for invisible text. It's not easy to handle that case
14839 below, and it's certainly not worth the effort since this is
14840 not a frequent case. */
14841 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
14842 return 0;
14844 IF_DEBUG (debug_method_add (w, "twu1"));
14846 /* Display up to a row that can be reused. The variable
14847 last_text_row is set to the last row displayed that displays
14848 text. Note that it.vpos == 0 if or if not there is a
14849 header-line; it's not the same as the MATRIX_ROW_VPOS! */
14850 start_display (&it, w, new_start);
14851 first_row_y = it.current_y;
14852 w->cursor.vpos = -1;
14853 last_text_row = last_reused_text_row = NULL;
14855 while (it.current_y < it.last_visible_y
14856 && !fonts_changed_p)
14858 /* If we have reached into the characters in the START row,
14859 that means the line boundaries have changed. So we
14860 can't start copying with the row START. Maybe it will
14861 work to start copying with the following row. */
14862 while (IT_CHARPOS (it) > CHARPOS (start))
14864 /* Advance to the next row as the "start". */
14865 start_row++;
14866 start = start_row->minpos;
14867 /* If there are no more rows to try, or just one, give up. */
14868 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
14869 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row)
14870 || CHARPOS (start) == ZV)
14872 clear_glyph_matrix (w->desired_matrix);
14873 return 0;
14876 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
14878 /* If we have reached alignment,
14879 we can copy the rest of the rows. */
14880 if (IT_CHARPOS (it) == CHARPOS (start))
14881 break;
14883 if (display_line (&it))
14884 last_text_row = it.glyph_row - 1;
14887 /* A value of current_y < last_visible_y means that we stopped
14888 at the previous window start, which in turn means that we
14889 have at least one reusable row. */
14890 if (it.current_y < it.last_visible_y)
14892 /* IT.vpos always starts from 0; it counts text lines. */
14893 nrows_scrolled = it.vpos - (start_row - MATRIX_FIRST_TEXT_ROW (w->current_matrix));
14895 /* Find PT if not already found in the lines displayed. */
14896 if (w->cursor.vpos < 0)
14898 int dy = it.current_y - start_row->y;
14900 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
14901 row = row_containing_pos (w, PT, row, NULL, dy);
14902 if (row)
14903 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
14904 dy, nrows_scrolled);
14905 else
14907 clear_glyph_matrix (w->desired_matrix);
14908 return 0;
14912 /* Scroll the display. Do it before the current matrix is
14913 changed. The problem here is that update has not yet
14914 run, i.e. part of the current matrix is not up to date.
14915 scroll_run_hook will clear the cursor, and use the
14916 current matrix to get the height of the row the cursor is
14917 in. */
14918 run.current_y = start_row->y;
14919 run.desired_y = it.current_y;
14920 run.height = it.last_visible_y - it.current_y;
14922 if (run.height > 0 && run.current_y != run.desired_y)
14924 update_begin (f);
14925 FRAME_RIF (f)->update_window_begin_hook (w);
14926 FRAME_RIF (f)->clear_window_mouse_face (w);
14927 FRAME_RIF (f)->scroll_run_hook (w, &run);
14928 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
14929 update_end (f);
14932 /* Shift current matrix down by nrows_scrolled lines. */
14933 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
14934 rotate_matrix (w->current_matrix,
14935 start_vpos,
14936 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
14937 nrows_scrolled);
14939 /* Disable lines that must be updated. */
14940 for (i = 0; i < nrows_scrolled; ++i)
14941 (start_row + i)->enabled_p = 0;
14943 /* Re-compute Y positions. */
14944 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
14945 max_y = it.last_visible_y;
14946 for (row = start_row + nrows_scrolled;
14947 row < bottom_row;
14948 ++row)
14950 row->y = it.current_y;
14951 row->visible_height = row->height;
14953 if (row->y < min_y)
14954 row->visible_height -= min_y - row->y;
14955 if (row->y + row->height > max_y)
14956 row->visible_height -= row->y + row->height - max_y;
14957 row->redraw_fringe_bitmaps_p = 1;
14959 it.current_y += row->height;
14961 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
14962 last_reused_text_row = row;
14963 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
14964 break;
14967 /* Disable lines in the current matrix which are now
14968 below the window. */
14969 for (++row; row < bottom_row; ++row)
14970 row->enabled_p = row->mode_line_p = 0;
14973 /* Update window_end_pos etc.; last_reused_text_row is the last
14974 reused row from the current matrix containing text, if any.
14975 The value of last_text_row is the last displayed line
14976 containing text. */
14977 if (last_reused_text_row)
14979 w->window_end_bytepos
14980 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
14981 w->window_end_pos
14982 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_reused_text_row));
14983 w->window_end_vpos
14984 = make_number (MATRIX_ROW_VPOS (last_reused_text_row,
14985 w->current_matrix));
14987 else if (last_text_row)
14989 w->window_end_bytepos
14990 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
14991 w->window_end_pos
14992 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
14993 w->window_end_vpos
14994 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
14996 else
14998 /* This window must be completely empty. */
14999 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
15000 w->window_end_pos = make_number (Z - ZV);
15001 w->window_end_vpos = make_number (0);
15003 w->window_end_valid = Qnil;
15005 /* Update hint: don't try scrolling again in update_window. */
15006 w->desired_matrix->no_scrolling_p = 1;
15008 #if GLYPH_DEBUG
15009 debug_method_add (w, "try_window_reusing_current_matrix 1");
15010 #endif
15011 return 1;
15013 else if (CHARPOS (new_start) > CHARPOS (start))
15015 struct glyph_row *pt_row, *row;
15016 struct glyph_row *first_reusable_row;
15017 struct glyph_row *first_row_to_display;
15018 int dy;
15019 int yb = window_text_bottom_y (w);
15021 /* Find the row starting at new_start, if there is one. Don't
15022 reuse a partially visible line at the end. */
15023 first_reusable_row = start_row;
15024 while (first_reusable_row->enabled_p
15025 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
15026 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
15027 < CHARPOS (new_start)))
15028 ++first_reusable_row;
15030 /* Give up if there is no row to reuse. */
15031 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
15032 || !first_reusable_row->enabled_p
15033 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
15034 != CHARPOS (new_start)))
15035 return 0;
15037 /* We can reuse fully visible rows beginning with
15038 first_reusable_row to the end of the window. Set
15039 first_row_to_display to the first row that cannot be reused.
15040 Set pt_row to the row containing point, if there is any. */
15041 pt_row = NULL;
15042 for (first_row_to_display = first_reusable_row;
15043 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
15044 ++first_row_to_display)
15046 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
15047 && PT < MATRIX_ROW_END_CHARPOS (first_row_to_display))
15048 pt_row = first_row_to_display;
15051 /* Start displaying at the start of first_row_to_display. */
15052 xassert (first_row_to_display->y < yb);
15053 init_to_row_start (&it, w, first_row_to_display);
15055 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
15056 - start_vpos);
15057 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
15058 - nrows_scrolled);
15059 it.current_y = (first_row_to_display->y - first_reusable_row->y
15060 + WINDOW_HEADER_LINE_HEIGHT (w));
15062 /* Display lines beginning with first_row_to_display in the
15063 desired matrix. Set last_text_row to the last row displayed
15064 that displays text. */
15065 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
15066 if (pt_row == NULL)
15067 w->cursor.vpos = -1;
15068 last_text_row = NULL;
15069 while (it.current_y < it.last_visible_y && !fonts_changed_p)
15070 if (display_line (&it))
15071 last_text_row = it.glyph_row - 1;
15073 /* If point is in a reused row, adjust y and vpos of the cursor
15074 position. */
15075 if (pt_row)
15077 w->cursor.vpos -= nrows_scrolled;
15078 w->cursor.y -= first_reusable_row->y - start_row->y;
15081 /* Give up if point isn't in a row displayed or reused. (This
15082 also handles the case where w->cursor.vpos < nrows_scrolled
15083 after the calls to display_line, which can happen with scroll
15084 margins. See bug#1295.) */
15085 if (w->cursor.vpos < 0)
15087 clear_glyph_matrix (w->desired_matrix);
15088 return 0;
15091 /* Scroll the display. */
15092 run.current_y = first_reusable_row->y;
15093 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
15094 run.height = it.last_visible_y - run.current_y;
15095 dy = run.current_y - run.desired_y;
15097 if (run.height)
15099 update_begin (f);
15100 FRAME_RIF (f)->update_window_begin_hook (w);
15101 FRAME_RIF (f)->clear_window_mouse_face (w);
15102 FRAME_RIF (f)->scroll_run_hook (w, &run);
15103 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
15104 update_end (f);
15107 /* Adjust Y positions of reused rows. */
15108 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
15109 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
15110 max_y = it.last_visible_y;
15111 for (row = first_reusable_row; row < first_row_to_display; ++row)
15113 row->y -= dy;
15114 row->visible_height = row->height;
15115 if (row->y < min_y)
15116 row->visible_height -= min_y - row->y;
15117 if (row->y + row->height > max_y)
15118 row->visible_height -= row->y + row->height - max_y;
15119 row->redraw_fringe_bitmaps_p = 1;
15122 /* Scroll the current matrix. */
15123 xassert (nrows_scrolled > 0);
15124 rotate_matrix (w->current_matrix,
15125 start_vpos,
15126 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
15127 -nrows_scrolled);
15129 /* Disable rows not reused. */
15130 for (row -= nrows_scrolled; row < bottom_row; ++row)
15131 row->enabled_p = 0;
15133 /* Point may have moved to a different line, so we cannot assume that
15134 the previous cursor position is valid; locate the correct row. */
15135 if (pt_row)
15137 for (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
15138 row < bottom_row && PT >= MATRIX_ROW_END_CHARPOS (row);
15139 row++)
15141 w->cursor.vpos++;
15142 w->cursor.y = row->y;
15144 if (row < bottom_row)
15146 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
15147 struct glyph *end = glyph + row->used[TEXT_AREA];
15149 /* Can't use this optimization with bidi-reordered glyph
15150 rows, unless cursor is already at point. */
15151 if (!NILP (XBUFFER (w->buffer)->bidi_display_reordering))
15153 if (!(w->cursor.hpos >= 0
15154 && w->cursor.hpos < row->used[TEXT_AREA]
15155 && BUFFERP (glyph->object)
15156 && glyph->charpos == PT))
15157 return 0;
15159 else
15160 for (; glyph < end
15161 && (!BUFFERP (glyph->object)
15162 || glyph->charpos < PT);
15163 glyph++)
15165 w->cursor.hpos++;
15166 w->cursor.x += glyph->pixel_width;
15171 /* Adjust window end. A null value of last_text_row means that
15172 the window end is in reused rows which in turn means that
15173 only its vpos can have changed. */
15174 if (last_text_row)
15176 w->window_end_bytepos
15177 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
15178 w->window_end_pos
15179 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
15180 w->window_end_vpos
15181 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
15183 else
15185 w->window_end_vpos
15186 = make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled);
15189 w->window_end_valid = Qnil;
15190 w->desired_matrix->no_scrolling_p = 1;
15192 #if GLYPH_DEBUG
15193 debug_method_add (w, "try_window_reusing_current_matrix 2");
15194 #endif
15195 return 1;
15198 return 0;
15203 /************************************************************************
15204 Window redisplay reusing current matrix when buffer has changed
15205 ************************************************************************/
15207 static struct glyph_row *find_last_unchanged_at_beg_row (struct window *);
15208 static struct glyph_row *find_first_unchanged_at_end_row (struct window *,
15209 EMACS_INT *, EMACS_INT *);
15210 static struct glyph_row *
15211 find_last_row_displaying_text (struct glyph_matrix *, struct it *,
15212 struct glyph_row *);
15215 /* Return the last row in MATRIX displaying text. If row START is
15216 non-null, start searching with that row. IT gives the dimensions
15217 of the display. Value is null if matrix is empty; otherwise it is
15218 a pointer to the row found. */
15220 static struct glyph_row *
15221 find_last_row_displaying_text (struct glyph_matrix *matrix, struct it *it,
15222 struct glyph_row *start)
15224 struct glyph_row *row, *row_found;
15226 /* Set row_found to the last row in IT->w's current matrix
15227 displaying text. The loop looks funny but think of partially
15228 visible lines. */
15229 row_found = NULL;
15230 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
15231 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
15233 xassert (row->enabled_p);
15234 row_found = row;
15235 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
15236 break;
15237 ++row;
15240 return row_found;
15244 /* Return the last row in the current matrix of W that is not affected
15245 by changes at the start of current_buffer that occurred since W's
15246 current matrix was built. Value is null if no such row exists.
15248 BEG_UNCHANGED us the number of characters unchanged at the start of
15249 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
15250 first changed character in current_buffer. Characters at positions <
15251 BEG + BEG_UNCHANGED are at the same buffer positions as they were
15252 when the current matrix was built. */
15254 static struct glyph_row *
15255 find_last_unchanged_at_beg_row (struct window *w)
15257 EMACS_INT first_changed_pos = BEG + BEG_UNCHANGED;
15258 struct glyph_row *row;
15259 struct glyph_row *row_found = NULL;
15260 int yb = window_text_bottom_y (w);
15262 /* Find the last row displaying unchanged text. */
15263 for (row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
15264 MATRIX_ROW_DISPLAYS_TEXT_P (row)
15265 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos;
15266 ++row)
15268 if (/* If row ends before first_changed_pos, it is unchanged,
15269 except in some case. */
15270 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
15271 /* When row ends in ZV and we write at ZV it is not
15272 unchanged. */
15273 && !row->ends_at_zv_p
15274 /* When first_changed_pos is the end of a continued line,
15275 row is not unchanged because it may be no longer
15276 continued. */
15277 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
15278 && (row->continued_p
15279 || row->exact_window_width_line_p)))
15280 row_found = row;
15282 /* Stop if last visible row. */
15283 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
15284 break;
15287 return row_found;
15291 /* Find the first glyph row in the current matrix of W that is not
15292 affected by changes at the end of current_buffer since the
15293 time W's current matrix was built.
15295 Return in *DELTA the number of chars by which buffer positions in
15296 unchanged text at the end of current_buffer must be adjusted.
15298 Return in *DELTA_BYTES the corresponding number of bytes.
15300 Value is null if no such row exists, i.e. all rows are affected by
15301 changes. */
15303 static struct glyph_row *
15304 find_first_unchanged_at_end_row (struct window *w,
15305 EMACS_INT *delta, EMACS_INT *delta_bytes)
15307 struct glyph_row *row;
15308 struct glyph_row *row_found = NULL;
15310 *delta = *delta_bytes = 0;
15312 /* Display must not have been paused, otherwise the current matrix
15313 is not up to date. */
15314 eassert (!NILP (w->window_end_valid));
15316 /* A value of window_end_pos >= END_UNCHANGED means that the window
15317 end is in the range of changed text. If so, there is no
15318 unchanged row at the end of W's current matrix. */
15319 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
15320 return NULL;
15322 /* Set row to the last row in W's current matrix displaying text. */
15323 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
15325 /* If matrix is entirely empty, no unchanged row exists. */
15326 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
15328 /* The value of row is the last glyph row in the matrix having a
15329 meaningful buffer position in it. The end position of row
15330 corresponds to window_end_pos. This allows us to translate
15331 buffer positions in the current matrix to current buffer
15332 positions for characters not in changed text. */
15333 EMACS_INT Z_old =
15334 MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
15335 EMACS_INT Z_BYTE_old =
15336 MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
15337 EMACS_INT last_unchanged_pos, last_unchanged_pos_old;
15338 struct glyph_row *first_text_row
15339 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
15341 *delta = Z - Z_old;
15342 *delta_bytes = Z_BYTE - Z_BYTE_old;
15344 /* Set last_unchanged_pos to the buffer position of the last
15345 character in the buffer that has not been changed. Z is the
15346 index + 1 of the last character in current_buffer, i.e. by
15347 subtracting END_UNCHANGED we get the index of the last
15348 unchanged character, and we have to add BEG to get its buffer
15349 position. */
15350 last_unchanged_pos = Z - END_UNCHANGED + BEG;
15351 last_unchanged_pos_old = last_unchanged_pos - *delta;
15353 /* Search backward from ROW for a row displaying a line that
15354 starts at a minimum position >= last_unchanged_pos_old. */
15355 for (; row > first_text_row; --row)
15357 /* This used to abort, but it can happen.
15358 It is ok to just stop the search instead here. KFS. */
15359 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
15360 break;
15362 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
15363 row_found = row;
15367 eassert (!row_found || MATRIX_ROW_DISPLAYS_TEXT_P (row_found));
15369 return row_found;
15373 /* Make sure that glyph rows in the current matrix of window W
15374 reference the same glyph memory as corresponding rows in the
15375 frame's frame matrix. This function is called after scrolling W's
15376 current matrix on a terminal frame in try_window_id and
15377 try_window_reusing_current_matrix. */
15379 static void
15380 sync_frame_with_window_matrix_rows (struct window *w)
15382 struct frame *f = XFRAME (w->frame);
15383 struct glyph_row *window_row, *window_row_end, *frame_row;
15385 /* Preconditions: W must be a leaf window and full-width. Its frame
15386 must have a frame matrix. */
15387 xassert (NILP (w->hchild) && NILP (w->vchild));
15388 xassert (WINDOW_FULL_WIDTH_P (w));
15389 xassert (!FRAME_WINDOW_P (f));
15391 /* If W is a full-width window, glyph pointers in W's current matrix
15392 have, by definition, to be the same as glyph pointers in the
15393 corresponding frame matrix. Note that frame matrices have no
15394 marginal areas (see build_frame_matrix). */
15395 window_row = w->current_matrix->rows;
15396 window_row_end = window_row + w->current_matrix->nrows;
15397 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
15398 while (window_row < window_row_end)
15400 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
15401 struct glyph *end = window_row->glyphs[LAST_AREA];
15403 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
15404 frame_row->glyphs[TEXT_AREA] = start;
15405 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
15406 frame_row->glyphs[LAST_AREA] = end;
15408 /* Disable frame rows whose corresponding window rows have
15409 been disabled in try_window_id. */
15410 if (!window_row->enabled_p)
15411 frame_row->enabled_p = 0;
15413 ++window_row, ++frame_row;
15418 /* Find the glyph row in window W containing CHARPOS. Consider all
15419 rows between START and END (not inclusive). END null means search
15420 all rows to the end of the display area of W. Value is the row
15421 containing CHARPOS or null. */
15423 struct glyph_row *
15424 row_containing_pos (struct window *w, EMACS_INT charpos,
15425 struct glyph_row *start, struct glyph_row *end, int dy)
15427 struct glyph_row *row = start;
15428 struct glyph_row *best_row = NULL;
15429 EMACS_INT mindif = BUF_ZV (XBUFFER (w->buffer)) + 1;
15430 int last_y;
15432 /* If we happen to start on a header-line, skip that. */
15433 if (row->mode_line_p)
15434 ++row;
15436 if ((end && row >= end) || !row->enabled_p)
15437 return NULL;
15439 last_y = window_text_bottom_y (w) - dy;
15441 while (1)
15443 /* Give up if we have gone too far. */
15444 if (end && row >= end)
15445 return NULL;
15446 /* This formerly returned if they were equal.
15447 I think that both quantities are of a "last plus one" type;
15448 if so, when they are equal, the row is within the screen. -- rms. */
15449 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
15450 return NULL;
15452 /* If it is in this row, return this row. */
15453 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
15454 || (MATRIX_ROW_END_CHARPOS (row) == charpos
15455 /* The end position of a row equals the start
15456 position of the next row. If CHARPOS is there, we
15457 would rather display it in the next line, except
15458 when this line ends in ZV. */
15459 && !row->ends_at_zv_p
15460 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
15461 && charpos >= MATRIX_ROW_START_CHARPOS (row))
15463 struct glyph *g;
15465 if (NILP (XBUFFER (w->buffer)->bidi_display_reordering)
15466 || (!best_row && !row->continued_p))
15467 return row;
15468 /* In bidi-reordered rows, there could be several rows
15469 occluding point, all of them belonging to the same
15470 continued line. We need to find the row which fits
15471 CHARPOS the best. */
15472 for (g = row->glyphs[TEXT_AREA];
15473 g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
15474 g++)
15476 if (!STRINGP (g->object))
15478 if (g->charpos > 0 && eabs (g->charpos - charpos) < mindif)
15480 mindif = eabs (g->charpos - charpos);
15481 best_row = row;
15482 /* Exact match always wins. */
15483 if (mindif == 0)
15484 return best_row;
15489 else if (best_row && !row->continued_p)
15490 return best_row;
15491 ++row;
15496 /* Try to redisplay window W by reusing its existing display. W's
15497 current matrix must be up to date when this function is called,
15498 i.e. window_end_valid must not be nil.
15500 Value is
15502 1 if display has been updated
15503 0 if otherwise unsuccessful
15504 -1 if redisplay with same window start is known not to succeed
15506 The following steps are performed:
15508 1. Find the last row in the current matrix of W that is not
15509 affected by changes at the start of current_buffer. If no such row
15510 is found, give up.
15512 2. Find the first row in W's current matrix that is not affected by
15513 changes at the end of current_buffer. Maybe there is no such row.
15515 3. Display lines beginning with the row + 1 found in step 1 to the
15516 row found in step 2 or, if step 2 didn't find a row, to the end of
15517 the window.
15519 4. If cursor is not known to appear on the window, give up.
15521 5. If display stopped at the row found in step 2, scroll the
15522 display and current matrix as needed.
15524 6. Maybe display some lines at the end of W, if we must. This can
15525 happen under various circumstances, like a partially visible line
15526 becoming fully visible, or because newly displayed lines are displayed
15527 in smaller font sizes.
15529 7. Update W's window end information. */
15531 static int
15532 try_window_id (struct window *w)
15534 struct frame *f = XFRAME (w->frame);
15535 struct glyph_matrix *current_matrix = w->current_matrix;
15536 struct glyph_matrix *desired_matrix = w->desired_matrix;
15537 struct glyph_row *last_unchanged_at_beg_row;
15538 struct glyph_row *first_unchanged_at_end_row;
15539 struct glyph_row *row;
15540 struct glyph_row *bottom_row;
15541 int bottom_vpos;
15542 struct it it;
15543 EMACS_INT delta = 0, delta_bytes = 0, stop_pos;
15544 int dvpos, dy;
15545 struct text_pos start_pos;
15546 struct run run;
15547 int first_unchanged_at_end_vpos = 0;
15548 struct glyph_row *last_text_row, *last_text_row_at_end;
15549 struct text_pos start;
15550 EMACS_INT first_changed_charpos, last_changed_charpos;
15552 #if GLYPH_DEBUG
15553 if (inhibit_try_window_id)
15554 return 0;
15555 #endif
15557 /* This is handy for debugging. */
15558 #if 0
15559 #define GIVE_UP(X) \
15560 do { \
15561 fprintf (stderr, "try_window_id give up %d\n", (X)); \
15562 return 0; \
15563 } while (0)
15564 #else
15565 #define GIVE_UP(X) return 0
15566 #endif
15568 SET_TEXT_POS_FROM_MARKER (start, w->start);
15570 /* Don't use this for mini-windows because these can show
15571 messages and mini-buffers, and we don't handle that here. */
15572 if (MINI_WINDOW_P (w))
15573 GIVE_UP (1);
15575 /* This flag is used to prevent redisplay optimizations. */
15576 if (windows_or_buffers_changed || cursor_type_changed)
15577 GIVE_UP (2);
15579 /* Verify that narrowing has not changed.
15580 Also verify that we were not told to prevent redisplay optimizations.
15581 It would be nice to further
15582 reduce the number of cases where this prevents try_window_id. */
15583 if (current_buffer->clip_changed
15584 || current_buffer->prevent_redisplay_optimizations_p)
15585 GIVE_UP (3);
15587 /* Window must either use window-based redisplay or be full width. */
15588 if (!FRAME_WINDOW_P (f)
15589 && (!FRAME_LINE_INS_DEL_OK (f)
15590 || !WINDOW_FULL_WIDTH_P (w)))
15591 GIVE_UP (4);
15593 /* Give up if point is known NOT to appear in W. */
15594 if (PT < CHARPOS (start))
15595 GIVE_UP (5);
15597 /* Another way to prevent redisplay optimizations. */
15598 if (XFASTINT (w->last_modified) == 0)
15599 GIVE_UP (6);
15601 /* Verify that window is not hscrolled. */
15602 if (XFASTINT (w->hscroll) != 0)
15603 GIVE_UP (7);
15605 /* Verify that display wasn't paused. */
15606 if (NILP (w->window_end_valid))
15607 GIVE_UP (8);
15609 /* Can't use this if highlighting a region because a cursor movement
15610 will do more than just set the cursor. */
15611 if (!NILP (Vtransient_mark_mode)
15612 && !NILP (current_buffer->mark_active))
15613 GIVE_UP (9);
15615 /* Likewise if highlighting trailing whitespace. */
15616 if (!NILP (Vshow_trailing_whitespace))
15617 GIVE_UP (11);
15619 /* Likewise if showing a region. */
15620 if (!NILP (w->region_showing))
15621 GIVE_UP (10);
15623 /* Can't use this if overlay arrow position and/or string have
15624 changed. */
15625 if (overlay_arrows_changed_p ())
15626 GIVE_UP (12);
15628 /* When word-wrap is on, adding a space to the first word of a
15629 wrapped line can change the wrap position, altering the line
15630 above it. It might be worthwhile to handle this more
15631 intelligently, but for now just redisplay from scratch. */
15632 if (!NILP (XBUFFER (w->buffer)->word_wrap))
15633 GIVE_UP (21);
15635 /* Under bidi reordering, adding or deleting a character in the
15636 beginning of a paragraph, before the first strong directional
15637 character, can change the base direction of the paragraph (unless
15638 the buffer specifies a fixed paragraph direction), which will
15639 require to redisplay the whole paragraph. It might be worthwhile
15640 to find the paragraph limits and widen the range of redisplayed
15641 lines to that, but for now just give up this optimization and
15642 redisplay from scratch. */
15643 if (!NILP (XBUFFER (w->buffer)->bidi_display_reordering)
15644 && NILP (XBUFFER (w->buffer)->bidi_paragraph_direction))
15645 GIVE_UP (22);
15647 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
15648 only if buffer has really changed. The reason is that the gap is
15649 initially at Z for freshly visited files. The code below would
15650 set end_unchanged to 0 in that case. */
15651 if (MODIFF > SAVE_MODIFF
15652 /* This seems to happen sometimes after saving a buffer. */
15653 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
15655 if (GPT - BEG < BEG_UNCHANGED)
15656 BEG_UNCHANGED = GPT - BEG;
15657 if (Z - GPT < END_UNCHANGED)
15658 END_UNCHANGED = Z - GPT;
15661 /* The position of the first and last character that has been changed. */
15662 first_changed_charpos = BEG + BEG_UNCHANGED;
15663 last_changed_charpos = Z - END_UNCHANGED;
15665 /* If window starts after a line end, and the last change is in
15666 front of that newline, then changes don't affect the display.
15667 This case happens with stealth-fontification. Note that although
15668 the display is unchanged, glyph positions in the matrix have to
15669 be adjusted, of course. */
15670 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
15671 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
15672 && ((last_changed_charpos < CHARPOS (start)
15673 && CHARPOS (start) == BEGV)
15674 || (last_changed_charpos < CHARPOS (start) - 1
15675 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
15677 EMACS_INT Z_old, delta, Z_BYTE_old, delta_bytes;
15678 struct glyph_row *r0;
15680 /* Compute how many chars/bytes have been added to or removed
15681 from the buffer. */
15682 Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
15683 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
15684 delta = Z - Z_old;
15685 delta_bytes = Z_BYTE - Z_BYTE_old;
15687 /* Give up if PT is not in the window. Note that it already has
15688 been checked at the start of try_window_id that PT is not in
15689 front of the window start. */
15690 if (PT >= MATRIX_ROW_END_CHARPOS (row) + delta)
15691 GIVE_UP (13);
15693 /* If window start is unchanged, we can reuse the whole matrix
15694 as is, after adjusting glyph positions. No need to compute
15695 the window end again, since its offset from Z hasn't changed. */
15696 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
15697 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + delta
15698 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + delta_bytes
15699 /* PT must not be in a partially visible line. */
15700 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + delta
15701 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
15703 /* Adjust positions in the glyph matrix. */
15704 if (delta || delta_bytes)
15706 struct glyph_row *r1
15707 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
15708 increment_matrix_positions (w->current_matrix,
15709 MATRIX_ROW_VPOS (r0, current_matrix),
15710 MATRIX_ROW_VPOS (r1, current_matrix),
15711 delta, delta_bytes);
15714 /* Set the cursor. */
15715 row = row_containing_pos (w, PT, r0, NULL, 0);
15716 if (row)
15717 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
15718 else
15719 abort ();
15720 return 1;
15724 /* Handle the case that changes are all below what is displayed in
15725 the window, and that PT is in the window. This shortcut cannot
15726 be taken if ZV is visible in the window, and text has been added
15727 there that is visible in the window. */
15728 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
15729 /* ZV is not visible in the window, or there are no
15730 changes at ZV, actually. */
15731 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
15732 || first_changed_charpos == last_changed_charpos))
15734 struct glyph_row *r0;
15736 /* Give up if PT is not in the window. Note that it already has
15737 been checked at the start of try_window_id that PT is not in
15738 front of the window start. */
15739 if (PT >= MATRIX_ROW_END_CHARPOS (row))
15740 GIVE_UP (14);
15742 /* If window start is unchanged, we can reuse the whole matrix
15743 as is, without changing glyph positions since no text has
15744 been added/removed in front of the window end. */
15745 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
15746 if (TEXT_POS_EQUAL_P (start, r0->minpos)
15747 /* PT must not be in a partially visible line. */
15748 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
15749 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
15751 /* We have to compute the window end anew since text
15752 could have been added/removed after it. */
15753 w->window_end_pos
15754 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
15755 w->window_end_bytepos
15756 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
15758 /* Set the cursor. */
15759 row = row_containing_pos (w, PT, r0, NULL, 0);
15760 if (row)
15761 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
15762 else
15763 abort ();
15764 return 2;
15768 /* Give up if window start is in the changed area.
15770 The condition used to read
15772 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
15774 but why that was tested escapes me at the moment. */
15775 if (CHARPOS (start) >= first_changed_charpos
15776 && CHARPOS (start) <= last_changed_charpos)
15777 GIVE_UP (15);
15779 /* Check that window start agrees with the start of the first glyph
15780 row in its current matrix. Check this after we know the window
15781 start is not in changed text, otherwise positions would not be
15782 comparable. */
15783 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
15784 if (!TEXT_POS_EQUAL_P (start, row->minpos))
15785 GIVE_UP (16);
15787 /* Give up if the window ends in strings. Overlay strings
15788 at the end are difficult to handle, so don't try. */
15789 row = MATRIX_ROW (current_matrix, XFASTINT (w->window_end_vpos));
15790 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
15791 GIVE_UP (20);
15793 /* Compute the position at which we have to start displaying new
15794 lines. Some of the lines at the top of the window might be
15795 reusable because they are not displaying changed text. Find the
15796 last row in W's current matrix not affected by changes at the
15797 start of current_buffer. Value is null if changes start in the
15798 first line of window. */
15799 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
15800 if (last_unchanged_at_beg_row)
15802 /* Avoid starting to display in the moddle of a character, a TAB
15803 for instance. This is easier than to set up the iterator
15804 exactly, and it's not a frequent case, so the additional
15805 effort wouldn't really pay off. */
15806 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
15807 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
15808 && last_unchanged_at_beg_row > w->current_matrix->rows)
15809 --last_unchanged_at_beg_row;
15811 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
15812 GIVE_UP (17);
15814 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
15815 GIVE_UP (18);
15816 start_pos = it.current.pos;
15818 /* Start displaying new lines in the desired matrix at the same
15819 vpos we would use in the current matrix, i.e. below
15820 last_unchanged_at_beg_row. */
15821 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
15822 current_matrix);
15823 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
15824 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
15826 xassert (it.hpos == 0 && it.current_x == 0);
15828 else
15830 /* There are no reusable lines at the start of the window.
15831 Start displaying in the first text line. */
15832 start_display (&it, w, start);
15833 it.vpos = it.first_vpos;
15834 start_pos = it.current.pos;
15837 /* Find the first row that is not affected by changes at the end of
15838 the buffer. Value will be null if there is no unchanged row, in
15839 which case we must redisplay to the end of the window. delta
15840 will be set to the value by which buffer positions beginning with
15841 first_unchanged_at_end_row have to be adjusted due to text
15842 changes. */
15843 first_unchanged_at_end_row
15844 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
15845 IF_DEBUG (debug_delta = delta);
15846 IF_DEBUG (debug_delta_bytes = delta_bytes);
15848 /* Set stop_pos to the buffer position up to which we will have to
15849 display new lines. If first_unchanged_at_end_row != NULL, this
15850 is the buffer position of the start of the line displayed in that
15851 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
15852 that we don't stop at a buffer position. */
15853 stop_pos = 0;
15854 if (first_unchanged_at_end_row)
15856 xassert (last_unchanged_at_beg_row == NULL
15857 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
15859 /* If this is a continuation line, move forward to the next one
15860 that isn't. Changes in lines above affect this line.
15861 Caution: this may move first_unchanged_at_end_row to a row
15862 not displaying text. */
15863 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
15864 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
15865 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
15866 < it.last_visible_y))
15867 ++first_unchanged_at_end_row;
15869 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
15870 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
15871 >= it.last_visible_y))
15872 first_unchanged_at_end_row = NULL;
15873 else
15875 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
15876 + delta);
15877 first_unchanged_at_end_vpos
15878 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
15879 xassert (stop_pos >= Z - END_UNCHANGED);
15882 else if (last_unchanged_at_beg_row == NULL)
15883 GIVE_UP (19);
15886 #if GLYPH_DEBUG
15888 /* Either there is no unchanged row at the end, or the one we have
15889 now displays text. This is a necessary condition for the window
15890 end pos calculation at the end of this function. */
15891 xassert (first_unchanged_at_end_row == NULL
15892 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
15894 debug_last_unchanged_at_beg_vpos
15895 = (last_unchanged_at_beg_row
15896 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
15897 : -1);
15898 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
15900 #endif /* GLYPH_DEBUG != 0 */
15903 /* Display new lines. Set last_text_row to the last new line
15904 displayed which has text on it, i.e. might end up as being the
15905 line where the window_end_vpos is. */
15906 w->cursor.vpos = -1;
15907 last_text_row = NULL;
15908 overlay_arrow_seen = 0;
15909 while (it.current_y < it.last_visible_y
15910 && !fonts_changed_p
15911 && (first_unchanged_at_end_row == NULL
15912 || IT_CHARPOS (it) < stop_pos))
15914 if (display_line (&it))
15915 last_text_row = it.glyph_row - 1;
15918 if (fonts_changed_p)
15919 return -1;
15922 /* Compute differences in buffer positions, y-positions etc. for
15923 lines reused at the bottom of the window. Compute what we can
15924 scroll. */
15925 if (first_unchanged_at_end_row
15926 /* No lines reused because we displayed everything up to the
15927 bottom of the window. */
15928 && it.current_y < it.last_visible_y)
15930 dvpos = (it.vpos
15931 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
15932 current_matrix));
15933 dy = it.current_y - first_unchanged_at_end_row->y;
15934 run.current_y = first_unchanged_at_end_row->y;
15935 run.desired_y = run.current_y + dy;
15936 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
15938 else
15940 delta = delta_bytes = dvpos = dy
15941 = run.current_y = run.desired_y = run.height = 0;
15942 first_unchanged_at_end_row = NULL;
15944 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
15947 /* Find the cursor if not already found. We have to decide whether
15948 PT will appear on this window (it sometimes doesn't, but this is
15949 not a very frequent case.) This decision has to be made before
15950 the current matrix is altered. A value of cursor.vpos < 0 means
15951 that PT is either in one of the lines beginning at
15952 first_unchanged_at_end_row or below the window. Don't care for
15953 lines that might be displayed later at the window end; as
15954 mentioned, this is not a frequent case. */
15955 if (w->cursor.vpos < 0)
15957 /* Cursor in unchanged rows at the top? */
15958 if (PT < CHARPOS (start_pos)
15959 && last_unchanged_at_beg_row)
15961 row = row_containing_pos (w, PT,
15962 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
15963 last_unchanged_at_beg_row + 1, 0);
15964 if (row)
15965 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
15968 /* Start from first_unchanged_at_end_row looking for PT. */
15969 else if (first_unchanged_at_end_row)
15971 row = row_containing_pos (w, PT - delta,
15972 first_unchanged_at_end_row, NULL, 0);
15973 if (row)
15974 set_cursor_from_row (w, row, w->current_matrix, delta,
15975 delta_bytes, dy, dvpos);
15978 /* Give up if cursor was not found. */
15979 if (w->cursor.vpos < 0)
15981 clear_glyph_matrix (w->desired_matrix);
15982 return -1;
15986 /* Don't let the cursor end in the scroll margins. */
15988 int this_scroll_margin, cursor_height;
15990 this_scroll_margin = max (0, scroll_margin);
15991 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
15992 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
15993 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
15995 if ((w->cursor.y < this_scroll_margin
15996 && CHARPOS (start) > BEGV)
15997 /* Old redisplay didn't take scroll margin into account at the bottom,
15998 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
15999 || (w->cursor.y + (make_cursor_line_fully_visible_p
16000 ? cursor_height + this_scroll_margin
16001 : 1)) > it.last_visible_y)
16003 w->cursor.vpos = -1;
16004 clear_glyph_matrix (w->desired_matrix);
16005 return -1;
16009 /* Scroll the display. Do it before changing the current matrix so
16010 that xterm.c doesn't get confused about where the cursor glyph is
16011 found. */
16012 if (dy && run.height)
16014 update_begin (f);
16016 if (FRAME_WINDOW_P (f))
16018 FRAME_RIF (f)->update_window_begin_hook (w);
16019 FRAME_RIF (f)->clear_window_mouse_face (w);
16020 FRAME_RIF (f)->scroll_run_hook (w, &run);
16021 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
16023 else
16025 /* Terminal frame. In this case, dvpos gives the number of
16026 lines to scroll by; dvpos < 0 means scroll up. */
16027 int first_unchanged_at_end_vpos
16028 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
16029 int from = WINDOW_TOP_EDGE_LINE (w) + first_unchanged_at_end_vpos;
16030 int end = (WINDOW_TOP_EDGE_LINE (w)
16031 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
16032 + window_internal_height (w));
16034 #if defined (HAVE_GPM) || defined (MSDOS)
16035 x_clear_window_mouse_face (w);
16036 #endif
16037 /* Perform the operation on the screen. */
16038 if (dvpos > 0)
16040 /* Scroll last_unchanged_at_beg_row to the end of the
16041 window down dvpos lines. */
16042 set_terminal_window (f, end);
16044 /* On dumb terminals delete dvpos lines at the end
16045 before inserting dvpos empty lines. */
16046 if (!FRAME_SCROLL_REGION_OK (f))
16047 ins_del_lines (f, end - dvpos, -dvpos);
16049 /* Insert dvpos empty lines in front of
16050 last_unchanged_at_beg_row. */
16051 ins_del_lines (f, from, dvpos);
16053 else if (dvpos < 0)
16055 /* Scroll up last_unchanged_at_beg_vpos to the end of
16056 the window to last_unchanged_at_beg_vpos - |dvpos|. */
16057 set_terminal_window (f, end);
16059 /* Delete dvpos lines in front of
16060 last_unchanged_at_beg_vpos. ins_del_lines will set
16061 the cursor to the given vpos and emit |dvpos| delete
16062 line sequences. */
16063 ins_del_lines (f, from + dvpos, dvpos);
16065 /* On a dumb terminal insert dvpos empty lines at the
16066 end. */
16067 if (!FRAME_SCROLL_REGION_OK (f))
16068 ins_del_lines (f, end + dvpos, -dvpos);
16071 set_terminal_window (f, 0);
16074 update_end (f);
16077 /* Shift reused rows of the current matrix to the right position.
16078 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
16079 text. */
16080 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
16081 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
16082 if (dvpos < 0)
16084 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
16085 bottom_vpos, dvpos);
16086 enable_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
16087 bottom_vpos, 0);
16089 else if (dvpos > 0)
16091 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
16092 bottom_vpos, dvpos);
16093 enable_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
16094 first_unchanged_at_end_vpos + dvpos, 0);
16097 /* For frame-based redisplay, make sure that current frame and window
16098 matrix are in sync with respect to glyph memory. */
16099 if (!FRAME_WINDOW_P (f))
16100 sync_frame_with_window_matrix_rows (w);
16102 /* Adjust buffer positions in reused rows. */
16103 if (delta || delta_bytes)
16104 increment_matrix_positions (current_matrix,
16105 first_unchanged_at_end_vpos + dvpos,
16106 bottom_vpos, delta, delta_bytes);
16108 /* Adjust Y positions. */
16109 if (dy)
16110 shift_glyph_matrix (w, current_matrix,
16111 first_unchanged_at_end_vpos + dvpos,
16112 bottom_vpos, dy);
16114 if (first_unchanged_at_end_row)
16116 first_unchanged_at_end_row += dvpos;
16117 if (first_unchanged_at_end_row->y >= it.last_visible_y
16118 || !MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row))
16119 first_unchanged_at_end_row = NULL;
16122 /* If scrolling up, there may be some lines to display at the end of
16123 the window. */
16124 last_text_row_at_end = NULL;
16125 if (dy < 0)
16127 /* Scrolling up can leave for example a partially visible line
16128 at the end of the window to be redisplayed. */
16129 /* Set last_row to the glyph row in the current matrix where the
16130 window end line is found. It has been moved up or down in
16131 the matrix by dvpos. */
16132 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
16133 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
16135 /* If last_row is the window end line, it should display text. */
16136 xassert (last_row->displays_text_p);
16138 /* If window end line was partially visible before, begin
16139 displaying at that line. Otherwise begin displaying with the
16140 line following it. */
16141 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
16143 init_to_row_start (&it, w, last_row);
16144 it.vpos = last_vpos;
16145 it.current_y = last_row->y;
16147 else
16149 init_to_row_end (&it, w, last_row);
16150 it.vpos = 1 + last_vpos;
16151 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
16152 ++last_row;
16155 /* We may start in a continuation line. If so, we have to
16156 get the right continuation_lines_width and current_x. */
16157 it.continuation_lines_width = last_row->continuation_lines_width;
16158 it.hpos = it.current_x = 0;
16160 /* Display the rest of the lines at the window end. */
16161 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
16162 while (it.current_y < it.last_visible_y
16163 && !fonts_changed_p)
16165 /* Is it always sure that the display agrees with lines in
16166 the current matrix? I don't think so, so we mark rows
16167 displayed invalid in the current matrix by setting their
16168 enabled_p flag to zero. */
16169 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
16170 if (display_line (&it))
16171 last_text_row_at_end = it.glyph_row - 1;
16175 /* Update window_end_pos and window_end_vpos. */
16176 if (first_unchanged_at_end_row
16177 && !last_text_row_at_end)
16179 /* Window end line if one of the preserved rows from the current
16180 matrix. Set row to the last row displaying text in current
16181 matrix starting at first_unchanged_at_end_row, after
16182 scrolling. */
16183 xassert (first_unchanged_at_end_row->displays_text_p);
16184 row = find_last_row_displaying_text (w->current_matrix, &it,
16185 first_unchanged_at_end_row);
16186 xassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
16188 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
16189 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
16190 w->window_end_vpos
16191 = make_number (MATRIX_ROW_VPOS (row, w->current_matrix));
16192 xassert (w->window_end_bytepos >= 0);
16193 IF_DEBUG (debug_method_add (w, "A"));
16195 else if (last_text_row_at_end)
16197 w->window_end_pos
16198 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end));
16199 w->window_end_bytepos
16200 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
16201 w->window_end_vpos
16202 = make_number (MATRIX_ROW_VPOS (last_text_row_at_end, desired_matrix));
16203 xassert (w->window_end_bytepos >= 0);
16204 IF_DEBUG (debug_method_add (w, "B"));
16206 else if (last_text_row)
16208 /* We have displayed either to the end of the window or at the
16209 end of the window, i.e. the last row with text is to be found
16210 in the desired matrix. */
16211 w->window_end_pos
16212 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
16213 w->window_end_bytepos
16214 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
16215 w->window_end_vpos
16216 = make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix));
16217 xassert (w->window_end_bytepos >= 0);
16219 else if (first_unchanged_at_end_row == NULL
16220 && last_text_row == NULL
16221 && last_text_row_at_end == NULL)
16223 /* Displayed to end of window, but no line containing text was
16224 displayed. Lines were deleted at the end of the window. */
16225 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
16226 int vpos = XFASTINT (w->window_end_vpos);
16227 struct glyph_row *current_row = current_matrix->rows + vpos;
16228 struct glyph_row *desired_row = desired_matrix->rows + vpos;
16230 for (row = NULL;
16231 row == NULL && vpos >= first_vpos;
16232 --vpos, --current_row, --desired_row)
16234 if (desired_row->enabled_p)
16236 if (desired_row->displays_text_p)
16237 row = desired_row;
16239 else if (current_row->displays_text_p)
16240 row = current_row;
16243 xassert (row != NULL);
16244 w->window_end_vpos = make_number (vpos + 1);
16245 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
16246 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
16247 xassert (w->window_end_bytepos >= 0);
16248 IF_DEBUG (debug_method_add (w, "C"));
16250 else
16251 abort ();
16253 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
16254 debug_end_vpos = XFASTINT (w->window_end_vpos));
16256 /* Record that display has not been completed. */
16257 w->window_end_valid = Qnil;
16258 w->desired_matrix->no_scrolling_p = 1;
16259 return 3;
16261 #undef GIVE_UP
16266 /***********************************************************************
16267 More debugging support
16268 ***********************************************************************/
16270 #if GLYPH_DEBUG
16272 void dump_glyph_row (struct glyph_row *, int, int);
16273 void dump_glyph_matrix (struct glyph_matrix *, int);
16274 void dump_glyph (struct glyph_row *, struct glyph *, int);
16277 /* Dump the contents of glyph matrix MATRIX on stderr.
16279 GLYPHS 0 means don't show glyph contents.
16280 GLYPHS 1 means show glyphs in short form
16281 GLYPHS > 1 means show glyphs in long form. */
16283 void
16284 dump_glyph_matrix (matrix, glyphs)
16285 struct glyph_matrix *matrix;
16286 int glyphs;
16288 int i;
16289 for (i = 0; i < matrix->nrows; ++i)
16290 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
16294 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
16295 the glyph row and area where the glyph comes from. */
16297 void
16298 dump_glyph (row, glyph, area)
16299 struct glyph_row *row;
16300 struct glyph *glyph;
16301 int area;
16303 if (glyph->type == CHAR_GLYPH)
16305 fprintf (stderr,
16306 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
16307 glyph - row->glyphs[TEXT_AREA],
16308 'C',
16309 glyph->charpos,
16310 (BUFFERP (glyph->object)
16311 ? 'B'
16312 : (STRINGP (glyph->object)
16313 ? 'S'
16314 : '-')),
16315 glyph->pixel_width,
16316 glyph->u.ch,
16317 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
16318 ? glyph->u.ch
16319 : '.'),
16320 glyph->face_id,
16321 glyph->left_box_line_p,
16322 glyph->right_box_line_p);
16324 else if (glyph->type == STRETCH_GLYPH)
16326 fprintf (stderr,
16327 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
16328 glyph - row->glyphs[TEXT_AREA],
16329 'S',
16330 glyph->charpos,
16331 (BUFFERP (glyph->object)
16332 ? 'B'
16333 : (STRINGP (glyph->object)
16334 ? 'S'
16335 : '-')),
16336 glyph->pixel_width,
16338 '.',
16339 glyph->face_id,
16340 glyph->left_box_line_p,
16341 glyph->right_box_line_p);
16343 else if (glyph->type == IMAGE_GLYPH)
16345 fprintf (stderr,
16346 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
16347 glyph - row->glyphs[TEXT_AREA],
16348 'I',
16349 glyph->charpos,
16350 (BUFFERP (glyph->object)
16351 ? 'B'
16352 : (STRINGP (glyph->object)
16353 ? 'S'
16354 : '-')),
16355 glyph->pixel_width,
16356 glyph->u.img_id,
16357 '.',
16358 glyph->face_id,
16359 glyph->left_box_line_p,
16360 glyph->right_box_line_p);
16362 else if (glyph->type == COMPOSITE_GLYPH)
16364 fprintf (stderr,
16365 " %5d %4c %6d %c %3d 0x%05x",
16366 glyph - row->glyphs[TEXT_AREA],
16367 '+',
16368 glyph->charpos,
16369 (BUFFERP (glyph->object)
16370 ? 'B'
16371 : (STRINGP (glyph->object)
16372 ? 'S'
16373 : '-')),
16374 glyph->pixel_width,
16375 glyph->u.cmp.id);
16376 if (glyph->u.cmp.automatic)
16377 fprintf (stderr,
16378 "[%d-%d]",
16379 glyph->slice.cmp.from, glyph->slice.cmp.to);
16380 fprintf (stderr, " . %4d %1.1d%1.1d\n",
16381 glyph->face_id,
16382 glyph->left_box_line_p,
16383 glyph->right_box_line_p);
16388 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
16389 GLYPHS 0 means don't show glyph contents.
16390 GLYPHS 1 means show glyphs in short form
16391 GLYPHS > 1 means show glyphs in long form. */
16393 void
16394 dump_glyph_row (row, vpos, glyphs)
16395 struct glyph_row *row;
16396 int vpos, glyphs;
16398 if (glyphs != 1)
16400 fprintf (stderr, "Row Start End Used oE><\\CTZFesm X Y W H V A P\n");
16401 fprintf (stderr, "======================================================================\n");
16403 fprintf (stderr, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d\
16404 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
16405 vpos,
16406 MATRIX_ROW_START_CHARPOS (row),
16407 MATRIX_ROW_END_CHARPOS (row),
16408 row->used[TEXT_AREA],
16409 row->contains_overlapping_glyphs_p,
16410 row->enabled_p,
16411 row->truncated_on_left_p,
16412 row->truncated_on_right_p,
16413 row->continued_p,
16414 MATRIX_ROW_CONTINUATION_LINE_P (row),
16415 row->displays_text_p,
16416 row->ends_at_zv_p,
16417 row->fill_line_p,
16418 row->ends_in_middle_of_char_p,
16419 row->starts_in_middle_of_char_p,
16420 row->mouse_face_p,
16421 row->x,
16422 row->y,
16423 row->pixel_width,
16424 row->height,
16425 row->visible_height,
16426 row->ascent,
16427 row->phys_ascent);
16428 fprintf (stderr, "%9d %5d\t%5d\n", row->start.overlay_string_index,
16429 row->end.overlay_string_index,
16430 row->continuation_lines_width);
16431 fprintf (stderr, "%9d %5d\n",
16432 CHARPOS (row->start.string_pos),
16433 CHARPOS (row->end.string_pos));
16434 fprintf (stderr, "%9d %5d\n", row->start.dpvec_index,
16435 row->end.dpvec_index);
16438 if (glyphs > 1)
16440 int area;
16442 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
16444 struct glyph *glyph = row->glyphs[area];
16445 struct glyph *glyph_end = glyph + row->used[area];
16447 /* Glyph for a line end in text. */
16448 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
16449 ++glyph_end;
16451 if (glyph < glyph_end)
16452 fprintf (stderr, " Glyph Type Pos O W Code C Face LR\n");
16454 for (; glyph < glyph_end; ++glyph)
16455 dump_glyph (row, glyph, area);
16458 else if (glyphs == 1)
16460 int area;
16462 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
16464 char *s = (char *) alloca (row->used[area] + 1);
16465 int i;
16467 for (i = 0; i < row->used[area]; ++i)
16469 struct glyph *glyph = row->glyphs[area] + i;
16470 if (glyph->type == CHAR_GLYPH
16471 && glyph->u.ch < 0x80
16472 && glyph->u.ch >= ' ')
16473 s[i] = glyph->u.ch;
16474 else
16475 s[i] = '.';
16478 s[i] = '\0';
16479 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
16485 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
16486 Sdump_glyph_matrix, 0, 1, "p",
16487 doc: /* Dump the current matrix of the selected window to stderr.
16488 Shows contents of glyph row structures. With non-nil
16489 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
16490 glyphs in short form, otherwise show glyphs in long form. */)
16491 (Lisp_Object glyphs)
16493 struct window *w = XWINDOW (selected_window);
16494 struct buffer *buffer = XBUFFER (w->buffer);
16496 fprintf (stderr, "PT = %d, BEGV = %d. ZV = %d\n",
16497 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
16498 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
16499 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
16500 fprintf (stderr, "=============================================\n");
16501 dump_glyph_matrix (w->current_matrix,
16502 NILP (glyphs) ? 0 : XINT (glyphs));
16503 return Qnil;
16507 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
16508 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
16509 (void)
16511 struct frame *f = XFRAME (selected_frame);
16512 dump_glyph_matrix (f->current_matrix, 1);
16513 return Qnil;
16517 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
16518 doc: /* Dump glyph row ROW to stderr.
16519 GLYPH 0 means don't dump glyphs.
16520 GLYPH 1 means dump glyphs in short form.
16521 GLYPH > 1 or omitted means dump glyphs in long form. */)
16522 (Lisp_Object row, Lisp_Object glyphs)
16524 struct glyph_matrix *matrix;
16525 int vpos;
16527 CHECK_NUMBER (row);
16528 matrix = XWINDOW (selected_window)->current_matrix;
16529 vpos = XINT (row);
16530 if (vpos >= 0 && vpos < matrix->nrows)
16531 dump_glyph_row (MATRIX_ROW (matrix, vpos),
16532 vpos,
16533 INTEGERP (glyphs) ? XINT (glyphs) : 2);
16534 return Qnil;
16538 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
16539 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
16540 GLYPH 0 means don't dump glyphs.
16541 GLYPH 1 means dump glyphs in short form.
16542 GLYPH > 1 or omitted means dump glyphs in long form. */)
16543 (Lisp_Object row, Lisp_Object glyphs)
16545 struct frame *sf = SELECTED_FRAME ();
16546 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
16547 int vpos;
16549 CHECK_NUMBER (row);
16550 vpos = XINT (row);
16551 if (vpos >= 0 && vpos < m->nrows)
16552 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
16553 INTEGERP (glyphs) ? XINT (glyphs) : 2);
16554 return Qnil;
16558 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
16559 doc: /* Toggle tracing of redisplay.
16560 With ARG, turn tracing on if and only if ARG is positive. */)
16561 (Lisp_Object arg)
16563 if (NILP (arg))
16564 trace_redisplay_p = !trace_redisplay_p;
16565 else
16567 arg = Fprefix_numeric_value (arg);
16568 trace_redisplay_p = XINT (arg) > 0;
16571 return Qnil;
16575 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
16576 doc: /* Like `format', but print result to stderr.
16577 usage: (trace-to-stderr STRING &rest OBJECTS) */)
16578 (int nargs, Lisp_Object *args)
16580 Lisp_Object s = Fformat (nargs, args);
16581 fprintf (stderr, "%s", SDATA (s));
16582 return Qnil;
16585 #endif /* GLYPH_DEBUG */
16589 /***********************************************************************
16590 Building Desired Matrix Rows
16591 ***********************************************************************/
16593 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
16594 Used for non-window-redisplay windows, and for windows w/o left fringe. */
16596 static struct glyph_row *
16597 get_overlay_arrow_glyph_row (struct window *w, Lisp_Object overlay_arrow_string)
16599 struct frame *f = XFRAME (WINDOW_FRAME (w));
16600 struct buffer *buffer = XBUFFER (w->buffer);
16601 struct buffer *old = current_buffer;
16602 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
16603 int arrow_len = SCHARS (overlay_arrow_string);
16604 const unsigned char *arrow_end = arrow_string + arrow_len;
16605 const unsigned char *p;
16606 struct it it;
16607 int multibyte_p;
16608 int n_glyphs_before;
16610 set_buffer_temp (buffer);
16611 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
16612 it.glyph_row->used[TEXT_AREA] = 0;
16613 SET_TEXT_POS (it.position, 0, 0);
16615 multibyte_p = !NILP (buffer->enable_multibyte_characters);
16616 p = arrow_string;
16617 while (p < arrow_end)
16619 Lisp_Object face, ilisp;
16621 /* Get the next character. */
16622 if (multibyte_p)
16623 it.c = it.char_to_display = string_char_and_length (p, &it.len);
16624 else
16626 it.c = it.char_to_display = *p, it.len = 1;
16627 if (! ASCII_CHAR_P (it.c))
16628 it.char_to_display = BYTE8_TO_CHAR (it.c);
16630 p += it.len;
16632 /* Get its face. */
16633 ilisp = make_number (p - arrow_string);
16634 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
16635 it.face_id = compute_char_face (f, it.char_to_display, face);
16637 /* Compute its width, get its glyphs. */
16638 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
16639 SET_TEXT_POS (it.position, -1, -1);
16640 PRODUCE_GLYPHS (&it);
16642 /* If this character doesn't fit any more in the line, we have
16643 to remove some glyphs. */
16644 if (it.current_x > it.last_visible_x)
16646 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
16647 break;
16651 set_buffer_temp (old);
16652 return it.glyph_row;
16656 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
16657 glyphs are only inserted for terminal frames since we can't really
16658 win with truncation glyphs when partially visible glyphs are
16659 involved. Which glyphs to insert is determined by
16660 produce_special_glyphs. */
16662 static void
16663 insert_left_trunc_glyphs (struct it *it)
16665 struct it truncate_it;
16666 struct glyph *from, *end, *to, *toend;
16668 xassert (!FRAME_WINDOW_P (it->f));
16670 /* Get the truncation glyphs. */
16671 truncate_it = *it;
16672 truncate_it.current_x = 0;
16673 truncate_it.face_id = DEFAULT_FACE_ID;
16674 truncate_it.glyph_row = &scratch_glyph_row;
16675 truncate_it.glyph_row->used[TEXT_AREA] = 0;
16676 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
16677 truncate_it.object = make_number (0);
16678 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
16680 /* Overwrite glyphs from IT with truncation glyphs. */
16681 if (!it->glyph_row->reversed_p)
16683 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
16684 end = from + truncate_it.glyph_row->used[TEXT_AREA];
16685 to = it->glyph_row->glyphs[TEXT_AREA];
16686 toend = to + it->glyph_row->used[TEXT_AREA];
16688 while (from < end)
16689 *to++ = *from++;
16691 /* There may be padding glyphs left over. Overwrite them too. */
16692 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
16694 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
16695 while (from < end)
16696 *to++ = *from++;
16699 if (to > toend)
16700 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
16702 else
16704 /* In R2L rows, overwrite the last (rightmost) glyphs, and do
16705 that back to front. */
16706 end = truncate_it.glyph_row->glyphs[TEXT_AREA];
16707 from = end + truncate_it.glyph_row->used[TEXT_AREA] - 1;
16708 toend = it->glyph_row->glyphs[TEXT_AREA];
16709 to = toend + it->glyph_row->used[TEXT_AREA] - 1;
16711 while (from >= end && to >= toend)
16712 *to-- = *from--;
16713 while (to >= toend && CHAR_GLYPH_PADDING_P (*to))
16715 from =
16716 truncate_it.glyph_row->glyphs[TEXT_AREA]
16717 + truncate_it.glyph_row->used[TEXT_AREA] - 1;
16718 while (from >= end && to >= toend)
16719 *to-- = *from--;
16721 if (from >= end)
16723 /* Need to free some room before prepending additional
16724 glyphs. */
16725 int move_by = from - end + 1;
16726 struct glyph *g0 = it->glyph_row->glyphs[TEXT_AREA];
16727 struct glyph *g = g0 + it->glyph_row->used[TEXT_AREA] - 1;
16729 for ( ; g >= g0; g--)
16730 g[move_by] = *g;
16731 while (from >= end)
16732 *to-- = *from--;
16733 it->glyph_row->used[TEXT_AREA] += move_by;
16739 /* Compute the pixel height and width of IT->glyph_row.
16741 Most of the time, ascent and height of a display line will be equal
16742 to the max_ascent and max_height values of the display iterator
16743 structure. This is not the case if
16745 1. We hit ZV without displaying anything. In this case, max_ascent
16746 and max_height will be zero.
16748 2. We have some glyphs that don't contribute to the line height.
16749 (The glyph row flag contributes_to_line_height_p is for future
16750 pixmap extensions).
16752 The first case is easily covered by using default values because in
16753 these cases, the line height does not really matter, except that it
16754 must not be zero. */
16756 static void
16757 compute_line_metrics (struct it *it)
16759 struct glyph_row *row = it->glyph_row;
16760 int area, i;
16762 if (FRAME_WINDOW_P (it->f))
16764 int i, min_y, max_y;
16766 /* The line may consist of one space only, that was added to
16767 place the cursor on it. If so, the row's height hasn't been
16768 computed yet. */
16769 if (row->height == 0)
16771 if (it->max_ascent + it->max_descent == 0)
16772 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
16773 row->ascent = it->max_ascent;
16774 row->height = it->max_ascent + it->max_descent;
16775 row->phys_ascent = it->max_phys_ascent;
16776 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
16777 row->extra_line_spacing = it->max_extra_line_spacing;
16780 /* Compute the width of this line. */
16781 row->pixel_width = row->x;
16782 for (i = 0; i < row->used[TEXT_AREA]; ++i)
16783 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
16785 xassert (row->pixel_width >= 0);
16786 xassert (row->ascent >= 0 && row->height > 0);
16788 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
16789 || MATRIX_ROW_OVERLAPS_PRED_P (row));
16791 /* If first line's physical ascent is larger than its logical
16792 ascent, use the physical ascent, and make the row taller.
16793 This makes accented characters fully visible. */
16794 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
16795 && row->phys_ascent > row->ascent)
16797 row->height += row->phys_ascent - row->ascent;
16798 row->ascent = row->phys_ascent;
16801 /* Compute how much of the line is visible. */
16802 row->visible_height = row->height;
16804 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
16805 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
16807 if (row->y < min_y)
16808 row->visible_height -= min_y - row->y;
16809 if (row->y + row->height > max_y)
16810 row->visible_height -= row->y + row->height - max_y;
16812 else
16814 row->pixel_width = row->used[TEXT_AREA];
16815 if (row->continued_p)
16816 row->pixel_width -= it->continuation_pixel_width;
16817 else if (row->truncated_on_right_p)
16818 row->pixel_width -= it->truncation_pixel_width;
16819 row->ascent = row->phys_ascent = 0;
16820 row->height = row->phys_height = row->visible_height = 1;
16821 row->extra_line_spacing = 0;
16824 /* Compute a hash code for this row. */
16825 row->hash = 0;
16826 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
16827 for (i = 0; i < row->used[area]; ++i)
16828 row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff)
16829 + row->glyphs[area][i].u.val
16830 + row->glyphs[area][i].face_id
16831 + row->glyphs[area][i].padding_p
16832 + (row->glyphs[area][i].type << 2));
16834 it->max_ascent = it->max_descent = 0;
16835 it->max_phys_ascent = it->max_phys_descent = 0;
16839 /* Append one space to the glyph row of iterator IT if doing a
16840 window-based redisplay. The space has the same face as
16841 IT->face_id. Value is non-zero if a space was added.
16843 This function is called to make sure that there is always one glyph
16844 at the end of a glyph row that the cursor can be set on under
16845 window-systems. (If there weren't such a glyph we would not know
16846 how wide and tall a box cursor should be displayed).
16848 At the same time this space let's a nicely handle clearing to the
16849 end of the line if the row ends in italic text. */
16851 static int
16852 append_space_for_newline (struct it *it, int default_face_p)
16854 if (FRAME_WINDOW_P (it->f))
16856 int n = it->glyph_row->used[TEXT_AREA];
16858 if (it->glyph_row->glyphs[TEXT_AREA] + n
16859 < it->glyph_row->glyphs[1 + TEXT_AREA])
16861 /* Save some values that must not be changed.
16862 Must save IT->c and IT->len because otherwise
16863 ITERATOR_AT_END_P wouldn't work anymore after
16864 append_space_for_newline has been called. */
16865 enum display_element_type saved_what = it->what;
16866 int saved_c = it->c, saved_len = it->len;
16867 int saved_char_to_display = it->char_to_display;
16868 int saved_x = it->current_x;
16869 int saved_face_id = it->face_id;
16870 struct text_pos saved_pos;
16871 Lisp_Object saved_object;
16872 struct face *face;
16874 saved_object = it->object;
16875 saved_pos = it->position;
16877 it->what = IT_CHARACTER;
16878 memset (&it->position, 0, sizeof it->position);
16879 it->object = make_number (0);
16880 it->c = it->char_to_display = ' ';
16881 it->len = 1;
16883 if (default_face_p)
16884 it->face_id = DEFAULT_FACE_ID;
16885 else if (it->face_before_selective_p)
16886 it->face_id = it->saved_face_id;
16887 face = FACE_FROM_ID (it->f, it->face_id);
16888 it->face_id = FACE_FOR_CHAR (it->f, face, 0, -1, Qnil);
16890 PRODUCE_GLYPHS (it);
16892 it->override_ascent = -1;
16893 it->constrain_row_ascent_descent_p = 0;
16894 it->current_x = saved_x;
16895 it->object = saved_object;
16896 it->position = saved_pos;
16897 it->what = saved_what;
16898 it->face_id = saved_face_id;
16899 it->len = saved_len;
16900 it->c = saved_c;
16901 it->char_to_display = saved_char_to_display;
16902 return 1;
16906 return 0;
16910 /* Extend the face of the last glyph in the text area of IT->glyph_row
16911 to the end of the display line. Called from display_line. If the
16912 glyph row is empty, add a space glyph to it so that we know the
16913 face to draw. Set the glyph row flag fill_line_p. If the glyph
16914 row is R2L, prepend a stretch glyph to cover the empty space to the
16915 left of the leftmost glyph. */
16917 static void
16918 extend_face_to_end_of_line (struct it *it)
16920 struct face *face;
16921 struct frame *f = it->f;
16923 /* If line is already filled, do nothing. Non window-system frames
16924 get a grace of one more ``pixel'' because their characters are
16925 1-``pixel'' wide, so they hit the equality too early. This grace
16926 is needed only for R2L rows that are not continued, to produce
16927 one extra blank where we could display the cursor. */
16928 if (it->current_x >= it->last_visible_x
16929 + (!FRAME_WINDOW_P (f)
16930 && it->glyph_row->reversed_p
16931 && !it->glyph_row->continued_p))
16932 return;
16934 /* Face extension extends the background and box of IT->face_id
16935 to the end of the line. If the background equals the background
16936 of the frame, we don't have to do anything. */
16937 if (it->face_before_selective_p)
16938 face = FACE_FROM_ID (f, it->saved_face_id);
16939 else
16940 face = FACE_FROM_ID (f, it->face_id);
16942 if (FRAME_WINDOW_P (f)
16943 && it->glyph_row->displays_text_p
16944 && face->box == FACE_NO_BOX
16945 && face->background == FRAME_BACKGROUND_PIXEL (f)
16946 && !face->stipple
16947 && !it->glyph_row->reversed_p)
16948 return;
16950 /* Set the glyph row flag indicating that the face of the last glyph
16951 in the text area has to be drawn to the end of the text area. */
16952 it->glyph_row->fill_line_p = 1;
16954 /* If current character of IT is not ASCII, make sure we have the
16955 ASCII face. This will be automatically undone the next time
16956 get_next_display_element returns a multibyte character. Note
16957 that the character will always be single byte in unibyte
16958 text. */
16959 if (!ASCII_CHAR_P (it->c))
16961 it->face_id = FACE_FOR_CHAR (f, face, 0, -1, Qnil);
16964 if (FRAME_WINDOW_P (f))
16966 /* If the row is empty, add a space with the current face of IT,
16967 so that we know which face to draw. */
16968 if (it->glyph_row->used[TEXT_AREA] == 0)
16970 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
16971 it->glyph_row->glyphs[TEXT_AREA][0].face_id = it->face_id;
16972 it->glyph_row->used[TEXT_AREA] = 1;
16974 #ifdef HAVE_WINDOW_SYSTEM
16975 if (it->glyph_row->reversed_p)
16977 /* Prepend a stretch glyph to the row, such that the
16978 rightmost glyph will be drawn flushed all the way to the
16979 right margin of the window. The stretch glyph that will
16980 occupy the empty space, if any, to the left of the
16981 glyphs. */
16982 struct font *font = face->font ? face->font : FRAME_FONT (f);
16983 struct glyph *row_start = it->glyph_row->glyphs[TEXT_AREA];
16984 struct glyph *row_end = row_start + it->glyph_row->used[TEXT_AREA];
16985 struct glyph *g;
16986 int row_width, stretch_ascent, stretch_width;
16987 struct text_pos saved_pos;
16988 int saved_face_id, saved_avoid_cursor;
16990 for (row_width = 0, g = row_start; g < row_end; g++)
16991 row_width += g->pixel_width;
16992 stretch_width = window_box_width (it->w, TEXT_AREA) - row_width;
16993 if (stretch_width > 0)
16995 stretch_ascent =
16996 (((it->ascent + it->descent)
16997 * FONT_BASE (font)) / FONT_HEIGHT (font));
16998 saved_pos = it->position;
16999 memset (&it->position, 0, sizeof it->position);
17000 saved_avoid_cursor = it->avoid_cursor_p;
17001 it->avoid_cursor_p = 1;
17002 saved_face_id = it->face_id;
17003 /* The last row's stretch glyph should get the default
17004 face, to avoid painting the rest of the window with
17005 the region face, if the region ends at ZV. */
17006 if (it->glyph_row->ends_at_zv_p)
17007 it->face_id = DEFAULT_FACE_ID;
17008 else
17009 it->face_id = face->id;
17010 append_stretch_glyph (it, make_number (0), stretch_width,
17011 it->ascent + it->descent, stretch_ascent);
17012 it->position = saved_pos;
17013 it->avoid_cursor_p = saved_avoid_cursor;
17014 it->face_id = saved_face_id;
17017 #endif /* HAVE_WINDOW_SYSTEM */
17019 else
17021 /* Save some values that must not be changed. */
17022 int saved_x = it->current_x;
17023 struct text_pos saved_pos;
17024 Lisp_Object saved_object;
17025 enum display_element_type saved_what = it->what;
17026 int saved_face_id = it->face_id;
17028 saved_object = it->object;
17029 saved_pos = it->position;
17031 it->what = IT_CHARACTER;
17032 memset (&it->position, 0, sizeof it->position);
17033 it->object = make_number (0);
17034 it->c = it->char_to_display = ' ';
17035 it->len = 1;
17036 /* The last row's blank glyphs should get the default face, to
17037 avoid painting the rest of the window with the region face,
17038 if the region ends at ZV. */
17039 if (it->glyph_row->ends_at_zv_p)
17040 it->face_id = DEFAULT_FACE_ID;
17041 else
17042 it->face_id = face->id;
17044 PRODUCE_GLYPHS (it);
17046 while (it->current_x <= it->last_visible_x)
17047 PRODUCE_GLYPHS (it);
17049 /* Don't count these blanks really. It would let us insert a left
17050 truncation glyph below and make us set the cursor on them, maybe. */
17051 it->current_x = saved_x;
17052 it->object = saved_object;
17053 it->position = saved_pos;
17054 it->what = saved_what;
17055 it->face_id = saved_face_id;
17060 /* Value is non-zero if text starting at CHARPOS in current_buffer is
17061 trailing whitespace. */
17063 static int
17064 trailing_whitespace_p (EMACS_INT charpos)
17066 EMACS_INT bytepos = CHAR_TO_BYTE (charpos);
17067 int c = 0;
17069 while (bytepos < ZV_BYTE
17070 && (c = FETCH_CHAR (bytepos),
17071 c == ' ' || c == '\t'))
17072 ++bytepos;
17074 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
17076 if (bytepos != PT_BYTE)
17077 return 1;
17079 return 0;
17083 /* Highlight trailing whitespace, if any, in ROW. */
17085 void
17086 highlight_trailing_whitespace (struct frame *f, struct glyph_row *row)
17088 int used = row->used[TEXT_AREA];
17090 if (used)
17092 struct glyph *start = row->glyphs[TEXT_AREA];
17093 struct glyph *glyph = start + used - 1;
17095 if (row->reversed_p)
17097 /* Right-to-left rows need to be processed in the opposite
17098 direction, so swap the edge pointers. */
17099 glyph = start;
17100 start = row->glyphs[TEXT_AREA] + used - 1;
17103 /* Skip over glyphs inserted to display the cursor at the
17104 end of a line, for extending the face of the last glyph
17105 to the end of the line on terminals, and for truncation
17106 and continuation glyphs. */
17107 if (!row->reversed_p)
17109 while (glyph >= start
17110 && glyph->type == CHAR_GLYPH
17111 && INTEGERP (glyph->object))
17112 --glyph;
17114 else
17116 while (glyph <= start
17117 && glyph->type == CHAR_GLYPH
17118 && INTEGERP (glyph->object))
17119 ++glyph;
17122 /* If last glyph is a space or stretch, and it's trailing
17123 whitespace, set the face of all trailing whitespace glyphs in
17124 IT->glyph_row to `trailing-whitespace'. */
17125 if ((row->reversed_p ? glyph <= start : glyph >= start)
17126 && BUFFERP (glyph->object)
17127 && (glyph->type == STRETCH_GLYPH
17128 || (glyph->type == CHAR_GLYPH
17129 && glyph->u.ch == ' '))
17130 && trailing_whitespace_p (glyph->charpos))
17132 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0);
17133 if (face_id < 0)
17134 return;
17136 if (!row->reversed_p)
17138 while (glyph >= start
17139 && BUFFERP (glyph->object)
17140 && (glyph->type == STRETCH_GLYPH
17141 || (glyph->type == CHAR_GLYPH
17142 && glyph->u.ch == ' ')))
17143 (glyph--)->face_id = face_id;
17145 else
17147 while (glyph <= start
17148 && BUFFERP (glyph->object)
17149 && (glyph->type == STRETCH_GLYPH
17150 || (glyph->type == CHAR_GLYPH
17151 && glyph->u.ch == ' ')))
17152 (glyph++)->face_id = face_id;
17159 /* Value is non-zero if glyph row ROW in window W should be
17160 used to hold the cursor. */
17162 static int
17163 cursor_row_p (struct window *w, struct glyph_row *row)
17165 int cursor_row_p = 1;
17167 if (PT == CHARPOS (row->end.pos))
17169 /* Suppose the row ends on a string.
17170 Unless the row is continued, that means it ends on a newline
17171 in the string. If it's anything other than a display string
17172 (e.g. a before-string from an overlay), we don't want the
17173 cursor there. (This heuristic seems to give the optimal
17174 behavior for the various types of multi-line strings.) */
17175 if (CHARPOS (row->end.string_pos) >= 0)
17177 if (row->continued_p)
17178 cursor_row_p = 1;
17179 else
17181 /* Check for `display' property. */
17182 struct glyph *beg = row->glyphs[TEXT_AREA];
17183 struct glyph *end = beg + row->used[TEXT_AREA] - 1;
17184 struct glyph *glyph;
17186 cursor_row_p = 0;
17187 for (glyph = end; glyph >= beg; --glyph)
17188 if (STRINGP (glyph->object))
17190 Lisp_Object prop
17191 = Fget_char_property (make_number (PT),
17192 Qdisplay, Qnil);
17193 cursor_row_p =
17194 (!NILP (prop)
17195 && display_prop_string_p (prop, glyph->object));
17196 break;
17200 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
17202 /* If the row ends in middle of a real character,
17203 and the line is continued, we want the cursor here.
17204 That's because CHARPOS (ROW->end.pos) would equal
17205 PT if PT is before the character. */
17206 if (!row->ends_in_ellipsis_p)
17207 cursor_row_p = row->continued_p;
17208 else
17209 /* If the row ends in an ellipsis, then
17210 CHARPOS (ROW->end.pos) will equal point after the
17211 invisible text. We want that position to be displayed
17212 after the ellipsis. */
17213 cursor_row_p = 0;
17215 /* If the row ends at ZV, display the cursor at the end of that
17216 row instead of at the start of the row below. */
17217 else if (row->ends_at_zv_p)
17218 cursor_row_p = 1;
17219 else
17220 cursor_row_p = 0;
17223 return cursor_row_p;
17228 /* Push the display property PROP so that it will be rendered at the
17229 current position in IT. Return 1 if PROP was successfully pushed,
17230 0 otherwise. */
17232 static int
17233 push_display_prop (struct it *it, Lisp_Object prop)
17235 push_it (it);
17237 if (STRINGP (prop))
17239 if (SCHARS (prop) == 0)
17241 pop_it (it);
17242 return 0;
17245 it->string = prop;
17246 it->multibyte_p = STRING_MULTIBYTE (it->string);
17247 it->current.overlay_string_index = -1;
17248 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
17249 it->end_charpos = it->string_nchars = SCHARS (it->string);
17250 it->method = GET_FROM_STRING;
17251 it->stop_charpos = 0;
17253 else if (CONSP (prop) && EQ (XCAR (prop), Qspace))
17255 it->method = GET_FROM_STRETCH;
17256 it->object = prop;
17258 #ifdef HAVE_WINDOW_SYSTEM
17259 else if (IMAGEP (prop))
17261 it->what = IT_IMAGE;
17262 it->image_id = lookup_image (it->f, prop);
17263 it->method = GET_FROM_IMAGE;
17265 #endif /* HAVE_WINDOW_SYSTEM */
17266 else
17268 pop_it (it); /* bogus display property, give up */
17269 return 0;
17272 return 1;
17275 /* Return the character-property PROP at the current position in IT. */
17277 static Lisp_Object
17278 get_it_property (struct it *it, Lisp_Object prop)
17280 Lisp_Object position;
17282 if (STRINGP (it->object))
17283 position = make_number (IT_STRING_CHARPOS (*it));
17284 else if (BUFFERP (it->object))
17285 position = make_number (IT_CHARPOS (*it));
17286 else
17287 return Qnil;
17289 return Fget_char_property (position, prop, it->object);
17292 /* See if there's a line- or wrap-prefix, and if so, push it on IT. */
17294 static void
17295 handle_line_prefix (struct it *it)
17297 Lisp_Object prefix;
17298 if (it->continuation_lines_width > 0)
17300 prefix = get_it_property (it, Qwrap_prefix);
17301 if (NILP (prefix))
17302 prefix = Vwrap_prefix;
17304 else
17306 prefix = get_it_property (it, Qline_prefix);
17307 if (NILP (prefix))
17308 prefix = Vline_prefix;
17310 if (! NILP (prefix) && push_display_prop (it, prefix))
17312 /* If the prefix is wider than the window, and we try to wrap
17313 it, it would acquire its own wrap prefix, and so on till the
17314 iterator stack overflows. So, don't wrap the prefix. */
17315 it->line_wrap = TRUNCATE;
17316 it->avoid_cursor_p = 1;
17322 /* Remove N glyphs at the start of a reversed IT->glyph_row. Called
17323 only for R2L lines from display_line, when it decides that too many
17324 glyphs were produced by PRODUCE_GLYPHS, and the line needs to be
17325 continued. */
17326 static void
17327 unproduce_glyphs (struct it *it, int n)
17329 struct glyph *glyph, *end;
17331 xassert (it->glyph_row);
17332 xassert (it->glyph_row->reversed_p);
17333 xassert (it->area == TEXT_AREA);
17334 xassert (n <= it->glyph_row->used[TEXT_AREA]);
17336 if (n > it->glyph_row->used[TEXT_AREA])
17337 n = it->glyph_row->used[TEXT_AREA];
17338 glyph = it->glyph_row->glyphs[TEXT_AREA] + n;
17339 end = it->glyph_row->glyphs[TEXT_AREA] + it->glyph_row->used[TEXT_AREA];
17340 for ( ; glyph < end; glyph++)
17341 glyph[-n] = *glyph;
17344 /* Find the positions in a bidi-reordered ROW to serve as ROW->minpos
17345 and ROW->maxpos. */
17346 static void
17347 find_row_edges (struct it *it, struct glyph_row *row,
17348 EMACS_INT min_pos, EMACS_INT min_bpos,
17349 EMACS_INT max_pos, EMACS_INT max_bpos)
17351 /* FIXME: Revisit this when glyph ``spilling'' in continuation
17352 lines' rows is implemented for bidi-reordered rows. */
17354 /* ROW->minpos is the value of min_pos, the minimal buffer position
17355 we have in ROW. */
17356 if (min_pos <= ZV)
17357 SET_TEXT_POS (row->minpos, min_pos, min_bpos);
17358 else
17360 /* We didn't find _any_ valid buffer positions in any of the
17361 glyphs, so we must trust the iterator's computed
17362 positions. */
17363 row->minpos = row->start.pos;
17364 max_pos = CHARPOS (it->current.pos);
17365 max_bpos = BYTEPOS (it->current.pos);
17368 if (!max_pos)
17369 abort ();
17371 /* Here are the various use-cases for ending the row, and the
17372 corresponding values for ROW->maxpos:
17374 Line ends in a newline from buffer eol_pos + 1
17375 Line is continued from buffer max_pos + 1
17376 Line is truncated on right it->current.pos
17377 Line ends in a newline from string max_pos
17378 Line is continued from string max_pos
17379 Line is continued from display vector max_pos
17380 Line is entirely from a string min_pos == max_pos
17381 Line is entirely from a display vector min_pos == max_pos
17382 Line that ends at ZV ZV
17384 If you discover other use-cases, please add them here as
17385 appropriate. */
17386 if (row->ends_at_zv_p)
17387 row->maxpos = it->current.pos;
17388 else if (row->used[TEXT_AREA])
17390 if (row->ends_in_newline_from_string_p)
17391 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
17392 else if (CHARPOS (it->eol_pos) > 0)
17393 SET_TEXT_POS (row->maxpos,
17394 CHARPOS (it->eol_pos) + 1, BYTEPOS (it->eol_pos) + 1);
17395 else if (row->continued_p)
17397 /* If max_pos is different from IT's current position, it
17398 means IT->method does not belong to the display element
17399 at max_pos. However, it also means that the display
17400 element at max_pos was displayed in its entirety on this
17401 line, which is equivalent to saying that the next line
17402 starts at the next buffer position. */
17403 if (IT_CHARPOS (*it) == max_pos && it->method != GET_FROM_BUFFER)
17404 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
17405 else
17407 INC_BOTH (max_pos, max_bpos);
17408 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
17411 else if (row->truncated_on_right_p)
17412 /* display_line already called reseat_at_next_visible_line_start,
17413 which puts the iterator at the beginning of the next line, in
17414 the logical order. */
17415 row->maxpos = it->current.pos;
17416 else if (max_pos == min_pos && it->method != GET_FROM_BUFFER)
17417 /* A line that is entirely from a string/image/stretch... */
17418 row->maxpos = row->minpos;
17419 else
17420 abort ();
17422 else
17423 row->maxpos = it->current.pos;
17426 /* Construct the glyph row IT->glyph_row in the desired matrix of
17427 IT->w from text at the current position of IT. See dispextern.h
17428 for an overview of struct it. Value is non-zero if
17429 IT->glyph_row displays text, as opposed to a line displaying ZV
17430 only. */
17432 static int
17433 display_line (struct it *it)
17435 struct glyph_row *row = it->glyph_row;
17436 Lisp_Object overlay_arrow_string;
17437 struct it wrap_it;
17438 int may_wrap = 0, wrap_x;
17439 int wrap_row_used = -1, wrap_row_ascent, wrap_row_height;
17440 int wrap_row_phys_ascent, wrap_row_phys_height;
17441 int wrap_row_extra_line_spacing;
17442 EMACS_INT wrap_row_min_pos, wrap_row_min_bpos;
17443 EMACS_INT wrap_row_max_pos, wrap_row_max_bpos;
17444 int cvpos;
17445 EMACS_INT min_pos = ZV + 1, min_bpos, max_pos = 0, max_bpos;
17447 /* We always start displaying at hpos zero even if hscrolled. */
17448 xassert (it->hpos == 0 && it->current_x == 0);
17450 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
17451 >= it->w->desired_matrix->nrows)
17453 it->w->nrows_scale_factor++;
17454 fonts_changed_p = 1;
17455 return 0;
17458 /* Is IT->w showing the region? */
17459 it->w->region_showing = it->region_beg_charpos > 0 ? Qt : Qnil;
17461 /* Clear the result glyph row and enable it. */
17462 prepare_desired_row (row);
17464 row->y = it->current_y;
17465 row->start = it->start;
17466 row->continuation_lines_width = it->continuation_lines_width;
17467 row->displays_text_p = 1;
17468 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
17469 it->starts_in_middle_of_char_p = 0;
17471 /* Arrange the overlays nicely for our purposes. Usually, we call
17472 display_line on only one line at a time, in which case this
17473 can't really hurt too much, or we call it on lines which appear
17474 one after another in the buffer, in which case all calls to
17475 recenter_overlay_lists but the first will be pretty cheap. */
17476 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
17478 /* Move over display elements that are not visible because we are
17479 hscrolled. This may stop at an x-position < IT->first_visible_x
17480 if the first glyph is partially visible or if we hit a line end. */
17481 if (it->current_x < it->first_visible_x)
17483 move_it_in_display_line_to (it, ZV, it->first_visible_x,
17484 MOVE_TO_POS | MOVE_TO_X);
17486 else
17488 /* We only do this when not calling `move_it_in_display_line_to'
17489 above, because move_it_in_display_line_to calls
17490 handle_line_prefix itself. */
17491 handle_line_prefix (it);
17494 /* Get the initial row height. This is either the height of the
17495 text hscrolled, if there is any, or zero. */
17496 row->ascent = it->max_ascent;
17497 row->height = it->max_ascent + it->max_descent;
17498 row->phys_ascent = it->max_phys_ascent;
17499 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
17500 row->extra_line_spacing = it->max_extra_line_spacing;
17502 /* Utility macro to record max and min buffer positions seen until now. */
17503 #define RECORD_MAX_MIN_POS(IT) \
17504 do \
17506 if (IT_CHARPOS (*(IT)) < min_pos) \
17508 min_pos = IT_CHARPOS (*(IT)); \
17509 min_bpos = IT_BYTEPOS (*(IT)); \
17511 if (IT_CHARPOS (*(IT)) > max_pos) \
17513 max_pos = IT_CHARPOS (*(IT)); \
17514 max_bpos = IT_BYTEPOS (*(IT)); \
17517 while (0)
17519 /* Loop generating characters. The loop is left with IT on the next
17520 character to display. */
17521 while (1)
17523 int n_glyphs_before, hpos_before, x_before;
17524 int x, i, nglyphs;
17525 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
17527 /* Retrieve the next thing to display. Value is zero if end of
17528 buffer reached. */
17529 if (!get_next_display_element (it))
17531 /* Maybe add a space at the end of this line that is used to
17532 display the cursor there under X. Set the charpos of the
17533 first glyph of blank lines not corresponding to any text
17534 to -1. */
17535 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
17536 row->exact_window_width_line_p = 1;
17537 else if ((append_space_for_newline (it, 1) && row->used[TEXT_AREA] == 1)
17538 || row->used[TEXT_AREA] == 0)
17540 row->glyphs[TEXT_AREA]->charpos = -1;
17541 row->displays_text_p = 0;
17543 if (!NILP (XBUFFER (it->w->buffer)->indicate_empty_lines)
17544 && (!MINI_WINDOW_P (it->w)
17545 || (minibuf_level && EQ (it->window, minibuf_window))))
17546 row->indicate_empty_line_p = 1;
17549 it->continuation_lines_width = 0;
17550 row->ends_at_zv_p = 1;
17551 /* A row that displays right-to-left text must always have
17552 its last face extended all the way to the end of line,
17553 even if this row ends in ZV, because we still write to
17554 the screen left to right. */
17555 if (row->reversed_p)
17556 extend_face_to_end_of_line (it);
17557 break;
17560 /* Now, get the metrics of what we want to display. This also
17561 generates glyphs in `row' (which is IT->glyph_row). */
17562 n_glyphs_before = row->used[TEXT_AREA];
17563 x = it->current_x;
17565 /* Remember the line height so far in case the next element doesn't
17566 fit on the line. */
17567 if (it->line_wrap != TRUNCATE)
17569 ascent = it->max_ascent;
17570 descent = it->max_descent;
17571 phys_ascent = it->max_phys_ascent;
17572 phys_descent = it->max_phys_descent;
17574 if (it->line_wrap == WORD_WRAP && it->area == TEXT_AREA)
17576 if (IT_DISPLAYING_WHITESPACE (it))
17577 may_wrap = 1;
17578 else if (may_wrap)
17580 wrap_it = *it;
17581 wrap_x = x;
17582 wrap_row_used = row->used[TEXT_AREA];
17583 wrap_row_ascent = row->ascent;
17584 wrap_row_height = row->height;
17585 wrap_row_phys_ascent = row->phys_ascent;
17586 wrap_row_phys_height = row->phys_height;
17587 wrap_row_extra_line_spacing = row->extra_line_spacing;
17588 wrap_row_min_pos = min_pos;
17589 wrap_row_min_bpos = min_bpos;
17590 wrap_row_max_pos = max_pos;
17591 wrap_row_max_bpos = max_bpos;
17592 may_wrap = 0;
17597 PRODUCE_GLYPHS (it);
17599 /* If this display element was in marginal areas, continue with
17600 the next one. */
17601 if (it->area != TEXT_AREA)
17603 row->ascent = max (row->ascent, it->max_ascent);
17604 row->height = max (row->height, it->max_ascent + it->max_descent);
17605 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
17606 row->phys_height = max (row->phys_height,
17607 it->max_phys_ascent + it->max_phys_descent);
17608 row->extra_line_spacing = max (row->extra_line_spacing,
17609 it->max_extra_line_spacing);
17610 set_iterator_to_next (it, 1);
17611 continue;
17614 /* Does the display element fit on the line? If we truncate
17615 lines, we should draw past the right edge of the window. If
17616 we don't truncate, we want to stop so that we can display the
17617 continuation glyph before the right margin. If lines are
17618 continued, there are two possible strategies for characters
17619 resulting in more than 1 glyph (e.g. tabs): Display as many
17620 glyphs as possible in this line and leave the rest for the
17621 continuation line, or display the whole element in the next
17622 line. Original redisplay did the former, so we do it also. */
17623 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
17624 hpos_before = it->hpos;
17625 x_before = x;
17627 if (/* Not a newline. */
17628 nglyphs > 0
17629 /* Glyphs produced fit entirely in the line. */
17630 && it->current_x < it->last_visible_x)
17632 it->hpos += nglyphs;
17633 row->ascent = max (row->ascent, it->max_ascent);
17634 row->height = max (row->height, it->max_ascent + it->max_descent);
17635 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
17636 row->phys_height = max (row->phys_height,
17637 it->max_phys_ascent + it->max_phys_descent);
17638 row->extra_line_spacing = max (row->extra_line_spacing,
17639 it->max_extra_line_spacing);
17640 if (it->current_x - it->pixel_width < it->first_visible_x)
17641 row->x = x - it->first_visible_x;
17642 /* Record the maximum and minimum buffer positions seen so
17643 far in glyphs that will be displayed by this row. */
17644 if (it->bidi_p)
17645 RECORD_MAX_MIN_POS (it);
17647 else
17649 int new_x;
17650 struct glyph *glyph;
17652 for (i = 0; i < nglyphs; ++i, x = new_x)
17654 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
17655 new_x = x + glyph->pixel_width;
17657 if (/* Lines are continued. */
17658 it->line_wrap != TRUNCATE
17659 && (/* Glyph doesn't fit on the line. */
17660 new_x > it->last_visible_x
17661 /* Or it fits exactly on a window system frame. */
17662 || (new_x == it->last_visible_x
17663 && FRAME_WINDOW_P (it->f))))
17665 /* End of a continued line. */
17667 if (it->hpos == 0
17668 || (new_x == it->last_visible_x
17669 && FRAME_WINDOW_P (it->f)))
17671 /* Current glyph is the only one on the line or
17672 fits exactly on the line. We must continue
17673 the line because we can't draw the cursor
17674 after the glyph. */
17675 row->continued_p = 1;
17676 it->current_x = new_x;
17677 it->continuation_lines_width += new_x;
17678 ++it->hpos;
17679 /* Record the maximum and minimum buffer
17680 positions seen so far in glyphs that will be
17681 displayed by this row. */
17682 if (it->bidi_p)
17683 RECORD_MAX_MIN_POS (it);
17684 if (i == nglyphs - 1)
17686 /* If line-wrap is on, check if a previous
17687 wrap point was found. */
17688 if (wrap_row_used > 0
17689 /* Even if there is a previous wrap
17690 point, continue the line here as
17691 usual, if (i) the previous character
17692 was a space or tab AND (ii) the
17693 current character is not. */
17694 && (!may_wrap
17695 || IT_DISPLAYING_WHITESPACE (it)))
17696 goto back_to_wrap;
17698 set_iterator_to_next (it, 1);
17699 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
17701 if (!get_next_display_element (it))
17703 row->exact_window_width_line_p = 1;
17704 it->continuation_lines_width = 0;
17705 row->continued_p = 0;
17706 row->ends_at_zv_p = 1;
17708 else if (ITERATOR_AT_END_OF_LINE_P (it))
17710 row->continued_p = 0;
17711 row->exact_window_width_line_p = 1;
17716 else if (CHAR_GLYPH_PADDING_P (*glyph)
17717 && !FRAME_WINDOW_P (it->f))
17719 /* A padding glyph that doesn't fit on this line.
17720 This means the whole character doesn't fit
17721 on the line. */
17722 if (row->reversed_p)
17723 unproduce_glyphs (it, row->used[TEXT_AREA]
17724 - n_glyphs_before);
17725 row->used[TEXT_AREA] = n_glyphs_before;
17727 /* Fill the rest of the row with continuation
17728 glyphs like in 20.x. */
17729 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
17730 < row->glyphs[1 + TEXT_AREA])
17731 produce_special_glyphs (it, IT_CONTINUATION);
17733 row->continued_p = 1;
17734 it->current_x = x_before;
17735 it->continuation_lines_width += x_before;
17737 /* Restore the height to what it was before the
17738 element not fitting on the line. */
17739 it->max_ascent = ascent;
17740 it->max_descent = descent;
17741 it->max_phys_ascent = phys_ascent;
17742 it->max_phys_descent = phys_descent;
17744 else if (wrap_row_used > 0)
17746 back_to_wrap:
17747 if (row->reversed_p)
17748 unproduce_glyphs (it,
17749 row->used[TEXT_AREA] - wrap_row_used);
17750 *it = wrap_it;
17751 it->continuation_lines_width += wrap_x;
17752 row->used[TEXT_AREA] = wrap_row_used;
17753 row->ascent = wrap_row_ascent;
17754 row->height = wrap_row_height;
17755 row->phys_ascent = wrap_row_phys_ascent;
17756 row->phys_height = wrap_row_phys_height;
17757 row->extra_line_spacing = wrap_row_extra_line_spacing;
17758 min_pos = wrap_row_min_pos;
17759 min_bpos = wrap_row_min_bpos;
17760 max_pos = wrap_row_max_pos;
17761 max_bpos = wrap_row_max_bpos;
17762 row->continued_p = 1;
17763 row->ends_at_zv_p = 0;
17764 row->exact_window_width_line_p = 0;
17765 it->continuation_lines_width += x;
17767 /* Make sure that a non-default face is extended
17768 up to the right margin of the window. */
17769 extend_face_to_end_of_line (it);
17771 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
17773 /* A TAB that extends past the right edge of the
17774 window. This produces a single glyph on
17775 window system frames. We leave the glyph in
17776 this row and let it fill the row, but don't
17777 consume the TAB. */
17778 it->continuation_lines_width += it->last_visible_x;
17779 row->ends_in_middle_of_char_p = 1;
17780 row->continued_p = 1;
17781 glyph->pixel_width = it->last_visible_x - x;
17782 it->starts_in_middle_of_char_p = 1;
17784 else
17786 /* Something other than a TAB that draws past
17787 the right edge of the window. Restore
17788 positions to values before the element. */
17789 if (row->reversed_p)
17790 unproduce_glyphs (it, row->used[TEXT_AREA]
17791 - (n_glyphs_before + i));
17792 row->used[TEXT_AREA] = n_glyphs_before + i;
17794 /* Display continuation glyphs. */
17795 if (!FRAME_WINDOW_P (it->f))
17796 produce_special_glyphs (it, IT_CONTINUATION);
17797 row->continued_p = 1;
17799 it->current_x = x_before;
17800 it->continuation_lines_width += x;
17801 extend_face_to_end_of_line (it);
17803 if (nglyphs > 1 && i > 0)
17805 row->ends_in_middle_of_char_p = 1;
17806 it->starts_in_middle_of_char_p = 1;
17809 /* Restore the height to what it was before the
17810 element not fitting on the line. */
17811 it->max_ascent = ascent;
17812 it->max_descent = descent;
17813 it->max_phys_ascent = phys_ascent;
17814 it->max_phys_descent = phys_descent;
17817 break;
17819 else if (new_x > it->first_visible_x)
17821 /* Increment number of glyphs actually displayed. */
17822 ++it->hpos;
17824 /* Record the maximum and minimum buffer positions
17825 seen so far in glyphs that will be displayed by
17826 this row. */
17827 if (it->bidi_p)
17828 RECORD_MAX_MIN_POS (it);
17830 if (x < it->first_visible_x)
17831 /* Glyph is partially visible, i.e. row starts at
17832 negative X position. */
17833 row->x = x - it->first_visible_x;
17835 else
17837 /* Glyph is completely off the left margin of the
17838 window. This should not happen because of the
17839 move_it_in_display_line at the start of this
17840 function, unless the text display area of the
17841 window is empty. */
17842 xassert (it->first_visible_x <= it->last_visible_x);
17846 row->ascent = max (row->ascent, it->max_ascent);
17847 row->height = max (row->height, it->max_ascent + it->max_descent);
17848 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
17849 row->phys_height = max (row->phys_height,
17850 it->max_phys_ascent + it->max_phys_descent);
17851 row->extra_line_spacing = max (row->extra_line_spacing,
17852 it->max_extra_line_spacing);
17854 /* End of this display line if row is continued. */
17855 if (row->continued_p || row->ends_at_zv_p)
17856 break;
17859 at_end_of_line:
17860 /* Is this a line end? If yes, we're also done, after making
17861 sure that a non-default face is extended up to the right
17862 margin of the window. */
17863 if (ITERATOR_AT_END_OF_LINE_P (it))
17865 int used_before = row->used[TEXT_AREA];
17867 row->ends_in_newline_from_string_p = STRINGP (it->object);
17869 /* Add a space at the end of the line that is used to
17870 display the cursor there. */
17871 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
17872 append_space_for_newline (it, 0);
17874 /* Extend the face to the end of the line. */
17875 extend_face_to_end_of_line (it);
17877 /* Make sure we have the position. */
17878 if (used_before == 0)
17879 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
17881 /* Record the position of the newline, for use in
17882 find_row_edges. */
17883 it->eol_pos = it->current.pos;
17885 /* Consume the line end. This skips over invisible lines. */
17886 set_iterator_to_next (it, 1);
17887 it->continuation_lines_width = 0;
17888 break;
17891 /* Proceed with next display element. Note that this skips
17892 over lines invisible because of selective display. */
17893 set_iterator_to_next (it, 1);
17895 /* If we truncate lines, we are done when the last displayed
17896 glyphs reach past the right margin of the window. */
17897 if (it->line_wrap == TRUNCATE
17898 && (FRAME_WINDOW_P (it->f)
17899 ? (it->current_x >= it->last_visible_x)
17900 : (it->current_x > it->last_visible_x)))
17902 /* Maybe add truncation glyphs. */
17903 if (!FRAME_WINDOW_P (it->f))
17905 int i, n;
17907 if (!row->reversed_p)
17909 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
17910 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
17911 break;
17913 else
17915 for (i = 0; i < row->used[TEXT_AREA]; i++)
17916 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
17917 break;
17918 /* Remove any padding glyphs at the front of ROW, to
17919 make room for the truncation glyphs we will be
17920 adding below. The loop below always inserts at
17921 least one truncation glyph, so also remove the
17922 last glyph added to ROW. */
17923 unproduce_glyphs (it, i + 1);
17924 /* Adjust i for the loop below. */
17925 i = row->used[TEXT_AREA] - (i + 1);
17928 for (n = row->used[TEXT_AREA]; i < n; ++i)
17930 row->used[TEXT_AREA] = i;
17931 produce_special_glyphs (it, IT_TRUNCATION);
17934 else if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
17936 /* Don't truncate if we can overflow newline into fringe. */
17937 if (!get_next_display_element (it))
17939 it->continuation_lines_width = 0;
17940 row->ends_at_zv_p = 1;
17941 row->exact_window_width_line_p = 1;
17942 break;
17944 if (ITERATOR_AT_END_OF_LINE_P (it))
17946 row->exact_window_width_line_p = 1;
17947 goto at_end_of_line;
17951 row->truncated_on_right_p = 1;
17952 it->continuation_lines_width = 0;
17953 reseat_at_next_visible_line_start (it, 0);
17954 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
17955 it->hpos = hpos_before;
17956 it->current_x = x_before;
17957 break;
17961 /* If line is not empty and hscrolled, maybe insert truncation glyphs
17962 at the left window margin. */
17963 if (it->first_visible_x
17964 && IT_CHARPOS (*it) != CHARPOS (row->start.pos))
17966 if (!FRAME_WINDOW_P (it->f))
17967 insert_left_trunc_glyphs (it);
17968 row->truncated_on_left_p = 1;
17971 /* Remember the position at which this line ends.
17973 BIDI Note: any code that needs MATRIX_ROW_START/END_CHARPOS
17974 cannot be before the call to find_row_edges below, since that is
17975 where these positions are determined. */
17976 row->end = it->current;
17977 if (!it->bidi_p)
17979 row->minpos = row->start.pos;
17980 row->maxpos = row->end.pos;
17982 else
17984 /* ROW->minpos and ROW->maxpos must be the smallest and
17985 `1 + the largest' buffer positions in ROW. But if ROW was
17986 bidi-reordered, these two positions can be anywhere in the
17987 row, so we must determine them now. */
17988 find_row_edges (it, row, min_pos, min_bpos, max_pos, max_bpos);
17991 /* If the start of this line is the overlay arrow-position, then
17992 mark this glyph row as the one containing the overlay arrow.
17993 This is clearly a mess with variable size fonts. It would be
17994 better to let it be displayed like cursors under X. */
17995 if ((row->displays_text_p || !overlay_arrow_seen)
17996 && (overlay_arrow_string = overlay_arrow_at_row (it, row),
17997 !NILP (overlay_arrow_string)))
17999 /* Overlay arrow in window redisplay is a fringe bitmap. */
18000 if (STRINGP (overlay_arrow_string))
18002 struct glyph_row *arrow_row
18003 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
18004 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
18005 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
18006 struct glyph *p = row->glyphs[TEXT_AREA];
18007 struct glyph *p2, *end;
18009 /* Copy the arrow glyphs. */
18010 while (glyph < arrow_end)
18011 *p++ = *glyph++;
18013 /* Throw away padding glyphs. */
18014 p2 = p;
18015 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
18016 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
18017 ++p2;
18018 if (p2 > p)
18020 while (p2 < end)
18021 *p++ = *p2++;
18022 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
18025 else
18027 xassert (INTEGERP (overlay_arrow_string));
18028 row->overlay_arrow_bitmap = XINT (overlay_arrow_string);
18030 overlay_arrow_seen = 1;
18033 /* Compute pixel dimensions of this line. */
18034 compute_line_metrics (it);
18036 /* Record whether this row ends inside an ellipsis. */
18037 row->ends_in_ellipsis_p
18038 = (it->method == GET_FROM_DISPLAY_VECTOR
18039 && it->ellipsis_p);
18041 /* Save fringe bitmaps in this row. */
18042 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
18043 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
18044 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
18045 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
18047 it->left_user_fringe_bitmap = 0;
18048 it->left_user_fringe_face_id = 0;
18049 it->right_user_fringe_bitmap = 0;
18050 it->right_user_fringe_face_id = 0;
18052 /* Maybe set the cursor. */
18053 cvpos = it->w->cursor.vpos;
18054 if ((cvpos < 0
18055 /* In bidi-reordered rows, keep checking for proper cursor
18056 position even if one has been found already, because buffer
18057 positions in such rows change non-linearly with ROW->VPOS,
18058 when a line is continued. One exception: when we are at ZV,
18059 display cursor on the first suitable glyph row, since all
18060 the empty rows after that also have their position set to ZV. */
18061 /* FIXME: Revisit this when glyph ``spilling'' in continuation
18062 lines' rows is implemented for bidi-reordered rows. */
18063 || (it->bidi_p
18064 && !MATRIX_ROW (it->w->desired_matrix, cvpos)->ends_at_zv_p))
18065 && PT >= MATRIX_ROW_START_CHARPOS (row)
18066 && PT <= MATRIX_ROW_END_CHARPOS (row)
18067 && cursor_row_p (it->w, row))
18068 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
18070 /* Highlight trailing whitespace. */
18071 if (!NILP (Vshow_trailing_whitespace))
18072 highlight_trailing_whitespace (it->f, it->glyph_row);
18074 /* Prepare for the next line. This line starts horizontally at (X
18075 HPOS) = (0 0). Vertical positions are incremented. As a
18076 convenience for the caller, IT->glyph_row is set to the next
18077 row to be used. */
18078 it->current_x = it->hpos = 0;
18079 it->current_y += row->height;
18080 SET_TEXT_POS (it->eol_pos, 0, 0);
18081 ++it->vpos;
18082 ++it->glyph_row;
18083 /* The next row should by default use the same value of the
18084 reversed_p flag as this one. set_iterator_to_next decides when
18085 it's a new paragraph, and PRODUCE_GLYPHS recomputes the value of
18086 the flag accordingly. */
18087 if (it->glyph_row < MATRIX_BOTTOM_TEXT_ROW (it->w->desired_matrix, it->w))
18088 it->glyph_row->reversed_p = row->reversed_p;
18089 it->start = row->end;
18090 return row->displays_text_p;
18092 #undef RECORD_MAX_MIN_POS
18095 DEFUN ("current-bidi-paragraph-direction", Fcurrent_bidi_paragraph_direction,
18096 Scurrent_bidi_paragraph_direction, 0, 1, 0,
18097 doc: /* Return paragraph direction at point in BUFFER.
18098 Value is either `left-to-right' or `right-to-left'.
18099 If BUFFER is omitted or nil, it defaults to the current buffer.
18101 Paragraph direction determines how the text in the paragraph is displayed.
18102 In left-to-right paragraphs, text begins at the left margin of the window
18103 and the reading direction is generally left to right. In right-to-left
18104 paragraphs, text begins at the right margin and is read from right to left.
18106 See also `bidi-paragraph-direction'. */)
18107 (Lisp_Object buffer)
18109 struct buffer *buf;
18110 struct buffer *old;
18112 if (NILP (buffer))
18113 buf = current_buffer;
18114 else
18116 CHECK_BUFFER (buffer);
18117 buf = XBUFFER (buffer);
18118 old = current_buffer;
18121 if (NILP (buf->bidi_display_reordering))
18122 return Qleft_to_right;
18123 else if (!NILP (buf->bidi_paragraph_direction))
18124 return buf->bidi_paragraph_direction;
18125 else
18127 /* Determine the direction from buffer text. We could try to
18128 use current_matrix if it is up to date, but this seems fast
18129 enough as it is. */
18130 struct bidi_it itb;
18131 EMACS_INT pos = BUF_PT (buf);
18132 EMACS_INT bytepos = BUF_PT_BYTE (buf);
18133 int c;
18135 if (buf != current_buffer)
18136 set_buffer_temp (buf);
18137 /* bidi_paragraph_init finds the base direction of the paragraph
18138 by searching forward from paragraph start. We need the base
18139 direction of the current or _previous_ paragraph, so we need
18140 to make sure we are within that paragraph. To that end, find
18141 the previous non-empty line. */
18142 if (pos >= ZV && pos > BEGV)
18144 pos--;
18145 bytepos = CHAR_TO_BYTE (pos);
18147 while ((c = FETCH_BYTE (bytepos)) == '\n'
18148 || c == ' ' || c == '\t' || c == '\f')
18150 if (bytepos <= BEGV_BYTE)
18151 break;
18152 bytepos--;
18153 pos--;
18155 while (!CHAR_HEAD_P (FETCH_BYTE (bytepos)))
18156 bytepos--;
18157 itb.charpos = pos;
18158 itb.bytepos = bytepos;
18159 itb.first_elt = 1;
18160 itb.separator_limit = -1;
18161 itb.paragraph_dir = NEUTRAL_DIR;
18163 bidi_paragraph_init (NEUTRAL_DIR, &itb, 1);
18164 if (buf != current_buffer)
18165 set_buffer_temp (old);
18166 switch (itb.paragraph_dir)
18168 case L2R:
18169 return Qleft_to_right;
18170 break;
18171 case R2L:
18172 return Qright_to_left;
18173 break;
18174 default:
18175 abort ();
18182 /***********************************************************************
18183 Menu Bar
18184 ***********************************************************************/
18186 /* Redisplay the menu bar in the frame for window W.
18188 The menu bar of X frames that don't have X toolkit support is
18189 displayed in a special window W->frame->menu_bar_window.
18191 The menu bar of terminal frames is treated specially as far as
18192 glyph matrices are concerned. Menu bar lines are not part of
18193 windows, so the update is done directly on the frame matrix rows
18194 for the menu bar. */
18196 static void
18197 display_menu_bar (struct window *w)
18199 struct frame *f = XFRAME (WINDOW_FRAME (w));
18200 struct it it;
18201 Lisp_Object items;
18202 int i;
18204 /* Don't do all this for graphical frames. */
18205 #ifdef HAVE_NTGUI
18206 if (FRAME_W32_P (f))
18207 return;
18208 #endif
18209 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
18210 if (FRAME_X_P (f))
18211 return;
18212 #endif
18214 #ifdef HAVE_NS
18215 if (FRAME_NS_P (f))
18216 return;
18217 #endif /* HAVE_NS */
18219 #ifdef USE_X_TOOLKIT
18220 xassert (!FRAME_WINDOW_P (f));
18221 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
18222 it.first_visible_x = 0;
18223 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
18224 #else /* not USE_X_TOOLKIT */
18225 if (FRAME_WINDOW_P (f))
18227 /* Menu bar lines are displayed in the desired matrix of the
18228 dummy window menu_bar_window. */
18229 struct window *menu_w;
18230 xassert (WINDOWP (f->menu_bar_window));
18231 menu_w = XWINDOW (f->menu_bar_window);
18232 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
18233 MENU_FACE_ID);
18234 it.first_visible_x = 0;
18235 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
18237 else
18239 /* This is a TTY frame, i.e. character hpos/vpos are used as
18240 pixel x/y. */
18241 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
18242 MENU_FACE_ID);
18243 it.first_visible_x = 0;
18244 it.last_visible_x = FRAME_COLS (f);
18246 #endif /* not USE_X_TOOLKIT */
18248 if (! mode_line_inverse_video)
18249 /* Force the menu-bar to be displayed in the default face. */
18250 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
18252 /* Clear all rows of the menu bar. */
18253 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
18255 struct glyph_row *row = it.glyph_row + i;
18256 clear_glyph_row (row);
18257 row->enabled_p = 1;
18258 row->full_width_p = 1;
18261 /* Display all items of the menu bar. */
18262 items = FRAME_MENU_BAR_ITEMS (it.f);
18263 for (i = 0; i < XVECTOR (items)->size; i += 4)
18265 Lisp_Object string;
18267 /* Stop at nil string. */
18268 string = AREF (items, i + 1);
18269 if (NILP (string))
18270 break;
18272 /* Remember where item was displayed. */
18273 ASET (items, i + 3, make_number (it.hpos));
18275 /* Display the item, pad with one space. */
18276 if (it.current_x < it.last_visible_x)
18277 display_string (NULL, string, Qnil, 0, 0, &it,
18278 SCHARS (string) + 1, 0, 0, -1);
18281 /* Fill out the line with spaces. */
18282 if (it.current_x < it.last_visible_x)
18283 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
18285 /* Compute the total height of the lines. */
18286 compute_line_metrics (&it);
18291 /***********************************************************************
18292 Mode Line
18293 ***********************************************************************/
18295 /* Redisplay mode lines in the window tree whose root is WINDOW. If
18296 FORCE is non-zero, redisplay mode lines unconditionally.
18297 Otherwise, redisplay only mode lines that are garbaged. Value is
18298 the number of windows whose mode lines were redisplayed. */
18300 static int
18301 redisplay_mode_lines (Lisp_Object window, int force)
18303 int nwindows = 0;
18305 while (!NILP (window))
18307 struct window *w = XWINDOW (window);
18309 if (WINDOWP (w->hchild))
18310 nwindows += redisplay_mode_lines (w->hchild, force);
18311 else if (WINDOWP (w->vchild))
18312 nwindows += redisplay_mode_lines (w->vchild, force);
18313 else if (force
18314 || FRAME_GARBAGED_P (XFRAME (w->frame))
18315 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
18317 struct text_pos lpoint;
18318 struct buffer *old = current_buffer;
18320 /* Set the window's buffer for the mode line display. */
18321 SET_TEXT_POS (lpoint, PT, PT_BYTE);
18322 set_buffer_internal_1 (XBUFFER (w->buffer));
18324 /* Point refers normally to the selected window. For any
18325 other window, set up appropriate value. */
18326 if (!EQ (window, selected_window))
18328 struct text_pos pt;
18330 SET_TEXT_POS_FROM_MARKER (pt, w->pointm);
18331 if (CHARPOS (pt) < BEGV)
18332 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
18333 else if (CHARPOS (pt) > (ZV - 1))
18334 TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
18335 else
18336 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
18339 /* Display mode lines. */
18340 clear_glyph_matrix (w->desired_matrix);
18341 if (display_mode_lines (w))
18343 ++nwindows;
18344 w->must_be_updated_p = 1;
18347 /* Restore old settings. */
18348 set_buffer_internal_1 (old);
18349 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
18352 window = w->next;
18355 return nwindows;
18359 /* Display the mode and/or header line of window W. Value is the
18360 sum number of mode lines and header lines displayed. */
18362 static int
18363 display_mode_lines (struct window *w)
18365 Lisp_Object old_selected_window, old_selected_frame;
18366 int n = 0;
18368 old_selected_frame = selected_frame;
18369 selected_frame = w->frame;
18370 old_selected_window = selected_window;
18371 XSETWINDOW (selected_window, w);
18373 /* These will be set while the mode line specs are processed. */
18374 line_number_displayed = 0;
18375 w->column_number_displayed = Qnil;
18377 if (WINDOW_WANTS_MODELINE_P (w))
18379 struct window *sel_w = XWINDOW (old_selected_window);
18381 /* Select mode line face based on the real selected window. */
18382 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
18383 current_buffer->mode_line_format);
18384 ++n;
18387 if (WINDOW_WANTS_HEADER_LINE_P (w))
18389 display_mode_line (w, HEADER_LINE_FACE_ID,
18390 current_buffer->header_line_format);
18391 ++n;
18394 selected_frame = old_selected_frame;
18395 selected_window = old_selected_window;
18396 return n;
18400 /* Display mode or header line of window W. FACE_ID specifies which
18401 line to display; it is either MODE_LINE_FACE_ID or
18402 HEADER_LINE_FACE_ID. FORMAT is the mode/header line format to
18403 display. Value is the pixel height of the mode/header line
18404 displayed. */
18406 static int
18407 display_mode_line (struct window *w, enum face_id face_id, Lisp_Object format)
18409 struct it it;
18410 struct face *face;
18411 int count = SPECPDL_INDEX ();
18413 init_iterator (&it, w, -1, -1, NULL, face_id);
18414 /* Don't extend on a previously drawn mode-line.
18415 This may happen if called from pos_visible_p. */
18416 it.glyph_row->enabled_p = 0;
18417 prepare_desired_row (it.glyph_row);
18419 it.glyph_row->mode_line_p = 1;
18421 if (! mode_line_inverse_video)
18422 /* Force the mode-line to be displayed in the default face. */
18423 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
18425 record_unwind_protect (unwind_format_mode_line,
18426 format_mode_line_unwind_data (NULL, Qnil, 0));
18428 mode_line_target = MODE_LINE_DISPLAY;
18430 /* Temporarily make frame's keyboard the current kboard so that
18431 kboard-local variables in the mode_line_format will get the right
18432 values. */
18433 push_kboard (FRAME_KBOARD (it.f));
18434 record_unwind_save_match_data ();
18435 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
18436 pop_kboard ();
18438 unbind_to (count, Qnil);
18440 /* Fill up with spaces. */
18441 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
18443 compute_line_metrics (&it);
18444 it.glyph_row->full_width_p = 1;
18445 it.glyph_row->continued_p = 0;
18446 it.glyph_row->truncated_on_left_p = 0;
18447 it.glyph_row->truncated_on_right_p = 0;
18449 /* Make a 3D mode-line have a shadow at its right end. */
18450 face = FACE_FROM_ID (it.f, face_id);
18451 extend_face_to_end_of_line (&it);
18452 if (face->box != FACE_NO_BOX)
18454 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
18455 + it.glyph_row->used[TEXT_AREA] - 1);
18456 last->right_box_line_p = 1;
18459 return it.glyph_row->height;
18462 /* Move element ELT in LIST to the front of LIST.
18463 Return the updated list. */
18465 static Lisp_Object
18466 move_elt_to_front (Lisp_Object elt, Lisp_Object list)
18468 register Lisp_Object tail, prev;
18469 register Lisp_Object tem;
18471 tail = list;
18472 prev = Qnil;
18473 while (CONSP (tail))
18475 tem = XCAR (tail);
18477 if (EQ (elt, tem))
18479 /* Splice out the link TAIL. */
18480 if (NILP (prev))
18481 list = XCDR (tail);
18482 else
18483 Fsetcdr (prev, XCDR (tail));
18485 /* Now make it the first. */
18486 Fsetcdr (tail, list);
18487 return tail;
18489 else
18490 prev = tail;
18491 tail = XCDR (tail);
18492 QUIT;
18495 /* Not found--return unchanged LIST. */
18496 return list;
18499 /* Contribute ELT to the mode line for window IT->w. How it
18500 translates into text depends on its data type.
18502 IT describes the display environment in which we display, as usual.
18504 DEPTH is the depth in recursion. It is used to prevent
18505 infinite recursion here.
18507 FIELD_WIDTH is the number of characters the display of ELT should
18508 occupy in the mode line, and PRECISION is the maximum number of
18509 characters to display from ELT's representation. See
18510 display_string for details.
18512 Returns the hpos of the end of the text generated by ELT.
18514 PROPS is a property list to add to any string we encounter.
18516 If RISKY is nonzero, remove (disregard) any properties in any string
18517 we encounter, and ignore :eval and :propertize.
18519 The global variable `mode_line_target' determines whether the
18520 output is passed to `store_mode_line_noprop',
18521 `store_mode_line_string', or `display_string'. */
18523 static int
18524 display_mode_element (struct it *it, int depth, int field_width, int precision,
18525 Lisp_Object elt, Lisp_Object props, int risky)
18527 int n = 0, field, prec;
18528 int literal = 0;
18530 tail_recurse:
18531 if (depth > 100)
18532 elt = build_string ("*too-deep*");
18534 depth++;
18536 switch (SWITCH_ENUM_CAST (XTYPE (elt)))
18538 case Lisp_String:
18540 /* A string: output it and check for %-constructs within it. */
18541 unsigned char c;
18542 EMACS_INT offset = 0;
18544 if (SCHARS (elt) > 0
18545 && (!NILP (props) || risky))
18547 Lisp_Object oprops, aelt;
18548 oprops = Ftext_properties_at (make_number (0), elt);
18550 /* If the starting string's properties are not what
18551 we want, translate the string. Also, if the string
18552 is risky, do that anyway. */
18554 if (NILP (Fequal (props, oprops)) || risky)
18556 /* If the starting string has properties,
18557 merge the specified ones onto the existing ones. */
18558 if (! NILP (oprops) && !risky)
18560 Lisp_Object tem;
18562 oprops = Fcopy_sequence (oprops);
18563 tem = props;
18564 while (CONSP (tem))
18566 oprops = Fplist_put (oprops, XCAR (tem),
18567 XCAR (XCDR (tem)));
18568 tem = XCDR (XCDR (tem));
18570 props = oprops;
18573 aelt = Fassoc (elt, mode_line_proptrans_alist);
18574 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
18576 /* AELT is what we want. Move it to the front
18577 without consing. */
18578 elt = XCAR (aelt);
18579 mode_line_proptrans_alist
18580 = move_elt_to_front (aelt, mode_line_proptrans_alist);
18582 else
18584 Lisp_Object tem;
18586 /* If AELT has the wrong props, it is useless.
18587 so get rid of it. */
18588 if (! NILP (aelt))
18589 mode_line_proptrans_alist
18590 = Fdelq (aelt, mode_line_proptrans_alist);
18592 elt = Fcopy_sequence (elt);
18593 Fset_text_properties (make_number (0), Flength (elt),
18594 props, elt);
18595 /* Add this item to mode_line_proptrans_alist. */
18596 mode_line_proptrans_alist
18597 = Fcons (Fcons (elt, props),
18598 mode_line_proptrans_alist);
18599 /* Truncate mode_line_proptrans_alist
18600 to at most 50 elements. */
18601 tem = Fnthcdr (make_number (50),
18602 mode_line_proptrans_alist);
18603 if (! NILP (tem))
18604 XSETCDR (tem, Qnil);
18609 offset = 0;
18611 if (literal)
18613 prec = precision - n;
18614 switch (mode_line_target)
18616 case MODE_LINE_NOPROP:
18617 case MODE_LINE_TITLE:
18618 n += store_mode_line_noprop (SDATA (elt), -1, prec);
18619 break;
18620 case MODE_LINE_STRING:
18621 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
18622 break;
18623 case MODE_LINE_DISPLAY:
18624 n += display_string (NULL, elt, Qnil, 0, 0, it,
18625 0, prec, 0, STRING_MULTIBYTE (elt));
18626 break;
18629 break;
18632 /* Handle the non-literal case. */
18634 while ((precision <= 0 || n < precision)
18635 && SREF (elt, offset) != 0
18636 && (mode_line_target != MODE_LINE_DISPLAY
18637 || it->current_x < it->last_visible_x))
18639 EMACS_INT last_offset = offset;
18641 /* Advance to end of string or next format specifier. */
18642 while ((c = SREF (elt, offset++)) != '\0' && c != '%')
18645 if (offset - 1 != last_offset)
18647 EMACS_INT nchars, nbytes;
18649 /* Output to end of string or up to '%'. Field width
18650 is length of string. Don't output more than
18651 PRECISION allows us. */
18652 offset--;
18654 prec = c_string_width (SDATA (elt) + last_offset,
18655 offset - last_offset, precision - n,
18656 &nchars, &nbytes);
18658 switch (mode_line_target)
18660 case MODE_LINE_NOPROP:
18661 case MODE_LINE_TITLE:
18662 n += store_mode_line_noprop (SDATA (elt) + last_offset, 0, prec);
18663 break;
18664 case MODE_LINE_STRING:
18666 EMACS_INT bytepos = last_offset;
18667 EMACS_INT charpos = string_byte_to_char (elt, bytepos);
18668 EMACS_INT endpos = (precision <= 0
18669 ? string_byte_to_char (elt, offset)
18670 : charpos + nchars);
18672 n += store_mode_line_string (NULL,
18673 Fsubstring (elt, make_number (charpos),
18674 make_number (endpos)),
18675 0, 0, 0, Qnil);
18677 break;
18678 case MODE_LINE_DISPLAY:
18680 EMACS_INT bytepos = last_offset;
18681 EMACS_INT charpos = string_byte_to_char (elt, bytepos);
18683 if (precision <= 0)
18684 nchars = string_byte_to_char (elt, offset) - charpos;
18685 n += display_string (NULL, elt, Qnil, 0, charpos,
18686 it, 0, nchars, 0,
18687 STRING_MULTIBYTE (elt));
18689 break;
18692 else /* c == '%' */
18694 EMACS_INT percent_position = offset;
18696 /* Get the specified minimum width. Zero means
18697 don't pad. */
18698 field = 0;
18699 while ((c = SREF (elt, offset++)) >= '0' && c <= '9')
18700 field = field * 10 + c - '0';
18702 /* Don't pad beyond the total padding allowed. */
18703 if (field_width - n > 0 && field > field_width - n)
18704 field = field_width - n;
18706 /* Note that either PRECISION <= 0 or N < PRECISION. */
18707 prec = precision - n;
18709 if (c == 'M')
18710 n += display_mode_element (it, depth, field, prec,
18711 Vglobal_mode_string, props,
18712 risky);
18713 else if (c != 0)
18715 int multibyte;
18716 EMACS_INT bytepos, charpos;
18717 const unsigned char *spec;
18718 Lisp_Object string;
18720 bytepos = percent_position;
18721 charpos = (STRING_MULTIBYTE (elt)
18722 ? string_byte_to_char (elt, bytepos)
18723 : bytepos);
18724 spec = decode_mode_spec (it->w, c, field, prec, &string);
18725 multibyte = STRINGP (string) && STRING_MULTIBYTE (string);
18727 switch (mode_line_target)
18729 case MODE_LINE_NOPROP:
18730 case MODE_LINE_TITLE:
18731 n += store_mode_line_noprop (spec, field, prec);
18732 break;
18733 case MODE_LINE_STRING:
18735 int len = strlen (spec);
18736 Lisp_Object tem = make_string (spec, len);
18737 props = Ftext_properties_at (make_number (charpos), elt);
18738 /* Should only keep face property in props */
18739 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
18741 break;
18742 case MODE_LINE_DISPLAY:
18744 int nglyphs_before, nwritten;
18746 nglyphs_before = it->glyph_row->used[TEXT_AREA];
18747 nwritten = display_string (spec, string, elt,
18748 charpos, 0, it,
18749 field, prec, 0,
18750 multibyte);
18752 /* Assign to the glyphs written above the
18753 string where the `%x' came from, position
18754 of the `%'. */
18755 if (nwritten > 0)
18757 struct glyph *glyph
18758 = (it->glyph_row->glyphs[TEXT_AREA]
18759 + nglyphs_before);
18760 int i;
18762 for (i = 0; i < nwritten; ++i)
18764 glyph[i].object = elt;
18765 glyph[i].charpos = charpos;
18768 n += nwritten;
18771 break;
18774 else /* c == 0 */
18775 break;
18779 break;
18781 case Lisp_Symbol:
18782 /* A symbol: process the value of the symbol recursively
18783 as if it appeared here directly. Avoid error if symbol void.
18784 Special case: if value of symbol is a string, output the string
18785 literally. */
18787 register Lisp_Object tem;
18789 /* If the variable is not marked as risky to set
18790 then its contents are risky to use. */
18791 if (NILP (Fget (elt, Qrisky_local_variable)))
18792 risky = 1;
18794 tem = Fboundp (elt);
18795 if (!NILP (tem))
18797 tem = Fsymbol_value (elt);
18798 /* If value is a string, output that string literally:
18799 don't check for % within it. */
18800 if (STRINGP (tem))
18801 literal = 1;
18803 if (!EQ (tem, elt))
18805 /* Give up right away for nil or t. */
18806 elt = tem;
18807 goto tail_recurse;
18811 break;
18813 case Lisp_Cons:
18815 register Lisp_Object car, tem;
18817 /* A cons cell: five distinct cases.
18818 If first element is :eval or :propertize, do something special.
18819 If first element is a string or a cons, process all the elements
18820 and effectively concatenate them.
18821 If first element is a negative number, truncate displaying cdr to
18822 at most that many characters. If positive, pad (with spaces)
18823 to at least that many characters.
18824 If first element is a symbol, process the cadr or caddr recursively
18825 according to whether the symbol's value is non-nil or nil. */
18826 car = XCAR (elt);
18827 if (EQ (car, QCeval))
18829 /* An element of the form (:eval FORM) means evaluate FORM
18830 and use the result as mode line elements. */
18832 if (risky)
18833 break;
18835 if (CONSP (XCDR (elt)))
18837 Lisp_Object spec;
18838 spec = safe_eval (XCAR (XCDR (elt)));
18839 n += display_mode_element (it, depth, field_width - n,
18840 precision - n, spec, props,
18841 risky);
18844 else if (EQ (car, QCpropertize))
18846 /* An element of the form (:propertize ELT PROPS...)
18847 means display ELT but applying properties PROPS. */
18849 if (risky)
18850 break;
18852 if (CONSP (XCDR (elt)))
18853 n += display_mode_element (it, depth, field_width - n,
18854 precision - n, XCAR (XCDR (elt)),
18855 XCDR (XCDR (elt)), risky);
18857 else if (SYMBOLP (car))
18859 tem = Fboundp (car);
18860 elt = XCDR (elt);
18861 if (!CONSP (elt))
18862 goto invalid;
18863 /* elt is now the cdr, and we know it is a cons cell.
18864 Use its car if CAR has a non-nil value. */
18865 if (!NILP (tem))
18867 tem = Fsymbol_value (car);
18868 if (!NILP (tem))
18870 elt = XCAR (elt);
18871 goto tail_recurse;
18874 /* Symbol's value is nil (or symbol is unbound)
18875 Get the cddr of the original list
18876 and if possible find the caddr and use that. */
18877 elt = XCDR (elt);
18878 if (NILP (elt))
18879 break;
18880 else if (!CONSP (elt))
18881 goto invalid;
18882 elt = XCAR (elt);
18883 goto tail_recurse;
18885 else if (INTEGERP (car))
18887 register int lim = XINT (car);
18888 elt = XCDR (elt);
18889 if (lim < 0)
18891 /* Negative int means reduce maximum width. */
18892 if (precision <= 0)
18893 precision = -lim;
18894 else
18895 precision = min (precision, -lim);
18897 else if (lim > 0)
18899 /* Padding specified. Don't let it be more than
18900 current maximum. */
18901 if (precision > 0)
18902 lim = min (precision, lim);
18904 /* If that's more padding than already wanted, queue it.
18905 But don't reduce padding already specified even if
18906 that is beyond the current truncation point. */
18907 field_width = max (lim, field_width);
18909 goto tail_recurse;
18911 else if (STRINGP (car) || CONSP (car))
18913 Lisp_Object halftail = elt;
18914 int len = 0;
18916 while (CONSP (elt)
18917 && (precision <= 0 || n < precision))
18919 n += display_mode_element (it, depth,
18920 /* Do padding only after the last
18921 element in the list. */
18922 (! CONSP (XCDR (elt))
18923 ? field_width - n
18924 : 0),
18925 precision - n, XCAR (elt),
18926 props, risky);
18927 elt = XCDR (elt);
18928 len++;
18929 if ((len & 1) == 0)
18930 halftail = XCDR (halftail);
18931 /* Check for cycle. */
18932 if (EQ (halftail, elt))
18933 break;
18937 break;
18939 default:
18940 invalid:
18941 elt = build_string ("*invalid*");
18942 goto tail_recurse;
18945 /* Pad to FIELD_WIDTH. */
18946 if (field_width > 0 && n < field_width)
18948 switch (mode_line_target)
18950 case MODE_LINE_NOPROP:
18951 case MODE_LINE_TITLE:
18952 n += store_mode_line_noprop ("", field_width - n, 0);
18953 break;
18954 case MODE_LINE_STRING:
18955 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
18956 break;
18957 case MODE_LINE_DISPLAY:
18958 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
18959 0, 0, 0);
18960 break;
18964 return n;
18967 /* Store a mode-line string element in mode_line_string_list.
18969 If STRING is non-null, display that C string. Otherwise, the Lisp
18970 string LISP_STRING is displayed.
18972 FIELD_WIDTH is the minimum number of output glyphs to produce.
18973 If STRING has fewer characters than FIELD_WIDTH, pad to the right
18974 with spaces. FIELD_WIDTH <= 0 means don't pad.
18976 PRECISION is the maximum number of characters to output from
18977 STRING. PRECISION <= 0 means don't truncate the string.
18979 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
18980 properties to the string.
18982 PROPS are the properties to add to the string.
18983 The mode_line_string_face face property is always added to the string.
18986 static int
18987 store_mode_line_string (const char *string, Lisp_Object lisp_string, int copy_string,
18988 int field_width, int precision, Lisp_Object props)
18990 EMACS_INT len;
18991 int n = 0;
18993 if (string != NULL)
18995 len = strlen (string);
18996 if (precision > 0 && len > precision)
18997 len = precision;
18998 lisp_string = make_string (string, len);
18999 if (NILP (props))
19000 props = mode_line_string_face_prop;
19001 else if (!NILP (mode_line_string_face))
19003 Lisp_Object face = Fplist_get (props, Qface);
19004 props = Fcopy_sequence (props);
19005 if (NILP (face))
19006 face = mode_line_string_face;
19007 else
19008 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
19009 props = Fplist_put (props, Qface, face);
19011 Fadd_text_properties (make_number (0), make_number (len),
19012 props, lisp_string);
19014 else
19016 len = XFASTINT (Flength (lisp_string));
19017 if (precision > 0 && len > precision)
19019 len = precision;
19020 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
19021 precision = -1;
19023 if (!NILP (mode_line_string_face))
19025 Lisp_Object face;
19026 if (NILP (props))
19027 props = Ftext_properties_at (make_number (0), lisp_string);
19028 face = Fplist_get (props, Qface);
19029 if (NILP (face))
19030 face = mode_line_string_face;
19031 else
19032 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
19033 props = Fcons (Qface, Fcons (face, Qnil));
19034 if (copy_string)
19035 lisp_string = Fcopy_sequence (lisp_string);
19037 if (!NILP (props))
19038 Fadd_text_properties (make_number (0), make_number (len),
19039 props, lisp_string);
19042 if (len > 0)
19044 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
19045 n += len;
19048 if (field_width > len)
19050 field_width -= len;
19051 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
19052 if (!NILP (props))
19053 Fadd_text_properties (make_number (0), make_number (field_width),
19054 props, lisp_string);
19055 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
19056 n += field_width;
19059 return n;
19063 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
19064 1, 4, 0,
19065 doc: /* Format a string out of a mode line format specification.
19066 First arg FORMAT specifies the mode line format (see `mode-line-format'
19067 for details) to use.
19069 By default, the format is evaluated for the currently selected window.
19071 Optional second arg FACE specifies the face property to put on all
19072 characters for which no face is specified. The value nil means the
19073 default face. The value t means whatever face the window's mode line
19074 currently uses (either `mode-line' or `mode-line-inactive',
19075 depending on whether the window is the selected window or not).
19076 An integer value means the value string has no text
19077 properties.
19079 Optional third and fourth args WINDOW and BUFFER specify the window
19080 and buffer to use as the context for the formatting (defaults
19081 are the selected window and the WINDOW's buffer). */)
19082 (Lisp_Object format, Lisp_Object face,
19083 Lisp_Object window, Lisp_Object buffer)
19085 struct it it;
19086 int len;
19087 struct window *w;
19088 struct buffer *old_buffer = NULL;
19089 int face_id;
19090 int no_props = INTEGERP (face);
19091 int count = SPECPDL_INDEX ();
19092 Lisp_Object str;
19093 int string_start = 0;
19095 if (NILP (window))
19096 window = selected_window;
19097 CHECK_WINDOW (window);
19098 w = XWINDOW (window);
19100 if (NILP (buffer))
19101 buffer = w->buffer;
19102 CHECK_BUFFER (buffer);
19104 /* Make formatting the modeline a non-op when noninteractive, otherwise
19105 there will be problems later caused by a partially initialized frame. */
19106 if (NILP (format) || noninteractive)
19107 return empty_unibyte_string;
19109 if (no_props)
19110 face = Qnil;
19112 face_id = (NILP (face) || EQ (face, Qdefault)) ? DEFAULT_FACE_ID
19113 : EQ (face, Qt) ? (EQ (window, selected_window)
19114 ? MODE_LINE_FACE_ID : MODE_LINE_INACTIVE_FACE_ID)
19115 : EQ (face, Qmode_line) ? MODE_LINE_FACE_ID
19116 : EQ (face, Qmode_line_inactive) ? MODE_LINE_INACTIVE_FACE_ID
19117 : EQ (face, Qheader_line) ? HEADER_LINE_FACE_ID
19118 : EQ (face, Qtool_bar) ? TOOL_BAR_FACE_ID
19119 : DEFAULT_FACE_ID;
19121 if (XBUFFER (buffer) != current_buffer)
19122 old_buffer = current_buffer;
19124 /* Save things including mode_line_proptrans_alist,
19125 and set that to nil so that we don't alter the outer value. */
19126 record_unwind_protect (unwind_format_mode_line,
19127 format_mode_line_unwind_data
19128 (old_buffer, selected_window, 1));
19129 mode_line_proptrans_alist = Qnil;
19131 Fselect_window (window, Qt);
19132 if (old_buffer)
19133 set_buffer_internal_1 (XBUFFER (buffer));
19135 init_iterator (&it, w, -1, -1, NULL, face_id);
19137 if (no_props)
19139 mode_line_target = MODE_LINE_NOPROP;
19140 mode_line_string_face_prop = Qnil;
19141 mode_line_string_list = Qnil;
19142 string_start = MODE_LINE_NOPROP_LEN (0);
19144 else
19146 mode_line_target = MODE_LINE_STRING;
19147 mode_line_string_list = Qnil;
19148 mode_line_string_face = face;
19149 mode_line_string_face_prop
19150 = (NILP (face) ? Qnil : Fcons (Qface, Fcons (face, Qnil)));
19153 push_kboard (FRAME_KBOARD (it.f));
19154 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
19155 pop_kboard ();
19157 if (no_props)
19159 len = MODE_LINE_NOPROP_LEN (string_start);
19160 str = make_string (mode_line_noprop_buf + string_start, len);
19162 else
19164 mode_line_string_list = Fnreverse (mode_line_string_list);
19165 str = Fmapconcat (intern ("identity"), mode_line_string_list,
19166 empty_unibyte_string);
19169 unbind_to (count, Qnil);
19170 return str;
19173 /* Write a null-terminated, right justified decimal representation of
19174 the positive integer D to BUF using a minimal field width WIDTH. */
19176 static void
19177 pint2str (register char *buf, register int width, register int d)
19179 register char *p = buf;
19181 if (d <= 0)
19182 *p++ = '0';
19183 else
19185 while (d > 0)
19187 *p++ = d % 10 + '0';
19188 d /= 10;
19192 for (width -= (int) (p - buf); width > 0; --width)
19193 *p++ = ' ';
19194 *p-- = '\0';
19195 while (p > buf)
19197 d = *buf;
19198 *buf++ = *p;
19199 *p-- = d;
19203 /* Write a null-terminated, right justified decimal and "human
19204 readable" representation of the nonnegative integer D to BUF using
19205 a minimal field width WIDTH. D should be smaller than 999.5e24. */
19207 static const char power_letter[] =
19209 0, /* not used */
19210 'k', /* kilo */
19211 'M', /* mega */
19212 'G', /* giga */
19213 'T', /* tera */
19214 'P', /* peta */
19215 'E', /* exa */
19216 'Z', /* zetta */
19217 'Y' /* yotta */
19220 static void
19221 pint2hrstr (char *buf, int width, int d)
19223 /* We aim to represent the nonnegative integer D as
19224 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
19225 int quotient = d;
19226 int remainder = 0;
19227 /* -1 means: do not use TENTHS. */
19228 int tenths = -1;
19229 int exponent = 0;
19231 /* Length of QUOTIENT.TENTHS as a string. */
19232 int length;
19234 char * psuffix;
19235 char * p;
19237 if (1000 <= quotient)
19239 /* Scale to the appropriate EXPONENT. */
19242 remainder = quotient % 1000;
19243 quotient /= 1000;
19244 exponent++;
19246 while (1000 <= quotient);
19248 /* Round to nearest and decide whether to use TENTHS or not. */
19249 if (quotient <= 9)
19251 tenths = remainder / 100;
19252 if (50 <= remainder % 100)
19254 if (tenths < 9)
19255 tenths++;
19256 else
19258 quotient++;
19259 if (quotient == 10)
19260 tenths = -1;
19261 else
19262 tenths = 0;
19266 else
19267 if (500 <= remainder)
19269 if (quotient < 999)
19270 quotient++;
19271 else
19273 quotient = 1;
19274 exponent++;
19275 tenths = 0;
19280 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
19281 if (tenths == -1 && quotient <= 99)
19282 if (quotient <= 9)
19283 length = 1;
19284 else
19285 length = 2;
19286 else
19287 length = 3;
19288 p = psuffix = buf + max (width, length);
19290 /* Print EXPONENT. */
19291 if (exponent)
19292 *psuffix++ = power_letter[exponent];
19293 *psuffix = '\0';
19295 /* Print TENTHS. */
19296 if (tenths >= 0)
19298 *--p = '0' + tenths;
19299 *--p = '.';
19302 /* Print QUOTIENT. */
19305 int digit = quotient % 10;
19306 *--p = '0' + digit;
19308 while ((quotient /= 10) != 0);
19310 /* Print leading spaces. */
19311 while (buf < p)
19312 *--p = ' ';
19315 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
19316 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
19317 type of CODING_SYSTEM. Return updated pointer into BUF. */
19319 static unsigned char invalid_eol_type[] = "(*invalid*)";
19321 static char *
19322 decode_mode_spec_coding (Lisp_Object coding_system, register char *buf, int eol_flag)
19324 Lisp_Object val;
19325 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
19326 const unsigned char *eol_str;
19327 int eol_str_len;
19328 /* The EOL conversion we are using. */
19329 Lisp_Object eoltype;
19331 val = CODING_SYSTEM_SPEC (coding_system);
19332 eoltype = Qnil;
19334 if (!VECTORP (val)) /* Not yet decided. */
19336 if (multibyte)
19337 *buf++ = '-';
19338 if (eol_flag)
19339 eoltype = eol_mnemonic_undecided;
19340 /* Don't mention EOL conversion if it isn't decided. */
19342 else
19344 Lisp_Object attrs;
19345 Lisp_Object eolvalue;
19347 attrs = AREF (val, 0);
19348 eolvalue = AREF (val, 2);
19350 if (multibyte)
19351 *buf++ = XFASTINT (CODING_ATTR_MNEMONIC (attrs));
19353 if (eol_flag)
19355 /* The EOL conversion that is normal on this system. */
19357 if (NILP (eolvalue)) /* Not yet decided. */
19358 eoltype = eol_mnemonic_undecided;
19359 else if (VECTORP (eolvalue)) /* Not yet decided. */
19360 eoltype = eol_mnemonic_undecided;
19361 else /* eolvalue is Qunix, Qdos, or Qmac. */
19362 eoltype = (EQ (eolvalue, Qunix)
19363 ? eol_mnemonic_unix
19364 : (EQ (eolvalue, Qdos) == 1
19365 ? eol_mnemonic_dos : eol_mnemonic_mac));
19369 if (eol_flag)
19371 /* Mention the EOL conversion if it is not the usual one. */
19372 if (STRINGP (eoltype))
19374 eol_str = SDATA (eoltype);
19375 eol_str_len = SBYTES (eoltype);
19377 else if (CHARACTERP (eoltype))
19379 unsigned char *tmp = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
19380 eol_str_len = CHAR_STRING (XINT (eoltype), tmp);
19381 eol_str = tmp;
19383 else
19385 eol_str = invalid_eol_type;
19386 eol_str_len = sizeof (invalid_eol_type) - 1;
19388 memcpy (buf, eol_str, eol_str_len);
19389 buf += eol_str_len;
19392 return buf;
19395 /* Return a string for the output of a mode line %-spec for window W,
19396 generated by character C. PRECISION >= 0 means don't return a
19397 string longer than that value. FIELD_WIDTH > 0 means pad the
19398 string returned with spaces to that value. Return a Lisp string in
19399 *STRING if the resulting string is taken from that Lisp string.
19401 Note we operate on the current buffer for most purposes,
19402 the exception being w->base_line_pos. */
19404 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
19406 static const char *
19407 decode_mode_spec (struct window *w, register int c, int field_width,
19408 int precision, Lisp_Object *string)
19410 Lisp_Object obj;
19411 struct frame *f = XFRAME (WINDOW_FRAME (w));
19412 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
19413 struct buffer *b = current_buffer;
19415 obj = Qnil;
19416 *string = Qnil;
19418 switch (c)
19420 case '*':
19421 if (!NILP (b->read_only))
19422 return "%";
19423 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
19424 return "*";
19425 return "-";
19427 case '+':
19428 /* This differs from %* only for a modified read-only buffer. */
19429 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
19430 return "*";
19431 if (!NILP (b->read_only))
19432 return "%";
19433 return "-";
19435 case '&':
19436 /* This differs from %* in ignoring read-only-ness. */
19437 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
19438 return "*";
19439 return "-";
19441 case '%':
19442 return "%";
19444 case '[':
19446 int i;
19447 char *p;
19449 if (command_loop_level > 5)
19450 return "[[[... ";
19451 p = decode_mode_spec_buf;
19452 for (i = 0; i < command_loop_level; i++)
19453 *p++ = '[';
19454 *p = 0;
19455 return decode_mode_spec_buf;
19458 case ']':
19460 int i;
19461 char *p;
19463 if (command_loop_level > 5)
19464 return " ...]]]";
19465 p = decode_mode_spec_buf;
19466 for (i = 0; i < command_loop_level; i++)
19467 *p++ = ']';
19468 *p = 0;
19469 return decode_mode_spec_buf;
19472 case '-':
19474 register int i;
19476 /* Let lots_of_dashes be a string of infinite length. */
19477 if (mode_line_target == MODE_LINE_NOPROP ||
19478 mode_line_target == MODE_LINE_STRING)
19479 return "--";
19480 if (field_width <= 0
19481 || field_width > sizeof (lots_of_dashes))
19483 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
19484 decode_mode_spec_buf[i] = '-';
19485 decode_mode_spec_buf[i] = '\0';
19486 return decode_mode_spec_buf;
19488 else
19489 return lots_of_dashes;
19492 case 'b':
19493 obj = b->name;
19494 break;
19496 case 'c':
19497 /* %c and %l are ignored in `frame-title-format'.
19498 (In redisplay_internal, the frame title is drawn _before_ the
19499 windows are updated, so the stuff which depends on actual
19500 window contents (such as %l) may fail to render properly, or
19501 even crash emacs.) */
19502 if (mode_line_target == MODE_LINE_TITLE)
19503 return "";
19504 else
19506 int col = (int) current_column (); /* iftc */
19507 w->column_number_displayed = make_number (col);
19508 pint2str (decode_mode_spec_buf, field_width, col);
19509 return decode_mode_spec_buf;
19512 case 'e':
19513 #ifndef SYSTEM_MALLOC
19515 if (NILP (Vmemory_full))
19516 return "";
19517 else
19518 return "!MEM FULL! ";
19520 #else
19521 return "";
19522 #endif
19524 case 'F':
19525 /* %F displays the frame name. */
19526 if (!NILP (f->title))
19527 return (char *) SDATA (f->title);
19528 if (f->explicit_name || ! FRAME_WINDOW_P (f))
19529 return (char *) SDATA (f->name);
19530 return "Emacs";
19532 case 'f':
19533 obj = b->filename;
19534 break;
19536 case 'i':
19538 EMACS_INT size = ZV - BEGV;
19539 pint2str (decode_mode_spec_buf, field_width, size);
19540 return decode_mode_spec_buf;
19543 case 'I':
19545 EMACS_INT size = ZV - BEGV;
19546 pint2hrstr (decode_mode_spec_buf, field_width, size);
19547 return decode_mode_spec_buf;
19550 case 'l':
19552 EMACS_INT startpos, startpos_byte, line, linepos, linepos_byte;
19553 int topline, nlines, height;
19554 EMACS_INT junk;
19556 /* %c and %l are ignored in `frame-title-format'. */
19557 if (mode_line_target == MODE_LINE_TITLE)
19558 return "";
19560 startpos = XMARKER (w->start)->charpos;
19561 startpos_byte = marker_byte_position (w->start);
19562 height = WINDOW_TOTAL_LINES (w);
19564 /* If we decided that this buffer isn't suitable for line numbers,
19565 don't forget that too fast. */
19566 if (EQ (w->base_line_pos, w->buffer))
19567 goto no_value;
19568 /* But do forget it, if the window shows a different buffer now. */
19569 else if (BUFFERP (w->base_line_pos))
19570 w->base_line_pos = Qnil;
19572 /* If the buffer is very big, don't waste time. */
19573 if (INTEGERP (Vline_number_display_limit)
19574 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
19576 w->base_line_pos = Qnil;
19577 w->base_line_number = Qnil;
19578 goto no_value;
19581 if (INTEGERP (w->base_line_number)
19582 && INTEGERP (w->base_line_pos)
19583 && XFASTINT (w->base_line_pos) <= startpos)
19585 line = XFASTINT (w->base_line_number);
19586 linepos = XFASTINT (w->base_line_pos);
19587 linepos_byte = buf_charpos_to_bytepos (b, linepos);
19589 else
19591 line = 1;
19592 linepos = BUF_BEGV (b);
19593 linepos_byte = BUF_BEGV_BYTE (b);
19596 /* Count lines from base line to window start position. */
19597 nlines = display_count_lines (linepos, linepos_byte,
19598 startpos_byte,
19599 startpos, &junk);
19601 topline = nlines + line;
19603 /* Determine a new base line, if the old one is too close
19604 or too far away, or if we did not have one.
19605 "Too close" means it's plausible a scroll-down would
19606 go back past it. */
19607 if (startpos == BUF_BEGV (b))
19609 w->base_line_number = make_number (topline);
19610 w->base_line_pos = make_number (BUF_BEGV (b));
19612 else if (nlines < height + 25 || nlines > height * 3 + 50
19613 || linepos == BUF_BEGV (b))
19615 EMACS_INT limit = BUF_BEGV (b);
19616 EMACS_INT limit_byte = BUF_BEGV_BYTE (b);
19617 EMACS_INT position;
19618 int distance = (height * 2 + 30) * line_number_display_limit_width;
19620 if (startpos - distance > limit)
19622 limit = startpos - distance;
19623 limit_byte = CHAR_TO_BYTE (limit);
19626 nlines = display_count_lines (startpos, startpos_byte,
19627 limit_byte,
19628 - (height * 2 + 30),
19629 &position);
19630 /* If we couldn't find the lines we wanted within
19631 line_number_display_limit_width chars per line,
19632 give up on line numbers for this window. */
19633 if (position == limit_byte && limit == startpos - distance)
19635 w->base_line_pos = w->buffer;
19636 w->base_line_number = Qnil;
19637 goto no_value;
19640 w->base_line_number = make_number (topline - nlines);
19641 w->base_line_pos = make_number (BYTE_TO_CHAR (position));
19644 /* Now count lines from the start pos to point. */
19645 nlines = display_count_lines (startpos, startpos_byte,
19646 PT_BYTE, PT, &junk);
19648 /* Record that we did display the line number. */
19649 line_number_displayed = 1;
19651 /* Make the string to show. */
19652 pint2str (decode_mode_spec_buf, field_width, topline + nlines);
19653 return decode_mode_spec_buf;
19654 no_value:
19656 char* p = decode_mode_spec_buf;
19657 int pad = field_width - 2;
19658 while (pad-- > 0)
19659 *p++ = ' ';
19660 *p++ = '?';
19661 *p++ = '?';
19662 *p = '\0';
19663 return decode_mode_spec_buf;
19666 break;
19668 case 'm':
19669 obj = b->mode_name;
19670 break;
19672 case 'n':
19673 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
19674 return " Narrow";
19675 break;
19677 case 'p':
19679 EMACS_INT pos = marker_position (w->start);
19680 EMACS_INT total = BUF_ZV (b) - BUF_BEGV (b);
19682 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
19684 if (pos <= BUF_BEGV (b))
19685 return "All";
19686 else
19687 return "Bottom";
19689 else if (pos <= BUF_BEGV (b))
19690 return "Top";
19691 else
19693 if (total > 1000000)
19694 /* Do it differently for a large value, to avoid overflow. */
19695 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
19696 else
19697 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
19698 /* We can't normally display a 3-digit number,
19699 so get us a 2-digit number that is close. */
19700 if (total == 100)
19701 total = 99;
19702 sprintf (decode_mode_spec_buf, "%2ld%%", (long)total);
19703 return decode_mode_spec_buf;
19707 /* Display percentage of size above the bottom of the screen. */
19708 case 'P':
19710 EMACS_INT toppos = marker_position (w->start);
19711 EMACS_INT botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
19712 EMACS_INT total = BUF_ZV (b) - BUF_BEGV (b);
19714 if (botpos >= BUF_ZV (b))
19716 if (toppos <= BUF_BEGV (b))
19717 return "All";
19718 else
19719 return "Bottom";
19721 else
19723 if (total > 1000000)
19724 /* Do it differently for a large value, to avoid overflow. */
19725 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
19726 else
19727 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
19728 /* We can't normally display a 3-digit number,
19729 so get us a 2-digit number that is close. */
19730 if (total == 100)
19731 total = 99;
19732 if (toppos <= BUF_BEGV (b))
19733 sprintf (decode_mode_spec_buf, "Top%2ld%%", (long)total);
19734 else
19735 sprintf (decode_mode_spec_buf, "%2ld%%", (long)total);
19736 return decode_mode_spec_buf;
19740 case 's':
19741 /* status of process */
19742 obj = Fget_buffer_process (Fcurrent_buffer ());
19743 if (NILP (obj))
19744 return "no process";
19745 #ifndef MSDOS
19746 obj = Fsymbol_name (Fprocess_status (obj));
19747 #endif
19748 break;
19750 case '@':
19752 int count = inhibit_garbage_collection ();
19753 Lisp_Object val = call1 (intern ("file-remote-p"),
19754 current_buffer->directory);
19755 unbind_to (count, Qnil);
19757 if (NILP (val))
19758 return "-";
19759 else
19760 return "@";
19763 case 't': /* indicate TEXT or BINARY */
19764 #ifdef MODE_LINE_BINARY_TEXT
19765 return MODE_LINE_BINARY_TEXT (b);
19766 #else
19767 return "T";
19768 #endif
19770 case 'z':
19771 /* coding-system (not including end-of-line format) */
19772 case 'Z':
19773 /* coding-system (including end-of-line type) */
19775 int eol_flag = (c == 'Z');
19776 char *p = decode_mode_spec_buf;
19778 if (! FRAME_WINDOW_P (f))
19780 /* No need to mention EOL here--the terminal never needs
19781 to do EOL conversion. */
19782 p = decode_mode_spec_coding (CODING_ID_NAME
19783 (FRAME_KEYBOARD_CODING (f)->id),
19784 p, 0);
19785 p = decode_mode_spec_coding (CODING_ID_NAME
19786 (FRAME_TERMINAL_CODING (f)->id),
19787 p, 0);
19789 p = decode_mode_spec_coding (b->buffer_file_coding_system,
19790 p, eol_flag);
19792 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
19793 #ifdef subprocesses
19794 obj = Fget_buffer_process (Fcurrent_buffer ());
19795 if (PROCESSP (obj))
19797 p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system,
19798 p, eol_flag);
19799 p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system,
19800 p, eol_flag);
19802 #endif /* subprocesses */
19803 #endif /* 0 */
19804 *p = 0;
19805 return decode_mode_spec_buf;
19809 if (STRINGP (obj))
19811 *string = obj;
19812 return (char *) SDATA (obj);
19814 else
19815 return "";
19819 /* Count up to COUNT lines starting from START / START_BYTE.
19820 But don't go beyond LIMIT_BYTE.
19821 Return the number of lines thus found (always nonnegative).
19823 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
19825 static int
19826 display_count_lines (EMACS_INT start, EMACS_INT start_byte,
19827 EMACS_INT limit_byte, int count,
19828 EMACS_INT *byte_pos_ptr)
19830 register unsigned char *cursor;
19831 unsigned char *base;
19833 register int ceiling;
19834 register unsigned char *ceiling_addr;
19835 int orig_count = count;
19837 /* If we are not in selective display mode,
19838 check only for newlines. */
19839 int selective_display = (!NILP (current_buffer->selective_display)
19840 && !INTEGERP (current_buffer->selective_display));
19842 if (count > 0)
19844 while (start_byte < limit_byte)
19846 ceiling = BUFFER_CEILING_OF (start_byte);
19847 ceiling = min (limit_byte - 1, ceiling);
19848 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
19849 base = (cursor = BYTE_POS_ADDR (start_byte));
19850 while (1)
19852 if (selective_display)
19853 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
19855 else
19856 while (*cursor != '\n' && ++cursor != ceiling_addr)
19859 if (cursor != ceiling_addr)
19861 if (--count == 0)
19863 start_byte += cursor - base + 1;
19864 *byte_pos_ptr = start_byte;
19865 return orig_count;
19867 else
19868 if (++cursor == ceiling_addr)
19869 break;
19871 else
19872 break;
19874 start_byte += cursor - base;
19877 else
19879 while (start_byte > limit_byte)
19881 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
19882 ceiling = max (limit_byte, ceiling);
19883 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1;
19884 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
19885 while (1)
19887 if (selective_display)
19888 while (--cursor != ceiling_addr
19889 && *cursor != '\n' && *cursor != 015)
19891 else
19892 while (--cursor != ceiling_addr && *cursor != '\n')
19895 if (cursor != ceiling_addr)
19897 if (++count == 0)
19899 start_byte += cursor - base + 1;
19900 *byte_pos_ptr = start_byte;
19901 /* When scanning backwards, we should
19902 not count the newline posterior to which we stop. */
19903 return - orig_count - 1;
19906 else
19907 break;
19909 /* Here we add 1 to compensate for the last decrement
19910 of CURSOR, which took it past the valid range. */
19911 start_byte += cursor - base + 1;
19915 *byte_pos_ptr = limit_byte;
19917 if (count < 0)
19918 return - orig_count + count;
19919 return orig_count - count;
19925 /***********************************************************************
19926 Displaying strings
19927 ***********************************************************************/
19929 /* Display a NUL-terminated string, starting with index START.
19931 If STRING is non-null, display that C string. Otherwise, the Lisp
19932 string LISP_STRING is displayed. There's a case that STRING is
19933 non-null and LISP_STRING is not nil. It means STRING is a string
19934 data of LISP_STRING. In that case, we display LISP_STRING while
19935 ignoring its text properties.
19937 If FACE_STRING is not nil, FACE_STRING_POS is a position in
19938 FACE_STRING. Display STRING or LISP_STRING with the face at
19939 FACE_STRING_POS in FACE_STRING:
19941 Display the string in the environment given by IT, but use the
19942 standard display table, temporarily.
19944 FIELD_WIDTH is the minimum number of output glyphs to produce.
19945 If STRING has fewer characters than FIELD_WIDTH, pad to the right
19946 with spaces. If STRING has more characters, more than FIELD_WIDTH
19947 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
19949 PRECISION is the maximum number of characters to output from
19950 STRING. PRECISION < 0 means don't truncate the string.
19952 This is roughly equivalent to printf format specifiers:
19954 FIELD_WIDTH PRECISION PRINTF
19955 ----------------------------------------
19956 -1 -1 %s
19957 -1 10 %.10s
19958 10 -1 %10s
19959 20 10 %20.10s
19961 MULTIBYTE zero means do not display multibyte chars, > 0 means do
19962 display them, and < 0 means obey the current buffer's value of
19963 enable_multibyte_characters.
19965 Value is the number of columns displayed. */
19967 static int
19968 display_string (const unsigned char *string, Lisp_Object lisp_string, Lisp_Object face_string,
19969 EMACS_INT face_string_pos, EMACS_INT start, struct it *it,
19970 int field_width, int precision, int max_x, int multibyte)
19972 int hpos_at_start = it->hpos;
19973 int saved_face_id = it->face_id;
19974 struct glyph_row *row = it->glyph_row;
19976 /* Initialize the iterator IT for iteration over STRING beginning
19977 with index START. */
19978 reseat_to_string (it, NILP (lisp_string) ? string : NULL, lisp_string, start,
19979 precision, field_width, multibyte);
19980 if (string && STRINGP (lisp_string))
19981 /* LISP_STRING is the one returned by decode_mode_spec. We should
19982 ignore its text properties. */
19983 it->stop_charpos = -1;
19985 /* If displaying STRING, set up the face of the iterator
19986 from LISP_STRING, if that's given. */
19987 if (STRINGP (face_string))
19989 EMACS_INT endptr;
19990 struct face *face;
19992 it->face_id
19993 = face_at_string_position (it->w, face_string, face_string_pos,
19994 0, it->region_beg_charpos,
19995 it->region_end_charpos,
19996 &endptr, it->base_face_id, 0);
19997 face = FACE_FROM_ID (it->f, it->face_id);
19998 it->face_box_p = face->box != FACE_NO_BOX;
20001 /* Set max_x to the maximum allowed X position. Don't let it go
20002 beyond the right edge of the window. */
20003 if (max_x <= 0)
20004 max_x = it->last_visible_x;
20005 else
20006 max_x = min (max_x, it->last_visible_x);
20008 /* Skip over display elements that are not visible. because IT->w is
20009 hscrolled. */
20010 if (it->current_x < it->first_visible_x)
20011 move_it_in_display_line_to (it, 100000, it->first_visible_x,
20012 MOVE_TO_POS | MOVE_TO_X);
20014 row->ascent = it->max_ascent;
20015 row->height = it->max_ascent + it->max_descent;
20016 row->phys_ascent = it->max_phys_ascent;
20017 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
20018 row->extra_line_spacing = it->max_extra_line_spacing;
20020 /* This condition is for the case that we are called with current_x
20021 past last_visible_x. */
20022 while (it->current_x < max_x)
20024 int x_before, x, n_glyphs_before, i, nglyphs;
20026 /* Get the next display element. */
20027 if (!get_next_display_element (it))
20028 break;
20030 /* Produce glyphs. */
20031 x_before = it->current_x;
20032 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
20033 PRODUCE_GLYPHS (it);
20035 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
20036 i = 0;
20037 x = x_before;
20038 while (i < nglyphs)
20040 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
20042 if (it->line_wrap != TRUNCATE
20043 && x + glyph->pixel_width > max_x)
20045 /* End of continued line or max_x reached. */
20046 if (CHAR_GLYPH_PADDING_P (*glyph))
20048 /* A wide character is unbreakable. */
20049 it->glyph_row->used[TEXT_AREA] = n_glyphs_before;
20050 it->current_x = x_before;
20052 else
20054 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
20055 it->current_x = x;
20057 break;
20059 else if (x + glyph->pixel_width >= it->first_visible_x)
20061 /* Glyph is at least partially visible. */
20062 ++it->hpos;
20063 if (x < it->first_visible_x)
20064 it->glyph_row->x = x - it->first_visible_x;
20066 else
20068 /* Glyph is off the left margin of the display area.
20069 Should not happen. */
20070 abort ();
20073 row->ascent = max (row->ascent, it->max_ascent);
20074 row->height = max (row->height, it->max_ascent + it->max_descent);
20075 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
20076 row->phys_height = max (row->phys_height,
20077 it->max_phys_ascent + it->max_phys_descent);
20078 row->extra_line_spacing = max (row->extra_line_spacing,
20079 it->max_extra_line_spacing);
20080 x += glyph->pixel_width;
20081 ++i;
20084 /* Stop if max_x reached. */
20085 if (i < nglyphs)
20086 break;
20088 /* Stop at line ends. */
20089 if (ITERATOR_AT_END_OF_LINE_P (it))
20091 it->continuation_lines_width = 0;
20092 break;
20095 set_iterator_to_next (it, 1);
20097 /* Stop if truncating at the right edge. */
20098 if (it->line_wrap == TRUNCATE
20099 && it->current_x >= it->last_visible_x)
20101 /* Add truncation mark, but don't do it if the line is
20102 truncated at a padding space. */
20103 if (IT_CHARPOS (*it) < it->string_nchars)
20105 if (!FRAME_WINDOW_P (it->f))
20107 int i, n;
20109 if (it->current_x > it->last_visible_x)
20111 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
20112 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
20113 break;
20114 for (n = row->used[TEXT_AREA]; i < n; ++i)
20116 row->used[TEXT_AREA] = i;
20117 produce_special_glyphs (it, IT_TRUNCATION);
20120 produce_special_glyphs (it, IT_TRUNCATION);
20122 it->glyph_row->truncated_on_right_p = 1;
20124 break;
20128 /* Maybe insert a truncation at the left. */
20129 if (it->first_visible_x
20130 && IT_CHARPOS (*it) > 0)
20132 if (!FRAME_WINDOW_P (it->f))
20133 insert_left_trunc_glyphs (it);
20134 it->glyph_row->truncated_on_left_p = 1;
20137 it->face_id = saved_face_id;
20139 /* Value is number of columns displayed. */
20140 return it->hpos - hpos_at_start;
20145 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
20146 appears as an element of LIST or as the car of an element of LIST.
20147 If PROPVAL is a list, compare each element against LIST in that
20148 way, and return 1/2 if any element of PROPVAL is found in LIST.
20149 Otherwise return 0. This function cannot quit.
20150 The return value is 2 if the text is invisible but with an ellipsis
20151 and 1 if it's invisible and without an ellipsis. */
20154 invisible_p (register Lisp_Object propval, Lisp_Object list)
20156 register Lisp_Object tail, proptail;
20158 for (tail = list; CONSP (tail); tail = XCDR (tail))
20160 register Lisp_Object tem;
20161 tem = XCAR (tail);
20162 if (EQ (propval, tem))
20163 return 1;
20164 if (CONSP (tem) && EQ (propval, XCAR (tem)))
20165 return NILP (XCDR (tem)) ? 1 : 2;
20168 if (CONSP (propval))
20170 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
20172 Lisp_Object propelt;
20173 propelt = XCAR (proptail);
20174 for (tail = list; CONSP (tail); tail = XCDR (tail))
20176 register Lisp_Object tem;
20177 tem = XCAR (tail);
20178 if (EQ (propelt, tem))
20179 return 1;
20180 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
20181 return NILP (XCDR (tem)) ? 1 : 2;
20186 return 0;
20189 DEFUN ("invisible-p", Finvisible_p, Sinvisible_p, 1, 1, 0,
20190 doc: /* Non-nil if the property makes the text invisible.
20191 POS-OR-PROP can be a marker or number, in which case it is taken to be
20192 a position in the current buffer and the value of the `invisible' property
20193 is checked; or it can be some other value, which is then presumed to be the
20194 value of the `invisible' property of the text of interest.
20195 The non-nil value returned can be t for truly invisible text or something
20196 else if the text is replaced by an ellipsis. */)
20197 (Lisp_Object pos_or_prop)
20199 Lisp_Object prop
20200 = (NATNUMP (pos_or_prop) || MARKERP (pos_or_prop)
20201 ? Fget_char_property (pos_or_prop, Qinvisible, Qnil)
20202 : pos_or_prop);
20203 int invis = TEXT_PROP_MEANS_INVISIBLE (prop);
20204 return (invis == 0 ? Qnil
20205 : invis == 1 ? Qt
20206 : make_number (invis));
20209 /* Calculate a width or height in pixels from a specification using
20210 the following elements:
20212 SPEC ::=
20213 NUM - a (fractional) multiple of the default font width/height
20214 (NUM) - specifies exactly NUM pixels
20215 UNIT - a fixed number of pixels, see below.
20216 ELEMENT - size of a display element in pixels, see below.
20217 (NUM . SPEC) - equals NUM * SPEC
20218 (+ SPEC SPEC ...) - add pixel values
20219 (- SPEC SPEC ...) - subtract pixel values
20220 (- SPEC) - negate pixel value
20222 NUM ::=
20223 INT or FLOAT - a number constant
20224 SYMBOL - use symbol's (buffer local) variable binding.
20226 UNIT ::=
20227 in - pixels per inch *)
20228 mm - pixels per 1/1000 meter *)
20229 cm - pixels per 1/100 meter *)
20230 width - width of current font in pixels.
20231 height - height of current font in pixels.
20233 *) using the ratio(s) defined in display-pixels-per-inch.
20235 ELEMENT ::=
20237 left-fringe - left fringe width in pixels
20238 right-fringe - right fringe width in pixels
20240 left-margin - left margin width in pixels
20241 right-margin - right margin width in pixels
20243 scroll-bar - scroll-bar area width in pixels
20245 Examples:
20247 Pixels corresponding to 5 inches:
20248 (5 . in)
20250 Total width of non-text areas on left side of window (if scroll-bar is on left):
20251 '(space :width (+ left-fringe left-margin scroll-bar))
20253 Align to first text column (in header line):
20254 '(space :align-to 0)
20256 Align to middle of text area minus half the width of variable `my-image'
20257 containing a loaded image:
20258 '(space :align-to (0.5 . (- text my-image)))
20260 Width of left margin minus width of 1 character in the default font:
20261 '(space :width (- left-margin 1))
20263 Width of left margin minus width of 2 characters in the current font:
20264 '(space :width (- left-margin (2 . width)))
20266 Center 1 character over left-margin (in header line):
20267 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
20269 Different ways to express width of left fringe plus left margin minus one pixel:
20270 '(space :width (- (+ left-fringe left-margin) (1)))
20271 '(space :width (+ left-fringe left-margin (- (1))))
20272 '(space :width (+ left-fringe left-margin (-1)))
20276 #define NUMVAL(X) \
20277 ((INTEGERP (X) || FLOATP (X)) \
20278 ? XFLOATINT (X) \
20279 : - 1)
20282 calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
20283 struct font *font, int width_p, int *align_to)
20285 double pixels;
20287 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
20288 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
20290 if (NILP (prop))
20291 return OK_PIXELS (0);
20293 xassert (FRAME_LIVE_P (it->f));
20295 if (SYMBOLP (prop))
20297 if (SCHARS (SYMBOL_NAME (prop)) == 2)
20299 char *unit = SDATA (SYMBOL_NAME (prop));
20301 if (unit[0] == 'i' && unit[1] == 'n')
20302 pixels = 1.0;
20303 else if (unit[0] == 'm' && unit[1] == 'm')
20304 pixels = 25.4;
20305 else if (unit[0] == 'c' && unit[1] == 'm')
20306 pixels = 2.54;
20307 else
20308 pixels = 0;
20309 if (pixels > 0)
20311 double ppi;
20312 #ifdef HAVE_WINDOW_SYSTEM
20313 if (FRAME_WINDOW_P (it->f)
20314 && (ppi = (width_p
20315 ? FRAME_X_DISPLAY_INFO (it->f)->resx
20316 : FRAME_X_DISPLAY_INFO (it->f)->resy),
20317 ppi > 0))
20318 return OK_PIXELS (ppi / pixels);
20319 #endif
20321 if ((ppi = NUMVAL (Vdisplay_pixels_per_inch), ppi > 0)
20322 || (CONSP (Vdisplay_pixels_per_inch)
20323 && (ppi = (width_p
20324 ? NUMVAL (XCAR (Vdisplay_pixels_per_inch))
20325 : NUMVAL (XCDR (Vdisplay_pixels_per_inch))),
20326 ppi > 0)))
20327 return OK_PIXELS (ppi / pixels);
20329 return 0;
20333 #ifdef HAVE_WINDOW_SYSTEM
20334 if (EQ (prop, Qheight))
20335 return OK_PIXELS (font ? FONT_HEIGHT (font) : FRAME_LINE_HEIGHT (it->f));
20336 if (EQ (prop, Qwidth))
20337 return OK_PIXELS (font ? FONT_WIDTH (font) : FRAME_COLUMN_WIDTH (it->f));
20338 #else
20339 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
20340 return OK_PIXELS (1);
20341 #endif
20343 if (EQ (prop, Qtext))
20344 return OK_PIXELS (width_p
20345 ? window_box_width (it->w, TEXT_AREA)
20346 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
20348 if (align_to && *align_to < 0)
20350 *res = 0;
20351 if (EQ (prop, Qleft))
20352 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA));
20353 if (EQ (prop, Qright))
20354 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
20355 if (EQ (prop, Qcenter))
20356 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
20357 + window_box_width (it->w, TEXT_AREA) / 2);
20358 if (EQ (prop, Qleft_fringe))
20359 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
20360 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
20361 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
20362 if (EQ (prop, Qright_fringe))
20363 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
20364 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
20365 : window_box_right_offset (it->w, TEXT_AREA));
20366 if (EQ (prop, Qleft_margin))
20367 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
20368 if (EQ (prop, Qright_margin))
20369 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
20370 if (EQ (prop, Qscroll_bar))
20371 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
20373 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
20374 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
20375 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
20376 : 0)));
20378 else
20380 if (EQ (prop, Qleft_fringe))
20381 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
20382 if (EQ (prop, Qright_fringe))
20383 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
20384 if (EQ (prop, Qleft_margin))
20385 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
20386 if (EQ (prop, Qright_margin))
20387 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
20388 if (EQ (prop, Qscroll_bar))
20389 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
20392 prop = Fbuffer_local_value (prop, it->w->buffer);
20395 if (INTEGERP (prop) || FLOATP (prop))
20397 int base_unit = (width_p
20398 ? FRAME_COLUMN_WIDTH (it->f)
20399 : FRAME_LINE_HEIGHT (it->f));
20400 return OK_PIXELS (XFLOATINT (prop) * base_unit);
20403 if (CONSP (prop))
20405 Lisp_Object car = XCAR (prop);
20406 Lisp_Object cdr = XCDR (prop);
20408 if (SYMBOLP (car))
20410 #ifdef HAVE_WINDOW_SYSTEM
20411 if (FRAME_WINDOW_P (it->f)
20412 && valid_image_p (prop))
20414 int id = lookup_image (it->f, prop);
20415 struct image *img = IMAGE_FROM_ID (it->f, id);
20417 return OK_PIXELS (width_p ? img->width : img->height);
20419 #endif
20420 if (EQ (car, Qplus) || EQ (car, Qminus))
20422 int first = 1;
20423 double px;
20425 pixels = 0;
20426 while (CONSP (cdr))
20428 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
20429 font, width_p, align_to))
20430 return 0;
20431 if (first)
20432 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
20433 else
20434 pixels += px;
20435 cdr = XCDR (cdr);
20437 if (EQ (car, Qminus))
20438 pixels = -pixels;
20439 return OK_PIXELS (pixels);
20442 car = Fbuffer_local_value (car, it->w->buffer);
20445 if (INTEGERP (car) || FLOATP (car))
20447 double fact;
20448 pixels = XFLOATINT (car);
20449 if (NILP (cdr))
20450 return OK_PIXELS (pixels);
20451 if (calc_pixel_width_or_height (&fact, it, cdr,
20452 font, width_p, align_to))
20453 return OK_PIXELS (pixels * fact);
20454 return 0;
20457 return 0;
20460 return 0;
20464 /***********************************************************************
20465 Glyph Display
20466 ***********************************************************************/
20468 #ifdef HAVE_WINDOW_SYSTEM
20470 #if GLYPH_DEBUG
20472 void
20473 dump_glyph_string (s)
20474 struct glyph_string *s;
20476 fprintf (stderr, "glyph string\n");
20477 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
20478 s->x, s->y, s->width, s->height);
20479 fprintf (stderr, " ybase = %d\n", s->ybase);
20480 fprintf (stderr, " hl = %d\n", s->hl);
20481 fprintf (stderr, " left overhang = %d, right = %d\n",
20482 s->left_overhang, s->right_overhang);
20483 fprintf (stderr, " nchars = %d\n", s->nchars);
20484 fprintf (stderr, " extends to end of line = %d\n",
20485 s->extends_to_end_of_line_p);
20486 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
20487 fprintf (stderr, " bg width = %d\n", s->background_width);
20490 #endif /* GLYPH_DEBUG */
20492 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
20493 of XChar2b structures for S; it can't be allocated in
20494 init_glyph_string because it must be allocated via `alloca'. W
20495 is the window on which S is drawn. ROW and AREA are the glyph row
20496 and area within the row from which S is constructed. START is the
20497 index of the first glyph structure covered by S. HL is a
20498 face-override for drawing S. */
20500 #ifdef HAVE_NTGUI
20501 #define OPTIONAL_HDC(hdc) HDC hdc,
20502 #define DECLARE_HDC(hdc) HDC hdc;
20503 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
20504 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
20505 #endif
20507 #ifndef OPTIONAL_HDC
20508 #define OPTIONAL_HDC(hdc)
20509 #define DECLARE_HDC(hdc)
20510 #define ALLOCATE_HDC(hdc, f)
20511 #define RELEASE_HDC(hdc, f)
20512 #endif
20514 static void
20515 init_glyph_string (struct glyph_string *s,
20516 OPTIONAL_HDC (hdc)
20517 XChar2b *char2b, struct window *w, struct glyph_row *row,
20518 enum glyph_row_area area, int start, enum draw_glyphs_face hl)
20520 memset (s, 0, sizeof *s);
20521 s->w = w;
20522 s->f = XFRAME (w->frame);
20523 #ifdef HAVE_NTGUI
20524 s->hdc = hdc;
20525 #endif
20526 s->display = FRAME_X_DISPLAY (s->f);
20527 s->window = FRAME_X_WINDOW (s->f);
20528 s->char2b = char2b;
20529 s->hl = hl;
20530 s->row = row;
20531 s->area = area;
20532 s->first_glyph = row->glyphs[area] + start;
20533 s->height = row->height;
20534 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
20535 s->ybase = s->y + row->ascent;
20539 /* Append the list of glyph strings with head H and tail T to the list
20540 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
20542 static INLINE void
20543 append_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
20544 struct glyph_string *h, struct glyph_string *t)
20546 if (h)
20548 if (*head)
20549 (*tail)->next = h;
20550 else
20551 *head = h;
20552 h->prev = *tail;
20553 *tail = t;
20558 /* Prepend the list of glyph strings with head H and tail T to the
20559 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
20560 result. */
20562 static INLINE void
20563 prepend_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
20564 struct glyph_string *h, struct glyph_string *t)
20566 if (h)
20568 if (*head)
20569 (*head)->prev = t;
20570 else
20571 *tail = t;
20572 t->next = *head;
20573 *head = h;
20578 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
20579 Set *HEAD and *TAIL to the resulting list. */
20581 static INLINE void
20582 append_glyph_string (struct glyph_string **head, struct glyph_string **tail,
20583 struct glyph_string *s)
20585 s->next = s->prev = NULL;
20586 append_glyph_string_lists (head, tail, s, s);
20590 /* Get face and two-byte form of character C in face FACE_ID on frame
20591 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
20592 means we want to display multibyte text. DISPLAY_P non-zero means
20593 make sure that X resources for the face returned are allocated.
20594 Value is a pointer to a realized face that is ready for display if
20595 DISPLAY_P is non-zero. */
20597 static INLINE struct face *
20598 get_char_face_and_encoding (struct frame *f, int c, int face_id,
20599 XChar2b *char2b, int multibyte_p, int display_p)
20601 struct face *face = FACE_FROM_ID (f, face_id);
20603 if (face->font)
20605 unsigned code = face->font->driver->encode_char (face->font, c);
20607 if (code != FONT_INVALID_CODE)
20608 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
20609 else
20610 STORE_XCHAR2B (char2b, 0, 0);
20613 /* Make sure X resources of the face are allocated. */
20614 #ifdef HAVE_X_WINDOWS
20615 if (display_p)
20616 #endif
20618 xassert (face != NULL);
20619 PREPARE_FACE_FOR_DISPLAY (f, face);
20622 return face;
20626 /* Get face and two-byte form of character glyph GLYPH on frame F.
20627 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
20628 a pointer to a realized face that is ready for display. */
20630 static INLINE struct face *
20631 get_glyph_face_and_encoding (struct frame *f, struct glyph *glyph,
20632 XChar2b *char2b, int *two_byte_p)
20634 struct face *face;
20636 xassert (glyph->type == CHAR_GLYPH);
20637 face = FACE_FROM_ID (f, glyph->face_id);
20639 if (two_byte_p)
20640 *two_byte_p = 0;
20642 if (face->font)
20644 unsigned code;
20646 if (CHAR_BYTE8_P (glyph->u.ch))
20647 code = CHAR_TO_BYTE8 (glyph->u.ch);
20648 else
20649 code = face->font->driver->encode_char (face->font, glyph->u.ch);
20651 if (code != FONT_INVALID_CODE)
20652 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
20653 else
20654 STORE_XCHAR2B (char2b, 0, 0);
20657 /* Make sure X resources of the face are allocated. */
20658 xassert (face != NULL);
20659 PREPARE_FACE_FOR_DISPLAY (f, face);
20660 return face;
20664 /* Get glyph code of character C in FONT in the two-byte form CHAR2B.
20665 Retunr 1 if FONT has a glyph for C, otherwise return 0. */
20667 static INLINE int
20668 get_char_glyph_code (int c, struct font *font, XChar2b *char2b)
20670 unsigned code;
20672 if (CHAR_BYTE8_P (c))
20673 code = CHAR_TO_BYTE8 (c);
20674 else
20675 code = font->driver->encode_char (font, c);
20677 if (code == FONT_INVALID_CODE)
20678 return 0;
20679 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
20680 return 1;
20684 /* Fill glyph string S with composition components specified by S->cmp.
20686 BASE_FACE is the base face of the composition.
20687 S->cmp_from is the index of the first component for S.
20689 OVERLAPS non-zero means S should draw the foreground only, and use
20690 its physical height for clipping. See also draw_glyphs.
20692 Value is the index of a component not in S. */
20694 static int
20695 fill_composite_glyph_string (struct glyph_string *s, struct face *base_face,
20696 int overlaps)
20698 int i;
20699 /* For all glyphs of this composition, starting at the offset
20700 S->cmp_from, until we reach the end of the definition or encounter a
20701 glyph that requires the different face, add it to S. */
20702 struct face *face;
20704 xassert (s);
20706 s->for_overlaps = overlaps;
20707 s->face = NULL;
20708 s->font = NULL;
20709 for (i = s->cmp_from; i < s->cmp->glyph_len; i++)
20711 int c = COMPOSITION_GLYPH (s->cmp, i);
20713 if (c != '\t')
20715 int face_id = FACE_FOR_CHAR (s->f, base_face->ascii_face, c,
20716 -1, Qnil);
20718 face = get_char_face_and_encoding (s->f, c, face_id,
20719 s->char2b + i, 1, 1);
20720 if (face)
20722 if (! s->face)
20724 s->face = face;
20725 s->font = s->face->font;
20727 else if (s->face != face)
20728 break;
20731 ++s->nchars;
20733 s->cmp_to = i;
20735 /* All glyph strings for the same composition has the same width,
20736 i.e. the width set for the first component of the composition. */
20737 s->width = s->first_glyph->pixel_width;
20739 /* If the specified font could not be loaded, use the frame's
20740 default font, but record the fact that we couldn't load it in
20741 the glyph string so that we can draw rectangles for the
20742 characters of the glyph string. */
20743 if (s->font == NULL)
20745 s->font_not_found_p = 1;
20746 s->font = FRAME_FONT (s->f);
20749 /* Adjust base line for subscript/superscript text. */
20750 s->ybase += s->first_glyph->voffset;
20752 /* This glyph string must always be drawn with 16-bit functions. */
20753 s->two_byte_p = 1;
20755 return s->cmp_to;
20758 static int
20759 fill_gstring_glyph_string (struct glyph_string *s, int face_id,
20760 int start, int end, int overlaps)
20762 struct glyph *glyph, *last;
20763 Lisp_Object lgstring;
20764 int i;
20766 s->for_overlaps = overlaps;
20767 glyph = s->row->glyphs[s->area] + start;
20768 last = s->row->glyphs[s->area] + end;
20769 s->cmp_id = glyph->u.cmp.id;
20770 s->cmp_from = glyph->slice.cmp.from;
20771 s->cmp_to = glyph->slice.cmp.to + 1;
20772 s->face = FACE_FROM_ID (s->f, face_id);
20773 lgstring = composition_gstring_from_id (s->cmp_id);
20774 s->font = XFONT_OBJECT (LGSTRING_FONT (lgstring));
20775 glyph++;
20776 while (glyph < last
20777 && glyph->u.cmp.automatic
20778 && glyph->u.cmp.id == s->cmp_id
20779 && s->cmp_to == glyph->slice.cmp.from)
20780 s->cmp_to = (glyph++)->slice.cmp.to + 1;
20782 for (i = s->cmp_from; i < s->cmp_to; i++)
20784 Lisp_Object lglyph = LGSTRING_GLYPH (lgstring, i);
20785 unsigned code = LGLYPH_CODE (lglyph);
20787 STORE_XCHAR2B ((s->char2b + i), code >> 8, code & 0xFF);
20789 s->width = composition_gstring_width (lgstring, s->cmp_from, s->cmp_to, NULL);
20790 return glyph - s->row->glyphs[s->area];
20794 /* Fill glyph string S from a sequence glyphs for glyphless characters.
20795 See the comment of fill_glyph_string for arguments.
20796 Value is the index of the first glyph not in S. */
20799 static int
20800 fill_glyphless_glyph_string (struct glyph_string *s, int face_id,
20801 int start, int end, int overlaps)
20803 struct glyph *glyph, *last;
20804 int voffset;
20806 xassert (s->first_glyph->type == GLYPHLESS_GLYPH);
20807 s->for_overlaps = overlaps;
20808 glyph = s->row->glyphs[s->area] + start;
20809 last = s->row->glyphs[s->area] + end;
20810 voffset = glyph->voffset;
20811 s->face = FACE_FROM_ID (s->f, face_id);
20812 s->font = s->face->font;
20813 s->nchars = 1;
20814 s->width = glyph->pixel_width;
20815 glyph++;
20816 while (glyph < last
20817 && glyph->type == GLYPHLESS_GLYPH
20818 && glyph->voffset == voffset
20819 && glyph->face_id == face_id)
20821 s->nchars++;
20822 s->width += glyph->pixel_width;
20823 glyph++;
20825 s->ybase += voffset;
20826 return glyph - s->row->glyphs[s->area];
20830 /* Fill glyph string S from a sequence of character glyphs.
20832 FACE_ID is the face id of the string. START is the index of the
20833 first glyph to consider, END is the index of the last + 1.
20834 OVERLAPS non-zero means S should draw the foreground only, and use
20835 its physical height for clipping. See also draw_glyphs.
20837 Value is the index of the first glyph not in S. */
20839 static int
20840 fill_glyph_string (struct glyph_string *s, int face_id,
20841 int start, int end, int overlaps)
20843 struct glyph *glyph, *last;
20844 int voffset;
20845 int glyph_not_available_p;
20847 xassert (s->f == XFRAME (s->w->frame));
20848 xassert (s->nchars == 0);
20849 xassert (start >= 0 && end > start);
20851 s->for_overlaps = overlaps;
20852 glyph = s->row->glyphs[s->area] + start;
20853 last = s->row->glyphs[s->area] + end;
20854 voffset = glyph->voffset;
20855 s->padding_p = glyph->padding_p;
20856 glyph_not_available_p = glyph->glyph_not_available_p;
20858 while (glyph < last
20859 && glyph->type == CHAR_GLYPH
20860 && glyph->voffset == voffset
20861 /* Same face id implies same font, nowadays. */
20862 && glyph->face_id == face_id
20863 && glyph->glyph_not_available_p == glyph_not_available_p)
20865 int two_byte_p;
20867 s->face = get_glyph_face_and_encoding (s->f, glyph,
20868 s->char2b + s->nchars,
20869 &two_byte_p);
20870 s->two_byte_p = two_byte_p;
20871 ++s->nchars;
20872 xassert (s->nchars <= end - start);
20873 s->width += glyph->pixel_width;
20874 if (glyph++->padding_p != s->padding_p)
20875 break;
20878 s->font = s->face->font;
20880 /* If the specified font could not be loaded, use the frame's font,
20881 but record the fact that we couldn't load it in
20882 S->font_not_found_p so that we can draw rectangles for the
20883 characters of the glyph string. */
20884 if (s->font == NULL || glyph_not_available_p)
20886 s->font_not_found_p = 1;
20887 s->font = FRAME_FONT (s->f);
20890 /* Adjust base line for subscript/superscript text. */
20891 s->ybase += voffset;
20893 xassert (s->face && s->face->gc);
20894 return glyph - s->row->glyphs[s->area];
20898 /* Fill glyph string S from image glyph S->first_glyph. */
20900 static void
20901 fill_image_glyph_string (struct glyph_string *s)
20903 xassert (s->first_glyph->type == IMAGE_GLYPH);
20904 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
20905 xassert (s->img);
20906 s->slice = s->first_glyph->slice.img;
20907 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
20908 s->font = s->face->font;
20909 s->width = s->first_glyph->pixel_width;
20911 /* Adjust base line for subscript/superscript text. */
20912 s->ybase += s->first_glyph->voffset;
20916 /* Fill glyph string S from a sequence of stretch glyphs.
20918 ROW is the glyph row in which the glyphs are found, AREA is the
20919 area within the row. START is the index of the first glyph to
20920 consider, END is the index of the last + 1.
20922 Value is the index of the first glyph not in S. */
20924 static int
20925 fill_stretch_glyph_string (struct glyph_string *s, struct glyph_row *row,
20926 enum glyph_row_area area, int start, int end)
20928 struct glyph *glyph, *last;
20929 int voffset, face_id;
20931 xassert (s->first_glyph->type == STRETCH_GLYPH);
20933 glyph = s->row->glyphs[s->area] + start;
20934 last = s->row->glyphs[s->area] + end;
20935 face_id = glyph->face_id;
20936 s->face = FACE_FROM_ID (s->f, face_id);
20937 s->font = s->face->font;
20938 s->width = glyph->pixel_width;
20939 s->nchars = 1;
20940 voffset = glyph->voffset;
20942 for (++glyph;
20943 (glyph < last
20944 && glyph->type == STRETCH_GLYPH
20945 && glyph->voffset == voffset
20946 && glyph->face_id == face_id);
20947 ++glyph)
20948 s->width += glyph->pixel_width;
20950 /* Adjust base line for subscript/superscript text. */
20951 s->ybase += voffset;
20953 /* The case that face->gc == 0 is handled when drawing the glyph
20954 string by calling PREPARE_FACE_FOR_DISPLAY. */
20955 xassert (s->face);
20956 return glyph - s->row->glyphs[s->area];
20959 static struct font_metrics *
20960 get_per_char_metric (struct frame *f, struct font *font, XChar2b *char2b)
20962 static struct font_metrics metrics;
20963 unsigned code = (XCHAR2B_BYTE1 (char2b) << 8) | XCHAR2B_BYTE2 (char2b);
20965 if (! font || code == FONT_INVALID_CODE)
20966 return NULL;
20967 font->driver->text_extents (font, &code, 1, &metrics);
20968 return &metrics;
20971 /* EXPORT for RIF:
20972 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
20973 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
20974 assumed to be zero. */
20976 void
20977 x_get_glyph_overhangs (struct glyph *glyph, struct frame *f, int *left, int *right)
20979 *left = *right = 0;
20981 if (glyph->type == CHAR_GLYPH)
20983 struct face *face;
20984 XChar2b char2b;
20985 struct font_metrics *pcm;
20987 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
20988 if (face->font && (pcm = get_per_char_metric (f, face->font, &char2b)))
20990 if (pcm->rbearing > pcm->width)
20991 *right = pcm->rbearing - pcm->width;
20992 if (pcm->lbearing < 0)
20993 *left = -pcm->lbearing;
20996 else if (glyph->type == COMPOSITE_GLYPH)
20998 if (! glyph->u.cmp.automatic)
21000 struct composition *cmp = composition_table[glyph->u.cmp.id];
21002 if (cmp->rbearing > cmp->pixel_width)
21003 *right = cmp->rbearing - cmp->pixel_width;
21004 if (cmp->lbearing < 0)
21005 *left = - cmp->lbearing;
21007 else
21009 Lisp_Object gstring = composition_gstring_from_id (glyph->u.cmp.id);
21010 struct font_metrics metrics;
21012 composition_gstring_width (gstring, glyph->slice.cmp.from,
21013 glyph->slice.cmp.to + 1, &metrics);
21014 if (metrics.rbearing > metrics.width)
21015 *right = metrics.rbearing - metrics.width;
21016 if (metrics.lbearing < 0)
21017 *left = - metrics.lbearing;
21023 /* Return the index of the first glyph preceding glyph string S that
21024 is overwritten by S because of S's left overhang. Value is -1
21025 if no glyphs are overwritten. */
21027 static int
21028 left_overwritten (struct glyph_string *s)
21030 int k;
21032 if (s->left_overhang)
21034 int x = 0, i;
21035 struct glyph *glyphs = s->row->glyphs[s->area];
21036 int first = s->first_glyph - glyphs;
21038 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
21039 x -= glyphs[i].pixel_width;
21041 k = i + 1;
21043 else
21044 k = -1;
21046 return k;
21050 /* Return the index of the first glyph preceding glyph string S that
21051 is overwriting S because of its right overhang. Value is -1 if no
21052 glyph in front of S overwrites S. */
21054 static int
21055 left_overwriting (struct glyph_string *s)
21057 int i, k, x;
21058 struct glyph *glyphs = s->row->glyphs[s->area];
21059 int first = s->first_glyph - glyphs;
21061 k = -1;
21062 x = 0;
21063 for (i = first - 1; i >= 0; --i)
21065 int left, right;
21066 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
21067 if (x + right > 0)
21068 k = i;
21069 x -= glyphs[i].pixel_width;
21072 return k;
21076 /* Return the index of the last glyph following glyph string S that is
21077 overwritten by S because of S's right overhang. Value is -1 if
21078 no such glyph is found. */
21080 static int
21081 right_overwritten (struct glyph_string *s)
21083 int k = -1;
21085 if (s->right_overhang)
21087 int x = 0, i;
21088 struct glyph *glyphs = s->row->glyphs[s->area];
21089 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
21090 int end = s->row->used[s->area];
21092 for (i = first; i < end && s->right_overhang > x; ++i)
21093 x += glyphs[i].pixel_width;
21095 k = i;
21098 return k;
21102 /* Return the index of the last glyph following glyph string S that
21103 overwrites S because of its left overhang. Value is negative
21104 if no such glyph is found. */
21106 static int
21107 right_overwriting (struct glyph_string *s)
21109 int i, k, x;
21110 int end = s->row->used[s->area];
21111 struct glyph *glyphs = s->row->glyphs[s->area];
21112 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
21114 k = -1;
21115 x = 0;
21116 for (i = first; i < end; ++i)
21118 int left, right;
21119 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
21120 if (x - left < 0)
21121 k = i;
21122 x += glyphs[i].pixel_width;
21125 return k;
21129 /* Set background width of glyph string S. START is the index of the
21130 first glyph following S. LAST_X is the right-most x-position + 1
21131 in the drawing area. */
21133 static INLINE void
21134 set_glyph_string_background_width (struct glyph_string *s, int start, int last_x)
21136 /* If the face of this glyph string has to be drawn to the end of
21137 the drawing area, set S->extends_to_end_of_line_p. */
21139 if (start == s->row->used[s->area]
21140 && s->area == TEXT_AREA
21141 && ((s->row->fill_line_p
21142 && (s->hl == DRAW_NORMAL_TEXT
21143 || s->hl == DRAW_IMAGE_RAISED
21144 || s->hl == DRAW_IMAGE_SUNKEN))
21145 || s->hl == DRAW_MOUSE_FACE))
21146 s->extends_to_end_of_line_p = 1;
21148 /* If S extends its face to the end of the line, set its
21149 background_width to the distance to the right edge of the drawing
21150 area. */
21151 if (s->extends_to_end_of_line_p)
21152 s->background_width = last_x - s->x + 1;
21153 else
21154 s->background_width = s->width;
21158 /* Compute overhangs and x-positions for glyph string S and its
21159 predecessors, or successors. X is the starting x-position for S.
21160 BACKWARD_P non-zero means process predecessors. */
21162 static void
21163 compute_overhangs_and_x (struct glyph_string *s, int x, int backward_p)
21165 if (backward_p)
21167 while (s)
21169 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
21170 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
21171 x -= s->width;
21172 s->x = x;
21173 s = s->prev;
21176 else
21178 while (s)
21180 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
21181 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
21182 s->x = x;
21183 x += s->width;
21184 s = s->next;
21191 /* The following macros are only called from draw_glyphs below.
21192 They reference the following parameters of that function directly:
21193 `w', `row', `area', and `overlap_p'
21194 as well as the following local variables:
21195 `s', `f', and `hdc' (in W32) */
21197 #ifdef HAVE_NTGUI
21198 /* On W32, silently add local `hdc' variable to argument list of
21199 init_glyph_string. */
21200 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
21201 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
21202 #else
21203 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
21204 init_glyph_string (s, char2b, w, row, area, start, hl)
21205 #endif
21207 /* Add a glyph string for a stretch glyph to the list of strings
21208 between HEAD and TAIL. START is the index of the stretch glyph in
21209 row area AREA of glyph row ROW. END is the index of the last glyph
21210 in that glyph row area. X is the current output position assigned
21211 to the new glyph string constructed. HL overrides that face of the
21212 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
21213 is the right-most x-position of the drawing area. */
21215 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
21216 and below -- keep them on one line. */
21217 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
21218 do \
21220 s = (struct glyph_string *) alloca (sizeof *s); \
21221 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
21222 START = fill_stretch_glyph_string (s, row, area, START, END); \
21223 append_glyph_string (&HEAD, &TAIL, s); \
21224 s->x = (X); \
21226 while (0)
21229 /* Add a glyph string for an image glyph to the list of strings
21230 between HEAD and TAIL. START is the index of the image glyph in
21231 row area AREA of glyph row ROW. END is the index of the last glyph
21232 in that glyph row area. X is the current output position assigned
21233 to the new glyph string constructed. HL overrides that face of the
21234 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
21235 is the right-most x-position of the drawing area. */
21237 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
21238 do \
21240 s = (struct glyph_string *) alloca (sizeof *s); \
21241 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
21242 fill_image_glyph_string (s); \
21243 append_glyph_string (&HEAD, &TAIL, s); \
21244 ++START; \
21245 s->x = (X); \
21247 while (0)
21250 /* Add a glyph string for a sequence of character glyphs to the list
21251 of strings between HEAD and TAIL. START is the index of the first
21252 glyph in row area AREA of glyph row ROW that is part of the new
21253 glyph string. END is the index of the last glyph in that glyph row
21254 area. X is the current output position assigned to the new glyph
21255 string constructed. HL overrides that face of the glyph; e.g. it
21256 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
21257 right-most x-position of the drawing area. */
21259 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
21260 do \
21262 int face_id; \
21263 XChar2b *char2b; \
21265 face_id = (row)->glyphs[area][START].face_id; \
21267 s = (struct glyph_string *) alloca (sizeof *s); \
21268 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
21269 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
21270 append_glyph_string (&HEAD, &TAIL, s); \
21271 s->x = (X); \
21272 START = fill_glyph_string (s, face_id, START, END, overlaps); \
21274 while (0)
21277 /* Add a glyph string for a composite sequence to the list of strings
21278 between HEAD and TAIL. START is the index of the first glyph in
21279 row area AREA of glyph row ROW that is part of the new glyph
21280 string. END is the index of the last glyph in that glyph row area.
21281 X is the current output position assigned to the new glyph string
21282 constructed. HL overrides that face of the glyph; e.g. it is
21283 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
21284 x-position of the drawing area. */
21286 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
21287 do { \
21288 int face_id = (row)->glyphs[area][START].face_id; \
21289 struct face *base_face = FACE_FROM_ID (f, face_id); \
21290 int cmp_id = (row)->glyphs[area][START].u.cmp.id; \
21291 struct composition *cmp = composition_table[cmp_id]; \
21292 XChar2b *char2b; \
21293 struct glyph_string *first_s; \
21294 int n; \
21296 char2b = (XChar2b *) alloca ((sizeof *char2b) * cmp->glyph_len); \
21298 /* Make glyph_strings for each glyph sequence that is drawable by \
21299 the same face, and append them to HEAD/TAIL. */ \
21300 for (n = 0; n < cmp->glyph_len;) \
21302 s = (struct glyph_string *) alloca (sizeof *s); \
21303 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
21304 append_glyph_string (&(HEAD), &(TAIL), s); \
21305 s->cmp = cmp; \
21306 s->cmp_from = n; \
21307 s->x = (X); \
21308 if (n == 0) \
21309 first_s = s; \
21310 n = fill_composite_glyph_string (s, base_face, overlaps); \
21313 ++START; \
21314 s = first_s; \
21315 } while (0)
21318 /* Add a glyph string for a glyph-string sequence to the list of strings
21319 between HEAD and TAIL. */
21321 #define BUILD_GSTRING_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
21322 do { \
21323 int face_id; \
21324 XChar2b *char2b; \
21325 Lisp_Object gstring; \
21327 face_id = (row)->glyphs[area][START].face_id; \
21328 gstring = (composition_gstring_from_id \
21329 ((row)->glyphs[area][START].u.cmp.id)); \
21330 s = (struct glyph_string *) alloca (sizeof *s); \
21331 char2b = (XChar2b *) alloca ((sizeof *char2b) \
21332 * LGSTRING_GLYPH_LEN (gstring)); \
21333 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
21334 append_glyph_string (&(HEAD), &(TAIL), s); \
21335 s->x = (X); \
21336 START = fill_gstring_glyph_string (s, face_id, START, END, overlaps); \
21337 } while (0)
21340 /* Add a glyph string for a sequence of glyphless character's glyphs
21341 to the list of strings between HEAD and TAIL. The meanings of
21342 arguments are the same as those of BUILD_CHAR_GLYPH_STRINGS. */
21344 #define BUILD_GLYPHLESS_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
21345 do \
21347 int face_id; \
21348 XChar2b *char2b; \
21350 face_id = (row)->glyphs[area][START].face_id; \
21352 s = (struct glyph_string *) alloca (sizeof *s); \
21353 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
21354 append_glyph_string (&HEAD, &TAIL, s); \
21355 s->x = (X); \
21356 START = fill_glyphless_glyph_string (s, face_id, START, END, \
21357 overlaps); \
21359 while (0)
21362 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
21363 of AREA of glyph row ROW on window W between indices START and END.
21364 HL overrides the face for drawing glyph strings, e.g. it is
21365 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
21366 x-positions of the drawing area.
21368 This is an ugly monster macro construct because we must use alloca
21369 to allocate glyph strings (because draw_glyphs can be called
21370 asynchronously). */
21372 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
21373 do \
21375 HEAD = TAIL = NULL; \
21376 while (START < END) \
21378 struct glyph *first_glyph = (row)->glyphs[area] + START; \
21379 switch (first_glyph->type) \
21381 case CHAR_GLYPH: \
21382 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
21383 HL, X, LAST_X); \
21384 break; \
21386 case COMPOSITE_GLYPH: \
21387 if (first_glyph->u.cmp.automatic) \
21388 BUILD_GSTRING_GLYPH_STRING (START, END, HEAD, TAIL, \
21389 HL, X, LAST_X); \
21390 else \
21391 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
21392 HL, X, LAST_X); \
21393 break; \
21395 case STRETCH_GLYPH: \
21396 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
21397 HL, X, LAST_X); \
21398 break; \
21400 case IMAGE_GLYPH: \
21401 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
21402 HL, X, LAST_X); \
21403 break; \
21405 case GLYPHLESS_GLYPH: \
21406 BUILD_GLYPHLESS_GLYPH_STRING (START, END, HEAD, TAIL, \
21407 HL, X, LAST_X); \
21408 break; \
21410 default: \
21411 abort (); \
21414 if (s) \
21416 set_glyph_string_background_width (s, START, LAST_X); \
21417 (X) += s->width; \
21420 } while (0)
21423 /* Draw glyphs between START and END in AREA of ROW on window W,
21424 starting at x-position X. X is relative to AREA in W. HL is a
21425 face-override with the following meaning:
21427 DRAW_NORMAL_TEXT draw normally
21428 DRAW_CURSOR draw in cursor face
21429 DRAW_MOUSE_FACE draw in mouse face.
21430 DRAW_INVERSE_VIDEO draw in mode line face
21431 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
21432 DRAW_IMAGE_RAISED draw an image with a raised relief around it
21434 If OVERLAPS is non-zero, draw only the foreground of characters and
21435 clip to the physical height of ROW. Non-zero value also defines
21436 the overlapping part to be drawn:
21438 OVERLAPS_PRED overlap with preceding rows
21439 OVERLAPS_SUCC overlap with succeeding rows
21440 OVERLAPS_BOTH overlap with both preceding/succeeding rows
21441 OVERLAPS_ERASED_CURSOR overlap with erased cursor area
21443 Value is the x-position reached, relative to AREA of W. */
21445 static int
21446 draw_glyphs (struct window *w, int x, struct glyph_row *row,
21447 enum glyph_row_area area, EMACS_INT start, EMACS_INT end,
21448 enum draw_glyphs_face hl, int overlaps)
21450 struct glyph_string *head, *tail;
21451 struct glyph_string *s;
21452 struct glyph_string *clip_head = NULL, *clip_tail = NULL;
21453 int i, j, x_reached, last_x, area_left = 0;
21454 struct frame *f = XFRAME (WINDOW_FRAME (w));
21455 DECLARE_HDC (hdc);
21457 ALLOCATE_HDC (hdc, f);
21459 /* Let's rather be paranoid than getting a SEGV. */
21460 end = min (end, row->used[area]);
21461 start = max (0, start);
21462 start = min (end, start);
21464 /* Translate X to frame coordinates. Set last_x to the right
21465 end of the drawing area. */
21466 if (row->full_width_p)
21468 /* X is relative to the left edge of W, without scroll bars
21469 or fringes. */
21470 area_left = WINDOW_LEFT_EDGE_X (w);
21471 last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
21473 else
21475 area_left = window_box_left (w, area);
21476 last_x = area_left + window_box_width (w, area);
21478 x += area_left;
21480 /* Build a doubly-linked list of glyph_string structures between
21481 head and tail from what we have to draw. Note that the macro
21482 BUILD_GLYPH_STRINGS will modify its start parameter. That's
21483 the reason we use a separate variable `i'. */
21484 i = start;
21485 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
21486 if (tail)
21487 x_reached = tail->x + tail->background_width;
21488 else
21489 x_reached = x;
21491 /* If there are any glyphs with lbearing < 0 or rbearing > width in
21492 the row, redraw some glyphs in front or following the glyph
21493 strings built above. */
21494 if (head && !overlaps && row->contains_overlapping_glyphs_p)
21496 struct glyph_string *h, *t;
21497 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
21498 int mouse_beg_col, mouse_end_col, check_mouse_face = 0;
21499 int dummy_x = 0;
21501 /* If mouse highlighting is on, we may need to draw adjacent
21502 glyphs using mouse-face highlighting. */
21503 if (area == TEXT_AREA && row->mouse_face_p)
21505 struct glyph_row *mouse_beg_row, *mouse_end_row;
21507 mouse_beg_row = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_beg_row);
21508 mouse_end_row = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_end_row);
21510 if (row >= mouse_beg_row && row <= mouse_end_row)
21512 check_mouse_face = 1;
21513 mouse_beg_col = (row == mouse_beg_row)
21514 ? hlinfo->mouse_face_beg_col : 0;
21515 mouse_end_col = (row == mouse_end_row)
21516 ? hlinfo->mouse_face_end_col
21517 : row->used[TEXT_AREA];
21521 /* Compute overhangs for all glyph strings. */
21522 if (FRAME_RIF (f)->compute_glyph_string_overhangs)
21523 for (s = head; s; s = s->next)
21524 FRAME_RIF (f)->compute_glyph_string_overhangs (s);
21526 /* Prepend glyph strings for glyphs in front of the first glyph
21527 string that are overwritten because of the first glyph
21528 string's left overhang. The background of all strings
21529 prepended must be drawn because the first glyph string
21530 draws over it. */
21531 i = left_overwritten (head);
21532 if (i >= 0)
21534 enum draw_glyphs_face overlap_hl;
21536 /* If this row contains mouse highlighting, attempt to draw
21537 the overlapped glyphs with the correct highlight. This
21538 code fails if the overlap encompasses more than one glyph
21539 and mouse-highlight spans only some of these glyphs.
21540 However, making it work perfectly involves a lot more
21541 code, and I don't know if the pathological case occurs in
21542 practice, so we'll stick to this for now. --- cyd */
21543 if (check_mouse_face
21544 && mouse_beg_col < start && mouse_end_col > i)
21545 overlap_hl = DRAW_MOUSE_FACE;
21546 else
21547 overlap_hl = DRAW_NORMAL_TEXT;
21549 j = i;
21550 BUILD_GLYPH_STRINGS (j, start, h, t,
21551 overlap_hl, dummy_x, last_x);
21552 start = i;
21553 compute_overhangs_and_x (t, head->x, 1);
21554 prepend_glyph_string_lists (&head, &tail, h, t);
21555 clip_head = head;
21558 /* Prepend glyph strings for glyphs in front of the first glyph
21559 string that overwrite that glyph string because of their
21560 right overhang. For these strings, only the foreground must
21561 be drawn, because it draws over the glyph string at `head'.
21562 The background must not be drawn because this would overwrite
21563 right overhangs of preceding glyphs for which no glyph
21564 strings exist. */
21565 i = left_overwriting (head);
21566 if (i >= 0)
21568 enum draw_glyphs_face overlap_hl;
21570 if (check_mouse_face
21571 && mouse_beg_col < start && mouse_end_col > i)
21572 overlap_hl = DRAW_MOUSE_FACE;
21573 else
21574 overlap_hl = DRAW_NORMAL_TEXT;
21576 clip_head = head;
21577 BUILD_GLYPH_STRINGS (i, start, h, t,
21578 overlap_hl, dummy_x, last_x);
21579 for (s = h; s; s = s->next)
21580 s->background_filled_p = 1;
21581 compute_overhangs_and_x (t, head->x, 1);
21582 prepend_glyph_string_lists (&head, &tail, h, t);
21585 /* Append glyphs strings for glyphs following the last glyph
21586 string tail that are overwritten by tail. The background of
21587 these strings has to be drawn because tail's foreground draws
21588 over it. */
21589 i = right_overwritten (tail);
21590 if (i >= 0)
21592 enum draw_glyphs_face overlap_hl;
21594 if (check_mouse_face
21595 && mouse_beg_col < i && mouse_end_col > end)
21596 overlap_hl = DRAW_MOUSE_FACE;
21597 else
21598 overlap_hl = DRAW_NORMAL_TEXT;
21600 BUILD_GLYPH_STRINGS (end, i, h, t,
21601 overlap_hl, x, last_x);
21602 /* Because BUILD_GLYPH_STRINGS updates the first argument,
21603 we don't have `end = i;' here. */
21604 compute_overhangs_and_x (h, tail->x + tail->width, 0);
21605 append_glyph_string_lists (&head, &tail, h, t);
21606 clip_tail = tail;
21609 /* Append glyph strings for glyphs following the last glyph
21610 string tail that overwrite tail. The foreground of such
21611 glyphs has to be drawn because it writes into the background
21612 of tail. The background must not be drawn because it could
21613 paint over the foreground of following glyphs. */
21614 i = right_overwriting (tail);
21615 if (i >= 0)
21617 enum draw_glyphs_face overlap_hl;
21618 if (check_mouse_face
21619 && mouse_beg_col < i && mouse_end_col > end)
21620 overlap_hl = DRAW_MOUSE_FACE;
21621 else
21622 overlap_hl = DRAW_NORMAL_TEXT;
21624 clip_tail = tail;
21625 i++; /* We must include the Ith glyph. */
21626 BUILD_GLYPH_STRINGS (end, i, h, t,
21627 overlap_hl, x, last_x);
21628 for (s = h; s; s = s->next)
21629 s->background_filled_p = 1;
21630 compute_overhangs_and_x (h, tail->x + tail->width, 0);
21631 append_glyph_string_lists (&head, &tail, h, t);
21633 if (clip_head || clip_tail)
21634 for (s = head; s; s = s->next)
21636 s->clip_head = clip_head;
21637 s->clip_tail = clip_tail;
21641 /* Draw all strings. */
21642 for (s = head; s; s = s->next)
21643 FRAME_RIF (f)->draw_glyph_string (s);
21645 #ifndef HAVE_NS
21646 /* When focus a sole frame and move horizontally, this sets on_p to 0
21647 causing a failure to erase prev cursor position. */
21648 if (area == TEXT_AREA
21649 && !row->full_width_p
21650 /* When drawing overlapping rows, only the glyph strings'
21651 foreground is drawn, which doesn't erase a cursor
21652 completely. */
21653 && !overlaps)
21655 int x0 = clip_head ? clip_head->x : (head ? head->x : x);
21656 int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width
21657 : (tail ? tail->x + tail->background_width : x));
21658 x0 -= area_left;
21659 x1 -= area_left;
21661 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
21662 row->y, MATRIX_ROW_BOTTOM_Y (row));
21664 #endif
21666 /* Value is the x-position up to which drawn, relative to AREA of W.
21667 This doesn't include parts drawn because of overhangs. */
21668 if (row->full_width_p)
21669 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
21670 else
21671 x_reached -= area_left;
21673 RELEASE_HDC (hdc, f);
21675 return x_reached;
21678 /* Expand row matrix if too narrow. Don't expand if area
21679 is not present. */
21681 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
21683 if (!fonts_changed_p \
21684 && (it->glyph_row->glyphs[area] \
21685 < it->glyph_row->glyphs[area + 1])) \
21687 it->w->ncols_scale_factor++; \
21688 fonts_changed_p = 1; \
21692 /* Store one glyph for IT->char_to_display in IT->glyph_row.
21693 Called from x_produce_glyphs when IT->glyph_row is non-null. */
21695 static INLINE void
21696 append_glyph (struct it *it)
21698 struct glyph *glyph;
21699 enum glyph_row_area area = it->area;
21701 xassert (it->glyph_row);
21702 xassert (it->char_to_display != '\n' && it->char_to_display != '\t');
21704 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
21705 if (glyph < it->glyph_row->glyphs[area + 1])
21707 /* If the glyph row is reversed, we need to prepend the glyph
21708 rather than append it. */
21709 if (it->glyph_row->reversed_p && area == TEXT_AREA)
21711 struct glyph *g;
21713 /* Make room for the additional glyph. */
21714 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
21715 g[1] = *g;
21716 glyph = it->glyph_row->glyphs[area];
21718 glyph->charpos = CHARPOS (it->position);
21719 glyph->object = it->object;
21720 if (it->pixel_width > 0)
21722 glyph->pixel_width = it->pixel_width;
21723 glyph->padding_p = 0;
21725 else
21727 /* Assure at least 1-pixel width. Otherwise, cursor can't
21728 be displayed correctly. */
21729 glyph->pixel_width = 1;
21730 glyph->padding_p = 1;
21732 glyph->ascent = it->ascent;
21733 glyph->descent = it->descent;
21734 glyph->voffset = it->voffset;
21735 glyph->type = CHAR_GLYPH;
21736 glyph->avoid_cursor_p = it->avoid_cursor_p;
21737 glyph->multibyte_p = it->multibyte_p;
21738 glyph->left_box_line_p = it->start_of_box_run_p;
21739 glyph->right_box_line_p = it->end_of_box_run_p;
21740 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
21741 || it->phys_descent > it->descent);
21742 glyph->glyph_not_available_p = it->glyph_not_available_p;
21743 glyph->face_id = it->face_id;
21744 glyph->u.ch = it->char_to_display;
21745 glyph->slice.img = null_glyph_slice;
21746 glyph->font_type = FONT_TYPE_UNKNOWN;
21747 if (it->bidi_p)
21749 glyph->resolved_level = it->bidi_it.resolved_level;
21750 if ((it->bidi_it.type & 7) != it->bidi_it.type)
21751 abort ();
21752 glyph->bidi_type = it->bidi_it.type;
21754 else
21756 glyph->resolved_level = 0;
21757 glyph->bidi_type = UNKNOWN_BT;
21759 ++it->glyph_row->used[area];
21761 else
21762 IT_EXPAND_MATRIX_WIDTH (it, area);
21765 /* Store one glyph for the composition IT->cmp_it.id in
21766 IT->glyph_row. Called from x_produce_glyphs when IT->glyph_row is
21767 non-null. */
21769 static INLINE void
21770 append_composite_glyph (struct it *it)
21772 struct glyph *glyph;
21773 enum glyph_row_area area = it->area;
21775 xassert (it->glyph_row);
21777 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
21778 if (glyph < it->glyph_row->glyphs[area + 1])
21780 /* If the glyph row is reversed, we need to prepend the glyph
21781 rather than append it. */
21782 if (it->glyph_row->reversed_p && it->area == TEXT_AREA)
21784 struct glyph *g;
21786 /* Make room for the new glyph. */
21787 for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
21788 g[1] = *g;
21789 glyph = it->glyph_row->glyphs[it->area];
21791 glyph->charpos = it->cmp_it.charpos;
21792 glyph->object = it->object;
21793 glyph->pixel_width = it->pixel_width;
21794 glyph->ascent = it->ascent;
21795 glyph->descent = it->descent;
21796 glyph->voffset = it->voffset;
21797 glyph->type = COMPOSITE_GLYPH;
21798 if (it->cmp_it.ch < 0)
21800 glyph->u.cmp.automatic = 0;
21801 glyph->u.cmp.id = it->cmp_it.id;
21802 glyph->slice.cmp.from = glyph->slice.cmp.to = 0;
21804 else
21806 glyph->u.cmp.automatic = 1;
21807 glyph->u.cmp.id = it->cmp_it.id;
21808 glyph->slice.cmp.from = it->cmp_it.from;
21809 glyph->slice.cmp.to = it->cmp_it.to - 1;
21811 glyph->avoid_cursor_p = it->avoid_cursor_p;
21812 glyph->multibyte_p = it->multibyte_p;
21813 glyph->left_box_line_p = it->start_of_box_run_p;
21814 glyph->right_box_line_p = it->end_of_box_run_p;
21815 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
21816 || it->phys_descent > it->descent);
21817 glyph->padding_p = 0;
21818 glyph->glyph_not_available_p = 0;
21819 glyph->face_id = it->face_id;
21820 glyph->font_type = FONT_TYPE_UNKNOWN;
21821 if (it->bidi_p)
21823 glyph->resolved_level = it->bidi_it.resolved_level;
21824 if ((it->bidi_it.type & 7) != it->bidi_it.type)
21825 abort ();
21826 glyph->bidi_type = it->bidi_it.type;
21828 ++it->glyph_row->used[area];
21830 else
21831 IT_EXPAND_MATRIX_WIDTH (it, area);
21835 /* Change IT->ascent and IT->height according to the setting of
21836 IT->voffset. */
21838 static INLINE void
21839 take_vertical_position_into_account (struct it *it)
21841 if (it->voffset)
21843 if (it->voffset < 0)
21844 /* Increase the ascent so that we can display the text higher
21845 in the line. */
21846 it->ascent -= it->voffset;
21847 else
21848 /* Increase the descent so that we can display the text lower
21849 in the line. */
21850 it->descent += it->voffset;
21855 /* Produce glyphs/get display metrics for the image IT is loaded with.
21856 See the description of struct display_iterator in dispextern.h for
21857 an overview of struct display_iterator. */
21859 static void
21860 produce_image_glyph (struct it *it)
21862 struct image *img;
21863 struct face *face;
21864 int glyph_ascent, crop;
21865 struct glyph_slice slice;
21867 xassert (it->what == IT_IMAGE);
21869 face = FACE_FROM_ID (it->f, it->face_id);
21870 xassert (face);
21871 /* Make sure X resources of the face is loaded. */
21872 PREPARE_FACE_FOR_DISPLAY (it->f, face);
21874 if (it->image_id < 0)
21876 /* Fringe bitmap. */
21877 it->ascent = it->phys_ascent = 0;
21878 it->descent = it->phys_descent = 0;
21879 it->pixel_width = 0;
21880 it->nglyphs = 0;
21881 return;
21884 img = IMAGE_FROM_ID (it->f, it->image_id);
21885 xassert (img);
21886 /* Make sure X resources of the image is loaded. */
21887 prepare_image_for_display (it->f, img);
21889 slice.x = slice.y = 0;
21890 slice.width = img->width;
21891 slice.height = img->height;
21893 if (INTEGERP (it->slice.x))
21894 slice.x = XINT (it->slice.x);
21895 else if (FLOATP (it->slice.x))
21896 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
21898 if (INTEGERP (it->slice.y))
21899 slice.y = XINT (it->slice.y);
21900 else if (FLOATP (it->slice.y))
21901 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
21903 if (INTEGERP (it->slice.width))
21904 slice.width = XINT (it->slice.width);
21905 else if (FLOATP (it->slice.width))
21906 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
21908 if (INTEGERP (it->slice.height))
21909 slice.height = XINT (it->slice.height);
21910 else if (FLOATP (it->slice.height))
21911 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
21913 if (slice.x >= img->width)
21914 slice.x = img->width;
21915 if (slice.y >= img->height)
21916 slice.y = img->height;
21917 if (slice.x + slice.width >= img->width)
21918 slice.width = img->width - slice.x;
21919 if (slice.y + slice.height > img->height)
21920 slice.height = img->height - slice.y;
21922 if (slice.width == 0 || slice.height == 0)
21923 return;
21925 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
21927 it->descent = slice.height - glyph_ascent;
21928 if (slice.y == 0)
21929 it->descent += img->vmargin;
21930 if (slice.y + slice.height == img->height)
21931 it->descent += img->vmargin;
21932 it->phys_descent = it->descent;
21934 it->pixel_width = slice.width;
21935 if (slice.x == 0)
21936 it->pixel_width += img->hmargin;
21937 if (slice.x + slice.width == img->width)
21938 it->pixel_width += img->hmargin;
21940 /* It's quite possible for images to have an ascent greater than
21941 their height, so don't get confused in that case. */
21942 if (it->descent < 0)
21943 it->descent = 0;
21945 it->nglyphs = 1;
21947 if (face->box != FACE_NO_BOX)
21949 if (face->box_line_width > 0)
21951 if (slice.y == 0)
21952 it->ascent += face->box_line_width;
21953 if (slice.y + slice.height == img->height)
21954 it->descent += face->box_line_width;
21957 if (it->start_of_box_run_p && slice.x == 0)
21958 it->pixel_width += eabs (face->box_line_width);
21959 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
21960 it->pixel_width += eabs (face->box_line_width);
21963 take_vertical_position_into_account (it);
21965 /* Automatically crop wide image glyphs at right edge so we can
21966 draw the cursor on same display row. */
21967 if ((crop = it->pixel_width - (it->last_visible_x - it->current_x), crop > 0)
21968 && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
21970 it->pixel_width -= crop;
21971 slice.width -= crop;
21974 if (it->glyph_row)
21976 struct glyph *glyph;
21977 enum glyph_row_area area = it->area;
21979 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
21980 if (glyph < it->glyph_row->glyphs[area + 1])
21982 glyph->charpos = CHARPOS (it->position);
21983 glyph->object = it->object;
21984 glyph->pixel_width = it->pixel_width;
21985 glyph->ascent = glyph_ascent;
21986 glyph->descent = it->descent;
21987 glyph->voffset = it->voffset;
21988 glyph->type = IMAGE_GLYPH;
21989 glyph->avoid_cursor_p = it->avoid_cursor_p;
21990 glyph->multibyte_p = it->multibyte_p;
21991 glyph->left_box_line_p = it->start_of_box_run_p;
21992 glyph->right_box_line_p = it->end_of_box_run_p;
21993 glyph->overlaps_vertically_p = 0;
21994 glyph->padding_p = 0;
21995 glyph->glyph_not_available_p = 0;
21996 glyph->face_id = it->face_id;
21997 glyph->u.img_id = img->id;
21998 glyph->slice.img = slice;
21999 glyph->font_type = FONT_TYPE_UNKNOWN;
22000 if (it->bidi_p)
22002 glyph->resolved_level = it->bidi_it.resolved_level;
22003 if ((it->bidi_it.type & 7) != it->bidi_it.type)
22004 abort ();
22005 glyph->bidi_type = it->bidi_it.type;
22007 ++it->glyph_row->used[area];
22009 else
22010 IT_EXPAND_MATRIX_WIDTH (it, area);
22015 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
22016 of the glyph, WIDTH and HEIGHT are the width and height of the
22017 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
22019 static void
22020 append_stretch_glyph (struct it *it, Lisp_Object object,
22021 int width, int height, int ascent)
22023 struct glyph *glyph;
22024 enum glyph_row_area area = it->area;
22026 xassert (ascent >= 0 && ascent <= height);
22028 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
22029 if (glyph < it->glyph_row->glyphs[area + 1])
22031 /* If the glyph row is reversed, we need to prepend the glyph
22032 rather than append it. */
22033 if (it->glyph_row->reversed_p && area == TEXT_AREA)
22035 struct glyph *g;
22037 /* Make room for the additional glyph. */
22038 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
22039 g[1] = *g;
22040 glyph = it->glyph_row->glyphs[area];
22042 glyph->charpos = CHARPOS (it->position);
22043 glyph->object = object;
22044 glyph->pixel_width = width;
22045 glyph->ascent = ascent;
22046 glyph->descent = height - ascent;
22047 glyph->voffset = it->voffset;
22048 glyph->type = STRETCH_GLYPH;
22049 glyph->avoid_cursor_p = it->avoid_cursor_p;
22050 glyph->multibyte_p = it->multibyte_p;
22051 glyph->left_box_line_p = it->start_of_box_run_p;
22052 glyph->right_box_line_p = it->end_of_box_run_p;
22053 glyph->overlaps_vertically_p = 0;
22054 glyph->padding_p = 0;
22055 glyph->glyph_not_available_p = 0;
22056 glyph->face_id = it->face_id;
22057 glyph->u.stretch.ascent = ascent;
22058 glyph->u.stretch.height = height;
22059 glyph->slice.img = null_glyph_slice;
22060 glyph->font_type = FONT_TYPE_UNKNOWN;
22061 if (it->bidi_p)
22063 glyph->resolved_level = it->bidi_it.resolved_level;
22064 if ((it->bidi_it.type & 7) != it->bidi_it.type)
22065 abort ();
22066 glyph->bidi_type = it->bidi_it.type;
22068 else
22070 glyph->resolved_level = 0;
22071 glyph->bidi_type = UNKNOWN_BT;
22073 ++it->glyph_row->used[area];
22075 else
22076 IT_EXPAND_MATRIX_WIDTH (it, area);
22080 /* Produce a stretch glyph for iterator IT. IT->object is the value
22081 of the glyph property displayed. The value must be a list
22082 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
22083 being recognized:
22085 1. `:width WIDTH' specifies that the space should be WIDTH *
22086 canonical char width wide. WIDTH may be an integer or floating
22087 point number.
22089 2. `:relative-width FACTOR' specifies that the width of the stretch
22090 should be computed from the width of the first character having the
22091 `glyph' property, and should be FACTOR times that width.
22093 3. `:align-to HPOS' specifies that the space should be wide enough
22094 to reach HPOS, a value in canonical character units.
22096 Exactly one of the above pairs must be present.
22098 4. `:height HEIGHT' specifies that the height of the stretch produced
22099 should be HEIGHT, measured in canonical character units.
22101 5. `:relative-height FACTOR' specifies that the height of the
22102 stretch should be FACTOR times the height of the characters having
22103 the glyph property.
22105 Either none or exactly one of 4 or 5 must be present.
22107 6. `:ascent ASCENT' specifies that ASCENT percent of the height
22108 of the stretch should be used for the ascent of the stretch.
22109 ASCENT must be in the range 0 <= ASCENT <= 100. */
22111 static void
22112 produce_stretch_glyph (struct it *it)
22114 /* (space :width WIDTH :height HEIGHT ...) */
22115 Lisp_Object prop, plist;
22116 int width = 0, height = 0, align_to = -1;
22117 int zero_width_ok_p = 0, zero_height_ok_p = 0;
22118 int ascent = 0;
22119 double tem;
22120 struct face *face = FACE_FROM_ID (it->f, it->face_id);
22121 struct font *font = face->font ? face->font : FRAME_FONT (it->f);
22123 PREPARE_FACE_FOR_DISPLAY (it->f, face);
22125 /* List should start with `space'. */
22126 xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
22127 plist = XCDR (it->object);
22129 /* Compute the width of the stretch. */
22130 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
22131 && calc_pixel_width_or_height (&tem, it, prop, font, 1, 0))
22133 /* Absolute width `:width WIDTH' specified and valid. */
22134 zero_width_ok_p = 1;
22135 width = (int)tem;
22137 else if (prop = Fplist_get (plist, QCrelative_width),
22138 NUMVAL (prop) > 0)
22140 /* Relative width `:relative-width FACTOR' specified and valid.
22141 Compute the width of the characters having the `glyph'
22142 property. */
22143 struct it it2;
22144 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
22146 it2 = *it;
22147 if (it->multibyte_p)
22148 it2.c = it2.char_to_display = STRING_CHAR_AND_LENGTH (p, it2.len);
22149 else
22151 it2.c = it2.char_to_display = *p, it2.len = 1;
22152 if (! ASCII_CHAR_P (it2.c))
22153 it2.char_to_display = BYTE8_TO_CHAR (it2.c);
22156 it2.glyph_row = NULL;
22157 it2.what = IT_CHARACTER;
22158 x_produce_glyphs (&it2);
22159 width = NUMVAL (prop) * it2.pixel_width;
22161 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
22162 && calc_pixel_width_or_height (&tem, it, prop, font, 1, &align_to))
22164 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
22165 align_to = (align_to < 0
22167 : align_to - window_box_left_offset (it->w, TEXT_AREA));
22168 else if (align_to < 0)
22169 align_to = window_box_left_offset (it->w, TEXT_AREA);
22170 width = max (0, (int)tem + align_to - it->current_x);
22171 zero_width_ok_p = 1;
22173 else
22174 /* Nothing specified -> width defaults to canonical char width. */
22175 width = FRAME_COLUMN_WIDTH (it->f);
22177 if (width <= 0 && (width < 0 || !zero_width_ok_p))
22178 width = 1;
22180 /* Compute height. */
22181 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
22182 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
22184 height = (int)tem;
22185 zero_height_ok_p = 1;
22187 else if (prop = Fplist_get (plist, QCrelative_height),
22188 NUMVAL (prop) > 0)
22189 height = FONT_HEIGHT (font) * NUMVAL (prop);
22190 else
22191 height = FONT_HEIGHT (font);
22193 if (height <= 0 && (height < 0 || !zero_height_ok_p))
22194 height = 1;
22196 /* Compute percentage of height used for ascent. If
22197 `:ascent ASCENT' is present and valid, use that. Otherwise,
22198 derive the ascent from the font in use. */
22199 if (prop = Fplist_get (plist, QCascent),
22200 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
22201 ascent = height * NUMVAL (prop) / 100.0;
22202 else if (!NILP (prop)
22203 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
22204 ascent = min (max (0, (int)tem), height);
22205 else
22206 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
22208 if (width > 0 && it->line_wrap != TRUNCATE
22209 && it->current_x + width > it->last_visible_x)
22210 width = it->last_visible_x - it->current_x - 1;
22212 if (width > 0 && height > 0 && it->glyph_row)
22214 Lisp_Object object = it->stack[it->sp - 1].string;
22215 if (!STRINGP (object))
22216 object = it->w->buffer;
22217 append_stretch_glyph (it, object, width, height, ascent);
22220 it->pixel_width = width;
22221 it->ascent = it->phys_ascent = ascent;
22222 it->descent = it->phys_descent = height - it->ascent;
22223 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
22225 take_vertical_position_into_account (it);
22228 /* Calculate line-height and line-spacing properties.
22229 An integer value specifies explicit pixel value.
22230 A float value specifies relative value to current face height.
22231 A cons (float . face-name) specifies relative value to
22232 height of specified face font.
22234 Returns height in pixels, or nil. */
22237 static Lisp_Object
22238 calc_line_height_property (struct it *it, Lisp_Object val, struct font *font,
22239 int boff, int override)
22241 Lisp_Object face_name = Qnil;
22242 int ascent, descent, height;
22244 if (NILP (val) || INTEGERP (val) || (override && EQ (val, Qt)))
22245 return val;
22247 if (CONSP (val))
22249 face_name = XCAR (val);
22250 val = XCDR (val);
22251 if (!NUMBERP (val))
22252 val = make_number (1);
22253 if (NILP (face_name))
22255 height = it->ascent + it->descent;
22256 goto scale;
22260 if (NILP (face_name))
22262 font = FRAME_FONT (it->f);
22263 boff = FRAME_BASELINE_OFFSET (it->f);
22265 else if (EQ (face_name, Qt))
22267 override = 0;
22269 else
22271 int face_id;
22272 struct face *face;
22274 face_id = lookup_named_face (it->f, face_name, 0);
22275 if (face_id < 0)
22276 return make_number (-1);
22278 face = FACE_FROM_ID (it->f, face_id);
22279 font = face->font;
22280 if (font == NULL)
22281 return make_number (-1);
22282 boff = font->baseline_offset;
22283 if (font->vertical_centering)
22284 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
22287 ascent = FONT_BASE (font) + boff;
22288 descent = FONT_DESCENT (font) - boff;
22290 if (override)
22292 it->override_ascent = ascent;
22293 it->override_descent = descent;
22294 it->override_boff = boff;
22297 height = ascent + descent;
22299 scale:
22300 if (FLOATP (val))
22301 height = (int)(XFLOAT_DATA (val) * height);
22302 else if (INTEGERP (val))
22303 height *= XINT (val);
22305 return make_number (height);
22309 /* Append a glyph for a glyphless character to IT->glyph_row. FACE_ID
22310 is a face ID to be used for the glyph. FOR_NO_FONT is nonzero if
22311 and only if this is for a character for which no font was found.
22313 If the display method (it->glyphless_method) is
22314 GLYPHLESS_DISPLAY_ACRONYM or GLYPHLESS_DISPLAY_HEX_CODE, LEN is a
22315 length of the acronym or the hexadecimal string, UPPER_XOFF and
22316 UPPER_YOFF are pixel offsets for the upper part of the string,
22317 LOWER_XOFF and LOWER_YOFF are for the lower part.
22319 For the other display methods, LEN through LOWER_YOFF are zero. */
22321 static void
22322 append_glyphless_glyph (struct it *it, int face_id, int for_no_font, int len,
22323 short upper_xoff, short upper_yoff,
22324 short lower_xoff, short lower_yoff)
22326 struct glyph *glyph;
22327 enum glyph_row_area area = it->area;
22329 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
22330 if (glyph < it->glyph_row->glyphs[area + 1])
22332 /* If the glyph row is reversed, we need to prepend the glyph
22333 rather than append it. */
22334 if (it->glyph_row->reversed_p && area == TEXT_AREA)
22336 struct glyph *g;
22338 /* Make room for the additional glyph. */
22339 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
22340 g[1] = *g;
22341 glyph = it->glyph_row->glyphs[area];
22343 glyph->charpos = CHARPOS (it->position);
22344 glyph->object = it->object;
22345 glyph->pixel_width = it->pixel_width;
22346 glyph->ascent = it->ascent;
22347 glyph->descent = it->descent;
22348 glyph->voffset = it->voffset;
22349 glyph->type = GLYPHLESS_GLYPH;
22350 glyph->u.glyphless.method = it->glyphless_method;
22351 glyph->u.glyphless.for_no_font = for_no_font;
22352 glyph->u.glyphless.len = len;
22353 glyph->u.glyphless.ch = it->c;
22354 glyph->slice.glyphless.upper_xoff = upper_xoff;
22355 glyph->slice.glyphless.upper_yoff = upper_yoff;
22356 glyph->slice.glyphless.lower_xoff = lower_xoff;
22357 glyph->slice.glyphless.lower_yoff = lower_yoff;
22358 glyph->avoid_cursor_p = it->avoid_cursor_p;
22359 glyph->multibyte_p = it->multibyte_p;
22360 glyph->left_box_line_p = it->start_of_box_run_p;
22361 glyph->right_box_line_p = it->end_of_box_run_p;
22362 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
22363 || it->phys_descent > it->descent);
22364 glyph->padding_p = 0;
22365 glyph->glyph_not_available_p = 0;
22366 glyph->face_id = face_id;
22367 glyph->font_type = FONT_TYPE_UNKNOWN;
22368 if (it->bidi_p)
22370 glyph->resolved_level = it->bidi_it.resolved_level;
22371 if ((it->bidi_it.type & 7) != it->bidi_it.type)
22372 abort ();
22373 glyph->bidi_type = it->bidi_it.type;
22375 ++it->glyph_row->used[area];
22377 else
22378 IT_EXPAND_MATRIX_WIDTH (it, area);
22382 /* Produce a glyph for a glyphless character for iterator IT.
22383 IT->glyphless_method specifies which method to use for displaying
22384 the character. See the description of enum
22385 glyphless_display_method in dispextern.h for the detail.
22387 FOR_NO_FONT is nonzero if and only if this is for a character for
22388 which no font was found. ACRONYM, if non-nil, is an acronym string
22389 for the character. */
22391 static void
22392 produce_glyphless_glyph (struct it *it, int for_no_font, Lisp_Object acronym)
22394 int face_id;
22395 struct face *face;
22396 struct font *font;
22397 int base_width, base_height, width, height;
22398 short upper_xoff, upper_yoff, lower_xoff, lower_yoff;
22399 int len;
22401 /* Get the metrics of the base font. We always refer to the current
22402 ASCII face. */
22403 face = FACE_FROM_ID (it->f, it->face_id)->ascii_face;
22404 font = face->font ? face->font : FRAME_FONT (it->f);
22405 it->ascent = FONT_BASE (font) + font->baseline_offset;
22406 it->descent = FONT_DESCENT (font) - font->baseline_offset;
22407 base_height = it->ascent + it->descent;
22408 base_width = font->average_width;
22410 /* Get a face ID for the glyph by utilizing a cache (the same way as
22411 doen for `escape-glyph' in get_next_display_element). */
22412 if (it->f == last_glyphless_glyph_frame
22413 && it->face_id == last_glyphless_glyph_face_id)
22415 face_id = last_glyphless_glyph_merged_face_id;
22417 else
22419 /* Merge the `glyphless-char' face into the current face. */
22420 face_id = merge_faces (it->f, Qglyphless_char, 0, it->face_id);
22421 last_glyphless_glyph_frame = it->f;
22422 last_glyphless_glyph_face_id = it->face_id;
22423 last_glyphless_glyph_merged_face_id = face_id;
22426 if (it->glyphless_method == GLYPHLESS_DISPLAY_THIN_SPACE)
22428 it->pixel_width = THIN_SPACE_WIDTH;
22429 len = 0;
22430 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
22432 else if (it->glyphless_method == GLYPHLESS_DISPLAY_EMPTY_BOX)
22434 width = CHAR_WIDTH (it->c);
22435 if (width == 0)
22436 width = 1;
22437 else if (width > 4)
22438 width = 4;
22439 it->pixel_width = base_width * width;
22440 len = 0;
22441 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
22443 else
22445 char buf[7], *str;
22446 unsigned int code[6];
22447 int upper_len;
22448 int ascent, descent;
22449 struct font_metrics metrics_upper, metrics_lower;
22451 face = FACE_FROM_ID (it->f, face_id);
22452 font = face->font ? face->font : FRAME_FONT (it->f);
22453 PREPARE_FACE_FOR_DISPLAY (it->f, face);
22455 if (it->glyphless_method == GLYPHLESS_DISPLAY_ACRONYM)
22457 if (! STRINGP (acronym) && CHAR_TABLE_P (Vglyphless_char_display))
22458 acronym = CHAR_TABLE_REF (Vglyphless_char_display, it->c);
22459 str = STRINGP (acronym) ? (char *) SDATA (acronym) : "";
22461 else
22463 xassert (it->glyphless_method == GLYPHLESS_DISPLAY_HEX_CODE);
22464 sprintf (buf, "%0*X", it->c < 0x10000 ? 4 : 6, it->c);
22465 str = buf;
22467 for (len = 0; str[len] && ASCII_BYTE_P (str[len]); len++)
22468 code[len] = font->driver->encode_char (font, str[len]);
22469 upper_len = (len + 1) / 2;
22470 font->driver->text_extents (font, code, upper_len,
22471 &metrics_upper);
22472 font->driver->text_extents (font, code + upper_len, len - upper_len,
22473 &metrics_lower);
22477 /* +4 is for vertical bars of a box plus 1-pixel spaces at both side. */
22478 width = max (metrics_upper.width, metrics_lower.width) + 4;
22479 upper_xoff = upper_yoff = 2; /* the typical case */
22480 if (base_width >= width)
22482 /* Align the upper to the left, the lower to the right. */
22483 it->pixel_width = base_width;
22484 lower_xoff = base_width - 2 - metrics_lower.width;
22486 else
22488 /* Center the shorter one. */
22489 it->pixel_width = width;
22490 if (metrics_upper.width >= metrics_lower.width)
22491 lower_xoff = (width - metrics_lower.width) / 2;
22492 else
22493 upper_xoff = (width - metrics_upper.width) / 2;
22496 /* +5 is for horizontal bars of a box plus 1-pixel spaces at
22497 top, bottom, and between upper and lower strings. */
22498 height = (metrics_upper.ascent + metrics_upper.descent
22499 + metrics_lower.ascent + metrics_lower.descent) + 5;
22500 /* Center vertically.
22501 H:base_height, D:base_descent
22502 h:height, ld:lower_descent, la:lower_ascent, ud:upper_descent
22504 ascent = - (D - H/2 - h/2 + 1); "+ 1" for rounding up
22505 descent = D - H/2 + h/2;
22506 lower_yoff = descent - 2 - ld;
22507 upper_yoff = lower_yoff - la - 1 - ud; */
22508 ascent = - (it->descent - (base_height + height + 1) / 2);
22509 descent = it->descent - (base_height - height) / 2;
22510 lower_yoff = descent - 2 - metrics_lower.descent;
22511 upper_yoff = (lower_yoff - metrics_lower.ascent - 1
22512 - metrics_upper.descent);
22513 /* Don't make the height shorter than the base height. */
22514 if (height > base_height)
22516 it->ascent = ascent;
22517 it->descent = descent;
22521 it->phys_ascent = it->ascent;
22522 it->phys_descent = it->descent;
22523 if (it->glyph_row)
22524 append_glyphless_glyph (it, face_id, for_no_font, len,
22525 upper_xoff, upper_yoff,
22526 lower_xoff, lower_yoff);
22527 it->nglyphs = 1;
22528 take_vertical_position_into_account (it);
22532 /* RIF:
22533 Produce glyphs/get display metrics for the display element IT is
22534 loaded with. See the description of struct it in dispextern.h
22535 for an overview of struct it. */
22537 void
22538 x_produce_glyphs (struct it *it)
22540 int extra_line_spacing = it->extra_line_spacing;
22542 it->glyph_not_available_p = 0;
22544 if (it->what == IT_CHARACTER)
22546 XChar2b char2b;
22547 struct face *face = FACE_FROM_ID (it->f, it->face_id);
22548 struct font *font = face->font;
22549 struct font_metrics *pcm = NULL;
22550 int boff; /* baseline offset */
22552 if (font == NULL)
22554 /* When no suitable font is found, display this character by
22555 the method specified in the first extra slot of
22556 Vglyphless_char_display. */
22557 Lisp_Object acronym = lookup_glyphless_char_display (-1, it);
22559 xassert (it->what == IT_GLYPHLESS);
22560 produce_glyphless_glyph (it, 1, STRINGP (acronym) ? acronym : Qnil);
22561 goto done;
22564 boff = font->baseline_offset;
22565 if (font->vertical_centering)
22566 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
22568 if (it->char_to_display != '\n' && it->char_to_display != '\t')
22570 int stretched_p;
22572 it->nglyphs = 1;
22574 if (it->override_ascent >= 0)
22576 it->ascent = it->override_ascent;
22577 it->descent = it->override_descent;
22578 boff = it->override_boff;
22580 else
22582 it->ascent = FONT_BASE (font) + boff;
22583 it->descent = FONT_DESCENT (font) - boff;
22586 if (get_char_glyph_code (it->char_to_display, font, &char2b))
22588 pcm = get_per_char_metric (it->f, font, &char2b);
22589 if (pcm->width == 0
22590 && pcm->rbearing == 0 && pcm->lbearing == 0)
22591 pcm = NULL;
22594 if (pcm)
22596 it->phys_ascent = pcm->ascent + boff;
22597 it->phys_descent = pcm->descent - boff;
22598 it->pixel_width = pcm->width;
22600 else
22602 it->glyph_not_available_p = 1;
22603 it->phys_ascent = it->ascent;
22604 it->phys_descent = it->descent;
22605 it->pixel_width = font->space_width;
22608 if (it->constrain_row_ascent_descent_p)
22610 if (it->descent > it->max_descent)
22612 it->ascent += it->descent - it->max_descent;
22613 it->descent = it->max_descent;
22615 if (it->ascent > it->max_ascent)
22617 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
22618 it->ascent = it->max_ascent;
22620 it->phys_ascent = min (it->phys_ascent, it->ascent);
22621 it->phys_descent = min (it->phys_descent, it->descent);
22622 extra_line_spacing = 0;
22625 /* If this is a space inside a region of text with
22626 `space-width' property, change its width. */
22627 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
22628 if (stretched_p)
22629 it->pixel_width *= XFLOATINT (it->space_width);
22631 /* If face has a box, add the box thickness to the character
22632 height. If character has a box line to the left and/or
22633 right, add the box line width to the character's width. */
22634 if (face->box != FACE_NO_BOX)
22636 int thick = face->box_line_width;
22638 if (thick > 0)
22640 it->ascent += thick;
22641 it->descent += thick;
22643 else
22644 thick = -thick;
22646 if (it->start_of_box_run_p)
22647 it->pixel_width += thick;
22648 if (it->end_of_box_run_p)
22649 it->pixel_width += thick;
22652 /* If face has an overline, add the height of the overline
22653 (1 pixel) and a 1 pixel margin to the character height. */
22654 if (face->overline_p)
22655 it->ascent += overline_margin;
22657 if (it->constrain_row_ascent_descent_p)
22659 if (it->ascent > it->max_ascent)
22660 it->ascent = it->max_ascent;
22661 if (it->descent > it->max_descent)
22662 it->descent = it->max_descent;
22665 take_vertical_position_into_account (it);
22667 /* If we have to actually produce glyphs, do it. */
22668 if (it->glyph_row)
22670 if (stretched_p)
22672 /* Translate a space with a `space-width' property
22673 into a stretch glyph. */
22674 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
22675 / FONT_HEIGHT (font));
22676 append_stretch_glyph (it, it->object, it->pixel_width,
22677 it->ascent + it->descent, ascent);
22679 else
22680 append_glyph (it);
22682 /* If characters with lbearing or rbearing are displayed
22683 in this line, record that fact in a flag of the
22684 glyph row. This is used to optimize X output code. */
22685 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
22686 it->glyph_row->contains_overlapping_glyphs_p = 1;
22688 if (! stretched_p && it->pixel_width == 0)
22689 /* We assure that all visible glyphs have at least 1-pixel
22690 width. */
22691 it->pixel_width = 1;
22693 else if (it->char_to_display == '\n')
22695 /* A newline has no width, but we need the height of the
22696 line. But if previous part of the line sets a height,
22697 don't increase that height */
22699 Lisp_Object height;
22700 Lisp_Object total_height = Qnil;
22702 it->override_ascent = -1;
22703 it->pixel_width = 0;
22704 it->nglyphs = 0;
22706 height = get_it_property (it, Qline_height);
22707 /* Split (line-height total-height) list */
22708 if (CONSP (height)
22709 && CONSP (XCDR (height))
22710 && NILP (XCDR (XCDR (height))))
22712 total_height = XCAR (XCDR (height));
22713 height = XCAR (height);
22715 height = calc_line_height_property (it, height, font, boff, 1);
22717 if (it->override_ascent >= 0)
22719 it->ascent = it->override_ascent;
22720 it->descent = it->override_descent;
22721 boff = it->override_boff;
22723 else
22725 it->ascent = FONT_BASE (font) + boff;
22726 it->descent = FONT_DESCENT (font) - boff;
22729 if (EQ (height, Qt))
22731 if (it->descent > it->max_descent)
22733 it->ascent += it->descent - it->max_descent;
22734 it->descent = it->max_descent;
22736 if (it->ascent > it->max_ascent)
22738 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
22739 it->ascent = it->max_ascent;
22741 it->phys_ascent = min (it->phys_ascent, it->ascent);
22742 it->phys_descent = min (it->phys_descent, it->descent);
22743 it->constrain_row_ascent_descent_p = 1;
22744 extra_line_spacing = 0;
22746 else
22748 Lisp_Object spacing;
22750 it->phys_ascent = it->ascent;
22751 it->phys_descent = it->descent;
22753 if ((it->max_ascent > 0 || it->max_descent > 0)
22754 && face->box != FACE_NO_BOX
22755 && face->box_line_width > 0)
22757 it->ascent += face->box_line_width;
22758 it->descent += face->box_line_width;
22760 if (!NILP (height)
22761 && XINT (height) > it->ascent + it->descent)
22762 it->ascent = XINT (height) - it->descent;
22764 if (!NILP (total_height))
22765 spacing = calc_line_height_property (it, total_height, font, boff, 0);
22766 else
22768 spacing = get_it_property (it, Qline_spacing);
22769 spacing = calc_line_height_property (it, spacing, font, boff, 0);
22771 if (INTEGERP (spacing))
22773 extra_line_spacing = XINT (spacing);
22774 if (!NILP (total_height))
22775 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
22779 else /* i.e. (it->char_to_display == '\t') */
22781 if (font->space_width > 0)
22783 int tab_width = it->tab_width * font->space_width;
22784 int x = it->current_x + it->continuation_lines_width;
22785 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
22787 /* If the distance from the current position to the next tab
22788 stop is less than a space character width, use the
22789 tab stop after that. */
22790 if (next_tab_x - x < font->space_width)
22791 next_tab_x += tab_width;
22793 it->pixel_width = next_tab_x - x;
22794 it->nglyphs = 1;
22795 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
22796 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
22798 if (it->glyph_row)
22800 append_stretch_glyph (it, it->object, it->pixel_width,
22801 it->ascent + it->descent, it->ascent);
22804 else
22806 it->pixel_width = 0;
22807 it->nglyphs = 1;
22811 else if (it->what == IT_COMPOSITION && it->cmp_it.ch < 0)
22813 /* A static composition.
22815 Note: A composition is represented as one glyph in the
22816 glyph matrix. There are no padding glyphs.
22818 Important note: pixel_width, ascent, and descent are the
22819 values of what is drawn by draw_glyphs (i.e. the values of
22820 the overall glyphs composed). */
22821 struct face *face = FACE_FROM_ID (it->f, it->face_id);
22822 int boff; /* baseline offset */
22823 struct composition *cmp = composition_table[it->cmp_it.id];
22824 int glyph_len = cmp->glyph_len;
22825 struct font *font = face->font;
22827 it->nglyphs = 1;
22829 /* If we have not yet calculated pixel size data of glyphs of
22830 the composition for the current face font, calculate them
22831 now. Theoretically, we have to check all fonts for the
22832 glyphs, but that requires much time and memory space. So,
22833 here we check only the font of the first glyph. This may
22834 lead to incorrect display, but it's very rare, and C-l
22835 (recenter-top-bottom) can correct the display anyway. */
22836 if (! cmp->font || cmp->font != font)
22838 /* Ascent and descent of the font of the first character
22839 of this composition (adjusted by baseline offset).
22840 Ascent and descent of overall glyphs should not be less
22841 than these, respectively. */
22842 int font_ascent, font_descent, font_height;
22843 /* Bounding box of the overall glyphs. */
22844 int leftmost, rightmost, lowest, highest;
22845 int lbearing, rbearing;
22846 int i, width, ascent, descent;
22847 int left_padded = 0, right_padded = 0;
22848 int c;
22849 XChar2b char2b;
22850 struct font_metrics *pcm;
22851 int font_not_found_p;
22852 EMACS_INT pos;
22854 for (glyph_len = cmp->glyph_len; glyph_len > 0; glyph_len--)
22855 if ((c = COMPOSITION_GLYPH (cmp, glyph_len - 1)) != '\t')
22856 break;
22857 if (glyph_len < cmp->glyph_len)
22858 right_padded = 1;
22859 for (i = 0; i < glyph_len; i++)
22861 if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
22862 break;
22863 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
22865 if (i > 0)
22866 left_padded = 1;
22868 pos = (STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
22869 : IT_CHARPOS (*it));
22870 /* If no suitable font is found, use the default font. */
22871 font_not_found_p = font == NULL;
22872 if (font_not_found_p)
22874 face = face->ascii_face;
22875 font = face->font;
22877 boff = font->baseline_offset;
22878 if (font->vertical_centering)
22879 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
22880 font_ascent = FONT_BASE (font) + boff;
22881 font_descent = FONT_DESCENT (font) - boff;
22882 font_height = FONT_HEIGHT (font);
22884 cmp->font = (void *) font;
22886 pcm = NULL;
22887 if (! font_not_found_p)
22889 get_char_face_and_encoding (it->f, c, it->face_id,
22890 &char2b, it->multibyte_p, 0);
22891 pcm = get_per_char_metric (it->f, font, &char2b);
22894 /* Initialize the bounding box. */
22895 if (pcm)
22897 width = pcm->width;
22898 ascent = pcm->ascent;
22899 descent = pcm->descent;
22900 lbearing = pcm->lbearing;
22901 rbearing = pcm->rbearing;
22903 else
22905 width = font->space_width;
22906 ascent = FONT_BASE (font);
22907 descent = FONT_DESCENT (font);
22908 lbearing = 0;
22909 rbearing = width;
22912 rightmost = width;
22913 leftmost = 0;
22914 lowest = - descent + boff;
22915 highest = ascent + boff;
22917 if (! font_not_found_p
22918 && font->default_ascent
22919 && CHAR_TABLE_P (Vuse_default_ascent)
22920 && !NILP (Faref (Vuse_default_ascent,
22921 make_number (it->char_to_display))))
22922 highest = font->default_ascent + boff;
22924 /* Draw the first glyph at the normal position. It may be
22925 shifted to right later if some other glyphs are drawn
22926 at the left. */
22927 cmp->offsets[i * 2] = 0;
22928 cmp->offsets[i * 2 + 1] = boff;
22929 cmp->lbearing = lbearing;
22930 cmp->rbearing = rbearing;
22932 /* Set cmp->offsets for the remaining glyphs. */
22933 for (i++; i < glyph_len; i++)
22935 int left, right, btm, top;
22936 int ch = COMPOSITION_GLYPH (cmp, i);
22937 int face_id;
22938 struct face *this_face;
22939 int this_boff;
22941 if (ch == '\t')
22942 ch = ' ';
22943 face_id = FACE_FOR_CHAR (it->f, face, ch, pos, it->string);
22944 this_face = FACE_FROM_ID (it->f, face_id);
22945 font = this_face->font;
22947 if (font == NULL)
22948 pcm = NULL;
22949 else
22951 this_boff = font->baseline_offset;
22952 if (font->vertical_centering)
22953 this_boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
22954 get_char_face_and_encoding (it->f, ch, face_id,
22955 &char2b, it->multibyte_p, 0);
22956 pcm = get_per_char_metric (it->f, font, &char2b);
22958 if (! pcm)
22959 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
22960 else
22962 width = pcm->width;
22963 ascent = pcm->ascent;
22964 descent = pcm->descent;
22965 lbearing = pcm->lbearing;
22966 rbearing = pcm->rbearing;
22967 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
22969 /* Relative composition with or without
22970 alternate chars. */
22971 left = (leftmost + rightmost - width) / 2;
22972 btm = - descent + boff;
22973 if (font->relative_compose
22974 && (! CHAR_TABLE_P (Vignore_relative_composition)
22975 || NILP (Faref (Vignore_relative_composition,
22976 make_number (ch)))))
22979 if (- descent >= font->relative_compose)
22980 /* One extra pixel between two glyphs. */
22981 btm = highest + 1;
22982 else if (ascent <= 0)
22983 /* One extra pixel between two glyphs. */
22984 btm = lowest - 1 - ascent - descent;
22987 else
22989 /* A composition rule is specified by an integer
22990 value that encodes global and new reference
22991 points (GREF and NREF). GREF and NREF are
22992 specified by numbers as below:
22994 0---1---2 -- ascent
22998 9--10--11 -- center
23000 ---3---4---5--- baseline
23002 6---7---8 -- descent
23004 int rule = COMPOSITION_RULE (cmp, i);
23005 int gref, nref, grefx, grefy, nrefx, nrefy, xoff, yoff;
23007 COMPOSITION_DECODE_RULE (rule, gref, nref, xoff, yoff);
23008 grefx = gref % 3, nrefx = nref % 3;
23009 grefy = gref / 3, nrefy = nref / 3;
23010 if (xoff)
23011 xoff = font_height * (xoff - 128) / 256;
23012 if (yoff)
23013 yoff = font_height * (yoff - 128) / 256;
23015 left = (leftmost
23016 + grefx * (rightmost - leftmost) / 2
23017 - nrefx * width / 2
23018 + xoff);
23020 btm = ((grefy == 0 ? highest
23021 : grefy == 1 ? 0
23022 : grefy == 2 ? lowest
23023 : (highest + lowest) / 2)
23024 - (nrefy == 0 ? ascent + descent
23025 : nrefy == 1 ? descent - boff
23026 : nrefy == 2 ? 0
23027 : (ascent + descent) / 2)
23028 + yoff);
23031 cmp->offsets[i * 2] = left;
23032 cmp->offsets[i * 2 + 1] = btm + descent;
23034 /* Update the bounding box of the overall glyphs. */
23035 if (width > 0)
23037 right = left + width;
23038 if (left < leftmost)
23039 leftmost = left;
23040 if (right > rightmost)
23041 rightmost = right;
23043 top = btm + descent + ascent;
23044 if (top > highest)
23045 highest = top;
23046 if (btm < lowest)
23047 lowest = btm;
23049 if (cmp->lbearing > left + lbearing)
23050 cmp->lbearing = left + lbearing;
23051 if (cmp->rbearing < left + rbearing)
23052 cmp->rbearing = left + rbearing;
23056 /* If there are glyphs whose x-offsets are negative,
23057 shift all glyphs to the right and make all x-offsets
23058 non-negative. */
23059 if (leftmost < 0)
23061 for (i = 0; i < cmp->glyph_len; i++)
23062 cmp->offsets[i * 2] -= leftmost;
23063 rightmost -= leftmost;
23064 cmp->lbearing -= leftmost;
23065 cmp->rbearing -= leftmost;
23068 if (left_padded && cmp->lbearing < 0)
23070 for (i = 0; i < cmp->glyph_len; i++)
23071 cmp->offsets[i * 2] -= cmp->lbearing;
23072 rightmost -= cmp->lbearing;
23073 cmp->rbearing -= cmp->lbearing;
23074 cmp->lbearing = 0;
23076 if (right_padded && rightmost < cmp->rbearing)
23078 rightmost = cmp->rbearing;
23081 cmp->pixel_width = rightmost;
23082 cmp->ascent = highest;
23083 cmp->descent = - lowest;
23084 if (cmp->ascent < font_ascent)
23085 cmp->ascent = font_ascent;
23086 if (cmp->descent < font_descent)
23087 cmp->descent = font_descent;
23090 if (it->glyph_row
23091 && (cmp->lbearing < 0
23092 || cmp->rbearing > cmp->pixel_width))
23093 it->glyph_row->contains_overlapping_glyphs_p = 1;
23095 it->pixel_width = cmp->pixel_width;
23096 it->ascent = it->phys_ascent = cmp->ascent;
23097 it->descent = it->phys_descent = cmp->descent;
23098 if (face->box != FACE_NO_BOX)
23100 int thick = face->box_line_width;
23102 if (thick > 0)
23104 it->ascent += thick;
23105 it->descent += thick;
23107 else
23108 thick = - thick;
23110 if (it->start_of_box_run_p)
23111 it->pixel_width += thick;
23112 if (it->end_of_box_run_p)
23113 it->pixel_width += thick;
23116 /* If face has an overline, add the height of the overline
23117 (1 pixel) and a 1 pixel margin to the character height. */
23118 if (face->overline_p)
23119 it->ascent += overline_margin;
23121 take_vertical_position_into_account (it);
23122 if (it->ascent < 0)
23123 it->ascent = 0;
23124 if (it->descent < 0)
23125 it->descent = 0;
23127 if (it->glyph_row)
23128 append_composite_glyph (it);
23130 else if (it->what == IT_COMPOSITION)
23132 /* A dynamic (automatic) composition. */
23133 struct face *face = FACE_FROM_ID (it->f, it->face_id);
23134 Lisp_Object gstring;
23135 struct font_metrics metrics;
23137 gstring = composition_gstring_from_id (it->cmp_it.id);
23138 it->pixel_width
23139 = composition_gstring_width (gstring, it->cmp_it.from, it->cmp_it.to,
23140 &metrics);
23141 if (it->glyph_row
23142 && (metrics.lbearing < 0 || metrics.rbearing > metrics.width))
23143 it->glyph_row->contains_overlapping_glyphs_p = 1;
23144 it->ascent = it->phys_ascent = metrics.ascent;
23145 it->descent = it->phys_descent = metrics.descent;
23146 if (face->box != FACE_NO_BOX)
23148 int thick = face->box_line_width;
23150 if (thick > 0)
23152 it->ascent += thick;
23153 it->descent += thick;
23155 else
23156 thick = - thick;
23158 if (it->start_of_box_run_p)
23159 it->pixel_width += thick;
23160 if (it->end_of_box_run_p)
23161 it->pixel_width += thick;
23163 /* If face has an overline, add the height of the overline
23164 (1 pixel) and a 1 pixel margin to the character height. */
23165 if (face->overline_p)
23166 it->ascent += overline_margin;
23167 take_vertical_position_into_account (it);
23168 if (it->ascent < 0)
23169 it->ascent = 0;
23170 if (it->descent < 0)
23171 it->descent = 0;
23173 if (it->glyph_row)
23174 append_composite_glyph (it);
23176 else if (it->what == IT_GLYPHLESS)
23177 produce_glyphless_glyph (it, 0, Qnil);
23178 else if (it->what == IT_IMAGE)
23179 produce_image_glyph (it);
23180 else if (it->what == IT_STRETCH)
23181 produce_stretch_glyph (it);
23183 done:
23184 /* Accumulate dimensions. Note: can't assume that it->descent > 0
23185 because this isn't true for images with `:ascent 100'. */
23186 xassert (it->ascent >= 0 && it->descent >= 0);
23187 if (it->area == TEXT_AREA)
23188 it->current_x += it->pixel_width;
23190 if (extra_line_spacing > 0)
23192 it->descent += extra_line_spacing;
23193 if (extra_line_spacing > it->max_extra_line_spacing)
23194 it->max_extra_line_spacing = extra_line_spacing;
23197 it->max_ascent = max (it->max_ascent, it->ascent);
23198 it->max_descent = max (it->max_descent, it->descent);
23199 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
23200 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
23203 /* EXPORT for RIF:
23204 Output LEN glyphs starting at START at the nominal cursor position.
23205 Advance the nominal cursor over the text. The global variable
23206 updated_window contains the window being updated, updated_row is
23207 the glyph row being updated, and updated_area is the area of that
23208 row being updated. */
23210 void
23211 x_write_glyphs (struct glyph *start, int len)
23213 int x, hpos;
23215 xassert (updated_window && updated_row);
23216 BLOCK_INPUT;
23218 /* Write glyphs. */
23220 hpos = start - updated_row->glyphs[updated_area];
23221 x = draw_glyphs (updated_window, output_cursor.x,
23222 updated_row, updated_area,
23223 hpos, hpos + len,
23224 DRAW_NORMAL_TEXT, 0);
23226 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
23227 if (updated_area == TEXT_AREA
23228 && updated_window->phys_cursor_on_p
23229 && updated_window->phys_cursor.vpos == output_cursor.vpos
23230 && updated_window->phys_cursor.hpos >= hpos
23231 && updated_window->phys_cursor.hpos < hpos + len)
23232 updated_window->phys_cursor_on_p = 0;
23234 UNBLOCK_INPUT;
23236 /* Advance the output cursor. */
23237 output_cursor.hpos += len;
23238 output_cursor.x = x;
23242 /* EXPORT for RIF:
23243 Insert LEN glyphs from START at the nominal cursor position. */
23245 void
23246 x_insert_glyphs (struct glyph *start, int len)
23248 struct frame *f;
23249 struct window *w;
23250 int line_height, shift_by_width, shifted_region_width;
23251 struct glyph_row *row;
23252 struct glyph *glyph;
23253 int frame_x, frame_y;
23254 EMACS_INT hpos;
23256 xassert (updated_window && updated_row);
23257 BLOCK_INPUT;
23258 w = updated_window;
23259 f = XFRAME (WINDOW_FRAME (w));
23261 /* Get the height of the line we are in. */
23262 row = updated_row;
23263 line_height = row->height;
23265 /* Get the width of the glyphs to insert. */
23266 shift_by_width = 0;
23267 for (glyph = start; glyph < start + len; ++glyph)
23268 shift_by_width += glyph->pixel_width;
23270 /* Get the width of the region to shift right. */
23271 shifted_region_width = (window_box_width (w, updated_area)
23272 - output_cursor.x
23273 - shift_by_width);
23275 /* Shift right. */
23276 frame_x = window_box_left (w, updated_area) + output_cursor.x;
23277 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
23279 FRAME_RIF (f)->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
23280 line_height, shift_by_width);
23282 /* Write the glyphs. */
23283 hpos = start - row->glyphs[updated_area];
23284 draw_glyphs (w, output_cursor.x, row, updated_area,
23285 hpos, hpos + len,
23286 DRAW_NORMAL_TEXT, 0);
23288 /* Advance the output cursor. */
23289 output_cursor.hpos += len;
23290 output_cursor.x += shift_by_width;
23291 UNBLOCK_INPUT;
23295 /* EXPORT for RIF:
23296 Erase the current text line from the nominal cursor position
23297 (inclusive) to pixel column TO_X (exclusive). The idea is that
23298 everything from TO_X onward is already erased.
23300 TO_X is a pixel position relative to updated_area of
23301 updated_window. TO_X == -1 means clear to the end of this area. */
23303 void
23304 x_clear_end_of_line (int to_x)
23306 struct frame *f;
23307 struct window *w = updated_window;
23308 int max_x, min_y, max_y;
23309 int from_x, from_y, to_y;
23311 xassert (updated_window && updated_row);
23312 f = XFRAME (w->frame);
23314 if (updated_row->full_width_p)
23315 max_x = WINDOW_TOTAL_WIDTH (w);
23316 else
23317 max_x = window_box_width (w, updated_area);
23318 max_y = window_text_bottom_y (w);
23320 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
23321 of window. For TO_X > 0, truncate to end of drawing area. */
23322 if (to_x == 0)
23323 return;
23324 else if (to_x < 0)
23325 to_x = max_x;
23326 else
23327 to_x = min (to_x, max_x);
23329 to_y = min (max_y, output_cursor.y + updated_row->height);
23331 /* Notice if the cursor will be cleared by this operation. */
23332 if (!updated_row->full_width_p)
23333 notice_overwritten_cursor (w, updated_area,
23334 output_cursor.x, -1,
23335 updated_row->y,
23336 MATRIX_ROW_BOTTOM_Y (updated_row));
23338 from_x = output_cursor.x;
23340 /* Translate to frame coordinates. */
23341 if (updated_row->full_width_p)
23343 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
23344 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
23346 else
23348 int area_left = window_box_left (w, updated_area);
23349 from_x += area_left;
23350 to_x += area_left;
23353 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
23354 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
23355 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
23357 /* Prevent inadvertently clearing to end of the X window. */
23358 if (to_x > from_x && to_y > from_y)
23360 BLOCK_INPUT;
23361 FRAME_RIF (f)->clear_frame_area (f, from_x, from_y,
23362 to_x - from_x, to_y - from_y);
23363 UNBLOCK_INPUT;
23367 #endif /* HAVE_WINDOW_SYSTEM */
23371 /***********************************************************************
23372 Cursor types
23373 ***********************************************************************/
23375 /* Value is the internal representation of the specified cursor type
23376 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
23377 of the bar cursor. */
23379 static enum text_cursor_kinds
23380 get_specified_cursor_type (Lisp_Object arg, int *width)
23382 enum text_cursor_kinds type;
23384 if (NILP (arg))
23385 return NO_CURSOR;
23387 if (EQ (arg, Qbox))
23388 return FILLED_BOX_CURSOR;
23390 if (EQ (arg, Qhollow))
23391 return HOLLOW_BOX_CURSOR;
23393 if (EQ (arg, Qbar))
23395 *width = 2;
23396 return BAR_CURSOR;
23399 if (CONSP (arg)
23400 && EQ (XCAR (arg), Qbar)
23401 && INTEGERP (XCDR (arg))
23402 && XINT (XCDR (arg)) >= 0)
23404 *width = XINT (XCDR (arg));
23405 return BAR_CURSOR;
23408 if (EQ (arg, Qhbar))
23410 *width = 2;
23411 return HBAR_CURSOR;
23414 if (CONSP (arg)
23415 && EQ (XCAR (arg), Qhbar)
23416 && INTEGERP (XCDR (arg))
23417 && XINT (XCDR (arg)) >= 0)
23419 *width = XINT (XCDR (arg));
23420 return HBAR_CURSOR;
23423 /* Treat anything unknown as "hollow box cursor".
23424 It was bad to signal an error; people have trouble fixing
23425 .Xdefaults with Emacs, when it has something bad in it. */
23426 type = HOLLOW_BOX_CURSOR;
23428 return type;
23431 /* Set the default cursor types for specified frame. */
23432 void
23433 set_frame_cursor_types (struct frame *f, Lisp_Object arg)
23435 int width;
23436 Lisp_Object tem;
23438 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
23439 FRAME_CURSOR_WIDTH (f) = width;
23441 /* By default, set up the blink-off state depending on the on-state. */
23443 tem = Fassoc (arg, Vblink_cursor_alist);
23444 if (!NILP (tem))
23446 FRAME_BLINK_OFF_CURSOR (f)
23447 = get_specified_cursor_type (XCDR (tem), &width);
23448 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
23450 else
23451 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
23455 #ifdef HAVE_WINDOW_SYSTEM
23457 /* Return the cursor we want to be displayed in window W. Return
23458 width of bar/hbar cursor through WIDTH arg. Return with
23459 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
23460 (i.e. if the `system caret' should track this cursor).
23462 In a mini-buffer window, we want the cursor only to appear if we
23463 are reading input from this window. For the selected window, we
23464 want the cursor type given by the frame parameter or buffer local
23465 setting of cursor-type. If explicitly marked off, draw no cursor.
23466 In all other cases, we want a hollow box cursor. */
23468 static enum text_cursor_kinds
23469 get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
23470 int *active_cursor)
23472 struct frame *f = XFRAME (w->frame);
23473 struct buffer *b = XBUFFER (w->buffer);
23474 int cursor_type = DEFAULT_CURSOR;
23475 Lisp_Object alt_cursor;
23476 int non_selected = 0;
23478 *active_cursor = 1;
23480 /* Echo area */
23481 if (cursor_in_echo_area
23482 && FRAME_HAS_MINIBUF_P (f)
23483 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
23485 if (w == XWINDOW (echo_area_window))
23487 if (EQ (b->cursor_type, Qt) || NILP (b->cursor_type))
23489 *width = FRAME_CURSOR_WIDTH (f);
23490 return FRAME_DESIRED_CURSOR (f);
23492 else
23493 return get_specified_cursor_type (b->cursor_type, width);
23496 *active_cursor = 0;
23497 non_selected = 1;
23500 /* Detect a nonselected window or nonselected frame. */
23501 else if (w != XWINDOW (f->selected_window)
23502 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame)
23504 *active_cursor = 0;
23506 if (MINI_WINDOW_P (w) && minibuf_level == 0)
23507 return NO_CURSOR;
23509 non_selected = 1;
23512 /* Never display a cursor in a window in which cursor-type is nil. */
23513 if (NILP (b->cursor_type))
23514 return NO_CURSOR;
23516 /* Get the normal cursor type for this window. */
23517 if (EQ (b->cursor_type, Qt))
23519 cursor_type = FRAME_DESIRED_CURSOR (f);
23520 *width = FRAME_CURSOR_WIDTH (f);
23522 else
23523 cursor_type = get_specified_cursor_type (b->cursor_type, width);
23525 /* Use cursor-in-non-selected-windows instead
23526 for non-selected window or frame. */
23527 if (non_selected)
23529 alt_cursor = b->cursor_in_non_selected_windows;
23530 if (!EQ (Qt, alt_cursor))
23531 return get_specified_cursor_type (alt_cursor, width);
23532 /* t means modify the normal cursor type. */
23533 if (cursor_type == FILLED_BOX_CURSOR)
23534 cursor_type = HOLLOW_BOX_CURSOR;
23535 else if (cursor_type == BAR_CURSOR && *width > 1)
23536 --*width;
23537 return cursor_type;
23540 /* Use normal cursor if not blinked off. */
23541 if (!w->cursor_off_p)
23543 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
23545 if (cursor_type == FILLED_BOX_CURSOR)
23547 /* Using a block cursor on large images can be very annoying.
23548 So use a hollow cursor for "large" images.
23549 If image is not transparent (no mask), also use hollow cursor. */
23550 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
23551 if (img != NULL && IMAGEP (img->spec))
23553 /* Arbitrarily, interpret "Large" as >32x32 and >NxN
23554 where N = size of default frame font size.
23555 This should cover most of the "tiny" icons people may use. */
23556 if (!img->mask
23557 || img->width > max (32, WINDOW_FRAME_COLUMN_WIDTH (w))
23558 || img->height > max (32, WINDOW_FRAME_LINE_HEIGHT (w)))
23559 cursor_type = HOLLOW_BOX_CURSOR;
23562 else if (cursor_type != NO_CURSOR)
23564 /* Display current only supports BOX and HOLLOW cursors for images.
23565 So for now, unconditionally use a HOLLOW cursor when cursor is
23566 not a solid box cursor. */
23567 cursor_type = HOLLOW_BOX_CURSOR;
23570 return cursor_type;
23573 /* Cursor is blinked off, so determine how to "toggle" it. */
23575 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
23576 if ((alt_cursor = Fassoc (b->cursor_type, Vblink_cursor_alist), !NILP (alt_cursor)))
23577 return get_specified_cursor_type (XCDR (alt_cursor), width);
23579 /* Then see if frame has specified a specific blink off cursor type. */
23580 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
23582 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
23583 return FRAME_BLINK_OFF_CURSOR (f);
23586 #if 0
23587 /* Some people liked having a permanently visible blinking cursor,
23588 while others had very strong opinions against it. So it was
23589 decided to remove it. KFS 2003-09-03 */
23591 /* Finally perform built-in cursor blinking:
23592 filled box <-> hollow box
23593 wide [h]bar <-> narrow [h]bar
23594 narrow [h]bar <-> no cursor
23595 other type <-> no cursor */
23597 if (cursor_type == FILLED_BOX_CURSOR)
23598 return HOLLOW_BOX_CURSOR;
23600 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
23602 *width = 1;
23603 return cursor_type;
23605 #endif
23607 return NO_CURSOR;
23611 /* Notice when the text cursor of window W has been completely
23612 overwritten by a drawing operation that outputs glyphs in AREA
23613 starting at X0 and ending at X1 in the line starting at Y0 and
23614 ending at Y1. X coordinates are area-relative. X1 < 0 means all
23615 the rest of the line after X0 has been written. Y coordinates
23616 are window-relative. */
23618 static void
23619 notice_overwritten_cursor (struct window *w, enum glyph_row_area area,
23620 int x0, int x1, int y0, int y1)
23622 int cx0, cx1, cy0, cy1;
23623 struct glyph_row *row;
23625 if (!w->phys_cursor_on_p)
23626 return;
23627 if (area != TEXT_AREA)
23628 return;
23630 if (w->phys_cursor.vpos < 0
23631 || w->phys_cursor.vpos >= w->current_matrix->nrows
23632 || (row = w->current_matrix->rows + w->phys_cursor.vpos,
23633 !(row->enabled_p && row->displays_text_p)))
23634 return;
23636 if (row->cursor_in_fringe_p)
23638 row->cursor_in_fringe_p = 0;
23639 draw_fringe_bitmap (w, row, row->reversed_p);
23640 w->phys_cursor_on_p = 0;
23641 return;
23644 cx0 = w->phys_cursor.x;
23645 cx1 = cx0 + w->phys_cursor_width;
23646 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
23647 return;
23649 /* The cursor image will be completely removed from the
23650 screen if the output area intersects the cursor area in
23651 y-direction. When we draw in [y0 y1[, and some part of
23652 the cursor is at y < y0, that part must have been drawn
23653 before. When scrolling, the cursor is erased before
23654 actually scrolling, so we don't come here. When not
23655 scrolling, the rows above the old cursor row must have
23656 changed, and in this case these rows must have written
23657 over the cursor image.
23659 Likewise if part of the cursor is below y1, with the
23660 exception of the cursor being in the first blank row at
23661 the buffer and window end because update_text_area
23662 doesn't draw that row. (Except when it does, but
23663 that's handled in update_text_area.) */
23665 cy0 = w->phys_cursor.y;
23666 cy1 = cy0 + w->phys_cursor_height;
23667 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
23668 return;
23670 w->phys_cursor_on_p = 0;
23673 #endif /* HAVE_WINDOW_SYSTEM */
23676 /************************************************************************
23677 Mouse Face
23678 ************************************************************************/
23680 #ifdef HAVE_WINDOW_SYSTEM
23682 /* EXPORT for RIF:
23683 Fix the display of area AREA of overlapping row ROW in window W
23684 with respect to the overlapping part OVERLAPS. */
23686 void
23687 x_fix_overlapping_area (struct window *w, struct glyph_row *row,
23688 enum glyph_row_area area, int overlaps)
23690 int i, x;
23692 BLOCK_INPUT;
23694 x = 0;
23695 for (i = 0; i < row->used[area];)
23697 if (row->glyphs[area][i].overlaps_vertically_p)
23699 int start = i, start_x = x;
23703 x += row->glyphs[area][i].pixel_width;
23704 ++i;
23706 while (i < row->used[area]
23707 && row->glyphs[area][i].overlaps_vertically_p);
23709 draw_glyphs (w, start_x, row, area,
23710 start, i,
23711 DRAW_NORMAL_TEXT, overlaps);
23713 else
23715 x += row->glyphs[area][i].pixel_width;
23716 ++i;
23720 UNBLOCK_INPUT;
23724 /* EXPORT:
23725 Draw the cursor glyph of window W in glyph row ROW. See the
23726 comment of draw_glyphs for the meaning of HL. */
23728 void
23729 draw_phys_cursor_glyph (struct window *w, struct glyph_row *row,
23730 enum draw_glyphs_face hl)
23732 /* If cursor hpos is out of bounds, don't draw garbage. This can
23733 happen in mini-buffer windows when switching between echo area
23734 glyphs and mini-buffer. */
23735 if ((row->reversed_p
23736 ? (w->phys_cursor.hpos >= 0)
23737 : (w->phys_cursor.hpos < row->used[TEXT_AREA])))
23739 int on_p = w->phys_cursor_on_p;
23740 int x1;
23741 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
23742 w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
23743 hl, 0);
23744 w->phys_cursor_on_p = on_p;
23746 if (hl == DRAW_CURSOR)
23747 w->phys_cursor_width = x1 - w->phys_cursor.x;
23748 /* When we erase the cursor, and ROW is overlapped by other
23749 rows, make sure that these overlapping parts of other rows
23750 are redrawn. */
23751 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
23753 w->phys_cursor_width = x1 - w->phys_cursor.x;
23755 if (row > w->current_matrix->rows
23756 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
23757 x_fix_overlapping_area (w, row - 1, TEXT_AREA,
23758 OVERLAPS_ERASED_CURSOR);
23760 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
23761 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
23762 x_fix_overlapping_area (w, row + 1, TEXT_AREA,
23763 OVERLAPS_ERASED_CURSOR);
23769 /* EXPORT:
23770 Erase the image of a cursor of window W from the screen. */
23772 void
23773 erase_phys_cursor (struct window *w)
23775 struct frame *f = XFRAME (w->frame);
23776 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
23777 int hpos = w->phys_cursor.hpos;
23778 int vpos = w->phys_cursor.vpos;
23779 int mouse_face_here_p = 0;
23780 struct glyph_matrix *active_glyphs = w->current_matrix;
23781 struct glyph_row *cursor_row;
23782 struct glyph *cursor_glyph;
23783 enum draw_glyphs_face hl;
23785 /* No cursor displayed or row invalidated => nothing to do on the
23786 screen. */
23787 if (w->phys_cursor_type == NO_CURSOR)
23788 goto mark_cursor_off;
23790 /* VPOS >= active_glyphs->nrows means that window has been resized.
23791 Don't bother to erase the cursor. */
23792 if (vpos >= active_glyphs->nrows)
23793 goto mark_cursor_off;
23795 /* If row containing cursor is marked invalid, there is nothing we
23796 can do. */
23797 cursor_row = MATRIX_ROW (active_glyphs, vpos);
23798 if (!cursor_row->enabled_p)
23799 goto mark_cursor_off;
23801 /* If line spacing is > 0, old cursor may only be partially visible in
23802 window after split-window. So adjust visible height. */
23803 cursor_row->visible_height = min (cursor_row->visible_height,
23804 window_text_bottom_y (w) - cursor_row->y);
23806 /* If row is completely invisible, don't attempt to delete a cursor which
23807 isn't there. This can happen if cursor is at top of a window, and
23808 we switch to a buffer with a header line in that window. */
23809 if (cursor_row->visible_height <= 0)
23810 goto mark_cursor_off;
23812 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
23813 if (cursor_row->cursor_in_fringe_p)
23815 cursor_row->cursor_in_fringe_p = 0;
23816 draw_fringe_bitmap (w, cursor_row, cursor_row->reversed_p);
23817 goto mark_cursor_off;
23820 /* This can happen when the new row is shorter than the old one.
23821 In this case, either draw_glyphs or clear_end_of_line
23822 should have cleared the cursor. Note that we wouldn't be
23823 able to erase the cursor in this case because we don't have a
23824 cursor glyph at hand. */
23825 if ((cursor_row->reversed_p
23826 ? (w->phys_cursor.hpos < 0)
23827 : (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])))
23828 goto mark_cursor_off;
23830 /* If the cursor is in the mouse face area, redisplay that when
23831 we clear the cursor. */
23832 if (! NILP (hlinfo->mouse_face_window)
23833 && coords_in_mouse_face_p (w, hpos, vpos)
23834 /* Don't redraw the cursor's spot in mouse face if it is at the
23835 end of a line (on a newline). The cursor appears there, but
23836 mouse highlighting does not. */
23837 && cursor_row->used[TEXT_AREA] > hpos && hpos >= 0)
23838 mouse_face_here_p = 1;
23840 /* Maybe clear the display under the cursor. */
23841 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
23843 int x, y, left_x;
23844 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
23845 int width;
23847 cursor_glyph = get_phys_cursor_glyph (w);
23848 if (cursor_glyph == NULL)
23849 goto mark_cursor_off;
23851 width = cursor_glyph->pixel_width;
23852 left_x = window_box_left_offset (w, TEXT_AREA);
23853 x = w->phys_cursor.x;
23854 if (x < left_x)
23855 width -= left_x - x;
23856 width = min (width, window_box_width (w, TEXT_AREA) - x);
23857 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
23858 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, max (x, left_x));
23860 if (width > 0)
23861 FRAME_RIF (f)->clear_frame_area (f, x, y, width, cursor_row->visible_height);
23864 /* Erase the cursor by redrawing the character underneath it. */
23865 if (mouse_face_here_p)
23866 hl = DRAW_MOUSE_FACE;
23867 else
23868 hl = DRAW_NORMAL_TEXT;
23869 draw_phys_cursor_glyph (w, cursor_row, hl);
23871 mark_cursor_off:
23872 w->phys_cursor_on_p = 0;
23873 w->phys_cursor_type = NO_CURSOR;
23877 /* EXPORT:
23878 Display or clear cursor of window W. If ON is zero, clear the
23879 cursor. If it is non-zero, display the cursor. If ON is nonzero,
23880 where to put the cursor is specified by HPOS, VPOS, X and Y. */
23882 void
23883 display_and_set_cursor (struct window *w, int on,
23884 int hpos, int vpos, int x, int y)
23886 struct frame *f = XFRAME (w->frame);
23887 int new_cursor_type;
23888 int new_cursor_width;
23889 int active_cursor;
23890 struct glyph_row *glyph_row;
23891 struct glyph *glyph;
23893 /* This is pointless on invisible frames, and dangerous on garbaged
23894 windows and frames; in the latter case, the frame or window may
23895 be in the midst of changing its size, and x and y may be off the
23896 window. */
23897 if (! FRAME_VISIBLE_P (f)
23898 || FRAME_GARBAGED_P (f)
23899 || vpos >= w->current_matrix->nrows
23900 || hpos >= w->current_matrix->matrix_w)
23901 return;
23903 /* If cursor is off and we want it off, return quickly. */
23904 if (!on && !w->phys_cursor_on_p)
23905 return;
23907 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
23908 /* If cursor row is not enabled, we don't really know where to
23909 display the cursor. */
23910 if (!glyph_row->enabled_p)
23912 w->phys_cursor_on_p = 0;
23913 return;
23916 glyph = NULL;
23917 if (!glyph_row->exact_window_width_line_p
23918 || (0 <= hpos && hpos < glyph_row->used[TEXT_AREA]))
23919 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
23921 xassert (interrupt_input_blocked);
23923 /* Set new_cursor_type to the cursor we want to be displayed. */
23924 new_cursor_type = get_window_cursor_type (w, glyph,
23925 &new_cursor_width, &active_cursor);
23927 /* If cursor is currently being shown and we don't want it to be or
23928 it is in the wrong place, or the cursor type is not what we want,
23929 erase it. */
23930 if (w->phys_cursor_on_p
23931 && (!on
23932 || w->phys_cursor.x != x
23933 || w->phys_cursor.y != y
23934 || new_cursor_type != w->phys_cursor_type
23935 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
23936 && new_cursor_width != w->phys_cursor_width)))
23937 erase_phys_cursor (w);
23939 /* Don't check phys_cursor_on_p here because that flag is only set
23940 to zero in some cases where we know that the cursor has been
23941 completely erased, to avoid the extra work of erasing the cursor
23942 twice. In other words, phys_cursor_on_p can be 1 and the cursor
23943 still not be visible, or it has only been partly erased. */
23944 if (on)
23946 w->phys_cursor_ascent = glyph_row->ascent;
23947 w->phys_cursor_height = glyph_row->height;
23949 /* Set phys_cursor_.* before x_draw_.* is called because some
23950 of them may need the information. */
23951 w->phys_cursor.x = x;
23952 w->phys_cursor.y = glyph_row->y;
23953 w->phys_cursor.hpos = hpos;
23954 w->phys_cursor.vpos = vpos;
23957 FRAME_RIF (f)->draw_window_cursor (w, glyph_row, x, y,
23958 new_cursor_type, new_cursor_width,
23959 on, active_cursor);
23963 /* Switch the display of W's cursor on or off, according to the value
23964 of ON. */
23966 void
23967 update_window_cursor (struct window *w, int on)
23969 /* Don't update cursor in windows whose frame is in the process
23970 of being deleted. */
23971 if (w->current_matrix)
23973 BLOCK_INPUT;
23974 display_and_set_cursor (w, on, w->phys_cursor.hpos, w->phys_cursor.vpos,
23975 w->phys_cursor.x, w->phys_cursor.y);
23976 UNBLOCK_INPUT;
23981 /* Call update_window_cursor with parameter ON_P on all leaf windows
23982 in the window tree rooted at W. */
23984 static void
23985 update_cursor_in_window_tree (struct window *w, int on_p)
23987 while (w)
23989 if (!NILP (w->hchild))
23990 update_cursor_in_window_tree (XWINDOW (w->hchild), on_p);
23991 else if (!NILP (w->vchild))
23992 update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
23993 else
23994 update_window_cursor (w, on_p);
23996 w = NILP (w->next) ? 0 : XWINDOW (w->next);
24001 /* EXPORT:
24002 Display the cursor on window W, or clear it, according to ON_P.
24003 Don't change the cursor's position. */
24005 void
24006 x_update_cursor (struct frame *f, int on_p)
24008 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
24012 /* EXPORT:
24013 Clear the cursor of window W to background color, and mark the
24014 cursor as not shown. This is used when the text where the cursor
24015 is about to be rewritten. */
24017 void
24018 x_clear_cursor (struct window *w)
24020 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
24021 update_window_cursor (w, 0);
24024 #endif /* HAVE_WINDOW_SYSTEM */
24026 /* Implementation of draw_row_with_mouse_face for GUI sessions, GPM,
24027 and MSDOS. */
24028 void
24029 draw_row_with_mouse_face (struct window *w, int start_x, struct glyph_row *row,
24030 int start_hpos, int end_hpos,
24031 enum draw_glyphs_face draw)
24033 #ifdef HAVE_WINDOW_SYSTEM
24034 if (FRAME_WINDOW_P (XFRAME (w->frame)))
24036 draw_glyphs (w, start_x, row, TEXT_AREA, start_hpos, end_hpos, draw, 0);
24037 return;
24039 #endif
24040 #if defined (HAVE_GPM) || defined (MSDOS)
24041 tty_draw_row_with_mouse_face (w, row, start_hpos, end_hpos, draw);
24042 #endif
24045 /* EXPORT:
24046 Display the active region described by mouse_face_* according to DRAW. */
24048 void
24049 show_mouse_face (Mouse_HLInfo *hlinfo, enum draw_glyphs_face draw)
24051 struct window *w = XWINDOW (hlinfo->mouse_face_window);
24052 struct frame *f = XFRAME (WINDOW_FRAME (w));
24054 if (/* If window is in the process of being destroyed, don't bother
24055 to do anything. */
24056 w->current_matrix != NULL
24057 /* Don't update mouse highlight if hidden */
24058 && (draw != DRAW_MOUSE_FACE || !hlinfo->mouse_face_hidden)
24059 /* Recognize when we are called to operate on rows that don't exist
24060 anymore. This can happen when a window is split. */
24061 && hlinfo->mouse_face_end_row < w->current_matrix->nrows)
24063 int phys_cursor_on_p = w->phys_cursor_on_p;
24064 struct glyph_row *row, *first, *last;
24066 first = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_beg_row);
24067 last = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_end_row);
24069 for (row = first; row <= last && row->enabled_p; ++row)
24071 int start_hpos, end_hpos, start_x;
24073 /* For all but the first row, the highlight starts at column 0. */
24074 if (row == first)
24076 /* R2L rows have BEG and END in reversed order, but the
24077 screen drawing geometry is always left to right. So
24078 we need to mirror the beginning and end of the
24079 highlighted area in R2L rows. */
24080 if (!row->reversed_p)
24082 start_hpos = hlinfo->mouse_face_beg_col;
24083 start_x = hlinfo->mouse_face_beg_x;
24085 else if (row == last)
24087 start_hpos = hlinfo->mouse_face_end_col;
24088 start_x = hlinfo->mouse_face_end_x;
24090 else
24092 start_hpos = 0;
24093 start_x = 0;
24096 else if (row->reversed_p && row == last)
24098 start_hpos = hlinfo->mouse_face_end_col;
24099 start_x = hlinfo->mouse_face_end_x;
24101 else
24103 start_hpos = 0;
24104 start_x = 0;
24107 if (row == last)
24109 if (!row->reversed_p)
24110 end_hpos = hlinfo->mouse_face_end_col;
24111 else if (row == first)
24112 end_hpos = hlinfo->mouse_face_beg_col;
24113 else
24115 end_hpos = row->used[TEXT_AREA];
24116 if (draw == DRAW_NORMAL_TEXT)
24117 row->fill_line_p = 1; /* Clear to end of line */
24120 else if (row->reversed_p && row == first)
24121 end_hpos = hlinfo->mouse_face_beg_col;
24122 else
24124 end_hpos = row->used[TEXT_AREA];
24125 if (draw == DRAW_NORMAL_TEXT)
24126 row->fill_line_p = 1; /* Clear to end of line */
24129 if (end_hpos > start_hpos)
24131 draw_row_with_mouse_face (w, start_x, row,
24132 start_hpos, end_hpos, draw);
24134 row->mouse_face_p
24135 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
24139 #ifdef HAVE_WINDOW_SYSTEM
24140 /* When we've written over the cursor, arrange for it to
24141 be displayed again. */
24142 if (FRAME_WINDOW_P (f)
24143 && phys_cursor_on_p && !w->phys_cursor_on_p)
24145 BLOCK_INPUT;
24146 display_and_set_cursor (w, 1,
24147 w->phys_cursor.hpos, w->phys_cursor.vpos,
24148 w->phys_cursor.x, w->phys_cursor.y);
24149 UNBLOCK_INPUT;
24151 #endif /* HAVE_WINDOW_SYSTEM */
24154 #ifdef HAVE_WINDOW_SYSTEM
24155 /* Change the mouse cursor. */
24156 if (FRAME_WINDOW_P (f))
24158 if (draw == DRAW_NORMAL_TEXT
24159 && !EQ (hlinfo->mouse_face_window, f->tool_bar_window))
24160 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
24161 else if (draw == DRAW_MOUSE_FACE)
24162 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
24163 else
24164 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
24166 #endif /* HAVE_WINDOW_SYSTEM */
24169 /* EXPORT:
24170 Clear out the mouse-highlighted active region.
24171 Redraw it un-highlighted first. Value is non-zero if mouse
24172 face was actually drawn unhighlighted. */
24175 clear_mouse_face (Mouse_HLInfo *hlinfo)
24177 int cleared = 0;
24179 if (!hlinfo->mouse_face_hidden && !NILP (hlinfo->mouse_face_window))
24181 show_mouse_face (hlinfo, DRAW_NORMAL_TEXT);
24182 cleared = 1;
24185 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
24186 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
24187 hlinfo->mouse_face_window = Qnil;
24188 hlinfo->mouse_face_overlay = Qnil;
24189 return cleared;
24192 /* Return non-zero if the coordinates HPOS and VPOS on windows W are
24193 within the mouse face on that window. */
24194 static int
24195 coords_in_mouse_face_p (struct window *w, int hpos, int vpos)
24197 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
24199 /* Quickly resolve the easy cases. */
24200 if (!(WINDOWP (hlinfo->mouse_face_window)
24201 && XWINDOW (hlinfo->mouse_face_window) == w))
24202 return 0;
24203 if (vpos < hlinfo->mouse_face_beg_row
24204 || vpos > hlinfo->mouse_face_end_row)
24205 return 0;
24206 if (vpos > hlinfo->mouse_face_beg_row
24207 && vpos < hlinfo->mouse_face_end_row)
24208 return 1;
24210 if (!MATRIX_ROW (w->current_matrix, vpos)->reversed_p)
24212 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
24214 if (hlinfo->mouse_face_beg_col <= hpos && hpos < hlinfo->mouse_face_end_col)
24215 return 1;
24217 else if ((vpos == hlinfo->mouse_face_beg_row
24218 && hpos >= hlinfo->mouse_face_beg_col)
24219 || (vpos == hlinfo->mouse_face_end_row
24220 && hpos < hlinfo->mouse_face_end_col))
24221 return 1;
24223 else
24225 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
24227 if (hlinfo->mouse_face_end_col < hpos && hpos <= hlinfo->mouse_face_beg_col)
24228 return 1;
24230 else if ((vpos == hlinfo->mouse_face_beg_row
24231 && hpos <= hlinfo->mouse_face_beg_col)
24232 || (vpos == hlinfo->mouse_face_end_row
24233 && hpos > hlinfo->mouse_face_end_col))
24234 return 1;
24236 return 0;
24240 /* EXPORT:
24241 Non-zero if physical cursor of window W is within mouse face. */
24244 cursor_in_mouse_face_p (struct window *w)
24246 return coords_in_mouse_face_p (w, w->phys_cursor.hpos, w->phys_cursor.vpos);
24251 /* Find the glyph rows START_ROW and END_ROW of window W that display
24252 characters between buffer positions START_CHARPOS and END_CHARPOS
24253 (excluding END_CHARPOS). This is similar to row_containing_pos,
24254 but is more accurate when bidi reordering makes buffer positions
24255 change non-linearly with glyph rows. */
24256 static void
24257 rows_from_pos_range (struct window *w,
24258 EMACS_INT start_charpos, EMACS_INT end_charpos,
24259 struct glyph_row **start, struct glyph_row **end)
24261 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
24262 int last_y = window_text_bottom_y (w);
24263 struct glyph_row *row;
24265 *start = NULL;
24266 *end = NULL;
24268 while (!first->enabled_p
24269 && first < MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w))
24270 first++;
24272 /* Find the START row. */
24273 for (row = first;
24274 row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y;
24275 row++)
24277 /* A row can potentially be the START row if the range of the
24278 characters it displays intersects the range
24279 [START_CHARPOS..END_CHARPOS). */
24280 if (! ((start_charpos < MATRIX_ROW_START_CHARPOS (row)
24281 && end_charpos < MATRIX_ROW_START_CHARPOS (row))
24282 /* See the commentary in row_containing_pos, for the
24283 explanation of the complicated way to check whether
24284 some position is beyond the end of the characters
24285 displayed by a row. */
24286 || ((start_charpos > MATRIX_ROW_END_CHARPOS (row)
24287 || (start_charpos == MATRIX_ROW_END_CHARPOS (row)
24288 && !row->ends_at_zv_p
24289 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
24290 && (end_charpos > MATRIX_ROW_END_CHARPOS (row)
24291 || (end_charpos == MATRIX_ROW_END_CHARPOS (row)
24292 && !row->ends_at_zv_p
24293 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))))))
24295 /* Found a candidate row. Now make sure at least one of the
24296 glyphs it displays has a charpos from the range
24297 [START_CHARPOS..END_CHARPOS).
24299 This is not obvious because bidi reordering could make
24300 buffer positions of a row be 1,2,3,102,101,100, and if we
24301 want to highlight characters in [50..60), we don't want
24302 this row, even though [50..60) does intersect [1..103),
24303 the range of character positions given by the row's start
24304 and end positions. */
24305 struct glyph *g = row->glyphs[TEXT_AREA];
24306 struct glyph *e = g + row->used[TEXT_AREA];
24308 while (g < e)
24310 if (BUFFERP (g->object)
24311 && start_charpos <= g->charpos && g->charpos < end_charpos)
24312 *start = row;
24313 g++;
24315 if (*start)
24316 break;
24320 /* Find the END row. */
24321 if (!*start
24322 /* If the last row is partially visible, start looking for END
24323 from that row, instead of starting from FIRST. */
24324 && !(row->enabled_p
24325 && row->y < last_y && MATRIX_ROW_BOTTOM_Y (row) > last_y))
24326 row = first;
24327 for ( ; row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y; row++)
24329 struct glyph_row *next = row + 1;
24331 if (!next->enabled_p
24332 || next >= MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w)
24333 /* The first row >= START whose range of displayed characters
24334 does NOT intersect the range [START_CHARPOS..END_CHARPOS]
24335 is the row END + 1. */
24336 || (start_charpos < MATRIX_ROW_START_CHARPOS (next)
24337 && end_charpos < MATRIX_ROW_START_CHARPOS (next))
24338 || ((start_charpos > MATRIX_ROW_END_CHARPOS (next)
24339 || (start_charpos == MATRIX_ROW_END_CHARPOS (next)
24340 && !next->ends_at_zv_p
24341 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))
24342 && (end_charpos > MATRIX_ROW_END_CHARPOS (next)
24343 || (end_charpos == MATRIX_ROW_END_CHARPOS (next)
24344 && !next->ends_at_zv_p
24345 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))))
24347 *end = row;
24348 break;
24350 else
24352 /* If the next row's edges intersect [START_CHARPOS..END_CHARPOS],
24353 but none of the characters it displays are in the range, it is
24354 also END + 1. */
24355 struct glyph *g = next->glyphs[TEXT_AREA];
24356 struct glyph *e = g + next->used[TEXT_AREA];
24358 while (g < e)
24360 if (BUFFERP (g->object)
24361 && start_charpos <= g->charpos && g->charpos < end_charpos)
24362 break;
24363 g++;
24365 if (g == e)
24367 *end = row;
24368 break;
24374 /* This function sets the mouse_face_* elements of HLINFO, assuming
24375 the mouse cursor is on a glyph with buffer charpos MOUSE_CHARPOS in
24376 window WINDOW. START_CHARPOS and END_CHARPOS are buffer positions
24377 for the overlay or run of text properties specifying the mouse
24378 face. BEFORE_STRING and AFTER_STRING, if non-nil, are a
24379 before-string and after-string that must also be highlighted.
24380 DISPLAY_STRING, if non-nil, is a display string that may cover some
24381 or all of the highlighted text. */
24383 static void
24384 mouse_face_from_buffer_pos (Lisp_Object window,
24385 Mouse_HLInfo *hlinfo,
24386 EMACS_INT mouse_charpos,
24387 EMACS_INT start_charpos,
24388 EMACS_INT end_charpos,
24389 Lisp_Object before_string,
24390 Lisp_Object after_string,
24391 Lisp_Object display_string)
24393 struct window *w = XWINDOW (window);
24394 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
24395 struct glyph_row *r1, *r2;
24396 struct glyph *glyph, *end;
24397 EMACS_INT ignore, pos;
24398 int x;
24400 xassert (NILP (display_string) || STRINGP (display_string));
24401 xassert (NILP (before_string) || STRINGP (before_string));
24402 xassert (NILP (after_string) || STRINGP (after_string));
24404 /* Find the rows corresponding to START_CHARPOS and END_CHARPOS. */
24405 rows_from_pos_range (w, start_charpos, end_charpos, &r1, &r2);
24406 if (r1 == NULL)
24407 r1 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
24408 /* If the before-string or display-string contains newlines,
24409 rows_from_pos_range skips to its last row. Move back. */
24410 if (!NILP (before_string) || !NILP (display_string))
24412 struct glyph_row *prev;
24413 while ((prev = r1 - 1, prev >= first)
24414 && MATRIX_ROW_END_CHARPOS (prev) == start_charpos
24415 && prev->used[TEXT_AREA] > 0)
24417 struct glyph *beg = prev->glyphs[TEXT_AREA];
24418 glyph = beg + prev->used[TEXT_AREA];
24419 while (--glyph >= beg && INTEGERP (glyph->object));
24420 if (glyph < beg
24421 || !(EQ (glyph->object, before_string)
24422 || EQ (glyph->object, display_string)))
24423 break;
24424 r1 = prev;
24427 if (r2 == NULL)
24429 r2 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
24430 hlinfo->mouse_face_past_end = 1;
24432 else if (!NILP (after_string))
24434 /* If the after-string has newlines, advance to its last row. */
24435 struct glyph_row *next;
24436 struct glyph_row *last
24437 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
24439 for (next = r2 + 1;
24440 next <= last
24441 && next->used[TEXT_AREA] > 0
24442 && EQ (next->glyphs[TEXT_AREA]->object, after_string);
24443 ++next)
24444 r2 = next;
24446 /* The rest of the display engine assumes that mouse_face_beg_row is
24447 either above below mouse_face_end_row or identical to it. But
24448 with bidi-reordered continued lines, the row for START_CHARPOS
24449 could be below the row for END_CHARPOS. If so, swap the rows and
24450 store them in correct order. */
24451 if (r1->y > r2->y)
24453 struct glyph_row *tem = r2;
24455 r2 = r1;
24456 r1 = tem;
24459 hlinfo->mouse_face_beg_y = r1->y;
24460 hlinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (r1, w->current_matrix);
24461 hlinfo->mouse_face_end_y = r2->y;
24462 hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r2, w->current_matrix);
24464 /* For a bidi-reordered row, the positions of BEFORE_STRING,
24465 AFTER_STRING, DISPLAY_STRING, START_CHARPOS, and END_CHARPOS
24466 could be anywhere in the row and in any order. The strategy
24467 below is to find the leftmost and the rightmost glyph that
24468 belongs to either of these 3 strings, or whose position is
24469 between START_CHARPOS and END_CHARPOS, and highlight all the
24470 glyphs between those two. This may cover more than just the text
24471 between START_CHARPOS and END_CHARPOS if the range of characters
24472 strides the bidi level boundary, e.g. if the beginning is in R2L
24473 text while the end is in L2R text or vice versa. */
24474 if (!r1->reversed_p)
24476 /* This row is in a left to right paragraph. Scan it left to
24477 right. */
24478 glyph = r1->glyphs[TEXT_AREA];
24479 end = glyph + r1->used[TEXT_AREA];
24480 x = r1->x;
24482 /* Skip truncation glyphs at the start of the glyph row. */
24483 if (r1->displays_text_p)
24484 for (; glyph < end
24485 && INTEGERP (glyph->object)
24486 && glyph->charpos < 0;
24487 ++glyph)
24488 x += glyph->pixel_width;
24490 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
24491 or DISPLAY_STRING, and the first glyph from buffer whose
24492 position is between START_CHARPOS and END_CHARPOS. */
24493 for (; glyph < end
24494 && !INTEGERP (glyph->object)
24495 && !EQ (glyph->object, display_string)
24496 && !(BUFFERP (glyph->object)
24497 && (glyph->charpos >= start_charpos
24498 && glyph->charpos < end_charpos));
24499 ++glyph)
24501 /* BEFORE_STRING or AFTER_STRING are only relevant if they
24502 are present at buffer positions between START_CHARPOS and
24503 END_CHARPOS, or if they come from an overlay. */
24504 if (EQ (glyph->object, before_string))
24506 pos = string_buffer_position (w, before_string,
24507 start_charpos);
24508 /* If pos == 0, it means before_string came from an
24509 overlay, not from a buffer position. */
24510 if (!pos || (pos >= start_charpos && pos < end_charpos))
24511 break;
24513 else if (EQ (glyph->object, after_string))
24515 pos = string_buffer_position (w, after_string, end_charpos);
24516 if (!pos || (pos >= start_charpos && pos < end_charpos))
24517 break;
24519 x += glyph->pixel_width;
24521 hlinfo->mouse_face_beg_x = x;
24522 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
24524 else
24526 /* This row is in a right to left paragraph. Scan it right to
24527 left. */
24528 struct glyph *g;
24530 end = r1->glyphs[TEXT_AREA] - 1;
24531 glyph = end + r1->used[TEXT_AREA];
24533 /* Skip truncation glyphs at the start of the glyph row. */
24534 if (r1->displays_text_p)
24535 for (; glyph > end
24536 && INTEGERP (glyph->object)
24537 && glyph->charpos < 0;
24538 --glyph)
24541 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
24542 or DISPLAY_STRING, and the first glyph from buffer whose
24543 position is between START_CHARPOS and END_CHARPOS. */
24544 for (; glyph > end
24545 && !INTEGERP (glyph->object)
24546 && !EQ (glyph->object, display_string)
24547 && !(BUFFERP (glyph->object)
24548 && (glyph->charpos >= start_charpos
24549 && glyph->charpos < end_charpos));
24550 --glyph)
24552 /* BEFORE_STRING or AFTER_STRING are only relevant if they
24553 are present at buffer positions between START_CHARPOS and
24554 END_CHARPOS, or if they come from an overlay. */
24555 if (EQ (glyph->object, before_string))
24557 pos = string_buffer_position (w, before_string, start_charpos);
24558 /* If pos == 0, it means before_string came from an
24559 overlay, not from a buffer position. */
24560 if (!pos || (pos >= start_charpos && pos < end_charpos))
24561 break;
24563 else if (EQ (glyph->object, after_string))
24565 pos = string_buffer_position (w, after_string, end_charpos);
24566 if (!pos || (pos >= start_charpos && pos < end_charpos))
24567 break;
24571 glyph++; /* first glyph to the right of the highlighted area */
24572 for (g = r1->glyphs[TEXT_AREA], x = r1->x; g < glyph; g++)
24573 x += g->pixel_width;
24574 hlinfo->mouse_face_beg_x = x;
24575 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
24578 /* If the highlight ends in a different row, compute GLYPH and END
24579 for the end row. Otherwise, reuse the values computed above for
24580 the row where the highlight begins. */
24581 if (r2 != r1)
24583 if (!r2->reversed_p)
24585 glyph = r2->glyphs[TEXT_AREA];
24586 end = glyph + r2->used[TEXT_AREA];
24587 x = r2->x;
24589 else
24591 end = r2->glyphs[TEXT_AREA] - 1;
24592 glyph = end + r2->used[TEXT_AREA];
24596 if (!r2->reversed_p)
24598 /* Skip truncation and continuation glyphs near the end of the
24599 row, and also blanks and stretch glyphs inserted by
24600 extend_face_to_end_of_line. */
24601 while (end > glyph
24602 && INTEGERP ((end - 1)->object)
24603 && (end - 1)->charpos <= 0)
24604 --end;
24605 /* Scan the rest of the glyph row from the end, looking for the
24606 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
24607 DISPLAY_STRING, or whose position is between START_CHARPOS
24608 and END_CHARPOS */
24609 for (--end;
24610 end > glyph
24611 && !INTEGERP (end->object)
24612 && !EQ (end->object, display_string)
24613 && !(BUFFERP (end->object)
24614 && (end->charpos >= start_charpos
24615 && end->charpos < end_charpos));
24616 --end)
24618 /* BEFORE_STRING or AFTER_STRING are only relevant if they
24619 are present at buffer positions between START_CHARPOS and
24620 END_CHARPOS, or if they come from an overlay. */
24621 if (EQ (end->object, before_string))
24623 pos = string_buffer_position (w, before_string, start_charpos);
24624 if (!pos || (pos >= start_charpos && pos < end_charpos))
24625 break;
24627 else if (EQ (end->object, after_string))
24629 pos = string_buffer_position (w, after_string, end_charpos);
24630 if (!pos || (pos >= start_charpos && pos < end_charpos))
24631 break;
24634 /* Find the X coordinate of the last glyph to be highlighted. */
24635 for (; glyph <= end; ++glyph)
24636 x += glyph->pixel_width;
24638 hlinfo->mouse_face_end_x = x;
24639 hlinfo->mouse_face_end_col = glyph - r2->glyphs[TEXT_AREA];
24641 else
24643 /* Skip truncation and continuation glyphs near the end of the
24644 row, and also blanks and stretch glyphs inserted by
24645 extend_face_to_end_of_line. */
24646 x = r2->x;
24647 end++;
24648 while (end < glyph
24649 && INTEGERP (end->object)
24650 && end->charpos <= 0)
24652 x += end->pixel_width;
24653 ++end;
24655 /* Scan the rest of the glyph row from the end, looking for the
24656 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
24657 DISPLAY_STRING, or whose position is between START_CHARPOS
24658 and END_CHARPOS */
24659 for ( ;
24660 end < glyph
24661 && !INTEGERP (end->object)
24662 && !EQ (end->object, display_string)
24663 && !(BUFFERP (end->object)
24664 && (end->charpos >= start_charpos
24665 && end->charpos < end_charpos));
24666 ++end)
24668 /* BEFORE_STRING or AFTER_STRING are only relevant if they
24669 are present at buffer positions between START_CHARPOS and
24670 END_CHARPOS, or if they come from an overlay. */
24671 if (EQ (end->object, before_string))
24673 pos = string_buffer_position (w, before_string, start_charpos);
24674 if (!pos || (pos >= start_charpos && pos < end_charpos))
24675 break;
24677 else if (EQ (end->object, after_string))
24679 pos = string_buffer_position (w, after_string, end_charpos);
24680 if (!pos || (pos >= start_charpos && pos < end_charpos))
24681 break;
24683 x += end->pixel_width;
24685 hlinfo->mouse_face_end_x = x;
24686 hlinfo->mouse_face_end_col = end - r2->glyphs[TEXT_AREA];
24689 hlinfo->mouse_face_window = window;
24690 hlinfo->mouse_face_face_id
24691 = face_at_buffer_position (w, mouse_charpos, 0, 0, &ignore,
24692 mouse_charpos + 1,
24693 !hlinfo->mouse_face_hidden, -1);
24694 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
24697 /* The following function is not used anymore (replaced with
24698 mouse_face_from_string_pos), but I leave it here for the time
24699 being, in case someone would. */
24701 #if 0 /* not used */
24703 /* Find the position of the glyph for position POS in OBJECT in
24704 window W's current matrix, and return in *X, *Y the pixel
24705 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
24707 RIGHT_P non-zero means return the position of the right edge of the
24708 glyph, RIGHT_P zero means return the left edge position.
24710 If no glyph for POS exists in the matrix, return the position of
24711 the glyph with the next smaller position that is in the matrix, if
24712 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
24713 exists in the matrix, return the position of the glyph with the
24714 next larger position in OBJECT.
24716 Value is non-zero if a glyph was found. */
24718 static int
24719 fast_find_string_pos (struct window *w, EMACS_INT pos, Lisp_Object object,
24720 int *hpos, int *vpos, int *x, int *y, int right_p)
24722 int yb = window_text_bottom_y (w);
24723 struct glyph_row *r;
24724 struct glyph *best_glyph = NULL;
24725 struct glyph_row *best_row = NULL;
24726 int best_x = 0;
24728 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
24729 r->enabled_p && r->y < yb;
24730 ++r)
24732 struct glyph *g = r->glyphs[TEXT_AREA];
24733 struct glyph *e = g + r->used[TEXT_AREA];
24734 int gx;
24736 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
24737 if (EQ (g->object, object))
24739 if (g->charpos == pos)
24741 best_glyph = g;
24742 best_x = gx;
24743 best_row = r;
24744 goto found;
24746 else if (best_glyph == NULL
24747 || ((eabs (g->charpos - pos)
24748 < eabs (best_glyph->charpos - pos))
24749 && (right_p
24750 ? g->charpos < pos
24751 : g->charpos > pos)))
24753 best_glyph = g;
24754 best_x = gx;
24755 best_row = r;
24760 found:
24762 if (best_glyph)
24764 *x = best_x;
24765 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
24767 if (right_p)
24769 *x += best_glyph->pixel_width;
24770 ++*hpos;
24773 *y = best_row->y;
24774 *vpos = best_row - w->current_matrix->rows;
24777 return best_glyph != NULL;
24779 #endif /* not used */
24781 /* Find the positions of the first and the last glyphs in window W's
24782 current matrix that occlude positions [STARTPOS..ENDPOS] in OBJECT
24783 (assumed to be a string), and return in HLINFO's mouse_face_*
24784 members the pixel and column/row coordinates of those glyphs. */
24786 static void
24787 mouse_face_from_string_pos (struct window *w, Mouse_HLInfo *hlinfo,
24788 Lisp_Object object,
24789 EMACS_INT startpos, EMACS_INT endpos)
24791 int yb = window_text_bottom_y (w);
24792 struct glyph_row *r;
24793 struct glyph *g, *e;
24794 int gx;
24795 int found = 0;
24797 /* Find the glyph row with at least one position in the range
24798 [STARTPOS..ENDPOS], and the first glyph in that row whose
24799 position belongs to that range. */
24800 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
24801 r->enabled_p && r->y < yb;
24802 ++r)
24804 if (!r->reversed_p)
24806 g = r->glyphs[TEXT_AREA];
24807 e = g + r->used[TEXT_AREA];
24808 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
24809 if (EQ (g->object, object)
24810 && startpos <= g->charpos && g->charpos <= endpos)
24812 hlinfo->mouse_face_beg_row = r - w->current_matrix->rows;
24813 hlinfo->mouse_face_beg_y = r->y;
24814 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
24815 hlinfo->mouse_face_beg_x = gx;
24816 found = 1;
24817 break;
24820 else
24822 struct glyph *g1;
24824 e = r->glyphs[TEXT_AREA];
24825 g = e + r->used[TEXT_AREA];
24826 for ( ; g > e; --g)
24827 if (EQ ((g-1)->object, object)
24828 && startpos <= (g-1)->charpos && (g-1)->charpos <= endpos)
24830 hlinfo->mouse_face_beg_row = r - w->current_matrix->rows;
24831 hlinfo->mouse_face_beg_y = r->y;
24832 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
24833 for (gx = r->x, g1 = r->glyphs[TEXT_AREA]; g1 < g; ++g1)
24834 gx += g1->pixel_width;
24835 hlinfo->mouse_face_beg_x = gx;
24836 found = 1;
24837 break;
24840 if (found)
24841 break;
24844 if (!found)
24845 return;
24847 /* Starting with the next row, look for the first row which does NOT
24848 include any glyphs whose positions are in the range. */
24849 for (++r; r->enabled_p && r->y < yb; ++r)
24851 g = r->glyphs[TEXT_AREA];
24852 e = g + r->used[TEXT_AREA];
24853 found = 0;
24854 for ( ; g < e; ++g)
24855 if (EQ (g->object, object)
24856 && startpos <= g->charpos && g->charpos <= endpos)
24858 found = 1;
24859 break;
24861 if (!found)
24862 break;
24865 /* The highlighted region ends on the previous row. */
24866 r--;
24868 /* Set the end row and its vertical pixel coordinate. */
24869 hlinfo->mouse_face_end_row = r - w->current_matrix->rows;
24870 hlinfo->mouse_face_end_y = r->y;
24872 /* Compute and set the end column and the end column's horizontal
24873 pixel coordinate. */
24874 if (!r->reversed_p)
24876 g = r->glyphs[TEXT_AREA];
24877 e = g + r->used[TEXT_AREA];
24878 for ( ; e > g; --e)
24879 if (EQ ((e-1)->object, object)
24880 && startpos <= (e-1)->charpos && (e-1)->charpos <= endpos)
24881 break;
24882 hlinfo->mouse_face_end_col = e - g;
24884 for (gx = r->x; g < e; ++g)
24885 gx += g->pixel_width;
24886 hlinfo->mouse_face_end_x = gx;
24888 else
24890 e = r->glyphs[TEXT_AREA];
24891 g = e + r->used[TEXT_AREA];
24892 for (gx = r->x ; e < g; ++e)
24894 if (EQ (e->object, object)
24895 && startpos <= e->charpos && e->charpos <= endpos)
24896 break;
24897 gx += e->pixel_width;
24899 hlinfo->mouse_face_end_col = e - r->glyphs[TEXT_AREA];
24900 hlinfo->mouse_face_end_x = gx;
24904 #ifdef HAVE_WINDOW_SYSTEM
24906 /* See if position X, Y is within a hot-spot of an image. */
24908 static int
24909 on_hot_spot_p (Lisp_Object hot_spot, int x, int y)
24911 if (!CONSP (hot_spot))
24912 return 0;
24914 if (EQ (XCAR (hot_spot), Qrect))
24916 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
24917 Lisp_Object rect = XCDR (hot_spot);
24918 Lisp_Object tem;
24919 if (!CONSP (rect))
24920 return 0;
24921 if (!CONSP (XCAR (rect)))
24922 return 0;
24923 if (!CONSP (XCDR (rect)))
24924 return 0;
24925 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
24926 return 0;
24927 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
24928 return 0;
24929 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
24930 return 0;
24931 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
24932 return 0;
24933 return 1;
24935 else if (EQ (XCAR (hot_spot), Qcircle))
24937 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
24938 Lisp_Object circ = XCDR (hot_spot);
24939 Lisp_Object lr, lx0, ly0;
24940 if (CONSP (circ)
24941 && CONSP (XCAR (circ))
24942 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
24943 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
24944 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
24946 double r = XFLOATINT (lr);
24947 double dx = XINT (lx0) - x;
24948 double dy = XINT (ly0) - y;
24949 return (dx * dx + dy * dy <= r * r);
24952 else if (EQ (XCAR (hot_spot), Qpoly))
24954 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
24955 if (VECTORP (XCDR (hot_spot)))
24957 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
24958 Lisp_Object *poly = v->contents;
24959 int n = v->size;
24960 int i;
24961 int inside = 0;
24962 Lisp_Object lx, ly;
24963 int x0, y0;
24965 /* Need an even number of coordinates, and at least 3 edges. */
24966 if (n < 6 || n & 1)
24967 return 0;
24969 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
24970 If count is odd, we are inside polygon. Pixels on edges
24971 may or may not be included depending on actual geometry of the
24972 polygon. */
24973 if ((lx = poly[n-2], !INTEGERP (lx))
24974 || (ly = poly[n-1], !INTEGERP (lx)))
24975 return 0;
24976 x0 = XINT (lx), y0 = XINT (ly);
24977 for (i = 0; i < n; i += 2)
24979 int x1 = x0, y1 = y0;
24980 if ((lx = poly[i], !INTEGERP (lx))
24981 || (ly = poly[i+1], !INTEGERP (ly)))
24982 return 0;
24983 x0 = XINT (lx), y0 = XINT (ly);
24985 /* Does this segment cross the X line? */
24986 if (x0 >= x)
24988 if (x1 >= x)
24989 continue;
24991 else if (x1 < x)
24992 continue;
24993 if (y > y0 && y > y1)
24994 continue;
24995 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
24996 inside = !inside;
24998 return inside;
25001 return 0;
25004 Lisp_Object
25005 find_hot_spot (Lisp_Object map, int x, int y)
25007 while (CONSP (map))
25009 if (CONSP (XCAR (map))
25010 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
25011 return XCAR (map);
25012 map = XCDR (map);
25015 return Qnil;
25018 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
25019 3, 3, 0,
25020 doc: /* Lookup in image map MAP coordinates X and Y.
25021 An image map is an alist where each element has the format (AREA ID PLIST).
25022 An AREA is specified as either a rectangle, a circle, or a polygon:
25023 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
25024 pixel coordinates of the upper left and bottom right corners.
25025 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
25026 and the radius of the circle; r may be a float or integer.
25027 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
25028 vector describes one corner in the polygon.
25029 Returns the alist element for the first matching AREA in MAP. */)
25030 (Lisp_Object map, Lisp_Object x, Lisp_Object y)
25032 if (NILP (map))
25033 return Qnil;
25035 CHECK_NUMBER (x);
25036 CHECK_NUMBER (y);
25038 return find_hot_spot (map, XINT (x), XINT (y));
25042 /* Display frame CURSOR, optionally using shape defined by POINTER. */
25043 static void
25044 define_frame_cursor1 (struct frame *f, Cursor cursor, Lisp_Object pointer)
25046 /* Do not change cursor shape while dragging mouse. */
25047 if (!NILP (do_mouse_tracking))
25048 return;
25050 if (!NILP (pointer))
25052 if (EQ (pointer, Qarrow))
25053 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
25054 else if (EQ (pointer, Qhand))
25055 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
25056 else if (EQ (pointer, Qtext))
25057 cursor = FRAME_X_OUTPUT (f)->text_cursor;
25058 else if (EQ (pointer, intern ("hdrag")))
25059 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
25060 #ifdef HAVE_X_WINDOWS
25061 else if (EQ (pointer, intern ("vdrag")))
25062 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
25063 #endif
25064 else if (EQ (pointer, intern ("hourglass")))
25065 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
25066 else if (EQ (pointer, Qmodeline))
25067 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
25068 else
25069 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
25072 if (cursor != No_Cursor)
25073 FRAME_RIF (f)->define_frame_cursor (f, cursor);
25076 #endif /* HAVE_WINDOW_SYSTEM */
25078 /* Take proper action when mouse has moved to the mode or header line
25079 or marginal area AREA of window W, x-position X and y-position Y.
25080 X is relative to the start of the text display area of W, so the
25081 width of bitmap areas and scroll bars must be subtracted to get a
25082 position relative to the start of the mode line. */
25084 static void
25085 note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
25086 enum window_part area)
25088 struct window *w = XWINDOW (window);
25089 struct frame *f = XFRAME (w->frame);
25090 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
25091 #ifdef HAVE_WINDOW_SYSTEM
25092 Display_Info *dpyinfo;
25093 #endif
25094 Cursor cursor = No_Cursor;
25095 Lisp_Object pointer = Qnil;
25096 int dx, dy, width, height;
25097 EMACS_INT charpos;
25098 Lisp_Object string, object = Qnil;
25099 Lisp_Object pos, help;
25101 Lisp_Object mouse_face;
25102 int original_x_pixel = x;
25103 struct glyph * glyph = NULL, * row_start_glyph = NULL;
25104 struct glyph_row *row;
25106 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
25108 int x0;
25109 struct glyph *end;
25111 /* Kludge alert: mode_line_string takes X/Y in pixels, but
25112 returns them in row/column units! */
25113 string = mode_line_string (w, area, &x, &y, &charpos,
25114 &object, &dx, &dy, &width, &height);
25116 row = (area == ON_MODE_LINE
25117 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
25118 : MATRIX_HEADER_LINE_ROW (w->current_matrix));
25120 /* Find the glyph under the mouse pointer. */
25121 if (row->mode_line_p && row->enabled_p)
25123 glyph = row_start_glyph = row->glyphs[TEXT_AREA];
25124 end = glyph + row->used[TEXT_AREA];
25126 for (x0 = original_x_pixel;
25127 glyph < end && x0 >= glyph->pixel_width;
25128 ++glyph)
25129 x0 -= glyph->pixel_width;
25131 if (glyph >= end)
25132 glyph = NULL;
25135 else
25137 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
25138 /* Kludge alert: marginal_area_string takes X/Y in pixels, but
25139 returns them in row/column units! */
25140 string = marginal_area_string (w, area, &x, &y, &charpos,
25141 &object, &dx, &dy, &width, &height);
25144 help = Qnil;
25146 #ifdef HAVE_WINDOW_SYSTEM
25147 if (IMAGEP (object))
25149 Lisp_Object image_map, hotspot;
25150 if ((image_map = Fplist_get (XCDR (object), QCmap),
25151 !NILP (image_map))
25152 && (hotspot = find_hot_spot (image_map, dx, dy),
25153 CONSP (hotspot))
25154 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
25156 Lisp_Object area_id, plist;
25158 area_id = XCAR (hotspot);
25159 /* Could check AREA_ID to see if we enter/leave this hot-spot.
25160 If so, we could look for mouse-enter, mouse-leave
25161 properties in PLIST (and do something...). */
25162 hotspot = XCDR (hotspot);
25163 if (CONSP (hotspot)
25164 && (plist = XCAR (hotspot), CONSP (plist)))
25166 pointer = Fplist_get (plist, Qpointer);
25167 if (NILP (pointer))
25168 pointer = Qhand;
25169 help = Fplist_get (plist, Qhelp_echo);
25170 if (!NILP (help))
25172 help_echo_string = help;
25173 /* Is this correct? ++kfs */
25174 XSETWINDOW (help_echo_window, w);
25175 help_echo_object = w->buffer;
25176 help_echo_pos = charpos;
25180 if (NILP (pointer))
25181 pointer = Fplist_get (XCDR (object), QCpointer);
25183 #endif /* HAVE_WINDOW_SYSTEM */
25185 if (STRINGP (string))
25187 pos = make_number (charpos);
25188 /* If we're on a string with `help-echo' text property, arrange
25189 for the help to be displayed. This is done by setting the
25190 global variable help_echo_string to the help string. */
25191 if (NILP (help))
25193 help = Fget_text_property (pos, Qhelp_echo, string);
25194 if (!NILP (help))
25196 help_echo_string = help;
25197 XSETWINDOW (help_echo_window, w);
25198 help_echo_object = string;
25199 help_echo_pos = charpos;
25203 #ifdef HAVE_WINDOW_SYSTEM
25204 if (FRAME_WINDOW_P (f))
25206 dpyinfo = FRAME_X_DISPLAY_INFO (f);
25207 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
25208 if (NILP (pointer))
25209 pointer = Fget_text_property (pos, Qpointer, string);
25211 /* Change the mouse pointer according to what is under X/Y. */
25212 if (NILP (pointer)
25213 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
25215 Lisp_Object map;
25216 map = Fget_text_property (pos, Qlocal_map, string);
25217 if (!KEYMAPP (map))
25218 map = Fget_text_property (pos, Qkeymap, string);
25219 if (!KEYMAPP (map))
25220 cursor = dpyinfo->vertical_scroll_bar_cursor;
25223 #endif
25225 /* Change the mouse face according to what is under X/Y. */
25226 mouse_face = Fget_text_property (pos, Qmouse_face, string);
25227 if (!NILP (mouse_face)
25228 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
25229 && glyph)
25231 Lisp_Object b, e;
25233 struct glyph * tmp_glyph;
25235 int gpos;
25236 int gseq_length;
25237 int total_pixel_width;
25238 EMACS_INT begpos, endpos, ignore;
25240 int vpos, hpos;
25242 b = Fprevious_single_property_change (make_number (charpos + 1),
25243 Qmouse_face, string, Qnil);
25244 if (NILP (b))
25245 begpos = 0;
25246 else
25247 begpos = XINT (b);
25249 e = Fnext_single_property_change (pos, Qmouse_face, string, Qnil);
25250 if (NILP (e))
25251 endpos = SCHARS (string);
25252 else
25253 endpos = XINT (e);
25255 /* Calculate the glyph position GPOS of GLYPH in the
25256 displayed string, relative to the beginning of the
25257 highlighted part of the string.
25259 Note: GPOS is different from CHARPOS. CHARPOS is the
25260 position of GLYPH in the internal string object. A mode
25261 line string format has structures which are converted to
25262 a flattened string by the Emacs Lisp interpreter. The
25263 internal string is an element of those structures. The
25264 displayed string is the flattened string. */
25265 tmp_glyph = row_start_glyph;
25266 while (tmp_glyph < glyph
25267 && (!(EQ (tmp_glyph->object, glyph->object)
25268 && begpos <= tmp_glyph->charpos
25269 && tmp_glyph->charpos < endpos)))
25270 tmp_glyph++;
25271 gpos = glyph - tmp_glyph;
25273 /* Calculate the length GSEQ_LENGTH of the glyph sequence of
25274 the highlighted part of the displayed string to which
25275 GLYPH belongs. Note: GSEQ_LENGTH is different from
25276 SCHARS (STRING), because the latter returns the length of
25277 the internal string. */
25278 for (tmp_glyph = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
25279 tmp_glyph > glyph
25280 && (!(EQ (tmp_glyph->object, glyph->object)
25281 && begpos <= tmp_glyph->charpos
25282 && tmp_glyph->charpos < endpos));
25283 tmp_glyph--)
25285 gseq_length = gpos + (tmp_glyph - glyph) + 1;
25287 /* Calculate the total pixel width of all the glyphs between
25288 the beginning of the highlighted area and GLYPH. */
25289 total_pixel_width = 0;
25290 for (tmp_glyph = glyph - gpos; tmp_glyph != glyph; tmp_glyph++)
25291 total_pixel_width += tmp_glyph->pixel_width;
25293 /* Pre calculation of re-rendering position. Note: X is in
25294 column units here, after the call to mode_line_string or
25295 marginal_area_string. */
25296 hpos = x - gpos;
25297 vpos = (area == ON_MODE_LINE
25298 ? (w->current_matrix)->nrows - 1
25299 : 0);
25301 /* If GLYPH's position is included in the region that is
25302 already drawn in mouse face, we have nothing to do. */
25303 if ( EQ (window, hlinfo->mouse_face_window)
25304 && (!row->reversed_p
25305 ? (hlinfo->mouse_face_beg_col <= hpos
25306 && hpos < hlinfo->mouse_face_end_col)
25307 /* In R2L rows we swap BEG and END, see below. */
25308 : (hlinfo->mouse_face_end_col <= hpos
25309 && hpos < hlinfo->mouse_face_beg_col))
25310 && hlinfo->mouse_face_beg_row == vpos )
25311 return;
25313 if (clear_mouse_face (hlinfo))
25314 cursor = No_Cursor;
25316 if (!row->reversed_p)
25318 hlinfo->mouse_face_beg_col = hpos;
25319 hlinfo->mouse_face_beg_x = original_x_pixel
25320 - (total_pixel_width + dx);
25321 hlinfo->mouse_face_end_col = hpos + gseq_length;
25322 hlinfo->mouse_face_end_x = 0;
25324 else
25326 /* In R2L rows, show_mouse_face expects BEG and END
25327 coordinates to be swapped. */
25328 hlinfo->mouse_face_end_col = hpos;
25329 hlinfo->mouse_face_end_x = original_x_pixel
25330 - (total_pixel_width + dx);
25331 hlinfo->mouse_face_beg_col = hpos + gseq_length;
25332 hlinfo->mouse_face_beg_x = 0;
25335 hlinfo->mouse_face_beg_row = vpos;
25336 hlinfo->mouse_face_end_row = hlinfo->mouse_face_beg_row;
25337 hlinfo->mouse_face_beg_y = 0;
25338 hlinfo->mouse_face_end_y = 0;
25339 hlinfo->mouse_face_past_end = 0;
25340 hlinfo->mouse_face_window = window;
25342 hlinfo->mouse_face_face_id = face_at_string_position (w, string,
25343 charpos,
25344 0, 0, 0,
25345 &ignore,
25346 glyph->face_id,
25348 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
25350 if (NILP (pointer))
25351 pointer = Qhand;
25353 else if ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
25354 clear_mouse_face (hlinfo);
25356 #ifdef HAVE_WINDOW_SYSTEM
25357 if (FRAME_WINDOW_P (f))
25358 define_frame_cursor1 (f, cursor, pointer);
25359 #endif
25363 /* EXPORT:
25364 Take proper action when the mouse has moved to position X, Y on
25365 frame F as regards highlighting characters that have mouse-face
25366 properties. Also de-highlighting chars where the mouse was before.
25367 X and Y can be negative or out of range. */
25369 void
25370 note_mouse_highlight (struct frame *f, int x, int y)
25372 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
25373 enum window_part part;
25374 Lisp_Object window;
25375 struct window *w;
25376 Cursor cursor = No_Cursor;
25377 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
25378 struct buffer *b;
25380 /* When a menu is active, don't highlight because this looks odd. */
25381 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) || defined (MSDOS)
25382 if (popup_activated ())
25383 return;
25384 #endif
25386 if (NILP (Vmouse_highlight)
25387 || !f->glyphs_initialized_p
25388 || f->pointer_invisible)
25389 return;
25391 hlinfo->mouse_face_mouse_x = x;
25392 hlinfo->mouse_face_mouse_y = y;
25393 hlinfo->mouse_face_mouse_frame = f;
25395 if (hlinfo->mouse_face_defer)
25396 return;
25398 if (gc_in_progress)
25400 hlinfo->mouse_face_deferred_gc = 1;
25401 return;
25404 /* Which window is that in? */
25405 window = window_from_coordinates (f, x, y, &part, 1);
25407 /* If we were displaying active text in another window, clear that.
25408 Also clear if we move out of text area in same window. */
25409 if (! EQ (window, hlinfo->mouse_face_window)
25410 || (part != ON_TEXT && part != ON_MODE_LINE && part != ON_HEADER_LINE
25411 && !NILP (hlinfo->mouse_face_window)))
25412 clear_mouse_face (hlinfo);
25414 /* Not on a window -> return. */
25415 if (!WINDOWP (window))
25416 return;
25418 /* Reset help_echo_string. It will get recomputed below. */
25419 help_echo_string = Qnil;
25421 /* Convert to window-relative pixel coordinates. */
25422 w = XWINDOW (window);
25423 frame_to_window_pixel_xy (w, &x, &y);
25425 #ifdef HAVE_WINDOW_SYSTEM
25426 /* Handle tool-bar window differently since it doesn't display a
25427 buffer. */
25428 if (EQ (window, f->tool_bar_window))
25430 note_tool_bar_highlight (f, x, y);
25431 return;
25433 #endif
25435 /* Mouse is on the mode, header line or margin? */
25436 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
25437 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
25439 note_mode_line_or_margin_highlight (window, x, y, part);
25440 return;
25443 #ifdef HAVE_WINDOW_SYSTEM
25444 if (part == ON_VERTICAL_BORDER)
25446 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
25447 help_echo_string = build_string ("drag-mouse-1: resize");
25449 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
25450 || part == ON_SCROLL_BAR)
25451 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
25452 else
25453 cursor = FRAME_X_OUTPUT (f)->text_cursor;
25454 #endif
25456 /* Are we in a window whose display is up to date?
25457 And verify the buffer's text has not changed. */
25458 b = XBUFFER (w->buffer);
25459 if (part == ON_TEXT
25460 && EQ (w->window_end_valid, w->buffer)
25461 && XFASTINT (w->last_modified) == BUF_MODIFF (b)
25462 && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
25464 int hpos, vpos, i, dx, dy, area;
25465 EMACS_INT pos;
25466 struct glyph *glyph;
25467 Lisp_Object object;
25468 Lisp_Object mouse_face = Qnil, overlay = Qnil, position;
25469 Lisp_Object *overlay_vec = NULL;
25470 int noverlays;
25471 struct buffer *obuf;
25472 EMACS_INT obegv, ozv;
25473 int same_region;
25475 /* Find the glyph under X/Y. */
25476 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
25478 #ifdef HAVE_WINDOW_SYSTEM
25479 /* Look for :pointer property on image. */
25480 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
25482 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
25483 if (img != NULL && IMAGEP (img->spec))
25485 Lisp_Object image_map, hotspot;
25486 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
25487 !NILP (image_map))
25488 && (hotspot = find_hot_spot (image_map,
25489 glyph->slice.img.x + dx,
25490 glyph->slice.img.y + dy),
25491 CONSP (hotspot))
25492 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
25494 Lisp_Object area_id, plist;
25496 area_id = XCAR (hotspot);
25497 /* Could check AREA_ID to see if we enter/leave this hot-spot.
25498 If so, we could look for mouse-enter, mouse-leave
25499 properties in PLIST (and do something...). */
25500 hotspot = XCDR (hotspot);
25501 if (CONSP (hotspot)
25502 && (plist = XCAR (hotspot), CONSP (plist)))
25504 pointer = Fplist_get (plist, Qpointer);
25505 if (NILP (pointer))
25506 pointer = Qhand;
25507 help_echo_string = Fplist_get (plist, Qhelp_echo);
25508 if (!NILP (help_echo_string))
25510 help_echo_window = window;
25511 help_echo_object = glyph->object;
25512 help_echo_pos = glyph->charpos;
25516 if (NILP (pointer))
25517 pointer = Fplist_get (XCDR (img->spec), QCpointer);
25520 #endif /* HAVE_WINDOW_SYSTEM */
25522 /* Clear mouse face if X/Y not over text. */
25523 if (glyph == NULL
25524 || area != TEXT_AREA
25525 || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p
25526 /* Glyph's OBJECT is an integer for glyphs inserted by the
25527 display engine for its internal purposes, like truncation
25528 and continuation glyphs and blanks beyond the end of
25529 line's text on text terminals. If we are over such a
25530 glyph, we are not over any text. */
25531 || INTEGERP (glyph->object)
25532 /* R2L rows have a stretch glyph at their front, which
25533 stands for no text, whereas L2R rows have no glyphs at
25534 all beyond the end of text. Treat such stretch glyphs
25535 like we do with NULL glyphs in L2R rows. */
25536 || (MATRIX_ROW (w->current_matrix, vpos)->reversed_p
25537 && glyph == MATRIX_ROW (w->current_matrix, vpos)->glyphs[TEXT_AREA]
25538 && glyph->type == STRETCH_GLYPH
25539 && glyph->avoid_cursor_p))
25541 if (clear_mouse_face (hlinfo))
25542 cursor = No_Cursor;
25543 #ifdef HAVE_WINDOW_SYSTEM
25544 if (FRAME_WINDOW_P (f) && NILP (pointer))
25546 if (area != TEXT_AREA)
25547 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
25548 else
25549 pointer = Vvoid_text_area_pointer;
25551 #endif
25552 goto set_cursor;
25555 pos = glyph->charpos;
25556 object = glyph->object;
25557 if (!STRINGP (object) && !BUFFERP (object))
25558 goto set_cursor;
25560 /* If we get an out-of-range value, return now; avoid an error. */
25561 if (BUFFERP (object) && pos > BUF_Z (b))
25562 goto set_cursor;
25564 /* Make the window's buffer temporarily current for
25565 overlays_at and compute_char_face. */
25566 obuf = current_buffer;
25567 current_buffer = b;
25568 obegv = BEGV;
25569 ozv = ZV;
25570 BEGV = BEG;
25571 ZV = Z;
25573 /* Is this char mouse-active or does it have help-echo? */
25574 position = make_number (pos);
25576 if (BUFFERP (object))
25578 /* Put all the overlays we want in a vector in overlay_vec. */
25579 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
25580 /* Sort overlays into increasing priority order. */
25581 noverlays = sort_overlays (overlay_vec, noverlays, w);
25583 else
25584 noverlays = 0;
25586 same_region = coords_in_mouse_face_p (w, hpos, vpos);
25588 if (same_region)
25589 cursor = No_Cursor;
25591 /* Check mouse-face highlighting. */
25592 if (! same_region
25593 /* If there exists an overlay with mouse-face overlapping
25594 the one we are currently highlighting, we have to
25595 check if we enter the overlapping overlay, and then
25596 highlight only that. */
25597 || (OVERLAYP (hlinfo->mouse_face_overlay)
25598 && mouse_face_overlay_overlaps (hlinfo->mouse_face_overlay)))
25600 /* Find the highest priority overlay with a mouse-face. */
25601 overlay = Qnil;
25602 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
25604 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
25605 if (!NILP (mouse_face))
25606 overlay = overlay_vec[i];
25609 /* If we're highlighting the same overlay as before, there's
25610 no need to do that again. */
25611 if (!NILP (overlay) && EQ (overlay, hlinfo->mouse_face_overlay))
25612 goto check_help_echo;
25613 hlinfo->mouse_face_overlay = overlay;
25615 /* Clear the display of the old active region, if any. */
25616 if (clear_mouse_face (hlinfo))
25617 cursor = No_Cursor;
25619 /* If no overlay applies, get a text property. */
25620 if (NILP (overlay))
25621 mouse_face = Fget_text_property (position, Qmouse_face, object);
25623 /* Next, compute the bounds of the mouse highlighting and
25624 display it. */
25625 if (!NILP (mouse_face) && STRINGP (object))
25627 /* The mouse-highlighting comes from a display string
25628 with a mouse-face. */
25629 Lisp_Object b, e;
25630 EMACS_INT ignore;
25632 b = Fprevious_single_property_change
25633 (make_number (pos + 1), Qmouse_face, object, Qnil);
25634 e = Fnext_single_property_change
25635 (position, Qmouse_face, object, Qnil);
25636 if (NILP (b))
25637 b = make_number (0);
25638 if (NILP (e))
25639 e = make_number (SCHARS (object) - 1);
25640 mouse_face_from_string_pos (w, hlinfo, object,
25641 XINT (b), XINT (e));
25642 hlinfo->mouse_face_past_end = 0;
25643 hlinfo->mouse_face_window = window;
25644 hlinfo->mouse_face_face_id
25645 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
25646 glyph->face_id, 1);
25647 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
25648 cursor = No_Cursor;
25650 else
25652 /* The mouse-highlighting, if any, comes from an overlay
25653 or text property in the buffer. */
25654 Lisp_Object buffer, display_string;
25656 if (STRINGP (object))
25658 /* If we are on a display string with no mouse-face,
25659 check if the text under it has one. */
25660 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
25661 EMACS_INT start = MATRIX_ROW_START_CHARPOS (r);
25662 pos = string_buffer_position (w, object, start);
25663 if (pos > 0)
25665 mouse_face = get_char_property_and_overlay
25666 (make_number (pos), Qmouse_face, w->buffer, &overlay);
25667 buffer = w->buffer;
25668 display_string = object;
25671 else
25673 buffer = object;
25674 display_string = Qnil;
25677 if (!NILP (mouse_face))
25679 Lisp_Object before, after;
25680 Lisp_Object before_string, after_string;
25681 /* To correctly find the limits of mouse highlight
25682 in a bidi-reordered buffer, we must not use the
25683 optimization of limiting the search in
25684 previous-single-property-change and
25685 next-single-property-change, because
25686 rows_from_pos_range needs the real start and end
25687 positions to DTRT in this case. That's because
25688 the first row visible in a window does not
25689 necessarily display the character whose position
25690 is the smallest. */
25691 Lisp_Object lim1 =
25692 NILP (XBUFFER (buffer)->bidi_display_reordering)
25693 ? Fmarker_position (w->start)
25694 : Qnil;
25695 Lisp_Object lim2 =
25696 NILP (XBUFFER (buffer)->bidi_display_reordering)
25697 ? make_number (BUF_Z (XBUFFER (buffer))
25698 - XFASTINT (w->window_end_pos))
25699 : Qnil;
25701 if (NILP (overlay))
25703 /* Handle the text property case. */
25704 before = Fprevious_single_property_change
25705 (make_number (pos + 1), Qmouse_face, buffer, lim1);
25706 after = Fnext_single_property_change
25707 (make_number (pos), Qmouse_face, buffer, lim2);
25708 before_string = after_string = Qnil;
25710 else
25712 /* Handle the overlay case. */
25713 before = Foverlay_start (overlay);
25714 after = Foverlay_end (overlay);
25715 before_string = Foverlay_get (overlay, Qbefore_string);
25716 after_string = Foverlay_get (overlay, Qafter_string);
25718 if (!STRINGP (before_string)) before_string = Qnil;
25719 if (!STRINGP (after_string)) after_string = Qnil;
25722 mouse_face_from_buffer_pos (window, hlinfo, pos,
25723 XFASTINT (before),
25724 XFASTINT (after),
25725 before_string, after_string,
25726 display_string);
25727 cursor = No_Cursor;
25732 check_help_echo:
25734 /* Look for a `help-echo' property. */
25735 if (NILP (help_echo_string)) {
25736 Lisp_Object help, overlay;
25738 /* Check overlays first. */
25739 help = overlay = Qnil;
25740 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
25742 overlay = overlay_vec[i];
25743 help = Foverlay_get (overlay, Qhelp_echo);
25746 if (!NILP (help))
25748 help_echo_string = help;
25749 help_echo_window = window;
25750 help_echo_object = overlay;
25751 help_echo_pos = pos;
25753 else
25755 Lisp_Object object = glyph->object;
25756 EMACS_INT charpos = glyph->charpos;
25758 /* Try text properties. */
25759 if (STRINGP (object)
25760 && charpos >= 0
25761 && charpos < SCHARS (object))
25763 help = Fget_text_property (make_number (charpos),
25764 Qhelp_echo, object);
25765 if (NILP (help))
25767 /* If the string itself doesn't specify a help-echo,
25768 see if the buffer text ``under'' it does. */
25769 struct glyph_row *r
25770 = MATRIX_ROW (w->current_matrix, vpos);
25771 EMACS_INT start = MATRIX_ROW_START_CHARPOS (r);
25772 EMACS_INT pos = string_buffer_position (w, object, start);
25773 if (pos > 0)
25775 help = Fget_char_property (make_number (pos),
25776 Qhelp_echo, w->buffer);
25777 if (!NILP (help))
25779 charpos = pos;
25780 object = w->buffer;
25785 else if (BUFFERP (object)
25786 && charpos >= BEGV
25787 && charpos < ZV)
25788 help = Fget_text_property (make_number (charpos), Qhelp_echo,
25789 object);
25791 if (!NILP (help))
25793 help_echo_string = help;
25794 help_echo_window = window;
25795 help_echo_object = object;
25796 help_echo_pos = charpos;
25801 #ifdef HAVE_WINDOW_SYSTEM
25802 /* Look for a `pointer' property. */
25803 if (FRAME_WINDOW_P (f) && NILP (pointer))
25805 /* Check overlays first. */
25806 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
25807 pointer = Foverlay_get (overlay_vec[i], Qpointer);
25809 if (NILP (pointer))
25811 Lisp_Object object = glyph->object;
25812 EMACS_INT charpos = glyph->charpos;
25814 /* Try text properties. */
25815 if (STRINGP (object)
25816 && charpos >= 0
25817 && charpos < SCHARS (object))
25819 pointer = Fget_text_property (make_number (charpos),
25820 Qpointer, object);
25821 if (NILP (pointer))
25823 /* If the string itself doesn't specify a pointer,
25824 see if the buffer text ``under'' it does. */
25825 struct glyph_row *r
25826 = MATRIX_ROW (w->current_matrix, vpos);
25827 EMACS_INT start = MATRIX_ROW_START_CHARPOS (r);
25828 EMACS_INT pos = string_buffer_position (w, object,
25829 start);
25830 if (pos > 0)
25831 pointer = Fget_char_property (make_number (pos),
25832 Qpointer, w->buffer);
25835 else if (BUFFERP (object)
25836 && charpos >= BEGV
25837 && charpos < ZV)
25838 pointer = Fget_text_property (make_number (charpos),
25839 Qpointer, object);
25842 #endif /* HAVE_WINDOW_SYSTEM */
25844 BEGV = obegv;
25845 ZV = ozv;
25846 current_buffer = obuf;
25849 set_cursor:
25851 #ifdef HAVE_WINDOW_SYSTEM
25852 if (FRAME_WINDOW_P (f))
25853 define_frame_cursor1 (f, cursor, pointer);
25854 #else
25855 /* This is here to prevent a compiler error, about "label at end of
25856 compound statement". */
25857 return;
25858 #endif
25862 /* EXPORT for RIF:
25863 Clear any mouse-face on window W. This function is part of the
25864 redisplay interface, and is called from try_window_id and similar
25865 functions to ensure the mouse-highlight is off. */
25867 void
25868 x_clear_window_mouse_face (struct window *w)
25870 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
25871 Lisp_Object window;
25873 BLOCK_INPUT;
25874 XSETWINDOW (window, w);
25875 if (EQ (window, hlinfo->mouse_face_window))
25876 clear_mouse_face (hlinfo);
25877 UNBLOCK_INPUT;
25881 /* EXPORT:
25882 Just discard the mouse face information for frame F, if any.
25883 This is used when the size of F is changed. */
25885 void
25886 cancel_mouse_face (struct frame *f)
25888 Lisp_Object window;
25889 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
25891 window = hlinfo->mouse_face_window;
25892 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
25894 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
25895 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
25896 hlinfo->mouse_face_window = Qnil;
25902 /***********************************************************************
25903 Exposure Events
25904 ***********************************************************************/
25906 #ifdef HAVE_WINDOW_SYSTEM
25908 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
25909 which intersects rectangle R. R is in window-relative coordinates. */
25911 static void
25912 expose_area (struct window *w, struct glyph_row *row, XRectangle *r,
25913 enum glyph_row_area area)
25915 struct glyph *first = row->glyphs[area];
25916 struct glyph *end = row->glyphs[area] + row->used[area];
25917 struct glyph *last;
25918 int first_x, start_x, x;
25920 if (area == TEXT_AREA && row->fill_line_p)
25921 /* If row extends face to end of line write the whole line. */
25922 draw_glyphs (w, 0, row, area,
25923 0, row->used[area],
25924 DRAW_NORMAL_TEXT, 0);
25925 else
25927 /* Set START_X to the window-relative start position for drawing glyphs of
25928 AREA. The first glyph of the text area can be partially visible.
25929 The first glyphs of other areas cannot. */
25930 start_x = window_box_left_offset (w, area);
25931 x = start_x;
25932 if (area == TEXT_AREA)
25933 x += row->x;
25935 /* Find the first glyph that must be redrawn. */
25936 while (first < end
25937 && x + first->pixel_width < r->x)
25939 x += first->pixel_width;
25940 ++first;
25943 /* Find the last one. */
25944 last = first;
25945 first_x = x;
25946 while (last < end
25947 && x < r->x + r->width)
25949 x += last->pixel_width;
25950 ++last;
25953 /* Repaint. */
25954 if (last > first)
25955 draw_glyphs (w, first_x - start_x, row, area,
25956 first - row->glyphs[area], last - row->glyphs[area],
25957 DRAW_NORMAL_TEXT, 0);
25962 /* Redraw the parts of the glyph row ROW on window W intersecting
25963 rectangle R. R is in window-relative coordinates. Value is
25964 non-zero if mouse-face was overwritten. */
25966 static int
25967 expose_line (struct window *w, struct glyph_row *row, XRectangle *r)
25969 xassert (row->enabled_p);
25971 if (row->mode_line_p || w->pseudo_window_p)
25972 draw_glyphs (w, 0, row, TEXT_AREA,
25973 0, row->used[TEXT_AREA],
25974 DRAW_NORMAL_TEXT, 0);
25975 else
25977 if (row->used[LEFT_MARGIN_AREA])
25978 expose_area (w, row, r, LEFT_MARGIN_AREA);
25979 if (row->used[TEXT_AREA])
25980 expose_area (w, row, r, TEXT_AREA);
25981 if (row->used[RIGHT_MARGIN_AREA])
25982 expose_area (w, row, r, RIGHT_MARGIN_AREA);
25983 draw_row_fringe_bitmaps (w, row);
25986 return row->mouse_face_p;
25990 /* Redraw those parts of glyphs rows during expose event handling that
25991 overlap other rows. Redrawing of an exposed line writes over parts
25992 of lines overlapping that exposed line; this function fixes that.
25994 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
25995 row in W's current matrix that is exposed and overlaps other rows.
25996 LAST_OVERLAPPING_ROW is the last such row. */
25998 static void
25999 expose_overlaps (struct window *w,
26000 struct glyph_row *first_overlapping_row,
26001 struct glyph_row *last_overlapping_row,
26002 XRectangle *r)
26004 struct glyph_row *row;
26006 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
26007 if (row->overlapping_p)
26009 xassert (row->enabled_p && !row->mode_line_p);
26011 row->clip = r;
26012 if (row->used[LEFT_MARGIN_AREA])
26013 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA, OVERLAPS_BOTH);
26015 if (row->used[TEXT_AREA])
26016 x_fix_overlapping_area (w, row, TEXT_AREA, OVERLAPS_BOTH);
26018 if (row->used[RIGHT_MARGIN_AREA])
26019 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, OVERLAPS_BOTH);
26020 row->clip = NULL;
26025 /* Return non-zero if W's cursor intersects rectangle R. */
26027 static int
26028 phys_cursor_in_rect_p (struct window *w, XRectangle *r)
26030 XRectangle cr, result;
26031 struct glyph *cursor_glyph;
26032 struct glyph_row *row;
26034 if (w->phys_cursor.vpos >= 0
26035 && w->phys_cursor.vpos < w->current_matrix->nrows
26036 && (row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos),
26037 row->enabled_p)
26038 && row->cursor_in_fringe_p)
26040 /* Cursor is in the fringe. */
26041 cr.x = window_box_right_offset (w,
26042 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
26043 ? RIGHT_MARGIN_AREA
26044 : TEXT_AREA));
26045 cr.y = row->y;
26046 cr.width = WINDOW_RIGHT_FRINGE_WIDTH (w);
26047 cr.height = row->height;
26048 return x_intersect_rectangles (&cr, r, &result);
26051 cursor_glyph = get_phys_cursor_glyph (w);
26052 if (cursor_glyph)
26054 /* r is relative to W's box, but w->phys_cursor.x is relative
26055 to left edge of W's TEXT area. Adjust it. */
26056 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
26057 cr.y = w->phys_cursor.y;
26058 cr.width = cursor_glyph->pixel_width;
26059 cr.height = w->phys_cursor_height;
26060 /* ++KFS: W32 version used W32-specific IntersectRect here, but
26061 I assume the effect is the same -- and this is portable. */
26062 return x_intersect_rectangles (&cr, r, &result);
26064 /* If we don't understand the format, pretend we're not in the hot-spot. */
26065 return 0;
26069 /* EXPORT:
26070 Draw a vertical window border to the right of window W if W doesn't
26071 have vertical scroll bars. */
26073 void
26074 x_draw_vertical_border (struct window *w)
26076 struct frame *f = XFRAME (WINDOW_FRAME (w));
26078 /* We could do better, if we knew what type of scroll-bar the adjacent
26079 windows (on either side) have... But we don't :-(
26080 However, I think this works ok. ++KFS 2003-04-25 */
26082 /* Redraw borders between horizontally adjacent windows. Don't
26083 do it for frames with vertical scroll bars because either the
26084 right scroll bar of a window, or the left scroll bar of its
26085 neighbor will suffice as a border. */
26086 if (FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (w->frame)))
26087 return;
26089 if (!WINDOW_RIGHTMOST_P (w)
26090 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
26092 int x0, x1, y0, y1;
26094 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
26095 y1 -= 1;
26097 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
26098 x1 -= 1;
26100 FRAME_RIF (f)->draw_vertical_window_border (w, x1, y0, y1);
26102 else if (!WINDOW_LEFTMOST_P (w)
26103 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
26105 int x0, x1, y0, y1;
26107 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
26108 y1 -= 1;
26110 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
26111 x0 -= 1;
26113 FRAME_RIF (f)->draw_vertical_window_border (w, x0, y0, y1);
26118 /* Redraw the part of window W intersection rectangle FR. Pixel
26119 coordinates in FR are frame-relative. Call this function with
26120 input blocked. Value is non-zero if the exposure overwrites
26121 mouse-face. */
26123 static int
26124 expose_window (struct window *w, XRectangle *fr)
26126 struct frame *f = XFRAME (w->frame);
26127 XRectangle wr, r;
26128 int mouse_face_overwritten_p = 0;
26130 /* If window is not yet fully initialized, do nothing. This can
26131 happen when toolkit scroll bars are used and a window is split.
26132 Reconfiguring the scroll bar will generate an expose for a newly
26133 created window. */
26134 if (w->current_matrix == NULL)
26135 return 0;
26137 /* When we're currently updating the window, display and current
26138 matrix usually don't agree. Arrange for a thorough display
26139 later. */
26140 if (w == updated_window)
26142 SET_FRAME_GARBAGED (f);
26143 return 0;
26146 /* Frame-relative pixel rectangle of W. */
26147 wr.x = WINDOW_LEFT_EDGE_X (w);
26148 wr.y = WINDOW_TOP_EDGE_Y (w);
26149 wr.width = WINDOW_TOTAL_WIDTH (w);
26150 wr.height = WINDOW_TOTAL_HEIGHT (w);
26152 if (x_intersect_rectangles (fr, &wr, &r))
26154 int yb = window_text_bottom_y (w);
26155 struct glyph_row *row;
26156 int cursor_cleared_p;
26157 struct glyph_row *first_overlapping_row, *last_overlapping_row;
26159 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
26160 r.x, r.y, r.width, r.height));
26162 /* Convert to window coordinates. */
26163 r.x -= WINDOW_LEFT_EDGE_X (w);
26164 r.y -= WINDOW_TOP_EDGE_Y (w);
26166 /* Turn off the cursor. */
26167 if (!w->pseudo_window_p
26168 && phys_cursor_in_rect_p (w, &r))
26170 x_clear_cursor (w);
26171 cursor_cleared_p = 1;
26173 else
26174 cursor_cleared_p = 0;
26176 /* Update lines intersecting rectangle R. */
26177 first_overlapping_row = last_overlapping_row = NULL;
26178 for (row = w->current_matrix->rows;
26179 row->enabled_p;
26180 ++row)
26182 int y0 = row->y;
26183 int y1 = MATRIX_ROW_BOTTOM_Y (row);
26185 if ((y0 >= r.y && y0 < r.y + r.height)
26186 || (y1 > r.y && y1 < r.y + r.height)
26187 || (r.y >= y0 && r.y < y1)
26188 || (r.y + r.height > y0 && r.y + r.height < y1))
26190 /* A header line may be overlapping, but there is no need
26191 to fix overlapping areas for them. KFS 2005-02-12 */
26192 if (row->overlapping_p && !row->mode_line_p)
26194 if (first_overlapping_row == NULL)
26195 first_overlapping_row = row;
26196 last_overlapping_row = row;
26199 row->clip = fr;
26200 if (expose_line (w, row, &r))
26201 mouse_face_overwritten_p = 1;
26202 row->clip = NULL;
26204 else if (row->overlapping_p)
26206 /* We must redraw a row overlapping the exposed area. */
26207 if (y0 < r.y
26208 ? y0 + row->phys_height > r.y
26209 : y0 + row->ascent - row->phys_ascent < r.y +r.height)
26211 if (first_overlapping_row == NULL)
26212 first_overlapping_row = row;
26213 last_overlapping_row = row;
26217 if (y1 >= yb)
26218 break;
26221 /* Display the mode line if there is one. */
26222 if (WINDOW_WANTS_MODELINE_P (w)
26223 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
26224 row->enabled_p)
26225 && row->y < r.y + r.height)
26227 if (expose_line (w, row, &r))
26228 mouse_face_overwritten_p = 1;
26231 if (!w->pseudo_window_p)
26233 /* Fix the display of overlapping rows. */
26234 if (first_overlapping_row)
26235 expose_overlaps (w, first_overlapping_row, last_overlapping_row,
26236 fr);
26238 /* Draw border between windows. */
26239 x_draw_vertical_border (w);
26241 /* Turn the cursor on again. */
26242 if (cursor_cleared_p)
26243 update_window_cursor (w, 1);
26247 return mouse_face_overwritten_p;
26252 /* Redraw (parts) of all windows in the window tree rooted at W that
26253 intersect R. R contains frame pixel coordinates. Value is
26254 non-zero if the exposure overwrites mouse-face. */
26256 static int
26257 expose_window_tree (struct window *w, XRectangle *r)
26259 struct frame *f = XFRAME (w->frame);
26260 int mouse_face_overwritten_p = 0;
26262 while (w && !FRAME_GARBAGED_P (f))
26264 if (!NILP (w->hchild))
26265 mouse_face_overwritten_p
26266 |= expose_window_tree (XWINDOW (w->hchild), r);
26267 else if (!NILP (w->vchild))
26268 mouse_face_overwritten_p
26269 |= expose_window_tree (XWINDOW (w->vchild), r);
26270 else
26271 mouse_face_overwritten_p |= expose_window (w, r);
26273 w = NILP (w->next) ? NULL : XWINDOW (w->next);
26276 return mouse_face_overwritten_p;
26280 /* EXPORT:
26281 Redisplay an exposed area of frame F. X and Y are the upper-left
26282 corner of the exposed rectangle. W and H are width and height of
26283 the exposed area. All are pixel values. W or H zero means redraw
26284 the entire frame. */
26286 void
26287 expose_frame (struct frame *f, int x, int y, int w, int h)
26289 XRectangle r;
26290 int mouse_face_overwritten_p = 0;
26292 TRACE ((stderr, "expose_frame "));
26294 /* No need to redraw if frame will be redrawn soon. */
26295 if (FRAME_GARBAGED_P (f))
26297 TRACE ((stderr, " garbaged\n"));
26298 return;
26301 /* If basic faces haven't been realized yet, there is no point in
26302 trying to redraw anything. This can happen when we get an expose
26303 event while Emacs is starting, e.g. by moving another window. */
26304 if (FRAME_FACE_CACHE (f) == NULL
26305 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
26307 TRACE ((stderr, " no faces\n"));
26308 return;
26311 if (w == 0 || h == 0)
26313 r.x = r.y = 0;
26314 r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f);
26315 r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f);
26317 else
26319 r.x = x;
26320 r.y = y;
26321 r.width = w;
26322 r.height = h;
26325 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
26326 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
26328 if (WINDOWP (f->tool_bar_window))
26329 mouse_face_overwritten_p
26330 |= expose_window (XWINDOW (f->tool_bar_window), &r);
26332 #ifdef HAVE_X_WINDOWS
26333 #ifndef MSDOS
26334 #ifndef USE_X_TOOLKIT
26335 if (WINDOWP (f->menu_bar_window))
26336 mouse_face_overwritten_p
26337 |= expose_window (XWINDOW (f->menu_bar_window), &r);
26338 #endif /* not USE_X_TOOLKIT */
26339 #endif
26340 #endif
26342 /* Some window managers support a focus-follows-mouse style with
26343 delayed raising of frames. Imagine a partially obscured frame,
26344 and moving the mouse into partially obscured mouse-face on that
26345 frame. The visible part of the mouse-face will be highlighted,
26346 then the WM raises the obscured frame. With at least one WM, KDE
26347 2.1, Emacs is not getting any event for the raising of the frame
26348 (even tried with SubstructureRedirectMask), only Expose events.
26349 These expose events will draw text normally, i.e. not
26350 highlighted. Which means we must redo the highlight here.
26351 Subsume it under ``we love X''. --gerd 2001-08-15 */
26352 /* Included in Windows version because Windows most likely does not
26353 do the right thing if any third party tool offers
26354 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
26355 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
26357 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
26358 if (f == hlinfo->mouse_face_mouse_frame)
26360 int x = hlinfo->mouse_face_mouse_x;
26361 int y = hlinfo->mouse_face_mouse_y;
26362 clear_mouse_face (hlinfo);
26363 note_mouse_highlight (f, x, y);
26369 /* EXPORT:
26370 Determine the intersection of two rectangles R1 and R2. Return
26371 the intersection in *RESULT. Value is non-zero if RESULT is not
26372 empty. */
26375 x_intersect_rectangles (XRectangle *r1, XRectangle *r2, XRectangle *result)
26377 XRectangle *left, *right;
26378 XRectangle *upper, *lower;
26379 int intersection_p = 0;
26381 /* Rearrange so that R1 is the left-most rectangle. */
26382 if (r1->x < r2->x)
26383 left = r1, right = r2;
26384 else
26385 left = r2, right = r1;
26387 /* X0 of the intersection is right.x0, if this is inside R1,
26388 otherwise there is no intersection. */
26389 if (right->x <= left->x + left->width)
26391 result->x = right->x;
26393 /* The right end of the intersection is the minimum of the
26394 the right ends of left and right. */
26395 result->width = (min (left->x + left->width, right->x + right->width)
26396 - result->x);
26398 /* Same game for Y. */
26399 if (r1->y < r2->y)
26400 upper = r1, lower = r2;
26401 else
26402 upper = r2, lower = r1;
26404 /* The upper end of the intersection is lower.y0, if this is inside
26405 of upper. Otherwise, there is no intersection. */
26406 if (lower->y <= upper->y + upper->height)
26408 result->y = lower->y;
26410 /* The lower end of the intersection is the minimum of the lower
26411 ends of upper and lower. */
26412 result->height = (min (lower->y + lower->height,
26413 upper->y + upper->height)
26414 - result->y);
26415 intersection_p = 1;
26419 return intersection_p;
26422 #endif /* HAVE_WINDOW_SYSTEM */
26425 /***********************************************************************
26426 Initialization
26427 ***********************************************************************/
26429 void
26430 syms_of_xdisp (void)
26432 Vwith_echo_area_save_vector = Qnil;
26433 staticpro (&Vwith_echo_area_save_vector);
26435 Vmessage_stack = Qnil;
26436 staticpro (&Vmessage_stack);
26438 Qinhibit_redisplay = intern_c_string ("inhibit-redisplay");
26439 staticpro (&Qinhibit_redisplay);
26441 message_dolog_marker1 = Fmake_marker ();
26442 staticpro (&message_dolog_marker1);
26443 message_dolog_marker2 = Fmake_marker ();
26444 staticpro (&message_dolog_marker2);
26445 message_dolog_marker3 = Fmake_marker ();
26446 staticpro (&message_dolog_marker3);
26448 #if GLYPH_DEBUG
26449 defsubr (&Sdump_frame_glyph_matrix);
26450 defsubr (&Sdump_glyph_matrix);
26451 defsubr (&Sdump_glyph_row);
26452 defsubr (&Sdump_tool_bar_row);
26453 defsubr (&Strace_redisplay);
26454 defsubr (&Strace_to_stderr);
26455 #endif
26456 #ifdef HAVE_WINDOW_SYSTEM
26457 defsubr (&Stool_bar_lines_needed);
26458 defsubr (&Slookup_image_map);
26459 #endif
26460 defsubr (&Sformat_mode_line);
26461 defsubr (&Sinvisible_p);
26462 defsubr (&Scurrent_bidi_paragraph_direction);
26464 staticpro (&Qmenu_bar_update_hook);
26465 Qmenu_bar_update_hook = intern_c_string ("menu-bar-update-hook");
26467 staticpro (&Qoverriding_terminal_local_map);
26468 Qoverriding_terminal_local_map = intern_c_string ("overriding-terminal-local-map");
26470 staticpro (&Qoverriding_local_map);
26471 Qoverriding_local_map = intern_c_string ("overriding-local-map");
26473 staticpro (&Qwindow_scroll_functions);
26474 Qwindow_scroll_functions = intern_c_string ("window-scroll-functions");
26476 staticpro (&Qwindow_text_change_functions);
26477 Qwindow_text_change_functions = intern_c_string ("window-text-change-functions");
26479 staticpro (&Qredisplay_end_trigger_functions);
26480 Qredisplay_end_trigger_functions = intern_c_string ("redisplay-end-trigger-functions");
26482 staticpro (&Qinhibit_point_motion_hooks);
26483 Qinhibit_point_motion_hooks = intern_c_string ("inhibit-point-motion-hooks");
26485 Qeval = intern_c_string ("eval");
26486 staticpro (&Qeval);
26488 QCdata = intern_c_string (":data");
26489 staticpro (&QCdata);
26490 Qdisplay = intern_c_string ("display");
26491 staticpro (&Qdisplay);
26492 Qspace_width = intern_c_string ("space-width");
26493 staticpro (&Qspace_width);
26494 Qraise = intern_c_string ("raise");
26495 staticpro (&Qraise);
26496 Qslice = intern_c_string ("slice");
26497 staticpro (&Qslice);
26498 Qspace = intern_c_string ("space");
26499 staticpro (&Qspace);
26500 Qmargin = intern_c_string ("margin");
26501 staticpro (&Qmargin);
26502 Qpointer = intern_c_string ("pointer");
26503 staticpro (&Qpointer);
26504 Qleft_margin = intern_c_string ("left-margin");
26505 staticpro (&Qleft_margin);
26506 Qright_margin = intern_c_string ("right-margin");
26507 staticpro (&Qright_margin);
26508 Qcenter = intern_c_string ("center");
26509 staticpro (&Qcenter);
26510 Qline_height = intern_c_string ("line-height");
26511 staticpro (&Qline_height);
26512 QCalign_to = intern_c_string (":align-to");
26513 staticpro (&QCalign_to);
26514 QCrelative_width = intern_c_string (":relative-width");
26515 staticpro (&QCrelative_width);
26516 QCrelative_height = intern_c_string (":relative-height");
26517 staticpro (&QCrelative_height);
26518 QCeval = intern_c_string (":eval");
26519 staticpro (&QCeval);
26520 QCpropertize = intern_c_string (":propertize");
26521 staticpro (&QCpropertize);
26522 QCfile = intern_c_string (":file");
26523 staticpro (&QCfile);
26524 Qfontified = intern_c_string ("fontified");
26525 staticpro (&Qfontified);
26526 Qfontification_functions = intern_c_string ("fontification-functions");
26527 staticpro (&Qfontification_functions);
26528 Qtrailing_whitespace = intern_c_string ("trailing-whitespace");
26529 staticpro (&Qtrailing_whitespace);
26530 Qescape_glyph = intern_c_string ("escape-glyph");
26531 staticpro (&Qescape_glyph);
26532 Qnobreak_space = intern_c_string ("nobreak-space");
26533 staticpro (&Qnobreak_space);
26534 Qimage = intern_c_string ("image");
26535 staticpro (&Qimage);
26536 Qtext = intern_c_string ("text");
26537 staticpro (&Qtext);
26538 Qboth = intern_c_string ("both");
26539 staticpro (&Qboth);
26540 Qboth_horiz = intern_c_string ("both-horiz");
26541 staticpro (&Qboth_horiz);
26542 Qtext_image_horiz = intern_c_string ("text-image-horiz");
26543 staticpro (&Qtext_image_horiz);
26544 QCmap = intern_c_string (":map");
26545 staticpro (&QCmap);
26546 QCpointer = intern_c_string (":pointer");
26547 staticpro (&QCpointer);
26548 Qrect = intern_c_string ("rect");
26549 staticpro (&Qrect);
26550 Qcircle = intern_c_string ("circle");
26551 staticpro (&Qcircle);
26552 Qpoly = intern_c_string ("poly");
26553 staticpro (&Qpoly);
26554 Qmessage_truncate_lines = intern_c_string ("message-truncate-lines");
26555 staticpro (&Qmessage_truncate_lines);
26556 Qgrow_only = intern_c_string ("grow-only");
26557 staticpro (&Qgrow_only);
26558 Qinhibit_menubar_update = intern_c_string ("inhibit-menubar-update");
26559 staticpro (&Qinhibit_menubar_update);
26560 Qinhibit_eval_during_redisplay = intern_c_string ("inhibit-eval-during-redisplay");
26561 staticpro (&Qinhibit_eval_during_redisplay);
26562 Qposition = intern_c_string ("position");
26563 staticpro (&Qposition);
26564 Qbuffer_position = intern_c_string ("buffer-position");
26565 staticpro (&Qbuffer_position);
26566 Qobject = intern_c_string ("object");
26567 staticpro (&Qobject);
26568 Qbar = intern_c_string ("bar");
26569 staticpro (&Qbar);
26570 Qhbar = intern_c_string ("hbar");
26571 staticpro (&Qhbar);
26572 Qbox = intern_c_string ("box");
26573 staticpro (&Qbox);
26574 Qhollow = intern_c_string ("hollow");
26575 staticpro (&Qhollow);
26576 Qhand = intern_c_string ("hand");
26577 staticpro (&Qhand);
26578 Qarrow = intern_c_string ("arrow");
26579 staticpro (&Qarrow);
26580 Qtext = intern_c_string ("text");
26581 staticpro (&Qtext);
26582 Qinhibit_free_realized_faces = intern_c_string ("inhibit-free-realized-faces");
26583 staticpro (&Qinhibit_free_realized_faces);
26585 list_of_error = Fcons (Fcons (intern_c_string ("error"),
26586 Fcons (intern_c_string ("void-variable"), Qnil)),
26587 Qnil);
26588 staticpro (&list_of_error);
26590 Qlast_arrow_position = intern_c_string ("last-arrow-position");
26591 staticpro (&Qlast_arrow_position);
26592 Qlast_arrow_string = intern_c_string ("last-arrow-string");
26593 staticpro (&Qlast_arrow_string);
26595 Qoverlay_arrow_string = intern_c_string ("overlay-arrow-string");
26596 staticpro (&Qoverlay_arrow_string);
26597 Qoverlay_arrow_bitmap = intern_c_string ("overlay-arrow-bitmap");
26598 staticpro (&Qoverlay_arrow_bitmap);
26600 echo_buffer[0] = echo_buffer[1] = Qnil;
26601 staticpro (&echo_buffer[0]);
26602 staticpro (&echo_buffer[1]);
26604 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
26605 staticpro (&echo_area_buffer[0]);
26606 staticpro (&echo_area_buffer[1]);
26608 Vmessages_buffer_name = make_pure_c_string ("*Messages*");
26609 staticpro (&Vmessages_buffer_name);
26611 mode_line_proptrans_alist = Qnil;
26612 staticpro (&mode_line_proptrans_alist);
26613 mode_line_string_list = Qnil;
26614 staticpro (&mode_line_string_list);
26615 mode_line_string_face = Qnil;
26616 staticpro (&mode_line_string_face);
26617 mode_line_string_face_prop = Qnil;
26618 staticpro (&mode_line_string_face_prop);
26619 Vmode_line_unwind_vector = Qnil;
26620 staticpro (&Vmode_line_unwind_vector);
26622 help_echo_string = Qnil;
26623 staticpro (&help_echo_string);
26624 help_echo_object = Qnil;
26625 staticpro (&help_echo_object);
26626 help_echo_window = Qnil;
26627 staticpro (&help_echo_window);
26628 previous_help_echo_string = Qnil;
26629 staticpro (&previous_help_echo_string);
26630 help_echo_pos = -1;
26632 Qright_to_left = intern_c_string ("right-to-left");
26633 staticpro (&Qright_to_left);
26634 Qleft_to_right = intern_c_string ("left-to-right");
26635 staticpro (&Qleft_to_right);
26637 #ifdef HAVE_WINDOW_SYSTEM
26638 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p,
26639 doc: /* *Non-nil means draw block cursor as wide as the glyph under it.
26640 For example, if a block cursor is over a tab, it will be drawn as
26641 wide as that tab on the display. */);
26642 x_stretch_cursor_p = 0;
26643 #endif
26645 DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace,
26646 doc: /* *Non-nil means highlight trailing whitespace.
26647 The face used for trailing whitespace is `trailing-whitespace'. */);
26648 Vshow_trailing_whitespace = Qnil;
26650 DEFVAR_LISP ("nobreak-char-display", &Vnobreak_char_display,
26651 doc: /* *Control highlighting of nobreak space and soft hyphen.
26652 A value of t means highlight the character itself (for nobreak space,
26653 use face `nobreak-space').
26654 A value of nil means no highlighting.
26655 Other values mean display the escape glyph followed by an ordinary
26656 space or ordinary hyphen. */);
26657 Vnobreak_char_display = Qt;
26659 DEFVAR_LISP ("void-text-area-pointer", &Vvoid_text_area_pointer,
26660 doc: /* *The pointer shape to show in void text areas.
26661 A value of nil means to show the text pointer. Other options are `arrow',
26662 `text', `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
26663 Vvoid_text_area_pointer = Qarrow;
26665 DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay,
26666 doc: /* Non-nil means don't actually do any redisplay.
26667 This is used for internal purposes. */);
26668 Vinhibit_redisplay = Qnil;
26670 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string,
26671 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
26672 Vglobal_mode_string = Qnil;
26674 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position,
26675 doc: /* Marker for where to display an arrow on top of the buffer text.
26676 This must be the beginning of a line in order to work.
26677 See also `overlay-arrow-string'. */);
26678 Voverlay_arrow_position = Qnil;
26680 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string,
26681 doc: /* String to display as an arrow in non-window frames.
26682 See also `overlay-arrow-position'. */);
26683 Voverlay_arrow_string = make_pure_c_string ("=>");
26685 DEFVAR_LISP ("overlay-arrow-variable-list", &Voverlay_arrow_variable_list,
26686 doc: /* List of variables (symbols) which hold markers for overlay arrows.
26687 The symbols on this list are examined during redisplay to determine
26688 where to display overlay arrows. */);
26689 Voverlay_arrow_variable_list
26690 = Fcons (intern_c_string ("overlay-arrow-position"), Qnil);
26692 DEFVAR_INT ("scroll-step", &scroll_step,
26693 doc: /* *The number of lines to try scrolling a window by when point moves out.
26694 If that fails to bring point back on frame, point is centered instead.
26695 If this is zero, point is always centered after it moves off frame.
26696 If you want scrolling to always be a line at a time, you should set
26697 `scroll-conservatively' to a large value rather than set this to 1. */);
26699 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively,
26700 doc: /* *Scroll up to this many lines, to bring point back on screen.
26701 If point moves off-screen, redisplay will scroll by up to
26702 `scroll-conservatively' lines in order to bring point just barely
26703 onto the screen again. If that cannot be done, then redisplay
26704 recenters point as usual.
26706 A value of zero means always recenter point if it moves off screen. */);
26707 scroll_conservatively = 0;
26709 DEFVAR_INT ("scroll-margin", &scroll_margin,
26710 doc: /* *Number of lines of margin at the top and bottom of a window.
26711 Recenter the window whenever point gets within this many lines
26712 of the top or bottom of the window. */);
26713 scroll_margin = 0;
26715 DEFVAR_LISP ("display-pixels-per-inch", &Vdisplay_pixels_per_inch,
26716 doc: /* Pixels per inch value for non-window system displays.
26717 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
26718 Vdisplay_pixels_per_inch = make_float (72.0);
26720 #if GLYPH_DEBUG
26721 DEFVAR_INT ("debug-end-pos", &debug_end_pos, doc: /* Don't ask. */);
26722 #endif
26724 DEFVAR_LISP ("truncate-partial-width-windows",
26725 &Vtruncate_partial_width_windows,
26726 doc: /* Non-nil means truncate lines in windows narrower than the frame.
26727 For an integer value, truncate lines in each window narrower than the
26728 full frame width, provided the window width is less than that integer;
26729 otherwise, respect the value of `truncate-lines'.
26731 For any other non-nil value, truncate lines in all windows that do
26732 not span the full frame width.
26734 A value of nil means to respect the value of `truncate-lines'.
26736 If `word-wrap' is enabled, you might want to reduce this. */);
26737 Vtruncate_partial_width_windows = make_number (50);
26739 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video,
26740 doc: /* When nil, display the mode-line/header-line/menu-bar in the default face.
26741 Any other value means to use the appropriate face, `mode-line',
26742 `header-line', or `menu' respectively. */);
26743 mode_line_inverse_video = 1;
26745 DEFVAR_LISP ("line-number-display-limit", &Vline_number_display_limit,
26746 doc: /* *Maximum buffer size for which line number should be displayed.
26747 If the buffer is bigger than this, the line number does not appear
26748 in the mode line. A value of nil means no limit. */);
26749 Vline_number_display_limit = Qnil;
26751 DEFVAR_INT ("line-number-display-limit-width",
26752 &line_number_display_limit_width,
26753 doc: /* *Maximum line width (in characters) for line number display.
26754 If the average length of the lines near point is bigger than this, then the
26755 line number may be omitted from the mode line. */);
26756 line_number_display_limit_width = 200;
26758 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows,
26759 doc: /* *Non-nil means highlight region even in nonselected windows. */);
26760 highlight_nonselected_windows = 0;
26762 DEFVAR_BOOL ("multiple-frames", &multiple_frames,
26763 doc: /* Non-nil if more than one frame is visible on this display.
26764 Minibuffer-only frames don't count, but iconified frames do.
26765 This variable is not guaranteed to be accurate except while processing
26766 `frame-title-format' and `icon-title-format'. */);
26768 DEFVAR_LISP ("frame-title-format", &Vframe_title_format,
26769 doc: /* Template for displaying the title bar of visible frames.
26770 \(Assuming the window manager supports this feature.)
26772 This variable has the same structure as `mode-line-format', except that
26773 the %c and %l constructs are ignored. It is used only on frames for
26774 which no explicit name has been set \(see `modify-frame-parameters'). */);
26776 DEFVAR_LISP ("icon-title-format", &Vicon_title_format,
26777 doc: /* Template for displaying the title bar of an iconified frame.
26778 \(Assuming the window manager supports this feature.)
26779 This variable has the same structure as `mode-line-format' (which see),
26780 and is used only on frames for which no explicit name has been set
26781 \(see `modify-frame-parameters'). */);
26782 Vicon_title_format
26783 = Vframe_title_format
26784 = pure_cons (intern_c_string ("multiple-frames"),
26785 pure_cons (make_pure_c_string ("%b"),
26786 pure_cons (pure_cons (empty_unibyte_string,
26787 pure_cons (intern_c_string ("invocation-name"),
26788 pure_cons (make_pure_c_string ("@"),
26789 pure_cons (intern_c_string ("system-name"),
26790 Qnil)))),
26791 Qnil)));
26793 DEFVAR_LISP ("message-log-max", &Vmessage_log_max,
26794 doc: /* Maximum number of lines to keep in the message log buffer.
26795 If nil, disable message logging. If t, log messages but don't truncate
26796 the buffer when it becomes large. */);
26797 Vmessage_log_max = make_number (100);
26799 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions,
26800 doc: /* Functions called before redisplay, if window sizes have changed.
26801 The value should be a list of functions that take one argument.
26802 Just before redisplay, for each frame, if any of its windows have changed
26803 size since the last redisplay, or have been split or deleted,
26804 all the functions in the list are called, with the frame as argument. */);
26805 Vwindow_size_change_functions = Qnil;
26807 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions,
26808 doc: /* List of functions to call before redisplaying a window with scrolling.
26809 Each function is called with two arguments, the window and its new
26810 display-start position. Note that these functions are also called by
26811 `set-window-buffer'. Also note that the value of `window-end' is not
26812 valid when these functions are called. */);
26813 Vwindow_scroll_functions = Qnil;
26815 DEFVAR_LISP ("window-text-change-functions",
26816 &Vwindow_text_change_functions,
26817 doc: /* Functions to call in redisplay when text in the window might change. */);
26818 Vwindow_text_change_functions = Qnil;
26820 DEFVAR_LISP ("redisplay-end-trigger-functions", &Vredisplay_end_trigger_functions,
26821 doc: /* Functions called when redisplay of a window reaches the end trigger.
26822 Each function is called with two arguments, the window and the end trigger value.
26823 See `set-window-redisplay-end-trigger'. */);
26824 Vredisplay_end_trigger_functions = Qnil;
26826 DEFVAR_LISP ("mouse-autoselect-window", &Vmouse_autoselect_window,
26827 doc: /* *Non-nil means autoselect window with mouse pointer.
26828 If nil, do not autoselect windows.
26829 A positive number means delay autoselection by that many seconds: a
26830 window is autoselected only after the mouse has remained in that
26831 window for the duration of the delay.
26832 A negative number has a similar effect, but causes windows to be
26833 autoselected only after the mouse has stopped moving. \(Because of
26834 the way Emacs compares mouse events, you will occasionally wait twice
26835 that time before the window gets selected.\)
26836 Any other value means to autoselect window instantaneously when the
26837 mouse pointer enters it.
26839 Autoselection selects the minibuffer only if it is active, and never
26840 unselects the minibuffer if it is active.
26842 When customizing this variable make sure that the actual value of
26843 `focus-follows-mouse' matches the behavior of your window manager. */);
26844 Vmouse_autoselect_window = Qnil;
26846 DEFVAR_LISP ("auto-resize-tool-bars", &Vauto_resize_tool_bars,
26847 doc: /* *Non-nil means automatically resize tool-bars.
26848 This dynamically changes the tool-bar's height to the minimum height
26849 that is needed to make all tool-bar items visible.
26850 If value is `grow-only', the tool-bar's height is only increased
26851 automatically; to decrease the tool-bar height, use \\[recenter]. */);
26852 Vauto_resize_tool_bars = Qt;
26854 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", &auto_raise_tool_bar_buttons_p,
26855 doc: /* *Non-nil means raise tool-bar buttons when the mouse moves over them. */);
26856 auto_raise_tool_bar_buttons_p = 1;
26858 DEFVAR_BOOL ("make-cursor-line-fully-visible", &make_cursor_line_fully_visible_p,
26859 doc: /* *Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
26860 make_cursor_line_fully_visible_p = 1;
26862 DEFVAR_LISP ("tool-bar-border", &Vtool_bar_border,
26863 doc: /* *Border below tool-bar in pixels.
26864 If an integer, use it as the height of the border.
26865 If it is one of `internal-border-width' or `border-width', use the
26866 value of the corresponding frame parameter.
26867 Otherwise, no border is added below the tool-bar. */);
26868 Vtool_bar_border = Qinternal_border_width;
26870 DEFVAR_LISP ("tool-bar-button-margin", &Vtool_bar_button_margin,
26871 doc: /* *Margin around tool-bar buttons in pixels.
26872 If an integer, use that for both horizontal and vertical margins.
26873 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
26874 HORZ specifying the horizontal margin, and VERT specifying the
26875 vertical margin. */);
26876 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
26878 DEFVAR_INT ("tool-bar-button-relief", &tool_bar_button_relief,
26879 doc: /* *Relief thickness of tool-bar buttons. */);
26880 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
26882 DEFVAR_LISP ("tool-bar-style", &Vtool_bar_style,
26883 doc: /* Tool bar style to use.
26884 It can be one of
26885 image - show images only
26886 text - show text only
26887 both - show both, text below image
26888 both-horiz - show text to the right of the image
26889 text-image-horiz - show text to the left of the image
26890 any other - use system default or image if no system default. */);
26891 Vtool_bar_style = Qnil;
26893 DEFVAR_INT ("tool-bar-max-label-size", &tool_bar_max_label_size,
26894 doc: /* *Maximum number of characters a label can have to be shown.
26895 The tool bar style must also show labels for this to have any effect, see
26896 `tool-bar-style'. */);
26897 tool_bar_max_label_size = DEFAULT_TOOL_BAR_LABEL_SIZE;
26899 DEFVAR_LISP ("fontification-functions", &Vfontification_functions,
26900 doc: /* List of functions to call to fontify regions of text.
26901 Each function is called with one argument POS. Functions must
26902 fontify a region starting at POS in the current buffer, and give
26903 fontified regions the property `fontified'. */);
26904 Vfontification_functions = Qnil;
26905 Fmake_variable_buffer_local (Qfontification_functions);
26907 DEFVAR_BOOL ("unibyte-display-via-language-environment",
26908 &unibyte_display_via_language_environment,
26909 doc: /* *Non-nil means display unibyte text according to language environment.
26910 Specifically, this means that raw bytes in the range 160-255 decimal
26911 are displayed by converting them to the equivalent multibyte characters
26912 according to the current language environment. As a result, they are
26913 displayed according to the current fontset.
26915 Note that this variable affects only how these bytes are displayed,
26916 but does not change the fact they are interpreted as raw bytes. */);
26917 unibyte_display_via_language_environment = 0;
26919 DEFVAR_LISP ("max-mini-window-height", &Vmax_mini_window_height,
26920 doc: /* *Maximum height for resizing mini-windows.
26921 If a float, it specifies a fraction of the mini-window frame's height.
26922 If an integer, it specifies a number of lines. */);
26923 Vmax_mini_window_height = make_float (0.25);
26925 DEFVAR_LISP ("resize-mini-windows", &Vresize_mini_windows,
26926 doc: /* *How to resize mini-windows.
26927 A value of nil means don't automatically resize mini-windows.
26928 A value of t means resize them to fit the text displayed in them.
26929 A value of `grow-only', the default, means let mini-windows grow
26930 only, until their display becomes empty, at which point the windows
26931 go back to their normal size. */);
26932 Vresize_mini_windows = Qgrow_only;
26934 DEFVAR_LISP ("blink-cursor-alist", &Vblink_cursor_alist,
26935 doc: /* Alist specifying how to blink the cursor off.
26936 Each element has the form (ON-STATE . OFF-STATE). Whenever the
26937 `cursor-type' frame-parameter or variable equals ON-STATE,
26938 comparing using `equal', Emacs uses OFF-STATE to specify
26939 how to blink it off. ON-STATE and OFF-STATE are values for
26940 the `cursor-type' frame parameter.
26942 If a frame's ON-STATE has no entry in this list,
26943 the frame's other specifications determine how to blink the cursor off. */);
26944 Vblink_cursor_alist = Qnil;
26946 DEFVAR_BOOL ("auto-hscroll-mode", &automatic_hscrolling_p,
26947 doc: /* Allow or disallow automatic horizontal scrolling of windows.
26948 If non-nil, windows are automatically scrolled horizontally to make
26949 point visible. */);
26950 automatic_hscrolling_p = 1;
26951 Qauto_hscroll_mode = intern_c_string ("auto-hscroll-mode");
26952 staticpro (&Qauto_hscroll_mode);
26954 DEFVAR_INT ("hscroll-margin", &hscroll_margin,
26955 doc: /* *How many columns away from the window edge point is allowed to get
26956 before automatic hscrolling will horizontally scroll the window. */);
26957 hscroll_margin = 5;
26959 DEFVAR_LISP ("hscroll-step", &Vhscroll_step,
26960 doc: /* *How many columns to scroll the window when point gets too close to the edge.
26961 When point is less than `hscroll-margin' columns from the window
26962 edge, automatic hscrolling will scroll the window by the amount of columns
26963 determined by this variable. If its value is a positive integer, scroll that
26964 many columns. If it's a positive floating-point number, it specifies the
26965 fraction of the window's width to scroll. If it's nil or zero, point will be
26966 centered horizontally after the scroll. Any other value, including negative
26967 numbers, are treated as if the value were zero.
26969 Automatic hscrolling always moves point outside the scroll margin, so if
26970 point was more than scroll step columns inside the margin, the window will
26971 scroll more than the value given by the scroll step.
26973 Note that the lower bound for automatic hscrolling specified by `scroll-left'
26974 and `scroll-right' overrides this variable's effect. */);
26975 Vhscroll_step = make_number (0);
26977 DEFVAR_BOOL ("message-truncate-lines", &message_truncate_lines,
26978 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
26979 Bind this around calls to `message' to let it take effect. */);
26980 message_truncate_lines = 0;
26982 DEFVAR_LISP ("menu-bar-update-hook", &Vmenu_bar_update_hook,
26983 doc: /* Normal hook run to update the menu bar definitions.
26984 Redisplay runs this hook before it redisplays the menu bar.
26985 This is used to update submenus such as Buffers,
26986 whose contents depend on various data. */);
26987 Vmenu_bar_update_hook = Qnil;
26989 DEFVAR_LISP ("menu-updating-frame", &Vmenu_updating_frame,
26990 doc: /* Frame for which we are updating a menu.
26991 The enable predicate for a menu binding should check this variable. */);
26992 Vmenu_updating_frame = Qnil;
26994 DEFVAR_BOOL ("inhibit-menubar-update", &inhibit_menubar_update,
26995 doc: /* Non-nil means don't update menu bars. Internal use only. */);
26996 inhibit_menubar_update = 0;
26998 DEFVAR_LISP ("wrap-prefix", &Vwrap_prefix,
26999 doc: /* Prefix prepended to all continuation lines at display time.
27000 The value may be a string, an image, or a stretch-glyph; it is
27001 interpreted in the same way as the value of a `display' text property.
27003 This variable is overridden by any `wrap-prefix' text or overlay
27004 property.
27006 To add a prefix to non-continuation lines, use `line-prefix'. */);
27007 Vwrap_prefix = Qnil;
27008 staticpro (&Qwrap_prefix);
27009 Qwrap_prefix = intern_c_string ("wrap-prefix");
27010 Fmake_variable_buffer_local (Qwrap_prefix);
27012 DEFVAR_LISP ("line-prefix", &Vline_prefix,
27013 doc: /* Prefix prepended to all non-continuation lines at display time.
27014 The value may be a string, an image, or a stretch-glyph; it is
27015 interpreted in the same way as the value of a `display' text property.
27017 This variable is overridden by any `line-prefix' text or overlay
27018 property.
27020 To add a prefix to continuation lines, use `wrap-prefix'. */);
27021 Vline_prefix = Qnil;
27022 staticpro (&Qline_prefix);
27023 Qline_prefix = intern_c_string ("line-prefix");
27024 Fmake_variable_buffer_local (Qline_prefix);
27026 DEFVAR_BOOL ("inhibit-eval-during-redisplay", &inhibit_eval_during_redisplay,
27027 doc: /* Non-nil means don't eval Lisp during redisplay. */);
27028 inhibit_eval_during_redisplay = 0;
27030 DEFVAR_BOOL ("inhibit-free-realized-faces", &inhibit_free_realized_faces,
27031 doc: /* Non-nil means don't free realized faces. Internal use only. */);
27032 inhibit_free_realized_faces = 0;
27034 #if GLYPH_DEBUG
27035 DEFVAR_BOOL ("inhibit-try-window-id", &inhibit_try_window_id,
27036 doc: /* Inhibit try_window_id display optimization. */);
27037 inhibit_try_window_id = 0;
27039 DEFVAR_BOOL ("inhibit-try-window-reusing", &inhibit_try_window_reusing,
27040 doc: /* Inhibit try_window_reusing display optimization. */);
27041 inhibit_try_window_reusing = 0;
27043 DEFVAR_BOOL ("inhibit-try-cursor-movement", &inhibit_try_cursor_movement,
27044 doc: /* Inhibit try_cursor_movement display optimization. */);
27045 inhibit_try_cursor_movement = 0;
27046 #endif /* GLYPH_DEBUG */
27048 DEFVAR_INT ("overline-margin", &overline_margin,
27049 doc: /* *Space between overline and text, in pixels.
27050 The default value is 2: the height of the overline (1 pixel) plus 1 pixel
27051 margin to the caracter height. */);
27052 overline_margin = 2;
27054 DEFVAR_INT ("underline-minimum-offset",
27055 &underline_minimum_offset,
27056 doc: /* Minimum distance between baseline and underline.
27057 This can improve legibility of underlined text at small font sizes,
27058 particularly when using variable `x-use-underline-position-properties'
27059 with fonts that specify an UNDERLINE_POSITION relatively close to the
27060 baseline. The default value is 1. */);
27061 underline_minimum_offset = 1;
27063 DEFVAR_BOOL ("display-hourglass", &display_hourglass_p,
27064 doc: /* Non-nil means show an hourglass pointer, when Emacs is busy.
27065 This feature only works when on a window system that can change
27066 cursor shapes. */);
27067 display_hourglass_p = 1;
27069 DEFVAR_LISP ("hourglass-delay", &Vhourglass_delay,
27070 doc: /* *Seconds to wait before displaying an hourglass pointer when Emacs is busy. */);
27071 Vhourglass_delay = make_number (DEFAULT_HOURGLASS_DELAY);
27073 hourglass_atimer = NULL;
27074 hourglass_shown_p = 0;
27076 DEFSYM (Qglyphless_char, "glyphless-char");
27077 DEFSYM (Qhex_code, "hex-code");
27078 DEFSYM (Qempty_box, "empty-box");
27079 DEFSYM (Qthin_space, "thin-space");
27080 DEFSYM (Qzero_width, "zero-width");
27082 DEFSYM (Qglyphless_char_display, "glyphless-char-display");
27083 /* Intern this now in case it isn't already done.
27084 Setting this variable twice is harmless.
27085 But don't staticpro it here--that is done in alloc.c. */
27086 Qchar_table_extra_slots = intern_c_string ("char-table-extra-slots");
27087 Fput (Qglyphless_char_display, Qchar_table_extra_slots, make_number (1));
27089 DEFVAR_LISP ("glyphless-char-display", &Vglyphless_char_display,
27090 doc: /* Char-table to control displaying of glyphless characters.
27091 Each element, if non-nil, is an ASCII acronym string (displayed in a box)
27092 or one of these symbols:
27093 hex-code: display the hexadecimal code of a character in a box
27094 empty-box: display as an empty box
27095 thin-space: display as 1-pixel width space
27096 zero-width: don't display
27098 It has one extra slot to control the display of a character for which
27099 no font is found. The value of the slot is `hex-code' or `empty-box'.
27100 The default is `empty-box'. */);
27101 Vglyphless_char_display = Fmake_char_table (Qglyphless_char_display, Qnil);
27102 Fset_char_table_extra_slot (Vglyphless_char_display, make_number (0),
27103 Qempty_box);
27107 /* Initialize this module when Emacs starts. */
27109 void
27110 init_xdisp (void)
27112 Lisp_Object root_window;
27113 struct window *mini_w;
27115 current_header_line_height = current_mode_line_height = -1;
27117 CHARPOS (this_line_start_pos) = 0;
27119 mini_w = XWINDOW (minibuf_window);
27120 root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w)));
27122 if (!noninteractive)
27124 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (root_window)));
27125 int i;
27127 XWINDOW (root_window)->top_line = make_number (FRAME_TOP_MARGIN (f));
27128 set_window_height (root_window,
27129 FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f),
27131 mini_w->top_line = make_number (FRAME_LINES (f) - 1);
27132 set_window_height (minibuf_window, 1, 0);
27134 XWINDOW (root_window)->total_cols = make_number (FRAME_COLS (f));
27135 mini_w->total_cols = make_number (FRAME_COLS (f));
27137 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
27138 scratch_glyph_row.glyphs[TEXT_AREA + 1]
27139 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
27141 /* The default ellipsis glyphs `...'. */
27142 for (i = 0; i < 3; ++i)
27143 default_invis_vector[i] = make_number ('.');
27147 /* Allocate the buffer for frame titles.
27148 Also used for `format-mode-line'. */
27149 int size = 100;
27150 mode_line_noprop_buf = (char *) xmalloc (size);
27151 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
27152 mode_line_noprop_ptr = mode_line_noprop_buf;
27153 mode_line_target = MODE_LINE_DISPLAY;
27156 help_echo_showing_p = 0;
27159 /* Since w32 does not support atimers, it defines its own implementation of
27160 the following three functions in w32fns.c. */
27161 #ifndef WINDOWSNT
27163 /* Platform-independent portion of hourglass implementation. */
27165 /* Return non-zero if houglass timer has been started or hourglass is shown. */
27167 hourglass_started (void)
27169 return hourglass_shown_p || hourglass_atimer != NULL;
27172 /* Cancel a currently active hourglass timer, and start a new one. */
27173 void
27174 start_hourglass (void)
27176 #if defined (HAVE_WINDOW_SYSTEM)
27177 EMACS_TIME delay;
27178 int secs, usecs = 0;
27180 cancel_hourglass ();
27182 if (INTEGERP (Vhourglass_delay)
27183 && XINT (Vhourglass_delay) > 0)
27184 secs = XFASTINT (Vhourglass_delay);
27185 else if (FLOATP (Vhourglass_delay)
27186 && XFLOAT_DATA (Vhourglass_delay) > 0)
27188 Lisp_Object tem;
27189 tem = Ftruncate (Vhourglass_delay, Qnil);
27190 secs = XFASTINT (tem);
27191 usecs = (XFLOAT_DATA (Vhourglass_delay) - secs) * 1000000;
27193 else
27194 secs = DEFAULT_HOURGLASS_DELAY;
27196 EMACS_SET_SECS_USECS (delay, secs, usecs);
27197 hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
27198 show_hourglass, NULL);
27199 #endif
27203 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
27204 shown. */
27205 void
27206 cancel_hourglass (void)
27208 #if defined (HAVE_WINDOW_SYSTEM)
27209 if (hourglass_atimer)
27211 cancel_atimer (hourglass_atimer);
27212 hourglass_atimer = NULL;
27215 if (hourglass_shown_p)
27216 hide_hourglass ();
27217 #endif
27219 #endif /* ! WINDOWSNT */