gnus-ems.el: Provide compatibility functions for gnus-set-process-plist by Katsumi...
[emacs.git] / src / xdisp.c
blob07078a199a33b631ccfcceaaceb8164cefa68d17
1 /* Display generation from window structure and buffer text.
2 Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995,
3 1997, 1998, 1999, 2000, 2001, 2002, 2003,
4 2004, 2005, 2006, 2007, 2008, 2009, 2010
5 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 with 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 Note one important detail mentioned above: that the bidi reordering
223 engine, driven by the iterator, produces characters in R2L rows
224 starting at the character that will be the rightmost on display.
225 As far as the iterator is concerned, the geometry of such rows is
226 still left to right, i.e. the iterator "thinks" the first character
227 is at the leftmost pixel position. The iterator does not know that
228 PRODUCE_GLYPHS reverses the order of the glyphs that the iterator
229 delivers. This is important when functions from the the move_it_*
230 family are used to get to certain screen position or to match
231 screen coordinates with buffer coordinates: these functions use the
232 iterator geometry, which is left to right even in R2L paragraphs.
233 This works well with most callers of move_it_*, because they need
234 to get to a specific column, and columns are still numbered in the
235 reading order, i.e. the rightmost character in a R2L paragraph is
236 still column zero. But some callers do not get well with this; a
237 notable example is mouse clicks that need to find the character
238 that corresponds to certain pixel coordinates. See
239 buffer_posn_from_coords in dispnew.c for how this is handled. */
241 #include <config.h>
242 #include <stdio.h>
243 #include <limits.h>
244 #include <setjmp.h>
246 #include "lisp.h"
247 #include "keyboard.h"
248 #include "frame.h"
249 #include "window.h"
250 #include "termchar.h"
251 #include "dispextern.h"
252 #include "buffer.h"
253 #include "character.h"
254 #include "charset.h"
255 #include "indent.h"
256 #include "commands.h"
257 #include "keymap.h"
258 #include "macros.h"
259 #include "disptab.h"
260 #include "termhooks.h"
261 #include "termopts.h"
262 #include "intervals.h"
263 #include "coding.h"
264 #include "process.h"
265 #include "region-cache.h"
266 #include "font.h"
267 #include "fontset.h"
268 #include "blockinput.h"
270 #ifdef HAVE_X_WINDOWS
271 #include "xterm.h"
272 #endif
273 #ifdef WINDOWSNT
274 #include "w32term.h"
275 #endif
276 #ifdef HAVE_NS
277 #include "nsterm.h"
278 #endif
279 #ifdef USE_GTK
280 #include "gtkutil.h"
281 #endif
283 #include "font.h"
285 #ifndef FRAME_X_OUTPUT
286 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
287 #endif
289 #define INFINITY 10000000
291 Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
292 Lisp_Object Qwindow_scroll_functions, Vwindow_scroll_functions;
293 Lisp_Object Qwindow_text_change_functions, Vwindow_text_change_functions;
294 Lisp_Object Qredisplay_end_trigger_functions, Vredisplay_end_trigger_functions;
295 Lisp_Object Qinhibit_point_motion_hooks;
296 Lisp_Object QCeval, QCfile, QCdata, QCpropertize;
297 Lisp_Object Qfontified;
298 Lisp_Object Qgrow_only;
299 Lisp_Object Qinhibit_eval_during_redisplay;
300 Lisp_Object Qbuffer_position, Qposition, Qobject;
301 Lisp_Object Qright_to_left, Qleft_to_right;
303 /* Cursor shapes */
304 Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
306 /* Pointer shapes */
307 Lisp_Object Qarrow, Qhand, Qtext;
309 Lisp_Object Qrisky_local_variable;
311 /* Holds the list (error). */
312 Lisp_Object list_of_error;
314 /* Functions called to fontify regions of text. */
316 Lisp_Object Vfontification_functions;
317 Lisp_Object Qfontification_functions;
319 /* Non-nil means automatically select any window when the mouse
320 cursor moves into it. */
321 Lisp_Object Vmouse_autoselect_window;
323 Lisp_Object Vwrap_prefix, Qwrap_prefix;
324 Lisp_Object Vline_prefix, Qline_prefix;
326 /* Non-zero means draw tool bar buttons raised when the mouse moves
327 over them. */
329 int auto_raise_tool_bar_buttons_p;
331 /* Non-zero means to reposition window if cursor line is only partially visible. */
333 int make_cursor_line_fully_visible_p;
335 /* Margin below tool bar in pixels. 0 or nil means no margin.
336 If value is `internal-border-width' or `border-width',
337 the corresponding frame parameter is used. */
339 Lisp_Object Vtool_bar_border;
341 /* Margin around tool bar buttons in pixels. */
343 Lisp_Object Vtool_bar_button_margin;
345 /* Thickness of shadow to draw around tool bar buttons. */
347 EMACS_INT tool_bar_button_relief;
349 /* Non-nil means automatically resize tool-bars so that all tool-bar
350 items are visible, and no blank lines remain.
352 If value is `grow-only', only make tool-bar bigger. */
354 Lisp_Object Vauto_resize_tool_bars;
356 /* Type of tool bar. Can be symbols image, text, both or both-hroiz. */
358 Lisp_Object Vtool_bar_style;
360 /* Maximum number of characters a label can have to be shown. */
362 EMACS_INT tool_bar_max_label_size;
364 /* Non-zero means draw block and hollow cursor as wide as the glyph
365 under it. For example, if a block cursor is over a tab, it will be
366 drawn as wide as that tab on the display. */
368 int x_stretch_cursor_p;
370 /* Non-nil means don't actually do any redisplay. */
372 Lisp_Object Vinhibit_redisplay, Qinhibit_redisplay;
374 /* Non-zero means Lisp evaluation during redisplay is inhibited. */
376 int inhibit_eval_during_redisplay;
378 /* Names of text properties relevant for redisplay. */
380 Lisp_Object Qdisplay;
382 /* Symbols used in text property values. */
384 Lisp_Object Vdisplay_pixels_per_inch;
385 Lisp_Object Qspace, QCalign_to, QCrelative_width, QCrelative_height;
386 Lisp_Object Qleft_margin, Qright_margin, Qspace_width, Qraise;
387 Lisp_Object Qslice;
388 Lisp_Object Qcenter;
389 Lisp_Object Qmargin, Qpointer;
390 Lisp_Object Qline_height;
392 /* Non-nil means highlight trailing whitespace. */
394 Lisp_Object Vshow_trailing_whitespace;
396 /* Non-nil means escape non-break space and hyphens. */
398 Lisp_Object Vnobreak_char_display;
400 #ifdef HAVE_WINDOW_SYSTEM
402 /* Test if overflow newline into fringe. Called with iterator IT
403 at or past right window margin, and with IT->current_x set. */
405 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(IT) \
406 (!NILP (Voverflow_newline_into_fringe) \
407 && FRAME_WINDOW_P ((IT)->f) \
408 && ((IT)->bidi_it.paragraph_dir == R2L \
409 ? (WINDOW_LEFT_FRINGE_WIDTH ((IT)->w) > 0) \
410 : (WINDOW_RIGHT_FRINGE_WIDTH ((IT)->w) > 0)) \
411 && (IT)->current_x == (IT)->last_visible_x \
412 && (IT)->line_wrap != WORD_WRAP)
414 #else /* !HAVE_WINDOW_SYSTEM */
415 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) 0
416 #endif /* HAVE_WINDOW_SYSTEM */
418 /* Test if the display element loaded in IT is a space or tab
419 character. This is used to determine word wrapping. */
421 #define IT_DISPLAYING_WHITESPACE(it) \
422 (it->what == IT_CHARACTER && (it->c == ' ' || it->c == '\t'))
424 /* Non-nil means show the text cursor in void text areas
425 i.e. in blank areas after eol and eob. This used to be
426 the default in 21.3. */
428 Lisp_Object Vvoid_text_area_pointer;
430 /* Name of the face used to highlight trailing whitespace. */
432 Lisp_Object Qtrailing_whitespace;
434 /* Name and number of the face used to highlight escape glyphs. */
436 Lisp_Object Qescape_glyph;
438 /* Name and number of the face used to highlight non-breaking spaces. */
440 Lisp_Object Qnobreak_space;
442 /* The symbol `image' which is the car of the lists used to represent
443 images in Lisp. Also a tool bar style. */
445 Lisp_Object Qimage;
447 /* The image map types. */
448 Lisp_Object QCmap, QCpointer;
449 Lisp_Object Qrect, Qcircle, Qpoly;
451 /* Tool bar styles */
452 Lisp_Object Qboth, Qboth_horiz, Qtext_image_horiz;
454 /* Non-zero means print newline to stdout before next mini-buffer
455 message. */
457 int noninteractive_need_newline;
459 /* Non-zero means print newline to message log before next message. */
461 static int message_log_need_newline;
463 /* Three markers that message_dolog uses.
464 It could allocate them itself, but that causes trouble
465 in handling memory-full errors. */
466 static Lisp_Object message_dolog_marker1;
467 static Lisp_Object message_dolog_marker2;
468 static Lisp_Object message_dolog_marker3;
470 /* The buffer position of the first character appearing entirely or
471 partially on the line of the selected window which contains the
472 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
473 redisplay optimization in redisplay_internal. */
475 static struct text_pos this_line_start_pos;
477 /* Number of characters past the end of the line above, including the
478 terminating newline. */
480 static struct text_pos this_line_end_pos;
482 /* The vertical positions and the height of this line. */
484 static int this_line_vpos;
485 static int this_line_y;
486 static int this_line_pixel_height;
488 /* X position at which this display line starts. Usually zero;
489 negative if first character is partially visible. */
491 static int this_line_start_x;
493 /* Buffer that this_line_.* variables are referring to. */
495 static struct buffer *this_line_buffer;
497 /* Nonzero means truncate lines in all windows less wide than the
498 frame. */
500 Lisp_Object Vtruncate_partial_width_windows;
502 /* A flag to control how to display unibyte 8-bit character. */
504 int unibyte_display_via_language_environment;
506 /* Nonzero means we have more than one non-mini-buffer-only frame.
507 Not guaranteed to be accurate except while parsing
508 frame-title-format. */
510 int multiple_frames;
512 Lisp_Object Vglobal_mode_string;
515 /* List of variables (symbols) which hold markers for overlay arrows.
516 The symbols on this list are examined during redisplay to determine
517 where to display overlay arrows. */
519 Lisp_Object Voverlay_arrow_variable_list;
521 /* Marker for where to display an arrow on top of the buffer text. */
523 Lisp_Object Voverlay_arrow_position;
525 /* String to display for the arrow. Only used on terminal frames. */
527 Lisp_Object Voverlay_arrow_string;
529 /* Values of those variables at last redisplay are stored as
530 properties on `overlay-arrow-position' symbol. However, if
531 Voverlay_arrow_position is a marker, last-arrow-position is its
532 numerical position. */
534 Lisp_Object Qlast_arrow_position, Qlast_arrow_string;
536 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
537 properties on a symbol in overlay-arrow-variable-list. */
539 Lisp_Object Qoverlay_arrow_string, Qoverlay_arrow_bitmap;
541 /* Like mode-line-format, but for the title bar on a visible frame. */
543 Lisp_Object Vframe_title_format;
545 /* Like mode-line-format, but for the title bar on an iconified frame. */
547 Lisp_Object Vicon_title_format;
549 /* List of functions to call when a window's size changes. These
550 functions get one arg, a frame on which one or more windows' sizes
551 have changed. */
553 static Lisp_Object Vwindow_size_change_functions;
555 Lisp_Object Qmenu_bar_update_hook, Vmenu_bar_update_hook;
557 /* Nonzero if an overlay arrow has been displayed in this window. */
559 static int overlay_arrow_seen;
561 /* Nonzero means highlight the region even in nonselected windows. */
563 int highlight_nonselected_windows;
565 /* If cursor motion alone moves point off frame, try scrolling this
566 many lines up or down if that will bring it back. */
568 static EMACS_INT scroll_step;
570 /* Nonzero means scroll just far enough to bring point back on the
571 screen, when appropriate. */
573 static EMACS_INT scroll_conservatively;
575 /* Recenter the window whenever point gets within this many lines of
576 the top or bottom of the window. This value is translated into a
577 pixel value by multiplying it with FRAME_LINE_HEIGHT, which means
578 that there is really a fixed pixel height scroll margin. */
580 EMACS_INT scroll_margin;
582 /* Number of windows showing the buffer of the selected window (or
583 another buffer with the same base buffer). keyboard.c refers to
584 this. */
586 int buffer_shared;
588 /* Vector containing glyphs for an ellipsis `...'. */
590 static Lisp_Object default_invis_vector[3];
592 /* Zero means display the mode-line/header-line/menu-bar in the default face
593 (this slightly odd definition is for compatibility with previous versions
594 of emacs), non-zero means display them using their respective faces.
596 This variable is deprecated. */
598 int mode_line_inverse_video;
600 /* Prompt to display in front of the mini-buffer contents. */
602 Lisp_Object minibuf_prompt;
604 /* Width of current mini-buffer prompt. Only set after display_line
605 of the line that contains the prompt. */
607 int minibuf_prompt_width;
609 /* This is the window where the echo area message was displayed. It
610 is always a mini-buffer window, but it may not be the same window
611 currently active as a mini-buffer. */
613 Lisp_Object echo_area_window;
615 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
616 pushes the current message and the value of
617 message_enable_multibyte on the stack, the function restore_message
618 pops the stack and displays MESSAGE again. */
620 Lisp_Object Vmessage_stack;
622 /* Nonzero means multibyte characters were enabled when the echo area
623 message was specified. */
625 int message_enable_multibyte;
627 /* Nonzero if we should redraw the mode lines on the next redisplay. */
629 int update_mode_lines;
631 /* Nonzero if window sizes or contents have changed since last
632 redisplay that finished. */
634 int windows_or_buffers_changed;
636 /* Nonzero means a frame's cursor type has been changed. */
638 int cursor_type_changed;
640 /* Nonzero after display_mode_line if %l was used and it displayed a
641 line number. */
643 int line_number_displayed;
645 /* Maximum buffer size for which to display line numbers. */
647 Lisp_Object Vline_number_display_limit;
649 /* Line width to consider when repositioning for line number display. */
651 static EMACS_INT line_number_display_limit_width;
653 /* Number of lines to keep in the message log buffer. t means
654 infinite. nil means don't log at all. */
656 Lisp_Object Vmessage_log_max;
658 /* The name of the *Messages* buffer, a string. */
660 static Lisp_Object Vmessages_buffer_name;
662 /* Current, index 0, and last displayed echo area message. Either
663 buffers from echo_buffers, or nil to indicate no message. */
665 Lisp_Object echo_area_buffer[2];
667 /* The buffers referenced from echo_area_buffer. */
669 static Lisp_Object echo_buffer[2];
671 /* A vector saved used in with_area_buffer to reduce consing. */
673 static Lisp_Object Vwith_echo_area_save_vector;
675 /* Non-zero means display_echo_area should display the last echo area
676 message again. Set by redisplay_preserve_echo_area. */
678 static int display_last_displayed_message_p;
680 /* Nonzero if echo area is being used by print; zero if being used by
681 message. */
683 int message_buf_print;
685 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
687 Lisp_Object Qinhibit_menubar_update;
688 int inhibit_menubar_update;
690 /* When evaluating expressions from menu bar items (enable conditions,
691 for instance), this is the frame they are being processed for. */
693 Lisp_Object Vmenu_updating_frame;
695 /* Maximum height for resizing mini-windows. Either a float
696 specifying a fraction of the available height, or an integer
697 specifying a number of lines. */
699 Lisp_Object Vmax_mini_window_height;
701 /* Non-zero means messages should be displayed with truncated
702 lines instead of being continued. */
704 int message_truncate_lines;
705 Lisp_Object Qmessage_truncate_lines;
707 /* Set to 1 in clear_message to make redisplay_internal aware
708 of an emptied echo area. */
710 static int message_cleared_p;
712 /* How to blink the default frame cursor off. */
713 Lisp_Object Vblink_cursor_alist;
715 /* A scratch glyph row with contents used for generating truncation
716 glyphs. Also used in direct_output_for_insert. */
718 #define MAX_SCRATCH_GLYPHS 100
719 struct glyph_row scratch_glyph_row;
720 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
722 /* Ascent and height of the last line processed by move_it_to. */
724 static int last_max_ascent, last_height;
726 /* Non-zero if there's a help-echo in the echo area. */
728 int help_echo_showing_p;
730 /* If >= 0, computed, exact values of mode-line and header-line height
731 to use in the macros CURRENT_MODE_LINE_HEIGHT and
732 CURRENT_HEADER_LINE_HEIGHT. */
734 int current_mode_line_height, current_header_line_height;
736 /* The maximum distance to look ahead for text properties. Values
737 that are too small let us call compute_char_face and similar
738 functions too often which is expensive. Values that are too large
739 let us call compute_char_face and alike too often because we
740 might not be interested in text properties that far away. */
742 #define TEXT_PROP_DISTANCE_LIMIT 100
744 #if GLYPH_DEBUG
746 /* Variables to turn off display optimizations from Lisp. */
748 int inhibit_try_window_id, inhibit_try_window_reusing;
749 int inhibit_try_cursor_movement;
751 /* Non-zero means print traces of redisplay if compiled with
752 GLYPH_DEBUG != 0. */
754 int trace_redisplay_p;
756 #endif /* GLYPH_DEBUG */
758 #ifdef DEBUG_TRACE_MOVE
759 /* Non-zero means trace with TRACE_MOVE to stderr. */
760 int trace_move;
762 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
763 #else
764 #define TRACE_MOVE(x) (void) 0
765 #endif
767 /* Non-zero means automatically scroll windows horizontally to make
768 point visible. */
770 int automatic_hscrolling_p;
771 Lisp_Object Qauto_hscroll_mode;
773 /* How close to the margin can point get before the window is scrolled
774 horizontally. */
775 EMACS_INT hscroll_margin;
777 /* How much to scroll horizontally when point is inside the above margin. */
778 Lisp_Object Vhscroll_step;
780 /* The variable `resize-mini-windows'. If nil, don't resize
781 mini-windows. If t, always resize them to fit the text they
782 display. If `grow-only', let mini-windows grow only until they
783 become empty. */
785 Lisp_Object Vresize_mini_windows;
787 /* Buffer being redisplayed -- for redisplay_window_error. */
789 struct buffer *displayed_buffer;
791 /* Space between overline and text. */
793 EMACS_INT overline_margin;
795 /* Require underline to be at least this many screen pixels below baseline
796 This to avoid underline "merging" with the base of letters at small
797 font sizes, particularly when x_use_underline_position_properties is on. */
799 EMACS_INT underline_minimum_offset;
801 /* Value returned from text property handlers (see below). */
803 enum prop_handled
805 HANDLED_NORMALLY,
806 HANDLED_RECOMPUTE_PROPS,
807 HANDLED_OVERLAY_STRING_CONSUMED,
808 HANDLED_RETURN
811 /* A description of text properties that redisplay is interested
812 in. */
814 struct props
816 /* The name of the property. */
817 Lisp_Object *name;
819 /* A unique index for the property. */
820 enum prop_idx idx;
822 /* A handler function called to set up iterator IT from the property
823 at IT's current position. Value is used to steer handle_stop. */
824 enum prop_handled (*handler) (struct it *it);
827 static enum prop_handled handle_face_prop (struct it *);
828 static enum prop_handled handle_invisible_prop (struct it *);
829 static enum prop_handled handle_display_prop (struct it *);
830 static enum prop_handled handle_composition_prop (struct it *);
831 static enum prop_handled handle_overlay_change (struct it *);
832 static enum prop_handled handle_fontified_prop (struct it *);
834 /* Properties handled by iterators. */
836 static struct props it_props[] =
838 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
839 /* Handle `face' before `display' because some sub-properties of
840 `display' need to know the face. */
841 {&Qface, FACE_PROP_IDX, handle_face_prop},
842 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
843 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
844 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
845 {NULL, 0, NULL}
848 /* Value is the position described by X. If X is a marker, value is
849 the marker_position of X. Otherwise, value is X. */
851 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
853 /* Enumeration returned by some move_it_.* functions internally. */
855 enum move_it_result
857 /* Not used. Undefined value. */
858 MOVE_UNDEFINED,
860 /* Move ended at the requested buffer position or ZV. */
861 MOVE_POS_MATCH_OR_ZV,
863 /* Move ended at the requested X pixel position. */
864 MOVE_X_REACHED,
866 /* Move within a line ended at the end of a line that must be
867 continued. */
868 MOVE_LINE_CONTINUED,
870 /* Move within a line ended at the end of a line that would
871 be displayed truncated. */
872 MOVE_LINE_TRUNCATED,
874 /* Move within a line ended at a line end. */
875 MOVE_NEWLINE_OR_CR
878 /* This counter is used to clear the face cache every once in a while
879 in redisplay_internal. It is incremented for each redisplay.
880 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
881 cleared. */
883 #define CLEAR_FACE_CACHE_COUNT 500
884 static int clear_face_cache_count;
886 /* Similarly for the image cache. */
888 #ifdef HAVE_WINDOW_SYSTEM
889 #define CLEAR_IMAGE_CACHE_COUNT 101
890 static int clear_image_cache_count;
891 #endif
893 /* Non-zero while redisplay_internal is in progress. */
895 int redisplaying_p;
897 /* Non-zero means don't free realized faces. Bound while freeing
898 realized faces is dangerous because glyph matrices might still
899 reference them. */
901 int inhibit_free_realized_faces;
902 Lisp_Object Qinhibit_free_realized_faces;
904 /* If a string, XTread_socket generates an event to display that string.
905 (The display is done in read_char.) */
907 Lisp_Object help_echo_string;
908 Lisp_Object help_echo_window;
909 Lisp_Object help_echo_object;
910 int help_echo_pos;
912 /* Temporary variable for XTread_socket. */
914 Lisp_Object previous_help_echo_string;
916 /* Null glyph slice */
918 static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 };
920 /* Platform-independent portion of hourglass implementation. */
922 /* Non-zero means we're allowed to display a hourglass pointer. */
923 int display_hourglass_p;
925 /* Non-zero means an hourglass cursor is currently shown. */
926 int hourglass_shown_p;
928 /* If non-null, an asynchronous timer that, when it expires, displays
929 an hourglass cursor on all frames. */
930 struct atimer *hourglass_atimer;
932 /* Number of seconds to wait before displaying an hourglass cursor. */
933 Lisp_Object Vhourglass_delay;
935 /* Default number of seconds to wait before displaying an hourglass
936 cursor. */
937 #define DEFAULT_HOURGLASS_DELAY 1
940 /* Function prototypes. */
942 static void setup_for_ellipsis (struct it *, int);
943 static void mark_window_display_accurate_1 (struct window *, int);
944 static int single_display_spec_string_p (Lisp_Object, Lisp_Object);
945 static int display_prop_string_p (Lisp_Object, Lisp_Object);
946 static int cursor_row_p (struct window *, struct glyph_row *);
947 static int redisplay_mode_lines (Lisp_Object, int);
948 static char *decode_mode_spec_coding (Lisp_Object, char *, int);
950 static Lisp_Object get_it_property (struct it *it, Lisp_Object prop);
952 static void handle_line_prefix (struct it *);
954 static void pint2str (char *, int, int);
955 static void pint2hrstr (char *, int, int);
956 static struct text_pos run_window_scroll_functions (Lisp_Object,
957 struct text_pos);
958 static void reconsider_clip_changes (struct window *, struct buffer *);
959 static int text_outside_line_unchanged_p (struct window *, int, int);
960 static void store_mode_line_noprop_char (char);
961 static int store_mode_line_noprop (const unsigned char *, int, int);
962 static void x_consider_frame_title (Lisp_Object);
963 static void handle_stop (struct it *);
964 static void handle_stop_backwards (struct it *, EMACS_INT);
965 static int tool_bar_lines_needed (struct frame *, int *);
966 static int single_display_spec_intangible_p (Lisp_Object);
967 static void ensure_echo_area_buffers (void);
968 static Lisp_Object unwind_with_echo_area_buffer (Lisp_Object);
969 static Lisp_Object with_echo_area_buffer_unwind_data (struct window *);
970 static int with_echo_area_buffer (struct window *, int,
971 int (*) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
972 EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
973 static void clear_garbaged_frames (void);
974 static int current_message_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
975 static int truncate_message_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
976 static int set_message_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
977 static int display_echo_area (struct window *);
978 static int display_echo_area_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
979 static int resize_mini_window_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
980 static Lisp_Object unwind_redisplay (Lisp_Object);
981 static int string_char_and_length (const unsigned char *, int *);
982 static struct text_pos display_prop_end (struct it *, Lisp_Object,
983 struct text_pos);
984 static int compute_window_start_on_continuation_line (struct window *);
985 static Lisp_Object safe_eval_handler (Lisp_Object);
986 static void insert_left_trunc_glyphs (struct it *);
987 static struct glyph_row *get_overlay_arrow_glyph_row (struct window *,
988 Lisp_Object);
989 static void extend_face_to_end_of_line (struct it *);
990 static int append_space_for_newline (struct it *, int);
991 static int cursor_row_fully_visible_p (struct window *, int, int);
992 static int try_scrolling (Lisp_Object, int, EMACS_INT, EMACS_INT, int, int);
993 static int try_cursor_movement (Lisp_Object, struct text_pos, int *);
994 static int trailing_whitespace_p (int);
995 static int message_log_check_duplicate (int, int, int, int);
996 static void push_it (struct it *);
997 static void pop_it (struct it *);
998 static void sync_frame_with_window_matrix_rows (struct window *);
999 static void select_frame_for_redisplay (Lisp_Object);
1000 static void redisplay_internal (int);
1001 static int echo_area_display (int);
1002 static void redisplay_windows (Lisp_Object);
1003 static void redisplay_window (Lisp_Object, int);
1004 static Lisp_Object redisplay_window_error (Lisp_Object);
1005 static Lisp_Object redisplay_window_0 (Lisp_Object);
1006 static Lisp_Object redisplay_window_1 (Lisp_Object);
1007 static int update_menu_bar (struct frame *, int, int);
1008 static int try_window_reusing_current_matrix (struct window *);
1009 static int try_window_id (struct window *);
1010 static int display_line (struct it *);
1011 static int display_mode_lines (struct window *);
1012 static int display_mode_line (struct window *, enum face_id, Lisp_Object);
1013 static int display_mode_element (struct it *, int, int, int, Lisp_Object, Lisp_Object, int);
1014 static int store_mode_line_string (const char *, Lisp_Object, int, int, int, Lisp_Object);
1015 static const char *decode_mode_spec (struct window *, int, int, int,
1016 Lisp_Object *);
1017 static void display_menu_bar (struct window *);
1018 static int display_count_lines (int, int, int, int, int *);
1019 static int display_string (const unsigned char *, Lisp_Object, Lisp_Object,
1020 EMACS_INT, EMACS_INT, struct it *, int, int, int, int);
1021 static void compute_line_metrics (struct it *);
1022 static void run_redisplay_end_trigger_hook (struct it *);
1023 static int get_overlay_strings (struct it *, int);
1024 static int get_overlay_strings_1 (struct it *, int, int);
1025 static void next_overlay_string (struct it *);
1026 static void reseat (struct it *, struct text_pos, int);
1027 static void reseat_1 (struct it *, struct text_pos, int);
1028 static void back_to_previous_visible_line_start (struct it *);
1029 void reseat_at_previous_visible_line_start (struct it *);
1030 static void reseat_at_next_visible_line_start (struct it *, int);
1031 static int next_element_from_ellipsis (struct it *);
1032 static int next_element_from_display_vector (struct it *);
1033 static int next_element_from_string (struct it *);
1034 static int next_element_from_c_string (struct it *);
1035 static int next_element_from_buffer (struct it *);
1036 static int next_element_from_composition (struct it *);
1037 static int next_element_from_image (struct it *);
1038 static int next_element_from_stretch (struct it *);
1039 static void load_overlay_strings (struct it *, int);
1040 static int init_from_display_pos (struct it *, struct window *,
1041 struct display_pos *);
1042 static void reseat_to_string (struct it *, const unsigned char *,
1043 Lisp_Object, int, int, int, int);
1044 static enum move_it_result
1045 move_it_in_display_line_to (struct it *, EMACS_INT, int,
1046 enum move_operation_enum);
1047 void move_it_vertically_backward (struct it *, int);
1048 static void init_to_row_start (struct it *, struct window *,
1049 struct glyph_row *);
1050 static int init_to_row_end (struct it *, struct window *,
1051 struct glyph_row *);
1052 static void back_to_previous_line_start (struct it *);
1053 static int forward_to_next_line_start (struct it *, int *);
1054 static struct text_pos string_pos_nchars_ahead (struct text_pos,
1055 Lisp_Object, int);
1056 static struct text_pos string_pos (int, Lisp_Object);
1057 static struct text_pos c_string_pos (int, const unsigned char *, int);
1058 static int number_of_chars (const unsigned char *, int);
1059 static void compute_stop_pos (struct it *);
1060 static void compute_string_pos (struct text_pos *, struct text_pos,
1061 Lisp_Object);
1062 static int face_before_or_after_it_pos (struct it *, int);
1063 static EMACS_INT next_overlay_change (EMACS_INT);
1064 static int handle_single_display_spec (struct it *, Lisp_Object,
1065 Lisp_Object, Lisp_Object,
1066 struct text_pos *, int);
1067 static int underlying_face_id (struct it *);
1068 static int in_ellipses_for_invisible_text_p (struct display_pos *,
1069 struct window *);
1071 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
1072 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
1074 #ifdef HAVE_WINDOW_SYSTEM
1076 static void update_tool_bar (struct frame *, int);
1077 static void build_desired_tool_bar_string (struct frame *f);
1078 static int redisplay_tool_bar (struct frame *);
1079 static void display_tool_bar_line (struct it *, int);
1080 static void notice_overwritten_cursor (struct window *,
1081 enum glyph_row_area,
1082 int, int, int, int);
1083 static void append_stretch_glyph (struct it *, Lisp_Object,
1084 int, int, int);
1088 #endif /* HAVE_WINDOW_SYSTEM */
1091 /***********************************************************************
1092 Window display dimensions
1093 ***********************************************************************/
1095 /* Return the bottom boundary y-position for text lines in window W.
1096 This is the first y position at which a line cannot start.
1097 It is relative to the top of the window.
1099 This is the height of W minus the height of a mode line, if any. */
1101 INLINE int
1102 window_text_bottom_y (struct window *w)
1104 int height = WINDOW_TOTAL_HEIGHT (w);
1106 if (WINDOW_WANTS_MODELINE_P (w))
1107 height -= CURRENT_MODE_LINE_HEIGHT (w);
1108 return height;
1111 /* Return the pixel width of display area AREA of window W. AREA < 0
1112 means return the total width of W, not including fringes to
1113 the left and right of the window. */
1115 INLINE int
1116 window_box_width (struct window *w, int area)
1118 int cols = XFASTINT (w->total_cols);
1119 int pixels = 0;
1121 if (!w->pseudo_window_p)
1123 cols -= WINDOW_SCROLL_BAR_COLS (w);
1125 if (area == TEXT_AREA)
1127 if (INTEGERP (w->left_margin_cols))
1128 cols -= XFASTINT (w->left_margin_cols);
1129 if (INTEGERP (w->right_margin_cols))
1130 cols -= XFASTINT (w->right_margin_cols);
1131 pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w);
1133 else if (area == LEFT_MARGIN_AREA)
1135 cols = (INTEGERP (w->left_margin_cols)
1136 ? XFASTINT (w->left_margin_cols) : 0);
1137 pixels = 0;
1139 else if (area == RIGHT_MARGIN_AREA)
1141 cols = (INTEGERP (w->right_margin_cols)
1142 ? XFASTINT (w->right_margin_cols) : 0);
1143 pixels = 0;
1147 return cols * WINDOW_FRAME_COLUMN_WIDTH (w) + pixels;
1151 /* Return the pixel height of the display area of window W, not
1152 including mode lines of W, if any. */
1154 INLINE int
1155 window_box_height (struct window *w)
1157 struct frame *f = XFRAME (w->frame);
1158 int height = WINDOW_TOTAL_HEIGHT (w);
1160 xassert (height >= 0);
1162 /* Note: the code below that determines the mode-line/header-line
1163 height is essentially the same as that contained in the macro
1164 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1165 the appropriate glyph row has its `mode_line_p' flag set,
1166 and if it doesn't, uses estimate_mode_line_height instead. */
1168 if (WINDOW_WANTS_MODELINE_P (w))
1170 struct glyph_row *ml_row
1171 = (w->current_matrix && w->current_matrix->rows
1172 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
1173 : 0);
1174 if (ml_row && ml_row->mode_line_p)
1175 height -= ml_row->height;
1176 else
1177 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
1180 if (WINDOW_WANTS_HEADER_LINE_P (w))
1182 struct glyph_row *hl_row
1183 = (w->current_matrix && w->current_matrix->rows
1184 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
1185 : 0);
1186 if (hl_row && hl_row->mode_line_p)
1187 height -= hl_row->height;
1188 else
1189 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1192 /* With a very small font and a mode-line that's taller than
1193 default, we might end up with a negative height. */
1194 return max (0, height);
1197 /* Return the window-relative coordinate of the left edge of display
1198 area AREA of window W. AREA < 0 means return the left edge of the
1199 whole window, to the right of the left fringe of W. */
1201 INLINE int
1202 window_box_left_offset (struct window *w, int area)
1204 int x;
1206 if (w->pseudo_window_p)
1207 return 0;
1209 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
1211 if (area == TEXT_AREA)
1212 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1213 + window_box_width (w, LEFT_MARGIN_AREA));
1214 else if (area == RIGHT_MARGIN_AREA)
1215 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1216 + window_box_width (w, LEFT_MARGIN_AREA)
1217 + window_box_width (w, TEXT_AREA)
1218 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1220 : WINDOW_RIGHT_FRINGE_WIDTH (w)));
1221 else if (area == LEFT_MARGIN_AREA
1222 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1223 x += WINDOW_LEFT_FRINGE_WIDTH (w);
1225 return x;
1229 /* Return the window-relative coordinate of the right edge of display
1230 area AREA of window W. AREA < 0 means return the right edge of the
1231 whole window, to the left of the right fringe of W. */
1233 INLINE int
1234 window_box_right_offset (struct window *w, int area)
1236 return window_box_left_offset (w, area) + window_box_width (w, area);
1239 /* Return the frame-relative coordinate of the left edge of display
1240 area AREA of window W. AREA < 0 means return the left edge of the
1241 whole window, to the right of the left fringe of W. */
1243 INLINE int
1244 window_box_left (struct window *w, int area)
1246 struct frame *f = XFRAME (w->frame);
1247 int x;
1249 if (w->pseudo_window_p)
1250 return FRAME_INTERNAL_BORDER_WIDTH (f);
1252 x = (WINDOW_LEFT_EDGE_X (w)
1253 + window_box_left_offset (w, area));
1255 return x;
1259 /* Return the frame-relative coordinate of the right edge of display
1260 area AREA of window W. AREA < 0 means return the right edge of the
1261 whole window, to the left of the right fringe of W. */
1263 INLINE int
1264 window_box_right (struct window *w, int area)
1266 return window_box_left (w, area) + window_box_width (w, area);
1269 /* Get the bounding box of the display area AREA of window W, without
1270 mode lines, in frame-relative coordinates. AREA < 0 means the
1271 whole window, not including the left and right fringes of
1272 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1273 coordinates of the upper-left corner of the box. Return in
1274 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1276 INLINE void
1277 window_box (struct window *w, int area, int *box_x, int *box_y,
1278 int *box_width, int *box_height)
1280 if (box_width)
1281 *box_width = window_box_width (w, area);
1282 if (box_height)
1283 *box_height = window_box_height (w);
1284 if (box_x)
1285 *box_x = window_box_left (w, area);
1286 if (box_y)
1288 *box_y = WINDOW_TOP_EDGE_Y (w);
1289 if (WINDOW_WANTS_HEADER_LINE_P (w))
1290 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1295 /* Get the bounding box of the display area AREA of window W, without
1296 mode lines. AREA < 0 means the whole window, not including the
1297 left and right fringe of the window. Return in *TOP_LEFT_X
1298 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1299 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1300 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1301 box. */
1303 INLINE void
1304 window_box_edges (struct window *w, int area, int *top_left_x, int *top_left_y,
1305 int *bottom_right_x, int *bottom_right_y)
1307 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
1308 bottom_right_y);
1309 *bottom_right_x += *top_left_x;
1310 *bottom_right_y += *top_left_y;
1315 /***********************************************************************
1316 Utilities
1317 ***********************************************************************/
1319 /* Return the bottom y-position of the line the iterator IT is in.
1320 This can modify IT's settings. */
1323 line_bottom_y (struct it *it)
1325 int line_height = it->max_ascent + it->max_descent;
1326 int line_top_y = it->current_y;
1328 if (line_height == 0)
1330 if (last_height)
1331 line_height = last_height;
1332 else if (IT_CHARPOS (*it) < ZV)
1334 move_it_by_lines (it, 1, 1);
1335 line_height = (it->max_ascent || it->max_descent
1336 ? it->max_ascent + it->max_descent
1337 : last_height);
1339 else
1341 struct glyph_row *row = it->glyph_row;
1343 /* Use the default character height. */
1344 it->glyph_row = NULL;
1345 it->what = IT_CHARACTER;
1346 it->c = ' ';
1347 it->len = 1;
1348 PRODUCE_GLYPHS (it);
1349 line_height = it->ascent + it->descent;
1350 it->glyph_row = row;
1354 return line_top_y + line_height;
1358 /* Return 1 if position CHARPOS is visible in window W.
1359 CHARPOS < 0 means return info about WINDOW_END position.
1360 If visible, set *X and *Y to pixel coordinates of top left corner.
1361 Set *RTOP and *RBOT to pixel height of an invisible area of glyph at POS.
1362 Set *ROWH and *VPOS to row's visible height and VPOS (row number). */
1365 pos_visible_p (struct window *w, int charpos, int *x, int *y,
1366 int *rtop, int *rbot, int *rowh, int *vpos)
1368 struct it it;
1369 struct text_pos top;
1370 int visible_p = 0;
1371 struct buffer *old_buffer = NULL;
1373 if (FRAME_INITIAL_P (XFRAME (WINDOW_FRAME (w))))
1374 return visible_p;
1376 if (XBUFFER (w->buffer) != current_buffer)
1378 old_buffer = current_buffer;
1379 set_buffer_internal_1 (XBUFFER (w->buffer));
1382 SET_TEXT_POS_FROM_MARKER (top, w->start);
1384 /* Compute exact mode line heights. */
1385 if (WINDOW_WANTS_MODELINE_P (w))
1386 current_mode_line_height
1387 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1388 current_buffer->mode_line_format);
1390 if (WINDOW_WANTS_HEADER_LINE_P (w))
1391 current_header_line_height
1392 = display_mode_line (w, HEADER_LINE_FACE_ID,
1393 current_buffer->header_line_format);
1395 start_display (&it, w, top);
1396 move_it_to (&it, charpos, -1, it.last_visible_y-1, -1,
1397 (charpos >= 0 ? MOVE_TO_POS : 0) | MOVE_TO_Y);
1399 if (charpos >= 0 && IT_CHARPOS (it) >= charpos)
1401 /* We have reached CHARPOS, or passed it. How the call to
1402 move_it_to can overshoot: (i) If CHARPOS is on invisible
1403 text, move_it_to stops at the end of the invisible text,
1404 after CHARPOS. (ii) If CHARPOS is in a display vector,
1405 move_it_to stops on its last glyph. */
1406 int top_x = it.current_x;
1407 int top_y = it.current_y;
1408 enum it_method it_method = it.method;
1409 /* Calling line_bottom_y may change it.method, it.position, etc. */
1410 int bottom_y = (last_height = 0, line_bottom_y (&it));
1411 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1413 if (top_y < window_top_y)
1414 visible_p = bottom_y > window_top_y;
1415 else if (top_y < it.last_visible_y)
1416 visible_p = 1;
1417 if (visible_p)
1419 if (it_method == GET_FROM_DISPLAY_VECTOR)
1421 /* We stopped on the last glyph of a display vector.
1422 Try and recompute. Hack alert! */
1423 if (charpos < 2 || top.charpos >= charpos)
1424 top_x = it.glyph_row->x;
1425 else
1427 struct it it2;
1428 start_display (&it2, w, top);
1429 move_it_to (&it2, charpos - 1, -1, -1, -1, MOVE_TO_POS);
1430 get_next_display_element (&it2);
1431 PRODUCE_GLYPHS (&it2);
1432 if (ITERATOR_AT_END_OF_LINE_P (&it2)
1433 || it2.current_x > it2.last_visible_x)
1434 top_x = it.glyph_row->x;
1435 else
1437 top_x = it2.current_x;
1438 top_y = it2.current_y;
1443 *x = top_x;
1444 *y = max (top_y + max (0, it.max_ascent - it.ascent), window_top_y);
1445 *rtop = max (0, window_top_y - top_y);
1446 *rbot = max (0, bottom_y - it.last_visible_y);
1447 *rowh = max (0, (min (bottom_y, it.last_visible_y)
1448 - max (top_y, window_top_y)));
1449 *vpos = it.vpos;
1452 else
1454 struct it it2;
1456 it2 = it;
1457 if (IT_CHARPOS (it) < ZV && FETCH_BYTE (IT_BYTEPOS (it)) != '\n')
1458 move_it_by_lines (&it, 1, 0);
1459 if (charpos < IT_CHARPOS (it)
1460 || (it.what == IT_EOB && charpos == IT_CHARPOS (it)))
1462 visible_p = 1;
1463 move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
1464 *x = it2.current_x;
1465 *y = it2.current_y + it2.max_ascent - it2.ascent;
1466 *rtop = max (0, -it2.current_y);
1467 *rbot = max (0, ((it2.current_y + it2.max_ascent + it2.max_descent)
1468 - it.last_visible_y));
1469 *rowh = max (0, (min (it2.current_y + it2.max_ascent + it2.max_descent,
1470 it.last_visible_y)
1471 - max (it2.current_y,
1472 WINDOW_HEADER_LINE_HEIGHT (w))));
1473 *vpos = it2.vpos;
1477 if (old_buffer)
1478 set_buffer_internal_1 (old_buffer);
1480 current_header_line_height = current_mode_line_height = -1;
1482 if (visible_p && XFASTINT (w->hscroll) > 0)
1483 *x -= XFASTINT (w->hscroll) * WINDOW_FRAME_COLUMN_WIDTH (w);
1485 #if 0
1486 /* Debugging code. */
1487 if (visible_p)
1488 fprintf (stderr, "+pv pt=%d vs=%d --> x=%d y=%d rt=%d rb=%d rh=%d vp=%d\n",
1489 charpos, w->vscroll, *x, *y, *rtop, *rbot, *rowh, *vpos);
1490 else
1491 fprintf (stderr, "-pv pt=%d vs=%d\n", charpos, w->vscroll);
1492 #endif
1494 return visible_p;
1498 /* Return the next character from STR which is MAXLEN bytes long.
1499 Return in *LEN the length of the character. This is like
1500 STRING_CHAR_AND_LENGTH but never returns an invalid character. If
1501 we find one, we return a `?', but with the length of the invalid
1502 character. */
1504 static INLINE int
1505 string_char_and_length (const unsigned char *str, int *len)
1507 int c;
1509 c = STRING_CHAR_AND_LENGTH (str, *len);
1510 if (!CHAR_VALID_P (c, 1))
1511 /* We may not change the length here because other places in Emacs
1512 don't use this function, i.e. they silently accept invalid
1513 characters. */
1514 c = '?';
1516 return c;
1521 /* Given a position POS containing a valid character and byte position
1522 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1524 static struct text_pos
1525 string_pos_nchars_ahead (struct text_pos pos, Lisp_Object string, int nchars)
1527 xassert (STRINGP (string) && nchars >= 0);
1529 if (STRING_MULTIBYTE (string))
1531 int rest = SBYTES (string) - BYTEPOS (pos);
1532 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1533 int len;
1535 while (nchars--)
1537 string_char_and_length (p, &len);
1538 p += len, rest -= len;
1539 xassert (rest >= 0);
1540 CHARPOS (pos) += 1;
1541 BYTEPOS (pos) += len;
1544 else
1545 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1547 return pos;
1551 /* Value is the text position, i.e. character and byte position,
1552 for character position CHARPOS in STRING. */
1554 static INLINE struct text_pos
1555 string_pos (int charpos, Lisp_Object string)
1557 struct text_pos pos;
1558 xassert (STRINGP (string));
1559 xassert (charpos >= 0);
1560 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1561 return pos;
1565 /* Value is a text position, i.e. character and byte position, for
1566 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1567 means recognize multibyte characters. */
1569 static struct text_pos
1570 c_string_pos (int charpos, const unsigned char *s, int multibyte_p)
1572 struct text_pos pos;
1574 xassert (s != NULL);
1575 xassert (charpos >= 0);
1577 if (multibyte_p)
1579 int rest = strlen (s), len;
1581 SET_TEXT_POS (pos, 0, 0);
1582 while (charpos--)
1584 string_char_and_length (s, &len);
1585 s += len, rest -= len;
1586 xassert (rest >= 0);
1587 CHARPOS (pos) += 1;
1588 BYTEPOS (pos) += len;
1591 else
1592 SET_TEXT_POS (pos, charpos, charpos);
1594 return pos;
1598 /* Value is the number of characters in C string S. MULTIBYTE_P
1599 non-zero means recognize multibyte characters. */
1601 static int
1602 number_of_chars (const unsigned char *s, int multibyte_p)
1604 int nchars;
1606 if (multibyte_p)
1608 int rest = strlen (s), len;
1609 unsigned char *p = (unsigned char *) s;
1611 for (nchars = 0; rest > 0; ++nchars)
1613 string_char_and_length (p, &len);
1614 rest -= len, p += len;
1617 else
1618 nchars = strlen (s);
1620 return nchars;
1624 /* Compute byte position NEWPOS->bytepos corresponding to
1625 NEWPOS->charpos. POS is a known position in string STRING.
1626 NEWPOS->charpos must be >= POS.charpos. */
1628 static void
1629 compute_string_pos (struct text_pos *newpos, struct text_pos pos, Lisp_Object string)
1631 xassert (STRINGP (string));
1632 xassert (CHARPOS (*newpos) >= CHARPOS (pos));
1634 if (STRING_MULTIBYTE (string))
1635 *newpos = string_pos_nchars_ahead (pos, string,
1636 CHARPOS (*newpos) - CHARPOS (pos));
1637 else
1638 BYTEPOS (*newpos) = CHARPOS (*newpos);
1641 /* EXPORT:
1642 Return an estimation of the pixel height of mode or header lines on
1643 frame F. FACE_ID specifies what line's height to estimate. */
1646 estimate_mode_line_height (struct frame *f, enum face_id face_id)
1648 #ifdef HAVE_WINDOW_SYSTEM
1649 if (FRAME_WINDOW_P (f))
1651 int height = FONT_HEIGHT (FRAME_FONT (f));
1653 /* This function is called so early when Emacs starts that the face
1654 cache and mode line face are not yet initialized. */
1655 if (FRAME_FACE_CACHE (f))
1657 struct face *face = FACE_FROM_ID (f, face_id);
1658 if (face)
1660 if (face->font)
1661 height = FONT_HEIGHT (face->font);
1662 if (face->box_line_width > 0)
1663 height += 2 * face->box_line_width;
1667 return height;
1669 #endif
1671 return 1;
1674 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1675 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1676 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1677 not force the value into range. */
1679 void
1680 pixel_to_glyph_coords (FRAME_PTR f, register int pix_x, register int pix_y,
1681 int *x, int *y, NativeRectangle *bounds, int noclip)
1684 #ifdef HAVE_WINDOW_SYSTEM
1685 if (FRAME_WINDOW_P (f))
1687 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1688 even for negative values. */
1689 if (pix_x < 0)
1690 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1691 if (pix_y < 0)
1692 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1694 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1695 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1697 if (bounds)
1698 STORE_NATIVE_RECT (*bounds,
1699 FRAME_COL_TO_PIXEL_X (f, pix_x),
1700 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1701 FRAME_COLUMN_WIDTH (f) - 1,
1702 FRAME_LINE_HEIGHT (f) - 1);
1704 if (!noclip)
1706 if (pix_x < 0)
1707 pix_x = 0;
1708 else if (pix_x > FRAME_TOTAL_COLS (f))
1709 pix_x = FRAME_TOTAL_COLS (f);
1711 if (pix_y < 0)
1712 pix_y = 0;
1713 else if (pix_y > FRAME_LINES (f))
1714 pix_y = FRAME_LINES (f);
1717 #endif
1719 *x = pix_x;
1720 *y = pix_y;
1724 /* Given HPOS/VPOS in the current matrix of W, return corresponding
1725 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
1726 can't tell the positions because W's display is not up to date,
1727 return 0. */
1730 glyph_to_pixel_coords (struct window *w, int hpos, int vpos,
1731 int *frame_x, int *frame_y)
1733 #ifdef HAVE_WINDOW_SYSTEM
1734 if (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w))))
1736 int success_p;
1738 xassert (hpos >= 0 && hpos < w->current_matrix->matrix_w);
1739 xassert (vpos >= 0 && vpos < w->current_matrix->matrix_h);
1741 if (display_completed)
1743 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
1744 struct glyph *glyph = row->glyphs[TEXT_AREA];
1745 struct glyph *end = glyph + min (hpos, row->used[TEXT_AREA]);
1747 hpos = row->x;
1748 vpos = row->y;
1749 while (glyph < end)
1751 hpos += glyph->pixel_width;
1752 ++glyph;
1755 /* If first glyph is partially visible, its first visible position is still 0. */
1756 if (hpos < 0)
1757 hpos = 0;
1759 success_p = 1;
1761 else
1763 hpos = vpos = 0;
1764 success_p = 0;
1767 *frame_x = WINDOW_TO_FRAME_PIXEL_X (w, hpos);
1768 *frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, vpos);
1769 return success_p;
1771 #endif
1773 *frame_x = hpos;
1774 *frame_y = vpos;
1775 return 1;
1779 #ifdef HAVE_WINDOW_SYSTEM
1781 /* Find the glyph under window-relative coordinates X/Y in window W.
1782 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1783 strings. Return in *HPOS and *VPOS the row and column number of
1784 the glyph found. Return in *AREA the glyph area containing X.
1785 Value is a pointer to the glyph found or null if X/Y is not on
1786 text, or we can't tell because W's current matrix is not up to
1787 date. */
1789 static
1790 struct glyph *
1791 x_y_to_hpos_vpos (struct window *w, int x, int y, int *hpos, int *vpos,
1792 int *dx, int *dy, int *area)
1794 struct glyph *glyph, *end;
1795 struct glyph_row *row = NULL;
1796 int x0, i;
1798 /* Find row containing Y. Give up if some row is not enabled. */
1799 for (i = 0; i < w->current_matrix->nrows; ++i)
1801 row = MATRIX_ROW (w->current_matrix, i);
1802 if (!row->enabled_p)
1803 return NULL;
1804 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1805 break;
1808 *vpos = i;
1809 *hpos = 0;
1811 /* Give up if Y is not in the window. */
1812 if (i == w->current_matrix->nrows)
1813 return NULL;
1815 /* Get the glyph area containing X. */
1816 if (w->pseudo_window_p)
1818 *area = TEXT_AREA;
1819 x0 = 0;
1821 else
1823 if (x < window_box_left_offset (w, TEXT_AREA))
1825 *area = LEFT_MARGIN_AREA;
1826 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
1828 else if (x < window_box_right_offset (w, TEXT_AREA))
1830 *area = TEXT_AREA;
1831 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
1833 else
1835 *area = RIGHT_MARGIN_AREA;
1836 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
1840 /* Find glyph containing X. */
1841 glyph = row->glyphs[*area];
1842 end = glyph + row->used[*area];
1843 x -= x0;
1844 while (glyph < end && x >= glyph->pixel_width)
1846 x -= glyph->pixel_width;
1847 ++glyph;
1850 if (glyph == end)
1851 return NULL;
1853 if (dx)
1855 *dx = x;
1856 *dy = y - (row->y + row->ascent - glyph->ascent);
1859 *hpos = glyph - row->glyphs[*area];
1860 return glyph;
1864 /* EXPORT:
1865 Convert frame-relative x/y to coordinates relative to window W.
1866 Takes pseudo-windows into account. */
1868 void
1869 frame_to_window_pixel_xy (struct window *w, int *x, int *y)
1871 if (w->pseudo_window_p)
1873 /* A pseudo-window is always full-width, and starts at the
1874 left edge of the frame, plus a frame border. */
1875 struct frame *f = XFRAME (w->frame);
1876 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
1877 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1879 else
1881 *x -= WINDOW_LEFT_EDGE_X (w);
1882 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1886 /* EXPORT:
1887 Return in RECTS[] at most N clipping rectangles for glyph string S.
1888 Return the number of stored rectangles. */
1891 get_glyph_string_clip_rects (struct glyph_string *s, NativeRectangle *rects, int n)
1893 XRectangle r;
1895 if (n <= 0)
1896 return 0;
1898 if (s->row->full_width_p)
1900 /* Draw full-width. X coordinates are relative to S->w->left_col. */
1901 r.x = WINDOW_LEFT_EDGE_X (s->w);
1902 r.width = WINDOW_TOTAL_WIDTH (s->w);
1904 /* Unless displaying a mode or menu bar line, which are always
1905 fully visible, clip to the visible part of the row. */
1906 if (s->w->pseudo_window_p)
1907 r.height = s->row->visible_height;
1908 else
1909 r.height = s->height;
1911 else
1913 /* This is a text line that may be partially visible. */
1914 r.x = window_box_left (s->w, s->area);
1915 r.width = window_box_width (s->w, s->area);
1916 r.height = s->row->visible_height;
1919 if (s->clip_head)
1920 if (r.x < s->clip_head->x)
1922 if (r.width >= s->clip_head->x - r.x)
1923 r.width -= s->clip_head->x - r.x;
1924 else
1925 r.width = 0;
1926 r.x = s->clip_head->x;
1928 if (s->clip_tail)
1929 if (r.x + r.width > s->clip_tail->x + s->clip_tail->background_width)
1931 if (s->clip_tail->x + s->clip_tail->background_width >= r.x)
1932 r.width = s->clip_tail->x + s->clip_tail->background_width - r.x;
1933 else
1934 r.width = 0;
1937 /* If S draws overlapping rows, it's sufficient to use the top and
1938 bottom of the window for clipping because this glyph string
1939 intentionally draws over other lines. */
1940 if (s->for_overlaps)
1942 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1943 r.height = window_text_bottom_y (s->w) - r.y;
1945 /* Alas, the above simple strategy does not work for the
1946 environments with anti-aliased text: if the same text is
1947 drawn onto the same place multiple times, it gets thicker.
1948 If the overlap we are processing is for the erased cursor, we
1949 take the intersection with the rectagle of the cursor. */
1950 if (s->for_overlaps & OVERLAPS_ERASED_CURSOR)
1952 XRectangle rc, r_save = r;
1954 rc.x = WINDOW_TEXT_TO_FRAME_PIXEL_X (s->w, s->w->phys_cursor.x);
1955 rc.y = s->w->phys_cursor.y;
1956 rc.width = s->w->phys_cursor_width;
1957 rc.height = s->w->phys_cursor_height;
1959 x_intersect_rectangles (&r_save, &rc, &r);
1962 else
1964 /* Don't use S->y for clipping because it doesn't take partially
1965 visible lines into account. For example, it can be negative for
1966 partially visible lines at the top of a window. */
1967 if (!s->row->full_width_p
1968 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
1969 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1970 else
1971 r.y = max (0, s->row->y);
1974 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
1976 /* If drawing the cursor, don't let glyph draw outside its
1977 advertised boundaries. Cleartype does this under some circumstances. */
1978 if (s->hl == DRAW_CURSOR)
1980 struct glyph *glyph = s->first_glyph;
1981 int height, max_y;
1983 if (s->x > r.x)
1985 r.width -= s->x - r.x;
1986 r.x = s->x;
1988 r.width = min (r.width, glyph->pixel_width);
1990 /* If r.y is below window bottom, ensure that we still see a cursor. */
1991 height = min (glyph->ascent + glyph->descent,
1992 min (FRAME_LINE_HEIGHT (s->f), s->row->visible_height));
1993 max_y = window_text_bottom_y (s->w) - height;
1994 max_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, max_y);
1995 if (s->ybase - glyph->ascent > max_y)
1997 r.y = max_y;
1998 r.height = height;
2000 else
2002 /* Don't draw cursor glyph taller than our actual glyph. */
2003 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
2004 if (height < r.height)
2006 max_y = r.y + r.height;
2007 r.y = min (max_y, max (r.y, s->ybase + glyph->descent - height));
2008 r.height = min (max_y - r.y, height);
2013 if (s->row->clip)
2015 XRectangle r_save = r;
2017 if (! x_intersect_rectangles (&r_save, s->row->clip, &r))
2018 r.width = 0;
2021 if ((s->for_overlaps & OVERLAPS_BOTH) == 0
2022 || ((s->for_overlaps & OVERLAPS_BOTH) == OVERLAPS_BOTH && n == 1))
2024 #ifdef CONVERT_FROM_XRECT
2025 CONVERT_FROM_XRECT (r, *rects);
2026 #else
2027 *rects = r;
2028 #endif
2029 return 1;
2031 else
2033 /* If we are processing overlapping and allowed to return
2034 multiple clipping rectangles, we exclude the row of the glyph
2035 string from the clipping rectangle. This is to avoid drawing
2036 the same text on the environment with anti-aliasing. */
2037 #ifdef CONVERT_FROM_XRECT
2038 XRectangle rs[2];
2039 #else
2040 XRectangle *rs = rects;
2041 #endif
2042 int i = 0, row_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, s->row->y);
2044 if (s->for_overlaps & OVERLAPS_PRED)
2046 rs[i] = r;
2047 if (r.y + r.height > row_y)
2049 if (r.y < row_y)
2050 rs[i].height = row_y - r.y;
2051 else
2052 rs[i].height = 0;
2054 i++;
2056 if (s->for_overlaps & OVERLAPS_SUCC)
2058 rs[i] = r;
2059 if (r.y < row_y + s->row->visible_height)
2061 if (r.y + r.height > row_y + s->row->visible_height)
2063 rs[i].y = row_y + s->row->visible_height;
2064 rs[i].height = r.y + r.height - rs[i].y;
2066 else
2067 rs[i].height = 0;
2069 i++;
2072 n = i;
2073 #ifdef CONVERT_FROM_XRECT
2074 for (i = 0; i < n; i++)
2075 CONVERT_FROM_XRECT (rs[i], rects[i]);
2076 #endif
2077 return n;
2081 /* EXPORT:
2082 Return in *NR the clipping rectangle for glyph string S. */
2084 void
2085 get_glyph_string_clip_rect (struct glyph_string *s, NativeRectangle *nr)
2087 get_glyph_string_clip_rects (s, nr, 1);
2091 /* EXPORT:
2092 Return the position and height of the phys cursor in window W.
2093 Set w->phys_cursor_width to width of phys cursor.
2096 void
2097 get_phys_cursor_geometry (struct window *w, struct glyph_row *row,
2098 struct glyph *glyph, int *xp, int *yp, int *heightp)
2100 struct frame *f = XFRAME (WINDOW_FRAME (w));
2101 int x, y, wd, h, h0, y0;
2103 /* Compute the width of the rectangle to draw. If on a stretch
2104 glyph, and `x-stretch-block-cursor' is nil, don't draw a
2105 rectangle as wide as the glyph, but use a canonical character
2106 width instead. */
2107 wd = glyph->pixel_width - 1;
2108 #if defined(HAVE_NTGUI) || defined(HAVE_NS)
2109 wd++; /* Why? */
2110 #endif
2112 x = w->phys_cursor.x;
2113 if (x < 0)
2115 wd += x;
2116 x = 0;
2119 if (glyph->type == STRETCH_GLYPH
2120 && !x_stretch_cursor_p)
2121 wd = min (FRAME_COLUMN_WIDTH (f), wd);
2122 w->phys_cursor_width = wd;
2124 y = w->phys_cursor.y + row->ascent - glyph->ascent;
2126 /* If y is below window bottom, ensure that we still see a cursor. */
2127 h0 = min (FRAME_LINE_HEIGHT (f), row->visible_height);
2129 h = max (h0, glyph->ascent + glyph->descent);
2130 h0 = min (h0, glyph->ascent + glyph->descent);
2132 y0 = WINDOW_HEADER_LINE_HEIGHT (w);
2133 if (y < y0)
2135 h = max (h - (y0 - y) + 1, h0);
2136 y = y0 - 1;
2138 else
2140 y0 = window_text_bottom_y (w) - h0;
2141 if (y > y0)
2143 h += y - y0;
2144 y = y0;
2148 *xp = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x);
2149 *yp = WINDOW_TO_FRAME_PIXEL_Y (w, y);
2150 *heightp = h;
2154 * Remember which glyph the mouse is over.
2157 void
2158 remember_mouse_glyph (struct frame *f, int gx, int gy, NativeRectangle *rect)
2160 Lisp_Object window;
2161 struct window *w;
2162 struct glyph_row *r, *gr, *end_row;
2163 enum window_part part;
2164 enum glyph_row_area area;
2165 int x, y, width, height;
2167 /* Try to determine frame pixel position and size of the glyph under
2168 frame pixel coordinates X/Y on frame F. */
2170 if (!f->glyphs_initialized_p
2171 || (window = window_from_coordinates (f, gx, gy, &part, &x, &y, 0),
2172 NILP (window)))
2174 width = FRAME_SMALLEST_CHAR_WIDTH (f);
2175 height = FRAME_SMALLEST_FONT_HEIGHT (f);
2176 goto virtual_glyph;
2179 w = XWINDOW (window);
2180 width = WINDOW_FRAME_COLUMN_WIDTH (w);
2181 height = WINDOW_FRAME_LINE_HEIGHT (w);
2183 r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
2184 end_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
2186 if (w->pseudo_window_p)
2188 area = TEXT_AREA;
2189 part = ON_MODE_LINE; /* Don't adjust margin. */
2190 goto text_glyph;
2193 switch (part)
2195 case ON_LEFT_MARGIN:
2196 area = LEFT_MARGIN_AREA;
2197 goto text_glyph;
2199 case ON_RIGHT_MARGIN:
2200 area = RIGHT_MARGIN_AREA;
2201 goto text_glyph;
2203 case ON_HEADER_LINE:
2204 case ON_MODE_LINE:
2205 gr = (part == ON_HEADER_LINE
2206 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
2207 : MATRIX_MODE_LINE_ROW (w->current_matrix));
2208 gy = gr->y;
2209 area = TEXT_AREA;
2210 goto text_glyph_row_found;
2212 case ON_TEXT:
2213 area = TEXT_AREA;
2215 text_glyph:
2216 gr = 0; gy = 0;
2217 for (; r <= end_row && r->enabled_p; ++r)
2218 if (r->y + r->height > y)
2220 gr = r; gy = r->y;
2221 break;
2224 text_glyph_row_found:
2225 if (gr && gy <= y)
2227 struct glyph *g = gr->glyphs[area];
2228 struct glyph *end = g + gr->used[area];
2230 height = gr->height;
2231 for (gx = gr->x; g < end; gx += g->pixel_width, ++g)
2232 if (gx + g->pixel_width > x)
2233 break;
2235 if (g < end)
2237 if (g->type == IMAGE_GLYPH)
2239 /* Don't remember when mouse is over image, as
2240 image may have hot-spots. */
2241 STORE_NATIVE_RECT (*rect, 0, 0, 0, 0);
2242 return;
2244 width = g->pixel_width;
2246 else
2248 /* Use nominal char spacing at end of line. */
2249 x -= gx;
2250 gx += (x / width) * width;
2253 if (part != ON_MODE_LINE && part != ON_HEADER_LINE)
2254 gx += window_box_left_offset (w, area);
2256 else
2258 /* Use nominal line height at end of window. */
2259 gx = (x / width) * width;
2260 y -= gy;
2261 gy += (y / height) * height;
2263 break;
2265 case ON_LEFT_FRINGE:
2266 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2267 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w)
2268 : window_box_right_offset (w, LEFT_MARGIN_AREA));
2269 width = WINDOW_LEFT_FRINGE_WIDTH (w);
2270 goto row_glyph;
2272 case ON_RIGHT_FRINGE:
2273 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2274 ? window_box_right_offset (w, RIGHT_MARGIN_AREA)
2275 : window_box_right_offset (w, TEXT_AREA));
2276 width = WINDOW_RIGHT_FRINGE_WIDTH (w);
2277 goto row_glyph;
2279 case ON_SCROLL_BAR:
2280 gx = (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)
2282 : (window_box_right_offset (w, RIGHT_MARGIN_AREA)
2283 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2284 ? WINDOW_RIGHT_FRINGE_WIDTH (w)
2285 : 0)));
2286 width = WINDOW_SCROLL_BAR_AREA_WIDTH (w);
2288 row_glyph:
2289 gr = 0, gy = 0;
2290 for (; r <= end_row && r->enabled_p; ++r)
2291 if (r->y + r->height > y)
2293 gr = r; gy = r->y;
2294 break;
2297 if (gr && gy <= y)
2298 height = gr->height;
2299 else
2301 /* Use nominal line height at end of window. */
2302 y -= gy;
2303 gy += (y / height) * height;
2305 break;
2307 default:
2309 virtual_glyph:
2310 /* If there is no glyph under the mouse, then we divide the screen
2311 into a grid of the smallest glyph in the frame, and use that
2312 as our "glyph". */
2314 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to
2315 round down even for negative values. */
2316 if (gx < 0)
2317 gx -= width - 1;
2318 if (gy < 0)
2319 gy -= height - 1;
2321 gx = (gx / width) * width;
2322 gy = (gy / height) * height;
2324 goto store_rect;
2327 gx += WINDOW_LEFT_EDGE_X (w);
2328 gy += WINDOW_TOP_EDGE_Y (w);
2330 store_rect:
2331 STORE_NATIVE_RECT (*rect, gx, gy, width, height);
2333 /* Visible feedback for debugging. */
2334 #if 0
2335 #if HAVE_X_WINDOWS
2336 XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2337 f->output_data.x->normal_gc,
2338 gx, gy, width, height);
2339 #endif
2340 #endif
2344 #endif /* HAVE_WINDOW_SYSTEM */
2347 /***********************************************************************
2348 Lisp form evaluation
2349 ***********************************************************************/
2351 /* Error handler for safe_eval and safe_call. */
2353 static Lisp_Object
2354 safe_eval_handler (Lisp_Object arg)
2356 add_to_log ("Error during redisplay: %s", arg, Qnil);
2357 return Qnil;
2361 /* Evaluate SEXPR and return the result, or nil if something went
2362 wrong. Prevent redisplay during the evaluation. */
2364 /* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1].
2365 Return the result, or nil if something went wrong. Prevent
2366 redisplay during the evaluation. */
2368 Lisp_Object
2369 safe_call (int nargs, Lisp_Object *args)
2371 Lisp_Object val;
2373 if (inhibit_eval_during_redisplay)
2374 val = Qnil;
2375 else
2377 int count = SPECPDL_INDEX ();
2378 struct gcpro gcpro1;
2380 GCPRO1 (args[0]);
2381 gcpro1.nvars = nargs;
2382 specbind (Qinhibit_redisplay, Qt);
2383 /* Use Qt to ensure debugger does not run,
2384 so there is no possibility of wanting to redisplay. */
2385 val = internal_condition_case_n (Ffuncall, nargs, args, Qt,
2386 safe_eval_handler);
2387 UNGCPRO;
2388 val = unbind_to (count, val);
2391 return val;
2395 /* Call function FN with one argument ARG.
2396 Return the result, or nil if something went wrong. */
2398 Lisp_Object
2399 safe_call1 (Lisp_Object fn, Lisp_Object arg)
2401 Lisp_Object args[2];
2402 args[0] = fn;
2403 args[1] = arg;
2404 return safe_call (2, args);
2407 static Lisp_Object Qeval;
2409 Lisp_Object
2410 safe_eval (Lisp_Object sexpr)
2412 return safe_call1 (Qeval, sexpr);
2415 /* Call function FN with one argument ARG.
2416 Return the result, or nil if something went wrong. */
2418 Lisp_Object
2419 safe_call2 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2)
2421 Lisp_Object args[3];
2422 args[0] = fn;
2423 args[1] = arg1;
2424 args[2] = arg2;
2425 return safe_call (3, args);
2430 /***********************************************************************
2431 Debugging
2432 ***********************************************************************/
2434 #if 0
2436 /* Define CHECK_IT to perform sanity checks on iterators.
2437 This is for debugging. It is too slow to do unconditionally. */
2439 static void
2440 check_it (it)
2441 struct it *it;
2443 if (it->method == GET_FROM_STRING)
2445 xassert (STRINGP (it->string));
2446 xassert (IT_STRING_CHARPOS (*it) >= 0);
2448 else
2450 xassert (IT_STRING_CHARPOS (*it) < 0);
2451 if (it->method == GET_FROM_BUFFER)
2453 /* Check that character and byte positions agree. */
2454 xassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
2458 if (it->dpvec)
2459 xassert (it->current.dpvec_index >= 0);
2460 else
2461 xassert (it->current.dpvec_index < 0);
2464 #define CHECK_IT(IT) check_it ((IT))
2466 #else /* not 0 */
2468 #define CHECK_IT(IT) (void) 0
2470 #endif /* not 0 */
2473 #if GLYPH_DEBUG
2475 /* Check that the window end of window W is what we expect it
2476 to be---the last row in the current matrix displaying text. */
2478 static void
2479 check_window_end (w)
2480 struct window *w;
2482 if (!MINI_WINDOW_P (w)
2483 && !NILP (w->window_end_valid))
2485 struct glyph_row *row;
2486 xassert ((row = MATRIX_ROW (w->current_matrix,
2487 XFASTINT (w->window_end_vpos)),
2488 !row->enabled_p
2489 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
2490 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
2494 #define CHECK_WINDOW_END(W) check_window_end ((W))
2496 #else /* not GLYPH_DEBUG */
2498 #define CHECK_WINDOW_END(W) (void) 0
2500 #endif /* not GLYPH_DEBUG */
2504 /***********************************************************************
2505 Iterator initialization
2506 ***********************************************************************/
2508 /* Initialize IT for displaying current_buffer in window W, starting
2509 at character position CHARPOS. CHARPOS < 0 means that no buffer
2510 position is specified which is useful when the iterator is assigned
2511 a position later. BYTEPOS is the byte position corresponding to
2512 CHARPOS. BYTEPOS < 0 means compute it from CHARPOS.
2514 If ROW is not null, calls to produce_glyphs with IT as parameter
2515 will produce glyphs in that row.
2517 BASE_FACE_ID is the id of a base face to use. It must be one of
2518 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2519 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2520 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2522 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2523 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2524 will be initialized to use the corresponding mode line glyph row of
2525 the desired matrix of W. */
2527 void
2528 init_iterator (struct it *it, struct window *w,
2529 EMACS_INT charpos, EMACS_INT bytepos,
2530 struct glyph_row *row, enum face_id base_face_id)
2532 int highlight_region_p;
2533 enum face_id remapped_base_face_id = base_face_id;
2535 /* Some precondition checks. */
2536 xassert (w != NULL && it != NULL);
2537 xassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
2538 && charpos <= ZV));
2540 /* If face attributes have been changed since the last redisplay,
2541 free realized faces now because they depend on face definitions
2542 that might have changed. Don't free faces while there might be
2543 desired matrices pending which reference these faces. */
2544 if (face_change_count && !inhibit_free_realized_faces)
2546 face_change_count = 0;
2547 free_all_realized_faces (Qnil);
2550 /* Perhaps remap BASE_FACE_ID to a user-specified alternative. */
2551 if (! NILP (Vface_remapping_alist))
2552 remapped_base_face_id = lookup_basic_face (XFRAME (w->frame), base_face_id);
2554 /* Use one of the mode line rows of W's desired matrix if
2555 appropriate. */
2556 if (row == NULL)
2558 if (base_face_id == MODE_LINE_FACE_ID
2559 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
2560 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
2561 else if (base_face_id == HEADER_LINE_FACE_ID)
2562 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
2565 /* Clear IT. */
2566 memset (it, 0, sizeof *it);
2567 it->current.overlay_string_index = -1;
2568 it->current.dpvec_index = -1;
2569 it->base_face_id = remapped_base_face_id;
2570 it->string = Qnil;
2571 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
2573 /* The window in which we iterate over current_buffer: */
2574 XSETWINDOW (it->window, w);
2575 it->w = w;
2576 it->f = XFRAME (w->frame);
2578 it->cmp_it.id = -1;
2580 /* Extra space between lines (on window systems only). */
2581 if (base_face_id == DEFAULT_FACE_ID
2582 && FRAME_WINDOW_P (it->f))
2584 if (NATNUMP (current_buffer->extra_line_spacing))
2585 it->extra_line_spacing = XFASTINT (current_buffer->extra_line_spacing);
2586 else if (FLOATP (current_buffer->extra_line_spacing))
2587 it->extra_line_spacing = (XFLOAT_DATA (current_buffer->extra_line_spacing)
2588 * FRAME_LINE_HEIGHT (it->f));
2589 else if (it->f->extra_line_spacing > 0)
2590 it->extra_line_spacing = it->f->extra_line_spacing;
2591 it->max_extra_line_spacing = 0;
2594 /* If realized faces have been removed, e.g. because of face
2595 attribute changes of named faces, recompute them. When running
2596 in batch mode, the face cache of the initial frame is null. If
2597 we happen to get called, make a dummy face cache. */
2598 if (FRAME_FACE_CACHE (it->f) == NULL)
2599 init_frame_faces (it->f);
2600 if (FRAME_FACE_CACHE (it->f)->used == 0)
2601 recompute_basic_faces (it->f);
2603 /* Current value of the `slice', `space-width', and 'height' properties. */
2604 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
2605 it->space_width = Qnil;
2606 it->font_height = Qnil;
2607 it->override_ascent = -1;
2609 /* Are control characters displayed as `^C'? */
2610 it->ctl_arrow_p = !NILP (current_buffer->ctl_arrow);
2612 /* -1 means everything between a CR and the following line end
2613 is invisible. >0 means lines indented more than this value are
2614 invisible. */
2615 it->selective = (INTEGERP (current_buffer->selective_display)
2616 ? XFASTINT (current_buffer->selective_display)
2617 : (!NILP (current_buffer->selective_display)
2618 ? -1 : 0));
2619 it->selective_display_ellipsis_p
2620 = !NILP (current_buffer->selective_display_ellipses);
2622 /* Display table to use. */
2623 it->dp = window_display_table (w);
2625 /* Are multibyte characters enabled in current_buffer? */
2626 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
2628 /* Do we need to reorder bidirectional text? Not if this is a
2629 unibyte buffer: by definition, none of the single-byte characters
2630 are strong R2L, so no reordering is needed. And bidi.c doesn't
2631 support unibyte buffers anyway. */
2632 it->bidi_p
2633 = !NILP (current_buffer->bidi_display_reordering) && it->multibyte_p;
2635 /* Non-zero if we should highlight the region. */
2636 highlight_region_p
2637 = (!NILP (Vtransient_mark_mode)
2638 && !NILP (current_buffer->mark_active)
2639 && XMARKER (current_buffer->mark)->buffer != 0);
2641 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
2642 start and end of a visible region in window IT->w. Set both to
2643 -1 to indicate no region. */
2644 if (highlight_region_p
2645 /* Maybe highlight only in selected window. */
2646 && (/* Either show region everywhere. */
2647 highlight_nonselected_windows
2648 /* Or show region in the selected window. */
2649 || w == XWINDOW (selected_window)
2650 /* Or show the region if we are in the mini-buffer and W is
2651 the window the mini-buffer refers to. */
2652 || (MINI_WINDOW_P (XWINDOW (selected_window))
2653 && WINDOWP (minibuf_selected_window)
2654 && w == XWINDOW (minibuf_selected_window))))
2656 int charpos = marker_position (current_buffer->mark);
2657 it->region_beg_charpos = min (PT, charpos);
2658 it->region_end_charpos = max (PT, charpos);
2660 else
2661 it->region_beg_charpos = it->region_end_charpos = -1;
2663 /* Get the position at which the redisplay_end_trigger hook should
2664 be run, if it is to be run at all. */
2665 if (MARKERP (w->redisplay_end_trigger)
2666 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2667 it->redisplay_end_trigger_charpos
2668 = marker_position (w->redisplay_end_trigger);
2669 else if (INTEGERP (w->redisplay_end_trigger))
2670 it->redisplay_end_trigger_charpos = XINT (w->redisplay_end_trigger);
2672 /* Correct bogus values of tab_width. */
2673 it->tab_width = XINT (current_buffer->tab_width);
2674 if (it->tab_width <= 0 || it->tab_width > 1000)
2675 it->tab_width = 8;
2677 /* Are lines in the display truncated? */
2678 if (base_face_id != DEFAULT_FACE_ID
2679 || XINT (it->w->hscroll)
2680 || (! WINDOW_FULL_WIDTH_P (it->w)
2681 && ((!NILP (Vtruncate_partial_width_windows)
2682 && !INTEGERP (Vtruncate_partial_width_windows))
2683 || (INTEGERP (Vtruncate_partial_width_windows)
2684 && (WINDOW_TOTAL_COLS (it->w)
2685 < XINT (Vtruncate_partial_width_windows))))))
2686 it->line_wrap = TRUNCATE;
2687 else if (NILP (current_buffer->truncate_lines))
2688 it->line_wrap = NILP (current_buffer->word_wrap)
2689 ? WINDOW_WRAP : WORD_WRAP;
2690 else
2691 it->line_wrap = TRUNCATE;
2693 /* Get dimensions of truncation and continuation glyphs. These are
2694 displayed as fringe bitmaps under X, so we don't need them for such
2695 frames. */
2696 if (!FRAME_WINDOW_P (it->f))
2698 if (it->line_wrap == TRUNCATE)
2700 /* We will need the truncation glyph. */
2701 xassert (it->glyph_row == NULL);
2702 produce_special_glyphs (it, IT_TRUNCATION);
2703 it->truncation_pixel_width = it->pixel_width;
2705 else
2707 /* We will need the continuation glyph. */
2708 xassert (it->glyph_row == NULL);
2709 produce_special_glyphs (it, IT_CONTINUATION);
2710 it->continuation_pixel_width = it->pixel_width;
2713 /* Reset these values to zero because the produce_special_glyphs
2714 above has changed them. */
2715 it->pixel_width = it->ascent = it->descent = 0;
2716 it->phys_ascent = it->phys_descent = 0;
2719 /* Set this after getting the dimensions of truncation and
2720 continuation glyphs, so that we don't produce glyphs when calling
2721 produce_special_glyphs, above. */
2722 it->glyph_row = row;
2723 it->area = TEXT_AREA;
2725 /* Forget any previous info about this row being reversed. */
2726 if (it->glyph_row)
2727 it->glyph_row->reversed_p = 0;
2729 /* Get the dimensions of the display area. The display area
2730 consists of the visible window area plus a horizontally scrolled
2731 part to the left of the window. All x-values are relative to the
2732 start of this total display area. */
2733 if (base_face_id != DEFAULT_FACE_ID)
2735 /* Mode lines, menu bar in terminal frames. */
2736 it->first_visible_x = 0;
2737 it->last_visible_x = WINDOW_TOTAL_WIDTH (w);
2739 else
2741 it->first_visible_x
2742 = XFASTINT (it->w->hscroll) * FRAME_COLUMN_WIDTH (it->f);
2743 it->last_visible_x = (it->first_visible_x
2744 + window_box_width (w, TEXT_AREA));
2746 /* If we truncate lines, leave room for the truncator glyph(s) at
2747 the right margin. Otherwise, leave room for the continuation
2748 glyph(s). Truncation and continuation glyphs are not inserted
2749 for window-based redisplay. */
2750 if (!FRAME_WINDOW_P (it->f))
2752 if (it->line_wrap == TRUNCATE)
2753 it->last_visible_x -= it->truncation_pixel_width;
2754 else
2755 it->last_visible_x -= it->continuation_pixel_width;
2758 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
2759 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
2762 /* Leave room for a border glyph. */
2763 if (!FRAME_WINDOW_P (it->f)
2764 && !WINDOW_RIGHTMOST_P (it->w))
2765 it->last_visible_x -= 1;
2767 it->last_visible_y = window_text_bottom_y (w);
2769 /* For mode lines and alike, arrange for the first glyph having a
2770 left box line if the face specifies a box. */
2771 if (base_face_id != DEFAULT_FACE_ID)
2773 struct face *face;
2775 it->face_id = remapped_base_face_id;
2777 /* If we have a boxed mode line, make the first character appear
2778 with a left box line. */
2779 face = FACE_FROM_ID (it->f, remapped_base_face_id);
2780 if (face->box != FACE_NO_BOX)
2781 it->start_of_box_run_p = 1;
2784 /* If we are to reorder bidirectional text, init the bidi
2785 iterator. */
2786 if (it->bidi_p)
2788 /* Note the paragraph direction that this buffer wants to
2789 use. */
2790 if (EQ (current_buffer->bidi_paragraph_direction, Qleft_to_right))
2791 it->paragraph_embedding = L2R;
2792 else if (EQ (current_buffer->bidi_paragraph_direction, Qright_to_left))
2793 it->paragraph_embedding = R2L;
2794 else
2795 it->paragraph_embedding = NEUTRAL_DIR;
2796 bidi_init_it (charpos, bytepos, &it->bidi_it);
2799 /* If a buffer position was specified, set the iterator there,
2800 getting overlays and face properties from that position. */
2801 if (charpos >= BUF_BEG (current_buffer))
2803 it->end_charpos = ZV;
2804 it->face_id = -1;
2805 IT_CHARPOS (*it) = charpos;
2807 /* Compute byte position if not specified. */
2808 if (bytepos < charpos)
2809 IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos);
2810 else
2811 IT_BYTEPOS (*it) = bytepos;
2813 it->start = it->current;
2815 /* Compute faces etc. */
2816 reseat (it, it->current.pos, 1);
2819 CHECK_IT (it);
2823 /* Initialize IT for the display of window W with window start POS. */
2825 void
2826 start_display (struct it *it, struct window *w, struct text_pos pos)
2828 struct glyph_row *row;
2829 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
2831 row = w->desired_matrix->rows + first_vpos;
2832 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
2833 it->first_vpos = first_vpos;
2835 /* Don't reseat to previous visible line start if current start
2836 position is in a string or image. */
2837 if (it->method == GET_FROM_BUFFER && it->line_wrap != TRUNCATE)
2839 int start_at_line_beg_p;
2840 int first_y = it->current_y;
2842 /* If window start is not at a line start, skip forward to POS to
2843 get the correct continuation lines width. */
2844 start_at_line_beg_p = (CHARPOS (pos) == BEGV
2845 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
2846 if (!start_at_line_beg_p)
2848 int new_x;
2850 reseat_at_previous_visible_line_start (it);
2851 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
2853 new_x = it->current_x + it->pixel_width;
2855 /* If lines are continued, this line may end in the middle
2856 of a multi-glyph character (e.g. a control character
2857 displayed as \003, or in the middle of an overlay
2858 string). In this case move_it_to above will not have
2859 taken us to the start of the continuation line but to the
2860 end of the continued line. */
2861 if (it->current_x > 0
2862 && it->line_wrap != TRUNCATE /* Lines are continued. */
2863 && (/* And glyph doesn't fit on the line. */
2864 new_x > it->last_visible_x
2865 /* Or it fits exactly and we're on a window
2866 system frame. */
2867 || (new_x == it->last_visible_x
2868 && FRAME_WINDOW_P (it->f))))
2870 if (it->current.dpvec_index >= 0
2871 || it->current.overlay_string_index >= 0)
2873 set_iterator_to_next (it, 1);
2874 move_it_in_display_line_to (it, -1, -1, 0);
2877 it->continuation_lines_width += it->current_x;
2880 /* We're starting a new display line, not affected by the
2881 height of the continued line, so clear the appropriate
2882 fields in the iterator structure. */
2883 it->max_ascent = it->max_descent = 0;
2884 it->max_phys_ascent = it->max_phys_descent = 0;
2886 it->current_y = first_y;
2887 it->vpos = 0;
2888 it->current_x = it->hpos = 0;
2894 /* Return 1 if POS is a position in ellipses displayed for invisible
2895 text. W is the window we display, for text property lookup. */
2897 static int
2898 in_ellipses_for_invisible_text_p (struct display_pos *pos, struct window *w)
2900 Lisp_Object prop, window;
2901 int ellipses_p = 0;
2902 int charpos = CHARPOS (pos->pos);
2904 /* If POS specifies a position in a display vector, this might
2905 be for an ellipsis displayed for invisible text. We won't
2906 get the iterator set up for delivering that ellipsis unless
2907 we make sure that it gets aware of the invisible text. */
2908 if (pos->dpvec_index >= 0
2909 && pos->overlay_string_index < 0
2910 && CHARPOS (pos->string_pos) < 0
2911 && charpos > BEGV
2912 && (XSETWINDOW (window, w),
2913 prop = Fget_char_property (make_number (charpos),
2914 Qinvisible, window),
2915 !TEXT_PROP_MEANS_INVISIBLE (prop)))
2917 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
2918 window);
2919 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
2922 return ellipses_p;
2926 /* Initialize IT for stepping through current_buffer in window W,
2927 starting at position POS that includes overlay string and display
2928 vector/ control character translation position information. Value
2929 is zero if there are overlay strings with newlines at POS. */
2931 static int
2932 init_from_display_pos (struct it *it, struct window *w, struct display_pos *pos)
2934 EMACS_INT charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
2935 int i, overlay_strings_with_newlines = 0;
2937 /* If POS specifies a position in a display vector, this might
2938 be for an ellipsis displayed for invisible text. We won't
2939 get the iterator set up for delivering that ellipsis unless
2940 we make sure that it gets aware of the invisible text. */
2941 if (in_ellipses_for_invisible_text_p (pos, w))
2943 --charpos;
2944 bytepos = 0;
2947 /* Keep in mind: the call to reseat in init_iterator skips invisible
2948 text, so we might end up at a position different from POS. This
2949 is only a problem when POS is a row start after a newline and an
2950 overlay starts there with an after-string, and the overlay has an
2951 invisible property. Since we don't skip invisible text in
2952 display_line and elsewhere immediately after consuming the
2953 newline before the row start, such a POS will not be in a string,
2954 but the call to init_iterator below will move us to the
2955 after-string. */
2956 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
2958 /* This only scans the current chunk -- it should scan all chunks.
2959 However, OVERLAY_STRING_CHUNK_SIZE has been increased from 3 in 21.1
2960 to 16 in 22.1 to make this a lesser problem. */
2961 for (i = 0; i < it->n_overlay_strings && i < OVERLAY_STRING_CHUNK_SIZE; ++i)
2963 const char *s = SDATA (it->overlay_strings[i]);
2964 const char *e = s + SBYTES (it->overlay_strings[i]);
2966 while (s < e && *s != '\n')
2967 ++s;
2969 if (s < e)
2971 overlay_strings_with_newlines = 1;
2972 break;
2976 /* If position is within an overlay string, set up IT to the right
2977 overlay string. */
2978 if (pos->overlay_string_index >= 0)
2980 int relative_index;
2982 /* If the first overlay string happens to have a `display'
2983 property for an image, the iterator will be set up for that
2984 image, and we have to undo that setup first before we can
2985 correct the overlay string index. */
2986 if (it->method == GET_FROM_IMAGE)
2987 pop_it (it);
2989 /* We already have the first chunk of overlay strings in
2990 IT->overlay_strings. Load more until the one for
2991 pos->overlay_string_index is in IT->overlay_strings. */
2992 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
2994 int n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
2995 it->current.overlay_string_index = 0;
2996 while (n--)
2998 load_overlay_strings (it, 0);
2999 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
3003 it->current.overlay_string_index = pos->overlay_string_index;
3004 relative_index = (it->current.overlay_string_index
3005 % OVERLAY_STRING_CHUNK_SIZE);
3006 it->string = it->overlay_strings[relative_index];
3007 xassert (STRINGP (it->string));
3008 it->current.string_pos = pos->string_pos;
3009 it->method = GET_FROM_STRING;
3012 if (CHARPOS (pos->string_pos) >= 0)
3014 /* Recorded position is not in an overlay string, but in another
3015 string. This can only be a string from a `display' property.
3016 IT should already be filled with that string. */
3017 it->current.string_pos = pos->string_pos;
3018 xassert (STRINGP (it->string));
3021 /* Restore position in display vector translations, control
3022 character translations or ellipses. */
3023 if (pos->dpvec_index >= 0)
3025 if (it->dpvec == NULL)
3026 get_next_display_element (it);
3027 xassert (it->dpvec && it->current.dpvec_index == 0);
3028 it->current.dpvec_index = pos->dpvec_index;
3031 CHECK_IT (it);
3032 return !overlay_strings_with_newlines;
3036 /* Initialize IT for stepping through current_buffer in window W
3037 starting at ROW->start. */
3039 static void
3040 init_to_row_start (struct it *it, struct window *w, struct glyph_row *row)
3042 init_from_display_pos (it, w, &row->start);
3043 it->start = row->start;
3044 it->continuation_lines_width = row->continuation_lines_width;
3045 CHECK_IT (it);
3049 /* Initialize IT for stepping through current_buffer in window W
3050 starting in the line following ROW, i.e. starting at ROW->end.
3051 Value is zero if there are overlay strings with newlines at ROW's
3052 end position. */
3054 static int
3055 init_to_row_end (struct it *it, struct window *w, struct glyph_row *row)
3057 int success = 0;
3059 if (init_from_display_pos (it, w, &row->end))
3061 if (row->continued_p)
3062 it->continuation_lines_width
3063 = row->continuation_lines_width + row->pixel_width;
3064 CHECK_IT (it);
3065 success = 1;
3068 return success;
3074 /***********************************************************************
3075 Text properties
3076 ***********************************************************************/
3078 /* Called when IT reaches IT->stop_charpos. Handle text property and
3079 overlay changes. Set IT->stop_charpos to the next position where
3080 to stop. */
3082 static void
3083 handle_stop (struct it *it)
3085 enum prop_handled handled;
3086 int handle_overlay_change_p;
3087 struct props *p;
3089 it->dpvec = NULL;
3090 it->current.dpvec_index = -1;
3091 handle_overlay_change_p = !it->ignore_overlay_strings_at_pos_p;
3092 it->ignore_overlay_strings_at_pos_p = 0;
3093 it->ellipsis_p = 0;
3095 /* Use face of preceding text for ellipsis (if invisible) */
3096 if (it->selective_display_ellipsis_p)
3097 it->saved_face_id = it->face_id;
3101 handled = HANDLED_NORMALLY;
3103 /* Call text property handlers. */
3104 for (p = it_props; p->handler; ++p)
3106 handled = p->handler (it);
3108 if (handled == HANDLED_RECOMPUTE_PROPS)
3109 break;
3110 else if (handled == HANDLED_RETURN)
3112 /* We still want to show before and after strings from
3113 overlays even if the actual buffer text is replaced. */
3114 if (!handle_overlay_change_p
3115 || it->sp > 1
3116 || !get_overlay_strings_1 (it, 0, 0))
3118 if (it->ellipsis_p)
3119 setup_for_ellipsis (it, 0);
3120 /* When handling a display spec, we might load an
3121 empty string. In that case, discard it here. We
3122 used to discard it in handle_single_display_spec,
3123 but that causes get_overlay_strings_1, above, to
3124 ignore overlay strings that we must check. */
3125 if (STRINGP (it->string) && !SCHARS (it->string))
3126 pop_it (it);
3127 return;
3129 else if (STRINGP (it->string) && !SCHARS (it->string))
3130 pop_it (it);
3131 else
3133 it->ignore_overlay_strings_at_pos_p = 1;
3134 it->string_from_display_prop_p = 0;
3135 handle_overlay_change_p = 0;
3137 handled = HANDLED_RECOMPUTE_PROPS;
3138 break;
3140 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
3141 handle_overlay_change_p = 0;
3144 if (handled != HANDLED_RECOMPUTE_PROPS)
3146 /* Don't check for overlay strings below when set to deliver
3147 characters from a display vector. */
3148 if (it->method == GET_FROM_DISPLAY_VECTOR)
3149 handle_overlay_change_p = 0;
3151 /* Handle overlay changes.
3152 This sets HANDLED to HANDLED_RECOMPUTE_PROPS
3153 if it finds overlays. */
3154 if (handle_overlay_change_p)
3155 handled = handle_overlay_change (it);
3158 if (it->ellipsis_p)
3160 setup_for_ellipsis (it, 0);
3161 break;
3164 while (handled == HANDLED_RECOMPUTE_PROPS);
3166 /* Determine where to stop next. */
3167 if (handled == HANDLED_NORMALLY)
3168 compute_stop_pos (it);
3172 /* Compute IT->stop_charpos from text property and overlay change
3173 information for IT's current position. */
3175 static void
3176 compute_stop_pos (struct it *it)
3178 register INTERVAL iv, next_iv;
3179 Lisp_Object object, limit, position;
3180 EMACS_INT charpos, bytepos, stoppos;
3182 /* If nowhere else, stop at the end. */
3183 it->stop_charpos = it->end_charpos;
3185 if (STRINGP (it->string))
3187 /* Strings are usually short, so don't limit the search for
3188 properties. */
3189 object = it->string;
3190 limit = Qnil;
3191 charpos = IT_STRING_CHARPOS (*it);
3192 bytepos = IT_STRING_BYTEPOS (*it);
3194 else
3196 EMACS_INT pos;
3198 /* If next overlay change is in front of the current stop pos
3199 (which is IT->end_charpos), stop there. Note: value of
3200 next_overlay_change is point-max if no overlay change
3201 follows. */
3202 charpos = IT_CHARPOS (*it);
3203 bytepos = IT_BYTEPOS (*it);
3204 pos = next_overlay_change (charpos);
3205 if (pos < it->stop_charpos)
3206 it->stop_charpos = pos;
3208 /* If showing the region, we have to stop at the region
3209 start or end because the face might change there. */
3210 if (it->region_beg_charpos > 0)
3212 if (IT_CHARPOS (*it) < it->region_beg_charpos)
3213 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
3214 else if (IT_CHARPOS (*it) < it->region_end_charpos)
3215 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
3218 /* Set up variables for computing the stop position from text
3219 property changes. */
3220 XSETBUFFER (object, current_buffer);
3221 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
3224 /* Get the interval containing IT's position. Value is a null
3225 interval if there isn't such an interval. */
3226 position = make_number (charpos);
3227 iv = validate_interval_range (object, &position, &position, 0);
3228 if (!NULL_INTERVAL_P (iv))
3230 Lisp_Object values_here[LAST_PROP_IDX];
3231 struct props *p;
3233 /* Get properties here. */
3234 for (p = it_props; p->handler; ++p)
3235 values_here[p->idx] = textget (iv->plist, *p->name);
3237 /* Look for an interval following iv that has different
3238 properties. */
3239 for (next_iv = next_interval (iv);
3240 (!NULL_INTERVAL_P (next_iv)
3241 && (NILP (limit)
3242 || XFASTINT (limit) > next_iv->position));
3243 next_iv = next_interval (next_iv))
3245 for (p = it_props; p->handler; ++p)
3247 Lisp_Object new_value;
3249 new_value = textget (next_iv->plist, *p->name);
3250 if (!EQ (values_here[p->idx], new_value))
3251 break;
3254 if (p->handler)
3255 break;
3258 if (!NULL_INTERVAL_P (next_iv))
3260 if (INTEGERP (limit)
3261 && next_iv->position >= XFASTINT (limit))
3262 /* No text property change up to limit. */
3263 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
3264 else
3265 /* Text properties change in next_iv. */
3266 it->stop_charpos = min (it->stop_charpos, next_iv->position);
3270 if (it->bidi_p && it->bidi_it.scan_dir < 0)
3271 stoppos = -1;
3272 else
3273 stoppos = it->stop_charpos;
3274 composition_compute_stop_pos (&it->cmp_it, charpos, bytepos,
3275 stoppos, it->string);
3277 xassert (STRINGP (it->string)
3278 || (it->stop_charpos >= BEGV
3279 && it->stop_charpos >= IT_CHARPOS (*it)));
3283 /* Return the position of the next overlay change after POS in
3284 current_buffer. Value is point-max if no overlay change
3285 follows. This is like `next-overlay-change' but doesn't use
3286 xmalloc. */
3288 static EMACS_INT
3289 next_overlay_change (EMACS_INT pos)
3291 int noverlays;
3292 EMACS_INT endpos;
3293 Lisp_Object *overlays;
3294 int i;
3296 /* Get all overlays at the given position. */
3297 GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, 1);
3299 /* If any of these overlays ends before endpos,
3300 use its ending point instead. */
3301 for (i = 0; i < noverlays; ++i)
3303 Lisp_Object oend;
3304 EMACS_INT oendpos;
3306 oend = OVERLAY_END (overlays[i]);
3307 oendpos = OVERLAY_POSITION (oend);
3308 endpos = min (endpos, oendpos);
3311 return endpos;
3316 /***********************************************************************
3317 Fontification
3318 ***********************************************************************/
3320 /* Handle changes in the `fontified' property of the current buffer by
3321 calling hook functions from Qfontification_functions to fontify
3322 regions of text. */
3324 static enum prop_handled
3325 handle_fontified_prop (struct it *it)
3327 Lisp_Object prop, pos;
3328 enum prop_handled handled = HANDLED_NORMALLY;
3330 if (!NILP (Vmemory_full))
3331 return handled;
3333 /* Get the value of the `fontified' property at IT's current buffer
3334 position. (The `fontified' property doesn't have a special
3335 meaning in strings.) If the value is nil, call functions from
3336 Qfontification_functions. */
3337 if (!STRINGP (it->string)
3338 && it->s == NULL
3339 && !NILP (Vfontification_functions)
3340 && !NILP (Vrun_hooks)
3341 && (pos = make_number (IT_CHARPOS (*it)),
3342 prop = Fget_char_property (pos, Qfontified, Qnil),
3343 /* Ignore the special cased nil value always present at EOB since
3344 no amount of fontifying will be able to change it. */
3345 NILP (prop) && IT_CHARPOS (*it) < Z))
3347 int count = SPECPDL_INDEX ();
3348 Lisp_Object val;
3350 val = Vfontification_functions;
3351 specbind (Qfontification_functions, Qnil);
3353 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
3354 safe_call1 (val, pos);
3355 else
3357 Lisp_Object globals, fn;
3358 struct gcpro gcpro1, gcpro2;
3360 globals = Qnil;
3361 GCPRO2 (val, globals);
3363 for (; CONSP (val); val = XCDR (val))
3365 fn = XCAR (val);
3367 if (EQ (fn, Qt))
3369 /* A value of t indicates this hook has a local
3370 binding; it means to run the global binding too.
3371 In a global value, t should not occur. If it
3372 does, we must ignore it to avoid an endless
3373 loop. */
3374 for (globals = Fdefault_value (Qfontification_functions);
3375 CONSP (globals);
3376 globals = XCDR (globals))
3378 fn = XCAR (globals);
3379 if (!EQ (fn, Qt))
3380 safe_call1 (fn, pos);
3383 else
3384 safe_call1 (fn, pos);
3387 UNGCPRO;
3390 unbind_to (count, Qnil);
3392 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
3393 something. This avoids an endless loop if they failed to
3394 fontify the text for which reason ever. */
3395 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
3396 handled = HANDLED_RECOMPUTE_PROPS;
3399 return handled;
3404 /***********************************************************************
3405 Faces
3406 ***********************************************************************/
3408 /* Set up iterator IT from face properties at its current position.
3409 Called from handle_stop. */
3411 static enum prop_handled
3412 handle_face_prop (struct it *it)
3414 int new_face_id;
3415 EMACS_INT next_stop;
3417 if (!STRINGP (it->string))
3419 new_face_id
3420 = face_at_buffer_position (it->w,
3421 IT_CHARPOS (*it),
3422 it->region_beg_charpos,
3423 it->region_end_charpos,
3424 &next_stop,
3425 (IT_CHARPOS (*it)
3426 + TEXT_PROP_DISTANCE_LIMIT),
3427 0, it->base_face_id);
3429 /* Is this a start of a run of characters with box face?
3430 Caveat: this can be called for a freshly initialized
3431 iterator; face_id is -1 in this case. We know that the new
3432 face will not change until limit, i.e. if the new face has a
3433 box, all characters up to limit will have one. But, as
3434 usual, we don't know whether limit is really the end. */
3435 if (new_face_id != it->face_id)
3437 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3439 /* If new face has a box but old face has not, this is
3440 the start of a run of characters with box, i.e. it has
3441 a shadow on the left side. The value of face_id of the
3442 iterator will be -1 if this is the initial call that gets
3443 the face. In this case, we have to look in front of IT's
3444 position and see whether there is a face != new_face_id. */
3445 it->start_of_box_run_p
3446 = (new_face->box != FACE_NO_BOX
3447 && (it->face_id >= 0
3448 || IT_CHARPOS (*it) == BEG
3449 || new_face_id != face_before_it_pos (it)));
3450 it->face_box_p = new_face->box != FACE_NO_BOX;
3453 else
3455 int base_face_id, bufpos;
3456 int i;
3457 Lisp_Object from_overlay
3458 = (it->current.overlay_string_index >= 0
3459 ? it->string_overlays[it->current.overlay_string_index]
3460 : Qnil);
3462 /* See if we got to this string directly or indirectly from
3463 an overlay property. That includes the before-string or
3464 after-string of an overlay, strings in display properties
3465 provided by an overlay, their text properties, etc.
3467 FROM_OVERLAY is the overlay that brought us here, or nil if none. */
3468 if (! NILP (from_overlay))
3469 for (i = it->sp - 1; i >= 0; i--)
3471 if (it->stack[i].current.overlay_string_index >= 0)
3472 from_overlay
3473 = it->string_overlays[it->stack[i].current.overlay_string_index];
3474 else if (! NILP (it->stack[i].from_overlay))
3475 from_overlay = it->stack[i].from_overlay;
3477 if (!NILP (from_overlay))
3478 break;
3481 if (! NILP (from_overlay))
3483 bufpos = IT_CHARPOS (*it);
3484 /* For a string from an overlay, the base face depends
3485 only on text properties and ignores overlays. */
3486 base_face_id
3487 = face_for_overlay_string (it->w,
3488 IT_CHARPOS (*it),
3489 it->region_beg_charpos,
3490 it->region_end_charpos,
3491 &next_stop,
3492 (IT_CHARPOS (*it)
3493 + TEXT_PROP_DISTANCE_LIMIT),
3495 from_overlay);
3497 else
3499 bufpos = 0;
3501 /* For strings from a `display' property, use the face at
3502 IT's current buffer position as the base face to merge
3503 with, so that overlay strings appear in the same face as
3504 surrounding text, unless they specify their own
3505 faces. */
3506 base_face_id = underlying_face_id (it);
3509 new_face_id = face_at_string_position (it->w,
3510 it->string,
3511 IT_STRING_CHARPOS (*it),
3512 bufpos,
3513 it->region_beg_charpos,
3514 it->region_end_charpos,
3515 &next_stop,
3516 base_face_id, 0);
3518 /* Is this a start of a run of characters with box? Caveat:
3519 this can be called for a freshly allocated iterator; face_id
3520 is -1 is this case. We know that the new face will not
3521 change until the next check pos, i.e. if the new face has a
3522 box, all characters up to that position will have a
3523 box. But, as usual, we don't know whether that position
3524 is really the end. */
3525 if (new_face_id != it->face_id)
3527 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3528 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
3530 /* If new face has a box but old face hasn't, this is the
3531 start of a run of characters with box, i.e. it has a
3532 shadow on the left side. */
3533 it->start_of_box_run_p
3534 = new_face->box && (old_face == NULL || !old_face->box);
3535 it->face_box_p = new_face->box != FACE_NO_BOX;
3539 it->face_id = new_face_id;
3540 return HANDLED_NORMALLY;
3544 /* Return the ID of the face ``underlying'' IT's current position,
3545 which is in a string. If the iterator is associated with a
3546 buffer, return the face at IT's current buffer position.
3547 Otherwise, use the iterator's base_face_id. */
3549 static int
3550 underlying_face_id (struct it *it)
3552 int face_id = it->base_face_id, i;
3554 xassert (STRINGP (it->string));
3556 for (i = it->sp - 1; i >= 0; --i)
3557 if (NILP (it->stack[i].string))
3558 face_id = it->stack[i].face_id;
3560 return face_id;
3564 /* Compute the face one character before or after the current position
3565 of IT. BEFORE_P non-zero means get the face in front of IT's
3566 position. Value is the id of the face. */
3568 static int
3569 face_before_or_after_it_pos (struct it *it, int before_p)
3571 int face_id, limit;
3572 EMACS_INT next_check_charpos;
3573 struct text_pos pos;
3575 xassert (it->s == NULL);
3577 if (STRINGP (it->string))
3579 int bufpos, base_face_id;
3581 /* No face change past the end of the string (for the case
3582 we are padding with spaces). No face change before the
3583 string start. */
3584 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
3585 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
3586 return it->face_id;
3588 /* Set pos to the position before or after IT's current position. */
3589 if (before_p)
3590 pos = string_pos (IT_STRING_CHARPOS (*it) - 1, it->string);
3591 else
3592 /* For composition, we must check the character after the
3593 composition. */
3594 pos = (it->what == IT_COMPOSITION
3595 ? string_pos (IT_STRING_CHARPOS (*it)
3596 + it->cmp_it.nchars, it->string)
3597 : string_pos (IT_STRING_CHARPOS (*it) + 1, it->string));
3599 if (it->current.overlay_string_index >= 0)
3600 bufpos = IT_CHARPOS (*it);
3601 else
3602 bufpos = 0;
3604 base_face_id = underlying_face_id (it);
3606 /* Get the face for ASCII, or unibyte. */
3607 face_id = face_at_string_position (it->w,
3608 it->string,
3609 CHARPOS (pos),
3610 bufpos,
3611 it->region_beg_charpos,
3612 it->region_end_charpos,
3613 &next_check_charpos,
3614 base_face_id, 0);
3616 /* Correct the face for charsets different from ASCII. Do it
3617 for the multibyte case only. The face returned above is
3618 suitable for unibyte text if IT->string is unibyte. */
3619 if (STRING_MULTIBYTE (it->string))
3621 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos);
3622 int rest = SBYTES (it->string) - BYTEPOS (pos);
3623 int c, len;
3624 struct face *face = FACE_FROM_ID (it->f, face_id);
3626 c = string_char_and_length (p, &len);
3627 face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), it->string);
3630 else
3632 if ((IT_CHARPOS (*it) >= ZV && !before_p)
3633 || (IT_CHARPOS (*it) <= BEGV && before_p))
3634 return it->face_id;
3636 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
3637 pos = it->current.pos;
3639 if (before_p)
3640 DEC_TEXT_POS (pos, it->multibyte_p);
3641 else
3643 if (it->what == IT_COMPOSITION)
3644 /* For composition, we must check the position after the
3645 composition. */
3646 pos.charpos += it->cmp_it.nchars, pos.bytepos += it->len;
3647 else
3648 INC_TEXT_POS (pos, it->multibyte_p);
3651 /* Determine face for CHARSET_ASCII, or unibyte. */
3652 face_id = face_at_buffer_position (it->w,
3653 CHARPOS (pos),
3654 it->region_beg_charpos,
3655 it->region_end_charpos,
3656 &next_check_charpos,
3657 limit, 0, -1);
3659 /* Correct the face for charsets different from ASCII. Do it
3660 for the multibyte case only. The face returned above is
3661 suitable for unibyte text if current_buffer is unibyte. */
3662 if (it->multibyte_p)
3664 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
3665 struct face *face = FACE_FROM_ID (it->f, face_id);
3666 face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), Qnil);
3670 return face_id;
3675 /***********************************************************************
3676 Invisible text
3677 ***********************************************************************/
3679 /* Set up iterator IT from invisible properties at its current
3680 position. Called from handle_stop. */
3682 static enum prop_handled
3683 handle_invisible_prop (struct it *it)
3685 enum prop_handled handled = HANDLED_NORMALLY;
3687 if (STRINGP (it->string))
3689 Lisp_Object prop, end_charpos, limit, charpos;
3691 /* Get the value of the invisible text property at the
3692 current position. Value will be nil if there is no such
3693 property. */
3694 charpos = make_number (IT_STRING_CHARPOS (*it));
3695 prop = Fget_text_property (charpos, Qinvisible, it->string);
3697 if (!NILP (prop)
3698 && IT_STRING_CHARPOS (*it) < it->end_charpos)
3700 handled = HANDLED_RECOMPUTE_PROPS;
3702 /* Get the position at which the next change of the
3703 invisible text property can be found in IT->string.
3704 Value will be nil if the property value is the same for
3705 all the rest of IT->string. */
3706 XSETINT (limit, SCHARS (it->string));
3707 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
3708 it->string, limit);
3710 /* Text at current position is invisible. The next
3711 change in the property is at position end_charpos.
3712 Move IT's current position to that position. */
3713 if (INTEGERP (end_charpos)
3714 && XFASTINT (end_charpos) < XFASTINT (limit))
3716 struct text_pos old;
3717 old = it->current.string_pos;
3718 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
3719 compute_string_pos (&it->current.string_pos, old, it->string);
3721 else
3723 /* The rest of the string is invisible. If this is an
3724 overlay string, proceed with the next overlay string
3725 or whatever comes and return a character from there. */
3726 if (it->current.overlay_string_index >= 0)
3728 next_overlay_string (it);
3729 /* Don't check for overlay strings when we just
3730 finished processing them. */
3731 handled = HANDLED_OVERLAY_STRING_CONSUMED;
3733 else
3735 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
3736 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
3741 else
3743 int invis_p;
3744 EMACS_INT newpos, next_stop, start_charpos, tem;
3745 Lisp_Object pos, prop, overlay;
3747 /* First of all, is there invisible text at this position? */
3748 tem = start_charpos = IT_CHARPOS (*it);
3749 pos = make_number (tem);
3750 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
3751 &overlay);
3752 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3754 /* If we are on invisible text, skip over it. */
3755 if (invis_p && start_charpos < it->end_charpos)
3757 /* Record whether we have to display an ellipsis for the
3758 invisible text. */
3759 int display_ellipsis_p = invis_p == 2;
3761 handled = HANDLED_RECOMPUTE_PROPS;
3763 /* Loop skipping over invisible text. The loop is left at
3764 ZV or with IT on the first char being visible again. */
3767 /* Try to skip some invisible text. Return value is the
3768 position reached which can be equal to where we start
3769 if there is nothing invisible there. This skips both
3770 over invisible text properties and overlays with
3771 invisible property. */
3772 newpos = skip_invisible (tem, &next_stop, ZV, it->window);
3774 /* If we skipped nothing at all we weren't at invisible
3775 text in the first place. If everything to the end of
3776 the buffer was skipped, end the loop. */
3777 if (newpos == tem || newpos >= ZV)
3778 invis_p = 0;
3779 else
3781 /* We skipped some characters but not necessarily
3782 all there are. Check if we ended up on visible
3783 text. Fget_char_property returns the property of
3784 the char before the given position, i.e. if we
3785 get invis_p = 0, this means that the char at
3786 newpos is visible. */
3787 pos = make_number (newpos);
3788 prop = Fget_char_property (pos, Qinvisible, it->window);
3789 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3792 /* If we ended up on invisible text, proceed to
3793 skip starting with next_stop. */
3794 if (invis_p)
3795 tem = next_stop;
3797 /* If there are adjacent invisible texts, don't lose the
3798 second one's ellipsis. */
3799 if (invis_p == 2)
3800 display_ellipsis_p = 1;
3802 while (invis_p);
3804 /* The position newpos is now either ZV or on visible text. */
3805 if (it->bidi_p && newpos < ZV)
3807 /* With bidi iteration, the region of invisible text
3808 could start and/or end in the middle of a non-base
3809 embedding level. Therefore, we need to skip
3810 invisible text using the bidi iterator, starting at
3811 IT's current position, until we find ourselves
3812 outside the invisible text. Skipping invisible text
3813 _after_ bidi iteration avoids affecting the visual
3814 order of the displayed text when invisible properties
3815 are added or removed. */
3816 if (it->bidi_it.first_elt)
3818 /* If we were `reseat'ed to a new paragraph,
3819 determine the paragraph base direction. We need
3820 to do it now because next_element_from_buffer may
3821 not have a chance to do it, if we are going to
3822 skip any text at the beginning, which resets the
3823 FIRST_ELT flag. */
3824 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it);
3828 bidi_move_to_visually_next (&it->bidi_it);
3830 while (it->stop_charpos <= it->bidi_it.charpos
3831 && it->bidi_it.charpos < newpos);
3832 IT_CHARPOS (*it) = it->bidi_it.charpos;
3833 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
3834 /* If we overstepped NEWPOS, record its position in the
3835 iterator, so that we skip invisible text if later the
3836 bidi iteration lands us in the invisible region
3837 again. */
3838 if (IT_CHARPOS (*it) >= newpos)
3839 it->prev_stop = newpos;
3841 else
3843 IT_CHARPOS (*it) = newpos;
3844 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
3847 /* If there are before-strings at the start of invisible
3848 text, and the text is invisible because of a text
3849 property, arrange to show before-strings because 20.x did
3850 it that way. (If the text is invisible because of an
3851 overlay property instead of a text property, this is
3852 already handled in the overlay code.) */
3853 if (NILP (overlay)
3854 && get_overlay_strings (it, it->stop_charpos))
3856 handled = HANDLED_RECOMPUTE_PROPS;
3857 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
3859 else if (display_ellipsis_p)
3861 /* Make sure that the glyphs of the ellipsis will get
3862 correct `charpos' values. If we would not update
3863 it->position here, the glyphs would belong to the
3864 last visible character _before_ the invisible
3865 text, which confuses `set_cursor_from_row'.
3867 We use the last invisible position instead of the
3868 first because this way the cursor is always drawn on
3869 the first "." of the ellipsis, whenever PT is inside
3870 the invisible text. Otherwise the cursor would be
3871 placed _after_ the ellipsis when the point is after the
3872 first invisible character. */
3873 if (!STRINGP (it->object))
3875 it->position.charpos = newpos - 1;
3876 it->position.bytepos = CHAR_TO_BYTE (it->position.charpos);
3878 it->ellipsis_p = 1;
3879 /* Let the ellipsis display before
3880 considering any properties of the following char.
3881 Fixes jasonr@gnu.org 01 Oct 07 bug. */
3882 handled = HANDLED_RETURN;
3887 return handled;
3891 /* Make iterator IT return `...' next.
3892 Replaces LEN characters from buffer. */
3894 static void
3895 setup_for_ellipsis (struct it *it, int len)
3897 /* Use the display table definition for `...'. Invalid glyphs
3898 will be handled by the method returning elements from dpvec. */
3899 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
3901 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
3902 it->dpvec = v->contents;
3903 it->dpend = v->contents + v->size;
3905 else
3907 /* Default `...'. */
3908 it->dpvec = default_invis_vector;
3909 it->dpend = default_invis_vector + 3;
3912 it->dpvec_char_len = len;
3913 it->current.dpvec_index = 0;
3914 it->dpvec_face_id = -1;
3916 /* Remember the current face id in case glyphs specify faces.
3917 IT's face is restored in set_iterator_to_next.
3918 saved_face_id was set to preceding char's face in handle_stop. */
3919 if (it->saved_face_id < 0 || it->saved_face_id != it->face_id)
3920 it->saved_face_id = it->face_id = DEFAULT_FACE_ID;
3922 it->method = GET_FROM_DISPLAY_VECTOR;
3923 it->ellipsis_p = 1;
3928 /***********************************************************************
3929 'display' property
3930 ***********************************************************************/
3932 /* Set up iterator IT from `display' property at its current position.
3933 Called from handle_stop.
3934 We return HANDLED_RETURN if some part of the display property
3935 overrides the display of the buffer text itself.
3936 Otherwise we return HANDLED_NORMALLY. */
3938 static enum prop_handled
3939 handle_display_prop (struct it *it)
3941 Lisp_Object prop, object, overlay;
3942 struct text_pos *position;
3943 /* Nonzero if some property replaces the display of the text itself. */
3944 int display_replaced_p = 0;
3946 if (STRINGP (it->string))
3948 object = it->string;
3949 position = &it->current.string_pos;
3951 else
3953 XSETWINDOW (object, it->w);
3954 position = &it->current.pos;
3957 /* Reset those iterator values set from display property values. */
3958 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
3959 it->space_width = Qnil;
3960 it->font_height = Qnil;
3961 it->voffset = 0;
3963 /* We don't support recursive `display' properties, i.e. string
3964 values that have a string `display' property, that have a string
3965 `display' property etc. */
3966 if (!it->string_from_display_prop_p)
3967 it->area = TEXT_AREA;
3969 prop = get_char_property_and_overlay (make_number (position->charpos),
3970 Qdisplay, object, &overlay);
3971 if (NILP (prop))
3972 return HANDLED_NORMALLY;
3973 /* Now OVERLAY is the overlay that gave us this property, or nil
3974 if it was a text property. */
3976 if (!STRINGP (it->string))
3977 object = it->w->buffer;
3979 if (CONSP (prop)
3980 /* Simple properties. */
3981 && !EQ (XCAR (prop), Qimage)
3982 && !EQ (XCAR (prop), Qspace)
3983 && !EQ (XCAR (prop), Qwhen)
3984 && !EQ (XCAR (prop), Qslice)
3985 && !EQ (XCAR (prop), Qspace_width)
3986 && !EQ (XCAR (prop), Qheight)
3987 && !EQ (XCAR (prop), Qraise)
3988 /* Marginal area specifications. */
3989 && !(CONSP (XCAR (prop)) && EQ (XCAR (XCAR (prop)), Qmargin))
3990 && !EQ (XCAR (prop), Qleft_fringe)
3991 && !EQ (XCAR (prop), Qright_fringe)
3992 && !NILP (XCAR (prop)))
3994 for (; CONSP (prop); prop = XCDR (prop))
3996 if (handle_single_display_spec (it, XCAR (prop), object, overlay,
3997 position, display_replaced_p))
3999 display_replaced_p = 1;
4000 /* If some text in a string is replaced, `position' no
4001 longer points to the position of `object'. */
4002 if (STRINGP (object))
4003 break;
4007 else if (VECTORP (prop))
4009 int i;
4010 for (i = 0; i < ASIZE (prop); ++i)
4011 if (handle_single_display_spec (it, AREF (prop, i), object, overlay,
4012 position, display_replaced_p))
4014 display_replaced_p = 1;
4015 /* If some text in a string is replaced, `position' no
4016 longer points to the position of `object'. */
4017 if (STRINGP (object))
4018 break;
4021 else
4023 if (handle_single_display_spec (it, prop, object, overlay,
4024 position, 0))
4025 display_replaced_p = 1;
4028 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
4032 /* Value is the position of the end of the `display' property starting
4033 at START_POS in OBJECT. */
4035 static struct text_pos
4036 display_prop_end (struct it *it, Lisp_Object object, struct text_pos start_pos)
4038 Lisp_Object end;
4039 struct text_pos end_pos;
4041 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
4042 Qdisplay, object, Qnil);
4043 CHARPOS (end_pos) = XFASTINT (end);
4044 if (STRINGP (object))
4045 compute_string_pos (&end_pos, start_pos, it->string);
4046 else
4047 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
4049 return end_pos;
4053 /* Set up IT from a single `display' specification PROP. OBJECT
4054 is the object in which the `display' property was found. *POSITION
4055 is the position at which it was found. DISPLAY_REPLACED_P non-zero
4056 means that we previously saw a display specification which already
4057 replaced text display with something else, for example an image;
4058 we ignore such properties after the first one has been processed.
4060 OVERLAY is the overlay this `display' property came from,
4061 or nil if it was a text property.
4063 If PROP is a `space' or `image' specification, and in some other
4064 cases too, set *POSITION to the position where the `display'
4065 property ends.
4067 Value is non-zero if something was found which replaces the display
4068 of buffer or string text. */
4070 static int
4071 handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4072 Lisp_Object overlay, struct text_pos *position,
4073 int display_replaced_before_p)
4075 Lisp_Object form;
4076 Lisp_Object location, value;
4077 struct text_pos start_pos, save_pos;
4078 int valid_p;
4080 /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
4081 If the result is non-nil, use VALUE instead of SPEC. */
4082 form = Qt;
4083 if (CONSP (spec) && EQ (XCAR (spec), Qwhen))
4085 spec = XCDR (spec);
4086 if (!CONSP (spec))
4087 return 0;
4088 form = XCAR (spec);
4089 spec = XCDR (spec);
4092 if (!NILP (form) && !EQ (form, Qt))
4094 int count = SPECPDL_INDEX ();
4095 struct gcpro gcpro1;
4097 /* Bind `object' to the object having the `display' property, a
4098 buffer or string. Bind `position' to the position in the
4099 object where the property was found, and `buffer-position'
4100 to the current position in the buffer. */
4101 specbind (Qobject, object);
4102 specbind (Qposition, make_number (CHARPOS (*position)));
4103 specbind (Qbuffer_position,
4104 make_number (STRINGP (object)
4105 ? IT_CHARPOS (*it) : CHARPOS (*position)));
4106 GCPRO1 (form);
4107 form = safe_eval (form);
4108 UNGCPRO;
4109 unbind_to (count, Qnil);
4112 if (NILP (form))
4113 return 0;
4115 /* Handle `(height HEIGHT)' specifications. */
4116 if (CONSP (spec)
4117 && EQ (XCAR (spec), Qheight)
4118 && CONSP (XCDR (spec)))
4120 if (!FRAME_WINDOW_P (it->f))
4121 return 0;
4123 it->font_height = XCAR (XCDR (spec));
4124 if (!NILP (it->font_height))
4126 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4127 int new_height = -1;
4129 if (CONSP (it->font_height)
4130 && (EQ (XCAR (it->font_height), Qplus)
4131 || EQ (XCAR (it->font_height), Qminus))
4132 && CONSP (XCDR (it->font_height))
4133 && INTEGERP (XCAR (XCDR (it->font_height))))
4135 /* `(+ N)' or `(- N)' where N is an integer. */
4136 int steps = XINT (XCAR (XCDR (it->font_height)));
4137 if (EQ (XCAR (it->font_height), Qplus))
4138 steps = - steps;
4139 it->face_id = smaller_face (it->f, it->face_id, steps);
4141 else if (FUNCTIONP (it->font_height))
4143 /* Call function with current height as argument.
4144 Value is the new height. */
4145 Lisp_Object height;
4146 height = safe_call1 (it->font_height,
4147 face->lface[LFACE_HEIGHT_INDEX]);
4148 if (NUMBERP (height))
4149 new_height = XFLOATINT (height);
4151 else if (NUMBERP (it->font_height))
4153 /* Value is a multiple of the canonical char height. */
4154 struct face *face;
4156 face = FACE_FROM_ID (it->f,
4157 lookup_basic_face (it->f, DEFAULT_FACE_ID));
4158 new_height = (XFLOATINT (it->font_height)
4159 * XINT (face->lface[LFACE_HEIGHT_INDEX]));
4161 else
4163 /* Evaluate IT->font_height with `height' bound to the
4164 current specified height to get the new height. */
4165 int count = SPECPDL_INDEX ();
4167 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
4168 value = safe_eval (it->font_height);
4169 unbind_to (count, Qnil);
4171 if (NUMBERP (value))
4172 new_height = XFLOATINT (value);
4175 if (new_height > 0)
4176 it->face_id = face_with_height (it->f, it->face_id, new_height);
4179 return 0;
4182 /* Handle `(space-width WIDTH)'. */
4183 if (CONSP (spec)
4184 && EQ (XCAR (spec), Qspace_width)
4185 && CONSP (XCDR (spec)))
4187 if (!FRAME_WINDOW_P (it->f))
4188 return 0;
4190 value = XCAR (XCDR (spec));
4191 if (NUMBERP (value) && XFLOATINT (value) > 0)
4192 it->space_width = value;
4194 return 0;
4197 /* Handle `(slice X Y WIDTH HEIGHT)'. */
4198 if (CONSP (spec)
4199 && EQ (XCAR (spec), Qslice))
4201 Lisp_Object tem;
4203 if (!FRAME_WINDOW_P (it->f))
4204 return 0;
4206 if (tem = XCDR (spec), CONSP (tem))
4208 it->slice.x = XCAR (tem);
4209 if (tem = XCDR (tem), CONSP (tem))
4211 it->slice.y = XCAR (tem);
4212 if (tem = XCDR (tem), CONSP (tem))
4214 it->slice.width = XCAR (tem);
4215 if (tem = XCDR (tem), CONSP (tem))
4216 it->slice.height = XCAR (tem);
4221 return 0;
4224 /* Handle `(raise FACTOR)'. */
4225 if (CONSP (spec)
4226 && EQ (XCAR (spec), Qraise)
4227 && CONSP (XCDR (spec)))
4229 if (!FRAME_WINDOW_P (it->f))
4230 return 0;
4232 #ifdef HAVE_WINDOW_SYSTEM
4233 value = XCAR (XCDR (spec));
4234 if (NUMBERP (value))
4236 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4237 it->voffset = - (XFLOATINT (value)
4238 * (FONT_HEIGHT (face->font)));
4240 #endif /* HAVE_WINDOW_SYSTEM */
4242 return 0;
4245 /* Don't handle the other kinds of display specifications
4246 inside a string that we got from a `display' property. */
4247 if (it->string_from_display_prop_p)
4248 return 0;
4250 /* Characters having this form of property are not displayed, so
4251 we have to find the end of the property. */
4252 start_pos = *position;
4253 *position = display_prop_end (it, object, start_pos);
4254 value = Qnil;
4256 /* Stop the scan at that end position--we assume that all
4257 text properties change there. */
4258 it->stop_charpos = position->charpos;
4260 /* Handle `(left-fringe BITMAP [FACE])'
4261 and `(right-fringe BITMAP [FACE])'. */
4262 if (CONSP (spec)
4263 && (EQ (XCAR (spec), Qleft_fringe)
4264 || EQ (XCAR (spec), Qright_fringe))
4265 && CONSP (XCDR (spec)))
4267 int face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);
4268 int fringe_bitmap;
4270 if (!FRAME_WINDOW_P (it->f))
4271 /* If we return here, POSITION has been advanced
4272 across the text with this property. */
4273 return 0;
4275 #ifdef HAVE_WINDOW_SYSTEM
4276 value = XCAR (XCDR (spec));
4277 if (!SYMBOLP (value)
4278 || !(fringe_bitmap = lookup_fringe_bitmap (value)))
4279 /* If we return here, POSITION has been advanced
4280 across the text with this property. */
4281 return 0;
4283 if (CONSP (XCDR (XCDR (spec))))
4285 Lisp_Object face_name = XCAR (XCDR (XCDR (spec)));
4286 int face_id2 = lookup_derived_face (it->f, face_name,
4287 FRINGE_FACE_ID, 0);
4288 if (face_id2 >= 0)
4289 face_id = face_id2;
4292 /* Save current settings of IT so that we can restore them
4293 when we are finished with the glyph property value. */
4295 save_pos = it->position;
4296 it->position = *position;
4297 push_it (it);
4298 it->position = save_pos;
4300 it->area = TEXT_AREA;
4301 it->what = IT_IMAGE;
4302 it->image_id = -1; /* no image */
4303 it->position = start_pos;
4304 it->object = NILP (object) ? it->w->buffer : object;
4305 it->method = GET_FROM_IMAGE;
4306 it->from_overlay = Qnil;
4307 it->face_id = face_id;
4309 /* Say that we haven't consumed the characters with
4310 `display' property yet. The call to pop_it in
4311 set_iterator_to_next will clean this up. */
4312 *position = start_pos;
4314 if (EQ (XCAR (spec), Qleft_fringe))
4316 it->left_user_fringe_bitmap = fringe_bitmap;
4317 it->left_user_fringe_face_id = face_id;
4319 else
4321 it->right_user_fringe_bitmap = fringe_bitmap;
4322 it->right_user_fringe_face_id = face_id;
4324 #endif /* HAVE_WINDOW_SYSTEM */
4325 return 1;
4328 /* Prepare to handle `((margin left-margin) ...)',
4329 `((margin right-margin) ...)' and `((margin nil) ...)'
4330 prefixes for display specifications. */
4331 location = Qunbound;
4332 if (CONSP (spec) && CONSP (XCAR (spec)))
4334 Lisp_Object tem;
4336 value = XCDR (spec);
4337 if (CONSP (value))
4338 value = XCAR (value);
4340 tem = XCAR (spec);
4341 if (EQ (XCAR (tem), Qmargin)
4342 && (tem = XCDR (tem),
4343 tem = CONSP (tem) ? XCAR (tem) : Qnil,
4344 (NILP (tem)
4345 || EQ (tem, Qleft_margin)
4346 || EQ (tem, Qright_margin))))
4347 location = tem;
4350 if (EQ (location, Qunbound))
4352 location = Qnil;
4353 value = spec;
4356 /* After this point, VALUE is the property after any
4357 margin prefix has been stripped. It must be a string,
4358 an image specification, or `(space ...)'.
4360 LOCATION specifies where to display: `left-margin',
4361 `right-margin' or nil. */
4363 valid_p = (STRINGP (value)
4364 #ifdef HAVE_WINDOW_SYSTEM
4365 || (FRAME_WINDOW_P (it->f) && valid_image_p (value))
4366 #endif /* not HAVE_WINDOW_SYSTEM */
4367 || (CONSP (value) && EQ (XCAR (value), Qspace)));
4369 if (valid_p && !display_replaced_before_p)
4371 /* Save current settings of IT so that we can restore them
4372 when we are finished with the glyph property value. */
4373 save_pos = it->position;
4374 it->position = *position;
4375 push_it (it);
4376 it->position = save_pos;
4377 it->from_overlay = overlay;
4379 if (NILP (location))
4380 it->area = TEXT_AREA;
4381 else if (EQ (location, Qleft_margin))
4382 it->area = LEFT_MARGIN_AREA;
4383 else
4384 it->area = RIGHT_MARGIN_AREA;
4386 if (STRINGP (value))
4388 it->string = value;
4389 it->multibyte_p = STRING_MULTIBYTE (it->string);
4390 it->current.overlay_string_index = -1;
4391 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
4392 it->end_charpos = it->string_nchars = SCHARS (it->string);
4393 it->method = GET_FROM_STRING;
4394 it->stop_charpos = 0;
4395 it->string_from_display_prop_p = 1;
4396 /* Say that we haven't consumed the characters with
4397 `display' property yet. The call to pop_it in
4398 set_iterator_to_next will clean this up. */
4399 if (BUFFERP (object))
4400 *position = start_pos;
4402 else if (CONSP (value) && EQ (XCAR (value), Qspace))
4404 it->method = GET_FROM_STRETCH;
4405 it->object = value;
4406 *position = it->position = start_pos;
4408 #ifdef HAVE_WINDOW_SYSTEM
4409 else
4411 it->what = IT_IMAGE;
4412 it->image_id = lookup_image (it->f, value);
4413 it->position = start_pos;
4414 it->object = NILP (object) ? it->w->buffer : object;
4415 it->method = GET_FROM_IMAGE;
4417 /* Say that we haven't consumed the characters with
4418 `display' property yet. The call to pop_it in
4419 set_iterator_to_next will clean this up. */
4420 *position = start_pos;
4422 #endif /* HAVE_WINDOW_SYSTEM */
4424 return 1;
4427 /* Invalid property or property not supported. Restore
4428 POSITION to what it was before. */
4429 *position = start_pos;
4430 return 0;
4434 /* Check if SPEC is a display sub-property value whose text should be
4435 treated as intangible. */
4437 static int
4438 single_display_spec_intangible_p (Lisp_Object prop)
4440 /* Skip over `when FORM'. */
4441 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
4443 prop = XCDR (prop);
4444 if (!CONSP (prop))
4445 return 0;
4446 prop = XCDR (prop);
4449 if (STRINGP (prop))
4450 return 1;
4452 if (!CONSP (prop))
4453 return 0;
4455 /* Skip over `margin LOCATION'. If LOCATION is in the margins,
4456 we don't need to treat text as intangible. */
4457 if (EQ (XCAR (prop), Qmargin))
4459 prop = XCDR (prop);
4460 if (!CONSP (prop))
4461 return 0;
4463 prop = XCDR (prop);
4464 if (!CONSP (prop)
4465 || EQ (XCAR (prop), Qleft_margin)
4466 || EQ (XCAR (prop), Qright_margin))
4467 return 0;
4470 return (CONSP (prop)
4471 && (EQ (XCAR (prop), Qimage)
4472 || EQ (XCAR (prop), Qspace)));
4476 /* Check if PROP is a display property value whose text should be
4477 treated as intangible. */
4480 display_prop_intangible_p (Lisp_Object prop)
4482 if (CONSP (prop)
4483 && CONSP (XCAR (prop))
4484 && !EQ (Qmargin, XCAR (XCAR (prop))))
4486 /* A list of sub-properties. */
4487 while (CONSP (prop))
4489 if (single_display_spec_intangible_p (XCAR (prop)))
4490 return 1;
4491 prop = XCDR (prop);
4494 else if (VECTORP (prop))
4496 /* A vector of sub-properties. */
4497 int i;
4498 for (i = 0; i < ASIZE (prop); ++i)
4499 if (single_display_spec_intangible_p (AREF (prop, i)))
4500 return 1;
4502 else
4503 return single_display_spec_intangible_p (prop);
4505 return 0;
4509 /* Return 1 if PROP is a display sub-property value containing STRING. */
4511 static int
4512 single_display_spec_string_p (Lisp_Object prop, Lisp_Object string)
4514 if (EQ (string, prop))
4515 return 1;
4517 /* Skip over `when FORM'. */
4518 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
4520 prop = XCDR (prop);
4521 if (!CONSP (prop))
4522 return 0;
4523 prop = XCDR (prop);
4526 if (CONSP (prop))
4527 /* Skip over `margin LOCATION'. */
4528 if (EQ (XCAR (prop), Qmargin))
4530 prop = XCDR (prop);
4531 if (!CONSP (prop))
4532 return 0;
4534 prop = XCDR (prop);
4535 if (!CONSP (prop))
4536 return 0;
4539 return CONSP (prop) && EQ (XCAR (prop), string);
4543 /* Return 1 if STRING appears in the `display' property PROP. */
4545 static int
4546 display_prop_string_p (Lisp_Object prop, Lisp_Object string)
4548 if (CONSP (prop)
4549 && CONSP (XCAR (prop))
4550 && !EQ (Qmargin, XCAR (XCAR (prop))))
4552 /* A list of sub-properties. */
4553 while (CONSP (prop))
4555 if (single_display_spec_string_p (XCAR (prop), string))
4556 return 1;
4557 prop = XCDR (prop);
4560 else if (VECTORP (prop))
4562 /* A vector of sub-properties. */
4563 int i;
4564 for (i = 0; i < ASIZE (prop); ++i)
4565 if (single_display_spec_string_p (AREF (prop, i), string))
4566 return 1;
4568 else
4569 return single_display_spec_string_p (prop, string);
4571 return 0;
4574 /* Look for STRING in overlays and text properties in W's buffer,
4575 between character positions FROM and TO (excluding TO).
4576 BACK_P non-zero means look back (in this case, TO is supposed to be
4577 less than FROM).
4578 Value is the first character position where STRING was found, or
4579 zero if it wasn't found before hitting TO.
4581 W's buffer must be current.
4583 This function may only use code that doesn't eval because it is
4584 called asynchronously from note_mouse_highlight. */
4586 static EMACS_INT
4587 string_buffer_position_lim (struct window *w, Lisp_Object string,
4588 EMACS_INT from, EMACS_INT to, int back_p)
4590 Lisp_Object limit, prop, pos;
4591 int found = 0;
4593 pos = make_number (from);
4595 if (!back_p) /* looking forward */
4597 limit = make_number (min (to, ZV));
4598 while (!found && !EQ (pos, limit))
4600 prop = Fget_char_property (pos, Qdisplay, Qnil);
4601 if (!NILP (prop) && display_prop_string_p (prop, string))
4602 found = 1;
4603 else
4604 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil,
4605 limit);
4608 else /* looking back */
4610 limit = make_number (max (to, BEGV));
4611 while (!found && !EQ (pos, limit))
4613 prop = Fget_char_property (pos, Qdisplay, Qnil);
4614 if (!NILP (prop) && display_prop_string_p (prop, string))
4615 found = 1;
4616 else
4617 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
4618 limit);
4622 return found ? XINT (pos) : 0;
4625 /* Determine which buffer position in W's buffer STRING comes from.
4626 AROUND_CHARPOS is an approximate position where it could come from.
4627 Value is the buffer position or 0 if it couldn't be determined.
4629 W's buffer must be current.
4631 This function is necessary because we don't record buffer positions
4632 in glyphs generated from strings (to keep struct glyph small).
4633 This function may only use code that doesn't eval because it is
4634 called asynchronously from note_mouse_highlight. */
4636 EMACS_INT
4637 string_buffer_position (struct window *w, Lisp_Object string, EMACS_INT around_charpos)
4639 Lisp_Object limit, prop, pos;
4640 const int MAX_DISTANCE = 1000;
4641 EMACS_INT found = string_buffer_position_lim (w, string, around_charpos,
4642 around_charpos + MAX_DISTANCE,
4645 if (!found)
4646 found = string_buffer_position_lim (w, string, around_charpos,
4647 around_charpos - MAX_DISTANCE, 1);
4648 return found;
4653 /***********************************************************************
4654 `composition' property
4655 ***********************************************************************/
4657 /* Set up iterator IT from `composition' property at its current
4658 position. Called from handle_stop. */
4660 static enum prop_handled
4661 handle_composition_prop (struct it *it)
4663 Lisp_Object prop, string;
4664 EMACS_INT pos, pos_byte, start, end;
4666 if (STRINGP (it->string))
4668 unsigned char *s;
4670 pos = IT_STRING_CHARPOS (*it);
4671 pos_byte = IT_STRING_BYTEPOS (*it);
4672 string = it->string;
4673 s = SDATA (string) + pos_byte;
4674 it->c = STRING_CHAR (s);
4676 else
4678 pos = IT_CHARPOS (*it);
4679 pos_byte = IT_BYTEPOS (*it);
4680 string = Qnil;
4681 it->c = FETCH_CHAR (pos_byte);
4684 /* If there's a valid composition and point is not inside of the
4685 composition (in the case that the composition is from the current
4686 buffer), draw a glyph composed from the composition components. */
4687 if (find_composition (pos, -1, &start, &end, &prop, string)
4688 && COMPOSITION_VALID_P (start, end, prop)
4689 && (STRINGP (it->string) || (PT <= start || PT >= end)))
4691 if (start != pos)
4693 if (STRINGP (it->string))
4694 pos_byte = string_char_to_byte (it->string, start);
4695 else
4696 pos_byte = CHAR_TO_BYTE (start);
4698 it->cmp_it.id = get_composition_id (start, pos_byte, end - start,
4699 prop, string);
4701 if (it->cmp_it.id >= 0)
4703 it->cmp_it.ch = -1;
4704 it->cmp_it.nchars = COMPOSITION_LENGTH (prop);
4705 it->cmp_it.nglyphs = -1;
4709 return HANDLED_NORMALLY;
4714 /***********************************************************************
4715 Overlay strings
4716 ***********************************************************************/
4718 /* The following structure is used to record overlay strings for
4719 later sorting in load_overlay_strings. */
4721 struct overlay_entry
4723 Lisp_Object overlay;
4724 Lisp_Object string;
4725 int priority;
4726 int after_string_p;
4730 /* Set up iterator IT from overlay strings at its current position.
4731 Called from handle_stop. */
4733 static enum prop_handled
4734 handle_overlay_change (struct it *it)
4736 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
4737 return HANDLED_RECOMPUTE_PROPS;
4738 else
4739 return HANDLED_NORMALLY;
4743 /* Set up the next overlay string for delivery by IT, if there is an
4744 overlay string to deliver. Called by set_iterator_to_next when the
4745 end of the current overlay string is reached. If there are more
4746 overlay strings to display, IT->string and
4747 IT->current.overlay_string_index are set appropriately here.
4748 Otherwise IT->string is set to nil. */
4750 static void
4751 next_overlay_string (struct it *it)
4753 ++it->current.overlay_string_index;
4754 if (it->current.overlay_string_index == it->n_overlay_strings)
4756 /* No more overlay strings. Restore IT's settings to what
4757 they were before overlay strings were processed, and
4758 continue to deliver from current_buffer. */
4760 it->ellipsis_p = (it->stack[it->sp - 1].display_ellipsis_p != 0);
4761 pop_it (it);
4762 xassert (it->sp > 0
4763 || (NILP (it->string)
4764 && it->method == GET_FROM_BUFFER
4765 && it->stop_charpos >= BEGV
4766 && it->stop_charpos <= it->end_charpos));
4767 it->current.overlay_string_index = -1;
4768 it->n_overlay_strings = 0;
4770 /* If we're at the end of the buffer, record that we have
4771 processed the overlay strings there already, so that
4772 next_element_from_buffer doesn't try it again. */
4773 if (NILP (it->string) && IT_CHARPOS (*it) >= it->end_charpos)
4774 it->overlay_strings_at_end_processed_p = 1;
4776 else
4778 /* There are more overlay strings to process. If
4779 IT->current.overlay_string_index has advanced to a position
4780 where we must load IT->overlay_strings with more strings, do
4781 it. */
4782 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
4784 if (it->current.overlay_string_index && i == 0)
4785 load_overlay_strings (it, 0);
4787 /* Initialize IT to deliver display elements from the overlay
4788 string. */
4789 it->string = it->overlay_strings[i];
4790 it->multibyte_p = STRING_MULTIBYTE (it->string);
4791 SET_TEXT_POS (it->current.string_pos, 0, 0);
4792 it->method = GET_FROM_STRING;
4793 it->stop_charpos = 0;
4794 if (it->cmp_it.stop_pos >= 0)
4795 it->cmp_it.stop_pos = 0;
4798 CHECK_IT (it);
4802 /* Compare two overlay_entry structures E1 and E2. Used as a
4803 comparison function for qsort in load_overlay_strings. Overlay
4804 strings for the same position are sorted so that
4806 1. All after-strings come in front of before-strings, except
4807 when they come from the same overlay.
4809 2. Within after-strings, strings are sorted so that overlay strings
4810 from overlays with higher priorities come first.
4812 2. Within before-strings, strings are sorted so that overlay
4813 strings from overlays with higher priorities come last.
4815 Value is analogous to strcmp. */
4818 static int
4819 compare_overlay_entries (const void *e1, const void *e2)
4821 struct overlay_entry *entry1 = (struct overlay_entry *) e1;
4822 struct overlay_entry *entry2 = (struct overlay_entry *) e2;
4823 int result;
4825 if (entry1->after_string_p != entry2->after_string_p)
4827 /* Let after-strings appear in front of before-strings if
4828 they come from different overlays. */
4829 if (EQ (entry1->overlay, entry2->overlay))
4830 result = entry1->after_string_p ? 1 : -1;
4831 else
4832 result = entry1->after_string_p ? -1 : 1;
4834 else if (entry1->after_string_p)
4835 /* After-strings sorted in order of decreasing priority. */
4836 result = entry2->priority - entry1->priority;
4837 else
4838 /* Before-strings sorted in order of increasing priority. */
4839 result = entry1->priority - entry2->priority;
4841 return result;
4845 /* Load the vector IT->overlay_strings with overlay strings from IT's
4846 current buffer position, or from CHARPOS if that is > 0. Set
4847 IT->n_overlays to the total number of overlay strings found.
4849 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
4850 a time. On entry into load_overlay_strings,
4851 IT->current.overlay_string_index gives the number of overlay
4852 strings that have already been loaded by previous calls to this
4853 function.
4855 IT->add_overlay_start contains an additional overlay start
4856 position to consider for taking overlay strings from, if non-zero.
4857 This position comes into play when the overlay has an `invisible'
4858 property, and both before and after-strings. When we've skipped to
4859 the end of the overlay, because of its `invisible' property, we
4860 nevertheless want its before-string to appear.
4861 IT->add_overlay_start will contain the overlay start position
4862 in this case.
4864 Overlay strings are sorted so that after-string strings come in
4865 front of before-string strings. Within before and after-strings,
4866 strings are sorted by overlay priority. See also function
4867 compare_overlay_entries. */
4869 static void
4870 load_overlay_strings (struct it *it, int charpos)
4872 Lisp_Object overlay, window, str, invisible;
4873 struct Lisp_Overlay *ov;
4874 int start, end;
4875 int size = 20;
4876 int n = 0, i, j, invis_p;
4877 struct overlay_entry *entries
4878 = (struct overlay_entry *) alloca (size * sizeof *entries);
4880 if (charpos <= 0)
4881 charpos = IT_CHARPOS (*it);
4883 /* Append the overlay string STRING of overlay OVERLAY to vector
4884 `entries' which has size `size' and currently contains `n'
4885 elements. AFTER_P non-zero means STRING is an after-string of
4886 OVERLAY. */
4887 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
4888 do \
4890 Lisp_Object priority; \
4892 if (n == size) \
4894 int new_size = 2 * size; \
4895 struct overlay_entry *old = entries; \
4896 entries = \
4897 (struct overlay_entry *) alloca (new_size \
4898 * sizeof *entries); \
4899 memcpy (entries, old, size * sizeof *entries); \
4900 size = new_size; \
4903 entries[n].string = (STRING); \
4904 entries[n].overlay = (OVERLAY); \
4905 priority = Foverlay_get ((OVERLAY), Qpriority); \
4906 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
4907 entries[n].after_string_p = (AFTER_P); \
4908 ++n; \
4910 while (0)
4912 /* Process overlay before the overlay center. */
4913 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
4915 XSETMISC (overlay, ov);
4916 xassert (OVERLAYP (overlay));
4917 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4918 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4920 if (end < charpos)
4921 break;
4923 /* Skip this overlay if it doesn't start or end at IT's current
4924 position. */
4925 if (end != charpos && start != charpos)
4926 continue;
4928 /* Skip this overlay if it doesn't apply to IT->w. */
4929 window = Foverlay_get (overlay, Qwindow);
4930 if (WINDOWP (window) && XWINDOW (window) != it->w)
4931 continue;
4933 /* If the text ``under'' the overlay is invisible, both before-
4934 and after-strings from this overlay are visible; start and
4935 end position are indistinguishable. */
4936 invisible = Foverlay_get (overlay, Qinvisible);
4937 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4939 /* If overlay has a non-empty before-string, record it. */
4940 if ((start == charpos || (end == charpos && invis_p))
4941 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4942 && SCHARS (str))
4943 RECORD_OVERLAY_STRING (overlay, str, 0);
4945 /* If overlay has a non-empty after-string, record it. */
4946 if ((end == charpos || (start == charpos && invis_p))
4947 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4948 && SCHARS (str))
4949 RECORD_OVERLAY_STRING (overlay, str, 1);
4952 /* Process overlays after the overlay center. */
4953 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
4955 XSETMISC (overlay, ov);
4956 xassert (OVERLAYP (overlay));
4957 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4958 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4960 if (start > charpos)
4961 break;
4963 /* Skip this overlay if it doesn't start or end at IT's current
4964 position. */
4965 if (end != charpos && start != charpos)
4966 continue;
4968 /* Skip this overlay if it doesn't apply to IT->w. */
4969 window = Foverlay_get (overlay, Qwindow);
4970 if (WINDOWP (window) && XWINDOW (window) != it->w)
4971 continue;
4973 /* If the text ``under'' the overlay is invisible, it has a zero
4974 dimension, and both before- and after-strings apply. */
4975 invisible = Foverlay_get (overlay, Qinvisible);
4976 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4978 /* If overlay has a non-empty before-string, record it. */
4979 if ((start == charpos || (end == charpos && invis_p))
4980 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4981 && SCHARS (str))
4982 RECORD_OVERLAY_STRING (overlay, str, 0);
4984 /* If overlay has a non-empty after-string, record it. */
4985 if ((end == charpos || (start == charpos && invis_p))
4986 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4987 && SCHARS (str))
4988 RECORD_OVERLAY_STRING (overlay, str, 1);
4991 #undef RECORD_OVERLAY_STRING
4993 /* Sort entries. */
4994 if (n > 1)
4995 qsort (entries, n, sizeof *entries, compare_overlay_entries);
4997 /* Record the total number of strings to process. */
4998 it->n_overlay_strings = n;
5000 /* IT->current.overlay_string_index is the number of overlay strings
5001 that have already been consumed by IT. Copy some of the
5002 remaining overlay strings to IT->overlay_strings. */
5003 i = 0;
5004 j = it->current.overlay_string_index;
5005 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
5007 it->overlay_strings[i] = entries[j].string;
5008 it->string_overlays[i++] = entries[j++].overlay;
5011 CHECK_IT (it);
5015 /* Get the first chunk of overlay strings at IT's current buffer
5016 position, or at CHARPOS if that is > 0. Value is non-zero if at
5017 least one overlay string was found. */
5019 static int
5020 get_overlay_strings_1 (struct it *it, int charpos, int compute_stop_p)
5022 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
5023 process. This fills IT->overlay_strings with strings, and sets
5024 IT->n_overlay_strings to the total number of strings to process.
5025 IT->pos.overlay_string_index has to be set temporarily to zero
5026 because load_overlay_strings needs this; it must be set to -1
5027 when no overlay strings are found because a zero value would
5028 indicate a position in the first overlay string. */
5029 it->current.overlay_string_index = 0;
5030 load_overlay_strings (it, charpos);
5032 /* If we found overlay strings, set up IT to deliver display
5033 elements from the first one. Otherwise set up IT to deliver
5034 from current_buffer. */
5035 if (it->n_overlay_strings)
5037 /* Make sure we know settings in current_buffer, so that we can
5038 restore meaningful values when we're done with the overlay
5039 strings. */
5040 if (compute_stop_p)
5041 compute_stop_pos (it);
5042 xassert (it->face_id >= 0);
5044 /* Save IT's settings. They are restored after all overlay
5045 strings have been processed. */
5046 xassert (!compute_stop_p || it->sp == 0);
5048 /* When called from handle_stop, there might be an empty display
5049 string loaded. In that case, don't bother saving it. */
5050 if (!STRINGP (it->string) || SCHARS (it->string))
5051 push_it (it);
5053 /* Set up IT to deliver display elements from the first overlay
5054 string. */
5055 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
5056 it->string = it->overlay_strings[0];
5057 it->from_overlay = Qnil;
5058 it->stop_charpos = 0;
5059 xassert (STRINGP (it->string));
5060 it->end_charpos = SCHARS (it->string);
5061 it->multibyte_p = STRING_MULTIBYTE (it->string);
5062 it->method = GET_FROM_STRING;
5063 return 1;
5066 it->current.overlay_string_index = -1;
5067 return 0;
5070 static int
5071 get_overlay_strings (struct it *it, int charpos)
5073 it->string = Qnil;
5074 it->method = GET_FROM_BUFFER;
5076 (void) get_overlay_strings_1 (it, charpos, 1);
5078 CHECK_IT (it);
5080 /* Value is non-zero if we found at least one overlay string. */
5081 return STRINGP (it->string);
5086 /***********************************************************************
5087 Saving and restoring state
5088 ***********************************************************************/
5090 /* Save current settings of IT on IT->stack. Called, for example,
5091 before setting up IT for an overlay string, to be able to restore
5092 IT's settings to what they were after the overlay string has been
5093 processed. */
5095 static void
5096 push_it (struct it *it)
5098 struct iterator_stack_entry *p;
5100 xassert (it->sp < IT_STACK_SIZE);
5101 p = it->stack + it->sp;
5103 p->stop_charpos = it->stop_charpos;
5104 p->prev_stop = it->prev_stop;
5105 p->base_level_stop = it->base_level_stop;
5106 p->cmp_it = it->cmp_it;
5107 xassert (it->face_id >= 0);
5108 p->face_id = it->face_id;
5109 p->string = it->string;
5110 p->method = it->method;
5111 p->from_overlay = it->from_overlay;
5112 switch (p->method)
5114 case GET_FROM_IMAGE:
5115 p->u.image.object = it->object;
5116 p->u.image.image_id = it->image_id;
5117 p->u.image.slice = it->slice;
5118 break;
5119 case GET_FROM_STRETCH:
5120 p->u.stretch.object = it->object;
5121 break;
5123 p->position = it->position;
5124 p->current = it->current;
5125 p->end_charpos = it->end_charpos;
5126 p->string_nchars = it->string_nchars;
5127 p->area = it->area;
5128 p->multibyte_p = it->multibyte_p;
5129 p->avoid_cursor_p = it->avoid_cursor_p;
5130 p->space_width = it->space_width;
5131 p->font_height = it->font_height;
5132 p->voffset = it->voffset;
5133 p->string_from_display_prop_p = it->string_from_display_prop_p;
5134 p->display_ellipsis_p = 0;
5135 p->line_wrap = it->line_wrap;
5136 ++it->sp;
5139 static void
5140 iterate_out_of_display_property (struct it *it)
5142 /* Maybe initialize paragraph direction. If we are at the beginning
5143 of a new paragraph, next_element_from_buffer may not have a
5144 chance to do that. */
5145 if (it->bidi_it.first_elt && it->bidi_it.charpos < ZV)
5146 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it);
5147 /* prev_stop can be zero, so check against BEGV as well. */
5148 while (it->bidi_it.charpos >= BEGV
5149 && it->prev_stop <= it->bidi_it.charpos
5150 && it->bidi_it.charpos < CHARPOS (it->position))
5151 bidi_move_to_visually_next (&it->bidi_it);
5152 /* Record the stop_pos we just crossed, for when we cross it
5153 back, maybe. */
5154 if (it->bidi_it.charpos > CHARPOS (it->position))
5155 it->prev_stop = CHARPOS (it->position);
5156 /* If we ended up not where pop_it put us, resync IT's
5157 positional members with the bidi iterator. */
5158 if (it->bidi_it.charpos != CHARPOS (it->position))
5160 SET_TEXT_POS (it->position,
5161 it->bidi_it.charpos, it->bidi_it.bytepos);
5162 it->current.pos = it->position;
5166 /* Restore IT's settings from IT->stack. Called, for example, when no
5167 more overlay strings must be processed, and we return to delivering
5168 display elements from a buffer, or when the end of a string from a
5169 `display' property is reached and we return to delivering display
5170 elements from an overlay string, or from a buffer. */
5172 static void
5173 pop_it (struct it *it)
5175 struct iterator_stack_entry *p;
5177 xassert (it->sp > 0);
5178 --it->sp;
5179 p = it->stack + it->sp;
5180 it->stop_charpos = p->stop_charpos;
5181 it->prev_stop = p->prev_stop;
5182 it->base_level_stop = p->base_level_stop;
5183 it->cmp_it = p->cmp_it;
5184 it->face_id = p->face_id;
5185 it->current = p->current;
5186 it->position = p->position;
5187 it->string = p->string;
5188 it->from_overlay = p->from_overlay;
5189 if (NILP (it->string))
5190 SET_TEXT_POS (it->current.string_pos, -1, -1);
5191 it->method = p->method;
5192 switch (it->method)
5194 case GET_FROM_IMAGE:
5195 it->image_id = p->u.image.image_id;
5196 it->object = p->u.image.object;
5197 it->slice = p->u.image.slice;
5198 break;
5199 case GET_FROM_STRETCH:
5200 it->object = p->u.comp.object;
5201 break;
5202 case GET_FROM_BUFFER:
5203 it->object = it->w->buffer;
5204 if (it->bidi_p)
5206 /* Bidi-iterate until we get out of the portion of text, if
5207 any, covered by a `display' text property or an overlay
5208 with `display' property. (We cannot just jump there,
5209 because the internal coherency of the bidi iterator state
5210 can not be preserved across such jumps.) We also must
5211 determine the paragraph base direction if the overlay we
5212 just processed is at the beginning of a new
5213 paragraph. */
5214 iterate_out_of_display_property (it);
5216 break;
5217 case GET_FROM_STRING:
5218 it->object = it->string;
5219 break;
5220 case GET_FROM_DISPLAY_VECTOR:
5221 if (it->s)
5222 it->method = GET_FROM_C_STRING;
5223 else if (STRINGP (it->string))
5224 it->method = GET_FROM_STRING;
5225 else
5227 it->method = GET_FROM_BUFFER;
5228 it->object = it->w->buffer;
5231 it->end_charpos = p->end_charpos;
5232 it->string_nchars = p->string_nchars;
5233 it->area = p->area;
5234 it->multibyte_p = p->multibyte_p;
5235 it->avoid_cursor_p = p->avoid_cursor_p;
5236 it->space_width = p->space_width;
5237 it->font_height = p->font_height;
5238 it->voffset = p->voffset;
5239 it->string_from_display_prop_p = p->string_from_display_prop_p;
5240 it->line_wrap = p->line_wrap;
5245 /***********************************************************************
5246 Moving over lines
5247 ***********************************************************************/
5249 /* Set IT's current position to the previous line start. */
5251 static void
5252 back_to_previous_line_start (struct it *it)
5254 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
5255 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
5259 /* Move IT to the next line start.
5261 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
5262 we skipped over part of the text (as opposed to moving the iterator
5263 continuously over the text). Otherwise, don't change the value
5264 of *SKIPPED_P.
5266 Newlines may come from buffer text, overlay strings, or strings
5267 displayed via the `display' property. That's the reason we can't
5268 simply use find_next_newline_no_quit.
5270 Note that this function may not skip over invisible text that is so
5271 because of text properties and immediately follows a newline. If
5272 it would, function reseat_at_next_visible_line_start, when called
5273 from set_iterator_to_next, would effectively make invisible
5274 characters following a newline part of the wrong glyph row, which
5275 leads to wrong cursor motion. */
5277 static int
5278 forward_to_next_line_start (struct it *it, int *skipped_p)
5280 int old_selective, newline_found_p, n;
5281 const int MAX_NEWLINE_DISTANCE = 500;
5283 /* If already on a newline, just consume it to avoid unintended
5284 skipping over invisible text below. */
5285 if (it->what == IT_CHARACTER
5286 && it->c == '\n'
5287 && CHARPOS (it->position) == IT_CHARPOS (*it))
5289 set_iterator_to_next (it, 0);
5290 it->c = 0;
5291 return 1;
5294 /* Don't handle selective display in the following. It's (a)
5295 unnecessary because it's done by the caller, and (b) leads to an
5296 infinite recursion because next_element_from_ellipsis indirectly
5297 calls this function. */
5298 old_selective = it->selective;
5299 it->selective = 0;
5301 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
5302 from buffer text. */
5303 for (n = newline_found_p = 0;
5304 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
5305 n += STRINGP (it->string) ? 0 : 1)
5307 if (!get_next_display_element (it))
5308 return 0;
5309 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
5310 set_iterator_to_next (it, 0);
5313 /* If we didn't find a newline near enough, see if we can use a
5314 short-cut. */
5315 if (!newline_found_p)
5317 int start = IT_CHARPOS (*it);
5318 int limit = find_next_newline_no_quit (start, 1);
5319 Lisp_Object pos;
5321 xassert (!STRINGP (it->string));
5323 /* If there isn't any `display' property in sight, and no
5324 overlays, we can just use the position of the newline in
5325 buffer text. */
5326 if (it->stop_charpos >= limit
5327 || ((pos = Fnext_single_property_change (make_number (start),
5328 Qdisplay,
5329 Qnil, make_number (limit)),
5330 NILP (pos))
5331 && next_overlay_change (start) == ZV))
5333 IT_CHARPOS (*it) = limit;
5334 IT_BYTEPOS (*it) = CHAR_TO_BYTE (limit);
5335 *skipped_p = newline_found_p = 1;
5337 else
5339 while (get_next_display_element (it)
5340 && !newline_found_p)
5342 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
5343 set_iterator_to_next (it, 0);
5348 it->selective = old_selective;
5349 return newline_found_p;
5353 /* Set IT's current position to the previous visible line start. Skip
5354 invisible text that is so either due to text properties or due to
5355 selective display. Caution: this does not change IT->current_x and
5356 IT->hpos. */
5358 static void
5359 back_to_previous_visible_line_start (struct it *it)
5361 while (IT_CHARPOS (*it) > BEGV)
5363 back_to_previous_line_start (it);
5365 if (IT_CHARPOS (*it) <= BEGV)
5366 break;
5368 /* If selective > 0, then lines indented more than its value are
5369 invisible. */
5370 if (it->selective > 0
5371 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
5372 (double) it->selective)) /* iftc */
5373 continue;
5375 /* Check the newline before point for invisibility. */
5377 Lisp_Object prop;
5378 prop = Fget_char_property (make_number (IT_CHARPOS (*it) - 1),
5379 Qinvisible, it->window);
5380 if (TEXT_PROP_MEANS_INVISIBLE (prop))
5381 continue;
5384 if (IT_CHARPOS (*it) <= BEGV)
5385 break;
5388 struct it it2;
5389 int pos;
5390 EMACS_INT beg, end;
5391 Lisp_Object val, overlay;
5393 /* If newline is part of a composition, continue from start of composition */
5394 if (find_composition (IT_CHARPOS (*it), -1, &beg, &end, &val, Qnil)
5395 && beg < IT_CHARPOS (*it))
5396 goto replaced;
5398 /* If newline is replaced by a display property, find start of overlay
5399 or interval and continue search from that point. */
5400 it2 = *it;
5401 pos = --IT_CHARPOS (it2);
5402 --IT_BYTEPOS (it2);
5403 it2.sp = 0;
5404 it2.string_from_display_prop_p = 0;
5405 if (handle_display_prop (&it2) == HANDLED_RETURN
5406 && !NILP (val = get_char_property_and_overlay
5407 (make_number (pos), Qdisplay, Qnil, &overlay))
5408 && (OVERLAYP (overlay)
5409 ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
5410 : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
5411 goto replaced;
5413 /* Newline is not replaced by anything -- so we are done. */
5414 break;
5416 replaced:
5417 if (beg < BEGV)
5418 beg = BEGV;
5419 IT_CHARPOS (*it) = beg;
5420 IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg);
5424 it->continuation_lines_width = 0;
5426 xassert (IT_CHARPOS (*it) >= BEGV);
5427 xassert (IT_CHARPOS (*it) == BEGV
5428 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
5429 CHECK_IT (it);
5433 /* Reseat iterator IT at the previous visible line start. Skip
5434 invisible text that is so either due to text properties or due to
5435 selective display. At the end, update IT's overlay information,
5436 face information etc. */
5438 void
5439 reseat_at_previous_visible_line_start (struct it *it)
5441 back_to_previous_visible_line_start (it);
5442 reseat (it, it->current.pos, 1);
5443 CHECK_IT (it);
5447 /* Reseat iterator IT on the next visible line start in the current
5448 buffer. ON_NEWLINE_P non-zero means position IT on the newline
5449 preceding the line start. Skip over invisible text that is so
5450 because of selective display. Compute faces, overlays etc at the
5451 new position. Note that this function does not skip over text that
5452 is invisible because of text properties. */
5454 static void
5455 reseat_at_next_visible_line_start (struct it *it, int on_newline_p)
5457 int newline_found_p, skipped_p = 0;
5459 newline_found_p = forward_to_next_line_start (it, &skipped_p);
5461 /* Skip over lines that are invisible because they are indented
5462 more than the value of IT->selective. */
5463 if (it->selective > 0)
5464 while (IT_CHARPOS (*it) < ZV
5465 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
5466 (double) it->selective)) /* iftc */
5468 xassert (IT_BYTEPOS (*it) == BEGV
5469 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
5470 newline_found_p = forward_to_next_line_start (it, &skipped_p);
5473 /* Position on the newline if that's what's requested. */
5474 if (on_newline_p && newline_found_p)
5476 if (STRINGP (it->string))
5478 if (IT_STRING_CHARPOS (*it) > 0)
5480 --IT_STRING_CHARPOS (*it);
5481 --IT_STRING_BYTEPOS (*it);
5484 else if (IT_CHARPOS (*it) > BEGV)
5486 --IT_CHARPOS (*it);
5487 --IT_BYTEPOS (*it);
5488 reseat (it, it->current.pos, 0);
5491 else if (skipped_p)
5492 reseat (it, it->current.pos, 0);
5494 CHECK_IT (it);
5499 /***********************************************************************
5500 Changing an iterator's position
5501 ***********************************************************************/
5503 /* Change IT's current position to POS in current_buffer. If FORCE_P
5504 is non-zero, always check for text properties at the new position.
5505 Otherwise, text properties are only looked up if POS >=
5506 IT->check_charpos of a property. */
5508 static void
5509 reseat (struct it *it, struct text_pos pos, int force_p)
5511 int original_pos = IT_CHARPOS (*it);
5513 reseat_1 (it, pos, 0);
5515 /* Determine where to check text properties. Avoid doing it
5516 where possible because text property lookup is very expensive. */
5517 if (force_p
5518 || CHARPOS (pos) > it->stop_charpos
5519 || CHARPOS (pos) < original_pos)
5521 if (it->bidi_p)
5523 /* For bidi iteration, we need to prime prev_stop and
5524 base_level_stop with our best estimations. */
5525 if (CHARPOS (pos) < it->prev_stop)
5527 handle_stop_backwards (it, BEGV);
5528 if (CHARPOS (pos) < it->base_level_stop)
5529 it->base_level_stop = 0;
5531 else if (CHARPOS (pos) > it->stop_charpos
5532 && it->stop_charpos >= BEGV)
5533 handle_stop_backwards (it, it->stop_charpos);
5534 else /* force_p */
5535 handle_stop (it);
5537 else
5539 handle_stop (it);
5540 it->prev_stop = it->base_level_stop = 0;
5545 CHECK_IT (it);
5549 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
5550 IT->stop_pos to POS, also. */
5552 static void
5553 reseat_1 (struct it *it, struct text_pos pos, int set_stop_p)
5555 /* Don't call this function when scanning a C string. */
5556 xassert (it->s == NULL);
5558 /* POS must be a reasonable value. */
5559 xassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
5561 it->current.pos = it->position = pos;
5562 it->end_charpos = ZV;
5563 it->dpvec = NULL;
5564 it->current.dpvec_index = -1;
5565 it->current.overlay_string_index = -1;
5566 IT_STRING_CHARPOS (*it) = -1;
5567 IT_STRING_BYTEPOS (*it) = -1;
5568 it->string = Qnil;
5569 it->string_from_display_prop_p = 0;
5570 it->method = GET_FROM_BUFFER;
5571 it->object = it->w->buffer;
5572 it->area = TEXT_AREA;
5573 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
5574 it->sp = 0;
5575 it->string_from_display_prop_p = 0;
5576 it->face_before_selective_p = 0;
5577 if (it->bidi_p)
5578 it->bidi_it.first_elt = 1;
5580 if (set_stop_p)
5582 it->stop_charpos = CHARPOS (pos);
5583 it->base_level_stop = CHARPOS (pos);
5588 /* Set up IT for displaying a string, starting at CHARPOS in window W.
5589 If S is non-null, it is a C string to iterate over. Otherwise,
5590 STRING gives a Lisp string to iterate over.
5592 If PRECISION > 0, don't return more then PRECISION number of
5593 characters from the string.
5595 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
5596 characters have been returned. FIELD_WIDTH < 0 means an infinite
5597 field width.
5599 MULTIBYTE = 0 means disable processing of multibyte characters,
5600 MULTIBYTE > 0 means enable it,
5601 MULTIBYTE < 0 means use IT->multibyte_p.
5603 IT must be initialized via a prior call to init_iterator before
5604 calling this function. */
5606 static void
5607 reseat_to_string (struct it *it, const unsigned char *s, Lisp_Object string,
5608 int charpos, int precision, int field_width, int multibyte)
5610 /* No region in strings. */
5611 it->region_beg_charpos = it->region_end_charpos = -1;
5613 /* No text property checks performed by default, but see below. */
5614 it->stop_charpos = -1;
5616 /* Set iterator position and end position. */
5617 memset (&it->current, 0, sizeof it->current);
5618 it->current.overlay_string_index = -1;
5619 it->current.dpvec_index = -1;
5620 xassert (charpos >= 0);
5622 /* If STRING is specified, use its multibyteness, otherwise use the
5623 setting of MULTIBYTE, if specified. */
5624 if (multibyte >= 0)
5625 it->multibyte_p = multibyte > 0;
5627 if (s == NULL)
5629 xassert (STRINGP (string));
5630 it->string = string;
5631 it->s = NULL;
5632 it->end_charpos = it->string_nchars = SCHARS (string);
5633 it->method = GET_FROM_STRING;
5634 it->current.string_pos = string_pos (charpos, string);
5636 else
5638 it->s = s;
5639 it->string = Qnil;
5641 /* Note that we use IT->current.pos, not it->current.string_pos,
5642 for displaying C strings. */
5643 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
5644 if (it->multibyte_p)
5646 it->current.pos = c_string_pos (charpos, s, 1);
5647 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
5649 else
5651 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
5652 it->end_charpos = it->string_nchars = strlen (s);
5655 it->method = GET_FROM_C_STRING;
5658 /* PRECISION > 0 means don't return more than PRECISION characters
5659 from the string. */
5660 if (precision > 0 && it->end_charpos - charpos > precision)
5661 it->end_charpos = it->string_nchars = charpos + precision;
5663 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
5664 characters have been returned. FIELD_WIDTH == 0 means don't pad,
5665 FIELD_WIDTH < 0 means infinite field width. This is useful for
5666 padding with `-' at the end of a mode line. */
5667 if (field_width < 0)
5668 field_width = INFINITY;
5669 if (field_width > it->end_charpos - charpos)
5670 it->end_charpos = charpos + field_width;
5672 /* Use the standard display table for displaying strings. */
5673 if (DISP_TABLE_P (Vstandard_display_table))
5674 it->dp = XCHAR_TABLE (Vstandard_display_table);
5676 it->stop_charpos = charpos;
5677 if (s == NULL && it->multibyte_p)
5679 EMACS_INT endpos = SCHARS (it->string);
5680 if (endpos > it->end_charpos)
5681 endpos = it->end_charpos;
5682 composition_compute_stop_pos (&it->cmp_it, charpos, -1, endpos,
5683 it->string);
5685 CHECK_IT (it);
5690 /***********************************************************************
5691 Iteration
5692 ***********************************************************************/
5694 /* Map enum it_method value to corresponding next_element_from_* function. */
5696 static int (* get_next_element[NUM_IT_METHODS]) (struct it *it) =
5698 next_element_from_buffer,
5699 next_element_from_display_vector,
5700 next_element_from_string,
5701 next_element_from_c_string,
5702 next_element_from_image,
5703 next_element_from_stretch
5706 #define GET_NEXT_DISPLAY_ELEMENT(it) (*get_next_element[(it)->method]) (it)
5709 /* Return 1 iff a character at CHARPOS (and BYTEPOS) is composed
5710 (possibly with the following characters). */
5712 #define CHAR_COMPOSED_P(IT,CHARPOS,BYTEPOS,END_CHARPOS) \
5713 ((IT)->cmp_it.id >= 0 \
5714 || ((IT)->cmp_it.stop_pos == (CHARPOS) \
5715 && composition_reseat_it (&(IT)->cmp_it, CHARPOS, BYTEPOS, \
5716 END_CHARPOS, (IT)->w, \
5717 FACE_FROM_ID ((IT)->f, (IT)->face_id), \
5718 (IT)->string)))
5721 /* Load IT's display element fields with information about the next
5722 display element from the current position of IT. Value is zero if
5723 end of buffer (or C string) is reached. */
5725 static struct frame *last_escape_glyph_frame = NULL;
5726 static unsigned last_escape_glyph_face_id = (1 << FACE_ID_BITS);
5727 static int last_escape_glyph_merged_face_id = 0;
5730 get_next_display_element (struct it *it)
5732 /* Non-zero means that we found a display element. Zero means that
5733 we hit the end of what we iterate over. Performance note: the
5734 function pointer `method' used here turns out to be faster than
5735 using a sequence of if-statements. */
5736 int success_p;
5738 get_next:
5739 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
5741 if (it->what == IT_CHARACTER)
5743 /* UAX#9, L4: "A character is depicted by a mirrored glyph if
5744 and only if (a) the resolved directionality of that character
5745 is R..." */
5746 /* FIXME: Do we need an exception for characters from display
5747 tables? */
5748 if (it->bidi_p && it->bidi_it.type == STRONG_R)
5749 it->c = bidi_mirror_char (it->c);
5750 /* Map via display table or translate control characters.
5751 IT->c, IT->len etc. have been set to the next character by
5752 the function call above. If we have a display table, and it
5753 contains an entry for IT->c, translate it. Don't do this if
5754 IT->c itself comes from a display table, otherwise we could
5755 end up in an infinite recursion. (An alternative could be to
5756 count the recursion depth of this function and signal an
5757 error when a certain maximum depth is reached.) Is it worth
5758 it? */
5759 if (success_p && it->dpvec == NULL)
5761 Lisp_Object dv;
5762 struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte);
5763 enum { char_is_other = 0, char_is_nbsp, char_is_soft_hyphen }
5764 nbsp_or_shy = char_is_other;
5765 int decoded = it->c;
5767 if (it->dp
5768 && (dv = DISP_CHAR_VECTOR (it->dp, it->c),
5769 VECTORP (dv)))
5771 struct Lisp_Vector *v = XVECTOR (dv);
5773 /* Return the first character from the display table
5774 entry, if not empty. If empty, don't display the
5775 current character. */
5776 if (v->size)
5778 it->dpvec_char_len = it->len;
5779 it->dpvec = v->contents;
5780 it->dpend = v->contents + v->size;
5781 it->current.dpvec_index = 0;
5782 it->dpvec_face_id = -1;
5783 it->saved_face_id = it->face_id;
5784 it->method = GET_FROM_DISPLAY_VECTOR;
5785 it->ellipsis_p = 0;
5787 else
5789 set_iterator_to_next (it, 0);
5791 goto get_next;
5794 if (unibyte_display_via_language_environment
5795 && !ASCII_CHAR_P (it->c))
5796 decoded = DECODE_CHAR (unibyte, it->c);
5798 if (it->c >= 0x80 && ! NILP (Vnobreak_char_display))
5800 if (it->multibyte_p)
5801 nbsp_or_shy = (it->c == 0xA0 ? char_is_nbsp
5802 : it->c == 0xAD ? char_is_soft_hyphen
5803 : char_is_other);
5804 else if (unibyte_display_via_language_environment)
5805 nbsp_or_shy = (decoded == 0xA0 ? char_is_nbsp
5806 : decoded == 0xAD ? char_is_soft_hyphen
5807 : char_is_other);
5810 /* Translate control characters into `\003' or `^C' form.
5811 Control characters coming from a display table entry are
5812 currently not translated because we use IT->dpvec to hold
5813 the translation. This could easily be changed but I
5814 don't believe that it is worth doing.
5816 If it->multibyte_p is nonzero, non-printable non-ASCII
5817 characters are also translated to octal form.
5819 If it->multibyte_p is zero, eight-bit characters that
5820 don't have corresponding multibyte char code are also
5821 translated to octal form. */
5822 if ((it->c < ' '
5823 ? (it->area != TEXT_AREA
5824 /* In mode line, treat \n, \t like other crl chars. */
5825 || (it->c != '\t'
5826 && it->glyph_row
5827 && (it->glyph_row->mode_line_p || it->avoid_cursor_p))
5828 || (it->c != '\n' && it->c != '\t'))
5829 : (nbsp_or_shy
5830 || (it->multibyte_p
5831 ? ! CHAR_PRINTABLE_P (it->c)
5832 : (! unibyte_display_via_language_environment
5833 ? it->c >= 0x80
5834 : (decoded >= 0x80 && decoded < 0xA0))))))
5836 /* IT->c is a control character which must be displayed
5837 either as '\003' or as `^C' where the '\\' and '^'
5838 can be defined in the display table. Fill
5839 IT->ctl_chars with glyphs for what we have to
5840 display. Then, set IT->dpvec to these glyphs. */
5841 Lisp_Object gc;
5842 int ctl_len;
5843 int face_id, lface_id = 0 ;
5844 int escape_glyph;
5846 /* Handle control characters with ^. */
5848 if (it->c < 128 && it->ctl_arrow_p)
5850 int g;
5852 g = '^'; /* default glyph for Control */
5853 /* Set IT->ctl_chars[0] to the glyph for `^'. */
5854 if (it->dp
5855 && (gc = DISP_CTRL_GLYPH (it->dp), GLYPH_CODE_P (gc))
5856 && GLYPH_CODE_CHAR_VALID_P (gc))
5858 g = GLYPH_CODE_CHAR (gc);
5859 lface_id = GLYPH_CODE_FACE (gc);
5861 if (lface_id)
5863 face_id = merge_faces (it->f, Qt, lface_id, it->face_id);
5865 else if (it->f == last_escape_glyph_frame
5866 && it->face_id == last_escape_glyph_face_id)
5868 face_id = last_escape_glyph_merged_face_id;
5870 else
5872 /* Merge the escape-glyph face into the current face. */
5873 face_id = merge_faces (it->f, Qescape_glyph, 0,
5874 it->face_id);
5875 last_escape_glyph_frame = it->f;
5876 last_escape_glyph_face_id = it->face_id;
5877 last_escape_glyph_merged_face_id = face_id;
5880 XSETINT (it->ctl_chars[0], g);
5881 XSETINT (it->ctl_chars[1], it->c ^ 0100);
5882 ctl_len = 2;
5883 goto display_control;
5886 /* Handle non-break space in the mode where it only gets
5887 highlighting. */
5889 if (EQ (Vnobreak_char_display, Qt)
5890 && nbsp_or_shy == char_is_nbsp)
5892 /* Merge the no-break-space face into the current face. */
5893 face_id = merge_faces (it->f, Qnobreak_space, 0,
5894 it->face_id);
5896 it->c = ' ';
5897 XSETINT (it->ctl_chars[0], ' ');
5898 ctl_len = 1;
5899 goto display_control;
5902 /* Handle sequences that start with the "escape glyph". */
5904 /* the default escape glyph is \. */
5905 escape_glyph = '\\';
5907 if (it->dp
5908 && (gc = DISP_ESCAPE_GLYPH (it->dp), GLYPH_CODE_P (gc))
5909 && GLYPH_CODE_CHAR_VALID_P (gc))
5911 escape_glyph = GLYPH_CODE_CHAR (gc);
5912 lface_id = GLYPH_CODE_FACE (gc);
5914 if (lface_id)
5916 /* The display table specified a face.
5917 Merge it into face_id and also into escape_glyph. */
5918 face_id = merge_faces (it->f, Qt, lface_id,
5919 it->face_id);
5921 else if (it->f == last_escape_glyph_frame
5922 && it->face_id == last_escape_glyph_face_id)
5924 face_id = last_escape_glyph_merged_face_id;
5926 else
5928 /* Merge the escape-glyph face into the current face. */
5929 face_id = merge_faces (it->f, Qescape_glyph, 0,
5930 it->face_id);
5931 last_escape_glyph_frame = it->f;
5932 last_escape_glyph_face_id = it->face_id;
5933 last_escape_glyph_merged_face_id = face_id;
5936 /* Handle soft hyphens in the mode where they only get
5937 highlighting. */
5939 if (EQ (Vnobreak_char_display, Qt)
5940 && nbsp_or_shy == char_is_soft_hyphen)
5942 it->c = '-';
5943 XSETINT (it->ctl_chars[0], '-');
5944 ctl_len = 1;
5945 goto display_control;
5948 /* Handle non-break space and soft hyphen
5949 with the escape glyph. */
5951 if (nbsp_or_shy)
5953 XSETINT (it->ctl_chars[0], escape_glyph);
5954 it->c = (nbsp_or_shy == char_is_nbsp ? ' ' : '-');
5955 XSETINT (it->ctl_chars[1], it->c);
5956 ctl_len = 2;
5957 goto display_control;
5961 unsigned char str[MAX_MULTIBYTE_LENGTH];
5962 int len;
5963 int i;
5965 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
5966 if (CHAR_BYTE8_P (it->c))
5968 str[0] = CHAR_TO_BYTE8 (it->c);
5969 len = 1;
5971 else if (it->c < 256)
5973 str[0] = it->c;
5974 len = 1;
5976 else
5978 /* It's an invalid character, which shouldn't
5979 happen actually, but due to bugs it may
5980 happen. Let's print the char as is, there's
5981 not much meaningful we can do with it. */
5982 str[0] = it->c;
5983 str[1] = it->c >> 8;
5984 str[2] = it->c >> 16;
5985 str[3] = it->c >> 24;
5986 len = 4;
5989 for (i = 0; i < len; i++)
5991 int g;
5992 XSETINT (it->ctl_chars[i * 4], escape_glyph);
5993 /* Insert three more glyphs into IT->ctl_chars for
5994 the octal display of the character. */
5995 g = ((str[i] >> 6) & 7) + '0';
5996 XSETINT (it->ctl_chars[i * 4 + 1], g);
5997 g = ((str[i] >> 3) & 7) + '0';
5998 XSETINT (it->ctl_chars[i * 4 + 2], g);
5999 g = (str[i] & 7) + '0';
6000 XSETINT (it->ctl_chars[i * 4 + 3], g);
6002 ctl_len = len * 4;
6005 display_control:
6006 /* Set up IT->dpvec and return first character from it. */
6007 it->dpvec_char_len = it->len;
6008 it->dpvec = it->ctl_chars;
6009 it->dpend = it->dpvec + ctl_len;
6010 it->current.dpvec_index = 0;
6011 it->dpvec_face_id = face_id;
6012 it->saved_face_id = it->face_id;
6013 it->method = GET_FROM_DISPLAY_VECTOR;
6014 it->ellipsis_p = 0;
6015 goto get_next;
6020 #ifdef HAVE_WINDOW_SYSTEM
6021 /* Adjust face id for a multibyte character. There are no multibyte
6022 character in unibyte text. */
6023 if ((it->what == IT_CHARACTER || it->what == IT_COMPOSITION)
6024 && it->multibyte_p
6025 && success_p
6026 && FRAME_WINDOW_P (it->f))
6028 struct face *face = FACE_FROM_ID (it->f, it->face_id);
6030 if (it->what == IT_COMPOSITION && it->cmp_it.ch >= 0)
6032 /* Automatic composition with glyph-string. */
6033 Lisp_Object gstring = composition_gstring_from_id (it->cmp_it.id);
6035 it->face_id = face_for_font (it->f, LGSTRING_FONT (gstring), face);
6037 else
6039 int pos = (it->s ? -1
6040 : STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
6041 : IT_CHARPOS (*it));
6043 it->face_id = FACE_FOR_CHAR (it->f, face, it->c, pos, it->string);
6046 #endif
6048 /* Is this character the last one of a run of characters with
6049 box? If yes, set IT->end_of_box_run_p to 1. */
6050 if (it->face_box_p
6051 && it->s == NULL)
6053 if (it->method == GET_FROM_STRING && it->sp)
6055 int face_id = underlying_face_id (it);
6056 struct face *face = FACE_FROM_ID (it->f, face_id);
6058 if (face)
6060 if (face->box == FACE_NO_BOX)
6062 /* If the box comes from face properties in a
6063 display string, check faces in that string. */
6064 int string_face_id = face_after_it_pos (it);
6065 it->end_of_box_run_p
6066 = (FACE_FROM_ID (it->f, string_face_id)->box
6067 == FACE_NO_BOX);
6069 /* Otherwise, the box comes from the underlying face.
6070 If this is the last string character displayed, check
6071 the next buffer location. */
6072 else if ((IT_STRING_CHARPOS (*it) >= SCHARS (it->string) - 1)
6073 && (it->current.overlay_string_index
6074 == it->n_overlay_strings - 1))
6076 EMACS_INT ignore;
6077 int next_face_id;
6078 struct text_pos pos = it->current.pos;
6079 INC_TEXT_POS (pos, it->multibyte_p);
6081 next_face_id = face_at_buffer_position
6082 (it->w, CHARPOS (pos), it->region_beg_charpos,
6083 it->region_end_charpos, &ignore,
6084 (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT), 0,
6085 -1);
6086 it->end_of_box_run_p
6087 = (FACE_FROM_ID (it->f, next_face_id)->box
6088 == FACE_NO_BOX);
6092 else
6094 int face_id = face_after_it_pos (it);
6095 it->end_of_box_run_p
6096 = (face_id != it->face_id
6097 && FACE_FROM_ID (it->f, face_id)->box == FACE_NO_BOX);
6101 /* Value is 0 if end of buffer or string reached. */
6102 return success_p;
6106 /* Move IT to the next display element.
6108 RESEAT_P non-zero means if called on a newline in buffer text,
6109 skip to the next visible line start.
6111 Functions get_next_display_element and set_iterator_to_next are
6112 separate because I find this arrangement easier to handle than a
6113 get_next_display_element function that also increments IT's
6114 position. The way it is we can first look at an iterator's current
6115 display element, decide whether it fits on a line, and if it does,
6116 increment the iterator position. The other way around we probably
6117 would either need a flag indicating whether the iterator has to be
6118 incremented the next time, or we would have to implement a
6119 decrement position function which would not be easy to write. */
6121 void
6122 set_iterator_to_next (struct it *it, int reseat_p)
6124 /* Reset flags indicating start and end of a sequence of characters
6125 with box. Reset them at the start of this function because
6126 moving the iterator to a new position might set them. */
6127 it->start_of_box_run_p = it->end_of_box_run_p = 0;
6129 switch (it->method)
6131 case GET_FROM_BUFFER:
6132 /* The current display element of IT is a character from
6133 current_buffer. Advance in the buffer, and maybe skip over
6134 invisible lines that are so because of selective display. */
6135 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
6136 reseat_at_next_visible_line_start (it, 0);
6137 else if (it->cmp_it.id >= 0)
6139 /* We are currently getting glyphs from a composition. */
6140 int i;
6142 if (! it->bidi_p)
6144 IT_CHARPOS (*it) += it->cmp_it.nchars;
6145 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
6146 if (it->cmp_it.to < it->cmp_it.nglyphs)
6148 it->cmp_it.from = it->cmp_it.to;
6150 else
6152 it->cmp_it.id = -1;
6153 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
6154 IT_BYTEPOS (*it),
6155 it->stop_charpos, Qnil);
6158 else if (! it->cmp_it.reversed_p)
6160 /* Composition created while scanning forward. */
6161 /* Update IT's char/byte positions to point to the first
6162 character of the next grapheme cluster, or to the
6163 character visually after the current composition. */
6164 for (i = 0; i < it->cmp_it.nchars; i++)
6165 bidi_move_to_visually_next (&it->bidi_it);
6166 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6167 IT_CHARPOS (*it) = it->bidi_it.charpos;
6169 if (it->cmp_it.to < it->cmp_it.nglyphs)
6171 /* Proceed to the next grapheme cluster. */
6172 it->cmp_it.from = it->cmp_it.to;
6174 else
6176 /* No more grapheme clusters in this composition.
6177 Find the next stop position. */
6178 EMACS_INT stop = it->stop_charpos;
6179 if (it->bidi_it.scan_dir < 0)
6180 /* Now we are scanning backward and don't know
6181 where to stop. */
6182 stop = -1;
6183 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
6184 IT_BYTEPOS (*it), stop, Qnil);
6187 else
6189 /* Composition created while scanning backward. */
6190 /* Update IT's char/byte positions to point to the last
6191 character of the previous grapheme cluster, or the
6192 character visually after the current composition. */
6193 for (i = 0; i < it->cmp_it.nchars; i++)
6194 bidi_move_to_visually_next (&it->bidi_it);
6195 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6196 IT_CHARPOS (*it) = it->bidi_it.charpos;
6197 if (it->cmp_it.from > 0)
6199 /* Proceed to the previous grapheme cluster. */
6200 it->cmp_it.to = it->cmp_it.from;
6202 else
6204 /* No more grapheme clusters in this composition.
6205 Find the next stop position. */
6206 EMACS_INT stop = it->stop_charpos;
6207 if (it->bidi_it.scan_dir < 0)
6208 /* Now we are scanning backward and don't know
6209 where to stop. */
6210 stop = -1;
6211 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
6212 IT_BYTEPOS (*it), stop, Qnil);
6216 else
6218 xassert (it->len != 0);
6220 if (!it->bidi_p)
6222 IT_BYTEPOS (*it) += it->len;
6223 IT_CHARPOS (*it) += 1;
6225 else
6227 int prev_scan_dir = it->bidi_it.scan_dir;
6228 /* If this is a new paragraph, determine its base
6229 direction (a.k.a. its base embedding level). */
6230 if (it->bidi_it.new_paragraph)
6231 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it);
6232 bidi_move_to_visually_next (&it->bidi_it);
6233 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6234 IT_CHARPOS (*it) = it->bidi_it.charpos;
6235 if (prev_scan_dir != it->bidi_it.scan_dir)
6237 /* As the scan direction was changed, we must
6238 re-compute the stop position for composition. */
6239 EMACS_INT stop = it->stop_charpos;
6240 if (it->bidi_it.scan_dir < 0)
6241 stop = -1;
6242 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
6243 IT_BYTEPOS (*it), stop, Qnil);
6246 xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
6248 break;
6250 case GET_FROM_C_STRING:
6251 /* Current display element of IT is from a C string. */
6252 IT_BYTEPOS (*it) += it->len;
6253 IT_CHARPOS (*it) += 1;
6254 break;
6256 case GET_FROM_DISPLAY_VECTOR:
6257 /* Current display element of IT is from a display table entry.
6258 Advance in the display table definition. Reset it to null if
6259 end reached, and continue with characters from buffers/
6260 strings. */
6261 ++it->current.dpvec_index;
6263 /* Restore face of the iterator to what they were before the
6264 display vector entry (these entries may contain faces). */
6265 it->face_id = it->saved_face_id;
6267 if (it->dpvec + it->current.dpvec_index == it->dpend)
6269 int recheck_faces = it->ellipsis_p;
6271 if (it->s)
6272 it->method = GET_FROM_C_STRING;
6273 else if (STRINGP (it->string))
6274 it->method = GET_FROM_STRING;
6275 else
6277 it->method = GET_FROM_BUFFER;
6278 it->object = it->w->buffer;
6281 it->dpvec = NULL;
6282 it->current.dpvec_index = -1;
6284 /* Skip over characters which were displayed via IT->dpvec. */
6285 if (it->dpvec_char_len < 0)
6286 reseat_at_next_visible_line_start (it, 1);
6287 else if (it->dpvec_char_len > 0)
6289 if (it->method == GET_FROM_STRING
6290 && it->n_overlay_strings > 0)
6291 it->ignore_overlay_strings_at_pos_p = 1;
6292 it->len = it->dpvec_char_len;
6293 set_iterator_to_next (it, reseat_p);
6296 /* Maybe recheck faces after display vector */
6297 if (recheck_faces)
6298 it->stop_charpos = IT_CHARPOS (*it);
6300 break;
6302 case GET_FROM_STRING:
6303 /* Current display element is a character from a Lisp string. */
6304 xassert (it->s == NULL && STRINGP (it->string));
6305 if (it->cmp_it.id >= 0)
6307 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
6308 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
6309 if (it->cmp_it.to < it->cmp_it.nglyphs)
6310 it->cmp_it.from = it->cmp_it.to;
6311 else
6313 it->cmp_it.id = -1;
6314 composition_compute_stop_pos (&it->cmp_it,
6315 IT_STRING_CHARPOS (*it),
6316 IT_STRING_BYTEPOS (*it),
6317 it->stop_charpos, it->string);
6320 else
6322 IT_STRING_BYTEPOS (*it) += it->len;
6323 IT_STRING_CHARPOS (*it) += 1;
6326 consider_string_end:
6328 if (it->current.overlay_string_index >= 0)
6330 /* IT->string is an overlay string. Advance to the
6331 next, if there is one. */
6332 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
6334 it->ellipsis_p = 0;
6335 next_overlay_string (it);
6336 if (it->ellipsis_p)
6337 setup_for_ellipsis (it, 0);
6340 else
6342 /* IT->string is not an overlay string. If we reached
6343 its end, and there is something on IT->stack, proceed
6344 with what is on the stack. This can be either another
6345 string, this time an overlay string, or a buffer. */
6346 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
6347 && it->sp > 0)
6349 pop_it (it);
6350 if (it->method == GET_FROM_STRING)
6351 goto consider_string_end;
6354 break;
6356 case GET_FROM_IMAGE:
6357 case GET_FROM_STRETCH:
6358 /* The position etc with which we have to proceed are on
6359 the stack. The position may be at the end of a string,
6360 if the `display' property takes up the whole string. */
6361 xassert (it->sp > 0);
6362 pop_it (it);
6363 if (it->method == GET_FROM_STRING)
6364 goto consider_string_end;
6365 break;
6367 default:
6368 /* There are no other methods defined, so this should be a bug. */
6369 abort ();
6372 xassert (it->method != GET_FROM_STRING
6373 || (STRINGP (it->string)
6374 && IT_STRING_CHARPOS (*it) >= 0));
6377 /* Load IT's display element fields with information about the next
6378 display element which comes from a display table entry or from the
6379 result of translating a control character to one of the forms `^C'
6380 or `\003'.
6382 IT->dpvec holds the glyphs to return as characters.
6383 IT->saved_face_id holds the face id before the display vector--it
6384 is restored into IT->face_id in set_iterator_to_next. */
6386 static int
6387 next_element_from_display_vector (struct it *it)
6389 Lisp_Object gc;
6391 /* Precondition. */
6392 xassert (it->dpvec && it->current.dpvec_index >= 0);
6394 it->face_id = it->saved_face_id;
6396 /* KFS: This code used to check ip->dpvec[0] instead of the current element.
6397 That seemed totally bogus - so I changed it... */
6398 gc = it->dpvec[it->current.dpvec_index];
6400 if (GLYPH_CODE_P (gc) && GLYPH_CODE_CHAR_VALID_P (gc))
6402 it->c = GLYPH_CODE_CHAR (gc);
6403 it->len = CHAR_BYTES (it->c);
6405 /* The entry may contain a face id to use. Such a face id is
6406 the id of a Lisp face, not a realized face. A face id of
6407 zero means no face is specified. */
6408 if (it->dpvec_face_id >= 0)
6409 it->face_id = it->dpvec_face_id;
6410 else
6412 int lface_id = GLYPH_CODE_FACE (gc);
6413 if (lface_id > 0)
6414 it->face_id = merge_faces (it->f, Qt, lface_id,
6415 it->saved_face_id);
6418 else
6419 /* Display table entry is invalid. Return a space. */
6420 it->c = ' ', it->len = 1;
6422 /* Don't change position and object of the iterator here. They are
6423 still the values of the character that had this display table
6424 entry or was translated, and that's what we want. */
6425 it->what = IT_CHARACTER;
6426 return 1;
6430 /* Load IT with the next display element from Lisp string IT->string.
6431 IT->current.string_pos is the current position within the string.
6432 If IT->current.overlay_string_index >= 0, the Lisp string is an
6433 overlay string. */
6435 static int
6436 next_element_from_string (struct it *it)
6438 struct text_pos position;
6440 xassert (STRINGP (it->string));
6441 xassert (IT_STRING_CHARPOS (*it) >= 0);
6442 position = it->current.string_pos;
6444 /* Time to check for invisible text? */
6445 if (IT_STRING_CHARPOS (*it) < it->end_charpos
6446 && IT_STRING_CHARPOS (*it) == it->stop_charpos)
6448 handle_stop (it);
6450 /* Since a handler may have changed IT->method, we must
6451 recurse here. */
6452 return GET_NEXT_DISPLAY_ELEMENT (it);
6455 if (it->current.overlay_string_index >= 0)
6457 /* Get the next character from an overlay string. In overlay
6458 strings, There is no field width or padding with spaces to
6459 do. */
6460 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
6462 it->what = IT_EOB;
6463 return 0;
6465 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
6466 IT_STRING_BYTEPOS (*it), SCHARS (it->string))
6467 && next_element_from_composition (it))
6469 return 1;
6471 else if (STRING_MULTIBYTE (it->string))
6473 int remaining = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
6474 const unsigned char *s = (SDATA (it->string)
6475 + IT_STRING_BYTEPOS (*it));
6476 it->c = string_char_and_length (s, &it->len);
6478 else
6480 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
6481 it->len = 1;
6484 else
6486 /* Get the next character from a Lisp string that is not an
6487 overlay string. Such strings come from the mode line, for
6488 example. We may have to pad with spaces, or truncate the
6489 string. See also next_element_from_c_string. */
6490 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
6492 it->what = IT_EOB;
6493 return 0;
6495 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
6497 /* Pad with spaces. */
6498 it->c = ' ', it->len = 1;
6499 CHARPOS (position) = BYTEPOS (position) = -1;
6501 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
6502 IT_STRING_BYTEPOS (*it), it->string_nchars)
6503 && next_element_from_composition (it))
6505 return 1;
6507 else if (STRING_MULTIBYTE (it->string))
6509 int maxlen = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
6510 const unsigned char *s = (SDATA (it->string)
6511 + IT_STRING_BYTEPOS (*it));
6512 it->c = string_char_and_length (s, &it->len);
6514 else
6516 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
6517 it->len = 1;
6521 /* Record what we have and where it came from. */
6522 it->what = IT_CHARACTER;
6523 it->object = it->string;
6524 it->position = position;
6525 return 1;
6529 /* Load IT with next display element from C string IT->s.
6530 IT->string_nchars is the maximum number of characters to return
6531 from the string. IT->end_charpos may be greater than
6532 IT->string_nchars when this function is called, in which case we
6533 may have to return padding spaces. Value is zero if end of string
6534 reached, including padding spaces. */
6536 static int
6537 next_element_from_c_string (struct it *it)
6539 int success_p = 1;
6541 xassert (it->s);
6542 it->what = IT_CHARACTER;
6543 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
6544 it->object = Qnil;
6546 /* IT's position can be greater IT->string_nchars in case a field
6547 width or precision has been specified when the iterator was
6548 initialized. */
6549 if (IT_CHARPOS (*it) >= it->end_charpos)
6551 /* End of the game. */
6552 it->what = IT_EOB;
6553 success_p = 0;
6555 else if (IT_CHARPOS (*it) >= it->string_nchars)
6557 /* Pad with spaces. */
6558 it->c = ' ', it->len = 1;
6559 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
6561 else if (it->multibyte_p)
6563 /* Implementation note: The calls to strlen apparently aren't a
6564 performance problem because there is no noticeable performance
6565 difference between Emacs running in unibyte or multibyte mode. */
6566 int maxlen = strlen (it->s) - IT_BYTEPOS (*it);
6567 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it), &it->len);
6569 else
6570 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
6572 return success_p;
6576 /* Set up IT to return characters from an ellipsis, if appropriate.
6577 The definition of the ellipsis glyphs may come from a display table
6578 entry. This function fills IT with the first glyph from the
6579 ellipsis if an ellipsis is to be displayed. */
6581 static int
6582 next_element_from_ellipsis (struct it *it)
6584 if (it->selective_display_ellipsis_p)
6585 setup_for_ellipsis (it, it->len);
6586 else
6588 /* The face at the current position may be different from the
6589 face we find after the invisible text. Remember what it
6590 was in IT->saved_face_id, and signal that it's there by
6591 setting face_before_selective_p. */
6592 it->saved_face_id = it->face_id;
6593 it->method = GET_FROM_BUFFER;
6594 it->object = it->w->buffer;
6595 reseat_at_next_visible_line_start (it, 1);
6596 it->face_before_selective_p = 1;
6599 return GET_NEXT_DISPLAY_ELEMENT (it);
6603 /* Deliver an image display element. The iterator IT is already
6604 filled with image information (done in handle_display_prop). Value
6605 is always 1. */
6608 static int
6609 next_element_from_image (struct it *it)
6611 it->what = IT_IMAGE;
6612 it->ignore_overlay_strings_at_pos_p = 0;
6613 return 1;
6617 /* Fill iterator IT with next display element from a stretch glyph
6618 property. IT->object is the value of the text property. Value is
6619 always 1. */
6621 static int
6622 next_element_from_stretch (struct it *it)
6624 it->what = IT_STRETCH;
6625 return 1;
6628 /* Scan forward from CHARPOS in the current buffer, until we find a
6629 stop position > current IT's position. Then handle the stop
6630 position before that. This is called when we bump into a stop
6631 position while reordering bidirectional text. CHARPOS should be
6632 the last previously processed stop_pos (or BEGV, if none were
6633 processed yet) whose position is less that IT's current
6634 position. */
6636 static void
6637 handle_stop_backwards (struct it *it, EMACS_INT charpos)
6639 EMACS_INT where_we_are = IT_CHARPOS (*it);
6640 struct display_pos save_current = it->current;
6641 struct text_pos save_position = it->position;
6642 struct text_pos pos1;
6643 EMACS_INT next_stop;
6645 /* Scan in strict logical order. */
6646 it->bidi_p = 0;
6649 it->prev_stop = charpos;
6650 SET_TEXT_POS (pos1, charpos, CHAR_TO_BYTE (charpos));
6651 reseat_1 (it, pos1, 0);
6652 compute_stop_pos (it);
6653 /* We must advance forward, right? */
6654 if (it->stop_charpos <= it->prev_stop)
6655 abort ();
6656 charpos = it->stop_charpos;
6658 while (charpos <= where_we_are);
6660 next_stop = it->stop_charpos;
6661 it->stop_charpos = it->prev_stop;
6662 it->bidi_p = 1;
6663 it->current = save_current;
6664 it->position = save_position;
6665 handle_stop (it);
6666 it->stop_charpos = next_stop;
6669 /* Load IT with the next display element from current_buffer. Value
6670 is zero if end of buffer reached. IT->stop_charpos is the next
6671 position at which to stop and check for text properties or buffer
6672 end. */
6674 static int
6675 next_element_from_buffer (struct it *it)
6677 int success_p = 1;
6679 xassert (IT_CHARPOS (*it) >= BEGV);
6681 /* With bidi reordering, the character to display might not be the
6682 character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that
6683 we were reseat()ed to a new buffer position, which is potentially
6684 a different paragraph. */
6685 if (it->bidi_p && it->bidi_it.first_elt)
6687 it->bidi_it.charpos = IT_CHARPOS (*it);
6688 it->bidi_it.bytepos = IT_BYTEPOS (*it);
6689 if (it->bidi_it.bytepos == ZV_BYTE)
6691 /* Nothing to do, but reset the FIRST_ELT flag, like
6692 bidi_paragraph_init does, because we are not going to
6693 call it. */
6694 it->bidi_it.first_elt = 0;
6696 else if (it->bidi_it.bytepos == BEGV_BYTE
6697 /* FIXME: Should support all Unicode line separators. */
6698 || FETCH_CHAR (it->bidi_it.bytepos - 1) == '\n'
6699 || FETCH_CHAR (it->bidi_it.bytepos) == '\n')
6701 /* If we are at the beginning of a line, we can produce the
6702 next element right away. */
6703 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it);
6704 bidi_move_to_visually_next (&it->bidi_it);
6706 else
6708 int orig_bytepos = IT_BYTEPOS (*it);
6710 /* We need to prime the bidi iterator starting at the line's
6711 beginning, before we will be able to produce the next
6712 element. */
6713 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it), -1);
6714 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
6715 it->bidi_it.charpos = IT_CHARPOS (*it);
6716 it->bidi_it.bytepos = IT_BYTEPOS (*it);
6717 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it);
6720 /* Now return to buffer position where we were asked to
6721 get the next display element, and produce that. */
6722 bidi_move_to_visually_next (&it->bidi_it);
6724 while (it->bidi_it.bytepos != orig_bytepos
6725 && it->bidi_it.bytepos < ZV_BYTE);
6728 it->bidi_it.first_elt = 0; /* paranoia: bidi.c does this */
6729 /* Adjust IT's position information to where we ended up. */
6730 IT_CHARPOS (*it) = it->bidi_it.charpos;
6731 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6732 SET_TEXT_POS (it->position, IT_CHARPOS (*it), IT_BYTEPOS (*it));
6734 EMACS_INT stop = it->stop_charpos;
6735 if (it->bidi_it.scan_dir < 0)
6736 stop = -1;
6737 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
6738 IT_BYTEPOS (*it), stop, Qnil);
6742 if (IT_CHARPOS (*it) >= it->stop_charpos)
6744 if (IT_CHARPOS (*it) >= it->end_charpos)
6746 int overlay_strings_follow_p;
6748 /* End of the game, except when overlay strings follow that
6749 haven't been returned yet. */
6750 if (it->overlay_strings_at_end_processed_p)
6751 overlay_strings_follow_p = 0;
6752 else
6754 it->overlay_strings_at_end_processed_p = 1;
6755 overlay_strings_follow_p = get_overlay_strings (it, 0);
6758 if (overlay_strings_follow_p)
6759 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
6760 else
6762 it->what = IT_EOB;
6763 it->position = it->current.pos;
6764 success_p = 0;
6767 else if (!(!it->bidi_p
6768 || BIDI_AT_BASE_LEVEL (it->bidi_it)
6769 || IT_CHARPOS (*it) == it->stop_charpos))
6771 /* With bidi non-linear iteration, we could find ourselves
6772 far beyond the last computed stop_charpos, with several
6773 other stop positions in between that we missed. Scan
6774 them all now, in buffer's logical order, until we find
6775 and handle the last stop_charpos that precedes our
6776 current position. */
6777 handle_stop_backwards (it, it->stop_charpos);
6778 return GET_NEXT_DISPLAY_ELEMENT (it);
6780 else
6782 if (it->bidi_p)
6784 /* Take note of the stop position we just moved across,
6785 for when we will move back across it. */
6786 it->prev_stop = it->stop_charpos;
6787 /* If we are at base paragraph embedding level, take
6788 note of the last stop position seen at this
6789 level. */
6790 if (BIDI_AT_BASE_LEVEL (it->bidi_it))
6791 it->base_level_stop = it->stop_charpos;
6793 handle_stop (it);
6794 return GET_NEXT_DISPLAY_ELEMENT (it);
6797 else if (it->bidi_p
6798 /* We can sometimes back up for reasons that have nothing
6799 to do with bidi reordering. E.g., compositions. The
6800 code below is only needed when we are above the base
6801 embedding level, so test for that explicitly. */
6802 && !BIDI_AT_BASE_LEVEL (it->bidi_it)
6803 && IT_CHARPOS (*it) < it->prev_stop)
6805 if (it->base_level_stop <= 0)
6806 it->base_level_stop = BEGV;
6807 if (IT_CHARPOS (*it) < it->base_level_stop)
6808 abort ();
6809 handle_stop_backwards (it, it->base_level_stop);
6810 return GET_NEXT_DISPLAY_ELEMENT (it);
6812 else
6814 /* No face changes, overlays etc. in sight, so just return a
6815 character from current_buffer. */
6816 unsigned char *p;
6817 EMACS_INT stop;
6819 /* Maybe run the redisplay end trigger hook. Performance note:
6820 This doesn't seem to cost measurable time. */
6821 if (it->redisplay_end_trigger_charpos
6822 && it->glyph_row
6823 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
6824 run_redisplay_end_trigger_hook (it);
6826 stop = it->bidi_it.scan_dir < 0 ? -1 : it->end_charpos;
6827 if (CHAR_COMPOSED_P (it, IT_CHARPOS (*it), IT_BYTEPOS (*it),
6828 stop)
6829 && next_element_from_composition (it))
6831 return 1;
6834 /* Get the next character, maybe multibyte. */
6835 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
6836 if (it->multibyte_p && !ASCII_BYTE_P (*p))
6837 it->c = STRING_CHAR_AND_LENGTH (p, it->len);
6838 else
6839 it->c = *p, it->len = 1;
6841 /* Record what we have and where it came from. */
6842 it->what = IT_CHARACTER;
6843 it->object = it->w->buffer;
6844 it->position = it->current.pos;
6846 /* Normally we return the character found above, except when we
6847 really want to return an ellipsis for selective display. */
6848 if (it->selective)
6850 if (it->c == '\n')
6852 /* A value of selective > 0 means hide lines indented more
6853 than that number of columns. */
6854 if (it->selective > 0
6855 && IT_CHARPOS (*it) + 1 < ZV
6856 && indented_beyond_p (IT_CHARPOS (*it) + 1,
6857 IT_BYTEPOS (*it) + 1,
6858 (double) it->selective)) /* iftc */
6860 success_p = next_element_from_ellipsis (it);
6861 it->dpvec_char_len = -1;
6864 else if (it->c == '\r' && it->selective == -1)
6866 /* A value of selective == -1 means that everything from the
6867 CR to the end of the line is invisible, with maybe an
6868 ellipsis displayed for it. */
6869 success_p = next_element_from_ellipsis (it);
6870 it->dpvec_char_len = -1;
6875 /* Value is zero if end of buffer reached. */
6876 xassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
6877 return success_p;
6881 /* Run the redisplay end trigger hook for IT. */
6883 static void
6884 run_redisplay_end_trigger_hook (struct it *it)
6886 Lisp_Object args[3];
6888 /* IT->glyph_row should be non-null, i.e. we should be actually
6889 displaying something, or otherwise we should not run the hook. */
6890 xassert (it->glyph_row);
6892 /* Set up hook arguments. */
6893 args[0] = Qredisplay_end_trigger_functions;
6894 args[1] = it->window;
6895 XSETINT (args[2], it->redisplay_end_trigger_charpos);
6896 it->redisplay_end_trigger_charpos = 0;
6898 /* Since we are *trying* to run these functions, don't try to run
6899 them again, even if they get an error. */
6900 it->w->redisplay_end_trigger = Qnil;
6901 Frun_hook_with_args (3, args);
6903 /* Notice if it changed the face of the character we are on. */
6904 handle_face_prop (it);
6908 /* Deliver a composition display element. Unlike the other
6909 next_element_from_XXX, this function is not registered in the array
6910 get_next_element[]. It is called from next_element_from_buffer and
6911 next_element_from_string when necessary. */
6913 static int
6914 next_element_from_composition (struct it *it)
6916 it->what = IT_COMPOSITION;
6917 it->len = it->cmp_it.nbytes;
6918 if (STRINGP (it->string))
6920 if (it->c < 0)
6922 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
6923 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
6924 return 0;
6926 it->position = it->current.string_pos;
6927 it->object = it->string;
6928 it->c = composition_update_it (&it->cmp_it, IT_STRING_CHARPOS (*it),
6929 IT_STRING_BYTEPOS (*it), it->string);
6931 else
6933 if (it->c < 0)
6935 IT_CHARPOS (*it) += it->cmp_it.nchars;
6936 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
6937 if (it->bidi_p)
6939 if (it->bidi_it.new_paragraph)
6940 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it);
6941 /* Resync the bidi iterator with IT's new position.
6942 FIXME: this doesn't support bidirectional text. */
6943 while (it->bidi_it.charpos < IT_CHARPOS (*it))
6944 bidi_move_to_visually_next (&it->bidi_it);
6946 return 0;
6948 it->position = it->current.pos;
6949 it->object = it->w->buffer;
6950 it->c = composition_update_it (&it->cmp_it, IT_CHARPOS (*it),
6951 IT_BYTEPOS (*it), Qnil);
6953 return 1;
6958 /***********************************************************************
6959 Moving an iterator without producing glyphs
6960 ***********************************************************************/
6962 /* Check if iterator is at a position corresponding to a valid buffer
6963 position after some move_it_ call. */
6965 #define IT_POS_VALID_AFTER_MOVE_P(it) \
6966 ((it)->method == GET_FROM_STRING \
6967 ? IT_STRING_CHARPOS (*it) == 0 \
6968 : 1)
6971 /* Move iterator IT to a specified buffer or X position within one
6972 line on the display without producing glyphs.
6974 OP should be a bit mask including some or all of these bits:
6975 MOVE_TO_X: Stop upon reaching x-position TO_X.
6976 MOVE_TO_POS: Stop upon reaching buffer or string position TO_CHARPOS.
6977 Regardless of OP's value, stop upon reaching the end of the display line.
6979 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
6980 This means, in particular, that TO_X includes window's horizontal
6981 scroll amount.
6983 The return value has several possible values that
6984 say what condition caused the scan to stop:
6986 MOVE_POS_MATCH_OR_ZV
6987 - when TO_POS or ZV was reached.
6989 MOVE_X_REACHED
6990 -when TO_X was reached before TO_POS or ZV were reached.
6992 MOVE_LINE_CONTINUED
6993 - when we reached the end of the display area and the line must
6994 be continued.
6996 MOVE_LINE_TRUNCATED
6997 - when we reached the end of the display area and the line is
6998 truncated.
7000 MOVE_NEWLINE_OR_CR
7001 - when we stopped at a line end, i.e. a newline or a CR and selective
7002 display is on. */
7004 static enum move_it_result
7005 move_it_in_display_line_to (struct it *it,
7006 EMACS_INT to_charpos, int to_x,
7007 enum move_operation_enum op)
7009 enum move_it_result result = MOVE_UNDEFINED;
7010 struct glyph_row *saved_glyph_row;
7011 struct it wrap_it, atpos_it, atx_it;
7012 int may_wrap = 0;
7013 enum it_method prev_method = it->method;
7014 EMACS_INT prev_pos = IT_CHARPOS (*it);
7016 /* Don't produce glyphs in produce_glyphs. */
7017 saved_glyph_row = it->glyph_row;
7018 it->glyph_row = NULL;
7020 /* Use wrap_it to save a copy of IT wherever a word wrap could
7021 occur. Use atpos_it to save a copy of IT at the desired buffer
7022 position, if found, so that we can scan ahead and check if the
7023 word later overshoots the window edge. Use atx_it similarly, for
7024 pixel positions. */
7025 wrap_it.sp = -1;
7026 atpos_it.sp = -1;
7027 atx_it.sp = -1;
7029 #define BUFFER_POS_REACHED_P() \
7030 ((op & MOVE_TO_POS) != 0 \
7031 && BUFFERP (it->object) \
7032 && (IT_CHARPOS (*it) == to_charpos \
7033 || (!it->bidi_p && IT_CHARPOS (*it) > to_charpos)) \
7034 && (it->method == GET_FROM_BUFFER \
7035 || (it->method == GET_FROM_DISPLAY_VECTOR \
7036 && it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
7038 /* If there's a line-/wrap-prefix, handle it. */
7039 if (it->hpos == 0 && it->method == GET_FROM_BUFFER
7040 && it->current_y < it->last_visible_y)
7041 handle_line_prefix (it);
7043 while (1)
7045 int x, i, ascent = 0, descent = 0;
7047 /* Utility macro to reset an iterator with x, ascent, and descent. */
7048 #define IT_RESET_X_ASCENT_DESCENT(IT) \
7049 ((IT)->current_x = x, (IT)->max_ascent = ascent, \
7050 (IT)->max_descent = descent)
7052 /* Stop if we move beyond TO_CHARPOS (after an image or stretch
7053 glyph). */
7054 if ((op & MOVE_TO_POS) != 0
7055 && BUFFERP (it->object)
7056 && it->method == GET_FROM_BUFFER
7057 && ((!it->bidi_p && IT_CHARPOS (*it) > to_charpos)
7058 || (it->bidi_p
7059 && (prev_method == GET_FROM_IMAGE
7060 || prev_method == GET_FROM_STRETCH)
7061 /* Passed TO_CHARPOS from left to right. */
7062 && ((prev_pos < to_charpos
7063 && IT_CHARPOS (*it) > to_charpos)
7064 /* Passed TO_CHARPOS from right to left. */
7065 || (prev_pos > to_charpos
7066 && IT_CHARPOS (*it) < to_charpos)))))
7068 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
7070 result = MOVE_POS_MATCH_OR_ZV;
7071 break;
7073 else if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
7074 /* If wrap_it is valid, the current position might be in a
7075 word that is wrapped. So, save the iterator in
7076 atpos_it and continue to see if wrapping happens. */
7077 atpos_it = *it;
7080 prev_method = it->method;
7081 if (it->method == GET_FROM_BUFFER)
7082 prev_pos = IT_CHARPOS (*it);
7083 /* Stop when ZV reached.
7084 We used to stop here when TO_CHARPOS reached as well, but that is
7085 too soon if this glyph does not fit on this line. So we handle it
7086 explicitly below. */
7087 if (!get_next_display_element (it))
7089 result = MOVE_POS_MATCH_OR_ZV;
7090 break;
7093 if (it->line_wrap == TRUNCATE)
7095 if (BUFFER_POS_REACHED_P ())
7097 result = MOVE_POS_MATCH_OR_ZV;
7098 break;
7101 else
7103 if (it->line_wrap == WORD_WRAP)
7105 if (IT_DISPLAYING_WHITESPACE (it))
7106 may_wrap = 1;
7107 else if (may_wrap)
7109 /* We have reached a glyph that follows one or more
7110 whitespace characters. If the position is
7111 already found, we are done. */
7112 if (atpos_it.sp >= 0)
7114 *it = atpos_it;
7115 result = MOVE_POS_MATCH_OR_ZV;
7116 goto done;
7118 if (atx_it.sp >= 0)
7120 *it = atx_it;
7121 result = MOVE_X_REACHED;
7122 goto done;
7124 /* Otherwise, we can wrap here. */
7125 wrap_it = *it;
7126 may_wrap = 0;
7131 /* Remember the line height for the current line, in case
7132 the next element doesn't fit on the line. */
7133 ascent = it->max_ascent;
7134 descent = it->max_descent;
7136 /* The call to produce_glyphs will get the metrics of the
7137 display element IT is loaded with. Record the x-position
7138 before this display element, in case it doesn't fit on the
7139 line. */
7140 x = it->current_x;
7142 PRODUCE_GLYPHS (it);
7144 if (it->area != TEXT_AREA)
7146 set_iterator_to_next (it, 1);
7147 continue;
7150 /* The number of glyphs we get back in IT->nglyphs will normally
7151 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
7152 character on a terminal frame, or (iii) a line end. For the
7153 second case, IT->nglyphs - 1 padding glyphs will be present.
7154 (On X frames, there is only one glyph produced for a
7155 composite character.)
7157 The behavior implemented below means, for continuation lines,
7158 that as many spaces of a TAB as fit on the current line are
7159 displayed there. For terminal frames, as many glyphs of a
7160 multi-glyph character are displayed in the current line, too.
7161 This is what the old redisplay code did, and we keep it that
7162 way. Under X, the whole shape of a complex character must
7163 fit on the line or it will be completely displayed in the
7164 next line.
7166 Note that both for tabs and padding glyphs, all glyphs have
7167 the same width. */
7168 if (it->nglyphs)
7170 /* More than one glyph or glyph doesn't fit on line. All
7171 glyphs have the same width. */
7172 int single_glyph_width = it->pixel_width / it->nglyphs;
7173 int new_x;
7174 int x_before_this_char = x;
7175 int hpos_before_this_char = it->hpos;
7177 for (i = 0; i < it->nglyphs; ++i, x = new_x)
7179 new_x = x + single_glyph_width;
7181 /* We want to leave anything reaching TO_X to the caller. */
7182 if ((op & MOVE_TO_X) && new_x > to_x)
7184 if (BUFFER_POS_REACHED_P ())
7186 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
7187 goto buffer_pos_reached;
7188 if (atpos_it.sp < 0)
7190 atpos_it = *it;
7191 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
7194 else
7196 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
7198 it->current_x = x;
7199 result = MOVE_X_REACHED;
7200 break;
7202 if (atx_it.sp < 0)
7204 atx_it = *it;
7205 IT_RESET_X_ASCENT_DESCENT (&atx_it);
7210 if (/* Lines are continued. */
7211 it->line_wrap != TRUNCATE
7212 && (/* And glyph doesn't fit on the line. */
7213 new_x > it->last_visible_x
7214 /* Or it fits exactly and we're on a window
7215 system frame. */
7216 || (new_x == it->last_visible_x
7217 && FRAME_WINDOW_P (it->f))))
7219 if (/* IT->hpos == 0 means the very first glyph
7220 doesn't fit on the line, e.g. a wide image. */
7221 it->hpos == 0
7222 || (new_x == it->last_visible_x
7223 && FRAME_WINDOW_P (it->f)))
7225 ++it->hpos;
7226 it->current_x = new_x;
7228 /* The character's last glyph just barely fits
7229 in this row. */
7230 if (i == it->nglyphs - 1)
7232 /* If this is the destination position,
7233 return a position *before* it in this row,
7234 now that we know it fits in this row. */
7235 if (BUFFER_POS_REACHED_P ())
7237 if (it->line_wrap != WORD_WRAP
7238 || wrap_it.sp < 0)
7240 it->hpos = hpos_before_this_char;
7241 it->current_x = x_before_this_char;
7242 result = MOVE_POS_MATCH_OR_ZV;
7243 break;
7245 if (it->line_wrap == WORD_WRAP
7246 && atpos_it.sp < 0)
7248 atpos_it = *it;
7249 atpos_it.current_x = x_before_this_char;
7250 atpos_it.hpos = hpos_before_this_char;
7254 set_iterator_to_next (it, 1);
7255 /* On graphical terminals, newlines may
7256 "overflow" into the fringe if
7257 overflow-newline-into-fringe is non-nil.
7258 On text-only terminals, newlines may
7259 overflow into the last glyph on the
7260 display line.*/
7261 if (!FRAME_WINDOW_P (it->f)
7262 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
7264 if (!get_next_display_element (it))
7266 result = MOVE_POS_MATCH_OR_ZV;
7267 break;
7269 if (BUFFER_POS_REACHED_P ())
7271 if (ITERATOR_AT_END_OF_LINE_P (it))
7272 result = MOVE_POS_MATCH_OR_ZV;
7273 else
7274 result = MOVE_LINE_CONTINUED;
7275 break;
7277 if (ITERATOR_AT_END_OF_LINE_P (it))
7279 result = MOVE_NEWLINE_OR_CR;
7280 break;
7285 else
7286 IT_RESET_X_ASCENT_DESCENT (it);
7288 if (wrap_it.sp >= 0)
7290 *it = wrap_it;
7291 atpos_it.sp = -1;
7292 atx_it.sp = -1;
7295 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
7296 IT_CHARPOS (*it)));
7297 result = MOVE_LINE_CONTINUED;
7298 break;
7301 if (BUFFER_POS_REACHED_P ())
7303 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
7304 goto buffer_pos_reached;
7305 if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
7307 atpos_it = *it;
7308 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
7312 if (new_x > it->first_visible_x)
7314 /* Glyph is visible. Increment number of glyphs that
7315 would be displayed. */
7316 ++it->hpos;
7320 if (result != MOVE_UNDEFINED)
7321 break;
7323 else if (BUFFER_POS_REACHED_P ())
7325 buffer_pos_reached:
7326 IT_RESET_X_ASCENT_DESCENT (it);
7327 result = MOVE_POS_MATCH_OR_ZV;
7328 break;
7330 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
7332 /* Stop when TO_X specified and reached. This check is
7333 necessary here because of lines consisting of a line end,
7334 only. The line end will not produce any glyphs and we
7335 would never get MOVE_X_REACHED. */
7336 xassert (it->nglyphs == 0);
7337 result = MOVE_X_REACHED;
7338 break;
7341 /* Is this a line end? If yes, we're done. */
7342 if (ITERATOR_AT_END_OF_LINE_P (it))
7344 result = MOVE_NEWLINE_OR_CR;
7345 break;
7348 if (it->method == GET_FROM_BUFFER)
7349 prev_pos = IT_CHARPOS (*it);
7350 /* The current display element has been consumed. Advance
7351 to the next. */
7352 set_iterator_to_next (it, 1);
7354 /* Stop if lines are truncated and IT's current x-position is
7355 past the right edge of the window now. */
7356 if (it->line_wrap == TRUNCATE
7357 && it->current_x >= it->last_visible_x)
7359 if (!FRAME_WINDOW_P (it->f)
7360 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
7362 if (!get_next_display_element (it)
7363 || BUFFER_POS_REACHED_P ())
7365 result = MOVE_POS_MATCH_OR_ZV;
7366 break;
7368 if (ITERATOR_AT_END_OF_LINE_P (it))
7370 result = MOVE_NEWLINE_OR_CR;
7371 break;
7374 result = MOVE_LINE_TRUNCATED;
7375 break;
7377 #undef IT_RESET_X_ASCENT_DESCENT
7380 #undef BUFFER_POS_REACHED_P
7382 /* If we scanned beyond to_pos and didn't find a point to wrap at,
7383 restore the saved iterator. */
7384 if (atpos_it.sp >= 0)
7385 *it = atpos_it;
7386 else if (atx_it.sp >= 0)
7387 *it = atx_it;
7389 done:
7391 /* Restore the iterator settings altered at the beginning of this
7392 function. */
7393 it->glyph_row = saved_glyph_row;
7394 return result;
7397 /* For external use. */
7398 void
7399 move_it_in_display_line (struct it *it,
7400 EMACS_INT to_charpos, int to_x,
7401 enum move_operation_enum op)
7403 if (it->line_wrap == WORD_WRAP
7404 && (op & MOVE_TO_X))
7406 struct it save_it = *it;
7407 int skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
7408 /* When word-wrap is on, TO_X may lie past the end
7409 of a wrapped line. Then it->current is the
7410 character on the next line, so backtrack to the
7411 space before the wrap point. */
7412 if (skip == MOVE_LINE_CONTINUED)
7414 int prev_x = max (it->current_x - 1, 0);
7415 *it = save_it;
7416 move_it_in_display_line_to
7417 (it, -1, prev_x, MOVE_TO_X);
7420 else
7421 move_it_in_display_line_to (it, to_charpos, to_x, op);
7425 /* Move IT forward until it satisfies one or more of the criteria in
7426 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
7428 OP is a bit-mask that specifies where to stop, and in particular,
7429 which of those four position arguments makes a difference. See the
7430 description of enum move_operation_enum.
7432 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
7433 screen line, this function will set IT to the next position >
7434 TO_CHARPOS. */
7436 void
7437 move_it_to (struct it *it, int to_charpos, int to_x, int to_y, int to_vpos, int op)
7439 enum move_it_result skip, skip2 = MOVE_X_REACHED;
7440 int line_height, line_start_x = 0, reached = 0;
7442 for (;;)
7444 if (op & MOVE_TO_VPOS)
7446 /* If no TO_CHARPOS and no TO_X specified, stop at the
7447 start of the line TO_VPOS. */
7448 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
7450 if (it->vpos == to_vpos)
7452 reached = 1;
7453 break;
7455 else
7456 skip = move_it_in_display_line_to (it, -1, -1, 0);
7458 else
7460 /* TO_VPOS >= 0 means stop at TO_X in the line at
7461 TO_VPOS, or at TO_POS, whichever comes first. */
7462 if (it->vpos == to_vpos)
7464 reached = 2;
7465 break;
7468 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
7470 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
7472 reached = 3;
7473 break;
7475 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
7477 /* We have reached TO_X but not in the line we want. */
7478 skip = move_it_in_display_line_to (it, to_charpos,
7479 -1, MOVE_TO_POS);
7480 if (skip == MOVE_POS_MATCH_OR_ZV)
7482 reached = 4;
7483 break;
7488 else if (op & MOVE_TO_Y)
7490 struct it it_backup;
7492 if (it->line_wrap == WORD_WRAP)
7493 it_backup = *it;
7495 /* TO_Y specified means stop at TO_X in the line containing
7496 TO_Y---or at TO_CHARPOS if this is reached first. The
7497 problem is that we can't really tell whether the line
7498 contains TO_Y before we have completely scanned it, and
7499 this may skip past TO_X. What we do is to first scan to
7500 TO_X.
7502 If TO_X is not specified, use a TO_X of zero. The reason
7503 is to make the outcome of this function more predictable.
7504 If we didn't use TO_X == 0, we would stop at the end of
7505 the line which is probably not what a caller would expect
7506 to happen. */
7507 skip = move_it_in_display_line_to
7508 (it, to_charpos, ((op & MOVE_TO_X) ? to_x : 0),
7509 (MOVE_TO_X | (op & MOVE_TO_POS)));
7511 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
7512 if (skip == MOVE_POS_MATCH_OR_ZV)
7513 reached = 5;
7514 else if (skip == MOVE_X_REACHED)
7516 /* If TO_X was reached, we want to know whether TO_Y is
7517 in the line. We know this is the case if the already
7518 scanned glyphs make the line tall enough. Otherwise,
7519 we must check by scanning the rest of the line. */
7520 line_height = it->max_ascent + it->max_descent;
7521 if (to_y >= it->current_y
7522 && to_y < it->current_y + line_height)
7524 reached = 6;
7525 break;
7527 it_backup = *it;
7528 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
7529 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
7530 op & MOVE_TO_POS);
7531 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
7532 line_height = it->max_ascent + it->max_descent;
7533 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
7535 if (to_y >= it->current_y
7536 && to_y < it->current_y + line_height)
7538 /* If TO_Y is in this line and TO_X was reached
7539 above, we scanned too far. We have to restore
7540 IT's settings to the ones before skipping. */
7541 *it = it_backup;
7542 reached = 6;
7544 else
7546 skip = skip2;
7547 if (skip == MOVE_POS_MATCH_OR_ZV)
7548 reached = 7;
7551 else
7553 /* Check whether TO_Y is in this line. */
7554 line_height = it->max_ascent + it->max_descent;
7555 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
7557 if (to_y >= it->current_y
7558 && to_y < it->current_y + line_height)
7560 /* When word-wrap is on, TO_X may lie past the end
7561 of a wrapped line. Then it->current is the
7562 character on the next line, so backtrack to the
7563 space before the wrap point. */
7564 if (skip == MOVE_LINE_CONTINUED
7565 && it->line_wrap == WORD_WRAP)
7567 int prev_x = max (it->current_x - 1, 0);
7568 *it = it_backup;
7569 skip = move_it_in_display_line_to
7570 (it, -1, prev_x, MOVE_TO_X);
7572 reached = 6;
7576 if (reached)
7577 break;
7579 else if (BUFFERP (it->object)
7580 && (it->method == GET_FROM_BUFFER
7581 || it->method == GET_FROM_STRETCH)
7582 && IT_CHARPOS (*it) >= to_charpos)
7583 skip = MOVE_POS_MATCH_OR_ZV;
7584 else
7585 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
7587 switch (skip)
7589 case MOVE_POS_MATCH_OR_ZV:
7590 reached = 8;
7591 goto out;
7593 case MOVE_NEWLINE_OR_CR:
7594 set_iterator_to_next (it, 1);
7595 it->continuation_lines_width = 0;
7596 break;
7598 case MOVE_LINE_TRUNCATED:
7599 it->continuation_lines_width = 0;
7600 reseat_at_next_visible_line_start (it, 0);
7601 if ((op & MOVE_TO_POS) != 0
7602 && IT_CHARPOS (*it) > to_charpos)
7604 reached = 9;
7605 goto out;
7607 break;
7609 case MOVE_LINE_CONTINUED:
7610 /* For continued lines ending in a tab, some of the glyphs
7611 associated with the tab are displayed on the current
7612 line. Since it->current_x does not include these glyphs,
7613 we use it->last_visible_x instead. */
7614 if (it->c == '\t')
7616 it->continuation_lines_width += it->last_visible_x;
7617 /* When moving by vpos, ensure that the iterator really
7618 advances to the next line (bug#847, bug#969). Fixme:
7619 do we need to do this in other circumstances? */
7620 if (it->current_x != it->last_visible_x
7621 && (op & MOVE_TO_VPOS)
7622 && !(op & (MOVE_TO_X | MOVE_TO_POS)))
7624 line_start_x = it->current_x + it->pixel_width
7625 - it->last_visible_x;
7626 set_iterator_to_next (it, 0);
7629 else
7630 it->continuation_lines_width += it->current_x;
7631 break;
7633 default:
7634 abort ();
7637 /* Reset/increment for the next run. */
7638 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
7639 it->current_x = line_start_x;
7640 line_start_x = 0;
7641 it->hpos = 0;
7642 it->current_y += it->max_ascent + it->max_descent;
7643 ++it->vpos;
7644 last_height = it->max_ascent + it->max_descent;
7645 last_max_ascent = it->max_ascent;
7646 it->max_ascent = it->max_descent = 0;
7649 out:
7651 /* On text terminals, we may stop at the end of a line in the middle
7652 of a multi-character glyph. If the glyph itself is continued,
7653 i.e. it is actually displayed on the next line, don't treat this
7654 stopping point as valid; move to the next line instead (unless
7655 that brings us offscreen). */
7656 if (!FRAME_WINDOW_P (it->f)
7657 && op & MOVE_TO_POS
7658 && IT_CHARPOS (*it) == to_charpos
7659 && it->what == IT_CHARACTER
7660 && it->nglyphs > 1
7661 && it->line_wrap == WINDOW_WRAP
7662 && it->current_x == it->last_visible_x - 1
7663 && it->c != '\n'
7664 && it->c != '\t'
7665 && it->vpos < XFASTINT (it->w->window_end_vpos))
7667 it->continuation_lines_width += it->current_x;
7668 it->current_x = it->hpos = it->max_ascent = it->max_descent = 0;
7669 it->current_y += it->max_ascent + it->max_descent;
7670 ++it->vpos;
7671 last_height = it->max_ascent + it->max_descent;
7672 last_max_ascent = it->max_ascent;
7675 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
7679 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
7681 If DY > 0, move IT backward at least that many pixels. DY = 0
7682 means move IT backward to the preceding line start or BEGV. This
7683 function may move over more than DY pixels if IT->current_y - DY
7684 ends up in the middle of a line; in this case IT->current_y will be
7685 set to the top of the line moved to. */
7687 void
7688 move_it_vertically_backward (struct it *it, int dy)
7690 int nlines, h;
7691 struct it it2, it3;
7692 int start_pos;
7694 move_further_back:
7695 xassert (dy >= 0);
7697 start_pos = IT_CHARPOS (*it);
7699 /* Estimate how many newlines we must move back. */
7700 nlines = max (1, dy / FRAME_LINE_HEIGHT (it->f));
7702 /* Set the iterator's position that many lines back. */
7703 while (nlines-- && IT_CHARPOS (*it) > BEGV)
7704 back_to_previous_visible_line_start (it);
7706 /* Reseat the iterator here. When moving backward, we don't want
7707 reseat to skip forward over invisible text, set up the iterator
7708 to deliver from overlay strings at the new position etc. So,
7709 use reseat_1 here. */
7710 reseat_1 (it, it->current.pos, 1);
7712 /* We are now surely at a line start. */
7713 it->current_x = it->hpos = 0;
7714 it->continuation_lines_width = 0;
7716 /* Move forward and see what y-distance we moved. First move to the
7717 start of the next line so that we get its height. We need this
7718 height to be able to tell whether we reached the specified
7719 y-distance. */
7720 it2 = *it;
7721 it2.max_ascent = it2.max_descent = 0;
7724 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
7725 MOVE_TO_POS | MOVE_TO_VPOS);
7727 while (!IT_POS_VALID_AFTER_MOVE_P (&it2));
7728 xassert (IT_CHARPOS (*it) >= BEGV);
7729 it3 = it2;
7731 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
7732 xassert (IT_CHARPOS (*it) >= BEGV);
7733 /* H is the actual vertical distance from the position in *IT
7734 and the starting position. */
7735 h = it2.current_y - it->current_y;
7736 /* NLINES is the distance in number of lines. */
7737 nlines = it2.vpos - it->vpos;
7739 /* Correct IT's y and vpos position
7740 so that they are relative to the starting point. */
7741 it->vpos -= nlines;
7742 it->current_y -= h;
7744 if (dy == 0)
7746 /* DY == 0 means move to the start of the screen line. The
7747 value of nlines is > 0 if continuation lines were involved. */
7748 if (nlines > 0)
7749 move_it_by_lines (it, nlines, 1);
7751 else
7753 /* The y-position we try to reach, relative to *IT.
7754 Note that H has been subtracted in front of the if-statement. */
7755 int target_y = it->current_y + h - dy;
7756 int y0 = it3.current_y;
7757 int y1 = line_bottom_y (&it3);
7758 int line_height = y1 - y0;
7760 /* If we did not reach target_y, try to move further backward if
7761 we can. If we moved too far backward, try to move forward. */
7762 if (target_y < it->current_y
7763 /* This is heuristic. In a window that's 3 lines high, with
7764 a line height of 13 pixels each, recentering with point
7765 on the bottom line will try to move -39/2 = 19 pixels
7766 backward. Try to avoid moving into the first line. */
7767 && (it->current_y - target_y
7768 > min (window_box_height (it->w), line_height * 2 / 3))
7769 && IT_CHARPOS (*it) > BEGV)
7771 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
7772 target_y - it->current_y));
7773 dy = it->current_y - target_y;
7774 goto move_further_back;
7776 else if (target_y >= it->current_y + line_height
7777 && IT_CHARPOS (*it) < ZV)
7779 /* Should move forward by at least one line, maybe more.
7781 Note: Calling move_it_by_lines can be expensive on
7782 terminal frames, where compute_motion is used (via
7783 vmotion) to do the job, when there are very long lines
7784 and truncate-lines is nil. That's the reason for
7785 treating terminal frames specially here. */
7787 if (!FRAME_WINDOW_P (it->f))
7788 move_it_vertically (it, target_y - (it->current_y + line_height));
7789 else
7793 move_it_by_lines (it, 1, 1);
7795 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
7802 /* Move IT by a specified amount of pixel lines DY. DY negative means
7803 move backwards. DY = 0 means move to start of screen line. At the
7804 end, IT will be on the start of a screen line. */
7806 void
7807 move_it_vertically (struct it *it, int dy)
7809 if (dy <= 0)
7810 move_it_vertically_backward (it, -dy);
7811 else
7813 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
7814 move_it_to (it, ZV, -1, it->current_y + dy, -1,
7815 MOVE_TO_POS | MOVE_TO_Y);
7816 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
7818 /* If buffer ends in ZV without a newline, move to the start of
7819 the line to satisfy the post-condition. */
7820 if (IT_CHARPOS (*it) == ZV
7821 && ZV > BEGV
7822 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
7823 move_it_by_lines (it, 0, 0);
7828 /* Move iterator IT past the end of the text line it is in. */
7830 void
7831 move_it_past_eol (struct it *it)
7833 enum move_it_result rc;
7835 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
7836 if (rc == MOVE_NEWLINE_OR_CR)
7837 set_iterator_to_next (it, 0);
7841 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
7842 negative means move up. DVPOS == 0 means move to the start of the
7843 screen line. NEED_Y_P non-zero means calculate IT->current_y. If
7844 NEED_Y_P is zero, IT->current_y will be left unchanged.
7846 Further optimization ideas: If we would know that IT->f doesn't use
7847 a face with proportional font, we could be faster for
7848 truncate-lines nil. */
7850 void
7851 move_it_by_lines (struct it *it, int dvpos, int need_y_p)
7853 struct position pos;
7855 /* The commented-out optimization uses vmotion on terminals. This
7856 gives bad results, because elements like it->what, on which
7857 callers such as pos_visible_p rely, aren't updated. */
7858 /* if (!FRAME_WINDOW_P (it->f))
7860 struct text_pos textpos;
7862 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
7863 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
7864 reseat (it, textpos, 1);
7865 it->vpos += pos.vpos;
7866 it->current_y += pos.vpos;
7868 else */
7870 if (dvpos == 0)
7872 /* DVPOS == 0 means move to the start of the screen line. */
7873 move_it_vertically_backward (it, 0);
7874 xassert (it->current_x == 0 && it->hpos == 0);
7875 /* Let next call to line_bottom_y calculate real line height */
7876 last_height = 0;
7878 else if (dvpos > 0)
7880 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
7881 if (!IT_POS_VALID_AFTER_MOVE_P (it))
7882 move_it_to (it, IT_CHARPOS (*it) + 1, -1, -1, -1, MOVE_TO_POS);
7884 else
7886 struct it it2;
7887 int start_charpos, i;
7889 /* Start at the beginning of the screen line containing IT's
7890 position. This may actually move vertically backwards,
7891 in case of overlays, so adjust dvpos accordingly. */
7892 dvpos += it->vpos;
7893 move_it_vertically_backward (it, 0);
7894 dvpos -= it->vpos;
7896 /* Go back -DVPOS visible lines and reseat the iterator there. */
7897 start_charpos = IT_CHARPOS (*it);
7898 for (i = -dvpos; i > 0 && IT_CHARPOS (*it) > BEGV; --i)
7899 back_to_previous_visible_line_start (it);
7900 reseat (it, it->current.pos, 1);
7902 /* Move further back if we end up in a string or an image. */
7903 while (!IT_POS_VALID_AFTER_MOVE_P (it))
7905 /* First try to move to start of display line. */
7906 dvpos += it->vpos;
7907 move_it_vertically_backward (it, 0);
7908 dvpos -= it->vpos;
7909 if (IT_POS_VALID_AFTER_MOVE_P (it))
7910 break;
7911 /* If start of line is still in string or image,
7912 move further back. */
7913 back_to_previous_visible_line_start (it);
7914 reseat (it, it->current.pos, 1);
7915 dvpos--;
7918 it->current_x = it->hpos = 0;
7920 /* Above call may have moved too far if continuation lines
7921 are involved. Scan forward and see if it did. */
7922 it2 = *it;
7923 it2.vpos = it2.current_y = 0;
7924 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
7925 it->vpos -= it2.vpos;
7926 it->current_y -= it2.current_y;
7927 it->current_x = it->hpos = 0;
7929 /* If we moved too far back, move IT some lines forward. */
7930 if (it2.vpos > -dvpos)
7932 int delta = it2.vpos + dvpos;
7933 it2 = *it;
7934 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
7935 /* Move back again if we got too far ahead. */
7936 if (IT_CHARPOS (*it) >= start_charpos)
7937 *it = it2;
7942 /* Return 1 if IT points into the middle of a display vector. */
7945 in_display_vector_p (struct it *it)
7947 return (it->method == GET_FROM_DISPLAY_VECTOR
7948 && it->current.dpvec_index > 0
7949 && it->dpvec + it->current.dpvec_index != it->dpend);
7953 /***********************************************************************
7954 Messages
7955 ***********************************************************************/
7958 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
7959 to *Messages*. */
7961 void
7962 add_to_log (const char *format, Lisp_Object arg1, Lisp_Object arg2)
7964 Lisp_Object args[3];
7965 Lisp_Object msg, fmt;
7966 char *buffer;
7967 int len;
7968 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
7969 USE_SAFE_ALLOCA;
7971 /* Do nothing if called asynchronously. Inserting text into
7972 a buffer may call after-change-functions and alike and
7973 that would means running Lisp asynchronously. */
7974 if (handling_signal)
7975 return;
7977 fmt = msg = Qnil;
7978 GCPRO4 (fmt, msg, arg1, arg2);
7980 args[0] = fmt = build_string (format);
7981 args[1] = arg1;
7982 args[2] = arg2;
7983 msg = Fformat (3, args);
7985 len = SBYTES (msg) + 1;
7986 SAFE_ALLOCA (buffer, char *, len);
7987 memcpy (buffer, SDATA (msg), len);
7989 message_dolog (buffer, len - 1, 1, 0);
7990 SAFE_FREE ();
7992 UNGCPRO;
7996 /* Output a newline in the *Messages* buffer if "needs" one. */
7998 void
7999 message_log_maybe_newline (void)
8001 if (message_log_need_newline)
8002 message_dolog ("", 0, 1, 0);
8006 /* Add a string M of length NBYTES to the message log, optionally
8007 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
8008 nonzero, means interpret the contents of M as multibyte. This
8009 function calls low-level routines in order to bypass text property
8010 hooks, etc. which might not be safe to run.
8012 This may GC (insert may run before/after change hooks),
8013 so the buffer M must NOT point to a Lisp string. */
8015 void
8016 message_dolog (const char *m, int nbytes, int nlflag, int multibyte)
8018 if (!NILP (Vmemory_full))
8019 return;
8021 if (!NILP (Vmessage_log_max))
8023 struct buffer *oldbuf;
8024 Lisp_Object oldpoint, oldbegv, oldzv;
8025 int old_windows_or_buffers_changed = windows_or_buffers_changed;
8026 int point_at_end = 0;
8027 int zv_at_end = 0;
8028 Lisp_Object old_deactivate_mark, tem;
8029 struct gcpro gcpro1;
8031 old_deactivate_mark = Vdeactivate_mark;
8032 oldbuf = current_buffer;
8033 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
8034 current_buffer->undo_list = Qt;
8036 oldpoint = message_dolog_marker1;
8037 set_marker_restricted (oldpoint, make_number (PT), Qnil);
8038 oldbegv = message_dolog_marker2;
8039 set_marker_restricted (oldbegv, make_number (BEGV), Qnil);
8040 oldzv = message_dolog_marker3;
8041 set_marker_restricted (oldzv, make_number (ZV), Qnil);
8042 GCPRO1 (old_deactivate_mark);
8044 if (PT == Z)
8045 point_at_end = 1;
8046 if (ZV == Z)
8047 zv_at_end = 1;
8049 BEGV = BEG;
8050 BEGV_BYTE = BEG_BYTE;
8051 ZV = Z;
8052 ZV_BYTE = Z_BYTE;
8053 TEMP_SET_PT_BOTH (Z, Z_BYTE);
8055 /* Insert the string--maybe converting multibyte to single byte
8056 or vice versa, so that all the text fits the buffer. */
8057 if (multibyte
8058 && NILP (current_buffer->enable_multibyte_characters))
8060 int i, c, char_bytes;
8061 unsigned char work[1];
8063 /* Convert a multibyte string to single-byte
8064 for the *Message* buffer. */
8065 for (i = 0; i < nbytes; i += char_bytes)
8067 c = string_char_and_length (m + i, &char_bytes);
8068 work[0] = (ASCII_CHAR_P (c)
8070 : multibyte_char_to_unibyte (c, Qnil));
8071 insert_1_both (work, 1, 1, 1, 0, 0);
8074 else if (! multibyte
8075 && ! NILP (current_buffer->enable_multibyte_characters))
8077 int i, c, char_bytes;
8078 unsigned char *msg = (unsigned char *) m;
8079 unsigned char str[MAX_MULTIBYTE_LENGTH];
8080 /* Convert a single-byte string to multibyte
8081 for the *Message* buffer. */
8082 for (i = 0; i < nbytes; i++)
8084 c = msg[i];
8085 MAKE_CHAR_MULTIBYTE (c);
8086 char_bytes = CHAR_STRING (c, str);
8087 insert_1_both (str, 1, char_bytes, 1, 0, 0);
8090 else if (nbytes)
8091 insert_1 (m, nbytes, 1, 0, 0);
8093 if (nlflag)
8095 int this_bol, this_bol_byte, prev_bol, prev_bol_byte, dup;
8096 insert_1 ("\n", 1, 1, 0, 0);
8098 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
8099 this_bol = PT;
8100 this_bol_byte = PT_BYTE;
8102 /* See if this line duplicates the previous one.
8103 If so, combine duplicates. */
8104 if (this_bol > BEG)
8106 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
8107 prev_bol = PT;
8108 prev_bol_byte = PT_BYTE;
8110 dup = message_log_check_duplicate (prev_bol, prev_bol_byte,
8111 this_bol, this_bol_byte);
8112 if (dup)
8114 del_range_both (prev_bol, prev_bol_byte,
8115 this_bol, this_bol_byte, 0);
8116 if (dup > 1)
8118 char dupstr[40];
8119 int duplen;
8121 /* If you change this format, don't forget to also
8122 change message_log_check_duplicate. */
8123 sprintf (dupstr, " [%d times]", dup);
8124 duplen = strlen (dupstr);
8125 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
8126 insert_1 (dupstr, duplen, 1, 0, 1);
8131 /* If we have more than the desired maximum number of lines
8132 in the *Messages* buffer now, delete the oldest ones.
8133 This is safe because we don't have undo in this buffer. */
8135 if (NATNUMP (Vmessage_log_max))
8137 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
8138 -XFASTINT (Vmessage_log_max) - 1, 0);
8139 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
8142 BEGV = XMARKER (oldbegv)->charpos;
8143 BEGV_BYTE = marker_byte_position (oldbegv);
8145 if (zv_at_end)
8147 ZV = Z;
8148 ZV_BYTE = Z_BYTE;
8150 else
8152 ZV = XMARKER (oldzv)->charpos;
8153 ZV_BYTE = marker_byte_position (oldzv);
8156 if (point_at_end)
8157 TEMP_SET_PT_BOTH (Z, Z_BYTE);
8158 else
8159 /* We can't do Fgoto_char (oldpoint) because it will run some
8160 Lisp code. */
8161 TEMP_SET_PT_BOTH (XMARKER (oldpoint)->charpos,
8162 XMARKER (oldpoint)->bytepos);
8164 UNGCPRO;
8165 unchain_marker (XMARKER (oldpoint));
8166 unchain_marker (XMARKER (oldbegv));
8167 unchain_marker (XMARKER (oldzv));
8169 tem = Fget_buffer_window (Fcurrent_buffer (), Qt);
8170 set_buffer_internal (oldbuf);
8171 if (NILP (tem))
8172 windows_or_buffers_changed = old_windows_or_buffers_changed;
8173 message_log_need_newline = !nlflag;
8174 Vdeactivate_mark = old_deactivate_mark;
8179 /* We are at the end of the buffer after just having inserted a newline.
8180 (Note: We depend on the fact we won't be crossing the gap.)
8181 Check to see if the most recent message looks a lot like the previous one.
8182 Return 0 if different, 1 if the new one should just replace it, or a
8183 value N > 1 if we should also append " [N times]". */
8185 static int
8186 message_log_check_duplicate (int prev_bol, int prev_bol_byte,
8187 int this_bol, int this_bol_byte)
8189 int i;
8190 int len = Z_BYTE - 1 - this_bol_byte;
8191 int seen_dots = 0;
8192 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
8193 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
8195 for (i = 0; i < len; i++)
8197 if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.')
8198 seen_dots = 1;
8199 if (p1[i] != p2[i])
8200 return seen_dots;
8202 p1 += len;
8203 if (*p1 == '\n')
8204 return 2;
8205 if (*p1++ == ' ' && *p1++ == '[')
8207 int n = 0;
8208 while (*p1 >= '0' && *p1 <= '9')
8209 n = n * 10 + *p1++ - '0';
8210 if (strncmp (p1, " times]\n", 8) == 0)
8211 return n+1;
8213 return 0;
8217 /* Display an echo area message M with a specified length of NBYTES
8218 bytes. The string may include null characters. If M is 0, clear
8219 out any existing message, and let the mini-buffer text show
8220 through.
8222 This may GC, so the buffer M must NOT point to a Lisp string. */
8224 void
8225 message2 (const char *m, int nbytes, int multibyte)
8227 /* First flush out any partial line written with print. */
8228 message_log_maybe_newline ();
8229 if (m)
8230 message_dolog (m, nbytes, 1, multibyte);
8231 message2_nolog (m, nbytes, multibyte);
8235 /* The non-logging counterpart of message2. */
8237 void
8238 message2_nolog (const char *m, int nbytes, int multibyte)
8240 struct frame *sf = SELECTED_FRAME ();
8241 message_enable_multibyte = multibyte;
8243 if (FRAME_INITIAL_P (sf))
8245 if (noninteractive_need_newline)
8246 putc ('\n', stderr);
8247 noninteractive_need_newline = 0;
8248 if (m)
8249 fwrite (m, nbytes, 1, stderr);
8250 if (cursor_in_echo_area == 0)
8251 fprintf (stderr, "\n");
8252 fflush (stderr);
8254 /* A null message buffer means that the frame hasn't really been
8255 initialized yet. Error messages get reported properly by
8256 cmd_error, so this must be just an informative message; toss it. */
8257 else if (INTERACTIVE
8258 && sf->glyphs_initialized_p
8259 && FRAME_MESSAGE_BUF (sf))
8261 Lisp_Object mini_window;
8262 struct frame *f;
8264 /* Get the frame containing the mini-buffer
8265 that the selected frame is using. */
8266 mini_window = FRAME_MINIBUF_WINDOW (sf);
8267 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
8269 FRAME_SAMPLE_VISIBILITY (f);
8270 if (FRAME_VISIBLE_P (sf)
8271 && ! FRAME_VISIBLE_P (f))
8272 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
8274 if (m)
8276 set_message (m, Qnil, nbytes, multibyte);
8277 if (minibuffer_auto_raise)
8278 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
8280 else
8281 clear_message (1, 1);
8283 do_pending_window_change (0);
8284 echo_area_display (1);
8285 do_pending_window_change (0);
8286 if (FRAME_TERMINAL (f)->frame_up_to_date_hook != 0 && ! gc_in_progress)
8287 (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
8292 /* Display an echo area message M with a specified length of NBYTES
8293 bytes. The string may include null characters. If M is not a
8294 string, clear out any existing message, and let the mini-buffer
8295 text show through.
8297 This function cancels echoing. */
8299 void
8300 message3 (Lisp_Object m, int nbytes, int multibyte)
8302 struct gcpro gcpro1;
8304 GCPRO1 (m);
8305 clear_message (1,1);
8306 cancel_echoing ();
8308 /* First flush out any partial line written with print. */
8309 message_log_maybe_newline ();
8310 if (STRINGP (m))
8312 char *buffer;
8313 USE_SAFE_ALLOCA;
8315 SAFE_ALLOCA (buffer, char *, nbytes);
8316 memcpy (buffer, SDATA (m), nbytes);
8317 message_dolog (buffer, nbytes, 1, multibyte);
8318 SAFE_FREE ();
8320 message3_nolog (m, nbytes, multibyte);
8322 UNGCPRO;
8326 /* The non-logging version of message3.
8327 This does not cancel echoing, because it is used for echoing.
8328 Perhaps we need to make a separate function for echoing
8329 and make this cancel echoing. */
8331 void
8332 message3_nolog (Lisp_Object m, int nbytes, int multibyte)
8334 struct frame *sf = SELECTED_FRAME ();
8335 message_enable_multibyte = multibyte;
8337 if (FRAME_INITIAL_P (sf))
8339 if (noninteractive_need_newline)
8340 putc ('\n', stderr);
8341 noninteractive_need_newline = 0;
8342 if (STRINGP (m))
8343 fwrite (SDATA (m), nbytes, 1, stderr);
8344 if (cursor_in_echo_area == 0)
8345 fprintf (stderr, "\n");
8346 fflush (stderr);
8348 /* A null message buffer means that the frame hasn't really been
8349 initialized yet. Error messages get reported properly by
8350 cmd_error, so this must be just an informative message; toss it. */
8351 else if (INTERACTIVE
8352 && sf->glyphs_initialized_p
8353 && FRAME_MESSAGE_BUF (sf))
8355 Lisp_Object mini_window;
8356 Lisp_Object frame;
8357 struct frame *f;
8359 /* Get the frame containing the mini-buffer
8360 that the selected frame is using. */
8361 mini_window = FRAME_MINIBUF_WINDOW (sf);
8362 frame = XWINDOW (mini_window)->frame;
8363 f = XFRAME (frame);
8365 FRAME_SAMPLE_VISIBILITY (f);
8366 if (FRAME_VISIBLE_P (sf)
8367 && !FRAME_VISIBLE_P (f))
8368 Fmake_frame_visible (frame);
8370 if (STRINGP (m) && SCHARS (m) > 0)
8372 set_message (NULL, m, nbytes, multibyte);
8373 if (minibuffer_auto_raise)
8374 Fraise_frame (frame);
8375 /* Assume we are not echoing.
8376 (If we are, echo_now will override this.) */
8377 echo_message_buffer = Qnil;
8379 else
8380 clear_message (1, 1);
8382 do_pending_window_change (0);
8383 echo_area_display (1);
8384 do_pending_window_change (0);
8385 if (FRAME_TERMINAL (f)->frame_up_to_date_hook != 0 && ! gc_in_progress)
8386 (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
8391 /* Display a null-terminated echo area message M. If M is 0, clear
8392 out any existing message, and let the mini-buffer text show through.
8394 The buffer M must continue to exist until after the echo area gets
8395 cleared or some other message gets displayed there. Do not pass
8396 text that is stored in a Lisp string. Do not pass text in a buffer
8397 that was alloca'd. */
8399 void
8400 message1 (const char *m)
8402 message2 (m, (m ? strlen (m) : 0), 0);
8406 /* The non-logging counterpart of message1. */
8408 void
8409 message1_nolog (const char *m)
8411 message2_nolog (m, (m ? strlen (m) : 0), 0);
8414 /* Display a message M which contains a single %s
8415 which gets replaced with STRING. */
8417 void
8418 message_with_string (const char *m, Lisp_Object string, int log)
8420 CHECK_STRING (string);
8422 if (noninteractive)
8424 if (m)
8426 if (noninteractive_need_newline)
8427 putc ('\n', stderr);
8428 noninteractive_need_newline = 0;
8429 fprintf (stderr, m, SDATA (string));
8430 if (!cursor_in_echo_area)
8431 fprintf (stderr, "\n");
8432 fflush (stderr);
8435 else if (INTERACTIVE)
8437 /* The frame whose minibuffer we're going to display the message on.
8438 It may be larger than the selected frame, so we need
8439 to use its buffer, not the selected frame's buffer. */
8440 Lisp_Object mini_window;
8441 struct frame *f, *sf = SELECTED_FRAME ();
8443 /* Get the frame containing the minibuffer
8444 that the selected frame is using. */
8445 mini_window = FRAME_MINIBUF_WINDOW (sf);
8446 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
8448 /* A null message buffer means that the frame hasn't really been
8449 initialized yet. Error messages get reported properly by
8450 cmd_error, so this must be just an informative message; toss it. */
8451 if (FRAME_MESSAGE_BUF (f))
8453 Lisp_Object args[2], message;
8454 struct gcpro gcpro1, gcpro2;
8456 args[0] = build_string (m);
8457 args[1] = message = string;
8458 GCPRO2 (args[0], message);
8459 gcpro1.nvars = 2;
8461 message = Fformat (2, args);
8463 if (log)
8464 message3 (message, SBYTES (message), STRING_MULTIBYTE (message));
8465 else
8466 message3_nolog (message, SBYTES (message), STRING_MULTIBYTE (message));
8468 UNGCPRO;
8470 /* Print should start at the beginning of the message
8471 buffer next time. */
8472 message_buf_print = 0;
8478 /* Dump an informative message to the minibuf. If M is 0, clear out
8479 any existing message, and let the mini-buffer text show through. */
8481 static void
8482 vmessage (const char *m, va_list ap)
8484 if (noninteractive)
8486 if (m)
8488 if (noninteractive_need_newline)
8489 putc ('\n', stderr);
8490 noninteractive_need_newline = 0;
8491 vfprintf (stderr, m, ap);
8492 if (cursor_in_echo_area == 0)
8493 fprintf (stderr, "\n");
8494 fflush (stderr);
8497 else if (INTERACTIVE)
8499 /* The frame whose mini-buffer we're going to display the message
8500 on. It may be larger than the selected frame, so we need to
8501 use its buffer, not the selected frame's buffer. */
8502 Lisp_Object mini_window;
8503 struct frame *f, *sf = SELECTED_FRAME ();
8505 /* Get the frame containing the mini-buffer
8506 that the selected frame is using. */
8507 mini_window = FRAME_MINIBUF_WINDOW (sf);
8508 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
8510 /* A null message buffer means that the frame hasn't really been
8511 initialized yet. Error messages get reported properly by
8512 cmd_error, so this must be just an informative message; toss
8513 it. */
8514 if (FRAME_MESSAGE_BUF (f))
8516 if (m)
8518 int len;
8520 len = doprnt (FRAME_MESSAGE_BUF (f),
8521 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, ap);
8523 message2 (FRAME_MESSAGE_BUF (f), len, 0);
8525 else
8526 message1 (0);
8528 /* Print should start at the beginning of the message
8529 buffer next time. */
8530 message_buf_print = 0;
8535 void
8536 message (const char *m, ...)
8538 va_list ap;
8539 va_start (ap, m);
8540 vmessage (m, ap);
8541 va_end (ap);
8545 /* The non-logging version of message. */
8547 void
8548 message_nolog (const char *m, ...)
8550 Lisp_Object old_log_max;
8551 va_list ap;
8552 va_start (ap, m);
8553 old_log_max = Vmessage_log_max;
8554 Vmessage_log_max = Qnil;
8555 vmessage (m, ap);
8556 Vmessage_log_max = old_log_max;
8557 va_end (ap);
8561 /* Display the current message in the current mini-buffer. This is
8562 only called from error handlers in process.c, and is not time
8563 critical. */
8565 void
8566 update_echo_area (void)
8568 if (!NILP (echo_area_buffer[0]))
8570 Lisp_Object string;
8571 string = Fcurrent_message ();
8572 message3 (string, SBYTES (string),
8573 !NILP (current_buffer->enable_multibyte_characters));
8578 /* Make sure echo area buffers in `echo_buffers' are live.
8579 If they aren't, make new ones. */
8581 static void
8582 ensure_echo_area_buffers (void)
8584 int i;
8586 for (i = 0; i < 2; ++i)
8587 if (!BUFFERP (echo_buffer[i])
8588 || NILP (XBUFFER (echo_buffer[i])->name))
8590 char name[30];
8591 Lisp_Object old_buffer;
8592 int j;
8594 old_buffer = echo_buffer[i];
8595 sprintf (name, " *Echo Area %d*", i);
8596 echo_buffer[i] = Fget_buffer_create (build_string (name));
8597 XBUFFER (echo_buffer[i])->truncate_lines = Qnil;
8598 /* to force word wrap in echo area -
8599 it was decided to postpone this*/
8600 /* XBUFFER (echo_buffer[i])->word_wrap = Qt; */
8602 for (j = 0; j < 2; ++j)
8603 if (EQ (old_buffer, echo_area_buffer[j]))
8604 echo_area_buffer[j] = echo_buffer[i];
8609 /* Call FN with args A1..A4 with either the current or last displayed
8610 echo_area_buffer as current buffer.
8612 WHICH zero means use the current message buffer
8613 echo_area_buffer[0]. If that is nil, choose a suitable buffer
8614 from echo_buffer[] and clear it.
8616 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
8617 suitable buffer from echo_buffer[] and clear it.
8619 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
8620 that the current message becomes the last displayed one, make
8621 choose a suitable buffer for echo_area_buffer[0], and clear it.
8623 Value is what FN returns. */
8625 static int
8626 with_echo_area_buffer (struct window *w, int which,
8627 int (*fn) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
8628 EMACS_INT a1, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4)
8630 Lisp_Object buffer;
8631 int this_one, the_other, clear_buffer_p, rc;
8632 int count = SPECPDL_INDEX ();
8634 /* If buffers aren't live, make new ones. */
8635 ensure_echo_area_buffers ();
8637 clear_buffer_p = 0;
8639 if (which == 0)
8640 this_one = 0, the_other = 1;
8641 else if (which > 0)
8642 this_one = 1, the_other = 0;
8643 else
8645 this_one = 0, the_other = 1;
8646 clear_buffer_p = 1;
8648 /* We need a fresh one in case the current echo buffer equals
8649 the one containing the last displayed echo area message. */
8650 if (!NILP (echo_area_buffer[this_one])
8651 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
8652 echo_area_buffer[this_one] = Qnil;
8655 /* Choose a suitable buffer from echo_buffer[] is we don't
8656 have one. */
8657 if (NILP (echo_area_buffer[this_one]))
8659 echo_area_buffer[this_one]
8660 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
8661 ? echo_buffer[the_other]
8662 : echo_buffer[this_one]);
8663 clear_buffer_p = 1;
8666 buffer = echo_area_buffer[this_one];
8668 /* Don't get confused by reusing the buffer used for echoing
8669 for a different purpose. */
8670 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
8671 cancel_echoing ();
8673 record_unwind_protect (unwind_with_echo_area_buffer,
8674 with_echo_area_buffer_unwind_data (w));
8676 /* Make the echo area buffer current. Note that for display
8677 purposes, it is not necessary that the displayed window's buffer
8678 == current_buffer, except for text property lookup. So, let's
8679 only set that buffer temporarily here without doing a full
8680 Fset_window_buffer. We must also change w->pointm, though,
8681 because otherwise an assertions in unshow_buffer fails, and Emacs
8682 aborts. */
8683 set_buffer_internal_1 (XBUFFER (buffer));
8684 if (w)
8686 w->buffer = buffer;
8687 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
8690 current_buffer->undo_list = Qt;
8691 current_buffer->read_only = Qnil;
8692 specbind (Qinhibit_read_only, Qt);
8693 specbind (Qinhibit_modification_hooks, Qt);
8695 if (clear_buffer_p && Z > BEG)
8696 del_range (BEG, Z);
8698 xassert (BEGV >= BEG);
8699 xassert (ZV <= Z && ZV >= BEGV);
8701 rc = fn (a1, a2, a3, a4);
8703 xassert (BEGV >= BEG);
8704 xassert (ZV <= Z && ZV >= BEGV);
8706 unbind_to (count, Qnil);
8707 return rc;
8711 /* Save state that should be preserved around the call to the function
8712 FN called in with_echo_area_buffer. */
8714 static Lisp_Object
8715 with_echo_area_buffer_unwind_data (struct window *w)
8717 int i = 0;
8718 Lisp_Object vector, tmp;
8720 /* Reduce consing by keeping one vector in
8721 Vwith_echo_area_save_vector. */
8722 vector = Vwith_echo_area_save_vector;
8723 Vwith_echo_area_save_vector = Qnil;
8725 if (NILP (vector))
8726 vector = Fmake_vector (make_number (7), Qnil);
8728 XSETBUFFER (tmp, current_buffer); ASET (vector, i, tmp); ++i;
8729 ASET (vector, i, Vdeactivate_mark); ++i;
8730 ASET (vector, i, make_number (windows_or_buffers_changed)); ++i;
8732 if (w)
8734 XSETWINDOW (tmp, w); ASET (vector, i, tmp); ++i;
8735 ASET (vector, i, w->buffer); ++i;
8736 ASET (vector, i, make_number (XMARKER (w->pointm)->charpos)); ++i;
8737 ASET (vector, i, make_number (XMARKER (w->pointm)->bytepos)); ++i;
8739 else
8741 int end = i + 4;
8742 for (; i < end; ++i)
8743 ASET (vector, i, Qnil);
8746 xassert (i == ASIZE (vector));
8747 return vector;
8751 /* Restore global state from VECTOR which was created by
8752 with_echo_area_buffer_unwind_data. */
8754 static Lisp_Object
8755 unwind_with_echo_area_buffer (Lisp_Object vector)
8757 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
8758 Vdeactivate_mark = AREF (vector, 1);
8759 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
8761 if (WINDOWP (AREF (vector, 3)))
8763 struct window *w;
8764 Lisp_Object buffer, charpos, bytepos;
8766 w = XWINDOW (AREF (vector, 3));
8767 buffer = AREF (vector, 4);
8768 charpos = AREF (vector, 5);
8769 bytepos = AREF (vector, 6);
8771 w->buffer = buffer;
8772 set_marker_both (w->pointm, buffer,
8773 XFASTINT (charpos), XFASTINT (bytepos));
8776 Vwith_echo_area_save_vector = vector;
8777 return Qnil;
8781 /* Set up the echo area for use by print functions. MULTIBYTE_P
8782 non-zero means we will print multibyte. */
8784 void
8785 setup_echo_area_for_printing (int multibyte_p)
8787 /* If we can't find an echo area any more, exit. */
8788 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
8789 Fkill_emacs (Qnil);
8791 ensure_echo_area_buffers ();
8793 if (!message_buf_print)
8795 /* A message has been output since the last time we printed.
8796 Choose a fresh echo area buffer. */
8797 if (EQ (echo_area_buffer[1], echo_buffer[0]))
8798 echo_area_buffer[0] = echo_buffer[1];
8799 else
8800 echo_area_buffer[0] = echo_buffer[0];
8802 /* Switch to that buffer and clear it. */
8803 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
8804 current_buffer->truncate_lines = Qnil;
8806 if (Z > BEG)
8808 int count = SPECPDL_INDEX ();
8809 specbind (Qinhibit_read_only, Qt);
8810 /* Note that undo recording is always disabled. */
8811 del_range (BEG, Z);
8812 unbind_to (count, Qnil);
8814 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
8816 /* Set up the buffer for the multibyteness we need. */
8817 if (multibyte_p
8818 != !NILP (current_buffer->enable_multibyte_characters))
8819 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
8821 /* Raise the frame containing the echo area. */
8822 if (minibuffer_auto_raise)
8824 struct frame *sf = SELECTED_FRAME ();
8825 Lisp_Object mini_window;
8826 mini_window = FRAME_MINIBUF_WINDOW (sf);
8827 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
8830 message_log_maybe_newline ();
8831 message_buf_print = 1;
8833 else
8835 if (NILP (echo_area_buffer[0]))
8837 if (EQ (echo_area_buffer[1], echo_buffer[0]))
8838 echo_area_buffer[0] = echo_buffer[1];
8839 else
8840 echo_area_buffer[0] = echo_buffer[0];
8843 if (current_buffer != XBUFFER (echo_area_buffer[0]))
8845 /* Someone switched buffers between print requests. */
8846 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
8847 current_buffer->truncate_lines = Qnil;
8853 /* Display an echo area message in window W. Value is non-zero if W's
8854 height is changed. If display_last_displayed_message_p is
8855 non-zero, display the message that was last displayed, otherwise
8856 display the current message. */
8858 static int
8859 display_echo_area (struct window *w)
8861 int i, no_message_p, window_height_changed_p, count;
8863 /* Temporarily disable garbage collections while displaying the echo
8864 area. This is done because a GC can print a message itself.
8865 That message would modify the echo area buffer's contents while a
8866 redisplay of the buffer is going on, and seriously confuse
8867 redisplay. */
8868 count = inhibit_garbage_collection ();
8870 /* If there is no message, we must call display_echo_area_1
8871 nevertheless because it resizes the window. But we will have to
8872 reset the echo_area_buffer in question to nil at the end because
8873 with_echo_area_buffer will sets it to an empty buffer. */
8874 i = display_last_displayed_message_p ? 1 : 0;
8875 no_message_p = NILP (echo_area_buffer[i]);
8877 window_height_changed_p
8878 = with_echo_area_buffer (w, display_last_displayed_message_p,
8879 display_echo_area_1,
8880 (EMACS_INT) w, Qnil, 0, 0);
8882 if (no_message_p)
8883 echo_area_buffer[i] = Qnil;
8885 unbind_to (count, Qnil);
8886 return window_height_changed_p;
8890 /* Helper for display_echo_area. Display the current buffer which
8891 contains the current echo area message in window W, a mini-window,
8892 a pointer to which is passed in A1. A2..A4 are currently not used.
8893 Change the height of W so that all of the message is displayed.
8894 Value is non-zero if height of W was changed. */
8896 static int
8897 display_echo_area_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4)
8899 struct window *w = (struct window *) a1;
8900 Lisp_Object window;
8901 struct text_pos start;
8902 int window_height_changed_p = 0;
8904 /* Do this before displaying, so that we have a large enough glyph
8905 matrix for the display. If we can't get enough space for the
8906 whole text, display the last N lines. That works by setting w->start. */
8907 window_height_changed_p = resize_mini_window (w, 0);
8909 /* Use the starting position chosen by resize_mini_window. */
8910 SET_TEXT_POS_FROM_MARKER (start, w->start);
8912 /* Display. */
8913 clear_glyph_matrix (w->desired_matrix);
8914 XSETWINDOW (window, w);
8915 try_window (window, start, 0);
8917 return window_height_changed_p;
8921 /* Resize the echo area window to exactly the size needed for the
8922 currently displayed message, if there is one. If a mini-buffer
8923 is active, don't shrink it. */
8925 void
8926 resize_echo_area_exactly (void)
8928 if (BUFFERP (echo_area_buffer[0])
8929 && WINDOWP (echo_area_window))
8931 struct window *w = XWINDOW (echo_area_window);
8932 int resized_p;
8933 Lisp_Object resize_exactly;
8935 if (minibuf_level == 0)
8936 resize_exactly = Qt;
8937 else
8938 resize_exactly = Qnil;
8940 resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
8941 (EMACS_INT) w, resize_exactly, 0, 0);
8942 if (resized_p)
8944 ++windows_or_buffers_changed;
8945 ++update_mode_lines;
8946 redisplay_internal (0);
8952 /* Callback function for with_echo_area_buffer, when used from
8953 resize_echo_area_exactly. A1 contains a pointer to the window to
8954 resize, EXACTLY non-nil means resize the mini-window exactly to the
8955 size of the text displayed. A3 and A4 are not used. Value is what
8956 resize_mini_window returns. */
8958 static int
8959 resize_mini_window_1 (EMACS_INT a1, Lisp_Object exactly, EMACS_INT a3, EMACS_INT a4)
8961 return resize_mini_window ((struct window *) a1, !NILP (exactly));
8965 /* Resize mini-window W to fit the size of its contents. EXACT_P
8966 means size the window exactly to the size needed. Otherwise, it's
8967 only enlarged until W's buffer is empty.
8969 Set W->start to the right place to begin display. If the whole
8970 contents fit, start at the beginning. Otherwise, start so as
8971 to make the end of the contents appear. This is particularly
8972 important for y-or-n-p, but seems desirable generally.
8974 Value is non-zero if the window height has been changed. */
8977 resize_mini_window (struct window *w, int exact_p)
8979 struct frame *f = XFRAME (w->frame);
8980 int window_height_changed_p = 0;
8982 xassert (MINI_WINDOW_P (w));
8984 /* By default, start display at the beginning. */
8985 set_marker_both (w->start, w->buffer,
8986 BUF_BEGV (XBUFFER (w->buffer)),
8987 BUF_BEGV_BYTE (XBUFFER (w->buffer)));
8989 /* Don't resize windows while redisplaying a window; it would
8990 confuse redisplay functions when the size of the window they are
8991 displaying changes from under them. Such a resizing can happen,
8992 for instance, when which-func prints a long message while
8993 we are running fontification-functions. We're running these
8994 functions with safe_call which binds inhibit-redisplay to t. */
8995 if (!NILP (Vinhibit_redisplay))
8996 return 0;
8998 /* Nil means don't try to resize. */
8999 if (NILP (Vresize_mini_windows)
9000 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
9001 return 0;
9003 if (!FRAME_MINIBUF_ONLY_P (f))
9005 struct it it;
9006 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
9007 int total_height = WINDOW_TOTAL_LINES (root) + WINDOW_TOTAL_LINES (w);
9008 int height, max_height;
9009 int unit = FRAME_LINE_HEIGHT (f);
9010 struct text_pos start;
9011 struct buffer *old_current_buffer = NULL;
9013 if (current_buffer != XBUFFER (w->buffer))
9015 old_current_buffer = current_buffer;
9016 set_buffer_internal (XBUFFER (w->buffer));
9019 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
9021 /* Compute the max. number of lines specified by the user. */
9022 if (FLOATP (Vmax_mini_window_height))
9023 max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_LINES (f);
9024 else if (INTEGERP (Vmax_mini_window_height))
9025 max_height = XINT (Vmax_mini_window_height);
9026 else
9027 max_height = total_height / 4;
9029 /* Correct that max. height if it's bogus. */
9030 max_height = max (1, max_height);
9031 max_height = min (total_height, max_height);
9033 /* Find out the height of the text in the window. */
9034 if (it.line_wrap == TRUNCATE)
9035 height = 1;
9036 else
9038 last_height = 0;
9039 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
9040 if (it.max_ascent == 0 && it.max_descent == 0)
9041 height = it.current_y + last_height;
9042 else
9043 height = it.current_y + it.max_ascent + it.max_descent;
9044 height -= min (it.extra_line_spacing, it.max_extra_line_spacing);
9045 height = (height + unit - 1) / unit;
9048 /* Compute a suitable window start. */
9049 if (height > max_height)
9051 height = max_height;
9052 init_iterator (&it, w, ZV, ZV_BYTE, NULL, DEFAULT_FACE_ID);
9053 move_it_vertically_backward (&it, (height - 1) * unit);
9054 start = it.current.pos;
9056 else
9057 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
9058 SET_MARKER_FROM_TEXT_POS (w->start, start);
9060 if (EQ (Vresize_mini_windows, Qgrow_only))
9062 /* Let it grow only, until we display an empty message, in which
9063 case the window shrinks again. */
9064 if (height > WINDOW_TOTAL_LINES (w))
9066 int old_height = WINDOW_TOTAL_LINES (w);
9067 freeze_window_starts (f, 1);
9068 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
9069 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
9071 else if (height < WINDOW_TOTAL_LINES (w)
9072 && (exact_p || BEGV == ZV))
9074 int old_height = WINDOW_TOTAL_LINES (w);
9075 freeze_window_starts (f, 0);
9076 shrink_mini_window (w);
9077 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
9080 else
9082 /* Always resize to exact size needed. */
9083 if (height > WINDOW_TOTAL_LINES (w))
9085 int old_height = WINDOW_TOTAL_LINES (w);
9086 freeze_window_starts (f, 1);
9087 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
9088 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
9090 else if (height < WINDOW_TOTAL_LINES (w))
9092 int old_height = WINDOW_TOTAL_LINES (w);
9093 freeze_window_starts (f, 0);
9094 shrink_mini_window (w);
9096 if (height)
9098 freeze_window_starts (f, 1);
9099 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
9102 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
9106 if (old_current_buffer)
9107 set_buffer_internal (old_current_buffer);
9110 return window_height_changed_p;
9114 /* Value is the current message, a string, or nil if there is no
9115 current message. */
9117 Lisp_Object
9118 current_message (void)
9120 Lisp_Object msg;
9122 if (!BUFFERP (echo_area_buffer[0]))
9123 msg = Qnil;
9124 else
9126 with_echo_area_buffer (0, 0, current_message_1,
9127 (EMACS_INT) &msg, Qnil, 0, 0);
9128 if (NILP (msg))
9129 echo_area_buffer[0] = Qnil;
9132 return msg;
9136 static int
9137 current_message_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4)
9139 Lisp_Object *msg = (Lisp_Object *) a1;
9141 if (Z > BEG)
9142 *msg = make_buffer_string (BEG, Z, 1);
9143 else
9144 *msg = Qnil;
9145 return 0;
9149 /* Push the current message on Vmessage_stack for later restauration
9150 by restore_message. Value is non-zero if the current message isn't
9151 empty. This is a relatively infrequent operation, so it's not
9152 worth optimizing. */
9155 push_message (void)
9157 Lisp_Object msg;
9158 msg = current_message ();
9159 Vmessage_stack = Fcons (msg, Vmessage_stack);
9160 return STRINGP (msg);
9164 /* Restore message display from the top of Vmessage_stack. */
9166 void
9167 restore_message (void)
9169 Lisp_Object msg;
9171 xassert (CONSP (Vmessage_stack));
9172 msg = XCAR (Vmessage_stack);
9173 if (STRINGP (msg))
9174 message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
9175 else
9176 message3_nolog (msg, 0, 0);
9180 /* Handler for record_unwind_protect calling pop_message. */
9182 Lisp_Object
9183 pop_message_unwind (Lisp_Object dummy)
9185 pop_message ();
9186 return Qnil;
9189 /* Pop the top-most entry off Vmessage_stack. */
9191 void
9192 pop_message (void)
9194 xassert (CONSP (Vmessage_stack));
9195 Vmessage_stack = XCDR (Vmessage_stack);
9199 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
9200 exits. If the stack is not empty, we have a missing pop_message
9201 somewhere. */
9203 void
9204 check_message_stack (void)
9206 if (!NILP (Vmessage_stack))
9207 abort ();
9211 /* Truncate to NCHARS what will be displayed in the echo area the next
9212 time we display it---but don't redisplay it now. */
9214 void
9215 truncate_echo_area (int nchars)
9217 if (nchars == 0)
9218 echo_area_buffer[0] = Qnil;
9219 /* A null message buffer means that the frame hasn't really been
9220 initialized yet. Error messages get reported properly by
9221 cmd_error, so this must be just an informative message; toss it. */
9222 else if (!noninteractive
9223 && INTERACTIVE
9224 && !NILP (echo_area_buffer[0]))
9226 struct frame *sf = SELECTED_FRAME ();
9227 if (FRAME_MESSAGE_BUF (sf))
9228 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil, 0, 0);
9233 /* Helper function for truncate_echo_area. Truncate the current
9234 message to at most NCHARS characters. */
9236 static int
9237 truncate_message_1 (EMACS_INT nchars, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4)
9239 if (BEG + nchars < Z)
9240 del_range (BEG + nchars, Z);
9241 if (Z == BEG)
9242 echo_area_buffer[0] = Qnil;
9243 return 0;
9247 /* Set the current message to a substring of S or STRING.
9249 If STRING is a Lisp string, set the message to the first NBYTES
9250 bytes from STRING. NBYTES zero means use the whole string. If
9251 STRING is multibyte, the message will be displayed multibyte.
9253 If S is not null, set the message to the first LEN bytes of S. LEN
9254 zero means use the whole string. MULTIBYTE_P non-zero means S is
9255 multibyte. Display the message multibyte in that case.
9257 Doesn't GC, as with_echo_area_buffer binds Qinhibit_modification_hooks
9258 to t before calling set_message_1 (which calls insert).
9261 void
9262 set_message (const char *s, Lisp_Object string, int nbytes, int multibyte_p)
9264 message_enable_multibyte
9265 = ((s && multibyte_p)
9266 || (STRINGP (string) && STRING_MULTIBYTE (string)));
9268 with_echo_area_buffer (0, -1, set_message_1,
9269 (EMACS_INT) s, string, nbytes, multibyte_p);
9270 message_buf_print = 0;
9271 help_echo_showing_p = 0;
9275 /* Helper function for set_message. Arguments have the same meaning
9276 as there, with A1 corresponding to S and A2 corresponding to STRING
9277 This function is called with the echo area buffer being
9278 current. */
9280 static int
9281 set_message_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT nbytes, EMACS_INT multibyte_p)
9283 const char *s = (const char *) a1;
9284 Lisp_Object string = a2;
9286 /* Change multibyteness of the echo buffer appropriately. */
9287 if (message_enable_multibyte
9288 != !NILP (current_buffer->enable_multibyte_characters))
9289 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
9291 current_buffer->truncate_lines = message_truncate_lines ? Qt : Qnil;
9293 /* Insert new message at BEG. */
9294 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
9296 if (STRINGP (string))
9298 int nchars;
9300 if (nbytes == 0)
9301 nbytes = SBYTES (string);
9302 nchars = string_byte_to_char (string, nbytes);
9304 /* This function takes care of single/multibyte conversion. We
9305 just have to ensure that the echo area buffer has the right
9306 setting of enable_multibyte_characters. */
9307 insert_from_string (string, 0, 0, nchars, nbytes, 1);
9309 else if (s)
9311 if (nbytes == 0)
9312 nbytes = strlen (s);
9314 if (multibyte_p && NILP (current_buffer->enable_multibyte_characters))
9316 /* Convert from multi-byte to single-byte. */
9317 int i, c, n;
9318 unsigned char work[1];
9320 /* Convert a multibyte string to single-byte. */
9321 for (i = 0; i < nbytes; i += n)
9323 c = string_char_and_length (s + i, &n);
9324 work[0] = (ASCII_CHAR_P (c)
9326 : multibyte_char_to_unibyte (c, Qnil));
9327 insert_1_both (work, 1, 1, 1, 0, 0);
9330 else if (!multibyte_p
9331 && !NILP (current_buffer->enable_multibyte_characters))
9333 /* Convert from single-byte to multi-byte. */
9334 int i, c, n;
9335 const unsigned char *msg = (const unsigned char *) s;
9336 unsigned char str[MAX_MULTIBYTE_LENGTH];
9338 /* Convert a single-byte string to multibyte. */
9339 for (i = 0; i < nbytes; i++)
9341 c = msg[i];
9342 MAKE_CHAR_MULTIBYTE (c);
9343 n = CHAR_STRING (c, str);
9344 insert_1_both (str, 1, n, 1, 0, 0);
9347 else
9348 insert_1 (s, nbytes, 1, 0, 0);
9351 return 0;
9355 /* Clear messages. CURRENT_P non-zero means clear the current
9356 message. LAST_DISPLAYED_P non-zero means clear the message
9357 last displayed. */
9359 void
9360 clear_message (int current_p, int last_displayed_p)
9362 if (current_p)
9364 echo_area_buffer[0] = Qnil;
9365 message_cleared_p = 1;
9368 if (last_displayed_p)
9369 echo_area_buffer[1] = Qnil;
9371 message_buf_print = 0;
9374 /* Clear garbaged frames.
9376 This function is used where the old redisplay called
9377 redraw_garbaged_frames which in turn called redraw_frame which in
9378 turn called clear_frame. The call to clear_frame was a source of
9379 flickering. I believe a clear_frame is not necessary. It should
9380 suffice in the new redisplay to invalidate all current matrices,
9381 and ensure a complete redisplay of all windows. */
9383 static void
9384 clear_garbaged_frames (void)
9386 if (frame_garbaged)
9388 Lisp_Object tail, frame;
9389 int changed_count = 0;
9391 FOR_EACH_FRAME (tail, frame)
9393 struct frame *f = XFRAME (frame);
9395 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
9397 if (f->resized_p)
9399 Fredraw_frame (frame);
9400 f->force_flush_display_p = 1;
9402 clear_current_matrices (f);
9403 changed_count++;
9404 f->garbaged = 0;
9405 f->resized_p = 0;
9409 frame_garbaged = 0;
9410 if (changed_count)
9411 ++windows_or_buffers_changed;
9416 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
9417 is non-zero update selected_frame. Value is non-zero if the
9418 mini-windows height has been changed. */
9420 static int
9421 echo_area_display (int update_frame_p)
9423 Lisp_Object mini_window;
9424 struct window *w;
9425 struct frame *f;
9426 int window_height_changed_p = 0;
9427 struct frame *sf = SELECTED_FRAME ();
9429 mini_window = FRAME_MINIBUF_WINDOW (sf);
9430 w = XWINDOW (mini_window);
9431 f = XFRAME (WINDOW_FRAME (w));
9433 /* Don't display if frame is invisible or not yet initialized. */
9434 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
9435 return 0;
9437 #ifdef HAVE_WINDOW_SYSTEM
9438 /* When Emacs starts, selected_frame may be the initial terminal
9439 frame. If we let this through, a message would be displayed on
9440 the terminal. */
9441 if (FRAME_INITIAL_P (XFRAME (selected_frame)))
9442 return 0;
9443 #endif /* HAVE_WINDOW_SYSTEM */
9445 /* Redraw garbaged frames. */
9446 if (frame_garbaged)
9447 clear_garbaged_frames ();
9449 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
9451 echo_area_window = mini_window;
9452 window_height_changed_p = display_echo_area (w);
9453 w->must_be_updated_p = 1;
9455 /* Update the display, unless called from redisplay_internal.
9456 Also don't update the screen during redisplay itself. The
9457 update will happen at the end of redisplay, and an update
9458 here could cause confusion. */
9459 if (update_frame_p && !redisplaying_p)
9461 int n = 0;
9463 /* If the display update has been interrupted by pending
9464 input, update mode lines in the frame. Due to the
9465 pending input, it might have been that redisplay hasn't
9466 been called, so that mode lines above the echo area are
9467 garbaged. This looks odd, so we prevent it here. */
9468 if (!display_completed)
9469 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), 0);
9471 if (window_height_changed_p
9472 /* Don't do this if Emacs is shutting down. Redisplay
9473 needs to run hooks. */
9474 && !NILP (Vrun_hooks))
9476 /* Must update other windows. Likewise as in other
9477 cases, don't let this update be interrupted by
9478 pending input. */
9479 int count = SPECPDL_INDEX ();
9480 specbind (Qredisplay_dont_pause, Qt);
9481 windows_or_buffers_changed = 1;
9482 redisplay_internal (0);
9483 unbind_to (count, Qnil);
9485 else if (FRAME_WINDOW_P (f) && n == 0)
9487 /* Window configuration is the same as before.
9488 Can do with a display update of the echo area,
9489 unless we displayed some mode lines. */
9490 update_single_window (w, 1);
9491 FRAME_RIF (f)->flush_display (f);
9493 else
9494 update_frame (f, 1, 1);
9496 /* If cursor is in the echo area, make sure that the next
9497 redisplay displays the minibuffer, so that the cursor will
9498 be replaced with what the minibuffer wants. */
9499 if (cursor_in_echo_area)
9500 ++windows_or_buffers_changed;
9503 else if (!EQ (mini_window, selected_window))
9504 windows_or_buffers_changed++;
9506 /* Last displayed message is now the current message. */
9507 echo_area_buffer[1] = echo_area_buffer[0];
9508 /* Inform read_char that we're not echoing. */
9509 echo_message_buffer = Qnil;
9511 /* Prevent redisplay optimization in redisplay_internal by resetting
9512 this_line_start_pos. This is done because the mini-buffer now
9513 displays the message instead of its buffer text. */
9514 if (EQ (mini_window, selected_window))
9515 CHARPOS (this_line_start_pos) = 0;
9517 return window_height_changed_p;
9522 /***********************************************************************
9523 Mode Lines and Frame Titles
9524 ***********************************************************************/
9526 /* A buffer for constructing non-propertized mode-line strings and
9527 frame titles in it; allocated from the heap in init_xdisp and
9528 resized as needed in store_mode_line_noprop_char. */
9530 static char *mode_line_noprop_buf;
9532 /* The buffer's end, and a current output position in it. */
9534 static char *mode_line_noprop_buf_end;
9535 static char *mode_line_noprop_ptr;
9537 #define MODE_LINE_NOPROP_LEN(start) \
9538 ((mode_line_noprop_ptr - mode_line_noprop_buf) - start)
9540 static enum {
9541 MODE_LINE_DISPLAY = 0,
9542 MODE_LINE_TITLE,
9543 MODE_LINE_NOPROP,
9544 MODE_LINE_STRING
9545 } mode_line_target;
9547 /* Alist that caches the results of :propertize.
9548 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
9549 static Lisp_Object mode_line_proptrans_alist;
9551 /* List of strings making up the mode-line. */
9552 static Lisp_Object mode_line_string_list;
9554 /* Base face property when building propertized mode line string. */
9555 static Lisp_Object mode_line_string_face;
9556 static Lisp_Object mode_line_string_face_prop;
9559 /* Unwind data for mode line strings */
9561 static Lisp_Object Vmode_line_unwind_vector;
9563 static Lisp_Object
9564 format_mode_line_unwind_data (struct buffer *obuf,
9565 Lisp_Object owin,
9566 int save_proptrans)
9568 Lisp_Object vector, tmp;
9570 /* Reduce consing by keeping one vector in
9571 Vwith_echo_area_save_vector. */
9572 vector = Vmode_line_unwind_vector;
9573 Vmode_line_unwind_vector = Qnil;
9575 if (NILP (vector))
9576 vector = Fmake_vector (make_number (8), Qnil);
9578 ASET (vector, 0, make_number (mode_line_target));
9579 ASET (vector, 1, make_number (MODE_LINE_NOPROP_LEN (0)));
9580 ASET (vector, 2, mode_line_string_list);
9581 ASET (vector, 3, save_proptrans ? mode_line_proptrans_alist : Qt);
9582 ASET (vector, 4, mode_line_string_face);
9583 ASET (vector, 5, mode_line_string_face_prop);
9585 if (obuf)
9586 XSETBUFFER (tmp, obuf);
9587 else
9588 tmp = Qnil;
9589 ASET (vector, 6, tmp);
9590 ASET (vector, 7, owin);
9592 return vector;
9595 static Lisp_Object
9596 unwind_format_mode_line (Lisp_Object vector)
9598 mode_line_target = XINT (AREF (vector, 0));
9599 mode_line_noprop_ptr = mode_line_noprop_buf + XINT (AREF (vector, 1));
9600 mode_line_string_list = AREF (vector, 2);
9601 if (! EQ (AREF (vector, 3), Qt))
9602 mode_line_proptrans_alist = AREF (vector, 3);
9603 mode_line_string_face = AREF (vector, 4);
9604 mode_line_string_face_prop = AREF (vector, 5);
9606 if (!NILP (AREF (vector, 7)))
9607 /* Select window before buffer, since it may change the buffer. */
9608 Fselect_window (AREF (vector, 7), Qt);
9610 if (!NILP (AREF (vector, 6)))
9612 set_buffer_internal_1 (XBUFFER (AREF (vector, 6)));
9613 ASET (vector, 6, Qnil);
9616 Vmode_line_unwind_vector = vector;
9617 return Qnil;
9621 /* Store a single character C for the frame title in mode_line_noprop_buf.
9622 Re-allocate mode_line_noprop_buf if necessary. */
9624 static void
9625 store_mode_line_noprop_char (char c)
9627 /* If output position has reached the end of the allocated buffer,
9628 double the buffer's size. */
9629 if (mode_line_noprop_ptr == mode_line_noprop_buf_end)
9631 int len = MODE_LINE_NOPROP_LEN (0);
9632 int new_size = 2 * len * sizeof *mode_line_noprop_buf;
9633 mode_line_noprop_buf = (char *) xrealloc (mode_line_noprop_buf, new_size);
9634 mode_line_noprop_buf_end = mode_line_noprop_buf + new_size;
9635 mode_line_noprop_ptr = mode_line_noprop_buf + len;
9638 *mode_line_noprop_ptr++ = c;
9642 /* Store part of a frame title in mode_line_noprop_buf, beginning at
9643 mode_line_noprop_ptr. STR is the string to store. Do not copy
9644 characters that yield more columns than PRECISION; PRECISION <= 0
9645 means copy the whole string. Pad with spaces until FIELD_WIDTH
9646 number of characters have been copied; FIELD_WIDTH <= 0 means don't
9647 pad. Called from display_mode_element when it is used to build a
9648 frame title. */
9650 static int
9651 store_mode_line_noprop (const unsigned char *str, int field_width, int precision)
9653 int n = 0;
9654 int dummy, nbytes;
9656 /* Copy at most PRECISION chars from STR. */
9657 nbytes = strlen (str);
9658 n += c_string_width (str, nbytes, precision, &dummy, &nbytes);
9659 while (nbytes--)
9660 store_mode_line_noprop_char (*str++);
9662 /* Fill up with spaces until FIELD_WIDTH reached. */
9663 while (field_width > 0
9664 && n < field_width)
9666 store_mode_line_noprop_char (' ');
9667 ++n;
9670 return n;
9673 /***********************************************************************
9674 Frame Titles
9675 ***********************************************************************/
9677 #ifdef HAVE_WINDOW_SYSTEM
9679 /* Set the title of FRAME, if it has changed. The title format is
9680 Vicon_title_format if FRAME is iconified, otherwise it is
9681 frame_title_format. */
9683 static void
9684 x_consider_frame_title (Lisp_Object frame)
9686 struct frame *f = XFRAME (frame);
9688 if (FRAME_WINDOW_P (f)
9689 || FRAME_MINIBUF_ONLY_P (f)
9690 || f->explicit_name)
9692 /* Do we have more than one visible frame on this X display? */
9693 Lisp_Object tail;
9694 Lisp_Object fmt;
9695 int title_start;
9696 char *title;
9697 int len;
9698 struct it it;
9699 int count = SPECPDL_INDEX ();
9701 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
9703 Lisp_Object other_frame = XCAR (tail);
9704 struct frame *tf = XFRAME (other_frame);
9706 if (tf != f
9707 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
9708 && !FRAME_MINIBUF_ONLY_P (tf)
9709 && !EQ (other_frame, tip_frame)
9710 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
9711 break;
9714 /* Set global variable indicating that multiple frames exist. */
9715 multiple_frames = CONSP (tail);
9717 /* Switch to the buffer of selected window of the frame. Set up
9718 mode_line_target so that display_mode_element will output into
9719 mode_line_noprop_buf; then display the title. */
9720 record_unwind_protect (unwind_format_mode_line,
9721 format_mode_line_unwind_data
9722 (current_buffer, selected_window, 0));
9724 Fselect_window (f->selected_window, Qt);
9725 set_buffer_internal_1 (XBUFFER (XWINDOW (f->selected_window)->buffer));
9726 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
9728 mode_line_target = MODE_LINE_TITLE;
9729 title_start = MODE_LINE_NOPROP_LEN (0);
9730 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
9731 NULL, DEFAULT_FACE_ID);
9732 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
9733 len = MODE_LINE_NOPROP_LEN (title_start);
9734 title = mode_line_noprop_buf + title_start;
9735 unbind_to (count, Qnil);
9737 /* Set the title only if it's changed. This avoids consing in
9738 the common case where it hasn't. (If it turns out that we've
9739 already wasted too much time by walking through the list with
9740 display_mode_element, then we might need to optimize at a
9741 higher level than this.) */
9742 if (! STRINGP (f->name)
9743 || SBYTES (f->name) != len
9744 || memcmp (title, SDATA (f->name), len) != 0)
9745 x_implicitly_set_name (f, make_string (title, len), Qnil);
9749 #endif /* not HAVE_WINDOW_SYSTEM */
9754 /***********************************************************************
9755 Menu Bars
9756 ***********************************************************************/
9759 /* Prepare for redisplay by updating menu-bar item lists when
9760 appropriate. This can call eval. */
9762 void
9763 prepare_menu_bars (void)
9765 int all_windows;
9766 struct gcpro gcpro1, gcpro2;
9767 struct frame *f;
9768 Lisp_Object tooltip_frame;
9770 #ifdef HAVE_WINDOW_SYSTEM
9771 tooltip_frame = tip_frame;
9772 #else
9773 tooltip_frame = Qnil;
9774 #endif
9776 /* Update all frame titles based on their buffer names, etc. We do
9777 this before the menu bars so that the buffer-menu will show the
9778 up-to-date frame titles. */
9779 #ifdef HAVE_WINDOW_SYSTEM
9780 if (windows_or_buffers_changed || update_mode_lines)
9782 Lisp_Object tail, frame;
9784 FOR_EACH_FRAME (tail, frame)
9786 f = XFRAME (frame);
9787 if (!EQ (frame, tooltip_frame)
9788 && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)))
9789 x_consider_frame_title (frame);
9792 #endif /* HAVE_WINDOW_SYSTEM */
9794 /* Update the menu bar item lists, if appropriate. This has to be
9795 done before any actual redisplay or generation of display lines. */
9796 all_windows = (update_mode_lines
9797 || buffer_shared > 1
9798 || windows_or_buffers_changed);
9799 if (all_windows)
9801 Lisp_Object tail, frame;
9802 int count = SPECPDL_INDEX ();
9803 /* 1 means that update_menu_bar has run its hooks
9804 so any further calls to update_menu_bar shouldn't do so again. */
9805 int menu_bar_hooks_run = 0;
9807 record_unwind_save_match_data ();
9809 FOR_EACH_FRAME (tail, frame)
9811 f = XFRAME (frame);
9813 /* Ignore tooltip frame. */
9814 if (EQ (frame, tooltip_frame))
9815 continue;
9817 /* If a window on this frame changed size, report that to
9818 the user and clear the size-change flag. */
9819 if (FRAME_WINDOW_SIZES_CHANGED (f))
9821 Lisp_Object functions;
9823 /* Clear flag first in case we get an error below. */
9824 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
9825 functions = Vwindow_size_change_functions;
9826 GCPRO2 (tail, functions);
9828 while (CONSP (functions))
9830 if (!EQ (XCAR (functions), Qt))
9831 call1 (XCAR (functions), frame);
9832 functions = XCDR (functions);
9834 UNGCPRO;
9837 GCPRO1 (tail);
9838 menu_bar_hooks_run = update_menu_bar (f, 0, menu_bar_hooks_run);
9839 #ifdef HAVE_WINDOW_SYSTEM
9840 update_tool_bar (f, 0);
9841 #endif
9842 #ifdef HAVE_NS
9843 if (windows_or_buffers_changed
9844 && FRAME_NS_P (f))
9845 ns_set_doc_edited (f, Fbuffer_modified_p
9846 (XWINDOW (f->selected_window)->buffer));
9847 #endif
9848 UNGCPRO;
9851 unbind_to (count, Qnil);
9853 else
9855 struct frame *sf = SELECTED_FRAME ();
9856 update_menu_bar (sf, 1, 0);
9857 #ifdef HAVE_WINDOW_SYSTEM
9858 update_tool_bar (sf, 1);
9859 #endif
9864 /* Update the menu bar item list for frame F. This has to be done
9865 before we start to fill in any display lines, because it can call
9866 eval.
9868 If SAVE_MATCH_DATA is non-zero, we must save and restore it here.
9870 If HOOKS_RUN is 1, that means a previous call to update_menu_bar
9871 already ran the menu bar hooks for this redisplay, so there
9872 is no need to run them again. The return value is the
9873 updated value of this flag, to pass to the next call. */
9875 static int
9876 update_menu_bar (struct frame *f, int save_match_data, int hooks_run)
9878 Lisp_Object window;
9879 register struct window *w;
9881 /* If called recursively during a menu update, do nothing. This can
9882 happen when, for instance, an activate-menubar-hook causes a
9883 redisplay. */
9884 if (inhibit_menubar_update)
9885 return hooks_run;
9887 window = FRAME_SELECTED_WINDOW (f);
9888 w = XWINDOW (window);
9890 if (FRAME_WINDOW_P (f)
9892 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
9893 || defined (HAVE_NS) || defined (USE_GTK)
9894 FRAME_EXTERNAL_MENU_BAR (f)
9895 #else
9896 FRAME_MENU_BAR_LINES (f) > 0
9897 #endif
9898 : FRAME_MENU_BAR_LINES (f) > 0)
9900 /* If the user has switched buffers or windows, we need to
9901 recompute to reflect the new bindings. But we'll
9902 recompute when update_mode_lines is set too; that means
9903 that people can use force-mode-line-update to request
9904 that the menu bar be recomputed. The adverse effect on
9905 the rest of the redisplay algorithm is about the same as
9906 windows_or_buffers_changed anyway. */
9907 if (windows_or_buffers_changed
9908 /* This used to test w->update_mode_line, but we believe
9909 there is no need to recompute the menu in that case. */
9910 || update_mode_lines
9911 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
9912 < BUF_MODIFF (XBUFFER (w->buffer)))
9913 != !NILP (w->last_had_star))
9914 || ((!NILP (Vtransient_mark_mode)
9915 && !NILP (XBUFFER (w->buffer)->mark_active))
9916 != !NILP (w->region_showing)))
9918 struct buffer *prev = current_buffer;
9919 int count = SPECPDL_INDEX ();
9921 specbind (Qinhibit_menubar_update, Qt);
9923 set_buffer_internal_1 (XBUFFER (w->buffer));
9924 if (save_match_data)
9925 record_unwind_save_match_data ();
9926 if (NILP (Voverriding_local_map_menu_flag))
9928 specbind (Qoverriding_terminal_local_map, Qnil);
9929 specbind (Qoverriding_local_map, Qnil);
9932 if (!hooks_run)
9934 /* Run the Lucid hook. */
9935 safe_run_hooks (Qactivate_menubar_hook);
9937 /* If it has changed current-menubar from previous value,
9938 really recompute the menu-bar from the value. */
9939 if (! NILP (Vlucid_menu_bar_dirty_flag))
9940 call0 (Qrecompute_lucid_menubar);
9942 safe_run_hooks (Qmenu_bar_update_hook);
9944 hooks_run = 1;
9947 XSETFRAME (Vmenu_updating_frame, f);
9948 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
9950 /* Redisplay the menu bar in case we changed it. */
9951 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
9952 || defined (HAVE_NS) || defined (USE_GTK)
9953 if (FRAME_WINDOW_P (f))
9955 #if defined (HAVE_NS)
9956 /* All frames on Mac OS share the same menubar. So only
9957 the selected frame should be allowed to set it. */
9958 if (f == SELECTED_FRAME ())
9959 #endif
9960 set_frame_menubar (f, 0, 0);
9962 else
9963 /* On a terminal screen, the menu bar is an ordinary screen
9964 line, and this makes it get updated. */
9965 w->update_mode_line = Qt;
9966 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
9967 /* In the non-toolkit version, the menu bar is an ordinary screen
9968 line, and this makes it get updated. */
9969 w->update_mode_line = Qt;
9970 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
9972 unbind_to (count, Qnil);
9973 set_buffer_internal_1 (prev);
9977 return hooks_run;
9982 /***********************************************************************
9983 Output Cursor
9984 ***********************************************************************/
9986 #ifdef HAVE_WINDOW_SYSTEM
9988 /* EXPORT:
9989 Nominal cursor position -- where to draw output.
9990 HPOS and VPOS are window relative glyph matrix coordinates.
9991 X and Y are window relative pixel coordinates. */
9993 struct cursor_pos output_cursor;
9996 /* EXPORT:
9997 Set the global variable output_cursor to CURSOR. All cursor
9998 positions are relative to updated_window. */
10000 void
10001 set_output_cursor (struct cursor_pos *cursor)
10003 output_cursor.hpos = cursor->hpos;
10004 output_cursor.vpos = cursor->vpos;
10005 output_cursor.x = cursor->x;
10006 output_cursor.y = cursor->y;
10010 /* EXPORT for RIF:
10011 Set a nominal cursor position.
10013 HPOS and VPOS are column/row positions in a window glyph matrix. X
10014 and Y are window text area relative pixel positions.
10016 If this is done during an update, updated_window will contain the
10017 window that is being updated and the position is the future output
10018 cursor position for that window. If updated_window is null, use
10019 selected_window and display the cursor at the given position. */
10021 void
10022 x_cursor_to (int vpos, int hpos, int y, int x)
10024 struct window *w;
10026 /* If updated_window is not set, work on selected_window. */
10027 if (updated_window)
10028 w = updated_window;
10029 else
10030 w = XWINDOW (selected_window);
10032 /* Set the output cursor. */
10033 output_cursor.hpos = hpos;
10034 output_cursor.vpos = vpos;
10035 output_cursor.x = x;
10036 output_cursor.y = y;
10038 /* If not called as part of an update, really display the cursor.
10039 This will also set the cursor position of W. */
10040 if (updated_window == NULL)
10042 BLOCK_INPUT;
10043 display_and_set_cursor (w, 1, hpos, vpos, x, y);
10044 if (FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
10045 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (SELECTED_FRAME ());
10046 UNBLOCK_INPUT;
10050 #endif /* HAVE_WINDOW_SYSTEM */
10053 /***********************************************************************
10054 Tool-bars
10055 ***********************************************************************/
10057 #ifdef HAVE_WINDOW_SYSTEM
10059 /* Where the mouse was last time we reported a mouse event. */
10061 FRAME_PTR last_mouse_frame;
10063 /* Tool-bar item index of the item on which a mouse button was pressed
10064 or -1. */
10066 int last_tool_bar_item;
10069 static Lisp_Object
10070 update_tool_bar_unwind (Lisp_Object frame)
10072 selected_frame = frame;
10073 return Qnil;
10076 /* Update the tool-bar item list for frame F. This has to be done
10077 before we start to fill in any display lines. Called from
10078 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
10079 and restore it here. */
10081 static void
10082 update_tool_bar (struct frame *f, int save_match_data)
10084 #if defined (USE_GTK) || defined (HAVE_NS)
10085 int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
10086 #else
10087 int do_update = WINDOWP (f->tool_bar_window)
10088 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0;
10089 #endif
10091 if (do_update)
10093 Lisp_Object window;
10094 struct window *w;
10096 window = FRAME_SELECTED_WINDOW (f);
10097 w = XWINDOW (window);
10099 /* If the user has switched buffers or windows, we need to
10100 recompute to reflect the new bindings. But we'll
10101 recompute when update_mode_lines is set too; that means
10102 that people can use force-mode-line-update to request
10103 that the menu bar be recomputed. The adverse effect on
10104 the rest of the redisplay algorithm is about the same as
10105 windows_or_buffers_changed anyway. */
10106 if (windows_or_buffers_changed
10107 || !NILP (w->update_mode_line)
10108 || update_mode_lines
10109 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
10110 < BUF_MODIFF (XBUFFER (w->buffer)))
10111 != !NILP (w->last_had_star))
10112 || ((!NILP (Vtransient_mark_mode)
10113 && !NILP (XBUFFER (w->buffer)->mark_active))
10114 != !NILP (w->region_showing)))
10116 struct buffer *prev = current_buffer;
10117 int count = SPECPDL_INDEX ();
10118 Lisp_Object frame, new_tool_bar;
10119 int new_n_tool_bar;
10120 struct gcpro gcpro1;
10122 /* Set current_buffer to the buffer of the selected
10123 window of the frame, so that we get the right local
10124 keymaps. */
10125 set_buffer_internal_1 (XBUFFER (w->buffer));
10127 /* Save match data, if we must. */
10128 if (save_match_data)
10129 record_unwind_save_match_data ();
10131 /* Make sure that we don't accidentally use bogus keymaps. */
10132 if (NILP (Voverriding_local_map_menu_flag))
10134 specbind (Qoverriding_terminal_local_map, Qnil);
10135 specbind (Qoverriding_local_map, Qnil);
10138 GCPRO1 (new_tool_bar);
10140 /* We must temporarily set the selected frame to this frame
10141 before calling tool_bar_items, because the calculation of
10142 the tool-bar keymap uses the selected frame (see
10143 `tool-bar-make-keymap' in tool-bar.el). */
10144 record_unwind_protect (update_tool_bar_unwind, selected_frame);
10145 XSETFRAME (frame, f);
10146 selected_frame = frame;
10148 /* Build desired tool-bar items from keymaps. */
10149 new_tool_bar = tool_bar_items (Fcopy_sequence (f->tool_bar_items),
10150 &new_n_tool_bar);
10152 /* Redisplay the tool-bar if we changed it. */
10153 if (new_n_tool_bar != f->n_tool_bar_items
10154 || NILP (Fequal (new_tool_bar, f->tool_bar_items)))
10156 /* Redisplay that happens asynchronously due to an expose event
10157 may access f->tool_bar_items. Make sure we update both
10158 variables within BLOCK_INPUT so no such event interrupts. */
10159 BLOCK_INPUT;
10160 f->tool_bar_items = new_tool_bar;
10161 f->n_tool_bar_items = new_n_tool_bar;
10162 w->update_mode_line = Qt;
10163 UNBLOCK_INPUT;
10166 UNGCPRO;
10168 unbind_to (count, Qnil);
10169 set_buffer_internal_1 (prev);
10175 /* Set F->desired_tool_bar_string to a Lisp string representing frame
10176 F's desired tool-bar contents. F->tool_bar_items must have
10177 been set up previously by calling prepare_menu_bars. */
10179 static void
10180 build_desired_tool_bar_string (struct frame *f)
10182 int i, size, size_needed;
10183 struct gcpro gcpro1, gcpro2, gcpro3;
10184 Lisp_Object image, plist, props;
10186 image = plist = props = Qnil;
10187 GCPRO3 (image, plist, props);
10189 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
10190 Otherwise, make a new string. */
10192 /* The size of the string we might be able to reuse. */
10193 size = (STRINGP (f->desired_tool_bar_string)
10194 ? SCHARS (f->desired_tool_bar_string)
10195 : 0);
10197 /* We need one space in the string for each image. */
10198 size_needed = f->n_tool_bar_items;
10200 /* Reuse f->desired_tool_bar_string, if possible. */
10201 if (size < size_needed || NILP (f->desired_tool_bar_string))
10202 f->desired_tool_bar_string = Fmake_string (make_number (size_needed),
10203 make_number (' '));
10204 else
10206 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
10207 Fremove_text_properties (make_number (0), make_number (size),
10208 props, f->desired_tool_bar_string);
10211 /* Put a `display' property on the string for the images to display,
10212 put a `menu_item' property on tool-bar items with a value that
10213 is the index of the item in F's tool-bar item vector. */
10214 for (i = 0; i < f->n_tool_bar_items; ++i)
10216 #define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
10218 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
10219 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
10220 int hmargin, vmargin, relief, idx, end;
10222 /* If image is a vector, choose the image according to the
10223 button state. */
10224 image = PROP (TOOL_BAR_ITEM_IMAGES);
10225 if (VECTORP (image))
10227 if (enabled_p)
10228 idx = (selected_p
10229 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
10230 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
10231 else
10232 idx = (selected_p
10233 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
10234 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
10236 xassert (ASIZE (image) >= idx);
10237 image = AREF (image, idx);
10239 else
10240 idx = -1;
10242 /* Ignore invalid image specifications. */
10243 if (!valid_image_p (image))
10244 continue;
10246 /* Display the tool-bar button pressed, or depressed. */
10247 plist = Fcopy_sequence (XCDR (image));
10249 /* Compute margin and relief to draw. */
10250 relief = (tool_bar_button_relief >= 0
10251 ? tool_bar_button_relief
10252 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
10253 hmargin = vmargin = relief;
10255 if (INTEGERP (Vtool_bar_button_margin)
10256 && XINT (Vtool_bar_button_margin) > 0)
10258 hmargin += XFASTINT (Vtool_bar_button_margin);
10259 vmargin += XFASTINT (Vtool_bar_button_margin);
10261 else if (CONSP (Vtool_bar_button_margin))
10263 if (INTEGERP (XCAR (Vtool_bar_button_margin))
10264 && XINT (XCAR (Vtool_bar_button_margin)) > 0)
10265 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
10267 if (INTEGERP (XCDR (Vtool_bar_button_margin))
10268 && XINT (XCDR (Vtool_bar_button_margin)) > 0)
10269 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
10272 if (auto_raise_tool_bar_buttons_p)
10274 /* Add a `:relief' property to the image spec if the item is
10275 selected. */
10276 if (selected_p)
10278 plist = Fplist_put (plist, QCrelief, make_number (-relief));
10279 hmargin -= relief;
10280 vmargin -= relief;
10283 else
10285 /* If image is selected, display it pressed, i.e. with a
10286 negative relief. If it's not selected, display it with a
10287 raised relief. */
10288 plist = Fplist_put (plist, QCrelief,
10289 (selected_p
10290 ? make_number (-relief)
10291 : make_number (relief)));
10292 hmargin -= relief;
10293 vmargin -= relief;
10296 /* Put a margin around the image. */
10297 if (hmargin || vmargin)
10299 if (hmargin == vmargin)
10300 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
10301 else
10302 plist = Fplist_put (plist, QCmargin,
10303 Fcons (make_number (hmargin),
10304 make_number (vmargin)));
10307 /* If button is not enabled, and we don't have special images
10308 for the disabled state, make the image appear disabled by
10309 applying an appropriate algorithm to it. */
10310 if (!enabled_p && idx < 0)
10311 plist = Fplist_put (plist, QCconversion, Qdisabled);
10313 /* Put a `display' text property on the string for the image to
10314 display. Put a `menu-item' property on the string that gives
10315 the start of this item's properties in the tool-bar items
10316 vector. */
10317 image = Fcons (Qimage, plist);
10318 props = list4 (Qdisplay, image,
10319 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS));
10321 /* Let the last image hide all remaining spaces in the tool bar
10322 string. The string can be longer than needed when we reuse a
10323 previous string. */
10324 if (i + 1 == f->n_tool_bar_items)
10325 end = SCHARS (f->desired_tool_bar_string);
10326 else
10327 end = i + 1;
10328 Fadd_text_properties (make_number (i), make_number (end),
10329 props, f->desired_tool_bar_string);
10330 #undef PROP
10333 UNGCPRO;
10337 /* Display one line of the tool-bar of frame IT->f.
10339 HEIGHT specifies the desired height of the tool-bar line.
10340 If the actual height of the glyph row is less than HEIGHT, the
10341 row's height is increased to HEIGHT, and the icons are centered
10342 vertically in the new height.
10344 If HEIGHT is -1, we are counting needed tool-bar lines, so don't
10345 count a final empty row in case the tool-bar width exactly matches
10346 the window width.
10349 static void
10350 display_tool_bar_line (struct it *it, int height)
10352 struct glyph_row *row = it->glyph_row;
10353 int max_x = it->last_visible_x;
10354 struct glyph *last;
10356 prepare_desired_row (row);
10357 row->y = it->current_y;
10359 /* Note that this isn't made use of if the face hasn't a box,
10360 so there's no need to check the face here. */
10361 it->start_of_box_run_p = 1;
10363 while (it->current_x < max_x)
10365 int x, n_glyphs_before, i, nglyphs;
10366 struct it it_before;
10368 /* Get the next display element. */
10369 if (!get_next_display_element (it))
10371 /* Don't count empty row if we are counting needed tool-bar lines. */
10372 if (height < 0 && !it->hpos)
10373 return;
10374 break;
10377 /* Produce glyphs. */
10378 n_glyphs_before = row->used[TEXT_AREA];
10379 it_before = *it;
10381 PRODUCE_GLYPHS (it);
10383 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
10384 i = 0;
10385 x = it_before.current_x;
10386 while (i < nglyphs)
10388 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
10390 if (x + glyph->pixel_width > max_x)
10392 /* Glyph doesn't fit on line. Backtrack. */
10393 row->used[TEXT_AREA] = n_glyphs_before;
10394 *it = it_before;
10395 /* If this is the only glyph on this line, it will never fit on the
10396 toolbar, so skip it. But ensure there is at least one glyph,
10397 so we don't accidentally disable the tool-bar. */
10398 if (n_glyphs_before == 0
10399 && (it->vpos > 0 || IT_STRING_CHARPOS (*it) < it->end_charpos-1))
10400 break;
10401 goto out;
10404 ++it->hpos;
10405 x += glyph->pixel_width;
10406 ++i;
10409 /* Stop at line ends. */
10410 if (ITERATOR_AT_END_OF_LINE_P (it))
10411 break;
10413 set_iterator_to_next (it, 1);
10416 out:;
10418 row->displays_text_p = row->used[TEXT_AREA] != 0;
10420 /* Use default face for the border below the tool bar.
10422 FIXME: When auto-resize-tool-bars is grow-only, there is
10423 no additional border below the possibly empty tool-bar lines.
10424 So to make the extra empty lines look "normal", we have to
10425 use the tool-bar face for the border too. */
10426 if (!row->displays_text_p && !EQ (Vauto_resize_tool_bars, Qgrow_only))
10427 it->face_id = DEFAULT_FACE_ID;
10429 extend_face_to_end_of_line (it);
10430 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
10431 last->right_box_line_p = 1;
10432 if (last == row->glyphs[TEXT_AREA])
10433 last->left_box_line_p = 1;
10435 /* Make line the desired height and center it vertically. */
10436 if ((height -= it->max_ascent + it->max_descent) > 0)
10438 /* Don't add more than one line height. */
10439 height %= FRAME_LINE_HEIGHT (it->f);
10440 it->max_ascent += height / 2;
10441 it->max_descent += (height + 1) / 2;
10444 compute_line_metrics (it);
10446 /* If line is empty, make it occupy the rest of the tool-bar. */
10447 if (!row->displays_text_p)
10449 row->height = row->phys_height = it->last_visible_y - row->y;
10450 row->visible_height = row->height;
10451 row->ascent = row->phys_ascent = 0;
10452 row->extra_line_spacing = 0;
10455 row->full_width_p = 1;
10456 row->continued_p = 0;
10457 row->truncated_on_left_p = 0;
10458 row->truncated_on_right_p = 0;
10460 it->current_x = it->hpos = 0;
10461 it->current_y += row->height;
10462 ++it->vpos;
10463 ++it->glyph_row;
10467 /* Max tool-bar height. */
10469 #define MAX_FRAME_TOOL_BAR_HEIGHT(f) \
10470 ((FRAME_LINE_HEIGHT (f) * FRAME_LINES (f)))
10472 /* Value is the number of screen lines needed to make all tool-bar
10473 items of frame F visible. The number of actual rows needed is
10474 returned in *N_ROWS if non-NULL. */
10476 static int
10477 tool_bar_lines_needed (struct frame *f, int *n_rows)
10479 struct window *w = XWINDOW (f->tool_bar_window);
10480 struct it it;
10481 /* tool_bar_lines_needed is called from redisplay_tool_bar after building
10482 the desired matrix, so use (unused) mode-line row as temporary row to
10483 avoid destroying the first tool-bar row. */
10484 struct glyph_row *temp_row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
10486 /* Initialize an iterator for iteration over
10487 F->desired_tool_bar_string in the tool-bar window of frame F. */
10488 init_iterator (&it, w, -1, -1, temp_row, TOOL_BAR_FACE_ID);
10489 it.first_visible_x = 0;
10490 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
10491 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
10493 while (!ITERATOR_AT_END_P (&it))
10495 clear_glyph_row (temp_row);
10496 it.glyph_row = temp_row;
10497 display_tool_bar_line (&it, -1);
10499 clear_glyph_row (temp_row);
10501 /* f->n_tool_bar_rows == 0 means "unknown"; -1 means no tool-bar. */
10502 if (n_rows)
10503 *n_rows = it.vpos > 0 ? it.vpos : -1;
10505 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
10509 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
10510 0, 1, 0,
10511 doc: /* Return the number of lines occupied by the tool bar of FRAME. */)
10512 (Lisp_Object frame)
10514 struct frame *f;
10515 struct window *w;
10516 int nlines = 0;
10518 if (NILP (frame))
10519 frame = selected_frame;
10520 else
10521 CHECK_FRAME (frame);
10522 f = XFRAME (frame);
10524 if (WINDOWP (f->tool_bar_window)
10525 || (w = XWINDOW (f->tool_bar_window),
10526 WINDOW_TOTAL_LINES (w) > 0))
10528 update_tool_bar (f, 1);
10529 if (f->n_tool_bar_items)
10531 build_desired_tool_bar_string (f);
10532 nlines = tool_bar_lines_needed (f, NULL);
10536 return make_number (nlines);
10540 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
10541 height should be changed. */
10543 static int
10544 redisplay_tool_bar (struct frame *f)
10546 struct window *w;
10547 struct it it;
10548 struct glyph_row *row;
10550 #if defined (USE_GTK) || defined (HAVE_NS)
10551 if (FRAME_EXTERNAL_TOOL_BAR (f))
10552 update_frame_tool_bar (f);
10553 return 0;
10554 #endif
10556 /* If frame hasn't a tool-bar window or if it is zero-height, don't
10557 do anything. This means you must start with tool-bar-lines
10558 non-zero to get the auto-sizing effect. Or in other words, you
10559 can turn off tool-bars by specifying tool-bar-lines zero. */
10560 if (!WINDOWP (f->tool_bar_window)
10561 || (w = XWINDOW (f->tool_bar_window),
10562 WINDOW_TOTAL_LINES (w) == 0))
10563 return 0;
10565 /* Set up an iterator for the tool-bar window. */
10566 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
10567 it.first_visible_x = 0;
10568 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
10569 row = it.glyph_row;
10571 /* Build a string that represents the contents of the tool-bar. */
10572 build_desired_tool_bar_string (f);
10573 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
10575 if (f->n_tool_bar_rows == 0)
10577 int nlines;
10579 if ((nlines = tool_bar_lines_needed (f, &f->n_tool_bar_rows),
10580 nlines != WINDOW_TOTAL_LINES (w)))
10582 Lisp_Object frame;
10583 int old_height = WINDOW_TOTAL_LINES (w);
10585 XSETFRAME (frame, f);
10586 Fmodify_frame_parameters (frame,
10587 Fcons (Fcons (Qtool_bar_lines,
10588 make_number (nlines)),
10589 Qnil));
10590 if (WINDOW_TOTAL_LINES (w) != old_height)
10592 clear_glyph_matrix (w->desired_matrix);
10593 fonts_changed_p = 1;
10594 return 1;
10599 /* Display as many lines as needed to display all tool-bar items. */
10601 if (f->n_tool_bar_rows > 0)
10603 int border, rows, height, extra;
10605 if (INTEGERP (Vtool_bar_border))
10606 border = XINT (Vtool_bar_border);
10607 else if (EQ (Vtool_bar_border, Qinternal_border_width))
10608 border = FRAME_INTERNAL_BORDER_WIDTH (f);
10609 else if (EQ (Vtool_bar_border, Qborder_width))
10610 border = f->border_width;
10611 else
10612 border = 0;
10613 if (border < 0)
10614 border = 0;
10616 rows = f->n_tool_bar_rows;
10617 height = max (1, (it.last_visible_y - border) / rows);
10618 extra = it.last_visible_y - border - height * rows;
10620 while (it.current_y < it.last_visible_y)
10622 int h = 0;
10623 if (extra > 0 && rows-- > 0)
10625 h = (extra + rows - 1) / rows;
10626 extra -= h;
10628 display_tool_bar_line (&it, height + h);
10631 else
10633 while (it.current_y < it.last_visible_y)
10634 display_tool_bar_line (&it, 0);
10637 /* It doesn't make much sense to try scrolling in the tool-bar
10638 window, so don't do it. */
10639 w->desired_matrix->no_scrolling_p = 1;
10640 w->must_be_updated_p = 1;
10642 if (!NILP (Vauto_resize_tool_bars))
10644 int max_tool_bar_height = MAX_FRAME_TOOL_BAR_HEIGHT (f);
10645 int change_height_p = 0;
10647 /* If we couldn't display everything, change the tool-bar's
10648 height if there is room for more. */
10649 if (IT_STRING_CHARPOS (it) < it.end_charpos
10650 && it.current_y < max_tool_bar_height)
10651 change_height_p = 1;
10653 row = it.glyph_row - 1;
10655 /* If there are blank lines at the end, except for a partially
10656 visible blank line at the end that is smaller than
10657 FRAME_LINE_HEIGHT, change the tool-bar's height. */
10658 if (!row->displays_text_p
10659 && row->height >= FRAME_LINE_HEIGHT (f))
10660 change_height_p = 1;
10662 /* If row displays tool-bar items, but is partially visible,
10663 change the tool-bar's height. */
10664 if (row->displays_text_p
10665 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y
10666 && MATRIX_ROW_BOTTOM_Y (row) < max_tool_bar_height)
10667 change_height_p = 1;
10669 /* Resize windows as needed by changing the `tool-bar-lines'
10670 frame parameter. */
10671 if (change_height_p)
10673 Lisp_Object frame;
10674 int old_height = WINDOW_TOTAL_LINES (w);
10675 int nrows;
10676 int nlines = tool_bar_lines_needed (f, &nrows);
10678 change_height_p = ((EQ (Vauto_resize_tool_bars, Qgrow_only)
10679 && !f->minimize_tool_bar_window_p)
10680 ? (nlines > old_height)
10681 : (nlines != old_height));
10682 f->minimize_tool_bar_window_p = 0;
10684 if (change_height_p)
10686 XSETFRAME (frame, f);
10687 Fmodify_frame_parameters (frame,
10688 Fcons (Fcons (Qtool_bar_lines,
10689 make_number (nlines)),
10690 Qnil));
10691 if (WINDOW_TOTAL_LINES (w) != old_height)
10693 clear_glyph_matrix (w->desired_matrix);
10694 f->n_tool_bar_rows = nrows;
10695 fonts_changed_p = 1;
10696 return 1;
10702 f->minimize_tool_bar_window_p = 0;
10703 return 0;
10707 /* Get information about the tool-bar item which is displayed in GLYPH
10708 on frame F. Return in *PROP_IDX the index where tool-bar item
10709 properties start in F->tool_bar_items. Value is zero if
10710 GLYPH doesn't display a tool-bar item. */
10712 static int
10713 tool_bar_item_info (struct frame *f, struct glyph *glyph, int *prop_idx)
10715 Lisp_Object prop;
10716 int success_p;
10717 int charpos;
10719 /* This function can be called asynchronously, which means we must
10720 exclude any possibility that Fget_text_property signals an
10721 error. */
10722 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
10723 charpos = max (0, charpos);
10725 /* Get the text property `menu-item' at pos. The value of that
10726 property is the start index of this item's properties in
10727 F->tool_bar_items. */
10728 prop = Fget_text_property (make_number (charpos),
10729 Qmenu_item, f->current_tool_bar_string);
10730 if (INTEGERP (prop))
10732 *prop_idx = XINT (prop);
10733 success_p = 1;
10735 else
10736 success_p = 0;
10738 return success_p;
10742 /* Get information about the tool-bar item at position X/Y on frame F.
10743 Return in *GLYPH a pointer to the glyph of the tool-bar item in
10744 the current matrix of the tool-bar window of F, or NULL if not
10745 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
10746 item in F->tool_bar_items. Value is
10748 -1 if X/Y is not on a tool-bar item
10749 0 if X/Y is on the same item that was highlighted before.
10750 1 otherwise. */
10752 static int
10753 get_tool_bar_item (struct frame *f, int x, int y, struct glyph **glyph,
10754 int *hpos, int *vpos, int *prop_idx)
10756 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
10757 struct window *w = XWINDOW (f->tool_bar_window);
10758 int area;
10760 /* Find the glyph under X/Y. */
10761 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
10762 if (*glyph == NULL)
10763 return -1;
10765 /* Get the start of this tool-bar item's properties in
10766 f->tool_bar_items. */
10767 if (!tool_bar_item_info (f, *glyph, prop_idx))
10768 return -1;
10770 /* Is mouse on the highlighted item? */
10771 if (EQ (f->tool_bar_window, dpyinfo->mouse_face_window)
10772 && *vpos >= dpyinfo->mouse_face_beg_row
10773 && *vpos <= dpyinfo->mouse_face_end_row
10774 && (*vpos > dpyinfo->mouse_face_beg_row
10775 || *hpos >= dpyinfo->mouse_face_beg_col)
10776 && (*vpos < dpyinfo->mouse_face_end_row
10777 || *hpos < dpyinfo->mouse_face_end_col
10778 || dpyinfo->mouse_face_past_end))
10779 return 0;
10781 return 1;
10785 /* EXPORT:
10786 Handle mouse button event on the tool-bar of frame F, at
10787 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
10788 0 for button release. MODIFIERS is event modifiers for button
10789 release. */
10791 void
10792 handle_tool_bar_click (struct frame *f, int x, int y, int down_p,
10793 unsigned int modifiers)
10795 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
10796 struct window *w = XWINDOW (f->tool_bar_window);
10797 int hpos, vpos, prop_idx;
10798 struct glyph *glyph;
10799 Lisp_Object enabled_p;
10801 /* If not on the highlighted tool-bar item, return. */
10802 frame_to_window_pixel_xy (w, &x, &y);
10803 if (get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0)
10804 return;
10806 /* If item is disabled, do nothing. */
10807 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
10808 if (NILP (enabled_p))
10809 return;
10811 if (down_p)
10813 /* Show item in pressed state. */
10814 show_mouse_face (dpyinfo, DRAW_IMAGE_SUNKEN);
10815 dpyinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN;
10816 last_tool_bar_item = prop_idx;
10818 else
10820 Lisp_Object key, frame;
10821 struct input_event event;
10822 EVENT_INIT (event);
10824 /* Show item in released state. */
10825 show_mouse_face (dpyinfo, DRAW_IMAGE_RAISED);
10826 dpyinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
10828 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
10830 XSETFRAME (frame, f);
10831 event.kind = TOOL_BAR_EVENT;
10832 event.frame_or_window = frame;
10833 event.arg = frame;
10834 kbd_buffer_store_event (&event);
10836 event.kind = TOOL_BAR_EVENT;
10837 event.frame_or_window = frame;
10838 event.arg = key;
10839 event.modifiers = modifiers;
10840 kbd_buffer_store_event (&event);
10841 last_tool_bar_item = -1;
10846 /* Possibly highlight a tool-bar item on frame F when mouse moves to
10847 tool-bar window-relative coordinates X/Y. Called from
10848 note_mouse_highlight. */
10850 static void
10851 note_tool_bar_highlight (struct frame *f, int x, int y)
10853 Lisp_Object window = f->tool_bar_window;
10854 struct window *w = XWINDOW (window);
10855 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
10856 int hpos, vpos;
10857 struct glyph *glyph;
10858 struct glyph_row *row;
10859 int i;
10860 Lisp_Object enabled_p;
10861 int prop_idx;
10862 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
10863 int mouse_down_p, rc;
10865 /* Function note_mouse_highlight is called with negative X/Y
10866 values when mouse moves outside of the frame. */
10867 if (x <= 0 || y <= 0)
10869 clear_mouse_face (dpyinfo);
10870 return;
10873 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
10874 if (rc < 0)
10876 /* Not on tool-bar item. */
10877 clear_mouse_face (dpyinfo);
10878 return;
10880 else if (rc == 0)
10881 /* On same tool-bar item as before. */
10882 goto set_help_echo;
10884 clear_mouse_face (dpyinfo);
10886 /* Mouse is down, but on different tool-bar item? */
10887 mouse_down_p = (dpyinfo->grabbed
10888 && f == last_mouse_frame
10889 && FRAME_LIVE_P (f));
10890 if (mouse_down_p
10891 && last_tool_bar_item != prop_idx)
10892 return;
10894 dpyinfo->mouse_face_image_state = DRAW_NORMAL_TEXT;
10895 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
10897 /* If tool-bar item is not enabled, don't highlight it. */
10898 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
10899 if (!NILP (enabled_p))
10901 /* Compute the x-position of the glyph. In front and past the
10902 image is a space. We include this in the highlighted area. */
10903 row = MATRIX_ROW (w->current_matrix, vpos);
10904 for (i = x = 0; i < hpos; ++i)
10905 x += row->glyphs[TEXT_AREA][i].pixel_width;
10907 /* Record this as the current active region. */
10908 dpyinfo->mouse_face_beg_col = hpos;
10909 dpyinfo->mouse_face_beg_row = vpos;
10910 dpyinfo->mouse_face_beg_x = x;
10911 dpyinfo->mouse_face_beg_y = row->y;
10912 dpyinfo->mouse_face_past_end = 0;
10914 dpyinfo->mouse_face_end_col = hpos + 1;
10915 dpyinfo->mouse_face_end_row = vpos;
10916 dpyinfo->mouse_face_end_x = x + glyph->pixel_width;
10917 dpyinfo->mouse_face_end_y = row->y;
10918 dpyinfo->mouse_face_window = window;
10919 dpyinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
10921 /* Display it as active. */
10922 show_mouse_face (dpyinfo, draw);
10923 dpyinfo->mouse_face_image_state = draw;
10926 set_help_echo:
10928 /* Set help_echo_string to a help string to display for this tool-bar item.
10929 XTread_socket does the rest. */
10930 help_echo_object = help_echo_window = Qnil;
10931 help_echo_pos = -1;
10932 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
10933 if (NILP (help_echo_string))
10934 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
10937 #endif /* HAVE_WINDOW_SYSTEM */
10941 /************************************************************************
10942 Horizontal scrolling
10943 ************************************************************************/
10945 static int hscroll_window_tree (Lisp_Object);
10946 static int hscroll_windows (Lisp_Object);
10948 /* For all leaf windows in the window tree rooted at WINDOW, set their
10949 hscroll value so that PT is (i) visible in the window, and (ii) so
10950 that it is not within a certain margin at the window's left and
10951 right border. Value is non-zero if any window's hscroll has been
10952 changed. */
10954 static int
10955 hscroll_window_tree (Lisp_Object window)
10957 int hscrolled_p = 0;
10958 int hscroll_relative_p = FLOATP (Vhscroll_step);
10959 int hscroll_step_abs = 0;
10960 double hscroll_step_rel = 0;
10962 if (hscroll_relative_p)
10964 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
10965 if (hscroll_step_rel < 0)
10967 hscroll_relative_p = 0;
10968 hscroll_step_abs = 0;
10971 else if (INTEGERP (Vhscroll_step))
10973 hscroll_step_abs = XINT (Vhscroll_step);
10974 if (hscroll_step_abs < 0)
10975 hscroll_step_abs = 0;
10977 else
10978 hscroll_step_abs = 0;
10980 while (WINDOWP (window))
10982 struct window *w = XWINDOW (window);
10984 if (WINDOWP (w->hchild))
10985 hscrolled_p |= hscroll_window_tree (w->hchild);
10986 else if (WINDOWP (w->vchild))
10987 hscrolled_p |= hscroll_window_tree (w->vchild);
10988 else if (w->cursor.vpos >= 0)
10990 int h_margin;
10991 int text_area_width;
10992 struct glyph_row *current_cursor_row
10993 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
10994 struct glyph_row *desired_cursor_row
10995 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
10996 struct glyph_row *cursor_row
10997 = (desired_cursor_row->enabled_p
10998 ? desired_cursor_row
10999 : current_cursor_row);
11001 text_area_width = window_box_width (w, TEXT_AREA);
11003 /* Scroll when cursor is inside this scroll margin. */
11004 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
11006 if (!NILP (Fbuffer_local_value (Qauto_hscroll_mode, w->buffer))
11007 && ((XFASTINT (w->hscroll)
11008 && w->cursor.x <= h_margin)
11009 || (cursor_row->enabled_p
11010 && cursor_row->truncated_on_right_p
11011 && (w->cursor.x >= text_area_width - h_margin))))
11013 struct it it;
11014 int hscroll;
11015 struct buffer *saved_current_buffer;
11016 int pt;
11017 int wanted_x;
11019 /* Find point in a display of infinite width. */
11020 saved_current_buffer = current_buffer;
11021 current_buffer = XBUFFER (w->buffer);
11023 if (w == XWINDOW (selected_window))
11024 pt = BUF_PT (current_buffer);
11025 else
11027 pt = marker_position (w->pointm);
11028 pt = max (BEGV, pt);
11029 pt = min (ZV, pt);
11032 /* Move iterator to pt starting at cursor_row->start in
11033 a line with infinite width. */
11034 init_to_row_start (&it, w, cursor_row);
11035 it.last_visible_x = INFINITY;
11036 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
11037 current_buffer = saved_current_buffer;
11039 /* Position cursor in window. */
11040 if (!hscroll_relative_p && hscroll_step_abs == 0)
11041 hscroll = max (0, (it.current_x
11042 - (ITERATOR_AT_END_OF_LINE_P (&it)
11043 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
11044 : (text_area_width / 2))))
11045 / FRAME_COLUMN_WIDTH (it.f);
11046 else if (w->cursor.x >= text_area_width - h_margin)
11048 if (hscroll_relative_p)
11049 wanted_x = text_area_width * (1 - hscroll_step_rel)
11050 - h_margin;
11051 else
11052 wanted_x = text_area_width
11053 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
11054 - h_margin;
11055 hscroll
11056 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
11058 else
11060 if (hscroll_relative_p)
11061 wanted_x = text_area_width * hscroll_step_rel
11062 + h_margin;
11063 else
11064 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
11065 + h_margin;
11066 hscroll
11067 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
11069 hscroll = max (hscroll, XFASTINT (w->min_hscroll));
11071 /* Don't call Fset_window_hscroll if value hasn't
11072 changed because it will prevent redisplay
11073 optimizations. */
11074 if (XFASTINT (w->hscroll) != hscroll)
11076 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
11077 w->hscroll = make_number (hscroll);
11078 hscrolled_p = 1;
11083 window = w->next;
11086 /* Value is non-zero if hscroll of any leaf window has been changed. */
11087 return hscrolled_p;
11091 /* Set hscroll so that cursor is visible and not inside horizontal
11092 scroll margins for all windows in the tree rooted at WINDOW. See
11093 also hscroll_window_tree above. Value is non-zero if any window's
11094 hscroll has been changed. If it has, desired matrices on the frame
11095 of WINDOW are cleared. */
11097 static int
11098 hscroll_windows (Lisp_Object window)
11100 int hscrolled_p = hscroll_window_tree (window);
11101 if (hscrolled_p)
11102 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
11103 return hscrolled_p;
11108 /************************************************************************
11109 Redisplay
11110 ************************************************************************/
11112 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
11113 to a non-zero value. This is sometimes handy to have in a debugger
11114 session. */
11116 #if GLYPH_DEBUG
11118 /* First and last unchanged row for try_window_id. */
11120 int debug_first_unchanged_at_end_vpos;
11121 int debug_last_unchanged_at_beg_vpos;
11123 /* Delta vpos and y. */
11125 int debug_dvpos, debug_dy;
11127 /* Delta in characters and bytes for try_window_id. */
11129 int debug_delta, debug_delta_bytes;
11131 /* Values of window_end_pos and window_end_vpos at the end of
11132 try_window_id. */
11134 EMACS_INT debug_end_pos, debug_end_vpos;
11136 /* Append a string to W->desired_matrix->method. FMT is a printf
11137 format string. A1...A9 are a supplement for a variable-length
11138 argument list. If trace_redisplay_p is non-zero also printf the
11139 resulting string to stderr. */
11141 static void
11142 debug_method_add (w, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
11143 struct window *w;
11144 char *fmt;
11145 int a1, a2, a3, a4, a5, a6, a7, a8, a9;
11147 char buffer[512];
11148 char *method = w->desired_matrix->method;
11149 int len = strlen (method);
11150 int size = sizeof w->desired_matrix->method;
11151 int remaining = size - len - 1;
11153 sprintf (buffer, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
11154 if (len && remaining)
11156 method[len] = '|';
11157 --remaining, ++len;
11160 strncpy (method + len, buffer, remaining);
11162 if (trace_redisplay_p)
11163 fprintf (stderr, "%p (%s): %s\n",
11165 ((BUFFERP (w->buffer)
11166 && STRINGP (XBUFFER (w->buffer)->name))
11167 ? (char *) SDATA (XBUFFER (w->buffer)->name)
11168 : "no buffer"),
11169 buffer);
11172 #endif /* GLYPH_DEBUG */
11175 /* Value is non-zero if all changes in window W, which displays
11176 current_buffer, are in the text between START and END. START is a
11177 buffer position, END is given as a distance from Z. Used in
11178 redisplay_internal for display optimization. */
11180 static INLINE int
11181 text_outside_line_unchanged_p (struct window *w, int start, int end)
11183 int unchanged_p = 1;
11185 /* If text or overlays have changed, see where. */
11186 if (XFASTINT (w->last_modified) < MODIFF
11187 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
11189 /* Gap in the line? */
11190 if (GPT < start || Z - GPT < end)
11191 unchanged_p = 0;
11193 /* Changes start in front of the line, or end after it? */
11194 if (unchanged_p
11195 && (BEG_UNCHANGED < start - 1
11196 || END_UNCHANGED < end))
11197 unchanged_p = 0;
11199 /* If selective display, can't optimize if changes start at the
11200 beginning of the line. */
11201 if (unchanged_p
11202 && INTEGERP (current_buffer->selective_display)
11203 && XINT (current_buffer->selective_display) > 0
11204 && (BEG_UNCHANGED < start || GPT <= start))
11205 unchanged_p = 0;
11207 /* If there are overlays at the start or end of the line, these
11208 may have overlay strings with newlines in them. A change at
11209 START, for instance, may actually concern the display of such
11210 overlay strings as well, and they are displayed on different
11211 lines. So, quickly rule out this case. (For the future, it
11212 might be desirable to implement something more telling than
11213 just BEG/END_UNCHANGED.) */
11214 if (unchanged_p)
11216 if (BEG + BEG_UNCHANGED == start
11217 && overlay_touches_p (start))
11218 unchanged_p = 0;
11219 if (END_UNCHANGED == end
11220 && overlay_touches_p (Z - end))
11221 unchanged_p = 0;
11224 /* Under bidi reordering, adding or deleting a character in the
11225 beginning of a paragraph, before the first strong directional
11226 character, can change the base direction of the paragraph (unless
11227 the buffer specifies a fixed paragraph direction), which will
11228 require to redisplay the whole paragraph. It might be worthwhile
11229 to find the paragraph limits and widen the range of redisplayed
11230 lines to that, but for now just give up this optimization. */
11231 if (!NILP (XBUFFER (w->buffer)->bidi_display_reordering)
11232 && NILP (XBUFFER (w->buffer)->bidi_paragraph_direction))
11233 unchanged_p = 0;
11236 return unchanged_p;
11240 /* Do a frame update, taking possible shortcuts into account. This is
11241 the main external entry point for redisplay.
11243 If the last redisplay displayed an echo area message and that message
11244 is no longer requested, we clear the echo area or bring back the
11245 mini-buffer if that is in use. */
11247 void
11248 redisplay (void)
11250 redisplay_internal (0);
11254 static Lisp_Object
11255 overlay_arrow_string_or_property (Lisp_Object var)
11257 Lisp_Object val;
11259 if (val = Fget (var, Qoverlay_arrow_string), STRINGP (val))
11260 return val;
11262 return Voverlay_arrow_string;
11265 /* Return 1 if there are any overlay-arrows in current_buffer. */
11266 static int
11267 overlay_arrow_in_current_buffer_p (void)
11269 Lisp_Object vlist;
11271 for (vlist = Voverlay_arrow_variable_list;
11272 CONSP (vlist);
11273 vlist = XCDR (vlist))
11275 Lisp_Object var = XCAR (vlist);
11276 Lisp_Object val;
11278 if (!SYMBOLP (var))
11279 continue;
11280 val = find_symbol_value (var);
11281 if (MARKERP (val)
11282 && current_buffer == XMARKER (val)->buffer)
11283 return 1;
11285 return 0;
11289 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
11290 has changed. */
11292 static int
11293 overlay_arrows_changed_p (void)
11295 Lisp_Object vlist;
11297 for (vlist = Voverlay_arrow_variable_list;
11298 CONSP (vlist);
11299 vlist = XCDR (vlist))
11301 Lisp_Object var = XCAR (vlist);
11302 Lisp_Object val, pstr;
11304 if (!SYMBOLP (var))
11305 continue;
11306 val = find_symbol_value (var);
11307 if (!MARKERP (val))
11308 continue;
11309 if (! EQ (COERCE_MARKER (val),
11310 Fget (var, Qlast_arrow_position))
11311 || ! (pstr = overlay_arrow_string_or_property (var),
11312 EQ (pstr, Fget (var, Qlast_arrow_string))))
11313 return 1;
11315 return 0;
11318 /* Mark overlay arrows to be updated on next redisplay. */
11320 static void
11321 update_overlay_arrows (int up_to_date)
11323 Lisp_Object vlist;
11325 for (vlist = Voverlay_arrow_variable_list;
11326 CONSP (vlist);
11327 vlist = XCDR (vlist))
11329 Lisp_Object var = XCAR (vlist);
11331 if (!SYMBOLP (var))
11332 continue;
11334 if (up_to_date > 0)
11336 Lisp_Object val = find_symbol_value (var);
11337 Fput (var, Qlast_arrow_position,
11338 COERCE_MARKER (val));
11339 Fput (var, Qlast_arrow_string,
11340 overlay_arrow_string_or_property (var));
11342 else if (up_to_date < 0
11343 || !NILP (Fget (var, Qlast_arrow_position)))
11345 Fput (var, Qlast_arrow_position, Qt);
11346 Fput (var, Qlast_arrow_string, Qt);
11352 /* Return overlay arrow string to display at row.
11353 Return integer (bitmap number) for arrow bitmap in left fringe.
11354 Return nil if no overlay arrow. */
11356 static Lisp_Object
11357 overlay_arrow_at_row (struct it *it, struct glyph_row *row)
11359 Lisp_Object vlist;
11361 for (vlist = Voverlay_arrow_variable_list;
11362 CONSP (vlist);
11363 vlist = XCDR (vlist))
11365 Lisp_Object var = XCAR (vlist);
11366 Lisp_Object val;
11368 if (!SYMBOLP (var))
11369 continue;
11371 val = find_symbol_value (var);
11373 if (MARKERP (val)
11374 && current_buffer == XMARKER (val)->buffer
11375 && (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
11377 if (FRAME_WINDOW_P (it->f)
11378 /* FIXME: if ROW->reversed_p is set, this should test
11379 the right fringe, not the left one. */
11380 && WINDOW_LEFT_FRINGE_WIDTH (it->w) > 0)
11382 #ifdef HAVE_WINDOW_SYSTEM
11383 if (val = Fget (var, Qoverlay_arrow_bitmap), SYMBOLP (val))
11385 int fringe_bitmap;
11386 if ((fringe_bitmap = lookup_fringe_bitmap (val)) != 0)
11387 return make_number (fringe_bitmap);
11389 #endif
11390 return make_number (-1); /* Use default arrow bitmap */
11392 return overlay_arrow_string_or_property (var);
11396 return Qnil;
11399 /* Return 1 if point moved out of or into a composition. Otherwise
11400 return 0. PREV_BUF and PREV_PT are the last point buffer and
11401 position. BUF and PT are the current point buffer and position. */
11404 check_point_in_composition (struct buffer *prev_buf, int prev_pt,
11405 struct buffer *buf, int pt)
11407 EMACS_INT start, end;
11408 Lisp_Object prop;
11409 Lisp_Object buffer;
11411 XSETBUFFER (buffer, buf);
11412 /* Check a composition at the last point if point moved within the
11413 same buffer. */
11414 if (prev_buf == buf)
11416 if (prev_pt == pt)
11417 /* Point didn't move. */
11418 return 0;
11420 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
11421 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
11422 && COMPOSITION_VALID_P (start, end, prop)
11423 && start < prev_pt && end > prev_pt)
11424 /* The last point was within the composition. Return 1 iff
11425 point moved out of the composition. */
11426 return (pt <= start || pt >= end);
11429 /* Check a composition at the current point. */
11430 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
11431 && find_composition (pt, -1, &start, &end, &prop, buffer)
11432 && COMPOSITION_VALID_P (start, end, prop)
11433 && start < pt && end > pt);
11437 /* Reconsider the setting of B->clip_changed which is displayed
11438 in window W. */
11440 static INLINE void
11441 reconsider_clip_changes (struct window *w, struct buffer *b)
11443 if (b->clip_changed
11444 && !NILP (w->window_end_valid)
11445 && w->current_matrix->buffer == b
11446 && w->current_matrix->zv == BUF_ZV (b)
11447 && w->current_matrix->begv == BUF_BEGV (b))
11448 b->clip_changed = 0;
11450 /* If display wasn't paused, and W is not a tool bar window, see if
11451 point has been moved into or out of a composition. In that case,
11452 we set b->clip_changed to 1 to force updating the screen. If
11453 b->clip_changed has already been set to 1, we can skip this
11454 check. */
11455 if (!b->clip_changed
11456 && BUFFERP (w->buffer) && !NILP (w->window_end_valid))
11458 int pt;
11460 if (w == XWINDOW (selected_window))
11461 pt = BUF_PT (current_buffer);
11462 else
11463 pt = marker_position (w->pointm);
11465 if ((w->current_matrix->buffer != XBUFFER (w->buffer)
11466 || pt != XINT (w->last_point))
11467 && check_point_in_composition (w->current_matrix->buffer,
11468 XINT (w->last_point),
11469 XBUFFER (w->buffer), pt))
11470 b->clip_changed = 1;
11475 /* Select FRAME to forward the values of frame-local variables into C
11476 variables so that the redisplay routines can access those values
11477 directly. */
11479 static void
11480 select_frame_for_redisplay (Lisp_Object frame)
11482 Lisp_Object tail, tem;
11483 Lisp_Object old = selected_frame;
11484 struct Lisp_Symbol *sym;
11486 xassert (FRAMEP (frame) && FRAME_LIVE_P (XFRAME (frame)));
11488 selected_frame = frame;
11490 do {
11491 for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail))
11492 if (CONSP (XCAR (tail))
11493 && (tem = XCAR (XCAR (tail)),
11494 SYMBOLP (tem))
11495 && (sym = indirect_variable (XSYMBOL (tem)),
11496 sym->redirect == SYMBOL_LOCALIZED)
11497 && sym->val.blv->frame_local)
11498 /* Use find_symbol_value rather than Fsymbol_value
11499 to avoid an error if it is void. */
11500 find_symbol_value (tem);
11501 } while (!EQ (frame, old) && (frame = old, 1));
11505 #define STOP_POLLING \
11506 do { if (! polling_stopped_here) stop_polling (); \
11507 polling_stopped_here = 1; } while (0)
11509 #define RESUME_POLLING \
11510 do { if (polling_stopped_here) start_polling (); \
11511 polling_stopped_here = 0; } while (0)
11514 /* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
11515 response to any user action; therefore, we should preserve the echo
11516 area. (Actually, our caller does that job.) Perhaps in the future
11517 avoid recentering windows if it is not necessary; currently that
11518 causes some problems. */
11520 static void
11521 redisplay_internal (int preserve_echo_area)
11523 struct window *w = XWINDOW (selected_window);
11524 struct frame *f;
11525 int pause;
11526 int must_finish = 0;
11527 struct text_pos tlbufpos, tlendpos;
11528 int number_of_visible_frames;
11529 int count, count1;
11530 struct frame *sf;
11531 int polling_stopped_here = 0;
11532 Lisp_Object old_frame = selected_frame;
11534 /* Non-zero means redisplay has to consider all windows on all
11535 frames. Zero means, only selected_window is considered. */
11536 int consider_all_windows_p;
11538 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
11540 /* No redisplay if running in batch mode or frame is not yet fully
11541 initialized, or redisplay is explicitly turned off by setting
11542 Vinhibit_redisplay. */
11543 if (FRAME_INITIAL_P (SELECTED_FRAME ())
11544 || !NILP (Vinhibit_redisplay))
11545 return;
11547 /* Don't examine these until after testing Vinhibit_redisplay.
11548 When Emacs is shutting down, perhaps because its connection to
11549 X has dropped, we should not look at them at all. */
11550 f = XFRAME (w->frame);
11551 sf = SELECTED_FRAME ();
11553 if (!f->glyphs_initialized_p)
11554 return;
11556 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS)
11557 if (popup_activated ())
11558 return;
11559 #endif
11561 /* I don't think this happens but let's be paranoid. */
11562 if (redisplaying_p)
11563 return;
11565 /* Record a function that resets redisplaying_p to its old value
11566 when we leave this function. */
11567 count = SPECPDL_INDEX ();
11568 record_unwind_protect (unwind_redisplay,
11569 Fcons (make_number (redisplaying_p), selected_frame));
11570 ++redisplaying_p;
11571 specbind (Qinhibit_free_realized_faces, Qnil);
11574 Lisp_Object tail, frame;
11576 FOR_EACH_FRAME (tail, frame)
11578 struct frame *f = XFRAME (frame);
11579 f->already_hscrolled_p = 0;
11583 retry:
11584 if (!EQ (old_frame, selected_frame)
11585 && FRAME_LIVE_P (XFRAME (old_frame)))
11586 /* When running redisplay, we play a bit fast-and-loose and allow e.g.
11587 selected_frame and selected_window to be temporarily out-of-sync so
11588 when we come back here via `goto retry', we need to resync because we
11589 may need to run Elisp code (via prepare_menu_bars). */
11590 select_frame_for_redisplay (old_frame);
11592 pause = 0;
11593 reconsider_clip_changes (w, current_buffer);
11594 last_escape_glyph_frame = NULL;
11595 last_escape_glyph_face_id = (1 << FACE_ID_BITS);
11597 /* If new fonts have been loaded that make a glyph matrix adjustment
11598 necessary, do it. */
11599 if (fonts_changed_p)
11601 adjust_glyphs (NULL);
11602 ++windows_or_buffers_changed;
11603 fonts_changed_p = 0;
11606 /* If face_change_count is non-zero, init_iterator will free all
11607 realized faces, which includes the faces referenced from current
11608 matrices. So, we can't reuse current matrices in this case. */
11609 if (face_change_count)
11610 ++windows_or_buffers_changed;
11612 if ((FRAME_TERMCAP_P (sf) || FRAME_MSDOS_P (sf))
11613 && FRAME_TTY (sf)->previous_frame != sf)
11615 /* Since frames on a single ASCII terminal share the same
11616 display area, displaying a different frame means redisplay
11617 the whole thing. */
11618 windows_or_buffers_changed++;
11619 SET_FRAME_GARBAGED (sf);
11620 #ifndef DOS_NT
11621 set_tty_color_mode (FRAME_TTY (sf), sf);
11622 #endif
11623 FRAME_TTY (sf)->previous_frame = sf;
11626 /* Set the visible flags for all frames. Do this before checking
11627 for resized or garbaged frames; they want to know if their frames
11628 are visible. See the comment in frame.h for
11629 FRAME_SAMPLE_VISIBILITY. */
11631 Lisp_Object tail, frame;
11633 number_of_visible_frames = 0;
11635 FOR_EACH_FRAME (tail, frame)
11637 struct frame *f = XFRAME (frame);
11639 FRAME_SAMPLE_VISIBILITY (f);
11640 if (FRAME_VISIBLE_P (f))
11641 ++number_of_visible_frames;
11642 clear_desired_matrices (f);
11646 /* Notice any pending interrupt request to change frame size. */
11647 do_pending_window_change (1);
11649 /* Clear frames marked as garbaged. */
11650 if (frame_garbaged)
11651 clear_garbaged_frames ();
11653 /* Build menubar and tool-bar items. */
11654 if (NILP (Vmemory_full))
11655 prepare_menu_bars ();
11657 if (windows_or_buffers_changed)
11658 update_mode_lines++;
11660 /* Detect case that we need to write or remove a star in the mode line. */
11661 if ((SAVE_MODIFF < MODIFF) != !NILP (w->last_had_star))
11663 w->update_mode_line = Qt;
11664 if (buffer_shared > 1)
11665 update_mode_lines++;
11668 /* Avoid invocation of point motion hooks by `current_column' below. */
11669 count1 = SPECPDL_INDEX ();
11670 specbind (Qinhibit_point_motion_hooks, Qt);
11672 /* If %c is in the mode line, update it if needed. */
11673 if (!NILP (w->column_number_displayed)
11674 /* This alternative quickly identifies a common case
11675 where no change is needed. */
11676 && !(PT == XFASTINT (w->last_point)
11677 && XFASTINT (w->last_modified) >= MODIFF
11678 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
11679 && (XFASTINT (w->column_number_displayed)
11680 != (int) current_column ())) /* iftc */
11681 w->update_mode_line = Qt;
11683 unbind_to (count1, Qnil);
11685 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
11687 /* The variable buffer_shared is set in redisplay_window and
11688 indicates that we redisplay a buffer in different windows. See
11689 there. */
11690 consider_all_windows_p = (update_mode_lines || buffer_shared > 1
11691 || cursor_type_changed);
11693 /* If specs for an arrow have changed, do thorough redisplay
11694 to ensure we remove any arrow that should no longer exist. */
11695 if (overlay_arrows_changed_p ())
11696 consider_all_windows_p = windows_or_buffers_changed = 1;
11698 /* Normally the message* functions will have already displayed and
11699 updated the echo area, but the frame may have been trashed, or
11700 the update may have been preempted, so display the echo area
11701 again here. Checking message_cleared_p captures the case that
11702 the echo area should be cleared. */
11703 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
11704 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
11705 || (message_cleared_p
11706 && minibuf_level == 0
11707 /* If the mini-window is currently selected, this means the
11708 echo-area doesn't show through. */
11709 && !MINI_WINDOW_P (XWINDOW (selected_window))))
11711 int window_height_changed_p = echo_area_display (0);
11712 must_finish = 1;
11714 /* If we don't display the current message, don't clear the
11715 message_cleared_p flag, because, if we did, we wouldn't clear
11716 the echo area in the next redisplay which doesn't preserve
11717 the echo area. */
11718 if (!display_last_displayed_message_p)
11719 message_cleared_p = 0;
11721 if (fonts_changed_p)
11722 goto retry;
11723 else if (window_height_changed_p)
11725 consider_all_windows_p = 1;
11726 ++update_mode_lines;
11727 ++windows_or_buffers_changed;
11729 /* If window configuration was changed, frames may have been
11730 marked garbaged. Clear them or we will experience
11731 surprises wrt scrolling. */
11732 if (frame_garbaged)
11733 clear_garbaged_frames ();
11736 else if (EQ (selected_window, minibuf_window)
11737 && (current_buffer->clip_changed
11738 || XFASTINT (w->last_modified) < MODIFF
11739 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
11740 && resize_mini_window (w, 0))
11742 /* Resized active mini-window to fit the size of what it is
11743 showing if its contents might have changed. */
11744 must_finish = 1;
11745 /* FIXME: this causes all frames to be updated, which seems unnecessary
11746 since only the current frame needs to be considered. This function needs
11747 to be rewritten with two variables, consider_all_windows and
11748 consider_all_frames. */
11749 consider_all_windows_p = 1;
11750 ++windows_or_buffers_changed;
11751 ++update_mode_lines;
11753 /* If window configuration was changed, frames may have been
11754 marked garbaged. Clear them or we will experience
11755 surprises wrt scrolling. */
11756 if (frame_garbaged)
11757 clear_garbaged_frames ();
11761 /* If showing the region, and mark has changed, we must redisplay
11762 the whole window. The assignment to this_line_start_pos prevents
11763 the optimization directly below this if-statement. */
11764 if (((!NILP (Vtransient_mark_mode)
11765 && !NILP (XBUFFER (w->buffer)->mark_active))
11766 != !NILP (w->region_showing))
11767 || (!NILP (w->region_showing)
11768 && !EQ (w->region_showing,
11769 Fmarker_position (XBUFFER (w->buffer)->mark))))
11770 CHARPOS (this_line_start_pos) = 0;
11772 /* Optimize the case that only the line containing the cursor in the
11773 selected window has changed. Variables starting with this_ are
11774 set in display_line and record information about the line
11775 containing the cursor. */
11776 tlbufpos = this_line_start_pos;
11777 tlendpos = this_line_end_pos;
11778 if (!consider_all_windows_p
11779 && CHARPOS (tlbufpos) > 0
11780 && NILP (w->update_mode_line)
11781 && !current_buffer->clip_changed
11782 && !current_buffer->prevent_redisplay_optimizations_p
11783 && FRAME_VISIBLE_P (XFRAME (w->frame))
11784 && !FRAME_OBSCURED_P (XFRAME (w->frame))
11785 /* Make sure recorded data applies to current buffer, etc. */
11786 && this_line_buffer == current_buffer
11787 && current_buffer == XBUFFER (w->buffer)
11788 && NILP (w->force_start)
11789 && NILP (w->optional_new_start)
11790 /* Point must be on the line that we have info recorded about. */
11791 && PT >= CHARPOS (tlbufpos)
11792 && PT <= Z - CHARPOS (tlendpos)
11793 /* All text outside that line, including its final newline,
11794 must be unchanged. */
11795 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
11796 CHARPOS (tlendpos)))
11798 if (CHARPOS (tlbufpos) > BEGV
11799 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
11800 && (CHARPOS (tlbufpos) == ZV
11801 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
11802 /* Former continuation line has disappeared by becoming empty. */
11803 goto cancel;
11804 else if (XFASTINT (w->last_modified) < MODIFF
11805 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF
11806 || MINI_WINDOW_P (w))
11808 /* We have to handle the case of continuation around a
11809 wide-column character (see the comment in indent.c around
11810 line 1340).
11812 For instance, in the following case:
11814 -------- Insert --------
11815 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
11816 J_I_ ==> J_I_ `^^' are cursors.
11817 ^^ ^^
11818 -------- --------
11820 As we have to redraw the line above, we cannot use this
11821 optimization. */
11823 struct it it;
11824 int line_height_before = this_line_pixel_height;
11826 /* Note that start_display will handle the case that the
11827 line starting at tlbufpos is a continuation line. */
11828 start_display (&it, w, tlbufpos);
11830 /* Implementation note: It this still necessary? */
11831 if (it.current_x != this_line_start_x)
11832 goto cancel;
11834 TRACE ((stderr, "trying display optimization 1\n"));
11835 w->cursor.vpos = -1;
11836 overlay_arrow_seen = 0;
11837 it.vpos = this_line_vpos;
11838 it.current_y = this_line_y;
11839 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
11840 display_line (&it);
11842 /* If line contains point, is not continued,
11843 and ends at same distance from eob as before, we win. */
11844 if (w->cursor.vpos >= 0
11845 /* Line is not continued, otherwise this_line_start_pos
11846 would have been set to 0 in display_line. */
11847 && CHARPOS (this_line_start_pos)
11848 /* Line ends as before. */
11849 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
11850 /* Line has same height as before. Otherwise other lines
11851 would have to be shifted up or down. */
11852 && this_line_pixel_height == line_height_before)
11854 /* If this is not the window's last line, we must adjust
11855 the charstarts of the lines below. */
11856 if (it.current_y < it.last_visible_y)
11858 struct glyph_row *row
11859 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
11860 int delta, delta_bytes;
11862 /* We used to distinguish between two cases here,
11863 conditioned by Z - CHARPOS (tlendpos) == ZV, for
11864 when the line ends in a newline or the end of the
11865 buffer's accessible portion. But both cases did
11866 the same, so they were collapsed. */
11867 delta = (Z
11868 - CHARPOS (tlendpos)
11869 - MATRIX_ROW_START_CHARPOS (row));
11870 delta_bytes = (Z_BYTE
11871 - BYTEPOS (tlendpos)
11872 - MATRIX_ROW_START_BYTEPOS (row));
11874 increment_matrix_positions (w->current_matrix,
11875 this_line_vpos + 1,
11876 w->current_matrix->nrows,
11877 delta, delta_bytes);
11880 /* If this row displays text now but previously didn't,
11881 or vice versa, w->window_end_vpos may have to be
11882 adjusted. */
11883 if ((it.glyph_row - 1)->displays_text_p)
11885 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
11886 XSETINT (w->window_end_vpos, this_line_vpos);
11888 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
11889 && this_line_vpos > 0)
11890 XSETINT (w->window_end_vpos, this_line_vpos - 1);
11891 w->window_end_valid = Qnil;
11893 /* Update hint: No need to try to scroll in update_window. */
11894 w->desired_matrix->no_scrolling_p = 1;
11896 #if GLYPH_DEBUG
11897 *w->desired_matrix->method = 0;
11898 debug_method_add (w, "optimization 1");
11899 #endif
11900 #ifdef HAVE_WINDOW_SYSTEM
11901 update_window_fringes (w, 0);
11902 #endif
11903 goto update;
11905 else
11906 goto cancel;
11908 else if (/* Cursor position hasn't changed. */
11909 PT == XFASTINT (w->last_point)
11910 /* Make sure the cursor was last displayed
11911 in this window. Otherwise we have to reposition it. */
11912 && 0 <= w->cursor.vpos
11913 && WINDOW_TOTAL_LINES (w) > w->cursor.vpos)
11915 if (!must_finish)
11917 do_pending_window_change (1);
11919 /* We used to always goto end_of_redisplay here, but this
11920 isn't enough if we have a blinking cursor. */
11921 if (w->cursor_off_p == w->last_cursor_off_p)
11922 goto end_of_redisplay;
11924 goto update;
11926 /* If highlighting the region, or if the cursor is in the echo area,
11927 then we can't just move the cursor. */
11928 else if (! (!NILP (Vtransient_mark_mode)
11929 && !NILP (current_buffer->mark_active))
11930 && (EQ (selected_window, current_buffer->last_selected_window)
11931 || highlight_nonselected_windows)
11932 && NILP (w->region_showing)
11933 && NILP (Vshow_trailing_whitespace)
11934 && !cursor_in_echo_area)
11936 struct it it;
11937 struct glyph_row *row;
11939 /* Skip from tlbufpos to PT and see where it is. Note that
11940 PT may be in invisible text. If so, we will end at the
11941 next visible position. */
11942 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
11943 NULL, DEFAULT_FACE_ID);
11944 it.current_x = this_line_start_x;
11945 it.current_y = this_line_y;
11946 it.vpos = this_line_vpos;
11948 /* The call to move_it_to stops in front of PT, but
11949 moves over before-strings. */
11950 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
11952 if (it.vpos == this_line_vpos
11953 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
11954 row->enabled_p))
11956 xassert (this_line_vpos == it.vpos);
11957 xassert (this_line_y == it.current_y);
11958 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11959 #if GLYPH_DEBUG
11960 *w->desired_matrix->method = 0;
11961 debug_method_add (w, "optimization 3");
11962 #endif
11963 goto update;
11965 else
11966 goto cancel;
11969 cancel:
11970 /* Text changed drastically or point moved off of line. */
11971 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
11974 CHARPOS (this_line_start_pos) = 0;
11975 consider_all_windows_p |= buffer_shared > 1;
11976 ++clear_face_cache_count;
11977 #ifdef HAVE_WINDOW_SYSTEM
11978 ++clear_image_cache_count;
11979 #endif
11981 /* Build desired matrices, and update the display. If
11982 consider_all_windows_p is non-zero, do it for all windows on all
11983 frames. Otherwise do it for selected_window, only. */
11985 if (consider_all_windows_p)
11987 Lisp_Object tail, frame;
11989 FOR_EACH_FRAME (tail, frame)
11990 XFRAME (frame)->updated_p = 0;
11992 /* Recompute # windows showing selected buffer. This will be
11993 incremented each time such a window is displayed. */
11994 buffer_shared = 0;
11996 FOR_EACH_FRAME (tail, frame)
11998 struct frame *f = XFRAME (frame);
12000 if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf)
12002 if (! EQ (frame, selected_frame))
12003 /* Select the frame, for the sake of frame-local
12004 variables. */
12005 select_frame_for_redisplay (frame);
12007 /* Mark all the scroll bars to be removed; we'll redeem
12008 the ones we want when we redisplay their windows. */
12009 if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
12010 FRAME_TERMINAL (f)->condemn_scroll_bars_hook (f);
12012 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
12013 redisplay_windows (FRAME_ROOT_WINDOW (f));
12015 /* The X error handler may have deleted that frame. */
12016 if (!FRAME_LIVE_P (f))
12017 continue;
12019 /* Any scroll bars which redisplay_windows should have
12020 nuked should now go away. */
12021 if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
12022 FRAME_TERMINAL (f)->judge_scroll_bars_hook (f);
12024 /* If fonts changed, display again. */
12025 /* ??? rms: I suspect it is a mistake to jump all the way
12026 back to retry here. It should just retry this frame. */
12027 if (fonts_changed_p)
12028 goto retry;
12030 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
12032 /* See if we have to hscroll. */
12033 if (!f->already_hscrolled_p)
12035 f->already_hscrolled_p = 1;
12036 if (hscroll_windows (f->root_window))
12037 goto retry;
12040 /* Prevent various kinds of signals during display
12041 update. stdio is not robust about handling
12042 signals, which can cause an apparent I/O
12043 error. */
12044 if (interrupt_input)
12045 unrequest_sigio ();
12046 STOP_POLLING;
12048 /* Update the display. */
12049 set_window_update_flags (XWINDOW (f->root_window), 1);
12050 pause |= update_frame (f, 0, 0);
12051 f->updated_p = 1;
12056 if (!EQ (old_frame, selected_frame)
12057 && FRAME_LIVE_P (XFRAME (old_frame)))
12058 /* We played a bit fast-and-loose above and allowed selected_frame
12059 and selected_window to be temporarily out-of-sync but let's make
12060 sure this stays contained. */
12061 select_frame_for_redisplay (old_frame);
12062 eassert (EQ (XFRAME (selected_frame)->selected_window, selected_window));
12064 if (!pause)
12066 /* Do the mark_window_display_accurate after all windows have
12067 been redisplayed because this call resets flags in buffers
12068 which are needed for proper redisplay. */
12069 FOR_EACH_FRAME (tail, frame)
12071 struct frame *f = XFRAME (frame);
12072 if (f->updated_p)
12074 mark_window_display_accurate (f->root_window, 1);
12075 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
12076 FRAME_TERMINAL (f)->frame_up_to_date_hook (f);
12081 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
12083 Lisp_Object mini_window;
12084 struct frame *mini_frame;
12086 displayed_buffer = XBUFFER (XWINDOW (selected_window)->buffer);
12087 /* Use list_of_error, not Qerror, so that
12088 we catch only errors and don't run the debugger. */
12089 internal_condition_case_1 (redisplay_window_1, selected_window,
12090 list_of_error,
12091 redisplay_window_error);
12093 /* Compare desired and current matrices, perform output. */
12095 update:
12096 /* If fonts changed, display again. */
12097 if (fonts_changed_p)
12098 goto retry;
12100 /* Prevent various kinds of signals during display update.
12101 stdio is not robust about handling signals,
12102 which can cause an apparent I/O error. */
12103 if (interrupt_input)
12104 unrequest_sigio ();
12105 STOP_POLLING;
12107 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
12109 if (hscroll_windows (selected_window))
12110 goto retry;
12112 XWINDOW (selected_window)->must_be_updated_p = 1;
12113 pause = update_frame (sf, 0, 0);
12116 /* We may have called echo_area_display at the top of this
12117 function. If the echo area is on another frame, that may
12118 have put text on a frame other than the selected one, so the
12119 above call to update_frame would not have caught it. Catch
12120 it here. */
12121 mini_window = FRAME_MINIBUF_WINDOW (sf);
12122 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
12124 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
12126 XWINDOW (mini_window)->must_be_updated_p = 1;
12127 pause |= update_frame (mini_frame, 0, 0);
12128 if (!pause && hscroll_windows (mini_window))
12129 goto retry;
12133 /* If display was paused because of pending input, make sure we do a
12134 thorough update the next time. */
12135 if (pause)
12137 /* Prevent the optimization at the beginning of
12138 redisplay_internal that tries a single-line update of the
12139 line containing the cursor in the selected window. */
12140 CHARPOS (this_line_start_pos) = 0;
12142 /* Let the overlay arrow be updated the next time. */
12143 update_overlay_arrows (0);
12145 /* If we pause after scrolling, some rows in the current
12146 matrices of some windows are not valid. */
12147 if (!WINDOW_FULL_WIDTH_P (w)
12148 && !FRAME_WINDOW_P (XFRAME (w->frame)))
12149 update_mode_lines = 1;
12151 else
12153 if (!consider_all_windows_p)
12155 /* This has already been done above if
12156 consider_all_windows_p is set. */
12157 mark_window_display_accurate_1 (w, 1);
12159 /* Say overlay arrows are up to date. */
12160 update_overlay_arrows (1);
12162 if (FRAME_TERMINAL (sf)->frame_up_to_date_hook != 0)
12163 FRAME_TERMINAL (sf)->frame_up_to_date_hook (sf);
12166 update_mode_lines = 0;
12167 windows_or_buffers_changed = 0;
12168 cursor_type_changed = 0;
12171 /* Start SIGIO interrupts coming again. Having them off during the
12172 code above makes it less likely one will discard output, but not
12173 impossible, since there might be stuff in the system buffer here.
12174 But it is much hairier to try to do anything about that. */
12175 if (interrupt_input)
12176 request_sigio ();
12177 RESUME_POLLING;
12179 /* If a frame has become visible which was not before, redisplay
12180 again, so that we display it. Expose events for such a frame
12181 (which it gets when becoming visible) don't call the parts of
12182 redisplay constructing glyphs, so simply exposing a frame won't
12183 display anything in this case. So, we have to display these
12184 frames here explicitly. */
12185 if (!pause)
12187 Lisp_Object tail, frame;
12188 int new_count = 0;
12190 FOR_EACH_FRAME (tail, frame)
12192 int this_is_visible = 0;
12194 if (XFRAME (frame)->visible)
12195 this_is_visible = 1;
12196 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
12197 if (XFRAME (frame)->visible)
12198 this_is_visible = 1;
12200 if (this_is_visible)
12201 new_count++;
12204 if (new_count != number_of_visible_frames)
12205 windows_or_buffers_changed++;
12208 /* Change frame size now if a change is pending. */
12209 do_pending_window_change (1);
12211 /* If we just did a pending size change, or have additional
12212 visible frames, redisplay again. */
12213 if (windows_or_buffers_changed && !pause)
12214 goto retry;
12216 /* Clear the face and image caches.
12218 We used to do this only if consider_all_windows_p. But the cache
12219 needs to be cleared if a timer creates images in the current
12220 buffer (e.g. the test case in Bug#6230). */
12222 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
12224 clear_face_cache (0);
12225 clear_face_cache_count = 0;
12228 #ifdef HAVE_WINDOW_SYSTEM
12229 if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT)
12231 clear_image_caches (Qnil);
12232 clear_image_cache_count = 0;
12234 #endif /* HAVE_WINDOW_SYSTEM */
12236 end_of_redisplay:
12237 unbind_to (count, Qnil);
12238 RESUME_POLLING;
12242 /* Redisplay, but leave alone any recent echo area message unless
12243 another message has been requested in its place.
12245 This is useful in situations where you need to redisplay but no
12246 user action has occurred, making it inappropriate for the message
12247 area to be cleared. See tracking_off and
12248 wait_reading_process_output for examples of these situations.
12250 FROM_WHERE is an integer saying from where this function was
12251 called. This is useful for debugging. */
12253 void
12254 redisplay_preserve_echo_area (int from_where)
12256 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
12258 if (!NILP (echo_area_buffer[1]))
12260 /* We have a previously displayed message, but no current
12261 message. Redisplay the previous message. */
12262 display_last_displayed_message_p = 1;
12263 redisplay_internal (1);
12264 display_last_displayed_message_p = 0;
12266 else
12267 redisplay_internal (1);
12269 if (FRAME_RIF (SELECTED_FRAME ()) != NULL
12270 && FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
12271 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (NULL);
12275 /* Function registered with record_unwind_protect in
12276 redisplay_internal. Reset redisplaying_p to the value it had
12277 before redisplay_internal was called, and clear
12278 prevent_freeing_realized_faces_p. It also selects the previously
12279 selected frame, unless it has been deleted (by an X connection
12280 failure during redisplay, for example). */
12282 static Lisp_Object
12283 unwind_redisplay (Lisp_Object val)
12285 Lisp_Object old_redisplaying_p, old_frame;
12287 old_redisplaying_p = XCAR (val);
12288 redisplaying_p = XFASTINT (old_redisplaying_p);
12289 old_frame = XCDR (val);
12290 if (! EQ (old_frame, selected_frame)
12291 && FRAME_LIVE_P (XFRAME (old_frame)))
12292 select_frame_for_redisplay (old_frame);
12293 return Qnil;
12297 /* Mark the display of window W as accurate or inaccurate. If
12298 ACCURATE_P is non-zero mark display of W as accurate. If
12299 ACCURATE_P is zero, arrange for W to be redisplayed the next time
12300 redisplay_internal is called. */
12302 static void
12303 mark_window_display_accurate_1 (struct window *w, int accurate_p)
12305 if (BUFFERP (w->buffer))
12307 struct buffer *b = XBUFFER (w->buffer);
12309 w->last_modified
12310 = make_number (accurate_p ? BUF_MODIFF (b) : 0);
12311 w->last_overlay_modified
12312 = make_number (accurate_p ? BUF_OVERLAY_MODIFF (b) : 0);
12313 w->last_had_star
12314 = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b) ? Qt : Qnil;
12316 if (accurate_p)
12318 b->clip_changed = 0;
12319 b->prevent_redisplay_optimizations_p = 0;
12321 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
12322 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
12323 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
12324 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
12326 w->current_matrix->buffer = b;
12327 w->current_matrix->begv = BUF_BEGV (b);
12328 w->current_matrix->zv = BUF_ZV (b);
12330 w->last_cursor = w->cursor;
12331 w->last_cursor_off_p = w->cursor_off_p;
12333 if (w == XWINDOW (selected_window))
12334 w->last_point = make_number (BUF_PT (b));
12335 else
12336 w->last_point = make_number (XMARKER (w->pointm)->charpos);
12340 if (accurate_p)
12342 w->window_end_valid = w->buffer;
12343 w->update_mode_line = Qnil;
12348 /* Mark the display of windows in the window tree rooted at WINDOW as
12349 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
12350 windows as accurate. If ACCURATE_P is zero, arrange for windows to
12351 be redisplayed the next time redisplay_internal is called. */
12353 void
12354 mark_window_display_accurate (Lisp_Object window, int accurate_p)
12356 struct window *w;
12358 for (; !NILP (window); window = w->next)
12360 w = XWINDOW (window);
12361 mark_window_display_accurate_1 (w, accurate_p);
12363 if (!NILP (w->vchild))
12364 mark_window_display_accurate (w->vchild, accurate_p);
12365 if (!NILP (w->hchild))
12366 mark_window_display_accurate (w->hchild, accurate_p);
12369 if (accurate_p)
12371 update_overlay_arrows (1);
12373 else
12375 /* Force a thorough redisplay the next time by setting
12376 last_arrow_position and last_arrow_string to t, which is
12377 unequal to any useful value of Voverlay_arrow_... */
12378 update_overlay_arrows (-1);
12383 /* Return value in display table DP (Lisp_Char_Table *) for character
12384 C. Since a display table doesn't have any parent, we don't have to
12385 follow parent. Do not call this function directly but use the
12386 macro DISP_CHAR_VECTOR. */
12388 Lisp_Object
12389 disp_char_vector (struct Lisp_Char_Table *dp, int c)
12391 Lisp_Object val;
12393 if (ASCII_CHAR_P (c))
12395 val = dp->ascii;
12396 if (SUB_CHAR_TABLE_P (val))
12397 val = XSUB_CHAR_TABLE (val)->contents[c];
12399 else
12401 Lisp_Object table;
12403 XSETCHAR_TABLE (table, dp);
12404 val = char_table_ref (table, c);
12406 if (NILP (val))
12407 val = dp->defalt;
12408 return val;
12413 /***********************************************************************
12414 Window Redisplay
12415 ***********************************************************************/
12417 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
12419 static void
12420 redisplay_windows (Lisp_Object window)
12422 while (!NILP (window))
12424 struct window *w = XWINDOW (window);
12426 if (!NILP (w->hchild))
12427 redisplay_windows (w->hchild);
12428 else if (!NILP (w->vchild))
12429 redisplay_windows (w->vchild);
12430 else if (!NILP (w->buffer))
12432 displayed_buffer = XBUFFER (w->buffer);
12433 /* Use list_of_error, not Qerror, so that
12434 we catch only errors and don't run the debugger. */
12435 internal_condition_case_1 (redisplay_window_0, window,
12436 list_of_error,
12437 redisplay_window_error);
12440 window = w->next;
12444 static Lisp_Object
12445 redisplay_window_error (Lisp_Object ignore)
12447 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
12448 return Qnil;
12451 static Lisp_Object
12452 redisplay_window_0 (Lisp_Object window)
12454 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
12455 redisplay_window (window, 0);
12456 return Qnil;
12459 static Lisp_Object
12460 redisplay_window_1 (Lisp_Object window)
12462 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
12463 redisplay_window (window, 1);
12464 return Qnil;
12468 /* Increment GLYPH until it reaches END or CONDITION fails while
12469 adding (GLYPH)->pixel_width to X. */
12471 #define SKIP_GLYPHS(glyph, end, x, condition) \
12472 do \
12474 (x) += (glyph)->pixel_width; \
12475 ++(glyph); \
12477 while ((glyph) < (end) && (condition))
12480 /* Set cursor position of W. PT is assumed to be displayed in ROW.
12481 DELTA and DELTA_BYTES are the numbers of characters and bytes by
12482 which positions recorded in ROW differ from current buffer
12483 positions.
12485 Return 0 if cursor is not on this row, 1 otherwise. */
12488 set_cursor_from_row (struct window *w, struct glyph_row *row,
12489 struct glyph_matrix *matrix, int delta, int delta_bytes,
12490 int dy, int dvpos)
12492 struct glyph *glyph = row->glyphs[TEXT_AREA];
12493 struct glyph *end = glyph + row->used[TEXT_AREA];
12494 struct glyph *cursor = NULL;
12495 /* The last known character position in row. */
12496 int last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
12497 int x = row->x;
12498 EMACS_INT pt_old = PT - delta;
12499 EMACS_INT pos_before = MATRIX_ROW_START_CHARPOS (row) + delta;
12500 EMACS_INT pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
12501 struct glyph *glyph_before = glyph - 1, *glyph_after = end;
12502 /* A glyph beyond the edge of TEXT_AREA which we should never
12503 touch. */
12504 struct glyph *glyphs_end = end;
12505 /* Non-zero means we've found a match for cursor position, but that
12506 glyph has the avoid_cursor_p flag set. */
12507 int match_with_avoid_cursor = 0;
12508 /* Non-zero means we've seen at least one glyph that came from a
12509 display string. */
12510 int string_seen = 0;
12511 /* Largest buffer position seen so far during scan of glyph row. */
12512 EMACS_INT bpos_max = last_pos;
12513 /* Last buffer position covered by an overlay string with an integer
12514 `cursor' property. */
12515 EMACS_INT bpos_covered = 0;
12517 /* Skip over glyphs not having an object at the start and the end of
12518 the row. These are special glyphs like truncation marks on
12519 terminal frames. */
12520 if (row->displays_text_p)
12522 if (!row->reversed_p)
12524 while (glyph < end
12525 && INTEGERP (glyph->object)
12526 && glyph->charpos < 0)
12528 x += glyph->pixel_width;
12529 ++glyph;
12531 while (end > glyph
12532 && INTEGERP ((end - 1)->object)
12533 /* CHARPOS is zero for blanks and stretch glyphs
12534 inserted by extend_face_to_end_of_line. */
12535 && (end - 1)->charpos <= 0)
12536 --end;
12537 glyph_before = glyph - 1;
12538 glyph_after = end;
12540 else
12542 struct glyph *g;
12544 /* If the glyph row is reversed, we need to process it from back
12545 to front, so swap the edge pointers. */
12546 glyphs_end = end = glyph - 1;
12547 glyph += row->used[TEXT_AREA] - 1;
12549 while (glyph > end + 1
12550 && INTEGERP (glyph->object)
12551 && glyph->charpos < 0)
12553 --glyph;
12554 x -= glyph->pixel_width;
12556 if (INTEGERP (glyph->object) && glyph->charpos < 0)
12557 --glyph;
12558 /* By default, in reversed rows we put the cursor on the
12559 rightmost (first in the reading order) glyph. */
12560 for (g = end + 1; g < glyph; g++)
12561 x += g->pixel_width;
12562 while (end < glyph
12563 && INTEGERP ((end + 1)->object)
12564 && (end + 1)->charpos <= 0)
12565 ++end;
12566 glyph_before = glyph + 1;
12567 glyph_after = end;
12570 else if (row->reversed_p)
12572 /* In R2L rows that don't display text, put the cursor on the
12573 rightmost glyph. Case in point: an empty last line that is
12574 part of an R2L paragraph. */
12575 cursor = end - 1;
12576 /* Avoid placing the cursor on the last glyph of the row, where
12577 on terminal frames we hold the vertical border between
12578 adjacent windows. */
12579 if (!FRAME_WINDOW_P (WINDOW_XFRAME (w))
12580 && !WINDOW_RIGHTMOST_P (w)
12581 && cursor == row->glyphs[LAST_AREA] - 1)
12582 cursor--;
12583 x = -1; /* will be computed below, at label compute_x */
12586 /* Step 1: Try to find the glyph whose character position
12587 corresponds to point. If that's not possible, find 2 glyphs
12588 whose character positions are the closest to point, one before
12589 point, the other after it. */
12590 if (!row->reversed_p)
12591 while (/* not marched to end of glyph row */
12592 glyph < end
12593 /* glyph was not inserted by redisplay for internal purposes */
12594 && !INTEGERP (glyph->object))
12596 if (BUFFERP (glyph->object))
12598 EMACS_INT dpos = glyph->charpos - pt_old;
12600 if (glyph->charpos > bpos_max)
12601 bpos_max = glyph->charpos;
12602 if (!glyph->avoid_cursor_p)
12604 /* If we hit point, we've found the glyph on which to
12605 display the cursor. */
12606 if (dpos == 0)
12608 match_with_avoid_cursor = 0;
12609 break;
12611 /* See if we've found a better approximation to
12612 POS_BEFORE or to POS_AFTER. Note that we want the
12613 first (leftmost) glyph of all those that are the
12614 closest from below, and the last (rightmost) of all
12615 those from above. */
12616 if (0 > dpos && dpos > pos_before - pt_old)
12618 pos_before = glyph->charpos;
12619 glyph_before = glyph;
12621 else if (0 < dpos && dpos <= pos_after - pt_old)
12623 pos_after = glyph->charpos;
12624 glyph_after = glyph;
12627 else if (dpos == 0)
12628 match_with_avoid_cursor = 1;
12630 else if (STRINGP (glyph->object))
12632 Lisp_Object chprop;
12633 int glyph_pos = glyph->charpos;
12635 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
12636 glyph->object);
12637 if (INTEGERP (chprop))
12639 bpos_covered = bpos_max + XINT (chprop);
12640 /* If the `cursor' property covers buffer positions up
12641 to and including point, we should display cursor on
12642 this glyph. Note that overlays and text properties
12643 with string values stop bidi reordering, so every
12644 buffer position to the left of the string is always
12645 smaller than any position to the right of the
12646 string. Therefore, if a `cursor' property on one
12647 of the string's characters has an integer value, we
12648 will break out of the loop below _before_ we get to
12649 the position match above. IOW, integer values of
12650 the `cursor' property override the "exact match for
12651 point" strategy of positioning the cursor. */
12652 /* Implementation note: bpos_max == pt_old when, e.g.,
12653 we are in an empty line, where bpos_max is set to
12654 MATRIX_ROW_START_CHARPOS, see above. */
12655 if (bpos_max <= pt_old && bpos_covered >= pt_old)
12657 cursor = glyph;
12658 break;
12662 string_seen = 1;
12664 x += glyph->pixel_width;
12665 ++glyph;
12667 else if (glyph > end) /* row is reversed */
12668 while (!INTEGERP (glyph->object))
12670 if (BUFFERP (glyph->object))
12672 EMACS_INT dpos = glyph->charpos - pt_old;
12674 if (glyph->charpos > bpos_max)
12675 bpos_max = glyph->charpos;
12676 if (!glyph->avoid_cursor_p)
12678 if (dpos == 0)
12680 match_with_avoid_cursor = 0;
12681 break;
12683 if (0 > dpos && dpos > pos_before - pt_old)
12685 pos_before = glyph->charpos;
12686 glyph_before = glyph;
12688 else if (0 < dpos && dpos <= pos_after - pt_old)
12690 pos_after = glyph->charpos;
12691 glyph_after = glyph;
12694 else if (dpos == 0)
12695 match_with_avoid_cursor = 1;
12697 else if (STRINGP (glyph->object))
12699 Lisp_Object chprop;
12700 int glyph_pos = glyph->charpos;
12702 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
12703 glyph->object);
12704 if (INTEGERP (chprop))
12706 bpos_covered = bpos_max + XINT (chprop);
12707 /* If the `cursor' property covers buffer positions up
12708 to and including point, we should display cursor on
12709 this glyph. */
12710 if (bpos_max <= pt_old && bpos_covered >= pt_old)
12712 cursor = glyph;
12713 break;
12716 string_seen = 1;
12718 --glyph;
12719 if (glyph == glyphs_end) /* don't dereference outside TEXT_AREA */
12721 x--; /* can't use any pixel_width */
12722 break;
12724 x -= glyph->pixel_width;
12727 /* Step 2: If we didn't find an exact match for point, we need to
12728 look for a proper place to put the cursor among glyphs between
12729 GLYPH_BEFORE and GLYPH_AFTER. */
12730 if (!((row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
12731 && BUFFERP (glyph->object) && glyph->charpos == pt_old)
12732 && bpos_covered < pt_old)
12734 if (row->ends_in_ellipsis_p && pos_after == last_pos)
12736 EMACS_INT ellipsis_pos;
12738 /* Scan back over the ellipsis glyphs. */
12739 if (!row->reversed_p)
12741 ellipsis_pos = (glyph - 1)->charpos;
12742 while (glyph > row->glyphs[TEXT_AREA]
12743 && (glyph - 1)->charpos == ellipsis_pos)
12744 glyph--, x -= glyph->pixel_width;
12745 /* That loop always goes one position too far, including
12746 the glyph before the ellipsis. So scan forward over
12747 that one. */
12748 x += glyph->pixel_width;
12749 glyph++;
12751 else /* row is reversed */
12753 ellipsis_pos = (glyph + 1)->charpos;
12754 while (glyph < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
12755 && (glyph + 1)->charpos == ellipsis_pos)
12756 glyph++, x += glyph->pixel_width;
12757 x -= glyph->pixel_width;
12758 glyph--;
12761 else if (match_with_avoid_cursor
12762 /* zero-width characters produce no glyphs */
12763 || ((row->reversed_p
12764 ? glyph_after > glyphs_end
12765 : glyph_after < glyphs_end)
12766 && eabs (glyph_after - glyph_before) == 1))
12768 cursor = glyph_after;
12769 x = -1;
12771 else if (string_seen)
12773 int incr = row->reversed_p ? -1 : +1;
12775 /* Need to find the glyph that came out of a string which is
12776 present at point. That glyph is somewhere between
12777 GLYPH_BEFORE and GLYPH_AFTER, and it came from a string
12778 positioned between POS_BEFORE and POS_AFTER in the
12779 buffer. */
12780 struct glyph *stop = glyph_after;
12781 EMACS_INT pos = pos_before;
12783 x = -1;
12784 for (glyph = glyph_before + incr;
12785 row->reversed_p ? glyph > stop : glyph < stop; )
12788 /* Any glyphs that come from the buffer are here because
12789 of bidi reordering. Skip them, and only pay
12790 attention to glyphs that came from some string. */
12791 if (STRINGP (glyph->object))
12793 Lisp_Object str;
12794 EMACS_INT tem;
12796 str = glyph->object;
12797 tem = string_buffer_position_lim (w, str, pos, pos_after, 0);
12798 if (tem == 0 /* from overlay */
12799 || pos <= tem)
12801 /* If the string from which this glyph came is
12802 found in the buffer at point, then we've
12803 found the glyph we've been looking for. If
12804 it comes from an overlay (tem == 0), and it
12805 has the `cursor' property on one of its
12806 glyphs, record that glyph as a candidate for
12807 displaying the cursor. (As in the
12808 unidirectional version, we will display the
12809 cursor on the last candidate we find.) */
12810 if (tem == 0 || tem == pt_old)
12812 /* The glyphs from this string could have
12813 been reordered. Find the one with the
12814 smallest string position. Or there could
12815 be a character in the string with the
12816 `cursor' property, which means display
12817 cursor on that character's glyph. */
12818 int strpos = glyph->charpos;
12820 cursor = glyph;
12821 for (glyph += incr;
12822 (row->reversed_p ? glyph > stop : glyph < stop)
12823 && EQ (glyph->object, str);
12824 glyph += incr)
12826 Lisp_Object cprop;
12827 int gpos = glyph->charpos;
12829 cprop = Fget_char_property (make_number (gpos),
12830 Qcursor,
12831 glyph->object);
12832 if (!NILP (cprop))
12834 cursor = glyph;
12835 break;
12837 if (glyph->charpos < strpos)
12839 strpos = glyph->charpos;
12840 cursor = glyph;
12844 if (tem == pt_old)
12845 goto compute_x;
12847 if (tem)
12848 pos = tem + 1; /* don't find previous instances */
12850 /* This string is not what we want; skip all of the
12851 glyphs that came from it. */
12853 glyph += incr;
12854 while ((row->reversed_p ? glyph > stop : glyph < stop)
12855 && EQ (glyph->object, str));
12857 else
12858 glyph += incr;
12861 /* If we reached the end of the line, and END was from a string,
12862 the cursor is not on this line. */
12863 if (cursor == NULL
12864 && (row->reversed_p ? glyph <= end : glyph >= end)
12865 && STRINGP (end->object)
12866 && row->continued_p)
12867 return 0;
12871 compute_x:
12872 if (cursor != NULL)
12873 glyph = cursor;
12874 if (x < 0)
12876 struct glyph *g;
12878 /* Need to compute x that corresponds to GLYPH. */
12879 for (g = row->glyphs[TEXT_AREA], x = row->x; g < glyph; g++)
12881 if (g >= row->glyphs[TEXT_AREA] + row->used[TEXT_AREA])
12882 abort ();
12883 x += g->pixel_width;
12887 /* ROW could be part of a continued line, which, under bidi
12888 reordering, might have other rows whose start and end charpos
12889 occlude point. Only set w->cursor if we found a better
12890 approximation to the cursor position than we have from previously
12891 examined candidate rows belonging to the same continued line. */
12892 if (/* we already have a candidate row */
12893 w->cursor.vpos >= 0
12894 /* that candidate is not the row we are processing */
12895 && MATRIX_ROW (matrix, w->cursor.vpos) != row
12896 /* the row we are processing is part of a continued line */
12897 && (row->continued_p || MATRIX_ROW_CONTINUATION_LINE_P (row))
12898 /* Make sure cursor.vpos specifies a row whose start and end
12899 charpos occlude point. This is because some callers of this
12900 function leave cursor.vpos at the row where the cursor was
12901 displayed during the last redisplay cycle. */
12902 && MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos)) <= pt_old
12903 && pt_old < MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos)))
12905 struct glyph *g1 =
12906 MATRIX_ROW_GLYPH_START (matrix, w->cursor.vpos) + w->cursor.hpos;
12908 /* Don't consider glyphs that are outside TEXT_AREA. */
12909 if (!(row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end))
12910 return 0;
12911 /* Keep the candidate whose buffer position is the closest to
12912 point. */
12913 if (/* previous candidate is a glyph in TEXT_AREA of that row */
12914 w->cursor.hpos >= 0
12915 && w->cursor.hpos < MATRIX_ROW_USED (matrix, w->cursor.vpos)
12916 && BUFFERP (g1->object)
12917 && (g1->charpos == pt_old /* an exact match always wins */
12918 || (BUFFERP (glyph->object)
12919 && eabs (g1->charpos - pt_old)
12920 < eabs (glyph->charpos - pt_old))))
12921 return 0;
12922 /* If this candidate gives an exact match, use that. */
12923 if (!(BUFFERP (glyph->object) && glyph->charpos == pt_old)
12924 /* Otherwise, keep the candidate that comes from a row
12925 spanning less buffer positions. This may win when one or
12926 both candidate positions are on glyphs that came from
12927 display strings, for which we cannot compare buffer
12928 positions. */
12929 && MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
12930 - MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
12931 < MATRIX_ROW_END_CHARPOS (row) - MATRIX_ROW_START_CHARPOS (row))
12932 return 0;
12934 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
12935 w->cursor.x = x;
12936 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
12937 w->cursor.y = row->y + dy;
12939 if (w == XWINDOW (selected_window))
12941 if (!row->continued_p
12942 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
12943 && row->x == 0)
12945 this_line_buffer = XBUFFER (w->buffer);
12947 CHARPOS (this_line_start_pos)
12948 = MATRIX_ROW_START_CHARPOS (row) + delta;
12949 BYTEPOS (this_line_start_pos)
12950 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
12952 CHARPOS (this_line_end_pos)
12953 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
12954 BYTEPOS (this_line_end_pos)
12955 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
12957 this_line_y = w->cursor.y;
12958 this_line_pixel_height = row->height;
12959 this_line_vpos = w->cursor.vpos;
12960 this_line_start_x = row->x;
12962 else
12963 CHARPOS (this_line_start_pos) = 0;
12966 return 1;
12970 /* Run window scroll functions, if any, for WINDOW with new window
12971 start STARTP. Sets the window start of WINDOW to that position.
12973 We assume that the window's buffer is really current. */
12975 static INLINE struct text_pos
12976 run_window_scroll_functions (Lisp_Object window, struct text_pos startp)
12978 struct window *w = XWINDOW (window);
12979 SET_MARKER_FROM_TEXT_POS (w->start, startp);
12981 if (current_buffer != XBUFFER (w->buffer))
12982 abort ();
12984 if (!NILP (Vwindow_scroll_functions))
12986 run_hook_with_args_2 (Qwindow_scroll_functions, window,
12987 make_number (CHARPOS (startp)));
12988 SET_TEXT_POS_FROM_MARKER (startp, w->start);
12989 /* In case the hook functions switch buffers. */
12990 if (current_buffer != XBUFFER (w->buffer))
12991 set_buffer_internal_1 (XBUFFER (w->buffer));
12994 return startp;
12998 /* Make sure the line containing the cursor is fully visible.
12999 A value of 1 means there is nothing to be done.
13000 (Either the line is fully visible, or it cannot be made so,
13001 or we cannot tell.)
13003 If FORCE_P is non-zero, return 0 even if partial visible cursor row
13004 is higher than window.
13006 A value of 0 means the caller should do scrolling
13007 as if point had gone off the screen. */
13009 static int
13010 cursor_row_fully_visible_p (struct window *w, int force_p, int current_matrix_p)
13012 struct glyph_matrix *matrix;
13013 struct glyph_row *row;
13014 int window_height;
13016 if (!make_cursor_line_fully_visible_p)
13017 return 1;
13019 /* It's not always possible to find the cursor, e.g, when a window
13020 is full of overlay strings. Don't do anything in that case. */
13021 if (w->cursor.vpos < 0)
13022 return 1;
13024 matrix = current_matrix_p ? w->current_matrix : w->desired_matrix;
13025 row = MATRIX_ROW (matrix, w->cursor.vpos);
13027 /* If the cursor row is not partially visible, there's nothing to do. */
13028 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row))
13029 return 1;
13031 /* If the row the cursor is in is taller than the window's height,
13032 it's not clear what to do, so do nothing. */
13033 window_height = window_box_height (w);
13034 if (row->height >= window_height)
13036 if (!force_p || MINI_WINDOW_P (w)
13037 || w->vscroll || w->cursor.vpos == 0)
13038 return 1;
13040 return 0;
13044 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
13045 non-zero means only WINDOW is redisplayed in redisplay_internal.
13046 TEMP_SCROLL_STEP has the same meaning as scroll_step, and is used
13047 in redisplay_window to bring a partially visible line into view in
13048 the case that only the cursor has moved.
13050 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
13051 last screen line's vertical height extends past the end of the screen.
13053 Value is
13055 1 if scrolling succeeded
13057 0 if scrolling didn't find point.
13059 -1 if new fonts have been loaded so that we must interrupt
13060 redisplay, adjust glyph matrices, and try again. */
13062 enum
13064 SCROLLING_SUCCESS,
13065 SCROLLING_FAILED,
13066 SCROLLING_NEED_LARGER_MATRICES
13069 static int
13070 try_scrolling (Lisp_Object window, int just_this_one_p,
13071 EMACS_INT scroll_conservatively, EMACS_INT scroll_step,
13072 int temp_scroll_step, int last_line_misfit)
13074 struct window *w = XWINDOW (window);
13075 struct frame *f = XFRAME (w->frame);
13076 struct text_pos pos, startp;
13077 struct it it;
13078 int this_scroll_margin, scroll_max, rc, height;
13079 int dy = 0, amount_to_scroll = 0, scroll_down_p = 0;
13080 int extra_scroll_margin_lines = last_line_misfit ? 1 : 0;
13081 Lisp_Object aggressive;
13082 int scroll_limit = INT_MAX / FRAME_LINE_HEIGHT (f);
13084 #if GLYPH_DEBUG
13085 debug_method_add (w, "try_scrolling");
13086 #endif
13088 SET_TEXT_POS_FROM_MARKER (startp, w->start);
13090 /* Compute scroll margin height in pixels. We scroll when point is
13091 within this distance from the top or bottom of the window. */
13092 if (scroll_margin > 0)
13093 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4)
13094 * FRAME_LINE_HEIGHT (f);
13095 else
13096 this_scroll_margin = 0;
13098 /* Force scroll_conservatively to have a reasonable value, to avoid
13099 overflow while computing how much to scroll. Note that the user
13100 can supply scroll-conservatively equal to `most-positive-fixnum',
13101 which can be larger than INT_MAX. */
13102 if (scroll_conservatively > scroll_limit)
13104 scroll_conservatively = scroll_limit;
13105 scroll_max = INT_MAX;
13107 else if (scroll_step || scroll_conservatively || temp_scroll_step)
13108 /* Compute how much we should try to scroll maximally to bring
13109 point into view. */
13110 scroll_max = (max (scroll_step,
13111 max (scroll_conservatively, temp_scroll_step))
13112 * FRAME_LINE_HEIGHT (f));
13113 else if (NUMBERP (current_buffer->scroll_down_aggressively)
13114 || NUMBERP (current_buffer->scroll_up_aggressively))
13115 /* We're trying to scroll because of aggressive scrolling but no
13116 scroll_step is set. Choose an arbitrary one. */
13117 scroll_max = 10 * FRAME_LINE_HEIGHT (f);
13118 else
13119 scroll_max = 0;
13121 too_near_end:
13123 /* Decide whether to scroll down. */
13124 if (PT > CHARPOS (startp))
13126 int scroll_margin_y;
13128 /* Compute the pixel ypos of the scroll margin, then move it to
13129 either that ypos or PT, whichever comes first. */
13130 start_display (&it, w, startp);
13131 scroll_margin_y = it.last_visible_y - this_scroll_margin
13132 - FRAME_LINE_HEIGHT (f) * extra_scroll_margin_lines;
13133 move_it_to (&it, PT, -1, scroll_margin_y - 1, -1,
13134 (MOVE_TO_POS | MOVE_TO_Y));
13136 if (PT > CHARPOS (it.current.pos))
13138 int y0 = line_bottom_y (&it);
13139 /* Compute how many pixels below window bottom to stop searching
13140 for PT. This avoids costly search for PT that is far away if
13141 the user limited scrolling by a small number of lines, but
13142 always finds PT if scroll_conservatively is set to a large
13143 number, such as most-positive-fixnum. */
13144 int slack = max (scroll_max, 10 * FRAME_LINE_HEIGHT (f));
13145 int y_to_move =
13146 slack >= INT_MAX - it.last_visible_y
13147 ? INT_MAX
13148 : it.last_visible_y + slack;
13150 /* Compute the distance from the scroll margin to PT or to
13151 the scroll limit, whichever comes first. This should
13152 include the height of the cursor line, to make that line
13153 fully visible. */
13154 move_it_to (&it, PT, -1, y_to_move,
13155 -1, MOVE_TO_POS | MOVE_TO_Y);
13156 dy = line_bottom_y (&it) - y0;
13158 if (dy > scroll_max)
13159 return SCROLLING_FAILED;
13161 scroll_down_p = 1;
13165 if (scroll_down_p)
13167 /* Point is in or below the bottom scroll margin, so move the
13168 window start down. If scrolling conservatively, move it just
13169 enough down to make point visible. If scroll_step is set,
13170 move it down by scroll_step. */
13171 if (scroll_conservatively)
13172 amount_to_scroll
13173 = min (max (dy, FRAME_LINE_HEIGHT (f)),
13174 FRAME_LINE_HEIGHT (f) * scroll_conservatively);
13175 else if (scroll_step || temp_scroll_step)
13176 amount_to_scroll = scroll_max;
13177 else
13179 aggressive = current_buffer->scroll_up_aggressively;
13180 height = WINDOW_BOX_TEXT_HEIGHT (w);
13181 if (NUMBERP (aggressive))
13183 double float_amount = XFLOATINT (aggressive) * height;
13184 amount_to_scroll = float_amount;
13185 if (amount_to_scroll == 0 && float_amount > 0)
13186 amount_to_scroll = 1;
13190 if (amount_to_scroll <= 0)
13191 return SCROLLING_FAILED;
13193 start_display (&it, w, startp);
13194 if (scroll_max < INT_MAX)
13195 move_it_vertically (&it, amount_to_scroll);
13196 else
13198 /* Extra precision for users who set scroll-conservatively
13199 to most-positive-fixnum: make sure the amount we scroll
13200 the window start is never less than amount_to_scroll,
13201 which was computed as distance from window bottom to
13202 point. This matters when lines at window top and lines
13203 below window bottom have different height. */
13204 struct it it1 = it;
13205 /* We use a temporary it1 because line_bottom_y can modify
13206 its argument, if it moves one line down; see there. */
13207 int start_y = line_bottom_y (&it1);
13209 do {
13210 move_it_by_lines (&it, 1, 1);
13211 it1 = it;
13212 } while (line_bottom_y (&it1) - start_y < amount_to_scroll);
13215 /* If STARTP is unchanged, move it down another screen line. */
13216 if (CHARPOS (it.current.pos) == CHARPOS (startp))
13217 move_it_by_lines (&it, 1, 1);
13218 startp = it.current.pos;
13220 else
13222 struct text_pos scroll_margin_pos = startp;
13224 /* See if point is inside the scroll margin at the top of the
13225 window. */
13226 if (this_scroll_margin)
13228 start_display (&it, w, startp);
13229 move_it_vertically (&it, this_scroll_margin);
13230 scroll_margin_pos = it.current.pos;
13233 if (PT < CHARPOS (scroll_margin_pos))
13235 /* Point is in the scroll margin at the top of the window or
13236 above what is displayed in the window. */
13237 int y0;
13239 /* Compute the vertical distance from PT to the scroll
13240 margin position. Give up if distance is greater than
13241 scroll_max. */
13242 SET_TEXT_POS (pos, PT, PT_BYTE);
13243 start_display (&it, w, pos);
13244 y0 = it.current_y;
13245 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
13246 it.last_visible_y, -1,
13247 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
13248 dy = it.current_y - y0;
13249 if (dy > scroll_max)
13250 return SCROLLING_FAILED;
13252 /* Compute new window start. */
13253 start_display (&it, w, startp);
13255 if (scroll_conservatively)
13256 amount_to_scroll
13257 = max (dy, FRAME_LINE_HEIGHT (f) * max (scroll_step, temp_scroll_step));
13258 else if (scroll_step || temp_scroll_step)
13259 amount_to_scroll = scroll_max;
13260 else
13262 aggressive = current_buffer->scroll_down_aggressively;
13263 height = WINDOW_BOX_TEXT_HEIGHT (w);
13264 if (NUMBERP (aggressive))
13266 double float_amount = XFLOATINT (aggressive) * height;
13267 amount_to_scroll = float_amount;
13268 if (amount_to_scroll == 0 && float_amount > 0)
13269 amount_to_scroll = 1;
13273 if (amount_to_scroll <= 0)
13274 return SCROLLING_FAILED;
13276 move_it_vertically_backward (&it, amount_to_scroll);
13277 startp = it.current.pos;
13281 /* Run window scroll functions. */
13282 startp = run_window_scroll_functions (window, startp);
13284 /* Display the window. Give up if new fonts are loaded, or if point
13285 doesn't appear. */
13286 if (!try_window (window, startp, 0))
13287 rc = SCROLLING_NEED_LARGER_MATRICES;
13288 else if (w->cursor.vpos < 0)
13290 clear_glyph_matrix (w->desired_matrix);
13291 rc = SCROLLING_FAILED;
13293 else
13295 /* Maybe forget recorded base line for line number display. */
13296 if (!just_this_one_p
13297 || current_buffer->clip_changed
13298 || BEG_UNCHANGED < CHARPOS (startp))
13299 w->base_line_number = Qnil;
13301 /* If cursor ends up on a partially visible line,
13302 treat that as being off the bottom of the screen. */
13303 if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1, 0))
13305 clear_glyph_matrix (w->desired_matrix);
13306 ++extra_scroll_margin_lines;
13307 goto too_near_end;
13309 rc = SCROLLING_SUCCESS;
13312 return rc;
13316 /* Compute a suitable window start for window W if display of W starts
13317 on a continuation line. Value is non-zero if a new window start
13318 was computed.
13320 The new window start will be computed, based on W's width, starting
13321 from the start of the continued line. It is the start of the
13322 screen line with the minimum distance from the old start W->start. */
13324 static int
13325 compute_window_start_on_continuation_line (struct window *w)
13327 struct text_pos pos, start_pos;
13328 int window_start_changed_p = 0;
13330 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
13332 /* If window start is on a continuation line... Window start may be
13333 < BEGV in case there's invisible text at the start of the
13334 buffer (M-x rmail, for example). */
13335 if (CHARPOS (start_pos) > BEGV
13336 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
13338 struct it it;
13339 struct glyph_row *row;
13341 /* Handle the case that the window start is out of range. */
13342 if (CHARPOS (start_pos) < BEGV)
13343 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
13344 else if (CHARPOS (start_pos) > ZV)
13345 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
13347 /* Find the start of the continued line. This should be fast
13348 because scan_buffer is fast (newline cache). */
13349 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
13350 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
13351 row, DEFAULT_FACE_ID);
13352 reseat_at_previous_visible_line_start (&it);
13354 /* If the line start is "too far" away from the window start,
13355 say it takes too much time to compute a new window start. */
13356 if (CHARPOS (start_pos) - IT_CHARPOS (it)
13357 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
13359 int min_distance, distance;
13361 /* Move forward by display lines to find the new window
13362 start. If window width was enlarged, the new start can
13363 be expected to be > the old start. If window width was
13364 decreased, the new window start will be < the old start.
13365 So, we're looking for the display line start with the
13366 minimum distance from the old window start. */
13367 pos = it.current.pos;
13368 min_distance = INFINITY;
13369 while ((distance = eabs (CHARPOS (start_pos) - IT_CHARPOS (it))),
13370 distance < min_distance)
13372 min_distance = distance;
13373 pos = it.current.pos;
13374 move_it_by_lines (&it, 1, 0);
13377 /* Set the window start there. */
13378 SET_MARKER_FROM_TEXT_POS (w->start, pos);
13379 window_start_changed_p = 1;
13383 return window_start_changed_p;
13387 /* Try cursor movement in case text has not changed in window WINDOW,
13388 with window start STARTP. Value is
13390 CURSOR_MOVEMENT_SUCCESS if successful
13392 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
13394 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
13395 display. *SCROLL_STEP is set to 1, under certain circumstances, if
13396 we want to scroll as if scroll-step were set to 1. See the code.
13398 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
13399 which case we have to abort this redisplay, and adjust matrices
13400 first. */
13402 enum
13404 CURSOR_MOVEMENT_SUCCESS,
13405 CURSOR_MOVEMENT_CANNOT_BE_USED,
13406 CURSOR_MOVEMENT_MUST_SCROLL,
13407 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
13410 static int
13411 try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_step)
13413 struct window *w = XWINDOW (window);
13414 struct frame *f = XFRAME (w->frame);
13415 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
13417 #if GLYPH_DEBUG
13418 if (inhibit_try_cursor_movement)
13419 return rc;
13420 #endif
13422 /* Handle case where text has not changed, only point, and it has
13423 not moved off the frame. */
13424 if (/* Point may be in this window. */
13425 PT >= CHARPOS (startp)
13426 /* Selective display hasn't changed. */
13427 && !current_buffer->clip_changed
13428 /* Function force-mode-line-update is used to force a thorough
13429 redisplay. It sets either windows_or_buffers_changed or
13430 update_mode_lines. So don't take a shortcut here for these
13431 cases. */
13432 && !update_mode_lines
13433 && !windows_or_buffers_changed
13434 && !cursor_type_changed
13435 /* Can't use this case if highlighting a region. When a
13436 region exists, cursor movement has to do more than just
13437 set the cursor. */
13438 && !(!NILP (Vtransient_mark_mode)
13439 && !NILP (current_buffer->mark_active))
13440 && NILP (w->region_showing)
13441 && NILP (Vshow_trailing_whitespace)
13442 /* Right after splitting windows, last_point may be nil. */
13443 && INTEGERP (w->last_point)
13444 /* This code is not used for mini-buffer for the sake of the case
13445 of redisplaying to replace an echo area message; since in
13446 that case the mini-buffer contents per se are usually
13447 unchanged. This code is of no real use in the mini-buffer
13448 since the handling of this_line_start_pos, etc., in redisplay
13449 handles the same cases. */
13450 && !EQ (window, minibuf_window)
13451 /* When splitting windows or for new windows, it happens that
13452 redisplay is called with a nil window_end_vpos or one being
13453 larger than the window. This should really be fixed in
13454 window.c. I don't have this on my list, now, so we do
13455 approximately the same as the old redisplay code. --gerd. */
13456 && INTEGERP (w->window_end_vpos)
13457 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
13458 && (FRAME_WINDOW_P (f)
13459 || !overlay_arrow_in_current_buffer_p ()))
13461 int this_scroll_margin, top_scroll_margin;
13462 struct glyph_row *row = NULL;
13464 #if GLYPH_DEBUG
13465 debug_method_add (w, "cursor movement");
13466 #endif
13468 /* Scroll if point within this distance from the top or bottom
13469 of the window. This is a pixel value. */
13470 if (scroll_margin > 0)
13472 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
13473 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
13475 else
13476 this_scroll_margin = 0;
13478 top_scroll_margin = this_scroll_margin;
13479 if (WINDOW_WANTS_HEADER_LINE_P (w))
13480 top_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w);
13482 /* Start with the row the cursor was displayed during the last
13483 not paused redisplay. Give up if that row is not valid. */
13484 if (w->last_cursor.vpos < 0
13485 || w->last_cursor.vpos >= w->current_matrix->nrows)
13486 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13487 else
13489 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
13490 if (row->mode_line_p)
13491 ++row;
13492 if (!row->enabled_p)
13493 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13496 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
13498 int scroll_p = 0, must_scroll = 0;
13499 int last_y = window_text_bottom_y (w) - this_scroll_margin;
13501 if (PT > XFASTINT (w->last_point))
13503 /* Point has moved forward. */
13504 while (MATRIX_ROW_END_CHARPOS (row) < PT
13505 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
13507 xassert (row->enabled_p);
13508 ++row;
13511 /* If the end position of a row equals the start
13512 position of the next row, and PT is at that position,
13513 we would rather display cursor in the next line. */
13514 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
13515 && MATRIX_ROW_END_CHARPOS (row) == PT
13516 && row < w->current_matrix->rows
13517 + w->current_matrix->nrows - 1
13518 && MATRIX_ROW_START_CHARPOS (row+1) == PT
13519 && !cursor_row_p (w, row))
13520 ++row;
13522 /* If within the scroll margin, scroll. Note that
13523 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
13524 the next line would be drawn, and that
13525 this_scroll_margin can be zero. */
13526 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
13527 || PT > MATRIX_ROW_END_CHARPOS (row)
13528 /* Line is completely visible last line in window
13529 and PT is to be set in the next line. */
13530 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
13531 && PT == MATRIX_ROW_END_CHARPOS (row)
13532 && !row->ends_at_zv_p
13533 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
13534 scroll_p = 1;
13536 else if (PT < XFASTINT (w->last_point))
13538 /* Cursor has to be moved backward. Note that PT >=
13539 CHARPOS (startp) because of the outer if-statement. */
13540 while (!row->mode_line_p
13541 && (MATRIX_ROW_START_CHARPOS (row) > PT
13542 || (MATRIX_ROW_START_CHARPOS (row) == PT
13543 && (MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)
13544 || (/* STARTS_IN_MIDDLE_OF_STRING_P (row) */
13545 row > w->current_matrix->rows
13546 && (row-1)->ends_in_newline_from_string_p))))
13547 && (row->y > top_scroll_margin
13548 || CHARPOS (startp) == BEGV))
13550 xassert (row->enabled_p);
13551 --row;
13554 /* Consider the following case: Window starts at BEGV,
13555 there is invisible, intangible text at BEGV, so that
13556 display starts at some point START > BEGV. It can
13557 happen that we are called with PT somewhere between
13558 BEGV and START. Try to handle that case. */
13559 if (row < w->current_matrix->rows
13560 || row->mode_line_p)
13562 row = w->current_matrix->rows;
13563 if (row->mode_line_p)
13564 ++row;
13567 /* Due to newlines in overlay strings, we may have to
13568 skip forward over overlay strings. */
13569 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
13570 && MATRIX_ROW_END_CHARPOS (row) == PT
13571 && !cursor_row_p (w, row))
13572 ++row;
13574 /* If within the scroll margin, scroll. */
13575 if (row->y < top_scroll_margin
13576 && CHARPOS (startp) != BEGV)
13577 scroll_p = 1;
13579 else
13581 /* Cursor did not move. So don't scroll even if cursor line
13582 is partially visible, as it was so before. */
13583 rc = CURSOR_MOVEMENT_SUCCESS;
13586 if (PT < MATRIX_ROW_START_CHARPOS (row)
13587 || PT > MATRIX_ROW_END_CHARPOS (row))
13589 /* if PT is not in the glyph row, give up. */
13590 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13591 must_scroll = 1;
13593 else if (rc != CURSOR_MOVEMENT_SUCCESS
13594 && !NILP (XBUFFER (w->buffer)->bidi_display_reordering))
13596 /* If rows are bidi-reordered and point moved, back up
13597 until we find a row that does not belong to a
13598 continuation line. This is because we must consider
13599 all rows of a continued line as candidates for the
13600 new cursor positioning, since row start and end
13601 positions change non-linearly with vertical position
13602 in such rows. */
13603 /* FIXME: Revisit this when glyph ``spilling'' in
13604 continuation lines' rows is implemented for
13605 bidi-reordered rows. */
13606 while (MATRIX_ROW_CONTINUATION_LINE_P (row))
13608 xassert (row->enabled_p);
13609 --row;
13610 /* If we hit the beginning of the displayed portion
13611 without finding the first row of a continued
13612 line, give up. */
13613 if (row <= w->current_matrix->rows)
13615 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13616 break;
13621 if (must_scroll)
13623 else if (rc != CURSOR_MOVEMENT_SUCCESS
13624 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
13625 && make_cursor_line_fully_visible_p)
13627 if (PT == MATRIX_ROW_END_CHARPOS (row)
13628 && !row->ends_at_zv_p
13629 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
13630 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13631 else if (row->height > window_box_height (w))
13633 /* If we end up in a partially visible line, let's
13634 make it fully visible, except when it's taller
13635 than the window, in which case we can't do much
13636 about it. */
13637 *scroll_step = 1;
13638 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13640 else
13642 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
13643 if (!cursor_row_fully_visible_p (w, 0, 1))
13644 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13645 else
13646 rc = CURSOR_MOVEMENT_SUCCESS;
13649 else if (scroll_p)
13650 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13651 else if (rc != CURSOR_MOVEMENT_SUCCESS
13652 && !NILP (XBUFFER (w->buffer)->bidi_display_reordering))
13654 /* With bidi-reordered rows, there could be more than
13655 one candidate row whose start and end positions
13656 occlude point. We need to let set_cursor_from_row
13657 find the best candidate. */
13658 /* FIXME: Revisit this when glyph ``spilling'' in
13659 continuation lines' rows is implemented for
13660 bidi-reordered rows. */
13661 int rv = 0;
13665 if (MATRIX_ROW_START_CHARPOS (row) <= PT
13666 && PT <= MATRIX_ROW_END_CHARPOS (row)
13667 && cursor_row_p (w, row))
13668 rv |= set_cursor_from_row (w, row, w->current_matrix,
13669 0, 0, 0, 0);
13670 /* As soon as we've found the first suitable row
13671 whose ends_at_zv_p flag is set, we are done. */
13672 if (rv
13673 && MATRIX_ROW (w->current_matrix, w->cursor.vpos)->ends_at_zv_p)
13675 rc = CURSOR_MOVEMENT_SUCCESS;
13676 break;
13678 ++row;
13680 while ((MATRIX_ROW_CONTINUATION_LINE_P (row)
13681 && MATRIX_ROW_BOTTOM_Y (row) <= last_y)
13682 || (MATRIX_ROW_START_CHARPOS (row) == PT
13683 && MATRIX_ROW_BOTTOM_Y (row) < last_y));
13684 /* If we didn't find any candidate rows, or exited the
13685 loop before all the candidates were examined, signal
13686 to the caller that this method failed. */
13687 if (rc != CURSOR_MOVEMENT_SUCCESS
13688 && (!rv || MATRIX_ROW_CONTINUATION_LINE_P (row)))
13689 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13690 else if (rv)
13691 rc = CURSOR_MOVEMENT_SUCCESS;
13693 else
13697 if (set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0))
13699 rc = CURSOR_MOVEMENT_SUCCESS;
13700 break;
13702 ++row;
13704 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
13705 && MATRIX_ROW_START_CHARPOS (row) == PT
13706 && cursor_row_p (w, row));
13711 return rc;
13714 void
13715 set_vertical_scroll_bar (struct window *w)
13717 int start, end, whole;
13719 /* Calculate the start and end positions for the current window.
13720 At some point, it would be nice to choose between scrollbars
13721 which reflect the whole buffer size, with special markers
13722 indicating narrowing, and scrollbars which reflect only the
13723 visible region.
13725 Note that mini-buffers sometimes aren't displaying any text. */
13726 if (!MINI_WINDOW_P (w)
13727 || (w == XWINDOW (minibuf_window)
13728 && NILP (echo_area_buffer[0])))
13730 struct buffer *buf = XBUFFER (w->buffer);
13731 whole = BUF_ZV (buf) - BUF_BEGV (buf);
13732 start = marker_position (w->start) - BUF_BEGV (buf);
13733 /* I don't think this is guaranteed to be right. For the
13734 moment, we'll pretend it is. */
13735 end = BUF_Z (buf) - XFASTINT (w->window_end_pos) - BUF_BEGV (buf);
13737 if (end < start)
13738 end = start;
13739 if (whole < (end - start))
13740 whole = end - start;
13742 else
13743 start = end = whole = 0;
13745 /* Indicate what this scroll bar ought to be displaying now. */
13746 if (FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
13747 (*FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
13748 (w, end - start, whole, start);
13752 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
13753 selected_window is redisplayed.
13755 We can return without actually redisplaying the window if
13756 fonts_changed_p is nonzero. In that case, redisplay_internal will
13757 retry. */
13759 static void
13760 redisplay_window (Lisp_Object window, int just_this_one_p)
13762 struct window *w = XWINDOW (window);
13763 struct frame *f = XFRAME (w->frame);
13764 struct buffer *buffer = XBUFFER (w->buffer);
13765 struct buffer *old = current_buffer;
13766 struct text_pos lpoint, opoint, startp;
13767 int update_mode_line;
13768 int tem;
13769 struct it it;
13770 /* Record it now because it's overwritten. */
13771 int current_matrix_up_to_date_p = 0;
13772 int used_current_matrix_p = 0;
13773 /* This is less strict than current_matrix_up_to_date_p.
13774 It indictes that the buffer contents and narrowing are unchanged. */
13775 int buffer_unchanged_p = 0;
13776 int temp_scroll_step = 0;
13777 int count = SPECPDL_INDEX ();
13778 int rc;
13779 int centering_position = -1;
13780 int last_line_misfit = 0;
13781 int beg_unchanged, end_unchanged;
13783 SET_TEXT_POS (lpoint, PT, PT_BYTE);
13784 opoint = lpoint;
13786 /* W must be a leaf window here. */
13787 xassert (!NILP (w->buffer));
13788 #if GLYPH_DEBUG
13789 *w->desired_matrix->method = 0;
13790 #endif
13792 restart:
13793 reconsider_clip_changes (w, buffer);
13795 /* Has the mode line to be updated? */
13796 update_mode_line = (!NILP (w->update_mode_line)
13797 || update_mode_lines
13798 || buffer->clip_changed
13799 || buffer->prevent_redisplay_optimizations_p);
13801 if (MINI_WINDOW_P (w))
13803 if (w == XWINDOW (echo_area_window)
13804 && !NILP (echo_area_buffer[0]))
13806 if (update_mode_line)
13807 /* We may have to update a tty frame's menu bar or a
13808 tool-bar. Example `M-x C-h C-h C-g'. */
13809 goto finish_menu_bars;
13810 else
13811 /* We've already displayed the echo area glyphs in this window. */
13812 goto finish_scroll_bars;
13814 else if ((w != XWINDOW (minibuf_window)
13815 || minibuf_level == 0)
13816 /* When buffer is nonempty, redisplay window normally. */
13817 && BUF_Z (XBUFFER (w->buffer)) == BUF_BEG (XBUFFER (w->buffer))
13818 /* Quail displays non-mini buffers in minibuffer window.
13819 In that case, redisplay the window normally. */
13820 && !NILP (Fmemq (w->buffer, Vminibuffer_list)))
13822 /* W is a mini-buffer window, but it's not active, so clear
13823 it. */
13824 int yb = window_text_bottom_y (w);
13825 struct glyph_row *row;
13826 int y;
13828 for (y = 0, row = w->desired_matrix->rows;
13829 y < yb;
13830 y += row->height, ++row)
13831 blank_row (w, row, y);
13832 goto finish_scroll_bars;
13835 clear_glyph_matrix (w->desired_matrix);
13838 /* Otherwise set up data on this window; select its buffer and point
13839 value. */
13840 /* Really select the buffer, for the sake of buffer-local
13841 variables. */
13842 set_buffer_internal_1 (XBUFFER (w->buffer));
13844 current_matrix_up_to_date_p
13845 = (!NILP (w->window_end_valid)
13846 && !current_buffer->clip_changed
13847 && !current_buffer->prevent_redisplay_optimizations_p
13848 && XFASTINT (w->last_modified) >= MODIFF
13849 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
13851 /* Run the window-bottom-change-functions
13852 if it is possible that the text on the screen has changed
13853 (either due to modification of the text, or any other reason). */
13854 if (!current_matrix_up_to_date_p
13855 && !NILP (Vwindow_text_change_functions))
13857 safe_run_hooks (Qwindow_text_change_functions);
13858 goto restart;
13861 beg_unchanged = BEG_UNCHANGED;
13862 end_unchanged = END_UNCHANGED;
13864 SET_TEXT_POS (opoint, PT, PT_BYTE);
13866 specbind (Qinhibit_point_motion_hooks, Qt);
13868 buffer_unchanged_p
13869 = (!NILP (w->window_end_valid)
13870 && !current_buffer->clip_changed
13871 && XFASTINT (w->last_modified) >= MODIFF
13872 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
13874 /* When windows_or_buffers_changed is non-zero, we can't rely on
13875 the window end being valid, so set it to nil there. */
13876 if (windows_or_buffers_changed)
13878 /* If window starts on a continuation line, maybe adjust the
13879 window start in case the window's width changed. */
13880 if (XMARKER (w->start)->buffer == current_buffer)
13881 compute_window_start_on_continuation_line (w);
13883 w->window_end_valid = Qnil;
13886 /* Some sanity checks. */
13887 CHECK_WINDOW_END (w);
13888 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
13889 abort ();
13890 if (BYTEPOS (opoint) < CHARPOS (opoint))
13891 abort ();
13893 /* If %c is in mode line, update it if needed. */
13894 if (!NILP (w->column_number_displayed)
13895 /* This alternative quickly identifies a common case
13896 where no change is needed. */
13897 && !(PT == XFASTINT (w->last_point)
13898 && XFASTINT (w->last_modified) >= MODIFF
13899 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
13900 && (XFASTINT (w->column_number_displayed)
13901 != (int) current_column ())) /* iftc */
13902 update_mode_line = 1;
13904 /* Count number of windows showing the selected buffer. An indirect
13905 buffer counts as its base buffer. */
13906 if (!just_this_one_p)
13908 struct buffer *current_base, *window_base;
13909 current_base = current_buffer;
13910 window_base = XBUFFER (XWINDOW (selected_window)->buffer);
13911 if (current_base->base_buffer)
13912 current_base = current_base->base_buffer;
13913 if (window_base->base_buffer)
13914 window_base = window_base->base_buffer;
13915 if (current_base == window_base)
13916 buffer_shared++;
13919 /* Point refers normally to the selected window. For any other
13920 window, set up appropriate value. */
13921 if (!EQ (window, selected_window))
13923 int new_pt = XMARKER (w->pointm)->charpos;
13924 int new_pt_byte = marker_byte_position (w->pointm);
13925 if (new_pt < BEGV)
13927 new_pt = BEGV;
13928 new_pt_byte = BEGV_BYTE;
13929 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
13931 else if (new_pt > (ZV - 1))
13933 new_pt = ZV;
13934 new_pt_byte = ZV_BYTE;
13935 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
13938 /* We don't use SET_PT so that the point-motion hooks don't run. */
13939 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
13942 /* If any of the character widths specified in the display table
13943 have changed, invalidate the width run cache. It's true that
13944 this may be a bit late to catch such changes, but the rest of
13945 redisplay goes (non-fatally) haywire when the display table is
13946 changed, so why should we worry about doing any better? */
13947 if (current_buffer->width_run_cache)
13949 struct Lisp_Char_Table *disptab = buffer_display_table ();
13951 if (! disptab_matches_widthtab (disptab,
13952 XVECTOR (current_buffer->width_table)))
13954 invalidate_region_cache (current_buffer,
13955 current_buffer->width_run_cache,
13956 BEG, Z);
13957 recompute_width_table (current_buffer, disptab);
13961 /* If window-start is screwed up, choose a new one. */
13962 if (XMARKER (w->start)->buffer != current_buffer)
13963 goto recenter;
13965 SET_TEXT_POS_FROM_MARKER (startp, w->start);
13967 /* If someone specified a new starting point but did not insist,
13968 check whether it can be used. */
13969 if (!NILP (w->optional_new_start)
13970 && CHARPOS (startp) >= BEGV
13971 && CHARPOS (startp) <= ZV)
13973 w->optional_new_start = Qnil;
13974 start_display (&it, w, startp);
13975 move_it_to (&it, PT, 0, it.last_visible_y, -1,
13976 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
13977 if (IT_CHARPOS (it) == PT)
13978 w->force_start = Qt;
13979 /* IT may overshoot PT if text at PT is invisible. */
13980 else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT)
13981 w->force_start = Qt;
13984 force_start:
13986 /* Handle case where place to start displaying has been specified,
13987 unless the specified location is outside the accessible range. */
13988 if (!NILP (w->force_start)
13989 || w->frozen_window_start_p)
13991 /* We set this later on if we have to adjust point. */
13992 int new_vpos = -1;
13994 w->force_start = Qnil;
13995 w->vscroll = 0;
13996 w->window_end_valid = Qnil;
13998 /* Forget any recorded base line for line number display. */
13999 if (!buffer_unchanged_p)
14000 w->base_line_number = Qnil;
14002 /* Redisplay the mode line. Select the buffer properly for that.
14003 Also, run the hook window-scroll-functions
14004 because we have scrolled. */
14005 /* Note, we do this after clearing force_start because
14006 if there's an error, it is better to forget about force_start
14007 than to get into an infinite loop calling the hook functions
14008 and having them get more errors. */
14009 if (!update_mode_line
14010 || ! NILP (Vwindow_scroll_functions))
14012 update_mode_line = 1;
14013 w->update_mode_line = Qt;
14014 startp = run_window_scroll_functions (window, startp);
14017 w->last_modified = make_number (0);
14018 w->last_overlay_modified = make_number (0);
14019 if (CHARPOS (startp) < BEGV)
14020 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
14021 else if (CHARPOS (startp) > ZV)
14022 SET_TEXT_POS (startp, ZV, ZV_BYTE);
14024 /* Redisplay, then check if cursor has been set during the
14025 redisplay. Give up if new fonts were loaded. */
14026 /* We used to issue a CHECK_MARGINS argument to try_window here,
14027 but this causes scrolling to fail when point begins inside
14028 the scroll margin (bug#148) -- cyd */
14029 if (!try_window (window, startp, 0))
14031 w->force_start = Qt;
14032 clear_glyph_matrix (w->desired_matrix);
14033 goto need_larger_matrices;
14036 if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
14038 /* If point does not appear, try to move point so it does
14039 appear. The desired matrix has been built above, so we
14040 can use it here. */
14041 new_vpos = window_box_height (w) / 2;
14044 if (!cursor_row_fully_visible_p (w, 0, 0))
14046 /* Point does appear, but on a line partly visible at end of window.
14047 Move it back to a fully-visible line. */
14048 new_vpos = window_box_height (w);
14051 /* If we need to move point for either of the above reasons,
14052 now actually do it. */
14053 if (new_vpos >= 0)
14055 struct glyph_row *row;
14057 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
14058 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
14059 ++row;
14061 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
14062 MATRIX_ROW_START_BYTEPOS (row));
14064 if (w != XWINDOW (selected_window))
14065 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
14066 else if (current_buffer == old)
14067 SET_TEXT_POS (lpoint, PT, PT_BYTE);
14069 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
14071 /* If we are highlighting the region, then we just changed
14072 the region, so redisplay to show it. */
14073 if (!NILP (Vtransient_mark_mode)
14074 && !NILP (current_buffer->mark_active))
14076 clear_glyph_matrix (w->desired_matrix);
14077 if (!try_window (window, startp, 0))
14078 goto need_larger_matrices;
14082 #if GLYPH_DEBUG
14083 debug_method_add (w, "forced window start");
14084 #endif
14085 goto done;
14088 /* Handle case where text has not changed, only point, and it has
14089 not moved off the frame, and we are not retrying after hscroll.
14090 (current_matrix_up_to_date_p is nonzero when retrying.) */
14091 if (current_matrix_up_to_date_p
14092 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
14093 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
14095 switch (rc)
14097 case CURSOR_MOVEMENT_SUCCESS:
14098 used_current_matrix_p = 1;
14099 goto done;
14101 case CURSOR_MOVEMENT_MUST_SCROLL:
14102 goto try_to_scroll;
14104 default:
14105 abort ();
14108 /* If current starting point was originally the beginning of a line
14109 but no longer is, find a new starting point. */
14110 else if (!NILP (w->start_at_line_beg)
14111 && !(CHARPOS (startp) <= BEGV
14112 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
14114 #if GLYPH_DEBUG
14115 debug_method_add (w, "recenter 1");
14116 #endif
14117 goto recenter;
14120 /* Try scrolling with try_window_id. Value is > 0 if update has
14121 been done, it is -1 if we know that the same window start will
14122 not work. It is 0 if unsuccessful for some other reason. */
14123 else if ((tem = try_window_id (w)) != 0)
14125 #if GLYPH_DEBUG
14126 debug_method_add (w, "try_window_id %d", tem);
14127 #endif
14129 if (fonts_changed_p)
14130 goto need_larger_matrices;
14131 if (tem > 0)
14132 goto done;
14134 /* Otherwise try_window_id has returned -1 which means that we
14135 don't want the alternative below this comment to execute. */
14137 else if (CHARPOS (startp) >= BEGV
14138 && CHARPOS (startp) <= ZV
14139 && PT >= CHARPOS (startp)
14140 && (CHARPOS (startp) < ZV
14141 /* Avoid starting at end of buffer. */
14142 || CHARPOS (startp) == BEGV
14143 || (XFASTINT (w->last_modified) >= MODIFF
14144 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)))
14147 /* If first window line is a continuation line, and window start
14148 is inside the modified region, but the first change is before
14149 current window start, we must select a new window start.
14151 However, if this is the result of a down-mouse event (e.g. by
14152 extending the mouse-drag-overlay), we don't want to select a
14153 new window start, since that would change the position under
14154 the mouse, resulting in an unwanted mouse-movement rather
14155 than a simple mouse-click. */
14156 if (NILP (w->start_at_line_beg)
14157 && NILP (do_mouse_tracking)
14158 && CHARPOS (startp) > BEGV
14159 && CHARPOS (startp) > BEG + beg_unchanged
14160 && CHARPOS (startp) <= Z - end_unchanged
14161 /* Even if w->start_at_line_beg is nil, a new window may
14162 start at a line_beg, since that's how set_buffer_window
14163 sets it. So, we need to check the return value of
14164 compute_window_start_on_continuation_line. (See also
14165 bug#197). */
14166 && XMARKER (w->start)->buffer == current_buffer
14167 && compute_window_start_on_continuation_line (w))
14169 w->force_start = Qt;
14170 SET_TEXT_POS_FROM_MARKER (startp, w->start);
14171 goto force_start;
14174 #if GLYPH_DEBUG
14175 debug_method_add (w, "same window start");
14176 #endif
14178 /* Try to redisplay starting at same place as before.
14179 If point has not moved off frame, accept the results. */
14180 if (!current_matrix_up_to_date_p
14181 /* Don't use try_window_reusing_current_matrix in this case
14182 because a window scroll function can have changed the
14183 buffer. */
14184 || !NILP (Vwindow_scroll_functions)
14185 || MINI_WINDOW_P (w)
14186 || !(used_current_matrix_p
14187 = try_window_reusing_current_matrix (w)))
14189 IF_DEBUG (debug_method_add (w, "1"));
14190 if (try_window (window, startp, TRY_WINDOW_CHECK_MARGINS) < 0)
14191 /* -1 means we need to scroll.
14192 0 means we need new matrices, but fonts_changed_p
14193 is set in that case, so we will detect it below. */
14194 goto try_to_scroll;
14197 if (fonts_changed_p)
14198 goto need_larger_matrices;
14200 if (w->cursor.vpos >= 0)
14202 if (!just_this_one_p
14203 || current_buffer->clip_changed
14204 || BEG_UNCHANGED < CHARPOS (startp))
14205 /* Forget any recorded base line for line number display. */
14206 w->base_line_number = Qnil;
14208 if (!cursor_row_fully_visible_p (w, 1, 0))
14210 clear_glyph_matrix (w->desired_matrix);
14211 last_line_misfit = 1;
14213 /* Drop through and scroll. */
14214 else
14215 goto done;
14217 else
14218 clear_glyph_matrix (w->desired_matrix);
14221 try_to_scroll:
14223 w->last_modified = make_number (0);
14224 w->last_overlay_modified = make_number (0);
14226 /* Redisplay the mode line. Select the buffer properly for that. */
14227 if (!update_mode_line)
14229 update_mode_line = 1;
14230 w->update_mode_line = Qt;
14233 /* Try to scroll by specified few lines. */
14234 if ((scroll_conservatively
14235 || scroll_step
14236 || temp_scroll_step
14237 || NUMBERP (current_buffer->scroll_up_aggressively)
14238 || NUMBERP (current_buffer->scroll_down_aggressively))
14239 && !current_buffer->clip_changed
14240 && CHARPOS (startp) >= BEGV
14241 && CHARPOS (startp) <= ZV)
14243 /* The function returns -1 if new fonts were loaded, 1 if
14244 successful, 0 if not successful. */
14245 int rc = try_scrolling (window, just_this_one_p,
14246 scroll_conservatively,
14247 scroll_step,
14248 temp_scroll_step, last_line_misfit);
14249 switch (rc)
14251 case SCROLLING_SUCCESS:
14252 goto done;
14254 case SCROLLING_NEED_LARGER_MATRICES:
14255 goto need_larger_matrices;
14257 case SCROLLING_FAILED:
14258 break;
14260 default:
14261 abort ();
14265 /* Finally, just choose place to start which centers point */
14267 recenter:
14268 if (centering_position < 0)
14269 centering_position = window_box_height (w) / 2;
14271 #if GLYPH_DEBUG
14272 debug_method_add (w, "recenter");
14273 #endif
14275 /* w->vscroll = 0; */
14277 /* Forget any previously recorded base line for line number display. */
14278 if (!buffer_unchanged_p)
14279 w->base_line_number = Qnil;
14281 /* Move backward half the height of the window. */
14282 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
14283 it.current_y = it.last_visible_y;
14284 move_it_vertically_backward (&it, centering_position);
14285 xassert (IT_CHARPOS (it) >= BEGV);
14287 /* The function move_it_vertically_backward may move over more
14288 than the specified y-distance. If it->w is small, e.g. a
14289 mini-buffer window, we may end up in front of the window's
14290 display area. Start displaying at the start of the line
14291 containing PT in this case. */
14292 if (it.current_y <= 0)
14294 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
14295 move_it_vertically_backward (&it, 0);
14296 it.current_y = 0;
14299 it.current_x = it.hpos = 0;
14301 /* Set startp here explicitly in case that helps avoid an infinite loop
14302 in case the window-scroll-functions functions get errors. */
14303 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
14305 /* Run scroll hooks. */
14306 startp = run_window_scroll_functions (window, it.current.pos);
14308 /* Redisplay the window. */
14309 if (!current_matrix_up_to_date_p
14310 || windows_or_buffers_changed
14311 || cursor_type_changed
14312 /* Don't use try_window_reusing_current_matrix in this case
14313 because it can have changed the buffer. */
14314 || !NILP (Vwindow_scroll_functions)
14315 || !just_this_one_p
14316 || MINI_WINDOW_P (w)
14317 || !(used_current_matrix_p
14318 = try_window_reusing_current_matrix (w)))
14319 try_window (window, startp, 0);
14321 /* If new fonts have been loaded (due to fontsets), give up. We
14322 have to start a new redisplay since we need to re-adjust glyph
14323 matrices. */
14324 if (fonts_changed_p)
14325 goto need_larger_matrices;
14327 /* If cursor did not appear assume that the middle of the window is
14328 in the first line of the window. Do it again with the next line.
14329 (Imagine a window of height 100, displaying two lines of height
14330 60. Moving back 50 from it->last_visible_y will end in the first
14331 line.) */
14332 if (w->cursor.vpos < 0)
14334 if (!NILP (w->window_end_valid)
14335 && PT >= Z - XFASTINT (w->window_end_pos))
14337 clear_glyph_matrix (w->desired_matrix);
14338 move_it_by_lines (&it, 1, 0);
14339 try_window (window, it.current.pos, 0);
14341 else if (PT < IT_CHARPOS (it))
14343 clear_glyph_matrix (w->desired_matrix);
14344 move_it_by_lines (&it, -1, 0);
14345 try_window (window, it.current.pos, 0);
14347 else
14349 /* Not much we can do about it. */
14353 /* Consider the following case: Window starts at BEGV, there is
14354 invisible, intangible text at BEGV, so that display starts at
14355 some point START > BEGV. It can happen that we are called with
14356 PT somewhere between BEGV and START. Try to handle that case. */
14357 if (w->cursor.vpos < 0)
14359 struct glyph_row *row = w->current_matrix->rows;
14360 if (row->mode_line_p)
14361 ++row;
14362 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
14365 if (!cursor_row_fully_visible_p (w, 0, 0))
14367 /* If vscroll is enabled, disable it and try again. */
14368 if (w->vscroll)
14370 w->vscroll = 0;
14371 clear_glyph_matrix (w->desired_matrix);
14372 goto recenter;
14375 /* If centering point failed to make the whole line visible,
14376 put point at the top instead. That has to make the whole line
14377 visible, if it can be done. */
14378 if (centering_position == 0)
14379 goto done;
14381 clear_glyph_matrix (w->desired_matrix);
14382 centering_position = 0;
14383 goto recenter;
14386 done:
14388 SET_TEXT_POS_FROM_MARKER (startp, w->start);
14389 w->start_at_line_beg = ((CHARPOS (startp) == BEGV
14390 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n')
14391 ? Qt : Qnil);
14393 /* Display the mode line, if we must. */
14394 if ((update_mode_line
14395 /* If window not full width, must redo its mode line
14396 if (a) the window to its side is being redone and
14397 (b) we do a frame-based redisplay. This is a consequence
14398 of how inverted lines are drawn in frame-based redisplay. */
14399 || (!just_this_one_p
14400 && !FRAME_WINDOW_P (f)
14401 && !WINDOW_FULL_WIDTH_P (w))
14402 /* Line number to display. */
14403 || INTEGERP (w->base_line_pos)
14404 /* Column number is displayed and different from the one displayed. */
14405 || (!NILP (w->column_number_displayed)
14406 && (XFASTINT (w->column_number_displayed)
14407 != (int) current_column ()))) /* iftc */
14408 /* This means that the window has a mode line. */
14409 && (WINDOW_WANTS_MODELINE_P (w)
14410 || WINDOW_WANTS_HEADER_LINE_P (w)))
14412 display_mode_lines (w);
14414 /* If mode line height has changed, arrange for a thorough
14415 immediate redisplay using the correct mode line height. */
14416 if (WINDOW_WANTS_MODELINE_P (w)
14417 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
14419 fonts_changed_p = 1;
14420 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
14421 = DESIRED_MODE_LINE_HEIGHT (w);
14424 /* If header line height has changed, arrange for a thorough
14425 immediate redisplay using the correct header line height. */
14426 if (WINDOW_WANTS_HEADER_LINE_P (w)
14427 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
14429 fonts_changed_p = 1;
14430 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
14431 = DESIRED_HEADER_LINE_HEIGHT (w);
14434 if (fonts_changed_p)
14435 goto need_larger_matrices;
14438 if (!line_number_displayed
14439 && !BUFFERP (w->base_line_pos))
14441 w->base_line_pos = Qnil;
14442 w->base_line_number = Qnil;
14445 finish_menu_bars:
14447 /* When we reach a frame's selected window, redo the frame's menu bar. */
14448 if (update_mode_line
14449 && EQ (FRAME_SELECTED_WINDOW (f), window))
14451 int redisplay_menu_p = 0;
14452 int redisplay_tool_bar_p = 0;
14454 if (FRAME_WINDOW_P (f))
14456 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
14457 || defined (HAVE_NS) || defined (USE_GTK)
14458 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
14459 #else
14460 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
14461 #endif
14463 else
14464 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
14466 if (redisplay_menu_p)
14467 display_menu_bar (w);
14469 #ifdef HAVE_WINDOW_SYSTEM
14470 if (FRAME_WINDOW_P (f))
14472 #if defined (USE_GTK) || defined (HAVE_NS)
14473 redisplay_tool_bar_p = FRAME_EXTERNAL_TOOL_BAR (f);
14474 #else
14475 redisplay_tool_bar_p = WINDOWP (f->tool_bar_window)
14476 && (FRAME_TOOL_BAR_LINES (f) > 0
14477 || !NILP (Vauto_resize_tool_bars));
14478 #endif
14480 if (redisplay_tool_bar_p && redisplay_tool_bar (f))
14482 ignore_mouse_drag_p = 1;
14485 #endif
14488 #ifdef HAVE_WINDOW_SYSTEM
14489 if (FRAME_WINDOW_P (f)
14490 && update_window_fringes (w, (just_this_one_p
14491 || (!used_current_matrix_p && !overlay_arrow_seen)
14492 || w->pseudo_window_p)))
14494 update_begin (f);
14495 BLOCK_INPUT;
14496 if (draw_window_fringes (w, 1))
14497 x_draw_vertical_border (w);
14498 UNBLOCK_INPUT;
14499 update_end (f);
14501 #endif /* HAVE_WINDOW_SYSTEM */
14503 /* We go to this label, with fonts_changed_p nonzero,
14504 if it is necessary to try again using larger glyph matrices.
14505 We have to redeem the scroll bar even in this case,
14506 because the loop in redisplay_internal expects that. */
14507 need_larger_matrices:
14509 finish_scroll_bars:
14511 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
14513 /* Set the thumb's position and size. */
14514 set_vertical_scroll_bar (w);
14516 /* Note that we actually used the scroll bar attached to this
14517 window, so it shouldn't be deleted at the end of redisplay. */
14518 if (FRAME_TERMINAL (f)->redeem_scroll_bar_hook)
14519 (*FRAME_TERMINAL (f)->redeem_scroll_bar_hook) (w);
14522 /* Restore current_buffer and value of point in it. The window
14523 update may have changed the buffer, so first make sure `opoint'
14524 is still valid (Bug#6177). */
14525 if (CHARPOS (opoint) < BEGV)
14526 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
14527 else if (CHARPOS (opoint) > ZV)
14528 TEMP_SET_PT_BOTH (Z, Z_BYTE);
14529 else
14530 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
14532 set_buffer_internal_1 (old);
14533 /* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become
14534 shorter. This can be caused by log truncation in *Messages*. */
14535 if (CHARPOS (lpoint) <= ZV)
14536 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
14538 unbind_to (count, Qnil);
14542 /* Build the complete desired matrix of WINDOW with a window start
14543 buffer position POS.
14545 Value is 1 if successful. It is zero if fonts were loaded during
14546 redisplay which makes re-adjusting glyph matrices necessary, and -1
14547 if point would appear in the scroll margins.
14548 (We check the former only if TRY_WINDOW_IGNORE_FONTS_CHANGE is
14549 unset in FLAGS, and the latter only if TRY_WINDOW_CHECK_MARGINS is
14550 set in FLAGS.) */
14553 try_window (Lisp_Object window, struct text_pos pos, int flags)
14555 struct window *w = XWINDOW (window);
14556 struct it it;
14557 struct glyph_row *last_text_row = NULL;
14558 struct frame *f = XFRAME (w->frame);
14560 /* Make POS the new window start. */
14561 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
14563 /* Mark cursor position as unknown. No overlay arrow seen. */
14564 w->cursor.vpos = -1;
14565 overlay_arrow_seen = 0;
14567 /* Initialize iterator and info to start at POS. */
14568 start_display (&it, w, pos);
14570 /* Display all lines of W. */
14571 while (it.current_y < it.last_visible_y)
14573 if (display_line (&it))
14574 last_text_row = it.glyph_row - 1;
14575 if (fonts_changed_p && !(flags & TRY_WINDOW_IGNORE_FONTS_CHANGE))
14576 return 0;
14579 /* Don't let the cursor end in the scroll margins. */
14580 if ((flags & TRY_WINDOW_CHECK_MARGINS)
14581 && !MINI_WINDOW_P (w))
14583 int this_scroll_margin;
14585 if (scroll_margin > 0)
14587 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
14588 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
14590 else
14591 this_scroll_margin = 0;
14593 if ((w->cursor.y >= 0 /* not vscrolled */
14594 && w->cursor.y < this_scroll_margin
14595 && CHARPOS (pos) > BEGV
14596 && IT_CHARPOS (it) < ZV)
14597 /* rms: considering make_cursor_line_fully_visible_p here
14598 seems to give wrong results. We don't want to recenter
14599 when the last line is partly visible, we want to allow
14600 that case to be handled in the usual way. */
14601 || w->cursor.y > it.last_visible_y - this_scroll_margin - 1)
14603 w->cursor.vpos = -1;
14604 clear_glyph_matrix (w->desired_matrix);
14605 return -1;
14609 /* If bottom moved off end of frame, change mode line percentage. */
14610 if (XFASTINT (w->window_end_pos) <= 0
14611 && Z != IT_CHARPOS (it))
14612 w->update_mode_line = Qt;
14614 /* Set window_end_pos to the offset of the last character displayed
14615 on the window from the end of current_buffer. Set
14616 window_end_vpos to its row number. */
14617 if (last_text_row)
14619 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
14620 w->window_end_bytepos
14621 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
14622 w->window_end_pos
14623 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
14624 w->window_end_vpos
14625 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
14626 xassert (MATRIX_ROW (w->desired_matrix, XFASTINT (w->window_end_vpos))
14627 ->displays_text_p);
14629 else
14631 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
14632 w->window_end_pos = make_number (Z - ZV);
14633 w->window_end_vpos = make_number (0);
14636 /* But that is not valid info until redisplay finishes. */
14637 w->window_end_valid = Qnil;
14638 return 1;
14643 /************************************************************************
14644 Window redisplay reusing current matrix when buffer has not changed
14645 ************************************************************************/
14647 /* Try redisplay of window W showing an unchanged buffer with a
14648 different window start than the last time it was displayed by
14649 reusing its current matrix. Value is non-zero if successful.
14650 W->start is the new window start. */
14652 static int
14653 try_window_reusing_current_matrix (struct window *w)
14655 struct frame *f = XFRAME (w->frame);
14656 struct glyph_row *row, *bottom_row;
14657 struct it it;
14658 struct run run;
14659 struct text_pos start, new_start;
14660 int nrows_scrolled, i;
14661 struct glyph_row *last_text_row;
14662 struct glyph_row *last_reused_text_row;
14663 struct glyph_row *start_row;
14664 int start_vpos, min_y, max_y;
14666 #if GLYPH_DEBUG
14667 if (inhibit_try_window_reusing)
14668 return 0;
14669 #endif
14671 if (/* This function doesn't handle terminal frames. */
14672 !FRAME_WINDOW_P (f)
14673 /* Don't try to reuse the display if windows have been split
14674 or such. */
14675 || windows_or_buffers_changed
14676 || cursor_type_changed)
14677 return 0;
14679 /* Can't do this if region may have changed. */
14680 if ((!NILP (Vtransient_mark_mode)
14681 && !NILP (current_buffer->mark_active))
14682 || !NILP (w->region_showing)
14683 || !NILP (Vshow_trailing_whitespace))
14684 return 0;
14686 /* If top-line visibility has changed, give up. */
14687 if (WINDOW_WANTS_HEADER_LINE_P (w)
14688 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
14689 return 0;
14691 /* Give up if old or new display is scrolled vertically. We could
14692 make this function handle this, but right now it doesn't. */
14693 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
14694 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row))
14695 return 0;
14697 /* The variable new_start now holds the new window start. The old
14698 start `start' can be determined from the current matrix. */
14699 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
14700 start = start_row->minpos;
14701 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
14703 /* Clear the desired matrix for the display below. */
14704 clear_glyph_matrix (w->desired_matrix);
14706 if (CHARPOS (new_start) <= CHARPOS (start))
14708 int first_row_y;
14710 /* Don't use this method if the display starts with an ellipsis
14711 displayed for invisible text. It's not easy to handle that case
14712 below, and it's certainly not worth the effort since this is
14713 not a frequent case. */
14714 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
14715 return 0;
14717 IF_DEBUG (debug_method_add (w, "twu1"));
14719 /* Display up to a row that can be reused. The variable
14720 last_text_row is set to the last row displayed that displays
14721 text. Note that it.vpos == 0 if or if not there is a
14722 header-line; it's not the same as the MATRIX_ROW_VPOS! */
14723 start_display (&it, w, new_start);
14724 first_row_y = it.current_y;
14725 w->cursor.vpos = -1;
14726 last_text_row = last_reused_text_row = NULL;
14728 while (it.current_y < it.last_visible_y
14729 && !fonts_changed_p)
14731 /* If we have reached into the characters in the START row,
14732 that means the line boundaries have changed. So we
14733 can't start copying with the row START. Maybe it will
14734 work to start copying with the following row. */
14735 while (IT_CHARPOS (it) > CHARPOS (start))
14737 /* Advance to the next row as the "start". */
14738 start_row++;
14739 start = start_row->minpos;
14740 /* If there are no more rows to try, or just one, give up. */
14741 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
14742 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row)
14743 || CHARPOS (start) == ZV)
14745 clear_glyph_matrix (w->desired_matrix);
14746 return 0;
14749 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
14751 /* If we have reached alignment,
14752 we can copy the rest of the rows. */
14753 if (IT_CHARPOS (it) == CHARPOS (start))
14754 break;
14756 if (display_line (&it))
14757 last_text_row = it.glyph_row - 1;
14760 /* A value of current_y < last_visible_y means that we stopped
14761 at the previous window start, which in turn means that we
14762 have at least one reusable row. */
14763 if (it.current_y < it.last_visible_y)
14765 /* IT.vpos always starts from 0; it counts text lines. */
14766 nrows_scrolled = it.vpos - (start_row - MATRIX_FIRST_TEXT_ROW (w->current_matrix));
14768 /* Find PT if not already found in the lines displayed. */
14769 if (w->cursor.vpos < 0)
14771 int dy = it.current_y - start_row->y;
14773 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
14774 row = row_containing_pos (w, PT, row, NULL, dy);
14775 if (row)
14776 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
14777 dy, nrows_scrolled);
14778 else
14780 clear_glyph_matrix (w->desired_matrix);
14781 return 0;
14785 /* Scroll the display. Do it before the current matrix is
14786 changed. The problem here is that update has not yet
14787 run, i.e. part of the current matrix is not up to date.
14788 scroll_run_hook will clear the cursor, and use the
14789 current matrix to get the height of the row the cursor is
14790 in. */
14791 run.current_y = start_row->y;
14792 run.desired_y = it.current_y;
14793 run.height = it.last_visible_y - it.current_y;
14795 if (run.height > 0 && run.current_y != run.desired_y)
14797 update_begin (f);
14798 FRAME_RIF (f)->update_window_begin_hook (w);
14799 FRAME_RIF (f)->clear_window_mouse_face (w);
14800 FRAME_RIF (f)->scroll_run_hook (w, &run);
14801 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
14802 update_end (f);
14805 /* Shift current matrix down by nrows_scrolled lines. */
14806 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
14807 rotate_matrix (w->current_matrix,
14808 start_vpos,
14809 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
14810 nrows_scrolled);
14812 /* Disable lines that must be updated. */
14813 for (i = 0; i < nrows_scrolled; ++i)
14814 (start_row + i)->enabled_p = 0;
14816 /* Re-compute Y positions. */
14817 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
14818 max_y = it.last_visible_y;
14819 for (row = start_row + nrows_scrolled;
14820 row < bottom_row;
14821 ++row)
14823 row->y = it.current_y;
14824 row->visible_height = row->height;
14826 if (row->y < min_y)
14827 row->visible_height -= min_y - row->y;
14828 if (row->y + row->height > max_y)
14829 row->visible_height -= row->y + row->height - max_y;
14830 row->redraw_fringe_bitmaps_p = 1;
14832 it.current_y += row->height;
14834 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
14835 last_reused_text_row = row;
14836 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
14837 break;
14840 /* Disable lines in the current matrix which are now
14841 below the window. */
14842 for (++row; row < bottom_row; ++row)
14843 row->enabled_p = row->mode_line_p = 0;
14846 /* Update window_end_pos etc.; last_reused_text_row is the last
14847 reused row from the current matrix containing text, if any.
14848 The value of last_text_row is the last displayed line
14849 containing text. */
14850 if (last_reused_text_row)
14852 w->window_end_bytepos
14853 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
14854 w->window_end_pos
14855 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_reused_text_row));
14856 w->window_end_vpos
14857 = make_number (MATRIX_ROW_VPOS (last_reused_text_row,
14858 w->current_matrix));
14860 else if (last_text_row)
14862 w->window_end_bytepos
14863 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
14864 w->window_end_pos
14865 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
14866 w->window_end_vpos
14867 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
14869 else
14871 /* This window must be completely empty. */
14872 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
14873 w->window_end_pos = make_number (Z - ZV);
14874 w->window_end_vpos = make_number (0);
14876 w->window_end_valid = Qnil;
14878 /* Update hint: don't try scrolling again in update_window. */
14879 w->desired_matrix->no_scrolling_p = 1;
14881 #if GLYPH_DEBUG
14882 debug_method_add (w, "try_window_reusing_current_matrix 1");
14883 #endif
14884 return 1;
14886 else if (CHARPOS (new_start) > CHARPOS (start))
14888 struct glyph_row *pt_row, *row;
14889 struct glyph_row *first_reusable_row;
14890 struct glyph_row *first_row_to_display;
14891 int dy;
14892 int yb = window_text_bottom_y (w);
14894 /* Find the row starting at new_start, if there is one. Don't
14895 reuse a partially visible line at the end. */
14896 first_reusable_row = start_row;
14897 while (first_reusable_row->enabled_p
14898 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
14899 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
14900 < CHARPOS (new_start)))
14901 ++first_reusable_row;
14903 /* Give up if there is no row to reuse. */
14904 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
14905 || !first_reusable_row->enabled_p
14906 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
14907 != CHARPOS (new_start)))
14908 return 0;
14910 /* We can reuse fully visible rows beginning with
14911 first_reusable_row to the end of the window. Set
14912 first_row_to_display to the first row that cannot be reused.
14913 Set pt_row to the row containing point, if there is any. */
14914 pt_row = NULL;
14915 for (first_row_to_display = first_reusable_row;
14916 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
14917 ++first_row_to_display)
14919 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
14920 && PT < MATRIX_ROW_END_CHARPOS (first_row_to_display))
14921 pt_row = first_row_to_display;
14924 /* Start displaying at the start of first_row_to_display. */
14925 xassert (first_row_to_display->y < yb);
14926 init_to_row_start (&it, w, first_row_to_display);
14928 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
14929 - start_vpos);
14930 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
14931 - nrows_scrolled);
14932 it.current_y = (first_row_to_display->y - first_reusable_row->y
14933 + WINDOW_HEADER_LINE_HEIGHT (w));
14935 /* Display lines beginning with first_row_to_display in the
14936 desired matrix. Set last_text_row to the last row displayed
14937 that displays text. */
14938 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
14939 if (pt_row == NULL)
14940 w->cursor.vpos = -1;
14941 last_text_row = NULL;
14942 while (it.current_y < it.last_visible_y && !fonts_changed_p)
14943 if (display_line (&it))
14944 last_text_row = it.glyph_row - 1;
14946 /* If point is in a reused row, adjust y and vpos of the cursor
14947 position. */
14948 if (pt_row)
14950 w->cursor.vpos -= nrows_scrolled;
14951 w->cursor.y -= first_reusable_row->y - start_row->y;
14954 /* Give up if point isn't in a row displayed or reused. (This
14955 also handles the case where w->cursor.vpos < nrows_scrolled
14956 after the calls to display_line, which can happen with scroll
14957 margins. See bug#1295.) */
14958 if (w->cursor.vpos < 0)
14960 clear_glyph_matrix (w->desired_matrix);
14961 return 0;
14964 /* Scroll the display. */
14965 run.current_y = first_reusable_row->y;
14966 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
14967 run.height = it.last_visible_y - run.current_y;
14968 dy = run.current_y - run.desired_y;
14970 if (run.height)
14972 update_begin (f);
14973 FRAME_RIF (f)->update_window_begin_hook (w);
14974 FRAME_RIF (f)->clear_window_mouse_face (w);
14975 FRAME_RIF (f)->scroll_run_hook (w, &run);
14976 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
14977 update_end (f);
14980 /* Adjust Y positions of reused rows. */
14981 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
14982 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
14983 max_y = it.last_visible_y;
14984 for (row = first_reusable_row; row < first_row_to_display; ++row)
14986 row->y -= dy;
14987 row->visible_height = row->height;
14988 if (row->y < min_y)
14989 row->visible_height -= min_y - row->y;
14990 if (row->y + row->height > max_y)
14991 row->visible_height -= row->y + row->height - max_y;
14992 row->redraw_fringe_bitmaps_p = 1;
14995 /* Scroll the current matrix. */
14996 xassert (nrows_scrolled > 0);
14997 rotate_matrix (w->current_matrix,
14998 start_vpos,
14999 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
15000 -nrows_scrolled);
15002 /* Disable rows not reused. */
15003 for (row -= nrows_scrolled; row < bottom_row; ++row)
15004 row->enabled_p = 0;
15006 /* Point may have moved to a different line, so we cannot assume that
15007 the previous cursor position is valid; locate the correct row. */
15008 if (pt_row)
15010 for (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
15011 row < bottom_row && PT >= MATRIX_ROW_END_CHARPOS (row);
15012 row++)
15014 w->cursor.vpos++;
15015 w->cursor.y = row->y;
15017 if (row < bottom_row)
15019 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
15020 struct glyph *end = glyph + row->used[TEXT_AREA];
15022 /* Can't use this optimization with bidi-reordered glyph
15023 rows, unless cursor is already at point. */
15024 if (!NILP (XBUFFER (w->buffer)->bidi_display_reordering))
15026 if (!(w->cursor.hpos >= 0
15027 && w->cursor.hpos < row->used[TEXT_AREA]
15028 && BUFFERP (glyph->object)
15029 && glyph->charpos == PT))
15030 return 0;
15032 else
15033 for (; glyph < end
15034 && (!BUFFERP (glyph->object)
15035 || glyph->charpos < PT);
15036 glyph++)
15038 w->cursor.hpos++;
15039 w->cursor.x += glyph->pixel_width;
15044 /* Adjust window end. A null value of last_text_row means that
15045 the window end is in reused rows which in turn means that
15046 only its vpos can have changed. */
15047 if (last_text_row)
15049 w->window_end_bytepos
15050 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
15051 w->window_end_pos
15052 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
15053 w->window_end_vpos
15054 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
15056 else
15058 w->window_end_vpos
15059 = make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled);
15062 w->window_end_valid = Qnil;
15063 w->desired_matrix->no_scrolling_p = 1;
15065 #if GLYPH_DEBUG
15066 debug_method_add (w, "try_window_reusing_current_matrix 2");
15067 #endif
15068 return 1;
15071 return 0;
15076 /************************************************************************
15077 Window redisplay reusing current matrix when buffer has changed
15078 ************************************************************************/
15080 static struct glyph_row *find_last_unchanged_at_beg_row (struct window *);
15081 static struct glyph_row *find_first_unchanged_at_end_row (struct window *,
15082 int *, int *);
15083 static struct glyph_row *
15084 find_last_row_displaying_text (struct glyph_matrix *, struct it *,
15085 struct glyph_row *);
15088 /* Return the last row in MATRIX displaying text. If row START is
15089 non-null, start searching with that row. IT gives the dimensions
15090 of the display. Value is null if matrix is empty; otherwise it is
15091 a pointer to the row found. */
15093 static struct glyph_row *
15094 find_last_row_displaying_text (struct glyph_matrix *matrix, struct it *it,
15095 struct glyph_row *start)
15097 struct glyph_row *row, *row_found;
15099 /* Set row_found to the last row in IT->w's current matrix
15100 displaying text. The loop looks funny but think of partially
15101 visible lines. */
15102 row_found = NULL;
15103 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
15104 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
15106 xassert (row->enabled_p);
15107 row_found = row;
15108 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
15109 break;
15110 ++row;
15113 return row_found;
15117 /* Return the last row in the current matrix of W that is not affected
15118 by changes at the start of current_buffer that occurred since W's
15119 current matrix was built. Value is null if no such row exists.
15121 BEG_UNCHANGED us the number of characters unchanged at the start of
15122 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
15123 first changed character in current_buffer. Characters at positions <
15124 BEG + BEG_UNCHANGED are at the same buffer positions as they were
15125 when the current matrix was built. */
15127 static struct glyph_row *
15128 find_last_unchanged_at_beg_row (struct window *w)
15130 int first_changed_pos = BEG + BEG_UNCHANGED;
15131 struct glyph_row *row;
15132 struct glyph_row *row_found = NULL;
15133 int yb = window_text_bottom_y (w);
15135 /* Find the last row displaying unchanged text. */
15136 for (row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
15137 MATRIX_ROW_DISPLAYS_TEXT_P (row)
15138 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos;
15139 ++row)
15141 if (/* If row ends before first_changed_pos, it is unchanged,
15142 except in some case. */
15143 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
15144 /* When row ends in ZV and we write at ZV it is not
15145 unchanged. */
15146 && !row->ends_at_zv_p
15147 /* When first_changed_pos is the end of a continued line,
15148 row is not unchanged because it may be no longer
15149 continued. */
15150 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
15151 && (row->continued_p
15152 || row->exact_window_width_line_p)))
15153 row_found = row;
15155 /* Stop if last visible row. */
15156 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
15157 break;
15160 return row_found;
15164 /* Find the first glyph row in the current matrix of W that is not
15165 affected by changes at the end of current_buffer since the
15166 time W's current matrix was built.
15168 Return in *DELTA the number of chars by which buffer positions in
15169 unchanged text at the end of current_buffer must be adjusted.
15171 Return in *DELTA_BYTES the corresponding number of bytes.
15173 Value is null if no such row exists, i.e. all rows are affected by
15174 changes. */
15176 static struct glyph_row *
15177 find_first_unchanged_at_end_row (struct window *w, int *delta, int *delta_bytes)
15179 struct glyph_row *row;
15180 struct glyph_row *row_found = NULL;
15182 *delta = *delta_bytes = 0;
15184 /* Display must not have been paused, otherwise the current matrix
15185 is not up to date. */
15186 eassert (!NILP (w->window_end_valid));
15188 /* A value of window_end_pos >= END_UNCHANGED means that the window
15189 end is in the range of changed text. If so, there is no
15190 unchanged row at the end of W's current matrix. */
15191 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
15192 return NULL;
15194 /* Set row to the last row in W's current matrix displaying text. */
15195 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
15197 /* If matrix is entirely empty, no unchanged row exists. */
15198 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
15200 /* The value of row is the last glyph row in the matrix having a
15201 meaningful buffer position in it. The end position of row
15202 corresponds to window_end_pos. This allows us to translate
15203 buffer positions in the current matrix to current buffer
15204 positions for characters not in changed text. */
15205 int Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
15206 int Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
15207 int last_unchanged_pos, last_unchanged_pos_old;
15208 struct glyph_row *first_text_row
15209 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
15211 *delta = Z - Z_old;
15212 *delta_bytes = Z_BYTE - Z_BYTE_old;
15214 /* Set last_unchanged_pos to the buffer position of the last
15215 character in the buffer that has not been changed. Z is the
15216 index + 1 of the last character in current_buffer, i.e. by
15217 subtracting END_UNCHANGED we get the index of the last
15218 unchanged character, and we have to add BEG to get its buffer
15219 position. */
15220 last_unchanged_pos = Z - END_UNCHANGED + BEG;
15221 last_unchanged_pos_old = last_unchanged_pos - *delta;
15223 /* Search backward from ROW for a row displaying a line that
15224 starts at a minimum position >= last_unchanged_pos_old. */
15225 for (; row > first_text_row; --row)
15227 /* This used to abort, but it can happen.
15228 It is ok to just stop the search instead here. KFS. */
15229 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
15230 break;
15232 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
15233 row_found = row;
15237 eassert (!row_found || MATRIX_ROW_DISPLAYS_TEXT_P (row_found));
15239 return row_found;
15243 /* Make sure that glyph rows in the current matrix of window W
15244 reference the same glyph memory as corresponding rows in the
15245 frame's frame matrix. This function is called after scrolling W's
15246 current matrix on a terminal frame in try_window_id and
15247 try_window_reusing_current_matrix. */
15249 static void
15250 sync_frame_with_window_matrix_rows (struct window *w)
15252 struct frame *f = XFRAME (w->frame);
15253 struct glyph_row *window_row, *window_row_end, *frame_row;
15255 /* Preconditions: W must be a leaf window and full-width. Its frame
15256 must have a frame matrix. */
15257 xassert (NILP (w->hchild) && NILP (w->vchild));
15258 xassert (WINDOW_FULL_WIDTH_P (w));
15259 xassert (!FRAME_WINDOW_P (f));
15261 /* If W is a full-width window, glyph pointers in W's current matrix
15262 have, by definition, to be the same as glyph pointers in the
15263 corresponding frame matrix. Note that frame matrices have no
15264 marginal areas (see build_frame_matrix). */
15265 window_row = w->current_matrix->rows;
15266 window_row_end = window_row + w->current_matrix->nrows;
15267 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
15268 while (window_row < window_row_end)
15270 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
15271 struct glyph *end = window_row->glyphs[LAST_AREA];
15273 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
15274 frame_row->glyphs[TEXT_AREA] = start;
15275 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
15276 frame_row->glyphs[LAST_AREA] = end;
15278 /* Disable frame rows whose corresponding window rows have
15279 been disabled in try_window_id. */
15280 if (!window_row->enabled_p)
15281 frame_row->enabled_p = 0;
15283 ++window_row, ++frame_row;
15288 /* Find the glyph row in window W containing CHARPOS. Consider all
15289 rows between START and END (not inclusive). END null means search
15290 all rows to the end of the display area of W. Value is the row
15291 containing CHARPOS or null. */
15293 struct glyph_row *
15294 row_containing_pos (struct window *w, int charpos, struct glyph_row *start,
15295 struct glyph_row *end, int dy)
15297 struct glyph_row *row = start;
15298 struct glyph_row *best_row = NULL;
15299 EMACS_INT mindif = BUF_ZV (XBUFFER (w->buffer)) + 1;
15300 int last_y;
15302 /* If we happen to start on a header-line, skip that. */
15303 if (row->mode_line_p)
15304 ++row;
15306 if ((end && row >= end) || !row->enabled_p)
15307 return NULL;
15309 last_y = window_text_bottom_y (w) - dy;
15311 while (1)
15313 /* Give up if we have gone too far. */
15314 if (end && row >= end)
15315 return NULL;
15316 /* This formerly returned if they were equal.
15317 I think that both quantities are of a "last plus one" type;
15318 if so, when they are equal, the row is within the screen. -- rms. */
15319 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
15320 return NULL;
15322 /* If it is in this row, return this row. */
15323 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
15324 || (MATRIX_ROW_END_CHARPOS (row) == charpos
15325 /* The end position of a row equals the start
15326 position of the next row. If CHARPOS is there, we
15327 would rather display it in the next line, except
15328 when this line ends in ZV. */
15329 && !row->ends_at_zv_p
15330 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
15331 && charpos >= MATRIX_ROW_START_CHARPOS (row))
15333 struct glyph *g;
15335 if (NILP (XBUFFER (w->buffer)->bidi_display_reordering))
15336 return row;
15337 /* In bidi-reordered rows, there could be several rows
15338 occluding point. We need to find the one which fits
15339 CHARPOS the best. */
15340 for (g = row->glyphs[TEXT_AREA];
15341 g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
15342 g++)
15344 if (!STRINGP (g->object))
15346 if (g->charpos > 0 && eabs (g->charpos - charpos) < mindif)
15348 mindif = eabs (g->charpos - charpos);
15349 best_row = row;
15354 else if (best_row)
15355 return best_row;
15356 ++row;
15361 /* Try to redisplay window W by reusing its existing display. W's
15362 current matrix must be up to date when this function is called,
15363 i.e. window_end_valid must not be nil.
15365 Value is
15367 1 if display has been updated
15368 0 if otherwise unsuccessful
15369 -1 if redisplay with same window start is known not to succeed
15371 The following steps are performed:
15373 1. Find the last row in the current matrix of W that is not
15374 affected by changes at the start of current_buffer. If no such row
15375 is found, give up.
15377 2. Find the first row in W's current matrix that is not affected by
15378 changes at the end of current_buffer. Maybe there is no such row.
15380 3. Display lines beginning with the row + 1 found in step 1 to the
15381 row found in step 2 or, if step 2 didn't find a row, to the end of
15382 the window.
15384 4. If cursor is not known to appear on the window, give up.
15386 5. If display stopped at the row found in step 2, scroll the
15387 display and current matrix as needed.
15389 6. Maybe display some lines at the end of W, if we must. This can
15390 happen under various circumstances, like a partially visible line
15391 becoming fully visible, or because newly displayed lines are displayed
15392 in smaller font sizes.
15394 7. Update W's window end information. */
15396 static int
15397 try_window_id (struct window *w)
15399 struct frame *f = XFRAME (w->frame);
15400 struct glyph_matrix *current_matrix = w->current_matrix;
15401 struct glyph_matrix *desired_matrix = w->desired_matrix;
15402 struct glyph_row *last_unchanged_at_beg_row;
15403 struct glyph_row *first_unchanged_at_end_row;
15404 struct glyph_row *row;
15405 struct glyph_row *bottom_row;
15406 int bottom_vpos;
15407 struct it it;
15408 int delta = 0, delta_bytes = 0, stop_pos, dvpos, dy;
15409 struct text_pos start_pos;
15410 struct run run;
15411 int first_unchanged_at_end_vpos = 0;
15412 struct glyph_row *last_text_row, *last_text_row_at_end;
15413 struct text_pos start;
15414 int first_changed_charpos, last_changed_charpos;
15416 #if GLYPH_DEBUG
15417 if (inhibit_try_window_id)
15418 return 0;
15419 #endif
15421 /* This is handy for debugging. */
15422 #if 0
15423 #define GIVE_UP(X) \
15424 do { \
15425 fprintf (stderr, "try_window_id give up %d\n", (X)); \
15426 return 0; \
15427 } while (0)
15428 #else
15429 #define GIVE_UP(X) return 0
15430 #endif
15432 SET_TEXT_POS_FROM_MARKER (start, w->start);
15434 /* Don't use this for mini-windows because these can show
15435 messages and mini-buffers, and we don't handle that here. */
15436 if (MINI_WINDOW_P (w))
15437 GIVE_UP (1);
15439 /* This flag is used to prevent redisplay optimizations. */
15440 if (windows_or_buffers_changed || cursor_type_changed)
15441 GIVE_UP (2);
15443 /* Verify that narrowing has not changed.
15444 Also verify that we were not told to prevent redisplay optimizations.
15445 It would be nice to further
15446 reduce the number of cases where this prevents try_window_id. */
15447 if (current_buffer->clip_changed
15448 || current_buffer->prevent_redisplay_optimizations_p)
15449 GIVE_UP (3);
15451 /* Window must either use window-based redisplay or be full width. */
15452 if (!FRAME_WINDOW_P (f)
15453 && (!FRAME_LINE_INS_DEL_OK (f)
15454 || !WINDOW_FULL_WIDTH_P (w)))
15455 GIVE_UP (4);
15457 /* Give up if point is known NOT to appear in W. */
15458 if (PT < CHARPOS (start))
15459 GIVE_UP (5);
15461 /* Another way to prevent redisplay optimizations. */
15462 if (XFASTINT (w->last_modified) == 0)
15463 GIVE_UP (6);
15465 /* Verify that window is not hscrolled. */
15466 if (XFASTINT (w->hscroll) != 0)
15467 GIVE_UP (7);
15469 /* Verify that display wasn't paused. */
15470 if (NILP (w->window_end_valid))
15471 GIVE_UP (8);
15473 /* Can't use this if highlighting a region because a cursor movement
15474 will do more than just set the cursor. */
15475 if (!NILP (Vtransient_mark_mode)
15476 && !NILP (current_buffer->mark_active))
15477 GIVE_UP (9);
15479 /* Likewise if highlighting trailing whitespace. */
15480 if (!NILP (Vshow_trailing_whitespace))
15481 GIVE_UP (11);
15483 /* Likewise if showing a region. */
15484 if (!NILP (w->region_showing))
15485 GIVE_UP (10);
15487 /* Can't use this if overlay arrow position and/or string have
15488 changed. */
15489 if (overlay_arrows_changed_p ())
15490 GIVE_UP (12);
15492 /* When word-wrap is on, adding a space to the first word of a
15493 wrapped line can change the wrap position, altering the line
15494 above it. It might be worthwhile to handle this more
15495 intelligently, but for now just redisplay from scratch. */
15496 if (!NILP (XBUFFER (w->buffer)->word_wrap))
15497 GIVE_UP (21);
15499 /* Under bidi reordering, adding or deleting a character in the
15500 beginning of a paragraph, before the first strong directional
15501 character, can change the base direction of the paragraph (unless
15502 the buffer specifies a fixed paragraph direction), which will
15503 require to redisplay the whole paragraph. It might be worthwhile
15504 to find the paragraph limits and widen the range of redisplayed
15505 lines to that, but for now just give up this optimization and
15506 redisplay from scratch. */
15507 if (!NILP (XBUFFER (w->buffer)->bidi_display_reordering)
15508 && NILP (XBUFFER (w->buffer)->bidi_paragraph_direction))
15509 GIVE_UP (22);
15511 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
15512 only if buffer has really changed. The reason is that the gap is
15513 initially at Z for freshly visited files. The code below would
15514 set end_unchanged to 0 in that case. */
15515 if (MODIFF > SAVE_MODIFF
15516 /* This seems to happen sometimes after saving a buffer. */
15517 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
15519 if (GPT - BEG < BEG_UNCHANGED)
15520 BEG_UNCHANGED = GPT - BEG;
15521 if (Z - GPT < END_UNCHANGED)
15522 END_UNCHANGED = Z - GPT;
15525 /* The position of the first and last character that has been changed. */
15526 first_changed_charpos = BEG + BEG_UNCHANGED;
15527 last_changed_charpos = Z - END_UNCHANGED;
15529 /* If window starts after a line end, and the last change is in
15530 front of that newline, then changes don't affect the display.
15531 This case happens with stealth-fontification. Note that although
15532 the display is unchanged, glyph positions in the matrix have to
15533 be adjusted, of course. */
15534 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
15535 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
15536 && ((last_changed_charpos < CHARPOS (start)
15537 && CHARPOS (start) == BEGV)
15538 || (last_changed_charpos < CHARPOS (start) - 1
15539 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
15541 int Z_old, delta, Z_BYTE_old, delta_bytes;
15542 struct glyph_row *r0;
15544 /* Compute how many chars/bytes have been added to or removed
15545 from the buffer. */
15546 Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
15547 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
15548 delta = Z - Z_old;
15549 delta_bytes = Z_BYTE - Z_BYTE_old;
15551 /* Give up if PT is not in the window. Note that it already has
15552 been checked at the start of try_window_id that PT is not in
15553 front of the window start. */
15554 if (PT >= MATRIX_ROW_END_CHARPOS (row) + delta)
15555 GIVE_UP (13);
15557 /* If window start is unchanged, we can reuse the whole matrix
15558 as is, after adjusting glyph positions. No need to compute
15559 the window end again, since its offset from Z hasn't changed. */
15560 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
15561 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + delta
15562 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + delta_bytes
15563 /* PT must not be in a partially visible line. */
15564 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + delta
15565 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
15567 /* Adjust positions in the glyph matrix. */
15568 if (delta || delta_bytes)
15570 struct glyph_row *r1
15571 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
15572 increment_matrix_positions (w->current_matrix,
15573 MATRIX_ROW_VPOS (r0, current_matrix),
15574 MATRIX_ROW_VPOS (r1, current_matrix),
15575 delta, delta_bytes);
15578 /* Set the cursor. */
15579 row = row_containing_pos (w, PT, r0, NULL, 0);
15580 if (row)
15581 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
15582 else
15583 abort ();
15584 return 1;
15588 /* Handle the case that changes are all below what is displayed in
15589 the window, and that PT is in the window. This shortcut cannot
15590 be taken if ZV is visible in the window, and text has been added
15591 there that is visible in the window. */
15592 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
15593 /* ZV is not visible in the window, or there are no
15594 changes at ZV, actually. */
15595 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
15596 || first_changed_charpos == last_changed_charpos))
15598 struct glyph_row *r0;
15600 /* Give up if PT is not in the window. Note that it already has
15601 been checked at the start of try_window_id that PT is not in
15602 front of the window start. */
15603 if (PT >= MATRIX_ROW_END_CHARPOS (row))
15604 GIVE_UP (14);
15606 /* If window start is unchanged, we can reuse the whole matrix
15607 as is, without changing glyph positions since no text has
15608 been added/removed in front of the window end. */
15609 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
15610 if (TEXT_POS_EQUAL_P (start, r0->minpos)
15611 /* PT must not be in a partially visible line. */
15612 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
15613 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
15615 /* We have to compute the window end anew since text
15616 could have been added/removed after it. */
15617 w->window_end_pos
15618 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
15619 w->window_end_bytepos
15620 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
15622 /* Set the cursor. */
15623 row = row_containing_pos (w, PT, r0, NULL, 0);
15624 if (row)
15625 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
15626 else
15627 abort ();
15628 return 2;
15632 /* Give up if window start is in the changed area.
15634 The condition used to read
15636 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
15638 but why that was tested escapes me at the moment. */
15639 if (CHARPOS (start) >= first_changed_charpos
15640 && CHARPOS (start) <= last_changed_charpos)
15641 GIVE_UP (15);
15643 /* Check that window start agrees with the start of the first glyph
15644 row in its current matrix. Check this after we know the window
15645 start is not in changed text, otherwise positions would not be
15646 comparable. */
15647 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
15648 if (!TEXT_POS_EQUAL_P (start, row->minpos))
15649 GIVE_UP (16);
15651 /* Give up if the window ends in strings. Overlay strings
15652 at the end are difficult to handle, so don't try. */
15653 row = MATRIX_ROW (current_matrix, XFASTINT (w->window_end_vpos));
15654 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
15655 GIVE_UP (20);
15657 /* Compute the position at which we have to start displaying new
15658 lines. Some of the lines at the top of the window might be
15659 reusable because they are not displaying changed text. Find the
15660 last row in W's current matrix not affected by changes at the
15661 start of current_buffer. Value is null if changes start in the
15662 first line of window. */
15663 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
15664 if (last_unchanged_at_beg_row)
15666 /* Avoid starting to display in the moddle of a character, a TAB
15667 for instance. This is easier than to set up the iterator
15668 exactly, and it's not a frequent case, so the additional
15669 effort wouldn't really pay off. */
15670 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
15671 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
15672 && last_unchanged_at_beg_row > w->current_matrix->rows)
15673 --last_unchanged_at_beg_row;
15675 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
15676 GIVE_UP (17);
15678 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
15679 GIVE_UP (18);
15680 start_pos = it.current.pos;
15682 /* Start displaying new lines in the desired matrix at the same
15683 vpos we would use in the current matrix, i.e. below
15684 last_unchanged_at_beg_row. */
15685 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
15686 current_matrix);
15687 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
15688 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
15690 xassert (it.hpos == 0 && it.current_x == 0);
15692 else
15694 /* There are no reusable lines at the start of the window.
15695 Start displaying in the first text line. */
15696 start_display (&it, w, start);
15697 it.vpos = it.first_vpos;
15698 start_pos = it.current.pos;
15701 /* Find the first row that is not affected by changes at the end of
15702 the buffer. Value will be null if there is no unchanged row, in
15703 which case we must redisplay to the end of the window. delta
15704 will be set to the value by which buffer positions beginning with
15705 first_unchanged_at_end_row have to be adjusted due to text
15706 changes. */
15707 first_unchanged_at_end_row
15708 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
15709 IF_DEBUG (debug_delta = delta);
15710 IF_DEBUG (debug_delta_bytes = delta_bytes);
15712 /* Set stop_pos to the buffer position up to which we will have to
15713 display new lines. If first_unchanged_at_end_row != NULL, this
15714 is the buffer position of the start of the line displayed in that
15715 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
15716 that we don't stop at a buffer position. */
15717 stop_pos = 0;
15718 if (first_unchanged_at_end_row)
15720 xassert (last_unchanged_at_beg_row == NULL
15721 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
15723 /* If this is a continuation line, move forward to the next one
15724 that isn't. Changes in lines above affect this line.
15725 Caution: this may move first_unchanged_at_end_row to a row
15726 not displaying text. */
15727 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
15728 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
15729 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
15730 < it.last_visible_y))
15731 ++first_unchanged_at_end_row;
15733 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
15734 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
15735 >= it.last_visible_y))
15736 first_unchanged_at_end_row = NULL;
15737 else
15739 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
15740 + delta);
15741 first_unchanged_at_end_vpos
15742 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
15743 xassert (stop_pos >= Z - END_UNCHANGED);
15746 else if (last_unchanged_at_beg_row == NULL)
15747 GIVE_UP (19);
15750 #if GLYPH_DEBUG
15752 /* Either there is no unchanged row at the end, or the one we have
15753 now displays text. This is a necessary condition for the window
15754 end pos calculation at the end of this function. */
15755 xassert (first_unchanged_at_end_row == NULL
15756 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
15758 debug_last_unchanged_at_beg_vpos
15759 = (last_unchanged_at_beg_row
15760 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
15761 : -1);
15762 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
15764 #endif /* GLYPH_DEBUG != 0 */
15767 /* Display new lines. Set last_text_row to the last new line
15768 displayed which has text on it, i.e. might end up as being the
15769 line where the window_end_vpos is. */
15770 w->cursor.vpos = -1;
15771 last_text_row = NULL;
15772 overlay_arrow_seen = 0;
15773 while (it.current_y < it.last_visible_y
15774 && !fonts_changed_p
15775 && (first_unchanged_at_end_row == NULL
15776 || IT_CHARPOS (it) < stop_pos))
15778 if (display_line (&it))
15779 last_text_row = it.glyph_row - 1;
15782 if (fonts_changed_p)
15783 return -1;
15786 /* Compute differences in buffer positions, y-positions etc. for
15787 lines reused at the bottom of the window. Compute what we can
15788 scroll. */
15789 if (first_unchanged_at_end_row
15790 /* No lines reused because we displayed everything up to the
15791 bottom of the window. */
15792 && it.current_y < it.last_visible_y)
15794 dvpos = (it.vpos
15795 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
15796 current_matrix));
15797 dy = it.current_y - first_unchanged_at_end_row->y;
15798 run.current_y = first_unchanged_at_end_row->y;
15799 run.desired_y = run.current_y + dy;
15800 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
15802 else
15804 delta = delta_bytes = dvpos = dy
15805 = run.current_y = run.desired_y = run.height = 0;
15806 first_unchanged_at_end_row = NULL;
15808 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
15811 /* Find the cursor if not already found. We have to decide whether
15812 PT will appear on this window (it sometimes doesn't, but this is
15813 not a very frequent case.) This decision has to be made before
15814 the current matrix is altered. A value of cursor.vpos < 0 means
15815 that PT is either in one of the lines beginning at
15816 first_unchanged_at_end_row or below the window. Don't care for
15817 lines that might be displayed later at the window end; as
15818 mentioned, this is not a frequent case. */
15819 if (w->cursor.vpos < 0)
15821 /* Cursor in unchanged rows at the top? */
15822 if (PT < CHARPOS (start_pos)
15823 && last_unchanged_at_beg_row)
15825 row = row_containing_pos (w, PT,
15826 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
15827 last_unchanged_at_beg_row + 1, 0);
15828 if (row)
15829 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
15832 /* Start from first_unchanged_at_end_row looking for PT. */
15833 else if (first_unchanged_at_end_row)
15835 row = row_containing_pos (w, PT - delta,
15836 first_unchanged_at_end_row, NULL, 0);
15837 if (row)
15838 set_cursor_from_row (w, row, w->current_matrix, delta,
15839 delta_bytes, dy, dvpos);
15842 /* Give up if cursor was not found. */
15843 if (w->cursor.vpos < 0)
15845 clear_glyph_matrix (w->desired_matrix);
15846 return -1;
15850 /* Don't let the cursor end in the scroll margins. */
15852 int this_scroll_margin, cursor_height;
15854 this_scroll_margin = max (0, scroll_margin);
15855 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
15856 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
15857 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
15859 if ((w->cursor.y < this_scroll_margin
15860 && CHARPOS (start) > BEGV)
15861 /* Old redisplay didn't take scroll margin into account at the bottom,
15862 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
15863 || (w->cursor.y + (make_cursor_line_fully_visible_p
15864 ? cursor_height + this_scroll_margin
15865 : 1)) > it.last_visible_y)
15867 w->cursor.vpos = -1;
15868 clear_glyph_matrix (w->desired_matrix);
15869 return -1;
15873 /* Scroll the display. Do it before changing the current matrix so
15874 that xterm.c doesn't get confused about where the cursor glyph is
15875 found. */
15876 if (dy && run.height)
15878 update_begin (f);
15880 if (FRAME_WINDOW_P (f))
15882 FRAME_RIF (f)->update_window_begin_hook (w);
15883 FRAME_RIF (f)->clear_window_mouse_face (w);
15884 FRAME_RIF (f)->scroll_run_hook (w, &run);
15885 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
15887 else
15889 /* Terminal frame. In this case, dvpos gives the number of
15890 lines to scroll by; dvpos < 0 means scroll up. */
15891 int first_unchanged_at_end_vpos
15892 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
15893 int from = WINDOW_TOP_EDGE_LINE (w) + first_unchanged_at_end_vpos;
15894 int end = (WINDOW_TOP_EDGE_LINE (w)
15895 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
15896 + window_internal_height (w));
15898 /* Perform the operation on the screen. */
15899 if (dvpos > 0)
15901 /* Scroll last_unchanged_at_beg_row to the end of the
15902 window down dvpos lines. */
15903 set_terminal_window (f, end);
15905 /* On dumb terminals delete dvpos lines at the end
15906 before inserting dvpos empty lines. */
15907 if (!FRAME_SCROLL_REGION_OK (f))
15908 ins_del_lines (f, end - dvpos, -dvpos);
15910 /* Insert dvpos empty lines in front of
15911 last_unchanged_at_beg_row. */
15912 ins_del_lines (f, from, dvpos);
15914 else if (dvpos < 0)
15916 /* Scroll up last_unchanged_at_beg_vpos to the end of
15917 the window to last_unchanged_at_beg_vpos - |dvpos|. */
15918 set_terminal_window (f, end);
15920 /* Delete dvpos lines in front of
15921 last_unchanged_at_beg_vpos. ins_del_lines will set
15922 the cursor to the given vpos and emit |dvpos| delete
15923 line sequences. */
15924 ins_del_lines (f, from + dvpos, dvpos);
15926 /* On a dumb terminal insert dvpos empty lines at the
15927 end. */
15928 if (!FRAME_SCROLL_REGION_OK (f))
15929 ins_del_lines (f, end + dvpos, -dvpos);
15932 set_terminal_window (f, 0);
15935 update_end (f);
15938 /* Shift reused rows of the current matrix to the right position.
15939 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
15940 text. */
15941 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
15942 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
15943 if (dvpos < 0)
15945 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
15946 bottom_vpos, dvpos);
15947 enable_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
15948 bottom_vpos, 0);
15950 else if (dvpos > 0)
15952 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
15953 bottom_vpos, dvpos);
15954 enable_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
15955 first_unchanged_at_end_vpos + dvpos, 0);
15958 /* For frame-based redisplay, make sure that current frame and window
15959 matrix are in sync with respect to glyph memory. */
15960 if (!FRAME_WINDOW_P (f))
15961 sync_frame_with_window_matrix_rows (w);
15963 /* Adjust buffer positions in reused rows. */
15964 if (delta || delta_bytes)
15965 increment_matrix_positions (current_matrix,
15966 first_unchanged_at_end_vpos + dvpos,
15967 bottom_vpos, delta, delta_bytes);
15969 /* Adjust Y positions. */
15970 if (dy)
15971 shift_glyph_matrix (w, current_matrix,
15972 first_unchanged_at_end_vpos + dvpos,
15973 bottom_vpos, dy);
15975 if (first_unchanged_at_end_row)
15977 first_unchanged_at_end_row += dvpos;
15978 if (first_unchanged_at_end_row->y >= it.last_visible_y
15979 || !MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row))
15980 first_unchanged_at_end_row = NULL;
15983 /* If scrolling up, there may be some lines to display at the end of
15984 the window. */
15985 last_text_row_at_end = NULL;
15986 if (dy < 0)
15988 /* Scrolling up can leave for example a partially visible line
15989 at the end of the window to be redisplayed. */
15990 /* Set last_row to the glyph row in the current matrix where the
15991 window end line is found. It has been moved up or down in
15992 the matrix by dvpos. */
15993 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
15994 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
15996 /* If last_row is the window end line, it should display text. */
15997 xassert (last_row->displays_text_p);
15999 /* If window end line was partially visible before, begin
16000 displaying at that line. Otherwise begin displaying with the
16001 line following it. */
16002 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
16004 init_to_row_start (&it, w, last_row);
16005 it.vpos = last_vpos;
16006 it.current_y = last_row->y;
16008 else
16010 init_to_row_end (&it, w, last_row);
16011 it.vpos = 1 + last_vpos;
16012 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
16013 ++last_row;
16016 /* We may start in a continuation line. If so, we have to
16017 get the right continuation_lines_width and current_x. */
16018 it.continuation_lines_width = last_row->continuation_lines_width;
16019 it.hpos = it.current_x = 0;
16021 /* Display the rest of the lines at the window end. */
16022 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
16023 while (it.current_y < it.last_visible_y
16024 && !fonts_changed_p)
16026 /* Is it always sure that the display agrees with lines in
16027 the current matrix? I don't think so, so we mark rows
16028 displayed invalid in the current matrix by setting their
16029 enabled_p flag to zero. */
16030 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
16031 if (display_line (&it))
16032 last_text_row_at_end = it.glyph_row - 1;
16036 /* Update window_end_pos and window_end_vpos. */
16037 if (first_unchanged_at_end_row
16038 && !last_text_row_at_end)
16040 /* Window end line if one of the preserved rows from the current
16041 matrix. Set row to the last row displaying text in current
16042 matrix starting at first_unchanged_at_end_row, after
16043 scrolling. */
16044 xassert (first_unchanged_at_end_row->displays_text_p);
16045 row = find_last_row_displaying_text (w->current_matrix, &it,
16046 first_unchanged_at_end_row);
16047 xassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
16049 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
16050 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
16051 w->window_end_vpos
16052 = make_number (MATRIX_ROW_VPOS (row, w->current_matrix));
16053 xassert (w->window_end_bytepos >= 0);
16054 IF_DEBUG (debug_method_add (w, "A"));
16056 else if (last_text_row_at_end)
16058 w->window_end_pos
16059 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end));
16060 w->window_end_bytepos
16061 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
16062 w->window_end_vpos
16063 = make_number (MATRIX_ROW_VPOS (last_text_row_at_end, desired_matrix));
16064 xassert (w->window_end_bytepos >= 0);
16065 IF_DEBUG (debug_method_add (w, "B"));
16067 else if (last_text_row)
16069 /* We have displayed either to the end of the window or at the
16070 end of the window, i.e. the last row with text is to be found
16071 in the desired matrix. */
16072 w->window_end_pos
16073 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
16074 w->window_end_bytepos
16075 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
16076 w->window_end_vpos
16077 = make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix));
16078 xassert (w->window_end_bytepos >= 0);
16080 else if (first_unchanged_at_end_row == NULL
16081 && last_text_row == NULL
16082 && last_text_row_at_end == NULL)
16084 /* Displayed to end of window, but no line containing text was
16085 displayed. Lines were deleted at the end of the window. */
16086 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
16087 int vpos = XFASTINT (w->window_end_vpos);
16088 struct glyph_row *current_row = current_matrix->rows + vpos;
16089 struct glyph_row *desired_row = desired_matrix->rows + vpos;
16091 for (row = NULL;
16092 row == NULL && vpos >= first_vpos;
16093 --vpos, --current_row, --desired_row)
16095 if (desired_row->enabled_p)
16097 if (desired_row->displays_text_p)
16098 row = desired_row;
16100 else if (current_row->displays_text_p)
16101 row = current_row;
16104 xassert (row != NULL);
16105 w->window_end_vpos = make_number (vpos + 1);
16106 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
16107 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
16108 xassert (w->window_end_bytepos >= 0);
16109 IF_DEBUG (debug_method_add (w, "C"));
16111 else
16112 abort ();
16114 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
16115 debug_end_vpos = XFASTINT (w->window_end_vpos));
16117 /* Record that display has not been completed. */
16118 w->window_end_valid = Qnil;
16119 w->desired_matrix->no_scrolling_p = 1;
16120 return 3;
16122 #undef GIVE_UP
16127 /***********************************************************************
16128 More debugging support
16129 ***********************************************************************/
16131 #if GLYPH_DEBUG
16133 void dump_glyph_row (struct glyph_row *, int, int);
16134 void dump_glyph_matrix (struct glyph_matrix *, int);
16135 void dump_glyph (struct glyph_row *, struct glyph *, int);
16138 /* Dump the contents of glyph matrix MATRIX on stderr.
16140 GLYPHS 0 means don't show glyph contents.
16141 GLYPHS 1 means show glyphs in short form
16142 GLYPHS > 1 means show glyphs in long form. */
16144 void
16145 dump_glyph_matrix (matrix, glyphs)
16146 struct glyph_matrix *matrix;
16147 int glyphs;
16149 int i;
16150 for (i = 0; i < matrix->nrows; ++i)
16151 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
16155 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
16156 the glyph row and area where the glyph comes from. */
16158 void
16159 dump_glyph (row, glyph, area)
16160 struct glyph_row *row;
16161 struct glyph *glyph;
16162 int area;
16164 if (glyph->type == CHAR_GLYPH)
16166 fprintf (stderr,
16167 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
16168 glyph - row->glyphs[TEXT_AREA],
16169 'C',
16170 glyph->charpos,
16171 (BUFFERP (glyph->object)
16172 ? 'B'
16173 : (STRINGP (glyph->object)
16174 ? 'S'
16175 : '-')),
16176 glyph->pixel_width,
16177 glyph->u.ch,
16178 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
16179 ? glyph->u.ch
16180 : '.'),
16181 glyph->face_id,
16182 glyph->left_box_line_p,
16183 glyph->right_box_line_p);
16185 else if (glyph->type == STRETCH_GLYPH)
16187 fprintf (stderr,
16188 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
16189 glyph - row->glyphs[TEXT_AREA],
16190 'S',
16191 glyph->charpos,
16192 (BUFFERP (glyph->object)
16193 ? 'B'
16194 : (STRINGP (glyph->object)
16195 ? 'S'
16196 : '-')),
16197 glyph->pixel_width,
16199 '.',
16200 glyph->face_id,
16201 glyph->left_box_line_p,
16202 glyph->right_box_line_p);
16204 else if (glyph->type == IMAGE_GLYPH)
16206 fprintf (stderr,
16207 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
16208 glyph - row->glyphs[TEXT_AREA],
16209 'I',
16210 glyph->charpos,
16211 (BUFFERP (glyph->object)
16212 ? 'B'
16213 : (STRINGP (glyph->object)
16214 ? 'S'
16215 : '-')),
16216 glyph->pixel_width,
16217 glyph->u.img_id,
16218 '.',
16219 glyph->face_id,
16220 glyph->left_box_line_p,
16221 glyph->right_box_line_p);
16223 else if (glyph->type == COMPOSITE_GLYPH)
16225 fprintf (stderr,
16226 " %5d %4c %6d %c %3d 0x%05x",
16227 glyph - row->glyphs[TEXT_AREA],
16228 '+',
16229 glyph->charpos,
16230 (BUFFERP (glyph->object)
16231 ? 'B'
16232 : (STRINGP (glyph->object)
16233 ? 'S'
16234 : '-')),
16235 glyph->pixel_width,
16236 glyph->u.cmp.id);
16237 if (glyph->u.cmp.automatic)
16238 fprintf (stderr,
16239 "[%d-%d]",
16240 glyph->u.cmp.from, glyph->u.cmp.to);
16241 fprintf (stderr, " . %4d %1.1d%1.1d\n",
16242 glyph->face_id,
16243 glyph->left_box_line_p,
16244 glyph->right_box_line_p);
16249 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
16250 GLYPHS 0 means don't show glyph contents.
16251 GLYPHS 1 means show glyphs in short form
16252 GLYPHS > 1 means show glyphs in long form. */
16254 void
16255 dump_glyph_row (row, vpos, glyphs)
16256 struct glyph_row *row;
16257 int vpos, glyphs;
16259 if (glyphs != 1)
16261 fprintf (stderr, "Row Start End Used oE><\\CTZFesm X Y W H V A P\n");
16262 fprintf (stderr, "======================================================================\n");
16264 fprintf (stderr, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d\
16265 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
16266 vpos,
16267 MATRIX_ROW_START_CHARPOS (row),
16268 MATRIX_ROW_END_CHARPOS (row),
16269 row->used[TEXT_AREA],
16270 row->contains_overlapping_glyphs_p,
16271 row->enabled_p,
16272 row->truncated_on_left_p,
16273 row->truncated_on_right_p,
16274 row->continued_p,
16275 MATRIX_ROW_CONTINUATION_LINE_P (row),
16276 row->displays_text_p,
16277 row->ends_at_zv_p,
16278 row->fill_line_p,
16279 row->ends_in_middle_of_char_p,
16280 row->starts_in_middle_of_char_p,
16281 row->mouse_face_p,
16282 row->x,
16283 row->y,
16284 row->pixel_width,
16285 row->height,
16286 row->visible_height,
16287 row->ascent,
16288 row->phys_ascent);
16289 fprintf (stderr, "%9d %5d\t%5d\n", row->start.overlay_string_index,
16290 row->end.overlay_string_index,
16291 row->continuation_lines_width);
16292 fprintf (stderr, "%9d %5d\n",
16293 CHARPOS (row->start.string_pos),
16294 CHARPOS (row->end.string_pos));
16295 fprintf (stderr, "%9d %5d\n", row->start.dpvec_index,
16296 row->end.dpvec_index);
16299 if (glyphs > 1)
16301 int area;
16303 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
16305 struct glyph *glyph = row->glyphs[area];
16306 struct glyph *glyph_end = glyph + row->used[area];
16308 /* Glyph for a line end in text. */
16309 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
16310 ++glyph_end;
16312 if (glyph < glyph_end)
16313 fprintf (stderr, " Glyph Type Pos O W Code C Face LR\n");
16315 for (; glyph < glyph_end; ++glyph)
16316 dump_glyph (row, glyph, area);
16319 else if (glyphs == 1)
16321 int area;
16323 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
16325 char *s = (char *) alloca (row->used[area] + 1);
16326 int i;
16328 for (i = 0; i < row->used[area]; ++i)
16330 struct glyph *glyph = row->glyphs[area] + i;
16331 if (glyph->type == CHAR_GLYPH
16332 && glyph->u.ch < 0x80
16333 && glyph->u.ch >= ' ')
16334 s[i] = glyph->u.ch;
16335 else
16336 s[i] = '.';
16339 s[i] = '\0';
16340 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
16346 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
16347 Sdump_glyph_matrix, 0, 1, "p",
16348 doc: /* Dump the current matrix of the selected window to stderr.
16349 Shows contents of glyph row structures. With non-nil
16350 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
16351 glyphs in short form, otherwise show glyphs in long form. */)
16352 (Lisp_Object glyphs)
16354 struct window *w = XWINDOW (selected_window);
16355 struct buffer *buffer = XBUFFER (w->buffer);
16357 fprintf (stderr, "PT = %d, BEGV = %d. ZV = %d\n",
16358 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
16359 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
16360 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
16361 fprintf (stderr, "=============================================\n");
16362 dump_glyph_matrix (w->current_matrix,
16363 NILP (glyphs) ? 0 : XINT (glyphs));
16364 return Qnil;
16368 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
16369 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
16370 (void)
16372 struct frame *f = XFRAME (selected_frame);
16373 dump_glyph_matrix (f->current_matrix, 1);
16374 return Qnil;
16378 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
16379 doc: /* Dump glyph row ROW to stderr.
16380 GLYPH 0 means don't dump glyphs.
16381 GLYPH 1 means dump glyphs in short form.
16382 GLYPH > 1 or omitted means dump glyphs in long form. */)
16383 (Lisp_Object row, Lisp_Object glyphs)
16385 struct glyph_matrix *matrix;
16386 int vpos;
16388 CHECK_NUMBER (row);
16389 matrix = XWINDOW (selected_window)->current_matrix;
16390 vpos = XINT (row);
16391 if (vpos >= 0 && vpos < matrix->nrows)
16392 dump_glyph_row (MATRIX_ROW (matrix, vpos),
16393 vpos,
16394 INTEGERP (glyphs) ? XINT (glyphs) : 2);
16395 return Qnil;
16399 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
16400 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
16401 GLYPH 0 means don't dump glyphs.
16402 GLYPH 1 means dump glyphs in short form.
16403 GLYPH > 1 or omitted means dump glyphs in long form. */)
16404 (Lisp_Object row, Lisp_Object glyphs)
16406 struct frame *sf = SELECTED_FRAME ();
16407 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
16408 int vpos;
16410 CHECK_NUMBER (row);
16411 vpos = XINT (row);
16412 if (vpos >= 0 && vpos < m->nrows)
16413 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
16414 INTEGERP (glyphs) ? XINT (glyphs) : 2);
16415 return Qnil;
16419 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
16420 doc: /* Toggle tracing of redisplay.
16421 With ARG, turn tracing on if and only if ARG is positive. */)
16422 (Lisp_Object arg)
16424 if (NILP (arg))
16425 trace_redisplay_p = !trace_redisplay_p;
16426 else
16428 arg = Fprefix_numeric_value (arg);
16429 trace_redisplay_p = XINT (arg) > 0;
16432 return Qnil;
16436 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
16437 doc: /* Like `format', but print result to stderr.
16438 usage: (trace-to-stderr STRING &rest OBJECTS) */)
16439 (int nargs, Lisp_Object *args)
16441 Lisp_Object s = Fformat (nargs, args);
16442 fprintf (stderr, "%s", SDATA (s));
16443 return Qnil;
16446 #endif /* GLYPH_DEBUG */
16450 /***********************************************************************
16451 Building Desired Matrix Rows
16452 ***********************************************************************/
16454 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
16455 Used for non-window-redisplay windows, and for windows w/o left fringe. */
16457 static struct glyph_row *
16458 get_overlay_arrow_glyph_row (struct window *w, Lisp_Object overlay_arrow_string)
16460 struct frame *f = XFRAME (WINDOW_FRAME (w));
16461 struct buffer *buffer = XBUFFER (w->buffer);
16462 struct buffer *old = current_buffer;
16463 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
16464 int arrow_len = SCHARS (overlay_arrow_string);
16465 const unsigned char *arrow_end = arrow_string + arrow_len;
16466 const unsigned char *p;
16467 struct it it;
16468 int multibyte_p;
16469 int n_glyphs_before;
16471 set_buffer_temp (buffer);
16472 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
16473 it.glyph_row->used[TEXT_AREA] = 0;
16474 SET_TEXT_POS (it.position, 0, 0);
16476 multibyte_p = !NILP (buffer->enable_multibyte_characters);
16477 p = arrow_string;
16478 while (p < arrow_end)
16480 Lisp_Object face, ilisp;
16482 /* Get the next character. */
16483 if (multibyte_p)
16484 it.c = string_char_and_length (p, &it.len);
16485 else
16486 it.c = *p, it.len = 1;
16487 p += it.len;
16489 /* Get its face. */
16490 ilisp = make_number (p - arrow_string);
16491 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
16492 it.face_id = compute_char_face (f, it.c, face);
16494 /* Compute its width, get its glyphs. */
16495 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
16496 SET_TEXT_POS (it.position, -1, -1);
16497 PRODUCE_GLYPHS (&it);
16499 /* If this character doesn't fit any more in the line, we have
16500 to remove some glyphs. */
16501 if (it.current_x > it.last_visible_x)
16503 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
16504 break;
16508 set_buffer_temp (old);
16509 return it.glyph_row;
16513 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
16514 glyphs are only inserted for terminal frames since we can't really
16515 win with truncation glyphs when partially visible glyphs are
16516 involved. Which glyphs to insert is determined by
16517 produce_special_glyphs. */
16519 static void
16520 insert_left_trunc_glyphs (struct it *it)
16522 struct it truncate_it;
16523 struct glyph *from, *end, *to, *toend;
16525 xassert (!FRAME_WINDOW_P (it->f));
16527 /* Get the truncation glyphs. */
16528 truncate_it = *it;
16529 truncate_it.current_x = 0;
16530 truncate_it.face_id = DEFAULT_FACE_ID;
16531 truncate_it.glyph_row = &scratch_glyph_row;
16532 truncate_it.glyph_row->used[TEXT_AREA] = 0;
16533 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
16534 truncate_it.object = make_number (0);
16535 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
16537 /* Overwrite glyphs from IT with truncation glyphs. */
16538 if (!it->glyph_row->reversed_p)
16540 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
16541 end = from + truncate_it.glyph_row->used[TEXT_AREA];
16542 to = it->glyph_row->glyphs[TEXT_AREA];
16543 toend = to + it->glyph_row->used[TEXT_AREA];
16545 while (from < end)
16546 *to++ = *from++;
16548 /* There may be padding glyphs left over. Overwrite them too. */
16549 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
16551 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
16552 while (from < end)
16553 *to++ = *from++;
16556 if (to > toend)
16557 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
16559 else
16561 /* In R2L rows, overwrite the last (rightmost) glyphs, and do
16562 that back to front. */
16563 end = truncate_it.glyph_row->glyphs[TEXT_AREA];
16564 from = end + truncate_it.glyph_row->used[TEXT_AREA] - 1;
16565 toend = it->glyph_row->glyphs[TEXT_AREA];
16566 to = toend + it->glyph_row->used[TEXT_AREA] - 1;
16568 while (from >= end && to >= toend)
16569 *to-- = *from--;
16570 while (to >= toend && CHAR_GLYPH_PADDING_P (*to))
16572 from =
16573 truncate_it.glyph_row->glyphs[TEXT_AREA]
16574 + truncate_it.glyph_row->used[TEXT_AREA] - 1;
16575 while (from >= end && to >= toend)
16576 *to-- = *from--;
16578 if (from >= end)
16580 /* Need to free some room before prepending additional
16581 glyphs. */
16582 int move_by = from - end + 1;
16583 struct glyph *g0 = it->glyph_row->glyphs[TEXT_AREA];
16584 struct glyph *g = g0 + it->glyph_row->used[TEXT_AREA] - 1;
16586 for ( ; g >= g0; g--)
16587 g[move_by] = *g;
16588 while (from >= end)
16589 *to-- = *from--;
16590 it->glyph_row->used[TEXT_AREA] += move_by;
16596 /* Compute the pixel height and width of IT->glyph_row.
16598 Most of the time, ascent and height of a display line will be equal
16599 to the max_ascent and max_height values of the display iterator
16600 structure. This is not the case if
16602 1. We hit ZV without displaying anything. In this case, max_ascent
16603 and max_height will be zero.
16605 2. We have some glyphs that don't contribute to the line height.
16606 (The glyph row flag contributes_to_line_height_p is for future
16607 pixmap extensions).
16609 The first case is easily covered by using default values because in
16610 these cases, the line height does not really matter, except that it
16611 must not be zero. */
16613 static void
16614 compute_line_metrics (struct it *it)
16616 struct glyph_row *row = it->glyph_row;
16617 int area, i;
16619 if (FRAME_WINDOW_P (it->f))
16621 int i, min_y, max_y;
16623 /* The line may consist of one space only, that was added to
16624 place the cursor on it. If so, the row's height hasn't been
16625 computed yet. */
16626 if (row->height == 0)
16628 if (it->max_ascent + it->max_descent == 0)
16629 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
16630 row->ascent = it->max_ascent;
16631 row->height = it->max_ascent + it->max_descent;
16632 row->phys_ascent = it->max_phys_ascent;
16633 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
16634 row->extra_line_spacing = it->max_extra_line_spacing;
16637 /* Compute the width of this line. */
16638 row->pixel_width = row->x;
16639 for (i = 0; i < row->used[TEXT_AREA]; ++i)
16640 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
16642 xassert (row->pixel_width >= 0);
16643 xassert (row->ascent >= 0 && row->height > 0);
16645 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
16646 || MATRIX_ROW_OVERLAPS_PRED_P (row));
16648 /* If first line's physical ascent is larger than its logical
16649 ascent, use the physical ascent, and make the row taller.
16650 This makes accented characters fully visible. */
16651 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
16652 && row->phys_ascent > row->ascent)
16654 row->height += row->phys_ascent - row->ascent;
16655 row->ascent = row->phys_ascent;
16658 /* Compute how much of the line is visible. */
16659 row->visible_height = row->height;
16661 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
16662 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
16664 if (row->y < min_y)
16665 row->visible_height -= min_y - row->y;
16666 if (row->y + row->height > max_y)
16667 row->visible_height -= row->y + row->height - max_y;
16669 else
16671 row->pixel_width = row->used[TEXT_AREA];
16672 if (row->continued_p)
16673 row->pixel_width -= it->continuation_pixel_width;
16674 else if (row->truncated_on_right_p)
16675 row->pixel_width -= it->truncation_pixel_width;
16676 row->ascent = row->phys_ascent = 0;
16677 row->height = row->phys_height = row->visible_height = 1;
16678 row->extra_line_spacing = 0;
16681 /* Compute a hash code for this row. */
16682 row->hash = 0;
16683 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
16684 for (i = 0; i < row->used[area]; ++i)
16685 row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff)
16686 + row->glyphs[area][i].u.val
16687 + row->glyphs[area][i].face_id
16688 + row->glyphs[area][i].padding_p
16689 + (row->glyphs[area][i].type << 2));
16691 it->max_ascent = it->max_descent = 0;
16692 it->max_phys_ascent = it->max_phys_descent = 0;
16696 /* Append one space to the glyph row of iterator IT if doing a
16697 window-based redisplay. The space has the same face as
16698 IT->face_id. Value is non-zero if a space was added.
16700 This function is called to make sure that there is always one glyph
16701 at the end of a glyph row that the cursor can be set on under
16702 window-systems. (If there weren't such a glyph we would not know
16703 how wide and tall a box cursor should be displayed).
16705 At the same time this space let's a nicely handle clearing to the
16706 end of the line if the row ends in italic text. */
16708 static int
16709 append_space_for_newline (struct it *it, int default_face_p)
16711 if (FRAME_WINDOW_P (it->f))
16713 int n = it->glyph_row->used[TEXT_AREA];
16715 if (it->glyph_row->glyphs[TEXT_AREA] + n
16716 < it->glyph_row->glyphs[1 + TEXT_AREA])
16718 /* Save some values that must not be changed.
16719 Must save IT->c and IT->len because otherwise
16720 ITERATOR_AT_END_P wouldn't work anymore after
16721 append_space_for_newline has been called. */
16722 enum display_element_type saved_what = it->what;
16723 int saved_c = it->c, saved_len = it->len;
16724 int saved_x = it->current_x;
16725 int saved_face_id = it->face_id;
16726 struct text_pos saved_pos;
16727 Lisp_Object saved_object;
16728 struct face *face;
16730 saved_object = it->object;
16731 saved_pos = it->position;
16733 it->what = IT_CHARACTER;
16734 memset (&it->position, 0, sizeof it->position);
16735 it->object = make_number (0);
16736 it->c = ' ';
16737 it->len = 1;
16739 if (default_face_p)
16740 it->face_id = DEFAULT_FACE_ID;
16741 else if (it->face_before_selective_p)
16742 it->face_id = it->saved_face_id;
16743 face = FACE_FROM_ID (it->f, it->face_id);
16744 it->face_id = FACE_FOR_CHAR (it->f, face, 0, -1, Qnil);
16746 PRODUCE_GLYPHS (it);
16748 it->override_ascent = -1;
16749 it->constrain_row_ascent_descent_p = 0;
16750 it->current_x = saved_x;
16751 it->object = saved_object;
16752 it->position = saved_pos;
16753 it->what = saved_what;
16754 it->face_id = saved_face_id;
16755 it->len = saved_len;
16756 it->c = saved_c;
16757 return 1;
16761 return 0;
16765 /* Extend the face of the last glyph in the text area of IT->glyph_row
16766 to the end of the display line. Called from display_line. If the
16767 glyph row is empty, add a space glyph to it so that we know the
16768 face to draw. Set the glyph row flag fill_line_p. If the glyph
16769 row is R2L, prepend a stretch glyph to cover the empty space to the
16770 left of the leftmost glyph. */
16772 static void
16773 extend_face_to_end_of_line (struct it *it)
16775 struct face *face;
16776 struct frame *f = it->f;
16778 /* If line is already filled, do nothing. Non window-system frames
16779 get a grace of one more ``pixel'' because their characters are
16780 1-``pixel'' wide, so they hit the equality too early. This grace
16781 is needed only for R2L rows that are not continued, to produce
16782 one extra blank where we could display the cursor. */
16783 if (it->current_x >= it->last_visible_x
16784 + (!FRAME_WINDOW_P (f)
16785 && it->glyph_row->reversed_p
16786 && !it->glyph_row->continued_p))
16787 return;
16789 /* Face extension extends the background and box of IT->face_id
16790 to the end of the line. If the background equals the background
16791 of the frame, we don't have to do anything. */
16792 if (it->face_before_selective_p)
16793 face = FACE_FROM_ID (f, it->saved_face_id);
16794 else
16795 face = FACE_FROM_ID (f, it->face_id);
16797 if (FRAME_WINDOW_P (f)
16798 && it->glyph_row->displays_text_p
16799 && face->box == FACE_NO_BOX
16800 && face->background == FRAME_BACKGROUND_PIXEL (f)
16801 && !face->stipple
16802 && !it->glyph_row->reversed_p)
16803 return;
16805 /* Set the glyph row flag indicating that the face of the last glyph
16806 in the text area has to be drawn to the end of the text area. */
16807 it->glyph_row->fill_line_p = 1;
16809 /* If current character of IT is not ASCII, make sure we have the
16810 ASCII face. This will be automatically undone the next time
16811 get_next_display_element returns a multibyte character. Note
16812 that the character will always be single byte in unibyte
16813 text. */
16814 if (!ASCII_CHAR_P (it->c))
16816 it->face_id = FACE_FOR_CHAR (f, face, 0, -1, Qnil);
16819 if (FRAME_WINDOW_P (f))
16821 /* If the row is empty, add a space with the current face of IT,
16822 so that we know which face to draw. */
16823 if (it->glyph_row->used[TEXT_AREA] == 0)
16825 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
16826 it->glyph_row->glyphs[TEXT_AREA][0].face_id = it->face_id;
16827 it->glyph_row->used[TEXT_AREA] = 1;
16829 #ifdef HAVE_WINDOW_SYSTEM
16830 if (it->glyph_row->reversed_p)
16832 /* Prepend a stretch glyph to the row, such that the
16833 rightmost glyph will be drawn flushed all the way to the
16834 right margin of the window. The stretch glyph that will
16835 occupy the empty space, if any, to the left of the
16836 glyphs. */
16837 struct font *font = face->font ? face->font : FRAME_FONT (f);
16838 struct glyph *row_start = it->glyph_row->glyphs[TEXT_AREA];
16839 struct glyph *row_end = row_start + it->glyph_row->used[TEXT_AREA];
16840 struct glyph *g;
16841 int row_width, stretch_ascent, stretch_width;
16842 struct text_pos saved_pos;
16843 int saved_face_id, saved_avoid_cursor;
16845 for (row_width = 0, g = row_start; g < row_end; g++)
16846 row_width += g->pixel_width;
16847 stretch_width = window_box_width (it->w, TEXT_AREA) - row_width;
16848 if (stretch_width > 0)
16850 stretch_ascent =
16851 (((it->ascent + it->descent)
16852 * FONT_BASE (font)) / FONT_HEIGHT (font));
16853 saved_pos = it->position;
16854 memset (&it->position, 0, sizeof it->position);
16855 saved_avoid_cursor = it->avoid_cursor_p;
16856 it->avoid_cursor_p = 1;
16857 saved_face_id = it->face_id;
16858 /* The last row's stretch glyph should get the default
16859 face, to avoid painting the rest of the window with
16860 the region face, if the region ends at ZV. */
16861 if (it->glyph_row->ends_at_zv_p)
16862 it->face_id = DEFAULT_FACE_ID;
16863 else
16864 it->face_id = face->id;
16865 append_stretch_glyph (it, make_number (0), stretch_width,
16866 it->ascent + it->descent, stretch_ascent);
16867 it->position = saved_pos;
16868 it->avoid_cursor_p = saved_avoid_cursor;
16869 it->face_id = saved_face_id;
16872 #endif /* HAVE_WINDOW_SYSTEM */
16874 else
16876 /* Save some values that must not be changed. */
16877 int saved_x = it->current_x;
16878 struct text_pos saved_pos;
16879 Lisp_Object saved_object;
16880 enum display_element_type saved_what = it->what;
16881 int saved_face_id = it->face_id;
16883 saved_object = it->object;
16884 saved_pos = it->position;
16886 it->what = IT_CHARACTER;
16887 memset (&it->position, 0, sizeof it->position);
16888 it->object = make_number (0);
16889 it->c = ' ';
16890 it->len = 1;
16891 /* The last row's blank glyphs should get the default face, to
16892 avoid painting the rest of the window with the region face,
16893 if the region ends at ZV. */
16894 if (it->glyph_row->ends_at_zv_p)
16895 it->face_id = DEFAULT_FACE_ID;
16896 else
16897 it->face_id = face->id;
16899 PRODUCE_GLYPHS (it);
16901 while (it->current_x <= it->last_visible_x)
16902 PRODUCE_GLYPHS (it);
16904 /* Don't count these blanks really. It would let us insert a left
16905 truncation glyph below and make us set the cursor on them, maybe. */
16906 it->current_x = saved_x;
16907 it->object = saved_object;
16908 it->position = saved_pos;
16909 it->what = saved_what;
16910 it->face_id = saved_face_id;
16915 /* Value is non-zero if text starting at CHARPOS in current_buffer is
16916 trailing whitespace. */
16918 static int
16919 trailing_whitespace_p (int charpos)
16921 int bytepos = CHAR_TO_BYTE (charpos);
16922 int c = 0;
16924 while (bytepos < ZV_BYTE
16925 && (c = FETCH_CHAR (bytepos),
16926 c == ' ' || c == '\t'))
16927 ++bytepos;
16929 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
16931 if (bytepos != PT_BYTE)
16932 return 1;
16934 return 0;
16938 /* Highlight trailing whitespace, if any, in ROW. */
16940 void
16941 highlight_trailing_whitespace (struct frame *f, struct glyph_row *row)
16943 int used = row->used[TEXT_AREA];
16945 if (used)
16947 struct glyph *start = row->glyphs[TEXT_AREA];
16948 struct glyph *glyph = start + used - 1;
16950 if (row->reversed_p)
16952 /* Right-to-left rows need to be processed in the opposite
16953 direction, so swap the edge pointers. */
16954 glyph = start;
16955 start = row->glyphs[TEXT_AREA] + used - 1;
16958 /* Skip over glyphs inserted to display the cursor at the
16959 end of a line, for extending the face of the last glyph
16960 to the end of the line on terminals, and for truncation
16961 and continuation glyphs. */
16962 if (!row->reversed_p)
16964 while (glyph >= start
16965 && glyph->type == CHAR_GLYPH
16966 && INTEGERP (glyph->object))
16967 --glyph;
16969 else
16971 while (glyph <= start
16972 && glyph->type == CHAR_GLYPH
16973 && INTEGERP (glyph->object))
16974 ++glyph;
16977 /* If last glyph is a space or stretch, and it's trailing
16978 whitespace, set the face of all trailing whitespace glyphs in
16979 IT->glyph_row to `trailing-whitespace'. */
16980 if ((row->reversed_p ? glyph <= start : glyph >= start)
16981 && BUFFERP (glyph->object)
16982 && (glyph->type == STRETCH_GLYPH
16983 || (glyph->type == CHAR_GLYPH
16984 && glyph->u.ch == ' '))
16985 && trailing_whitespace_p (glyph->charpos))
16987 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0);
16988 if (face_id < 0)
16989 return;
16991 if (!row->reversed_p)
16993 while (glyph >= start
16994 && BUFFERP (glyph->object)
16995 && (glyph->type == STRETCH_GLYPH
16996 || (glyph->type == CHAR_GLYPH
16997 && glyph->u.ch == ' ')))
16998 (glyph--)->face_id = face_id;
17000 else
17002 while (glyph <= start
17003 && BUFFERP (glyph->object)
17004 && (glyph->type == STRETCH_GLYPH
17005 || (glyph->type == CHAR_GLYPH
17006 && glyph->u.ch == ' ')))
17007 (glyph++)->face_id = face_id;
17014 /* Value is non-zero if glyph row ROW in window W should be
17015 used to hold the cursor. */
17017 static int
17018 cursor_row_p (struct window *w, struct glyph_row *row)
17020 int cursor_row_p = 1;
17022 if (PT == CHARPOS (row->end.pos))
17024 /* Suppose the row ends on a string.
17025 Unless the row is continued, that means it ends on a newline
17026 in the string. If it's anything other than a display string
17027 (e.g. a before-string from an overlay), we don't want the
17028 cursor there. (This heuristic seems to give the optimal
17029 behavior for the various types of multi-line strings.) */
17030 if (CHARPOS (row->end.string_pos) >= 0)
17032 if (row->continued_p)
17033 cursor_row_p = 1;
17034 else
17036 /* Check for `display' property. */
17037 struct glyph *beg = row->glyphs[TEXT_AREA];
17038 struct glyph *end = beg + row->used[TEXT_AREA] - 1;
17039 struct glyph *glyph;
17041 cursor_row_p = 0;
17042 for (glyph = end; glyph >= beg; --glyph)
17043 if (STRINGP (glyph->object))
17045 Lisp_Object prop
17046 = Fget_char_property (make_number (PT),
17047 Qdisplay, Qnil);
17048 cursor_row_p =
17049 (!NILP (prop)
17050 && display_prop_string_p (prop, glyph->object));
17051 break;
17055 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
17057 /* If the row ends in middle of a real character,
17058 and the line is continued, we want the cursor here.
17059 That's because CHARPOS (ROW->end.pos) would equal
17060 PT if PT is before the character. */
17061 if (!row->ends_in_ellipsis_p)
17062 cursor_row_p = row->continued_p;
17063 else
17064 /* If the row ends in an ellipsis, then
17065 CHARPOS (ROW->end.pos) will equal point after the
17066 invisible text. We want that position to be displayed
17067 after the ellipsis. */
17068 cursor_row_p = 0;
17070 /* If the row ends at ZV, display the cursor at the end of that
17071 row instead of at the start of the row below. */
17072 else if (row->ends_at_zv_p)
17073 cursor_row_p = 1;
17074 else
17075 cursor_row_p = 0;
17078 return cursor_row_p;
17083 /* Push the display property PROP so that it will be rendered at the
17084 current position in IT. Return 1 if PROP was successfully pushed,
17085 0 otherwise. */
17087 static int
17088 push_display_prop (struct it *it, Lisp_Object prop)
17090 push_it (it);
17092 if (STRINGP (prop))
17094 if (SCHARS (prop) == 0)
17096 pop_it (it);
17097 return 0;
17100 it->string = prop;
17101 it->multibyte_p = STRING_MULTIBYTE (it->string);
17102 it->current.overlay_string_index = -1;
17103 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
17104 it->end_charpos = it->string_nchars = SCHARS (it->string);
17105 it->method = GET_FROM_STRING;
17106 it->stop_charpos = 0;
17108 else if (CONSP (prop) && EQ (XCAR (prop), Qspace))
17110 it->method = GET_FROM_STRETCH;
17111 it->object = prop;
17113 #ifdef HAVE_WINDOW_SYSTEM
17114 else if (IMAGEP (prop))
17116 it->what = IT_IMAGE;
17117 it->image_id = lookup_image (it->f, prop);
17118 it->method = GET_FROM_IMAGE;
17120 #endif /* HAVE_WINDOW_SYSTEM */
17121 else
17123 pop_it (it); /* bogus display property, give up */
17124 return 0;
17127 return 1;
17130 /* Return the character-property PROP at the current position in IT. */
17132 static Lisp_Object
17133 get_it_property (struct it *it, Lisp_Object prop)
17135 Lisp_Object position;
17137 if (STRINGP (it->object))
17138 position = make_number (IT_STRING_CHARPOS (*it));
17139 else if (BUFFERP (it->object))
17140 position = make_number (IT_CHARPOS (*it));
17141 else
17142 return Qnil;
17144 return Fget_char_property (position, prop, it->object);
17147 /* See if there's a line- or wrap-prefix, and if so, push it on IT. */
17149 static void
17150 handle_line_prefix (struct it *it)
17152 Lisp_Object prefix;
17153 if (it->continuation_lines_width > 0)
17155 prefix = get_it_property (it, Qwrap_prefix);
17156 if (NILP (prefix))
17157 prefix = Vwrap_prefix;
17159 else
17161 prefix = get_it_property (it, Qline_prefix);
17162 if (NILP (prefix))
17163 prefix = Vline_prefix;
17165 if (! NILP (prefix) && push_display_prop (it, prefix))
17167 /* If the prefix is wider than the window, and we try to wrap
17168 it, it would acquire its own wrap prefix, and so on till the
17169 iterator stack overflows. So, don't wrap the prefix. */
17170 it->line_wrap = TRUNCATE;
17171 it->avoid_cursor_p = 1;
17177 /* Remove N glyphs at the start of a reversed IT->glyph_row. Called
17178 only for R2L lines from display_line, when it decides that too many
17179 glyphs were produced by PRODUCE_GLYPHS, and the line needs to be
17180 continued. */
17181 static void
17182 unproduce_glyphs (struct it *it, int n)
17184 struct glyph *glyph, *end;
17186 xassert (it->glyph_row);
17187 xassert (it->glyph_row->reversed_p);
17188 xassert (it->area == TEXT_AREA);
17189 xassert (n <= it->glyph_row->used[TEXT_AREA]);
17191 if (n > it->glyph_row->used[TEXT_AREA])
17192 n = it->glyph_row->used[TEXT_AREA];
17193 glyph = it->glyph_row->glyphs[TEXT_AREA] + n;
17194 end = it->glyph_row->glyphs[TEXT_AREA] + it->glyph_row->used[TEXT_AREA];
17195 for ( ; glyph < end; glyph++)
17196 glyph[-n] = *glyph;
17199 /* Find the positions in a bidi-reordered ROW to serve as ROW->minpos
17200 and ROW->maxpos. */
17201 static void
17202 find_row_edges (struct it *it, struct glyph_row *row,
17203 EMACS_INT min_pos, EMACS_INT min_bpos,
17204 EMACS_INT max_pos, EMACS_INT max_bpos)
17206 /* FIXME: Revisit this when glyph ``spilling'' in continuation
17207 lines' rows is implemented for bidi-reordered rows. */
17209 /* ROW->minpos is the value of min_pos, the minimal buffer position
17210 we have in ROW. */
17211 if (min_pos <= ZV)
17212 SET_TEXT_POS (row->minpos, min_pos, min_bpos);
17213 else
17215 /* We didn't find _any_ valid buffer positions in any of the
17216 glyphs, so we must trust the iterator's computed
17217 positions. */
17218 row->minpos = row->start.pos;
17219 max_pos = CHARPOS (it->current.pos);
17220 max_bpos = BYTEPOS (it->current.pos);
17223 if (!max_pos)
17224 abort ();
17226 /* Here are the various use-cases for ending the row, and the
17227 corresponding values for ROW->maxpos:
17229 Line ends in a newline from buffer eol_pos + 1
17230 Line is continued from buffer max_pos + 1
17231 Line is truncated on right it->current.pos
17232 Line ends in a newline from string max_pos
17233 Line is continued from string max_pos
17234 Line is continued from display vector max_pos
17235 Line is entirely from a string min_pos == max_pos
17236 Line is entirely from a display vector min_pos == max_pos
17237 Line that ends at ZV ZV
17239 If you discover other use-cases, please add them here as
17240 appropriate. */
17241 if (row->ends_at_zv_p)
17242 row->maxpos = it->current.pos;
17243 else if (row->used[TEXT_AREA])
17245 if (row->ends_in_newline_from_string_p)
17246 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
17247 else if (CHARPOS (it->eol_pos) > 0)
17248 SET_TEXT_POS (row->maxpos,
17249 CHARPOS (it->eol_pos) + 1, BYTEPOS (it->eol_pos) + 1);
17250 else if (row->continued_p)
17252 /* If max_pos is different from IT's current position, it
17253 means IT->method does not belong to the display element
17254 at max_pos. However, it also means that the display
17255 element at max_pos was displayed in its entirety on this
17256 line, which is equivalent to saying that the next line
17257 starts at the next buffer position. */
17258 if (IT_CHARPOS (*it) == max_pos && it->method != GET_FROM_BUFFER)
17259 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
17260 else
17262 INC_BOTH (max_pos, max_bpos);
17263 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
17266 else if (row->truncated_on_right_p)
17267 /* display_line already called reseat_at_next_visible_line_start,
17268 which puts the iterator at the beginning of the next line, in
17269 the logical order. */
17270 row->maxpos = it->current.pos;
17271 else if (max_pos == min_pos && it->method != GET_FROM_BUFFER)
17272 /* A line that is entirely from a string/image/stretch... */
17273 row->maxpos = row->minpos;
17274 else
17275 abort ();
17277 else
17278 row->maxpos = it->current.pos;
17281 /* Construct the glyph row IT->glyph_row in the desired matrix of
17282 IT->w from text at the current position of IT. See dispextern.h
17283 for an overview of struct it. Value is non-zero if
17284 IT->glyph_row displays text, as opposed to a line displaying ZV
17285 only. */
17287 static int
17288 display_line (struct it *it)
17290 struct glyph_row *row = it->glyph_row;
17291 Lisp_Object overlay_arrow_string;
17292 struct it wrap_it;
17293 int may_wrap = 0, wrap_x;
17294 int wrap_row_used = -1, wrap_row_ascent, wrap_row_height;
17295 int wrap_row_phys_ascent, wrap_row_phys_height;
17296 int wrap_row_extra_line_spacing;
17297 EMACS_INT wrap_row_min_pos, wrap_row_min_bpos;
17298 EMACS_INT wrap_row_max_pos, wrap_row_max_bpos;
17299 int cvpos;
17300 EMACS_INT min_pos = ZV + 1, min_bpos, max_pos = 0, max_bpos;
17302 /* We always start displaying at hpos zero even if hscrolled. */
17303 xassert (it->hpos == 0 && it->current_x == 0);
17305 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
17306 >= it->w->desired_matrix->nrows)
17308 it->w->nrows_scale_factor++;
17309 fonts_changed_p = 1;
17310 return 0;
17313 /* Is IT->w showing the region? */
17314 it->w->region_showing = it->region_beg_charpos > 0 ? Qt : Qnil;
17316 /* Clear the result glyph row and enable it. */
17317 prepare_desired_row (row);
17319 row->y = it->current_y;
17320 row->start = it->start;
17321 row->continuation_lines_width = it->continuation_lines_width;
17322 row->displays_text_p = 1;
17323 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
17324 it->starts_in_middle_of_char_p = 0;
17326 /* Arrange the overlays nicely for our purposes. Usually, we call
17327 display_line on only one line at a time, in which case this
17328 can't really hurt too much, or we call it on lines which appear
17329 one after another in the buffer, in which case all calls to
17330 recenter_overlay_lists but the first will be pretty cheap. */
17331 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
17333 /* Move over display elements that are not visible because we are
17334 hscrolled. This may stop at an x-position < IT->first_visible_x
17335 if the first glyph is partially visible or if we hit a line end. */
17336 if (it->current_x < it->first_visible_x)
17338 move_it_in_display_line_to (it, ZV, it->first_visible_x,
17339 MOVE_TO_POS | MOVE_TO_X);
17341 else
17343 /* We only do this when not calling `move_it_in_display_line_to'
17344 above, because move_it_in_display_line_to calls
17345 handle_line_prefix itself. */
17346 handle_line_prefix (it);
17349 /* Get the initial row height. This is either the height of the
17350 text hscrolled, if there is any, or zero. */
17351 row->ascent = it->max_ascent;
17352 row->height = it->max_ascent + it->max_descent;
17353 row->phys_ascent = it->max_phys_ascent;
17354 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
17355 row->extra_line_spacing = it->max_extra_line_spacing;
17357 /* Utility macro to record max and min buffer positions seen until now. */
17358 #define RECORD_MAX_MIN_POS(IT) \
17359 do \
17361 if (IT_CHARPOS (*(IT)) < min_pos) \
17363 min_pos = IT_CHARPOS (*(IT)); \
17364 min_bpos = IT_BYTEPOS (*(IT)); \
17366 if (IT_CHARPOS (*(IT)) > max_pos) \
17368 max_pos = IT_CHARPOS (*(IT)); \
17369 max_bpos = IT_BYTEPOS (*(IT)); \
17372 while (0)
17374 /* Loop generating characters. The loop is left with IT on the next
17375 character to display. */
17376 while (1)
17378 int n_glyphs_before, hpos_before, x_before;
17379 int x, i, nglyphs;
17380 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
17382 /* Retrieve the next thing to display. Value is zero if end of
17383 buffer reached. */
17384 if (!get_next_display_element (it))
17386 /* Maybe add a space at the end of this line that is used to
17387 display the cursor there under X. Set the charpos of the
17388 first glyph of blank lines not corresponding to any text
17389 to -1. */
17390 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
17391 row->exact_window_width_line_p = 1;
17392 else if ((append_space_for_newline (it, 1) && row->used[TEXT_AREA] == 1)
17393 || row->used[TEXT_AREA] == 0)
17395 row->glyphs[TEXT_AREA]->charpos = -1;
17396 row->displays_text_p = 0;
17398 if (!NILP (XBUFFER (it->w->buffer)->indicate_empty_lines)
17399 && (!MINI_WINDOW_P (it->w)
17400 || (minibuf_level && EQ (it->window, minibuf_window))))
17401 row->indicate_empty_line_p = 1;
17404 it->continuation_lines_width = 0;
17405 row->ends_at_zv_p = 1;
17406 /* A row that displays right-to-left text must always have
17407 its last face extended all the way to the end of line,
17408 even if this row ends in ZV, because we still write to
17409 the screen left to right. */
17410 if (row->reversed_p)
17411 extend_face_to_end_of_line (it);
17412 break;
17415 /* Now, get the metrics of what we want to display. This also
17416 generates glyphs in `row' (which is IT->glyph_row). */
17417 n_glyphs_before = row->used[TEXT_AREA];
17418 x = it->current_x;
17420 /* Remember the line height so far in case the next element doesn't
17421 fit on the line. */
17422 if (it->line_wrap != TRUNCATE)
17424 ascent = it->max_ascent;
17425 descent = it->max_descent;
17426 phys_ascent = it->max_phys_ascent;
17427 phys_descent = it->max_phys_descent;
17429 if (it->line_wrap == WORD_WRAP && it->area == TEXT_AREA)
17431 if (IT_DISPLAYING_WHITESPACE (it))
17432 may_wrap = 1;
17433 else if (may_wrap)
17435 wrap_it = *it;
17436 wrap_x = x;
17437 wrap_row_used = row->used[TEXT_AREA];
17438 wrap_row_ascent = row->ascent;
17439 wrap_row_height = row->height;
17440 wrap_row_phys_ascent = row->phys_ascent;
17441 wrap_row_phys_height = row->phys_height;
17442 wrap_row_extra_line_spacing = row->extra_line_spacing;
17443 wrap_row_min_pos = min_pos;
17444 wrap_row_min_bpos = min_bpos;
17445 wrap_row_max_pos = max_pos;
17446 wrap_row_max_bpos = max_bpos;
17447 may_wrap = 0;
17452 PRODUCE_GLYPHS (it);
17454 /* If this display element was in marginal areas, continue with
17455 the next one. */
17456 if (it->area != TEXT_AREA)
17458 row->ascent = max (row->ascent, it->max_ascent);
17459 row->height = max (row->height, it->max_ascent + it->max_descent);
17460 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
17461 row->phys_height = max (row->phys_height,
17462 it->max_phys_ascent + it->max_phys_descent);
17463 row->extra_line_spacing = max (row->extra_line_spacing,
17464 it->max_extra_line_spacing);
17465 set_iterator_to_next (it, 1);
17466 continue;
17469 /* Does the display element fit on the line? If we truncate
17470 lines, we should draw past the right edge of the window. If
17471 we don't truncate, we want to stop so that we can display the
17472 continuation glyph before the right margin. If lines are
17473 continued, there are two possible strategies for characters
17474 resulting in more than 1 glyph (e.g. tabs): Display as many
17475 glyphs as possible in this line and leave the rest for the
17476 continuation line, or display the whole element in the next
17477 line. Original redisplay did the former, so we do it also. */
17478 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
17479 hpos_before = it->hpos;
17480 x_before = x;
17482 if (/* Not a newline. */
17483 nglyphs > 0
17484 /* Glyphs produced fit entirely in the line. */
17485 && it->current_x < it->last_visible_x)
17487 it->hpos += nglyphs;
17488 row->ascent = max (row->ascent, it->max_ascent);
17489 row->height = max (row->height, it->max_ascent + it->max_descent);
17490 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
17491 row->phys_height = max (row->phys_height,
17492 it->max_phys_ascent + it->max_phys_descent);
17493 row->extra_line_spacing = max (row->extra_line_spacing,
17494 it->max_extra_line_spacing);
17495 if (it->current_x - it->pixel_width < it->first_visible_x)
17496 row->x = x - it->first_visible_x;
17497 /* Record the maximum and minimum buffer positions seen so
17498 far in glyphs that will be displayed by this row. */
17499 if (it->bidi_p)
17500 RECORD_MAX_MIN_POS (it);
17502 else
17504 int new_x;
17505 struct glyph *glyph;
17507 for (i = 0; i < nglyphs; ++i, x = new_x)
17509 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
17510 new_x = x + glyph->pixel_width;
17512 if (/* Lines are continued. */
17513 it->line_wrap != TRUNCATE
17514 && (/* Glyph doesn't fit on the line. */
17515 new_x > it->last_visible_x
17516 /* Or it fits exactly on a window system frame. */
17517 || (new_x == it->last_visible_x
17518 && FRAME_WINDOW_P (it->f))))
17520 /* End of a continued line. */
17522 if (it->hpos == 0
17523 || (new_x == it->last_visible_x
17524 && FRAME_WINDOW_P (it->f)))
17526 /* Current glyph is the only one on the line or
17527 fits exactly on the line. We must continue
17528 the line because we can't draw the cursor
17529 after the glyph. */
17530 row->continued_p = 1;
17531 it->current_x = new_x;
17532 it->continuation_lines_width += new_x;
17533 ++it->hpos;
17534 /* Record the maximum and minimum buffer
17535 positions seen so far in glyphs that will be
17536 displayed by this row. */
17537 if (it->bidi_p)
17538 RECORD_MAX_MIN_POS (it);
17539 if (i == nglyphs - 1)
17541 /* If line-wrap is on, check if a previous
17542 wrap point was found. */
17543 if (wrap_row_used > 0
17544 /* Even if there is a previous wrap
17545 point, continue the line here as
17546 usual, if (i) the previous character
17547 was a space or tab AND (ii) the
17548 current character is not. */
17549 && (!may_wrap
17550 || IT_DISPLAYING_WHITESPACE (it)))
17551 goto back_to_wrap;
17553 set_iterator_to_next (it, 1);
17554 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
17556 if (!get_next_display_element (it))
17558 row->exact_window_width_line_p = 1;
17559 it->continuation_lines_width = 0;
17560 row->continued_p = 0;
17561 row->ends_at_zv_p = 1;
17563 else if (ITERATOR_AT_END_OF_LINE_P (it))
17565 row->continued_p = 0;
17566 row->exact_window_width_line_p = 1;
17571 else if (CHAR_GLYPH_PADDING_P (*glyph)
17572 && !FRAME_WINDOW_P (it->f))
17574 /* A padding glyph that doesn't fit on this line.
17575 This means the whole character doesn't fit
17576 on the line. */
17577 if (row->reversed_p)
17578 unproduce_glyphs (it, row->used[TEXT_AREA]
17579 - n_glyphs_before);
17580 row->used[TEXT_AREA] = n_glyphs_before;
17582 /* Fill the rest of the row with continuation
17583 glyphs like in 20.x. */
17584 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
17585 < row->glyphs[1 + TEXT_AREA])
17586 produce_special_glyphs (it, IT_CONTINUATION);
17588 row->continued_p = 1;
17589 it->current_x = x_before;
17590 it->continuation_lines_width += x_before;
17592 /* Restore the height to what it was before the
17593 element not fitting on the line. */
17594 it->max_ascent = ascent;
17595 it->max_descent = descent;
17596 it->max_phys_ascent = phys_ascent;
17597 it->max_phys_descent = phys_descent;
17599 else if (wrap_row_used > 0)
17601 back_to_wrap:
17602 if (row->reversed_p)
17603 unproduce_glyphs (it,
17604 row->used[TEXT_AREA] - wrap_row_used);
17605 *it = wrap_it;
17606 it->continuation_lines_width += wrap_x;
17607 row->used[TEXT_AREA] = wrap_row_used;
17608 row->ascent = wrap_row_ascent;
17609 row->height = wrap_row_height;
17610 row->phys_ascent = wrap_row_phys_ascent;
17611 row->phys_height = wrap_row_phys_height;
17612 row->extra_line_spacing = wrap_row_extra_line_spacing;
17613 min_pos = wrap_row_min_pos;
17614 min_bpos = wrap_row_min_bpos;
17615 max_pos = wrap_row_max_pos;
17616 max_bpos = wrap_row_max_bpos;
17617 row->continued_p = 1;
17618 row->ends_at_zv_p = 0;
17619 row->exact_window_width_line_p = 0;
17620 it->continuation_lines_width += x;
17622 /* Make sure that a non-default face is extended
17623 up to the right margin of the window. */
17624 extend_face_to_end_of_line (it);
17626 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
17628 /* A TAB that extends past the right edge of the
17629 window. This produces a single glyph on
17630 window system frames. We leave the glyph in
17631 this row and let it fill the row, but don't
17632 consume the TAB. */
17633 it->continuation_lines_width += it->last_visible_x;
17634 row->ends_in_middle_of_char_p = 1;
17635 row->continued_p = 1;
17636 glyph->pixel_width = it->last_visible_x - x;
17637 it->starts_in_middle_of_char_p = 1;
17639 else
17641 /* Something other than a TAB that draws past
17642 the right edge of the window. Restore
17643 positions to values before the element. */
17644 if (row->reversed_p)
17645 unproduce_glyphs (it, row->used[TEXT_AREA]
17646 - (n_glyphs_before + i));
17647 row->used[TEXT_AREA] = n_glyphs_before + i;
17649 /* Display continuation glyphs. */
17650 if (!FRAME_WINDOW_P (it->f))
17651 produce_special_glyphs (it, IT_CONTINUATION);
17652 row->continued_p = 1;
17654 it->current_x = x_before;
17655 it->continuation_lines_width += x;
17656 extend_face_to_end_of_line (it);
17658 if (nglyphs > 1 && i > 0)
17660 row->ends_in_middle_of_char_p = 1;
17661 it->starts_in_middle_of_char_p = 1;
17664 /* Restore the height to what it was before the
17665 element not fitting on the line. */
17666 it->max_ascent = ascent;
17667 it->max_descent = descent;
17668 it->max_phys_ascent = phys_ascent;
17669 it->max_phys_descent = phys_descent;
17672 break;
17674 else if (new_x > it->first_visible_x)
17676 /* Increment number of glyphs actually displayed. */
17677 ++it->hpos;
17679 /* Record the maximum and minimum buffer positions
17680 seen so far in glyphs that will be displayed by
17681 this row. */
17682 if (it->bidi_p)
17683 RECORD_MAX_MIN_POS (it);
17685 if (x < it->first_visible_x)
17686 /* Glyph is partially visible, i.e. row starts at
17687 negative X position. */
17688 row->x = x - it->first_visible_x;
17690 else
17692 /* Glyph is completely off the left margin of the
17693 window. This should not happen because of the
17694 move_it_in_display_line at the start of this
17695 function, unless the text display area of the
17696 window is empty. */
17697 xassert (it->first_visible_x <= it->last_visible_x);
17701 row->ascent = max (row->ascent, it->max_ascent);
17702 row->height = max (row->height, it->max_ascent + it->max_descent);
17703 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
17704 row->phys_height = max (row->phys_height,
17705 it->max_phys_ascent + it->max_phys_descent);
17706 row->extra_line_spacing = max (row->extra_line_spacing,
17707 it->max_extra_line_spacing);
17709 /* End of this display line if row is continued. */
17710 if (row->continued_p || row->ends_at_zv_p)
17711 break;
17714 at_end_of_line:
17715 /* Is this a line end? If yes, we're also done, after making
17716 sure that a non-default face is extended up to the right
17717 margin of the window. */
17718 if (ITERATOR_AT_END_OF_LINE_P (it))
17720 int used_before = row->used[TEXT_AREA];
17722 row->ends_in_newline_from_string_p = STRINGP (it->object);
17724 /* Add a space at the end of the line that is used to
17725 display the cursor there. */
17726 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
17727 append_space_for_newline (it, 0);
17729 /* Extend the face to the end of the line. */
17730 extend_face_to_end_of_line (it);
17732 /* Make sure we have the position. */
17733 if (used_before == 0)
17734 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
17736 /* Record the position of the newline, for use in
17737 find_row_edges. */
17738 it->eol_pos = it->current.pos;
17740 /* Consume the line end. This skips over invisible lines. */
17741 set_iterator_to_next (it, 1);
17742 it->continuation_lines_width = 0;
17743 break;
17746 /* Proceed with next display element. Note that this skips
17747 over lines invisible because of selective display. */
17748 set_iterator_to_next (it, 1);
17750 /* If we truncate lines, we are done when the last displayed
17751 glyphs reach past the right margin of the window. */
17752 if (it->line_wrap == TRUNCATE
17753 && (FRAME_WINDOW_P (it->f)
17754 ? (it->current_x >= it->last_visible_x)
17755 : (it->current_x > it->last_visible_x)))
17757 /* Maybe add truncation glyphs. */
17758 if (!FRAME_WINDOW_P (it->f))
17760 int i, n;
17762 if (!row->reversed_p)
17764 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
17765 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
17766 break;
17768 else
17770 for (i = 0; i < row->used[TEXT_AREA]; i++)
17771 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
17772 break;
17773 /* Remove any padding glyphs at the front of ROW, to
17774 make room for the truncation glyphs we will be
17775 adding below. The loop below always inserts at
17776 least one truncation glyph, so also remove the
17777 last glyph added to ROW. */
17778 unproduce_glyphs (it, i + 1);
17779 /* Adjust i for the loop below. */
17780 i = row->used[TEXT_AREA] - (i + 1);
17783 for (n = row->used[TEXT_AREA]; i < n; ++i)
17785 row->used[TEXT_AREA] = i;
17786 produce_special_glyphs (it, IT_TRUNCATION);
17789 else if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
17791 /* Don't truncate if we can overflow newline into fringe. */
17792 if (!get_next_display_element (it))
17794 it->continuation_lines_width = 0;
17795 row->ends_at_zv_p = 1;
17796 row->exact_window_width_line_p = 1;
17797 break;
17799 if (ITERATOR_AT_END_OF_LINE_P (it))
17801 row->exact_window_width_line_p = 1;
17802 goto at_end_of_line;
17806 row->truncated_on_right_p = 1;
17807 it->continuation_lines_width = 0;
17808 reseat_at_next_visible_line_start (it, 0);
17809 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
17810 it->hpos = hpos_before;
17811 it->current_x = x_before;
17812 break;
17816 /* If line is not empty and hscrolled, maybe insert truncation glyphs
17817 at the left window margin. */
17818 if (it->first_visible_x
17819 && IT_CHARPOS (*it) != CHARPOS (row->start.pos))
17821 if (!FRAME_WINDOW_P (it->f))
17822 insert_left_trunc_glyphs (it);
17823 row->truncated_on_left_p = 1;
17826 /* Remember the position at which this line ends.
17828 BIDI Note: any code that needs MATRIX_ROW_START/END_CHARPOS
17829 cannot be before the call to find_row_edges below, since that is
17830 where these positions are determined. */
17831 row->end = it->current;
17832 if (!it->bidi_p)
17834 row->minpos = row->start.pos;
17835 row->maxpos = row->end.pos;
17837 else
17839 /* ROW->minpos and ROW->maxpos must be the smallest and
17840 `1 + the largest' buffer positions in ROW. But if ROW was
17841 bidi-reordered, these two positions can be anywhere in the
17842 row, so we must determine them now. */
17843 find_row_edges (it, row, min_pos, min_bpos, max_pos, max_bpos);
17846 /* If the start of this line is the overlay arrow-position, then
17847 mark this glyph row as the one containing the overlay arrow.
17848 This is clearly a mess with variable size fonts. It would be
17849 better to let it be displayed like cursors under X. */
17850 if ((row->displays_text_p || !overlay_arrow_seen)
17851 && (overlay_arrow_string = overlay_arrow_at_row (it, row),
17852 !NILP (overlay_arrow_string)))
17854 /* Overlay arrow in window redisplay is a fringe bitmap. */
17855 if (STRINGP (overlay_arrow_string))
17857 struct glyph_row *arrow_row
17858 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
17859 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
17860 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
17861 struct glyph *p = row->glyphs[TEXT_AREA];
17862 struct glyph *p2, *end;
17864 /* Copy the arrow glyphs. */
17865 while (glyph < arrow_end)
17866 *p++ = *glyph++;
17868 /* Throw away padding glyphs. */
17869 p2 = p;
17870 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
17871 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
17872 ++p2;
17873 if (p2 > p)
17875 while (p2 < end)
17876 *p++ = *p2++;
17877 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
17880 else
17882 xassert (INTEGERP (overlay_arrow_string));
17883 row->overlay_arrow_bitmap = XINT (overlay_arrow_string);
17885 overlay_arrow_seen = 1;
17888 /* Compute pixel dimensions of this line. */
17889 compute_line_metrics (it);
17891 /* Record whether this row ends inside an ellipsis. */
17892 row->ends_in_ellipsis_p
17893 = (it->method == GET_FROM_DISPLAY_VECTOR
17894 && it->ellipsis_p);
17896 /* Save fringe bitmaps in this row. */
17897 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
17898 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
17899 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
17900 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
17902 it->left_user_fringe_bitmap = 0;
17903 it->left_user_fringe_face_id = 0;
17904 it->right_user_fringe_bitmap = 0;
17905 it->right_user_fringe_face_id = 0;
17907 /* Maybe set the cursor. */
17908 cvpos = it->w->cursor.vpos;
17909 if ((cvpos < 0
17910 /* In bidi-reordered rows, keep checking for proper cursor
17911 position even if one has been found already, because buffer
17912 positions in such rows change non-linearly with ROW->VPOS,
17913 when a line is continued. One exception: when we are at ZV,
17914 display cursor on the first suitable glyph row, since all
17915 the empty rows after that also have their position set to ZV. */
17916 /* FIXME: Revisit this when glyph ``spilling'' in continuation
17917 lines' rows is implemented for bidi-reordered rows. */
17918 || (it->bidi_p
17919 && !MATRIX_ROW (it->w->desired_matrix, cvpos)->ends_at_zv_p))
17920 && PT >= MATRIX_ROW_START_CHARPOS (row)
17921 && PT <= MATRIX_ROW_END_CHARPOS (row)
17922 && cursor_row_p (it->w, row))
17923 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
17925 /* Highlight trailing whitespace. */
17926 if (!NILP (Vshow_trailing_whitespace))
17927 highlight_trailing_whitespace (it->f, it->glyph_row);
17929 /* Prepare for the next line. This line starts horizontally at (X
17930 HPOS) = (0 0). Vertical positions are incremented. As a
17931 convenience for the caller, IT->glyph_row is set to the next
17932 row to be used. */
17933 it->current_x = it->hpos = 0;
17934 it->current_y += row->height;
17935 SET_TEXT_POS (it->eol_pos, 0, 0);
17936 ++it->vpos;
17937 ++it->glyph_row;
17938 /* The next row should by default use the same value of the
17939 reversed_p flag as this one. set_iterator_to_next decides when
17940 it's a new paragraph, and PRODUCE_GLYPHS recomputes the value of
17941 the flag accordingly. */
17942 if (it->glyph_row < MATRIX_BOTTOM_TEXT_ROW (it->w->desired_matrix, it->w))
17943 it->glyph_row->reversed_p = row->reversed_p;
17944 it->start = row->end;
17945 return row->displays_text_p;
17947 #undef RECORD_MAX_MIN_POS
17950 DEFUN ("current-bidi-paragraph-direction", Fcurrent_bidi_paragraph_direction,
17951 Scurrent_bidi_paragraph_direction, 0, 1, 0,
17952 doc: /* Return paragraph direction at point in BUFFER.
17953 Value is either `left-to-right' or `right-to-left'.
17954 If BUFFER is omitted or nil, it defaults to the current buffer.
17956 Paragraph direction determines how the text in the paragraph is displayed.
17957 In left-to-right paragraphs, text begins at the left margin of the window
17958 and the reading direction is generally left to right. In right-to-left
17959 paragraphs, text begins at the right margin and is read from right to left.
17961 See also `bidi-paragraph-direction'. */)
17962 (Lisp_Object buffer)
17964 struct buffer *buf;
17965 struct buffer *old;
17967 if (NILP (buffer))
17968 buf = current_buffer;
17969 else
17971 CHECK_BUFFER (buffer);
17972 buf = XBUFFER (buffer);
17973 old = current_buffer;
17976 if (NILP (buf->bidi_display_reordering))
17977 return Qleft_to_right;
17978 else if (!NILP (buf->bidi_paragraph_direction))
17979 return buf->bidi_paragraph_direction;
17980 else
17982 /* Determine the direction from buffer text. We could try to
17983 use current_matrix if it is up to date, but this seems fast
17984 enough as it is. */
17985 struct bidi_it itb;
17986 EMACS_INT pos = BUF_PT (buf);
17987 EMACS_INT bytepos = BUF_PT_BYTE (buf);
17988 int c;
17990 if (buf != current_buffer)
17991 set_buffer_temp (buf);
17992 /* bidi_paragraph_init finds the base direction of the paragraph
17993 by searching forward from paragraph start. We need the base
17994 direction of the current or _previous_ paragraph, so we need
17995 to make sure we are within that paragraph. To that end, find
17996 the previous non-empty line. */
17997 if (pos >= ZV && pos > BEGV)
17999 pos--;
18000 bytepos = CHAR_TO_BYTE (pos);
18002 while ((c = FETCH_BYTE (bytepos)) == '\n'
18003 || c == ' ' || c == '\t' || c == '\f')
18005 if (bytepos <= BEGV_BYTE)
18006 break;
18007 bytepos--;
18008 pos--;
18010 while (!CHAR_HEAD_P (FETCH_BYTE (bytepos)))
18011 bytepos--;
18012 itb.charpos = pos;
18013 itb.bytepos = bytepos;
18014 itb.first_elt = 1;
18015 itb.separator_limit = -1;
18017 bidi_paragraph_init (NEUTRAL_DIR, &itb);
18018 if (buf != current_buffer)
18019 set_buffer_temp (old);
18020 switch (itb.paragraph_dir)
18022 case L2R:
18023 return Qleft_to_right;
18024 break;
18025 case R2L:
18026 return Qright_to_left;
18027 break;
18028 default:
18029 abort ();
18036 /***********************************************************************
18037 Menu Bar
18038 ***********************************************************************/
18040 /* Redisplay the menu bar in the frame for window W.
18042 The menu bar of X frames that don't have X toolkit support is
18043 displayed in a special window W->frame->menu_bar_window.
18045 The menu bar of terminal frames is treated specially as far as
18046 glyph matrices are concerned. Menu bar lines are not part of
18047 windows, so the update is done directly on the frame matrix rows
18048 for the menu bar. */
18050 static void
18051 display_menu_bar (struct window *w)
18053 struct frame *f = XFRAME (WINDOW_FRAME (w));
18054 struct it it;
18055 Lisp_Object items;
18056 int i;
18058 /* Don't do all this for graphical frames. */
18059 #ifdef HAVE_NTGUI
18060 if (FRAME_W32_P (f))
18061 return;
18062 #endif
18063 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
18064 if (FRAME_X_P (f))
18065 return;
18066 #endif
18068 #ifdef HAVE_NS
18069 if (FRAME_NS_P (f))
18070 return;
18071 #endif /* HAVE_NS */
18073 #ifdef USE_X_TOOLKIT
18074 xassert (!FRAME_WINDOW_P (f));
18075 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
18076 it.first_visible_x = 0;
18077 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
18078 #else /* not USE_X_TOOLKIT */
18079 if (FRAME_WINDOW_P (f))
18081 /* Menu bar lines are displayed in the desired matrix of the
18082 dummy window menu_bar_window. */
18083 struct window *menu_w;
18084 xassert (WINDOWP (f->menu_bar_window));
18085 menu_w = XWINDOW (f->menu_bar_window);
18086 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
18087 MENU_FACE_ID);
18088 it.first_visible_x = 0;
18089 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
18091 else
18093 /* This is a TTY frame, i.e. character hpos/vpos are used as
18094 pixel x/y. */
18095 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
18096 MENU_FACE_ID);
18097 it.first_visible_x = 0;
18098 it.last_visible_x = FRAME_COLS (f);
18100 #endif /* not USE_X_TOOLKIT */
18102 if (! mode_line_inverse_video)
18103 /* Force the menu-bar to be displayed in the default face. */
18104 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
18106 /* Clear all rows of the menu bar. */
18107 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
18109 struct glyph_row *row = it.glyph_row + i;
18110 clear_glyph_row (row);
18111 row->enabled_p = 1;
18112 row->full_width_p = 1;
18115 /* Display all items of the menu bar. */
18116 items = FRAME_MENU_BAR_ITEMS (it.f);
18117 for (i = 0; i < XVECTOR (items)->size; i += 4)
18119 Lisp_Object string;
18121 /* Stop at nil string. */
18122 string = AREF (items, i + 1);
18123 if (NILP (string))
18124 break;
18126 /* Remember where item was displayed. */
18127 ASET (items, i + 3, make_number (it.hpos));
18129 /* Display the item, pad with one space. */
18130 if (it.current_x < it.last_visible_x)
18131 display_string (NULL, string, Qnil, 0, 0, &it,
18132 SCHARS (string) + 1, 0, 0, -1);
18135 /* Fill out the line with spaces. */
18136 if (it.current_x < it.last_visible_x)
18137 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
18139 /* Compute the total height of the lines. */
18140 compute_line_metrics (&it);
18145 /***********************************************************************
18146 Mode Line
18147 ***********************************************************************/
18149 /* Redisplay mode lines in the window tree whose root is WINDOW. If
18150 FORCE is non-zero, redisplay mode lines unconditionally.
18151 Otherwise, redisplay only mode lines that are garbaged. Value is
18152 the number of windows whose mode lines were redisplayed. */
18154 static int
18155 redisplay_mode_lines (Lisp_Object window, int force)
18157 int nwindows = 0;
18159 while (!NILP (window))
18161 struct window *w = XWINDOW (window);
18163 if (WINDOWP (w->hchild))
18164 nwindows += redisplay_mode_lines (w->hchild, force);
18165 else if (WINDOWP (w->vchild))
18166 nwindows += redisplay_mode_lines (w->vchild, force);
18167 else if (force
18168 || FRAME_GARBAGED_P (XFRAME (w->frame))
18169 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
18171 struct text_pos lpoint;
18172 struct buffer *old = current_buffer;
18174 /* Set the window's buffer for the mode line display. */
18175 SET_TEXT_POS (lpoint, PT, PT_BYTE);
18176 set_buffer_internal_1 (XBUFFER (w->buffer));
18178 /* Point refers normally to the selected window. For any
18179 other window, set up appropriate value. */
18180 if (!EQ (window, selected_window))
18182 struct text_pos pt;
18184 SET_TEXT_POS_FROM_MARKER (pt, w->pointm);
18185 if (CHARPOS (pt) < BEGV)
18186 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
18187 else if (CHARPOS (pt) > (ZV - 1))
18188 TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
18189 else
18190 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
18193 /* Display mode lines. */
18194 clear_glyph_matrix (w->desired_matrix);
18195 if (display_mode_lines (w))
18197 ++nwindows;
18198 w->must_be_updated_p = 1;
18201 /* Restore old settings. */
18202 set_buffer_internal_1 (old);
18203 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
18206 window = w->next;
18209 return nwindows;
18213 /* Display the mode and/or header line of window W. Value is the
18214 sum number of mode lines and header lines displayed. */
18216 static int
18217 display_mode_lines (struct window *w)
18219 Lisp_Object old_selected_window, old_selected_frame;
18220 int n = 0;
18222 old_selected_frame = selected_frame;
18223 selected_frame = w->frame;
18224 old_selected_window = selected_window;
18225 XSETWINDOW (selected_window, w);
18227 /* These will be set while the mode line specs are processed. */
18228 line_number_displayed = 0;
18229 w->column_number_displayed = Qnil;
18231 if (WINDOW_WANTS_MODELINE_P (w))
18233 struct window *sel_w = XWINDOW (old_selected_window);
18235 /* Select mode line face based on the real selected window. */
18236 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
18237 current_buffer->mode_line_format);
18238 ++n;
18241 if (WINDOW_WANTS_HEADER_LINE_P (w))
18243 display_mode_line (w, HEADER_LINE_FACE_ID,
18244 current_buffer->header_line_format);
18245 ++n;
18248 selected_frame = old_selected_frame;
18249 selected_window = old_selected_window;
18250 return n;
18254 /* Display mode or header line of window W. FACE_ID specifies which
18255 line to display; it is either MODE_LINE_FACE_ID or
18256 HEADER_LINE_FACE_ID. FORMAT is the mode/header line format to
18257 display. Value is the pixel height of the mode/header line
18258 displayed. */
18260 static int
18261 display_mode_line (struct window *w, enum face_id face_id, Lisp_Object format)
18263 struct it it;
18264 struct face *face;
18265 int count = SPECPDL_INDEX ();
18267 init_iterator (&it, w, -1, -1, NULL, face_id);
18268 /* Don't extend on a previously drawn mode-line.
18269 This may happen if called from pos_visible_p. */
18270 it.glyph_row->enabled_p = 0;
18271 prepare_desired_row (it.glyph_row);
18273 it.glyph_row->mode_line_p = 1;
18275 if (! mode_line_inverse_video)
18276 /* Force the mode-line to be displayed in the default face. */
18277 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
18279 record_unwind_protect (unwind_format_mode_line,
18280 format_mode_line_unwind_data (NULL, Qnil, 0));
18282 mode_line_target = MODE_LINE_DISPLAY;
18284 /* Temporarily make frame's keyboard the current kboard so that
18285 kboard-local variables in the mode_line_format will get the right
18286 values. */
18287 push_kboard (FRAME_KBOARD (it.f));
18288 record_unwind_save_match_data ();
18289 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
18290 pop_kboard ();
18292 unbind_to (count, Qnil);
18294 /* Fill up with spaces. */
18295 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
18297 compute_line_metrics (&it);
18298 it.glyph_row->full_width_p = 1;
18299 it.glyph_row->continued_p = 0;
18300 it.glyph_row->truncated_on_left_p = 0;
18301 it.glyph_row->truncated_on_right_p = 0;
18303 /* Make a 3D mode-line have a shadow at its right end. */
18304 face = FACE_FROM_ID (it.f, face_id);
18305 extend_face_to_end_of_line (&it);
18306 if (face->box != FACE_NO_BOX)
18308 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
18309 + it.glyph_row->used[TEXT_AREA] - 1);
18310 last->right_box_line_p = 1;
18313 return it.glyph_row->height;
18316 /* Move element ELT in LIST to the front of LIST.
18317 Return the updated list. */
18319 static Lisp_Object
18320 move_elt_to_front (Lisp_Object elt, Lisp_Object list)
18322 register Lisp_Object tail, prev;
18323 register Lisp_Object tem;
18325 tail = list;
18326 prev = Qnil;
18327 while (CONSP (tail))
18329 tem = XCAR (tail);
18331 if (EQ (elt, tem))
18333 /* Splice out the link TAIL. */
18334 if (NILP (prev))
18335 list = XCDR (tail);
18336 else
18337 Fsetcdr (prev, XCDR (tail));
18339 /* Now make it the first. */
18340 Fsetcdr (tail, list);
18341 return tail;
18343 else
18344 prev = tail;
18345 tail = XCDR (tail);
18346 QUIT;
18349 /* Not found--return unchanged LIST. */
18350 return list;
18353 /* Contribute ELT to the mode line for window IT->w. How it
18354 translates into text depends on its data type.
18356 IT describes the display environment in which we display, as usual.
18358 DEPTH is the depth in recursion. It is used to prevent
18359 infinite recursion here.
18361 FIELD_WIDTH is the number of characters the display of ELT should
18362 occupy in the mode line, and PRECISION is the maximum number of
18363 characters to display from ELT's representation. See
18364 display_string for details.
18366 Returns the hpos of the end of the text generated by ELT.
18368 PROPS is a property list to add to any string we encounter.
18370 If RISKY is nonzero, remove (disregard) any properties in any string
18371 we encounter, and ignore :eval and :propertize.
18373 The global variable `mode_line_target' determines whether the
18374 output is passed to `store_mode_line_noprop',
18375 `store_mode_line_string', or `display_string'. */
18377 static int
18378 display_mode_element (struct it *it, int depth, int field_width, int precision,
18379 Lisp_Object elt, Lisp_Object props, int risky)
18381 int n = 0, field, prec;
18382 int literal = 0;
18384 tail_recurse:
18385 if (depth > 100)
18386 elt = build_string ("*too-deep*");
18388 depth++;
18390 switch (SWITCH_ENUM_CAST (XTYPE (elt)))
18392 case Lisp_String:
18394 /* A string: output it and check for %-constructs within it. */
18395 unsigned char c;
18396 int offset = 0;
18398 if (SCHARS (elt) > 0
18399 && (!NILP (props) || risky))
18401 Lisp_Object oprops, aelt;
18402 oprops = Ftext_properties_at (make_number (0), elt);
18404 /* If the starting string's properties are not what
18405 we want, translate the string. Also, if the string
18406 is risky, do that anyway. */
18408 if (NILP (Fequal (props, oprops)) || risky)
18410 /* If the starting string has properties,
18411 merge the specified ones onto the existing ones. */
18412 if (! NILP (oprops) && !risky)
18414 Lisp_Object tem;
18416 oprops = Fcopy_sequence (oprops);
18417 tem = props;
18418 while (CONSP (tem))
18420 oprops = Fplist_put (oprops, XCAR (tem),
18421 XCAR (XCDR (tem)));
18422 tem = XCDR (XCDR (tem));
18424 props = oprops;
18427 aelt = Fassoc (elt, mode_line_proptrans_alist);
18428 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
18430 /* AELT is what we want. Move it to the front
18431 without consing. */
18432 elt = XCAR (aelt);
18433 mode_line_proptrans_alist
18434 = move_elt_to_front (aelt, mode_line_proptrans_alist);
18436 else
18438 Lisp_Object tem;
18440 /* If AELT has the wrong props, it is useless.
18441 so get rid of it. */
18442 if (! NILP (aelt))
18443 mode_line_proptrans_alist
18444 = Fdelq (aelt, mode_line_proptrans_alist);
18446 elt = Fcopy_sequence (elt);
18447 Fset_text_properties (make_number (0), Flength (elt),
18448 props, elt);
18449 /* Add this item to mode_line_proptrans_alist. */
18450 mode_line_proptrans_alist
18451 = Fcons (Fcons (elt, props),
18452 mode_line_proptrans_alist);
18453 /* Truncate mode_line_proptrans_alist
18454 to at most 50 elements. */
18455 tem = Fnthcdr (make_number (50),
18456 mode_line_proptrans_alist);
18457 if (! NILP (tem))
18458 XSETCDR (tem, Qnil);
18463 offset = 0;
18465 if (literal)
18467 prec = precision - n;
18468 switch (mode_line_target)
18470 case MODE_LINE_NOPROP:
18471 case MODE_LINE_TITLE:
18472 n += store_mode_line_noprop (SDATA (elt), -1, prec);
18473 break;
18474 case MODE_LINE_STRING:
18475 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
18476 break;
18477 case MODE_LINE_DISPLAY:
18478 n += display_string (NULL, elt, Qnil, 0, 0, it,
18479 0, prec, 0, STRING_MULTIBYTE (elt));
18480 break;
18483 break;
18486 /* Handle the non-literal case. */
18488 while ((precision <= 0 || n < precision)
18489 && SREF (elt, offset) != 0
18490 && (mode_line_target != MODE_LINE_DISPLAY
18491 || it->current_x < it->last_visible_x))
18493 int last_offset = offset;
18495 /* Advance to end of string or next format specifier. */
18496 while ((c = SREF (elt, offset++)) != '\0' && c != '%')
18499 if (offset - 1 != last_offset)
18501 int nchars, nbytes;
18503 /* Output to end of string or up to '%'. Field width
18504 is length of string. Don't output more than
18505 PRECISION allows us. */
18506 offset--;
18508 prec = c_string_width (SDATA (elt) + last_offset,
18509 offset - last_offset, precision - n,
18510 &nchars, &nbytes);
18512 switch (mode_line_target)
18514 case MODE_LINE_NOPROP:
18515 case MODE_LINE_TITLE:
18516 n += store_mode_line_noprop (SDATA (elt) + last_offset, 0, prec);
18517 break;
18518 case MODE_LINE_STRING:
18520 int bytepos = last_offset;
18521 int charpos = string_byte_to_char (elt, bytepos);
18522 int endpos = (precision <= 0
18523 ? string_byte_to_char (elt, offset)
18524 : charpos + nchars);
18526 n += store_mode_line_string (NULL,
18527 Fsubstring (elt, make_number (charpos),
18528 make_number (endpos)),
18529 0, 0, 0, Qnil);
18531 break;
18532 case MODE_LINE_DISPLAY:
18534 int bytepos = last_offset;
18535 int charpos = string_byte_to_char (elt, bytepos);
18537 if (precision <= 0)
18538 nchars = string_byte_to_char (elt, offset) - charpos;
18539 n += display_string (NULL, elt, Qnil, 0, charpos,
18540 it, 0, nchars, 0,
18541 STRING_MULTIBYTE (elt));
18543 break;
18546 else /* c == '%' */
18548 int percent_position = offset;
18550 /* Get the specified minimum width. Zero means
18551 don't pad. */
18552 field = 0;
18553 while ((c = SREF (elt, offset++)) >= '0' && c <= '9')
18554 field = field * 10 + c - '0';
18556 /* Don't pad beyond the total padding allowed. */
18557 if (field_width - n > 0 && field > field_width - n)
18558 field = field_width - n;
18560 /* Note that either PRECISION <= 0 or N < PRECISION. */
18561 prec = precision - n;
18563 if (c == 'M')
18564 n += display_mode_element (it, depth, field, prec,
18565 Vglobal_mode_string, props,
18566 risky);
18567 else if (c != 0)
18569 int multibyte;
18570 int bytepos, charpos;
18571 const unsigned char *spec;
18572 Lisp_Object string;
18574 bytepos = percent_position;
18575 charpos = (STRING_MULTIBYTE (elt)
18576 ? string_byte_to_char (elt, bytepos)
18577 : bytepos);
18578 spec = decode_mode_spec (it->w, c, field, prec, &string);
18579 multibyte = STRINGP (string) && STRING_MULTIBYTE (string);
18581 switch (mode_line_target)
18583 case MODE_LINE_NOPROP:
18584 case MODE_LINE_TITLE:
18585 n += store_mode_line_noprop (spec, field, prec);
18586 break;
18587 case MODE_LINE_STRING:
18589 int len = strlen (spec);
18590 Lisp_Object tem = make_string (spec, len);
18591 props = Ftext_properties_at (make_number (charpos), elt);
18592 /* Should only keep face property in props */
18593 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
18595 break;
18596 case MODE_LINE_DISPLAY:
18598 int nglyphs_before, nwritten;
18600 nglyphs_before = it->glyph_row->used[TEXT_AREA];
18601 nwritten = display_string (spec, string, elt,
18602 charpos, 0, it,
18603 field, prec, 0,
18604 multibyte);
18606 /* Assign to the glyphs written above the
18607 string where the `%x' came from, position
18608 of the `%'. */
18609 if (nwritten > 0)
18611 struct glyph *glyph
18612 = (it->glyph_row->glyphs[TEXT_AREA]
18613 + nglyphs_before);
18614 int i;
18616 for (i = 0; i < nwritten; ++i)
18618 glyph[i].object = elt;
18619 glyph[i].charpos = charpos;
18622 n += nwritten;
18625 break;
18628 else /* c == 0 */
18629 break;
18633 break;
18635 case Lisp_Symbol:
18636 /* A symbol: process the value of the symbol recursively
18637 as if it appeared here directly. Avoid error if symbol void.
18638 Special case: if value of symbol is a string, output the string
18639 literally. */
18641 register Lisp_Object tem;
18643 /* If the variable is not marked as risky to set
18644 then its contents are risky to use. */
18645 if (NILP (Fget (elt, Qrisky_local_variable)))
18646 risky = 1;
18648 tem = Fboundp (elt);
18649 if (!NILP (tem))
18651 tem = Fsymbol_value (elt);
18652 /* If value is a string, output that string literally:
18653 don't check for % within it. */
18654 if (STRINGP (tem))
18655 literal = 1;
18657 if (!EQ (tem, elt))
18659 /* Give up right away for nil or t. */
18660 elt = tem;
18661 goto tail_recurse;
18665 break;
18667 case Lisp_Cons:
18669 register Lisp_Object car, tem;
18671 /* A cons cell: five distinct cases.
18672 If first element is :eval or :propertize, do something special.
18673 If first element is a string or a cons, process all the elements
18674 and effectively concatenate them.
18675 If first element is a negative number, truncate displaying cdr to
18676 at most that many characters. If positive, pad (with spaces)
18677 to at least that many characters.
18678 If first element is a symbol, process the cadr or caddr recursively
18679 according to whether the symbol's value is non-nil or nil. */
18680 car = XCAR (elt);
18681 if (EQ (car, QCeval))
18683 /* An element of the form (:eval FORM) means evaluate FORM
18684 and use the result as mode line elements. */
18686 if (risky)
18687 break;
18689 if (CONSP (XCDR (elt)))
18691 Lisp_Object spec;
18692 spec = safe_eval (XCAR (XCDR (elt)));
18693 n += display_mode_element (it, depth, field_width - n,
18694 precision - n, spec, props,
18695 risky);
18698 else if (EQ (car, QCpropertize))
18700 /* An element of the form (:propertize ELT PROPS...)
18701 means display ELT but applying properties PROPS. */
18703 if (risky)
18704 break;
18706 if (CONSP (XCDR (elt)))
18707 n += display_mode_element (it, depth, field_width - n,
18708 precision - n, XCAR (XCDR (elt)),
18709 XCDR (XCDR (elt)), risky);
18711 else if (SYMBOLP (car))
18713 tem = Fboundp (car);
18714 elt = XCDR (elt);
18715 if (!CONSP (elt))
18716 goto invalid;
18717 /* elt is now the cdr, and we know it is a cons cell.
18718 Use its car if CAR has a non-nil value. */
18719 if (!NILP (tem))
18721 tem = Fsymbol_value (car);
18722 if (!NILP (tem))
18724 elt = XCAR (elt);
18725 goto tail_recurse;
18728 /* Symbol's value is nil (or symbol is unbound)
18729 Get the cddr of the original list
18730 and if possible find the caddr and use that. */
18731 elt = XCDR (elt);
18732 if (NILP (elt))
18733 break;
18734 else if (!CONSP (elt))
18735 goto invalid;
18736 elt = XCAR (elt);
18737 goto tail_recurse;
18739 else if (INTEGERP (car))
18741 register int lim = XINT (car);
18742 elt = XCDR (elt);
18743 if (lim < 0)
18745 /* Negative int means reduce maximum width. */
18746 if (precision <= 0)
18747 precision = -lim;
18748 else
18749 precision = min (precision, -lim);
18751 else if (lim > 0)
18753 /* Padding specified. Don't let it be more than
18754 current maximum. */
18755 if (precision > 0)
18756 lim = min (precision, lim);
18758 /* If that's more padding than already wanted, queue it.
18759 But don't reduce padding already specified even if
18760 that is beyond the current truncation point. */
18761 field_width = max (lim, field_width);
18763 goto tail_recurse;
18765 else if (STRINGP (car) || CONSP (car))
18767 Lisp_Object halftail = elt;
18768 int len = 0;
18770 while (CONSP (elt)
18771 && (precision <= 0 || n < precision))
18773 n += display_mode_element (it, depth,
18774 /* Do padding only after the last
18775 element in the list. */
18776 (! CONSP (XCDR (elt))
18777 ? field_width - n
18778 : 0),
18779 precision - n, XCAR (elt),
18780 props, risky);
18781 elt = XCDR (elt);
18782 len++;
18783 if ((len & 1) == 0)
18784 halftail = XCDR (halftail);
18785 /* Check for cycle. */
18786 if (EQ (halftail, elt))
18787 break;
18791 break;
18793 default:
18794 invalid:
18795 elt = build_string ("*invalid*");
18796 goto tail_recurse;
18799 /* Pad to FIELD_WIDTH. */
18800 if (field_width > 0 && n < field_width)
18802 switch (mode_line_target)
18804 case MODE_LINE_NOPROP:
18805 case MODE_LINE_TITLE:
18806 n += store_mode_line_noprop ("", field_width - n, 0);
18807 break;
18808 case MODE_LINE_STRING:
18809 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
18810 break;
18811 case MODE_LINE_DISPLAY:
18812 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
18813 0, 0, 0);
18814 break;
18818 return n;
18821 /* Store a mode-line string element in mode_line_string_list.
18823 If STRING is non-null, display that C string. Otherwise, the Lisp
18824 string LISP_STRING is displayed.
18826 FIELD_WIDTH is the minimum number of output glyphs to produce.
18827 If STRING has fewer characters than FIELD_WIDTH, pad to the right
18828 with spaces. FIELD_WIDTH <= 0 means don't pad.
18830 PRECISION is the maximum number of characters to output from
18831 STRING. PRECISION <= 0 means don't truncate the string.
18833 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
18834 properties to the string.
18836 PROPS are the properties to add to the string.
18837 The mode_line_string_face face property is always added to the string.
18840 static int
18841 store_mode_line_string (const char *string, Lisp_Object lisp_string, int copy_string,
18842 int field_width, int precision, Lisp_Object props)
18844 int len;
18845 int n = 0;
18847 if (string != NULL)
18849 len = strlen (string);
18850 if (precision > 0 && len > precision)
18851 len = precision;
18852 lisp_string = make_string (string, len);
18853 if (NILP (props))
18854 props = mode_line_string_face_prop;
18855 else if (!NILP (mode_line_string_face))
18857 Lisp_Object face = Fplist_get (props, Qface);
18858 props = Fcopy_sequence (props);
18859 if (NILP (face))
18860 face = mode_line_string_face;
18861 else
18862 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
18863 props = Fplist_put (props, Qface, face);
18865 Fadd_text_properties (make_number (0), make_number (len),
18866 props, lisp_string);
18868 else
18870 len = XFASTINT (Flength (lisp_string));
18871 if (precision > 0 && len > precision)
18873 len = precision;
18874 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
18875 precision = -1;
18877 if (!NILP (mode_line_string_face))
18879 Lisp_Object face;
18880 if (NILP (props))
18881 props = Ftext_properties_at (make_number (0), lisp_string);
18882 face = Fplist_get (props, Qface);
18883 if (NILP (face))
18884 face = mode_line_string_face;
18885 else
18886 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
18887 props = Fcons (Qface, Fcons (face, Qnil));
18888 if (copy_string)
18889 lisp_string = Fcopy_sequence (lisp_string);
18891 if (!NILP (props))
18892 Fadd_text_properties (make_number (0), make_number (len),
18893 props, lisp_string);
18896 if (len > 0)
18898 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
18899 n += len;
18902 if (field_width > len)
18904 field_width -= len;
18905 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
18906 if (!NILP (props))
18907 Fadd_text_properties (make_number (0), make_number (field_width),
18908 props, lisp_string);
18909 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
18910 n += field_width;
18913 return n;
18917 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
18918 1, 4, 0,
18919 doc: /* Format a string out of a mode line format specification.
18920 First arg FORMAT specifies the mode line format (see `mode-line-format'
18921 for details) to use.
18923 Optional second arg FACE specifies the face property to put
18924 on all characters for which no face is specified.
18925 The value t means whatever face the window's mode line currently uses
18926 \(either `mode-line' or `mode-line-inactive', depending).
18927 A value of nil means the default is no face property.
18928 If FACE is an integer, the value string has no text properties.
18930 Optional third and fourth args WINDOW and BUFFER specify the window
18931 and buffer to use as the context for the formatting (defaults
18932 are the selected window and the window's buffer). */)
18933 (Lisp_Object format, Lisp_Object face, Lisp_Object window, Lisp_Object buffer)
18935 struct it it;
18936 int len;
18937 struct window *w;
18938 struct buffer *old_buffer = NULL;
18939 int face_id = -1;
18940 int no_props = INTEGERP (face);
18941 int count = SPECPDL_INDEX ();
18942 Lisp_Object str;
18943 int string_start = 0;
18945 if (NILP (window))
18946 window = selected_window;
18947 CHECK_WINDOW (window);
18948 w = XWINDOW (window);
18950 if (NILP (buffer))
18951 buffer = w->buffer;
18952 CHECK_BUFFER (buffer);
18954 /* Make formatting the modeline a non-op when noninteractive, otherwise
18955 there will be problems later caused by a partially initialized frame. */
18956 if (NILP (format) || noninteractive)
18957 return empty_unibyte_string;
18959 if (no_props)
18960 face = Qnil;
18962 if (!NILP (face))
18964 if (EQ (face, Qt))
18965 face = (EQ (window, selected_window) ? Qmode_line : Qmode_line_inactive);
18966 face_id = lookup_named_face (XFRAME (WINDOW_FRAME (w)), face, 0);
18969 if (face_id < 0)
18970 face_id = DEFAULT_FACE_ID;
18972 if (XBUFFER (buffer) != current_buffer)
18973 old_buffer = current_buffer;
18975 /* Save things including mode_line_proptrans_alist,
18976 and set that to nil so that we don't alter the outer value. */
18977 record_unwind_protect (unwind_format_mode_line,
18978 format_mode_line_unwind_data
18979 (old_buffer, selected_window, 1));
18980 mode_line_proptrans_alist = Qnil;
18982 Fselect_window (window, Qt);
18983 if (old_buffer)
18984 set_buffer_internal_1 (XBUFFER (buffer));
18986 init_iterator (&it, w, -1, -1, NULL, face_id);
18988 if (no_props)
18990 mode_line_target = MODE_LINE_NOPROP;
18991 mode_line_string_face_prop = Qnil;
18992 mode_line_string_list = Qnil;
18993 string_start = MODE_LINE_NOPROP_LEN (0);
18995 else
18997 mode_line_target = MODE_LINE_STRING;
18998 mode_line_string_list = Qnil;
18999 mode_line_string_face = face;
19000 mode_line_string_face_prop
19001 = (NILP (face) ? Qnil : Fcons (Qface, Fcons (face, Qnil)));
19004 push_kboard (FRAME_KBOARD (it.f));
19005 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
19006 pop_kboard ();
19008 if (no_props)
19010 len = MODE_LINE_NOPROP_LEN (string_start);
19011 str = make_string (mode_line_noprop_buf + string_start, len);
19013 else
19015 mode_line_string_list = Fnreverse (mode_line_string_list);
19016 str = Fmapconcat (intern ("identity"), mode_line_string_list,
19017 empty_unibyte_string);
19020 unbind_to (count, Qnil);
19021 return str;
19024 /* Write a null-terminated, right justified decimal representation of
19025 the positive integer D to BUF using a minimal field width WIDTH. */
19027 static void
19028 pint2str (register char *buf, register int width, register int d)
19030 register char *p = buf;
19032 if (d <= 0)
19033 *p++ = '0';
19034 else
19036 while (d > 0)
19038 *p++ = d % 10 + '0';
19039 d /= 10;
19043 for (width -= (int) (p - buf); width > 0; --width)
19044 *p++ = ' ';
19045 *p-- = '\0';
19046 while (p > buf)
19048 d = *buf;
19049 *buf++ = *p;
19050 *p-- = d;
19054 /* Write a null-terminated, right justified decimal and "human
19055 readable" representation of the nonnegative integer D to BUF using
19056 a minimal field width WIDTH. D should be smaller than 999.5e24. */
19058 static const char power_letter[] =
19060 0, /* not used */
19061 'k', /* kilo */
19062 'M', /* mega */
19063 'G', /* giga */
19064 'T', /* tera */
19065 'P', /* peta */
19066 'E', /* exa */
19067 'Z', /* zetta */
19068 'Y' /* yotta */
19071 static void
19072 pint2hrstr (char *buf, int width, int d)
19074 /* We aim to represent the nonnegative integer D as
19075 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
19076 int quotient = d;
19077 int remainder = 0;
19078 /* -1 means: do not use TENTHS. */
19079 int tenths = -1;
19080 int exponent = 0;
19082 /* Length of QUOTIENT.TENTHS as a string. */
19083 int length;
19085 char * psuffix;
19086 char * p;
19088 if (1000 <= quotient)
19090 /* Scale to the appropriate EXPONENT. */
19093 remainder = quotient % 1000;
19094 quotient /= 1000;
19095 exponent++;
19097 while (1000 <= quotient);
19099 /* Round to nearest and decide whether to use TENTHS or not. */
19100 if (quotient <= 9)
19102 tenths = remainder / 100;
19103 if (50 <= remainder % 100)
19105 if (tenths < 9)
19106 tenths++;
19107 else
19109 quotient++;
19110 if (quotient == 10)
19111 tenths = -1;
19112 else
19113 tenths = 0;
19117 else
19118 if (500 <= remainder)
19120 if (quotient < 999)
19121 quotient++;
19122 else
19124 quotient = 1;
19125 exponent++;
19126 tenths = 0;
19131 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
19132 if (tenths == -1 && quotient <= 99)
19133 if (quotient <= 9)
19134 length = 1;
19135 else
19136 length = 2;
19137 else
19138 length = 3;
19139 p = psuffix = buf + max (width, length);
19141 /* Print EXPONENT. */
19142 if (exponent)
19143 *psuffix++ = power_letter[exponent];
19144 *psuffix = '\0';
19146 /* Print TENTHS. */
19147 if (tenths >= 0)
19149 *--p = '0' + tenths;
19150 *--p = '.';
19153 /* Print QUOTIENT. */
19156 int digit = quotient % 10;
19157 *--p = '0' + digit;
19159 while ((quotient /= 10) != 0);
19161 /* Print leading spaces. */
19162 while (buf < p)
19163 *--p = ' ';
19166 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
19167 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
19168 type of CODING_SYSTEM. Return updated pointer into BUF. */
19170 static unsigned char invalid_eol_type[] = "(*invalid*)";
19172 static char *
19173 decode_mode_spec_coding (Lisp_Object coding_system, register char *buf, int eol_flag)
19175 Lisp_Object val;
19176 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
19177 const unsigned char *eol_str;
19178 int eol_str_len;
19179 /* The EOL conversion we are using. */
19180 Lisp_Object eoltype;
19182 val = CODING_SYSTEM_SPEC (coding_system);
19183 eoltype = Qnil;
19185 if (!VECTORP (val)) /* Not yet decided. */
19187 if (multibyte)
19188 *buf++ = '-';
19189 if (eol_flag)
19190 eoltype = eol_mnemonic_undecided;
19191 /* Don't mention EOL conversion if it isn't decided. */
19193 else
19195 Lisp_Object attrs;
19196 Lisp_Object eolvalue;
19198 attrs = AREF (val, 0);
19199 eolvalue = AREF (val, 2);
19201 if (multibyte)
19202 *buf++ = XFASTINT (CODING_ATTR_MNEMONIC (attrs));
19204 if (eol_flag)
19206 /* The EOL conversion that is normal on this system. */
19208 if (NILP (eolvalue)) /* Not yet decided. */
19209 eoltype = eol_mnemonic_undecided;
19210 else if (VECTORP (eolvalue)) /* Not yet decided. */
19211 eoltype = eol_mnemonic_undecided;
19212 else /* eolvalue is Qunix, Qdos, or Qmac. */
19213 eoltype = (EQ (eolvalue, Qunix)
19214 ? eol_mnemonic_unix
19215 : (EQ (eolvalue, Qdos) == 1
19216 ? eol_mnemonic_dos : eol_mnemonic_mac));
19220 if (eol_flag)
19222 /* Mention the EOL conversion if it is not the usual one. */
19223 if (STRINGP (eoltype))
19225 eol_str = SDATA (eoltype);
19226 eol_str_len = SBYTES (eoltype);
19228 else if (CHARACTERP (eoltype))
19230 unsigned char *tmp = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
19231 eol_str_len = CHAR_STRING (XINT (eoltype), tmp);
19232 eol_str = tmp;
19234 else
19236 eol_str = invalid_eol_type;
19237 eol_str_len = sizeof (invalid_eol_type) - 1;
19239 memcpy (buf, eol_str, eol_str_len);
19240 buf += eol_str_len;
19243 return buf;
19246 /* Return a string for the output of a mode line %-spec for window W,
19247 generated by character C. PRECISION >= 0 means don't return a
19248 string longer than that value. FIELD_WIDTH > 0 means pad the
19249 string returned with spaces to that value. Return a Lisp string in
19250 *STRING if the resulting string is taken from that Lisp string.
19252 Note we operate on the current buffer for most purposes,
19253 the exception being w->base_line_pos. */
19255 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
19257 static const char *
19258 decode_mode_spec (struct window *w, register int c, int field_width,
19259 int precision, Lisp_Object *string)
19261 Lisp_Object obj;
19262 struct frame *f = XFRAME (WINDOW_FRAME (w));
19263 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
19264 struct buffer *b = current_buffer;
19266 obj = Qnil;
19267 *string = Qnil;
19269 switch (c)
19271 case '*':
19272 if (!NILP (b->read_only))
19273 return "%";
19274 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
19275 return "*";
19276 return "-";
19278 case '+':
19279 /* This differs from %* only for a modified read-only buffer. */
19280 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
19281 return "*";
19282 if (!NILP (b->read_only))
19283 return "%";
19284 return "-";
19286 case '&':
19287 /* This differs from %* in ignoring read-only-ness. */
19288 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
19289 return "*";
19290 return "-";
19292 case '%':
19293 return "%";
19295 case '[':
19297 int i;
19298 char *p;
19300 if (command_loop_level > 5)
19301 return "[[[... ";
19302 p = decode_mode_spec_buf;
19303 for (i = 0; i < command_loop_level; i++)
19304 *p++ = '[';
19305 *p = 0;
19306 return decode_mode_spec_buf;
19309 case ']':
19311 int i;
19312 char *p;
19314 if (command_loop_level > 5)
19315 return " ...]]]";
19316 p = decode_mode_spec_buf;
19317 for (i = 0; i < command_loop_level; i++)
19318 *p++ = ']';
19319 *p = 0;
19320 return decode_mode_spec_buf;
19323 case '-':
19325 register int i;
19327 /* Let lots_of_dashes be a string of infinite length. */
19328 if (mode_line_target == MODE_LINE_NOPROP ||
19329 mode_line_target == MODE_LINE_STRING)
19330 return "--";
19331 if (field_width <= 0
19332 || field_width > sizeof (lots_of_dashes))
19334 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
19335 decode_mode_spec_buf[i] = '-';
19336 decode_mode_spec_buf[i] = '\0';
19337 return decode_mode_spec_buf;
19339 else
19340 return lots_of_dashes;
19343 case 'b':
19344 obj = b->name;
19345 break;
19347 case 'c':
19348 /* %c and %l are ignored in `frame-title-format'.
19349 (In redisplay_internal, the frame title is drawn _before_ the
19350 windows are updated, so the stuff which depends on actual
19351 window contents (such as %l) may fail to render properly, or
19352 even crash emacs.) */
19353 if (mode_line_target == MODE_LINE_TITLE)
19354 return "";
19355 else
19357 int col = (int) current_column (); /* iftc */
19358 w->column_number_displayed = make_number (col);
19359 pint2str (decode_mode_spec_buf, field_width, col);
19360 return decode_mode_spec_buf;
19363 case 'e':
19364 #ifndef SYSTEM_MALLOC
19366 if (NILP (Vmemory_full))
19367 return "";
19368 else
19369 return "!MEM FULL! ";
19371 #else
19372 return "";
19373 #endif
19375 case 'F':
19376 /* %F displays the frame name. */
19377 if (!NILP (f->title))
19378 return (char *) SDATA (f->title);
19379 if (f->explicit_name || ! FRAME_WINDOW_P (f))
19380 return (char *) SDATA (f->name);
19381 return "Emacs";
19383 case 'f':
19384 obj = b->filename;
19385 break;
19387 case 'i':
19389 int size = ZV - BEGV;
19390 pint2str (decode_mode_spec_buf, field_width, size);
19391 return decode_mode_spec_buf;
19394 case 'I':
19396 int size = ZV - BEGV;
19397 pint2hrstr (decode_mode_spec_buf, field_width, size);
19398 return decode_mode_spec_buf;
19401 case 'l':
19403 int startpos, startpos_byte, line, linepos, linepos_byte;
19404 int topline, nlines, junk, height;
19406 /* %c and %l are ignored in `frame-title-format'. */
19407 if (mode_line_target == MODE_LINE_TITLE)
19408 return "";
19410 startpos = XMARKER (w->start)->charpos;
19411 startpos_byte = marker_byte_position (w->start);
19412 height = WINDOW_TOTAL_LINES (w);
19414 /* If we decided that this buffer isn't suitable for line numbers,
19415 don't forget that too fast. */
19416 if (EQ (w->base_line_pos, w->buffer))
19417 goto no_value;
19418 /* But do forget it, if the window shows a different buffer now. */
19419 else if (BUFFERP (w->base_line_pos))
19420 w->base_line_pos = Qnil;
19422 /* If the buffer is very big, don't waste time. */
19423 if (INTEGERP (Vline_number_display_limit)
19424 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
19426 w->base_line_pos = Qnil;
19427 w->base_line_number = Qnil;
19428 goto no_value;
19431 if (INTEGERP (w->base_line_number)
19432 && INTEGERP (w->base_line_pos)
19433 && XFASTINT (w->base_line_pos) <= startpos)
19435 line = XFASTINT (w->base_line_number);
19436 linepos = XFASTINT (w->base_line_pos);
19437 linepos_byte = buf_charpos_to_bytepos (b, linepos);
19439 else
19441 line = 1;
19442 linepos = BUF_BEGV (b);
19443 linepos_byte = BUF_BEGV_BYTE (b);
19446 /* Count lines from base line to window start position. */
19447 nlines = display_count_lines (linepos, linepos_byte,
19448 startpos_byte,
19449 startpos, &junk);
19451 topline = nlines + line;
19453 /* Determine a new base line, if the old one is too close
19454 or too far away, or if we did not have one.
19455 "Too close" means it's plausible a scroll-down would
19456 go back past it. */
19457 if (startpos == BUF_BEGV (b))
19459 w->base_line_number = make_number (topline);
19460 w->base_line_pos = make_number (BUF_BEGV (b));
19462 else if (nlines < height + 25 || nlines > height * 3 + 50
19463 || linepos == BUF_BEGV (b))
19465 int limit = BUF_BEGV (b);
19466 int limit_byte = BUF_BEGV_BYTE (b);
19467 int position;
19468 int distance = (height * 2 + 30) * line_number_display_limit_width;
19470 if (startpos - distance > limit)
19472 limit = startpos - distance;
19473 limit_byte = CHAR_TO_BYTE (limit);
19476 nlines = display_count_lines (startpos, startpos_byte,
19477 limit_byte,
19478 - (height * 2 + 30),
19479 &position);
19480 /* If we couldn't find the lines we wanted within
19481 line_number_display_limit_width chars per line,
19482 give up on line numbers for this window. */
19483 if (position == limit_byte && limit == startpos - distance)
19485 w->base_line_pos = w->buffer;
19486 w->base_line_number = Qnil;
19487 goto no_value;
19490 w->base_line_number = make_number (topline - nlines);
19491 w->base_line_pos = make_number (BYTE_TO_CHAR (position));
19494 /* Now count lines from the start pos to point. */
19495 nlines = display_count_lines (startpos, startpos_byte,
19496 PT_BYTE, PT, &junk);
19498 /* Record that we did display the line number. */
19499 line_number_displayed = 1;
19501 /* Make the string to show. */
19502 pint2str (decode_mode_spec_buf, field_width, topline + nlines);
19503 return decode_mode_spec_buf;
19504 no_value:
19506 char* p = decode_mode_spec_buf;
19507 int pad = field_width - 2;
19508 while (pad-- > 0)
19509 *p++ = ' ';
19510 *p++ = '?';
19511 *p++ = '?';
19512 *p = '\0';
19513 return decode_mode_spec_buf;
19516 break;
19518 case 'm':
19519 obj = b->mode_name;
19520 break;
19522 case 'n':
19523 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
19524 return " Narrow";
19525 break;
19527 case 'p':
19529 int pos = marker_position (w->start);
19530 int total = BUF_ZV (b) - BUF_BEGV (b);
19532 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
19534 if (pos <= BUF_BEGV (b))
19535 return "All";
19536 else
19537 return "Bottom";
19539 else if (pos <= BUF_BEGV (b))
19540 return "Top";
19541 else
19543 if (total > 1000000)
19544 /* Do it differently for a large value, to avoid overflow. */
19545 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
19546 else
19547 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
19548 /* We can't normally display a 3-digit number,
19549 so get us a 2-digit number that is close. */
19550 if (total == 100)
19551 total = 99;
19552 sprintf (decode_mode_spec_buf, "%2d%%", total);
19553 return decode_mode_spec_buf;
19557 /* Display percentage of size above the bottom of the screen. */
19558 case 'P':
19560 int toppos = marker_position (w->start);
19561 int botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
19562 int total = BUF_ZV (b) - BUF_BEGV (b);
19564 if (botpos >= BUF_ZV (b))
19566 if (toppos <= BUF_BEGV (b))
19567 return "All";
19568 else
19569 return "Bottom";
19571 else
19573 if (total > 1000000)
19574 /* Do it differently for a large value, to avoid overflow. */
19575 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
19576 else
19577 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
19578 /* We can't normally display a 3-digit number,
19579 so get us a 2-digit number that is close. */
19580 if (total == 100)
19581 total = 99;
19582 if (toppos <= BUF_BEGV (b))
19583 sprintf (decode_mode_spec_buf, "Top%2d%%", total);
19584 else
19585 sprintf (decode_mode_spec_buf, "%2d%%", total);
19586 return decode_mode_spec_buf;
19590 case 's':
19591 /* status of process */
19592 obj = Fget_buffer_process (Fcurrent_buffer ());
19593 if (NILP (obj))
19594 return "no process";
19595 #ifndef MSDOS
19596 obj = Fsymbol_name (Fprocess_status (obj));
19597 #endif
19598 break;
19600 case '@':
19602 int count = inhibit_garbage_collection ();
19603 Lisp_Object val = call1 (intern ("file-remote-p"),
19604 current_buffer->directory);
19605 unbind_to (count, Qnil);
19607 if (NILP (val))
19608 return "-";
19609 else
19610 return "@";
19613 case 't': /* indicate TEXT or BINARY */
19614 #ifdef MODE_LINE_BINARY_TEXT
19615 return MODE_LINE_BINARY_TEXT (b);
19616 #else
19617 return "T";
19618 #endif
19620 case 'z':
19621 /* coding-system (not including end-of-line format) */
19622 case 'Z':
19623 /* coding-system (including end-of-line type) */
19625 int eol_flag = (c == 'Z');
19626 char *p = decode_mode_spec_buf;
19628 if (! FRAME_WINDOW_P (f))
19630 /* No need to mention EOL here--the terminal never needs
19631 to do EOL conversion. */
19632 p = decode_mode_spec_coding (CODING_ID_NAME
19633 (FRAME_KEYBOARD_CODING (f)->id),
19634 p, 0);
19635 p = decode_mode_spec_coding (CODING_ID_NAME
19636 (FRAME_TERMINAL_CODING (f)->id),
19637 p, 0);
19639 p = decode_mode_spec_coding (b->buffer_file_coding_system,
19640 p, eol_flag);
19642 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
19643 #ifdef subprocesses
19644 obj = Fget_buffer_process (Fcurrent_buffer ());
19645 if (PROCESSP (obj))
19647 p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system,
19648 p, eol_flag);
19649 p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system,
19650 p, eol_flag);
19652 #endif /* subprocesses */
19653 #endif /* 0 */
19654 *p = 0;
19655 return decode_mode_spec_buf;
19659 if (STRINGP (obj))
19661 *string = obj;
19662 return (char *) SDATA (obj);
19664 else
19665 return "";
19669 /* Count up to COUNT lines starting from START / START_BYTE.
19670 But don't go beyond LIMIT_BYTE.
19671 Return the number of lines thus found (always nonnegative).
19673 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
19675 static int
19676 display_count_lines (int start, int start_byte, int limit_byte, int count,
19677 int *byte_pos_ptr)
19679 register unsigned char *cursor;
19680 unsigned char *base;
19682 register int ceiling;
19683 register unsigned char *ceiling_addr;
19684 int orig_count = count;
19686 /* If we are not in selective display mode,
19687 check only for newlines. */
19688 int selective_display = (!NILP (current_buffer->selective_display)
19689 && !INTEGERP (current_buffer->selective_display));
19691 if (count > 0)
19693 while (start_byte < limit_byte)
19695 ceiling = BUFFER_CEILING_OF (start_byte);
19696 ceiling = min (limit_byte - 1, ceiling);
19697 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
19698 base = (cursor = BYTE_POS_ADDR (start_byte));
19699 while (1)
19701 if (selective_display)
19702 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
19704 else
19705 while (*cursor != '\n' && ++cursor != ceiling_addr)
19708 if (cursor != ceiling_addr)
19710 if (--count == 0)
19712 start_byte += cursor - base + 1;
19713 *byte_pos_ptr = start_byte;
19714 return orig_count;
19716 else
19717 if (++cursor == ceiling_addr)
19718 break;
19720 else
19721 break;
19723 start_byte += cursor - base;
19726 else
19728 while (start_byte > limit_byte)
19730 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
19731 ceiling = max (limit_byte, ceiling);
19732 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1;
19733 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
19734 while (1)
19736 if (selective_display)
19737 while (--cursor != ceiling_addr
19738 && *cursor != '\n' && *cursor != 015)
19740 else
19741 while (--cursor != ceiling_addr && *cursor != '\n')
19744 if (cursor != ceiling_addr)
19746 if (++count == 0)
19748 start_byte += cursor - base + 1;
19749 *byte_pos_ptr = start_byte;
19750 /* When scanning backwards, we should
19751 not count the newline posterior to which we stop. */
19752 return - orig_count - 1;
19755 else
19756 break;
19758 /* Here we add 1 to compensate for the last decrement
19759 of CURSOR, which took it past the valid range. */
19760 start_byte += cursor - base + 1;
19764 *byte_pos_ptr = limit_byte;
19766 if (count < 0)
19767 return - orig_count + count;
19768 return orig_count - count;
19774 /***********************************************************************
19775 Displaying strings
19776 ***********************************************************************/
19778 /* Display a NUL-terminated string, starting with index START.
19780 If STRING is non-null, display that C string. Otherwise, the Lisp
19781 string LISP_STRING is displayed. There's a case that STRING is
19782 non-null and LISP_STRING is not nil. It means STRING is a string
19783 data of LISP_STRING. In that case, we display LISP_STRING while
19784 ignoring its text properties.
19786 If FACE_STRING is not nil, FACE_STRING_POS is a position in
19787 FACE_STRING. Display STRING or LISP_STRING with the face at
19788 FACE_STRING_POS in FACE_STRING:
19790 Display the string in the environment given by IT, but use the
19791 standard display table, temporarily.
19793 FIELD_WIDTH is the minimum number of output glyphs to produce.
19794 If STRING has fewer characters than FIELD_WIDTH, pad to the right
19795 with spaces. If STRING has more characters, more than FIELD_WIDTH
19796 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
19798 PRECISION is the maximum number of characters to output from
19799 STRING. PRECISION < 0 means don't truncate the string.
19801 This is roughly equivalent to printf format specifiers:
19803 FIELD_WIDTH PRECISION PRINTF
19804 ----------------------------------------
19805 -1 -1 %s
19806 -1 10 %.10s
19807 10 -1 %10s
19808 20 10 %20.10s
19810 MULTIBYTE zero means do not display multibyte chars, > 0 means do
19811 display them, and < 0 means obey the current buffer's value of
19812 enable_multibyte_characters.
19814 Value is the number of columns displayed. */
19816 static int
19817 display_string (const unsigned char *string, Lisp_Object lisp_string, Lisp_Object face_string,
19818 EMACS_INT face_string_pos, EMACS_INT start, struct it *it,
19819 int field_width, int precision, int max_x, int multibyte)
19821 int hpos_at_start = it->hpos;
19822 int saved_face_id = it->face_id;
19823 struct glyph_row *row = it->glyph_row;
19825 /* Initialize the iterator IT for iteration over STRING beginning
19826 with index START. */
19827 reseat_to_string (it, NILP (lisp_string) ? string : NULL, lisp_string, start,
19828 precision, field_width, multibyte);
19829 if (string && STRINGP (lisp_string))
19830 /* LISP_STRING is the one returned by decode_mode_spec. We should
19831 ignore its text properties. */
19832 it->stop_charpos = -1;
19834 /* If displaying STRING, set up the face of the iterator
19835 from LISP_STRING, if that's given. */
19836 if (STRINGP (face_string))
19838 EMACS_INT endptr;
19839 struct face *face;
19841 it->face_id
19842 = face_at_string_position (it->w, face_string, face_string_pos,
19843 0, it->region_beg_charpos,
19844 it->region_end_charpos,
19845 &endptr, it->base_face_id, 0);
19846 face = FACE_FROM_ID (it->f, it->face_id);
19847 it->face_box_p = face->box != FACE_NO_BOX;
19850 /* Set max_x to the maximum allowed X position. Don't let it go
19851 beyond the right edge of the window. */
19852 if (max_x <= 0)
19853 max_x = it->last_visible_x;
19854 else
19855 max_x = min (max_x, it->last_visible_x);
19857 /* Skip over display elements that are not visible. because IT->w is
19858 hscrolled. */
19859 if (it->current_x < it->first_visible_x)
19860 move_it_in_display_line_to (it, 100000, it->first_visible_x,
19861 MOVE_TO_POS | MOVE_TO_X);
19863 row->ascent = it->max_ascent;
19864 row->height = it->max_ascent + it->max_descent;
19865 row->phys_ascent = it->max_phys_ascent;
19866 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
19867 row->extra_line_spacing = it->max_extra_line_spacing;
19869 /* This condition is for the case that we are called with current_x
19870 past last_visible_x. */
19871 while (it->current_x < max_x)
19873 int x_before, x, n_glyphs_before, i, nglyphs;
19875 /* Get the next display element. */
19876 if (!get_next_display_element (it))
19877 break;
19879 /* Produce glyphs. */
19880 x_before = it->current_x;
19881 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
19882 PRODUCE_GLYPHS (it);
19884 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
19885 i = 0;
19886 x = x_before;
19887 while (i < nglyphs)
19889 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
19891 if (it->line_wrap != TRUNCATE
19892 && x + glyph->pixel_width > max_x)
19894 /* End of continued line or max_x reached. */
19895 if (CHAR_GLYPH_PADDING_P (*glyph))
19897 /* A wide character is unbreakable. */
19898 it->glyph_row->used[TEXT_AREA] = n_glyphs_before;
19899 it->current_x = x_before;
19901 else
19903 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
19904 it->current_x = x;
19906 break;
19908 else if (x + glyph->pixel_width >= it->first_visible_x)
19910 /* Glyph is at least partially visible. */
19911 ++it->hpos;
19912 if (x < it->first_visible_x)
19913 it->glyph_row->x = x - it->first_visible_x;
19915 else
19917 /* Glyph is off the left margin of the display area.
19918 Should not happen. */
19919 abort ();
19922 row->ascent = max (row->ascent, it->max_ascent);
19923 row->height = max (row->height, it->max_ascent + it->max_descent);
19924 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
19925 row->phys_height = max (row->phys_height,
19926 it->max_phys_ascent + it->max_phys_descent);
19927 row->extra_line_spacing = max (row->extra_line_spacing,
19928 it->max_extra_line_spacing);
19929 x += glyph->pixel_width;
19930 ++i;
19933 /* Stop if max_x reached. */
19934 if (i < nglyphs)
19935 break;
19937 /* Stop at line ends. */
19938 if (ITERATOR_AT_END_OF_LINE_P (it))
19940 it->continuation_lines_width = 0;
19941 break;
19944 set_iterator_to_next (it, 1);
19946 /* Stop if truncating at the right edge. */
19947 if (it->line_wrap == TRUNCATE
19948 && it->current_x >= it->last_visible_x)
19950 /* Add truncation mark, but don't do it if the line is
19951 truncated at a padding space. */
19952 if (IT_CHARPOS (*it) < it->string_nchars)
19954 if (!FRAME_WINDOW_P (it->f))
19956 int i, n;
19958 if (it->current_x > it->last_visible_x)
19960 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
19961 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
19962 break;
19963 for (n = row->used[TEXT_AREA]; i < n; ++i)
19965 row->used[TEXT_AREA] = i;
19966 produce_special_glyphs (it, IT_TRUNCATION);
19969 produce_special_glyphs (it, IT_TRUNCATION);
19971 it->glyph_row->truncated_on_right_p = 1;
19973 break;
19977 /* Maybe insert a truncation at the left. */
19978 if (it->first_visible_x
19979 && IT_CHARPOS (*it) > 0)
19981 if (!FRAME_WINDOW_P (it->f))
19982 insert_left_trunc_glyphs (it);
19983 it->glyph_row->truncated_on_left_p = 1;
19986 it->face_id = saved_face_id;
19988 /* Value is number of columns displayed. */
19989 return it->hpos - hpos_at_start;
19994 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
19995 appears as an element of LIST or as the car of an element of LIST.
19996 If PROPVAL is a list, compare each element against LIST in that
19997 way, and return 1/2 if any element of PROPVAL is found in LIST.
19998 Otherwise return 0. This function cannot quit.
19999 The return value is 2 if the text is invisible but with an ellipsis
20000 and 1 if it's invisible and without an ellipsis. */
20003 invisible_p (register Lisp_Object propval, Lisp_Object list)
20005 register Lisp_Object tail, proptail;
20007 for (tail = list; CONSP (tail); tail = XCDR (tail))
20009 register Lisp_Object tem;
20010 tem = XCAR (tail);
20011 if (EQ (propval, tem))
20012 return 1;
20013 if (CONSP (tem) && EQ (propval, XCAR (tem)))
20014 return NILP (XCDR (tem)) ? 1 : 2;
20017 if (CONSP (propval))
20019 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
20021 Lisp_Object propelt;
20022 propelt = XCAR (proptail);
20023 for (tail = list; CONSP (tail); tail = XCDR (tail))
20025 register Lisp_Object tem;
20026 tem = XCAR (tail);
20027 if (EQ (propelt, tem))
20028 return 1;
20029 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
20030 return NILP (XCDR (tem)) ? 1 : 2;
20035 return 0;
20038 DEFUN ("invisible-p", Finvisible_p, Sinvisible_p, 1, 1, 0,
20039 doc: /* Non-nil if the property makes the text invisible.
20040 POS-OR-PROP can be a marker or number, in which case it is taken to be
20041 a position in the current buffer and the value of the `invisible' property
20042 is checked; or it can be some other value, which is then presumed to be the
20043 value of the `invisible' property of the text of interest.
20044 The non-nil value returned can be t for truly invisible text or something
20045 else if the text is replaced by an ellipsis. */)
20046 (Lisp_Object pos_or_prop)
20048 Lisp_Object prop
20049 = (NATNUMP (pos_or_prop) || MARKERP (pos_or_prop)
20050 ? Fget_char_property (pos_or_prop, Qinvisible, Qnil)
20051 : pos_or_prop);
20052 int invis = TEXT_PROP_MEANS_INVISIBLE (prop);
20053 return (invis == 0 ? Qnil
20054 : invis == 1 ? Qt
20055 : make_number (invis));
20058 /* Calculate a width or height in pixels from a specification using
20059 the following elements:
20061 SPEC ::=
20062 NUM - a (fractional) multiple of the default font width/height
20063 (NUM) - specifies exactly NUM pixels
20064 UNIT - a fixed number of pixels, see below.
20065 ELEMENT - size of a display element in pixels, see below.
20066 (NUM . SPEC) - equals NUM * SPEC
20067 (+ SPEC SPEC ...) - add pixel values
20068 (- SPEC SPEC ...) - subtract pixel values
20069 (- SPEC) - negate pixel value
20071 NUM ::=
20072 INT or FLOAT - a number constant
20073 SYMBOL - use symbol's (buffer local) variable binding.
20075 UNIT ::=
20076 in - pixels per inch *)
20077 mm - pixels per 1/1000 meter *)
20078 cm - pixels per 1/100 meter *)
20079 width - width of current font in pixels.
20080 height - height of current font in pixels.
20082 *) using the ratio(s) defined in display-pixels-per-inch.
20084 ELEMENT ::=
20086 left-fringe - left fringe width in pixels
20087 right-fringe - right fringe width in pixels
20089 left-margin - left margin width in pixels
20090 right-margin - right margin width in pixels
20092 scroll-bar - scroll-bar area width in pixels
20094 Examples:
20096 Pixels corresponding to 5 inches:
20097 (5 . in)
20099 Total width of non-text areas on left side of window (if scroll-bar is on left):
20100 '(space :width (+ left-fringe left-margin scroll-bar))
20102 Align to first text column (in header line):
20103 '(space :align-to 0)
20105 Align to middle of text area minus half the width of variable `my-image'
20106 containing a loaded image:
20107 '(space :align-to (0.5 . (- text my-image)))
20109 Width of left margin minus width of 1 character in the default font:
20110 '(space :width (- left-margin 1))
20112 Width of left margin minus width of 2 characters in the current font:
20113 '(space :width (- left-margin (2 . width)))
20115 Center 1 character over left-margin (in header line):
20116 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
20118 Different ways to express width of left fringe plus left margin minus one pixel:
20119 '(space :width (- (+ left-fringe left-margin) (1)))
20120 '(space :width (+ left-fringe left-margin (- (1))))
20121 '(space :width (+ left-fringe left-margin (-1)))
20125 #define NUMVAL(X) \
20126 ((INTEGERP (X) || FLOATP (X)) \
20127 ? XFLOATINT (X) \
20128 : - 1)
20131 calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
20132 struct font *font, int width_p, int *align_to)
20134 double pixels;
20136 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
20137 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
20139 if (NILP (prop))
20140 return OK_PIXELS (0);
20142 xassert (FRAME_LIVE_P (it->f));
20144 if (SYMBOLP (prop))
20146 if (SCHARS (SYMBOL_NAME (prop)) == 2)
20148 char *unit = SDATA (SYMBOL_NAME (prop));
20150 if (unit[0] == 'i' && unit[1] == 'n')
20151 pixels = 1.0;
20152 else if (unit[0] == 'm' && unit[1] == 'm')
20153 pixels = 25.4;
20154 else if (unit[0] == 'c' && unit[1] == 'm')
20155 pixels = 2.54;
20156 else
20157 pixels = 0;
20158 if (pixels > 0)
20160 double ppi;
20161 #ifdef HAVE_WINDOW_SYSTEM
20162 if (FRAME_WINDOW_P (it->f)
20163 && (ppi = (width_p
20164 ? FRAME_X_DISPLAY_INFO (it->f)->resx
20165 : FRAME_X_DISPLAY_INFO (it->f)->resy),
20166 ppi > 0))
20167 return OK_PIXELS (ppi / pixels);
20168 #endif
20170 if ((ppi = NUMVAL (Vdisplay_pixels_per_inch), ppi > 0)
20171 || (CONSP (Vdisplay_pixels_per_inch)
20172 && (ppi = (width_p
20173 ? NUMVAL (XCAR (Vdisplay_pixels_per_inch))
20174 : NUMVAL (XCDR (Vdisplay_pixels_per_inch))),
20175 ppi > 0)))
20176 return OK_PIXELS (ppi / pixels);
20178 return 0;
20182 #ifdef HAVE_WINDOW_SYSTEM
20183 if (EQ (prop, Qheight))
20184 return OK_PIXELS (font ? FONT_HEIGHT (font) : FRAME_LINE_HEIGHT (it->f));
20185 if (EQ (prop, Qwidth))
20186 return OK_PIXELS (font ? FONT_WIDTH (font) : FRAME_COLUMN_WIDTH (it->f));
20187 #else
20188 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
20189 return OK_PIXELS (1);
20190 #endif
20192 if (EQ (prop, Qtext))
20193 return OK_PIXELS (width_p
20194 ? window_box_width (it->w, TEXT_AREA)
20195 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
20197 if (align_to && *align_to < 0)
20199 *res = 0;
20200 if (EQ (prop, Qleft))
20201 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA));
20202 if (EQ (prop, Qright))
20203 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
20204 if (EQ (prop, Qcenter))
20205 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
20206 + window_box_width (it->w, TEXT_AREA) / 2);
20207 if (EQ (prop, Qleft_fringe))
20208 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
20209 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
20210 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
20211 if (EQ (prop, Qright_fringe))
20212 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
20213 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
20214 : window_box_right_offset (it->w, TEXT_AREA));
20215 if (EQ (prop, Qleft_margin))
20216 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
20217 if (EQ (prop, Qright_margin))
20218 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
20219 if (EQ (prop, Qscroll_bar))
20220 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
20222 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
20223 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
20224 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
20225 : 0)));
20227 else
20229 if (EQ (prop, Qleft_fringe))
20230 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
20231 if (EQ (prop, Qright_fringe))
20232 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
20233 if (EQ (prop, Qleft_margin))
20234 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
20235 if (EQ (prop, Qright_margin))
20236 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
20237 if (EQ (prop, Qscroll_bar))
20238 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
20241 prop = Fbuffer_local_value (prop, it->w->buffer);
20244 if (INTEGERP (prop) || FLOATP (prop))
20246 int base_unit = (width_p
20247 ? FRAME_COLUMN_WIDTH (it->f)
20248 : FRAME_LINE_HEIGHT (it->f));
20249 return OK_PIXELS (XFLOATINT (prop) * base_unit);
20252 if (CONSP (prop))
20254 Lisp_Object car = XCAR (prop);
20255 Lisp_Object cdr = XCDR (prop);
20257 if (SYMBOLP (car))
20259 #ifdef HAVE_WINDOW_SYSTEM
20260 if (FRAME_WINDOW_P (it->f)
20261 && valid_image_p (prop))
20263 int id = lookup_image (it->f, prop);
20264 struct image *img = IMAGE_FROM_ID (it->f, id);
20266 return OK_PIXELS (width_p ? img->width : img->height);
20268 #endif
20269 if (EQ (car, Qplus) || EQ (car, Qminus))
20271 int first = 1;
20272 double px;
20274 pixels = 0;
20275 while (CONSP (cdr))
20277 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
20278 font, width_p, align_to))
20279 return 0;
20280 if (first)
20281 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
20282 else
20283 pixels += px;
20284 cdr = XCDR (cdr);
20286 if (EQ (car, Qminus))
20287 pixels = -pixels;
20288 return OK_PIXELS (pixels);
20291 car = Fbuffer_local_value (car, it->w->buffer);
20294 if (INTEGERP (car) || FLOATP (car))
20296 double fact;
20297 pixels = XFLOATINT (car);
20298 if (NILP (cdr))
20299 return OK_PIXELS (pixels);
20300 if (calc_pixel_width_or_height (&fact, it, cdr,
20301 font, width_p, align_to))
20302 return OK_PIXELS (pixels * fact);
20303 return 0;
20306 return 0;
20309 return 0;
20313 /***********************************************************************
20314 Glyph Display
20315 ***********************************************************************/
20317 #ifdef HAVE_WINDOW_SYSTEM
20319 #if GLYPH_DEBUG
20321 void
20322 dump_glyph_string (s)
20323 struct glyph_string *s;
20325 fprintf (stderr, "glyph string\n");
20326 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
20327 s->x, s->y, s->width, s->height);
20328 fprintf (stderr, " ybase = %d\n", s->ybase);
20329 fprintf (stderr, " hl = %d\n", s->hl);
20330 fprintf (stderr, " left overhang = %d, right = %d\n",
20331 s->left_overhang, s->right_overhang);
20332 fprintf (stderr, " nchars = %d\n", s->nchars);
20333 fprintf (stderr, " extends to end of line = %d\n",
20334 s->extends_to_end_of_line_p);
20335 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
20336 fprintf (stderr, " bg width = %d\n", s->background_width);
20339 #endif /* GLYPH_DEBUG */
20341 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
20342 of XChar2b structures for S; it can't be allocated in
20343 init_glyph_string because it must be allocated via `alloca'. W
20344 is the window on which S is drawn. ROW and AREA are the glyph row
20345 and area within the row from which S is constructed. START is the
20346 index of the first glyph structure covered by S. HL is a
20347 face-override for drawing S. */
20349 #ifdef HAVE_NTGUI
20350 #define OPTIONAL_HDC(hdc) HDC hdc,
20351 #define DECLARE_HDC(hdc) HDC hdc;
20352 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
20353 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
20354 #endif
20356 #ifndef OPTIONAL_HDC
20357 #define OPTIONAL_HDC(hdc)
20358 #define DECLARE_HDC(hdc)
20359 #define ALLOCATE_HDC(hdc, f)
20360 #define RELEASE_HDC(hdc, f)
20361 #endif
20363 static void
20364 init_glyph_string (struct glyph_string *s,
20365 OPTIONAL_HDC (hdc)
20366 XChar2b *char2b, struct window *w, struct glyph_row *row,
20367 enum glyph_row_area area, int start, enum draw_glyphs_face hl)
20369 memset (s, 0, sizeof *s);
20370 s->w = w;
20371 s->f = XFRAME (w->frame);
20372 #ifdef HAVE_NTGUI
20373 s->hdc = hdc;
20374 #endif
20375 s->display = FRAME_X_DISPLAY (s->f);
20376 s->window = FRAME_X_WINDOW (s->f);
20377 s->char2b = char2b;
20378 s->hl = hl;
20379 s->row = row;
20380 s->area = area;
20381 s->first_glyph = row->glyphs[area] + start;
20382 s->height = row->height;
20383 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
20384 s->ybase = s->y + row->ascent;
20388 /* Append the list of glyph strings with head H and tail T to the list
20389 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
20391 static INLINE void
20392 append_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
20393 struct glyph_string *h, struct glyph_string *t)
20395 if (h)
20397 if (*head)
20398 (*tail)->next = h;
20399 else
20400 *head = h;
20401 h->prev = *tail;
20402 *tail = t;
20407 /* Prepend the list of glyph strings with head H and tail T to the
20408 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
20409 result. */
20411 static INLINE void
20412 prepend_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
20413 struct glyph_string *h, struct glyph_string *t)
20415 if (h)
20417 if (*head)
20418 (*head)->prev = t;
20419 else
20420 *tail = t;
20421 t->next = *head;
20422 *head = h;
20427 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
20428 Set *HEAD and *TAIL to the resulting list. */
20430 static INLINE void
20431 append_glyph_string (struct glyph_string **head, struct glyph_string **tail,
20432 struct glyph_string *s)
20434 s->next = s->prev = NULL;
20435 append_glyph_string_lists (head, tail, s, s);
20439 /* Get face and two-byte form of character C in face FACE_ID on frame
20440 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
20441 means we want to display multibyte text. DISPLAY_P non-zero means
20442 make sure that X resources for the face returned are allocated.
20443 Value is a pointer to a realized face that is ready for display if
20444 DISPLAY_P is non-zero. */
20446 static INLINE struct face *
20447 get_char_face_and_encoding (struct frame *f, int c, int face_id,
20448 XChar2b *char2b, int multibyte_p, int display_p)
20450 struct face *face = FACE_FROM_ID (f, face_id);
20452 if (face->font)
20454 unsigned code = face->font->driver->encode_char (face->font, c);
20456 if (code != FONT_INVALID_CODE)
20457 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
20458 else
20459 STORE_XCHAR2B (char2b, 0, 0);
20462 /* Make sure X resources of the face are allocated. */
20463 #ifdef HAVE_X_WINDOWS
20464 if (display_p)
20465 #endif
20467 xassert (face != NULL);
20468 PREPARE_FACE_FOR_DISPLAY (f, face);
20471 return face;
20475 /* Get face and two-byte form of character glyph GLYPH on frame F.
20476 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
20477 a pointer to a realized face that is ready for display. */
20479 static INLINE struct face *
20480 get_glyph_face_and_encoding (struct frame *f, struct glyph *glyph,
20481 XChar2b *char2b, int *two_byte_p)
20483 struct face *face;
20485 xassert (glyph->type == CHAR_GLYPH);
20486 face = FACE_FROM_ID (f, glyph->face_id);
20488 if (two_byte_p)
20489 *two_byte_p = 0;
20491 if (face->font)
20493 unsigned code = face->font->driver->encode_char (face->font, glyph->u.ch);
20495 if (code != FONT_INVALID_CODE)
20496 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
20497 else
20498 STORE_XCHAR2B (char2b, 0, 0);
20501 /* Make sure X resources of the face are allocated. */
20502 xassert (face != NULL);
20503 PREPARE_FACE_FOR_DISPLAY (f, face);
20504 return face;
20508 /* Fill glyph string S with composition components specified by S->cmp.
20510 BASE_FACE is the base face of the composition.
20511 S->cmp_from is the index of the first component for S.
20513 OVERLAPS non-zero means S should draw the foreground only, and use
20514 its physical height for clipping. See also draw_glyphs.
20516 Value is the index of a component not in S. */
20518 static int
20519 fill_composite_glyph_string (struct glyph_string *s, struct face *base_face,
20520 int overlaps)
20522 int i;
20523 /* For all glyphs of this composition, starting at the offset
20524 S->cmp_from, until we reach the end of the definition or encounter a
20525 glyph that requires the different face, add it to S. */
20526 struct face *face;
20528 xassert (s);
20530 s->for_overlaps = overlaps;
20531 s->face = NULL;
20532 s->font = NULL;
20533 for (i = s->cmp_from; i < s->cmp->glyph_len; i++)
20535 int c = COMPOSITION_GLYPH (s->cmp, i);
20537 if (c != '\t')
20539 int face_id = FACE_FOR_CHAR (s->f, base_face->ascii_face, c,
20540 -1, Qnil);
20542 face = get_char_face_and_encoding (s->f, c, face_id,
20543 s->char2b + i, 1, 1);
20544 if (face)
20546 if (! s->face)
20548 s->face = face;
20549 s->font = s->face->font;
20551 else if (s->face != face)
20552 break;
20555 ++s->nchars;
20557 s->cmp_to = i;
20559 /* All glyph strings for the same composition has the same width,
20560 i.e. the width set for the first component of the composition. */
20561 s->width = s->first_glyph->pixel_width;
20563 /* If the specified font could not be loaded, use the frame's
20564 default font, but record the fact that we couldn't load it in
20565 the glyph string so that we can draw rectangles for the
20566 characters of the glyph string. */
20567 if (s->font == NULL)
20569 s->font_not_found_p = 1;
20570 s->font = FRAME_FONT (s->f);
20573 /* Adjust base line for subscript/superscript text. */
20574 s->ybase += s->first_glyph->voffset;
20576 /* This glyph string must always be drawn with 16-bit functions. */
20577 s->two_byte_p = 1;
20579 return s->cmp_to;
20582 static int
20583 fill_gstring_glyph_string (struct glyph_string *s, int face_id,
20584 int start, int end, int overlaps)
20586 struct glyph *glyph, *last;
20587 Lisp_Object lgstring;
20588 int i;
20590 s->for_overlaps = overlaps;
20591 glyph = s->row->glyphs[s->area] + start;
20592 last = s->row->glyphs[s->area] + end;
20593 s->cmp_id = glyph->u.cmp.id;
20594 s->cmp_from = glyph->u.cmp.from;
20595 s->cmp_to = glyph->u.cmp.to + 1;
20596 s->face = FACE_FROM_ID (s->f, face_id);
20597 lgstring = composition_gstring_from_id (s->cmp_id);
20598 s->font = XFONT_OBJECT (LGSTRING_FONT (lgstring));
20599 glyph++;
20600 while (glyph < last
20601 && glyph->u.cmp.automatic
20602 && glyph->u.cmp.id == s->cmp_id
20603 && s->cmp_to == glyph->u.cmp.from)
20604 s->cmp_to = (glyph++)->u.cmp.to + 1;
20606 for (i = s->cmp_from; i < s->cmp_to; i++)
20608 Lisp_Object lglyph = LGSTRING_GLYPH (lgstring, i);
20609 unsigned code = LGLYPH_CODE (lglyph);
20611 STORE_XCHAR2B ((s->char2b + i), code >> 8, code & 0xFF);
20613 s->width = composition_gstring_width (lgstring, s->cmp_from, s->cmp_to, NULL);
20614 return glyph - s->row->glyphs[s->area];
20618 /* Fill glyph string S from a sequence of character glyphs.
20620 FACE_ID is the face id of the string. START is the index of the
20621 first glyph to consider, END is the index of the last + 1.
20622 OVERLAPS non-zero means S should draw the foreground only, and use
20623 its physical height for clipping. See also draw_glyphs.
20625 Value is the index of the first glyph not in S. */
20627 static int
20628 fill_glyph_string (struct glyph_string *s, int face_id,
20629 int start, int end, int overlaps)
20631 struct glyph *glyph, *last;
20632 int voffset;
20633 int glyph_not_available_p;
20635 xassert (s->f == XFRAME (s->w->frame));
20636 xassert (s->nchars == 0);
20637 xassert (start >= 0 && end > start);
20639 s->for_overlaps = overlaps;
20640 glyph = s->row->glyphs[s->area] + start;
20641 last = s->row->glyphs[s->area] + end;
20642 voffset = glyph->voffset;
20643 s->padding_p = glyph->padding_p;
20644 glyph_not_available_p = glyph->glyph_not_available_p;
20646 while (glyph < last
20647 && glyph->type == CHAR_GLYPH
20648 && glyph->voffset == voffset
20649 /* Same face id implies same font, nowadays. */
20650 && glyph->face_id == face_id
20651 && glyph->glyph_not_available_p == glyph_not_available_p)
20653 int two_byte_p;
20655 s->face = get_glyph_face_and_encoding (s->f, glyph,
20656 s->char2b + s->nchars,
20657 &two_byte_p);
20658 s->two_byte_p = two_byte_p;
20659 ++s->nchars;
20660 xassert (s->nchars <= end - start);
20661 s->width += glyph->pixel_width;
20662 if (glyph++->padding_p != s->padding_p)
20663 break;
20666 s->font = s->face->font;
20668 /* If the specified font could not be loaded, use the frame's font,
20669 but record the fact that we couldn't load it in
20670 S->font_not_found_p so that we can draw rectangles for the
20671 characters of the glyph string. */
20672 if (s->font == NULL || glyph_not_available_p)
20674 s->font_not_found_p = 1;
20675 s->font = FRAME_FONT (s->f);
20678 /* Adjust base line for subscript/superscript text. */
20679 s->ybase += voffset;
20681 xassert (s->face && s->face->gc);
20682 return glyph - s->row->glyphs[s->area];
20686 /* Fill glyph string S from image glyph S->first_glyph. */
20688 static void
20689 fill_image_glyph_string (struct glyph_string *s)
20691 xassert (s->first_glyph->type == IMAGE_GLYPH);
20692 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
20693 xassert (s->img);
20694 s->slice = s->first_glyph->slice;
20695 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
20696 s->font = s->face->font;
20697 s->width = s->first_glyph->pixel_width;
20699 /* Adjust base line for subscript/superscript text. */
20700 s->ybase += s->first_glyph->voffset;
20704 /* Fill glyph string S from a sequence of stretch glyphs.
20706 ROW is the glyph row in which the glyphs are found, AREA is the
20707 area within the row. START is the index of the first glyph to
20708 consider, END is the index of the last + 1.
20710 Value is the index of the first glyph not in S. */
20712 static int
20713 fill_stretch_glyph_string (struct glyph_string *s, struct glyph_row *row,
20714 enum glyph_row_area area, int start, int end)
20716 struct glyph *glyph, *last;
20717 int voffset, face_id;
20719 xassert (s->first_glyph->type == STRETCH_GLYPH);
20721 glyph = s->row->glyphs[s->area] + start;
20722 last = s->row->glyphs[s->area] + end;
20723 face_id = glyph->face_id;
20724 s->face = FACE_FROM_ID (s->f, face_id);
20725 s->font = s->face->font;
20726 s->width = glyph->pixel_width;
20727 s->nchars = 1;
20728 voffset = glyph->voffset;
20730 for (++glyph;
20731 (glyph < last
20732 && glyph->type == STRETCH_GLYPH
20733 && glyph->voffset == voffset
20734 && glyph->face_id == face_id);
20735 ++glyph)
20736 s->width += glyph->pixel_width;
20738 /* Adjust base line for subscript/superscript text. */
20739 s->ybase += voffset;
20741 /* The case that face->gc == 0 is handled when drawing the glyph
20742 string by calling PREPARE_FACE_FOR_DISPLAY. */
20743 xassert (s->face);
20744 return glyph - s->row->glyphs[s->area];
20747 static struct font_metrics *
20748 get_per_char_metric (struct frame *f, struct font *font, XChar2b *char2b)
20750 static struct font_metrics metrics;
20751 unsigned code = (XCHAR2B_BYTE1 (char2b) << 8) | XCHAR2B_BYTE2 (char2b);
20753 if (! font || code == FONT_INVALID_CODE)
20754 return NULL;
20755 font->driver->text_extents (font, &code, 1, &metrics);
20756 return &metrics;
20759 /* EXPORT for RIF:
20760 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
20761 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
20762 assumed to be zero. */
20764 void
20765 x_get_glyph_overhangs (struct glyph *glyph, struct frame *f, int *left, int *right)
20767 *left = *right = 0;
20769 if (glyph->type == CHAR_GLYPH)
20771 struct face *face;
20772 XChar2b char2b;
20773 struct font_metrics *pcm;
20775 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
20776 if (face->font && (pcm = get_per_char_metric (f, face->font, &char2b)))
20778 if (pcm->rbearing > pcm->width)
20779 *right = pcm->rbearing - pcm->width;
20780 if (pcm->lbearing < 0)
20781 *left = -pcm->lbearing;
20784 else if (glyph->type == COMPOSITE_GLYPH)
20786 if (! glyph->u.cmp.automatic)
20788 struct composition *cmp = composition_table[glyph->u.cmp.id];
20790 if (cmp->rbearing > cmp->pixel_width)
20791 *right = cmp->rbearing - cmp->pixel_width;
20792 if (cmp->lbearing < 0)
20793 *left = - cmp->lbearing;
20795 else
20797 Lisp_Object gstring = composition_gstring_from_id (glyph->u.cmp.id);
20798 struct font_metrics metrics;
20800 composition_gstring_width (gstring, glyph->u.cmp.from,
20801 glyph->u.cmp.to + 1, &metrics);
20802 if (metrics.rbearing > metrics.width)
20803 *right = metrics.rbearing - metrics.width;
20804 if (metrics.lbearing < 0)
20805 *left = - metrics.lbearing;
20811 /* Return the index of the first glyph preceding glyph string S that
20812 is overwritten by S because of S's left overhang. Value is -1
20813 if no glyphs are overwritten. */
20815 static int
20816 left_overwritten (struct glyph_string *s)
20818 int k;
20820 if (s->left_overhang)
20822 int x = 0, i;
20823 struct glyph *glyphs = s->row->glyphs[s->area];
20824 int first = s->first_glyph - glyphs;
20826 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
20827 x -= glyphs[i].pixel_width;
20829 k = i + 1;
20831 else
20832 k = -1;
20834 return k;
20838 /* Return the index of the first glyph preceding glyph string S that
20839 is overwriting S because of its right overhang. Value is -1 if no
20840 glyph in front of S overwrites S. */
20842 static int
20843 left_overwriting (struct glyph_string *s)
20845 int i, k, x;
20846 struct glyph *glyphs = s->row->glyphs[s->area];
20847 int first = s->first_glyph - glyphs;
20849 k = -1;
20850 x = 0;
20851 for (i = first - 1; i >= 0; --i)
20853 int left, right;
20854 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
20855 if (x + right > 0)
20856 k = i;
20857 x -= glyphs[i].pixel_width;
20860 return k;
20864 /* Return the index of the last glyph following glyph string S that is
20865 overwritten by S because of S's right overhang. Value is -1 if
20866 no such glyph is found. */
20868 static int
20869 right_overwritten (struct glyph_string *s)
20871 int k = -1;
20873 if (s->right_overhang)
20875 int x = 0, i;
20876 struct glyph *glyphs = s->row->glyphs[s->area];
20877 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
20878 int end = s->row->used[s->area];
20880 for (i = first; i < end && s->right_overhang > x; ++i)
20881 x += glyphs[i].pixel_width;
20883 k = i;
20886 return k;
20890 /* Return the index of the last glyph following glyph string S that
20891 overwrites S because of its left overhang. Value is negative
20892 if no such glyph is found. */
20894 static int
20895 right_overwriting (struct glyph_string *s)
20897 int i, k, x;
20898 int end = s->row->used[s->area];
20899 struct glyph *glyphs = s->row->glyphs[s->area];
20900 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
20902 k = -1;
20903 x = 0;
20904 for (i = first; i < end; ++i)
20906 int left, right;
20907 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
20908 if (x - left < 0)
20909 k = i;
20910 x += glyphs[i].pixel_width;
20913 return k;
20917 /* Set background width of glyph string S. START is the index of the
20918 first glyph following S. LAST_X is the right-most x-position + 1
20919 in the drawing area. */
20921 static INLINE void
20922 set_glyph_string_background_width (struct glyph_string *s, int start, int last_x)
20924 /* If the face of this glyph string has to be drawn to the end of
20925 the drawing area, set S->extends_to_end_of_line_p. */
20927 if (start == s->row->used[s->area]
20928 && s->area == TEXT_AREA
20929 && ((s->row->fill_line_p
20930 && (s->hl == DRAW_NORMAL_TEXT
20931 || s->hl == DRAW_IMAGE_RAISED
20932 || s->hl == DRAW_IMAGE_SUNKEN))
20933 || s->hl == DRAW_MOUSE_FACE))
20934 s->extends_to_end_of_line_p = 1;
20936 /* If S extends its face to the end of the line, set its
20937 background_width to the distance to the right edge of the drawing
20938 area. */
20939 if (s->extends_to_end_of_line_p)
20940 s->background_width = last_x - s->x + 1;
20941 else
20942 s->background_width = s->width;
20946 /* Compute overhangs and x-positions for glyph string S and its
20947 predecessors, or successors. X is the starting x-position for S.
20948 BACKWARD_P non-zero means process predecessors. */
20950 static void
20951 compute_overhangs_and_x (struct glyph_string *s, int x, int backward_p)
20953 if (backward_p)
20955 while (s)
20957 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
20958 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
20959 x -= s->width;
20960 s->x = x;
20961 s = s->prev;
20964 else
20966 while (s)
20968 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
20969 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
20970 s->x = x;
20971 x += s->width;
20972 s = s->next;
20979 /* The following macros are only called from draw_glyphs below.
20980 They reference the following parameters of that function directly:
20981 `w', `row', `area', and `overlap_p'
20982 as well as the following local variables:
20983 `s', `f', and `hdc' (in W32) */
20985 #ifdef HAVE_NTGUI
20986 /* On W32, silently add local `hdc' variable to argument list of
20987 init_glyph_string. */
20988 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
20989 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
20990 #else
20991 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
20992 init_glyph_string (s, char2b, w, row, area, start, hl)
20993 #endif
20995 /* Add a glyph string for a stretch glyph to the list of strings
20996 between HEAD and TAIL. START is the index of the stretch glyph in
20997 row area AREA of glyph row ROW. END is the index of the last glyph
20998 in that glyph row area. X is the current output position assigned
20999 to the new glyph string constructed. HL overrides that face of the
21000 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
21001 is the right-most x-position of the drawing area. */
21003 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
21004 and below -- keep them on one line. */
21005 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
21006 do \
21008 s = (struct glyph_string *) alloca (sizeof *s); \
21009 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
21010 START = fill_stretch_glyph_string (s, row, area, START, END); \
21011 append_glyph_string (&HEAD, &TAIL, s); \
21012 s->x = (X); \
21014 while (0)
21017 /* Add a glyph string for an image glyph to the list of strings
21018 between HEAD and TAIL. START is the index of the image glyph in
21019 row area AREA of glyph row ROW. END is the index of the last glyph
21020 in that glyph row area. X is the current output position assigned
21021 to the new glyph string constructed. HL overrides that face of the
21022 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
21023 is the right-most x-position of the drawing area. */
21025 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
21026 do \
21028 s = (struct glyph_string *) alloca (sizeof *s); \
21029 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
21030 fill_image_glyph_string (s); \
21031 append_glyph_string (&HEAD, &TAIL, s); \
21032 ++START; \
21033 s->x = (X); \
21035 while (0)
21038 /* Add a glyph string for a sequence of character glyphs to the list
21039 of strings between HEAD and TAIL. START is the index of the first
21040 glyph in row area AREA of glyph row ROW that is part of the new
21041 glyph string. END is the index of the last glyph in that glyph row
21042 area. X is the current output position assigned to the new glyph
21043 string constructed. HL overrides that face of the glyph; e.g. it
21044 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
21045 right-most x-position of the drawing area. */
21047 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
21048 do \
21050 int face_id; \
21051 XChar2b *char2b; \
21053 face_id = (row)->glyphs[area][START].face_id; \
21055 s = (struct glyph_string *) alloca (sizeof *s); \
21056 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
21057 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
21058 append_glyph_string (&HEAD, &TAIL, s); \
21059 s->x = (X); \
21060 START = fill_glyph_string (s, face_id, START, END, overlaps); \
21062 while (0)
21065 /* Add a glyph string for a composite sequence to the list of strings
21066 between HEAD and TAIL. START is the index of the first glyph in
21067 row area AREA of glyph row ROW that is part of the new glyph
21068 string. END is the index of the last glyph in that glyph row area.
21069 X is the current output position assigned to the new glyph string
21070 constructed. HL overrides that face of the glyph; e.g. it is
21071 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
21072 x-position of the drawing area. */
21074 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
21075 do { \
21076 int face_id = (row)->glyphs[area][START].face_id; \
21077 struct face *base_face = FACE_FROM_ID (f, face_id); \
21078 int cmp_id = (row)->glyphs[area][START].u.cmp.id; \
21079 struct composition *cmp = composition_table[cmp_id]; \
21080 XChar2b *char2b; \
21081 struct glyph_string *first_s; \
21082 int n; \
21084 char2b = (XChar2b *) alloca ((sizeof *char2b) * cmp->glyph_len); \
21086 /* Make glyph_strings for each glyph sequence that is drawable by \
21087 the same face, and append them to HEAD/TAIL. */ \
21088 for (n = 0; n < cmp->glyph_len;) \
21090 s = (struct glyph_string *) alloca (sizeof *s); \
21091 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
21092 append_glyph_string (&(HEAD), &(TAIL), s); \
21093 s->cmp = cmp; \
21094 s->cmp_from = n; \
21095 s->x = (X); \
21096 if (n == 0) \
21097 first_s = s; \
21098 n = fill_composite_glyph_string (s, base_face, overlaps); \
21101 ++START; \
21102 s = first_s; \
21103 } while (0)
21106 /* Add a glyph string for a glyph-string sequence to the list of strings
21107 between HEAD and TAIL. */
21109 #define BUILD_GSTRING_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
21110 do { \
21111 int face_id; \
21112 XChar2b *char2b; \
21113 Lisp_Object gstring; \
21115 face_id = (row)->glyphs[area][START].face_id; \
21116 gstring = (composition_gstring_from_id \
21117 ((row)->glyphs[area][START].u.cmp.id)); \
21118 s = (struct glyph_string *) alloca (sizeof *s); \
21119 char2b = (XChar2b *) alloca ((sizeof *char2b) \
21120 * LGSTRING_GLYPH_LEN (gstring)); \
21121 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
21122 append_glyph_string (&(HEAD), &(TAIL), s); \
21123 s->x = (X); \
21124 START = fill_gstring_glyph_string (s, face_id, START, END, overlaps); \
21125 } while (0)
21128 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
21129 of AREA of glyph row ROW on window W between indices START and END.
21130 HL overrides the face for drawing glyph strings, e.g. it is
21131 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
21132 x-positions of the drawing area.
21134 This is an ugly monster macro construct because we must use alloca
21135 to allocate glyph strings (because draw_glyphs can be called
21136 asynchronously). */
21138 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
21139 do \
21141 HEAD = TAIL = NULL; \
21142 while (START < END) \
21144 struct glyph *first_glyph = (row)->glyphs[area] + START; \
21145 switch (first_glyph->type) \
21147 case CHAR_GLYPH: \
21148 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
21149 HL, X, LAST_X); \
21150 break; \
21152 case COMPOSITE_GLYPH: \
21153 if (first_glyph->u.cmp.automatic) \
21154 BUILD_GSTRING_GLYPH_STRING (START, END, HEAD, TAIL, \
21155 HL, X, LAST_X); \
21156 else \
21157 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
21158 HL, X, LAST_X); \
21159 break; \
21161 case STRETCH_GLYPH: \
21162 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
21163 HL, X, LAST_X); \
21164 break; \
21166 case IMAGE_GLYPH: \
21167 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
21168 HL, X, LAST_X); \
21169 break; \
21171 default: \
21172 abort (); \
21175 if (s) \
21177 set_glyph_string_background_width (s, START, LAST_X); \
21178 (X) += s->width; \
21181 } while (0)
21184 /* Draw glyphs between START and END in AREA of ROW on window W,
21185 starting at x-position X. X is relative to AREA in W. HL is a
21186 face-override with the following meaning:
21188 DRAW_NORMAL_TEXT draw normally
21189 DRAW_CURSOR draw in cursor face
21190 DRAW_MOUSE_FACE draw in mouse face.
21191 DRAW_INVERSE_VIDEO draw in mode line face
21192 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
21193 DRAW_IMAGE_RAISED draw an image with a raised relief around it
21195 If OVERLAPS is non-zero, draw only the foreground of characters and
21196 clip to the physical height of ROW. Non-zero value also defines
21197 the overlapping part to be drawn:
21199 OVERLAPS_PRED overlap with preceding rows
21200 OVERLAPS_SUCC overlap with succeeding rows
21201 OVERLAPS_BOTH overlap with both preceding/succeeding rows
21202 OVERLAPS_ERASED_CURSOR overlap with erased cursor area
21204 Value is the x-position reached, relative to AREA of W. */
21206 static int
21207 draw_glyphs (struct window *w, int x, struct glyph_row *row,
21208 enum glyph_row_area area, EMACS_INT start, EMACS_INT end,
21209 enum draw_glyphs_face hl, int overlaps)
21211 struct glyph_string *head, *tail;
21212 struct glyph_string *s;
21213 struct glyph_string *clip_head = NULL, *clip_tail = NULL;
21214 int i, j, x_reached, last_x, area_left = 0;
21215 struct frame *f = XFRAME (WINDOW_FRAME (w));
21216 DECLARE_HDC (hdc);
21218 ALLOCATE_HDC (hdc, f);
21220 /* Let's rather be paranoid than getting a SEGV. */
21221 end = min (end, row->used[area]);
21222 start = max (0, start);
21223 start = min (end, start);
21225 /* Translate X to frame coordinates. Set last_x to the right
21226 end of the drawing area. */
21227 if (row->full_width_p)
21229 /* X is relative to the left edge of W, without scroll bars
21230 or fringes. */
21231 area_left = WINDOW_LEFT_EDGE_X (w);
21232 last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
21234 else
21236 area_left = window_box_left (w, area);
21237 last_x = area_left + window_box_width (w, area);
21239 x += area_left;
21241 /* Build a doubly-linked list of glyph_string structures between
21242 head and tail from what we have to draw. Note that the macro
21243 BUILD_GLYPH_STRINGS will modify its start parameter. That's
21244 the reason we use a separate variable `i'. */
21245 i = start;
21246 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
21247 if (tail)
21248 x_reached = tail->x + tail->background_width;
21249 else
21250 x_reached = x;
21252 /* If there are any glyphs with lbearing < 0 or rbearing > width in
21253 the row, redraw some glyphs in front or following the glyph
21254 strings built above. */
21255 if (head && !overlaps && row->contains_overlapping_glyphs_p)
21257 struct glyph_string *h, *t;
21258 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
21259 int mouse_beg_col, mouse_end_col, check_mouse_face = 0;
21260 int dummy_x = 0;
21262 /* If mouse highlighting is on, we may need to draw adjacent
21263 glyphs using mouse-face highlighting. */
21264 if (area == TEXT_AREA && row->mouse_face_p)
21266 struct glyph_row *mouse_beg_row, *mouse_end_row;
21268 mouse_beg_row = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row);
21269 mouse_end_row = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row);
21271 if (row >= mouse_beg_row && row <= mouse_end_row)
21273 check_mouse_face = 1;
21274 mouse_beg_col = (row == mouse_beg_row)
21275 ? dpyinfo->mouse_face_beg_col : 0;
21276 mouse_end_col = (row == mouse_end_row)
21277 ? dpyinfo->mouse_face_end_col
21278 : row->used[TEXT_AREA];
21282 /* Compute overhangs for all glyph strings. */
21283 if (FRAME_RIF (f)->compute_glyph_string_overhangs)
21284 for (s = head; s; s = s->next)
21285 FRAME_RIF (f)->compute_glyph_string_overhangs (s);
21287 /* Prepend glyph strings for glyphs in front of the first glyph
21288 string that are overwritten because of the first glyph
21289 string's left overhang. The background of all strings
21290 prepended must be drawn because the first glyph string
21291 draws over it. */
21292 i = left_overwritten (head);
21293 if (i >= 0)
21295 enum draw_glyphs_face overlap_hl;
21297 /* If this row contains mouse highlighting, attempt to draw
21298 the overlapped glyphs with the correct highlight. This
21299 code fails if the overlap encompasses more than one glyph
21300 and mouse-highlight spans only some of these glyphs.
21301 However, making it work perfectly involves a lot more
21302 code, and I don't know if the pathological case occurs in
21303 practice, so we'll stick to this for now. --- cyd */
21304 if (check_mouse_face
21305 && mouse_beg_col < start && mouse_end_col > i)
21306 overlap_hl = DRAW_MOUSE_FACE;
21307 else
21308 overlap_hl = DRAW_NORMAL_TEXT;
21310 j = i;
21311 BUILD_GLYPH_STRINGS (j, start, h, t,
21312 overlap_hl, dummy_x, last_x);
21313 start = i;
21314 compute_overhangs_and_x (t, head->x, 1);
21315 prepend_glyph_string_lists (&head, &tail, h, t);
21316 clip_head = head;
21319 /* Prepend glyph strings for glyphs in front of the first glyph
21320 string that overwrite that glyph string because of their
21321 right overhang. For these strings, only the foreground must
21322 be drawn, because it draws over the glyph string at `head'.
21323 The background must not be drawn because this would overwrite
21324 right overhangs of preceding glyphs for which no glyph
21325 strings exist. */
21326 i = left_overwriting (head);
21327 if (i >= 0)
21329 enum draw_glyphs_face overlap_hl;
21331 if (check_mouse_face
21332 && mouse_beg_col < start && mouse_end_col > i)
21333 overlap_hl = DRAW_MOUSE_FACE;
21334 else
21335 overlap_hl = DRAW_NORMAL_TEXT;
21337 clip_head = head;
21338 BUILD_GLYPH_STRINGS (i, start, h, t,
21339 overlap_hl, dummy_x, last_x);
21340 for (s = h; s; s = s->next)
21341 s->background_filled_p = 1;
21342 compute_overhangs_and_x (t, head->x, 1);
21343 prepend_glyph_string_lists (&head, &tail, h, t);
21346 /* Append glyphs strings for glyphs following the last glyph
21347 string tail that are overwritten by tail. The background of
21348 these strings has to be drawn because tail's foreground draws
21349 over it. */
21350 i = right_overwritten (tail);
21351 if (i >= 0)
21353 enum draw_glyphs_face overlap_hl;
21355 if (check_mouse_face
21356 && mouse_beg_col < i && mouse_end_col > end)
21357 overlap_hl = DRAW_MOUSE_FACE;
21358 else
21359 overlap_hl = DRAW_NORMAL_TEXT;
21361 BUILD_GLYPH_STRINGS (end, i, h, t,
21362 overlap_hl, x, last_x);
21363 /* Because BUILD_GLYPH_STRINGS updates the first argument,
21364 we don't have `end = i;' here. */
21365 compute_overhangs_and_x (h, tail->x + tail->width, 0);
21366 append_glyph_string_lists (&head, &tail, h, t);
21367 clip_tail = tail;
21370 /* Append glyph strings for glyphs following the last glyph
21371 string tail that overwrite tail. The foreground of such
21372 glyphs has to be drawn because it writes into the background
21373 of tail. The background must not be drawn because it could
21374 paint over the foreground of following glyphs. */
21375 i = right_overwriting (tail);
21376 if (i >= 0)
21378 enum draw_glyphs_face overlap_hl;
21379 if (check_mouse_face
21380 && mouse_beg_col < i && mouse_end_col > end)
21381 overlap_hl = DRAW_MOUSE_FACE;
21382 else
21383 overlap_hl = DRAW_NORMAL_TEXT;
21385 clip_tail = tail;
21386 i++; /* We must include the Ith glyph. */
21387 BUILD_GLYPH_STRINGS (end, i, h, t,
21388 overlap_hl, x, last_x);
21389 for (s = h; s; s = s->next)
21390 s->background_filled_p = 1;
21391 compute_overhangs_and_x (h, tail->x + tail->width, 0);
21392 append_glyph_string_lists (&head, &tail, h, t);
21394 if (clip_head || clip_tail)
21395 for (s = head; s; s = s->next)
21397 s->clip_head = clip_head;
21398 s->clip_tail = clip_tail;
21402 /* Draw all strings. */
21403 for (s = head; s; s = s->next)
21404 FRAME_RIF (f)->draw_glyph_string (s);
21406 #ifndef HAVE_NS
21407 /* When focus a sole frame and move horizontally, this sets on_p to 0
21408 causing a failure to erase prev cursor position. */
21409 if (area == TEXT_AREA
21410 && !row->full_width_p
21411 /* When drawing overlapping rows, only the glyph strings'
21412 foreground is drawn, which doesn't erase a cursor
21413 completely. */
21414 && !overlaps)
21416 int x0 = clip_head ? clip_head->x : (head ? head->x : x);
21417 int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width
21418 : (tail ? tail->x + tail->background_width : x));
21419 x0 -= area_left;
21420 x1 -= area_left;
21422 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
21423 row->y, MATRIX_ROW_BOTTOM_Y (row));
21425 #endif
21427 /* Value is the x-position up to which drawn, relative to AREA of W.
21428 This doesn't include parts drawn because of overhangs. */
21429 if (row->full_width_p)
21430 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
21431 else
21432 x_reached -= area_left;
21434 RELEASE_HDC (hdc, f);
21436 return x_reached;
21439 /* Expand row matrix if too narrow. Don't expand if area
21440 is not present. */
21442 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
21444 if (!fonts_changed_p \
21445 && (it->glyph_row->glyphs[area] \
21446 < it->glyph_row->glyphs[area + 1])) \
21448 it->w->ncols_scale_factor++; \
21449 fonts_changed_p = 1; \
21453 /* Store one glyph for IT->char_to_display in IT->glyph_row.
21454 Called from x_produce_glyphs when IT->glyph_row is non-null. */
21456 static INLINE void
21457 append_glyph (struct it *it)
21459 struct glyph *glyph;
21460 enum glyph_row_area area = it->area;
21462 xassert (it->glyph_row);
21463 xassert (it->char_to_display != '\n' && it->char_to_display != '\t');
21465 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
21466 if (glyph < it->glyph_row->glyphs[area + 1])
21468 /* If the glyph row is reversed, we need to prepend the glyph
21469 rather than append it. */
21470 if (it->glyph_row->reversed_p && area == TEXT_AREA)
21472 struct glyph *g;
21474 /* Make room for the additional glyph. */
21475 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
21476 g[1] = *g;
21477 glyph = it->glyph_row->glyphs[area];
21479 glyph->charpos = CHARPOS (it->position);
21480 glyph->object = it->object;
21481 if (it->pixel_width > 0)
21483 glyph->pixel_width = it->pixel_width;
21484 glyph->padding_p = 0;
21486 else
21488 /* Assure at least 1-pixel width. Otherwise, cursor can't
21489 be displayed correctly. */
21490 glyph->pixel_width = 1;
21491 glyph->padding_p = 1;
21493 glyph->ascent = it->ascent;
21494 glyph->descent = it->descent;
21495 glyph->voffset = it->voffset;
21496 glyph->type = CHAR_GLYPH;
21497 glyph->avoid_cursor_p = it->avoid_cursor_p;
21498 glyph->multibyte_p = it->multibyte_p;
21499 glyph->left_box_line_p = it->start_of_box_run_p;
21500 glyph->right_box_line_p = it->end_of_box_run_p;
21501 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
21502 || it->phys_descent > it->descent);
21503 glyph->glyph_not_available_p = it->glyph_not_available_p;
21504 glyph->face_id = it->face_id;
21505 glyph->u.ch = it->char_to_display;
21506 glyph->slice = null_glyph_slice;
21507 glyph->font_type = FONT_TYPE_UNKNOWN;
21508 if (it->bidi_p)
21510 glyph->resolved_level = it->bidi_it.resolved_level;
21511 if ((it->bidi_it.type & 7) != it->bidi_it.type)
21512 abort ();
21513 glyph->bidi_type = it->bidi_it.type;
21515 else
21517 glyph->resolved_level = 0;
21518 glyph->bidi_type = UNKNOWN_BT;
21520 ++it->glyph_row->used[area];
21522 else
21523 IT_EXPAND_MATRIX_WIDTH (it, area);
21526 /* Store one glyph for the composition IT->cmp_it.id in
21527 IT->glyph_row. Called from x_produce_glyphs when IT->glyph_row is
21528 non-null. */
21530 static INLINE void
21531 append_composite_glyph (struct it *it)
21533 struct glyph *glyph;
21534 enum glyph_row_area area = it->area;
21536 xassert (it->glyph_row);
21538 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
21539 if (glyph < it->glyph_row->glyphs[area + 1])
21541 /* If the glyph row is reversed, we need to prepend the glyph
21542 rather than append it. */
21543 if (it->glyph_row->reversed_p && it->area == TEXT_AREA)
21545 struct glyph *g;
21547 /* Make room for the new glyph. */
21548 for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
21549 g[1] = *g;
21550 glyph = it->glyph_row->glyphs[it->area];
21552 glyph->charpos = it->cmp_it.charpos;
21553 glyph->object = it->object;
21554 glyph->pixel_width = it->pixel_width;
21555 glyph->ascent = it->ascent;
21556 glyph->descent = it->descent;
21557 glyph->voffset = it->voffset;
21558 glyph->type = COMPOSITE_GLYPH;
21559 if (it->cmp_it.ch < 0)
21561 glyph->u.cmp.automatic = 0;
21562 glyph->u.cmp.id = it->cmp_it.id;
21564 else
21566 glyph->u.cmp.automatic = 1;
21567 glyph->u.cmp.id = it->cmp_it.id;
21568 glyph->u.cmp.from = it->cmp_it.from;
21569 glyph->u.cmp.to = it->cmp_it.to - 1;
21571 glyph->avoid_cursor_p = it->avoid_cursor_p;
21572 glyph->multibyte_p = it->multibyte_p;
21573 glyph->left_box_line_p = it->start_of_box_run_p;
21574 glyph->right_box_line_p = it->end_of_box_run_p;
21575 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
21576 || it->phys_descent > it->descent);
21577 glyph->padding_p = 0;
21578 glyph->glyph_not_available_p = 0;
21579 glyph->face_id = it->face_id;
21580 glyph->slice = null_glyph_slice;
21581 glyph->font_type = FONT_TYPE_UNKNOWN;
21582 if (it->bidi_p)
21584 glyph->resolved_level = it->bidi_it.resolved_level;
21585 if ((it->bidi_it.type & 7) != it->bidi_it.type)
21586 abort ();
21587 glyph->bidi_type = it->bidi_it.type;
21589 ++it->glyph_row->used[area];
21591 else
21592 IT_EXPAND_MATRIX_WIDTH (it, area);
21596 /* Change IT->ascent and IT->height according to the setting of
21597 IT->voffset. */
21599 static INLINE void
21600 take_vertical_position_into_account (struct it *it)
21602 if (it->voffset)
21604 if (it->voffset < 0)
21605 /* Increase the ascent so that we can display the text higher
21606 in the line. */
21607 it->ascent -= it->voffset;
21608 else
21609 /* Increase the descent so that we can display the text lower
21610 in the line. */
21611 it->descent += it->voffset;
21616 /* Produce glyphs/get display metrics for the image IT is loaded with.
21617 See the description of struct display_iterator in dispextern.h for
21618 an overview of struct display_iterator. */
21620 static void
21621 produce_image_glyph (struct it *it)
21623 struct image *img;
21624 struct face *face;
21625 int glyph_ascent, crop;
21626 struct glyph_slice slice;
21628 xassert (it->what == IT_IMAGE);
21630 face = FACE_FROM_ID (it->f, it->face_id);
21631 xassert (face);
21632 /* Make sure X resources of the face is loaded. */
21633 PREPARE_FACE_FOR_DISPLAY (it->f, face);
21635 if (it->image_id < 0)
21637 /* Fringe bitmap. */
21638 it->ascent = it->phys_ascent = 0;
21639 it->descent = it->phys_descent = 0;
21640 it->pixel_width = 0;
21641 it->nglyphs = 0;
21642 return;
21645 img = IMAGE_FROM_ID (it->f, it->image_id);
21646 xassert (img);
21647 /* Make sure X resources of the image is loaded. */
21648 prepare_image_for_display (it->f, img);
21650 slice.x = slice.y = 0;
21651 slice.width = img->width;
21652 slice.height = img->height;
21654 if (INTEGERP (it->slice.x))
21655 slice.x = XINT (it->slice.x);
21656 else if (FLOATP (it->slice.x))
21657 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
21659 if (INTEGERP (it->slice.y))
21660 slice.y = XINT (it->slice.y);
21661 else if (FLOATP (it->slice.y))
21662 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
21664 if (INTEGERP (it->slice.width))
21665 slice.width = XINT (it->slice.width);
21666 else if (FLOATP (it->slice.width))
21667 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
21669 if (INTEGERP (it->slice.height))
21670 slice.height = XINT (it->slice.height);
21671 else if (FLOATP (it->slice.height))
21672 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
21674 if (slice.x >= img->width)
21675 slice.x = img->width;
21676 if (slice.y >= img->height)
21677 slice.y = img->height;
21678 if (slice.x + slice.width >= img->width)
21679 slice.width = img->width - slice.x;
21680 if (slice.y + slice.height > img->height)
21681 slice.height = img->height - slice.y;
21683 if (slice.width == 0 || slice.height == 0)
21684 return;
21686 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
21688 it->descent = slice.height - glyph_ascent;
21689 if (slice.y == 0)
21690 it->descent += img->vmargin;
21691 if (slice.y + slice.height == img->height)
21692 it->descent += img->vmargin;
21693 it->phys_descent = it->descent;
21695 it->pixel_width = slice.width;
21696 if (slice.x == 0)
21697 it->pixel_width += img->hmargin;
21698 if (slice.x + slice.width == img->width)
21699 it->pixel_width += img->hmargin;
21701 /* It's quite possible for images to have an ascent greater than
21702 their height, so don't get confused in that case. */
21703 if (it->descent < 0)
21704 it->descent = 0;
21706 it->nglyphs = 1;
21708 if (face->box != FACE_NO_BOX)
21710 if (face->box_line_width > 0)
21712 if (slice.y == 0)
21713 it->ascent += face->box_line_width;
21714 if (slice.y + slice.height == img->height)
21715 it->descent += face->box_line_width;
21718 if (it->start_of_box_run_p && slice.x == 0)
21719 it->pixel_width += eabs (face->box_line_width);
21720 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
21721 it->pixel_width += eabs (face->box_line_width);
21724 take_vertical_position_into_account (it);
21726 /* Automatically crop wide image glyphs at right edge so we can
21727 draw the cursor on same display row. */
21728 if ((crop = it->pixel_width - (it->last_visible_x - it->current_x), crop > 0)
21729 && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
21731 it->pixel_width -= crop;
21732 slice.width -= crop;
21735 if (it->glyph_row)
21737 struct glyph *glyph;
21738 enum glyph_row_area area = it->area;
21740 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
21741 if (glyph < it->glyph_row->glyphs[area + 1])
21743 glyph->charpos = CHARPOS (it->position);
21744 glyph->object = it->object;
21745 glyph->pixel_width = it->pixel_width;
21746 glyph->ascent = glyph_ascent;
21747 glyph->descent = it->descent;
21748 glyph->voffset = it->voffset;
21749 glyph->type = IMAGE_GLYPH;
21750 glyph->avoid_cursor_p = it->avoid_cursor_p;
21751 glyph->multibyte_p = it->multibyte_p;
21752 glyph->left_box_line_p = it->start_of_box_run_p;
21753 glyph->right_box_line_p = it->end_of_box_run_p;
21754 glyph->overlaps_vertically_p = 0;
21755 glyph->padding_p = 0;
21756 glyph->glyph_not_available_p = 0;
21757 glyph->face_id = it->face_id;
21758 glyph->u.img_id = img->id;
21759 glyph->slice = slice;
21760 glyph->font_type = FONT_TYPE_UNKNOWN;
21761 if (it->bidi_p)
21763 glyph->resolved_level = it->bidi_it.resolved_level;
21764 if ((it->bidi_it.type & 7) != it->bidi_it.type)
21765 abort ();
21766 glyph->bidi_type = it->bidi_it.type;
21768 ++it->glyph_row->used[area];
21770 else
21771 IT_EXPAND_MATRIX_WIDTH (it, area);
21776 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
21777 of the glyph, WIDTH and HEIGHT are the width and height of the
21778 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
21780 static void
21781 append_stretch_glyph (struct it *it, Lisp_Object object,
21782 int width, int height, int ascent)
21784 struct glyph *glyph;
21785 enum glyph_row_area area = it->area;
21787 xassert (ascent >= 0 && ascent <= height);
21789 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
21790 if (glyph < it->glyph_row->glyphs[area + 1])
21792 /* If the glyph row is reversed, we need to prepend the glyph
21793 rather than append it. */
21794 if (it->glyph_row->reversed_p && area == TEXT_AREA)
21796 struct glyph *g;
21798 /* Make room for the additional glyph. */
21799 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
21800 g[1] = *g;
21801 glyph = it->glyph_row->glyphs[area];
21803 glyph->charpos = CHARPOS (it->position);
21804 glyph->object = object;
21805 glyph->pixel_width = width;
21806 glyph->ascent = ascent;
21807 glyph->descent = height - ascent;
21808 glyph->voffset = it->voffset;
21809 glyph->type = STRETCH_GLYPH;
21810 glyph->avoid_cursor_p = it->avoid_cursor_p;
21811 glyph->multibyte_p = it->multibyte_p;
21812 glyph->left_box_line_p = it->start_of_box_run_p;
21813 glyph->right_box_line_p = it->end_of_box_run_p;
21814 glyph->overlaps_vertically_p = 0;
21815 glyph->padding_p = 0;
21816 glyph->glyph_not_available_p = 0;
21817 glyph->face_id = it->face_id;
21818 glyph->u.stretch.ascent = ascent;
21819 glyph->u.stretch.height = height;
21820 glyph->slice = null_glyph_slice;
21821 glyph->font_type = FONT_TYPE_UNKNOWN;
21822 if (it->bidi_p)
21824 glyph->resolved_level = it->bidi_it.resolved_level;
21825 if ((it->bidi_it.type & 7) != it->bidi_it.type)
21826 abort ();
21827 glyph->bidi_type = it->bidi_it.type;
21829 else
21831 glyph->resolved_level = 0;
21832 glyph->bidi_type = UNKNOWN_BT;
21834 ++it->glyph_row->used[area];
21836 else
21837 IT_EXPAND_MATRIX_WIDTH (it, area);
21841 /* Produce a stretch glyph for iterator IT. IT->object is the value
21842 of the glyph property displayed. The value must be a list
21843 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
21844 being recognized:
21846 1. `:width WIDTH' specifies that the space should be WIDTH *
21847 canonical char width wide. WIDTH may be an integer or floating
21848 point number.
21850 2. `:relative-width FACTOR' specifies that the width of the stretch
21851 should be computed from the width of the first character having the
21852 `glyph' property, and should be FACTOR times that width.
21854 3. `:align-to HPOS' specifies that the space should be wide enough
21855 to reach HPOS, a value in canonical character units.
21857 Exactly one of the above pairs must be present.
21859 4. `:height HEIGHT' specifies that the height of the stretch produced
21860 should be HEIGHT, measured in canonical character units.
21862 5. `:relative-height FACTOR' specifies that the height of the
21863 stretch should be FACTOR times the height of the characters having
21864 the glyph property.
21866 Either none or exactly one of 4 or 5 must be present.
21868 6. `:ascent ASCENT' specifies that ASCENT percent of the height
21869 of the stretch should be used for the ascent of the stretch.
21870 ASCENT must be in the range 0 <= ASCENT <= 100. */
21872 static void
21873 produce_stretch_glyph (struct it *it)
21875 /* (space :width WIDTH :height HEIGHT ...) */
21876 Lisp_Object prop, plist;
21877 int width = 0, height = 0, align_to = -1;
21878 int zero_width_ok_p = 0, zero_height_ok_p = 0;
21879 int ascent = 0;
21880 double tem;
21881 struct face *face = FACE_FROM_ID (it->f, it->face_id);
21882 struct font *font = face->font ? face->font : FRAME_FONT (it->f);
21884 PREPARE_FACE_FOR_DISPLAY (it->f, face);
21886 /* List should start with `space'. */
21887 xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
21888 plist = XCDR (it->object);
21890 /* Compute the width of the stretch. */
21891 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
21892 && calc_pixel_width_or_height (&tem, it, prop, font, 1, 0))
21894 /* Absolute width `:width WIDTH' specified and valid. */
21895 zero_width_ok_p = 1;
21896 width = (int)tem;
21898 else if (prop = Fplist_get (plist, QCrelative_width),
21899 NUMVAL (prop) > 0)
21901 /* Relative width `:relative-width FACTOR' specified and valid.
21902 Compute the width of the characters having the `glyph'
21903 property. */
21904 struct it it2;
21905 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
21907 it2 = *it;
21908 if (it->multibyte_p)
21910 int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT)
21911 - IT_BYTEPOS (*it));
21912 it2.c = STRING_CHAR_AND_LENGTH (p, it2.len);
21914 else
21915 it2.c = *p, it2.len = 1;
21917 it2.glyph_row = NULL;
21918 it2.what = IT_CHARACTER;
21919 x_produce_glyphs (&it2);
21920 width = NUMVAL (prop) * it2.pixel_width;
21922 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
21923 && calc_pixel_width_or_height (&tem, it, prop, font, 1, &align_to))
21925 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
21926 align_to = (align_to < 0
21928 : align_to - window_box_left_offset (it->w, TEXT_AREA));
21929 else if (align_to < 0)
21930 align_to = window_box_left_offset (it->w, TEXT_AREA);
21931 width = max (0, (int)tem + align_to - it->current_x);
21932 zero_width_ok_p = 1;
21934 else
21935 /* Nothing specified -> width defaults to canonical char width. */
21936 width = FRAME_COLUMN_WIDTH (it->f);
21938 if (width <= 0 && (width < 0 || !zero_width_ok_p))
21939 width = 1;
21941 /* Compute height. */
21942 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
21943 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
21945 height = (int)tem;
21946 zero_height_ok_p = 1;
21948 else if (prop = Fplist_get (plist, QCrelative_height),
21949 NUMVAL (prop) > 0)
21950 height = FONT_HEIGHT (font) * NUMVAL (prop);
21951 else
21952 height = FONT_HEIGHT (font);
21954 if (height <= 0 && (height < 0 || !zero_height_ok_p))
21955 height = 1;
21957 /* Compute percentage of height used for ascent. If
21958 `:ascent ASCENT' is present and valid, use that. Otherwise,
21959 derive the ascent from the font in use. */
21960 if (prop = Fplist_get (plist, QCascent),
21961 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
21962 ascent = height * NUMVAL (prop) / 100.0;
21963 else if (!NILP (prop)
21964 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
21965 ascent = min (max (0, (int)tem), height);
21966 else
21967 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
21969 if (width > 0 && it->line_wrap != TRUNCATE
21970 && it->current_x + width > it->last_visible_x)
21971 width = it->last_visible_x - it->current_x - 1;
21973 if (width > 0 && height > 0 && it->glyph_row)
21975 Lisp_Object object = it->stack[it->sp - 1].string;
21976 if (!STRINGP (object))
21977 object = it->w->buffer;
21978 append_stretch_glyph (it, object, width, height, ascent);
21981 it->pixel_width = width;
21982 it->ascent = it->phys_ascent = ascent;
21983 it->descent = it->phys_descent = height - it->ascent;
21984 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
21986 take_vertical_position_into_account (it);
21989 /* Calculate line-height and line-spacing properties.
21990 An integer value specifies explicit pixel value.
21991 A float value specifies relative value to current face height.
21992 A cons (float . face-name) specifies relative value to
21993 height of specified face font.
21995 Returns height in pixels, or nil. */
21998 static Lisp_Object
21999 calc_line_height_property (struct it *it, Lisp_Object val, struct font *font,
22000 int boff, int override)
22002 Lisp_Object face_name = Qnil;
22003 int ascent, descent, height;
22005 if (NILP (val) || INTEGERP (val) || (override && EQ (val, Qt)))
22006 return val;
22008 if (CONSP (val))
22010 face_name = XCAR (val);
22011 val = XCDR (val);
22012 if (!NUMBERP (val))
22013 val = make_number (1);
22014 if (NILP (face_name))
22016 height = it->ascent + it->descent;
22017 goto scale;
22021 if (NILP (face_name))
22023 font = FRAME_FONT (it->f);
22024 boff = FRAME_BASELINE_OFFSET (it->f);
22026 else if (EQ (face_name, Qt))
22028 override = 0;
22030 else
22032 int face_id;
22033 struct face *face;
22035 face_id = lookup_named_face (it->f, face_name, 0);
22036 if (face_id < 0)
22037 return make_number (-1);
22039 face = FACE_FROM_ID (it->f, face_id);
22040 font = face->font;
22041 if (font == NULL)
22042 return make_number (-1);
22043 boff = font->baseline_offset;
22044 if (font->vertical_centering)
22045 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
22048 ascent = FONT_BASE (font) + boff;
22049 descent = FONT_DESCENT (font) - boff;
22051 if (override)
22053 it->override_ascent = ascent;
22054 it->override_descent = descent;
22055 it->override_boff = boff;
22058 height = ascent + descent;
22060 scale:
22061 if (FLOATP (val))
22062 height = (int)(XFLOAT_DATA (val) * height);
22063 else if (INTEGERP (val))
22064 height *= XINT (val);
22066 return make_number (height);
22070 /* RIF:
22071 Produce glyphs/get display metrics for the display element IT is
22072 loaded with. See the description of struct it in dispextern.h
22073 for an overview of struct it. */
22075 void
22076 x_produce_glyphs (struct it *it)
22078 int extra_line_spacing = it->extra_line_spacing;
22080 it->glyph_not_available_p = 0;
22082 if (it->what == IT_CHARACTER)
22084 XChar2b char2b;
22085 struct font *font;
22086 struct face *face = FACE_FROM_ID (it->f, it->face_id);
22087 struct font_metrics *pcm;
22088 int font_not_found_p;
22089 int boff; /* baseline offset */
22090 /* We may change it->multibyte_p upon unibyte<->multibyte
22091 conversion. So, save the current value now and restore it
22092 later.
22094 Note: It seems that we don't have to record multibyte_p in
22095 struct glyph because the character code itself tells whether
22096 or not the character is multibyte. Thus, in the future, we
22097 must consider eliminating the field `multibyte_p' in the
22098 struct glyph. */
22099 int saved_multibyte_p = it->multibyte_p;
22101 /* Maybe translate single-byte characters to multibyte, or the
22102 other way. */
22103 it->char_to_display = it->c;
22104 if (!ASCII_BYTE_P (it->c)
22105 && ! it->multibyte_p)
22107 if (SINGLE_BYTE_CHAR_P (it->c)
22108 && unibyte_display_via_language_environment)
22110 struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte);
22112 /* get_next_display_element assures that this decoding
22113 never fails. */
22114 it->char_to_display = DECODE_CHAR (unibyte, it->c);
22115 it->multibyte_p = 1;
22116 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display,
22117 -1, Qnil);
22118 face = FACE_FROM_ID (it->f, it->face_id);
22122 /* Get font to use. Encode IT->char_to_display. */
22123 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
22124 &char2b, it->multibyte_p, 0);
22125 font = face->font;
22127 font_not_found_p = font == NULL;
22128 if (font_not_found_p)
22130 /* When no suitable font found, display an empty box based
22131 on the metrics of the font of the default face (or what
22132 remapped). */
22133 struct face *no_font_face
22134 = FACE_FROM_ID (it->f,
22135 NILP (Vface_remapping_alist) ? DEFAULT_FACE_ID
22136 : lookup_basic_face (it->f, DEFAULT_FACE_ID));
22137 font = no_font_face->font;
22138 boff = font->baseline_offset;
22140 else
22142 boff = font->baseline_offset;
22143 if (font->vertical_centering)
22144 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
22147 if (it->char_to_display >= ' '
22148 && (!it->multibyte_p || it->char_to_display < 128))
22150 /* Either unibyte or ASCII. */
22151 int stretched_p;
22153 it->nglyphs = 1;
22155 pcm = get_per_char_metric (it->f, font, &char2b);
22157 if (it->override_ascent >= 0)
22159 it->ascent = it->override_ascent;
22160 it->descent = it->override_descent;
22161 boff = it->override_boff;
22163 else
22165 it->ascent = FONT_BASE (font) + boff;
22166 it->descent = FONT_DESCENT (font) - boff;
22169 if (pcm)
22171 it->phys_ascent = pcm->ascent + boff;
22172 it->phys_descent = pcm->descent - boff;
22173 it->pixel_width = pcm->width;
22175 else
22177 it->glyph_not_available_p = 1;
22178 it->phys_ascent = it->ascent;
22179 it->phys_descent = it->descent;
22180 it->pixel_width = FONT_WIDTH (font);
22183 if (it->constrain_row_ascent_descent_p)
22185 if (it->descent > it->max_descent)
22187 it->ascent += it->descent - it->max_descent;
22188 it->descent = it->max_descent;
22190 if (it->ascent > it->max_ascent)
22192 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
22193 it->ascent = it->max_ascent;
22195 it->phys_ascent = min (it->phys_ascent, it->ascent);
22196 it->phys_descent = min (it->phys_descent, it->descent);
22197 extra_line_spacing = 0;
22200 /* If this is a space inside a region of text with
22201 `space-width' property, change its width. */
22202 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
22203 if (stretched_p)
22204 it->pixel_width *= XFLOATINT (it->space_width);
22206 /* If face has a box, add the box thickness to the character
22207 height. If character has a box line to the left and/or
22208 right, add the box line width to the character's width. */
22209 if (face->box != FACE_NO_BOX)
22211 int thick = face->box_line_width;
22213 if (thick > 0)
22215 it->ascent += thick;
22216 it->descent += thick;
22218 else
22219 thick = -thick;
22221 if (it->start_of_box_run_p)
22222 it->pixel_width += thick;
22223 if (it->end_of_box_run_p)
22224 it->pixel_width += thick;
22227 /* If face has an overline, add the height of the overline
22228 (1 pixel) and a 1 pixel margin to the character height. */
22229 if (face->overline_p)
22230 it->ascent += overline_margin;
22232 if (it->constrain_row_ascent_descent_p)
22234 if (it->ascent > it->max_ascent)
22235 it->ascent = it->max_ascent;
22236 if (it->descent > it->max_descent)
22237 it->descent = it->max_descent;
22240 take_vertical_position_into_account (it);
22242 /* If we have to actually produce glyphs, do it. */
22243 if (it->glyph_row)
22245 if (stretched_p)
22247 /* Translate a space with a `space-width' property
22248 into a stretch glyph. */
22249 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
22250 / FONT_HEIGHT (font));
22251 append_stretch_glyph (it, it->object, it->pixel_width,
22252 it->ascent + it->descent, ascent);
22254 else
22255 append_glyph (it);
22257 /* If characters with lbearing or rbearing are displayed
22258 in this line, record that fact in a flag of the
22259 glyph row. This is used to optimize X output code. */
22260 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
22261 it->glyph_row->contains_overlapping_glyphs_p = 1;
22263 if (! stretched_p && it->pixel_width == 0)
22264 /* We assure that all visible glyphs have at least 1-pixel
22265 width. */
22266 it->pixel_width = 1;
22268 else if (it->char_to_display == '\n')
22270 /* A newline has no width, but we need the height of the
22271 line. But if previous part of the line sets a height,
22272 don't increase that height */
22274 Lisp_Object height;
22275 Lisp_Object total_height = Qnil;
22277 it->override_ascent = -1;
22278 it->pixel_width = 0;
22279 it->nglyphs = 0;
22281 height = get_it_property (it, Qline_height);
22282 /* Split (line-height total-height) list */
22283 if (CONSP (height)
22284 && CONSP (XCDR (height))
22285 && NILP (XCDR (XCDR (height))))
22287 total_height = XCAR (XCDR (height));
22288 height = XCAR (height);
22290 height = calc_line_height_property (it, height, font, boff, 1);
22292 if (it->override_ascent >= 0)
22294 it->ascent = it->override_ascent;
22295 it->descent = it->override_descent;
22296 boff = it->override_boff;
22298 else
22300 it->ascent = FONT_BASE (font) + boff;
22301 it->descent = FONT_DESCENT (font) - boff;
22304 if (EQ (height, Qt))
22306 if (it->descent > it->max_descent)
22308 it->ascent += it->descent - it->max_descent;
22309 it->descent = it->max_descent;
22311 if (it->ascent > it->max_ascent)
22313 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
22314 it->ascent = it->max_ascent;
22316 it->phys_ascent = min (it->phys_ascent, it->ascent);
22317 it->phys_descent = min (it->phys_descent, it->descent);
22318 it->constrain_row_ascent_descent_p = 1;
22319 extra_line_spacing = 0;
22321 else
22323 Lisp_Object spacing;
22325 it->phys_ascent = it->ascent;
22326 it->phys_descent = it->descent;
22328 if ((it->max_ascent > 0 || it->max_descent > 0)
22329 && face->box != FACE_NO_BOX
22330 && face->box_line_width > 0)
22332 it->ascent += face->box_line_width;
22333 it->descent += face->box_line_width;
22335 if (!NILP (height)
22336 && XINT (height) > it->ascent + it->descent)
22337 it->ascent = XINT (height) - it->descent;
22339 if (!NILP (total_height))
22340 spacing = calc_line_height_property (it, total_height, font, boff, 0);
22341 else
22343 spacing = get_it_property (it, Qline_spacing);
22344 spacing = calc_line_height_property (it, spacing, font, boff, 0);
22346 if (INTEGERP (spacing))
22348 extra_line_spacing = XINT (spacing);
22349 if (!NILP (total_height))
22350 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
22354 else if (it->char_to_display == '\t')
22356 if (font->space_width > 0)
22358 int tab_width = it->tab_width * font->space_width;
22359 int x = it->current_x + it->continuation_lines_width;
22360 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
22362 /* If the distance from the current position to the next tab
22363 stop is less than a space character width, use the
22364 tab stop after that. */
22365 if (next_tab_x - x < font->space_width)
22366 next_tab_x += tab_width;
22368 it->pixel_width = next_tab_x - x;
22369 it->nglyphs = 1;
22370 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
22371 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
22373 if (it->glyph_row)
22375 append_stretch_glyph (it, it->object, it->pixel_width,
22376 it->ascent + it->descent, it->ascent);
22379 else
22381 it->pixel_width = 0;
22382 it->nglyphs = 1;
22385 else
22387 /* A multi-byte character. Assume that the display width of the
22388 character is the width of the character multiplied by the
22389 width of the font. */
22391 /* If we found a font, this font should give us the right
22392 metrics. If we didn't find a font, use the frame's
22393 default font and calculate the width of the character by
22394 multiplying the width of font by the width of the
22395 character. */
22397 pcm = get_per_char_metric (it->f, font, &char2b);
22399 if (font_not_found_p || !pcm)
22401 int char_width = CHAR_WIDTH (it->char_to_display);
22403 if (char_width == 0)
22404 /* This is a non spacing character. But, as we are
22405 going to display an empty box, the box must occupy
22406 at least one column. */
22407 char_width = 1;
22408 it->glyph_not_available_p = 1;
22409 it->pixel_width = font->space_width * char_width;
22410 it->phys_ascent = FONT_BASE (font) + boff;
22411 it->phys_descent = FONT_DESCENT (font) - boff;
22413 else
22415 it->pixel_width = pcm->width;
22416 it->phys_ascent = pcm->ascent + boff;
22417 it->phys_descent = pcm->descent - boff;
22418 if (it->glyph_row
22419 && (pcm->lbearing < 0
22420 || pcm->rbearing > pcm->width))
22421 it->glyph_row->contains_overlapping_glyphs_p = 1;
22423 it->nglyphs = 1;
22424 it->ascent = FONT_BASE (font) + boff;
22425 it->descent = FONT_DESCENT (font) - boff;
22426 if (face->box != FACE_NO_BOX)
22428 int thick = face->box_line_width;
22430 if (thick > 0)
22432 it->ascent += thick;
22433 it->descent += thick;
22435 else
22436 thick = - thick;
22438 if (it->start_of_box_run_p)
22439 it->pixel_width += thick;
22440 if (it->end_of_box_run_p)
22441 it->pixel_width += thick;
22444 /* If face has an overline, add the height of the overline
22445 (1 pixel) and a 1 pixel margin to the character height. */
22446 if (face->overline_p)
22447 it->ascent += overline_margin;
22449 take_vertical_position_into_account (it);
22451 if (it->ascent < 0)
22452 it->ascent = 0;
22453 if (it->descent < 0)
22454 it->descent = 0;
22456 if (it->glyph_row)
22457 append_glyph (it);
22458 if (it->pixel_width == 0)
22459 /* We assure that all visible glyphs have at least 1-pixel
22460 width. */
22461 it->pixel_width = 1;
22463 it->multibyte_p = saved_multibyte_p;
22465 else if (it->what == IT_COMPOSITION && it->cmp_it.ch < 0)
22467 /* A static composition.
22469 Note: A composition is represented as one glyph in the
22470 glyph matrix. There are no padding glyphs.
22472 Important note: pixel_width, ascent, and descent are the
22473 values of what is drawn by draw_glyphs (i.e. the values of
22474 the overall glyphs composed). */
22475 struct face *face = FACE_FROM_ID (it->f, it->face_id);
22476 int boff; /* baseline offset */
22477 struct composition *cmp = composition_table[it->cmp_it.id];
22478 int glyph_len = cmp->glyph_len;
22479 struct font *font = face->font;
22481 it->nglyphs = 1;
22483 /* If we have not yet calculated pixel size data of glyphs of
22484 the composition for the current face font, calculate them
22485 now. Theoretically, we have to check all fonts for the
22486 glyphs, but that requires much time and memory space. So,
22487 here we check only the font of the first glyph. This may
22488 lead to incorrect display, but it's very rare, and C-l
22489 (recenter-top-bottom) can correct the display anyway. */
22490 if (! cmp->font || cmp->font != font)
22492 /* Ascent and descent of the font of the first character
22493 of this composition (adjusted by baseline offset).
22494 Ascent and descent of overall glyphs should not be less
22495 than these, respectively. */
22496 int font_ascent, font_descent, font_height;
22497 /* Bounding box of the overall glyphs. */
22498 int leftmost, rightmost, lowest, highest;
22499 int lbearing, rbearing;
22500 int i, width, ascent, descent;
22501 int left_padded = 0, right_padded = 0;
22502 int c;
22503 XChar2b char2b;
22504 struct font_metrics *pcm;
22505 int font_not_found_p;
22506 int pos;
22508 for (glyph_len = cmp->glyph_len; glyph_len > 0; glyph_len--)
22509 if ((c = COMPOSITION_GLYPH (cmp, glyph_len - 1)) != '\t')
22510 break;
22511 if (glyph_len < cmp->glyph_len)
22512 right_padded = 1;
22513 for (i = 0; i < glyph_len; i++)
22515 if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
22516 break;
22517 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
22519 if (i > 0)
22520 left_padded = 1;
22522 pos = (STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
22523 : IT_CHARPOS (*it));
22524 /* If no suitable font is found, use the default font. */
22525 font_not_found_p = font == NULL;
22526 if (font_not_found_p)
22528 face = face->ascii_face;
22529 font = face->font;
22531 boff = font->baseline_offset;
22532 if (font->vertical_centering)
22533 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
22534 font_ascent = FONT_BASE (font) + boff;
22535 font_descent = FONT_DESCENT (font) - boff;
22536 font_height = FONT_HEIGHT (font);
22538 cmp->font = (void *) font;
22540 pcm = NULL;
22541 if (! font_not_found_p)
22543 get_char_face_and_encoding (it->f, c, it->face_id,
22544 &char2b, it->multibyte_p, 0);
22545 pcm = get_per_char_metric (it->f, font, &char2b);
22548 /* Initialize the bounding box. */
22549 if (pcm)
22551 width = pcm->width;
22552 ascent = pcm->ascent;
22553 descent = pcm->descent;
22554 lbearing = pcm->lbearing;
22555 rbearing = pcm->rbearing;
22557 else
22559 width = FONT_WIDTH (font);
22560 ascent = FONT_BASE (font);
22561 descent = FONT_DESCENT (font);
22562 lbearing = 0;
22563 rbearing = width;
22566 rightmost = width;
22567 leftmost = 0;
22568 lowest = - descent + boff;
22569 highest = ascent + boff;
22571 if (! font_not_found_p
22572 && font->default_ascent
22573 && CHAR_TABLE_P (Vuse_default_ascent)
22574 && !NILP (Faref (Vuse_default_ascent,
22575 make_number (it->char_to_display))))
22576 highest = font->default_ascent + boff;
22578 /* Draw the first glyph at the normal position. It may be
22579 shifted to right later if some other glyphs are drawn
22580 at the left. */
22581 cmp->offsets[i * 2] = 0;
22582 cmp->offsets[i * 2 + 1] = boff;
22583 cmp->lbearing = lbearing;
22584 cmp->rbearing = rbearing;
22586 /* Set cmp->offsets for the remaining glyphs. */
22587 for (i++; i < glyph_len; i++)
22589 int left, right, btm, top;
22590 int ch = COMPOSITION_GLYPH (cmp, i);
22591 int face_id;
22592 struct face *this_face;
22593 int this_boff;
22595 if (ch == '\t')
22596 ch = ' ';
22597 face_id = FACE_FOR_CHAR (it->f, face, ch, pos, it->string);
22598 this_face = FACE_FROM_ID (it->f, face_id);
22599 font = this_face->font;
22601 if (font == NULL)
22602 pcm = NULL;
22603 else
22605 this_boff = font->baseline_offset;
22606 if (font->vertical_centering)
22607 this_boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
22608 get_char_face_and_encoding (it->f, ch, face_id,
22609 &char2b, it->multibyte_p, 0);
22610 pcm = get_per_char_metric (it->f, font, &char2b);
22612 if (! pcm)
22613 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
22614 else
22616 width = pcm->width;
22617 ascent = pcm->ascent;
22618 descent = pcm->descent;
22619 lbearing = pcm->lbearing;
22620 rbearing = pcm->rbearing;
22621 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
22623 /* Relative composition with or without
22624 alternate chars. */
22625 left = (leftmost + rightmost - width) / 2;
22626 btm = - descent + boff;
22627 if (font->relative_compose
22628 && (! CHAR_TABLE_P (Vignore_relative_composition)
22629 || NILP (Faref (Vignore_relative_composition,
22630 make_number (ch)))))
22633 if (- descent >= font->relative_compose)
22634 /* One extra pixel between two glyphs. */
22635 btm = highest + 1;
22636 else if (ascent <= 0)
22637 /* One extra pixel between two glyphs. */
22638 btm = lowest - 1 - ascent - descent;
22641 else
22643 /* A composition rule is specified by an integer
22644 value that encodes global and new reference
22645 points (GREF and NREF). GREF and NREF are
22646 specified by numbers as below:
22648 0---1---2 -- ascent
22652 9--10--11 -- center
22654 ---3---4---5--- baseline
22656 6---7---8 -- descent
22658 int rule = COMPOSITION_RULE (cmp, i);
22659 int gref, nref, grefx, grefy, nrefx, nrefy, xoff, yoff;
22661 COMPOSITION_DECODE_RULE (rule, gref, nref, xoff, yoff);
22662 grefx = gref % 3, nrefx = nref % 3;
22663 grefy = gref / 3, nrefy = nref / 3;
22664 if (xoff)
22665 xoff = font_height * (xoff - 128) / 256;
22666 if (yoff)
22667 yoff = font_height * (yoff - 128) / 256;
22669 left = (leftmost
22670 + grefx * (rightmost - leftmost) / 2
22671 - nrefx * width / 2
22672 + xoff);
22674 btm = ((grefy == 0 ? highest
22675 : grefy == 1 ? 0
22676 : grefy == 2 ? lowest
22677 : (highest + lowest) / 2)
22678 - (nrefy == 0 ? ascent + descent
22679 : nrefy == 1 ? descent - boff
22680 : nrefy == 2 ? 0
22681 : (ascent + descent) / 2)
22682 + yoff);
22685 cmp->offsets[i * 2] = left;
22686 cmp->offsets[i * 2 + 1] = btm + descent;
22688 /* Update the bounding box of the overall glyphs. */
22689 if (width > 0)
22691 right = left + width;
22692 if (left < leftmost)
22693 leftmost = left;
22694 if (right > rightmost)
22695 rightmost = right;
22697 top = btm + descent + ascent;
22698 if (top > highest)
22699 highest = top;
22700 if (btm < lowest)
22701 lowest = btm;
22703 if (cmp->lbearing > left + lbearing)
22704 cmp->lbearing = left + lbearing;
22705 if (cmp->rbearing < left + rbearing)
22706 cmp->rbearing = left + rbearing;
22710 /* If there are glyphs whose x-offsets are negative,
22711 shift all glyphs to the right and make all x-offsets
22712 non-negative. */
22713 if (leftmost < 0)
22715 for (i = 0; i < cmp->glyph_len; i++)
22716 cmp->offsets[i * 2] -= leftmost;
22717 rightmost -= leftmost;
22718 cmp->lbearing -= leftmost;
22719 cmp->rbearing -= leftmost;
22722 if (left_padded && cmp->lbearing < 0)
22724 for (i = 0; i < cmp->glyph_len; i++)
22725 cmp->offsets[i * 2] -= cmp->lbearing;
22726 rightmost -= cmp->lbearing;
22727 cmp->rbearing -= cmp->lbearing;
22728 cmp->lbearing = 0;
22730 if (right_padded && rightmost < cmp->rbearing)
22732 rightmost = cmp->rbearing;
22735 cmp->pixel_width = rightmost;
22736 cmp->ascent = highest;
22737 cmp->descent = - lowest;
22738 if (cmp->ascent < font_ascent)
22739 cmp->ascent = font_ascent;
22740 if (cmp->descent < font_descent)
22741 cmp->descent = font_descent;
22744 if (it->glyph_row
22745 && (cmp->lbearing < 0
22746 || cmp->rbearing > cmp->pixel_width))
22747 it->glyph_row->contains_overlapping_glyphs_p = 1;
22749 it->pixel_width = cmp->pixel_width;
22750 it->ascent = it->phys_ascent = cmp->ascent;
22751 it->descent = it->phys_descent = cmp->descent;
22752 if (face->box != FACE_NO_BOX)
22754 int thick = face->box_line_width;
22756 if (thick > 0)
22758 it->ascent += thick;
22759 it->descent += thick;
22761 else
22762 thick = - thick;
22764 if (it->start_of_box_run_p)
22765 it->pixel_width += thick;
22766 if (it->end_of_box_run_p)
22767 it->pixel_width += thick;
22770 /* If face has an overline, add the height of the overline
22771 (1 pixel) and a 1 pixel margin to the character height. */
22772 if (face->overline_p)
22773 it->ascent += overline_margin;
22775 take_vertical_position_into_account (it);
22776 if (it->ascent < 0)
22777 it->ascent = 0;
22778 if (it->descent < 0)
22779 it->descent = 0;
22781 if (it->glyph_row)
22782 append_composite_glyph (it);
22784 else if (it->what == IT_COMPOSITION)
22786 /* A dynamic (automatic) composition. */
22787 struct face *face = FACE_FROM_ID (it->f, it->face_id);
22788 Lisp_Object gstring;
22789 struct font_metrics metrics;
22791 gstring = composition_gstring_from_id (it->cmp_it.id);
22792 it->pixel_width
22793 = composition_gstring_width (gstring, it->cmp_it.from, it->cmp_it.to,
22794 &metrics);
22795 if (it->glyph_row
22796 && (metrics.lbearing < 0 || metrics.rbearing > metrics.width))
22797 it->glyph_row->contains_overlapping_glyphs_p = 1;
22798 it->ascent = it->phys_ascent = metrics.ascent;
22799 it->descent = it->phys_descent = metrics.descent;
22800 if (face->box != FACE_NO_BOX)
22802 int thick = face->box_line_width;
22804 if (thick > 0)
22806 it->ascent += thick;
22807 it->descent += thick;
22809 else
22810 thick = - thick;
22812 if (it->start_of_box_run_p)
22813 it->pixel_width += thick;
22814 if (it->end_of_box_run_p)
22815 it->pixel_width += thick;
22817 /* If face has an overline, add the height of the overline
22818 (1 pixel) and a 1 pixel margin to the character height. */
22819 if (face->overline_p)
22820 it->ascent += overline_margin;
22821 take_vertical_position_into_account (it);
22822 if (it->ascent < 0)
22823 it->ascent = 0;
22824 if (it->descent < 0)
22825 it->descent = 0;
22827 if (it->glyph_row)
22828 append_composite_glyph (it);
22830 else if (it->what == IT_IMAGE)
22831 produce_image_glyph (it);
22832 else if (it->what == IT_STRETCH)
22833 produce_stretch_glyph (it);
22835 /* Accumulate dimensions. Note: can't assume that it->descent > 0
22836 because this isn't true for images with `:ascent 100'. */
22837 xassert (it->ascent >= 0 && it->descent >= 0);
22838 if (it->area == TEXT_AREA)
22839 it->current_x += it->pixel_width;
22841 if (extra_line_spacing > 0)
22843 it->descent += extra_line_spacing;
22844 if (extra_line_spacing > it->max_extra_line_spacing)
22845 it->max_extra_line_spacing = extra_line_spacing;
22848 it->max_ascent = max (it->max_ascent, it->ascent);
22849 it->max_descent = max (it->max_descent, it->descent);
22850 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
22851 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
22854 /* EXPORT for RIF:
22855 Output LEN glyphs starting at START at the nominal cursor position.
22856 Advance the nominal cursor over the text. The global variable
22857 updated_window contains the window being updated, updated_row is
22858 the glyph row being updated, and updated_area is the area of that
22859 row being updated. */
22861 void
22862 x_write_glyphs (struct glyph *start, int len)
22864 int x, hpos;
22866 xassert (updated_window && updated_row);
22867 BLOCK_INPUT;
22869 /* Write glyphs. */
22871 hpos = start - updated_row->glyphs[updated_area];
22872 x = draw_glyphs (updated_window, output_cursor.x,
22873 updated_row, updated_area,
22874 hpos, hpos + len,
22875 DRAW_NORMAL_TEXT, 0);
22877 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
22878 if (updated_area == TEXT_AREA
22879 && updated_window->phys_cursor_on_p
22880 && updated_window->phys_cursor.vpos == output_cursor.vpos
22881 && updated_window->phys_cursor.hpos >= hpos
22882 && updated_window->phys_cursor.hpos < hpos + len)
22883 updated_window->phys_cursor_on_p = 0;
22885 UNBLOCK_INPUT;
22887 /* Advance the output cursor. */
22888 output_cursor.hpos += len;
22889 output_cursor.x = x;
22893 /* EXPORT for RIF:
22894 Insert LEN glyphs from START at the nominal cursor position. */
22896 void
22897 x_insert_glyphs (struct glyph *start, int len)
22899 struct frame *f;
22900 struct window *w;
22901 int line_height, shift_by_width, shifted_region_width;
22902 struct glyph_row *row;
22903 struct glyph *glyph;
22904 int frame_x, frame_y;
22905 EMACS_INT hpos;
22907 xassert (updated_window && updated_row);
22908 BLOCK_INPUT;
22909 w = updated_window;
22910 f = XFRAME (WINDOW_FRAME (w));
22912 /* Get the height of the line we are in. */
22913 row = updated_row;
22914 line_height = row->height;
22916 /* Get the width of the glyphs to insert. */
22917 shift_by_width = 0;
22918 for (glyph = start; glyph < start + len; ++glyph)
22919 shift_by_width += glyph->pixel_width;
22921 /* Get the width of the region to shift right. */
22922 shifted_region_width = (window_box_width (w, updated_area)
22923 - output_cursor.x
22924 - shift_by_width);
22926 /* Shift right. */
22927 frame_x = window_box_left (w, updated_area) + output_cursor.x;
22928 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
22930 FRAME_RIF (f)->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
22931 line_height, shift_by_width);
22933 /* Write the glyphs. */
22934 hpos = start - row->glyphs[updated_area];
22935 draw_glyphs (w, output_cursor.x, row, updated_area,
22936 hpos, hpos + len,
22937 DRAW_NORMAL_TEXT, 0);
22939 /* Advance the output cursor. */
22940 output_cursor.hpos += len;
22941 output_cursor.x += shift_by_width;
22942 UNBLOCK_INPUT;
22946 /* EXPORT for RIF:
22947 Erase the current text line from the nominal cursor position
22948 (inclusive) to pixel column TO_X (exclusive). The idea is that
22949 everything from TO_X onward is already erased.
22951 TO_X is a pixel position relative to updated_area of
22952 updated_window. TO_X == -1 means clear to the end of this area. */
22954 void
22955 x_clear_end_of_line (int to_x)
22957 struct frame *f;
22958 struct window *w = updated_window;
22959 int max_x, min_y, max_y;
22960 int from_x, from_y, to_y;
22962 xassert (updated_window && updated_row);
22963 f = XFRAME (w->frame);
22965 if (updated_row->full_width_p)
22966 max_x = WINDOW_TOTAL_WIDTH (w);
22967 else
22968 max_x = window_box_width (w, updated_area);
22969 max_y = window_text_bottom_y (w);
22971 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
22972 of window. For TO_X > 0, truncate to end of drawing area. */
22973 if (to_x == 0)
22974 return;
22975 else if (to_x < 0)
22976 to_x = max_x;
22977 else
22978 to_x = min (to_x, max_x);
22980 to_y = min (max_y, output_cursor.y + updated_row->height);
22982 /* Notice if the cursor will be cleared by this operation. */
22983 if (!updated_row->full_width_p)
22984 notice_overwritten_cursor (w, updated_area,
22985 output_cursor.x, -1,
22986 updated_row->y,
22987 MATRIX_ROW_BOTTOM_Y (updated_row));
22989 from_x = output_cursor.x;
22991 /* Translate to frame coordinates. */
22992 if (updated_row->full_width_p)
22994 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
22995 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
22997 else
22999 int area_left = window_box_left (w, updated_area);
23000 from_x += area_left;
23001 to_x += area_left;
23004 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
23005 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
23006 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
23008 /* Prevent inadvertently clearing to end of the X window. */
23009 if (to_x > from_x && to_y > from_y)
23011 BLOCK_INPUT;
23012 FRAME_RIF (f)->clear_frame_area (f, from_x, from_y,
23013 to_x - from_x, to_y - from_y);
23014 UNBLOCK_INPUT;
23018 #endif /* HAVE_WINDOW_SYSTEM */
23022 /***********************************************************************
23023 Cursor types
23024 ***********************************************************************/
23026 /* Value is the internal representation of the specified cursor type
23027 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
23028 of the bar cursor. */
23030 static enum text_cursor_kinds
23031 get_specified_cursor_type (Lisp_Object arg, int *width)
23033 enum text_cursor_kinds type;
23035 if (NILP (arg))
23036 return NO_CURSOR;
23038 if (EQ (arg, Qbox))
23039 return FILLED_BOX_CURSOR;
23041 if (EQ (arg, Qhollow))
23042 return HOLLOW_BOX_CURSOR;
23044 if (EQ (arg, Qbar))
23046 *width = 2;
23047 return BAR_CURSOR;
23050 if (CONSP (arg)
23051 && EQ (XCAR (arg), Qbar)
23052 && INTEGERP (XCDR (arg))
23053 && XINT (XCDR (arg)) >= 0)
23055 *width = XINT (XCDR (arg));
23056 return BAR_CURSOR;
23059 if (EQ (arg, Qhbar))
23061 *width = 2;
23062 return HBAR_CURSOR;
23065 if (CONSP (arg)
23066 && EQ (XCAR (arg), Qhbar)
23067 && INTEGERP (XCDR (arg))
23068 && XINT (XCDR (arg)) >= 0)
23070 *width = XINT (XCDR (arg));
23071 return HBAR_CURSOR;
23074 /* Treat anything unknown as "hollow box cursor".
23075 It was bad to signal an error; people have trouble fixing
23076 .Xdefaults with Emacs, when it has something bad in it. */
23077 type = HOLLOW_BOX_CURSOR;
23079 return type;
23082 /* Set the default cursor types for specified frame. */
23083 void
23084 set_frame_cursor_types (struct frame *f, Lisp_Object arg)
23086 int width;
23087 Lisp_Object tem;
23089 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
23090 FRAME_CURSOR_WIDTH (f) = width;
23092 /* By default, set up the blink-off state depending on the on-state. */
23094 tem = Fassoc (arg, Vblink_cursor_alist);
23095 if (!NILP (tem))
23097 FRAME_BLINK_OFF_CURSOR (f)
23098 = get_specified_cursor_type (XCDR (tem), &width);
23099 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
23101 else
23102 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
23106 /* Return the cursor we want to be displayed in window W. Return
23107 width of bar/hbar cursor through WIDTH arg. Return with
23108 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
23109 (i.e. if the `system caret' should track this cursor).
23111 In a mini-buffer window, we want the cursor only to appear if we
23112 are reading input from this window. For the selected window, we
23113 want the cursor type given by the frame parameter or buffer local
23114 setting of cursor-type. If explicitly marked off, draw no cursor.
23115 In all other cases, we want a hollow box cursor. */
23117 static enum text_cursor_kinds
23118 get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
23119 int *active_cursor)
23121 struct frame *f = XFRAME (w->frame);
23122 struct buffer *b = XBUFFER (w->buffer);
23123 int cursor_type = DEFAULT_CURSOR;
23124 Lisp_Object alt_cursor;
23125 int non_selected = 0;
23127 *active_cursor = 1;
23129 /* Echo area */
23130 if (cursor_in_echo_area
23131 && FRAME_HAS_MINIBUF_P (f)
23132 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
23134 if (w == XWINDOW (echo_area_window))
23136 if (EQ (b->cursor_type, Qt) || NILP (b->cursor_type))
23138 *width = FRAME_CURSOR_WIDTH (f);
23139 return FRAME_DESIRED_CURSOR (f);
23141 else
23142 return get_specified_cursor_type (b->cursor_type, width);
23145 *active_cursor = 0;
23146 non_selected = 1;
23149 /* Detect a nonselected window or nonselected frame. */
23150 else if (w != XWINDOW (f->selected_window)
23151 #ifdef HAVE_WINDOW_SYSTEM
23152 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame
23153 #endif
23156 *active_cursor = 0;
23158 if (MINI_WINDOW_P (w) && minibuf_level == 0)
23159 return NO_CURSOR;
23161 non_selected = 1;
23164 /* Never display a cursor in a window in which cursor-type is nil. */
23165 if (NILP (b->cursor_type))
23166 return NO_CURSOR;
23168 /* Get the normal cursor type for this window. */
23169 if (EQ (b->cursor_type, Qt))
23171 cursor_type = FRAME_DESIRED_CURSOR (f);
23172 *width = FRAME_CURSOR_WIDTH (f);
23174 else
23175 cursor_type = get_specified_cursor_type (b->cursor_type, width);
23177 /* Use cursor-in-non-selected-windows instead
23178 for non-selected window or frame. */
23179 if (non_selected)
23181 alt_cursor = b->cursor_in_non_selected_windows;
23182 if (!EQ (Qt, alt_cursor))
23183 return get_specified_cursor_type (alt_cursor, width);
23184 /* t means modify the normal cursor type. */
23185 if (cursor_type == FILLED_BOX_CURSOR)
23186 cursor_type = HOLLOW_BOX_CURSOR;
23187 else if (cursor_type == BAR_CURSOR && *width > 1)
23188 --*width;
23189 return cursor_type;
23192 /* Use normal cursor if not blinked off. */
23193 if (!w->cursor_off_p)
23195 #ifdef HAVE_WINDOW_SYSTEM
23196 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
23198 if (cursor_type == FILLED_BOX_CURSOR)
23200 /* Using a block cursor on large images can be very annoying.
23201 So use a hollow cursor for "large" images.
23202 If image is not transparent (no mask), also use hollow cursor. */
23203 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
23204 if (img != NULL && IMAGEP (img->spec))
23206 /* Arbitrarily, interpret "Large" as >32x32 and >NxN
23207 where N = size of default frame font size.
23208 This should cover most of the "tiny" icons people may use. */
23209 if (!img->mask
23210 || img->width > max (32, WINDOW_FRAME_COLUMN_WIDTH (w))
23211 || img->height > max (32, WINDOW_FRAME_LINE_HEIGHT (w)))
23212 cursor_type = HOLLOW_BOX_CURSOR;
23215 else if (cursor_type != NO_CURSOR)
23217 /* Display current only supports BOX and HOLLOW cursors for images.
23218 So for now, unconditionally use a HOLLOW cursor when cursor is
23219 not a solid box cursor. */
23220 cursor_type = HOLLOW_BOX_CURSOR;
23223 #endif
23224 return cursor_type;
23227 /* Cursor is blinked off, so determine how to "toggle" it. */
23229 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
23230 if ((alt_cursor = Fassoc (b->cursor_type, Vblink_cursor_alist), !NILP (alt_cursor)))
23231 return get_specified_cursor_type (XCDR (alt_cursor), width);
23233 /* Then see if frame has specified a specific blink off cursor type. */
23234 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
23236 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
23237 return FRAME_BLINK_OFF_CURSOR (f);
23240 #if 0
23241 /* Some people liked having a permanently visible blinking cursor,
23242 while others had very strong opinions against it. So it was
23243 decided to remove it. KFS 2003-09-03 */
23245 /* Finally perform built-in cursor blinking:
23246 filled box <-> hollow box
23247 wide [h]bar <-> narrow [h]bar
23248 narrow [h]bar <-> no cursor
23249 other type <-> no cursor */
23251 if (cursor_type == FILLED_BOX_CURSOR)
23252 return HOLLOW_BOX_CURSOR;
23254 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
23256 *width = 1;
23257 return cursor_type;
23259 #endif
23261 return NO_CURSOR;
23265 #ifdef HAVE_WINDOW_SYSTEM
23267 /* Notice when the text cursor of window W has been completely
23268 overwritten by a drawing operation that outputs glyphs in AREA
23269 starting at X0 and ending at X1 in the line starting at Y0 and
23270 ending at Y1. X coordinates are area-relative. X1 < 0 means all
23271 the rest of the line after X0 has been written. Y coordinates
23272 are window-relative. */
23274 static void
23275 notice_overwritten_cursor (struct window *w, enum glyph_row_area area,
23276 int x0, int x1, int y0, int y1)
23278 int cx0, cx1, cy0, cy1;
23279 struct glyph_row *row;
23281 if (!w->phys_cursor_on_p)
23282 return;
23283 if (area != TEXT_AREA)
23284 return;
23286 if (w->phys_cursor.vpos < 0
23287 || w->phys_cursor.vpos >= w->current_matrix->nrows
23288 || (row = w->current_matrix->rows + w->phys_cursor.vpos,
23289 !(row->enabled_p && row->displays_text_p)))
23290 return;
23292 if (row->cursor_in_fringe_p)
23294 row->cursor_in_fringe_p = 0;
23295 draw_fringe_bitmap (w, row, row->reversed_p);
23296 w->phys_cursor_on_p = 0;
23297 return;
23300 cx0 = w->phys_cursor.x;
23301 cx1 = cx0 + w->phys_cursor_width;
23302 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
23303 return;
23305 /* The cursor image will be completely removed from the
23306 screen if the output area intersects the cursor area in
23307 y-direction. When we draw in [y0 y1[, and some part of
23308 the cursor is at y < y0, that part must have been drawn
23309 before. When scrolling, the cursor is erased before
23310 actually scrolling, so we don't come here. When not
23311 scrolling, the rows above the old cursor row must have
23312 changed, and in this case these rows must have written
23313 over the cursor image.
23315 Likewise if part of the cursor is below y1, with the
23316 exception of the cursor being in the first blank row at
23317 the buffer and window end because update_text_area
23318 doesn't draw that row. (Except when it does, but
23319 that's handled in update_text_area.) */
23321 cy0 = w->phys_cursor.y;
23322 cy1 = cy0 + w->phys_cursor_height;
23323 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
23324 return;
23326 w->phys_cursor_on_p = 0;
23329 #endif /* HAVE_WINDOW_SYSTEM */
23332 /************************************************************************
23333 Mouse Face
23334 ************************************************************************/
23336 #ifdef HAVE_WINDOW_SYSTEM
23338 /* EXPORT for RIF:
23339 Fix the display of area AREA of overlapping row ROW in window W
23340 with respect to the overlapping part OVERLAPS. */
23342 void
23343 x_fix_overlapping_area (struct window *w, struct glyph_row *row,
23344 enum glyph_row_area area, int overlaps)
23346 int i, x;
23348 BLOCK_INPUT;
23350 x = 0;
23351 for (i = 0; i < row->used[area];)
23353 if (row->glyphs[area][i].overlaps_vertically_p)
23355 int start = i, start_x = x;
23359 x += row->glyphs[area][i].pixel_width;
23360 ++i;
23362 while (i < row->used[area]
23363 && row->glyphs[area][i].overlaps_vertically_p);
23365 draw_glyphs (w, start_x, row, area,
23366 start, i,
23367 DRAW_NORMAL_TEXT, overlaps);
23369 else
23371 x += row->glyphs[area][i].pixel_width;
23372 ++i;
23376 UNBLOCK_INPUT;
23380 /* EXPORT:
23381 Draw the cursor glyph of window W in glyph row ROW. See the
23382 comment of draw_glyphs for the meaning of HL. */
23384 void
23385 draw_phys_cursor_glyph (struct window *w, struct glyph_row *row,
23386 enum draw_glyphs_face hl)
23388 /* If cursor hpos is out of bounds, don't draw garbage. This can
23389 happen in mini-buffer windows when switching between echo area
23390 glyphs and mini-buffer. */
23391 if ((row->reversed_p
23392 ? (w->phys_cursor.hpos >= 0)
23393 : (w->phys_cursor.hpos < row->used[TEXT_AREA])))
23395 int on_p = w->phys_cursor_on_p;
23396 int x1;
23397 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
23398 w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
23399 hl, 0);
23400 w->phys_cursor_on_p = on_p;
23402 if (hl == DRAW_CURSOR)
23403 w->phys_cursor_width = x1 - w->phys_cursor.x;
23404 /* When we erase the cursor, and ROW is overlapped by other
23405 rows, make sure that these overlapping parts of other rows
23406 are redrawn. */
23407 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
23409 w->phys_cursor_width = x1 - w->phys_cursor.x;
23411 if (row > w->current_matrix->rows
23412 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
23413 x_fix_overlapping_area (w, row - 1, TEXT_AREA,
23414 OVERLAPS_ERASED_CURSOR);
23416 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
23417 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
23418 x_fix_overlapping_area (w, row + 1, TEXT_AREA,
23419 OVERLAPS_ERASED_CURSOR);
23425 /* EXPORT:
23426 Erase the image of a cursor of window W from the screen. */
23428 void
23429 erase_phys_cursor (struct window *w)
23431 struct frame *f = XFRAME (w->frame);
23432 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
23433 int hpos = w->phys_cursor.hpos;
23434 int vpos = w->phys_cursor.vpos;
23435 int mouse_face_here_p = 0;
23436 struct glyph_matrix *active_glyphs = w->current_matrix;
23437 struct glyph_row *cursor_row;
23438 struct glyph *cursor_glyph;
23439 enum draw_glyphs_face hl;
23441 /* No cursor displayed or row invalidated => nothing to do on the
23442 screen. */
23443 if (w->phys_cursor_type == NO_CURSOR)
23444 goto mark_cursor_off;
23446 /* VPOS >= active_glyphs->nrows means that window has been resized.
23447 Don't bother to erase the cursor. */
23448 if (vpos >= active_glyphs->nrows)
23449 goto mark_cursor_off;
23451 /* If row containing cursor is marked invalid, there is nothing we
23452 can do. */
23453 cursor_row = MATRIX_ROW (active_glyphs, vpos);
23454 if (!cursor_row->enabled_p)
23455 goto mark_cursor_off;
23457 /* If line spacing is > 0, old cursor may only be partially visible in
23458 window after split-window. So adjust visible height. */
23459 cursor_row->visible_height = min (cursor_row->visible_height,
23460 window_text_bottom_y (w) - cursor_row->y);
23462 /* If row is completely invisible, don't attempt to delete a cursor which
23463 isn't there. This can happen if cursor is at top of a window, and
23464 we switch to a buffer with a header line in that window. */
23465 if (cursor_row->visible_height <= 0)
23466 goto mark_cursor_off;
23468 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
23469 if (cursor_row->cursor_in_fringe_p)
23471 cursor_row->cursor_in_fringe_p = 0;
23472 draw_fringe_bitmap (w, cursor_row, cursor_row->reversed_p);
23473 goto mark_cursor_off;
23476 /* This can happen when the new row is shorter than the old one.
23477 In this case, either draw_glyphs or clear_end_of_line
23478 should have cleared the cursor. Note that we wouldn't be
23479 able to erase the cursor in this case because we don't have a
23480 cursor glyph at hand. */
23481 if ((cursor_row->reversed_p
23482 ? (w->phys_cursor.hpos < 0)
23483 : (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])))
23484 goto mark_cursor_off;
23486 /* If the cursor is in the mouse face area, redisplay that when
23487 we clear the cursor. */
23488 if (! NILP (dpyinfo->mouse_face_window)
23489 && w == XWINDOW (dpyinfo->mouse_face_window)
23490 && (vpos > dpyinfo->mouse_face_beg_row
23491 || (vpos == dpyinfo->mouse_face_beg_row
23492 && hpos >= dpyinfo->mouse_face_beg_col))
23493 && (vpos < dpyinfo->mouse_face_end_row
23494 || (vpos == dpyinfo->mouse_face_end_row
23495 && hpos < dpyinfo->mouse_face_end_col))
23496 /* Don't redraw the cursor's spot in mouse face if it is at the
23497 end of a line (on a newline). The cursor appears there, but
23498 mouse highlighting does not. */
23499 && cursor_row->used[TEXT_AREA] > hpos && hpos >= 0)
23500 mouse_face_here_p = 1;
23502 /* Maybe clear the display under the cursor. */
23503 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
23505 int x, y, left_x;
23506 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
23507 int width;
23509 cursor_glyph = get_phys_cursor_glyph (w);
23510 if (cursor_glyph == NULL)
23511 goto mark_cursor_off;
23513 width = cursor_glyph->pixel_width;
23514 left_x = window_box_left_offset (w, TEXT_AREA);
23515 x = w->phys_cursor.x;
23516 if (x < left_x)
23517 width -= left_x - x;
23518 width = min (width, window_box_width (w, TEXT_AREA) - x);
23519 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
23520 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, max (x, left_x));
23522 if (width > 0)
23523 FRAME_RIF (f)->clear_frame_area (f, x, y, width, cursor_row->visible_height);
23526 /* Erase the cursor by redrawing the character underneath it. */
23527 if (mouse_face_here_p)
23528 hl = DRAW_MOUSE_FACE;
23529 else
23530 hl = DRAW_NORMAL_TEXT;
23531 draw_phys_cursor_glyph (w, cursor_row, hl);
23533 mark_cursor_off:
23534 w->phys_cursor_on_p = 0;
23535 w->phys_cursor_type = NO_CURSOR;
23539 /* EXPORT:
23540 Display or clear cursor of window W. If ON is zero, clear the
23541 cursor. If it is non-zero, display the cursor. If ON is nonzero,
23542 where to put the cursor is specified by HPOS, VPOS, X and Y. */
23544 void
23545 display_and_set_cursor (struct window *w, int on,
23546 int hpos, int vpos, int x, int y)
23548 struct frame *f = XFRAME (w->frame);
23549 int new_cursor_type;
23550 int new_cursor_width;
23551 int active_cursor;
23552 struct glyph_row *glyph_row;
23553 struct glyph *glyph;
23555 /* This is pointless on invisible frames, and dangerous on garbaged
23556 windows and frames; in the latter case, the frame or window may
23557 be in the midst of changing its size, and x and y may be off the
23558 window. */
23559 if (! FRAME_VISIBLE_P (f)
23560 || FRAME_GARBAGED_P (f)
23561 || vpos >= w->current_matrix->nrows
23562 || hpos >= w->current_matrix->matrix_w)
23563 return;
23565 /* If cursor is off and we want it off, return quickly. */
23566 if (!on && !w->phys_cursor_on_p)
23567 return;
23569 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
23570 /* If cursor row is not enabled, we don't really know where to
23571 display the cursor. */
23572 if (!glyph_row->enabled_p)
23574 w->phys_cursor_on_p = 0;
23575 return;
23578 glyph = NULL;
23579 if (!glyph_row->exact_window_width_line_p
23580 || (0 <= hpos && hpos < glyph_row->used[TEXT_AREA]))
23581 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
23583 xassert (interrupt_input_blocked);
23585 /* Set new_cursor_type to the cursor we want to be displayed. */
23586 new_cursor_type = get_window_cursor_type (w, glyph,
23587 &new_cursor_width, &active_cursor);
23589 /* If cursor is currently being shown and we don't want it to be or
23590 it is in the wrong place, or the cursor type is not what we want,
23591 erase it. */
23592 if (w->phys_cursor_on_p
23593 && (!on
23594 || w->phys_cursor.x != x
23595 || w->phys_cursor.y != y
23596 || new_cursor_type != w->phys_cursor_type
23597 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
23598 && new_cursor_width != w->phys_cursor_width)))
23599 erase_phys_cursor (w);
23601 /* Don't check phys_cursor_on_p here because that flag is only set
23602 to zero in some cases where we know that the cursor has been
23603 completely erased, to avoid the extra work of erasing the cursor
23604 twice. In other words, phys_cursor_on_p can be 1 and the cursor
23605 still not be visible, or it has only been partly erased. */
23606 if (on)
23608 w->phys_cursor_ascent = glyph_row->ascent;
23609 w->phys_cursor_height = glyph_row->height;
23611 /* Set phys_cursor_.* before x_draw_.* is called because some
23612 of them may need the information. */
23613 w->phys_cursor.x = x;
23614 w->phys_cursor.y = glyph_row->y;
23615 w->phys_cursor.hpos = hpos;
23616 w->phys_cursor.vpos = vpos;
23619 FRAME_RIF (f)->draw_window_cursor (w, glyph_row, x, y,
23620 new_cursor_type, new_cursor_width,
23621 on, active_cursor);
23625 /* Switch the display of W's cursor on or off, according to the value
23626 of ON. */
23628 void
23629 update_window_cursor (struct window *w, int on)
23631 /* Don't update cursor in windows whose frame is in the process
23632 of being deleted. */
23633 if (w->current_matrix)
23635 BLOCK_INPUT;
23636 display_and_set_cursor (w, on, w->phys_cursor.hpos, w->phys_cursor.vpos,
23637 w->phys_cursor.x, w->phys_cursor.y);
23638 UNBLOCK_INPUT;
23643 /* Call update_window_cursor with parameter ON_P on all leaf windows
23644 in the window tree rooted at W. */
23646 static void
23647 update_cursor_in_window_tree (struct window *w, int on_p)
23649 while (w)
23651 if (!NILP (w->hchild))
23652 update_cursor_in_window_tree (XWINDOW (w->hchild), on_p);
23653 else if (!NILP (w->vchild))
23654 update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
23655 else
23656 update_window_cursor (w, on_p);
23658 w = NILP (w->next) ? 0 : XWINDOW (w->next);
23663 /* EXPORT:
23664 Display the cursor on window W, or clear it, according to ON_P.
23665 Don't change the cursor's position. */
23667 void
23668 x_update_cursor (struct frame *f, int on_p)
23670 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
23674 /* EXPORT:
23675 Clear the cursor of window W to background color, and mark the
23676 cursor as not shown. This is used when the text where the cursor
23677 is about to be rewritten. */
23679 void
23680 x_clear_cursor (struct window *w)
23682 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
23683 update_window_cursor (w, 0);
23687 /* EXPORT:
23688 Display the active region described by mouse_face_* according to DRAW. */
23690 void
23691 show_mouse_face (Display_Info *dpyinfo, enum draw_glyphs_face draw)
23693 struct window *w = XWINDOW (dpyinfo->mouse_face_window);
23694 struct frame *f = XFRAME (WINDOW_FRAME (w));
23696 if (/* If window is in the process of being destroyed, don't bother
23697 to do anything. */
23698 w->current_matrix != NULL
23699 /* Don't update mouse highlight if hidden */
23700 && (draw != DRAW_MOUSE_FACE || !dpyinfo->mouse_face_hidden)
23701 /* Recognize when we are called to operate on rows that don't exist
23702 anymore. This can happen when a window is split. */
23703 && dpyinfo->mouse_face_end_row < w->current_matrix->nrows)
23705 int phys_cursor_on_p = w->phys_cursor_on_p;
23706 struct glyph_row *row, *first, *last;
23708 first = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row);
23709 last = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row);
23711 for (row = first; row <= last && row->enabled_p; ++row)
23713 int start_hpos, end_hpos, start_x;
23715 /* For all but the first row, the highlight starts at column 0. */
23716 if (row == first)
23718 start_hpos = dpyinfo->mouse_face_beg_col;
23719 start_x = dpyinfo->mouse_face_beg_x;
23721 else
23723 start_hpos = 0;
23724 start_x = 0;
23727 if (row == last)
23728 end_hpos = dpyinfo->mouse_face_end_col;
23729 else
23731 end_hpos = row->used[TEXT_AREA];
23732 if (draw == DRAW_NORMAL_TEXT)
23733 row->fill_line_p = 1; /* Clear to end of line */
23736 if (end_hpos > start_hpos)
23738 draw_glyphs (w, start_x, row, TEXT_AREA,
23739 start_hpos, end_hpos,
23740 draw, 0);
23742 row->mouse_face_p
23743 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
23747 /* When we've written over the cursor, arrange for it to
23748 be displayed again. */
23749 if (phys_cursor_on_p && !w->phys_cursor_on_p)
23751 BLOCK_INPUT;
23752 display_and_set_cursor (w, 1,
23753 w->phys_cursor.hpos, w->phys_cursor.vpos,
23754 w->phys_cursor.x, w->phys_cursor.y);
23755 UNBLOCK_INPUT;
23759 /* Change the mouse cursor. */
23760 if (draw == DRAW_NORMAL_TEXT && !EQ (dpyinfo->mouse_face_window, f->tool_bar_window))
23761 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
23762 else if (draw == DRAW_MOUSE_FACE)
23763 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
23764 else
23765 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
23768 /* EXPORT:
23769 Clear out the mouse-highlighted active region.
23770 Redraw it un-highlighted first. Value is non-zero if mouse
23771 face was actually drawn unhighlighted. */
23774 clear_mouse_face (Display_Info *dpyinfo)
23776 int cleared = 0;
23778 if (!dpyinfo->mouse_face_hidden && !NILP (dpyinfo->mouse_face_window))
23780 show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT);
23781 cleared = 1;
23784 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
23785 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
23786 dpyinfo->mouse_face_window = Qnil;
23787 dpyinfo->mouse_face_overlay = Qnil;
23788 return cleared;
23792 /* EXPORT:
23793 Non-zero if physical cursor of window W is within mouse face. */
23796 cursor_in_mouse_face_p (struct window *w)
23798 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
23799 int in_mouse_face = 0;
23801 if (WINDOWP (dpyinfo->mouse_face_window)
23802 && XWINDOW (dpyinfo->mouse_face_window) == w)
23804 int hpos = w->phys_cursor.hpos;
23805 int vpos = w->phys_cursor.vpos;
23807 if (vpos >= dpyinfo->mouse_face_beg_row
23808 && vpos <= dpyinfo->mouse_face_end_row
23809 && (vpos > dpyinfo->mouse_face_beg_row
23810 || hpos >= dpyinfo->mouse_face_beg_col)
23811 && (vpos < dpyinfo->mouse_face_end_row
23812 || hpos < dpyinfo->mouse_face_end_col
23813 || dpyinfo->mouse_face_past_end))
23814 in_mouse_face = 1;
23817 return in_mouse_face;
23823 /* This function sets the mouse_face_* elements of DPYINFO, assuming
23824 the mouse cursor is on a glyph with buffer charpos MOUSE_CHARPOS in
23825 window WINDOW. START_CHARPOS and END_CHARPOS are buffer positions
23826 for the overlay or run of text properties specifying the mouse
23827 face. BEFORE_STRING and AFTER_STRING, if non-nil, are a
23828 before-string and after-string that must also be highlighted.
23829 DISPLAY_STRING, if non-nil, is a display string that may cover some
23830 or all of the highlighted text. */
23832 static void
23833 mouse_face_from_buffer_pos (Lisp_Object window,
23834 Display_Info *dpyinfo,
23835 EMACS_INT mouse_charpos,
23836 EMACS_INT start_charpos,
23837 EMACS_INT end_charpos,
23838 Lisp_Object before_string,
23839 Lisp_Object after_string,
23840 Lisp_Object display_string)
23842 struct window *w = XWINDOW (window);
23843 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
23844 struct glyph_row *row;
23845 struct glyph *glyph, *end;
23846 EMACS_INT ignore;
23847 int x;
23849 xassert (NILP (display_string) || STRINGP (display_string));
23850 xassert (NILP (before_string) || STRINGP (before_string));
23851 xassert (NILP (after_string) || STRINGP (after_string));
23853 /* Find the first highlighted glyph. */
23854 if (start_charpos < MATRIX_ROW_START_CHARPOS (first))
23856 dpyinfo->mouse_face_beg_col = 0;
23857 dpyinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (first, w->current_matrix);
23858 dpyinfo->mouse_face_beg_x = first->x;
23859 dpyinfo->mouse_face_beg_y = first->y;
23861 else
23863 row = row_containing_pos (w, start_charpos, first, NULL, 0);
23864 if (row == NULL)
23865 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
23867 /* If the before-string or display-string contains newlines,
23868 row_containing_pos skips to its last row. Move back. */
23869 if (!NILP (before_string) || !NILP (display_string))
23871 struct glyph_row *prev;
23872 while ((prev = row - 1, prev >= first)
23873 && MATRIX_ROW_END_CHARPOS (prev) == start_charpos
23874 && prev->used[TEXT_AREA] > 0)
23876 struct glyph *beg = prev->glyphs[TEXT_AREA];
23877 glyph = beg + prev->used[TEXT_AREA];
23878 while (--glyph >= beg && INTEGERP (glyph->object));
23879 if (glyph < beg
23880 || !(EQ (glyph->object, before_string)
23881 || EQ (glyph->object, display_string)))
23882 break;
23883 row = prev;
23887 glyph = row->glyphs[TEXT_AREA];
23888 end = glyph + row->used[TEXT_AREA];
23889 x = row->x;
23890 dpyinfo->mouse_face_beg_y = row->y;
23891 dpyinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (row, w->current_matrix);
23893 /* Skip truncation glyphs at the start of the glyph row. */
23894 if (row->displays_text_p)
23895 for (; glyph < end
23896 && INTEGERP (glyph->object)
23897 && glyph->charpos < 0;
23898 ++glyph)
23899 x += glyph->pixel_width;
23901 /* Scan the glyph row, stopping before BEFORE_STRING or
23902 DISPLAY_STRING or START_CHARPOS. */
23903 for (; glyph < end
23904 && !INTEGERP (glyph->object)
23905 && !EQ (glyph->object, before_string)
23906 && !EQ (glyph->object, display_string)
23907 && !(BUFFERP (glyph->object)
23908 && glyph->charpos >= start_charpos);
23909 ++glyph)
23910 x += glyph->pixel_width;
23912 dpyinfo->mouse_face_beg_x = x;
23913 dpyinfo->mouse_face_beg_col = glyph - row->glyphs[TEXT_AREA];
23916 /* Find the last highlighted glyph. */
23917 row = row_containing_pos (w, end_charpos, first, NULL, 0);
23918 if (row == NULL)
23920 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
23921 dpyinfo->mouse_face_past_end = 1;
23923 else if (!NILP (after_string))
23925 /* If the after-string has newlines, advance to its last row. */
23926 struct glyph_row *next;
23927 struct glyph_row *last
23928 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
23930 for (next = row + 1;
23931 next <= last
23932 && next->used[TEXT_AREA] > 0
23933 && EQ (next->glyphs[TEXT_AREA]->object, after_string);
23934 ++next)
23935 row = next;
23938 glyph = row->glyphs[TEXT_AREA];
23939 end = glyph + row->used[TEXT_AREA];
23940 x = row->x;
23941 dpyinfo->mouse_face_end_y = row->y;
23942 dpyinfo->mouse_face_end_row = MATRIX_ROW_VPOS (row, w->current_matrix);
23944 /* Skip truncation glyphs at the start of the row. */
23945 if (row->displays_text_p)
23946 for (; glyph < end
23947 && INTEGERP (glyph->object)
23948 && glyph->charpos < 0;
23949 ++glyph)
23950 x += glyph->pixel_width;
23952 /* Scan the glyph row, stopping at END_CHARPOS or when we encounter
23953 AFTER_STRING. */
23954 for (; glyph < end
23955 && !INTEGERP (glyph->object)
23956 && !EQ (glyph->object, after_string)
23957 && !(BUFFERP (glyph->object) && glyph->charpos >= end_charpos);
23958 ++glyph)
23959 x += glyph->pixel_width;
23961 /* If we found AFTER_STRING, consume it and stop. */
23962 if (EQ (glyph->object, after_string))
23964 for (; EQ (glyph->object, after_string) && glyph < end; ++glyph)
23965 x += glyph->pixel_width;
23967 else
23969 /* If there's no after-string, we must check if we overshot,
23970 which might be the case if we stopped after a string glyph.
23971 That glyph may belong to a before-string or display-string
23972 associated with the end position, which must not be
23973 highlighted. */
23974 Lisp_Object prev_object;
23975 EMACS_INT pos;
23977 while (glyph > row->glyphs[TEXT_AREA])
23979 prev_object = (glyph - 1)->object;
23980 if (!STRINGP (prev_object) || EQ (prev_object, display_string))
23981 break;
23983 pos = string_buffer_position (w, prev_object, end_charpos);
23984 if (pos && pos < end_charpos)
23985 break;
23987 for (; glyph > row->glyphs[TEXT_AREA]
23988 && EQ ((glyph - 1)->object, prev_object);
23989 --glyph)
23990 x -= (glyph - 1)->pixel_width;
23994 dpyinfo->mouse_face_end_x = x;
23995 dpyinfo->mouse_face_end_col = glyph - row->glyphs[TEXT_AREA];
23996 dpyinfo->mouse_face_window = window;
23997 dpyinfo->mouse_face_face_id
23998 = face_at_buffer_position (w, mouse_charpos, 0, 0, &ignore,
23999 mouse_charpos + 1,
24000 !dpyinfo->mouse_face_hidden, -1);
24001 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
24005 /* Find the position of the glyph for position POS in OBJECT in
24006 window W's current matrix, and return in *X, *Y the pixel
24007 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
24009 RIGHT_P non-zero means return the position of the right edge of the
24010 glyph, RIGHT_P zero means return the left edge position.
24012 If no glyph for POS exists in the matrix, return the position of
24013 the glyph with the next smaller position that is in the matrix, if
24014 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
24015 exists in the matrix, return the position of the glyph with the
24016 next larger position in OBJECT.
24018 Value is non-zero if a glyph was found. */
24020 static int
24021 fast_find_string_pos (struct window *w, EMACS_INT pos, Lisp_Object object,
24022 int *hpos, int *vpos, int *x, int *y, int right_p)
24024 int yb = window_text_bottom_y (w);
24025 struct glyph_row *r;
24026 struct glyph *best_glyph = NULL;
24027 struct glyph_row *best_row = NULL;
24028 int best_x = 0;
24030 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
24031 r->enabled_p && r->y < yb;
24032 ++r)
24034 struct glyph *g = r->glyphs[TEXT_AREA];
24035 struct glyph *e = g + r->used[TEXT_AREA];
24036 int gx;
24038 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
24039 if (EQ (g->object, object))
24041 if (g->charpos == pos)
24043 best_glyph = g;
24044 best_x = gx;
24045 best_row = r;
24046 goto found;
24048 else if (best_glyph == NULL
24049 || ((eabs (g->charpos - pos)
24050 < eabs (best_glyph->charpos - pos))
24051 && (right_p
24052 ? g->charpos < pos
24053 : g->charpos > pos)))
24055 best_glyph = g;
24056 best_x = gx;
24057 best_row = r;
24062 found:
24064 if (best_glyph)
24066 *x = best_x;
24067 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
24069 if (right_p)
24071 *x += best_glyph->pixel_width;
24072 ++*hpos;
24075 *y = best_row->y;
24076 *vpos = best_row - w->current_matrix->rows;
24079 return best_glyph != NULL;
24083 /* See if position X, Y is within a hot-spot of an image. */
24085 static int
24086 on_hot_spot_p (Lisp_Object hot_spot, int x, int y)
24088 if (!CONSP (hot_spot))
24089 return 0;
24091 if (EQ (XCAR (hot_spot), Qrect))
24093 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
24094 Lisp_Object rect = XCDR (hot_spot);
24095 Lisp_Object tem;
24096 if (!CONSP (rect))
24097 return 0;
24098 if (!CONSP (XCAR (rect)))
24099 return 0;
24100 if (!CONSP (XCDR (rect)))
24101 return 0;
24102 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
24103 return 0;
24104 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
24105 return 0;
24106 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
24107 return 0;
24108 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
24109 return 0;
24110 return 1;
24112 else if (EQ (XCAR (hot_spot), Qcircle))
24114 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
24115 Lisp_Object circ = XCDR (hot_spot);
24116 Lisp_Object lr, lx0, ly0;
24117 if (CONSP (circ)
24118 && CONSP (XCAR (circ))
24119 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
24120 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
24121 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
24123 double r = XFLOATINT (lr);
24124 double dx = XINT (lx0) - x;
24125 double dy = XINT (ly0) - y;
24126 return (dx * dx + dy * dy <= r * r);
24129 else if (EQ (XCAR (hot_spot), Qpoly))
24131 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
24132 if (VECTORP (XCDR (hot_spot)))
24134 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
24135 Lisp_Object *poly = v->contents;
24136 int n = v->size;
24137 int i;
24138 int inside = 0;
24139 Lisp_Object lx, ly;
24140 int x0, y0;
24142 /* Need an even number of coordinates, and at least 3 edges. */
24143 if (n < 6 || n & 1)
24144 return 0;
24146 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
24147 If count is odd, we are inside polygon. Pixels on edges
24148 may or may not be included depending on actual geometry of the
24149 polygon. */
24150 if ((lx = poly[n-2], !INTEGERP (lx))
24151 || (ly = poly[n-1], !INTEGERP (lx)))
24152 return 0;
24153 x0 = XINT (lx), y0 = XINT (ly);
24154 for (i = 0; i < n; i += 2)
24156 int x1 = x0, y1 = y0;
24157 if ((lx = poly[i], !INTEGERP (lx))
24158 || (ly = poly[i+1], !INTEGERP (ly)))
24159 return 0;
24160 x0 = XINT (lx), y0 = XINT (ly);
24162 /* Does this segment cross the X line? */
24163 if (x0 >= x)
24165 if (x1 >= x)
24166 continue;
24168 else if (x1 < x)
24169 continue;
24170 if (y > y0 && y > y1)
24171 continue;
24172 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
24173 inside = !inside;
24175 return inside;
24178 return 0;
24181 Lisp_Object
24182 find_hot_spot (Lisp_Object map, int x, int y)
24184 while (CONSP (map))
24186 if (CONSP (XCAR (map))
24187 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
24188 return XCAR (map);
24189 map = XCDR (map);
24192 return Qnil;
24195 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
24196 3, 3, 0,
24197 doc: /* Lookup in image map MAP coordinates X and Y.
24198 An image map is an alist where each element has the format (AREA ID PLIST).
24199 An AREA is specified as either a rectangle, a circle, or a polygon:
24200 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
24201 pixel coordinates of the upper left and bottom right corners.
24202 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
24203 and the radius of the circle; r may be a float or integer.
24204 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
24205 vector describes one corner in the polygon.
24206 Returns the alist element for the first matching AREA in MAP. */)
24207 (Lisp_Object map, Lisp_Object x, Lisp_Object y)
24209 if (NILP (map))
24210 return Qnil;
24212 CHECK_NUMBER (x);
24213 CHECK_NUMBER (y);
24215 return find_hot_spot (map, XINT (x), XINT (y));
24219 /* Display frame CURSOR, optionally using shape defined by POINTER. */
24220 static void
24221 define_frame_cursor1 (struct frame *f, Cursor cursor, Lisp_Object pointer)
24223 /* Do not change cursor shape while dragging mouse. */
24224 if (!NILP (do_mouse_tracking))
24225 return;
24227 if (!NILP (pointer))
24229 if (EQ (pointer, Qarrow))
24230 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
24231 else if (EQ (pointer, Qhand))
24232 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
24233 else if (EQ (pointer, Qtext))
24234 cursor = FRAME_X_OUTPUT (f)->text_cursor;
24235 else if (EQ (pointer, intern ("hdrag")))
24236 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
24237 #ifdef HAVE_X_WINDOWS
24238 else if (EQ (pointer, intern ("vdrag")))
24239 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
24240 #endif
24241 else if (EQ (pointer, intern ("hourglass")))
24242 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
24243 else if (EQ (pointer, Qmodeline))
24244 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
24245 else
24246 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
24249 if (cursor != No_Cursor)
24250 FRAME_RIF (f)->define_frame_cursor (f, cursor);
24253 /* Take proper action when mouse has moved to the mode or header line
24254 or marginal area AREA of window W, x-position X and y-position Y.
24255 X is relative to the start of the text display area of W, so the
24256 width of bitmap areas and scroll bars must be subtracted to get a
24257 position relative to the start of the mode line. */
24259 static void
24260 note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
24261 enum window_part area)
24263 struct window *w = XWINDOW (window);
24264 struct frame *f = XFRAME (w->frame);
24265 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
24266 Cursor cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
24267 Lisp_Object pointer = Qnil;
24268 int charpos, dx, dy, width, height;
24269 Lisp_Object string, object = Qnil;
24270 Lisp_Object pos, help;
24272 Lisp_Object mouse_face;
24273 int original_x_pixel = x;
24274 struct glyph * glyph = NULL, * row_start_glyph = NULL;
24275 struct glyph_row *row;
24277 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
24279 int x0;
24280 struct glyph *end;
24282 string = mode_line_string (w, area, &x, &y, &charpos,
24283 &object, &dx, &dy, &width, &height);
24285 row = (area == ON_MODE_LINE
24286 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
24287 : MATRIX_HEADER_LINE_ROW (w->current_matrix));
24289 /* Find glyph */
24290 if (row->mode_line_p && row->enabled_p)
24292 glyph = row_start_glyph = row->glyphs[TEXT_AREA];
24293 end = glyph + row->used[TEXT_AREA];
24295 for (x0 = original_x_pixel;
24296 glyph < end && x0 >= glyph->pixel_width;
24297 ++glyph)
24298 x0 -= glyph->pixel_width;
24300 if (glyph >= end)
24301 glyph = NULL;
24304 else
24306 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
24307 string = marginal_area_string (w, area, &x, &y, &charpos,
24308 &object, &dx, &dy, &width, &height);
24311 help = Qnil;
24313 if (IMAGEP (object))
24315 Lisp_Object image_map, hotspot;
24316 if ((image_map = Fplist_get (XCDR (object), QCmap),
24317 !NILP (image_map))
24318 && (hotspot = find_hot_spot (image_map, dx, dy),
24319 CONSP (hotspot))
24320 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
24322 Lisp_Object area_id, plist;
24324 area_id = XCAR (hotspot);
24325 /* Could check AREA_ID to see if we enter/leave this hot-spot.
24326 If so, we could look for mouse-enter, mouse-leave
24327 properties in PLIST (and do something...). */
24328 hotspot = XCDR (hotspot);
24329 if (CONSP (hotspot)
24330 && (plist = XCAR (hotspot), CONSP (plist)))
24332 pointer = Fplist_get (plist, Qpointer);
24333 if (NILP (pointer))
24334 pointer = Qhand;
24335 help = Fplist_get (plist, Qhelp_echo);
24336 if (!NILP (help))
24338 help_echo_string = help;
24339 /* Is this correct? ++kfs */
24340 XSETWINDOW (help_echo_window, w);
24341 help_echo_object = w->buffer;
24342 help_echo_pos = charpos;
24346 if (NILP (pointer))
24347 pointer = Fplist_get (XCDR (object), QCpointer);
24350 if (STRINGP (string))
24352 pos = make_number (charpos);
24353 /* If we're on a string with `help-echo' text property, arrange
24354 for the help to be displayed. This is done by setting the
24355 global variable help_echo_string to the help string. */
24356 if (NILP (help))
24358 help = Fget_text_property (pos, Qhelp_echo, string);
24359 if (!NILP (help))
24361 help_echo_string = help;
24362 XSETWINDOW (help_echo_window, w);
24363 help_echo_object = string;
24364 help_echo_pos = charpos;
24368 if (NILP (pointer))
24369 pointer = Fget_text_property (pos, Qpointer, string);
24371 /* Change the mouse pointer according to what is under X/Y. */
24372 if (NILP (pointer) && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
24374 Lisp_Object map;
24375 map = Fget_text_property (pos, Qlocal_map, string);
24376 if (!KEYMAPP (map))
24377 map = Fget_text_property (pos, Qkeymap, string);
24378 if (!KEYMAPP (map))
24379 cursor = dpyinfo->vertical_scroll_bar_cursor;
24382 /* Change the mouse face according to what is under X/Y. */
24383 mouse_face = Fget_text_property (pos, Qmouse_face, string);
24384 if (!NILP (mouse_face)
24385 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
24386 && glyph)
24388 Lisp_Object b, e;
24390 struct glyph * tmp_glyph;
24392 int gpos;
24393 int gseq_length;
24394 int total_pixel_width;
24395 EMACS_INT ignore;
24397 int vpos, hpos;
24399 b = Fprevious_single_property_change (make_number (charpos + 1),
24400 Qmouse_face, string, Qnil);
24401 if (NILP (b))
24402 b = make_number (0);
24404 e = Fnext_single_property_change (pos, Qmouse_face, string, Qnil);
24405 if (NILP (e))
24406 e = make_number (SCHARS (string));
24408 /* Calculate the position(glyph position: GPOS) of GLYPH in
24409 displayed string. GPOS is different from CHARPOS.
24411 CHARPOS is the position of glyph in internal string
24412 object. A mode line string format has structures which
24413 is converted to a flatten by emacs lisp interpreter.
24414 The internal string is an element of the structures.
24415 The displayed string is the flatten string. */
24416 gpos = 0;
24417 if (glyph > row_start_glyph)
24419 tmp_glyph = glyph - 1;
24420 while (tmp_glyph >= row_start_glyph
24421 && tmp_glyph->charpos >= XINT (b)
24422 && EQ (tmp_glyph->object, glyph->object))
24424 tmp_glyph--;
24425 gpos++;
24429 /* Calculate the lenght(glyph sequence length: GSEQ_LENGTH) of
24430 displayed string holding GLYPH.
24432 GSEQ_LENGTH is different from SCHARS (STRING).
24433 SCHARS (STRING) returns the length of the internal string. */
24434 for (tmp_glyph = glyph, gseq_length = gpos;
24435 tmp_glyph->charpos < XINT (e);
24436 tmp_glyph++, gseq_length++)
24438 if (!EQ (tmp_glyph->object, glyph->object))
24439 break;
24442 total_pixel_width = 0;
24443 for (tmp_glyph = glyph - gpos; tmp_glyph != glyph; tmp_glyph++)
24444 total_pixel_width += tmp_glyph->pixel_width;
24446 /* Pre calculation of re-rendering position */
24447 vpos = (x - gpos);
24448 hpos = (area == ON_MODE_LINE
24449 ? (w->current_matrix)->nrows - 1
24450 : 0);
24452 /* If the re-rendering position is included in the last
24453 re-rendering area, we should do nothing. */
24454 if ( EQ (window, dpyinfo->mouse_face_window)
24455 && dpyinfo->mouse_face_beg_col <= vpos
24456 && vpos < dpyinfo->mouse_face_end_col
24457 && dpyinfo->mouse_face_beg_row == hpos )
24458 return;
24460 if (clear_mouse_face (dpyinfo))
24461 cursor = No_Cursor;
24463 dpyinfo->mouse_face_beg_col = vpos;
24464 dpyinfo->mouse_face_beg_row = hpos;
24466 dpyinfo->mouse_face_beg_x = original_x_pixel - (total_pixel_width + dx);
24467 dpyinfo->mouse_face_beg_y = 0;
24469 dpyinfo->mouse_face_end_col = vpos + gseq_length;
24470 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_beg_row;
24472 dpyinfo->mouse_face_end_x = 0;
24473 dpyinfo->mouse_face_end_y = 0;
24475 dpyinfo->mouse_face_past_end = 0;
24476 dpyinfo->mouse_face_window = window;
24478 dpyinfo->mouse_face_face_id = face_at_string_position (w, string,
24479 charpos,
24480 0, 0, 0, &ignore,
24481 glyph->face_id, 1);
24482 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
24484 if (NILP (pointer))
24485 pointer = Qhand;
24487 else if ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
24488 clear_mouse_face (dpyinfo);
24490 define_frame_cursor1 (f, cursor, pointer);
24494 /* EXPORT:
24495 Take proper action when the mouse has moved to position X, Y on
24496 frame F as regards highlighting characters that have mouse-face
24497 properties. Also de-highlighting chars where the mouse was before.
24498 X and Y can be negative or out of range. */
24500 void
24501 note_mouse_highlight (struct frame *f, int x, int y)
24503 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
24504 enum window_part part;
24505 Lisp_Object window;
24506 struct window *w;
24507 Cursor cursor = No_Cursor;
24508 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
24509 struct buffer *b;
24511 /* When a menu is active, don't highlight because this looks odd. */
24512 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS)
24513 if (popup_activated ())
24514 return;
24515 #endif
24517 if (NILP (Vmouse_highlight)
24518 || !f->glyphs_initialized_p
24519 || f->pointer_invisible)
24520 return;
24522 dpyinfo->mouse_face_mouse_x = x;
24523 dpyinfo->mouse_face_mouse_y = y;
24524 dpyinfo->mouse_face_mouse_frame = f;
24526 if (dpyinfo->mouse_face_defer)
24527 return;
24529 if (gc_in_progress)
24531 dpyinfo->mouse_face_deferred_gc = 1;
24532 return;
24535 /* Which window is that in? */
24536 window = window_from_coordinates (f, x, y, &part, 0, 0, 1);
24538 /* If we were displaying active text in another window, clear that.
24539 Also clear if we move out of text area in same window. */
24540 if (! EQ (window, dpyinfo->mouse_face_window)
24541 || (part != ON_TEXT && part != ON_MODE_LINE && part != ON_HEADER_LINE
24542 && !NILP (dpyinfo->mouse_face_window)))
24543 clear_mouse_face (dpyinfo);
24545 /* Not on a window -> return. */
24546 if (!WINDOWP (window))
24547 return;
24549 /* Reset help_echo_string. It will get recomputed below. */
24550 help_echo_string = Qnil;
24552 /* Convert to window-relative pixel coordinates. */
24553 w = XWINDOW (window);
24554 frame_to_window_pixel_xy (w, &x, &y);
24556 /* Handle tool-bar window differently since it doesn't display a
24557 buffer. */
24558 if (EQ (window, f->tool_bar_window))
24560 note_tool_bar_highlight (f, x, y);
24561 return;
24564 /* Mouse is on the mode, header line or margin? */
24565 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
24566 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
24568 note_mode_line_or_margin_highlight (window, x, y, part);
24569 return;
24572 if (part == ON_VERTICAL_BORDER)
24574 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
24575 help_echo_string = build_string ("drag-mouse-1: resize");
24577 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
24578 || part == ON_SCROLL_BAR)
24579 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
24580 else
24581 cursor = FRAME_X_OUTPUT (f)->text_cursor;
24583 /* Are we in a window whose display is up to date?
24584 And verify the buffer's text has not changed. */
24585 b = XBUFFER (w->buffer);
24586 if (part == ON_TEXT
24587 && EQ (w->window_end_valid, w->buffer)
24588 && XFASTINT (w->last_modified) == BUF_MODIFF (b)
24589 && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
24591 int hpos, vpos, i, dx, dy, area;
24592 EMACS_INT pos;
24593 struct glyph *glyph;
24594 Lisp_Object object;
24595 Lisp_Object mouse_face = Qnil, overlay = Qnil, position;
24596 Lisp_Object *overlay_vec = NULL;
24597 int noverlays;
24598 struct buffer *obuf;
24599 int obegv, ozv, same_region;
24601 /* Find the glyph under X/Y. */
24602 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
24604 /* Look for :pointer property on image. */
24605 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
24607 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
24608 if (img != NULL && IMAGEP (img->spec))
24610 Lisp_Object image_map, hotspot;
24611 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
24612 !NILP (image_map))
24613 && (hotspot = find_hot_spot (image_map,
24614 glyph->slice.x + dx,
24615 glyph->slice.y + dy),
24616 CONSP (hotspot))
24617 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
24619 Lisp_Object area_id, plist;
24621 area_id = XCAR (hotspot);
24622 /* Could check AREA_ID to see if we enter/leave this hot-spot.
24623 If so, we could look for mouse-enter, mouse-leave
24624 properties in PLIST (and do something...). */
24625 hotspot = XCDR (hotspot);
24626 if (CONSP (hotspot)
24627 && (plist = XCAR (hotspot), CONSP (plist)))
24629 pointer = Fplist_get (plist, Qpointer);
24630 if (NILP (pointer))
24631 pointer = Qhand;
24632 help_echo_string = Fplist_get (plist, Qhelp_echo);
24633 if (!NILP (help_echo_string))
24635 help_echo_window = window;
24636 help_echo_object = glyph->object;
24637 help_echo_pos = glyph->charpos;
24641 if (NILP (pointer))
24642 pointer = Fplist_get (XCDR (img->spec), QCpointer);
24646 /* Clear mouse face if X/Y not over text. */
24647 if (glyph == NULL
24648 || area != TEXT_AREA
24649 || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p)
24651 if (clear_mouse_face (dpyinfo))
24652 cursor = No_Cursor;
24653 if (NILP (pointer))
24655 if (area != TEXT_AREA)
24656 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
24657 else
24658 pointer = Vvoid_text_area_pointer;
24660 goto set_cursor;
24663 pos = glyph->charpos;
24664 object = glyph->object;
24665 if (!STRINGP (object) && !BUFFERP (object))
24666 goto set_cursor;
24668 /* If we get an out-of-range value, return now; avoid an error. */
24669 if (BUFFERP (object) && pos > BUF_Z (b))
24670 goto set_cursor;
24672 /* Make the window's buffer temporarily current for
24673 overlays_at and compute_char_face. */
24674 obuf = current_buffer;
24675 current_buffer = b;
24676 obegv = BEGV;
24677 ozv = ZV;
24678 BEGV = BEG;
24679 ZV = Z;
24681 /* Is this char mouse-active or does it have help-echo? */
24682 position = make_number (pos);
24684 if (BUFFERP (object))
24686 /* Put all the overlays we want in a vector in overlay_vec. */
24687 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
24688 /* Sort overlays into increasing priority order. */
24689 noverlays = sort_overlays (overlay_vec, noverlays, w);
24691 else
24692 noverlays = 0;
24694 same_region = (EQ (window, dpyinfo->mouse_face_window)
24695 && vpos >= dpyinfo->mouse_face_beg_row
24696 && vpos <= dpyinfo->mouse_face_end_row
24697 && (vpos > dpyinfo->mouse_face_beg_row
24698 || hpos >= dpyinfo->mouse_face_beg_col)
24699 && (vpos < dpyinfo->mouse_face_end_row
24700 || hpos < dpyinfo->mouse_face_end_col
24701 || dpyinfo->mouse_face_past_end));
24703 if (same_region)
24704 cursor = No_Cursor;
24706 /* Check mouse-face highlighting. */
24707 if (! same_region
24708 /* If there exists an overlay with mouse-face overlapping
24709 the one we are currently highlighting, we have to
24710 check if we enter the overlapping overlay, and then
24711 highlight only that. */
24712 || (OVERLAYP (dpyinfo->mouse_face_overlay)
24713 && mouse_face_overlay_overlaps (dpyinfo->mouse_face_overlay)))
24715 /* Find the highest priority overlay with a mouse-face. */
24716 overlay = Qnil;
24717 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
24719 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
24720 if (!NILP (mouse_face))
24721 overlay = overlay_vec[i];
24724 /* If we're highlighting the same overlay as before, there's
24725 no need to do that again. */
24726 if (!NILP (overlay) && EQ (overlay, dpyinfo->mouse_face_overlay))
24727 goto check_help_echo;
24728 dpyinfo->mouse_face_overlay = overlay;
24730 /* Clear the display of the old active region, if any. */
24731 if (clear_mouse_face (dpyinfo))
24732 cursor = No_Cursor;
24734 /* If no overlay applies, get a text property. */
24735 if (NILP (overlay))
24736 mouse_face = Fget_text_property (position, Qmouse_face, object);
24738 /* Next, compute the bounds of the mouse highlighting and
24739 display it. */
24740 if (!NILP (mouse_face) && STRINGP (object))
24742 /* The mouse-highlighting comes from a display string
24743 with a mouse-face. */
24744 Lisp_Object b, e;
24745 EMACS_INT ignore;
24747 b = Fprevious_single_property_change
24748 (make_number (pos + 1), Qmouse_face, object, Qnil);
24749 e = Fnext_single_property_change
24750 (position, Qmouse_face, object, Qnil);
24751 if (NILP (b))
24752 b = make_number (0);
24753 if (NILP (e))
24754 e = make_number (SCHARS (object) - 1);
24756 fast_find_string_pos (w, XINT (b), object,
24757 &dpyinfo->mouse_face_beg_col,
24758 &dpyinfo->mouse_face_beg_row,
24759 &dpyinfo->mouse_face_beg_x,
24760 &dpyinfo->mouse_face_beg_y, 0);
24761 fast_find_string_pos (w, XINT (e), object,
24762 &dpyinfo->mouse_face_end_col,
24763 &dpyinfo->mouse_face_end_row,
24764 &dpyinfo->mouse_face_end_x,
24765 &dpyinfo->mouse_face_end_y, 1);
24766 dpyinfo->mouse_face_past_end = 0;
24767 dpyinfo->mouse_face_window = window;
24768 dpyinfo->mouse_face_face_id
24769 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
24770 glyph->face_id, 1);
24771 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
24772 cursor = No_Cursor;
24774 else
24776 /* The mouse-highlighting, if any, comes from an overlay
24777 or text property in the buffer. */
24778 Lisp_Object buffer, display_string;
24780 if (STRINGP (object))
24782 /* If we are on a display string with no mouse-face,
24783 check if the text under it has one. */
24784 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
24785 int start = MATRIX_ROW_START_CHARPOS (r);
24786 pos = string_buffer_position (w, object, start);
24787 if (pos > 0)
24789 mouse_face = get_char_property_and_overlay
24790 (make_number (pos), Qmouse_face, w->buffer, &overlay);
24791 buffer = w->buffer;
24792 display_string = object;
24795 else
24797 buffer = object;
24798 display_string = Qnil;
24801 if (!NILP (mouse_face))
24803 Lisp_Object before, after;
24804 Lisp_Object before_string, after_string;
24806 if (NILP (overlay))
24808 /* Handle the text property case. */
24809 before = Fprevious_single_property_change
24810 (make_number (pos + 1), Qmouse_face, buffer,
24811 Fmarker_position (w->start));
24812 after = Fnext_single_property_change
24813 (make_number (pos), Qmouse_face, buffer,
24814 make_number (BUF_Z (XBUFFER (buffer))
24815 - XFASTINT (w->window_end_pos)));
24816 before_string = after_string = Qnil;
24818 else
24820 /* Handle the overlay case. */
24821 before = Foverlay_start (overlay);
24822 after = Foverlay_end (overlay);
24823 before_string = Foverlay_get (overlay, Qbefore_string);
24824 after_string = Foverlay_get (overlay, Qafter_string);
24826 if (!STRINGP (before_string)) before_string = Qnil;
24827 if (!STRINGP (after_string)) after_string = Qnil;
24830 mouse_face_from_buffer_pos (window, dpyinfo, pos,
24831 XFASTINT (before),
24832 XFASTINT (after),
24833 before_string, after_string,
24834 display_string);
24835 cursor = No_Cursor;
24840 check_help_echo:
24842 /* Look for a `help-echo' property. */
24843 if (NILP (help_echo_string)) {
24844 Lisp_Object help, overlay;
24846 /* Check overlays first. */
24847 help = overlay = Qnil;
24848 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
24850 overlay = overlay_vec[i];
24851 help = Foverlay_get (overlay, Qhelp_echo);
24854 if (!NILP (help))
24856 help_echo_string = help;
24857 help_echo_window = window;
24858 help_echo_object = overlay;
24859 help_echo_pos = pos;
24861 else
24863 Lisp_Object object = glyph->object;
24864 int charpos = glyph->charpos;
24866 /* Try text properties. */
24867 if (STRINGP (object)
24868 && charpos >= 0
24869 && charpos < SCHARS (object))
24871 help = Fget_text_property (make_number (charpos),
24872 Qhelp_echo, object);
24873 if (NILP (help))
24875 /* If the string itself doesn't specify a help-echo,
24876 see if the buffer text ``under'' it does. */
24877 struct glyph_row *r
24878 = MATRIX_ROW (w->current_matrix, vpos);
24879 int start = MATRIX_ROW_START_CHARPOS (r);
24880 EMACS_INT pos = string_buffer_position (w, object, start);
24881 if (pos > 0)
24883 help = Fget_char_property (make_number (pos),
24884 Qhelp_echo, w->buffer);
24885 if (!NILP (help))
24887 charpos = pos;
24888 object = w->buffer;
24893 else if (BUFFERP (object)
24894 && charpos >= BEGV
24895 && charpos < ZV)
24896 help = Fget_text_property (make_number (charpos), Qhelp_echo,
24897 object);
24899 if (!NILP (help))
24901 help_echo_string = help;
24902 help_echo_window = window;
24903 help_echo_object = object;
24904 help_echo_pos = charpos;
24909 /* Look for a `pointer' property. */
24910 if (NILP (pointer))
24912 /* Check overlays first. */
24913 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
24914 pointer = Foverlay_get (overlay_vec[i], Qpointer);
24916 if (NILP (pointer))
24918 Lisp_Object object = glyph->object;
24919 int charpos = glyph->charpos;
24921 /* Try text properties. */
24922 if (STRINGP (object)
24923 && charpos >= 0
24924 && charpos < SCHARS (object))
24926 pointer = Fget_text_property (make_number (charpos),
24927 Qpointer, object);
24928 if (NILP (pointer))
24930 /* If the string itself doesn't specify a pointer,
24931 see if the buffer text ``under'' it does. */
24932 struct glyph_row *r
24933 = MATRIX_ROW (w->current_matrix, vpos);
24934 int start = MATRIX_ROW_START_CHARPOS (r);
24935 EMACS_INT pos = string_buffer_position (w, object,
24936 start);
24937 if (pos > 0)
24938 pointer = Fget_char_property (make_number (pos),
24939 Qpointer, w->buffer);
24942 else if (BUFFERP (object)
24943 && charpos >= BEGV
24944 && charpos < ZV)
24945 pointer = Fget_text_property (make_number (charpos),
24946 Qpointer, object);
24950 BEGV = obegv;
24951 ZV = ozv;
24952 current_buffer = obuf;
24955 set_cursor:
24957 define_frame_cursor1 (f, cursor, pointer);
24961 /* EXPORT for RIF:
24962 Clear any mouse-face on window W. This function is part of the
24963 redisplay interface, and is called from try_window_id and similar
24964 functions to ensure the mouse-highlight is off. */
24966 void
24967 x_clear_window_mouse_face (struct window *w)
24969 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
24970 Lisp_Object window;
24972 BLOCK_INPUT;
24973 XSETWINDOW (window, w);
24974 if (EQ (window, dpyinfo->mouse_face_window))
24975 clear_mouse_face (dpyinfo);
24976 UNBLOCK_INPUT;
24980 /* EXPORT:
24981 Just discard the mouse face information for frame F, if any.
24982 This is used when the size of F is changed. */
24984 void
24985 cancel_mouse_face (struct frame *f)
24987 Lisp_Object window;
24988 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
24990 window = dpyinfo->mouse_face_window;
24991 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
24993 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
24994 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
24995 dpyinfo->mouse_face_window = Qnil;
25000 #endif /* HAVE_WINDOW_SYSTEM */
25003 /***********************************************************************
25004 Exposure Events
25005 ***********************************************************************/
25007 #ifdef HAVE_WINDOW_SYSTEM
25009 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
25010 which intersects rectangle R. R is in window-relative coordinates. */
25012 static void
25013 expose_area (struct window *w, struct glyph_row *row, XRectangle *r,
25014 enum glyph_row_area area)
25016 struct glyph *first = row->glyphs[area];
25017 struct glyph *end = row->glyphs[area] + row->used[area];
25018 struct glyph *last;
25019 int first_x, start_x, x;
25021 if (area == TEXT_AREA && row->fill_line_p)
25022 /* If row extends face to end of line write the whole line. */
25023 draw_glyphs (w, 0, row, area,
25024 0, row->used[area],
25025 DRAW_NORMAL_TEXT, 0);
25026 else
25028 /* Set START_X to the window-relative start position for drawing glyphs of
25029 AREA. The first glyph of the text area can be partially visible.
25030 The first glyphs of other areas cannot. */
25031 start_x = window_box_left_offset (w, area);
25032 x = start_x;
25033 if (area == TEXT_AREA)
25034 x += row->x;
25036 /* Find the first glyph that must be redrawn. */
25037 while (first < end
25038 && x + first->pixel_width < r->x)
25040 x += first->pixel_width;
25041 ++first;
25044 /* Find the last one. */
25045 last = first;
25046 first_x = x;
25047 while (last < end
25048 && x < r->x + r->width)
25050 x += last->pixel_width;
25051 ++last;
25054 /* Repaint. */
25055 if (last > first)
25056 draw_glyphs (w, first_x - start_x, row, area,
25057 first - row->glyphs[area], last - row->glyphs[area],
25058 DRAW_NORMAL_TEXT, 0);
25063 /* Redraw the parts of the glyph row ROW on window W intersecting
25064 rectangle R. R is in window-relative coordinates. Value is
25065 non-zero if mouse-face was overwritten. */
25067 static int
25068 expose_line (struct window *w, struct glyph_row *row, XRectangle *r)
25070 xassert (row->enabled_p);
25072 if (row->mode_line_p || w->pseudo_window_p)
25073 draw_glyphs (w, 0, row, TEXT_AREA,
25074 0, row->used[TEXT_AREA],
25075 DRAW_NORMAL_TEXT, 0);
25076 else
25078 if (row->used[LEFT_MARGIN_AREA])
25079 expose_area (w, row, r, LEFT_MARGIN_AREA);
25080 if (row->used[TEXT_AREA])
25081 expose_area (w, row, r, TEXT_AREA);
25082 if (row->used[RIGHT_MARGIN_AREA])
25083 expose_area (w, row, r, RIGHT_MARGIN_AREA);
25084 draw_row_fringe_bitmaps (w, row);
25087 return row->mouse_face_p;
25091 /* Redraw those parts of glyphs rows during expose event handling that
25092 overlap other rows. Redrawing of an exposed line writes over parts
25093 of lines overlapping that exposed line; this function fixes that.
25095 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
25096 row in W's current matrix that is exposed and overlaps other rows.
25097 LAST_OVERLAPPING_ROW is the last such row. */
25099 static void
25100 expose_overlaps (struct window *w,
25101 struct glyph_row *first_overlapping_row,
25102 struct glyph_row *last_overlapping_row,
25103 XRectangle *r)
25105 struct glyph_row *row;
25107 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
25108 if (row->overlapping_p)
25110 xassert (row->enabled_p && !row->mode_line_p);
25112 row->clip = r;
25113 if (row->used[LEFT_MARGIN_AREA])
25114 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA, OVERLAPS_BOTH);
25116 if (row->used[TEXT_AREA])
25117 x_fix_overlapping_area (w, row, TEXT_AREA, OVERLAPS_BOTH);
25119 if (row->used[RIGHT_MARGIN_AREA])
25120 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, OVERLAPS_BOTH);
25121 row->clip = NULL;
25126 /* Return non-zero if W's cursor intersects rectangle R. */
25128 static int
25129 phys_cursor_in_rect_p (struct window *w, XRectangle *r)
25131 XRectangle cr, result;
25132 struct glyph *cursor_glyph;
25133 struct glyph_row *row;
25135 if (w->phys_cursor.vpos >= 0
25136 && w->phys_cursor.vpos < w->current_matrix->nrows
25137 && (row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos),
25138 row->enabled_p)
25139 && row->cursor_in_fringe_p)
25141 /* Cursor is in the fringe. */
25142 cr.x = window_box_right_offset (w,
25143 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
25144 ? RIGHT_MARGIN_AREA
25145 : TEXT_AREA));
25146 cr.y = row->y;
25147 cr.width = WINDOW_RIGHT_FRINGE_WIDTH (w);
25148 cr.height = row->height;
25149 return x_intersect_rectangles (&cr, r, &result);
25152 cursor_glyph = get_phys_cursor_glyph (w);
25153 if (cursor_glyph)
25155 /* r is relative to W's box, but w->phys_cursor.x is relative
25156 to left edge of W's TEXT area. Adjust it. */
25157 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
25158 cr.y = w->phys_cursor.y;
25159 cr.width = cursor_glyph->pixel_width;
25160 cr.height = w->phys_cursor_height;
25161 /* ++KFS: W32 version used W32-specific IntersectRect here, but
25162 I assume the effect is the same -- and this is portable. */
25163 return x_intersect_rectangles (&cr, r, &result);
25165 /* If we don't understand the format, pretend we're not in the hot-spot. */
25166 return 0;
25170 /* EXPORT:
25171 Draw a vertical window border to the right of window W if W doesn't
25172 have vertical scroll bars. */
25174 void
25175 x_draw_vertical_border (struct window *w)
25177 struct frame *f = XFRAME (WINDOW_FRAME (w));
25179 /* We could do better, if we knew what type of scroll-bar the adjacent
25180 windows (on either side) have... But we don't :-(
25181 However, I think this works ok. ++KFS 2003-04-25 */
25183 /* Redraw borders between horizontally adjacent windows. Don't
25184 do it for frames with vertical scroll bars because either the
25185 right scroll bar of a window, or the left scroll bar of its
25186 neighbor will suffice as a border. */
25187 if (FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (w->frame)))
25188 return;
25190 if (!WINDOW_RIGHTMOST_P (w)
25191 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
25193 int x0, x1, y0, y1;
25195 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
25196 y1 -= 1;
25198 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
25199 x1 -= 1;
25201 FRAME_RIF (f)->draw_vertical_window_border (w, x1, y0, y1);
25203 else if (!WINDOW_LEFTMOST_P (w)
25204 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
25206 int x0, x1, y0, y1;
25208 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
25209 y1 -= 1;
25211 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
25212 x0 -= 1;
25214 FRAME_RIF (f)->draw_vertical_window_border (w, x0, y0, y1);
25219 /* Redraw the part of window W intersection rectangle FR. Pixel
25220 coordinates in FR are frame-relative. Call this function with
25221 input blocked. Value is non-zero if the exposure overwrites
25222 mouse-face. */
25224 static int
25225 expose_window (struct window *w, XRectangle *fr)
25227 struct frame *f = XFRAME (w->frame);
25228 XRectangle wr, r;
25229 int mouse_face_overwritten_p = 0;
25231 /* If window is not yet fully initialized, do nothing. This can
25232 happen when toolkit scroll bars are used and a window is split.
25233 Reconfiguring the scroll bar will generate an expose for a newly
25234 created window. */
25235 if (w->current_matrix == NULL)
25236 return 0;
25238 /* When we're currently updating the window, display and current
25239 matrix usually don't agree. Arrange for a thorough display
25240 later. */
25241 if (w == updated_window)
25243 SET_FRAME_GARBAGED (f);
25244 return 0;
25247 /* Frame-relative pixel rectangle of W. */
25248 wr.x = WINDOW_LEFT_EDGE_X (w);
25249 wr.y = WINDOW_TOP_EDGE_Y (w);
25250 wr.width = WINDOW_TOTAL_WIDTH (w);
25251 wr.height = WINDOW_TOTAL_HEIGHT (w);
25253 if (x_intersect_rectangles (fr, &wr, &r))
25255 int yb = window_text_bottom_y (w);
25256 struct glyph_row *row;
25257 int cursor_cleared_p;
25258 struct glyph_row *first_overlapping_row, *last_overlapping_row;
25260 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
25261 r.x, r.y, r.width, r.height));
25263 /* Convert to window coordinates. */
25264 r.x -= WINDOW_LEFT_EDGE_X (w);
25265 r.y -= WINDOW_TOP_EDGE_Y (w);
25267 /* Turn off the cursor. */
25268 if (!w->pseudo_window_p
25269 && phys_cursor_in_rect_p (w, &r))
25271 x_clear_cursor (w);
25272 cursor_cleared_p = 1;
25274 else
25275 cursor_cleared_p = 0;
25277 /* Update lines intersecting rectangle R. */
25278 first_overlapping_row = last_overlapping_row = NULL;
25279 for (row = w->current_matrix->rows;
25280 row->enabled_p;
25281 ++row)
25283 int y0 = row->y;
25284 int y1 = MATRIX_ROW_BOTTOM_Y (row);
25286 if ((y0 >= r.y && y0 < r.y + r.height)
25287 || (y1 > r.y && y1 < r.y + r.height)
25288 || (r.y >= y0 && r.y < y1)
25289 || (r.y + r.height > y0 && r.y + r.height < y1))
25291 /* A header line may be overlapping, but there is no need
25292 to fix overlapping areas for them. KFS 2005-02-12 */
25293 if (row->overlapping_p && !row->mode_line_p)
25295 if (first_overlapping_row == NULL)
25296 first_overlapping_row = row;
25297 last_overlapping_row = row;
25300 row->clip = fr;
25301 if (expose_line (w, row, &r))
25302 mouse_face_overwritten_p = 1;
25303 row->clip = NULL;
25305 else if (row->overlapping_p)
25307 /* We must redraw a row overlapping the exposed area. */
25308 if (y0 < r.y
25309 ? y0 + row->phys_height > r.y
25310 : y0 + row->ascent - row->phys_ascent < r.y +r.height)
25312 if (first_overlapping_row == NULL)
25313 first_overlapping_row = row;
25314 last_overlapping_row = row;
25318 if (y1 >= yb)
25319 break;
25322 /* Display the mode line if there is one. */
25323 if (WINDOW_WANTS_MODELINE_P (w)
25324 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
25325 row->enabled_p)
25326 && row->y < r.y + r.height)
25328 if (expose_line (w, row, &r))
25329 mouse_face_overwritten_p = 1;
25332 if (!w->pseudo_window_p)
25334 /* Fix the display of overlapping rows. */
25335 if (first_overlapping_row)
25336 expose_overlaps (w, first_overlapping_row, last_overlapping_row,
25337 fr);
25339 /* Draw border between windows. */
25340 x_draw_vertical_border (w);
25342 /* Turn the cursor on again. */
25343 if (cursor_cleared_p)
25344 update_window_cursor (w, 1);
25348 return mouse_face_overwritten_p;
25353 /* Redraw (parts) of all windows in the window tree rooted at W that
25354 intersect R. R contains frame pixel coordinates. Value is
25355 non-zero if the exposure overwrites mouse-face. */
25357 static int
25358 expose_window_tree (struct window *w, XRectangle *r)
25360 struct frame *f = XFRAME (w->frame);
25361 int mouse_face_overwritten_p = 0;
25363 while (w && !FRAME_GARBAGED_P (f))
25365 if (!NILP (w->hchild))
25366 mouse_face_overwritten_p
25367 |= expose_window_tree (XWINDOW (w->hchild), r);
25368 else if (!NILP (w->vchild))
25369 mouse_face_overwritten_p
25370 |= expose_window_tree (XWINDOW (w->vchild), r);
25371 else
25372 mouse_face_overwritten_p |= expose_window (w, r);
25374 w = NILP (w->next) ? NULL : XWINDOW (w->next);
25377 return mouse_face_overwritten_p;
25381 /* EXPORT:
25382 Redisplay an exposed area of frame F. X and Y are the upper-left
25383 corner of the exposed rectangle. W and H are width and height of
25384 the exposed area. All are pixel values. W or H zero means redraw
25385 the entire frame. */
25387 void
25388 expose_frame (struct frame *f, int x, int y, int w, int h)
25390 XRectangle r;
25391 int mouse_face_overwritten_p = 0;
25393 TRACE ((stderr, "expose_frame "));
25395 /* No need to redraw if frame will be redrawn soon. */
25396 if (FRAME_GARBAGED_P (f))
25398 TRACE ((stderr, " garbaged\n"));
25399 return;
25402 /* If basic faces haven't been realized yet, there is no point in
25403 trying to redraw anything. This can happen when we get an expose
25404 event while Emacs is starting, e.g. by moving another window. */
25405 if (FRAME_FACE_CACHE (f) == NULL
25406 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
25408 TRACE ((stderr, " no faces\n"));
25409 return;
25412 if (w == 0 || h == 0)
25414 r.x = r.y = 0;
25415 r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f);
25416 r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f);
25418 else
25420 r.x = x;
25421 r.y = y;
25422 r.width = w;
25423 r.height = h;
25426 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
25427 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
25429 if (WINDOWP (f->tool_bar_window))
25430 mouse_face_overwritten_p
25431 |= expose_window (XWINDOW (f->tool_bar_window), &r);
25433 #ifdef HAVE_X_WINDOWS
25434 #ifndef MSDOS
25435 #ifndef USE_X_TOOLKIT
25436 if (WINDOWP (f->menu_bar_window))
25437 mouse_face_overwritten_p
25438 |= expose_window (XWINDOW (f->menu_bar_window), &r);
25439 #endif /* not USE_X_TOOLKIT */
25440 #endif
25441 #endif
25443 /* Some window managers support a focus-follows-mouse style with
25444 delayed raising of frames. Imagine a partially obscured frame,
25445 and moving the mouse into partially obscured mouse-face on that
25446 frame. The visible part of the mouse-face will be highlighted,
25447 then the WM raises the obscured frame. With at least one WM, KDE
25448 2.1, Emacs is not getting any event for the raising of the frame
25449 (even tried with SubstructureRedirectMask), only Expose events.
25450 These expose events will draw text normally, i.e. not
25451 highlighted. Which means we must redo the highlight here.
25452 Subsume it under ``we love X''. --gerd 2001-08-15 */
25453 /* Included in Windows version because Windows most likely does not
25454 do the right thing if any third party tool offers
25455 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
25456 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
25458 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
25459 if (f == dpyinfo->mouse_face_mouse_frame)
25461 int x = dpyinfo->mouse_face_mouse_x;
25462 int y = dpyinfo->mouse_face_mouse_y;
25463 clear_mouse_face (dpyinfo);
25464 note_mouse_highlight (f, x, y);
25470 /* EXPORT:
25471 Determine the intersection of two rectangles R1 and R2. Return
25472 the intersection in *RESULT. Value is non-zero if RESULT is not
25473 empty. */
25476 x_intersect_rectangles (XRectangle *r1, XRectangle *r2, XRectangle *result)
25478 XRectangle *left, *right;
25479 XRectangle *upper, *lower;
25480 int intersection_p = 0;
25482 /* Rearrange so that R1 is the left-most rectangle. */
25483 if (r1->x < r2->x)
25484 left = r1, right = r2;
25485 else
25486 left = r2, right = r1;
25488 /* X0 of the intersection is right.x0, if this is inside R1,
25489 otherwise there is no intersection. */
25490 if (right->x <= left->x + left->width)
25492 result->x = right->x;
25494 /* The right end of the intersection is the minimum of the
25495 the right ends of left and right. */
25496 result->width = (min (left->x + left->width, right->x + right->width)
25497 - result->x);
25499 /* Same game for Y. */
25500 if (r1->y < r2->y)
25501 upper = r1, lower = r2;
25502 else
25503 upper = r2, lower = r1;
25505 /* The upper end of the intersection is lower.y0, if this is inside
25506 of upper. Otherwise, there is no intersection. */
25507 if (lower->y <= upper->y + upper->height)
25509 result->y = lower->y;
25511 /* The lower end of the intersection is the minimum of the lower
25512 ends of upper and lower. */
25513 result->height = (min (lower->y + lower->height,
25514 upper->y + upper->height)
25515 - result->y);
25516 intersection_p = 1;
25520 return intersection_p;
25523 #endif /* HAVE_WINDOW_SYSTEM */
25526 /***********************************************************************
25527 Initialization
25528 ***********************************************************************/
25530 void
25531 syms_of_xdisp (void)
25533 Vwith_echo_area_save_vector = Qnil;
25534 staticpro (&Vwith_echo_area_save_vector);
25536 Vmessage_stack = Qnil;
25537 staticpro (&Vmessage_stack);
25539 Qinhibit_redisplay = intern_c_string ("inhibit-redisplay");
25540 staticpro (&Qinhibit_redisplay);
25542 message_dolog_marker1 = Fmake_marker ();
25543 staticpro (&message_dolog_marker1);
25544 message_dolog_marker2 = Fmake_marker ();
25545 staticpro (&message_dolog_marker2);
25546 message_dolog_marker3 = Fmake_marker ();
25547 staticpro (&message_dolog_marker3);
25549 #if GLYPH_DEBUG
25550 defsubr (&Sdump_frame_glyph_matrix);
25551 defsubr (&Sdump_glyph_matrix);
25552 defsubr (&Sdump_glyph_row);
25553 defsubr (&Sdump_tool_bar_row);
25554 defsubr (&Strace_redisplay);
25555 defsubr (&Strace_to_stderr);
25556 #endif
25557 #ifdef HAVE_WINDOW_SYSTEM
25558 defsubr (&Stool_bar_lines_needed);
25559 defsubr (&Slookup_image_map);
25560 #endif
25561 defsubr (&Sformat_mode_line);
25562 defsubr (&Sinvisible_p);
25563 defsubr (&Scurrent_bidi_paragraph_direction);
25565 staticpro (&Qmenu_bar_update_hook);
25566 Qmenu_bar_update_hook = intern_c_string ("menu-bar-update-hook");
25568 staticpro (&Qoverriding_terminal_local_map);
25569 Qoverriding_terminal_local_map = intern_c_string ("overriding-terminal-local-map");
25571 staticpro (&Qoverriding_local_map);
25572 Qoverriding_local_map = intern_c_string ("overriding-local-map");
25574 staticpro (&Qwindow_scroll_functions);
25575 Qwindow_scroll_functions = intern_c_string ("window-scroll-functions");
25577 staticpro (&Qwindow_text_change_functions);
25578 Qwindow_text_change_functions = intern_c_string ("window-text-change-functions");
25580 staticpro (&Qredisplay_end_trigger_functions);
25581 Qredisplay_end_trigger_functions = intern_c_string ("redisplay-end-trigger-functions");
25583 staticpro (&Qinhibit_point_motion_hooks);
25584 Qinhibit_point_motion_hooks = intern_c_string ("inhibit-point-motion-hooks");
25586 Qeval = intern_c_string ("eval");
25587 staticpro (&Qeval);
25589 QCdata = intern_c_string (":data");
25590 staticpro (&QCdata);
25591 Qdisplay = intern_c_string ("display");
25592 staticpro (&Qdisplay);
25593 Qspace_width = intern_c_string ("space-width");
25594 staticpro (&Qspace_width);
25595 Qraise = intern_c_string ("raise");
25596 staticpro (&Qraise);
25597 Qslice = intern_c_string ("slice");
25598 staticpro (&Qslice);
25599 Qspace = intern_c_string ("space");
25600 staticpro (&Qspace);
25601 Qmargin = intern_c_string ("margin");
25602 staticpro (&Qmargin);
25603 Qpointer = intern_c_string ("pointer");
25604 staticpro (&Qpointer);
25605 Qleft_margin = intern_c_string ("left-margin");
25606 staticpro (&Qleft_margin);
25607 Qright_margin = intern_c_string ("right-margin");
25608 staticpro (&Qright_margin);
25609 Qcenter = intern_c_string ("center");
25610 staticpro (&Qcenter);
25611 Qline_height = intern_c_string ("line-height");
25612 staticpro (&Qline_height);
25613 QCalign_to = intern_c_string (":align-to");
25614 staticpro (&QCalign_to);
25615 QCrelative_width = intern_c_string (":relative-width");
25616 staticpro (&QCrelative_width);
25617 QCrelative_height = intern_c_string (":relative-height");
25618 staticpro (&QCrelative_height);
25619 QCeval = intern_c_string (":eval");
25620 staticpro (&QCeval);
25621 QCpropertize = intern_c_string (":propertize");
25622 staticpro (&QCpropertize);
25623 QCfile = intern_c_string (":file");
25624 staticpro (&QCfile);
25625 Qfontified = intern_c_string ("fontified");
25626 staticpro (&Qfontified);
25627 Qfontification_functions = intern_c_string ("fontification-functions");
25628 staticpro (&Qfontification_functions);
25629 Qtrailing_whitespace = intern_c_string ("trailing-whitespace");
25630 staticpro (&Qtrailing_whitespace);
25631 Qescape_glyph = intern_c_string ("escape-glyph");
25632 staticpro (&Qescape_glyph);
25633 Qnobreak_space = intern_c_string ("nobreak-space");
25634 staticpro (&Qnobreak_space);
25635 Qimage = intern_c_string ("image");
25636 staticpro (&Qimage);
25637 Qtext = intern_c_string ("text");
25638 staticpro (&Qtext);
25639 Qboth = intern_c_string ("both");
25640 staticpro (&Qboth);
25641 Qboth_horiz = intern_c_string ("both-horiz");
25642 staticpro (&Qboth_horiz);
25643 Qtext_image_horiz = intern_c_string ("text-image-horiz");
25644 staticpro (&Qtext_image_horiz);
25645 QCmap = intern_c_string (":map");
25646 staticpro (&QCmap);
25647 QCpointer = intern_c_string (":pointer");
25648 staticpro (&QCpointer);
25649 Qrect = intern_c_string ("rect");
25650 staticpro (&Qrect);
25651 Qcircle = intern_c_string ("circle");
25652 staticpro (&Qcircle);
25653 Qpoly = intern_c_string ("poly");
25654 staticpro (&Qpoly);
25655 Qmessage_truncate_lines = intern_c_string ("message-truncate-lines");
25656 staticpro (&Qmessage_truncate_lines);
25657 Qgrow_only = intern_c_string ("grow-only");
25658 staticpro (&Qgrow_only);
25659 Qinhibit_menubar_update = intern_c_string ("inhibit-menubar-update");
25660 staticpro (&Qinhibit_menubar_update);
25661 Qinhibit_eval_during_redisplay = intern_c_string ("inhibit-eval-during-redisplay");
25662 staticpro (&Qinhibit_eval_during_redisplay);
25663 Qposition = intern_c_string ("position");
25664 staticpro (&Qposition);
25665 Qbuffer_position = intern_c_string ("buffer-position");
25666 staticpro (&Qbuffer_position);
25667 Qobject = intern_c_string ("object");
25668 staticpro (&Qobject);
25669 Qbar = intern_c_string ("bar");
25670 staticpro (&Qbar);
25671 Qhbar = intern_c_string ("hbar");
25672 staticpro (&Qhbar);
25673 Qbox = intern_c_string ("box");
25674 staticpro (&Qbox);
25675 Qhollow = intern_c_string ("hollow");
25676 staticpro (&Qhollow);
25677 Qhand = intern_c_string ("hand");
25678 staticpro (&Qhand);
25679 Qarrow = intern_c_string ("arrow");
25680 staticpro (&Qarrow);
25681 Qtext = intern_c_string ("text");
25682 staticpro (&Qtext);
25683 Qrisky_local_variable = intern_c_string ("risky-local-variable");
25684 staticpro (&Qrisky_local_variable);
25685 Qinhibit_free_realized_faces = intern_c_string ("inhibit-free-realized-faces");
25686 staticpro (&Qinhibit_free_realized_faces);
25688 list_of_error = Fcons (Fcons (intern_c_string ("error"),
25689 Fcons (intern_c_string ("void-variable"), Qnil)),
25690 Qnil);
25691 staticpro (&list_of_error);
25693 Qlast_arrow_position = intern_c_string ("last-arrow-position");
25694 staticpro (&Qlast_arrow_position);
25695 Qlast_arrow_string = intern_c_string ("last-arrow-string");
25696 staticpro (&Qlast_arrow_string);
25698 Qoverlay_arrow_string = intern_c_string ("overlay-arrow-string");
25699 staticpro (&Qoverlay_arrow_string);
25700 Qoverlay_arrow_bitmap = intern_c_string ("overlay-arrow-bitmap");
25701 staticpro (&Qoverlay_arrow_bitmap);
25703 echo_buffer[0] = echo_buffer[1] = Qnil;
25704 staticpro (&echo_buffer[0]);
25705 staticpro (&echo_buffer[1]);
25707 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
25708 staticpro (&echo_area_buffer[0]);
25709 staticpro (&echo_area_buffer[1]);
25711 Vmessages_buffer_name = make_pure_c_string ("*Messages*");
25712 staticpro (&Vmessages_buffer_name);
25714 mode_line_proptrans_alist = Qnil;
25715 staticpro (&mode_line_proptrans_alist);
25716 mode_line_string_list = Qnil;
25717 staticpro (&mode_line_string_list);
25718 mode_line_string_face = Qnil;
25719 staticpro (&mode_line_string_face);
25720 mode_line_string_face_prop = Qnil;
25721 staticpro (&mode_line_string_face_prop);
25722 Vmode_line_unwind_vector = Qnil;
25723 staticpro (&Vmode_line_unwind_vector);
25725 help_echo_string = Qnil;
25726 staticpro (&help_echo_string);
25727 help_echo_object = Qnil;
25728 staticpro (&help_echo_object);
25729 help_echo_window = Qnil;
25730 staticpro (&help_echo_window);
25731 previous_help_echo_string = Qnil;
25732 staticpro (&previous_help_echo_string);
25733 help_echo_pos = -1;
25735 Qright_to_left = intern_c_string ("right-to-left");
25736 staticpro (&Qright_to_left);
25737 Qleft_to_right = intern_c_string ("left-to-right");
25738 staticpro (&Qleft_to_right);
25740 #ifdef HAVE_WINDOW_SYSTEM
25741 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p,
25742 doc: /* *Non-nil means draw block cursor as wide as the glyph under it.
25743 For example, if a block cursor is over a tab, it will be drawn as
25744 wide as that tab on the display. */);
25745 x_stretch_cursor_p = 0;
25746 #endif
25748 DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace,
25749 doc: /* *Non-nil means highlight trailing whitespace.
25750 The face used for trailing whitespace is `trailing-whitespace'. */);
25751 Vshow_trailing_whitespace = Qnil;
25753 DEFVAR_LISP ("nobreak-char-display", &Vnobreak_char_display,
25754 doc: /* *Control highlighting of nobreak space and soft hyphen.
25755 A value of t means highlight the character itself (for nobreak space,
25756 use face `nobreak-space').
25757 A value of nil means no highlighting.
25758 Other values mean display the escape glyph followed by an ordinary
25759 space or ordinary hyphen. */);
25760 Vnobreak_char_display = Qt;
25762 DEFVAR_LISP ("void-text-area-pointer", &Vvoid_text_area_pointer,
25763 doc: /* *The pointer shape to show in void text areas.
25764 A value of nil means to show the text pointer. Other options are `arrow',
25765 `text', `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
25766 Vvoid_text_area_pointer = Qarrow;
25768 DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay,
25769 doc: /* Non-nil means don't actually do any redisplay.
25770 This is used for internal purposes. */);
25771 Vinhibit_redisplay = Qnil;
25773 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string,
25774 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
25775 Vglobal_mode_string = Qnil;
25777 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position,
25778 doc: /* Marker for where to display an arrow on top of the buffer text.
25779 This must be the beginning of a line in order to work.
25780 See also `overlay-arrow-string'. */);
25781 Voverlay_arrow_position = Qnil;
25783 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string,
25784 doc: /* String to display as an arrow in non-window frames.
25785 See also `overlay-arrow-position'. */);
25786 Voverlay_arrow_string = make_pure_c_string ("=>");
25788 DEFVAR_LISP ("overlay-arrow-variable-list", &Voverlay_arrow_variable_list,
25789 doc: /* List of variables (symbols) which hold markers for overlay arrows.
25790 The symbols on this list are examined during redisplay to determine
25791 where to display overlay arrows. */);
25792 Voverlay_arrow_variable_list
25793 = Fcons (intern_c_string ("overlay-arrow-position"), Qnil);
25795 DEFVAR_INT ("scroll-step", &scroll_step,
25796 doc: /* *The number of lines to try scrolling a window by when point moves out.
25797 If that fails to bring point back on frame, point is centered instead.
25798 If this is zero, point is always centered after it moves off frame.
25799 If you want scrolling to always be a line at a time, you should set
25800 `scroll-conservatively' to a large value rather than set this to 1. */);
25802 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively,
25803 doc: /* *Scroll up to this many lines, to bring point back on screen.
25804 If point moves off-screen, redisplay will scroll by up to
25805 `scroll-conservatively' lines in order to bring point just barely
25806 onto the screen again. If that cannot be done, then redisplay
25807 recenters point as usual.
25809 A value of zero means always recenter point if it moves off screen. */);
25810 scroll_conservatively = 0;
25812 DEFVAR_INT ("scroll-margin", &scroll_margin,
25813 doc: /* *Number of lines of margin at the top and bottom of a window.
25814 Recenter the window whenever point gets within this many lines
25815 of the top or bottom of the window. */);
25816 scroll_margin = 0;
25818 DEFVAR_LISP ("display-pixels-per-inch", &Vdisplay_pixels_per_inch,
25819 doc: /* Pixels per inch value for non-window system displays.
25820 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
25821 Vdisplay_pixels_per_inch = make_float (72.0);
25823 #if GLYPH_DEBUG
25824 DEFVAR_INT ("debug-end-pos", &debug_end_pos, doc: /* Don't ask. */);
25825 #endif
25827 DEFVAR_LISP ("truncate-partial-width-windows",
25828 &Vtruncate_partial_width_windows,
25829 doc: /* Non-nil means truncate lines in windows narrower than the frame.
25830 For an integer value, truncate lines in each window narrower than the
25831 full frame width, provided the window width is less than that integer;
25832 otherwise, respect the value of `truncate-lines'.
25834 For any other non-nil value, truncate lines in all windows that do
25835 not span the full frame width.
25837 A value of nil means to respect the value of `truncate-lines'.
25839 If `word-wrap' is enabled, you might want to reduce this. */);
25840 Vtruncate_partial_width_windows = make_number (50);
25842 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video,
25843 doc: /* When nil, display the mode-line/header-line/menu-bar in the default face.
25844 Any other value means to use the appropriate face, `mode-line',
25845 `header-line', or `menu' respectively. */);
25846 mode_line_inverse_video = 1;
25848 DEFVAR_LISP ("line-number-display-limit", &Vline_number_display_limit,
25849 doc: /* *Maximum buffer size for which line number should be displayed.
25850 If the buffer is bigger than this, the line number does not appear
25851 in the mode line. A value of nil means no limit. */);
25852 Vline_number_display_limit = Qnil;
25854 DEFVAR_INT ("line-number-display-limit-width",
25855 &line_number_display_limit_width,
25856 doc: /* *Maximum line width (in characters) for line number display.
25857 If the average length of the lines near point is bigger than this, then the
25858 line number may be omitted from the mode line. */);
25859 line_number_display_limit_width = 200;
25861 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows,
25862 doc: /* *Non-nil means highlight region even in nonselected windows. */);
25863 highlight_nonselected_windows = 0;
25865 DEFVAR_BOOL ("multiple-frames", &multiple_frames,
25866 doc: /* Non-nil if more than one frame is visible on this display.
25867 Minibuffer-only frames don't count, but iconified frames do.
25868 This variable is not guaranteed to be accurate except while processing
25869 `frame-title-format' and `icon-title-format'. */);
25871 DEFVAR_LISP ("frame-title-format", &Vframe_title_format,
25872 doc: /* Template for displaying the title bar of visible frames.
25873 \(Assuming the window manager supports this feature.)
25875 This variable has the same structure as `mode-line-format', except that
25876 the %c and %l constructs are ignored. It is used only on frames for
25877 which no explicit name has been set \(see `modify-frame-parameters'). */);
25879 DEFVAR_LISP ("icon-title-format", &Vicon_title_format,
25880 doc: /* Template for displaying the title bar of an iconified frame.
25881 \(Assuming the window manager supports this feature.)
25882 This variable has the same structure as `mode-line-format' (which see),
25883 and is used only on frames for which no explicit name has been set
25884 \(see `modify-frame-parameters'). */);
25885 Vicon_title_format
25886 = Vframe_title_format
25887 = pure_cons (intern_c_string ("multiple-frames"),
25888 pure_cons (make_pure_c_string ("%b"),
25889 pure_cons (pure_cons (empty_unibyte_string,
25890 pure_cons (intern_c_string ("invocation-name"),
25891 pure_cons (make_pure_c_string ("@"),
25892 pure_cons (intern_c_string ("system-name"),
25893 Qnil)))),
25894 Qnil)));
25896 DEFVAR_LISP ("message-log-max", &Vmessage_log_max,
25897 doc: /* Maximum number of lines to keep in the message log buffer.
25898 If nil, disable message logging. If t, log messages but don't truncate
25899 the buffer when it becomes large. */);
25900 Vmessage_log_max = make_number (100);
25902 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions,
25903 doc: /* Functions called before redisplay, if window sizes have changed.
25904 The value should be a list of functions that take one argument.
25905 Just before redisplay, for each frame, if any of its windows have changed
25906 size since the last redisplay, or have been split or deleted,
25907 all the functions in the list are called, with the frame as argument. */);
25908 Vwindow_size_change_functions = Qnil;
25910 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions,
25911 doc: /* List of functions to call before redisplaying a window with scrolling.
25912 Each function is called with two arguments, the window and its new
25913 display-start position. Note that these functions are also called by
25914 `set-window-buffer'. Also note that the value of `window-end' is not
25915 valid when these functions are called. */);
25916 Vwindow_scroll_functions = Qnil;
25918 DEFVAR_LISP ("window-text-change-functions",
25919 &Vwindow_text_change_functions,
25920 doc: /* Functions to call in redisplay when text in the window might change. */);
25921 Vwindow_text_change_functions = Qnil;
25923 DEFVAR_LISP ("redisplay-end-trigger-functions", &Vredisplay_end_trigger_functions,
25924 doc: /* Functions called when redisplay of a window reaches the end trigger.
25925 Each function is called with two arguments, the window and the end trigger value.
25926 See `set-window-redisplay-end-trigger'. */);
25927 Vredisplay_end_trigger_functions = Qnil;
25929 DEFVAR_LISP ("mouse-autoselect-window", &Vmouse_autoselect_window,
25930 doc: /* *Non-nil means autoselect window with mouse pointer.
25931 If nil, do not autoselect windows.
25932 A positive number means delay autoselection by that many seconds: a
25933 window is autoselected only after the mouse has remained in that
25934 window for the duration of the delay.
25935 A negative number has a similar effect, but causes windows to be
25936 autoselected only after the mouse has stopped moving. \(Because of
25937 the way Emacs compares mouse events, you will occasionally wait twice
25938 that time before the window gets selected.\)
25939 Any other value means to autoselect window instantaneously when the
25940 mouse pointer enters it.
25942 Autoselection selects the minibuffer only if it is active, and never
25943 unselects the minibuffer if it is active.
25945 When customizing this variable make sure that the actual value of
25946 `focus-follows-mouse' matches the behavior of your window manager. */);
25947 Vmouse_autoselect_window = Qnil;
25949 DEFVAR_LISP ("auto-resize-tool-bars", &Vauto_resize_tool_bars,
25950 doc: /* *Non-nil means automatically resize tool-bars.
25951 This dynamically changes the tool-bar's height to the minimum height
25952 that is needed to make all tool-bar items visible.
25953 If value is `grow-only', the tool-bar's height is only increased
25954 automatically; to decrease the tool-bar height, use \\[recenter]. */);
25955 Vauto_resize_tool_bars = Qt;
25957 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", &auto_raise_tool_bar_buttons_p,
25958 doc: /* *Non-nil means raise tool-bar buttons when the mouse moves over them. */);
25959 auto_raise_tool_bar_buttons_p = 1;
25961 DEFVAR_BOOL ("make-cursor-line-fully-visible", &make_cursor_line_fully_visible_p,
25962 doc: /* *Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
25963 make_cursor_line_fully_visible_p = 1;
25965 DEFVAR_LISP ("tool-bar-border", &Vtool_bar_border,
25966 doc: /* *Border below tool-bar in pixels.
25967 If an integer, use it as the height of the border.
25968 If it is one of `internal-border-width' or `border-width', use the
25969 value of the corresponding frame parameter.
25970 Otherwise, no border is added below the tool-bar. */);
25971 Vtool_bar_border = Qinternal_border_width;
25973 DEFVAR_LISP ("tool-bar-button-margin", &Vtool_bar_button_margin,
25974 doc: /* *Margin around tool-bar buttons in pixels.
25975 If an integer, use that for both horizontal and vertical margins.
25976 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
25977 HORZ specifying the horizontal margin, and VERT specifying the
25978 vertical margin. */);
25979 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
25981 DEFVAR_INT ("tool-bar-button-relief", &tool_bar_button_relief,
25982 doc: /* *Relief thickness of tool-bar buttons. */);
25983 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
25985 DEFVAR_LISP ("tool-bar-style", &Vtool_bar_style,
25986 doc: /* *Tool bar style to use.
25987 It can be one of
25988 image - show images only
25989 text - show text only
25990 both - show both, text below image
25991 both-horiz - show text to the right of the image
25992 text-image-horiz - show text to the left of the image
25993 any other - use system default or image if no system default. */);
25994 Vtool_bar_style = Qnil;
25996 DEFVAR_INT ("tool-bar-max-label-size", &tool_bar_max_label_size,
25997 doc: /* *Maximum number of characters a label can have to be shown.
25998 The tool bar style must also show labels for this to have any effect, see
25999 `tool-bar-style'. */);
26000 tool_bar_max_label_size = DEFAULT_TOOL_BAR_LABEL_SIZE;
26002 DEFVAR_LISP ("fontification-functions", &Vfontification_functions,
26003 doc: /* List of functions to call to fontify regions of text.
26004 Each function is called with one argument POS. Functions must
26005 fontify a region starting at POS in the current buffer, and give
26006 fontified regions the property `fontified'. */);
26007 Vfontification_functions = Qnil;
26008 Fmake_variable_buffer_local (Qfontification_functions);
26010 DEFVAR_BOOL ("unibyte-display-via-language-environment",
26011 &unibyte_display_via_language_environment,
26012 doc: /* *Non-nil means display unibyte text according to language environment.
26013 Specifically, this means that raw bytes in the range 160-255 decimal
26014 are displayed by converting them to the equivalent multibyte characters
26015 according to the current language environment. As a result, they are
26016 displayed according to the current fontset.
26018 Note that this variable affects only how these bytes are displayed,
26019 but does not change the fact they are interpreted as raw bytes. */);
26020 unibyte_display_via_language_environment = 0;
26022 DEFVAR_LISP ("max-mini-window-height", &Vmax_mini_window_height,
26023 doc: /* *Maximum height for resizing mini-windows.
26024 If a float, it specifies a fraction of the mini-window frame's height.
26025 If an integer, it specifies a number of lines. */);
26026 Vmax_mini_window_height = make_float (0.25);
26028 DEFVAR_LISP ("resize-mini-windows", &Vresize_mini_windows,
26029 doc: /* *How to resize mini-windows.
26030 A value of nil means don't automatically resize mini-windows.
26031 A value of t means resize them to fit the text displayed in them.
26032 A value of `grow-only', the default, means let mini-windows grow
26033 only, until their display becomes empty, at which point the windows
26034 go back to their normal size. */);
26035 Vresize_mini_windows = Qgrow_only;
26037 DEFVAR_LISP ("blink-cursor-alist", &Vblink_cursor_alist,
26038 doc: /* Alist specifying how to blink the cursor off.
26039 Each element has the form (ON-STATE . OFF-STATE). Whenever the
26040 `cursor-type' frame-parameter or variable equals ON-STATE,
26041 comparing using `equal', Emacs uses OFF-STATE to specify
26042 how to blink it off. ON-STATE and OFF-STATE are values for
26043 the `cursor-type' frame parameter.
26045 If a frame's ON-STATE has no entry in this list,
26046 the frame's other specifications determine how to blink the cursor off. */);
26047 Vblink_cursor_alist = Qnil;
26049 DEFVAR_BOOL ("auto-hscroll-mode", &automatic_hscrolling_p,
26050 doc: /* *Non-nil means scroll the display automatically to make point visible. */);
26051 automatic_hscrolling_p = 1;
26052 Qauto_hscroll_mode = intern_c_string ("auto-hscroll-mode");
26053 staticpro (&Qauto_hscroll_mode);
26055 DEFVAR_INT ("hscroll-margin", &hscroll_margin,
26056 doc: /* *How many columns away from the window edge point is allowed to get
26057 before automatic hscrolling will horizontally scroll the window. */);
26058 hscroll_margin = 5;
26060 DEFVAR_LISP ("hscroll-step", &Vhscroll_step,
26061 doc: /* *How many columns to scroll the window when point gets too close to the edge.
26062 When point is less than `hscroll-margin' columns from the window
26063 edge, automatic hscrolling will scroll the window by the amount of columns
26064 determined by this variable. If its value is a positive integer, scroll that
26065 many columns. If it's a positive floating-point number, it specifies the
26066 fraction of the window's width to scroll. If it's nil or zero, point will be
26067 centered horizontally after the scroll. Any other value, including negative
26068 numbers, are treated as if the value were zero.
26070 Automatic hscrolling always moves point outside the scroll margin, so if
26071 point was more than scroll step columns inside the margin, the window will
26072 scroll more than the value given by the scroll step.
26074 Note that the lower bound for automatic hscrolling specified by `scroll-left'
26075 and `scroll-right' overrides this variable's effect. */);
26076 Vhscroll_step = make_number (0);
26078 DEFVAR_BOOL ("message-truncate-lines", &message_truncate_lines,
26079 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
26080 Bind this around calls to `message' to let it take effect. */);
26081 message_truncate_lines = 0;
26083 DEFVAR_LISP ("menu-bar-update-hook", &Vmenu_bar_update_hook,
26084 doc: /* Normal hook run to update the menu bar definitions.
26085 Redisplay runs this hook before it redisplays the menu bar.
26086 This is used to update submenus such as Buffers,
26087 whose contents depend on various data. */);
26088 Vmenu_bar_update_hook = Qnil;
26090 DEFVAR_LISP ("menu-updating-frame", &Vmenu_updating_frame,
26091 doc: /* Frame for which we are updating a menu.
26092 The enable predicate for a menu binding should check this variable. */);
26093 Vmenu_updating_frame = Qnil;
26095 DEFVAR_BOOL ("inhibit-menubar-update", &inhibit_menubar_update,
26096 doc: /* Non-nil means don't update menu bars. Internal use only. */);
26097 inhibit_menubar_update = 0;
26099 DEFVAR_LISP ("wrap-prefix", &Vwrap_prefix,
26100 doc: /* Prefix prepended to all continuation lines at display time.
26101 The value may be a string, an image, or a stretch-glyph; it is
26102 interpreted in the same way as the value of a `display' text property.
26104 This variable is overridden by any `wrap-prefix' text or overlay
26105 property.
26107 To add a prefix to non-continuation lines, use `line-prefix'. */);
26108 Vwrap_prefix = Qnil;
26109 staticpro (&Qwrap_prefix);
26110 Qwrap_prefix = intern_c_string ("wrap-prefix");
26111 Fmake_variable_buffer_local (Qwrap_prefix);
26113 DEFVAR_LISP ("line-prefix", &Vline_prefix,
26114 doc: /* Prefix prepended to all non-continuation lines at display time.
26115 The value may be a string, an image, or a stretch-glyph; it is
26116 interpreted in the same way as the value of a `display' text property.
26118 This variable is overridden by any `line-prefix' text or overlay
26119 property.
26121 To add a prefix to continuation lines, use `wrap-prefix'. */);
26122 Vline_prefix = Qnil;
26123 staticpro (&Qline_prefix);
26124 Qline_prefix = intern_c_string ("line-prefix");
26125 Fmake_variable_buffer_local (Qline_prefix);
26127 DEFVAR_BOOL ("inhibit-eval-during-redisplay", &inhibit_eval_during_redisplay,
26128 doc: /* Non-nil means don't eval Lisp during redisplay. */);
26129 inhibit_eval_during_redisplay = 0;
26131 DEFVAR_BOOL ("inhibit-free-realized-faces", &inhibit_free_realized_faces,
26132 doc: /* Non-nil means don't free realized faces. Internal use only. */);
26133 inhibit_free_realized_faces = 0;
26135 #if GLYPH_DEBUG
26136 DEFVAR_BOOL ("inhibit-try-window-id", &inhibit_try_window_id,
26137 doc: /* Inhibit try_window_id display optimization. */);
26138 inhibit_try_window_id = 0;
26140 DEFVAR_BOOL ("inhibit-try-window-reusing", &inhibit_try_window_reusing,
26141 doc: /* Inhibit try_window_reusing display optimization. */);
26142 inhibit_try_window_reusing = 0;
26144 DEFVAR_BOOL ("inhibit-try-cursor-movement", &inhibit_try_cursor_movement,
26145 doc: /* Inhibit try_cursor_movement display optimization. */);
26146 inhibit_try_cursor_movement = 0;
26147 #endif /* GLYPH_DEBUG */
26149 DEFVAR_INT ("overline-margin", &overline_margin,
26150 doc: /* *Space between overline and text, in pixels.
26151 The default value is 2: the height of the overline (1 pixel) plus 1 pixel
26152 margin to the caracter height. */);
26153 overline_margin = 2;
26155 DEFVAR_INT ("underline-minimum-offset",
26156 &underline_minimum_offset,
26157 doc: /* Minimum distance between baseline and underline.
26158 This can improve legibility of underlined text at small font sizes,
26159 particularly when using variable `x-use-underline-position-properties'
26160 with fonts that specify an UNDERLINE_POSITION relatively close to the
26161 baseline. The default value is 1. */);
26162 underline_minimum_offset = 1;
26164 DEFVAR_BOOL ("display-hourglass", &display_hourglass_p,
26165 doc: /* Non-zero means Emacs displays an hourglass pointer on window systems. */);
26166 display_hourglass_p = 1;
26168 DEFVAR_LISP ("hourglass-delay", &Vhourglass_delay,
26169 doc: /* *Seconds to wait before displaying an hourglass pointer.
26170 Value must be an integer or float. */);
26171 Vhourglass_delay = make_number (DEFAULT_HOURGLASS_DELAY);
26173 hourglass_atimer = NULL;
26174 hourglass_shown_p = 0;
26178 /* Initialize this module when Emacs starts. */
26180 void
26181 init_xdisp (void)
26183 Lisp_Object root_window;
26184 struct window *mini_w;
26186 current_header_line_height = current_mode_line_height = -1;
26188 CHARPOS (this_line_start_pos) = 0;
26190 mini_w = XWINDOW (minibuf_window);
26191 root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w)));
26193 if (!noninteractive)
26195 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (root_window)));
26196 int i;
26198 XWINDOW (root_window)->top_line = make_number (FRAME_TOP_MARGIN (f));
26199 set_window_height (root_window,
26200 FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f),
26202 mini_w->top_line = make_number (FRAME_LINES (f) - 1);
26203 set_window_height (minibuf_window, 1, 0);
26205 XWINDOW (root_window)->total_cols = make_number (FRAME_COLS (f));
26206 mini_w->total_cols = make_number (FRAME_COLS (f));
26208 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
26209 scratch_glyph_row.glyphs[TEXT_AREA + 1]
26210 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
26212 /* The default ellipsis glyphs `...'. */
26213 for (i = 0; i < 3; ++i)
26214 default_invis_vector[i] = make_number ('.');
26218 /* Allocate the buffer for frame titles.
26219 Also used for `format-mode-line'. */
26220 int size = 100;
26221 mode_line_noprop_buf = (char *) xmalloc (size);
26222 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
26223 mode_line_noprop_ptr = mode_line_noprop_buf;
26224 mode_line_target = MODE_LINE_DISPLAY;
26227 help_echo_showing_p = 0;
26230 /* Since w32 does not support atimers, it defines its own implementation of
26231 the following three functions in w32fns.c. */
26232 #ifndef WINDOWSNT
26234 /* Platform-independent portion of hourglass implementation. */
26236 /* Return non-zero if houglass timer has been started or hourglass is shown. */
26238 hourglass_started (void)
26240 return hourglass_shown_p || hourglass_atimer != NULL;
26243 /* Cancel a currently active hourglass timer, and start a new one. */
26244 void
26245 start_hourglass (void)
26247 #if defined (HAVE_WINDOW_SYSTEM)
26248 EMACS_TIME delay;
26249 int secs, usecs = 0;
26251 cancel_hourglass ();
26253 if (INTEGERP (Vhourglass_delay)
26254 && XINT (Vhourglass_delay) > 0)
26255 secs = XFASTINT (Vhourglass_delay);
26256 else if (FLOATP (Vhourglass_delay)
26257 && XFLOAT_DATA (Vhourglass_delay) > 0)
26259 Lisp_Object tem;
26260 tem = Ftruncate (Vhourglass_delay, Qnil);
26261 secs = XFASTINT (tem);
26262 usecs = (XFLOAT_DATA (Vhourglass_delay) - secs) * 1000000;
26264 else
26265 secs = DEFAULT_HOURGLASS_DELAY;
26267 EMACS_SET_SECS_USECS (delay, secs, usecs);
26268 hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
26269 show_hourglass, NULL);
26270 #endif
26274 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
26275 shown. */
26276 void
26277 cancel_hourglass (void)
26279 #if defined (HAVE_WINDOW_SYSTEM)
26280 if (hourglass_atimer)
26282 cancel_atimer (hourglass_atimer);
26283 hourglass_atimer = NULL;
26286 if (hourglass_shown_p)
26287 hide_hourglass ();
26288 #endif
26290 #endif /* ! WINDOWSNT */
26292 /* arch-tag: eacc864d-bb6a-4b74-894a-1a4399a1358b
26293 (do not change this comment) */