*** empty log message ***
[emacs.git] / src / xdisp.c
blobccce95b9d10768b4f31f60ed205066d8afe8e122
1 /* Display generation from window structure and buffer text.
2 Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
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. (Or,
36 let's say almost---see the description of direct update
37 operations, below.)
39 The following diagram shows how redisplay code is invoked. As you
40 can see, Lisp calls redisplay and vice versa. Under window systems
41 like X, some portions of the redisplay code are also called
42 asynchronously during mouse movement or expose events. It is very
43 important that these code parts do NOT use the C library (malloc,
44 free) because many C libraries under Unix are not reentrant. They
45 may also NOT call functions of the Lisp interpreter which could
46 change the interpreter's state. If you don't follow these rules,
47 you will encounter bugs which are very hard to explain.
49 (Direct functions, see below)
50 direct_output_for_insert,
51 direct_forward_char (dispnew.c)
52 +---------------------------------+
53 | |
54 | V
55 +--------------+ redisplay +----------------+
56 | Lisp machine |---------------->| Redisplay code |<--+
57 +--------------+ (xdisp.c) +----------------+ |
58 ^ | |
59 +----------------------------------+ |
60 Don't use this path when called |
61 asynchronously! |
63 expose_window (asynchronous) |
65 X expose events -----+
67 What does redisplay do? Obviously, it has to figure out somehow what
68 has been changed since the last time the display has been updated,
69 and to make these changes visible. Preferably it would do that in
70 a moderately intelligent way, i.e. fast.
72 Changes in buffer text can be deduced from window and buffer
73 structures, and from some global variables like `beg_unchanged' and
74 `end_unchanged'. The contents of the display are additionally
75 recorded in a `glyph matrix', a two-dimensional matrix of glyph
76 structures. Each row in such a matrix corresponds to a line on the
77 display, and each glyph in a row corresponds to a column displaying
78 a character, an image, or what else. This matrix is called the
79 `current glyph matrix' or `current matrix' in redisplay
80 terminology.
82 For buffer parts that have been changed since the last update, a
83 second glyph matrix is constructed, the so called `desired glyph
84 matrix' or short `desired matrix'. Current and desired matrix are
85 then compared to find a cheap way to update the display, e.g. by
86 reusing part of the display by scrolling lines.
89 Direct operations.
91 You will find a lot of redisplay optimizations when you start
92 looking at the innards of redisplay. The overall goal of all these
93 optimizations is to make redisplay fast because it is done
94 frequently.
96 Two optimizations are not found in xdisp.c. These are the direct
97 operations mentioned above. As the name suggests they follow a
98 different principle than the rest of redisplay. Instead of
99 building a desired matrix and then comparing it with the current
100 display, they perform their actions directly on the display and on
101 the current matrix.
103 One direct operation updates the display after one character has
104 been entered. The other one moves the cursor by one position
105 forward or backward. You find these functions under the names
106 `direct_output_for_insert' and `direct_output_forward_char' in
107 dispnew.c.
110 Desired matrices.
112 Desired matrices are always built per Emacs window. The function
113 `display_line' is the central function to look at if you are
114 interested. It constructs one row in a desired matrix given an
115 iterator structure containing both a buffer position and a
116 description of the environment in which the text is to be
117 displayed. But this is too early, read on.
119 Characters and pixmaps displayed for a range of buffer text depend
120 on various settings of buffers and windows, on overlays and text
121 properties, on display tables, on selective display. The good news
122 is that all this hairy stuff is hidden behind a small set of
123 interface functions taking an iterator structure (struct it)
124 argument.
126 Iteration over things to be displayed is then simple. It is
127 started by initializing an iterator with a call to init_iterator.
128 Calls to get_next_display_element fill the iterator structure with
129 relevant information about the next thing to display. Calls to
130 set_iterator_to_next move the iterator to the next thing.
132 Besides this, an iterator also contains information about the
133 display environment in which glyphs for display elements are to be
134 produced. It has fields for the width and height of the display,
135 the information whether long lines are truncated or continued, a
136 current X and Y position, and lots of other stuff you can better
137 see in dispextern.h.
139 Glyphs in a desired matrix are normally constructed in a loop
140 calling get_next_display_element and then produce_glyphs. The call
141 to produce_glyphs will fill the iterator structure with pixel
142 information about the element being displayed and at the same time
143 produce glyphs for it. If the display element fits on the line
144 being displayed, set_iterator_to_next is called next, otherwise the
145 glyphs produced are discarded.
148 Frame matrices.
150 That just couldn't be all, could it? What about terminal types not
151 supporting operations on sub-windows of the screen? To update the
152 display on such a terminal, window-based glyph matrices are not
153 well suited. To be able to reuse part of the display (scrolling
154 lines up and down), we must instead have a view of the whole
155 screen. This is what `frame matrices' are for. They are a trick.
157 Frames on terminals like above have a glyph pool. Windows on such
158 a frame sub-allocate their glyph memory from their frame's glyph
159 pool. The frame itself is given its own glyph matrices. By
160 coincidence---or maybe something else---rows in window glyph
161 matrices are slices of corresponding rows in frame matrices. Thus
162 writing to window matrices implicitly updates a frame matrix which
163 provides us with the view of the whole screen that we originally
164 wanted to have without having to move many bytes around. To be
165 honest, there is a little bit more done, but not much more. If you
166 plan to extend that code, take a look at dispnew.c. The function
167 build_frame_matrix is a good starting point. */
169 #include <config.h>
170 #include <stdio.h>
172 #include "lisp.h"
173 #include "keyboard.h"
174 #include "frame.h"
175 #include "window.h"
176 #include "termchar.h"
177 #include "dispextern.h"
178 #include "buffer.h"
179 #include "charset.h"
180 #include "indent.h"
181 #include "commands.h"
182 #include "keymap.h"
183 #include "macros.h"
184 #include "disptab.h"
185 #include "termhooks.h"
186 #include "intervals.h"
187 #include "coding.h"
188 #include "process.h"
189 #include "region-cache.h"
190 #include "fontset.h"
191 #include "blockinput.h"
193 #ifdef HAVE_X_WINDOWS
194 #include "xterm.h"
195 #endif
196 #ifdef WINDOWSNT
197 #include "w32term.h"
198 #endif
199 #ifdef MAC_OS
200 #include "macterm.h"
201 #endif
203 #ifndef FRAME_X_OUTPUT
204 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
205 #endif
207 #define INFINITY 10000000
209 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
210 || defined (USE_GTK)
211 extern void set_frame_menubar P_ ((struct frame *f, int, int));
212 extern int pending_menu_activation;
213 #endif
215 extern int interrupt_input;
216 extern int command_loop_level;
218 extern Lisp_Object do_mouse_tracking;
220 extern int minibuffer_auto_raise;
221 extern Lisp_Object Vminibuffer_list;
223 extern Lisp_Object Qface;
224 extern Lisp_Object Qmode_line, Qmode_line_inactive, Qheader_line;
226 extern Lisp_Object Voverriding_local_map;
227 extern Lisp_Object Voverriding_local_map_menu_flag;
228 extern Lisp_Object Qmenu_item;
229 extern Lisp_Object Qwhen;
230 extern Lisp_Object Qhelp_echo;
232 Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
233 Lisp_Object Qwindow_scroll_functions, Vwindow_scroll_functions;
234 Lisp_Object Qredisplay_end_trigger_functions;
235 Lisp_Object Qinhibit_point_motion_hooks;
236 Lisp_Object QCeval, QCfile, QCdata, QCpropertize;
237 Lisp_Object Qfontified;
238 Lisp_Object Qgrow_only;
239 Lisp_Object Qinhibit_eval_during_redisplay;
240 Lisp_Object Qbuffer_position, Qposition, Qobject;
242 /* Cursor shapes */
243 Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
245 /* Pointer shapes */
246 Lisp_Object Qarrow, Qhand, Qtext;
248 Lisp_Object Qrisky_local_variable;
250 /* Holds the list (error). */
251 Lisp_Object list_of_error;
253 /* Functions called to fontify regions of text. */
255 Lisp_Object Vfontification_functions;
256 Lisp_Object Qfontification_functions;
258 /* Non-zero means automatically select any window when the mouse
259 cursor moves into it. */
260 int mouse_autoselect_window;
262 /* Non-zero means draw tool bar buttons raised when the mouse moves
263 over them. */
265 int auto_raise_tool_bar_buttons_p;
267 /* Non-zero means to reposition window if cursor line is only partially visible. */
269 int make_cursor_line_fully_visible_p;
271 /* Margin around tool bar buttons in pixels. */
273 Lisp_Object Vtool_bar_button_margin;
275 /* Thickness of shadow to draw around tool bar buttons. */
277 EMACS_INT tool_bar_button_relief;
279 /* Non-zero means automatically resize tool-bars so that all tool-bar
280 items are visible, and no blank lines remain. */
282 int auto_resize_tool_bars_p;
284 /* Non-zero means draw block and hollow cursor as wide as the glyph
285 under it. For example, if a block cursor is over a tab, it will be
286 drawn as wide as that tab on the display. */
288 int x_stretch_cursor_p;
290 /* Non-nil means don't actually do any redisplay. */
292 Lisp_Object Vinhibit_redisplay, Qinhibit_redisplay;
294 /* Non-zero means Lisp evaluation during redisplay is inhibited. */
296 int inhibit_eval_during_redisplay;
298 /* Names of text properties relevant for redisplay. */
300 Lisp_Object Qdisplay;
301 extern Lisp_Object Qface, Qinvisible, Qwidth;
303 /* Symbols used in text property values. */
305 Lisp_Object Vdisplay_pixels_per_inch;
306 Lisp_Object Qspace, QCalign_to, QCrelative_width, QCrelative_height;
307 Lisp_Object Qleft_margin, Qright_margin, Qspace_width, Qraise;
308 Lisp_Object Qslice;
309 Lisp_Object Qcenter;
310 Lisp_Object Qmargin, Qpointer;
311 Lisp_Object Qline_height;
312 extern Lisp_Object Qheight;
313 extern Lisp_Object QCwidth, QCheight, QCascent;
314 extern Lisp_Object Qscroll_bar;
315 extern Lisp_Object Qcursor;
317 /* Non-nil means highlight trailing whitespace. */
319 Lisp_Object Vshow_trailing_whitespace;
321 /* Non-nil means escape non-break space and hyphens. */
323 Lisp_Object Vshow_nonbreak_escape;
325 #ifdef HAVE_WINDOW_SYSTEM
326 extern Lisp_Object Voverflow_newline_into_fringe;
328 /* Test if overflow newline into fringe. Called with iterator IT
329 at or past right window margin, and with IT->current_x set. */
331 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) \
332 (!NILP (Voverflow_newline_into_fringe) \
333 && FRAME_WINDOW_P (it->f) \
334 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) > 0 \
335 && it->current_x == it->last_visible_x)
337 #endif /* HAVE_WINDOW_SYSTEM */
339 /* Non-nil means show the text cursor in void text areas
340 i.e. in blank areas after eol and eob. This used to be
341 the default in 21.3. */
343 Lisp_Object Vvoid_text_area_pointer;
345 /* Name of the face used to highlight trailing whitespace. */
347 Lisp_Object Qtrailing_whitespace;
349 /* Name and number of the face used to highlight escape glyphs. */
351 Lisp_Object Qescape_glyph;
353 /* The symbol `image' which is the car of the lists used to represent
354 images in Lisp. */
356 Lisp_Object Qimage;
358 /* The image map types. */
359 Lisp_Object QCmap, QCpointer;
360 Lisp_Object Qrect, Qcircle, Qpoly;
362 /* Non-zero means print newline to stdout before next mini-buffer
363 message. */
365 int noninteractive_need_newline;
367 /* Non-zero means print newline to message log before next message. */
369 static int message_log_need_newline;
371 /* Three markers that message_dolog uses.
372 It could allocate them itself, but that causes trouble
373 in handling memory-full errors. */
374 static Lisp_Object message_dolog_marker1;
375 static Lisp_Object message_dolog_marker2;
376 static Lisp_Object message_dolog_marker3;
378 /* The buffer position of the first character appearing entirely or
379 partially on the line of the selected window which contains the
380 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
381 redisplay optimization in redisplay_internal. */
383 static struct text_pos this_line_start_pos;
385 /* Number of characters past the end of the line above, including the
386 terminating newline. */
388 static struct text_pos this_line_end_pos;
390 /* The vertical positions and the height of this line. */
392 static int this_line_vpos;
393 static int this_line_y;
394 static int this_line_pixel_height;
396 /* X position at which this display line starts. Usually zero;
397 negative if first character is partially visible. */
399 static int this_line_start_x;
401 /* Buffer that this_line_.* variables are referring to. */
403 static struct buffer *this_line_buffer;
405 /* Nonzero means truncate lines in all windows less wide than the
406 frame. */
408 int truncate_partial_width_windows;
410 /* A flag to control how to display unibyte 8-bit character. */
412 int unibyte_display_via_language_environment;
414 /* Nonzero means we have more than one non-mini-buffer-only frame.
415 Not guaranteed to be accurate except while parsing
416 frame-title-format. */
418 int multiple_frames;
420 Lisp_Object Vglobal_mode_string;
423 /* List of variables (symbols) which hold markers for overlay arrows.
424 The symbols on this list are examined during redisplay to determine
425 where to display overlay arrows. */
427 Lisp_Object Voverlay_arrow_variable_list;
429 /* Marker for where to display an arrow on top of the buffer text. */
431 Lisp_Object Voverlay_arrow_position;
433 /* String to display for the arrow. Only used on terminal frames. */
435 Lisp_Object Voverlay_arrow_string;
437 /* Values of those variables at last redisplay are stored as
438 properties on `overlay-arrow-position' symbol. However, if
439 Voverlay_arrow_position is a marker, last-arrow-position is its
440 numerical position. */
442 Lisp_Object Qlast_arrow_position, Qlast_arrow_string;
444 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
445 properties on a symbol in overlay-arrow-variable-list. */
447 Lisp_Object Qoverlay_arrow_string, Qoverlay_arrow_bitmap;
449 /* Like mode-line-format, but for the title bar on a visible frame. */
451 Lisp_Object Vframe_title_format;
453 /* Like mode-line-format, but for the title bar on an iconified frame. */
455 Lisp_Object Vicon_title_format;
457 /* List of functions to call when a window's size changes. These
458 functions get one arg, a frame on which one or more windows' sizes
459 have changed. */
461 static Lisp_Object Vwindow_size_change_functions;
463 Lisp_Object Qmenu_bar_update_hook, Vmenu_bar_update_hook;
465 /* Nonzero if an overlay arrow has been displayed in this window. */
467 static int overlay_arrow_seen;
469 /* Nonzero means highlight the region even in nonselected windows. */
471 int highlight_nonselected_windows;
473 /* If cursor motion alone moves point off frame, try scrolling this
474 many lines up or down if that will bring it back. */
476 static EMACS_INT scroll_step;
478 /* Nonzero means scroll just far enough to bring point back on the
479 screen, when appropriate. */
481 static EMACS_INT scroll_conservatively;
483 /* Recenter the window whenever point gets within this many lines of
484 the top or bottom of the window. This value is translated into a
485 pixel value by multiplying it with FRAME_LINE_HEIGHT, which means
486 that there is really a fixed pixel height scroll margin. */
488 EMACS_INT scroll_margin;
490 /* Number of windows showing the buffer of the selected window (or
491 another buffer with the same base buffer). keyboard.c refers to
492 this. */
494 int buffer_shared;
496 /* Vector containing glyphs for an ellipsis `...'. */
498 static Lisp_Object default_invis_vector[3];
500 /* Zero means display the mode-line/header-line/menu-bar in the default face
501 (this slightly odd definition is for compatibility with previous versions
502 of emacs), non-zero means display them using their respective faces.
504 This variable is deprecated. */
506 int mode_line_inverse_video;
508 /* Prompt to display in front of the mini-buffer contents. */
510 Lisp_Object minibuf_prompt;
512 /* Width of current mini-buffer prompt. Only set after display_line
513 of the line that contains the prompt. */
515 int minibuf_prompt_width;
517 /* This is the window where the echo area message was displayed. It
518 is always a mini-buffer window, but it may not be the same window
519 currently active as a mini-buffer. */
521 Lisp_Object echo_area_window;
523 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
524 pushes the current message and the value of
525 message_enable_multibyte on the stack, the function restore_message
526 pops the stack and displays MESSAGE again. */
528 Lisp_Object Vmessage_stack;
530 /* Nonzero means multibyte characters were enabled when the echo area
531 message was specified. */
533 int message_enable_multibyte;
535 /* Nonzero if we should redraw the mode lines on the next redisplay. */
537 int update_mode_lines;
539 /* Nonzero if window sizes or contents have changed since last
540 redisplay that finished. */
542 int windows_or_buffers_changed;
544 /* Nonzero means a frame's cursor type has been changed. */
546 int cursor_type_changed;
548 /* Nonzero after display_mode_line if %l was used and it displayed a
549 line number. */
551 int line_number_displayed;
553 /* Maximum buffer size for which to display line numbers. */
555 Lisp_Object Vline_number_display_limit;
557 /* Line width to consider when repositioning for line number display. */
559 static EMACS_INT line_number_display_limit_width;
561 /* Number of lines to keep in the message log buffer. t means
562 infinite. nil means don't log at all. */
564 Lisp_Object Vmessage_log_max;
566 /* The name of the *Messages* buffer, a string. */
568 static Lisp_Object Vmessages_buffer_name;
570 /* Index 0 is the buffer that holds the current (desired) echo area message,
571 or nil if none is desired right now.
573 Index 1 is the buffer that holds the previously displayed echo area message,
574 or nil to indicate no message. This is normally what's on the screen now.
576 These two can point to the same buffer. That happens when the last
577 message output by the user (or made by echoing) has been displayed. */
579 Lisp_Object echo_area_buffer[2];
581 /* Permanent pointers to the two buffers that are used for echo area
582 purposes. Once the two buffers are made, and their pointers are
583 placed here, these two slots remain unchanged unless those buffers
584 need to be created afresh. */
586 static Lisp_Object echo_buffer[2];
588 /* A vector saved used in with_area_buffer to reduce consing. */
590 static Lisp_Object Vwith_echo_area_save_vector;
592 /* Non-zero means display_echo_area should display the last echo area
593 message again. Set by redisplay_preserve_echo_area. */
595 static int display_last_displayed_message_p;
597 /* Nonzero if echo area is being used by print; zero if being used by
598 message. */
600 int message_buf_print;
602 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
604 Lisp_Object Qinhibit_menubar_update;
605 int inhibit_menubar_update;
607 /* Maximum height for resizing mini-windows. Either a float
608 specifying a fraction of the available height, or an integer
609 specifying a number of lines. */
611 Lisp_Object Vmax_mini_window_height;
613 /* Non-zero means messages should be displayed with truncated
614 lines instead of being continued. */
616 int message_truncate_lines;
617 Lisp_Object Qmessage_truncate_lines;
619 /* Set to 1 in clear_message to make redisplay_internal aware
620 of an emptied echo area. */
622 static int message_cleared_p;
624 /* Non-zero means we want a hollow cursor in windows that are not
625 selected. Zero means there's no cursor in such windows. */
627 Lisp_Object Vcursor_in_non_selected_windows;
628 Lisp_Object Qcursor_in_non_selected_windows;
630 /* How to blink the default frame cursor off. */
631 Lisp_Object Vblink_cursor_alist;
633 /* A scratch glyph row with contents used for generating truncation
634 glyphs. Also used in direct_output_for_insert. */
636 #define MAX_SCRATCH_GLYPHS 100
637 struct glyph_row scratch_glyph_row;
638 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
640 /* Ascent and height of the last line processed by move_it_to. */
642 static int last_max_ascent, last_height;
644 /* Non-zero if there's a help-echo in the echo area. */
646 int help_echo_showing_p;
648 /* If >= 0, computed, exact values of mode-line and header-line height
649 to use in the macros CURRENT_MODE_LINE_HEIGHT and
650 CURRENT_HEADER_LINE_HEIGHT. */
652 int current_mode_line_height, current_header_line_height;
654 /* The maximum distance to look ahead for text properties. Values
655 that are too small let us call compute_char_face and similar
656 functions too often which is expensive. Values that are too large
657 let us call compute_char_face and alike too often because we
658 might not be interested in text properties that far away. */
660 #define TEXT_PROP_DISTANCE_LIMIT 100
662 #if GLYPH_DEBUG
664 /* Variables to turn off display optimizations from Lisp. */
666 int inhibit_try_window_id, inhibit_try_window_reusing;
667 int inhibit_try_cursor_movement;
669 /* Non-zero means print traces of redisplay if compiled with
670 GLYPH_DEBUG != 0. */
672 int trace_redisplay_p;
674 #endif /* GLYPH_DEBUG */
676 #ifdef DEBUG_TRACE_MOVE
677 /* Non-zero means trace with TRACE_MOVE to stderr. */
678 int trace_move;
680 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
681 #else
682 #define TRACE_MOVE(x) (void) 0
683 #endif
685 /* Non-zero means automatically scroll windows horizontally to make
686 point visible. */
688 int automatic_hscrolling_p;
690 /* How close to the margin can point get before the window is scrolled
691 horizontally. */
692 EMACS_INT hscroll_margin;
694 /* How much to scroll horizontally when point is inside the above margin. */
695 Lisp_Object Vhscroll_step;
697 /* The variable `resize-mini-windows'. If nil, don't resize
698 mini-windows. If t, always resize them to fit the text they
699 display. If `grow-only', let mini-windows grow only until they
700 become empty. */
702 Lisp_Object Vresize_mini_windows;
704 /* Buffer being redisplayed -- for redisplay_window_error. */
706 struct buffer *displayed_buffer;
708 /* Value returned from text property handlers (see below). */
710 enum prop_handled
712 HANDLED_NORMALLY,
713 HANDLED_RECOMPUTE_PROPS,
714 HANDLED_OVERLAY_STRING_CONSUMED,
715 HANDLED_RETURN
718 /* A description of text properties that redisplay is interested
719 in. */
721 struct props
723 /* The name of the property. */
724 Lisp_Object *name;
726 /* A unique index for the property. */
727 enum prop_idx idx;
729 /* A handler function called to set up iterator IT from the property
730 at IT's current position. Value is used to steer handle_stop. */
731 enum prop_handled (*handler) P_ ((struct it *it));
734 static enum prop_handled handle_face_prop P_ ((struct it *));
735 static enum prop_handled handle_invisible_prop P_ ((struct it *));
736 static enum prop_handled handle_display_prop P_ ((struct it *));
737 static enum prop_handled handle_composition_prop P_ ((struct it *));
738 static enum prop_handled handle_overlay_change P_ ((struct it *));
739 static enum prop_handled handle_fontified_prop P_ ((struct it *));
741 /* Properties handled by iterators. */
743 static struct props it_props[] =
745 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
746 /* Handle `face' before `display' because some sub-properties of
747 `display' need to know the face. */
748 {&Qface, FACE_PROP_IDX, handle_face_prop},
749 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
750 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
751 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
752 {NULL, 0, NULL}
755 /* Value is the position described by X. If X is a marker, value is
756 the marker_position of X. Otherwise, value is X. */
758 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
760 /* Enumeration returned by some move_it_.* functions internally. */
762 enum move_it_result
764 /* Not used. Undefined value. */
765 MOVE_UNDEFINED,
767 /* Move ended at the requested buffer position or ZV. */
768 MOVE_POS_MATCH_OR_ZV,
770 /* Move ended at the requested X pixel position. */
771 MOVE_X_REACHED,
773 /* Move within a line ended at the end of a line that must be
774 continued. */
775 MOVE_LINE_CONTINUED,
777 /* Move within a line ended at the end of a line that would
778 be displayed truncated. */
779 MOVE_LINE_TRUNCATED,
781 /* Move within a line ended at a line end. */
782 MOVE_NEWLINE_OR_CR
785 /* This counter is used to clear the face cache every once in a while
786 in redisplay_internal. It is incremented for each redisplay.
787 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
788 cleared. */
790 #define CLEAR_FACE_CACHE_COUNT 500
791 static int clear_face_cache_count;
793 /* Similarly for the image cache. */
795 #ifdef HAVE_WINDOW_SYSTEM
796 #define CLEAR_IMAGE_CACHE_COUNT 101
797 static int clear_image_cache_count;
798 #endif
800 /* Record the previous terminal frame we displayed. */
802 static struct frame *previous_terminal_frame;
804 /* Non-zero while redisplay_internal is in progress. */
806 int redisplaying_p;
808 /* Non-zero means don't free realized faces. Bound while freeing
809 realized faces is dangerous because glyph matrices might still
810 reference them. */
812 int inhibit_free_realized_faces;
813 Lisp_Object Qinhibit_free_realized_faces;
815 /* If a string, XTread_socket generates an event to display that string.
816 (The display is done in read_char.) */
818 Lisp_Object help_echo_string;
819 Lisp_Object help_echo_window;
820 Lisp_Object help_echo_object;
821 int help_echo_pos;
823 /* Temporary variable for XTread_socket. */
825 Lisp_Object previous_help_echo_string;
827 /* Null glyph slice */
829 static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 };
832 /* Function prototypes. */
834 static void setup_for_ellipsis P_ ((struct it *, int));
835 static void mark_window_display_accurate_1 P_ ((struct window *, int));
836 static int single_display_spec_string_p P_ ((Lisp_Object, Lisp_Object));
837 static int display_prop_string_p P_ ((Lisp_Object, Lisp_Object));
838 static int cursor_row_p P_ ((struct window *, struct glyph_row *));
839 static int redisplay_mode_lines P_ ((Lisp_Object, int));
840 static char *decode_mode_spec_coding P_ ((Lisp_Object, char *, int));
842 #if 0
843 static int invisible_text_between_p P_ ((struct it *, int, int));
844 #endif
846 static void pint2str P_ ((char *, int, int));
847 static void pint2hrstr P_ ((char *, int, int));
848 static struct text_pos run_window_scroll_functions P_ ((Lisp_Object,
849 struct text_pos));
850 static void reconsider_clip_changes P_ ((struct window *, struct buffer *));
851 static int text_outside_line_unchanged_p P_ ((struct window *, int, int));
852 static void store_frame_title_char P_ ((char));
853 static int store_frame_title P_ ((const unsigned char *, int, int));
854 static void x_consider_frame_title P_ ((Lisp_Object));
855 static void handle_stop P_ ((struct it *));
856 static int tool_bar_lines_needed P_ ((struct frame *));
857 static int single_display_spec_intangible_p P_ ((Lisp_Object));
858 static void ensure_echo_area_buffers P_ ((void));
859 static Lisp_Object unwind_with_echo_area_buffer P_ ((Lisp_Object));
860 static Lisp_Object with_echo_area_buffer_unwind_data P_ ((struct window *));
861 static int with_echo_area_buffer P_ ((struct window *, int,
862 int (*) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
863 EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
864 static void clear_garbaged_frames P_ ((void));
865 static int current_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
866 static int truncate_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
867 static int set_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
868 static int display_echo_area P_ ((struct window *));
869 static int display_echo_area_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
870 static int resize_mini_window_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
871 static Lisp_Object unwind_redisplay P_ ((Lisp_Object));
872 static int string_char_and_length P_ ((const unsigned char *, int, int *));
873 static struct text_pos display_prop_end P_ ((struct it *, Lisp_Object,
874 struct text_pos));
875 static int compute_window_start_on_continuation_line P_ ((struct window *));
876 static Lisp_Object safe_eval_handler P_ ((Lisp_Object));
877 static void insert_left_trunc_glyphs P_ ((struct it *));
878 static struct glyph_row *get_overlay_arrow_glyph_row P_ ((struct window *,
879 Lisp_Object));
880 static void extend_face_to_end_of_line P_ ((struct it *));
881 static int append_space_for_newline P_ ((struct it *, int));
882 static int cursor_row_fully_visible_p P_ ((struct window *, int, int));
883 static int try_scrolling P_ ((Lisp_Object, int, EMACS_INT, EMACS_INT, int, int));
884 static int try_cursor_movement P_ ((Lisp_Object, struct text_pos, int *));
885 static int trailing_whitespace_p P_ ((int));
886 static int message_log_check_duplicate P_ ((int, int, int, int));
887 static void push_it P_ ((struct it *));
888 static void pop_it P_ ((struct it *));
889 static void sync_frame_with_window_matrix_rows P_ ((struct window *));
890 static void select_frame_for_redisplay P_ ((Lisp_Object));
891 static void redisplay_internal P_ ((int));
892 static int echo_area_display P_ ((int));
893 static void redisplay_windows P_ ((Lisp_Object));
894 static void redisplay_window P_ ((Lisp_Object, int));
895 static Lisp_Object redisplay_window_error ();
896 static Lisp_Object redisplay_window_0 P_ ((Lisp_Object));
897 static Lisp_Object redisplay_window_1 P_ ((Lisp_Object));
898 static void update_menu_bar P_ ((struct frame *, int));
899 static int try_window_reusing_current_matrix P_ ((struct window *));
900 static int try_window_id P_ ((struct window *));
901 static int display_line P_ ((struct it *));
902 static int display_mode_lines P_ ((struct window *));
903 static int display_mode_line P_ ((struct window *, enum face_id, Lisp_Object));
904 static int display_mode_element P_ ((struct it *, int, int, int, Lisp_Object, Lisp_Object, int));
905 static int store_mode_line_string P_ ((char *, Lisp_Object, int, int, int, Lisp_Object));
906 static char *decode_mode_spec P_ ((struct window *, int, int, int, int *));
907 static void display_menu_bar P_ ((struct window *));
908 static int display_count_lines P_ ((int, int, int, int, int *));
909 static int display_string P_ ((unsigned char *, Lisp_Object, Lisp_Object,
910 int, int, struct it *, int, int, int, int));
911 static void compute_line_metrics P_ ((struct it *));
912 static void run_redisplay_end_trigger_hook P_ ((struct it *));
913 static int get_overlay_strings P_ ((struct it *, int));
914 static void next_overlay_string P_ ((struct it *));
915 static void reseat P_ ((struct it *, struct text_pos, int));
916 static void reseat_1 P_ ((struct it *, struct text_pos, int));
917 static void back_to_previous_visible_line_start P_ ((struct it *));
918 void reseat_at_previous_visible_line_start P_ ((struct it *));
919 static void reseat_at_next_visible_line_start P_ ((struct it *, int));
920 static int next_element_from_ellipsis P_ ((struct it *));
921 static int next_element_from_display_vector P_ ((struct it *));
922 static int next_element_from_string P_ ((struct it *));
923 static int next_element_from_c_string P_ ((struct it *));
924 static int next_element_from_buffer P_ ((struct it *));
925 static int next_element_from_composition P_ ((struct it *));
926 static int next_element_from_image P_ ((struct it *));
927 static int next_element_from_stretch P_ ((struct it *));
928 static void load_overlay_strings P_ ((struct it *, int));
929 static int init_from_display_pos P_ ((struct it *, struct window *,
930 struct display_pos *));
931 static void reseat_to_string P_ ((struct it *, unsigned char *,
932 Lisp_Object, int, int, int, int));
933 static enum move_it_result move_it_in_display_line_to P_ ((struct it *,
934 int, int, int));
935 void move_it_vertically_backward P_ ((struct it *, int));
936 static void init_to_row_start P_ ((struct it *, struct window *,
937 struct glyph_row *));
938 static int init_to_row_end P_ ((struct it *, struct window *,
939 struct glyph_row *));
940 static void back_to_previous_line_start P_ ((struct it *));
941 static int forward_to_next_line_start P_ ((struct it *, int *));
942 static struct text_pos string_pos_nchars_ahead P_ ((struct text_pos,
943 Lisp_Object, int));
944 static struct text_pos string_pos P_ ((int, Lisp_Object));
945 static struct text_pos c_string_pos P_ ((int, unsigned char *, int));
946 static int number_of_chars P_ ((unsigned char *, int));
947 static void compute_stop_pos P_ ((struct it *));
948 static void compute_string_pos P_ ((struct text_pos *, struct text_pos,
949 Lisp_Object));
950 static int face_before_or_after_it_pos P_ ((struct it *, int));
951 static int next_overlay_change P_ ((int));
952 static int handle_single_display_spec P_ ((struct it *, Lisp_Object,
953 Lisp_Object, struct text_pos *,
954 int));
955 static int underlying_face_id P_ ((struct it *));
956 static int in_ellipses_for_invisible_text_p P_ ((struct display_pos *,
957 struct window *));
959 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
960 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
962 #ifdef HAVE_WINDOW_SYSTEM
964 static void update_tool_bar P_ ((struct frame *, int));
965 static void build_desired_tool_bar_string P_ ((struct frame *f));
966 static int redisplay_tool_bar P_ ((struct frame *));
967 static void display_tool_bar_line P_ ((struct it *));
968 static void notice_overwritten_cursor P_ ((struct window *,
969 enum glyph_row_area,
970 int, int, int, int));
974 #endif /* HAVE_WINDOW_SYSTEM */
977 /***********************************************************************
978 Window display dimensions
979 ***********************************************************************/
981 /* Return the bottom boundary y-position for text lines in window W.
982 This is the first y position at which a line cannot start.
983 It is relative to the top of the window.
985 This is the height of W minus the height of a mode line, if any. */
987 INLINE int
988 window_text_bottom_y (w)
989 struct window *w;
991 int height = WINDOW_TOTAL_HEIGHT (w);
993 if (WINDOW_WANTS_MODELINE_P (w))
994 height -= CURRENT_MODE_LINE_HEIGHT (w);
995 return height;
998 /* Return the pixel width of display area AREA of window W. AREA < 0
999 means return the total width of W, not including fringes to
1000 the left and right of the window. */
1002 INLINE int
1003 window_box_width (w, area)
1004 struct window *w;
1005 int area;
1007 int cols = XFASTINT (w->total_cols);
1008 int pixels = 0;
1010 if (!w->pseudo_window_p)
1012 cols -= WINDOW_SCROLL_BAR_COLS (w);
1014 if (area == TEXT_AREA)
1016 if (INTEGERP (w->left_margin_cols))
1017 cols -= XFASTINT (w->left_margin_cols);
1018 if (INTEGERP (w->right_margin_cols))
1019 cols -= XFASTINT (w->right_margin_cols);
1020 pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w);
1022 else if (area == LEFT_MARGIN_AREA)
1024 cols = (INTEGERP (w->left_margin_cols)
1025 ? XFASTINT (w->left_margin_cols) : 0);
1026 pixels = 0;
1028 else if (area == RIGHT_MARGIN_AREA)
1030 cols = (INTEGERP (w->right_margin_cols)
1031 ? XFASTINT (w->right_margin_cols) : 0);
1032 pixels = 0;
1036 return cols * WINDOW_FRAME_COLUMN_WIDTH (w) + pixels;
1040 /* Return the pixel height of the display area of window W, not
1041 including mode lines of W, if any. */
1043 INLINE int
1044 window_box_height (w)
1045 struct window *w;
1047 struct frame *f = XFRAME (w->frame);
1048 int height = WINDOW_TOTAL_HEIGHT (w);
1050 xassert (height >= 0);
1052 /* Note: the code below that determines the mode-line/header-line
1053 height is essentially the same as that contained in the macro
1054 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1055 the appropriate glyph row has its `mode_line_p' flag set,
1056 and if it doesn't, uses estimate_mode_line_height instead. */
1058 if (WINDOW_WANTS_MODELINE_P (w))
1060 struct glyph_row *ml_row
1061 = (w->current_matrix && w->current_matrix->rows
1062 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
1063 : 0);
1064 if (ml_row && ml_row->mode_line_p)
1065 height -= ml_row->height;
1066 else
1067 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
1070 if (WINDOW_WANTS_HEADER_LINE_P (w))
1072 struct glyph_row *hl_row
1073 = (w->current_matrix && w->current_matrix->rows
1074 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
1075 : 0);
1076 if (hl_row && hl_row->mode_line_p)
1077 height -= hl_row->height;
1078 else
1079 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1082 /* With a very small font and a mode-line that's taller than
1083 default, we might end up with a negative height. */
1084 return max (0, height);
1087 /* Return the window-relative coordinate of the left edge of display
1088 area AREA of window W. AREA < 0 means return the left edge of the
1089 whole window, to the right of the left fringe of W. */
1091 INLINE int
1092 window_box_left_offset (w, area)
1093 struct window *w;
1094 int area;
1096 int x;
1098 if (w->pseudo_window_p)
1099 return 0;
1101 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
1103 if (area == TEXT_AREA)
1104 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1105 + window_box_width (w, LEFT_MARGIN_AREA));
1106 else if (area == RIGHT_MARGIN_AREA)
1107 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1108 + window_box_width (w, LEFT_MARGIN_AREA)
1109 + window_box_width (w, TEXT_AREA)
1110 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1112 : WINDOW_RIGHT_FRINGE_WIDTH (w)));
1113 else if (area == LEFT_MARGIN_AREA
1114 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1115 x += WINDOW_LEFT_FRINGE_WIDTH (w);
1117 return x;
1121 /* Return the window-relative coordinate of the right edge of display
1122 area AREA of window W. AREA < 0 means return the left edge of the
1123 whole window, to the left of the right fringe of W. */
1125 INLINE int
1126 window_box_right_offset (w, area)
1127 struct window *w;
1128 int area;
1130 return window_box_left_offset (w, area) + window_box_width (w, area);
1133 /* Return the frame-relative coordinate of the left edge of display
1134 area AREA of window W. AREA < 0 means return the left edge of the
1135 whole window, to the right of the left fringe of W. */
1137 INLINE int
1138 window_box_left (w, area)
1139 struct window *w;
1140 int area;
1142 struct frame *f = XFRAME (w->frame);
1143 int x;
1145 if (w->pseudo_window_p)
1146 return FRAME_INTERNAL_BORDER_WIDTH (f);
1148 x = (WINDOW_LEFT_EDGE_X (w)
1149 + window_box_left_offset (w, area));
1151 return x;
1155 /* Return the frame-relative coordinate of the right edge of display
1156 area AREA of window W. AREA < 0 means return the left edge of the
1157 whole window, to the left of the right fringe of W. */
1159 INLINE int
1160 window_box_right (w, area)
1161 struct window *w;
1162 int area;
1164 return window_box_left (w, area) + window_box_width (w, area);
1167 /* Get the bounding box of the display area AREA of window W, without
1168 mode lines, in frame-relative coordinates. AREA < 0 means the
1169 whole window, not including the left and right fringes of
1170 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1171 coordinates of the upper-left corner of the box. Return in
1172 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1174 INLINE void
1175 window_box (w, area, box_x, box_y, box_width, box_height)
1176 struct window *w;
1177 int area;
1178 int *box_x, *box_y, *box_width, *box_height;
1180 if (box_width)
1181 *box_width = window_box_width (w, area);
1182 if (box_height)
1183 *box_height = window_box_height (w);
1184 if (box_x)
1185 *box_x = window_box_left (w, area);
1186 if (box_y)
1188 *box_y = WINDOW_TOP_EDGE_Y (w);
1189 if (WINDOW_WANTS_HEADER_LINE_P (w))
1190 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1195 /* Get the bounding box of the display area AREA of window W, without
1196 mode lines. AREA < 0 means the whole window, not including the
1197 left and right fringe of the window. Return in *TOP_LEFT_X
1198 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1199 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1200 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1201 box. */
1203 INLINE void
1204 window_box_edges (w, area, top_left_x, top_left_y,
1205 bottom_right_x, bottom_right_y)
1206 struct window *w;
1207 int area;
1208 int *top_left_x, *top_left_y, *bottom_right_x, *bottom_right_y;
1210 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
1211 bottom_right_y);
1212 *bottom_right_x += *top_left_x;
1213 *bottom_right_y += *top_left_y;
1218 /***********************************************************************
1219 Utilities
1220 ***********************************************************************/
1222 /* Return the bottom y-position of the line the iterator IT is in.
1223 This can modify IT's settings. */
1226 line_bottom_y (it)
1227 struct it *it;
1229 int line_height = it->max_ascent + it->max_descent;
1230 int line_top_y = it->current_y;
1232 if (line_height == 0)
1234 if (last_height)
1235 line_height = last_height;
1236 else if (IT_CHARPOS (*it) < ZV)
1238 move_it_by_lines (it, 1, 1);
1239 line_height = (it->max_ascent || it->max_descent
1240 ? it->max_ascent + it->max_descent
1241 : last_height);
1243 else
1245 struct glyph_row *row = it->glyph_row;
1247 /* Use the default character height. */
1248 it->glyph_row = NULL;
1249 it->what = IT_CHARACTER;
1250 it->c = ' ';
1251 it->len = 1;
1252 PRODUCE_GLYPHS (it);
1253 line_height = it->ascent + it->descent;
1254 it->glyph_row = row;
1258 return line_top_y + line_height;
1262 /* Return 1 if position CHARPOS is visible in window W.
1263 If visible, set *X and *Y to pixel coordinates of top left corner.
1264 Set *RTOP and *RBOT to pixel height of an invisible area of glyph at POS.
1265 EXACT_MODE_LINE_HEIGHTS_P non-zero means compute exact mode-line
1266 and header-lines heights. */
1269 pos_visible_p (w, charpos, x, y, rtop, rbot, exact_mode_line_heights_p)
1270 struct window *w;
1271 int charpos, *x, *y, *rtop, *rbot, exact_mode_line_heights_p;
1273 struct it it;
1274 struct text_pos top;
1275 int visible_p = 0;
1276 struct buffer *old_buffer = NULL;
1278 if (noninteractive)
1279 return visible_p;
1281 if (XBUFFER (w->buffer) != current_buffer)
1283 old_buffer = current_buffer;
1284 set_buffer_internal_1 (XBUFFER (w->buffer));
1287 SET_TEXT_POS_FROM_MARKER (top, w->start);
1289 /* Compute exact mode line heights, if requested. */
1290 if (exact_mode_line_heights_p)
1292 if (WINDOW_WANTS_MODELINE_P (w))
1293 current_mode_line_height
1294 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1295 current_buffer->mode_line_format);
1297 if (WINDOW_WANTS_HEADER_LINE_P (w))
1298 current_header_line_height
1299 = display_mode_line (w, HEADER_LINE_FACE_ID,
1300 current_buffer->header_line_format);
1303 start_display (&it, w, top);
1304 move_it_to (&it, charpos, -1, it.last_visible_y, -1,
1305 MOVE_TO_POS | MOVE_TO_Y);
1307 /* Note that we may overshoot because of invisible text. */
1308 if (IT_CHARPOS (it) >= charpos)
1310 int top_x = it.current_x;
1311 int top_y = it.current_y;
1312 int bottom_y = (last_height = 0, line_bottom_y (&it));
1313 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1315 if (top_y < window_top_y)
1316 visible_p = bottom_y > window_top_y;
1317 else if (top_y < it.last_visible_y)
1318 visible_p = 1;
1319 if (visible_p)
1321 *x = top_x;
1322 *y = max (top_y + max (0, it.max_ascent - it.ascent), window_top_y);
1323 *rtop = max (0, window_top_y - top_y);
1324 *rbot = max (0, bottom_y - it.last_visible_y);
1327 else
1329 struct it it2;
1331 it2 = it;
1332 if (IT_CHARPOS (it) < ZV && FETCH_BYTE (IT_BYTEPOS (it)) != '\n')
1333 move_it_by_lines (&it, 1, 0);
1334 if (charpos < IT_CHARPOS (it))
1336 visible_p = 1;
1337 move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
1338 *x = it2.current_x;
1339 *y = it2.current_y + it2.max_ascent - it2.ascent;
1340 *rtop = max (0, -it2.current_y);
1341 *rbot = max (0, ((it2.current_y + it2.max_ascent + it2.max_descent)
1342 - it.last_visible_y));
1346 if (old_buffer)
1347 set_buffer_internal_1 (old_buffer);
1349 current_header_line_height = current_mode_line_height = -1;
1351 return visible_p;
1355 /* Return the next character from STR which is MAXLEN bytes long.
1356 Return in *LEN the length of the character. This is like
1357 STRING_CHAR_AND_LENGTH but never returns an invalid character. If
1358 we find one, we return a `?', but with the length of the invalid
1359 character. */
1361 static INLINE int
1362 string_char_and_length (str, maxlen, len)
1363 const unsigned char *str;
1364 int maxlen, *len;
1366 int c;
1368 c = STRING_CHAR_AND_LENGTH (str, maxlen, *len);
1369 if (!CHAR_VALID_P (c, 1))
1370 /* We may not change the length here because other places in Emacs
1371 don't use this function, i.e. they silently accept invalid
1372 characters. */
1373 c = '?';
1375 return c;
1380 /* Given a position POS containing a valid character and byte position
1381 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1383 static struct text_pos
1384 string_pos_nchars_ahead (pos, string, nchars)
1385 struct text_pos pos;
1386 Lisp_Object string;
1387 int nchars;
1389 xassert (STRINGP (string) && nchars >= 0);
1391 if (STRING_MULTIBYTE (string))
1393 int rest = SBYTES (string) - BYTEPOS (pos);
1394 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1395 int len;
1397 while (nchars--)
1399 string_char_and_length (p, rest, &len);
1400 p += len, rest -= len;
1401 xassert (rest >= 0);
1402 CHARPOS (pos) += 1;
1403 BYTEPOS (pos) += len;
1406 else
1407 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1409 return pos;
1413 /* Value is the text position, i.e. character and byte position,
1414 for character position CHARPOS in STRING. */
1416 static INLINE struct text_pos
1417 string_pos (charpos, string)
1418 int charpos;
1419 Lisp_Object string;
1421 struct text_pos pos;
1422 xassert (STRINGP (string));
1423 xassert (charpos >= 0);
1424 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1425 return pos;
1429 /* Value is a text position, i.e. character and byte position, for
1430 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1431 means recognize multibyte characters. */
1433 static struct text_pos
1434 c_string_pos (charpos, s, multibyte_p)
1435 int charpos;
1436 unsigned char *s;
1437 int multibyte_p;
1439 struct text_pos pos;
1441 xassert (s != NULL);
1442 xassert (charpos >= 0);
1444 if (multibyte_p)
1446 int rest = strlen (s), len;
1448 SET_TEXT_POS (pos, 0, 0);
1449 while (charpos--)
1451 string_char_and_length (s, rest, &len);
1452 s += len, rest -= len;
1453 xassert (rest >= 0);
1454 CHARPOS (pos) += 1;
1455 BYTEPOS (pos) += len;
1458 else
1459 SET_TEXT_POS (pos, charpos, charpos);
1461 return pos;
1465 /* Value is the number of characters in C string S. MULTIBYTE_P
1466 non-zero means recognize multibyte characters. */
1468 static int
1469 number_of_chars (s, multibyte_p)
1470 unsigned char *s;
1471 int multibyte_p;
1473 int nchars;
1475 if (multibyte_p)
1477 int rest = strlen (s), len;
1478 unsigned char *p = (unsigned char *) s;
1480 for (nchars = 0; rest > 0; ++nchars)
1482 string_char_and_length (p, rest, &len);
1483 rest -= len, p += len;
1486 else
1487 nchars = strlen (s);
1489 return nchars;
1493 /* Compute byte position NEWPOS->bytepos corresponding to
1494 NEWPOS->charpos. POS is a known position in string STRING.
1495 NEWPOS->charpos must be >= POS.charpos. */
1497 static void
1498 compute_string_pos (newpos, pos, string)
1499 struct text_pos *newpos, pos;
1500 Lisp_Object string;
1502 xassert (STRINGP (string));
1503 xassert (CHARPOS (*newpos) >= CHARPOS (pos));
1505 if (STRING_MULTIBYTE (string))
1506 *newpos = string_pos_nchars_ahead (pos, string,
1507 CHARPOS (*newpos) - CHARPOS (pos));
1508 else
1509 BYTEPOS (*newpos) = CHARPOS (*newpos);
1512 /* EXPORT:
1513 Return an estimation of the pixel height of mode or top lines on
1514 frame F. FACE_ID specifies what line's height to estimate. */
1517 estimate_mode_line_height (f, face_id)
1518 struct frame *f;
1519 enum face_id face_id;
1521 #ifdef HAVE_WINDOW_SYSTEM
1522 if (FRAME_WINDOW_P (f))
1524 int height = FONT_HEIGHT (FRAME_FONT (f));
1526 /* This function is called so early when Emacs starts that the face
1527 cache and mode line face are not yet initialized. */
1528 if (FRAME_FACE_CACHE (f))
1530 struct face *face = FACE_FROM_ID (f, face_id);
1531 if (face)
1533 if (face->font)
1534 height = FONT_HEIGHT (face->font);
1535 if (face->box_line_width > 0)
1536 height += 2 * face->box_line_width;
1540 return height;
1542 #endif
1544 return 1;
1547 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1548 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1549 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1550 not force the value into range. */
1552 void
1553 pixel_to_glyph_coords (f, pix_x, pix_y, x, y, bounds, noclip)
1554 FRAME_PTR f;
1555 register int pix_x, pix_y;
1556 int *x, *y;
1557 NativeRectangle *bounds;
1558 int noclip;
1561 #ifdef HAVE_WINDOW_SYSTEM
1562 if (FRAME_WINDOW_P (f))
1564 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1565 even for negative values. */
1566 if (pix_x < 0)
1567 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1568 if (pix_y < 0)
1569 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1571 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1572 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1574 if (bounds)
1575 STORE_NATIVE_RECT (*bounds,
1576 FRAME_COL_TO_PIXEL_X (f, pix_x),
1577 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1578 FRAME_COLUMN_WIDTH (f) - 1,
1579 FRAME_LINE_HEIGHT (f) - 1);
1581 if (!noclip)
1583 if (pix_x < 0)
1584 pix_x = 0;
1585 else if (pix_x > FRAME_TOTAL_COLS (f))
1586 pix_x = FRAME_TOTAL_COLS (f);
1588 if (pix_y < 0)
1589 pix_y = 0;
1590 else if (pix_y > FRAME_LINES (f))
1591 pix_y = FRAME_LINES (f);
1594 #endif
1596 *x = pix_x;
1597 *y = pix_y;
1601 /* Given HPOS/VPOS in the current matrix of W, return corresponding
1602 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
1603 can't tell the positions because W's display is not up to date,
1604 return 0. */
1607 glyph_to_pixel_coords (w, hpos, vpos, frame_x, frame_y)
1608 struct window *w;
1609 int hpos, vpos;
1610 int *frame_x, *frame_y;
1612 #ifdef HAVE_WINDOW_SYSTEM
1613 if (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w))))
1615 int success_p;
1617 xassert (hpos >= 0 && hpos < w->current_matrix->matrix_w);
1618 xassert (vpos >= 0 && vpos < w->current_matrix->matrix_h);
1620 if (display_completed)
1622 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
1623 struct glyph *glyph = row->glyphs[TEXT_AREA];
1624 struct glyph *end = glyph + min (hpos, row->used[TEXT_AREA]);
1626 hpos = row->x;
1627 vpos = row->y;
1628 while (glyph < end)
1630 hpos += glyph->pixel_width;
1631 ++glyph;
1634 /* If first glyph is partially visible, its first visible position is still 0. */
1635 if (hpos < 0)
1636 hpos = 0;
1638 success_p = 1;
1640 else
1642 hpos = vpos = 0;
1643 success_p = 0;
1646 *frame_x = WINDOW_TO_FRAME_PIXEL_X (w, hpos);
1647 *frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, vpos);
1648 return success_p;
1650 #endif
1652 *frame_x = hpos;
1653 *frame_y = vpos;
1654 return 1;
1658 #ifdef HAVE_WINDOW_SYSTEM
1660 /* Find the glyph under window-relative coordinates X/Y in window W.
1661 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1662 strings. Return in *HPOS and *VPOS the row and column number of
1663 the glyph found. Return in *AREA the glyph area containing X.
1664 Value is a pointer to the glyph found or null if X/Y is not on
1665 text, or we can't tell because W's current matrix is not up to
1666 date. */
1668 static struct glyph *
1669 x_y_to_hpos_vpos (w, x, y, hpos, vpos, dx, dy, area)
1670 struct window *w;
1671 int x, y;
1672 int *hpos, *vpos, *dx, *dy, *area;
1674 struct glyph *glyph, *end;
1675 struct glyph_row *row = NULL;
1676 int x0, i;
1678 /* Find row containing Y. Give up if some row is not enabled. */
1679 for (i = 0; i < w->current_matrix->nrows; ++i)
1681 row = MATRIX_ROW (w->current_matrix, i);
1682 if (!row->enabled_p)
1683 return NULL;
1684 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1685 break;
1688 *vpos = i;
1689 *hpos = 0;
1691 /* Give up if Y is not in the window. */
1692 if (i == w->current_matrix->nrows)
1693 return NULL;
1695 /* Get the glyph area containing X. */
1696 if (w->pseudo_window_p)
1698 *area = TEXT_AREA;
1699 x0 = 0;
1701 else
1703 if (x < window_box_left_offset (w, TEXT_AREA))
1705 *area = LEFT_MARGIN_AREA;
1706 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
1708 else if (x < window_box_right_offset (w, TEXT_AREA))
1710 *area = TEXT_AREA;
1711 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
1713 else
1715 *area = RIGHT_MARGIN_AREA;
1716 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
1720 /* Find glyph containing X. */
1721 glyph = row->glyphs[*area];
1722 end = glyph + row->used[*area];
1723 x -= x0;
1724 while (glyph < end && x >= glyph->pixel_width)
1726 x -= glyph->pixel_width;
1727 ++glyph;
1730 if (glyph == end)
1731 return NULL;
1733 if (dx)
1735 *dx = x;
1736 *dy = y - (row->y + row->ascent - glyph->ascent);
1739 *hpos = glyph - row->glyphs[*area];
1740 return glyph;
1744 /* EXPORT:
1745 Convert frame-relative x/y to coordinates relative to window W.
1746 Takes pseudo-windows into account. */
1748 void
1749 frame_to_window_pixel_xy (w, x, y)
1750 struct window *w;
1751 int *x, *y;
1753 if (w->pseudo_window_p)
1755 /* A pseudo-window is always full-width, and starts at the
1756 left edge of the frame, plus a frame border. */
1757 struct frame *f = XFRAME (w->frame);
1758 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
1759 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1761 else
1763 *x -= WINDOW_LEFT_EDGE_X (w);
1764 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1768 /* EXPORT:
1769 Return in *R the clipping rectangle for glyph string S. */
1771 void
1772 get_glyph_string_clip_rect (s, nr)
1773 struct glyph_string *s;
1774 NativeRectangle *nr;
1776 XRectangle r;
1778 if (s->row->full_width_p)
1780 /* Draw full-width. X coordinates are relative to S->w->left_col. */
1781 r.x = WINDOW_LEFT_EDGE_X (s->w);
1782 r.width = WINDOW_TOTAL_WIDTH (s->w);
1784 /* Unless displaying a mode or menu bar line, which are always
1785 fully visible, clip to the visible part of the row. */
1786 if (s->w->pseudo_window_p)
1787 r.height = s->row->visible_height;
1788 else
1789 r.height = s->height;
1791 else
1793 /* This is a text line that may be partially visible. */
1794 r.x = window_box_left (s->w, s->area);
1795 r.width = window_box_width (s->w, s->area);
1796 r.height = s->row->visible_height;
1799 if (s->clip_head)
1800 if (r.x < s->clip_head->x)
1802 if (r.width >= s->clip_head->x - r.x)
1803 r.width -= s->clip_head->x - r.x;
1804 else
1805 r.width = 0;
1806 r.x = s->clip_head->x;
1808 if (s->clip_tail)
1809 if (r.x + r.width > s->clip_tail->x + s->clip_tail->background_width)
1811 if (s->clip_tail->x + s->clip_tail->background_width >= r.x)
1812 r.width = s->clip_tail->x + s->clip_tail->background_width - r.x;
1813 else
1814 r.width = 0;
1817 /* If S draws overlapping rows, it's sufficient to use the top and
1818 bottom of the window for clipping because this glyph string
1819 intentionally draws over other lines. */
1820 if (s->for_overlaps_p)
1822 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1823 r.height = window_text_bottom_y (s->w) - r.y;
1825 else
1827 /* Don't use S->y for clipping because it doesn't take partially
1828 visible lines into account. For example, it can be negative for
1829 partially visible lines at the top of a window. */
1830 if (!s->row->full_width_p
1831 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
1832 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1833 else
1834 r.y = max (0, s->row->y);
1836 /* If drawing a tool-bar window, draw it over the internal border
1837 at the top of the window. */
1838 if (WINDOWP (s->f->tool_bar_window)
1839 && s->w == XWINDOW (s->f->tool_bar_window))
1840 r.y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
1843 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
1845 /* If drawing the cursor, don't let glyph draw outside its
1846 advertised boundaries. Cleartype does this under some circumstances. */
1847 if (s->hl == DRAW_CURSOR)
1849 struct glyph *glyph = s->first_glyph;
1850 int height, max_y;
1852 if (s->x > r.x)
1854 r.width -= s->x - r.x;
1855 r.x = s->x;
1857 r.width = min (r.width, glyph->pixel_width);
1859 /* If r.y is below window bottom, ensure that we still see a cursor. */
1860 height = min (glyph->ascent + glyph->descent,
1861 min (FRAME_LINE_HEIGHT (s->f), s->row->visible_height));
1862 max_y = window_text_bottom_y (s->w) - height;
1863 max_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, max_y);
1864 if (s->ybase - glyph->ascent > max_y)
1866 r.y = max_y;
1867 r.height = height;
1869 else
1871 /* Don't draw cursor glyph taller than our actual glyph. */
1872 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
1873 if (height < r.height)
1875 max_y = r.y + r.height;
1876 r.y = min (max_y, max (r.y, s->ybase + glyph->descent - height));
1877 r.height = min (max_y - r.y, height);
1882 #ifdef CONVERT_FROM_XRECT
1883 CONVERT_FROM_XRECT (r, *nr);
1884 #else
1885 *nr = r;
1886 #endif
1890 /* EXPORT:
1891 Return the position and height of the phys cursor in window W.
1892 Set w->phys_cursor_width to width of phys cursor.
1896 get_phys_cursor_geometry (w, row, glyph, heightp)
1897 struct window *w;
1898 struct glyph_row *row;
1899 struct glyph *glyph;
1900 int *heightp;
1902 struct frame *f = XFRAME (WINDOW_FRAME (w));
1903 int x, y, wd, h, h0, y0;
1905 /* Compute the width of the rectangle to draw. If on a stretch
1906 glyph, and `x-stretch-block-cursor' is nil, don't draw a
1907 rectangle as wide as the glyph, but use a canonical character
1908 width instead. */
1909 wd = glyph->pixel_width - 1;
1910 #ifdef HAVE_NTGUI
1911 wd++; /* Why? */
1912 #endif
1913 if (glyph->type == STRETCH_GLYPH
1914 && !x_stretch_cursor_p)
1915 wd = min (FRAME_COLUMN_WIDTH (f), wd);
1916 w->phys_cursor_width = wd;
1918 y = w->phys_cursor.y + row->ascent - glyph->ascent;
1920 /* If y is below window bottom, ensure that we still see a cursor. */
1921 h0 = min (FRAME_LINE_HEIGHT (f), row->visible_height);
1923 h = max (h0, glyph->ascent + glyph->descent);
1924 h0 = min (h0, glyph->ascent + glyph->descent);
1926 y0 = WINDOW_HEADER_LINE_HEIGHT (w);
1927 if (y < y0)
1929 h = max (h - (y0 - y) + 1, h0);
1930 y = y0 - 1;
1932 else
1934 y0 = window_text_bottom_y (w) - h0;
1935 if (y > y0)
1937 h += y - y0;
1938 y = y0;
1942 *heightp = h - 1;
1943 return WINDOW_TO_FRAME_PIXEL_Y (w, y);
1947 #endif /* HAVE_WINDOW_SYSTEM */
1950 /***********************************************************************
1951 Lisp form evaluation
1952 ***********************************************************************/
1954 /* Error handler for safe_eval and safe_call. */
1956 static Lisp_Object
1957 safe_eval_handler (arg)
1958 Lisp_Object arg;
1960 add_to_log ("Error during redisplay: %s", arg, Qnil);
1961 return Qnil;
1965 /* Evaluate SEXPR and return the result, or nil if something went
1966 wrong. Prevent redisplay during the evaluation. */
1968 Lisp_Object
1969 safe_eval (sexpr)
1970 Lisp_Object sexpr;
1972 Lisp_Object val;
1974 if (inhibit_eval_during_redisplay)
1975 val = Qnil;
1976 else
1978 int count = SPECPDL_INDEX ();
1979 struct gcpro gcpro1;
1981 GCPRO1 (sexpr);
1982 specbind (Qinhibit_redisplay, Qt);
1983 /* Use Qt to ensure debugger does not run,
1984 so there is no possibility of wanting to redisplay. */
1985 val = internal_condition_case_1 (Feval, sexpr, Qt,
1986 safe_eval_handler);
1987 UNGCPRO;
1988 val = unbind_to (count, val);
1991 return val;
1995 /* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1].
1996 Return the result, or nil if something went wrong. Prevent
1997 redisplay during the evaluation. */
1999 Lisp_Object
2000 safe_call (nargs, args)
2001 int nargs;
2002 Lisp_Object *args;
2004 Lisp_Object val;
2006 if (inhibit_eval_during_redisplay)
2007 val = Qnil;
2008 else
2010 int count = SPECPDL_INDEX ();
2011 struct gcpro gcpro1;
2013 GCPRO1 (args[0]);
2014 gcpro1.nvars = nargs;
2015 specbind (Qinhibit_redisplay, Qt);
2016 /* Use Qt to ensure debugger does not run,
2017 so there is no possibility of wanting to redisplay. */
2018 val = internal_condition_case_2 (Ffuncall, nargs, args, Qt,
2019 safe_eval_handler);
2020 UNGCPRO;
2021 val = unbind_to (count, val);
2024 return val;
2028 /* Call function FN with one argument ARG.
2029 Return the result, or nil if something went wrong. */
2031 Lisp_Object
2032 safe_call1 (fn, arg)
2033 Lisp_Object fn, arg;
2035 Lisp_Object args[2];
2036 args[0] = fn;
2037 args[1] = arg;
2038 return safe_call (2, args);
2043 /***********************************************************************
2044 Debugging
2045 ***********************************************************************/
2047 #if 0
2049 /* Define CHECK_IT to perform sanity checks on iterators.
2050 This is for debugging. It is too slow to do unconditionally. */
2052 static void
2053 check_it (it)
2054 struct it *it;
2056 if (it->method == GET_FROM_STRING)
2058 xassert (STRINGP (it->string));
2059 xassert (IT_STRING_CHARPOS (*it) >= 0);
2061 else
2063 xassert (IT_STRING_CHARPOS (*it) < 0);
2064 if (it->method == GET_FROM_BUFFER)
2066 /* Check that character and byte positions agree. */
2067 xassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
2071 if (it->dpvec)
2072 xassert (it->current.dpvec_index >= 0);
2073 else
2074 xassert (it->current.dpvec_index < 0);
2077 #define CHECK_IT(IT) check_it ((IT))
2079 #else /* not 0 */
2081 #define CHECK_IT(IT) (void) 0
2083 #endif /* not 0 */
2086 #if GLYPH_DEBUG
2088 /* Check that the window end of window W is what we expect it
2089 to be---the last row in the current matrix displaying text. */
2091 static void
2092 check_window_end (w)
2093 struct window *w;
2095 if (!MINI_WINDOW_P (w)
2096 && !NILP (w->window_end_valid))
2098 struct glyph_row *row;
2099 xassert ((row = MATRIX_ROW (w->current_matrix,
2100 XFASTINT (w->window_end_vpos)),
2101 !row->enabled_p
2102 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
2103 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
2107 #define CHECK_WINDOW_END(W) check_window_end ((W))
2109 #else /* not GLYPH_DEBUG */
2111 #define CHECK_WINDOW_END(W) (void) 0
2113 #endif /* not GLYPH_DEBUG */
2117 /***********************************************************************
2118 Iterator initialization
2119 ***********************************************************************/
2121 /* Initialize IT for displaying current_buffer in window W, starting
2122 at character position CHARPOS. CHARPOS < 0 means that no buffer
2123 position is specified which is useful when the iterator is assigned
2124 a position later. BYTEPOS is the byte position corresponding to
2125 CHARPOS. BYTEPOS < 0 means compute it from CHARPOS.
2127 If ROW is not null, calls to produce_glyphs with IT as parameter
2128 will produce glyphs in that row.
2130 BASE_FACE_ID is the id of a base face to use. It must be one of
2131 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2132 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2133 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2135 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2136 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2137 will be initialized to use the corresponding mode line glyph row of
2138 the desired matrix of W. */
2140 void
2141 init_iterator (it, w, charpos, bytepos, row, base_face_id)
2142 struct it *it;
2143 struct window *w;
2144 int charpos, bytepos;
2145 struct glyph_row *row;
2146 enum face_id base_face_id;
2148 int highlight_region_p;
2150 /* Some precondition checks. */
2151 xassert (w != NULL && it != NULL);
2152 xassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
2153 && charpos <= ZV));
2155 /* If face attributes have been changed since the last redisplay,
2156 free realized faces now because they depend on face definitions
2157 that might have changed. Don't free faces while there might be
2158 desired matrices pending which reference these faces. */
2159 if (face_change_count && !inhibit_free_realized_faces)
2161 face_change_count = 0;
2162 free_all_realized_faces (Qnil);
2165 /* Use one of the mode line rows of W's desired matrix if
2166 appropriate. */
2167 if (row == NULL)
2169 if (base_face_id == MODE_LINE_FACE_ID
2170 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
2171 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
2172 else if (base_face_id == HEADER_LINE_FACE_ID)
2173 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
2176 /* Clear IT. */
2177 bzero (it, sizeof *it);
2178 it->current.overlay_string_index = -1;
2179 it->current.dpvec_index = -1;
2180 it->base_face_id = base_face_id;
2181 it->string = Qnil;
2182 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
2184 /* The window in which we iterate over current_buffer: */
2185 XSETWINDOW (it->window, w);
2186 it->w = w;
2187 it->f = XFRAME (w->frame);
2189 /* Extra space between lines (on window systems only). */
2190 if (base_face_id == DEFAULT_FACE_ID
2191 && FRAME_WINDOW_P (it->f))
2193 if (NATNUMP (current_buffer->extra_line_spacing))
2194 it->extra_line_spacing = XFASTINT (current_buffer->extra_line_spacing);
2195 else if (FLOATP (current_buffer->extra_line_spacing))
2196 it->extra_line_spacing = (XFLOAT_DATA (current_buffer->extra_line_spacing)
2197 * FRAME_LINE_HEIGHT (it->f));
2198 else if (it->f->extra_line_spacing > 0)
2199 it->extra_line_spacing = it->f->extra_line_spacing;
2200 it->max_extra_line_spacing = 0;
2203 /* If realized faces have been removed, e.g. because of face
2204 attribute changes of named faces, recompute them. When running
2205 in batch mode, the face cache of Vterminal_frame is null. If
2206 we happen to get called, make a dummy face cache. */
2207 if (noninteractive && FRAME_FACE_CACHE (it->f) == NULL)
2208 init_frame_faces (it->f);
2209 if (FRAME_FACE_CACHE (it->f)->used == 0)
2210 recompute_basic_faces (it->f);
2212 /* Current value of the `slice', `space-width', and 'height' properties. */
2213 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
2214 it->space_width = Qnil;
2215 it->font_height = Qnil;
2216 it->override_ascent = -1;
2218 /* Are control characters displayed as `^C'? */
2219 it->ctl_arrow_p = !NILP (current_buffer->ctl_arrow);
2221 /* -1 means everything between a CR and the following line end
2222 is invisible. >0 means lines indented more than this value are
2223 invisible. */
2224 it->selective = (INTEGERP (current_buffer->selective_display)
2225 ? XFASTINT (current_buffer->selective_display)
2226 : (!NILP (current_buffer->selective_display)
2227 ? -1 : 0));
2228 it->selective_display_ellipsis_p
2229 = !NILP (current_buffer->selective_display_ellipses);
2231 /* Display table to use. */
2232 it->dp = window_display_table (w);
2234 /* Are multibyte characters enabled in current_buffer? */
2235 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
2237 /* Non-zero if we should highlight the region. */
2238 highlight_region_p
2239 = (!NILP (Vtransient_mark_mode)
2240 && !NILP (current_buffer->mark_active)
2241 && XMARKER (current_buffer->mark)->buffer != 0);
2243 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
2244 start and end of a visible region in window IT->w. Set both to
2245 -1 to indicate no region. */
2246 if (highlight_region_p
2247 /* Maybe highlight only in selected window. */
2248 && (/* Either show region everywhere. */
2249 highlight_nonselected_windows
2250 /* Or show region in the selected window. */
2251 || w == XWINDOW (selected_window)
2252 /* Or show the region if we are in the mini-buffer and W is
2253 the window the mini-buffer refers to. */
2254 || (MINI_WINDOW_P (XWINDOW (selected_window))
2255 && WINDOWP (minibuf_selected_window)
2256 && w == XWINDOW (minibuf_selected_window))))
2258 int charpos = marker_position (current_buffer->mark);
2259 it->region_beg_charpos = min (PT, charpos);
2260 it->region_end_charpos = max (PT, charpos);
2262 else
2263 it->region_beg_charpos = it->region_end_charpos = -1;
2265 /* Get the position at which the redisplay_end_trigger hook should
2266 be run, if it is to be run at all. */
2267 if (MARKERP (w->redisplay_end_trigger)
2268 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2269 it->redisplay_end_trigger_charpos
2270 = marker_position (w->redisplay_end_trigger);
2271 else if (INTEGERP (w->redisplay_end_trigger))
2272 it->redisplay_end_trigger_charpos = XINT (w->redisplay_end_trigger);
2274 /* Correct bogus values of tab_width. */
2275 it->tab_width = XINT (current_buffer->tab_width);
2276 if (it->tab_width <= 0 || it->tab_width > 1000)
2277 it->tab_width = 8;
2279 /* Are lines in the display truncated? */
2280 it->truncate_lines_p
2281 = (base_face_id != DEFAULT_FACE_ID
2282 || XINT (it->w->hscroll)
2283 || (truncate_partial_width_windows
2284 && !WINDOW_FULL_WIDTH_P (it->w))
2285 || !NILP (current_buffer->truncate_lines));
2287 /* Get dimensions of truncation and continuation glyphs. These are
2288 displayed as fringe bitmaps under X, so we don't need them for such
2289 frames. */
2290 if (!FRAME_WINDOW_P (it->f))
2292 if (it->truncate_lines_p)
2294 /* We will need the truncation glyph. */
2295 xassert (it->glyph_row == NULL);
2296 produce_special_glyphs (it, IT_TRUNCATION);
2297 it->truncation_pixel_width = it->pixel_width;
2299 else
2301 /* We will need the continuation glyph. */
2302 xassert (it->glyph_row == NULL);
2303 produce_special_glyphs (it, IT_CONTINUATION);
2304 it->continuation_pixel_width = it->pixel_width;
2307 /* Reset these values to zero because the produce_special_glyphs
2308 above has changed them. */
2309 it->pixel_width = it->ascent = it->descent = 0;
2310 it->phys_ascent = it->phys_descent = 0;
2313 /* Set this after getting the dimensions of truncation and
2314 continuation glyphs, so that we don't produce glyphs when calling
2315 produce_special_glyphs, above. */
2316 it->glyph_row = row;
2317 it->area = TEXT_AREA;
2319 /* Get the dimensions of the display area. The display area
2320 consists of the visible window area plus a horizontally scrolled
2321 part to the left of the window. All x-values are relative to the
2322 start of this total display area. */
2323 if (base_face_id != DEFAULT_FACE_ID)
2325 /* Mode lines, menu bar in terminal frames. */
2326 it->first_visible_x = 0;
2327 it->last_visible_x = WINDOW_TOTAL_WIDTH (w);
2329 else
2331 it->first_visible_x
2332 = XFASTINT (it->w->hscroll) * FRAME_COLUMN_WIDTH (it->f);
2333 it->last_visible_x = (it->first_visible_x
2334 + window_box_width (w, TEXT_AREA));
2336 /* If we truncate lines, leave room for the truncator glyph(s) at
2337 the right margin. Otherwise, leave room for the continuation
2338 glyph(s). Truncation and continuation glyphs are not inserted
2339 for window-based redisplay. */
2340 if (!FRAME_WINDOW_P (it->f))
2342 if (it->truncate_lines_p)
2343 it->last_visible_x -= it->truncation_pixel_width;
2344 else
2345 it->last_visible_x -= it->continuation_pixel_width;
2348 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
2349 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
2352 /* Leave room for a border glyph. */
2353 if (!FRAME_WINDOW_P (it->f)
2354 && !WINDOW_RIGHTMOST_P (it->w))
2355 it->last_visible_x -= 1;
2357 it->last_visible_y = window_text_bottom_y (w);
2359 /* For mode lines and alike, arrange for the first glyph having a
2360 left box line if the face specifies a box. */
2361 if (base_face_id != DEFAULT_FACE_ID)
2363 struct face *face;
2365 it->face_id = base_face_id;
2367 /* If we have a boxed mode line, make the first character appear
2368 with a left box line. */
2369 face = FACE_FROM_ID (it->f, base_face_id);
2370 if (face->box != FACE_NO_BOX)
2371 it->start_of_box_run_p = 1;
2374 /* If a buffer position was specified, set the iterator there,
2375 getting overlays and face properties from that position. */
2376 if (charpos >= BUF_BEG (current_buffer))
2378 it->end_charpos = ZV;
2379 it->face_id = -1;
2380 IT_CHARPOS (*it) = charpos;
2382 /* Compute byte position if not specified. */
2383 if (bytepos < charpos)
2384 IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos);
2385 else
2386 IT_BYTEPOS (*it) = bytepos;
2388 it->start = it->current;
2390 /* Compute faces etc. */
2391 reseat (it, it->current.pos, 1);
2394 CHECK_IT (it);
2398 /* Initialize IT for the display of window W with window start POS. */
2400 void
2401 start_display (it, w, pos)
2402 struct it *it;
2403 struct window *w;
2404 struct text_pos pos;
2406 struct glyph_row *row;
2407 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
2409 row = w->desired_matrix->rows + first_vpos;
2410 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
2411 it->first_vpos = first_vpos;
2413 if (!it->truncate_lines_p)
2415 int start_at_line_beg_p;
2416 int first_y = it->current_y;
2418 /* If window start is not at a line start, skip forward to POS to
2419 get the correct continuation lines width. */
2420 start_at_line_beg_p = (CHARPOS (pos) == BEGV
2421 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
2422 if (!start_at_line_beg_p)
2424 int new_x;
2426 reseat_at_previous_visible_line_start (it);
2427 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
2429 new_x = it->current_x + it->pixel_width;
2431 /* If lines are continued, this line may end in the middle
2432 of a multi-glyph character (e.g. a control character
2433 displayed as \003, or in the middle of an overlay
2434 string). In this case move_it_to above will not have
2435 taken us to the start of the continuation line but to the
2436 end of the continued line. */
2437 if (it->current_x > 0
2438 && !it->truncate_lines_p /* Lines are continued. */
2439 && (/* And glyph doesn't fit on the line. */
2440 new_x > it->last_visible_x
2441 /* Or it fits exactly and we're on a window
2442 system frame. */
2443 || (new_x == it->last_visible_x
2444 && FRAME_WINDOW_P (it->f))))
2446 if (it->current.dpvec_index >= 0
2447 || it->current.overlay_string_index >= 0)
2449 set_iterator_to_next (it, 1);
2450 move_it_in_display_line_to (it, -1, -1, 0);
2453 it->continuation_lines_width += it->current_x;
2456 /* We're starting a new display line, not affected by the
2457 height of the continued line, so clear the appropriate
2458 fields in the iterator structure. */
2459 it->max_ascent = it->max_descent = 0;
2460 it->max_phys_ascent = it->max_phys_descent = 0;
2462 it->current_y = first_y;
2463 it->vpos = 0;
2464 it->current_x = it->hpos = 0;
2468 #if 0 /* Don't assert the following because start_display is sometimes
2469 called intentionally with a window start that is not at a
2470 line start. Please leave this code in as a comment. */
2472 /* Window start should be on a line start, now. */
2473 xassert (it->continuation_lines_width
2474 || IT_CHARPOS (it) == BEGV
2475 || FETCH_BYTE (IT_BYTEPOS (it) - 1) == '\n');
2476 #endif /* 0 */
2480 /* Return 1 if POS is a position in ellipses displayed for invisible
2481 text. W is the window we display, for text property lookup. */
2483 static int
2484 in_ellipses_for_invisible_text_p (pos, w)
2485 struct display_pos *pos;
2486 struct window *w;
2488 Lisp_Object prop, window;
2489 int ellipses_p = 0;
2490 int charpos = CHARPOS (pos->pos);
2492 /* If POS specifies a position in a display vector, this might
2493 be for an ellipsis displayed for invisible text. We won't
2494 get the iterator set up for delivering that ellipsis unless
2495 we make sure that it gets aware of the invisible text. */
2496 if (pos->dpvec_index >= 0
2497 && pos->overlay_string_index < 0
2498 && CHARPOS (pos->string_pos) < 0
2499 && charpos > BEGV
2500 && (XSETWINDOW (window, w),
2501 prop = Fget_char_property (make_number (charpos),
2502 Qinvisible, window),
2503 !TEXT_PROP_MEANS_INVISIBLE (prop)))
2505 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
2506 window);
2507 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
2510 return ellipses_p;
2514 /* Initialize IT for stepping through current_buffer in window W,
2515 starting at position POS that includes overlay string and display
2516 vector/ control character translation position information. Value
2517 is zero if there are overlay strings with newlines at POS. */
2519 static int
2520 init_from_display_pos (it, w, pos)
2521 struct it *it;
2522 struct window *w;
2523 struct display_pos *pos;
2525 int charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
2526 int i, overlay_strings_with_newlines = 0;
2528 /* If POS specifies a position in a display vector, this might
2529 be for an ellipsis displayed for invisible text. We won't
2530 get the iterator set up for delivering that ellipsis unless
2531 we make sure that it gets aware of the invisible text. */
2532 if (in_ellipses_for_invisible_text_p (pos, w))
2534 --charpos;
2535 bytepos = 0;
2538 /* Keep in mind: the call to reseat in init_iterator skips invisible
2539 text, so we might end up at a position different from POS. This
2540 is only a problem when POS is a row start after a newline and an
2541 overlay starts there with an after-string, and the overlay has an
2542 invisible property. Since we don't skip invisible text in
2543 display_line and elsewhere immediately after consuming the
2544 newline before the row start, such a POS will not be in a string,
2545 but the call to init_iterator below will move us to the
2546 after-string. */
2547 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
2549 /* This only scans the current chunk -- it should scan all chunks.
2550 However, OVERLAY_STRING_CHUNK_SIZE has been increased from 3 in 21.1
2551 to 16 in 22.1 to make this a lesser problem. */
2552 for (i = 0; i < it->n_overlay_strings && i < OVERLAY_STRING_CHUNK_SIZE; ++i)
2554 const char *s = SDATA (it->overlay_strings[i]);
2555 const char *e = s + SBYTES (it->overlay_strings[i]);
2557 while (s < e && *s != '\n')
2558 ++s;
2560 if (s < e)
2562 overlay_strings_with_newlines = 1;
2563 break;
2567 /* If position is within an overlay string, set up IT to the right
2568 overlay string. */
2569 if (pos->overlay_string_index >= 0)
2571 int relative_index;
2573 /* If the first overlay string happens to have a `display'
2574 property for an image, the iterator will be set up for that
2575 image, and we have to undo that setup first before we can
2576 correct the overlay string index. */
2577 if (it->method == GET_FROM_IMAGE)
2578 pop_it (it);
2580 /* We already have the first chunk of overlay strings in
2581 IT->overlay_strings. Load more until the one for
2582 pos->overlay_string_index is in IT->overlay_strings. */
2583 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
2585 int n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
2586 it->current.overlay_string_index = 0;
2587 while (n--)
2589 load_overlay_strings (it, 0);
2590 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
2594 it->current.overlay_string_index = pos->overlay_string_index;
2595 relative_index = (it->current.overlay_string_index
2596 % OVERLAY_STRING_CHUNK_SIZE);
2597 it->string = it->overlay_strings[relative_index];
2598 xassert (STRINGP (it->string));
2599 it->current.string_pos = pos->string_pos;
2600 it->method = GET_FROM_STRING;
2603 #if 0 /* This is bogus because POS not having an overlay string
2604 position does not mean it's after the string. Example: A
2605 line starting with a before-string and initialization of IT
2606 to the previous row's end position. */
2607 else if (it->current.overlay_string_index >= 0)
2609 /* If POS says we're already after an overlay string ending at
2610 POS, make sure to pop the iterator because it will be in
2611 front of that overlay string. When POS is ZV, we've thereby
2612 also ``processed'' overlay strings at ZV. */
2613 while (it->sp)
2614 pop_it (it);
2615 it->current.overlay_string_index = -1;
2616 it->method = GET_FROM_BUFFER;
2617 if (CHARPOS (pos->pos) == ZV)
2618 it->overlay_strings_at_end_processed_p = 1;
2620 #endif /* 0 */
2622 if (CHARPOS (pos->string_pos) >= 0)
2624 /* Recorded position is not in an overlay string, but in another
2625 string. This can only be a string from a `display' property.
2626 IT should already be filled with that string. */
2627 it->current.string_pos = pos->string_pos;
2628 xassert (STRINGP (it->string));
2631 /* Restore position in display vector translations, control
2632 character translations or ellipses. */
2633 if (pos->dpvec_index >= 0)
2635 if (it->dpvec == NULL)
2636 get_next_display_element (it);
2637 xassert (it->dpvec && it->current.dpvec_index == 0);
2638 it->current.dpvec_index = pos->dpvec_index;
2641 CHECK_IT (it);
2642 return !overlay_strings_with_newlines;
2646 /* Initialize IT for stepping through current_buffer in window W
2647 starting at ROW->start. */
2649 static void
2650 init_to_row_start (it, w, row)
2651 struct it *it;
2652 struct window *w;
2653 struct glyph_row *row;
2655 init_from_display_pos (it, w, &row->start);
2656 it->start = row->start;
2657 it->continuation_lines_width = row->continuation_lines_width;
2658 CHECK_IT (it);
2662 /* Initialize IT for stepping through current_buffer in window W
2663 starting in the line following ROW, i.e. starting at ROW->end.
2664 Value is zero if there are overlay strings with newlines at ROW's
2665 end position. */
2667 static int
2668 init_to_row_end (it, w, row)
2669 struct it *it;
2670 struct window *w;
2671 struct glyph_row *row;
2673 int success = 0;
2675 if (init_from_display_pos (it, w, &row->end))
2677 if (row->continued_p)
2678 it->continuation_lines_width
2679 = row->continuation_lines_width + row->pixel_width;
2680 CHECK_IT (it);
2681 success = 1;
2684 return success;
2690 /***********************************************************************
2691 Text properties
2692 ***********************************************************************/
2694 /* Called when IT reaches IT->stop_charpos. Handle text property and
2695 overlay changes. Set IT->stop_charpos to the next position where
2696 to stop. */
2698 static void
2699 handle_stop (it)
2700 struct it *it;
2702 enum prop_handled handled;
2703 int handle_overlay_change_p = 1;
2704 struct props *p;
2706 it->dpvec = NULL;
2707 it->current.dpvec_index = -1;
2709 /* Use face of preceding text for ellipsis (if invisible) */
2710 if (it->selective_display_ellipsis_p)
2711 it->saved_face_id = it->face_id;
2715 handled = HANDLED_NORMALLY;
2717 /* Call text property handlers. */
2718 for (p = it_props; p->handler; ++p)
2720 handled = p->handler (it);
2722 if (handled == HANDLED_RECOMPUTE_PROPS)
2723 break;
2724 else if (handled == HANDLED_RETURN)
2725 return;
2726 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
2727 handle_overlay_change_p = 0;
2730 if (handled != HANDLED_RECOMPUTE_PROPS)
2732 /* Don't check for overlay strings below when set to deliver
2733 characters from a display vector. */
2734 if (it->method == GET_FROM_DISPLAY_VECTOR)
2735 handle_overlay_change_p = 0;
2737 /* Handle overlay changes. */
2738 if (handle_overlay_change_p)
2739 handled = handle_overlay_change (it);
2741 /* Determine where to stop next. */
2742 if (handled == HANDLED_NORMALLY)
2743 compute_stop_pos (it);
2746 while (handled == HANDLED_RECOMPUTE_PROPS);
2750 /* Compute IT->stop_charpos from text property and overlay change
2751 information for IT's current position. */
2753 static void
2754 compute_stop_pos (it)
2755 struct it *it;
2757 register INTERVAL iv, next_iv;
2758 Lisp_Object object, limit, position;
2760 /* If nowhere else, stop at the end. */
2761 it->stop_charpos = it->end_charpos;
2763 if (STRINGP (it->string))
2765 /* Strings are usually short, so don't limit the search for
2766 properties. */
2767 object = it->string;
2768 limit = Qnil;
2769 position = make_number (IT_STRING_CHARPOS (*it));
2771 else
2773 int charpos;
2775 /* If next overlay change is in front of the current stop pos
2776 (which is IT->end_charpos), stop there. Note: value of
2777 next_overlay_change is point-max if no overlay change
2778 follows. */
2779 charpos = next_overlay_change (IT_CHARPOS (*it));
2780 if (charpos < it->stop_charpos)
2781 it->stop_charpos = charpos;
2783 /* If showing the region, we have to stop at the region
2784 start or end because the face might change there. */
2785 if (it->region_beg_charpos > 0)
2787 if (IT_CHARPOS (*it) < it->region_beg_charpos)
2788 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
2789 else if (IT_CHARPOS (*it) < it->region_end_charpos)
2790 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
2793 /* Set up variables for computing the stop position from text
2794 property changes. */
2795 XSETBUFFER (object, current_buffer);
2796 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
2797 position = make_number (IT_CHARPOS (*it));
2801 /* Get the interval containing IT's position. Value is a null
2802 interval if there isn't such an interval. */
2803 iv = validate_interval_range (object, &position, &position, 0);
2804 if (!NULL_INTERVAL_P (iv))
2806 Lisp_Object values_here[LAST_PROP_IDX];
2807 struct props *p;
2809 /* Get properties here. */
2810 for (p = it_props; p->handler; ++p)
2811 values_here[p->idx] = textget (iv->plist, *p->name);
2813 /* Look for an interval following iv that has different
2814 properties. */
2815 for (next_iv = next_interval (iv);
2816 (!NULL_INTERVAL_P (next_iv)
2817 && (NILP (limit)
2818 || XFASTINT (limit) > next_iv->position));
2819 next_iv = next_interval (next_iv))
2821 for (p = it_props; p->handler; ++p)
2823 Lisp_Object new_value;
2825 new_value = textget (next_iv->plist, *p->name);
2826 if (!EQ (values_here[p->idx], new_value))
2827 break;
2830 if (p->handler)
2831 break;
2834 if (!NULL_INTERVAL_P (next_iv))
2836 if (INTEGERP (limit)
2837 && next_iv->position >= XFASTINT (limit))
2838 /* No text property change up to limit. */
2839 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
2840 else
2841 /* Text properties change in next_iv. */
2842 it->stop_charpos = min (it->stop_charpos, next_iv->position);
2846 xassert (STRINGP (it->string)
2847 || (it->stop_charpos >= BEGV
2848 && it->stop_charpos >= IT_CHARPOS (*it)));
2852 /* Return the position of the next overlay change after POS in
2853 current_buffer. Value is point-max if no overlay change
2854 follows. This is like `next-overlay-change' but doesn't use
2855 xmalloc. */
2857 static int
2858 next_overlay_change (pos)
2859 int pos;
2861 int noverlays;
2862 int endpos;
2863 Lisp_Object *overlays;
2864 int i;
2866 /* Get all overlays at the given position. */
2867 GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, 1);
2869 /* If any of these overlays ends before endpos,
2870 use its ending point instead. */
2871 for (i = 0; i < noverlays; ++i)
2873 Lisp_Object oend;
2874 int oendpos;
2876 oend = OVERLAY_END (overlays[i]);
2877 oendpos = OVERLAY_POSITION (oend);
2878 endpos = min (endpos, oendpos);
2881 return endpos;
2886 /***********************************************************************
2887 Fontification
2888 ***********************************************************************/
2890 /* Handle changes in the `fontified' property of the current buffer by
2891 calling hook functions from Qfontification_functions to fontify
2892 regions of text. */
2894 static enum prop_handled
2895 handle_fontified_prop (it)
2896 struct it *it;
2898 Lisp_Object prop, pos;
2899 enum prop_handled handled = HANDLED_NORMALLY;
2901 /* Get the value of the `fontified' property at IT's current buffer
2902 position. (The `fontified' property doesn't have a special
2903 meaning in strings.) If the value is nil, call functions from
2904 Qfontification_functions. */
2905 if (!STRINGP (it->string)
2906 && it->s == NULL
2907 && !NILP (Vfontification_functions)
2908 && !NILP (Vrun_hooks)
2909 && (pos = make_number (IT_CHARPOS (*it)),
2910 prop = Fget_char_property (pos, Qfontified, Qnil),
2911 NILP (prop)))
2913 int count = SPECPDL_INDEX ();
2914 Lisp_Object val;
2916 val = Vfontification_functions;
2917 specbind (Qfontification_functions, Qnil);
2919 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
2920 safe_call1 (val, pos);
2921 else
2923 Lisp_Object globals, fn;
2924 struct gcpro gcpro1, gcpro2;
2926 globals = Qnil;
2927 GCPRO2 (val, globals);
2929 for (; CONSP (val); val = XCDR (val))
2931 fn = XCAR (val);
2933 if (EQ (fn, Qt))
2935 /* A value of t indicates this hook has a local
2936 binding; it means to run the global binding too.
2937 In a global value, t should not occur. If it
2938 does, we must ignore it to avoid an endless
2939 loop. */
2940 for (globals = Fdefault_value (Qfontification_functions);
2941 CONSP (globals);
2942 globals = XCDR (globals))
2944 fn = XCAR (globals);
2945 if (!EQ (fn, Qt))
2946 safe_call1 (fn, pos);
2949 else
2950 safe_call1 (fn, pos);
2953 UNGCPRO;
2956 unbind_to (count, Qnil);
2958 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
2959 something. This avoids an endless loop if they failed to
2960 fontify the text for which reason ever. */
2961 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
2962 handled = HANDLED_RECOMPUTE_PROPS;
2965 return handled;
2970 /***********************************************************************
2971 Faces
2972 ***********************************************************************/
2974 /* Set up iterator IT from face properties at its current position.
2975 Called from handle_stop. */
2977 static enum prop_handled
2978 handle_face_prop (it)
2979 struct it *it;
2981 int new_face_id, next_stop;
2983 if (!STRINGP (it->string))
2985 new_face_id
2986 = face_at_buffer_position (it->w,
2987 IT_CHARPOS (*it),
2988 it->region_beg_charpos,
2989 it->region_end_charpos,
2990 &next_stop,
2991 (IT_CHARPOS (*it)
2992 + TEXT_PROP_DISTANCE_LIMIT),
2995 /* Is this a start of a run of characters with box face?
2996 Caveat: this can be called for a freshly initialized
2997 iterator; face_id is -1 in this case. We know that the new
2998 face will not change until limit, i.e. if the new face has a
2999 box, all characters up to limit will have one. But, as
3000 usual, we don't know whether limit is really the end. */
3001 if (new_face_id != it->face_id)
3003 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3005 /* If new face has a box but old face has not, this is
3006 the start of a run of characters with box, i.e. it has
3007 a shadow on the left side. The value of face_id of the
3008 iterator will be -1 if this is the initial call that gets
3009 the face. In this case, we have to look in front of IT's
3010 position and see whether there is a face != new_face_id. */
3011 it->start_of_box_run_p
3012 = (new_face->box != FACE_NO_BOX
3013 && (it->face_id >= 0
3014 || IT_CHARPOS (*it) == BEG
3015 || new_face_id != face_before_it_pos (it)));
3016 it->face_box_p = new_face->box != FACE_NO_BOX;
3019 else
3021 int base_face_id, bufpos;
3023 if (it->current.overlay_string_index >= 0)
3024 bufpos = IT_CHARPOS (*it);
3025 else
3026 bufpos = 0;
3028 /* For strings from a buffer, i.e. overlay strings or strings
3029 from a `display' property, use the face at IT's current
3030 buffer position as the base face to merge with, so that
3031 overlay strings appear in the same face as surrounding
3032 text, unless they specify their own faces. */
3033 base_face_id = underlying_face_id (it);
3035 new_face_id = face_at_string_position (it->w,
3036 it->string,
3037 IT_STRING_CHARPOS (*it),
3038 bufpos,
3039 it->region_beg_charpos,
3040 it->region_end_charpos,
3041 &next_stop,
3042 base_face_id, 0);
3044 #if 0 /* This shouldn't be neccessary. Let's check it. */
3045 /* If IT is used to display a mode line we would really like to
3046 use the mode line face instead of the frame's default face. */
3047 if (it->glyph_row == MATRIX_MODE_LINE_ROW (it->w->desired_matrix)
3048 && new_face_id == DEFAULT_FACE_ID)
3049 new_face_id = CURRENT_MODE_LINE_FACE_ID (it->w);
3050 #endif
3052 /* Is this a start of a run of characters with box? Caveat:
3053 this can be called for a freshly allocated iterator; face_id
3054 is -1 is this case. We know that the new face will not
3055 change until the next check pos, i.e. if the new face has a
3056 box, all characters up to that position will have a
3057 box. But, as usual, we don't know whether that position
3058 is really the end. */
3059 if (new_face_id != it->face_id)
3061 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3062 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
3064 /* If new face has a box but old face hasn't, this is the
3065 start of a run of characters with box, i.e. it has a
3066 shadow on the left side. */
3067 it->start_of_box_run_p
3068 = new_face->box && (old_face == NULL || !old_face->box);
3069 it->face_box_p = new_face->box != FACE_NO_BOX;
3073 it->face_id = new_face_id;
3074 return HANDLED_NORMALLY;
3078 /* Return the ID of the face ``underlying'' IT's current position,
3079 which is in a string. If the iterator is associated with a
3080 buffer, return the face at IT's current buffer position.
3081 Otherwise, use the iterator's base_face_id. */
3083 static int
3084 underlying_face_id (it)
3085 struct it *it;
3087 int face_id = it->base_face_id, i;
3089 xassert (STRINGP (it->string));
3091 for (i = it->sp - 1; i >= 0; --i)
3092 if (NILP (it->stack[i].string))
3093 face_id = it->stack[i].face_id;
3095 return face_id;
3099 /* Compute the face one character before or after the current position
3100 of IT. BEFORE_P non-zero means get the face in front of IT's
3101 position. Value is the id of the face. */
3103 static int
3104 face_before_or_after_it_pos (it, before_p)
3105 struct it *it;
3106 int before_p;
3108 int face_id, limit;
3109 int next_check_charpos;
3110 struct text_pos pos;
3112 xassert (it->s == NULL);
3114 if (STRINGP (it->string))
3116 int bufpos, base_face_id;
3118 /* No face change past the end of the string (for the case
3119 we are padding with spaces). No face change before the
3120 string start. */
3121 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
3122 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
3123 return it->face_id;
3125 /* Set pos to the position before or after IT's current position. */
3126 if (before_p)
3127 pos = string_pos (IT_STRING_CHARPOS (*it) - 1, it->string);
3128 else
3129 /* For composition, we must check the character after the
3130 composition. */
3131 pos = (it->what == IT_COMPOSITION
3132 ? string_pos (IT_STRING_CHARPOS (*it) + it->cmp_len, it->string)
3133 : string_pos (IT_STRING_CHARPOS (*it) + 1, it->string));
3135 if (it->current.overlay_string_index >= 0)
3136 bufpos = IT_CHARPOS (*it);
3137 else
3138 bufpos = 0;
3140 base_face_id = underlying_face_id (it);
3142 /* Get the face for ASCII, or unibyte. */
3143 face_id = face_at_string_position (it->w,
3144 it->string,
3145 CHARPOS (pos),
3146 bufpos,
3147 it->region_beg_charpos,
3148 it->region_end_charpos,
3149 &next_check_charpos,
3150 base_face_id, 0);
3152 /* Correct the face for charsets different from ASCII. Do it
3153 for the multibyte case only. The face returned above is
3154 suitable for unibyte text if IT->string is unibyte. */
3155 if (STRING_MULTIBYTE (it->string))
3157 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos);
3158 int rest = SBYTES (it->string) - BYTEPOS (pos);
3159 int c, len;
3160 struct face *face = FACE_FROM_ID (it->f, face_id);
3162 c = string_char_and_length (p, rest, &len);
3163 face_id = FACE_FOR_CHAR (it->f, face, c);
3166 else
3168 if ((IT_CHARPOS (*it) >= ZV && !before_p)
3169 || (IT_CHARPOS (*it) <= BEGV && before_p))
3170 return it->face_id;
3172 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
3173 pos = it->current.pos;
3175 if (before_p)
3176 DEC_TEXT_POS (pos, it->multibyte_p);
3177 else
3179 if (it->what == IT_COMPOSITION)
3180 /* For composition, we must check the position after the
3181 composition. */
3182 pos.charpos += it->cmp_len, pos.bytepos += it->len;
3183 else
3184 INC_TEXT_POS (pos, it->multibyte_p);
3187 /* Determine face for CHARSET_ASCII, or unibyte. */
3188 face_id = face_at_buffer_position (it->w,
3189 CHARPOS (pos),
3190 it->region_beg_charpos,
3191 it->region_end_charpos,
3192 &next_check_charpos,
3193 limit, 0);
3195 /* Correct the face for charsets different from ASCII. Do it
3196 for the multibyte case only. The face returned above is
3197 suitable for unibyte text if current_buffer is unibyte. */
3198 if (it->multibyte_p)
3200 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
3201 struct face *face = FACE_FROM_ID (it->f, face_id);
3202 face_id = FACE_FOR_CHAR (it->f, face, c);
3206 return face_id;
3211 /***********************************************************************
3212 Invisible text
3213 ***********************************************************************/
3215 /* Set up iterator IT from invisible properties at its current
3216 position. Called from handle_stop. */
3218 static enum prop_handled
3219 handle_invisible_prop (it)
3220 struct it *it;
3222 enum prop_handled handled = HANDLED_NORMALLY;
3224 if (STRINGP (it->string))
3226 extern Lisp_Object Qinvisible;
3227 Lisp_Object prop, end_charpos, limit, charpos;
3229 /* Get the value of the invisible text property at the
3230 current position. Value will be nil if there is no such
3231 property. */
3232 charpos = make_number (IT_STRING_CHARPOS (*it));
3233 prop = Fget_text_property (charpos, Qinvisible, it->string);
3235 if (!NILP (prop)
3236 && IT_STRING_CHARPOS (*it) < it->end_charpos)
3238 handled = HANDLED_RECOMPUTE_PROPS;
3240 /* Get the position at which the next change of the
3241 invisible text property can be found in IT->string.
3242 Value will be nil if the property value is the same for
3243 all the rest of IT->string. */
3244 XSETINT (limit, SCHARS (it->string));
3245 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
3246 it->string, limit);
3248 /* Text at current position is invisible. The next
3249 change in the property is at position end_charpos.
3250 Move IT's current position to that position. */
3251 if (INTEGERP (end_charpos)
3252 && XFASTINT (end_charpos) < XFASTINT (limit))
3254 struct text_pos old;
3255 old = it->current.string_pos;
3256 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
3257 compute_string_pos (&it->current.string_pos, old, it->string);
3259 else
3261 /* The rest of the string is invisible. If this is an
3262 overlay string, proceed with the next overlay string
3263 or whatever comes and return a character from there. */
3264 if (it->current.overlay_string_index >= 0)
3266 next_overlay_string (it);
3267 /* Don't check for overlay strings when we just
3268 finished processing them. */
3269 handled = HANDLED_OVERLAY_STRING_CONSUMED;
3271 else
3273 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
3274 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
3279 else
3281 int invis_p, newpos, next_stop, start_charpos;
3282 Lisp_Object pos, prop, overlay;
3284 /* First of all, is there invisible text at this position? */
3285 start_charpos = IT_CHARPOS (*it);
3286 pos = make_number (IT_CHARPOS (*it));
3287 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
3288 &overlay);
3289 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3291 /* If we are on invisible text, skip over it. */
3292 if (invis_p && IT_CHARPOS (*it) < it->end_charpos)
3294 /* Record whether we have to display an ellipsis for the
3295 invisible text. */
3296 int display_ellipsis_p = invis_p == 2;
3298 handled = HANDLED_RECOMPUTE_PROPS;
3300 /* Loop skipping over invisible text. The loop is left at
3301 ZV or with IT on the first char being visible again. */
3304 /* Try to skip some invisible text. Return value is the
3305 position reached which can be equal to IT's position
3306 if there is nothing invisible here. This skips both
3307 over invisible text properties and overlays with
3308 invisible property. */
3309 newpos = skip_invisible (IT_CHARPOS (*it),
3310 &next_stop, ZV, it->window);
3312 /* If we skipped nothing at all we weren't at invisible
3313 text in the first place. If everything to the end of
3314 the buffer was skipped, end the loop. */
3315 if (newpos == IT_CHARPOS (*it) || newpos >= ZV)
3316 invis_p = 0;
3317 else
3319 /* We skipped some characters but not necessarily
3320 all there are. Check if we ended up on visible
3321 text. Fget_char_property returns the property of
3322 the char before the given position, i.e. if we
3323 get invis_p = 0, this means that the char at
3324 newpos is visible. */
3325 pos = make_number (newpos);
3326 prop = Fget_char_property (pos, Qinvisible, it->window);
3327 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3330 /* If we ended up on invisible text, proceed to
3331 skip starting with next_stop. */
3332 if (invis_p)
3333 IT_CHARPOS (*it) = next_stop;
3335 while (invis_p);
3337 /* The position newpos is now either ZV or on visible text. */
3338 IT_CHARPOS (*it) = newpos;
3339 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
3341 /* If there are before-strings at the start of invisible
3342 text, and the text is invisible because of a text
3343 property, arrange to show before-strings because 20.x did
3344 it that way. (If the text is invisible because of an
3345 overlay property instead of a text property, this is
3346 already handled in the overlay code.) */
3347 if (NILP (overlay)
3348 && get_overlay_strings (it, start_charpos))
3350 handled = HANDLED_RECOMPUTE_PROPS;
3351 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
3353 else if (display_ellipsis_p)
3354 setup_for_ellipsis (it, 0);
3358 return handled;
3362 /* Make iterator IT return `...' next.
3363 Replaces LEN characters from buffer. */
3365 static void
3366 setup_for_ellipsis (it, len)
3367 struct it *it;
3368 int len;
3370 /* Use the display table definition for `...'. Invalid glyphs
3371 will be handled by the method returning elements from dpvec. */
3372 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
3374 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
3375 it->dpvec = v->contents;
3376 it->dpend = v->contents + v->size;
3378 else
3380 /* Default `...'. */
3381 it->dpvec = default_invis_vector;
3382 it->dpend = default_invis_vector + 3;
3385 it->dpvec_char_len = len;
3386 it->current.dpvec_index = 0;
3387 it->dpvec_face_id = -1;
3389 /* Remember the current face id in case glyphs specify faces.
3390 IT's face is restored in set_iterator_to_next.
3391 saved_face_id was set to preceding char's face in handle_stop. */
3392 if (it->saved_face_id < 0 || it->saved_face_id != it->face_id)
3393 it->saved_face_id = it->face_id = DEFAULT_FACE_ID;
3395 it->method = GET_FROM_DISPLAY_VECTOR;
3396 it->ellipsis_p = 1;
3401 /***********************************************************************
3402 'display' property
3403 ***********************************************************************/
3405 /* Set up iterator IT from `display' property at its current position.
3406 Called from handle_stop.
3407 We return HANDLED_RETURN if some part of the display property
3408 overrides the display of the buffer text itself.
3409 Otherwise we return HANDLED_NORMALLY. */
3411 static enum prop_handled
3412 handle_display_prop (it)
3413 struct it *it;
3415 Lisp_Object prop, object;
3416 struct text_pos *position;
3417 /* Nonzero if some property replaces the display of the text itself. */
3418 int display_replaced_p = 0;
3420 if (STRINGP (it->string))
3422 object = it->string;
3423 position = &it->current.string_pos;
3425 else
3427 object = it->w->buffer;
3428 position = &it->current.pos;
3431 /* Reset those iterator values set from display property values. */
3432 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
3433 it->space_width = Qnil;
3434 it->font_height = Qnil;
3435 it->voffset = 0;
3437 /* We don't support recursive `display' properties, i.e. string
3438 values that have a string `display' property, that have a string
3439 `display' property etc. */
3440 if (!it->string_from_display_prop_p)
3441 it->area = TEXT_AREA;
3443 prop = Fget_char_property (make_number (position->charpos),
3444 Qdisplay, object);
3445 if (NILP (prop))
3446 return HANDLED_NORMALLY;
3448 if (CONSP (prop)
3449 /* Simple properties. */
3450 && !EQ (XCAR (prop), Qimage)
3451 && !EQ (XCAR (prop), Qspace)
3452 && !EQ (XCAR (prop), Qwhen)
3453 && !EQ (XCAR (prop), Qslice)
3454 && !EQ (XCAR (prop), Qspace_width)
3455 && !EQ (XCAR (prop), Qheight)
3456 && !EQ (XCAR (prop), Qraise)
3457 /* Marginal area specifications. */
3458 && !(CONSP (XCAR (prop)) && EQ (XCAR (XCAR (prop)), Qmargin))
3459 && !EQ (XCAR (prop), Qleft_fringe)
3460 && !EQ (XCAR (prop), Qright_fringe)
3461 && !NILP (XCAR (prop)))
3463 for (; CONSP (prop); prop = XCDR (prop))
3465 if (handle_single_display_spec (it, XCAR (prop), object,
3466 position, display_replaced_p))
3467 display_replaced_p = 1;
3470 else if (VECTORP (prop))
3472 int i;
3473 for (i = 0; i < ASIZE (prop); ++i)
3474 if (handle_single_display_spec (it, AREF (prop, i), object,
3475 position, display_replaced_p))
3476 display_replaced_p = 1;
3478 else
3480 if (handle_single_display_spec (it, prop, object, position, 0))
3481 display_replaced_p = 1;
3484 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
3488 /* Value is the position of the end of the `display' property starting
3489 at START_POS in OBJECT. */
3491 static struct text_pos
3492 display_prop_end (it, object, start_pos)
3493 struct it *it;
3494 Lisp_Object object;
3495 struct text_pos start_pos;
3497 Lisp_Object end;
3498 struct text_pos end_pos;
3500 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
3501 Qdisplay, object, Qnil);
3502 CHARPOS (end_pos) = XFASTINT (end);
3503 if (STRINGP (object))
3504 compute_string_pos (&end_pos, start_pos, it->string);
3505 else
3506 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
3508 return end_pos;
3512 /* Set up IT from a single `display' specification PROP. OBJECT
3513 is the object in which the `display' property was found. *POSITION
3514 is the position at which it was found. DISPLAY_REPLACED_P non-zero
3515 means that we previously saw a display specification which already
3516 replaced text display with something else, for example an image;
3517 we ignore such properties after the first one has been processed.
3519 If PROP is a `space' or `image' specification, and in some other
3520 cases too, set *POSITION to the position where the `display'
3521 property ends.
3523 Value is non-zero if something was found which replaces the display
3524 of buffer or string text. */
3526 static int
3527 handle_single_display_spec (it, spec, object, position,
3528 display_replaced_before_p)
3529 struct it *it;
3530 Lisp_Object spec;
3531 Lisp_Object object;
3532 struct text_pos *position;
3533 int display_replaced_before_p;
3535 Lisp_Object form;
3536 Lisp_Object location, value;
3537 struct text_pos start_pos;
3538 int valid_p;
3540 /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
3541 If the result is non-nil, use VALUE instead of SPEC. */
3542 form = Qt;
3543 if (CONSP (spec) && EQ (XCAR (spec), Qwhen))
3545 spec = XCDR (spec);
3546 if (!CONSP (spec))
3547 return 0;
3548 form = XCAR (spec);
3549 spec = XCDR (spec);
3552 if (!NILP (form) && !EQ (form, Qt))
3554 int count = SPECPDL_INDEX ();
3555 struct gcpro gcpro1;
3557 /* Bind `object' to the object having the `display' property, a
3558 buffer or string. Bind `position' to the position in the
3559 object where the property was found, and `buffer-position'
3560 to the current position in the buffer. */
3561 specbind (Qobject, object);
3562 specbind (Qposition, make_number (CHARPOS (*position)));
3563 specbind (Qbuffer_position,
3564 make_number (STRINGP (object)
3565 ? IT_CHARPOS (*it) : CHARPOS (*position)));
3566 GCPRO1 (form);
3567 form = safe_eval (form);
3568 UNGCPRO;
3569 unbind_to (count, Qnil);
3572 if (NILP (form))
3573 return 0;
3575 /* Handle `(height HEIGHT)' specifications. */
3576 if (CONSP (spec)
3577 && EQ (XCAR (spec), Qheight)
3578 && CONSP (XCDR (spec)))
3580 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3581 return 0;
3583 it->font_height = XCAR (XCDR (spec));
3584 if (!NILP (it->font_height))
3586 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3587 int new_height = -1;
3589 if (CONSP (it->font_height)
3590 && (EQ (XCAR (it->font_height), Qplus)
3591 || EQ (XCAR (it->font_height), Qminus))
3592 && CONSP (XCDR (it->font_height))
3593 && INTEGERP (XCAR (XCDR (it->font_height))))
3595 /* `(+ N)' or `(- N)' where N is an integer. */
3596 int steps = XINT (XCAR (XCDR (it->font_height)));
3597 if (EQ (XCAR (it->font_height), Qplus))
3598 steps = - steps;
3599 it->face_id = smaller_face (it->f, it->face_id, steps);
3601 else if (FUNCTIONP (it->font_height))
3603 /* Call function with current height as argument.
3604 Value is the new height. */
3605 Lisp_Object height;
3606 height = safe_call1 (it->font_height,
3607 face->lface[LFACE_HEIGHT_INDEX]);
3608 if (NUMBERP (height))
3609 new_height = XFLOATINT (height);
3611 else if (NUMBERP (it->font_height))
3613 /* Value is a multiple of the canonical char height. */
3614 struct face *face;
3616 face = FACE_FROM_ID (it->f, DEFAULT_FACE_ID);
3617 new_height = (XFLOATINT (it->font_height)
3618 * XINT (face->lface[LFACE_HEIGHT_INDEX]));
3620 else
3622 /* Evaluate IT->font_height with `height' bound to the
3623 current specified height to get the new height. */
3624 int count = SPECPDL_INDEX ();
3626 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
3627 value = safe_eval (it->font_height);
3628 unbind_to (count, Qnil);
3630 if (NUMBERP (value))
3631 new_height = XFLOATINT (value);
3634 if (new_height > 0)
3635 it->face_id = face_with_height (it->f, it->face_id, new_height);
3638 return 0;
3641 /* Handle `(space_width WIDTH)'. */
3642 if (CONSP (spec)
3643 && EQ (XCAR (spec), Qspace_width)
3644 && CONSP (XCDR (spec)))
3646 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3647 return 0;
3649 value = XCAR (XCDR (spec));
3650 if (NUMBERP (value) && XFLOATINT (value) > 0)
3651 it->space_width = value;
3653 return 0;
3656 /* Handle `(slice X Y WIDTH HEIGHT)'. */
3657 if (CONSP (spec)
3658 && EQ (XCAR (spec), Qslice))
3660 Lisp_Object tem;
3662 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3663 return 0;
3665 if (tem = XCDR (spec), CONSP (tem))
3667 it->slice.x = XCAR (tem);
3668 if (tem = XCDR (tem), CONSP (tem))
3670 it->slice.y = XCAR (tem);
3671 if (tem = XCDR (tem), CONSP (tem))
3673 it->slice.width = XCAR (tem);
3674 if (tem = XCDR (tem), CONSP (tem))
3675 it->slice.height = XCAR (tem);
3680 return 0;
3683 /* Handle `(raise FACTOR)'. */
3684 if (CONSP (spec)
3685 && EQ (XCAR (spec), Qraise)
3686 && CONSP (XCDR (spec)))
3688 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3689 return 0;
3691 #ifdef HAVE_WINDOW_SYSTEM
3692 value = XCAR (XCDR (spec));
3693 if (NUMBERP (value))
3695 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3696 it->voffset = - (XFLOATINT (value)
3697 * (FONT_HEIGHT (face->font)));
3699 #endif /* HAVE_WINDOW_SYSTEM */
3701 return 0;
3704 /* Don't handle the other kinds of display specifications
3705 inside a string that we got from a `display' property. */
3706 if (it->string_from_display_prop_p)
3707 return 0;
3709 /* Characters having this form of property are not displayed, so
3710 we have to find the end of the property. */
3711 start_pos = *position;
3712 *position = display_prop_end (it, object, start_pos);
3713 value = Qnil;
3715 /* Stop the scan at that end position--we assume that all
3716 text properties change there. */
3717 it->stop_charpos = position->charpos;
3719 /* Handle `(left-fringe BITMAP [FACE])'
3720 and `(right-fringe BITMAP [FACE])'. */
3721 if (CONSP (spec)
3722 && (EQ (XCAR (spec), Qleft_fringe)
3723 || EQ (XCAR (spec), Qright_fringe))
3724 && CONSP (XCDR (spec)))
3726 int face_id = DEFAULT_FACE_ID;
3727 int fringe_bitmap;
3729 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3730 /* If we return here, POSITION has been advanced
3731 across the text with this property. */
3732 return 0;
3734 #ifdef HAVE_WINDOW_SYSTEM
3735 value = XCAR (XCDR (spec));
3736 if (!SYMBOLP (value)
3737 || !(fringe_bitmap = lookup_fringe_bitmap (value)))
3738 /* If we return here, POSITION has been advanced
3739 across the text with this property. */
3740 return 0;
3742 if (CONSP (XCDR (XCDR (spec))))
3744 Lisp_Object face_name = XCAR (XCDR (XCDR (spec)));
3745 int face_id2 = lookup_derived_face (it->f, face_name,
3746 'A', FRINGE_FACE_ID, 0);
3747 if (face_id2 >= 0)
3748 face_id = face_id2;
3751 /* Save current settings of IT so that we can restore them
3752 when we are finished with the glyph property value. */
3754 push_it (it);
3756 it->area = TEXT_AREA;
3757 it->what = IT_IMAGE;
3758 it->image_id = -1; /* no image */
3759 it->position = start_pos;
3760 it->object = NILP (object) ? it->w->buffer : object;
3761 it->method = GET_FROM_IMAGE;
3762 it->face_id = face_id;
3764 /* Say that we haven't consumed the characters with
3765 `display' property yet. The call to pop_it in
3766 set_iterator_to_next will clean this up. */
3767 *position = start_pos;
3769 if (EQ (XCAR (spec), Qleft_fringe))
3771 it->left_user_fringe_bitmap = fringe_bitmap;
3772 it->left_user_fringe_face_id = face_id;
3774 else
3776 it->right_user_fringe_bitmap = fringe_bitmap;
3777 it->right_user_fringe_face_id = face_id;
3779 #endif /* HAVE_WINDOW_SYSTEM */
3780 return 1;
3783 /* Prepare to handle `((margin left-margin) ...)',
3784 `((margin right-margin) ...)' and `((margin nil) ...)'
3785 prefixes for display specifications. */
3786 location = Qunbound;
3787 if (CONSP (spec) && CONSP (XCAR (spec)))
3789 Lisp_Object tem;
3791 value = XCDR (spec);
3792 if (CONSP (value))
3793 value = XCAR (value);
3795 tem = XCAR (spec);
3796 if (EQ (XCAR (tem), Qmargin)
3797 && (tem = XCDR (tem),
3798 tem = CONSP (tem) ? XCAR (tem) : Qnil,
3799 (NILP (tem)
3800 || EQ (tem, Qleft_margin)
3801 || EQ (tem, Qright_margin))))
3802 location = tem;
3805 if (EQ (location, Qunbound))
3807 location = Qnil;
3808 value = spec;
3811 /* After this point, VALUE is the property after any
3812 margin prefix has been stripped. It must be a string,
3813 an image specification, or `(space ...)'.
3815 LOCATION specifies where to display: `left-margin',
3816 `right-margin' or nil. */
3818 valid_p = (STRINGP (value)
3819 #ifdef HAVE_WINDOW_SYSTEM
3820 || (!FRAME_TERMCAP_P (it->f) && valid_image_p (value))
3821 #endif /* not HAVE_WINDOW_SYSTEM */
3822 || (CONSP (value) && EQ (XCAR (value), Qspace)));
3824 if (valid_p && !display_replaced_before_p)
3826 /* Save current settings of IT so that we can restore them
3827 when we are finished with the glyph property value. */
3828 push_it (it);
3830 if (NILP (location))
3831 it->area = TEXT_AREA;
3832 else if (EQ (location, Qleft_margin))
3833 it->area = LEFT_MARGIN_AREA;
3834 else
3835 it->area = RIGHT_MARGIN_AREA;
3837 if (STRINGP (value))
3839 it->string = value;
3840 it->multibyte_p = STRING_MULTIBYTE (it->string);
3841 it->current.overlay_string_index = -1;
3842 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
3843 it->end_charpos = it->string_nchars = SCHARS (it->string);
3844 it->method = GET_FROM_STRING;
3845 it->stop_charpos = 0;
3846 it->string_from_display_prop_p = 1;
3847 /* Say that we haven't consumed the characters with
3848 `display' property yet. The call to pop_it in
3849 set_iterator_to_next will clean this up. */
3850 *position = start_pos;
3852 else if (CONSP (value) && EQ (XCAR (value), Qspace))
3854 it->method = GET_FROM_STRETCH;
3855 it->object = value;
3856 it->current.pos = it->position = start_pos;
3858 #ifdef HAVE_WINDOW_SYSTEM
3859 else
3861 it->what = IT_IMAGE;
3862 it->image_id = lookup_image (it->f, value);
3863 it->position = start_pos;
3864 it->object = NILP (object) ? it->w->buffer : object;
3865 it->method = GET_FROM_IMAGE;
3867 /* Say that we haven't consumed the characters with
3868 `display' property yet. The call to pop_it in
3869 set_iterator_to_next will clean this up. */
3870 *position = start_pos;
3872 #endif /* HAVE_WINDOW_SYSTEM */
3874 return 1;
3877 /* Invalid property or property not supported. Restore
3878 POSITION to what it was before. */
3879 *position = start_pos;
3880 return 0;
3884 /* Check if SPEC is a display specification value whose text should be
3885 treated as intangible. */
3887 static int
3888 single_display_spec_intangible_p (prop)
3889 Lisp_Object prop;
3891 /* Skip over `when FORM'. */
3892 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3894 prop = XCDR (prop);
3895 if (!CONSP (prop))
3896 return 0;
3897 prop = XCDR (prop);
3900 if (STRINGP (prop))
3901 return 1;
3903 if (!CONSP (prop))
3904 return 0;
3906 /* Skip over `margin LOCATION'. If LOCATION is in the margins,
3907 we don't need to treat text as intangible. */
3908 if (EQ (XCAR (prop), Qmargin))
3910 prop = XCDR (prop);
3911 if (!CONSP (prop))
3912 return 0;
3914 prop = XCDR (prop);
3915 if (!CONSP (prop)
3916 || EQ (XCAR (prop), Qleft_margin)
3917 || EQ (XCAR (prop), Qright_margin))
3918 return 0;
3921 return (CONSP (prop)
3922 && (EQ (XCAR (prop), Qimage)
3923 || EQ (XCAR (prop), Qspace)));
3927 /* Check if PROP is a display property value whose text should be
3928 treated as intangible. */
3931 display_prop_intangible_p (prop)
3932 Lisp_Object prop;
3934 if (CONSP (prop)
3935 && CONSP (XCAR (prop))
3936 && !EQ (Qmargin, XCAR (XCAR (prop))))
3938 /* A list of sub-properties. */
3939 while (CONSP (prop))
3941 if (single_display_spec_intangible_p (XCAR (prop)))
3942 return 1;
3943 prop = XCDR (prop);
3946 else if (VECTORP (prop))
3948 /* A vector of sub-properties. */
3949 int i;
3950 for (i = 0; i < ASIZE (prop); ++i)
3951 if (single_display_spec_intangible_p (AREF (prop, i)))
3952 return 1;
3954 else
3955 return single_display_spec_intangible_p (prop);
3957 return 0;
3961 /* Return 1 if PROP is a display sub-property value containing STRING. */
3963 static int
3964 single_display_spec_string_p (prop, string)
3965 Lisp_Object prop, string;
3967 if (EQ (string, prop))
3968 return 1;
3970 /* Skip over `when FORM'. */
3971 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3973 prop = XCDR (prop);
3974 if (!CONSP (prop))
3975 return 0;
3976 prop = XCDR (prop);
3979 if (CONSP (prop))
3980 /* Skip over `margin LOCATION'. */
3981 if (EQ (XCAR (prop), Qmargin))
3983 prop = XCDR (prop);
3984 if (!CONSP (prop))
3985 return 0;
3987 prop = XCDR (prop);
3988 if (!CONSP (prop))
3989 return 0;
3992 return CONSP (prop) && EQ (XCAR (prop), string);
3996 /* Return 1 if STRING appears in the `display' property PROP. */
3998 static int
3999 display_prop_string_p (prop, string)
4000 Lisp_Object prop, string;
4002 if (CONSP (prop)
4003 && CONSP (XCAR (prop))
4004 && !EQ (Qmargin, XCAR (XCAR (prop))))
4006 /* A list of sub-properties. */
4007 while (CONSP (prop))
4009 if (single_display_spec_string_p (XCAR (prop), string))
4010 return 1;
4011 prop = XCDR (prop);
4014 else if (VECTORP (prop))
4016 /* A vector of sub-properties. */
4017 int i;
4018 for (i = 0; i < ASIZE (prop); ++i)
4019 if (single_display_spec_string_p (AREF (prop, i), string))
4020 return 1;
4022 else
4023 return single_display_spec_string_p (prop, string);
4025 return 0;
4029 /* Determine from which buffer position in W's buffer STRING comes
4030 from. AROUND_CHARPOS is an approximate position where it could
4031 be from. Value is the buffer position or 0 if it couldn't be
4032 determined.
4034 W's buffer must be current.
4036 This function is necessary because we don't record buffer positions
4037 in glyphs generated from strings (to keep struct glyph small).
4038 This function may only use code that doesn't eval because it is
4039 called asynchronously from note_mouse_highlight. */
4042 string_buffer_position (w, string, around_charpos)
4043 struct window *w;
4044 Lisp_Object string;
4045 int around_charpos;
4047 Lisp_Object limit, prop, pos;
4048 const int MAX_DISTANCE = 1000;
4049 int found = 0;
4051 pos = make_number (around_charpos);
4052 limit = make_number (min (XINT (pos) + MAX_DISTANCE, ZV));
4053 while (!found && !EQ (pos, limit))
4055 prop = Fget_char_property (pos, Qdisplay, Qnil);
4056 if (!NILP (prop) && display_prop_string_p (prop, string))
4057 found = 1;
4058 else
4059 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil, limit);
4062 if (!found)
4064 pos = make_number (around_charpos);
4065 limit = make_number (max (XINT (pos) - MAX_DISTANCE, BEGV));
4066 while (!found && !EQ (pos, limit))
4068 prop = Fget_char_property (pos, Qdisplay, Qnil);
4069 if (!NILP (prop) && display_prop_string_p (prop, string))
4070 found = 1;
4071 else
4072 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
4073 limit);
4077 return found ? XINT (pos) : 0;
4082 /***********************************************************************
4083 `composition' property
4084 ***********************************************************************/
4086 /* Set up iterator IT from `composition' property at its current
4087 position. Called from handle_stop. */
4089 static enum prop_handled
4090 handle_composition_prop (it)
4091 struct it *it;
4093 Lisp_Object prop, string;
4094 int pos, pos_byte, end;
4095 enum prop_handled handled = HANDLED_NORMALLY;
4097 if (STRINGP (it->string))
4099 pos = IT_STRING_CHARPOS (*it);
4100 pos_byte = IT_STRING_BYTEPOS (*it);
4101 string = it->string;
4103 else
4105 pos = IT_CHARPOS (*it);
4106 pos_byte = IT_BYTEPOS (*it);
4107 string = Qnil;
4110 /* If there's a valid composition and point is not inside of the
4111 composition (in the case that the composition is from the current
4112 buffer), draw a glyph composed from the composition components. */
4113 if (find_composition (pos, -1, &pos, &end, &prop, string)
4114 && COMPOSITION_VALID_P (pos, end, prop)
4115 && (STRINGP (it->string) || (PT <= pos || PT >= end)))
4117 int id = get_composition_id (pos, pos_byte, end - pos, prop, string);
4119 if (id >= 0)
4121 it->method = GET_FROM_COMPOSITION;
4122 it->cmp_id = id;
4123 it->cmp_len = COMPOSITION_LENGTH (prop);
4124 /* For a terminal, draw only the first character of the
4125 components. */
4126 it->c = COMPOSITION_GLYPH (composition_table[id], 0);
4127 it->len = (STRINGP (it->string)
4128 ? string_char_to_byte (it->string, end)
4129 : CHAR_TO_BYTE (end)) - pos_byte;
4130 it->stop_charpos = end;
4131 handled = HANDLED_RETURN;
4135 return handled;
4140 /***********************************************************************
4141 Overlay strings
4142 ***********************************************************************/
4144 /* The following structure is used to record overlay strings for
4145 later sorting in load_overlay_strings. */
4147 struct overlay_entry
4149 Lisp_Object overlay;
4150 Lisp_Object string;
4151 int priority;
4152 int after_string_p;
4156 /* Set up iterator IT from overlay strings at its current position.
4157 Called from handle_stop. */
4159 static enum prop_handled
4160 handle_overlay_change (it)
4161 struct it *it;
4163 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
4164 return HANDLED_RECOMPUTE_PROPS;
4165 else
4166 return HANDLED_NORMALLY;
4170 /* Set up the next overlay string for delivery by IT, if there is an
4171 overlay string to deliver. Called by set_iterator_to_next when the
4172 end of the current overlay string is reached. If there are more
4173 overlay strings to display, IT->string and
4174 IT->current.overlay_string_index are set appropriately here.
4175 Otherwise IT->string is set to nil. */
4177 static void
4178 next_overlay_string (it)
4179 struct it *it;
4181 ++it->current.overlay_string_index;
4182 if (it->current.overlay_string_index == it->n_overlay_strings)
4184 /* No more overlay strings. Restore IT's settings to what
4185 they were before overlay strings were processed, and
4186 continue to deliver from current_buffer. */
4187 int display_ellipsis_p = it->stack[it->sp - 1].display_ellipsis_p;
4189 pop_it (it);
4190 xassert (it->stop_charpos >= BEGV
4191 && it->stop_charpos <= it->end_charpos);
4192 it->string = Qnil;
4193 it->current.overlay_string_index = -1;
4194 SET_TEXT_POS (it->current.string_pos, -1, -1);
4195 it->n_overlay_strings = 0;
4196 it->method = GET_FROM_BUFFER;
4198 /* If we're at the end of the buffer, record that we have
4199 processed the overlay strings there already, so that
4200 next_element_from_buffer doesn't try it again. */
4201 if (IT_CHARPOS (*it) >= it->end_charpos)
4202 it->overlay_strings_at_end_processed_p = 1;
4204 /* If we have to display `...' for invisible text, set
4205 the iterator up for that. */
4206 if (display_ellipsis_p)
4207 setup_for_ellipsis (it, 0);
4209 else
4211 /* There are more overlay strings to process. If
4212 IT->current.overlay_string_index has advanced to a position
4213 where we must load IT->overlay_strings with more strings, do
4214 it. */
4215 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
4217 if (it->current.overlay_string_index && i == 0)
4218 load_overlay_strings (it, 0);
4220 /* Initialize IT to deliver display elements from the overlay
4221 string. */
4222 it->string = it->overlay_strings[i];
4223 it->multibyte_p = STRING_MULTIBYTE (it->string);
4224 SET_TEXT_POS (it->current.string_pos, 0, 0);
4225 it->method = GET_FROM_STRING;
4226 it->stop_charpos = 0;
4229 CHECK_IT (it);
4233 /* Compare two overlay_entry structures E1 and E2. Used as a
4234 comparison function for qsort in load_overlay_strings. Overlay
4235 strings for the same position are sorted so that
4237 1. All after-strings come in front of before-strings, except
4238 when they come from the same overlay.
4240 2. Within after-strings, strings are sorted so that overlay strings
4241 from overlays with higher priorities come first.
4243 2. Within before-strings, strings are sorted so that overlay
4244 strings from overlays with higher priorities come last.
4246 Value is analogous to strcmp. */
4249 static int
4250 compare_overlay_entries (e1, e2)
4251 void *e1, *e2;
4253 struct overlay_entry *entry1 = (struct overlay_entry *) e1;
4254 struct overlay_entry *entry2 = (struct overlay_entry *) e2;
4255 int result;
4257 if (entry1->after_string_p != entry2->after_string_p)
4259 /* Let after-strings appear in front of before-strings if
4260 they come from different overlays. */
4261 if (EQ (entry1->overlay, entry2->overlay))
4262 result = entry1->after_string_p ? 1 : -1;
4263 else
4264 result = entry1->after_string_p ? -1 : 1;
4266 else if (entry1->after_string_p)
4267 /* After-strings sorted in order of decreasing priority. */
4268 result = entry2->priority - entry1->priority;
4269 else
4270 /* Before-strings sorted in order of increasing priority. */
4271 result = entry1->priority - entry2->priority;
4273 return result;
4277 /* Load the vector IT->overlay_strings with overlay strings from IT's
4278 current buffer position, or from CHARPOS if that is > 0. Set
4279 IT->n_overlays to the total number of overlay strings found.
4281 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
4282 a time. On entry into load_overlay_strings,
4283 IT->current.overlay_string_index gives the number of overlay
4284 strings that have already been loaded by previous calls to this
4285 function.
4287 IT->add_overlay_start contains an additional overlay start
4288 position to consider for taking overlay strings from, if non-zero.
4289 This position comes into play when the overlay has an `invisible'
4290 property, and both before and after-strings. When we've skipped to
4291 the end of the overlay, because of its `invisible' property, we
4292 nevertheless want its before-string to appear.
4293 IT->add_overlay_start will contain the overlay start position
4294 in this case.
4296 Overlay strings are sorted so that after-string strings come in
4297 front of before-string strings. Within before and after-strings,
4298 strings are sorted by overlay priority. See also function
4299 compare_overlay_entries. */
4301 static void
4302 load_overlay_strings (it, charpos)
4303 struct it *it;
4304 int charpos;
4306 extern Lisp_Object Qafter_string, Qbefore_string, Qwindow, Qpriority;
4307 Lisp_Object overlay, window, str, invisible;
4308 struct Lisp_Overlay *ov;
4309 int start, end;
4310 int size = 20;
4311 int n = 0, i, j, invis_p;
4312 struct overlay_entry *entries
4313 = (struct overlay_entry *) alloca (size * sizeof *entries);
4315 if (charpos <= 0)
4316 charpos = IT_CHARPOS (*it);
4318 /* Append the overlay string STRING of overlay OVERLAY to vector
4319 `entries' which has size `size' and currently contains `n'
4320 elements. AFTER_P non-zero means STRING is an after-string of
4321 OVERLAY. */
4322 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
4323 do \
4325 Lisp_Object priority; \
4327 if (n == size) \
4329 int new_size = 2 * size; \
4330 struct overlay_entry *old = entries; \
4331 entries = \
4332 (struct overlay_entry *) alloca (new_size \
4333 * sizeof *entries); \
4334 bcopy (old, entries, size * sizeof *entries); \
4335 size = new_size; \
4338 entries[n].string = (STRING); \
4339 entries[n].overlay = (OVERLAY); \
4340 priority = Foverlay_get ((OVERLAY), Qpriority); \
4341 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
4342 entries[n].after_string_p = (AFTER_P); \
4343 ++n; \
4345 while (0)
4347 /* Process overlay before the overlay center. */
4348 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
4350 XSETMISC (overlay, ov);
4351 xassert (OVERLAYP (overlay));
4352 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4353 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4355 if (end < charpos)
4356 break;
4358 /* Skip this overlay if it doesn't start or end at IT's current
4359 position. */
4360 if (end != charpos && start != charpos)
4361 continue;
4363 /* Skip this overlay if it doesn't apply to IT->w. */
4364 window = Foverlay_get (overlay, Qwindow);
4365 if (WINDOWP (window) && XWINDOW (window) != it->w)
4366 continue;
4368 /* If the text ``under'' the overlay is invisible, both before-
4369 and after-strings from this overlay are visible; start and
4370 end position are indistinguishable. */
4371 invisible = Foverlay_get (overlay, Qinvisible);
4372 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4374 /* If overlay has a non-empty before-string, record it. */
4375 if ((start == charpos || (end == charpos && invis_p))
4376 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4377 && SCHARS (str))
4378 RECORD_OVERLAY_STRING (overlay, str, 0);
4380 /* If overlay has a non-empty after-string, record it. */
4381 if ((end == charpos || (start == charpos && invis_p))
4382 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4383 && SCHARS (str))
4384 RECORD_OVERLAY_STRING (overlay, str, 1);
4387 /* Process overlays after the overlay center. */
4388 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
4390 XSETMISC (overlay, ov);
4391 xassert (OVERLAYP (overlay));
4392 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4393 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4395 if (start > charpos)
4396 break;
4398 /* Skip this overlay if it doesn't start or end at IT's current
4399 position. */
4400 if (end != charpos && start != charpos)
4401 continue;
4403 /* Skip this overlay if it doesn't apply to IT->w. */
4404 window = Foverlay_get (overlay, Qwindow);
4405 if (WINDOWP (window) && XWINDOW (window) != it->w)
4406 continue;
4408 /* If the text ``under'' the overlay is invisible, it has a zero
4409 dimension, and both before- and after-strings apply. */
4410 invisible = Foverlay_get (overlay, Qinvisible);
4411 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4413 /* If overlay has a non-empty before-string, record it. */
4414 if ((start == charpos || (end == charpos && invis_p))
4415 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4416 && SCHARS (str))
4417 RECORD_OVERLAY_STRING (overlay, str, 0);
4419 /* If overlay has a non-empty after-string, record it. */
4420 if ((end == charpos || (start == charpos && invis_p))
4421 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4422 && SCHARS (str))
4423 RECORD_OVERLAY_STRING (overlay, str, 1);
4426 #undef RECORD_OVERLAY_STRING
4428 /* Sort entries. */
4429 if (n > 1)
4430 qsort (entries, n, sizeof *entries, compare_overlay_entries);
4432 /* Record the total number of strings to process. */
4433 it->n_overlay_strings = n;
4435 /* IT->current.overlay_string_index is the number of overlay strings
4436 that have already been consumed by IT. Copy some of the
4437 remaining overlay strings to IT->overlay_strings. */
4438 i = 0;
4439 j = it->current.overlay_string_index;
4440 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
4441 it->overlay_strings[i++] = entries[j++].string;
4443 CHECK_IT (it);
4447 /* Get the first chunk of overlay strings at IT's current buffer
4448 position, or at CHARPOS if that is > 0. Value is non-zero if at
4449 least one overlay string was found. */
4451 static int
4452 get_overlay_strings (it, charpos)
4453 struct it *it;
4454 int charpos;
4456 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
4457 process. This fills IT->overlay_strings with strings, and sets
4458 IT->n_overlay_strings to the total number of strings to process.
4459 IT->pos.overlay_string_index has to be set temporarily to zero
4460 because load_overlay_strings needs this; it must be set to -1
4461 when no overlay strings are found because a zero value would
4462 indicate a position in the first overlay string. */
4463 it->current.overlay_string_index = 0;
4464 load_overlay_strings (it, charpos);
4466 /* If we found overlay strings, set up IT to deliver display
4467 elements from the first one. Otherwise set up IT to deliver
4468 from current_buffer. */
4469 if (it->n_overlay_strings)
4471 /* Make sure we know settings in current_buffer, so that we can
4472 restore meaningful values when we're done with the overlay
4473 strings. */
4474 compute_stop_pos (it);
4475 xassert (it->face_id >= 0);
4477 /* Save IT's settings. They are restored after all overlay
4478 strings have been processed. */
4479 xassert (it->sp == 0);
4480 push_it (it);
4482 /* Set up IT to deliver display elements from the first overlay
4483 string. */
4484 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
4485 it->string = it->overlay_strings[0];
4486 it->stop_charpos = 0;
4487 xassert (STRINGP (it->string));
4488 it->end_charpos = SCHARS (it->string);
4489 it->multibyte_p = STRING_MULTIBYTE (it->string);
4490 it->method = GET_FROM_STRING;
4492 else
4494 it->string = Qnil;
4495 it->current.overlay_string_index = -1;
4496 it->method = GET_FROM_BUFFER;
4499 CHECK_IT (it);
4501 /* Value is non-zero if we found at least one overlay string. */
4502 return STRINGP (it->string);
4507 /***********************************************************************
4508 Saving and restoring state
4509 ***********************************************************************/
4511 /* Save current settings of IT on IT->stack. Called, for example,
4512 before setting up IT for an overlay string, to be able to restore
4513 IT's settings to what they were after the overlay string has been
4514 processed. */
4516 static void
4517 push_it (it)
4518 struct it *it;
4520 struct iterator_stack_entry *p;
4522 xassert (it->sp < 2);
4523 p = it->stack + it->sp;
4525 p->stop_charpos = it->stop_charpos;
4526 xassert (it->face_id >= 0);
4527 p->face_id = it->face_id;
4528 p->string = it->string;
4529 p->pos = it->current;
4530 p->end_charpos = it->end_charpos;
4531 p->string_nchars = it->string_nchars;
4532 p->area = it->area;
4533 p->multibyte_p = it->multibyte_p;
4534 p->slice = it->slice;
4535 p->space_width = it->space_width;
4536 p->font_height = it->font_height;
4537 p->voffset = it->voffset;
4538 p->string_from_display_prop_p = it->string_from_display_prop_p;
4539 p->display_ellipsis_p = 0;
4540 ++it->sp;
4544 /* Restore IT's settings from IT->stack. Called, for example, when no
4545 more overlay strings must be processed, and we return to delivering
4546 display elements from a buffer, or when the end of a string from a
4547 `display' property is reached and we return to delivering display
4548 elements from an overlay string, or from a buffer. */
4550 static void
4551 pop_it (it)
4552 struct it *it;
4554 struct iterator_stack_entry *p;
4556 xassert (it->sp > 0);
4557 --it->sp;
4558 p = it->stack + it->sp;
4559 it->stop_charpos = p->stop_charpos;
4560 it->face_id = p->face_id;
4561 it->string = p->string;
4562 it->current = p->pos;
4563 it->end_charpos = p->end_charpos;
4564 it->string_nchars = p->string_nchars;
4565 it->area = p->area;
4566 it->multibyte_p = p->multibyte_p;
4567 it->slice = p->slice;
4568 it->space_width = p->space_width;
4569 it->font_height = p->font_height;
4570 it->voffset = p->voffset;
4571 it->string_from_display_prop_p = p->string_from_display_prop_p;
4576 /***********************************************************************
4577 Moving over lines
4578 ***********************************************************************/
4580 /* Set IT's current position to the previous line start. */
4582 static void
4583 back_to_previous_line_start (it)
4584 struct it *it;
4586 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
4587 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
4591 /* Move IT to the next line start.
4593 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
4594 we skipped over part of the text (as opposed to moving the iterator
4595 continuously over the text). Otherwise, don't change the value
4596 of *SKIPPED_P.
4598 Newlines may come from buffer text, overlay strings, or strings
4599 displayed via the `display' property. That's the reason we can't
4600 simply use find_next_newline_no_quit.
4602 Note that this function may not skip over invisible text that is so
4603 because of text properties and immediately follows a newline. If
4604 it would, function reseat_at_next_visible_line_start, when called
4605 from set_iterator_to_next, would effectively make invisible
4606 characters following a newline part of the wrong glyph row, which
4607 leads to wrong cursor motion. */
4609 static int
4610 forward_to_next_line_start (it, skipped_p)
4611 struct it *it;
4612 int *skipped_p;
4614 int old_selective, newline_found_p, n;
4615 const int MAX_NEWLINE_DISTANCE = 500;
4617 /* If already on a newline, just consume it to avoid unintended
4618 skipping over invisible text below. */
4619 if (it->what == IT_CHARACTER
4620 && it->c == '\n'
4621 && CHARPOS (it->position) == IT_CHARPOS (*it))
4623 set_iterator_to_next (it, 0);
4624 it->c = 0;
4625 return 1;
4628 /* Don't handle selective display in the following. It's (a)
4629 unnecessary because it's done by the caller, and (b) leads to an
4630 infinite recursion because next_element_from_ellipsis indirectly
4631 calls this function. */
4632 old_selective = it->selective;
4633 it->selective = 0;
4635 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
4636 from buffer text. */
4637 for (n = newline_found_p = 0;
4638 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
4639 n += STRINGP (it->string) ? 0 : 1)
4641 if (!get_next_display_element (it))
4642 return 0;
4643 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
4644 set_iterator_to_next (it, 0);
4647 /* If we didn't find a newline near enough, see if we can use a
4648 short-cut. */
4649 if (!newline_found_p)
4651 int start = IT_CHARPOS (*it);
4652 int limit = find_next_newline_no_quit (start, 1);
4653 Lisp_Object pos;
4655 xassert (!STRINGP (it->string));
4657 /* If there isn't any `display' property in sight, and no
4658 overlays, we can just use the position of the newline in
4659 buffer text. */
4660 if (it->stop_charpos >= limit
4661 || ((pos = Fnext_single_property_change (make_number (start),
4662 Qdisplay,
4663 Qnil, make_number (limit)),
4664 NILP (pos))
4665 && next_overlay_change (start) == ZV))
4667 IT_CHARPOS (*it) = limit;
4668 IT_BYTEPOS (*it) = CHAR_TO_BYTE (limit);
4669 *skipped_p = newline_found_p = 1;
4671 else
4673 while (get_next_display_element (it)
4674 && !newline_found_p)
4676 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
4677 set_iterator_to_next (it, 0);
4682 it->selective = old_selective;
4683 return newline_found_p;
4687 /* Set IT's current position to the previous visible line start. Skip
4688 invisible text that is so either due to text properties or due to
4689 selective display. Caution: this does not change IT->current_x and
4690 IT->hpos. */
4692 static void
4693 back_to_previous_visible_line_start (it)
4694 struct it *it;
4696 while (IT_CHARPOS (*it) > BEGV)
4698 back_to_previous_line_start (it);
4699 if (IT_CHARPOS (*it) <= BEGV)
4700 break;
4702 /* If selective > 0, then lines indented more than that values
4703 are invisible. */
4704 if (it->selective > 0
4705 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
4706 (double) it->selective)) /* iftc */
4707 continue;
4709 /* Check the newline before point for invisibility. */
4711 Lisp_Object prop;
4712 prop = Fget_char_property (make_number (IT_CHARPOS (*it) - 1),
4713 Qinvisible, it->window);
4714 if (TEXT_PROP_MEANS_INVISIBLE (prop))
4715 continue;
4718 /* If newline has a display property that replaces the newline with something
4719 else (image or text), find start of overlay or interval and continue search
4720 from that point. */
4721 if (IT_CHARPOS (*it) > BEGV)
4723 struct it it2 = *it;
4724 int pos;
4725 int beg, end;
4726 Lisp_Object val, overlay;
4728 pos = --IT_CHARPOS (it2);
4729 --IT_BYTEPOS (it2);
4730 it2.sp = 0;
4731 if (handle_display_prop (&it2) == HANDLED_RETURN
4732 && !NILP (val = get_char_property_and_overlay
4733 (make_number (pos), Qdisplay, Qnil, &overlay))
4734 && (OVERLAYP (overlay)
4735 ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
4736 : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
4738 if (beg < BEGV)
4739 beg = BEGV;
4740 IT_CHARPOS (*it) = beg;
4741 IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg);
4742 continue;
4746 break;
4749 xassert (IT_CHARPOS (*it) >= BEGV);
4750 xassert (IT_CHARPOS (*it) == BEGV
4751 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
4752 CHECK_IT (it);
4756 /* Reseat iterator IT at the previous visible line start. Skip
4757 invisible text that is so either due to text properties or due to
4758 selective display. At the end, update IT's overlay information,
4759 face information etc. */
4761 void
4762 reseat_at_previous_visible_line_start (it)
4763 struct it *it;
4765 back_to_previous_visible_line_start (it);
4766 reseat (it, it->current.pos, 1);
4767 CHECK_IT (it);
4771 /* Reseat iterator IT on the next visible line start in the current
4772 buffer. ON_NEWLINE_P non-zero means position IT on the newline
4773 preceding the line start. Skip over invisible text that is so
4774 because of selective display. Compute faces, overlays etc at the
4775 new position. Note that this function does not skip over text that
4776 is invisible because of text properties. */
4778 static void
4779 reseat_at_next_visible_line_start (it, on_newline_p)
4780 struct it *it;
4781 int on_newline_p;
4783 int newline_found_p, skipped_p = 0;
4785 newline_found_p = forward_to_next_line_start (it, &skipped_p);
4787 /* Skip over lines that are invisible because they are indented
4788 more than the value of IT->selective. */
4789 if (it->selective > 0)
4790 while (IT_CHARPOS (*it) < ZV
4791 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
4792 (double) it->selective)) /* iftc */
4794 xassert (FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
4795 newline_found_p = forward_to_next_line_start (it, &skipped_p);
4798 /* Position on the newline if that's what's requested. */
4799 if (on_newline_p && newline_found_p)
4801 if (STRINGP (it->string))
4803 if (IT_STRING_CHARPOS (*it) > 0)
4805 --IT_STRING_CHARPOS (*it);
4806 --IT_STRING_BYTEPOS (*it);
4809 else if (IT_CHARPOS (*it) > BEGV)
4811 --IT_CHARPOS (*it);
4812 --IT_BYTEPOS (*it);
4813 reseat (it, it->current.pos, 0);
4816 else if (skipped_p)
4817 reseat (it, it->current.pos, 0);
4819 CHECK_IT (it);
4824 /***********************************************************************
4825 Changing an iterator's position
4826 ***********************************************************************/
4828 /* Change IT's current position to POS in current_buffer. If FORCE_P
4829 is non-zero, always check for text properties at the new position.
4830 Otherwise, text properties are only looked up if POS >=
4831 IT->check_charpos of a property. */
4833 static void
4834 reseat (it, pos, force_p)
4835 struct it *it;
4836 struct text_pos pos;
4837 int force_p;
4839 int original_pos = IT_CHARPOS (*it);
4841 reseat_1 (it, pos, 0);
4843 /* Determine where to check text properties. Avoid doing it
4844 where possible because text property lookup is very expensive. */
4845 if (force_p
4846 || CHARPOS (pos) > it->stop_charpos
4847 || CHARPOS (pos) < original_pos)
4848 handle_stop (it);
4850 CHECK_IT (it);
4854 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
4855 IT->stop_pos to POS, also. */
4857 static void
4858 reseat_1 (it, pos, set_stop_p)
4859 struct it *it;
4860 struct text_pos pos;
4861 int set_stop_p;
4863 /* Don't call this function when scanning a C string. */
4864 xassert (it->s == NULL);
4866 /* POS must be a reasonable value. */
4867 xassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
4869 it->current.pos = it->position = pos;
4870 XSETBUFFER (it->object, current_buffer);
4871 it->end_charpos = ZV;
4872 it->dpvec = NULL;
4873 it->current.dpvec_index = -1;
4874 it->current.overlay_string_index = -1;
4875 IT_STRING_CHARPOS (*it) = -1;
4876 IT_STRING_BYTEPOS (*it) = -1;
4877 it->string = Qnil;
4878 it->method = GET_FROM_BUFFER;
4879 /* RMS: I added this to fix a bug in move_it_vertically_backward
4880 where it->area continued to relate to the starting point
4881 for the backward motion. Bug report from
4882 Nick Roberts <nick@nick.uklinux.net> on 19 May 2003.
4883 However, I am not sure whether reseat still does the right thing
4884 in general after this change. */
4885 it->area = TEXT_AREA;
4886 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
4887 it->sp = 0;
4888 it->face_before_selective_p = 0;
4890 if (set_stop_p)
4891 it->stop_charpos = CHARPOS (pos);
4895 /* Set up IT for displaying a string, starting at CHARPOS in window W.
4896 If S is non-null, it is a C string to iterate over. Otherwise,
4897 STRING gives a Lisp string to iterate over.
4899 If PRECISION > 0, don't return more then PRECISION number of
4900 characters from the string.
4902 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
4903 characters have been returned. FIELD_WIDTH < 0 means an infinite
4904 field width.
4906 MULTIBYTE = 0 means disable processing of multibyte characters,
4907 MULTIBYTE > 0 means enable it,
4908 MULTIBYTE < 0 means use IT->multibyte_p.
4910 IT must be initialized via a prior call to init_iterator before
4911 calling this function. */
4913 static void
4914 reseat_to_string (it, s, string, charpos, precision, field_width, multibyte)
4915 struct it *it;
4916 unsigned char *s;
4917 Lisp_Object string;
4918 int charpos;
4919 int precision, field_width, multibyte;
4921 /* No region in strings. */
4922 it->region_beg_charpos = it->region_end_charpos = -1;
4924 /* No text property checks performed by default, but see below. */
4925 it->stop_charpos = -1;
4927 /* Set iterator position and end position. */
4928 bzero (&it->current, sizeof it->current);
4929 it->current.overlay_string_index = -1;
4930 it->current.dpvec_index = -1;
4931 xassert (charpos >= 0);
4933 /* If STRING is specified, use its multibyteness, otherwise use the
4934 setting of MULTIBYTE, if specified. */
4935 if (multibyte >= 0)
4936 it->multibyte_p = multibyte > 0;
4938 if (s == NULL)
4940 xassert (STRINGP (string));
4941 it->string = string;
4942 it->s = NULL;
4943 it->end_charpos = it->string_nchars = SCHARS (string);
4944 it->method = GET_FROM_STRING;
4945 it->current.string_pos = string_pos (charpos, string);
4947 else
4949 it->s = s;
4950 it->string = Qnil;
4952 /* Note that we use IT->current.pos, not it->current.string_pos,
4953 for displaying C strings. */
4954 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
4955 if (it->multibyte_p)
4957 it->current.pos = c_string_pos (charpos, s, 1);
4958 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
4960 else
4962 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
4963 it->end_charpos = it->string_nchars = strlen (s);
4966 it->method = GET_FROM_C_STRING;
4969 /* PRECISION > 0 means don't return more than PRECISION characters
4970 from the string. */
4971 if (precision > 0 && it->end_charpos - charpos > precision)
4972 it->end_charpos = it->string_nchars = charpos + precision;
4974 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
4975 characters have been returned. FIELD_WIDTH == 0 means don't pad,
4976 FIELD_WIDTH < 0 means infinite field width. This is useful for
4977 padding with `-' at the end of a mode line. */
4978 if (field_width < 0)
4979 field_width = INFINITY;
4980 if (field_width > it->end_charpos - charpos)
4981 it->end_charpos = charpos + field_width;
4983 /* Use the standard display table for displaying strings. */
4984 if (DISP_TABLE_P (Vstandard_display_table))
4985 it->dp = XCHAR_TABLE (Vstandard_display_table);
4987 it->stop_charpos = charpos;
4988 CHECK_IT (it);
4993 /***********************************************************************
4994 Iteration
4995 ***********************************************************************/
4997 /* Map enum it_method value to corresponding next_element_from_* function. */
4999 static int (* get_next_element[NUM_IT_METHODS]) P_ ((struct it *it)) =
5001 next_element_from_buffer,
5002 next_element_from_display_vector,
5003 next_element_from_composition,
5004 next_element_from_string,
5005 next_element_from_c_string,
5006 next_element_from_image,
5007 next_element_from_stretch
5011 /* Load IT's display element fields with information about the next
5012 display element from the current position of IT. Value is zero if
5013 end of buffer (or C string) is reached. */
5016 get_next_display_element (it)
5017 struct it *it;
5019 /* Non-zero means that we found a display element. Zero means that
5020 we hit the end of what we iterate over. Performance note: the
5021 function pointer `method' used here turns out to be faster than
5022 using a sequence of if-statements. */
5023 int success_p;
5025 get_next:
5026 success_p = (*get_next_element[it->method]) (it);
5028 if (it->what == IT_CHARACTER)
5030 /* Map via display table or translate control characters.
5031 IT->c, IT->len etc. have been set to the next character by
5032 the function call above. If we have a display table, and it
5033 contains an entry for IT->c, translate it. Don't do this if
5034 IT->c itself comes from a display table, otherwise we could
5035 end up in an infinite recursion. (An alternative could be to
5036 count the recursion depth of this function and signal an
5037 error when a certain maximum depth is reached.) Is it worth
5038 it? */
5039 if (success_p && it->dpvec == NULL)
5041 Lisp_Object dv;
5043 if (it->dp
5044 && (dv = DISP_CHAR_VECTOR (it->dp, it->c),
5045 VECTORP (dv)))
5047 struct Lisp_Vector *v = XVECTOR (dv);
5049 /* Return the first character from the display table
5050 entry, if not empty. If empty, don't display the
5051 current character. */
5052 if (v->size)
5054 it->dpvec_char_len = it->len;
5055 it->dpvec = v->contents;
5056 it->dpend = v->contents + v->size;
5057 it->current.dpvec_index = 0;
5058 it->dpvec_face_id = -1;
5059 it->saved_face_id = it->face_id;
5060 it->method = GET_FROM_DISPLAY_VECTOR;
5061 it->ellipsis_p = 0;
5063 else
5065 set_iterator_to_next (it, 0);
5067 goto get_next;
5070 /* Translate control characters into `\003' or `^C' form.
5071 Control characters coming from a display table entry are
5072 currently not translated because we use IT->dpvec to hold
5073 the translation. This could easily be changed but I
5074 don't believe that it is worth doing.
5076 If it->multibyte_p is nonzero, eight-bit characters and
5077 non-printable multibyte characters are also translated to
5078 octal form.
5080 If it->multibyte_p is zero, eight-bit characters that
5081 don't have corresponding multibyte char code are also
5082 translated to octal form. */
5083 else if ((it->c < ' '
5084 && (it->area != TEXT_AREA
5085 /* In mode line, treat \n like other crl chars. */
5086 || (it->c != '\t'
5087 && it->glyph_row && it->glyph_row->mode_line_p)
5088 || (it->c != '\n' && it->c != '\t')))
5089 || (it->multibyte_p
5090 ? ((it->c >= 127
5091 && it->len == 1)
5092 || !CHAR_PRINTABLE_P (it->c)
5093 || (!NILP (Vshow_nonbreak_escape)
5094 && (it->c == 0x8ad || it->c == 0x8a0
5095 || it->c == 0xf2d || it->c == 0xf20)))
5096 : (it->c >= 127
5097 && (!unibyte_display_via_language_environment
5098 || it->c == unibyte_char_to_multibyte (it->c)))))
5100 /* IT->c is a control character which must be displayed
5101 either as '\003' or as `^C' where the '\\' and '^'
5102 can be defined in the display table. Fill
5103 IT->ctl_chars with glyphs for what we have to
5104 display. Then, set IT->dpvec to these glyphs. */
5105 GLYPH g;
5106 int ctl_len;
5107 int face_id, lface_id = 0 ;
5108 GLYPH escape_glyph;
5110 if (it->c < 128 && it->ctl_arrow_p)
5112 g = '^'; /* default glyph for Control */
5113 /* Set IT->ctl_chars[0] to the glyph for `^'. */
5114 if (it->dp
5115 && INTEGERP (DISP_CTRL_GLYPH (it->dp))
5116 && GLYPH_CHAR_VALID_P (XINT (DISP_CTRL_GLYPH (it->dp))))
5118 g = XINT (DISP_CTRL_GLYPH (it->dp));
5119 lface_id = FAST_GLYPH_FACE (g);
5121 if (lface_id)
5123 g = FAST_GLYPH_CHAR (g);
5124 face_id = merge_faces (it->f, Qt, lface_id,
5125 it->face_id);
5127 else
5129 /* Merge the escape-glyph face into the current face. */
5130 face_id = merge_faces (it->f, Qescape_glyph, 0,
5131 it->face_id);
5134 XSETINT (it->ctl_chars[0], g);
5135 g = it->c ^ 0100;
5136 XSETINT (it->ctl_chars[1], g);
5137 ctl_len = 2;
5138 goto display_control;
5141 escape_glyph = '\\'; /* default for Octal display */
5142 if (it->dp
5143 && INTEGERP (DISP_ESCAPE_GLYPH (it->dp))
5144 && GLYPH_CHAR_VALID_P (XFASTINT (DISP_ESCAPE_GLYPH (it->dp))))
5146 escape_glyph = XFASTINT (DISP_ESCAPE_GLYPH (it->dp));
5147 lface_id = FAST_GLYPH_FACE (escape_glyph);
5149 if (lface_id)
5151 escape_glyph = FAST_GLYPH_CHAR (escape_glyph);
5152 face_id = merge_faces (it->f, Qt, lface_id,
5153 it->face_id);
5155 else
5157 /* Merge the escape-glyph face into the current face. */
5158 face_id = merge_faces (it->f, Qescape_glyph, 0,
5159 it->face_id);
5162 if (it->c == 0x8a0 || it->c == 0x8ad
5163 || it->c == 0xf20 || it->c == 0xf2d)
5165 XSETINT (it->ctl_chars[0], escape_glyph);
5166 g = it->c;
5167 XSETINT (it->ctl_chars[1], g);
5168 ctl_len = 2;
5169 goto display_control;
5173 unsigned char str[MAX_MULTIBYTE_LENGTH];
5174 int len;
5175 int i;
5177 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
5178 if (SINGLE_BYTE_CHAR_P (it->c))
5179 str[0] = it->c, len = 1;
5180 else
5182 len = CHAR_STRING_NO_SIGNAL (it->c, str);
5183 if (len < 0)
5185 /* It's an invalid character, which shouldn't
5186 happen actually, but due to bugs it may
5187 happen. Let's print the char as is, there's
5188 not much meaningful we can do with it. */
5189 str[0] = it->c;
5190 str[1] = it->c >> 8;
5191 str[2] = it->c >> 16;
5192 str[3] = it->c >> 24;
5193 len = 4;
5197 for (i = 0; i < len; i++)
5199 XSETINT (it->ctl_chars[i * 4], escape_glyph);
5200 /* Insert three more glyphs into IT->ctl_chars for
5201 the octal display of the character. */
5202 g = ((str[i] >> 6) & 7) + '0';
5203 XSETINT (it->ctl_chars[i * 4 + 1], g);
5204 g = ((str[i] >> 3) & 7) + '0';
5205 XSETINT (it->ctl_chars[i * 4 + 2], g);
5206 g = (str[i] & 7) + '0';
5207 XSETINT (it->ctl_chars[i * 4 + 3], g);
5209 ctl_len = len * 4;
5212 display_control:
5213 /* Set up IT->dpvec and return first character from it. */
5214 it->dpvec_char_len = it->len;
5215 it->dpvec = it->ctl_chars;
5216 it->dpend = it->dpvec + ctl_len;
5217 it->current.dpvec_index = 0;
5218 it->dpvec_face_id = face_id;
5219 it->saved_face_id = it->face_id;
5220 it->method = GET_FROM_DISPLAY_VECTOR;
5221 it->ellipsis_p = 0;
5222 goto get_next;
5226 /* Adjust face id for a multibyte character. There are no
5227 multibyte character in unibyte text. */
5228 if (it->multibyte_p
5229 && success_p
5230 && FRAME_WINDOW_P (it->f))
5232 struct face *face = FACE_FROM_ID (it->f, it->face_id);
5233 it->face_id = FACE_FOR_CHAR (it->f, face, it->c);
5237 /* Is this character the last one of a run of characters with
5238 box? If yes, set IT->end_of_box_run_p to 1. */
5239 if (it->face_box_p
5240 && it->s == NULL)
5242 int face_id;
5243 struct face *face;
5245 it->end_of_box_run_p
5246 = ((face_id = face_after_it_pos (it),
5247 face_id != it->face_id)
5248 && (face = FACE_FROM_ID (it->f, face_id),
5249 face->box == FACE_NO_BOX));
5252 /* Value is 0 if end of buffer or string reached. */
5253 return success_p;
5257 /* Move IT to the next display element.
5259 RESEAT_P non-zero means if called on a newline in buffer text,
5260 skip to the next visible line start.
5262 Functions get_next_display_element and set_iterator_to_next are
5263 separate because I find this arrangement easier to handle than a
5264 get_next_display_element function that also increments IT's
5265 position. The way it is we can first look at an iterator's current
5266 display element, decide whether it fits on a line, and if it does,
5267 increment the iterator position. The other way around we probably
5268 would either need a flag indicating whether the iterator has to be
5269 incremented the next time, or we would have to implement a
5270 decrement position function which would not be easy to write. */
5272 void
5273 set_iterator_to_next (it, reseat_p)
5274 struct it *it;
5275 int reseat_p;
5277 /* Reset flags indicating start and end of a sequence of characters
5278 with box. Reset them at the start of this function because
5279 moving the iterator to a new position might set them. */
5280 it->start_of_box_run_p = it->end_of_box_run_p = 0;
5282 switch (it->method)
5284 case GET_FROM_BUFFER:
5285 /* The current display element of IT is a character from
5286 current_buffer. Advance in the buffer, and maybe skip over
5287 invisible lines that are so because of selective display. */
5288 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
5289 reseat_at_next_visible_line_start (it, 0);
5290 else
5292 xassert (it->len != 0);
5293 IT_BYTEPOS (*it) += it->len;
5294 IT_CHARPOS (*it) += 1;
5295 xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
5297 break;
5299 case GET_FROM_COMPOSITION:
5300 xassert (it->cmp_id >= 0 && it->cmp_id < n_compositions);
5301 if (STRINGP (it->string))
5303 IT_STRING_BYTEPOS (*it) += it->len;
5304 IT_STRING_CHARPOS (*it) += it->cmp_len;
5305 it->method = GET_FROM_STRING;
5306 goto consider_string_end;
5308 else
5310 IT_BYTEPOS (*it) += it->len;
5311 IT_CHARPOS (*it) += it->cmp_len;
5312 it->method = GET_FROM_BUFFER;
5314 break;
5316 case GET_FROM_C_STRING:
5317 /* Current display element of IT is from a C string. */
5318 IT_BYTEPOS (*it) += it->len;
5319 IT_CHARPOS (*it) += 1;
5320 break;
5322 case GET_FROM_DISPLAY_VECTOR:
5323 /* Current display element of IT is from a display table entry.
5324 Advance in the display table definition. Reset it to null if
5325 end reached, and continue with characters from buffers/
5326 strings. */
5327 ++it->current.dpvec_index;
5329 /* Restore face of the iterator to what they were before the
5330 display vector entry (these entries may contain faces). */
5331 it->face_id = it->saved_face_id;
5333 if (it->dpvec + it->current.dpvec_index == it->dpend)
5335 if (it->s)
5336 it->method = GET_FROM_C_STRING;
5337 else if (STRINGP (it->string))
5338 it->method = GET_FROM_STRING;
5339 else
5340 it->method = GET_FROM_BUFFER;
5342 it->dpvec = NULL;
5343 it->current.dpvec_index = -1;
5345 /* Skip over characters which were displayed via IT->dpvec. */
5346 if (it->dpvec_char_len < 0)
5347 reseat_at_next_visible_line_start (it, 1);
5348 else if (it->dpvec_char_len > 0)
5350 it->len = it->dpvec_char_len;
5351 set_iterator_to_next (it, reseat_p);
5354 /* Recheck faces after display vector */
5355 it->stop_charpos = IT_CHARPOS (*it);
5357 break;
5359 case GET_FROM_STRING:
5360 /* Current display element is a character from a Lisp string. */
5361 xassert (it->s == NULL && STRINGP (it->string));
5362 IT_STRING_BYTEPOS (*it) += it->len;
5363 IT_STRING_CHARPOS (*it) += 1;
5365 consider_string_end:
5367 if (it->current.overlay_string_index >= 0)
5369 /* IT->string is an overlay string. Advance to the
5370 next, if there is one. */
5371 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
5372 next_overlay_string (it);
5374 else
5376 /* IT->string is not an overlay string. If we reached
5377 its end, and there is something on IT->stack, proceed
5378 with what is on the stack. This can be either another
5379 string, this time an overlay string, or a buffer. */
5380 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
5381 && it->sp > 0)
5383 pop_it (it);
5384 if (STRINGP (it->string))
5385 goto consider_string_end;
5386 it->method = GET_FROM_BUFFER;
5389 break;
5391 case GET_FROM_IMAGE:
5392 case GET_FROM_STRETCH:
5393 /* The position etc with which we have to proceed are on
5394 the stack. The position may be at the end of a string,
5395 if the `display' property takes up the whole string. */
5396 xassert (it->sp > 0);
5397 pop_it (it);
5398 it->image_id = 0;
5399 if (STRINGP (it->string))
5401 it->method = GET_FROM_STRING;
5402 goto consider_string_end;
5404 it->method = GET_FROM_BUFFER;
5405 break;
5407 default:
5408 /* There are no other methods defined, so this should be a bug. */
5409 abort ();
5412 xassert (it->method != GET_FROM_STRING
5413 || (STRINGP (it->string)
5414 && IT_STRING_CHARPOS (*it) >= 0));
5417 /* Load IT's display element fields with information about the next
5418 display element which comes from a display table entry or from the
5419 result of translating a control character to one of the forms `^C'
5420 or `\003'.
5422 IT->dpvec holds the glyphs to return as characters.
5423 IT->saved_face_id holds the face id before the display vector--
5424 it is restored into IT->face_idin set_iterator_to_next. */
5426 static int
5427 next_element_from_display_vector (it)
5428 struct it *it;
5430 /* Precondition. */
5431 xassert (it->dpvec && it->current.dpvec_index >= 0);
5433 it->face_id = it->saved_face_id;
5435 if (INTEGERP (*it->dpvec)
5436 && GLYPH_CHAR_VALID_P (XFASTINT (*it->dpvec)))
5438 GLYPH g;
5440 g = XFASTINT (it->dpvec[it->current.dpvec_index]);
5441 it->c = FAST_GLYPH_CHAR (g);
5442 it->len = CHAR_BYTES (it->c);
5444 /* The entry may contain a face id to use. Such a face id is
5445 the id of a Lisp face, not a realized face. A face id of
5446 zero means no face is specified. */
5447 if (it->dpvec_face_id >= 0)
5448 it->face_id = it->dpvec_face_id;
5449 else
5451 int lface_id = FAST_GLYPH_FACE (g);
5452 if (lface_id > 0)
5453 it->face_id = merge_faces (it->f, Qt, lface_id,
5454 it->saved_face_id);
5457 else
5458 /* Display table entry is invalid. Return a space. */
5459 it->c = ' ', it->len = 1;
5461 /* Don't change position and object of the iterator here. They are
5462 still the values of the character that had this display table
5463 entry or was translated, and that's what we want. */
5464 it->what = IT_CHARACTER;
5465 return 1;
5469 /* Load IT with the next display element from Lisp string IT->string.
5470 IT->current.string_pos is the current position within the string.
5471 If IT->current.overlay_string_index >= 0, the Lisp string is an
5472 overlay string. */
5474 static int
5475 next_element_from_string (it)
5476 struct it *it;
5478 struct text_pos position;
5480 xassert (STRINGP (it->string));
5481 xassert (IT_STRING_CHARPOS (*it) >= 0);
5482 position = it->current.string_pos;
5484 /* Time to check for invisible text? */
5485 if (IT_STRING_CHARPOS (*it) < it->end_charpos
5486 && IT_STRING_CHARPOS (*it) == it->stop_charpos)
5488 handle_stop (it);
5490 /* Since a handler may have changed IT->method, we must
5491 recurse here. */
5492 return get_next_display_element (it);
5495 if (it->current.overlay_string_index >= 0)
5497 /* Get the next character from an overlay string. In overlay
5498 strings, There is no field width or padding with spaces to
5499 do. */
5500 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
5502 it->what = IT_EOB;
5503 return 0;
5505 else if (STRING_MULTIBYTE (it->string))
5507 int remaining = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
5508 const unsigned char *s = (SDATA (it->string)
5509 + IT_STRING_BYTEPOS (*it));
5510 it->c = string_char_and_length (s, remaining, &it->len);
5512 else
5514 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
5515 it->len = 1;
5518 else
5520 /* Get the next character from a Lisp string that is not an
5521 overlay string. Such strings come from the mode line, for
5522 example. We may have to pad with spaces, or truncate the
5523 string. See also next_element_from_c_string. */
5524 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
5526 it->what = IT_EOB;
5527 return 0;
5529 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
5531 /* Pad with spaces. */
5532 it->c = ' ', it->len = 1;
5533 CHARPOS (position) = BYTEPOS (position) = -1;
5535 else if (STRING_MULTIBYTE (it->string))
5537 int maxlen = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
5538 const unsigned char *s = (SDATA (it->string)
5539 + IT_STRING_BYTEPOS (*it));
5540 it->c = string_char_and_length (s, maxlen, &it->len);
5542 else
5544 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
5545 it->len = 1;
5549 /* Record what we have and where it came from. Note that we store a
5550 buffer position in IT->position although it could arguably be a
5551 string position. */
5552 it->what = IT_CHARACTER;
5553 it->object = it->string;
5554 it->position = position;
5555 return 1;
5559 /* Load IT with next display element from C string IT->s.
5560 IT->string_nchars is the maximum number of characters to return
5561 from the string. IT->end_charpos may be greater than
5562 IT->string_nchars when this function is called, in which case we
5563 may have to return padding spaces. Value is zero if end of string
5564 reached, including padding spaces. */
5566 static int
5567 next_element_from_c_string (it)
5568 struct it *it;
5570 int success_p = 1;
5572 xassert (it->s);
5573 it->what = IT_CHARACTER;
5574 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
5575 it->object = Qnil;
5577 /* IT's position can be greater IT->string_nchars in case a field
5578 width or precision has been specified when the iterator was
5579 initialized. */
5580 if (IT_CHARPOS (*it) >= it->end_charpos)
5582 /* End of the game. */
5583 it->what = IT_EOB;
5584 success_p = 0;
5586 else if (IT_CHARPOS (*it) >= it->string_nchars)
5588 /* Pad with spaces. */
5589 it->c = ' ', it->len = 1;
5590 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
5592 else if (it->multibyte_p)
5594 /* Implementation note: The calls to strlen apparently aren't a
5595 performance problem because there is no noticeable performance
5596 difference between Emacs running in unibyte or multibyte mode. */
5597 int maxlen = strlen (it->s) - IT_BYTEPOS (*it);
5598 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it),
5599 maxlen, &it->len);
5601 else
5602 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
5604 return success_p;
5608 /* Set up IT to return characters from an ellipsis, if appropriate.
5609 The definition of the ellipsis glyphs may come from a display table
5610 entry. This function Fills IT with the first glyph from the
5611 ellipsis if an ellipsis is to be displayed. */
5613 static int
5614 next_element_from_ellipsis (it)
5615 struct it *it;
5617 if (it->selective_display_ellipsis_p)
5618 setup_for_ellipsis (it, it->len);
5619 else
5621 /* The face at the current position may be different from the
5622 face we find after the invisible text. Remember what it
5623 was in IT->saved_face_id, and signal that it's there by
5624 setting face_before_selective_p. */
5625 it->saved_face_id = it->face_id;
5626 it->method = GET_FROM_BUFFER;
5627 reseat_at_next_visible_line_start (it, 1);
5628 it->face_before_selective_p = 1;
5631 return get_next_display_element (it);
5635 /* Deliver an image display element. The iterator IT is already
5636 filled with image information (done in handle_display_prop). Value
5637 is always 1. */
5640 static int
5641 next_element_from_image (it)
5642 struct it *it;
5644 it->what = IT_IMAGE;
5645 return 1;
5649 /* Fill iterator IT with next display element from a stretch glyph
5650 property. IT->object is the value of the text property. Value is
5651 always 1. */
5653 static int
5654 next_element_from_stretch (it)
5655 struct it *it;
5657 it->what = IT_STRETCH;
5658 return 1;
5662 /* Load IT with the next display element from current_buffer. Value
5663 is zero if end of buffer reached. IT->stop_charpos is the next
5664 position at which to stop and check for text properties or buffer
5665 end. */
5667 static int
5668 next_element_from_buffer (it)
5669 struct it *it;
5671 int success_p = 1;
5673 /* Check this assumption, otherwise, we would never enter the
5674 if-statement, below. */
5675 xassert (IT_CHARPOS (*it) >= BEGV
5676 && IT_CHARPOS (*it) <= it->stop_charpos);
5678 if (IT_CHARPOS (*it) >= it->stop_charpos)
5680 if (IT_CHARPOS (*it) >= it->end_charpos)
5682 int overlay_strings_follow_p;
5684 /* End of the game, except when overlay strings follow that
5685 haven't been returned yet. */
5686 if (it->overlay_strings_at_end_processed_p)
5687 overlay_strings_follow_p = 0;
5688 else
5690 it->overlay_strings_at_end_processed_p = 1;
5691 overlay_strings_follow_p = get_overlay_strings (it, 0);
5694 if (overlay_strings_follow_p)
5695 success_p = get_next_display_element (it);
5696 else
5698 it->what = IT_EOB;
5699 it->position = it->current.pos;
5700 success_p = 0;
5703 else
5705 handle_stop (it);
5706 return get_next_display_element (it);
5709 else
5711 /* No face changes, overlays etc. in sight, so just return a
5712 character from current_buffer. */
5713 unsigned char *p;
5715 /* Maybe run the redisplay end trigger hook. Performance note:
5716 This doesn't seem to cost measurable time. */
5717 if (it->redisplay_end_trigger_charpos
5718 && it->glyph_row
5719 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
5720 run_redisplay_end_trigger_hook (it);
5722 /* Get the next character, maybe multibyte. */
5723 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
5724 if (it->multibyte_p && !ASCII_BYTE_P (*p))
5726 int maxlen = ((IT_BYTEPOS (*it) >= GPT_BYTE ? ZV_BYTE : GPT_BYTE)
5727 - IT_BYTEPOS (*it));
5728 it->c = string_char_and_length (p, maxlen, &it->len);
5730 else
5731 it->c = *p, it->len = 1;
5733 /* Record what we have and where it came from. */
5734 it->what = IT_CHARACTER;;
5735 it->object = it->w->buffer;
5736 it->position = it->current.pos;
5738 /* Normally we return the character found above, except when we
5739 really want to return an ellipsis for selective display. */
5740 if (it->selective)
5742 if (it->c == '\n')
5744 /* A value of selective > 0 means hide lines indented more
5745 than that number of columns. */
5746 if (it->selective > 0
5747 && IT_CHARPOS (*it) + 1 < ZV
5748 && indented_beyond_p (IT_CHARPOS (*it) + 1,
5749 IT_BYTEPOS (*it) + 1,
5750 (double) it->selective)) /* iftc */
5752 success_p = next_element_from_ellipsis (it);
5753 it->dpvec_char_len = -1;
5756 else if (it->c == '\r' && it->selective == -1)
5758 /* A value of selective == -1 means that everything from the
5759 CR to the end of the line is invisible, with maybe an
5760 ellipsis displayed for it. */
5761 success_p = next_element_from_ellipsis (it);
5762 it->dpvec_char_len = -1;
5767 /* Value is zero if end of buffer reached. */
5768 xassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
5769 return success_p;
5773 /* Run the redisplay end trigger hook for IT. */
5775 static void
5776 run_redisplay_end_trigger_hook (it)
5777 struct it *it;
5779 Lisp_Object args[3];
5781 /* IT->glyph_row should be non-null, i.e. we should be actually
5782 displaying something, or otherwise we should not run the hook. */
5783 xassert (it->glyph_row);
5785 /* Set up hook arguments. */
5786 args[0] = Qredisplay_end_trigger_functions;
5787 args[1] = it->window;
5788 XSETINT (args[2], it->redisplay_end_trigger_charpos);
5789 it->redisplay_end_trigger_charpos = 0;
5791 /* Since we are *trying* to run these functions, don't try to run
5792 them again, even if they get an error. */
5793 it->w->redisplay_end_trigger = Qnil;
5794 Frun_hook_with_args (3, args);
5796 /* Notice if it changed the face of the character we are on. */
5797 handle_face_prop (it);
5801 /* Deliver a composition display element. The iterator IT is already
5802 filled with composition information (done in
5803 handle_composition_prop). Value is always 1. */
5805 static int
5806 next_element_from_composition (it)
5807 struct it *it;
5809 it->what = IT_COMPOSITION;
5810 it->position = (STRINGP (it->string)
5811 ? it->current.string_pos
5812 : it->current.pos);
5813 return 1;
5818 /***********************************************************************
5819 Moving an iterator without producing glyphs
5820 ***********************************************************************/
5822 /* Move iterator IT to a specified buffer or X position within one
5823 line on the display without producing glyphs.
5825 OP should be a bit mask including some or all of these bits:
5826 MOVE_TO_X: Stop on reaching x-position TO_X.
5827 MOVE_TO_POS: Stop on reaching buffer or string position TO_CHARPOS.
5828 Regardless of OP's value, stop in reaching the end of the display line.
5830 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
5831 This means, in particular, that TO_X includes window's horizontal
5832 scroll amount.
5834 The return value has several possible values that
5835 say what condition caused the scan to stop:
5837 MOVE_POS_MATCH_OR_ZV
5838 - when TO_POS or ZV was reached.
5840 MOVE_X_REACHED
5841 -when TO_X was reached before TO_POS or ZV were reached.
5843 MOVE_LINE_CONTINUED
5844 - when we reached the end of the display area and the line must
5845 be continued.
5847 MOVE_LINE_TRUNCATED
5848 - when we reached the end of the display area and the line is
5849 truncated.
5851 MOVE_NEWLINE_OR_CR
5852 - when we stopped at a line end, i.e. a newline or a CR and selective
5853 display is on. */
5855 static enum move_it_result
5856 move_it_in_display_line_to (it, to_charpos, to_x, op)
5857 struct it *it;
5858 int to_charpos, to_x, op;
5860 enum move_it_result result = MOVE_UNDEFINED;
5861 struct glyph_row *saved_glyph_row;
5863 /* Don't produce glyphs in produce_glyphs. */
5864 saved_glyph_row = it->glyph_row;
5865 it->glyph_row = NULL;
5867 #define BUFFER_POS_REACHED_P() \
5868 ((op & MOVE_TO_POS) != 0 \
5869 && BUFFERP (it->object) \
5870 && IT_CHARPOS (*it) >= to_charpos \
5871 && (it->method == GET_FROM_BUFFER \
5872 || (it->method == GET_FROM_DISPLAY_VECTOR \
5873 && it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
5876 while (1)
5878 int x, i, ascent = 0, descent = 0;
5880 /* Stop when ZV reached.
5881 We used to stop here when TO_CHARPOS reached as well, but that is
5882 too soon if this glyph does not fit on this line. So we handle it
5883 explicitly below. */
5884 if (!get_next_display_element (it)
5885 || (it->truncate_lines_p
5886 && BUFFER_POS_REACHED_P ()))
5888 result = MOVE_POS_MATCH_OR_ZV;
5889 break;
5892 /* The call to produce_glyphs will get the metrics of the
5893 display element IT is loaded with. We record in x the
5894 x-position before this display element in case it does not
5895 fit on the line. */
5896 x = it->current_x;
5898 /* Remember the line height so far in case the next element doesn't
5899 fit on the line. */
5900 if (!it->truncate_lines_p)
5902 ascent = it->max_ascent;
5903 descent = it->max_descent;
5906 PRODUCE_GLYPHS (it);
5908 if (it->area != TEXT_AREA)
5910 set_iterator_to_next (it, 1);
5911 continue;
5914 /* The number of glyphs we get back in IT->nglyphs will normally
5915 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
5916 character on a terminal frame, or (iii) a line end. For the
5917 second case, IT->nglyphs - 1 padding glyphs will be present
5918 (on X frames, there is only one glyph produced for a
5919 composite character.
5921 The behavior implemented below means, for continuation lines,
5922 that as many spaces of a TAB as fit on the current line are
5923 displayed there. For terminal frames, as many glyphs of a
5924 multi-glyph character are displayed in the current line, too.
5925 This is what the old redisplay code did, and we keep it that
5926 way. Under X, the whole shape of a complex character must
5927 fit on the line or it will be completely displayed in the
5928 next line.
5930 Note that both for tabs and padding glyphs, all glyphs have
5931 the same width. */
5932 if (it->nglyphs)
5934 /* More than one glyph or glyph doesn't fit on line. All
5935 glyphs have the same width. */
5936 int single_glyph_width = it->pixel_width / it->nglyphs;
5937 int new_x;
5939 for (i = 0; i < it->nglyphs; ++i, x = new_x)
5941 new_x = x + single_glyph_width;
5943 /* We want to leave anything reaching TO_X to the caller. */
5944 if ((op & MOVE_TO_X) && new_x > to_x)
5946 if (BUFFER_POS_REACHED_P ())
5947 goto buffer_pos_reached;
5948 it->current_x = x;
5949 result = MOVE_X_REACHED;
5950 break;
5952 else if (/* Lines are continued. */
5953 !it->truncate_lines_p
5954 && (/* And glyph doesn't fit on the line. */
5955 new_x > it->last_visible_x
5956 /* Or it fits exactly and we're on a window
5957 system frame. */
5958 || (new_x == it->last_visible_x
5959 && FRAME_WINDOW_P (it->f))))
5961 if (/* IT->hpos == 0 means the very first glyph
5962 doesn't fit on the line, e.g. a wide image. */
5963 it->hpos == 0
5964 || (new_x == it->last_visible_x
5965 && FRAME_WINDOW_P (it->f)))
5967 ++it->hpos;
5968 it->current_x = new_x;
5969 if (i == it->nglyphs - 1)
5971 set_iterator_to_next (it, 1);
5972 #ifdef HAVE_WINDOW_SYSTEM
5973 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
5975 if (!get_next_display_element (it))
5977 result = MOVE_POS_MATCH_OR_ZV;
5978 break;
5980 if (BUFFER_POS_REACHED_P ())
5982 if (ITERATOR_AT_END_OF_LINE_P (it))
5983 result = MOVE_POS_MATCH_OR_ZV;
5984 else
5985 result = MOVE_LINE_CONTINUED;
5986 break;
5988 if (ITERATOR_AT_END_OF_LINE_P (it))
5990 result = MOVE_NEWLINE_OR_CR;
5991 break;
5994 #endif /* HAVE_WINDOW_SYSTEM */
5997 else
5999 it->current_x = x;
6000 it->max_ascent = ascent;
6001 it->max_descent = descent;
6004 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
6005 IT_CHARPOS (*it)));
6006 result = MOVE_LINE_CONTINUED;
6007 break;
6009 else if (BUFFER_POS_REACHED_P ())
6010 goto buffer_pos_reached;
6011 else if (new_x > it->first_visible_x)
6013 /* Glyph is visible. Increment number of glyphs that
6014 would be displayed. */
6015 ++it->hpos;
6017 else
6019 /* Glyph is completely off the left margin of the display
6020 area. Nothing to do. */
6024 if (result != MOVE_UNDEFINED)
6025 break;
6027 else if (BUFFER_POS_REACHED_P ())
6029 buffer_pos_reached:
6030 it->current_x = x;
6031 it->max_ascent = ascent;
6032 it->max_descent = descent;
6033 result = MOVE_POS_MATCH_OR_ZV;
6034 break;
6036 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
6038 /* Stop when TO_X specified and reached. This check is
6039 necessary here because of lines consisting of a line end,
6040 only. The line end will not produce any glyphs and we
6041 would never get MOVE_X_REACHED. */
6042 xassert (it->nglyphs == 0);
6043 result = MOVE_X_REACHED;
6044 break;
6047 /* Is this a line end? If yes, we're done. */
6048 if (ITERATOR_AT_END_OF_LINE_P (it))
6050 result = MOVE_NEWLINE_OR_CR;
6051 break;
6054 /* The current display element has been consumed. Advance
6055 to the next. */
6056 set_iterator_to_next (it, 1);
6058 /* Stop if lines are truncated and IT's current x-position is
6059 past the right edge of the window now. */
6060 if (it->truncate_lines_p
6061 && it->current_x >= it->last_visible_x)
6063 #ifdef HAVE_WINDOW_SYSTEM
6064 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
6066 if (!get_next_display_element (it)
6067 || BUFFER_POS_REACHED_P ())
6069 result = MOVE_POS_MATCH_OR_ZV;
6070 break;
6072 if (ITERATOR_AT_END_OF_LINE_P (it))
6074 result = MOVE_NEWLINE_OR_CR;
6075 break;
6078 #endif /* HAVE_WINDOW_SYSTEM */
6079 result = MOVE_LINE_TRUNCATED;
6080 break;
6084 #undef BUFFER_POS_REACHED_P
6086 /* Restore the iterator settings altered at the beginning of this
6087 function. */
6088 it->glyph_row = saved_glyph_row;
6089 return result;
6093 /* Move IT forward until it satisfies one or more of the criteria in
6094 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
6096 OP is a bit-mask that specifies where to stop, and in particular,
6097 which of those four position arguments makes a difference. See the
6098 description of enum move_operation_enum.
6100 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
6101 screen line, this function will set IT to the next position >
6102 TO_CHARPOS. */
6104 void
6105 move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
6106 struct it *it;
6107 int to_charpos, to_x, to_y, to_vpos;
6108 int op;
6110 enum move_it_result skip, skip2 = MOVE_X_REACHED;
6111 int line_height;
6112 int reached = 0;
6114 for (;;)
6116 if (op & MOVE_TO_VPOS)
6118 /* If no TO_CHARPOS and no TO_X specified, stop at the
6119 start of the line TO_VPOS. */
6120 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
6122 if (it->vpos == to_vpos)
6124 reached = 1;
6125 break;
6127 else
6128 skip = move_it_in_display_line_to (it, -1, -1, 0);
6130 else
6132 /* TO_VPOS >= 0 means stop at TO_X in the line at
6133 TO_VPOS, or at TO_POS, whichever comes first. */
6134 if (it->vpos == to_vpos)
6136 reached = 2;
6137 break;
6140 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
6142 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
6144 reached = 3;
6145 break;
6147 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
6149 /* We have reached TO_X but not in the line we want. */
6150 skip = move_it_in_display_line_to (it, to_charpos,
6151 -1, MOVE_TO_POS);
6152 if (skip == MOVE_POS_MATCH_OR_ZV)
6154 reached = 4;
6155 break;
6160 else if (op & MOVE_TO_Y)
6162 struct it it_backup;
6164 /* TO_Y specified means stop at TO_X in the line containing
6165 TO_Y---or at TO_CHARPOS if this is reached first. The
6166 problem is that we can't really tell whether the line
6167 contains TO_Y before we have completely scanned it, and
6168 this may skip past TO_X. What we do is to first scan to
6169 TO_X.
6171 If TO_X is not specified, use a TO_X of zero. The reason
6172 is to make the outcome of this function more predictable.
6173 If we didn't use TO_X == 0, we would stop at the end of
6174 the line which is probably not what a caller would expect
6175 to happen. */
6176 skip = move_it_in_display_line_to (it, to_charpos,
6177 ((op & MOVE_TO_X)
6178 ? to_x : 0),
6179 (MOVE_TO_X
6180 | (op & MOVE_TO_POS)));
6182 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
6183 if (skip == MOVE_POS_MATCH_OR_ZV)
6185 reached = 5;
6186 break;
6189 /* If TO_X was reached, we would like to know whether TO_Y
6190 is in the line. This can only be said if we know the
6191 total line height which requires us to scan the rest of
6192 the line. */
6193 if (skip == MOVE_X_REACHED)
6195 it_backup = *it;
6196 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
6197 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
6198 op & MOVE_TO_POS);
6199 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
6202 /* Now, decide whether TO_Y is in this line. */
6203 line_height = it->max_ascent + it->max_descent;
6204 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
6206 if (to_y >= it->current_y
6207 && to_y < it->current_y + line_height)
6209 if (skip == MOVE_X_REACHED)
6210 /* If TO_Y is in this line and TO_X was reached above,
6211 we scanned too far. We have to restore IT's settings
6212 to the ones before skipping. */
6213 *it = it_backup;
6214 reached = 6;
6216 else if (skip == MOVE_X_REACHED)
6218 skip = skip2;
6219 if (skip == MOVE_POS_MATCH_OR_ZV)
6220 reached = 7;
6223 if (reached)
6224 break;
6226 else
6227 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
6229 switch (skip)
6231 case MOVE_POS_MATCH_OR_ZV:
6232 reached = 8;
6233 goto out;
6235 case MOVE_NEWLINE_OR_CR:
6236 set_iterator_to_next (it, 1);
6237 it->continuation_lines_width = 0;
6238 break;
6240 case MOVE_LINE_TRUNCATED:
6241 it->continuation_lines_width = 0;
6242 reseat_at_next_visible_line_start (it, 0);
6243 if ((op & MOVE_TO_POS) != 0
6244 && IT_CHARPOS (*it) > to_charpos)
6246 reached = 9;
6247 goto out;
6249 break;
6251 case MOVE_LINE_CONTINUED:
6252 it->continuation_lines_width += it->current_x;
6253 break;
6255 default:
6256 abort ();
6259 /* Reset/increment for the next run. */
6260 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
6261 it->current_x = it->hpos = 0;
6262 it->current_y += it->max_ascent + it->max_descent;
6263 ++it->vpos;
6264 last_height = it->max_ascent + it->max_descent;
6265 last_max_ascent = it->max_ascent;
6266 it->max_ascent = it->max_descent = 0;
6269 out:
6271 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
6275 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
6277 If DY > 0, move IT backward at least that many pixels. DY = 0
6278 means move IT backward to the preceding line start or BEGV. This
6279 function may move over more than DY pixels if IT->current_y - DY
6280 ends up in the middle of a line; in this case IT->current_y will be
6281 set to the top of the line moved to. */
6283 void
6284 move_it_vertically_backward (it, dy)
6285 struct it *it;
6286 int dy;
6288 int nlines, h;
6289 struct it it2, it3;
6290 int start_pos;
6292 move_further_back:
6293 xassert (dy >= 0);
6295 start_pos = IT_CHARPOS (*it);
6297 /* Estimate how many newlines we must move back. */
6298 nlines = max (1, dy / FRAME_LINE_HEIGHT (it->f));
6300 /* Set the iterator's position that many lines back. */
6301 while (nlines-- && IT_CHARPOS (*it) > BEGV)
6302 back_to_previous_visible_line_start (it);
6304 /* Reseat the iterator here. When moving backward, we don't want
6305 reseat to skip forward over invisible text, set up the iterator
6306 to deliver from overlay strings at the new position etc. So,
6307 use reseat_1 here. */
6308 reseat_1 (it, it->current.pos, 1);
6310 /* We are now surely at a line start. */
6311 it->current_x = it->hpos = 0;
6312 it->continuation_lines_width = 0;
6314 /* Move forward and see what y-distance we moved. First move to the
6315 start of the next line so that we get its height. We need this
6316 height to be able to tell whether we reached the specified
6317 y-distance. */
6318 it2 = *it;
6319 it2.max_ascent = it2.max_descent = 0;
6320 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
6321 MOVE_TO_POS | MOVE_TO_VPOS);
6322 xassert (IT_CHARPOS (*it) >= BEGV);
6323 it3 = it2;
6325 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
6326 xassert (IT_CHARPOS (*it) >= BEGV);
6327 /* H is the actual vertical distance from the position in *IT
6328 and the starting position. */
6329 h = it2.current_y - it->current_y;
6330 /* NLINES is the distance in number of lines. */
6331 nlines = it2.vpos - it->vpos;
6333 /* Correct IT's y and vpos position
6334 so that they are relative to the starting point. */
6335 it->vpos -= nlines;
6336 it->current_y -= h;
6338 if (dy == 0)
6340 /* DY == 0 means move to the start of the screen line. The
6341 value of nlines is > 0 if continuation lines were involved. */
6342 if (nlines > 0)
6343 move_it_by_lines (it, nlines, 1);
6344 #if 0
6345 /* I think this assert is bogus if buffer contains
6346 invisible text or images. KFS. */
6347 xassert (IT_CHARPOS (*it) <= start_pos);
6348 #endif
6350 else
6352 /* The y-position we try to reach, relative to *IT.
6353 Note that H has been subtracted in front of the if-statement. */
6354 int target_y = it->current_y + h - dy;
6355 int y0 = it3.current_y;
6356 int y1 = line_bottom_y (&it3);
6357 int line_height = y1 - y0;
6359 /* If we did not reach target_y, try to move further backward if
6360 we can. If we moved too far backward, try to move forward. */
6361 if (target_y < it->current_y
6362 /* This is heuristic. In a window that's 3 lines high, with
6363 a line height of 13 pixels each, recentering with point
6364 on the bottom line will try to move -39/2 = 19 pixels
6365 backward. Try to avoid moving into the first line. */
6366 && (it->current_y - target_y
6367 > min (window_box_height (it->w), line_height * 2 / 3))
6368 && IT_CHARPOS (*it) > BEGV)
6370 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
6371 target_y - it->current_y));
6372 dy = it->current_y - target_y;
6373 goto move_further_back;
6375 else if (target_y >= it->current_y + line_height
6376 && IT_CHARPOS (*it) < ZV)
6378 /* Should move forward by at least one line, maybe more.
6380 Note: Calling move_it_by_lines can be expensive on
6381 terminal frames, where compute_motion is used (via
6382 vmotion) to do the job, when there are very long lines
6383 and truncate-lines is nil. That's the reason for
6384 treating terminal frames specially here. */
6386 if (!FRAME_WINDOW_P (it->f))
6387 move_it_vertically (it, target_y - (it->current_y + line_height));
6388 else
6392 move_it_by_lines (it, 1, 1);
6394 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
6397 #if 0
6398 /* I think this assert is bogus if buffer contains
6399 invisible text or images. KFS. */
6400 xassert (IT_CHARPOS (*it) >= BEGV);
6401 #endif
6407 /* Move IT by a specified amount of pixel lines DY. DY negative means
6408 move backwards. DY = 0 means move to start of screen line. At the
6409 end, IT will be on the start of a screen line. */
6411 void
6412 move_it_vertically (it, dy)
6413 struct it *it;
6414 int dy;
6416 if (dy <= 0)
6417 move_it_vertically_backward (it, -dy);
6418 else
6420 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
6421 move_it_to (it, ZV, -1, it->current_y + dy, -1,
6422 MOVE_TO_POS | MOVE_TO_Y);
6423 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
6425 /* If buffer ends in ZV without a newline, move to the start of
6426 the line to satisfy the post-condition. */
6427 if (IT_CHARPOS (*it) == ZV
6428 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
6429 move_it_by_lines (it, 0, 0);
6434 /* Move iterator IT past the end of the text line it is in. */
6436 void
6437 move_it_past_eol (it)
6438 struct it *it;
6440 enum move_it_result rc;
6442 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
6443 if (rc == MOVE_NEWLINE_OR_CR)
6444 set_iterator_to_next (it, 0);
6448 #if 0 /* Currently not used. */
6450 /* Return non-zero if some text between buffer positions START_CHARPOS
6451 and END_CHARPOS is invisible. IT->window is the window for text
6452 property lookup. */
6454 static int
6455 invisible_text_between_p (it, start_charpos, end_charpos)
6456 struct it *it;
6457 int start_charpos, end_charpos;
6459 Lisp_Object prop, limit;
6460 int invisible_found_p;
6462 xassert (it != NULL && start_charpos <= end_charpos);
6464 /* Is text at START invisible? */
6465 prop = Fget_char_property (make_number (start_charpos), Qinvisible,
6466 it->window);
6467 if (TEXT_PROP_MEANS_INVISIBLE (prop))
6468 invisible_found_p = 1;
6469 else
6471 limit = Fnext_single_char_property_change (make_number (start_charpos),
6472 Qinvisible, Qnil,
6473 make_number (end_charpos));
6474 invisible_found_p = XFASTINT (limit) < end_charpos;
6477 return invisible_found_p;
6480 #endif /* 0 */
6483 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
6484 negative means move up. DVPOS == 0 means move to the start of the
6485 screen line. NEED_Y_P non-zero means calculate IT->current_y. If
6486 NEED_Y_P is zero, IT->current_y will be left unchanged.
6488 Further optimization ideas: If we would know that IT->f doesn't use
6489 a face with proportional font, we could be faster for
6490 truncate-lines nil. */
6492 void
6493 move_it_by_lines (it, dvpos, need_y_p)
6494 struct it *it;
6495 int dvpos, need_y_p;
6497 struct position pos;
6499 if (!FRAME_WINDOW_P (it->f))
6501 struct text_pos textpos;
6503 /* We can use vmotion on frames without proportional fonts. */
6504 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
6505 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
6506 reseat (it, textpos, 1);
6507 it->vpos += pos.vpos;
6508 it->current_y += pos.vpos;
6510 else if (dvpos == 0)
6512 /* DVPOS == 0 means move to the start of the screen line. */
6513 move_it_vertically_backward (it, 0);
6514 xassert (it->current_x == 0 && it->hpos == 0);
6515 /* Let next call to line_bottom_y calculate real line height */
6516 last_height = 0;
6518 else if (dvpos > 0)
6519 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
6520 else
6522 struct it it2;
6523 int start_charpos, i;
6525 /* Start at the beginning of the screen line containing IT's
6526 position. */
6527 move_it_vertically_backward (it, 0);
6529 /* Go back -DVPOS visible lines and reseat the iterator there. */
6530 start_charpos = IT_CHARPOS (*it);
6531 for (i = -dvpos; i && IT_CHARPOS (*it) > BEGV; --i)
6532 back_to_previous_visible_line_start (it);
6533 reseat (it, it->current.pos, 1);
6534 it->current_x = it->hpos = 0;
6536 /* Above call may have moved too far if continuation lines
6537 are involved. Scan forward and see if it did. */
6538 it2 = *it;
6539 it2.vpos = it2.current_y = 0;
6540 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
6541 it->vpos -= it2.vpos;
6542 it->current_y -= it2.current_y;
6543 it->current_x = it->hpos = 0;
6545 /* If we moved too far back, move IT some lines forward. */
6546 if (it2.vpos > -dvpos)
6548 int delta = it2.vpos + dvpos;
6549 it2 = *it;
6550 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
6551 /* Move back again if we got too far ahead. */
6552 if (IT_CHARPOS (*it) >= start_charpos)
6553 *it = it2;
6558 /* Return 1 if IT points into the middle of a display vector. */
6561 in_display_vector_p (it)
6562 struct it *it;
6564 return (it->method == GET_FROM_DISPLAY_VECTOR
6565 && it->current.dpvec_index > 0
6566 && it->dpvec + it->current.dpvec_index != it->dpend);
6570 /***********************************************************************
6571 Messages
6572 ***********************************************************************/
6575 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
6576 to *Messages*. */
6578 void
6579 add_to_log (format, arg1, arg2)
6580 char *format;
6581 Lisp_Object arg1, arg2;
6583 Lisp_Object args[3];
6584 Lisp_Object msg, fmt;
6585 char *buffer;
6586 int len;
6587 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
6588 USE_SAFE_ALLOCA;
6590 /* Do nothing if called asynchronously. Inserting text into
6591 a buffer may call after-change-functions and alike and
6592 that would means running Lisp asynchronously. */
6593 if (handling_signal)
6594 return;
6596 fmt = msg = Qnil;
6597 GCPRO4 (fmt, msg, arg1, arg2);
6599 args[0] = fmt = build_string (format);
6600 args[1] = arg1;
6601 args[2] = arg2;
6602 msg = Fformat (3, args);
6604 len = SBYTES (msg) + 1;
6605 SAFE_ALLOCA (buffer, char *, len);
6606 bcopy (SDATA (msg), buffer, len);
6608 message_dolog (buffer, len - 1, 1, 0);
6609 SAFE_FREE ();
6611 UNGCPRO;
6615 /* Output a newline in the *Messages* buffer if "needs" one. */
6617 void
6618 message_log_maybe_newline ()
6620 if (message_log_need_newline)
6621 message_dolog ("", 0, 1, 0);
6625 /* Add a string M of length NBYTES to the message log, optionally
6626 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
6627 nonzero, means interpret the contents of M as multibyte. This
6628 function calls low-level routines in order to bypass text property
6629 hooks, etc. which might not be safe to run. */
6631 void
6632 message_dolog (m, nbytes, nlflag, multibyte)
6633 const char *m;
6634 int nbytes, nlflag, multibyte;
6636 if (!NILP (Vmemory_full))
6637 return;
6639 if (!NILP (Vmessage_log_max))
6641 struct buffer *oldbuf;
6642 Lisp_Object oldpoint, oldbegv, oldzv;
6643 int old_windows_or_buffers_changed = windows_or_buffers_changed;
6644 int point_at_end = 0;
6645 int zv_at_end = 0;
6646 Lisp_Object old_deactivate_mark, tem;
6647 struct gcpro gcpro1;
6649 old_deactivate_mark = Vdeactivate_mark;
6650 oldbuf = current_buffer;
6651 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
6652 current_buffer->undo_list = Qt;
6654 oldpoint = message_dolog_marker1;
6655 set_marker_restricted (oldpoint, make_number (PT), Qnil);
6656 oldbegv = message_dolog_marker2;
6657 set_marker_restricted (oldbegv, make_number (BEGV), Qnil);
6658 oldzv = message_dolog_marker3;
6659 set_marker_restricted (oldzv, make_number (ZV), Qnil);
6660 GCPRO1 (old_deactivate_mark);
6662 if (PT == Z)
6663 point_at_end = 1;
6664 if (ZV == Z)
6665 zv_at_end = 1;
6667 BEGV = BEG;
6668 BEGV_BYTE = BEG_BYTE;
6669 ZV = Z;
6670 ZV_BYTE = Z_BYTE;
6671 TEMP_SET_PT_BOTH (Z, Z_BYTE);
6673 /* Insert the string--maybe converting multibyte to single byte
6674 or vice versa, so that all the text fits the buffer. */
6675 if (multibyte
6676 && NILP (current_buffer->enable_multibyte_characters))
6678 int i, c, char_bytes;
6679 unsigned char work[1];
6681 /* Convert a multibyte string to single-byte
6682 for the *Message* buffer. */
6683 for (i = 0; i < nbytes; i += char_bytes)
6685 c = string_char_and_length (m + i, nbytes - i, &char_bytes);
6686 work[0] = (SINGLE_BYTE_CHAR_P (c)
6688 : multibyte_char_to_unibyte (c, Qnil));
6689 insert_1_both (work, 1, 1, 1, 0, 0);
6692 else if (! multibyte
6693 && ! NILP (current_buffer->enable_multibyte_characters))
6695 int i, c, char_bytes;
6696 unsigned char *msg = (unsigned char *) m;
6697 unsigned char str[MAX_MULTIBYTE_LENGTH];
6698 /* Convert a single-byte string to multibyte
6699 for the *Message* buffer. */
6700 for (i = 0; i < nbytes; i++)
6702 c = unibyte_char_to_multibyte (msg[i]);
6703 char_bytes = CHAR_STRING (c, str);
6704 insert_1_both (str, 1, char_bytes, 1, 0, 0);
6707 else if (nbytes)
6708 insert_1 (m, nbytes, 1, 0, 0);
6710 if (nlflag)
6712 int this_bol, this_bol_byte, prev_bol, prev_bol_byte, dup;
6713 insert_1 ("\n", 1, 1, 0, 0);
6715 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
6716 this_bol = PT;
6717 this_bol_byte = PT_BYTE;
6719 /* See if this line duplicates the previous one.
6720 If so, combine duplicates. */
6721 if (this_bol > BEG)
6723 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
6724 prev_bol = PT;
6725 prev_bol_byte = PT_BYTE;
6727 dup = message_log_check_duplicate (prev_bol, prev_bol_byte,
6728 this_bol, this_bol_byte);
6729 if (dup)
6731 del_range_both (prev_bol, prev_bol_byte,
6732 this_bol, this_bol_byte, 0);
6733 if (dup > 1)
6735 char dupstr[40];
6736 int duplen;
6738 /* If you change this format, don't forget to also
6739 change message_log_check_duplicate. */
6740 sprintf (dupstr, " [%d times]", dup);
6741 duplen = strlen (dupstr);
6742 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
6743 insert_1 (dupstr, duplen, 1, 0, 1);
6748 /* If we have more than the desired maximum number of lines
6749 in the *Messages* buffer now, delete the oldest ones.
6750 This is safe because we don't have undo in this buffer. */
6752 if (NATNUMP (Vmessage_log_max))
6754 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
6755 -XFASTINT (Vmessage_log_max) - 1, 0);
6756 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
6759 BEGV = XMARKER (oldbegv)->charpos;
6760 BEGV_BYTE = marker_byte_position (oldbegv);
6762 if (zv_at_end)
6764 ZV = Z;
6765 ZV_BYTE = Z_BYTE;
6767 else
6769 ZV = XMARKER (oldzv)->charpos;
6770 ZV_BYTE = marker_byte_position (oldzv);
6773 if (point_at_end)
6774 TEMP_SET_PT_BOTH (Z, Z_BYTE);
6775 else
6776 /* We can't do Fgoto_char (oldpoint) because it will run some
6777 Lisp code. */
6778 TEMP_SET_PT_BOTH (XMARKER (oldpoint)->charpos,
6779 XMARKER (oldpoint)->bytepos);
6781 UNGCPRO;
6782 unchain_marker (XMARKER (oldpoint));
6783 unchain_marker (XMARKER (oldbegv));
6784 unchain_marker (XMARKER (oldzv));
6786 tem = Fget_buffer_window (Fcurrent_buffer (), Qt);
6787 set_buffer_internal (oldbuf);
6788 if (NILP (tem))
6789 windows_or_buffers_changed = old_windows_or_buffers_changed;
6790 message_log_need_newline = !nlflag;
6791 Vdeactivate_mark = old_deactivate_mark;
6796 /* We are at the end of the buffer after just having inserted a newline.
6797 (Note: We depend on the fact we won't be crossing the gap.)
6798 Check to see if the most recent message looks a lot like the previous one.
6799 Return 0 if different, 1 if the new one should just replace it, or a
6800 value N > 1 if we should also append " [N times]". */
6802 static int
6803 message_log_check_duplicate (prev_bol, prev_bol_byte, this_bol, this_bol_byte)
6804 int prev_bol, this_bol;
6805 int prev_bol_byte, this_bol_byte;
6807 int i;
6808 int len = Z_BYTE - 1 - this_bol_byte;
6809 int seen_dots = 0;
6810 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
6811 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
6813 for (i = 0; i < len; i++)
6815 if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.')
6816 seen_dots = 1;
6817 if (p1[i] != p2[i])
6818 return seen_dots;
6820 p1 += len;
6821 if (*p1 == '\n')
6822 return 2;
6823 if (*p1++ == ' ' && *p1++ == '[')
6825 int n = 0;
6826 while (*p1 >= '0' && *p1 <= '9')
6827 n = n * 10 + *p1++ - '0';
6828 if (strncmp (p1, " times]\n", 8) == 0)
6829 return n+1;
6831 return 0;
6835 /* Display an echo area message M with a specified length of NBYTES
6836 bytes. The string may include null characters. If M is 0, clear
6837 out any existing message, and let the mini-buffer text show
6838 through.
6840 The buffer M must continue to exist until after the echo area gets
6841 cleared or some other message gets displayed there. This means do
6842 not pass text that is stored in a Lisp string; do not pass text in
6843 a buffer that was alloca'd. */
6845 void
6846 message2 (m, nbytes, multibyte)
6847 const char *m;
6848 int nbytes;
6849 int multibyte;
6851 /* First flush out any partial line written with print. */
6852 message_log_maybe_newline ();
6853 if (m)
6854 message_dolog (m, nbytes, 1, multibyte);
6855 message2_nolog (m, nbytes, multibyte);
6859 /* The non-logging counterpart of message2. */
6861 void
6862 message2_nolog (m, nbytes, multibyte)
6863 const char *m;
6864 int nbytes, multibyte;
6866 struct frame *sf = SELECTED_FRAME ();
6867 message_enable_multibyte = multibyte;
6869 if (noninteractive)
6871 if (noninteractive_need_newline)
6872 putc ('\n', stderr);
6873 noninteractive_need_newline = 0;
6874 if (m)
6875 fwrite (m, nbytes, 1, stderr);
6876 if (cursor_in_echo_area == 0)
6877 fprintf (stderr, "\n");
6878 fflush (stderr);
6880 /* A null message buffer means that the frame hasn't really been
6881 initialized yet. Error messages get reported properly by
6882 cmd_error, so this must be just an informative message; toss it. */
6883 else if (INTERACTIVE
6884 && sf->glyphs_initialized_p
6885 && FRAME_MESSAGE_BUF (sf))
6887 Lisp_Object mini_window;
6888 struct frame *f;
6890 /* Get the frame containing the mini-buffer
6891 that the selected frame is using. */
6892 mini_window = FRAME_MINIBUF_WINDOW (sf);
6893 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6895 FRAME_SAMPLE_VISIBILITY (f);
6896 if (FRAME_VISIBLE_P (sf)
6897 && ! FRAME_VISIBLE_P (f))
6898 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
6900 if (m)
6902 set_message (m, Qnil, nbytes, multibyte);
6903 if (minibuffer_auto_raise)
6904 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
6906 else
6907 clear_message (1, 1);
6909 do_pending_window_change (0);
6910 echo_area_display (1);
6911 do_pending_window_change (0);
6912 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
6913 (*frame_up_to_date_hook) (f);
6918 /* Display an echo area message M with a specified length of NBYTES
6919 bytes. The string may include null characters. If M is not a
6920 string, clear out any existing message, and let the mini-buffer
6921 text show through. */
6923 void
6924 message3 (m, nbytes, multibyte)
6925 Lisp_Object m;
6926 int nbytes;
6927 int multibyte;
6929 struct gcpro gcpro1;
6931 GCPRO1 (m);
6932 clear_message (1,1);
6934 /* First flush out any partial line written with print. */
6935 message_log_maybe_newline ();
6936 if (STRINGP (m))
6937 message_dolog (SDATA (m), nbytes, 1, multibyte);
6938 message3_nolog (m, nbytes, multibyte);
6940 UNGCPRO;
6944 /* The non-logging version of message3. */
6946 void
6947 message3_nolog (m, nbytes, multibyte)
6948 Lisp_Object m;
6949 int nbytes, multibyte;
6951 struct frame *sf = SELECTED_FRAME ();
6952 message_enable_multibyte = multibyte;
6954 if (noninteractive)
6956 if (noninteractive_need_newline)
6957 putc ('\n', stderr);
6958 noninteractive_need_newline = 0;
6959 if (STRINGP (m))
6960 fwrite (SDATA (m), nbytes, 1, stderr);
6961 if (cursor_in_echo_area == 0)
6962 fprintf (stderr, "\n");
6963 fflush (stderr);
6965 /* A null message buffer means that the frame hasn't really been
6966 initialized yet. Error messages get reported properly by
6967 cmd_error, so this must be just an informative message; toss it. */
6968 else if (INTERACTIVE
6969 && sf->glyphs_initialized_p
6970 && FRAME_MESSAGE_BUF (sf))
6972 Lisp_Object mini_window;
6973 Lisp_Object frame;
6974 struct frame *f;
6976 /* Get the frame containing the mini-buffer
6977 that the selected frame is using. */
6978 mini_window = FRAME_MINIBUF_WINDOW (sf);
6979 frame = XWINDOW (mini_window)->frame;
6980 f = XFRAME (frame);
6982 FRAME_SAMPLE_VISIBILITY (f);
6983 if (FRAME_VISIBLE_P (sf)
6984 && !FRAME_VISIBLE_P (f))
6985 Fmake_frame_visible (frame);
6987 if (STRINGP (m) && SCHARS (m) > 0)
6989 set_message (NULL, m, nbytes, multibyte);
6990 if (minibuffer_auto_raise)
6991 Fraise_frame (frame);
6993 else
6994 clear_message (1, 1);
6996 do_pending_window_change (0);
6997 echo_area_display (1);
6998 do_pending_window_change (0);
6999 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
7000 (*frame_up_to_date_hook) (f);
7005 /* Display a null-terminated echo area message M. If M is 0, clear
7006 out any existing message, and let the mini-buffer text show through.
7008 The buffer M must continue to exist until after the echo area gets
7009 cleared or some other message gets displayed there. Do not pass
7010 text that is stored in a Lisp string. Do not pass text in a buffer
7011 that was alloca'd. */
7013 void
7014 message1 (m)
7015 char *m;
7017 message2 (m, (m ? strlen (m) : 0), 0);
7021 /* The non-logging counterpart of message1. */
7023 void
7024 message1_nolog (m)
7025 char *m;
7027 message2_nolog (m, (m ? strlen (m) : 0), 0);
7030 /* Display a message M which contains a single %s
7031 which gets replaced with STRING. */
7033 void
7034 message_with_string (m, string, log)
7035 char *m;
7036 Lisp_Object string;
7037 int log;
7039 CHECK_STRING (string);
7041 if (noninteractive)
7043 if (m)
7045 if (noninteractive_need_newline)
7046 putc ('\n', stderr);
7047 noninteractive_need_newline = 0;
7048 fprintf (stderr, m, SDATA (string));
7049 if (cursor_in_echo_area == 0)
7050 fprintf (stderr, "\n");
7051 fflush (stderr);
7054 else if (INTERACTIVE)
7056 /* The frame whose minibuffer we're going to display the message on.
7057 It may be larger than the selected frame, so we need
7058 to use its buffer, not the selected frame's buffer. */
7059 Lisp_Object mini_window;
7060 struct frame *f, *sf = SELECTED_FRAME ();
7062 /* Get the frame containing the minibuffer
7063 that the selected frame is using. */
7064 mini_window = FRAME_MINIBUF_WINDOW (sf);
7065 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
7067 /* A null message buffer means that the frame hasn't really been
7068 initialized yet. Error messages get reported properly by
7069 cmd_error, so this must be just an informative message; toss it. */
7070 if (FRAME_MESSAGE_BUF (f))
7072 Lisp_Object args[2], message;
7073 struct gcpro gcpro1, gcpro2;
7075 args[0] = build_string (m);
7076 args[1] = message = string;
7077 GCPRO2 (args[0], message);
7078 gcpro1.nvars = 2;
7080 message = Fformat (2, args);
7082 if (log)
7083 message3 (message, SBYTES (message), STRING_MULTIBYTE (message));
7084 else
7085 message3_nolog (message, SBYTES (message), STRING_MULTIBYTE (message));
7087 UNGCPRO;
7089 /* Print should start at the beginning of the message
7090 buffer next time. */
7091 message_buf_print = 0;
7097 /* Dump an informative message to the minibuf. If M is 0, clear out
7098 any existing message, and let the mini-buffer text show through. */
7100 /* VARARGS 1 */
7101 void
7102 message (m, a1, a2, a3)
7103 char *m;
7104 EMACS_INT a1, a2, a3;
7106 if (noninteractive)
7108 if (m)
7110 if (noninteractive_need_newline)
7111 putc ('\n', stderr);
7112 noninteractive_need_newline = 0;
7113 fprintf (stderr, m, a1, a2, a3);
7114 if (cursor_in_echo_area == 0)
7115 fprintf (stderr, "\n");
7116 fflush (stderr);
7119 else if (INTERACTIVE)
7121 /* The frame whose mini-buffer we're going to display the message
7122 on. It may be larger than the selected frame, so we need to
7123 use its buffer, not the selected frame's buffer. */
7124 Lisp_Object mini_window;
7125 struct frame *f, *sf = SELECTED_FRAME ();
7127 /* Get the frame containing the mini-buffer
7128 that the selected frame is using. */
7129 mini_window = FRAME_MINIBUF_WINDOW (sf);
7130 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
7132 /* A null message buffer means that the frame hasn't really been
7133 initialized yet. Error messages get reported properly by
7134 cmd_error, so this must be just an informative message; toss
7135 it. */
7136 if (FRAME_MESSAGE_BUF (f))
7138 if (m)
7140 int len;
7141 #ifdef NO_ARG_ARRAY
7142 char *a[3];
7143 a[0] = (char *) a1;
7144 a[1] = (char *) a2;
7145 a[2] = (char *) a3;
7147 len = doprnt (FRAME_MESSAGE_BUF (f),
7148 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
7149 #else
7150 len = doprnt (FRAME_MESSAGE_BUF (f),
7151 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3,
7152 (char **) &a1);
7153 #endif /* NO_ARG_ARRAY */
7155 message2 (FRAME_MESSAGE_BUF (f), len, 0);
7157 else
7158 message1 (0);
7160 /* Print should start at the beginning of the message
7161 buffer next time. */
7162 message_buf_print = 0;
7168 /* The non-logging version of message. */
7170 void
7171 message_nolog (m, a1, a2, a3)
7172 char *m;
7173 EMACS_INT a1, a2, a3;
7175 Lisp_Object old_log_max;
7176 old_log_max = Vmessage_log_max;
7177 Vmessage_log_max = Qnil;
7178 message (m, a1, a2, a3);
7179 Vmessage_log_max = old_log_max;
7183 /* Display the current message in the current mini-buffer. This is
7184 only called from error handlers in process.c, and is not time
7185 critical. */
7187 void
7188 update_echo_area ()
7190 if (!NILP (echo_area_buffer[0]))
7192 Lisp_Object string;
7193 string = Fcurrent_message ();
7194 message3 (string, SBYTES (string),
7195 !NILP (current_buffer->enable_multibyte_characters));
7200 /* Make sure echo area buffers in `echo_buffers' are live.
7201 If they aren't, make new ones. */
7203 static void
7204 ensure_echo_area_buffers ()
7206 int i;
7208 for (i = 0; i < 2; ++i)
7209 if (!BUFFERP (echo_buffer[i])
7210 || NILP (XBUFFER (echo_buffer[i])->name))
7212 char name[30];
7213 Lisp_Object old_buffer;
7214 int j;
7216 old_buffer = echo_buffer[i];
7217 sprintf (name, " *Echo Area %d*", i);
7218 echo_buffer[i] = Fget_buffer_create (build_string (name));
7219 XBUFFER (echo_buffer[i])->truncate_lines = Qnil;
7221 for (j = 0; j < 2; ++j)
7222 if (EQ (old_buffer, echo_area_buffer[j]))
7223 echo_area_buffer[j] = echo_buffer[i];
7228 /* Call FN with args A1..A4 with either the current or last displayed
7229 echo_area_buffer as current buffer.
7231 WHICH zero means use the current message buffer
7232 echo_area_buffer[0]. If that is nil, choose a suitable buffer
7233 from echo_buffer[] and clear it.
7235 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
7236 suitable buffer from echo_buffer[] and clear it.
7238 Value is what FN returns. */
7240 static int
7241 with_echo_area_buffer (w, which, fn, a1, a2, a3, a4)
7242 struct window *w;
7243 int which;
7244 int (*fn) P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
7245 EMACS_INT a1;
7246 Lisp_Object a2;
7247 EMACS_INT a3, a4;
7249 Lisp_Object buffer;
7250 int this_one, the_other, clear_buffer_p, rc;
7251 int count = SPECPDL_INDEX ();
7253 /* If buffers aren't live, make new ones. */
7254 ensure_echo_area_buffers ();
7256 clear_buffer_p = 0;
7258 if (which == 0)
7259 this_one = 0, the_other = 1;
7260 else if (which > 0)
7261 this_one = 1, the_other = 0;
7263 /* Choose a suitable buffer from echo_buffer[] is we don't
7264 have one. */
7265 if (NILP (echo_area_buffer[this_one]))
7267 echo_area_buffer[this_one]
7268 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
7269 ? echo_buffer[the_other]
7270 : echo_buffer[this_one]);
7271 clear_buffer_p = 1;
7274 buffer = echo_area_buffer[this_one];
7276 /* Don't get confused by reusing the buffer used for echoing
7277 for a different purpose. */
7278 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
7279 cancel_echoing ();
7281 record_unwind_protect (unwind_with_echo_area_buffer,
7282 with_echo_area_buffer_unwind_data (w));
7284 /* Make the echo area buffer current. Note that for display
7285 purposes, it is not necessary that the displayed window's buffer
7286 == current_buffer, except for text property lookup. So, let's
7287 only set that buffer temporarily here without doing a full
7288 Fset_window_buffer. We must also change w->pointm, though,
7289 because otherwise an assertions in unshow_buffer fails, and Emacs
7290 aborts. */
7291 set_buffer_internal_1 (XBUFFER (buffer));
7292 if (w)
7294 w->buffer = buffer;
7295 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
7298 current_buffer->undo_list = Qt;
7299 current_buffer->read_only = Qnil;
7300 specbind (Qinhibit_read_only, Qt);
7301 specbind (Qinhibit_modification_hooks, Qt);
7303 if (clear_buffer_p && Z > BEG)
7304 del_range (BEG, Z);
7306 xassert (BEGV >= BEG);
7307 xassert (ZV <= Z && ZV >= BEGV);
7309 rc = fn (a1, a2, a3, a4);
7311 xassert (BEGV >= BEG);
7312 xassert (ZV <= Z && ZV >= BEGV);
7314 unbind_to (count, Qnil);
7315 return rc;
7319 /* Save state that should be preserved around the call to the function
7320 FN called in with_echo_area_buffer. */
7322 static Lisp_Object
7323 with_echo_area_buffer_unwind_data (w)
7324 struct window *w;
7326 int i = 0;
7327 Lisp_Object vector;
7329 /* Reduce consing by keeping one vector in
7330 Vwith_echo_area_save_vector. */
7331 vector = Vwith_echo_area_save_vector;
7332 Vwith_echo_area_save_vector = Qnil;
7334 if (NILP (vector))
7335 vector = Fmake_vector (make_number (7), Qnil);
7337 XSETBUFFER (AREF (vector, i), current_buffer); ++i;
7338 AREF (vector, i) = Vdeactivate_mark, ++i;
7339 AREF (vector, i) = make_number (windows_or_buffers_changed), ++i;
7341 if (w)
7343 XSETWINDOW (AREF (vector, i), w); ++i;
7344 AREF (vector, i) = w->buffer; ++i;
7345 AREF (vector, i) = make_number (XMARKER (w->pointm)->charpos); ++i;
7346 AREF (vector, i) = make_number (XMARKER (w->pointm)->bytepos); ++i;
7348 else
7350 int end = i + 4;
7351 for (; i < end; ++i)
7352 AREF (vector, i) = Qnil;
7355 xassert (i == ASIZE (vector));
7356 return vector;
7360 /* Restore global state from VECTOR which was created by
7361 with_echo_area_buffer_unwind_data. */
7363 static Lisp_Object
7364 unwind_with_echo_area_buffer (vector)
7365 Lisp_Object vector;
7367 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
7368 Vdeactivate_mark = AREF (vector, 1);
7369 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
7371 if (WINDOWP (AREF (vector, 3)))
7373 struct window *w;
7374 Lisp_Object buffer, charpos, bytepos;
7376 w = XWINDOW (AREF (vector, 3));
7377 buffer = AREF (vector, 4);
7378 charpos = AREF (vector, 5);
7379 bytepos = AREF (vector, 6);
7381 w->buffer = buffer;
7382 set_marker_both (w->pointm, buffer,
7383 XFASTINT (charpos), XFASTINT (bytepos));
7386 Vwith_echo_area_save_vector = vector;
7387 return Qnil;
7391 /* Set up the echo area for use by print functions. MULTIBYTE_P
7392 non-zero means we will print multibyte. */
7394 void
7395 setup_echo_area_for_printing (multibyte_p)
7396 int multibyte_p;
7398 /* If we can't find an echo area any more, exit. */
7399 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
7400 Fkill_emacs (Qnil);
7402 ensure_echo_area_buffers ();
7404 if (!message_buf_print)
7406 /* A message has been output since the last time we printed.
7407 Choose a fresh echo area buffer. */
7408 if (EQ (echo_area_buffer[1], echo_buffer[0]))
7409 echo_area_buffer[0] = echo_buffer[1];
7410 else
7411 echo_area_buffer[0] = echo_buffer[0];
7413 /* Switch to that buffer and clear it. */
7414 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
7415 current_buffer->truncate_lines = Qnil;
7417 if (Z > BEG)
7419 int count = SPECPDL_INDEX ();
7420 specbind (Qinhibit_read_only, Qt);
7421 /* Note that undo recording is always disabled. */
7422 del_range (BEG, Z);
7423 unbind_to (count, Qnil);
7425 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
7427 /* Set up the buffer for the multibyteness we need. */
7428 if (multibyte_p
7429 != !NILP (current_buffer->enable_multibyte_characters))
7430 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
7432 /* Raise the frame containing the echo area. */
7433 if (minibuffer_auto_raise)
7435 struct frame *sf = SELECTED_FRAME ();
7436 Lisp_Object mini_window;
7437 mini_window = FRAME_MINIBUF_WINDOW (sf);
7438 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
7441 message_log_maybe_newline ();
7442 message_buf_print = 1;
7444 else
7446 if (NILP (echo_area_buffer[0]))
7448 if (EQ (echo_area_buffer[1], echo_buffer[0]))
7449 echo_area_buffer[0] = echo_buffer[1];
7450 else
7451 echo_area_buffer[0] = echo_buffer[0];
7454 if (current_buffer != XBUFFER (echo_area_buffer[0]))
7456 /* Someone switched buffers between print requests. */
7457 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
7458 current_buffer->truncate_lines = Qnil;
7464 /* Display an echo area message in window W. Value is non-zero if W's
7465 height is changed. If display_last_displayed_message_p is
7466 non-zero, display the message that was last displayed, otherwise
7467 display the current message. */
7469 static int
7470 display_echo_area (w)
7471 struct window *w;
7473 int i, no_message_p, window_height_changed_p, count;
7475 /* Temporarily disable garbage collections while displaying the echo
7476 area. This is done because a GC can print a message itself.
7477 That message would modify the echo area buffer's contents while a
7478 redisplay of the buffer is going on, and seriously confuse
7479 redisplay. */
7480 count = inhibit_garbage_collection ();
7482 /* If there is no message, we must call display_echo_area_1
7483 nevertheless because it resizes the window. But we will have to
7484 reset the echo_area_buffer in question to nil at the end because
7485 with_echo_area_buffer will sets it to an empty buffer. */
7486 i = display_last_displayed_message_p ? 1 : 0;
7487 no_message_p = NILP (echo_area_buffer[i]);
7489 window_height_changed_p
7490 = with_echo_area_buffer (w, display_last_displayed_message_p,
7491 display_echo_area_1,
7492 (EMACS_INT) w, Qnil, 0, 0);
7494 if (no_message_p)
7495 echo_area_buffer[i] = Qnil;
7497 unbind_to (count, Qnil);
7498 return window_height_changed_p;
7502 /* Helper for display_echo_area. Display the current buffer which
7503 contains the current echo area message in window W, a mini-window,
7504 a pointer to which is passed in A1. A2..A4 are currently not used.
7505 Change the height of W so that all of the message is displayed.
7506 Value is non-zero if height of W was changed. */
7508 static int
7509 display_echo_area_1 (a1, a2, a3, a4)
7510 EMACS_INT a1;
7511 Lisp_Object a2;
7512 EMACS_INT a3, a4;
7514 struct window *w = (struct window *) a1;
7515 Lisp_Object window;
7516 struct text_pos start;
7517 int window_height_changed_p = 0;
7519 /* Do this before displaying, so that we have a large enough glyph
7520 matrix for the display. */
7521 window_height_changed_p = resize_mini_window (w, 0);
7523 /* Display. */
7524 clear_glyph_matrix (w->desired_matrix);
7525 XSETWINDOW (window, w);
7526 SET_TEXT_POS (start, BEG, BEG_BYTE);
7527 try_window (window, start);
7529 return window_height_changed_p;
7533 /* Resize the echo area window to exactly the size needed for the
7534 currently displayed message, if there is one. If a mini-buffer
7535 is active, don't shrink it. */
7537 void
7538 resize_echo_area_exactly ()
7540 if (BUFFERP (echo_area_buffer[0])
7541 && WINDOWP (echo_area_window))
7543 struct window *w = XWINDOW (echo_area_window);
7544 int resized_p;
7545 Lisp_Object resize_exactly;
7547 if (minibuf_level == 0)
7548 resize_exactly = Qt;
7549 else
7550 resize_exactly = Qnil;
7552 resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
7553 (EMACS_INT) w, resize_exactly, 0, 0);
7554 if (resized_p)
7556 ++windows_or_buffers_changed;
7557 ++update_mode_lines;
7558 redisplay_internal (0);
7564 /* Callback function for with_echo_area_buffer, when used from
7565 resize_echo_area_exactly. A1 contains a pointer to the window to
7566 resize, EXACTLY non-nil means resize the mini-window exactly to the
7567 size of the text displayed. A3 and A4 are not used. Value is what
7568 resize_mini_window returns. */
7570 static int
7571 resize_mini_window_1 (a1, exactly, a3, a4)
7572 EMACS_INT a1;
7573 Lisp_Object exactly;
7574 EMACS_INT a3, a4;
7576 return resize_mini_window ((struct window *) a1, !NILP (exactly));
7580 /* Resize mini-window W to fit the size of its contents. EXACT:P
7581 means size the window exactly to the size needed. Otherwise, it's
7582 only enlarged until W's buffer is empty. Value is non-zero if
7583 the window height has been changed. */
7586 resize_mini_window (w, exact_p)
7587 struct window *w;
7588 int exact_p;
7590 struct frame *f = XFRAME (w->frame);
7591 int window_height_changed_p = 0;
7593 xassert (MINI_WINDOW_P (w));
7595 /* Don't resize windows while redisplaying a window; it would
7596 confuse redisplay functions when the size of the window they are
7597 displaying changes from under them. Such a resizing can happen,
7598 for instance, when which-func prints a long message while
7599 we are running fontification-functions. We're running these
7600 functions with safe_call which binds inhibit-redisplay to t. */
7601 if (!NILP (Vinhibit_redisplay))
7602 return 0;
7604 /* Nil means don't try to resize. */
7605 if (NILP (Vresize_mini_windows)
7606 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
7607 return 0;
7609 if (!FRAME_MINIBUF_ONLY_P (f))
7611 struct it it;
7612 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
7613 int total_height = WINDOW_TOTAL_LINES (root) + WINDOW_TOTAL_LINES (w);
7614 int height, max_height;
7615 int unit = FRAME_LINE_HEIGHT (f);
7616 struct text_pos start;
7617 struct buffer *old_current_buffer = NULL;
7619 if (current_buffer != XBUFFER (w->buffer))
7621 old_current_buffer = current_buffer;
7622 set_buffer_internal (XBUFFER (w->buffer));
7625 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
7627 /* Compute the max. number of lines specified by the user. */
7628 if (FLOATP (Vmax_mini_window_height))
7629 max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_LINES (f);
7630 else if (INTEGERP (Vmax_mini_window_height))
7631 max_height = XINT (Vmax_mini_window_height);
7632 else
7633 max_height = total_height / 4;
7635 /* Correct that max. height if it's bogus. */
7636 max_height = max (1, max_height);
7637 max_height = min (total_height, max_height);
7639 /* Find out the height of the text in the window. */
7640 if (it.truncate_lines_p)
7641 height = 1;
7642 else
7644 last_height = 0;
7645 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
7646 if (it.max_ascent == 0 && it.max_descent == 0)
7647 height = it.current_y + last_height;
7648 else
7649 height = it.current_y + it.max_ascent + it.max_descent;
7650 height -= min (it.extra_line_spacing, it.max_extra_line_spacing);
7651 height = (height + unit - 1) / unit;
7654 /* Compute a suitable window start. */
7655 if (height > max_height)
7657 height = max_height;
7658 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
7659 move_it_vertically_backward (&it, (height - 1) * unit);
7660 start = it.current.pos;
7662 else
7663 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
7664 SET_MARKER_FROM_TEXT_POS (w->start, start);
7666 if (EQ (Vresize_mini_windows, Qgrow_only))
7668 /* Let it grow only, until we display an empty message, in which
7669 case the window shrinks again. */
7670 if (height > WINDOW_TOTAL_LINES (w))
7672 int old_height = WINDOW_TOTAL_LINES (w);
7673 freeze_window_starts (f, 1);
7674 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7675 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7677 else if (height < WINDOW_TOTAL_LINES (w)
7678 && (exact_p || BEGV == ZV))
7680 int old_height = WINDOW_TOTAL_LINES (w);
7681 freeze_window_starts (f, 0);
7682 shrink_mini_window (w);
7683 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7686 else
7688 /* Always resize to exact size needed. */
7689 if (height > WINDOW_TOTAL_LINES (w))
7691 int old_height = WINDOW_TOTAL_LINES (w);
7692 freeze_window_starts (f, 1);
7693 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7694 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7696 else if (height < WINDOW_TOTAL_LINES (w))
7698 int old_height = WINDOW_TOTAL_LINES (w);
7699 freeze_window_starts (f, 0);
7700 shrink_mini_window (w);
7702 if (height)
7704 freeze_window_starts (f, 1);
7705 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7708 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7712 if (old_current_buffer)
7713 set_buffer_internal (old_current_buffer);
7716 return window_height_changed_p;
7720 /* Value is the current message, a string, or nil if there is no
7721 current message. */
7723 Lisp_Object
7724 current_message ()
7726 Lisp_Object msg;
7728 if (NILP (echo_area_buffer[0]))
7729 msg = Qnil;
7730 else
7732 with_echo_area_buffer (0, 0, current_message_1,
7733 (EMACS_INT) &msg, Qnil, 0, 0);
7734 if (NILP (msg))
7735 echo_area_buffer[0] = Qnil;
7738 return msg;
7742 static int
7743 current_message_1 (a1, a2, a3, a4)
7744 EMACS_INT a1;
7745 Lisp_Object a2;
7746 EMACS_INT a3, a4;
7748 Lisp_Object *msg = (Lisp_Object *) a1;
7750 if (Z > BEG)
7751 *msg = make_buffer_string (BEG, Z, 1);
7752 else
7753 *msg = Qnil;
7754 return 0;
7758 /* Push the current message on Vmessage_stack for later restauration
7759 by restore_message. Value is non-zero if the current message isn't
7760 empty. This is a relatively infrequent operation, so it's not
7761 worth optimizing. */
7764 push_message ()
7766 Lisp_Object msg;
7767 msg = current_message ();
7768 Vmessage_stack = Fcons (msg, Vmessage_stack);
7769 return STRINGP (msg);
7773 /* Restore message display from the top of Vmessage_stack. */
7775 void
7776 restore_message ()
7778 Lisp_Object msg;
7780 xassert (CONSP (Vmessage_stack));
7781 msg = XCAR (Vmessage_stack);
7782 if (STRINGP (msg))
7783 message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
7784 else
7785 message3_nolog (msg, 0, 0);
7789 /* Handler for record_unwind_protect calling pop_message. */
7791 Lisp_Object
7792 pop_message_unwind (dummy)
7793 Lisp_Object dummy;
7795 pop_message ();
7796 return Qnil;
7799 /* Pop the top-most entry off Vmessage_stack. */
7801 void
7802 pop_message ()
7804 xassert (CONSP (Vmessage_stack));
7805 Vmessage_stack = XCDR (Vmessage_stack);
7809 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
7810 exits. If the stack is not empty, we have a missing pop_message
7811 somewhere. */
7813 void
7814 check_message_stack ()
7816 if (!NILP (Vmessage_stack))
7817 abort ();
7821 /* Truncate to NCHARS what will be displayed in the echo area the next
7822 time we display it---but don't redisplay it now. */
7824 void
7825 truncate_echo_area (nchars)
7826 int nchars;
7828 if (nchars == 0)
7829 echo_area_buffer[0] = Qnil;
7830 /* A null message buffer means that the frame hasn't really been
7831 initialized yet. Error messages get reported properly by
7832 cmd_error, so this must be just an informative message; toss it. */
7833 else if (!noninteractive
7834 && INTERACTIVE
7835 && !NILP (echo_area_buffer[0]))
7837 struct frame *sf = SELECTED_FRAME ();
7838 if (FRAME_MESSAGE_BUF (sf))
7839 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil, 0, 0);
7844 /* Helper function for truncate_echo_area. Truncate the current
7845 message to at most NCHARS characters. */
7847 static int
7848 truncate_message_1 (nchars, a2, a3, a4)
7849 EMACS_INT nchars;
7850 Lisp_Object a2;
7851 EMACS_INT a3, a4;
7853 if (BEG + nchars < Z)
7854 del_range (BEG + nchars, Z);
7855 if (Z == BEG)
7856 echo_area_buffer[0] = Qnil;
7857 return 0;
7861 /* Set the current message to a substring of S or STRING.
7863 If STRING is a Lisp string, set the message to the first NBYTES
7864 bytes from STRING. NBYTES zero means use the whole string. If
7865 STRING is multibyte, the message will be displayed multibyte.
7867 If S is not null, set the message to the first LEN bytes of S. LEN
7868 zero means use the whole string. MULTIBYTE_P non-zero means S is
7869 multibyte. Display the message multibyte in that case. */
7871 void
7872 set_message (s, string, nbytes, multibyte_p)
7873 const char *s;
7874 Lisp_Object string;
7875 int nbytes, multibyte_p;
7877 message_enable_multibyte
7878 = ((s && multibyte_p)
7879 || (STRINGP (string) && STRING_MULTIBYTE (string)));
7881 with_echo_area_buffer (0, 0, set_message_1,
7882 (EMACS_INT) s, string, nbytes, multibyte_p);
7883 message_buf_print = 0;
7884 help_echo_showing_p = 0;
7888 /* Helper function for set_message. Arguments have the same meaning
7889 as there, with A1 corresponding to S and A2 corresponding to STRING
7890 This function is called with the echo area buffer being
7891 current. */
7893 static int
7894 set_message_1 (a1, a2, nbytes, multibyte_p)
7895 EMACS_INT a1;
7896 Lisp_Object a2;
7897 EMACS_INT nbytes, multibyte_p;
7899 const char *s = (const char *) a1;
7900 Lisp_Object string = a2;
7902 xassert (BEG == Z);
7904 /* Change multibyteness of the echo buffer appropriately. */
7905 if (message_enable_multibyte
7906 != !NILP (current_buffer->enable_multibyte_characters))
7907 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
7909 current_buffer->truncate_lines = message_truncate_lines ? Qt : Qnil;
7911 /* Insert new message at BEG. */
7912 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
7913 Ferase_buffer ();
7915 if (STRINGP (string))
7917 int nchars;
7919 if (nbytes == 0)
7920 nbytes = SBYTES (string);
7921 nchars = string_byte_to_char (string, nbytes);
7923 /* This function takes care of single/multibyte conversion. We
7924 just have to ensure that the echo area buffer has the right
7925 setting of enable_multibyte_characters. */
7926 insert_from_string (string, 0, 0, nchars, nbytes, 1);
7928 else if (s)
7930 if (nbytes == 0)
7931 nbytes = strlen (s);
7933 if (multibyte_p && NILP (current_buffer->enable_multibyte_characters))
7935 /* Convert from multi-byte to single-byte. */
7936 int i, c, n;
7937 unsigned char work[1];
7939 /* Convert a multibyte string to single-byte. */
7940 for (i = 0; i < nbytes; i += n)
7942 c = string_char_and_length (s + i, nbytes - i, &n);
7943 work[0] = (SINGLE_BYTE_CHAR_P (c)
7945 : multibyte_char_to_unibyte (c, Qnil));
7946 insert_1_both (work, 1, 1, 1, 0, 0);
7949 else if (!multibyte_p
7950 && !NILP (current_buffer->enable_multibyte_characters))
7952 /* Convert from single-byte to multi-byte. */
7953 int i, c, n;
7954 const unsigned char *msg = (const unsigned char *) s;
7955 unsigned char str[MAX_MULTIBYTE_LENGTH];
7957 /* Convert a single-byte string to multibyte. */
7958 for (i = 0; i < nbytes; i++)
7960 c = unibyte_char_to_multibyte (msg[i]);
7961 n = CHAR_STRING (c, str);
7962 insert_1_both (str, 1, n, 1, 0, 0);
7965 else
7966 insert_1 (s, nbytes, 1, 0, 0);
7969 return 0;
7973 /* Clear messages. CURRENT_P non-zero means clear the current
7974 message. LAST_DISPLAYED_P non-zero means clear the message
7975 last displayed. */
7977 void
7978 clear_message (current_p, last_displayed_p)
7979 int current_p, last_displayed_p;
7981 if (current_p)
7983 echo_area_buffer[0] = Qnil;
7984 message_cleared_p = 1;
7987 if (last_displayed_p)
7988 echo_area_buffer[1] = Qnil;
7990 message_buf_print = 0;
7993 /* Clear garbaged frames.
7995 This function is used where the old redisplay called
7996 redraw_garbaged_frames which in turn called redraw_frame which in
7997 turn called clear_frame. The call to clear_frame was a source of
7998 flickering. I believe a clear_frame is not necessary. It should
7999 suffice in the new redisplay to invalidate all current matrices,
8000 and ensure a complete redisplay of all windows. */
8002 static void
8003 clear_garbaged_frames ()
8005 if (frame_garbaged)
8007 Lisp_Object tail, frame;
8008 int changed_count = 0;
8010 FOR_EACH_FRAME (tail, frame)
8012 struct frame *f = XFRAME (frame);
8014 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
8016 if (f->resized_p)
8018 Fredraw_frame (frame);
8019 f->force_flush_display_p = 1;
8021 clear_current_matrices (f);
8022 changed_count++;
8023 f->garbaged = 0;
8024 f->resized_p = 0;
8028 frame_garbaged = 0;
8029 if (changed_count)
8030 ++windows_or_buffers_changed;
8035 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
8036 is non-zero update selected_frame. Value is non-zero if the
8037 mini-windows height has been changed. */
8039 static int
8040 echo_area_display (update_frame_p)
8041 int update_frame_p;
8043 Lisp_Object mini_window;
8044 struct window *w;
8045 struct frame *f;
8046 int window_height_changed_p = 0;
8047 struct frame *sf = SELECTED_FRAME ();
8049 mini_window = FRAME_MINIBUF_WINDOW (sf);
8050 w = XWINDOW (mini_window);
8051 f = XFRAME (WINDOW_FRAME (w));
8053 /* Don't display if frame is invisible or not yet initialized. */
8054 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
8055 return 0;
8057 /* The terminal frame is used as the first Emacs frame on the Mac OS. */
8058 #ifndef MAC_OS8
8059 #ifdef HAVE_WINDOW_SYSTEM
8060 /* When Emacs starts, selected_frame may be a visible terminal
8061 frame, even if we run under a window system. If we let this
8062 through, a message would be displayed on the terminal. */
8063 if (EQ (selected_frame, Vterminal_frame)
8064 && !NILP (Vwindow_system))
8065 return 0;
8066 #endif /* HAVE_WINDOW_SYSTEM */
8067 #endif
8069 /* Redraw garbaged frames. */
8070 if (frame_garbaged)
8071 clear_garbaged_frames ();
8073 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
8075 echo_area_window = mini_window;
8076 window_height_changed_p = display_echo_area (w);
8077 w->must_be_updated_p = 1;
8079 /* Update the display, unless called from redisplay_internal.
8080 Also don't update the screen during redisplay itself. The
8081 update will happen at the end of redisplay, and an update
8082 here could cause confusion. */
8083 if (update_frame_p && !redisplaying_p)
8085 int n = 0;
8087 /* If the display update has been interrupted by pending
8088 input, update mode lines in the frame. Due to the
8089 pending input, it might have been that redisplay hasn't
8090 been called, so that mode lines above the echo area are
8091 garbaged. This looks odd, so we prevent it here. */
8092 if (!display_completed)
8093 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), 0);
8095 if (window_height_changed_p
8096 /* Don't do this if Emacs is shutting down. Redisplay
8097 needs to run hooks. */
8098 && !NILP (Vrun_hooks))
8100 /* Must update other windows. Likewise as in other
8101 cases, don't let this update be interrupted by
8102 pending input. */
8103 int count = SPECPDL_INDEX ();
8104 specbind (Qredisplay_dont_pause, Qt);
8105 windows_or_buffers_changed = 1;
8106 redisplay_internal (0);
8107 unbind_to (count, Qnil);
8109 else if (FRAME_WINDOW_P (f) && n == 0)
8111 /* Window configuration is the same as before.
8112 Can do with a display update of the echo area,
8113 unless we displayed some mode lines. */
8114 update_single_window (w, 1);
8115 rif->flush_display (f);
8117 else
8118 update_frame (f, 1, 1);
8120 /* If cursor is in the echo area, make sure that the next
8121 redisplay displays the minibuffer, so that the cursor will
8122 be replaced with what the minibuffer wants. */
8123 if (cursor_in_echo_area)
8124 ++windows_or_buffers_changed;
8127 else if (!EQ (mini_window, selected_window))
8128 windows_or_buffers_changed++;
8130 /* The current message is now also the last one displayed. */
8131 echo_area_buffer[1] = echo_area_buffer[0];
8133 /* Prevent redisplay optimization in redisplay_internal by resetting
8134 this_line_start_pos. This is done because the mini-buffer now
8135 displays the message instead of its buffer text. */
8136 if (EQ (mini_window, selected_window))
8137 CHARPOS (this_line_start_pos) = 0;
8139 return window_height_changed_p;
8144 /***********************************************************************
8145 Frame Titles
8146 ***********************************************************************/
8149 /* The frame title buffering code is also used by Fformat_mode_line.
8150 So it is not conditioned by HAVE_WINDOW_SYSTEM. */
8152 /* A buffer for constructing frame titles in it; allocated from the
8153 heap in init_xdisp and resized as needed in store_frame_title_char. */
8155 static char *frame_title_buf;
8157 /* The buffer's end, and a current output position in it. */
8159 static char *frame_title_buf_end;
8160 static char *frame_title_ptr;
8163 /* Store a single character C for the frame title in frame_title_buf.
8164 Re-allocate frame_title_buf if necessary. */
8166 static void
8167 #ifdef PROTOTYPES
8168 store_frame_title_char (char c)
8169 #else
8170 store_frame_title_char (c)
8171 char c;
8172 #endif
8174 /* If output position has reached the end of the allocated buffer,
8175 double the buffer's size. */
8176 if (frame_title_ptr == frame_title_buf_end)
8178 int len = frame_title_ptr - frame_title_buf;
8179 int new_size = 2 * len * sizeof *frame_title_buf;
8180 frame_title_buf = (char *) xrealloc (frame_title_buf, new_size);
8181 frame_title_buf_end = frame_title_buf + new_size;
8182 frame_title_ptr = frame_title_buf + len;
8185 *frame_title_ptr++ = c;
8189 /* Store part of a frame title in frame_title_buf, beginning at
8190 frame_title_ptr. STR is the string to store. Do not copy
8191 characters that yield more columns than PRECISION; PRECISION <= 0
8192 means copy the whole string. Pad with spaces until FIELD_WIDTH
8193 number of characters have been copied; FIELD_WIDTH <= 0 means don't
8194 pad. Called from display_mode_element when it is used to build a
8195 frame title. */
8197 static int
8198 store_frame_title (str, field_width, precision)
8199 const unsigned char *str;
8200 int field_width, precision;
8202 int n = 0;
8203 int dummy, nbytes;
8205 /* Copy at most PRECISION chars from STR. */
8206 nbytes = strlen (str);
8207 n += c_string_width (str, nbytes, precision, &dummy, &nbytes);
8208 while (nbytes--)
8209 store_frame_title_char (*str++);
8211 /* Fill up with spaces until FIELD_WIDTH reached. */
8212 while (field_width > 0
8213 && n < field_width)
8215 store_frame_title_char (' ');
8216 ++n;
8219 return n;
8222 #ifdef HAVE_WINDOW_SYSTEM
8224 /* Set the title of FRAME, if it has changed. The title format is
8225 Vicon_title_format if FRAME is iconified, otherwise it is
8226 frame_title_format. */
8228 static void
8229 x_consider_frame_title (frame)
8230 Lisp_Object frame;
8232 struct frame *f = XFRAME (frame);
8234 if (FRAME_WINDOW_P (f)
8235 || FRAME_MINIBUF_ONLY_P (f)
8236 || f->explicit_name)
8238 /* Do we have more than one visible frame on this X display? */
8239 Lisp_Object tail;
8240 Lisp_Object fmt;
8241 struct buffer *obuf;
8242 int len;
8243 struct it it;
8245 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
8247 Lisp_Object other_frame = XCAR (tail);
8248 struct frame *tf = XFRAME (other_frame);
8250 if (tf != f
8251 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
8252 && !FRAME_MINIBUF_ONLY_P (tf)
8253 && !EQ (other_frame, tip_frame)
8254 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
8255 break;
8258 /* Set global variable indicating that multiple frames exist. */
8259 multiple_frames = CONSP (tail);
8261 /* Switch to the buffer of selected window of the frame. Set up
8262 frame_title_ptr so that display_mode_element will output into it;
8263 then display the title. */
8264 obuf = current_buffer;
8265 set_buffer_internal_1 (XBUFFER (XWINDOW (f->selected_window)->buffer));
8266 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
8267 frame_title_ptr = frame_title_buf;
8268 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
8269 NULL, DEFAULT_FACE_ID);
8270 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
8271 len = frame_title_ptr - frame_title_buf;
8272 frame_title_ptr = NULL;
8273 set_buffer_internal_1 (obuf);
8275 /* Set the title only if it's changed. This avoids consing in
8276 the common case where it hasn't. (If it turns out that we've
8277 already wasted too much time by walking through the list with
8278 display_mode_element, then we might need to optimize at a
8279 higher level than this.) */
8280 if (! STRINGP (f->name)
8281 || SBYTES (f->name) != len
8282 || bcmp (frame_title_buf, SDATA (f->name), len) != 0)
8283 x_implicitly_set_name (f, make_string (frame_title_buf, len), Qnil);
8287 #endif /* not HAVE_WINDOW_SYSTEM */
8292 /***********************************************************************
8293 Menu Bars
8294 ***********************************************************************/
8297 /* Prepare for redisplay by updating menu-bar item lists when
8298 appropriate. This can call eval. */
8300 void
8301 prepare_menu_bars ()
8303 int all_windows;
8304 struct gcpro gcpro1, gcpro2;
8305 struct frame *f;
8306 Lisp_Object tooltip_frame;
8308 #ifdef HAVE_WINDOW_SYSTEM
8309 tooltip_frame = tip_frame;
8310 #else
8311 tooltip_frame = Qnil;
8312 #endif
8314 /* Update all frame titles based on their buffer names, etc. We do
8315 this before the menu bars so that the buffer-menu will show the
8316 up-to-date frame titles. */
8317 #ifdef HAVE_WINDOW_SYSTEM
8318 if (windows_or_buffers_changed || update_mode_lines)
8320 Lisp_Object tail, frame;
8322 FOR_EACH_FRAME (tail, frame)
8324 f = XFRAME (frame);
8325 if (!EQ (frame, tooltip_frame)
8326 && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)))
8327 x_consider_frame_title (frame);
8330 #endif /* HAVE_WINDOW_SYSTEM */
8332 /* Update the menu bar item lists, if appropriate. This has to be
8333 done before any actual redisplay or generation of display lines. */
8334 all_windows = (update_mode_lines
8335 || buffer_shared > 1
8336 || windows_or_buffers_changed);
8337 if (all_windows)
8339 Lisp_Object tail, frame;
8340 int count = SPECPDL_INDEX ();
8342 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
8344 FOR_EACH_FRAME (tail, frame)
8346 f = XFRAME (frame);
8348 /* Ignore tooltip frame. */
8349 if (EQ (frame, tooltip_frame))
8350 continue;
8352 /* If a window on this frame changed size, report that to
8353 the user and clear the size-change flag. */
8354 if (FRAME_WINDOW_SIZES_CHANGED (f))
8356 Lisp_Object functions;
8358 /* Clear flag first in case we get an error below. */
8359 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
8360 functions = Vwindow_size_change_functions;
8361 GCPRO2 (tail, functions);
8363 while (CONSP (functions))
8365 call1 (XCAR (functions), frame);
8366 functions = XCDR (functions);
8368 UNGCPRO;
8371 GCPRO1 (tail);
8372 update_menu_bar (f, 0);
8373 #ifdef HAVE_WINDOW_SYSTEM
8374 update_tool_bar (f, 0);
8375 #endif
8376 UNGCPRO;
8379 unbind_to (count, Qnil);
8381 else
8383 struct frame *sf = SELECTED_FRAME ();
8384 update_menu_bar (sf, 1);
8385 #ifdef HAVE_WINDOW_SYSTEM
8386 update_tool_bar (sf, 1);
8387 #endif
8390 /* Motif needs this. See comment in xmenu.c. Turn it off when
8391 pending_menu_activation is not defined. */
8392 #ifdef USE_X_TOOLKIT
8393 pending_menu_activation = 0;
8394 #endif
8398 /* Update the menu bar item list for frame F. This has to be done
8399 before we start to fill in any display lines, because it can call
8400 eval.
8402 If SAVE_MATCH_DATA is non-zero, we must save and restore it here. */
8404 static void
8405 update_menu_bar (f, save_match_data)
8406 struct frame *f;
8407 int save_match_data;
8409 Lisp_Object window;
8410 register struct window *w;
8412 /* If called recursively during a menu update, do nothing. This can
8413 happen when, for instance, an activate-menubar-hook causes a
8414 redisplay. */
8415 if (inhibit_menubar_update)
8416 return;
8418 window = FRAME_SELECTED_WINDOW (f);
8419 w = XWINDOW (window);
8421 #if 0 /* The if statement below this if statement used to include the
8422 condition !NILP (w->update_mode_line), rather than using
8423 update_mode_lines directly, and this if statement may have
8424 been added to make that condition work. Now the if
8425 statement below matches its comment, this isn't needed. */
8426 if (update_mode_lines)
8427 w->update_mode_line = Qt;
8428 #endif
8430 if (FRAME_WINDOW_P (f)
8432 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
8433 || defined (USE_GTK)
8434 FRAME_EXTERNAL_MENU_BAR (f)
8435 #else
8436 FRAME_MENU_BAR_LINES (f) > 0
8437 #endif
8438 : FRAME_MENU_BAR_LINES (f) > 0)
8440 /* If the user has switched buffers or windows, we need to
8441 recompute to reflect the new bindings. But we'll
8442 recompute when update_mode_lines is set too; that means
8443 that people can use force-mode-line-update to request
8444 that the menu bar be recomputed. The adverse effect on
8445 the rest of the redisplay algorithm is about the same as
8446 windows_or_buffers_changed anyway. */
8447 if (windows_or_buffers_changed
8448 /* This used to test w->update_mode_line, but we believe
8449 there is no need to recompute the menu in that case. */
8450 || update_mode_lines
8451 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
8452 < BUF_MODIFF (XBUFFER (w->buffer)))
8453 != !NILP (w->last_had_star))
8454 || ((!NILP (Vtransient_mark_mode)
8455 && !NILP (XBUFFER (w->buffer)->mark_active))
8456 != !NILP (w->region_showing)))
8458 struct buffer *prev = current_buffer;
8459 int count = SPECPDL_INDEX ();
8461 specbind (Qinhibit_menubar_update, Qt);
8463 set_buffer_internal_1 (XBUFFER (w->buffer));
8464 if (save_match_data)
8465 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
8466 if (NILP (Voverriding_local_map_menu_flag))
8468 specbind (Qoverriding_terminal_local_map, Qnil);
8469 specbind (Qoverriding_local_map, Qnil);
8472 /* Run the Lucid hook. */
8473 safe_run_hooks (Qactivate_menubar_hook);
8475 /* If it has changed current-menubar from previous value,
8476 really recompute the menu-bar from the value. */
8477 if (! NILP (Vlucid_menu_bar_dirty_flag))
8478 call0 (Qrecompute_lucid_menubar);
8480 safe_run_hooks (Qmenu_bar_update_hook);
8481 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
8483 /* Redisplay the menu bar in case we changed it. */
8484 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
8485 || defined (USE_GTK)
8486 if (FRAME_WINDOW_P (f)
8487 #if defined (MAC_OS)
8488 /* All frames on Mac OS share the same menubar. So only the
8489 selected frame should be allowed to set it. */
8490 && f == SELECTED_FRAME ()
8491 #endif
8493 set_frame_menubar (f, 0, 0);
8494 else
8495 /* On a terminal screen, the menu bar is an ordinary screen
8496 line, and this makes it get updated. */
8497 w->update_mode_line = Qt;
8498 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
8499 /* In the non-toolkit version, the menu bar is an ordinary screen
8500 line, and this makes it get updated. */
8501 w->update_mode_line = Qt;
8502 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
8504 unbind_to (count, Qnil);
8505 set_buffer_internal_1 (prev);
8512 /***********************************************************************
8513 Output Cursor
8514 ***********************************************************************/
8516 #ifdef HAVE_WINDOW_SYSTEM
8518 /* EXPORT:
8519 Nominal cursor position -- where to draw output.
8520 HPOS and VPOS are window relative glyph matrix coordinates.
8521 X and Y are window relative pixel coordinates. */
8523 struct cursor_pos output_cursor;
8526 /* EXPORT:
8527 Set the global variable output_cursor to CURSOR. All cursor
8528 positions are relative to updated_window. */
8530 void
8531 set_output_cursor (cursor)
8532 struct cursor_pos *cursor;
8534 output_cursor.hpos = cursor->hpos;
8535 output_cursor.vpos = cursor->vpos;
8536 output_cursor.x = cursor->x;
8537 output_cursor.y = cursor->y;
8541 /* EXPORT for RIF:
8542 Set a nominal cursor position.
8544 HPOS and VPOS are column/row positions in a window glyph matrix. X
8545 and Y are window text area relative pixel positions.
8547 If this is done during an update, updated_window will contain the
8548 window that is being updated and the position is the future output
8549 cursor position for that window. If updated_window is null, use
8550 selected_window and display the cursor at the given position. */
8552 void
8553 x_cursor_to (vpos, hpos, y, x)
8554 int vpos, hpos, y, x;
8556 struct window *w;
8558 /* If updated_window is not set, work on selected_window. */
8559 if (updated_window)
8560 w = updated_window;
8561 else
8562 w = XWINDOW (selected_window);
8564 /* Set the output cursor. */
8565 output_cursor.hpos = hpos;
8566 output_cursor.vpos = vpos;
8567 output_cursor.x = x;
8568 output_cursor.y = y;
8570 /* If not called as part of an update, really display the cursor.
8571 This will also set the cursor position of W. */
8572 if (updated_window == NULL)
8574 BLOCK_INPUT;
8575 display_and_set_cursor (w, 1, hpos, vpos, x, y);
8576 if (rif->flush_display_optional)
8577 rif->flush_display_optional (SELECTED_FRAME ());
8578 UNBLOCK_INPUT;
8582 #endif /* HAVE_WINDOW_SYSTEM */
8585 /***********************************************************************
8586 Tool-bars
8587 ***********************************************************************/
8589 #ifdef HAVE_WINDOW_SYSTEM
8591 /* Where the mouse was last time we reported a mouse event. */
8593 FRAME_PTR last_mouse_frame;
8595 /* Tool-bar item index of the item on which a mouse button was pressed
8596 or -1. */
8598 int last_tool_bar_item;
8601 /* Update the tool-bar item list for frame F. This has to be done
8602 before we start to fill in any display lines. Called from
8603 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
8604 and restore it here. */
8606 static void
8607 update_tool_bar (f, save_match_data)
8608 struct frame *f;
8609 int save_match_data;
8611 #ifdef USE_GTK
8612 int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
8613 #else
8614 int do_update = WINDOWP (f->tool_bar_window)
8615 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0;
8616 #endif
8618 if (do_update)
8620 Lisp_Object window;
8621 struct window *w;
8623 window = FRAME_SELECTED_WINDOW (f);
8624 w = XWINDOW (window);
8626 /* If the user has switched buffers or windows, we need to
8627 recompute to reflect the new bindings. But we'll
8628 recompute when update_mode_lines is set too; that means
8629 that people can use force-mode-line-update to request
8630 that the menu bar be recomputed. The adverse effect on
8631 the rest of the redisplay algorithm is about the same as
8632 windows_or_buffers_changed anyway. */
8633 if (windows_or_buffers_changed
8634 || !NILP (w->update_mode_line)
8635 || update_mode_lines
8636 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
8637 < BUF_MODIFF (XBUFFER (w->buffer)))
8638 != !NILP (w->last_had_star))
8639 || ((!NILP (Vtransient_mark_mode)
8640 && !NILP (XBUFFER (w->buffer)->mark_active))
8641 != !NILP (w->region_showing)))
8643 struct buffer *prev = current_buffer;
8644 int count = SPECPDL_INDEX ();
8645 Lisp_Object new_tool_bar;
8646 int new_n_tool_bar;
8647 struct gcpro gcpro1;
8649 /* Set current_buffer to the buffer of the selected
8650 window of the frame, so that we get the right local
8651 keymaps. */
8652 set_buffer_internal_1 (XBUFFER (w->buffer));
8654 /* Save match data, if we must. */
8655 if (save_match_data)
8656 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
8658 /* Make sure that we don't accidentally use bogus keymaps. */
8659 if (NILP (Voverriding_local_map_menu_flag))
8661 specbind (Qoverriding_terminal_local_map, Qnil);
8662 specbind (Qoverriding_local_map, Qnil);
8665 GCPRO1 (new_tool_bar);
8667 /* Build desired tool-bar items from keymaps. */
8668 new_tool_bar = tool_bar_items (Fcopy_sequence (f->tool_bar_items),
8669 &new_n_tool_bar);
8671 /* Redisplay the tool-bar if we changed it. */
8672 if (NILP (Fequal (new_tool_bar, f->tool_bar_items)))
8674 /* Redisplay that happens asynchronously due to an expose event
8675 may access f->tool_bar_items. Make sure we update both
8676 variables within BLOCK_INPUT so no such event interrupts. */
8677 BLOCK_INPUT;
8678 f->tool_bar_items = new_tool_bar;
8679 f->n_tool_bar_items = new_n_tool_bar;
8680 w->update_mode_line = Qt;
8681 UNBLOCK_INPUT;
8684 UNGCPRO;
8686 unbind_to (count, Qnil);
8687 set_buffer_internal_1 (prev);
8693 /* Set F->desired_tool_bar_string to a Lisp string representing frame
8694 F's desired tool-bar contents. F->tool_bar_items must have
8695 been set up previously by calling prepare_menu_bars. */
8697 static void
8698 build_desired_tool_bar_string (f)
8699 struct frame *f;
8701 int i, size, size_needed;
8702 struct gcpro gcpro1, gcpro2, gcpro3;
8703 Lisp_Object image, plist, props;
8705 image = plist = props = Qnil;
8706 GCPRO3 (image, plist, props);
8708 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
8709 Otherwise, make a new string. */
8711 /* The size of the string we might be able to reuse. */
8712 size = (STRINGP (f->desired_tool_bar_string)
8713 ? SCHARS (f->desired_tool_bar_string)
8714 : 0);
8716 /* We need one space in the string for each image. */
8717 size_needed = f->n_tool_bar_items;
8719 /* Reuse f->desired_tool_bar_string, if possible. */
8720 if (size < size_needed || NILP (f->desired_tool_bar_string))
8721 f->desired_tool_bar_string = Fmake_string (make_number (size_needed),
8722 make_number (' '));
8723 else
8725 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
8726 Fremove_text_properties (make_number (0), make_number (size),
8727 props, f->desired_tool_bar_string);
8730 /* Put a `display' property on the string for the images to display,
8731 put a `menu_item' property on tool-bar items with a value that
8732 is the index of the item in F's tool-bar item vector. */
8733 for (i = 0; i < f->n_tool_bar_items; ++i)
8735 #define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
8737 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
8738 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
8739 int hmargin, vmargin, relief, idx, end;
8740 extern Lisp_Object QCrelief, QCmargin, QCconversion;
8742 /* If image is a vector, choose the image according to the
8743 button state. */
8744 image = PROP (TOOL_BAR_ITEM_IMAGES);
8745 if (VECTORP (image))
8747 if (enabled_p)
8748 idx = (selected_p
8749 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
8750 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
8751 else
8752 idx = (selected_p
8753 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
8754 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
8756 xassert (ASIZE (image) >= idx);
8757 image = AREF (image, idx);
8759 else
8760 idx = -1;
8762 /* Ignore invalid image specifications. */
8763 if (!valid_image_p (image))
8764 continue;
8766 /* Display the tool-bar button pressed, or depressed. */
8767 plist = Fcopy_sequence (XCDR (image));
8769 /* Compute margin and relief to draw. */
8770 relief = (tool_bar_button_relief >= 0
8771 ? tool_bar_button_relief
8772 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
8773 hmargin = vmargin = relief;
8775 if (INTEGERP (Vtool_bar_button_margin)
8776 && XINT (Vtool_bar_button_margin) > 0)
8778 hmargin += XFASTINT (Vtool_bar_button_margin);
8779 vmargin += XFASTINT (Vtool_bar_button_margin);
8781 else if (CONSP (Vtool_bar_button_margin))
8783 if (INTEGERP (XCAR (Vtool_bar_button_margin))
8784 && XINT (XCAR (Vtool_bar_button_margin)) > 0)
8785 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
8787 if (INTEGERP (XCDR (Vtool_bar_button_margin))
8788 && XINT (XCDR (Vtool_bar_button_margin)) > 0)
8789 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
8792 if (auto_raise_tool_bar_buttons_p)
8794 /* Add a `:relief' property to the image spec if the item is
8795 selected. */
8796 if (selected_p)
8798 plist = Fplist_put (plist, QCrelief, make_number (-relief));
8799 hmargin -= relief;
8800 vmargin -= relief;
8803 else
8805 /* If image is selected, display it pressed, i.e. with a
8806 negative relief. If it's not selected, display it with a
8807 raised relief. */
8808 plist = Fplist_put (plist, QCrelief,
8809 (selected_p
8810 ? make_number (-relief)
8811 : make_number (relief)));
8812 hmargin -= relief;
8813 vmargin -= relief;
8816 /* Put a margin around the image. */
8817 if (hmargin || vmargin)
8819 if (hmargin == vmargin)
8820 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
8821 else
8822 plist = Fplist_put (plist, QCmargin,
8823 Fcons (make_number (hmargin),
8824 make_number (vmargin)));
8827 /* If button is not enabled, and we don't have special images
8828 for the disabled state, make the image appear disabled by
8829 applying an appropriate algorithm to it. */
8830 if (!enabled_p && idx < 0)
8831 plist = Fplist_put (plist, QCconversion, Qdisabled);
8833 /* Put a `display' text property on the string for the image to
8834 display. Put a `menu-item' property on the string that gives
8835 the start of this item's properties in the tool-bar items
8836 vector. */
8837 image = Fcons (Qimage, plist);
8838 props = list4 (Qdisplay, image,
8839 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS));
8841 /* Let the last image hide all remaining spaces in the tool bar
8842 string. The string can be longer than needed when we reuse a
8843 previous string. */
8844 if (i + 1 == f->n_tool_bar_items)
8845 end = SCHARS (f->desired_tool_bar_string);
8846 else
8847 end = i + 1;
8848 Fadd_text_properties (make_number (i), make_number (end),
8849 props, f->desired_tool_bar_string);
8850 #undef PROP
8853 UNGCPRO;
8857 /* Display one line of the tool-bar of frame IT->f. */
8859 static void
8860 display_tool_bar_line (it)
8861 struct it *it;
8863 struct glyph_row *row = it->glyph_row;
8864 int max_x = it->last_visible_x;
8865 struct glyph *last;
8867 prepare_desired_row (row);
8868 row->y = it->current_y;
8870 /* Note that this isn't made use of if the face hasn't a box,
8871 so there's no need to check the face here. */
8872 it->start_of_box_run_p = 1;
8874 while (it->current_x < max_x)
8876 int x_before, x, n_glyphs_before, i, nglyphs;
8878 /* Get the next display element. */
8879 if (!get_next_display_element (it))
8880 break;
8882 /* Produce glyphs. */
8883 x_before = it->current_x;
8884 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
8885 PRODUCE_GLYPHS (it);
8887 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
8888 i = 0;
8889 x = x_before;
8890 while (i < nglyphs)
8892 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
8894 if (x + glyph->pixel_width > max_x)
8896 /* Glyph doesn't fit on line. */
8897 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
8898 it->current_x = x;
8899 goto out;
8902 ++it->hpos;
8903 x += glyph->pixel_width;
8904 ++i;
8907 /* Stop at line ends. */
8908 if (ITERATOR_AT_END_OF_LINE_P (it))
8909 break;
8911 set_iterator_to_next (it, 1);
8914 out:;
8916 row->displays_text_p = row->used[TEXT_AREA] != 0;
8917 extend_face_to_end_of_line (it);
8918 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
8919 last->right_box_line_p = 1;
8920 if (last == row->glyphs[TEXT_AREA])
8921 last->left_box_line_p = 1;
8922 compute_line_metrics (it);
8924 /* If line is empty, make it occupy the rest of the tool-bar. */
8925 if (!row->displays_text_p)
8927 row->height = row->phys_height = it->last_visible_y - row->y;
8928 row->ascent = row->phys_ascent = 0;
8929 row->extra_line_spacing = 0;
8932 row->full_width_p = 1;
8933 row->continued_p = 0;
8934 row->truncated_on_left_p = 0;
8935 row->truncated_on_right_p = 0;
8937 it->current_x = it->hpos = 0;
8938 it->current_y += row->height;
8939 ++it->vpos;
8940 ++it->glyph_row;
8944 /* Value is the number of screen lines needed to make all tool-bar
8945 items of frame F visible. */
8947 static int
8948 tool_bar_lines_needed (f)
8949 struct frame *f;
8951 struct window *w = XWINDOW (f->tool_bar_window);
8952 struct it it;
8954 /* Initialize an iterator for iteration over
8955 F->desired_tool_bar_string in the tool-bar window of frame F. */
8956 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
8957 it.first_visible_x = 0;
8958 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
8959 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
8961 while (!ITERATOR_AT_END_P (&it))
8963 it.glyph_row = w->desired_matrix->rows;
8964 clear_glyph_row (it.glyph_row);
8965 display_tool_bar_line (&it);
8968 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
8972 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
8973 0, 1, 0,
8974 doc: /* Return the number of lines occupied by the tool bar of FRAME. */)
8975 (frame)
8976 Lisp_Object frame;
8978 struct frame *f;
8979 struct window *w;
8980 int nlines = 0;
8982 if (NILP (frame))
8983 frame = selected_frame;
8984 else
8985 CHECK_FRAME (frame);
8986 f = XFRAME (frame);
8988 if (WINDOWP (f->tool_bar_window)
8989 || (w = XWINDOW (f->tool_bar_window),
8990 WINDOW_TOTAL_LINES (w) > 0))
8992 update_tool_bar (f, 1);
8993 if (f->n_tool_bar_items)
8995 build_desired_tool_bar_string (f);
8996 nlines = tool_bar_lines_needed (f);
9000 return make_number (nlines);
9004 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
9005 height should be changed. */
9007 static int
9008 redisplay_tool_bar (f)
9009 struct frame *f;
9011 struct window *w;
9012 struct it it;
9013 struct glyph_row *row;
9014 int change_height_p = 0;
9016 #ifdef USE_GTK
9017 if (FRAME_EXTERNAL_TOOL_BAR (f))
9018 update_frame_tool_bar (f);
9019 return 0;
9020 #endif
9022 /* If frame hasn't a tool-bar window or if it is zero-height, don't
9023 do anything. This means you must start with tool-bar-lines
9024 non-zero to get the auto-sizing effect. Or in other words, you
9025 can turn off tool-bars by specifying tool-bar-lines zero. */
9026 if (!WINDOWP (f->tool_bar_window)
9027 || (w = XWINDOW (f->tool_bar_window),
9028 WINDOW_TOTAL_LINES (w) == 0))
9029 return 0;
9031 /* Set up an iterator for the tool-bar window. */
9032 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
9033 it.first_visible_x = 0;
9034 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
9035 row = it.glyph_row;
9037 /* Build a string that represents the contents of the tool-bar. */
9038 build_desired_tool_bar_string (f);
9039 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
9041 /* Display as many lines as needed to display all tool-bar items. */
9042 while (it.current_y < it.last_visible_y)
9043 display_tool_bar_line (&it);
9045 /* It doesn't make much sense to try scrolling in the tool-bar
9046 window, so don't do it. */
9047 w->desired_matrix->no_scrolling_p = 1;
9048 w->must_be_updated_p = 1;
9050 if (auto_resize_tool_bars_p)
9052 int nlines;
9054 /* If we couldn't display everything, change the tool-bar's
9055 height. */
9056 if (IT_STRING_CHARPOS (it) < it.end_charpos)
9057 change_height_p = 1;
9059 /* If there are blank lines at the end, except for a partially
9060 visible blank line at the end that is smaller than
9061 FRAME_LINE_HEIGHT, change the tool-bar's height. */
9062 row = it.glyph_row - 1;
9063 if (!row->displays_text_p
9064 && row->height >= FRAME_LINE_HEIGHT (f))
9065 change_height_p = 1;
9067 /* If row displays tool-bar items, but is partially visible,
9068 change the tool-bar's height. */
9069 if (row->displays_text_p
9070 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y)
9071 change_height_p = 1;
9073 /* Resize windows as needed by changing the `tool-bar-lines'
9074 frame parameter. */
9075 if (change_height_p
9076 && (nlines = tool_bar_lines_needed (f),
9077 nlines != WINDOW_TOTAL_LINES (w)))
9079 extern Lisp_Object Qtool_bar_lines;
9080 Lisp_Object frame;
9081 int old_height = WINDOW_TOTAL_LINES (w);
9083 XSETFRAME (frame, f);
9084 clear_glyph_matrix (w->desired_matrix);
9085 Fmodify_frame_parameters (frame,
9086 Fcons (Fcons (Qtool_bar_lines,
9087 make_number (nlines)),
9088 Qnil));
9089 if (WINDOW_TOTAL_LINES (w) != old_height)
9090 fonts_changed_p = 1;
9094 return change_height_p;
9098 /* Get information about the tool-bar item which is displayed in GLYPH
9099 on frame F. Return in *PROP_IDX the index where tool-bar item
9100 properties start in F->tool_bar_items. Value is zero if
9101 GLYPH doesn't display a tool-bar item. */
9103 static int
9104 tool_bar_item_info (f, glyph, prop_idx)
9105 struct frame *f;
9106 struct glyph *glyph;
9107 int *prop_idx;
9109 Lisp_Object prop;
9110 int success_p;
9111 int charpos;
9113 /* This function can be called asynchronously, which means we must
9114 exclude any possibility that Fget_text_property signals an
9115 error. */
9116 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
9117 charpos = max (0, charpos);
9119 /* Get the text property `menu-item' at pos. The value of that
9120 property is the start index of this item's properties in
9121 F->tool_bar_items. */
9122 prop = Fget_text_property (make_number (charpos),
9123 Qmenu_item, f->current_tool_bar_string);
9124 if (INTEGERP (prop))
9126 *prop_idx = XINT (prop);
9127 success_p = 1;
9129 else
9130 success_p = 0;
9132 return success_p;
9136 /* Get information about the tool-bar item at position X/Y on frame F.
9137 Return in *GLYPH a pointer to the glyph of the tool-bar item in
9138 the current matrix of the tool-bar window of F, or NULL if not
9139 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
9140 item in F->tool_bar_items. Value is
9142 -1 if X/Y is not on a tool-bar item
9143 0 if X/Y is on the same item that was highlighted before.
9144 1 otherwise. */
9146 static int
9147 get_tool_bar_item (f, x, y, glyph, hpos, vpos, prop_idx)
9148 struct frame *f;
9149 int x, y;
9150 struct glyph **glyph;
9151 int *hpos, *vpos, *prop_idx;
9153 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
9154 struct window *w = XWINDOW (f->tool_bar_window);
9155 int area;
9157 /* Find the glyph under X/Y. */
9158 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
9159 if (*glyph == NULL)
9160 return -1;
9162 /* Get the start of this tool-bar item's properties in
9163 f->tool_bar_items. */
9164 if (!tool_bar_item_info (f, *glyph, prop_idx))
9165 return -1;
9167 /* Is mouse on the highlighted item? */
9168 if (EQ (f->tool_bar_window, dpyinfo->mouse_face_window)
9169 && *vpos >= dpyinfo->mouse_face_beg_row
9170 && *vpos <= dpyinfo->mouse_face_end_row
9171 && (*vpos > dpyinfo->mouse_face_beg_row
9172 || *hpos >= dpyinfo->mouse_face_beg_col)
9173 && (*vpos < dpyinfo->mouse_face_end_row
9174 || *hpos < dpyinfo->mouse_face_end_col
9175 || dpyinfo->mouse_face_past_end))
9176 return 0;
9178 return 1;
9182 /* EXPORT:
9183 Handle mouse button event on the tool-bar of frame F, at
9184 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
9185 0 for button release. MODIFIERS is event modifiers for button
9186 release. */
9188 void
9189 handle_tool_bar_click (f, x, y, down_p, modifiers)
9190 struct frame *f;
9191 int x, y, down_p;
9192 unsigned int modifiers;
9194 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
9195 struct window *w = XWINDOW (f->tool_bar_window);
9196 int hpos, vpos, prop_idx;
9197 struct glyph *glyph;
9198 Lisp_Object enabled_p;
9200 /* If not on the highlighted tool-bar item, return. */
9201 frame_to_window_pixel_xy (w, &x, &y);
9202 if (get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0)
9203 return;
9205 /* If item is disabled, do nothing. */
9206 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
9207 if (NILP (enabled_p))
9208 return;
9210 if (down_p)
9212 /* Show item in pressed state. */
9213 show_mouse_face (dpyinfo, DRAW_IMAGE_SUNKEN);
9214 dpyinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN;
9215 last_tool_bar_item = prop_idx;
9217 else
9219 Lisp_Object key, frame;
9220 struct input_event event;
9221 EVENT_INIT (event);
9223 /* Show item in released state. */
9224 show_mouse_face (dpyinfo, DRAW_IMAGE_RAISED);
9225 dpyinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
9227 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
9229 XSETFRAME (frame, f);
9230 event.kind = TOOL_BAR_EVENT;
9231 event.frame_or_window = frame;
9232 event.arg = frame;
9233 kbd_buffer_store_event (&event);
9235 event.kind = TOOL_BAR_EVENT;
9236 event.frame_or_window = frame;
9237 event.arg = key;
9238 event.modifiers = modifiers;
9239 kbd_buffer_store_event (&event);
9240 last_tool_bar_item = -1;
9245 /* Possibly highlight a tool-bar item on frame F when mouse moves to
9246 tool-bar window-relative coordinates X/Y. Called from
9247 note_mouse_highlight. */
9249 static void
9250 note_tool_bar_highlight (f, x, y)
9251 struct frame *f;
9252 int x, y;
9254 Lisp_Object window = f->tool_bar_window;
9255 struct window *w = XWINDOW (window);
9256 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
9257 int hpos, vpos;
9258 struct glyph *glyph;
9259 struct glyph_row *row;
9260 int i;
9261 Lisp_Object enabled_p;
9262 int prop_idx;
9263 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
9264 int mouse_down_p, rc;
9266 /* Function note_mouse_highlight is called with negative x(y
9267 values when mouse moves outside of the frame. */
9268 if (x <= 0 || y <= 0)
9270 clear_mouse_face (dpyinfo);
9271 return;
9274 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
9275 if (rc < 0)
9277 /* Not on tool-bar item. */
9278 clear_mouse_face (dpyinfo);
9279 return;
9281 else if (rc == 0)
9282 /* On same tool-bar item as before. */
9283 goto set_help_echo;
9285 clear_mouse_face (dpyinfo);
9287 /* Mouse is down, but on different tool-bar item? */
9288 mouse_down_p = (dpyinfo->grabbed
9289 && f == last_mouse_frame
9290 && FRAME_LIVE_P (f));
9291 if (mouse_down_p
9292 && last_tool_bar_item != prop_idx)
9293 return;
9295 dpyinfo->mouse_face_image_state = DRAW_NORMAL_TEXT;
9296 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
9298 /* If tool-bar item is not enabled, don't highlight it. */
9299 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
9300 if (!NILP (enabled_p))
9302 /* Compute the x-position of the glyph. In front and past the
9303 image is a space. We include this in the highlighted area. */
9304 row = MATRIX_ROW (w->current_matrix, vpos);
9305 for (i = x = 0; i < hpos; ++i)
9306 x += row->glyphs[TEXT_AREA][i].pixel_width;
9308 /* Record this as the current active region. */
9309 dpyinfo->mouse_face_beg_col = hpos;
9310 dpyinfo->mouse_face_beg_row = vpos;
9311 dpyinfo->mouse_face_beg_x = x;
9312 dpyinfo->mouse_face_beg_y = row->y;
9313 dpyinfo->mouse_face_past_end = 0;
9315 dpyinfo->mouse_face_end_col = hpos + 1;
9316 dpyinfo->mouse_face_end_row = vpos;
9317 dpyinfo->mouse_face_end_x = x + glyph->pixel_width;
9318 dpyinfo->mouse_face_end_y = row->y;
9319 dpyinfo->mouse_face_window = window;
9320 dpyinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
9322 /* Display it as active. */
9323 show_mouse_face (dpyinfo, draw);
9324 dpyinfo->mouse_face_image_state = draw;
9327 set_help_echo:
9329 /* Set help_echo_string to a help string to display for this tool-bar item.
9330 XTread_socket does the rest. */
9331 help_echo_object = help_echo_window = Qnil;
9332 help_echo_pos = -1;
9333 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
9334 if (NILP (help_echo_string))
9335 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
9338 #endif /* HAVE_WINDOW_SYSTEM */
9342 /************************************************************************
9343 Horizontal scrolling
9344 ************************************************************************/
9346 static int hscroll_window_tree P_ ((Lisp_Object));
9347 static int hscroll_windows P_ ((Lisp_Object));
9349 /* For all leaf windows in the window tree rooted at WINDOW, set their
9350 hscroll value so that PT is (i) visible in the window, and (ii) so
9351 that it is not within a certain margin at the window's left and
9352 right border. Value is non-zero if any window's hscroll has been
9353 changed. */
9355 static int
9356 hscroll_window_tree (window)
9357 Lisp_Object window;
9359 int hscrolled_p = 0;
9360 int hscroll_relative_p = FLOATP (Vhscroll_step);
9361 int hscroll_step_abs = 0;
9362 double hscroll_step_rel = 0;
9364 if (hscroll_relative_p)
9366 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
9367 if (hscroll_step_rel < 0)
9369 hscroll_relative_p = 0;
9370 hscroll_step_abs = 0;
9373 else if (INTEGERP (Vhscroll_step))
9375 hscroll_step_abs = XINT (Vhscroll_step);
9376 if (hscroll_step_abs < 0)
9377 hscroll_step_abs = 0;
9379 else
9380 hscroll_step_abs = 0;
9382 while (WINDOWP (window))
9384 struct window *w = XWINDOW (window);
9386 if (WINDOWP (w->hchild))
9387 hscrolled_p |= hscroll_window_tree (w->hchild);
9388 else if (WINDOWP (w->vchild))
9389 hscrolled_p |= hscroll_window_tree (w->vchild);
9390 else if (w->cursor.vpos >= 0)
9392 int h_margin;
9393 int text_area_width;
9394 struct glyph_row *current_cursor_row
9395 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
9396 struct glyph_row *desired_cursor_row
9397 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
9398 struct glyph_row *cursor_row
9399 = (desired_cursor_row->enabled_p
9400 ? desired_cursor_row
9401 : current_cursor_row);
9403 text_area_width = window_box_width (w, TEXT_AREA);
9405 /* Scroll when cursor is inside this scroll margin. */
9406 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
9408 if ((XFASTINT (w->hscroll)
9409 && w->cursor.x <= h_margin)
9410 || (cursor_row->enabled_p
9411 && cursor_row->truncated_on_right_p
9412 && (w->cursor.x >= text_area_width - h_margin)))
9414 struct it it;
9415 int hscroll;
9416 struct buffer *saved_current_buffer;
9417 int pt;
9418 int wanted_x;
9420 /* Find point in a display of infinite width. */
9421 saved_current_buffer = current_buffer;
9422 current_buffer = XBUFFER (w->buffer);
9424 if (w == XWINDOW (selected_window))
9425 pt = BUF_PT (current_buffer);
9426 else
9428 pt = marker_position (w->pointm);
9429 pt = max (BEGV, pt);
9430 pt = min (ZV, pt);
9433 /* Move iterator to pt starting at cursor_row->start in
9434 a line with infinite width. */
9435 init_to_row_start (&it, w, cursor_row);
9436 it.last_visible_x = INFINITY;
9437 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
9438 current_buffer = saved_current_buffer;
9440 /* Position cursor in window. */
9441 if (!hscroll_relative_p && hscroll_step_abs == 0)
9442 hscroll = max (0, (it.current_x
9443 - (ITERATOR_AT_END_OF_LINE_P (&it)
9444 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
9445 : (text_area_width / 2))))
9446 / FRAME_COLUMN_WIDTH (it.f);
9447 else if (w->cursor.x >= text_area_width - h_margin)
9449 if (hscroll_relative_p)
9450 wanted_x = text_area_width * (1 - hscroll_step_rel)
9451 - h_margin;
9452 else
9453 wanted_x = text_area_width
9454 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
9455 - h_margin;
9456 hscroll
9457 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
9459 else
9461 if (hscroll_relative_p)
9462 wanted_x = text_area_width * hscroll_step_rel
9463 + h_margin;
9464 else
9465 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
9466 + h_margin;
9467 hscroll
9468 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
9470 hscroll = max (hscroll, XFASTINT (w->min_hscroll));
9472 /* Don't call Fset_window_hscroll if value hasn't
9473 changed because it will prevent redisplay
9474 optimizations. */
9475 if (XFASTINT (w->hscroll) != hscroll)
9477 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
9478 w->hscroll = make_number (hscroll);
9479 hscrolled_p = 1;
9484 window = w->next;
9487 /* Value is non-zero if hscroll of any leaf window has been changed. */
9488 return hscrolled_p;
9492 /* Set hscroll so that cursor is visible and not inside horizontal
9493 scroll margins for all windows in the tree rooted at WINDOW. See
9494 also hscroll_window_tree above. Value is non-zero if any window's
9495 hscroll has been changed. If it has, desired matrices on the frame
9496 of WINDOW are cleared. */
9498 static int
9499 hscroll_windows (window)
9500 Lisp_Object window;
9502 int hscrolled_p;
9504 if (automatic_hscrolling_p)
9506 hscrolled_p = hscroll_window_tree (window);
9507 if (hscrolled_p)
9508 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
9510 else
9511 hscrolled_p = 0;
9512 return hscrolled_p;
9517 /************************************************************************
9518 Redisplay
9519 ************************************************************************/
9521 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
9522 to a non-zero value. This is sometimes handy to have in a debugger
9523 session. */
9525 #if GLYPH_DEBUG
9527 /* First and last unchanged row for try_window_id. */
9529 int debug_first_unchanged_at_end_vpos;
9530 int debug_last_unchanged_at_beg_vpos;
9532 /* Delta vpos and y. */
9534 int debug_dvpos, debug_dy;
9536 /* Delta in characters and bytes for try_window_id. */
9538 int debug_delta, debug_delta_bytes;
9540 /* Values of window_end_pos and window_end_vpos at the end of
9541 try_window_id. */
9543 EMACS_INT debug_end_pos, debug_end_vpos;
9545 /* Append a string to W->desired_matrix->method. FMT is a printf
9546 format string. A1...A9 are a supplement for a variable-length
9547 argument list. If trace_redisplay_p is non-zero also printf the
9548 resulting string to stderr. */
9550 static void
9551 debug_method_add (w, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
9552 struct window *w;
9553 char *fmt;
9554 int a1, a2, a3, a4, a5, a6, a7, a8, a9;
9556 char buffer[512];
9557 char *method = w->desired_matrix->method;
9558 int len = strlen (method);
9559 int size = sizeof w->desired_matrix->method;
9560 int remaining = size - len - 1;
9562 sprintf (buffer, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
9563 if (len && remaining)
9565 method[len] = '|';
9566 --remaining, ++len;
9569 strncpy (method + len, buffer, remaining);
9571 if (trace_redisplay_p)
9572 fprintf (stderr, "%p (%s): %s\n",
9574 ((BUFFERP (w->buffer)
9575 && STRINGP (XBUFFER (w->buffer)->name))
9576 ? (char *) SDATA (XBUFFER (w->buffer)->name)
9577 : "no buffer"),
9578 buffer);
9581 #endif /* GLYPH_DEBUG */
9584 /* Value is non-zero if all changes in window W, which displays
9585 current_buffer, are in the text between START and END. START is a
9586 buffer position, END is given as a distance from Z. Used in
9587 redisplay_internal for display optimization. */
9589 static INLINE int
9590 text_outside_line_unchanged_p (w, start, end)
9591 struct window *w;
9592 int start, end;
9594 int unchanged_p = 1;
9596 /* If text or overlays have changed, see where. */
9597 if (XFASTINT (w->last_modified) < MODIFF
9598 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
9600 /* Gap in the line? */
9601 if (GPT < start || Z - GPT < end)
9602 unchanged_p = 0;
9604 /* Changes start in front of the line, or end after it? */
9605 if (unchanged_p
9606 && (BEG_UNCHANGED < start - 1
9607 || END_UNCHANGED < end))
9608 unchanged_p = 0;
9610 /* If selective display, can't optimize if changes start at the
9611 beginning of the line. */
9612 if (unchanged_p
9613 && INTEGERP (current_buffer->selective_display)
9614 && XINT (current_buffer->selective_display) > 0
9615 && (BEG_UNCHANGED < start || GPT <= start))
9616 unchanged_p = 0;
9618 /* If there are overlays at the start or end of the line, these
9619 may have overlay strings with newlines in them. A change at
9620 START, for instance, may actually concern the display of such
9621 overlay strings as well, and they are displayed on different
9622 lines. So, quickly rule out this case. (For the future, it
9623 might be desirable to implement something more telling than
9624 just BEG/END_UNCHANGED.) */
9625 if (unchanged_p)
9627 if (BEG + BEG_UNCHANGED == start
9628 && overlay_touches_p (start))
9629 unchanged_p = 0;
9630 if (END_UNCHANGED == end
9631 && overlay_touches_p (Z - end))
9632 unchanged_p = 0;
9636 return unchanged_p;
9640 /* Do a frame update, taking possible shortcuts into account. This is
9641 the main external entry point for redisplay.
9643 If the last redisplay displayed an echo area message and that message
9644 is no longer requested, we clear the echo area or bring back the
9645 mini-buffer if that is in use. */
9647 void
9648 redisplay ()
9650 redisplay_internal (0);
9654 static Lisp_Object
9655 overlay_arrow_string_or_property (var)
9656 Lisp_Object var;
9658 Lisp_Object val;
9660 if (val = Fget (var, Qoverlay_arrow_string), STRINGP (val))
9661 return val;
9663 return Voverlay_arrow_string;
9666 /* Return 1 if there are any overlay-arrows in current_buffer. */
9667 static int
9668 overlay_arrow_in_current_buffer_p ()
9670 Lisp_Object vlist;
9672 for (vlist = Voverlay_arrow_variable_list;
9673 CONSP (vlist);
9674 vlist = XCDR (vlist))
9676 Lisp_Object var = XCAR (vlist);
9677 Lisp_Object val;
9679 if (!SYMBOLP (var))
9680 continue;
9681 val = find_symbol_value (var);
9682 if (MARKERP (val)
9683 && current_buffer == XMARKER (val)->buffer)
9684 return 1;
9686 return 0;
9690 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
9691 has changed. */
9693 static int
9694 overlay_arrows_changed_p ()
9696 Lisp_Object vlist;
9698 for (vlist = Voverlay_arrow_variable_list;
9699 CONSP (vlist);
9700 vlist = XCDR (vlist))
9702 Lisp_Object var = XCAR (vlist);
9703 Lisp_Object val, pstr;
9705 if (!SYMBOLP (var))
9706 continue;
9707 val = find_symbol_value (var);
9708 if (!MARKERP (val))
9709 continue;
9710 if (! EQ (COERCE_MARKER (val),
9711 Fget (var, Qlast_arrow_position))
9712 || ! (pstr = overlay_arrow_string_or_property (var),
9713 EQ (pstr, Fget (var, Qlast_arrow_string))))
9714 return 1;
9716 return 0;
9719 /* Mark overlay arrows to be updated on next redisplay. */
9721 static void
9722 update_overlay_arrows (up_to_date)
9723 int up_to_date;
9725 Lisp_Object vlist;
9727 for (vlist = Voverlay_arrow_variable_list;
9728 CONSP (vlist);
9729 vlist = XCDR (vlist))
9731 Lisp_Object var = XCAR (vlist);
9733 if (!SYMBOLP (var))
9734 continue;
9736 if (up_to_date > 0)
9738 Lisp_Object val = find_symbol_value (var);
9739 Fput (var, Qlast_arrow_position,
9740 COERCE_MARKER (val));
9741 Fput (var, Qlast_arrow_string,
9742 overlay_arrow_string_or_property (var));
9744 else if (up_to_date < 0
9745 || !NILP (Fget (var, Qlast_arrow_position)))
9747 Fput (var, Qlast_arrow_position, Qt);
9748 Fput (var, Qlast_arrow_string, Qt);
9754 /* Return overlay arrow string to display at row.
9755 Return integer (bitmap number) for arrow bitmap in left fringe.
9756 Return nil if no overlay arrow. */
9758 static Lisp_Object
9759 overlay_arrow_at_row (it, row)
9760 struct it *it;
9761 struct glyph_row *row;
9763 Lisp_Object vlist;
9765 for (vlist = Voverlay_arrow_variable_list;
9766 CONSP (vlist);
9767 vlist = XCDR (vlist))
9769 Lisp_Object var = XCAR (vlist);
9770 Lisp_Object val;
9772 if (!SYMBOLP (var))
9773 continue;
9775 val = find_symbol_value (var);
9777 if (MARKERP (val)
9778 && current_buffer == XMARKER (val)->buffer
9779 && (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
9781 if (FRAME_WINDOW_P (it->f)
9782 && WINDOW_LEFT_FRINGE_WIDTH (it->w) > 0)
9784 if (val = Fget (var, Qoverlay_arrow_bitmap), SYMBOLP (val))
9786 int fringe_bitmap;
9787 if ((fringe_bitmap = lookup_fringe_bitmap (val)) != 0)
9788 return make_number (fringe_bitmap);
9790 return make_number (-1); /* Use default arrow bitmap */
9792 return overlay_arrow_string_or_property (var);
9796 return Qnil;
9799 /* Return 1 if point moved out of or into a composition. Otherwise
9800 return 0. PREV_BUF and PREV_PT are the last point buffer and
9801 position. BUF and PT are the current point buffer and position. */
9804 check_point_in_composition (prev_buf, prev_pt, buf, pt)
9805 struct buffer *prev_buf, *buf;
9806 int prev_pt, pt;
9808 int start, end;
9809 Lisp_Object prop;
9810 Lisp_Object buffer;
9812 XSETBUFFER (buffer, buf);
9813 /* Check a composition at the last point if point moved within the
9814 same buffer. */
9815 if (prev_buf == buf)
9817 if (prev_pt == pt)
9818 /* Point didn't move. */
9819 return 0;
9821 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
9822 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
9823 && COMPOSITION_VALID_P (start, end, prop)
9824 && start < prev_pt && end > prev_pt)
9825 /* The last point was within the composition. Return 1 iff
9826 point moved out of the composition. */
9827 return (pt <= start || pt >= end);
9830 /* Check a composition at the current point. */
9831 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
9832 && find_composition (pt, -1, &start, &end, &prop, buffer)
9833 && COMPOSITION_VALID_P (start, end, prop)
9834 && start < pt && end > pt);
9838 /* Reconsider the setting of B->clip_changed which is displayed
9839 in window W. */
9841 static INLINE void
9842 reconsider_clip_changes (w, b)
9843 struct window *w;
9844 struct buffer *b;
9846 if (b->clip_changed
9847 && !NILP (w->window_end_valid)
9848 && w->current_matrix->buffer == b
9849 && w->current_matrix->zv == BUF_ZV (b)
9850 && w->current_matrix->begv == BUF_BEGV (b))
9851 b->clip_changed = 0;
9853 /* If display wasn't paused, and W is not a tool bar window, see if
9854 point has been moved into or out of a composition. In that case,
9855 we set b->clip_changed to 1 to force updating the screen. If
9856 b->clip_changed has already been set to 1, we can skip this
9857 check. */
9858 if (!b->clip_changed
9859 && BUFFERP (w->buffer) && !NILP (w->window_end_valid))
9861 int pt;
9863 if (w == XWINDOW (selected_window))
9864 pt = BUF_PT (current_buffer);
9865 else
9866 pt = marker_position (w->pointm);
9868 if ((w->current_matrix->buffer != XBUFFER (w->buffer)
9869 || pt != XINT (w->last_point))
9870 && check_point_in_composition (w->current_matrix->buffer,
9871 XINT (w->last_point),
9872 XBUFFER (w->buffer), pt))
9873 b->clip_changed = 1;
9878 /* Select FRAME to forward the values of frame-local variables into C
9879 variables so that the redisplay routines can access those values
9880 directly. */
9882 static void
9883 select_frame_for_redisplay (frame)
9884 Lisp_Object frame;
9886 Lisp_Object tail, sym, val;
9887 Lisp_Object old = selected_frame;
9889 selected_frame = frame;
9891 for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail))
9892 if (CONSP (XCAR (tail))
9893 && (sym = XCAR (XCAR (tail)),
9894 SYMBOLP (sym))
9895 && (sym = indirect_variable (sym),
9896 val = SYMBOL_VALUE (sym),
9897 (BUFFER_LOCAL_VALUEP (val)
9898 || SOME_BUFFER_LOCAL_VALUEP (val)))
9899 && XBUFFER_LOCAL_VALUE (val)->check_frame)
9900 Fsymbol_value (sym);
9902 for (tail = XFRAME (old)->param_alist; CONSP (tail); tail = XCDR (tail))
9903 if (CONSP (XCAR (tail))
9904 && (sym = XCAR (XCAR (tail)),
9905 SYMBOLP (sym))
9906 && (sym = indirect_variable (sym),
9907 val = SYMBOL_VALUE (sym),
9908 (BUFFER_LOCAL_VALUEP (val)
9909 || SOME_BUFFER_LOCAL_VALUEP (val)))
9910 && XBUFFER_LOCAL_VALUE (val)->check_frame)
9911 Fsymbol_value (sym);
9915 #define STOP_POLLING \
9916 do { if (! polling_stopped_here) stop_polling (); \
9917 polling_stopped_here = 1; } while (0)
9919 #define RESUME_POLLING \
9920 do { if (polling_stopped_here) start_polling (); \
9921 polling_stopped_here = 0; } while (0)
9924 /* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
9925 response to any user action; therefore, we should preserve the echo
9926 area. (Actually, our caller does that job.) Perhaps in the future
9927 avoid recentering windows if it is not necessary; currently that
9928 causes some problems. */
9930 static void
9931 redisplay_internal (preserve_echo_area)
9932 int preserve_echo_area;
9934 struct window *w = XWINDOW (selected_window);
9935 struct frame *f = XFRAME (w->frame);
9936 int pause;
9937 int must_finish = 0;
9938 struct text_pos tlbufpos, tlendpos;
9939 int number_of_visible_frames;
9940 int count;
9941 struct frame *sf = SELECTED_FRAME ();
9942 int polling_stopped_here = 0;
9944 /* Non-zero means redisplay has to consider all windows on all
9945 frames. Zero means, only selected_window is considered. */
9946 int consider_all_windows_p;
9948 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
9950 /* No redisplay if running in batch mode or frame is not yet fully
9951 initialized, or redisplay is explicitly turned off by setting
9952 Vinhibit_redisplay. */
9953 if (noninteractive
9954 || !NILP (Vinhibit_redisplay)
9955 || !f->glyphs_initialized_p)
9956 return;
9958 /* The flag redisplay_performed_directly_p is set by
9959 direct_output_for_insert when it already did the whole screen
9960 update necessary. */
9961 if (redisplay_performed_directly_p)
9963 redisplay_performed_directly_p = 0;
9964 if (!hscroll_windows (selected_window))
9965 return;
9968 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
9969 if (popup_activated ())
9970 return;
9971 #endif
9973 /* I don't think this happens but let's be paranoid. */
9974 if (redisplaying_p)
9975 return;
9977 /* Record a function that resets redisplaying_p to its old value
9978 when we leave this function. */
9979 count = SPECPDL_INDEX ();
9980 record_unwind_protect (unwind_redisplay,
9981 Fcons (make_number (redisplaying_p), selected_frame));
9982 ++redisplaying_p;
9983 specbind (Qinhibit_free_realized_faces, Qnil);
9985 retry:
9986 pause = 0;
9987 reconsider_clip_changes (w, current_buffer);
9989 /* If new fonts have been loaded that make a glyph matrix adjustment
9990 necessary, do it. */
9991 if (fonts_changed_p)
9993 adjust_glyphs (NULL);
9994 ++windows_or_buffers_changed;
9995 fonts_changed_p = 0;
9998 /* If face_change_count is non-zero, init_iterator will free all
9999 realized faces, which includes the faces referenced from current
10000 matrices. So, we can't reuse current matrices in this case. */
10001 if (face_change_count)
10002 ++windows_or_buffers_changed;
10004 if (! FRAME_WINDOW_P (sf)
10005 && previous_terminal_frame != sf)
10007 /* Since frames on an ASCII terminal share the same display
10008 area, displaying a different frame means redisplay the whole
10009 thing. */
10010 windows_or_buffers_changed++;
10011 SET_FRAME_GARBAGED (sf);
10012 XSETFRAME (Vterminal_frame, sf);
10014 previous_terminal_frame = sf;
10016 /* Set the visible flags for all frames. Do this before checking
10017 for resized or garbaged frames; they want to know if their frames
10018 are visible. See the comment in frame.h for
10019 FRAME_SAMPLE_VISIBILITY. */
10021 Lisp_Object tail, frame;
10023 number_of_visible_frames = 0;
10025 FOR_EACH_FRAME (tail, frame)
10027 struct frame *f = XFRAME (frame);
10029 FRAME_SAMPLE_VISIBILITY (f);
10030 if (FRAME_VISIBLE_P (f))
10031 ++number_of_visible_frames;
10032 clear_desired_matrices (f);
10036 /* Notice any pending interrupt request to change frame size. */
10037 do_pending_window_change (1);
10039 /* Clear frames marked as garbaged. */
10040 if (frame_garbaged)
10041 clear_garbaged_frames ();
10043 /* Build menubar and tool-bar items. */
10044 prepare_menu_bars ();
10046 if (windows_or_buffers_changed)
10047 update_mode_lines++;
10049 /* Detect case that we need to write or remove a star in the mode line. */
10050 if ((SAVE_MODIFF < MODIFF) != !NILP (w->last_had_star))
10052 w->update_mode_line = Qt;
10053 if (buffer_shared > 1)
10054 update_mode_lines++;
10057 /* If %c is in the mode line, update it if needed. */
10058 if (!NILP (w->column_number_displayed)
10059 /* This alternative quickly identifies a common case
10060 where no change is needed. */
10061 && !(PT == XFASTINT (w->last_point)
10062 && XFASTINT (w->last_modified) >= MODIFF
10063 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
10064 && (XFASTINT (w->column_number_displayed)
10065 != (int) current_column ())) /* iftc */
10066 w->update_mode_line = Qt;
10068 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
10070 /* The variable buffer_shared is set in redisplay_window and
10071 indicates that we redisplay a buffer in different windows. See
10072 there. */
10073 consider_all_windows_p = (update_mode_lines || buffer_shared > 1
10074 || cursor_type_changed);
10076 /* If specs for an arrow have changed, do thorough redisplay
10077 to ensure we remove any arrow that should no longer exist. */
10078 if (overlay_arrows_changed_p ())
10079 consider_all_windows_p = windows_or_buffers_changed = 1;
10081 /* Normally the message* functions will have already displayed and
10082 updated the echo area, but the frame may have been trashed, or
10083 the update may have been preempted, so display the echo area
10084 again here. Checking message_cleared_p captures the case that
10085 the echo area should be cleared. */
10086 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
10087 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
10088 || (message_cleared_p
10089 && minibuf_level == 0
10090 /* If the mini-window is currently selected, this means the
10091 echo-area doesn't show through. */
10092 && !MINI_WINDOW_P (XWINDOW (selected_window))))
10094 int window_height_changed_p = echo_area_display (0);
10095 must_finish = 1;
10097 /* If we don't display the current message, don't clear the
10098 message_cleared_p flag, because, if we did, we wouldn't clear
10099 the echo area in the next redisplay which doesn't preserve
10100 the echo area. */
10101 if (!display_last_displayed_message_p)
10102 message_cleared_p = 0;
10104 if (fonts_changed_p)
10105 goto retry;
10106 else if (window_height_changed_p)
10108 consider_all_windows_p = 1;
10109 ++update_mode_lines;
10110 ++windows_or_buffers_changed;
10112 /* If window configuration was changed, frames may have been
10113 marked garbaged. Clear them or we will experience
10114 surprises wrt scrolling. */
10115 if (frame_garbaged)
10116 clear_garbaged_frames ();
10119 else if (EQ (selected_window, minibuf_window)
10120 && (current_buffer->clip_changed
10121 || XFASTINT (w->last_modified) < MODIFF
10122 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
10123 && resize_mini_window (w, 0))
10125 /* Resized active mini-window to fit the size of what it is
10126 showing if its contents might have changed. */
10127 must_finish = 1;
10128 consider_all_windows_p = 1;
10129 ++windows_or_buffers_changed;
10130 ++update_mode_lines;
10132 /* If window configuration was changed, frames may have been
10133 marked garbaged. Clear them or we will experience
10134 surprises wrt scrolling. */
10135 if (frame_garbaged)
10136 clear_garbaged_frames ();
10140 /* If showing the region, and mark has changed, we must redisplay
10141 the whole window. The assignment to this_line_start_pos prevents
10142 the optimization directly below this if-statement. */
10143 if (((!NILP (Vtransient_mark_mode)
10144 && !NILP (XBUFFER (w->buffer)->mark_active))
10145 != !NILP (w->region_showing))
10146 || (!NILP (w->region_showing)
10147 && !EQ (w->region_showing,
10148 Fmarker_position (XBUFFER (w->buffer)->mark))))
10149 CHARPOS (this_line_start_pos) = 0;
10151 /* Optimize the case that only the line containing the cursor in the
10152 selected window has changed. Variables starting with this_ are
10153 set in display_line and record information about the line
10154 containing the cursor. */
10155 tlbufpos = this_line_start_pos;
10156 tlendpos = this_line_end_pos;
10157 if (!consider_all_windows_p
10158 && CHARPOS (tlbufpos) > 0
10159 && NILP (w->update_mode_line)
10160 && !current_buffer->clip_changed
10161 && !current_buffer->prevent_redisplay_optimizations_p
10162 && FRAME_VISIBLE_P (XFRAME (w->frame))
10163 && !FRAME_OBSCURED_P (XFRAME (w->frame))
10164 /* Make sure recorded data applies to current buffer, etc. */
10165 && this_line_buffer == current_buffer
10166 && current_buffer == XBUFFER (w->buffer)
10167 && NILP (w->force_start)
10168 && NILP (w->optional_new_start)
10169 /* Point must be on the line that we have info recorded about. */
10170 && PT >= CHARPOS (tlbufpos)
10171 && PT <= Z - CHARPOS (tlendpos)
10172 /* All text outside that line, including its final newline,
10173 must be unchanged */
10174 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
10175 CHARPOS (tlendpos)))
10177 if (CHARPOS (tlbufpos) > BEGV
10178 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
10179 && (CHARPOS (tlbufpos) == ZV
10180 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
10181 /* Former continuation line has disappeared by becoming empty */
10182 goto cancel;
10183 else if (XFASTINT (w->last_modified) < MODIFF
10184 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF
10185 || MINI_WINDOW_P (w))
10187 /* We have to handle the case of continuation around a
10188 wide-column character (See the comment in indent.c around
10189 line 885).
10191 For instance, in the following case:
10193 -------- Insert --------
10194 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
10195 J_I_ ==> J_I_ `^^' are cursors.
10196 ^^ ^^
10197 -------- --------
10199 As we have to redraw the line above, we should goto cancel. */
10201 struct it it;
10202 int line_height_before = this_line_pixel_height;
10204 /* Note that start_display will handle the case that the
10205 line starting at tlbufpos is a continuation lines. */
10206 start_display (&it, w, tlbufpos);
10208 /* Implementation note: It this still necessary? */
10209 if (it.current_x != this_line_start_x)
10210 goto cancel;
10212 TRACE ((stderr, "trying display optimization 1\n"));
10213 w->cursor.vpos = -1;
10214 overlay_arrow_seen = 0;
10215 it.vpos = this_line_vpos;
10216 it.current_y = this_line_y;
10217 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
10218 display_line (&it);
10220 /* If line contains point, is not continued,
10221 and ends at same distance from eob as before, we win */
10222 if (w->cursor.vpos >= 0
10223 /* Line is not continued, otherwise this_line_start_pos
10224 would have been set to 0 in display_line. */
10225 && CHARPOS (this_line_start_pos)
10226 /* Line ends as before. */
10227 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
10228 /* Line has same height as before. Otherwise other lines
10229 would have to be shifted up or down. */
10230 && this_line_pixel_height == line_height_before)
10232 /* If this is not the window's last line, we must adjust
10233 the charstarts of the lines below. */
10234 if (it.current_y < it.last_visible_y)
10236 struct glyph_row *row
10237 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
10238 int delta, delta_bytes;
10240 if (Z - CHARPOS (tlendpos) == ZV)
10242 /* This line ends at end of (accessible part of)
10243 buffer. There is no newline to count. */
10244 delta = (Z
10245 - CHARPOS (tlendpos)
10246 - MATRIX_ROW_START_CHARPOS (row));
10247 delta_bytes = (Z_BYTE
10248 - BYTEPOS (tlendpos)
10249 - MATRIX_ROW_START_BYTEPOS (row));
10251 else
10253 /* This line ends in a newline. Must take
10254 account of the newline and the rest of the
10255 text that follows. */
10256 delta = (Z
10257 - CHARPOS (tlendpos)
10258 - MATRIX_ROW_START_CHARPOS (row));
10259 delta_bytes = (Z_BYTE
10260 - BYTEPOS (tlendpos)
10261 - MATRIX_ROW_START_BYTEPOS (row));
10264 increment_matrix_positions (w->current_matrix,
10265 this_line_vpos + 1,
10266 w->current_matrix->nrows,
10267 delta, delta_bytes);
10270 /* If this row displays text now but previously didn't,
10271 or vice versa, w->window_end_vpos may have to be
10272 adjusted. */
10273 if ((it.glyph_row - 1)->displays_text_p)
10275 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
10276 XSETINT (w->window_end_vpos, this_line_vpos);
10278 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
10279 && this_line_vpos > 0)
10280 XSETINT (w->window_end_vpos, this_line_vpos - 1);
10281 w->window_end_valid = Qnil;
10283 /* Update hint: No need to try to scroll in update_window. */
10284 w->desired_matrix->no_scrolling_p = 1;
10286 #if GLYPH_DEBUG
10287 *w->desired_matrix->method = 0;
10288 debug_method_add (w, "optimization 1");
10289 #endif
10290 #ifdef HAVE_WINDOW_SYSTEM
10291 update_window_fringes (w, 0);
10292 #endif
10293 goto update;
10295 else
10296 goto cancel;
10298 else if (/* Cursor position hasn't changed. */
10299 PT == XFASTINT (w->last_point)
10300 /* Make sure the cursor was last displayed
10301 in this window. Otherwise we have to reposition it. */
10302 && 0 <= w->cursor.vpos
10303 && WINDOW_TOTAL_LINES (w) > w->cursor.vpos)
10305 if (!must_finish)
10307 do_pending_window_change (1);
10309 /* We used to always goto end_of_redisplay here, but this
10310 isn't enough if we have a blinking cursor. */
10311 if (w->cursor_off_p == w->last_cursor_off_p)
10312 goto end_of_redisplay;
10314 goto update;
10316 /* If highlighting the region, or if the cursor is in the echo area,
10317 then we can't just move the cursor. */
10318 else if (! (!NILP (Vtransient_mark_mode)
10319 && !NILP (current_buffer->mark_active))
10320 && (EQ (selected_window, current_buffer->last_selected_window)
10321 || highlight_nonselected_windows)
10322 && NILP (w->region_showing)
10323 && NILP (Vshow_trailing_whitespace)
10324 && !cursor_in_echo_area)
10326 struct it it;
10327 struct glyph_row *row;
10329 /* Skip from tlbufpos to PT and see where it is. Note that
10330 PT may be in invisible text. If so, we will end at the
10331 next visible position. */
10332 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
10333 NULL, DEFAULT_FACE_ID);
10334 it.current_x = this_line_start_x;
10335 it.current_y = this_line_y;
10336 it.vpos = this_line_vpos;
10338 /* The call to move_it_to stops in front of PT, but
10339 moves over before-strings. */
10340 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
10342 if (it.vpos == this_line_vpos
10343 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
10344 row->enabled_p))
10346 xassert (this_line_vpos == it.vpos);
10347 xassert (this_line_y == it.current_y);
10348 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
10349 #if GLYPH_DEBUG
10350 *w->desired_matrix->method = 0;
10351 debug_method_add (w, "optimization 3");
10352 #endif
10353 goto update;
10355 else
10356 goto cancel;
10359 cancel:
10360 /* Text changed drastically or point moved off of line. */
10361 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
10364 CHARPOS (this_line_start_pos) = 0;
10365 consider_all_windows_p |= buffer_shared > 1;
10366 ++clear_face_cache_count;
10367 #ifdef HAVE_WINDOW_SYSTEM
10368 ++clear_image_cache_count;
10369 #endif
10371 /* Build desired matrices, and update the display. If
10372 consider_all_windows_p is non-zero, do it for all windows on all
10373 frames. Otherwise do it for selected_window, only. */
10375 if (consider_all_windows_p)
10377 Lisp_Object tail, frame;
10378 int i, n = 0, size = 50;
10379 struct frame **updated
10380 = (struct frame **) alloca (size * sizeof *updated);
10382 /* Recompute # windows showing selected buffer. This will be
10383 incremented each time such a window is displayed. */
10384 buffer_shared = 0;
10386 FOR_EACH_FRAME (tail, frame)
10388 struct frame *f = XFRAME (frame);
10390 if (FRAME_WINDOW_P (f) || f == sf)
10392 if (! EQ (frame, selected_frame))
10393 /* Select the frame, for the sake of frame-local
10394 variables. */
10395 select_frame_for_redisplay (frame);
10397 /* Mark all the scroll bars to be removed; we'll redeem
10398 the ones we want when we redisplay their windows. */
10399 if (condemn_scroll_bars_hook)
10400 condemn_scroll_bars_hook (f);
10402 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
10403 redisplay_windows (FRAME_ROOT_WINDOW (f));
10405 /* Any scroll bars which redisplay_windows should have
10406 nuked should now go away. */
10407 if (judge_scroll_bars_hook)
10408 judge_scroll_bars_hook (f);
10410 /* If fonts changed, display again. */
10411 /* ??? rms: I suspect it is a mistake to jump all the way
10412 back to retry here. It should just retry this frame. */
10413 if (fonts_changed_p)
10414 goto retry;
10416 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
10418 /* See if we have to hscroll. */
10419 if (hscroll_windows (f->root_window))
10420 goto retry;
10422 /* Prevent various kinds of signals during display
10423 update. stdio is not robust about handling
10424 signals, which can cause an apparent I/O
10425 error. */
10426 if (interrupt_input)
10427 unrequest_sigio ();
10428 STOP_POLLING;
10430 /* Update the display. */
10431 set_window_update_flags (XWINDOW (f->root_window), 1);
10432 pause |= update_frame (f, 0, 0);
10433 #if 0 /* Exiting the loop can leave the wrong value for buffer_shared. */
10434 if (pause)
10435 break;
10436 #endif
10438 if (n == size)
10440 int nbytes = size * sizeof *updated;
10441 struct frame **p = (struct frame **) alloca (2 * nbytes);
10442 bcopy (updated, p, nbytes);
10443 size *= 2;
10446 updated[n++] = f;
10451 if (!pause)
10453 /* Do the mark_window_display_accurate after all windows have
10454 been redisplayed because this call resets flags in buffers
10455 which are needed for proper redisplay. */
10456 for (i = 0; i < n; ++i)
10458 struct frame *f = updated[i];
10459 mark_window_display_accurate (f->root_window, 1);
10460 if (frame_up_to_date_hook)
10461 frame_up_to_date_hook (f);
10465 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
10467 Lisp_Object mini_window;
10468 struct frame *mini_frame;
10470 displayed_buffer = XBUFFER (XWINDOW (selected_window)->buffer);
10471 /* Use list_of_error, not Qerror, so that
10472 we catch only errors and don't run the debugger. */
10473 internal_condition_case_1 (redisplay_window_1, selected_window,
10474 list_of_error,
10475 redisplay_window_error);
10477 /* Compare desired and current matrices, perform output. */
10479 update:
10480 /* If fonts changed, display again. */
10481 if (fonts_changed_p)
10482 goto retry;
10484 /* Prevent various kinds of signals during display update.
10485 stdio is not robust about handling signals,
10486 which can cause an apparent I/O error. */
10487 if (interrupt_input)
10488 unrequest_sigio ();
10489 STOP_POLLING;
10491 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
10493 if (hscroll_windows (selected_window))
10494 goto retry;
10496 XWINDOW (selected_window)->must_be_updated_p = 1;
10497 pause = update_frame (sf, 0, 0);
10500 /* We may have called echo_area_display at the top of this
10501 function. If the echo area is on another frame, that may
10502 have put text on a frame other than the selected one, so the
10503 above call to update_frame would not have caught it. Catch
10504 it here. */
10505 mini_window = FRAME_MINIBUF_WINDOW (sf);
10506 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
10508 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
10510 XWINDOW (mini_window)->must_be_updated_p = 1;
10511 pause |= update_frame (mini_frame, 0, 0);
10512 if (!pause && hscroll_windows (mini_window))
10513 goto retry;
10517 /* If display was paused because of pending input, make sure we do a
10518 thorough update the next time. */
10519 if (pause)
10521 /* Prevent the optimization at the beginning of
10522 redisplay_internal that tries a single-line update of the
10523 line containing the cursor in the selected window. */
10524 CHARPOS (this_line_start_pos) = 0;
10526 /* Let the overlay arrow be updated the next time. */
10527 update_overlay_arrows (0);
10529 /* If we pause after scrolling, some rows in the current
10530 matrices of some windows are not valid. */
10531 if (!WINDOW_FULL_WIDTH_P (w)
10532 && !FRAME_WINDOW_P (XFRAME (w->frame)))
10533 update_mode_lines = 1;
10535 else
10537 if (!consider_all_windows_p)
10539 /* This has already been done above if
10540 consider_all_windows_p is set. */
10541 mark_window_display_accurate_1 (w, 1);
10543 /* Say overlay arrows are up to date. */
10544 update_overlay_arrows (1);
10546 if (frame_up_to_date_hook != 0)
10547 frame_up_to_date_hook (sf);
10550 update_mode_lines = 0;
10551 windows_or_buffers_changed = 0;
10552 cursor_type_changed = 0;
10555 /* Start SIGIO interrupts coming again. Having them off during the
10556 code above makes it less likely one will discard output, but not
10557 impossible, since there might be stuff in the system buffer here.
10558 But it is much hairier to try to do anything about that. */
10559 if (interrupt_input)
10560 request_sigio ();
10561 RESUME_POLLING;
10563 /* If a frame has become visible which was not before, redisplay
10564 again, so that we display it. Expose events for such a frame
10565 (which it gets when becoming visible) don't call the parts of
10566 redisplay constructing glyphs, so simply exposing a frame won't
10567 display anything in this case. So, we have to display these
10568 frames here explicitly. */
10569 if (!pause)
10571 Lisp_Object tail, frame;
10572 int new_count = 0;
10574 FOR_EACH_FRAME (tail, frame)
10576 int this_is_visible = 0;
10578 if (XFRAME (frame)->visible)
10579 this_is_visible = 1;
10580 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
10581 if (XFRAME (frame)->visible)
10582 this_is_visible = 1;
10584 if (this_is_visible)
10585 new_count++;
10588 if (new_count != number_of_visible_frames)
10589 windows_or_buffers_changed++;
10592 /* Change frame size now if a change is pending. */
10593 do_pending_window_change (1);
10595 /* If we just did a pending size change, or have additional
10596 visible frames, redisplay again. */
10597 if (windows_or_buffers_changed && !pause)
10598 goto retry;
10600 /* Clear the face cache eventually. */
10601 if (consider_all_windows_p)
10603 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
10605 clear_face_cache (0);
10606 clear_face_cache_count = 0;
10608 #ifdef HAVE_WINDOW_SYSTEM
10609 if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT)
10611 Lisp_Object tail, frame;
10612 FOR_EACH_FRAME (tail, frame)
10614 struct frame *f = XFRAME (frame);
10615 if (FRAME_WINDOW_P (f))
10616 clear_image_cache (f, 0);
10618 clear_image_cache_count = 0;
10620 #endif /* HAVE_WINDOW_SYSTEM */
10623 end_of_redisplay:
10624 unbind_to (count, Qnil);
10625 RESUME_POLLING;
10629 /* Redisplay, but leave alone any recent echo area message unless
10630 another message has been requested in its place.
10632 This is useful in situations where you need to redisplay but no
10633 user action has occurred, making it inappropriate for the message
10634 area to be cleared. See tracking_off and
10635 wait_reading_process_output for examples of these situations.
10637 FROM_WHERE is an integer saying from where this function was
10638 called. This is useful for debugging. */
10640 void
10641 redisplay_preserve_echo_area (from_where)
10642 int from_where;
10644 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
10646 if (!NILP (echo_area_buffer[1]))
10648 /* We have a previously displayed message, but no current
10649 message. Redisplay the previous message. */
10650 display_last_displayed_message_p = 1;
10651 redisplay_internal (1);
10652 display_last_displayed_message_p = 0;
10654 else
10655 redisplay_internal (1);
10657 if (rif != NULL && rif->flush_display_optional)
10658 rif->flush_display_optional (NULL);
10662 /* Function registered with record_unwind_protect in
10663 redisplay_internal. Reset redisplaying_p to the value it had
10664 before redisplay_internal was called, and clear
10665 prevent_freeing_realized_faces_p. It also selects the previously
10666 selected frame. */
10668 static Lisp_Object
10669 unwind_redisplay (val)
10670 Lisp_Object val;
10672 Lisp_Object old_redisplaying_p, old_frame;
10674 old_redisplaying_p = XCAR (val);
10675 redisplaying_p = XFASTINT (old_redisplaying_p);
10676 old_frame = XCDR (val);
10677 if (! EQ (old_frame, selected_frame))
10678 select_frame_for_redisplay (old_frame);
10679 return Qnil;
10683 /* Mark the display of window W as accurate or inaccurate. If
10684 ACCURATE_P is non-zero mark display of W as accurate. If
10685 ACCURATE_P is zero, arrange for W to be redisplayed the next time
10686 redisplay_internal is called. */
10688 static void
10689 mark_window_display_accurate_1 (w, accurate_p)
10690 struct window *w;
10691 int accurate_p;
10693 if (BUFFERP (w->buffer))
10695 struct buffer *b = XBUFFER (w->buffer);
10697 w->last_modified
10698 = make_number (accurate_p ? BUF_MODIFF (b) : 0);
10699 w->last_overlay_modified
10700 = make_number (accurate_p ? BUF_OVERLAY_MODIFF (b) : 0);
10701 w->last_had_star
10702 = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b) ? Qt : Qnil;
10704 if (accurate_p)
10706 b->clip_changed = 0;
10707 b->prevent_redisplay_optimizations_p = 0;
10709 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
10710 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
10711 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
10712 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
10714 w->current_matrix->buffer = b;
10715 w->current_matrix->begv = BUF_BEGV (b);
10716 w->current_matrix->zv = BUF_ZV (b);
10718 w->last_cursor = w->cursor;
10719 w->last_cursor_off_p = w->cursor_off_p;
10721 if (w == XWINDOW (selected_window))
10722 w->last_point = make_number (BUF_PT (b));
10723 else
10724 w->last_point = make_number (XMARKER (w->pointm)->charpos);
10728 if (accurate_p)
10730 w->window_end_valid = w->buffer;
10731 #if 0 /* This is incorrect with variable-height lines. */
10732 xassert (XINT (w->window_end_vpos)
10733 < (WINDOW_TOTAL_LINES (w)
10734 - (WINDOW_WANTS_MODELINE_P (w) ? 1 : 0)));
10735 #endif
10736 w->update_mode_line = Qnil;
10741 /* Mark the display of windows in the window tree rooted at WINDOW as
10742 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
10743 windows as accurate. If ACCURATE_P is zero, arrange for windows to
10744 be redisplayed the next time redisplay_internal is called. */
10746 void
10747 mark_window_display_accurate (window, accurate_p)
10748 Lisp_Object window;
10749 int accurate_p;
10751 struct window *w;
10753 for (; !NILP (window); window = w->next)
10755 w = XWINDOW (window);
10756 mark_window_display_accurate_1 (w, accurate_p);
10758 if (!NILP (w->vchild))
10759 mark_window_display_accurate (w->vchild, accurate_p);
10760 if (!NILP (w->hchild))
10761 mark_window_display_accurate (w->hchild, accurate_p);
10764 if (accurate_p)
10766 update_overlay_arrows (1);
10768 else
10770 /* Force a thorough redisplay the next time by setting
10771 last_arrow_position and last_arrow_string to t, which is
10772 unequal to any useful value of Voverlay_arrow_... */
10773 update_overlay_arrows (-1);
10778 /* Return value in display table DP (Lisp_Char_Table *) for character
10779 C. Since a display table doesn't have any parent, we don't have to
10780 follow parent. Do not call this function directly but use the
10781 macro DISP_CHAR_VECTOR. */
10783 Lisp_Object
10784 disp_char_vector (dp, c)
10785 struct Lisp_Char_Table *dp;
10786 int c;
10788 int code[4], i;
10789 Lisp_Object val;
10791 if (SINGLE_BYTE_CHAR_P (c))
10792 return (dp->contents[c]);
10794 SPLIT_CHAR (c, code[0], code[1], code[2]);
10795 if (code[1] < 32)
10796 code[1] = -1;
10797 else if (code[2] < 32)
10798 code[2] = -1;
10800 /* Here, the possible range of code[0] (== charset ID) is
10801 128..max_charset. Since the top level char table contains data
10802 for multibyte characters after 256th element, we must increment
10803 code[0] by 128 to get a correct index. */
10804 code[0] += 128;
10805 code[3] = -1; /* anchor */
10807 for (i = 0; code[i] >= 0; i++, dp = XCHAR_TABLE (val))
10809 val = dp->contents[code[i]];
10810 if (!SUB_CHAR_TABLE_P (val))
10811 return (NILP (val) ? dp->defalt : val);
10814 /* Here, val is a sub char table. We return the default value of
10815 it. */
10816 return (dp->defalt);
10821 /***********************************************************************
10822 Window Redisplay
10823 ***********************************************************************/
10825 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
10827 static void
10828 redisplay_windows (window)
10829 Lisp_Object window;
10831 while (!NILP (window))
10833 struct window *w = XWINDOW (window);
10835 if (!NILP (w->hchild))
10836 redisplay_windows (w->hchild);
10837 else if (!NILP (w->vchild))
10838 redisplay_windows (w->vchild);
10839 else
10841 displayed_buffer = XBUFFER (w->buffer);
10842 /* Use list_of_error, not Qerror, so that
10843 we catch only errors and don't run the debugger. */
10844 internal_condition_case_1 (redisplay_window_0, window,
10845 list_of_error,
10846 redisplay_window_error);
10849 window = w->next;
10853 static Lisp_Object
10854 redisplay_window_error ()
10856 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
10857 return Qnil;
10860 static Lisp_Object
10861 redisplay_window_0 (window)
10862 Lisp_Object window;
10864 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
10865 redisplay_window (window, 0);
10866 return Qnil;
10869 static Lisp_Object
10870 redisplay_window_1 (window)
10871 Lisp_Object window;
10873 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
10874 redisplay_window (window, 1);
10875 return Qnil;
10879 /* Increment GLYPH until it reaches END or CONDITION fails while
10880 adding (GLYPH)->pixel_width to X. */
10882 #define SKIP_GLYPHS(glyph, end, x, condition) \
10883 do \
10885 (x) += (glyph)->pixel_width; \
10886 ++(glyph); \
10888 while ((glyph) < (end) && (condition))
10891 /* Set cursor position of W. PT is assumed to be displayed in ROW.
10892 DELTA is the number of bytes by which positions recorded in ROW
10893 differ from current buffer positions. */
10895 void
10896 set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
10897 struct window *w;
10898 struct glyph_row *row;
10899 struct glyph_matrix *matrix;
10900 int delta, delta_bytes, dy, dvpos;
10902 struct glyph *glyph = row->glyphs[TEXT_AREA];
10903 struct glyph *end = glyph + row->used[TEXT_AREA];
10904 struct glyph *cursor = NULL;
10905 /* The first glyph that starts a sequence of glyphs from string. */
10906 struct glyph *string_start;
10907 /* The X coordinate of string_start. */
10908 int string_start_x;
10909 /* The last known character position. */
10910 int last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
10911 /* The last known character position before string_start. */
10912 int string_before_pos;
10913 int x = row->x;
10914 int cursor_x = x;
10915 int cursor_from_overlay_pos = 0;
10916 int pt_old = PT - delta;
10918 /* Skip over glyphs not having an object at the start of the row.
10919 These are special glyphs like truncation marks on terminal
10920 frames. */
10921 if (row->displays_text_p)
10922 while (glyph < end
10923 && INTEGERP (glyph->object)
10924 && glyph->charpos < 0)
10926 x += glyph->pixel_width;
10927 ++glyph;
10930 string_start = NULL;
10931 while (glyph < end
10932 && !INTEGERP (glyph->object)
10933 && (!BUFFERP (glyph->object)
10934 || (last_pos = glyph->charpos) < pt_old))
10936 if (! STRINGP (glyph->object))
10938 string_start = NULL;
10939 x += glyph->pixel_width;
10940 ++glyph;
10941 if (cursor_from_overlay_pos
10942 && last_pos > cursor_from_overlay_pos)
10944 cursor_from_overlay_pos = 0;
10945 cursor = 0;
10948 else
10950 string_before_pos = last_pos;
10951 string_start = glyph;
10952 string_start_x = x;
10953 /* Skip all glyphs from string. */
10956 int pos;
10957 if ((cursor == NULL || glyph > cursor)
10958 && !NILP (Fget_char_property (make_number ((glyph)->charpos),
10959 Qcursor, (glyph)->object))
10960 && (pos = string_buffer_position (w, glyph->object,
10961 string_before_pos),
10962 (pos == 0 /* From overlay */
10963 || pos == pt_old)))
10965 /* Estimate overlay buffer position from the buffer
10966 positions of the glyphs before and after the overlay.
10967 Add 1 to last_pos so that if point corresponds to the
10968 glyph right after the overlay, we still use a 'cursor'
10969 property found in that overlay. */
10970 cursor_from_overlay_pos = pos == 0 ? last_pos+1 : 0;
10971 cursor = glyph;
10972 cursor_x = x;
10974 x += glyph->pixel_width;
10975 ++glyph;
10977 while (glyph < end && STRINGP (glyph->object));
10981 if (cursor != NULL)
10983 glyph = cursor;
10984 x = cursor_x;
10986 else if (row->ends_in_ellipsis_p && glyph == end)
10988 /* Scan back over the ellipsis glyphs, decrementing positions. */
10989 while (glyph > row->glyphs[TEXT_AREA]
10990 && (glyph - 1)->charpos == last_pos)
10991 glyph--, x -= glyph->pixel_width;
10992 /* That loop always goes one position too far,
10993 including the glyph before the ellipsis.
10994 So scan forward over that one. */
10995 x += glyph->pixel_width;
10996 glyph++;
10998 else if (string_start
10999 && (glyph == end || !BUFFERP (glyph->object) || last_pos > pt_old))
11001 /* We may have skipped over point because the previous glyphs
11002 are from string. As there's no easy way to know the
11003 character position of the current glyph, find the correct
11004 glyph on point by scanning from string_start again. */
11005 Lisp_Object limit;
11006 Lisp_Object string;
11007 int pos;
11009 limit = make_number (pt_old + 1);
11010 end = glyph;
11011 glyph = string_start;
11012 x = string_start_x;
11013 string = glyph->object;
11014 pos = string_buffer_position (w, string, string_before_pos);
11015 /* If STRING is from overlay, LAST_POS == 0. We skip such glyphs
11016 because we always put cursor after overlay strings. */
11017 while (pos == 0 && glyph < end)
11019 string = glyph->object;
11020 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
11021 if (glyph < end)
11022 pos = string_buffer_position (w, glyph->object, string_before_pos);
11025 while (glyph < end)
11027 pos = XINT (Fnext_single_char_property_change
11028 (make_number (pos), Qdisplay, Qnil, limit));
11029 if (pos > pt_old)
11030 break;
11031 /* Skip glyphs from the same string. */
11032 string = glyph->object;
11033 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
11034 /* Skip glyphs from an overlay. */
11035 while (glyph < end
11036 && ! string_buffer_position (w, glyph->object, pos))
11038 string = glyph->object;
11039 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
11044 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
11045 w->cursor.x = x;
11046 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
11047 w->cursor.y = row->y + dy;
11049 if (w == XWINDOW (selected_window))
11051 if (!row->continued_p
11052 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
11053 && row->x == 0)
11055 this_line_buffer = XBUFFER (w->buffer);
11057 CHARPOS (this_line_start_pos)
11058 = MATRIX_ROW_START_CHARPOS (row) + delta;
11059 BYTEPOS (this_line_start_pos)
11060 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
11062 CHARPOS (this_line_end_pos)
11063 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
11064 BYTEPOS (this_line_end_pos)
11065 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
11067 this_line_y = w->cursor.y;
11068 this_line_pixel_height = row->height;
11069 this_line_vpos = w->cursor.vpos;
11070 this_line_start_x = row->x;
11072 else
11073 CHARPOS (this_line_start_pos) = 0;
11078 /* Run window scroll functions, if any, for WINDOW with new window
11079 start STARTP. Sets the window start of WINDOW to that position.
11081 We assume that the window's buffer is really current. */
11083 static INLINE struct text_pos
11084 run_window_scroll_functions (window, startp)
11085 Lisp_Object window;
11086 struct text_pos startp;
11088 struct window *w = XWINDOW (window);
11089 SET_MARKER_FROM_TEXT_POS (w->start, startp);
11091 if (current_buffer != XBUFFER (w->buffer))
11092 abort ();
11094 if (!NILP (Vwindow_scroll_functions))
11096 run_hook_with_args_2 (Qwindow_scroll_functions, window,
11097 make_number (CHARPOS (startp)));
11098 SET_TEXT_POS_FROM_MARKER (startp, w->start);
11099 /* In case the hook functions switch buffers. */
11100 if (current_buffer != XBUFFER (w->buffer))
11101 set_buffer_internal_1 (XBUFFER (w->buffer));
11104 return startp;
11108 /* Make sure the line containing the cursor is fully visible.
11109 A value of 1 means there is nothing to be done.
11110 (Either the line is fully visible, or it cannot be made so,
11111 or we cannot tell.)
11113 If FORCE_P is non-zero, return 0 even if partial visible cursor row
11114 is higher than window.
11116 A value of 0 means the caller should do scrolling
11117 as if point had gone off the screen. */
11119 static int
11120 cursor_row_fully_visible_p (w, force_p, current_matrix_p)
11121 struct window *w;
11122 int force_p;
11124 struct glyph_matrix *matrix;
11125 struct glyph_row *row;
11126 int window_height;
11128 if (!make_cursor_line_fully_visible_p)
11129 return 1;
11131 /* It's not always possible to find the cursor, e.g, when a window
11132 is full of overlay strings. Don't do anything in that case. */
11133 if (w->cursor.vpos < 0)
11134 return 1;
11136 matrix = current_matrix_p ? w->current_matrix : w->desired_matrix;
11137 row = MATRIX_ROW (matrix, w->cursor.vpos);
11139 /* If the cursor row is not partially visible, there's nothing to do. */
11140 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row))
11141 return 1;
11143 /* If the row the cursor is in is taller than the window's height,
11144 it's not clear what to do, so do nothing. */
11145 window_height = window_box_height (w);
11146 if (row->height >= window_height)
11148 if (!force_p || w->vscroll)
11149 return 1;
11151 return 0;
11153 #if 0
11154 /* This code used to try to scroll the window just enough to make
11155 the line visible. It returned 0 to say that the caller should
11156 allocate larger glyph matrices. */
11158 if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row))
11160 int dy = row->height - row->visible_height;
11161 w->vscroll = 0;
11162 w->cursor.y += dy;
11163 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
11165 else /* MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row)) */
11167 int dy = - (row->height - row->visible_height);
11168 w->vscroll = dy;
11169 w->cursor.y += dy;
11170 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
11173 /* When we change the cursor y-position of the selected window,
11174 change this_line_y as well so that the display optimization for
11175 the cursor line of the selected window in redisplay_internal uses
11176 the correct y-position. */
11177 if (w == XWINDOW (selected_window))
11178 this_line_y = w->cursor.y;
11180 /* If vscrolling requires a larger glyph matrix, arrange for a fresh
11181 redisplay with larger matrices. */
11182 if (matrix->nrows < required_matrix_height (w))
11184 fonts_changed_p = 1;
11185 return 0;
11188 return 1;
11189 #endif /* 0 */
11193 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
11194 non-zero means only WINDOW is redisplayed in redisplay_internal.
11195 TEMP_SCROLL_STEP has the same meaning as scroll_step, and is used
11196 in redisplay_window to bring a partially visible line into view in
11197 the case that only the cursor has moved.
11199 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
11200 last screen line's vertical height extends past the end of the screen.
11202 Value is
11204 1 if scrolling succeeded
11206 0 if scrolling didn't find point.
11208 -1 if new fonts have been loaded so that we must interrupt
11209 redisplay, adjust glyph matrices, and try again. */
11211 enum
11213 SCROLLING_SUCCESS,
11214 SCROLLING_FAILED,
11215 SCROLLING_NEED_LARGER_MATRICES
11218 static int
11219 try_scrolling (window, just_this_one_p, scroll_conservatively,
11220 scroll_step, temp_scroll_step, last_line_misfit)
11221 Lisp_Object window;
11222 int just_this_one_p;
11223 EMACS_INT scroll_conservatively, scroll_step;
11224 int temp_scroll_step;
11225 int last_line_misfit;
11227 struct window *w = XWINDOW (window);
11228 struct frame *f = XFRAME (w->frame);
11229 struct text_pos scroll_margin_pos;
11230 struct text_pos pos;
11231 struct text_pos startp;
11232 struct it it;
11233 Lisp_Object window_end;
11234 int this_scroll_margin;
11235 int dy = 0;
11236 int scroll_max;
11237 int rc;
11238 int amount_to_scroll = 0;
11239 Lisp_Object aggressive;
11240 int height;
11241 int extra_scroll_margin_lines = last_line_misfit ? 1 : 0;
11243 #if GLYPH_DEBUG
11244 debug_method_add (w, "try_scrolling");
11245 #endif
11247 SET_TEXT_POS_FROM_MARKER (startp, w->start);
11249 /* Compute scroll margin height in pixels. We scroll when point is
11250 within this distance from the top or bottom of the window. */
11251 if (scroll_margin > 0)
11253 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
11254 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
11256 else
11257 this_scroll_margin = 0;
11259 /* Force scroll_conservatively to have a reasonable value so it doesn't
11260 cause an overflow while computing how much to scroll. */
11261 if (scroll_conservatively)
11262 scroll_conservatively = min (scroll_conservatively,
11263 MOST_POSITIVE_FIXNUM / FRAME_LINE_HEIGHT (f));
11265 /* Compute how much we should try to scroll maximally to bring point
11266 into view. */
11267 if (scroll_step || scroll_conservatively || temp_scroll_step)
11268 scroll_max = max (scroll_step,
11269 max (scroll_conservatively, temp_scroll_step));
11270 else if (NUMBERP (current_buffer->scroll_down_aggressively)
11271 || NUMBERP (current_buffer->scroll_up_aggressively))
11272 /* We're trying to scroll because of aggressive scrolling
11273 but no scroll_step is set. Choose an arbitrary one. Maybe
11274 there should be a variable for this. */
11275 scroll_max = 10;
11276 else
11277 scroll_max = 0;
11278 scroll_max *= FRAME_LINE_HEIGHT (f);
11280 /* Decide whether we have to scroll down. Start at the window end
11281 and move this_scroll_margin up to find the position of the scroll
11282 margin. */
11283 window_end = Fwindow_end (window, Qt);
11285 too_near_end:
11287 CHARPOS (scroll_margin_pos) = XINT (window_end);
11288 BYTEPOS (scroll_margin_pos) = CHAR_TO_BYTE (CHARPOS (scroll_margin_pos));
11290 if (this_scroll_margin || extra_scroll_margin_lines)
11292 start_display (&it, w, scroll_margin_pos);
11293 if (this_scroll_margin)
11294 move_it_vertically_backward (&it, this_scroll_margin);
11295 if (extra_scroll_margin_lines)
11296 move_it_by_lines (&it, - extra_scroll_margin_lines, 0);
11297 scroll_margin_pos = it.current.pos;
11300 if (PT >= CHARPOS (scroll_margin_pos))
11302 int y0;
11304 /* Point is in the scroll margin at the bottom of the window, or
11305 below. Compute a new window start that makes point visible. */
11307 /* Compute the distance from the scroll margin to PT.
11308 Give up if the distance is greater than scroll_max. */
11309 start_display (&it, w, scroll_margin_pos);
11310 y0 = it.current_y;
11311 move_it_to (&it, PT, 0, it.last_visible_y, -1,
11312 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
11314 /* To make point visible, we have to move the window start
11315 down so that the line the cursor is in is visible, which
11316 means we have to add in the height of the cursor line. */
11317 dy = line_bottom_y (&it) - y0;
11319 if (dy > scroll_max)
11320 return SCROLLING_FAILED;
11322 /* Move the window start down. If scrolling conservatively,
11323 move it just enough down to make point visible. If
11324 scroll_step is set, move it down by scroll_step. */
11325 start_display (&it, w, startp);
11327 if (scroll_conservatively)
11328 /* Set AMOUNT_TO_SCROLL to at least one line,
11329 and at most scroll_conservatively lines. */
11330 amount_to_scroll
11331 = min (max (dy, FRAME_LINE_HEIGHT (f)),
11332 FRAME_LINE_HEIGHT (f) * scroll_conservatively);
11333 else if (scroll_step || temp_scroll_step)
11334 amount_to_scroll = scroll_max;
11335 else
11337 aggressive = current_buffer->scroll_up_aggressively;
11338 height = WINDOW_BOX_TEXT_HEIGHT (w);
11339 if (NUMBERP (aggressive))
11341 double float_amount = XFLOATINT (aggressive) * height;
11342 amount_to_scroll = float_amount;
11343 if (amount_to_scroll == 0 && float_amount > 0)
11344 amount_to_scroll = 1;
11348 if (amount_to_scroll <= 0)
11349 return SCROLLING_FAILED;
11351 /* If moving by amount_to_scroll leaves STARTP unchanged,
11352 move it down one screen line. */
11354 move_it_vertically (&it, amount_to_scroll);
11355 if (CHARPOS (it.current.pos) == CHARPOS (startp))
11356 move_it_by_lines (&it, 1, 1);
11357 startp = it.current.pos;
11359 else
11361 /* See if point is inside the scroll margin at the top of the
11362 window. */
11363 scroll_margin_pos = startp;
11364 if (this_scroll_margin)
11366 start_display (&it, w, startp);
11367 move_it_vertically (&it, this_scroll_margin);
11368 scroll_margin_pos = it.current.pos;
11371 if (PT < CHARPOS (scroll_margin_pos))
11373 /* Point is in the scroll margin at the top of the window or
11374 above what is displayed in the window. */
11375 int y0;
11377 /* Compute the vertical distance from PT to the scroll
11378 margin position. Give up if distance is greater than
11379 scroll_max. */
11380 SET_TEXT_POS (pos, PT, PT_BYTE);
11381 start_display (&it, w, pos);
11382 y0 = it.current_y;
11383 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
11384 it.last_visible_y, -1,
11385 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
11386 dy = it.current_y - y0;
11387 if (dy > scroll_max)
11388 return SCROLLING_FAILED;
11390 /* Compute new window start. */
11391 start_display (&it, w, startp);
11393 if (scroll_conservatively)
11394 amount_to_scroll
11395 = max (dy, FRAME_LINE_HEIGHT (f) * max (scroll_step, temp_scroll_step));
11396 else if (scroll_step || temp_scroll_step)
11397 amount_to_scroll = scroll_max;
11398 else
11400 aggressive = current_buffer->scroll_down_aggressively;
11401 height = WINDOW_BOX_TEXT_HEIGHT (w);
11402 if (NUMBERP (aggressive))
11404 double float_amount = XFLOATINT (aggressive) * height;
11405 amount_to_scroll = float_amount;
11406 if (amount_to_scroll == 0 && float_amount > 0)
11407 amount_to_scroll = 1;
11411 if (amount_to_scroll <= 0)
11412 return SCROLLING_FAILED;
11414 move_it_vertically_backward (&it, amount_to_scroll);
11415 startp = it.current.pos;
11419 /* Run window scroll functions. */
11420 startp = run_window_scroll_functions (window, startp);
11422 /* Display the window. Give up if new fonts are loaded, or if point
11423 doesn't appear. */
11424 if (!try_window (window, startp))
11425 rc = SCROLLING_NEED_LARGER_MATRICES;
11426 else if (w->cursor.vpos < 0)
11428 clear_glyph_matrix (w->desired_matrix);
11429 rc = SCROLLING_FAILED;
11431 else
11433 /* Maybe forget recorded base line for line number display. */
11434 if (!just_this_one_p
11435 || current_buffer->clip_changed
11436 || BEG_UNCHANGED < CHARPOS (startp))
11437 w->base_line_number = Qnil;
11439 /* If cursor ends up on a partially visible line,
11440 treat that as being off the bottom of the screen. */
11441 if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1, 0))
11443 clear_glyph_matrix (w->desired_matrix);
11444 ++extra_scroll_margin_lines;
11445 goto too_near_end;
11447 rc = SCROLLING_SUCCESS;
11450 return rc;
11454 /* Compute a suitable window start for window W if display of W starts
11455 on a continuation line. Value is non-zero if a new window start
11456 was computed.
11458 The new window start will be computed, based on W's width, starting
11459 from the start of the continued line. It is the start of the
11460 screen line with the minimum distance from the old start W->start. */
11462 static int
11463 compute_window_start_on_continuation_line (w)
11464 struct window *w;
11466 struct text_pos pos, start_pos;
11467 int window_start_changed_p = 0;
11469 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
11471 /* If window start is on a continuation line... Window start may be
11472 < BEGV in case there's invisible text at the start of the
11473 buffer (M-x rmail, for example). */
11474 if (CHARPOS (start_pos) > BEGV
11475 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
11477 struct it it;
11478 struct glyph_row *row;
11480 /* Handle the case that the window start is out of range. */
11481 if (CHARPOS (start_pos) < BEGV)
11482 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
11483 else if (CHARPOS (start_pos) > ZV)
11484 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
11486 /* Find the start of the continued line. This should be fast
11487 because scan_buffer is fast (newline cache). */
11488 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
11489 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
11490 row, DEFAULT_FACE_ID);
11491 reseat_at_previous_visible_line_start (&it);
11493 /* If the line start is "too far" away from the window start,
11494 say it takes too much time to compute a new window start. */
11495 if (CHARPOS (start_pos) - IT_CHARPOS (it)
11496 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
11498 int min_distance, distance;
11500 /* Move forward by display lines to find the new window
11501 start. If window width was enlarged, the new start can
11502 be expected to be > the old start. If window width was
11503 decreased, the new window start will be < the old start.
11504 So, we're looking for the display line start with the
11505 minimum distance from the old window start. */
11506 pos = it.current.pos;
11507 min_distance = INFINITY;
11508 while ((distance = abs (CHARPOS (start_pos) - IT_CHARPOS (it))),
11509 distance < min_distance)
11511 min_distance = distance;
11512 pos = it.current.pos;
11513 move_it_by_lines (&it, 1, 0);
11516 /* Set the window start there. */
11517 SET_MARKER_FROM_TEXT_POS (w->start, pos);
11518 window_start_changed_p = 1;
11522 return window_start_changed_p;
11526 /* Try cursor movement in case text has not changed in window WINDOW,
11527 with window start STARTP. Value is
11529 CURSOR_MOVEMENT_SUCCESS if successful
11531 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
11533 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
11534 display. *SCROLL_STEP is set to 1, under certain circumstances, if
11535 we want to scroll as if scroll-step were set to 1. See the code.
11537 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
11538 which case we have to abort this redisplay, and adjust matrices
11539 first. */
11541 enum
11543 CURSOR_MOVEMENT_SUCCESS,
11544 CURSOR_MOVEMENT_CANNOT_BE_USED,
11545 CURSOR_MOVEMENT_MUST_SCROLL,
11546 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
11549 static int
11550 try_cursor_movement (window, startp, scroll_step)
11551 Lisp_Object window;
11552 struct text_pos startp;
11553 int *scroll_step;
11555 struct window *w = XWINDOW (window);
11556 struct frame *f = XFRAME (w->frame);
11557 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
11559 #if GLYPH_DEBUG
11560 if (inhibit_try_cursor_movement)
11561 return rc;
11562 #endif
11564 /* Handle case where text has not changed, only point, and it has
11565 not moved off the frame. */
11566 if (/* Point may be in this window. */
11567 PT >= CHARPOS (startp)
11568 /* Selective display hasn't changed. */
11569 && !current_buffer->clip_changed
11570 /* Function force-mode-line-update is used to force a thorough
11571 redisplay. It sets either windows_or_buffers_changed or
11572 update_mode_lines. So don't take a shortcut here for these
11573 cases. */
11574 && !update_mode_lines
11575 && !windows_or_buffers_changed
11576 && !cursor_type_changed
11577 /* Can't use this case if highlighting a region. When a
11578 region exists, cursor movement has to do more than just
11579 set the cursor. */
11580 && !(!NILP (Vtransient_mark_mode)
11581 && !NILP (current_buffer->mark_active))
11582 && NILP (w->region_showing)
11583 && NILP (Vshow_trailing_whitespace)
11584 /* Right after splitting windows, last_point may be nil. */
11585 && INTEGERP (w->last_point)
11586 /* This code is not used for mini-buffer for the sake of the case
11587 of redisplaying to replace an echo area message; since in
11588 that case the mini-buffer contents per se are usually
11589 unchanged. This code is of no real use in the mini-buffer
11590 since the handling of this_line_start_pos, etc., in redisplay
11591 handles the same cases. */
11592 && !EQ (window, minibuf_window)
11593 /* When splitting windows or for new windows, it happens that
11594 redisplay is called with a nil window_end_vpos or one being
11595 larger than the window. This should really be fixed in
11596 window.c. I don't have this on my list, now, so we do
11597 approximately the same as the old redisplay code. --gerd. */
11598 && INTEGERP (w->window_end_vpos)
11599 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
11600 && (FRAME_WINDOW_P (f)
11601 || !overlay_arrow_in_current_buffer_p ()))
11603 int this_scroll_margin, top_scroll_margin;
11604 struct glyph_row *row = NULL;
11606 #if GLYPH_DEBUG
11607 debug_method_add (w, "cursor movement");
11608 #endif
11610 /* Scroll if point within this distance from the top or bottom
11611 of the window. This is a pixel value. */
11612 this_scroll_margin = max (0, scroll_margin);
11613 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
11614 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
11616 top_scroll_margin = this_scroll_margin;
11617 if (WINDOW_WANTS_HEADER_LINE_P (w))
11618 top_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w);
11620 /* Start with the row the cursor was displayed during the last
11621 not paused redisplay. Give up if that row is not valid. */
11622 if (w->last_cursor.vpos < 0
11623 || w->last_cursor.vpos >= w->current_matrix->nrows)
11624 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11625 else
11627 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
11628 if (row->mode_line_p)
11629 ++row;
11630 if (!row->enabled_p)
11631 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11634 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
11636 int scroll_p = 0;
11637 int last_y = window_text_bottom_y (w) - this_scroll_margin;
11639 if (PT > XFASTINT (w->last_point))
11641 /* Point has moved forward. */
11642 while (MATRIX_ROW_END_CHARPOS (row) < PT
11643 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
11645 xassert (row->enabled_p);
11646 ++row;
11649 /* The end position of a row equals the start position
11650 of the next row. If PT is there, we would rather
11651 display it in the next line. */
11652 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
11653 && MATRIX_ROW_END_CHARPOS (row) == PT
11654 && !cursor_row_p (w, row))
11655 ++row;
11657 /* If within the scroll margin, scroll. Note that
11658 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
11659 the next line would be drawn, and that
11660 this_scroll_margin can be zero. */
11661 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
11662 || PT > MATRIX_ROW_END_CHARPOS (row)
11663 /* Line is completely visible last line in window
11664 and PT is to be set in the next line. */
11665 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
11666 && PT == MATRIX_ROW_END_CHARPOS (row)
11667 && !row->ends_at_zv_p
11668 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
11669 scroll_p = 1;
11671 else if (PT < XFASTINT (w->last_point))
11673 /* Cursor has to be moved backward. Note that PT >=
11674 CHARPOS (startp) because of the outer if-statement. */
11675 while (!row->mode_line_p
11676 && (MATRIX_ROW_START_CHARPOS (row) > PT
11677 || (MATRIX_ROW_START_CHARPOS (row) == PT
11678 && MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)))
11679 && (row->y > top_scroll_margin
11680 || CHARPOS (startp) == BEGV))
11682 xassert (row->enabled_p);
11683 --row;
11686 /* Consider the following case: Window starts at BEGV,
11687 there is invisible, intangible text at BEGV, so that
11688 display starts at some point START > BEGV. It can
11689 happen that we are called with PT somewhere between
11690 BEGV and START. Try to handle that case. */
11691 if (row < w->current_matrix->rows
11692 || row->mode_line_p)
11694 row = w->current_matrix->rows;
11695 if (row->mode_line_p)
11696 ++row;
11699 /* Due to newlines in overlay strings, we may have to
11700 skip forward over overlay strings. */
11701 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
11702 && MATRIX_ROW_END_CHARPOS (row) == PT
11703 && !cursor_row_p (w, row))
11704 ++row;
11706 /* If within the scroll margin, scroll. */
11707 if (row->y < top_scroll_margin
11708 && CHARPOS (startp) != BEGV)
11709 scroll_p = 1;
11711 else
11713 /* Cursor did not move. So don't scroll even if cursor line
11714 is partially visible, as it was so before. */
11715 rc = CURSOR_MOVEMENT_SUCCESS;
11718 if (PT < MATRIX_ROW_START_CHARPOS (row)
11719 || PT > MATRIX_ROW_END_CHARPOS (row))
11721 /* if PT is not in the glyph row, give up. */
11722 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11724 else if (rc != CURSOR_MOVEMENT_SUCCESS
11725 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
11726 && make_cursor_line_fully_visible_p)
11728 if (PT == MATRIX_ROW_END_CHARPOS (row)
11729 && !row->ends_at_zv_p
11730 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
11731 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11732 else if (row->height > window_box_height (w))
11734 /* If we end up in a partially visible line, let's
11735 make it fully visible, except when it's taller
11736 than the window, in which case we can't do much
11737 about it. */
11738 *scroll_step = 1;
11739 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11741 else
11743 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11744 if (!cursor_row_fully_visible_p (w, 0, 1))
11745 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11746 else
11747 rc = CURSOR_MOVEMENT_SUCCESS;
11750 else if (scroll_p)
11751 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11752 else
11754 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11755 rc = CURSOR_MOVEMENT_SUCCESS;
11760 return rc;
11763 void
11764 set_vertical_scroll_bar (w)
11765 struct window *w;
11767 int start, end, whole;
11769 /* Calculate the start and end positions for the current window.
11770 At some point, it would be nice to choose between scrollbars
11771 which reflect the whole buffer size, with special markers
11772 indicating narrowing, and scrollbars which reflect only the
11773 visible region.
11775 Note that mini-buffers sometimes aren't displaying any text. */
11776 if (!MINI_WINDOW_P (w)
11777 || (w == XWINDOW (minibuf_window)
11778 && NILP (echo_area_buffer[0])))
11780 struct buffer *buf = XBUFFER (w->buffer);
11781 whole = BUF_ZV (buf) - BUF_BEGV (buf);
11782 start = marker_position (w->start) - BUF_BEGV (buf);
11783 /* I don't think this is guaranteed to be right. For the
11784 moment, we'll pretend it is. */
11785 end = BUF_Z (buf) - XFASTINT (w->window_end_pos) - BUF_BEGV (buf);
11787 if (end < start)
11788 end = start;
11789 if (whole < (end - start))
11790 whole = end - start;
11792 else
11793 start = end = whole = 0;
11795 /* Indicate what this scroll bar ought to be displaying now. */
11796 set_vertical_scroll_bar_hook (w, end - start, whole, start);
11800 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
11801 selected_window is redisplayed.
11803 We can return without actually redisplaying the window if
11804 fonts_changed_p is nonzero. In that case, redisplay_internal will
11805 retry. */
11807 static void
11808 redisplay_window (window, just_this_one_p)
11809 Lisp_Object window;
11810 int just_this_one_p;
11812 struct window *w = XWINDOW (window);
11813 struct frame *f = XFRAME (w->frame);
11814 struct buffer *buffer = XBUFFER (w->buffer);
11815 struct buffer *old = current_buffer;
11816 struct text_pos lpoint, opoint, startp;
11817 int update_mode_line;
11818 int tem;
11819 struct it it;
11820 /* Record it now because it's overwritten. */
11821 int current_matrix_up_to_date_p = 0;
11822 int used_current_matrix_p = 0;
11823 /* This is less strict than current_matrix_up_to_date_p.
11824 It indictes that the buffer contents and narrowing are unchanged. */
11825 int buffer_unchanged_p = 0;
11826 int temp_scroll_step = 0;
11827 int count = SPECPDL_INDEX ();
11828 int rc;
11829 int centering_position = -1;
11830 int last_line_misfit = 0;
11832 SET_TEXT_POS (lpoint, PT, PT_BYTE);
11833 opoint = lpoint;
11835 /* W must be a leaf window here. */
11836 xassert (!NILP (w->buffer));
11837 #if GLYPH_DEBUG
11838 *w->desired_matrix->method = 0;
11839 #endif
11841 specbind (Qinhibit_point_motion_hooks, Qt);
11843 reconsider_clip_changes (w, buffer);
11845 /* Has the mode line to be updated? */
11846 update_mode_line = (!NILP (w->update_mode_line)
11847 || update_mode_lines
11848 || buffer->clip_changed
11849 || buffer->prevent_redisplay_optimizations_p);
11851 if (MINI_WINDOW_P (w))
11853 if (w == XWINDOW (echo_area_window)
11854 && !NILP (echo_area_buffer[0]))
11856 if (update_mode_line)
11857 /* We may have to update a tty frame's menu bar or a
11858 tool-bar. Example `M-x C-h C-h C-g'. */
11859 goto finish_menu_bars;
11860 else
11861 /* We've already displayed the echo area glyphs in this window. */
11862 goto finish_scroll_bars;
11864 else if ((w != XWINDOW (minibuf_window)
11865 || minibuf_level == 0)
11866 /* When buffer is nonempty, redisplay window normally. */
11867 && BUF_Z (XBUFFER (w->buffer)) == BUF_BEG (XBUFFER (w->buffer))
11868 /* Quail displays non-mini buffers in minibuffer window.
11869 In that case, redisplay the window normally. */
11870 && !NILP (Fmemq (w->buffer, Vminibuffer_list)))
11872 /* W is a mini-buffer window, but it's not active, so clear
11873 it. */
11874 int yb = window_text_bottom_y (w);
11875 struct glyph_row *row;
11876 int y;
11878 for (y = 0, row = w->desired_matrix->rows;
11879 y < yb;
11880 y += row->height, ++row)
11881 blank_row (w, row, y);
11882 goto finish_scroll_bars;
11885 clear_glyph_matrix (w->desired_matrix);
11888 /* Otherwise set up data on this window; select its buffer and point
11889 value. */
11890 /* Really select the buffer, for the sake of buffer-local
11891 variables. */
11892 set_buffer_internal_1 (XBUFFER (w->buffer));
11893 SET_TEXT_POS (opoint, PT, PT_BYTE);
11895 current_matrix_up_to_date_p
11896 = (!NILP (w->window_end_valid)
11897 && !current_buffer->clip_changed
11898 && !current_buffer->prevent_redisplay_optimizations_p
11899 && XFASTINT (w->last_modified) >= MODIFF
11900 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
11902 buffer_unchanged_p
11903 = (!NILP (w->window_end_valid)
11904 && !current_buffer->clip_changed
11905 && XFASTINT (w->last_modified) >= MODIFF
11906 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
11908 /* When windows_or_buffers_changed is non-zero, we can't rely on
11909 the window end being valid, so set it to nil there. */
11910 if (windows_or_buffers_changed)
11912 /* If window starts on a continuation line, maybe adjust the
11913 window start in case the window's width changed. */
11914 if (XMARKER (w->start)->buffer == current_buffer)
11915 compute_window_start_on_continuation_line (w);
11917 w->window_end_valid = Qnil;
11920 /* Some sanity checks. */
11921 CHECK_WINDOW_END (w);
11922 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
11923 abort ();
11924 if (BYTEPOS (opoint) < CHARPOS (opoint))
11925 abort ();
11927 /* If %c is in mode line, update it if needed. */
11928 if (!NILP (w->column_number_displayed)
11929 /* This alternative quickly identifies a common case
11930 where no change is needed. */
11931 && !(PT == XFASTINT (w->last_point)
11932 && XFASTINT (w->last_modified) >= MODIFF
11933 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
11934 && (XFASTINT (w->column_number_displayed)
11935 != (int) current_column ())) /* iftc */
11936 update_mode_line = 1;
11938 /* Count number of windows showing the selected buffer. An indirect
11939 buffer counts as its base buffer. */
11940 if (!just_this_one_p)
11942 struct buffer *current_base, *window_base;
11943 current_base = current_buffer;
11944 window_base = XBUFFER (XWINDOW (selected_window)->buffer);
11945 if (current_base->base_buffer)
11946 current_base = current_base->base_buffer;
11947 if (window_base->base_buffer)
11948 window_base = window_base->base_buffer;
11949 if (current_base == window_base)
11950 buffer_shared++;
11953 /* Point refers normally to the selected window. For any other
11954 window, set up appropriate value. */
11955 if (!EQ (window, selected_window))
11957 int new_pt = XMARKER (w->pointm)->charpos;
11958 int new_pt_byte = marker_byte_position (w->pointm);
11959 if (new_pt < BEGV)
11961 new_pt = BEGV;
11962 new_pt_byte = BEGV_BYTE;
11963 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
11965 else if (new_pt > (ZV - 1))
11967 new_pt = ZV;
11968 new_pt_byte = ZV_BYTE;
11969 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
11972 /* We don't use SET_PT so that the point-motion hooks don't run. */
11973 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
11976 /* If any of the character widths specified in the display table
11977 have changed, invalidate the width run cache. It's true that
11978 this may be a bit late to catch such changes, but the rest of
11979 redisplay goes (non-fatally) haywire when the display table is
11980 changed, so why should we worry about doing any better? */
11981 if (current_buffer->width_run_cache)
11983 struct Lisp_Char_Table *disptab = buffer_display_table ();
11985 if (! disptab_matches_widthtab (disptab,
11986 XVECTOR (current_buffer->width_table)))
11988 invalidate_region_cache (current_buffer,
11989 current_buffer->width_run_cache,
11990 BEG, Z);
11991 recompute_width_table (current_buffer, disptab);
11995 /* If window-start is screwed up, choose a new one. */
11996 if (XMARKER (w->start)->buffer != current_buffer)
11997 goto recenter;
11999 SET_TEXT_POS_FROM_MARKER (startp, w->start);
12001 /* If someone specified a new starting point but did not insist,
12002 check whether it can be used. */
12003 if (!NILP (w->optional_new_start)
12004 && CHARPOS (startp) >= BEGV
12005 && CHARPOS (startp) <= ZV)
12007 w->optional_new_start = Qnil;
12008 start_display (&it, w, startp);
12009 move_it_to (&it, PT, 0, it.last_visible_y, -1,
12010 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
12011 if (IT_CHARPOS (it) == PT)
12012 w->force_start = Qt;
12013 /* IT may overshoot PT if text at PT is invisible. */
12014 else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT)
12015 w->force_start = Qt;
12020 /* Handle case where place to start displaying has been specified,
12021 unless the specified location is outside the accessible range. */
12022 if (!NILP (w->force_start)
12023 || w->frozen_window_start_p)
12025 /* We set this later on if we have to adjust point. */
12026 int new_vpos = -1;
12028 w->force_start = Qnil;
12029 w->vscroll = 0;
12030 w->window_end_valid = Qnil;
12032 /* Forget any recorded base line for line number display. */
12033 if (!buffer_unchanged_p)
12034 w->base_line_number = Qnil;
12036 /* Redisplay the mode line. Select the buffer properly for that.
12037 Also, run the hook window-scroll-functions
12038 because we have scrolled. */
12039 /* Note, we do this after clearing force_start because
12040 if there's an error, it is better to forget about force_start
12041 than to get into an infinite loop calling the hook functions
12042 and having them get more errors. */
12043 if (!update_mode_line
12044 || ! NILP (Vwindow_scroll_functions))
12046 update_mode_line = 1;
12047 w->update_mode_line = Qt;
12048 startp = run_window_scroll_functions (window, startp);
12051 w->last_modified = make_number (0);
12052 w->last_overlay_modified = make_number (0);
12053 if (CHARPOS (startp) < BEGV)
12054 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
12055 else if (CHARPOS (startp) > ZV)
12056 SET_TEXT_POS (startp, ZV, ZV_BYTE);
12058 /* Redisplay, then check if cursor has been set during the
12059 redisplay. Give up if new fonts were loaded. */
12060 if (!try_window (window, startp))
12062 w->force_start = Qt;
12063 clear_glyph_matrix (w->desired_matrix);
12064 goto need_larger_matrices;
12067 if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
12069 /* If point does not appear, try to move point so it does
12070 appear. The desired matrix has been built above, so we
12071 can use it here. */
12072 new_vpos = window_box_height (w) / 2;
12075 if (!cursor_row_fully_visible_p (w, 0, 0))
12077 /* Point does appear, but on a line partly visible at end of window.
12078 Move it back to a fully-visible line. */
12079 new_vpos = window_box_height (w);
12082 /* If we need to move point for either of the above reasons,
12083 now actually do it. */
12084 if (new_vpos >= 0)
12086 struct glyph_row *row;
12088 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
12089 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
12090 ++row;
12092 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
12093 MATRIX_ROW_START_BYTEPOS (row));
12095 if (w != XWINDOW (selected_window))
12096 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
12097 else if (current_buffer == old)
12098 SET_TEXT_POS (lpoint, PT, PT_BYTE);
12100 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
12102 /* If we are highlighting the region, then we just changed
12103 the region, so redisplay to show it. */
12104 if (!NILP (Vtransient_mark_mode)
12105 && !NILP (current_buffer->mark_active))
12107 clear_glyph_matrix (w->desired_matrix);
12108 if (!try_window (window, startp))
12109 goto need_larger_matrices;
12113 #if GLYPH_DEBUG
12114 debug_method_add (w, "forced window start");
12115 #endif
12116 goto done;
12119 /* Handle case where text has not changed, only point, and it has
12120 not moved off the frame, and we are not retrying after hscroll.
12121 (current_matrix_up_to_date_p is nonzero when retrying.) */
12122 if (current_matrix_up_to_date_p
12123 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
12124 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
12126 switch (rc)
12128 case CURSOR_MOVEMENT_SUCCESS:
12129 used_current_matrix_p = 1;
12130 goto done;
12132 #if 0 /* try_cursor_movement never returns this value. */
12133 case CURSOR_MOVEMENT_NEED_LARGER_MATRICES:
12134 goto need_larger_matrices;
12135 #endif
12137 case CURSOR_MOVEMENT_MUST_SCROLL:
12138 goto try_to_scroll;
12140 default:
12141 abort ();
12144 /* If current starting point was originally the beginning of a line
12145 but no longer is, find a new starting point. */
12146 else if (!NILP (w->start_at_line_beg)
12147 && !(CHARPOS (startp) <= BEGV
12148 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
12150 #if GLYPH_DEBUG
12151 debug_method_add (w, "recenter 1");
12152 #endif
12153 goto recenter;
12156 /* Try scrolling with try_window_id. Value is > 0 if update has
12157 been done, it is -1 if we know that the same window start will
12158 not work. It is 0 if unsuccessful for some other reason. */
12159 else if ((tem = try_window_id (w)) != 0)
12161 #if GLYPH_DEBUG
12162 debug_method_add (w, "try_window_id %d", tem);
12163 #endif
12165 if (fonts_changed_p)
12166 goto need_larger_matrices;
12167 if (tem > 0)
12168 goto done;
12170 /* Otherwise try_window_id has returned -1 which means that we
12171 don't want the alternative below this comment to execute. */
12173 else if (CHARPOS (startp) >= BEGV
12174 && CHARPOS (startp) <= ZV
12175 && PT >= CHARPOS (startp)
12176 && (CHARPOS (startp) < ZV
12177 /* Avoid starting at end of buffer. */
12178 || CHARPOS (startp) == BEGV
12179 || (XFASTINT (w->last_modified) >= MODIFF
12180 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)))
12182 #if GLYPH_DEBUG
12183 debug_method_add (w, "same window start");
12184 #endif
12186 /* Try to redisplay starting at same place as before.
12187 If point has not moved off frame, accept the results. */
12188 if (!current_matrix_up_to_date_p
12189 /* Don't use try_window_reusing_current_matrix in this case
12190 because a window scroll function can have changed the
12191 buffer. */
12192 || !NILP (Vwindow_scroll_functions)
12193 || MINI_WINDOW_P (w)
12194 || !(used_current_matrix_p
12195 = try_window_reusing_current_matrix (w)))
12197 IF_DEBUG (debug_method_add (w, "1"));
12198 try_window (window, startp);
12201 if (fonts_changed_p)
12202 goto need_larger_matrices;
12204 if (w->cursor.vpos >= 0)
12206 if (!just_this_one_p
12207 || current_buffer->clip_changed
12208 || BEG_UNCHANGED < CHARPOS (startp))
12209 /* Forget any recorded base line for line number display. */
12210 w->base_line_number = Qnil;
12212 if (!cursor_row_fully_visible_p (w, 1, 0))
12214 clear_glyph_matrix (w->desired_matrix);
12215 last_line_misfit = 1;
12217 /* Drop through and scroll. */
12218 else
12219 goto done;
12221 else
12222 clear_glyph_matrix (w->desired_matrix);
12225 try_to_scroll:
12227 w->last_modified = make_number (0);
12228 w->last_overlay_modified = make_number (0);
12230 /* Redisplay the mode line. Select the buffer properly for that. */
12231 if (!update_mode_line)
12233 update_mode_line = 1;
12234 w->update_mode_line = Qt;
12237 /* Try to scroll by specified few lines. */
12238 if ((scroll_conservatively
12239 || scroll_step
12240 || temp_scroll_step
12241 || NUMBERP (current_buffer->scroll_up_aggressively)
12242 || NUMBERP (current_buffer->scroll_down_aggressively))
12243 && !current_buffer->clip_changed
12244 && CHARPOS (startp) >= BEGV
12245 && CHARPOS (startp) <= ZV)
12247 /* The function returns -1 if new fonts were loaded, 1 if
12248 successful, 0 if not successful. */
12249 int rc = try_scrolling (window, just_this_one_p,
12250 scroll_conservatively,
12251 scroll_step,
12252 temp_scroll_step, last_line_misfit);
12253 switch (rc)
12255 case SCROLLING_SUCCESS:
12256 goto done;
12258 case SCROLLING_NEED_LARGER_MATRICES:
12259 goto need_larger_matrices;
12261 case SCROLLING_FAILED:
12262 break;
12264 default:
12265 abort ();
12269 /* Finally, just choose place to start which centers point */
12271 recenter:
12272 if (centering_position < 0)
12273 centering_position = window_box_height (w) / 2;
12275 #if GLYPH_DEBUG
12276 debug_method_add (w, "recenter");
12277 #endif
12279 /* w->vscroll = 0; */
12281 /* Forget any previously recorded base line for line number display. */
12282 if (!buffer_unchanged_p)
12283 w->base_line_number = Qnil;
12285 /* Move backward half the height of the window. */
12286 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
12287 it.current_y = it.last_visible_y;
12288 move_it_vertically_backward (&it, centering_position);
12289 xassert (IT_CHARPOS (it) >= BEGV);
12291 /* The function move_it_vertically_backward may move over more
12292 than the specified y-distance. If it->w is small, e.g. a
12293 mini-buffer window, we may end up in front of the window's
12294 display area. Start displaying at the start of the line
12295 containing PT in this case. */
12296 if (it.current_y <= 0)
12298 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
12299 move_it_vertically_backward (&it, 0);
12300 #if 0
12301 /* I think this assert is bogus if buffer contains
12302 invisible text or images. KFS. */
12303 xassert (IT_CHARPOS (it) <= PT);
12304 #endif
12305 it.current_y = 0;
12308 it.current_x = it.hpos = 0;
12310 /* Set startp here explicitly in case that helps avoid an infinite loop
12311 in case the window-scroll-functions functions get errors. */
12312 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
12314 /* Run scroll hooks. */
12315 startp = run_window_scroll_functions (window, it.current.pos);
12317 /* Redisplay the window. */
12318 if (!current_matrix_up_to_date_p
12319 || windows_or_buffers_changed
12320 || cursor_type_changed
12321 /* Don't use try_window_reusing_current_matrix in this case
12322 because it can have changed the buffer. */
12323 || !NILP (Vwindow_scroll_functions)
12324 || !just_this_one_p
12325 || MINI_WINDOW_P (w)
12326 || !(used_current_matrix_p
12327 = try_window_reusing_current_matrix (w)))
12328 try_window (window, startp);
12330 /* If new fonts have been loaded (due to fontsets), give up. We
12331 have to start a new redisplay since we need to re-adjust glyph
12332 matrices. */
12333 if (fonts_changed_p)
12334 goto need_larger_matrices;
12336 /* If cursor did not appear assume that the middle of the window is
12337 in the first line of the window. Do it again with the next line.
12338 (Imagine a window of height 100, displaying two lines of height
12339 60. Moving back 50 from it->last_visible_y will end in the first
12340 line.) */
12341 if (w->cursor.vpos < 0)
12343 if (!NILP (w->window_end_valid)
12344 && PT >= Z - XFASTINT (w->window_end_pos))
12346 clear_glyph_matrix (w->desired_matrix);
12347 move_it_by_lines (&it, 1, 0);
12348 try_window (window, it.current.pos);
12350 else if (PT < IT_CHARPOS (it))
12352 clear_glyph_matrix (w->desired_matrix);
12353 move_it_by_lines (&it, -1, 0);
12354 try_window (window, it.current.pos);
12356 else
12358 /* Not much we can do about it. */
12362 /* Consider the following case: Window starts at BEGV, there is
12363 invisible, intangible text at BEGV, so that display starts at
12364 some point START > BEGV. It can happen that we are called with
12365 PT somewhere between BEGV and START. Try to handle that case. */
12366 if (w->cursor.vpos < 0)
12368 struct glyph_row *row = w->current_matrix->rows;
12369 if (row->mode_line_p)
12370 ++row;
12371 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
12374 if (!cursor_row_fully_visible_p (w, 0, 0))
12376 /* If vscroll is enabled, disable it and try again. */
12377 if (w->vscroll)
12379 w->vscroll = 0;
12380 clear_glyph_matrix (w->desired_matrix);
12381 goto recenter;
12384 /* If centering point failed to make the whole line visible,
12385 put point at the top instead. That has to make the whole line
12386 visible, if it can be done. */
12387 if (centering_position == 0)
12388 goto done;
12390 clear_glyph_matrix (w->desired_matrix);
12391 centering_position = 0;
12392 goto recenter;
12395 done:
12397 SET_TEXT_POS_FROM_MARKER (startp, w->start);
12398 w->start_at_line_beg = ((CHARPOS (startp) == BEGV
12399 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n')
12400 ? Qt : Qnil);
12402 /* Display the mode line, if we must. */
12403 if ((update_mode_line
12404 /* If window not full width, must redo its mode line
12405 if (a) the window to its side is being redone and
12406 (b) we do a frame-based redisplay. This is a consequence
12407 of how inverted lines are drawn in frame-based redisplay. */
12408 || (!just_this_one_p
12409 && !FRAME_WINDOW_P (f)
12410 && !WINDOW_FULL_WIDTH_P (w))
12411 /* Line number to display. */
12412 || INTEGERP (w->base_line_pos)
12413 /* Column number is displayed and different from the one displayed. */
12414 || (!NILP (w->column_number_displayed)
12415 && (XFASTINT (w->column_number_displayed)
12416 != (int) current_column ()))) /* iftc */
12417 /* This means that the window has a mode line. */
12418 && (WINDOW_WANTS_MODELINE_P (w)
12419 || WINDOW_WANTS_HEADER_LINE_P (w)))
12421 display_mode_lines (w);
12423 /* If mode line height has changed, arrange for a thorough
12424 immediate redisplay using the correct mode line height. */
12425 if (WINDOW_WANTS_MODELINE_P (w)
12426 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
12428 fonts_changed_p = 1;
12429 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
12430 = DESIRED_MODE_LINE_HEIGHT (w);
12433 /* If top line height has changed, arrange for a thorough
12434 immediate redisplay using the correct mode line height. */
12435 if (WINDOW_WANTS_HEADER_LINE_P (w)
12436 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
12438 fonts_changed_p = 1;
12439 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
12440 = DESIRED_HEADER_LINE_HEIGHT (w);
12443 if (fonts_changed_p)
12444 goto need_larger_matrices;
12447 if (!line_number_displayed
12448 && !BUFFERP (w->base_line_pos))
12450 w->base_line_pos = Qnil;
12451 w->base_line_number = Qnil;
12454 finish_menu_bars:
12456 /* When we reach a frame's selected window, redo the frame's menu bar. */
12457 if (update_mode_line
12458 && EQ (FRAME_SELECTED_WINDOW (f), window))
12460 int redisplay_menu_p = 0;
12461 int redisplay_tool_bar_p = 0;
12463 if (FRAME_WINDOW_P (f))
12465 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
12466 || defined (USE_GTK)
12467 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
12468 #else
12469 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
12470 #endif
12472 else
12473 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
12475 if (redisplay_menu_p)
12476 display_menu_bar (w);
12478 #ifdef HAVE_WINDOW_SYSTEM
12479 #ifdef USE_GTK
12480 redisplay_tool_bar_p = FRAME_EXTERNAL_TOOL_BAR (f);
12481 #else
12482 redisplay_tool_bar_p = WINDOWP (f->tool_bar_window)
12483 && (FRAME_TOOL_BAR_LINES (f) > 0
12484 || auto_resize_tool_bars_p);
12486 #endif
12488 if (redisplay_tool_bar_p)
12489 redisplay_tool_bar (f);
12490 #endif
12493 #ifdef HAVE_WINDOW_SYSTEM
12494 if (FRAME_WINDOW_P (f)
12495 && update_window_fringes (w, 0)
12496 && !just_this_one_p
12497 && (used_current_matrix_p || overlay_arrow_seen)
12498 && !w->pseudo_window_p)
12500 update_begin (f);
12501 BLOCK_INPUT;
12502 if (draw_window_fringes (w, 1))
12503 x_draw_vertical_border (w);
12504 UNBLOCK_INPUT;
12505 update_end (f);
12507 #endif /* HAVE_WINDOW_SYSTEM */
12509 /* We go to this label, with fonts_changed_p nonzero,
12510 if it is necessary to try again using larger glyph matrices.
12511 We have to redeem the scroll bar even in this case,
12512 because the loop in redisplay_internal expects that. */
12513 need_larger_matrices:
12515 finish_scroll_bars:
12517 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
12519 /* Set the thumb's position and size. */
12520 set_vertical_scroll_bar (w);
12522 /* Note that we actually used the scroll bar attached to this
12523 window, so it shouldn't be deleted at the end of redisplay. */
12524 redeem_scroll_bar_hook (w);
12527 /* Restore current_buffer and value of point in it. */
12528 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
12529 set_buffer_internal_1 (old);
12530 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
12532 unbind_to (count, Qnil);
12536 /* Build the complete desired matrix of WINDOW with a window start
12537 buffer position POS. Value is non-zero if successful. It is zero
12538 if fonts were loaded during redisplay which makes re-adjusting
12539 glyph matrices necessary. */
12542 try_window (window, pos)
12543 Lisp_Object window;
12544 struct text_pos pos;
12546 struct window *w = XWINDOW (window);
12547 struct it it;
12548 struct glyph_row *last_text_row = NULL;
12550 /* Make POS the new window start. */
12551 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
12553 /* Mark cursor position as unknown. No overlay arrow seen. */
12554 w->cursor.vpos = -1;
12555 overlay_arrow_seen = 0;
12557 /* Initialize iterator and info to start at POS. */
12558 start_display (&it, w, pos);
12560 /* Display all lines of W. */
12561 while (it.current_y < it.last_visible_y)
12563 if (display_line (&it))
12564 last_text_row = it.glyph_row - 1;
12565 if (fonts_changed_p)
12566 return 0;
12569 /* If bottom moved off end of frame, change mode line percentage. */
12570 if (XFASTINT (w->window_end_pos) <= 0
12571 && Z != IT_CHARPOS (it))
12572 w->update_mode_line = Qt;
12574 /* Set window_end_pos to the offset of the last character displayed
12575 on the window from the end of current_buffer. Set
12576 window_end_vpos to its row number. */
12577 if (last_text_row)
12579 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
12580 w->window_end_bytepos
12581 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12582 w->window_end_pos
12583 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12584 w->window_end_vpos
12585 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12586 xassert (MATRIX_ROW (w->desired_matrix, XFASTINT (w->window_end_vpos))
12587 ->displays_text_p);
12589 else
12591 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
12592 w->window_end_pos = make_number (Z - ZV);
12593 w->window_end_vpos = make_number (0);
12596 /* But that is not valid info until redisplay finishes. */
12597 w->window_end_valid = Qnil;
12598 return 1;
12603 /************************************************************************
12604 Window redisplay reusing current matrix when buffer has not changed
12605 ************************************************************************/
12607 /* Try redisplay of window W showing an unchanged buffer with a
12608 different window start than the last time it was displayed by
12609 reusing its current matrix. Value is non-zero if successful.
12610 W->start is the new window start. */
12612 static int
12613 try_window_reusing_current_matrix (w)
12614 struct window *w;
12616 struct frame *f = XFRAME (w->frame);
12617 struct glyph_row *row, *bottom_row;
12618 struct it it;
12619 struct run run;
12620 struct text_pos start, new_start;
12621 int nrows_scrolled, i;
12622 struct glyph_row *last_text_row;
12623 struct glyph_row *last_reused_text_row;
12624 struct glyph_row *start_row;
12625 int start_vpos, min_y, max_y;
12627 #if GLYPH_DEBUG
12628 if (inhibit_try_window_reusing)
12629 return 0;
12630 #endif
12632 if (/* This function doesn't handle terminal frames. */
12633 !FRAME_WINDOW_P (f)
12634 /* Don't try to reuse the display if windows have been split
12635 or such. */
12636 || windows_or_buffers_changed
12637 || cursor_type_changed)
12638 return 0;
12640 /* Can't do this if region may have changed. */
12641 if ((!NILP (Vtransient_mark_mode)
12642 && !NILP (current_buffer->mark_active))
12643 || !NILP (w->region_showing)
12644 || !NILP (Vshow_trailing_whitespace))
12645 return 0;
12647 /* If top-line visibility has changed, give up. */
12648 if (WINDOW_WANTS_HEADER_LINE_P (w)
12649 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
12650 return 0;
12652 /* Give up if old or new display is scrolled vertically. We could
12653 make this function handle this, but right now it doesn't. */
12654 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12655 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row))
12656 return 0;
12658 /* The variable new_start now holds the new window start. The old
12659 start `start' can be determined from the current matrix. */
12660 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
12661 start = start_row->start.pos;
12662 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
12664 /* Clear the desired matrix for the display below. */
12665 clear_glyph_matrix (w->desired_matrix);
12667 if (CHARPOS (new_start) <= CHARPOS (start))
12669 int first_row_y;
12671 /* Don't use this method if the display starts with an ellipsis
12672 displayed for invisible text. It's not easy to handle that case
12673 below, and it's certainly not worth the effort since this is
12674 not a frequent case. */
12675 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
12676 return 0;
12678 IF_DEBUG (debug_method_add (w, "twu1"));
12680 /* Display up to a row that can be reused. The variable
12681 last_text_row is set to the last row displayed that displays
12682 text. Note that it.vpos == 0 if or if not there is a
12683 header-line; it's not the same as the MATRIX_ROW_VPOS! */
12684 start_display (&it, w, new_start);
12685 first_row_y = it.current_y;
12686 w->cursor.vpos = -1;
12687 last_text_row = last_reused_text_row = NULL;
12689 while (it.current_y < it.last_visible_y
12690 && !fonts_changed_p)
12692 /* If we have reached into the characters in the START row,
12693 that means the line boundaries have changed. So we
12694 can't start copying with the row START. Maybe it will
12695 work to start copying with the following row. */
12696 while (IT_CHARPOS (it) > CHARPOS (start))
12698 /* Advance to the next row as the "start". */
12699 start_row++;
12700 start = start_row->start.pos;
12701 /* If there are no more rows to try, or just one, give up. */
12702 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
12703 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row)
12704 || CHARPOS (start) == ZV)
12706 clear_glyph_matrix (w->desired_matrix);
12707 return 0;
12710 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
12712 /* If we have reached alignment,
12713 we can copy the rest of the rows. */
12714 if (IT_CHARPOS (it) == CHARPOS (start))
12715 break;
12717 if (display_line (&it))
12718 last_text_row = it.glyph_row - 1;
12721 /* A value of current_y < last_visible_y means that we stopped
12722 at the previous window start, which in turn means that we
12723 have at least one reusable row. */
12724 if (it.current_y < it.last_visible_y)
12726 /* IT.vpos always starts from 0; it counts text lines. */
12727 nrows_scrolled = it.vpos - (start_row - MATRIX_FIRST_TEXT_ROW (w->current_matrix));
12729 /* Find PT if not already found in the lines displayed. */
12730 if (w->cursor.vpos < 0)
12732 int dy = it.current_y - start_row->y;
12734 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12735 row = row_containing_pos (w, PT, row, NULL, dy);
12736 if (row)
12737 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
12738 dy, nrows_scrolled);
12739 else
12741 clear_glyph_matrix (w->desired_matrix);
12742 return 0;
12746 /* Scroll the display. Do it before the current matrix is
12747 changed. The problem here is that update has not yet
12748 run, i.e. part of the current matrix is not up to date.
12749 scroll_run_hook will clear the cursor, and use the
12750 current matrix to get the height of the row the cursor is
12751 in. */
12752 run.current_y = start_row->y;
12753 run.desired_y = it.current_y;
12754 run.height = it.last_visible_y - it.current_y;
12756 if (run.height > 0 && run.current_y != run.desired_y)
12758 update_begin (f);
12759 rif->update_window_begin_hook (w);
12760 rif->clear_window_mouse_face (w);
12761 rif->scroll_run_hook (w, &run);
12762 rif->update_window_end_hook (w, 0, 0);
12763 update_end (f);
12766 /* Shift current matrix down by nrows_scrolled lines. */
12767 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
12768 rotate_matrix (w->current_matrix,
12769 start_vpos,
12770 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
12771 nrows_scrolled);
12773 /* Disable lines that must be updated. */
12774 for (i = 0; i < it.vpos; ++i)
12775 (start_row + i)->enabled_p = 0;
12777 /* Re-compute Y positions. */
12778 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
12779 max_y = it.last_visible_y;
12780 for (row = start_row + nrows_scrolled;
12781 row < bottom_row;
12782 ++row)
12784 row->y = it.current_y;
12785 row->visible_height = row->height;
12787 if (row->y < min_y)
12788 row->visible_height -= min_y - row->y;
12789 if (row->y + row->height > max_y)
12790 row->visible_height -= row->y + row->height - max_y;
12791 row->redraw_fringe_bitmaps_p = 1;
12793 it.current_y += row->height;
12795 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
12796 last_reused_text_row = row;
12797 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
12798 break;
12801 /* Disable lines in the current matrix which are now
12802 below the window. */
12803 for (++row; row < bottom_row; ++row)
12804 row->enabled_p = 0;
12807 /* Update window_end_pos etc.; last_reused_text_row is the last
12808 reused row from the current matrix containing text, if any.
12809 The value of last_text_row is the last displayed line
12810 containing text. */
12811 if (last_reused_text_row)
12813 w->window_end_bytepos
12814 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
12815 w->window_end_pos
12816 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_reused_text_row));
12817 w->window_end_vpos
12818 = make_number (MATRIX_ROW_VPOS (last_reused_text_row,
12819 w->current_matrix));
12821 else if (last_text_row)
12823 w->window_end_bytepos
12824 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12825 w->window_end_pos
12826 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12827 w->window_end_vpos
12828 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12830 else
12832 /* This window must be completely empty. */
12833 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
12834 w->window_end_pos = make_number (Z - ZV);
12835 w->window_end_vpos = make_number (0);
12837 w->window_end_valid = Qnil;
12839 /* Update hint: don't try scrolling again in update_window. */
12840 w->desired_matrix->no_scrolling_p = 1;
12842 #if GLYPH_DEBUG
12843 debug_method_add (w, "try_window_reusing_current_matrix 1");
12844 #endif
12845 return 1;
12847 else if (CHARPOS (new_start) > CHARPOS (start))
12849 struct glyph_row *pt_row, *row;
12850 struct glyph_row *first_reusable_row;
12851 struct glyph_row *first_row_to_display;
12852 int dy;
12853 int yb = window_text_bottom_y (w);
12855 /* Find the row starting at new_start, if there is one. Don't
12856 reuse a partially visible line at the end. */
12857 first_reusable_row = start_row;
12858 while (first_reusable_row->enabled_p
12859 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
12860 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
12861 < CHARPOS (new_start)))
12862 ++first_reusable_row;
12864 /* Give up if there is no row to reuse. */
12865 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
12866 || !first_reusable_row->enabled_p
12867 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
12868 != CHARPOS (new_start)))
12869 return 0;
12871 /* We can reuse fully visible rows beginning with
12872 first_reusable_row to the end of the window. Set
12873 first_row_to_display to the first row that cannot be reused.
12874 Set pt_row to the row containing point, if there is any. */
12875 pt_row = NULL;
12876 for (first_row_to_display = first_reusable_row;
12877 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
12878 ++first_row_to_display)
12880 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
12881 && PT < MATRIX_ROW_END_CHARPOS (first_row_to_display))
12882 pt_row = first_row_to_display;
12885 /* Start displaying at the start of first_row_to_display. */
12886 xassert (first_row_to_display->y < yb);
12887 init_to_row_start (&it, w, first_row_to_display);
12889 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
12890 - start_vpos);
12891 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
12892 - nrows_scrolled);
12893 it.current_y = (first_row_to_display->y - first_reusable_row->y
12894 + WINDOW_HEADER_LINE_HEIGHT (w));
12896 /* Display lines beginning with first_row_to_display in the
12897 desired matrix. Set last_text_row to the last row displayed
12898 that displays text. */
12899 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
12900 if (pt_row == NULL)
12901 w->cursor.vpos = -1;
12902 last_text_row = NULL;
12903 while (it.current_y < it.last_visible_y && !fonts_changed_p)
12904 if (display_line (&it))
12905 last_text_row = it.glyph_row - 1;
12907 /* Give up If point isn't in a row displayed or reused. */
12908 if (w->cursor.vpos < 0)
12910 clear_glyph_matrix (w->desired_matrix);
12911 return 0;
12914 /* If point is in a reused row, adjust y and vpos of the cursor
12915 position. */
12916 if (pt_row)
12918 w->cursor.vpos -= nrows_scrolled;
12919 w->cursor.y -= first_reusable_row->y - start_row->y;
12922 /* Scroll the display. */
12923 run.current_y = first_reusable_row->y;
12924 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
12925 run.height = it.last_visible_y - run.current_y;
12926 dy = run.current_y - run.desired_y;
12928 if (run.height)
12930 update_begin (f);
12931 rif->update_window_begin_hook (w);
12932 rif->clear_window_mouse_face (w);
12933 rif->scroll_run_hook (w, &run);
12934 rif->update_window_end_hook (w, 0, 0);
12935 update_end (f);
12938 /* Adjust Y positions of reused rows. */
12939 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
12940 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
12941 max_y = it.last_visible_y;
12942 for (row = first_reusable_row; row < first_row_to_display; ++row)
12944 row->y -= dy;
12945 row->visible_height = row->height;
12946 if (row->y < min_y)
12947 row->visible_height -= min_y - row->y;
12948 if (row->y + row->height > max_y)
12949 row->visible_height -= row->y + row->height - max_y;
12950 row->redraw_fringe_bitmaps_p = 1;
12953 /* Scroll the current matrix. */
12954 xassert (nrows_scrolled > 0);
12955 rotate_matrix (w->current_matrix,
12956 start_vpos,
12957 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
12958 -nrows_scrolled);
12960 /* Disable rows not reused. */
12961 for (row -= nrows_scrolled; row < bottom_row; ++row)
12962 row->enabled_p = 0;
12964 /* Point may have moved to a different line, so we cannot assume that
12965 the previous cursor position is valid; locate the correct row. */
12966 if (pt_row)
12968 for (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
12969 row < bottom_row && PT >= MATRIX_ROW_END_CHARPOS (row);
12970 row++)
12972 w->cursor.vpos++;
12973 w->cursor.y = row->y;
12975 if (row < bottom_row)
12977 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
12978 while (glyph->charpos < PT)
12980 w->cursor.hpos++;
12981 w->cursor.x += glyph->pixel_width;
12982 glyph++;
12987 /* Adjust window end. A null value of last_text_row means that
12988 the window end is in reused rows which in turn means that
12989 only its vpos can have changed. */
12990 if (last_text_row)
12992 w->window_end_bytepos
12993 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12994 w->window_end_pos
12995 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12996 w->window_end_vpos
12997 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12999 else
13001 w->window_end_vpos
13002 = make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled);
13005 w->window_end_valid = Qnil;
13006 w->desired_matrix->no_scrolling_p = 1;
13008 #if GLYPH_DEBUG
13009 debug_method_add (w, "try_window_reusing_current_matrix 2");
13010 #endif
13011 return 1;
13014 return 0;
13019 /************************************************************************
13020 Window redisplay reusing current matrix when buffer has changed
13021 ************************************************************************/
13023 static struct glyph_row *find_last_unchanged_at_beg_row P_ ((struct window *));
13024 static struct glyph_row *find_first_unchanged_at_end_row P_ ((struct window *,
13025 int *, int *));
13026 static struct glyph_row *
13027 find_last_row_displaying_text P_ ((struct glyph_matrix *, struct it *,
13028 struct glyph_row *));
13031 /* Return the last row in MATRIX displaying text. If row START is
13032 non-null, start searching with that row. IT gives the dimensions
13033 of the display. Value is null if matrix is empty; otherwise it is
13034 a pointer to the row found. */
13036 static struct glyph_row *
13037 find_last_row_displaying_text (matrix, it, start)
13038 struct glyph_matrix *matrix;
13039 struct it *it;
13040 struct glyph_row *start;
13042 struct glyph_row *row, *row_found;
13044 /* Set row_found to the last row in IT->w's current matrix
13045 displaying text. The loop looks funny but think of partially
13046 visible lines. */
13047 row_found = NULL;
13048 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
13049 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
13051 xassert (row->enabled_p);
13052 row_found = row;
13053 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
13054 break;
13055 ++row;
13058 return row_found;
13062 /* Return the last row in the current matrix of W that is not affected
13063 by changes at the start of current_buffer that occurred since W's
13064 current matrix was built. Value is null if no such row exists.
13066 BEG_UNCHANGED us the number of characters unchanged at the start of
13067 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
13068 first changed character in current_buffer. Characters at positions <
13069 BEG + BEG_UNCHANGED are at the same buffer positions as they were
13070 when the current matrix was built. */
13072 static struct glyph_row *
13073 find_last_unchanged_at_beg_row (w)
13074 struct window *w;
13076 int first_changed_pos = BEG + BEG_UNCHANGED;
13077 struct glyph_row *row;
13078 struct glyph_row *row_found = NULL;
13079 int yb = window_text_bottom_y (w);
13081 /* Find the last row displaying unchanged text. */
13082 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
13083 while (MATRIX_ROW_DISPLAYS_TEXT_P (row)
13084 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos)
13086 if (/* If row ends before first_changed_pos, it is unchanged,
13087 except in some case. */
13088 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
13089 /* When row ends in ZV and we write at ZV it is not
13090 unchanged. */
13091 && !row->ends_at_zv_p
13092 /* When first_changed_pos is the end of a continued line,
13093 row is not unchanged because it may be no longer
13094 continued. */
13095 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
13096 && (row->continued_p
13097 || row->exact_window_width_line_p)))
13098 row_found = row;
13100 /* Stop if last visible row. */
13101 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
13102 break;
13104 ++row;
13107 return row_found;
13111 /* Find the first glyph row in the current matrix of W that is not
13112 affected by changes at the end of current_buffer since the
13113 time W's current matrix was built.
13115 Return in *DELTA the number of chars by which buffer positions in
13116 unchanged text at the end of current_buffer must be adjusted.
13118 Return in *DELTA_BYTES the corresponding number of bytes.
13120 Value is null if no such row exists, i.e. all rows are affected by
13121 changes. */
13123 static struct glyph_row *
13124 find_first_unchanged_at_end_row (w, delta, delta_bytes)
13125 struct window *w;
13126 int *delta, *delta_bytes;
13128 struct glyph_row *row;
13129 struct glyph_row *row_found = NULL;
13131 *delta = *delta_bytes = 0;
13133 /* Display must not have been paused, otherwise the current matrix
13134 is not up to date. */
13135 if (NILP (w->window_end_valid))
13136 abort ();
13138 /* A value of window_end_pos >= END_UNCHANGED means that the window
13139 end is in the range of changed text. If so, there is no
13140 unchanged row at the end of W's current matrix. */
13141 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
13142 return NULL;
13144 /* Set row to the last row in W's current matrix displaying text. */
13145 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
13147 /* If matrix is entirely empty, no unchanged row exists. */
13148 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
13150 /* The value of row is the last glyph row in the matrix having a
13151 meaningful buffer position in it. The end position of row
13152 corresponds to window_end_pos. This allows us to translate
13153 buffer positions in the current matrix to current buffer
13154 positions for characters not in changed text. */
13155 int Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
13156 int Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
13157 int last_unchanged_pos, last_unchanged_pos_old;
13158 struct glyph_row *first_text_row
13159 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
13161 *delta = Z - Z_old;
13162 *delta_bytes = Z_BYTE - Z_BYTE_old;
13164 /* Set last_unchanged_pos to the buffer position of the last
13165 character in the buffer that has not been changed. Z is the
13166 index + 1 of the last character in current_buffer, i.e. by
13167 subtracting END_UNCHANGED we get the index of the last
13168 unchanged character, and we have to add BEG to get its buffer
13169 position. */
13170 last_unchanged_pos = Z - END_UNCHANGED + BEG;
13171 last_unchanged_pos_old = last_unchanged_pos - *delta;
13173 /* Search backward from ROW for a row displaying a line that
13174 starts at a minimum position >= last_unchanged_pos_old. */
13175 for (; row > first_text_row; --row)
13177 /* This used to abort, but it can happen.
13178 It is ok to just stop the search instead here. KFS. */
13179 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
13180 break;
13182 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
13183 row_found = row;
13187 if (row_found && !MATRIX_ROW_DISPLAYS_TEXT_P (row_found))
13188 abort ();
13190 return row_found;
13194 /* Make sure that glyph rows in the current matrix of window W
13195 reference the same glyph memory as corresponding rows in the
13196 frame's frame matrix. This function is called after scrolling W's
13197 current matrix on a terminal frame in try_window_id and
13198 try_window_reusing_current_matrix. */
13200 static void
13201 sync_frame_with_window_matrix_rows (w)
13202 struct window *w;
13204 struct frame *f = XFRAME (w->frame);
13205 struct glyph_row *window_row, *window_row_end, *frame_row;
13207 /* Preconditions: W must be a leaf window and full-width. Its frame
13208 must have a frame matrix. */
13209 xassert (NILP (w->hchild) && NILP (w->vchild));
13210 xassert (WINDOW_FULL_WIDTH_P (w));
13211 xassert (!FRAME_WINDOW_P (f));
13213 /* If W is a full-width window, glyph pointers in W's current matrix
13214 have, by definition, to be the same as glyph pointers in the
13215 corresponding frame matrix. Note that frame matrices have no
13216 marginal areas (see build_frame_matrix). */
13217 window_row = w->current_matrix->rows;
13218 window_row_end = window_row + w->current_matrix->nrows;
13219 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
13220 while (window_row < window_row_end)
13222 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
13223 struct glyph *end = window_row->glyphs[LAST_AREA];
13225 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
13226 frame_row->glyphs[TEXT_AREA] = start;
13227 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
13228 frame_row->glyphs[LAST_AREA] = end;
13230 /* Disable frame rows whose corresponding window rows have
13231 been disabled in try_window_id. */
13232 if (!window_row->enabled_p)
13233 frame_row->enabled_p = 0;
13235 ++window_row, ++frame_row;
13240 /* Find the glyph row in window W containing CHARPOS. Consider all
13241 rows between START and END (not inclusive). END null means search
13242 all rows to the end of the display area of W. Value is the row
13243 containing CHARPOS or null. */
13245 struct glyph_row *
13246 row_containing_pos (w, charpos, start, end, dy)
13247 struct window *w;
13248 int charpos;
13249 struct glyph_row *start, *end;
13250 int dy;
13252 struct glyph_row *row = start;
13253 int last_y;
13255 /* If we happen to start on a header-line, skip that. */
13256 if (row->mode_line_p)
13257 ++row;
13259 if ((end && row >= end) || !row->enabled_p)
13260 return NULL;
13262 last_y = window_text_bottom_y (w) - dy;
13264 while (1)
13266 /* Give up if we have gone too far. */
13267 if (end && row >= end)
13268 return NULL;
13269 /* This formerly returned if they were equal.
13270 I think that both quantities are of a "last plus one" type;
13271 if so, when they are equal, the row is within the screen. -- rms. */
13272 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
13273 return NULL;
13275 /* If it is in this row, return this row. */
13276 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
13277 || (MATRIX_ROW_END_CHARPOS (row) == charpos
13278 /* The end position of a row equals the start
13279 position of the next row. If CHARPOS is there, we
13280 would rather display it in the next line, except
13281 when this line ends in ZV. */
13282 && !row->ends_at_zv_p
13283 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
13284 && charpos >= MATRIX_ROW_START_CHARPOS (row))
13285 return row;
13286 ++row;
13291 /* Try to redisplay window W by reusing its existing display. W's
13292 current matrix must be up to date when this function is called,
13293 i.e. window_end_valid must not be nil.
13295 Value is
13297 1 if display has been updated
13298 0 if otherwise unsuccessful
13299 -1 if redisplay with same window start is known not to succeed
13301 The following steps are performed:
13303 1. Find the last row in the current matrix of W that is not
13304 affected by changes at the start of current_buffer. If no such row
13305 is found, give up.
13307 2. Find the first row in W's current matrix that is not affected by
13308 changes at the end of current_buffer. Maybe there is no such row.
13310 3. Display lines beginning with the row + 1 found in step 1 to the
13311 row found in step 2 or, if step 2 didn't find a row, to the end of
13312 the window.
13314 4. If cursor is not known to appear on the window, give up.
13316 5. If display stopped at the row found in step 2, scroll the
13317 display and current matrix as needed.
13319 6. Maybe display some lines at the end of W, if we must. This can
13320 happen under various circumstances, like a partially visible line
13321 becoming fully visible, or because newly displayed lines are displayed
13322 in smaller font sizes.
13324 7. Update W's window end information. */
13326 static int
13327 try_window_id (w)
13328 struct window *w;
13330 struct frame *f = XFRAME (w->frame);
13331 struct glyph_matrix *current_matrix = w->current_matrix;
13332 struct glyph_matrix *desired_matrix = w->desired_matrix;
13333 struct glyph_row *last_unchanged_at_beg_row;
13334 struct glyph_row *first_unchanged_at_end_row;
13335 struct glyph_row *row;
13336 struct glyph_row *bottom_row;
13337 int bottom_vpos;
13338 struct it it;
13339 int delta = 0, delta_bytes = 0, stop_pos, dvpos, dy;
13340 struct text_pos start_pos;
13341 struct run run;
13342 int first_unchanged_at_end_vpos = 0;
13343 struct glyph_row *last_text_row, *last_text_row_at_end;
13344 struct text_pos start;
13345 int first_changed_charpos, last_changed_charpos;
13347 #if GLYPH_DEBUG
13348 if (inhibit_try_window_id)
13349 return 0;
13350 #endif
13352 /* This is handy for debugging. */
13353 #if 0
13354 #define GIVE_UP(X) \
13355 do { \
13356 fprintf (stderr, "try_window_id give up %d\n", (X)); \
13357 return 0; \
13358 } while (0)
13359 #else
13360 #define GIVE_UP(X) return 0
13361 #endif
13363 SET_TEXT_POS_FROM_MARKER (start, w->start);
13365 /* Don't use this for mini-windows because these can show
13366 messages and mini-buffers, and we don't handle that here. */
13367 if (MINI_WINDOW_P (w))
13368 GIVE_UP (1);
13370 /* This flag is used to prevent redisplay optimizations. */
13371 if (windows_or_buffers_changed || cursor_type_changed)
13372 GIVE_UP (2);
13374 /* Verify that narrowing has not changed.
13375 Also verify that we were not told to prevent redisplay optimizations.
13376 It would be nice to further
13377 reduce the number of cases where this prevents try_window_id. */
13378 if (current_buffer->clip_changed
13379 || current_buffer->prevent_redisplay_optimizations_p)
13380 GIVE_UP (3);
13382 /* Window must either use window-based redisplay or be full width. */
13383 if (!FRAME_WINDOW_P (f)
13384 && (!line_ins_del_ok
13385 || !WINDOW_FULL_WIDTH_P (w)))
13386 GIVE_UP (4);
13388 /* Give up if point is not known NOT to appear in W. */
13389 if (PT < CHARPOS (start))
13390 GIVE_UP (5);
13392 /* Another way to prevent redisplay optimizations. */
13393 if (XFASTINT (w->last_modified) == 0)
13394 GIVE_UP (6);
13396 /* Verify that window is not hscrolled. */
13397 if (XFASTINT (w->hscroll) != 0)
13398 GIVE_UP (7);
13400 /* Verify that display wasn't paused. */
13401 if (NILP (w->window_end_valid))
13402 GIVE_UP (8);
13404 /* Can't use this if highlighting a region because a cursor movement
13405 will do more than just set the cursor. */
13406 if (!NILP (Vtransient_mark_mode)
13407 && !NILP (current_buffer->mark_active))
13408 GIVE_UP (9);
13410 /* Likewise if highlighting trailing whitespace. */
13411 if (!NILP (Vshow_trailing_whitespace))
13412 GIVE_UP (11);
13414 /* Likewise if showing a region. */
13415 if (!NILP (w->region_showing))
13416 GIVE_UP (10);
13418 /* Can use this if overlay arrow position and or string have changed. */
13419 if (overlay_arrows_changed_p ())
13420 GIVE_UP (12);
13423 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
13424 only if buffer has really changed. The reason is that the gap is
13425 initially at Z for freshly visited files. The code below would
13426 set end_unchanged to 0 in that case. */
13427 if (MODIFF > SAVE_MODIFF
13428 /* This seems to happen sometimes after saving a buffer. */
13429 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
13431 if (GPT - BEG < BEG_UNCHANGED)
13432 BEG_UNCHANGED = GPT - BEG;
13433 if (Z - GPT < END_UNCHANGED)
13434 END_UNCHANGED = Z - GPT;
13437 /* The position of the first and last character that has been changed. */
13438 first_changed_charpos = BEG + BEG_UNCHANGED;
13439 last_changed_charpos = Z - END_UNCHANGED;
13441 /* If window starts after a line end, and the last change is in
13442 front of that newline, then changes don't affect the display.
13443 This case happens with stealth-fontification. Note that although
13444 the display is unchanged, glyph positions in the matrix have to
13445 be adjusted, of course. */
13446 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
13447 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
13448 && ((last_changed_charpos < CHARPOS (start)
13449 && CHARPOS (start) == BEGV)
13450 || (last_changed_charpos < CHARPOS (start) - 1
13451 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
13453 int Z_old, delta, Z_BYTE_old, delta_bytes;
13454 struct glyph_row *r0;
13456 /* Compute how many chars/bytes have been added to or removed
13457 from the buffer. */
13458 Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
13459 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
13460 delta = Z - Z_old;
13461 delta_bytes = Z_BYTE - Z_BYTE_old;
13463 /* Give up if PT is not in the window. Note that it already has
13464 been checked at the start of try_window_id that PT is not in
13465 front of the window start. */
13466 if (PT >= MATRIX_ROW_END_CHARPOS (row) + delta)
13467 GIVE_UP (13);
13469 /* If window start is unchanged, we can reuse the whole matrix
13470 as is, after adjusting glyph positions. No need to compute
13471 the window end again, since its offset from Z hasn't changed. */
13472 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
13473 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + delta
13474 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + delta_bytes
13475 /* PT must not be in a partially visible line. */
13476 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + delta
13477 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
13479 /* Adjust positions in the glyph matrix. */
13480 if (delta || delta_bytes)
13482 struct glyph_row *r1
13483 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
13484 increment_matrix_positions (w->current_matrix,
13485 MATRIX_ROW_VPOS (r0, current_matrix),
13486 MATRIX_ROW_VPOS (r1, current_matrix),
13487 delta, delta_bytes);
13490 /* Set the cursor. */
13491 row = row_containing_pos (w, PT, r0, NULL, 0);
13492 if (row)
13493 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
13494 else
13495 abort ();
13496 return 1;
13500 /* Handle the case that changes are all below what is displayed in
13501 the window, and that PT is in the window. This shortcut cannot
13502 be taken if ZV is visible in the window, and text has been added
13503 there that is visible in the window. */
13504 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
13505 /* ZV is not visible in the window, or there are no
13506 changes at ZV, actually. */
13507 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
13508 || first_changed_charpos == last_changed_charpos))
13510 struct glyph_row *r0;
13512 /* Give up if PT is not in the window. Note that it already has
13513 been checked at the start of try_window_id that PT is not in
13514 front of the window start. */
13515 if (PT >= MATRIX_ROW_END_CHARPOS (row))
13516 GIVE_UP (14);
13518 /* If window start is unchanged, we can reuse the whole matrix
13519 as is, without changing glyph positions since no text has
13520 been added/removed in front of the window end. */
13521 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
13522 if (TEXT_POS_EQUAL_P (start, r0->start.pos)
13523 /* PT must not be in a partially visible line. */
13524 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
13525 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
13527 /* We have to compute the window end anew since text
13528 can have been added/removed after it. */
13529 w->window_end_pos
13530 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13531 w->window_end_bytepos
13532 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13534 /* Set the cursor. */
13535 row = row_containing_pos (w, PT, r0, NULL, 0);
13536 if (row)
13537 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
13538 else
13539 abort ();
13540 return 2;
13544 /* Give up if window start is in the changed area.
13546 The condition used to read
13548 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
13550 but why that was tested escapes me at the moment. */
13551 if (CHARPOS (start) >= first_changed_charpos
13552 && CHARPOS (start) <= last_changed_charpos)
13553 GIVE_UP (15);
13555 /* Check that window start agrees with the start of the first glyph
13556 row in its current matrix. Check this after we know the window
13557 start is not in changed text, otherwise positions would not be
13558 comparable. */
13559 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
13560 if (!TEXT_POS_EQUAL_P (start, row->start.pos))
13561 GIVE_UP (16);
13563 /* Give up if the window ends in strings. Overlay strings
13564 at the end are difficult to handle, so don't try. */
13565 row = MATRIX_ROW (current_matrix, XFASTINT (w->window_end_vpos));
13566 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
13567 GIVE_UP (20);
13569 /* Compute the position at which we have to start displaying new
13570 lines. Some of the lines at the top of the window might be
13571 reusable because they are not displaying changed text. Find the
13572 last row in W's current matrix not affected by changes at the
13573 start of current_buffer. Value is null if changes start in the
13574 first line of window. */
13575 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
13576 if (last_unchanged_at_beg_row)
13578 /* Avoid starting to display in the moddle of a character, a TAB
13579 for instance. This is easier than to set up the iterator
13580 exactly, and it's not a frequent case, so the additional
13581 effort wouldn't really pay off. */
13582 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
13583 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
13584 && last_unchanged_at_beg_row > w->current_matrix->rows)
13585 --last_unchanged_at_beg_row;
13587 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
13588 GIVE_UP (17);
13590 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
13591 GIVE_UP (18);
13592 start_pos = it.current.pos;
13594 /* Start displaying new lines in the desired matrix at the same
13595 vpos we would use in the current matrix, i.e. below
13596 last_unchanged_at_beg_row. */
13597 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
13598 current_matrix);
13599 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
13600 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
13602 xassert (it.hpos == 0 && it.current_x == 0);
13604 else
13606 /* There are no reusable lines at the start of the window.
13607 Start displaying in the first text line. */
13608 start_display (&it, w, start);
13609 it.vpos = it.first_vpos;
13610 start_pos = it.current.pos;
13613 /* Find the first row that is not affected by changes at the end of
13614 the buffer. Value will be null if there is no unchanged row, in
13615 which case we must redisplay to the end of the window. delta
13616 will be set to the value by which buffer positions beginning with
13617 first_unchanged_at_end_row have to be adjusted due to text
13618 changes. */
13619 first_unchanged_at_end_row
13620 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
13621 IF_DEBUG (debug_delta = delta);
13622 IF_DEBUG (debug_delta_bytes = delta_bytes);
13624 /* Set stop_pos to the buffer position up to which we will have to
13625 display new lines. If first_unchanged_at_end_row != NULL, this
13626 is the buffer position of the start of the line displayed in that
13627 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
13628 that we don't stop at a buffer position. */
13629 stop_pos = 0;
13630 if (first_unchanged_at_end_row)
13632 xassert (last_unchanged_at_beg_row == NULL
13633 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
13635 /* If this is a continuation line, move forward to the next one
13636 that isn't. Changes in lines above affect this line.
13637 Caution: this may move first_unchanged_at_end_row to a row
13638 not displaying text. */
13639 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
13640 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
13641 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
13642 < it.last_visible_y))
13643 ++first_unchanged_at_end_row;
13645 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
13646 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
13647 >= it.last_visible_y))
13648 first_unchanged_at_end_row = NULL;
13649 else
13651 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
13652 + delta);
13653 first_unchanged_at_end_vpos
13654 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
13655 xassert (stop_pos >= Z - END_UNCHANGED);
13658 else if (last_unchanged_at_beg_row == NULL)
13659 GIVE_UP (19);
13662 #if GLYPH_DEBUG
13664 /* Either there is no unchanged row at the end, or the one we have
13665 now displays text. This is a necessary condition for the window
13666 end pos calculation at the end of this function. */
13667 xassert (first_unchanged_at_end_row == NULL
13668 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
13670 debug_last_unchanged_at_beg_vpos
13671 = (last_unchanged_at_beg_row
13672 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
13673 : -1);
13674 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
13676 #endif /* GLYPH_DEBUG != 0 */
13679 /* Display new lines. Set last_text_row to the last new line
13680 displayed which has text on it, i.e. might end up as being the
13681 line where the window_end_vpos is. */
13682 w->cursor.vpos = -1;
13683 last_text_row = NULL;
13684 overlay_arrow_seen = 0;
13685 while (it.current_y < it.last_visible_y
13686 && !fonts_changed_p
13687 && (first_unchanged_at_end_row == NULL
13688 || IT_CHARPOS (it) < stop_pos))
13690 if (display_line (&it))
13691 last_text_row = it.glyph_row - 1;
13694 if (fonts_changed_p)
13695 return -1;
13698 /* Compute differences in buffer positions, y-positions etc. for
13699 lines reused at the bottom of the window. Compute what we can
13700 scroll. */
13701 if (first_unchanged_at_end_row
13702 /* No lines reused because we displayed everything up to the
13703 bottom of the window. */
13704 && it.current_y < it.last_visible_y)
13706 dvpos = (it.vpos
13707 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
13708 current_matrix));
13709 dy = it.current_y - first_unchanged_at_end_row->y;
13710 run.current_y = first_unchanged_at_end_row->y;
13711 run.desired_y = run.current_y + dy;
13712 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
13714 else
13716 delta = dvpos = dy = run.current_y = run.desired_y = run.height = 0;
13717 first_unchanged_at_end_row = NULL;
13719 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
13722 /* Find the cursor if not already found. We have to decide whether
13723 PT will appear on this window (it sometimes doesn't, but this is
13724 not a very frequent case.) This decision has to be made before
13725 the current matrix is altered. A value of cursor.vpos < 0 means
13726 that PT is either in one of the lines beginning at
13727 first_unchanged_at_end_row or below the window. Don't care for
13728 lines that might be displayed later at the window end; as
13729 mentioned, this is not a frequent case. */
13730 if (w->cursor.vpos < 0)
13732 /* Cursor in unchanged rows at the top? */
13733 if (PT < CHARPOS (start_pos)
13734 && last_unchanged_at_beg_row)
13736 row = row_containing_pos (w, PT,
13737 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
13738 last_unchanged_at_beg_row + 1, 0);
13739 if (row)
13740 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
13743 /* Start from first_unchanged_at_end_row looking for PT. */
13744 else if (first_unchanged_at_end_row)
13746 row = row_containing_pos (w, PT - delta,
13747 first_unchanged_at_end_row, NULL, 0);
13748 if (row)
13749 set_cursor_from_row (w, row, w->current_matrix, delta,
13750 delta_bytes, dy, dvpos);
13753 /* Give up if cursor was not found. */
13754 if (w->cursor.vpos < 0)
13756 clear_glyph_matrix (w->desired_matrix);
13757 return -1;
13761 /* Don't let the cursor end in the scroll margins. */
13763 int this_scroll_margin, cursor_height;
13765 this_scroll_margin = max (0, scroll_margin);
13766 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
13767 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
13768 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
13770 if ((w->cursor.y < this_scroll_margin
13771 && CHARPOS (start) > BEGV)
13772 /* Old redisplay didn't take scroll margin into account at the bottom,
13773 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
13774 || (w->cursor.y + (make_cursor_line_fully_visible_p
13775 ? cursor_height + this_scroll_margin
13776 : 1)) > it.last_visible_y)
13778 w->cursor.vpos = -1;
13779 clear_glyph_matrix (w->desired_matrix);
13780 return -1;
13784 /* Scroll the display. Do it before changing the current matrix so
13785 that xterm.c doesn't get confused about where the cursor glyph is
13786 found. */
13787 if (dy && run.height)
13789 update_begin (f);
13791 if (FRAME_WINDOW_P (f))
13793 rif->update_window_begin_hook (w);
13794 rif->clear_window_mouse_face (w);
13795 rif->scroll_run_hook (w, &run);
13796 rif->update_window_end_hook (w, 0, 0);
13798 else
13800 /* Terminal frame. In this case, dvpos gives the number of
13801 lines to scroll by; dvpos < 0 means scroll up. */
13802 int first_unchanged_at_end_vpos
13803 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
13804 int from = WINDOW_TOP_EDGE_LINE (w) + first_unchanged_at_end_vpos;
13805 int end = (WINDOW_TOP_EDGE_LINE (w)
13806 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
13807 + window_internal_height (w));
13809 /* Perform the operation on the screen. */
13810 if (dvpos > 0)
13812 /* Scroll last_unchanged_at_beg_row to the end of the
13813 window down dvpos lines. */
13814 set_terminal_window (end);
13816 /* On dumb terminals delete dvpos lines at the end
13817 before inserting dvpos empty lines. */
13818 if (!scroll_region_ok)
13819 ins_del_lines (end - dvpos, -dvpos);
13821 /* Insert dvpos empty lines in front of
13822 last_unchanged_at_beg_row. */
13823 ins_del_lines (from, dvpos);
13825 else if (dvpos < 0)
13827 /* Scroll up last_unchanged_at_beg_vpos to the end of
13828 the window to last_unchanged_at_beg_vpos - |dvpos|. */
13829 set_terminal_window (end);
13831 /* Delete dvpos lines in front of
13832 last_unchanged_at_beg_vpos. ins_del_lines will set
13833 the cursor to the given vpos and emit |dvpos| delete
13834 line sequences. */
13835 ins_del_lines (from + dvpos, dvpos);
13837 /* On a dumb terminal insert dvpos empty lines at the
13838 end. */
13839 if (!scroll_region_ok)
13840 ins_del_lines (end + dvpos, -dvpos);
13843 set_terminal_window (0);
13846 update_end (f);
13849 /* Shift reused rows of the current matrix to the right position.
13850 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
13851 text. */
13852 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
13853 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
13854 if (dvpos < 0)
13856 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
13857 bottom_vpos, dvpos);
13858 enable_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
13859 bottom_vpos, 0);
13861 else if (dvpos > 0)
13863 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
13864 bottom_vpos, dvpos);
13865 enable_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
13866 first_unchanged_at_end_vpos + dvpos, 0);
13869 /* For frame-based redisplay, make sure that current frame and window
13870 matrix are in sync with respect to glyph memory. */
13871 if (!FRAME_WINDOW_P (f))
13872 sync_frame_with_window_matrix_rows (w);
13874 /* Adjust buffer positions in reused rows. */
13875 if (delta)
13876 increment_matrix_positions (current_matrix,
13877 first_unchanged_at_end_vpos + dvpos,
13878 bottom_vpos, delta, delta_bytes);
13880 /* Adjust Y positions. */
13881 if (dy)
13882 shift_glyph_matrix (w, current_matrix,
13883 first_unchanged_at_end_vpos + dvpos,
13884 bottom_vpos, dy);
13886 if (first_unchanged_at_end_row)
13888 first_unchanged_at_end_row += dvpos;
13889 if (first_unchanged_at_end_row->y >= it.last_visible_y
13890 || !MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row))
13891 first_unchanged_at_end_row = NULL;
13894 /* If scrolling up, there may be some lines to display at the end of
13895 the window. */
13896 last_text_row_at_end = NULL;
13897 if (dy < 0)
13899 /* Scrolling up can leave for example a partially visible line
13900 at the end of the window to be redisplayed. */
13901 /* Set last_row to the glyph row in the current matrix where the
13902 window end line is found. It has been moved up or down in
13903 the matrix by dvpos. */
13904 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
13905 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
13907 /* If last_row is the window end line, it should display text. */
13908 xassert (last_row->displays_text_p);
13910 /* If window end line was partially visible before, begin
13911 displaying at that line. Otherwise begin displaying with the
13912 line following it. */
13913 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
13915 init_to_row_start (&it, w, last_row);
13916 it.vpos = last_vpos;
13917 it.current_y = last_row->y;
13919 else
13921 init_to_row_end (&it, w, last_row);
13922 it.vpos = 1 + last_vpos;
13923 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
13924 ++last_row;
13927 /* We may start in a continuation line. If so, we have to
13928 get the right continuation_lines_width and current_x. */
13929 it.continuation_lines_width = last_row->continuation_lines_width;
13930 it.hpos = it.current_x = 0;
13932 /* Display the rest of the lines at the window end. */
13933 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
13934 while (it.current_y < it.last_visible_y
13935 && !fonts_changed_p)
13937 /* Is it always sure that the display agrees with lines in
13938 the current matrix? I don't think so, so we mark rows
13939 displayed invalid in the current matrix by setting their
13940 enabled_p flag to zero. */
13941 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
13942 if (display_line (&it))
13943 last_text_row_at_end = it.glyph_row - 1;
13947 /* Update window_end_pos and window_end_vpos. */
13948 if (first_unchanged_at_end_row
13949 && !last_text_row_at_end)
13951 /* Window end line if one of the preserved rows from the current
13952 matrix. Set row to the last row displaying text in current
13953 matrix starting at first_unchanged_at_end_row, after
13954 scrolling. */
13955 xassert (first_unchanged_at_end_row->displays_text_p);
13956 row = find_last_row_displaying_text (w->current_matrix, &it,
13957 first_unchanged_at_end_row);
13958 xassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
13960 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13961 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13962 w->window_end_vpos
13963 = make_number (MATRIX_ROW_VPOS (row, w->current_matrix));
13964 xassert (w->window_end_bytepos >= 0);
13965 IF_DEBUG (debug_method_add (w, "A"));
13967 else if (last_text_row_at_end)
13969 w->window_end_pos
13970 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end));
13971 w->window_end_bytepos
13972 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
13973 w->window_end_vpos
13974 = make_number (MATRIX_ROW_VPOS (last_text_row_at_end, desired_matrix));
13975 xassert (w->window_end_bytepos >= 0);
13976 IF_DEBUG (debug_method_add (w, "B"));
13978 else if (last_text_row)
13980 /* We have displayed either to the end of the window or at the
13981 end of the window, i.e. the last row with text is to be found
13982 in the desired matrix. */
13983 w->window_end_pos
13984 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
13985 w->window_end_bytepos
13986 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
13987 w->window_end_vpos
13988 = make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix));
13989 xassert (w->window_end_bytepos >= 0);
13991 else if (first_unchanged_at_end_row == NULL
13992 && last_text_row == NULL
13993 && last_text_row_at_end == NULL)
13995 /* Displayed to end of window, but no line containing text was
13996 displayed. Lines were deleted at the end of the window. */
13997 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
13998 int vpos = XFASTINT (w->window_end_vpos);
13999 struct glyph_row *current_row = current_matrix->rows + vpos;
14000 struct glyph_row *desired_row = desired_matrix->rows + vpos;
14002 for (row = NULL;
14003 row == NULL && vpos >= first_vpos;
14004 --vpos, --current_row, --desired_row)
14006 if (desired_row->enabled_p)
14008 if (desired_row->displays_text_p)
14009 row = desired_row;
14011 else if (current_row->displays_text_p)
14012 row = current_row;
14015 xassert (row != NULL);
14016 w->window_end_vpos = make_number (vpos + 1);
14017 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
14018 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
14019 xassert (w->window_end_bytepos >= 0);
14020 IF_DEBUG (debug_method_add (w, "C"));
14022 else
14023 abort ();
14025 #if 0 /* This leads to problems, for instance when the cursor is
14026 at ZV, and the cursor line displays no text. */
14027 /* Disable rows below what's displayed in the window. This makes
14028 debugging easier. */
14029 enable_glyph_matrix_rows (current_matrix,
14030 XFASTINT (w->window_end_vpos) + 1,
14031 bottom_vpos, 0);
14032 #endif
14034 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
14035 debug_end_vpos = XFASTINT (w->window_end_vpos));
14037 /* Record that display has not been completed. */
14038 w->window_end_valid = Qnil;
14039 w->desired_matrix->no_scrolling_p = 1;
14040 return 3;
14042 #undef GIVE_UP
14047 /***********************************************************************
14048 More debugging support
14049 ***********************************************************************/
14051 #if GLYPH_DEBUG
14053 void dump_glyph_row P_ ((struct glyph_row *, int, int));
14054 void dump_glyph_matrix P_ ((struct glyph_matrix *, int));
14055 void dump_glyph P_ ((struct glyph_row *, struct glyph *, int));
14058 /* Dump the contents of glyph matrix MATRIX on stderr.
14060 GLYPHS 0 means don't show glyph contents.
14061 GLYPHS 1 means show glyphs in short form
14062 GLYPHS > 1 means show glyphs in long form. */
14064 void
14065 dump_glyph_matrix (matrix, glyphs)
14066 struct glyph_matrix *matrix;
14067 int glyphs;
14069 int i;
14070 for (i = 0; i < matrix->nrows; ++i)
14071 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
14075 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
14076 the glyph row and area where the glyph comes from. */
14078 void
14079 dump_glyph (row, glyph, area)
14080 struct glyph_row *row;
14081 struct glyph *glyph;
14082 int area;
14084 if (glyph->type == CHAR_GLYPH)
14086 fprintf (stderr,
14087 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
14088 glyph - row->glyphs[TEXT_AREA],
14089 'C',
14090 glyph->charpos,
14091 (BUFFERP (glyph->object)
14092 ? 'B'
14093 : (STRINGP (glyph->object)
14094 ? 'S'
14095 : '-')),
14096 glyph->pixel_width,
14097 glyph->u.ch,
14098 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
14099 ? glyph->u.ch
14100 : '.'),
14101 glyph->face_id,
14102 glyph->left_box_line_p,
14103 glyph->right_box_line_p);
14105 else if (glyph->type == STRETCH_GLYPH)
14107 fprintf (stderr,
14108 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
14109 glyph - row->glyphs[TEXT_AREA],
14110 'S',
14111 glyph->charpos,
14112 (BUFFERP (glyph->object)
14113 ? 'B'
14114 : (STRINGP (glyph->object)
14115 ? 'S'
14116 : '-')),
14117 glyph->pixel_width,
14119 '.',
14120 glyph->face_id,
14121 glyph->left_box_line_p,
14122 glyph->right_box_line_p);
14124 else if (glyph->type == IMAGE_GLYPH)
14126 fprintf (stderr,
14127 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
14128 glyph - row->glyphs[TEXT_AREA],
14129 'I',
14130 glyph->charpos,
14131 (BUFFERP (glyph->object)
14132 ? 'B'
14133 : (STRINGP (glyph->object)
14134 ? 'S'
14135 : '-')),
14136 glyph->pixel_width,
14137 glyph->u.img_id,
14138 '.',
14139 glyph->face_id,
14140 glyph->left_box_line_p,
14141 glyph->right_box_line_p);
14146 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
14147 GLYPHS 0 means don't show glyph contents.
14148 GLYPHS 1 means show glyphs in short form
14149 GLYPHS > 1 means show glyphs in long form. */
14151 void
14152 dump_glyph_row (row, vpos, glyphs)
14153 struct glyph_row *row;
14154 int vpos, glyphs;
14156 if (glyphs != 1)
14158 fprintf (stderr, "Row Start End Used oEI><O\\CTZFesm X Y W H V A P\n");
14159 fprintf (stderr, "=======================================================================\n");
14161 fprintf (stderr, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d%1.1d\
14162 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
14163 vpos,
14164 MATRIX_ROW_START_CHARPOS (row),
14165 MATRIX_ROW_END_CHARPOS (row),
14166 row->used[TEXT_AREA],
14167 row->contains_overlapping_glyphs_p,
14168 row->enabled_p,
14169 row->truncated_on_left_p,
14170 row->truncated_on_right_p,
14171 row->overlay_arrow_p,
14172 row->continued_p,
14173 MATRIX_ROW_CONTINUATION_LINE_P (row),
14174 row->displays_text_p,
14175 row->ends_at_zv_p,
14176 row->fill_line_p,
14177 row->ends_in_middle_of_char_p,
14178 row->starts_in_middle_of_char_p,
14179 row->mouse_face_p,
14180 row->x,
14181 row->y,
14182 row->pixel_width,
14183 row->height,
14184 row->visible_height,
14185 row->ascent,
14186 row->phys_ascent);
14187 fprintf (stderr, "%9d %5d\t%5d\n", row->start.overlay_string_index,
14188 row->end.overlay_string_index,
14189 row->continuation_lines_width);
14190 fprintf (stderr, "%9d %5d\n",
14191 CHARPOS (row->start.string_pos),
14192 CHARPOS (row->end.string_pos));
14193 fprintf (stderr, "%9d %5d\n", row->start.dpvec_index,
14194 row->end.dpvec_index);
14197 if (glyphs > 1)
14199 int area;
14201 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
14203 struct glyph *glyph = row->glyphs[area];
14204 struct glyph *glyph_end = glyph + row->used[area];
14206 /* Glyph for a line end in text. */
14207 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
14208 ++glyph_end;
14210 if (glyph < glyph_end)
14211 fprintf (stderr, " Glyph Type Pos O W Code C Face LR\n");
14213 for (; glyph < glyph_end; ++glyph)
14214 dump_glyph (row, glyph, area);
14217 else if (glyphs == 1)
14219 int area;
14221 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
14223 char *s = (char *) alloca (row->used[area] + 1);
14224 int i;
14226 for (i = 0; i < row->used[area]; ++i)
14228 struct glyph *glyph = row->glyphs[area] + i;
14229 if (glyph->type == CHAR_GLYPH
14230 && glyph->u.ch < 0x80
14231 && glyph->u.ch >= ' ')
14232 s[i] = glyph->u.ch;
14233 else
14234 s[i] = '.';
14237 s[i] = '\0';
14238 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
14244 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
14245 Sdump_glyph_matrix, 0, 1, "p",
14246 doc: /* Dump the current matrix of the selected window to stderr.
14247 Shows contents of glyph row structures. With non-nil
14248 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
14249 glyphs in short form, otherwise show glyphs in long form. */)
14250 (glyphs)
14251 Lisp_Object glyphs;
14253 struct window *w = XWINDOW (selected_window);
14254 struct buffer *buffer = XBUFFER (w->buffer);
14256 fprintf (stderr, "PT = %d, BEGV = %d. ZV = %d\n",
14257 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
14258 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
14259 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
14260 fprintf (stderr, "=============================================\n");
14261 dump_glyph_matrix (w->current_matrix,
14262 NILP (glyphs) ? 0 : XINT (glyphs));
14263 return Qnil;
14267 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
14268 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
14271 struct frame *f = XFRAME (selected_frame);
14272 dump_glyph_matrix (f->current_matrix, 1);
14273 return Qnil;
14277 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
14278 doc: /* Dump glyph row ROW to stderr.
14279 GLYPH 0 means don't dump glyphs.
14280 GLYPH 1 means dump glyphs in short form.
14281 GLYPH > 1 or omitted means dump glyphs in long form. */)
14282 (row, glyphs)
14283 Lisp_Object row, glyphs;
14285 struct glyph_matrix *matrix;
14286 int vpos;
14288 CHECK_NUMBER (row);
14289 matrix = XWINDOW (selected_window)->current_matrix;
14290 vpos = XINT (row);
14291 if (vpos >= 0 && vpos < matrix->nrows)
14292 dump_glyph_row (MATRIX_ROW (matrix, vpos),
14293 vpos,
14294 INTEGERP (glyphs) ? XINT (glyphs) : 2);
14295 return Qnil;
14299 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
14300 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
14301 GLYPH 0 means don't dump glyphs.
14302 GLYPH 1 means dump glyphs in short form.
14303 GLYPH > 1 or omitted means dump glyphs in long form. */)
14304 (row, glyphs)
14305 Lisp_Object row, glyphs;
14307 struct frame *sf = SELECTED_FRAME ();
14308 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
14309 int vpos;
14311 CHECK_NUMBER (row);
14312 vpos = XINT (row);
14313 if (vpos >= 0 && vpos < m->nrows)
14314 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
14315 INTEGERP (glyphs) ? XINT (glyphs) : 2);
14316 return Qnil;
14320 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
14321 doc: /* Toggle tracing of redisplay.
14322 With ARG, turn tracing on if and only if ARG is positive. */)
14323 (arg)
14324 Lisp_Object arg;
14326 if (NILP (arg))
14327 trace_redisplay_p = !trace_redisplay_p;
14328 else
14330 arg = Fprefix_numeric_value (arg);
14331 trace_redisplay_p = XINT (arg) > 0;
14334 return Qnil;
14338 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
14339 doc: /* Like `format', but print result to stderr.
14340 usage: (trace-to-stderr STRING &rest OBJECTS) */)
14341 (nargs, args)
14342 int nargs;
14343 Lisp_Object *args;
14345 Lisp_Object s = Fformat (nargs, args);
14346 fprintf (stderr, "%s", SDATA (s));
14347 return Qnil;
14350 #endif /* GLYPH_DEBUG */
14354 /***********************************************************************
14355 Building Desired Matrix Rows
14356 ***********************************************************************/
14358 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
14359 Used for non-window-redisplay windows, and for windows w/o left fringe. */
14361 static struct glyph_row *
14362 get_overlay_arrow_glyph_row (w, overlay_arrow_string)
14363 struct window *w;
14364 Lisp_Object overlay_arrow_string;
14366 struct frame *f = XFRAME (WINDOW_FRAME (w));
14367 struct buffer *buffer = XBUFFER (w->buffer);
14368 struct buffer *old = current_buffer;
14369 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
14370 int arrow_len = SCHARS (overlay_arrow_string);
14371 const unsigned char *arrow_end = arrow_string + arrow_len;
14372 const unsigned char *p;
14373 struct it it;
14374 int multibyte_p;
14375 int n_glyphs_before;
14377 set_buffer_temp (buffer);
14378 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
14379 it.glyph_row->used[TEXT_AREA] = 0;
14380 SET_TEXT_POS (it.position, 0, 0);
14382 multibyte_p = !NILP (buffer->enable_multibyte_characters);
14383 p = arrow_string;
14384 while (p < arrow_end)
14386 Lisp_Object face, ilisp;
14388 /* Get the next character. */
14389 if (multibyte_p)
14390 it.c = string_char_and_length (p, arrow_len, &it.len);
14391 else
14392 it.c = *p, it.len = 1;
14393 p += it.len;
14395 /* Get its face. */
14396 ilisp = make_number (p - arrow_string);
14397 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
14398 it.face_id = compute_char_face (f, it.c, face);
14400 /* Compute its width, get its glyphs. */
14401 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
14402 SET_TEXT_POS (it.position, -1, -1);
14403 PRODUCE_GLYPHS (&it);
14405 /* If this character doesn't fit any more in the line, we have
14406 to remove some glyphs. */
14407 if (it.current_x > it.last_visible_x)
14409 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
14410 break;
14414 set_buffer_temp (old);
14415 return it.glyph_row;
14419 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
14420 glyphs are only inserted for terminal frames since we can't really
14421 win with truncation glyphs when partially visible glyphs are
14422 involved. Which glyphs to insert is determined by
14423 produce_special_glyphs. */
14425 static void
14426 insert_left_trunc_glyphs (it)
14427 struct it *it;
14429 struct it truncate_it;
14430 struct glyph *from, *end, *to, *toend;
14432 xassert (!FRAME_WINDOW_P (it->f));
14434 /* Get the truncation glyphs. */
14435 truncate_it = *it;
14436 truncate_it.current_x = 0;
14437 truncate_it.face_id = DEFAULT_FACE_ID;
14438 truncate_it.glyph_row = &scratch_glyph_row;
14439 truncate_it.glyph_row->used[TEXT_AREA] = 0;
14440 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
14441 truncate_it.object = make_number (0);
14442 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
14444 /* Overwrite glyphs from IT with truncation glyphs. */
14445 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
14446 end = from + truncate_it.glyph_row->used[TEXT_AREA];
14447 to = it->glyph_row->glyphs[TEXT_AREA];
14448 toend = to + it->glyph_row->used[TEXT_AREA];
14450 while (from < end)
14451 *to++ = *from++;
14453 /* There may be padding glyphs left over. Overwrite them too. */
14454 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
14456 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
14457 while (from < end)
14458 *to++ = *from++;
14461 if (to > toend)
14462 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
14466 /* Compute the pixel height and width of IT->glyph_row.
14468 Most of the time, ascent and height of a display line will be equal
14469 to the max_ascent and max_height values of the display iterator
14470 structure. This is not the case if
14472 1. We hit ZV without displaying anything. In this case, max_ascent
14473 and max_height will be zero.
14475 2. We have some glyphs that don't contribute to the line height.
14476 (The glyph row flag contributes_to_line_height_p is for future
14477 pixmap extensions).
14479 The first case is easily covered by using default values because in
14480 these cases, the line height does not really matter, except that it
14481 must not be zero. */
14483 static void
14484 compute_line_metrics (it)
14485 struct it *it;
14487 struct glyph_row *row = it->glyph_row;
14488 int area, i;
14490 if (FRAME_WINDOW_P (it->f))
14492 int i, min_y, max_y;
14494 /* The line may consist of one space only, that was added to
14495 place the cursor on it. If so, the row's height hasn't been
14496 computed yet. */
14497 if (row->height == 0)
14499 if (it->max_ascent + it->max_descent == 0)
14500 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
14501 row->ascent = it->max_ascent;
14502 row->height = it->max_ascent + it->max_descent;
14503 row->phys_ascent = it->max_phys_ascent;
14504 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
14505 row->extra_line_spacing = it->max_extra_line_spacing;
14508 /* Compute the width of this line. */
14509 row->pixel_width = row->x;
14510 for (i = 0; i < row->used[TEXT_AREA]; ++i)
14511 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
14513 xassert (row->pixel_width >= 0);
14514 xassert (row->ascent >= 0 && row->height > 0);
14516 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
14517 || MATRIX_ROW_OVERLAPS_PRED_P (row));
14519 /* If first line's physical ascent is larger than its logical
14520 ascent, use the physical ascent, and make the row taller.
14521 This makes accented characters fully visible. */
14522 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
14523 && row->phys_ascent > row->ascent)
14525 row->height += row->phys_ascent - row->ascent;
14526 row->ascent = row->phys_ascent;
14529 /* Compute how much of the line is visible. */
14530 row->visible_height = row->height;
14532 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
14533 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
14535 if (row->y < min_y)
14536 row->visible_height -= min_y - row->y;
14537 if (row->y + row->height > max_y)
14538 row->visible_height -= row->y + row->height - max_y;
14540 else
14542 row->pixel_width = row->used[TEXT_AREA];
14543 if (row->continued_p)
14544 row->pixel_width -= it->continuation_pixel_width;
14545 else if (row->truncated_on_right_p)
14546 row->pixel_width -= it->truncation_pixel_width;
14547 row->ascent = row->phys_ascent = 0;
14548 row->height = row->phys_height = row->visible_height = 1;
14549 row->extra_line_spacing = 0;
14552 /* Compute a hash code for this row. */
14553 row->hash = 0;
14554 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
14555 for (i = 0; i < row->used[area]; ++i)
14556 row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff)
14557 + row->glyphs[area][i].u.val
14558 + row->glyphs[area][i].face_id
14559 + row->glyphs[area][i].padding_p
14560 + (row->glyphs[area][i].type << 2));
14562 it->max_ascent = it->max_descent = 0;
14563 it->max_phys_ascent = it->max_phys_descent = 0;
14567 /* Append one space to the glyph row of iterator IT if doing a
14568 window-based redisplay. The space has the same face as
14569 IT->face_id. Value is non-zero if a space was added.
14571 This function is called to make sure that there is always one glyph
14572 at the end of a glyph row that the cursor can be set on under
14573 window-systems. (If there weren't such a glyph we would not know
14574 how wide and tall a box cursor should be displayed).
14576 At the same time this space let's a nicely handle clearing to the
14577 end of the line if the row ends in italic text. */
14579 static int
14580 append_space_for_newline (it, default_face_p)
14581 struct it *it;
14582 int default_face_p;
14584 if (FRAME_WINDOW_P (it->f))
14586 int n = it->glyph_row->used[TEXT_AREA];
14588 if (it->glyph_row->glyphs[TEXT_AREA] + n
14589 < it->glyph_row->glyphs[1 + TEXT_AREA])
14591 /* Save some values that must not be changed.
14592 Must save IT->c and IT->len because otherwise
14593 ITERATOR_AT_END_P wouldn't work anymore after
14594 append_space_for_newline has been called. */
14595 enum display_element_type saved_what = it->what;
14596 int saved_c = it->c, saved_len = it->len;
14597 int saved_x = it->current_x;
14598 int saved_face_id = it->face_id;
14599 struct text_pos saved_pos;
14600 Lisp_Object saved_object;
14601 struct face *face;
14603 saved_object = it->object;
14604 saved_pos = it->position;
14606 it->what = IT_CHARACTER;
14607 bzero (&it->position, sizeof it->position);
14608 it->object = make_number (0);
14609 it->c = ' ';
14610 it->len = 1;
14612 if (default_face_p)
14613 it->face_id = DEFAULT_FACE_ID;
14614 else if (it->face_before_selective_p)
14615 it->face_id = it->saved_face_id;
14616 face = FACE_FROM_ID (it->f, it->face_id);
14617 it->face_id = FACE_FOR_CHAR (it->f, face, 0);
14619 PRODUCE_GLYPHS (it);
14621 it->override_ascent = -1;
14622 it->constrain_row_ascent_descent_p = 0;
14623 it->current_x = saved_x;
14624 it->object = saved_object;
14625 it->position = saved_pos;
14626 it->what = saved_what;
14627 it->face_id = saved_face_id;
14628 it->len = saved_len;
14629 it->c = saved_c;
14630 return 1;
14634 return 0;
14638 /* Extend the face of the last glyph in the text area of IT->glyph_row
14639 to the end of the display line. Called from display_line.
14640 If the glyph row is empty, add a space glyph to it so that we
14641 know the face to draw. Set the glyph row flag fill_line_p. */
14643 static void
14644 extend_face_to_end_of_line (it)
14645 struct it *it;
14647 struct face *face;
14648 struct frame *f = it->f;
14650 /* If line is already filled, do nothing. */
14651 if (it->current_x >= it->last_visible_x)
14652 return;
14654 /* Face extension extends the background and box of IT->face_id
14655 to the end of the line. If the background equals the background
14656 of the frame, we don't have to do anything. */
14657 if (it->face_before_selective_p)
14658 face = FACE_FROM_ID (it->f, it->saved_face_id);
14659 else
14660 face = FACE_FROM_ID (f, it->face_id);
14662 if (FRAME_WINDOW_P (f)
14663 && face->box == FACE_NO_BOX
14664 && face->background == FRAME_BACKGROUND_PIXEL (f)
14665 && !face->stipple)
14666 return;
14668 /* Set the glyph row flag indicating that the face of the last glyph
14669 in the text area has to be drawn to the end of the text area. */
14670 it->glyph_row->fill_line_p = 1;
14672 /* If current character of IT is not ASCII, make sure we have the
14673 ASCII face. This will be automatically undone the next time
14674 get_next_display_element returns a multibyte character. Note
14675 that the character will always be single byte in unibyte text. */
14676 if (!SINGLE_BYTE_CHAR_P (it->c))
14678 it->face_id = FACE_FOR_CHAR (f, face, 0);
14681 if (FRAME_WINDOW_P (f))
14683 /* If the row is empty, add a space with the current face of IT,
14684 so that we know which face to draw. */
14685 if (it->glyph_row->used[TEXT_AREA] == 0)
14687 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
14688 it->glyph_row->glyphs[TEXT_AREA][0].face_id = it->face_id;
14689 it->glyph_row->used[TEXT_AREA] = 1;
14692 else
14694 /* Save some values that must not be changed. */
14695 int saved_x = it->current_x;
14696 struct text_pos saved_pos;
14697 Lisp_Object saved_object;
14698 enum display_element_type saved_what = it->what;
14699 int saved_face_id = it->face_id;
14701 saved_object = it->object;
14702 saved_pos = it->position;
14704 it->what = IT_CHARACTER;
14705 bzero (&it->position, sizeof it->position);
14706 it->object = make_number (0);
14707 it->c = ' ';
14708 it->len = 1;
14709 it->face_id = face->id;
14711 PRODUCE_GLYPHS (it);
14713 while (it->current_x <= it->last_visible_x)
14714 PRODUCE_GLYPHS (it);
14716 /* Don't count these blanks really. It would let us insert a left
14717 truncation glyph below and make us set the cursor on them, maybe. */
14718 it->current_x = saved_x;
14719 it->object = saved_object;
14720 it->position = saved_pos;
14721 it->what = saved_what;
14722 it->face_id = saved_face_id;
14727 /* Value is non-zero if text starting at CHARPOS in current_buffer is
14728 trailing whitespace. */
14730 static int
14731 trailing_whitespace_p (charpos)
14732 int charpos;
14734 int bytepos = CHAR_TO_BYTE (charpos);
14735 int c = 0;
14737 while (bytepos < ZV_BYTE
14738 && (c = FETCH_CHAR (bytepos),
14739 c == ' ' || c == '\t'))
14740 ++bytepos;
14742 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
14744 if (bytepos != PT_BYTE)
14745 return 1;
14747 return 0;
14751 /* Highlight trailing whitespace, if any, in ROW. */
14753 void
14754 highlight_trailing_whitespace (f, row)
14755 struct frame *f;
14756 struct glyph_row *row;
14758 int used = row->used[TEXT_AREA];
14760 if (used)
14762 struct glyph *start = row->glyphs[TEXT_AREA];
14763 struct glyph *glyph = start + used - 1;
14765 /* Skip over glyphs inserted to display the cursor at the
14766 end of a line, for extending the face of the last glyph
14767 to the end of the line on terminals, and for truncation
14768 and continuation glyphs. */
14769 while (glyph >= start
14770 && glyph->type == CHAR_GLYPH
14771 && INTEGERP (glyph->object))
14772 --glyph;
14774 /* If last glyph is a space or stretch, and it's trailing
14775 whitespace, set the face of all trailing whitespace glyphs in
14776 IT->glyph_row to `trailing-whitespace'. */
14777 if (glyph >= start
14778 && BUFFERP (glyph->object)
14779 && (glyph->type == STRETCH_GLYPH
14780 || (glyph->type == CHAR_GLYPH
14781 && glyph->u.ch == ' '))
14782 && trailing_whitespace_p (glyph->charpos))
14784 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0, 0);
14785 if (face_id < 0)
14786 return;
14788 while (glyph >= start
14789 && BUFFERP (glyph->object)
14790 && (glyph->type == STRETCH_GLYPH
14791 || (glyph->type == CHAR_GLYPH
14792 && glyph->u.ch == ' ')))
14793 (glyph--)->face_id = face_id;
14799 /* Value is non-zero if glyph row ROW in window W should be
14800 used to hold the cursor. */
14802 static int
14803 cursor_row_p (w, row)
14804 struct window *w;
14805 struct glyph_row *row;
14807 int cursor_row_p = 1;
14809 if (PT == MATRIX_ROW_END_CHARPOS (row))
14811 /* If the row ends with a newline from a string, we don't want
14812 the cursor there (if the row is continued it doesn't end in a
14813 newline). */
14814 if (CHARPOS (row->end.string_pos) >= 0)
14815 cursor_row_p = row->continued_p;
14816 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
14818 /* If the row ends in middle of a real character,
14819 and the line is continued, we want the cursor here.
14820 That's because MATRIX_ROW_END_CHARPOS would equal
14821 PT if PT is before the character. */
14822 if (!row->ends_in_ellipsis_p)
14823 cursor_row_p = row->continued_p;
14824 else
14825 /* If the row ends in an ellipsis, then
14826 MATRIX_ROW_END_CHARPOS will equal point after the invisible text.
14827 We want that position to be displayed after the ellipsis. */
14828 cursor_row_p = 0;
14830 /* If the row ends at ZV, display the cursor at the end of that
14831 row instead of at the start of the row below. */
14832 else if (row->ends_at_zv_p)
14833 cursor_row_p = 1;
14834 else
14835 cursor_row_p = 0;
14838 return cursor_row_p;
14842 /* Construct the glyph row IT->glyph_row in the desired matrix of
14843 IT->w from text at the current position of IT. See dispextern.h
14844 for an overview of struct it. Value is non-zero if
14845 IT->glyph_row displays text, as opposed to a line displaying ZV
14846 only. */
14848 static int
14849 display_line (it)
14850 struct it *it;
14852 struct glyph_row *row = it->glyph_row;
14853 Lisp_Object overlay_arrow_string;
14855 /* We always start displaying at hpos zero even if hscrolled. */
14856 xassert (it->hpos == 0 && it->current_x == 0);
14858 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
14859 >= it->w->desired_matrix->nrows)
14861 it->w->nrows_scale_factor++;
14862 fonts_changed_p = 1;
14863 return 0;
14866 /* Is IT->w showing the region? */
14867 it->w->region_showing = it->region_beg_charpos > 0 ? Qt : Qnil;
14869 /* Clear the result glyph row and enable it. */
14870 prepare_desired_row (row);
14872 row->y = it->current_y;
14873 row->start = it->start;
14874 row->continuation_lines_width = it->continuation_lines_width;
14875 row->displays_text_p = 1;
14876 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
14877 it->starts_in_middle_of_char_p = 0;
14879 /* Arrange the overlays nicely for our purposes. Usually, we call
14880 display_line on only one line at a time, in which case this
14881 can't really hurt too much, or we call it on lines which appear
14882 one after another in the buffer, in which case all calls to
14883 recenter_overlay_lists but the first will be pretty cheap. */
14884 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
14886 /* Move over display elements that are not visible because we are
14887 hscrolled. This may stop at an x-position < IT->first_visible_x
14888 if the first glyph is partially visible or if we hit a line end. */
14889 if (it->current_x < it->first_visible_x)
14891 move_it_in_display_line_to (it, ZV, it->first_visible_x,
14892 MOVE_TO_POS | MOVE_TO_X);
14895 /* Get the initial row height. This is either the height of the
14896 text hscrolled, if there is any, or zero. */
14897 row->ascent = it->max_ascent;
14898 row->height = it->max_ascent + it->max_descent;
14899 row->phys_ascent = it->max_phys_ascent;
14900 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
14901 row->extra_line_spacing = it->max_extra_line_spacing;
14903 /* Loop generating characters. The loop is left with IT on the next
14904 character to display. */
14905 while (1)
14907 int n_glyphs_before, hpos_before, x_before;
14908 int x, i, nglyphs;
14909 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
14911 /* Retrieve the next thing to display. Value is zero if end of
14912 buffer reached. */
14913 if (!get_next_display_element (it))
14915 /* Maybe add a space at the end of this line that is used to
14916 display the cursor there under X. Set the charpos of the
14917 first glyph of blank lines not corresponding to any text
14918 to -1. */
14919 #ifdef HAVE_WINDOW_SYSTEM
14920 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14921 row->exact_window_width_line_p = 1;
14922 else
14923 #endif /* HAVE_WINDOW_SYSTEM */
14924 if ((append_space_for_newline (it, 1) && row->used[TEXT_AREA] == 1)
14925 || row->used[TEXT_AREA] == 0)
14927 row->glyphs[TEXT_AREA]->charpos = -1;
14928 row->displays_text_p = 0;
14930 if (!NILP (XBUFFER (it->w->buffer)->indicate_empty_lines)
14931 && (!MINI_WINDOW_P (it->w)
14932 || (minibuf_level && EQ (it->window, minibuf_window))))
14933 row->indicate_empty_line_p = 1;
14936 it->continuation_lines_width = 0;
14937 row->ends_at_zv_p = 1;
14938 break;
14941 /* Now, get the metrics of what we want to display. This also
14942 generates glyphs in `row' (which is IT->glyph_row). */
14943 n_glyphs_before = row->used[TEXT_AREA];
14944 x = it->current_x;
14946 /* Remember the line height so far in case the next element doesn't
14947 fit on the line. */
14948 if (!it->truncate_lines_p)
14950 ascent = it->max_ascent;
14951 descent = it->max_descent;
14952 phys_ascent = it->max_phys_ascent;
14953 phys_descent = it->max_phys_descent;
14956 PRODUCE_GLYPHS (it);
14958 /* If this display element was in marginal areas, continue with
14959 the next one. */
14960 if (it->area != TEXT_AREA)
14962 row->ascent = max (row->ascent, it->max_ascent);
14963 row->height = max (row->height, it->max_ascent + it->max_descent);
14964 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14965 row->phys_height = max (row->phys_height,
14966 it->max_phys_ascent + it->max_phys_descent);
14967 row->extra_line_spacing = max (row->extra_line_spacing,
14968 it->max_extra_line_spacing);
14969 set_iterator_to_next (it, 1);
14970 continue;
14973 /* Does the display element fit on the line? If we truncate
14974 lines, we should draw past the right edge of the window. If
14975 we don't truncate, we want to stop so that we can display the
14976 continuation glyph before the right margin. If lines are
14977 continued, there are two possible strategies for characters
14978 resulting in more than 1 glyph (e.g. tabs): Display as many
14979 glyphs as possible in this line and leave the rest for the
14980 continuation line, or display the whole element in the next
14981 line. Original redisplay did the former, so we do it also. */
14982 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
14983 hpos_before = it->hpos;
14984 x_before = x;
14986 if (/* Not a newline. */
14987 nglyphs > 0
14988 /* Glyphs produced fit entirely in the line. */
14989 && it->current_x < it->last_visible_x)
14991 it->hpos += nglyphs;
14992 row->ascent = max (row->ascent, it->max_ascent);
14993 row->height = max (row->height, it->max_ascent + it->max_descent);
14994 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14995 row->phys_height = max (row->phys_height,
14996 it->max_phys_ascent + it->max_phys_descent);
14997 row->extra_line_spacing = max (row->extra_line_spacing,
14998 it->max_extra_line_spacing);
14999 if (it->current_x - it->pixel_width < it->first_visible_x)
15000 row->x = x - it->first_visible_x;
15002 else
15004 int new_x;
15005 struct glyph *glyph;
15007 for (i = 0; i < nglyphs; ++i, x = new_x)
15009 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
15010 new_x = x + glyph->pixel_width;
15012 if (/* Lines are continued. */
15013 !it->truncate_lines_p
15014 && (/* Glyph doesn't fit on the line. */
15015 new_x > it->last_visible_x
15016 /* Or it fits exactly on a window system frame. */
15017 || (new_x == it->last_visible_x
15018 && FRAME_WINDOW_P (it->f))))
15020 /* End of a continued line. */
15022 if (it->hpos == 0
15023 || (new_x == it->last_visible_x
15024 && FRAME_WINDOW_P (it->f)))
15026 /* Current glyph is the only one on the line or
15027 fits exactly on the line. We must continue
15028 the line because we can't draw the cursor
15029 after the glyph. */
15030 row->continued_p = 1;
15031 it->current_x = new_x;
15032 it->continuation_lines_width += new_x;
15033 ++it->hpos;
15034 if (i == nglyphs - 1)
15036 set_iterator_to_next (it, 1);
15037 #ifdef HAVE_WINDOW_SYSTEM
15038 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
15040 if (!get_next_display_element (it))
15042 row->exact_window_width_line_p = 1;
15043 it->continuation_lines_width = 0;
15044 row->continued_p = 0;
15045 row->ends_at_zv_p = 1;
15047 else if (ITERATOR_AT_END_OF_LINE_P (it))
15049 row->continued_p = 0;
15050 row->exact_window_width_line_p = 1;
15053 #endif /* HAVE_WINDOW_SYSTEM */
15056 else if (CHAR_GLYPH_PADDING_P (*glyph)
15057 && !FRAME_WINDOW_P (it->f))
15059 /* A padding glyph that doesn't fit on this line.
15060 This means the whole character doesn't fit
15061 on the line. */
15062 row->used[TEXT_AREA] = n_glyphs_before;
15064 /* Fill the rest of the row with continuation
15065 glyphs like in 20.x. */
15066 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
15067 < row->glyphs[1 + TEXT_AREA])
15068 produce_special_glyphs (it, IT_CONTINUATION);
15070 row->continued_p = 1;
15071 it->current_x = x_before;
15072 it->continuation_lines_width += x_before;
15074 /* Restore the height to what it was before the
15075 element not fitting on the line. */
15076 it->max_ascent = ascent;
15077 it->max_descent = descent;
15078 it->max_phys_ascent = phys_ascent;
15079 it->max_phys_descent = phys_descent;
15081 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
15083 /* A TAB that extends past the right edge of the
15084 window. This produces a single glyph on
15085 window system frames. We leave the glyph in
15086 this row and let it fill the row, but don't
15087 consume the TAB. */
15088 it->continuation_lines_width += it->last_visible_x;
15089 row->ends_in_middle_of_char_p = 1;
15090 row->continued_p = 1;
15091 glyph->pixel_width = it->last_visible_x - x;
15092 it->starts_in_middle_of_char_p = 1;
15094 else
15096 /* Something other than a TAB that draws past
15097 the right edge of the window. Restore
15098 positions to values before the element. */
15099 row->used[TEXT_AREA] = n_glyphs_before + i;
15101 /* Display continuation glyphs. */
15102 if (!FRAME_WINDOW_P (it->f))
15103 produce_special_glyphs (it, IT_CONTINUATION);
15104 row->continued_p = 1;
15106 it->continuation_lines_width += x;
15108 if (nglyphs > 1 && i > 0)
15110 row->ends_in_middle_of_char_p = 1;
15111 it->starts_in_middle_of_char_p = 1;
15114 /* Restore the height to what it was before the
15115 element not fitting on the line. */
15116 it->max_ascent = ascent;
15117 it->max_descent = descent;
15118 it->max_phys_ascent = phys_ascent;
15119 it->max_phys_descent = phys_descent;
15122 break;
15124 else if (new_x > it->first_visible_x)
15126 /* Increment number of glyphs actually displayed. */
15127 ++it->hpos;
15129 if (x < it->first_visible_x)
15130 /* Glyph is partially visible, i.e. row starts at
15131 negative X position. */
15132 row->x = x - it->first_visible_x;
15134 else
15136 /* Glyph is completely off the left margin of the
15137 window. This should not happen because of the
15138 move_it_in_display_line at the start of this
15139 function, unless the text display area of the
15140 window is empty. */
15141 xassert (it->first_visible_x <= it->last_visible_x);
15145 row->ascent = max (row->ascent, it->max_ascent);
15146 row->height = max (row->height, it->max_ascent + it->max_descent);
15147 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
15148 row->phys_height = max (row->phys_height,
15149 it->max_phys_ascent + it->max_phys_descent);
15150 row->extra_line_spacing = max (row->extra_line_spacing,
15151 it->max_extra_line_spacing);
15153 /* End of this display line if row is continued. */
15154 if (row->continued_p || row->ends_at_zv_p)
15155 break;
15158 at_end_of_line:
15159 /* Is this a line end? If yes, we're also done, after making
15160 sure that a non-default face is extended up to the right
15161 margin of the window. */
15162 if (ITERATOR_AT_END_OF_LINE_P (it))
15164 int used_before = row->used[TEXT_AREA];
15166 row->ends_in_newline_from_string_p = STRINGP (it->object);
15168 #ifdef HAVE_WINDOW_SYSTEM
15169 /* Add a space at the end of the line that is used to
15170 display the cursor there. */
15171 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
15172 append_space_for_newline (it, 0);
15173 #endif /* HAVE_WINDOW_SYSTEM */
15175 /* Extend the face to the end of the line. */
15176 extend_face_to_end_of_line (it);
15178 /* Make sure we have the position. */
15179 if (used_before == 0)
15180 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
15182 /* Consume the line end. This skips over invisible lines. */
15183 set_iterator_to_next (it, 1);
15184 it->continuation_lines_width = 0;
15185 break;
15188 /* Proceed with next display element. Note that this skips
15189 over lines invisible because of selective display. */
15190 set_iterator_to_next (it, 1);
15192 /* If we truncate lines, we are done when the last displayed
15193 glyphs reach past the right margin of the window. */
15194 if (it->truncate_lines_p
15195 && (FRAME_WINDOW_P (it->f)
15196 ? (it->current_x >= it->last_visible_x)
15197 : (it->current_x > it->last_visible_x)))
15199 /* Maybe add truncation glyphs. */
15200 if (!FRAME_WINDOW_P (it->f))
15202 int i, n;
15204 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
15205 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
15206 break;
15208 for (n = row->used[TEXT_AREA]; i < n; ++i)
15210 row->used[TEXT_AREA] = i;
15211 produce_special_glyphs (it, IT_TRUNCATION);
15214 #ifdef HAVE_WINDOW_SYSTEM
15215 else
15217 /* Don't truncate if we can overflow newline into fringe. */
15218 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
15220 if (!get_next_display_element (it))
15222 it->continuation_lines_width = 0;
15223 row->ends_at_zv_p = 1;
15224 row->exact_window_width_line_p = 1;
15225 break;
15227 if (ITERATOR_AT_END_OF_LINE_P (it))
15229 row->exact_window_width_line_p = 1;
15230 goto at_end_of_line;
15234 #endif /* HAVE_WINDOW_SYSTEM */
15236 row->truncated_on_right_p = 1;
15237 it->continuation_lines_width = 0;
15238 reseat_at_next_visible_line_start (it, 0);
15239 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
15240 it->hpos = hpos_before;
15241 it->current_x = x_before;
15242 break;
15246 /* If line is not empty and hscrolled, maybe insert truncation glyphs
15247 at the left window margin. */
15248 if (it->first_visible_x
15249 && IT_CHARPOS (*it) != MATRIX_ROW_START_CHARPOS (row))
15251 if (!FRAME_WINDOW_P (it->f))
15252 insert_left_trunc_glyphs (it);
15253 row->truncated_on_left_p = 1;
15256 /* If the start of this line is the overlay arrow-position, then
15257 mark this glyph row as the one containing the overlay arrow.
15258 This is clearly a mess with variable size fonts. It would be
15259 better to let it be displayed like cursors under X. */
15260 if ((row->displays_text_p || !overlay_arrow_seen)
15261 && (overlay_arrow_string = overlay_arrow_at_row (it, row),
15262 !NILP (overlay_arrow_string)))
15264 /* Overlay arrow in window redisplay is a fringe bitmap. */
15265 if (STRINGP (overlay_arrow_string))
15267 struct glyph_row *arrow_row
15268 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
15269 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
15270 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
15271 struct glyph *p = row->glyphs[TEXT_AREA];
15272 struct glyph *p2, *end;
15274 /* Copy the arrow glyphs. */
15275 while (glyph < arrow_end)
15276 *p++ = *glyph++;
15278 /* Throw away padding glyphs. */
15279 p2 = p;
15280 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
15281 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
15282 ++p2;
15283 if (p2 > p)
15285 while (p2 < end)
15286 *p++ = *p2++;
15287 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
15290 else
15292 xassert (INTEGERP (overlay_arrow_string));
15293 row->overlay_arrow_bitmap = XINT (overlay_arrow_string);
15295 overlay_arrow_seen = 1;
15298 /* Compute pixel dimensions of this line. */
15299 compute_line_metrics (it);
15301 /* Remember the position at which this line ends. */
15302 row->end = it->current;
15304 /* Record whether this row ends inside an ellipsis. */
15305 row->ends_in_ellipsis_p
15306 = (it->method == GET_FROM_DISPLAY_VECTOR
15307 && it->ellipsis_p);
15309 /* Save fringe bitmaps in this row. */
15310 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
15311 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
15312 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
15313 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
15315 it->left_user_fringe_bitmap = 0;
15316 it->left_user_fringe_face_id = 0;
15317 it->right_user_fringe_bitmap = 0;
15318 it->right_user_fringe_face_id = 0;
15320 /* Maybe set the cursor. */
15321 if (it->w->cursor.vpos < 0
15322 && PT >= MATRIX_ROW_START_CHARPOS (row)
15323 && PT <= MATRIX_ROW_END_CHARPOS (row)
15324 && cursor_row_p (it->w, row))
15325 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
15327 /* Highlight trailing whitespace. */
15328 if (!NILP (Vshow_trailing_whitespace))
15329 highlight_trailing_whitespace (it->f, it->glyph_row);
15331 /* Prepare for the next line. This line starts horizontally at (X
15332 HPOS) = (0 0). Vertical positions are incremented. As a
15333 convenience for the caller, IT->glyph_row is set to the next
15334 row to be used. */
15335 it->current_x = it->hpos = 0;
15336 it->current_y += row->height;
15337 ++it->vpos;
15338 ++it->glyph_row;
15339 it->start = it->current;
15340 return row->displays_text_p;
15345 /***********************************************************************
15346 Menu Bar
15347 ***********************************************************************/
15349 /* Redisplay the menu bar in the frame for window W.
15351 The menu bar of X frames that don't have X toolkit support is
15352 displayed in a special window W->frame->menu_bar_window.
15354 The menu bar of terminal frames is treated specially as far as
15355 glyph matrices are concerned. Menu bar lines are not part of
15356 windows, so the update is done directly on the frame matrix rows
15357 for the menu bar. */
15359 static void
15360 display_menu_bar (w)
15361 struct window *w;
15363 struct frame *f = XFRAME (WINDOW_FRAME (w));
15364 struct it it;
15365 Lisp_Object items;
15366 int i;
15368 /* Don't do all this for graphical frames. */
15369 #ifdef HAVE_NTGUI
15370 if (!NILP (Vwindow_system))
15371 return;
15372 #endif
15373 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
15374 if (FRAME_X_P (f))
15375 return;
15376 #endif
15377 #ifdef MAC_OS
15378 if (FRAME_MAC_P (f))
15379 return;
15380 #endif
15382 #ifdef USE_X_TOOLKIT
15383 xassert (!FRAME_WINDOW_P (f));
15384 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
15385 it.first_visible_x = 0;
15386 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
15387 #else /* not USE_X_TOOLKIT */
15388 if (FRAME_WINDOW_P (f))
15390 /* Menu bar lines are displayed in the desired matrix of the
15391 dummy window menu_bar_window. */
15392 struct window *menu_w;
15393 xassert (WINDOWP (f->menu_bar_window));
15394 menu_w = XWINDOW (f->menu_bar_window);
15395 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
15396 MENU_FACE_ID);
15397 it.first_visible_x = 0;
15398 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
15400 else
15402 /* This is a TTY frame, i.e. character hpos/vpos are used as
15403 pixel x/y. */
15404 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
15405 MENU_FACE_ID);
15406 it.first_visible_x = 0;
15407 it.last_visible_x = FRAME_COLS (f);
15409 #endif /* not USE_X_TOOLKIT */
15411 if (! mode_line_inverse_video)
15412 /* Force the menu-bar to be displayed in the default face. */
15413 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
15415 /* Clear all rows of the menu bar. */
15416 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
15418 struct glyph_row *row = it.glyph_row + i;
15419 clear_glyph_row (row);
15420 row->enabled_p = 1;
15421 row->full_width_p = 1;
15424 /* Display all items of the menu bar. */
15425 items = FRAME_MENU_BAR_ITEMS (it.f);
15426 for (i = 0; i < XVECTOR (items)->size; i += 4)
15428 Lisp_Object string;
15430 /* Stop at nil string. */
15431 string = AREF (items, i + 1);
15432 if (NILP (string))
15433 break;
15435 /* Remember where item was displayed. */
15436 AREF (items, i + 3) = make_number (it.hpos);
15438 /* Display the item, pad with one space. */
15439 if (it.current_x < it.last_visible_x)
15440 display_string (NULL, string, Qnil, 0, 0, &it,
15441 SCHARS (string) + 1, 0, 0, -1);
15444 /* Fill out the line with spaces. */
15445 if (it.current_x < it.last_visible_x)
15446 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
15448 /* Compute the total height of the lines. */
15449 compute_line_metrics (&it);
15454 /***********************************************************************
15455 Mode Line
15456 ***********************************************************************/
15458 /* Redisplay mode lines in the window tree whose root is WINDOW. If
15459 FORCE is non-zero, redisplay mode lines unconditionally.
15460 Otherwise, redisplay only mode lines that are garbaged. Value is
15461 the number of windows whose mode lines were redisplayed. */
15463 static int
15464 redisplay_mode_lines (window, force)
15465 Lisp_Object window;
15466 int force;
15468 int nwindows = 0;
15470 while (!NILP (window))
15472 struct window *w = XWINDOW (window);
15474 if (WINDOWP (w->hchild))
15475 nwindows += redisplay_mode_lines (w->hchild, force);
15476 else if (WINDOWP (w->vchild))
15477 nwindows += redisplay_mode_lines (w->vchild, force);
15478 else if (force
15479 || FRAME_GARBAGED_P (XFRAME (w->frame))
15480 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
15482 struct text_pos lpoint;
15483 struct buffer *old = current_buffer;
15485 /* Set the window's buffer for the mode line display. */
15486 SET_TEXT_POS (lpoint, PT, PT_BYTE);
15487 set_buffer_internal_1 (XBUFFER (w->buffer));
15489 /* Point refers normally to the selected window. For any
15490 other window, set up appropriate value. */
15491 if (!EQ (window, selected_window))
15493 struct text_pos pt;
15495 SET_TEXT_POS_FROM_MARKER (pt, w->pointm);
15496 if (CHARPOS (pt) < BEGV)
15497 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
15498 else if (CHARPOS (pt) > (ZV - 1))
15499 TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
15500 else
15501 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
15504 /* Display mode lines. */
15505 clear_glyph_matrix (w->desired_matrix);
15506 if (display_mode_lines (w))
15508 ++nwindows;
15509 w->must_be_updated_p = 1;
15512 /* Restore old settings. */
15513 set_buffer_internal_1 (old);
15514 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
15517 window = w->next;
15520 return nwindows;
15524 /* Display the mode and/or top line of window W. Value is the number
15525 of mode lines displayed. */
15527 static int
15528 display_mode_lines (w)
15529 struct window *w;
15531 Lisp_Object old_selected_window, old_selected_frame;
15532 int n = 0;
15534 old_selected_frame = selected_frame;
15535 selected_frame = w->frame;
15536 old_selected_window = selected_window;
15537 XSETWINDOW (selected_window, w);
15539 /* These will be set while the mode line specs are processed. */
15540 line_number_displayed = 0;
15541 w->column_number_displayed = Qnil;
15543 if (WINDOW_WANTS_MODELINE_P (w))
15545 struct window *sel_w = XWINDOW (old_selected_window);
15547 /* Select mode line face based on the real selected window. */
15548 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
15549 current_buffer->mode_line_format);
15550 ++n;
15553 if (WINDOW_WANTS_HEADER_LINE_P (w))
15555 display_mode_line (w, HEADER_LINE_FACE_ID,
15556 current_buffer->header_line_format);
15557 ++n;
15560 selected_frame = old_selected_frame;
15561 selected_window = old_selected_window;
15562 return n;
15566 /* Display mode or top line of window W. FACE_ID specifies which line
15567 to display; it is either MODE_LINE_FACE_ID or HEADER_LINE_FACE_ID.
15568 FORMAT is the mode line format to display. Value is the pixel
15569 height of the mode line displayed. */
15571 static int
15572 display_mode_line (w, face_id, format)
15573 struct window *w;
15574 enum face_id face_id;
15575 Lisp_Object format;
15577 struct it it;
15578 struct face *face;
15580 init_iterator (&it, w, -1, -1, NULL, face_id);
15581 prepare_desired_row (it.glyph_row);
15583 it.glyph_row->mode_line_p = 1;
15585 if (! mode_line_inverse_video)
15586 /* Force the mode-line to be displayed in the default face. */
15587 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
15589 /* Temporarily make frame's keyboard the current kboard so that
15590 kboard-local variables in the mode_line_format will get the right
15591 values. */
15592 push_frame_kboard (it.f);
15593 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
15594 pop_frame_kboard ();
15596 /* Fill up with spaces. */
15597 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
15599 compute_line_metrics (&it);
15600 it.glyph_row->full_width_p = 1;
15601 it.glyph_row->continued_p = 0;
15602 it.glyph_row->truncated_on_left_p = 0;
15603 it.glyph_row->truncated_on_right_p = 0;
15605 /* Make a 3D mode-line have a shadow at its right end. */
15606 face = FACE_FROM_ID (it.f, face_id);
15607 extend_face_to_end_of_line (&it);
15608 if (face->box != FACE_NO_BOX)
15610 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
15611 + it.glyph_row->used[TEXT_AREA] - 1);
15612 last->right_box_line_p = 1;
15615 return it.glyph_row->height;
15618 /* Alist that caches the results of :propertize.
15619 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
15620 Lisp_Object mode_line_proptrans_alist;
15622 /* List of strings making up the mode-line. */
15623 Lisp_Object mode_line_string_list;
15625 /* Base face property when building propertized mode line string. */
15626 static Lisp_Object mode_line_string_face;
15627 static Lisp_Object mode_line_string_face_prop;
15630 /* Contribute ELT to the mode line for window IT->w. How it
15631 translates into text depends on its data type.
15633 IT describes the display environment in which we display, as usual.
15635 DEPTH is the depth in recursion. It is used to prevent
15636 infinite recursion here.
15638 FIELD_WIDTH is the number of characters the display of ELT should
15639 occupy in the mode line, and PRECISION is the maximum number of
15640 characters to display from ELT's representation. See
15641 display_string for details.
15643 Returns the hpos of the end of the text generated by ELT.
15645 PROPS is a property list to add to any string we encounter.
15647 If RISKY is nonzero, remove (disregard) any properties in any string
15648 we encounter, and ignore :eval and :propertize.
15650 If the global variable `frame_title_ptr' is non-NULL, then the output
15651 is passed to `store_frame_title' instead of `display_string'. */
15653 static int
15654 display_mode_element (it, depth, field_width, precision, elt, props, risky)
15655 struct it *it;
15656 int depth;
15657 int field_width, precision;
15658 Lisp_Object elt, props;
15659 int risky;
15661 int n = 0, field, prec;
15662 int literal = 0;
15664 tail_recurse:
15665 if (depth > 100)
15666 elt = build_string ("*too-deep*");
15668 depth++;
15670 switch (SWITCH_ENUM_CAST (XTYPE (elt)))
15672 case Lisp_String:
15674 /* A string: output it and check for %-constructs within it. */
15675 unsigned char c;
15676 const unsigned char *this, *lisp_string;
15678 if (!NILP (props) || risky)
15680 Lisp_Object oprops, aelt;
15681 oprops = Ftext_properties_at (make_number (0), elt);
15683 /* If the starting string's properties are not what
15684 we want, translate the string. Also, if the string
15685 is risky, do that anyway. */
15687 if (NILP (Fequal (props, oprops)) || risky)
15689 /* If the starting string has properties,
15690 merge the specified ones onto the existing ones. */
15691 if (! NILP (oprops) && !risky)
15693 Lisp_Object tem;
15695 oprops = Fcopy_sequence (oprops);
15696 tem = props;
15697 while (CONSP (tem))
15699 oprops = Fplist_put (oprops, XCAR (tem),
15700 XCAR (XCDR (tem)));
15701 tem = XCDR (XCDR (tem));
15703 props = oprops;
15706 aelt = Fassoc (elt, mode_line_proptrans_alist);
15707 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
15709 mode_line_proptrans_alist
15710 = Fcons (aelt, Fdelq (aelt, mode_line_proptrans_alist));
15711 elt = XCAR (aelt);
15713 else
15715 Lisp_Object tem;
15717 elt = Fcopy_sequence (elt);
15718 Fset_text_properties (make_number (0), Flength (elt),
15719 props, elt);
15720 /* Add this item to mode_line_proptrans_alist. */
15721 mode_line_proptrans_alist
15722 = Fcons (Fcons (elt, props),
15723 mode_line_proptrans_alist);
15724 /* Truncate mode_line_proptrans_alist
15725 to at most 50 elements. */
15726 tem = Fnthcdr (make_number (50),
15727 mode_line_proptrans_alist);
15728 if (! NILP (tem))
15729 XSETCDR (tem, Qnil);
15734 this = SDATA (elt);
15735 lisp_string = this;
15737 if (literal)
15739 prec = precision - n;
15740 if (frame_title_ptr)
15741 n += store_frame_title (SDATA (elt), -1, prec);
15742 else if (!NILP (mode_line_string_list))
15743 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
15744 else
15745 n += display_string (NULL, elt, Qnil, 0, 0, it,
15746 0, prec, 0, STRING_MULTIBYTE (elt));
15748 break;
15751 while ((precision <= 0 || n < precision)
15752 && *this
15753 && (frame_title_ptr
15754 || !NILP (mode_line_string_list)
15755 || it->current_x < it->last_visible_x))
15757 const unsigned char *last = this;
15759 /* Advance to end of string or next format specifier. */
15760 while ((c = *this++) != '\0' && c != '%')
15763 if (this - 1 != last)
15765 int nchars, nbytes;
15767 /* Output to end of string or up to '%'. Field width
15768 is length of string. Don't output more than
15769 PRECISION allows us. */
15770 --this;
15772 prec = c_string_width (last, this - last, precision - n,
15773 &nchars, &nbytes);
15775 if (frame_title_ptr)
15776 n += store_frame_title (last, 0, prec);
15777 else if (!NILP (mode_line_string_list))
15779 int bytepos = last - lisp_string;
15780 int charpos = string_byte_to_char (elt, bytepos);
15781 int endpos = (precision <= 0
15782 ? string_byte_to_char (elt,
15783 this - lisp_string)
15784 : charpos + nchars);
15786 n += store_mode_line_string (NULL,
15787 Fsubstring (elt, make_number (charpos),
15788 make_number (endpos)),
15789 0, 0, 0, Qnil);
15791 else
15793 int bytepos = last - lisp_string;
15794 int charpos = string_byte_to_char (elt, bytepos);
15795 n += display_string (NULL, elt, Qnil, 0, charpos,
15796 it, 0, prec, 0,
15797 STRING_MULTIBYTE (elt));
15800 else /* c == '%' */
15802 const unsigned char *percent_position = this;
15804 /* Get the specified minimum width. Zero means
15805 don't pad. */
15806 field = 0;
15807 while ((c = *this++) >= '0' && c <= '9')
15808 field = field * 10 + c - '0';
15810 /* Don't pad beyond the total padding allowed. */
15811 if (field_width - n > 0 && field > field_width - n)
15812 field = field_width - n;
15814 /* Note that either PRECISION <= 0 or N < PRECISION. */
15815 prec = precision - n;
15817 if (c == 'M')
15818 n += display_mode_element (it, depth, field, prec,
15819 Vglobal_mode_string, props,
15820 risky);
15821 else if (c != 0)
15823 int multibyte;
15824 int bytepos, charpos;
15825 unsigned char *spec;
15827 bytepos = percent_position - lisp_string;
15828 charpos = (STRING_MULTIBYTE (elt)
15829 ? string_byte_to_char (elt, bytepos)
15830 : bytepos);
15832 spec
15833 = decode_mode_spec (it->w, c, field, prec, &multibyte);
15835 if (frame_title_ptr)
15836 n += store_frame_title (spec, field, prec);
15837 else if (!NILP (mode_line_string_list))
15839 int len = strlen (spec);
15840 Lisp_Object tem = make_string (spec, len);
15841 props = Ftext_properties_at (make_number (charpos), elt);
15842 /* Should only keep face property in props */
15843 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
15845 else
15847 int nglyphs_before, nwritten;
15849 nglyphs_before = it->glyph_row->used[TEXT_AREA];
15850 nwritten = display_string (spec, Qnil, elt,
15851 charpos, 0, it,
15852 field, prec, 0,
15853 multibyte);
15855 /* Assign to the glyphs written above the
15856 string where the `%x' came from, position
15857 of the `%'. */
15858 if (nwritten > 0)
15860 struct glyph *glyph
15861 = (it->glyph_row->glyphs[TEXT_AREA]
15862 + nglyphs_before);
15863 int i;
15865 for (i = 0; i < nwritten; ++i)
15867 glyph[i].object = elt;
15868 glyph[i].charpos = charpos;
15871 n += nwritten;
15875 else /* c == 0 */
15876 break;
15880 break;
15882 case Lisp_Symbol:
15883 /* A symbol: process the value of the symbol recursively
15884 as if it appeared here directly. Avoid error if symbol void.
15885 Special case: if value of symbol is a string, output the string
15886 literally. */
15888 register Lisp_Object tem;
15890 /* If the variable is not marked as risky to set
15891 then its contents are risky to use. */
15892 if (NILP (Fget (elt, Qrisky_local_variable)))
15893 risky = 1;
15895 tem = Fboundp (elt);
15896 if (!NILP (tem))
15898 tem = Fsymbol_value (elt);
15899 /* If value is a string, output that string literally:
15900 don't check for % within it. */
15901 if (STRINGP (tem))
15902 literal = 1;
15904 if (!EQ (tem, elt))
15906 /* Give up right away for nil or t. */
15907 elt = tem;
15908 goto tail_recurse;
15912 break;
15914 case Lisp_Cons:
15916 register Lisp_Object car, tem;
15918 /* A cons cell: five distinct cases.
15919 If first element is :eval or :propertize, do something special.
15920 If first element is a string or a cons, process all the elements
15921 and effectively concatenate them.
15922 If first element is a negative number, truncate displaying cdr to
15923 at most that many characters. If positive, pad (with spaces)
15924 to at least that many characters.
15925 If first element is a symbol, process the cadr or caddr recursively
15926 according to whether the symbol's value is non-nil or nil. */
15927 car = XCAR (elt);
15928 if (EQ (car, QCeval))
15930 /* An element of the form (:eval FORM) means evaluate FORM
15931 and use the result as mode line elements. */
15933 if (risky)
15934 break;
15936 if (CONSP (XCDR (elt)))
15938 Lisp_Object spec;
15939 spec = safe_eval (XCAR (XCDR (elt)));
15940 n += display_mode_element (it, depth, field_width - n,
15941 precision - n, spec, props,
15942 risky);
15945 else if (EQ (car, QCpropertize))
15947 /* An element of the form (:propertize ELT PROPS...)
15948 means display ELT but applying properties PROPS. */
15950 if (risky)
15951 break;
15953 if (CONSP (XCDR (elt)))
15954 n += display_mode_element (it, depth, field_width - n,
15955 precision - n, XCAR (XCDR (elt)),
15956 XCDR (XCDR (elt)), risky);
15958 else if (SYMBOLP (car))
15960 tem = Fboundp (car);
15961 elt = XCDR (elt);
15962 if (!CONSP (elt))
15963 goto invalid;
15964 /* elt is now the cdr, and we know it is a cons cell.
15965 Use its car if CAR has a non-nil value. */
15966 if (!NILP (tem))
15968 tem = Fsymbol_value (car);
15969 if (!NILP (tem))
15971 elt = XCAR (elt);
15972 goto tail_recurse;
15975 /* Symbol's value is nil (or symbol is unbound)
15976 Get the cddr of the original list
15977 and if possible find the caddr and use that. */
15978 elt = XCDR (elt);
15979 if (NILP (elt))
15980 break;
15981 else if (!CONSP (elt))
15982 goto invalid;
15983 elt = XCAR (elt);
15984 goto tail_recurse;
15986 else if (INTEGERP (car))
15988 register int lim = XINT (car);
15989 elt = XCDR (elt);
15990 if (lim < 0)
15992 /* Negative int means reduce maximum width. */
15993 if (precision <= 0)
15994 precision = -lim;
15995 else
15996 precision = min (precision, -lim);
15998 else if (lim > 0)
16000 /* Padding specified. Don't let it be more than
16001 current maximum. */
16002 if (precision > 0)
16003 lim = min (precision, lim);
16005 /* If that's more padding than already wanted, queue it.
16006 But don't reduce padding already specified even if
16007 that is beyond the current truncation point. */
16008 field_width = max (lim, field_width);
16010 goto tail_recurse;
16012 else if (STRINGP (car) || CONSP (car))
16014 register int limit = 50;
16015 /* Limit is to protect against circular lists. */
16016 while (CONSP (elt)
16017 && --limit > 0
16018 && (precision <= 0 || n < precision))
16020 n += display_mode_element (it, depth, field_width - n,
16021 precision - n, XCAR (elt),
16022 props, risky);
16023 elt = XCDR (elt);
16027 break;
16029 default:
16030 invalid:
16031 elt = build_string ("*invalid*");
16032 goto tail_recurse;
16035 /* Pad to FIELD_WIDTH. */
16036 if (field_width > 0 && n < field_width)
16038 if (frame_title_ptr)
16039 n += store_frame_title ("", field_width - n, 0);
16040 else if (!NILP (mode_line_string_list))
16041 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
16042 else
16043 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
16044 0, 0, 0);
16047 return n;
16050 /* Store a mode-line string element in mode_line_string_list.
16052 If STRING is non-null, display that C string. Otherwise, the Lisp
16053 string LISP_STRING is displayed.
16055 FIELD_WIDTH is the minimum number of output glyphs to produce.
16056 If STRING has fewer characters than FIELD_WIDTH, pad to the right
16057 with spaces. FIELD_WIDTH <= 0 means don't pad.
16059 PRECISION is the maximum number of characters to output from
16060 STRING. PRECISION <= 0 means don't truncate the string.
16062 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
16063 properties to the string.
16065 PROPS are the properties to add to the string.
16066 The mode_line_string_face face property is always added to the string.
16069 static int
16070 store_mode_line_string (string, lisp_string, copy_string, field_width, precision, props)
16071 char *string;
16072 Lisp_Object lisp_string;
16073 int copy_string;
16074 int field_width;
16075 int precision;
16076 Lisp_Object props;
16078 int len;
16079 int n = 0;
16081 if (string != NULL)
16083 len = strlen (string);
16084 if (precision > 0 && len > precision)
16085 len = precision;
16086 lisp_string = make_string (string, len);
16087 if (NILP (props))
16088 props = mode_line_string_face_prop;
16089 else if (!NILP (mode_line_string_face))
16091 Lisp_Object face = Fsafe_plist_get (props, Qface);
16092 props = Fcopy_sequence (props);
16093 if (NILP (face))
16094 face = mode_line_string_face;
16095 else
16096 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
16097 props = Fplist_put (props, Qface, face);
16099 Fadd_text_properties (make_number (0), make_number (len),
16100 props, lisp_string);
16102 else
16104 len = XFASTINT (Flength (lisp_string));
16105 if (precision > 0 && len > precision)
16107 len = precision;
16108 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
16109 precision = -1;
16111 if (!NILP (mode_line_string_face))
16113 Lisp_Object face;
16114 if (NILP (props))
16115 props = Ftext_properties_at (make_number (0), lisp_string);
16116 face = Fsafe_plist_get (props, Qface);
16117 if (NILP (face))
16118 face = mode_line_string_face;
16119 else
16120 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
16121 props = Fcons (Qface, Fcons (face, Qnil));
16122 if (copy_string)
16123 lisp_string = Fcopy_sequence (lisp_string);
16125 if (!NILP (props))
16126 Fadd_text_properties (make_number (0), make_number (len),
16127 props, lisp_string);
16130 if (len > 0)
16132 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
16133 n += len;
16136 if (field_width > len)
16138 field_width -= len;
16139 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
16140 if (!NILP (props))
16141 Fadd_text_properties (make_number (0), make_number (field_width),
16142 props, lisp_string);
16143 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
16144 n += field_width;
16147 return n;
16151 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
16152 1, 4, 0,
16153 doc: /* Format a string out of a mode line format specification.
16154 First arg FORMAT specifies the mode line format (see `mode-line-format'
16155 for details) to use.
16157 Optional second arg FACE specifies the face property to put
16158 on all characters for which no face is specified.
16159 t means whatever face the window's mode line currently uses
16160 \(either `mode-line' or `mode-line-inactive', depending).
16161 nil means the default is no face property.
16162 If FACE is an integer, the value string has no text properties.
16164 Optional third and fourth args WINDOW and BUFFER specify the window
16165 and buffer to use as the context for the formatting (defaults
16166 are the selected window and the window's buffer). */)
16167 (format, face, window, buffer)
16168 Lisp_Object format, face, window, buffer;
16170 struct it it;
16171 int len;
16172 struct window *w;
16173 struct buffer *old_buffer = NULL;
16174 int face_id = -1;
16175 int no_props = INTEGERP (face);
16177 if (NILP (window))
16178 window = selected_window;
16179 CHECK_WINDOW (window);
16180 w = XWINDOW (window);
16182 if (NILP (buffer))
16183 buffer = w->buffer;
16184 CHECK_BUFFER (buffer);
16186 if (NILP (format))
16187 return build_string ("");
16189 if (no_props)
16190 face = Qnil;
16192 if (!NILP (face))
16194 if (EQ (face, Qt))
16195 face = (EQ (window, selected_window) ? Qmode_line : Qmode_line_inactive);
16196 face_id = lookup_named_face (XFRAME (WINDOW_FRAME (w)), face, 0, 0);
16199 if (face_id < 0)
16200 face_id = DEFAULT_FACE_ID;
16202 if (XBUFFER (buffer) != current_buffer)
16204 old_buffer = current_buffer;
16205 set_buffer_internal_1 (XBUFFER (buffer));
16208 init_iterator (&it, w, -1, -1, NULL, face_id);
16210 if (!no_props)
16212 mode_line_string_face = face;
16213 mode_line_string_face_prop
16214 = (NILP (face) ? Qnil : Fcons (Qface, Fcons (face, Qnil)));
16216 /* We need a dummy last element in mode_line_string_list to
16217 indicate we are building the propertized mode-line string.
16218 Using mode_line_string_face_prop here GC protects it. */
16219 mode_line_string_list
16220 = Fcons (mode_line_string_face_prop, Qnil);
16221 frame_title_ptr = NULL;
16223 else
16225 mode_line_string_face_prop = Qnil;
16226 mode_line_string_list = Qnil;
16227 frame_title_ptr = frame_title_buf;
16230 push_frame_kboard (it.f);
16231 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
16232 pop_frame_kboard ();
16234 if (old_buffer)
16235 set_buffer_internal_1 (old_buffer);
16237 if (!no_props)
16239 Lisp_Object str;
16240 mode_line_string_list = Fnreverse (mode_line_string_list);
16241 str = Fmapconcat (intern ("identity"), XCDR (mode_line_string_list),
16242 make_string ("", 0));
16243 mode_line_string_face_prop = Qnil;
16244 mode_line_string_list = Qnil;
16245 return str;
16248 len = frame_title_ptr - frame_title_buf;
16249 if (len > 0 && frame_title_ptr[-1] == '-')
16251 /* Mode lines typically ends with numerous dashes; reduce to two dashes. */
16252 while (frame_title_ptr > frame_title_buf && *--frame_title_ptr == '-')
16254 frame_title_ptr += 3; /* restore last non-dash + two dashes */
16255 if (len > frame_title_ptr - frame_title_buf)
16256 len = frame_title_ptr - frame_title_buf;
16259 frame_title_ptr = NULL;
16260 return make_string (frame_title_buf, len);
16263 /* Write a null-terminated, right justified decimal representation of
16264 the positive integer D to BUF using a minimal field width WIDTH. */
16266 static void
16267 pint2str (buf, width, d)
16268 register char *buf;
16269 register int width;
16270 register int d;
16272 register char *p = buf;
16274 if (d <= 0)
16275 *p++ = '0';
16276 else
16278 while (d > 0)
16280 *p++ = d % 10 + '0';
16281 d /= 10;
16285 for (width -= (int) (p - buf); width > 0; --width)
16286 *p++ = ' ';
16287 *p-- = '\0';
16288 while (p > buf)
16290 d = *buf;
16291 *buf++ = *p;
16292 *p-- = d;
16296 /* Write a null-terminated, right justified decimal and "human
16297 readable" representation of the nonnegative integer D to BUF using
16298 a minimal field width WIDTH. D should be smaller than 999.5e24. */
16300 static const char power_letter[] =
16302 0, /* not used */
16303 'k', /* kilo */
16304 'M', /* mega */
16305 'G', /* giga */
16306 'T', /* tera */
16307 'P', /* peta */
16308 'E', /* exa */
16309 'Z', /* zetta */
16310 'Y' /* yotta */
16313 static void
16314 pint2hrstr (buf, width, d)
16315 char *buf;
16316 int width;
16317 int d;
16319 /* We aim to represent the nonnegative integer D as
16320 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
16321 int quotient = d;
16322 int remainder = 0;
16323 /* -1 means: do not use TENTHS. */
16324 int tenths = -1;
16325 int exponent = 0;
16327 /* Length of QUOTIENT.TENTHS as a string. */
16328 int length;
16330 char * psuffix;
16331 char * p;
16333 if (1000 <= quotient)
16335 /* Scale to the appropriate EXPONENT. */
16338 remainder = quotient % 1000;
16339 quotient /= 1000;
16340 exponent++;
16342 while (1000 <= quotient);
16344 /* Round to nearest and decide whether to use TENTHS or not. */
16345 if (quotient <= 9)
16347 tenths = remainder / 100;
16348 if (50 <= remainder % 100)
16350 if (tenths < 9)
16351 tenths++;
16352 else
16354 quotient++;
16355 if (quotient == 10)
16356 tenths = -1;
16357 else
16358 tenths = 0;
16362 else
16363 if (500 <= remainder)
16365 if (quotient < 999)
16366 quotient++;
16367 else
16369 quotient = 1;
16370 exponent++;
16371 tenths = 0;
16376 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
16377 if (tenths == -1 && quotient <= 99)
16378 if (quotient <= 9)
16379 length = 1;
16380 else
16381 length = 2;
16382 else
16383 length = 3;
16384 p = psuffix = buf + max (width, length);
16386 /* Print EXPONENT. */
16387 if (exponent)
16388 *psuffix++ = power_letter[exponent];
16389 *psuffix = '\0';
16391 /* Print TENTHS. */
16392 if (tenths >= 0)
16394 *--p = '0' + tenths;
16395 *--p = '.';
16398 /* Print QUOTIENT. */
16401 int digit = quotient % 10;
16402 *--p = '0' + digit;
16404 while ((quotient /= 10) != 0);
16406 /* Print leading spaces. */
16407 while (buf < p)
16408 *--p = ' ';
16411 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
16412 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
16413 type of CODING_SYSTEM. Return updated pointer into BUF. */
16415 static unsigned char invalid_eol_type[] = "(*invalid*)";
16417 static char *
16418 decode_mode_spec_coding (coding_system, buf, eol_flag)
16419 Lisp_Object coding_system;
16420 register char *buf;
16421 int eol_flag;
16423 Lisp_Object val;
16424 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
16425 const unsigned char *eol_str;
16426 int eol_str_len;
16427 /* The EOL conversion we are using. */
16428 Lisp_Object eoltype;
16430 val = Fget (coding_system, Qcoding_system);
16431 eoltype = Qnil;
16433 if (!VECTORP (val)) /* Not yet decided. */
16435 if (multibyte)
16436 *buf++ = '-';
16437 if (eol_flag)
16438 eoltype = eol_mnemonic_undecided;
16439 /* Don't mention EOL conversion if it isn't decided. */
16441 else
16443 Lisp_Object eolvalue;
16445 eolvalue = Fget (coding_system, Qeol_type);
16447 if (multibyte)
16448 *buf++ = XFASTINT (AREF (val, 1));
16450 if (eol_flag)
16452 /* The EOL conversion that is normal on this system. */
16454 if (NILP (eolvalue)) /* Not yet decided. */
16455 eoltype = eol_mnemonic_undecided;
16456 else if (VECTORP (eolvalue)) /* Not yet decided. */
16457 eoltype = eol_mnemonic_undecided;
16458 else /* INTEGERP (eolvalue) -- 0:LF, 1:CRLF, 2:CR */
16459 eoltype = (XFASTINT (eolvalue) == 0
16460 ? eol_mnemonic_unix
16461 : (XFASTINT (eolvalue) == 1
16462 ? eol_mnemonic_dos : eol_mnemonic_mac));
16466 if (eol_flag)
16468 /* Mention the EOL conversion if it is not the usual one. */
16469 if (STRINGP (eoltype))
16471 eol_str = SDATA (eoltype);
16472 eol_str_len = SBYTES (eoltype);
16474 else if (INTEGERP (eoltype)
16475 && CHAR_VALID_P (XINT (eoltype), 0))
16477 unsigned char *tmp = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
16478 eol_str_len = CHAR_STRING (XINT (eoltype), tmp);
16479 eol_str = tmp;
16481 else
16483 eol_str = invalid_eol_type;
16484 eol_str_len = sizeof (invalid_eol_type) - 1;
16486 bcopy (eol_str, buf, eol_str_len);
16487 buf += eol_str_len;
16490 return buf;
16493 /* Return a string for the output of a mode line %-spec for window W,
16494 generated by character C. PRECISION >= 0 means don't return a
16495 string longer than that value. FIELD_WIDTH > 0 means pad the
16496 string returned with spaces to that value. Return 1 in *MULTIBYTE
16497 if the result is multibyte text.
16499 Note we operate on the current buffer for most purposes,
16500 the exception being w->base_line_pos. */
16502 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
16504 static char *
16505 decode_mode_spec (w, c, field_width, precision, multibyte)
16506 struct window *w;
16507 register int c;
16508 int field_width, precision;
16509 int *multibyte;
16511 Lisp_Object obj;
16512 struct frame *f = XFRAME (WINDOW_FRAME (w));
16513 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
16514 struct buffer *b = current_buffer;
16516 obj = Qnil;
16517 *multibyte = 0;
16519 switch (c)
16521 case '*':
16522 if (!NILP (b->read_only))
16523 return "%";
16524 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
16525 return "*";
16526 return "-";
16528 case '+':
16529 /* This differs from %* only for a modified read-only buffer. */
16530 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
16531 return "*";
16532 if (!NILP (b->read_only))
16533 return "%";
16534 return "-";
16536 case '&':
16537 /* This differs from %* in ignoring read-only-ness. */
16538 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
16539 return "*";
16540 return "-";
16542 case '%':
16543 return "%";
16545 case '[':
16547 int i;
16548 char *p;
16550 if (command_loop_level > 5)
16551 return "[[[... ";
16552 p = decode_mode_spec_buf;
16553 for (i = 0; i < command_loop_level; i++)
16554 *p++ = '[';
16555 *p = 0;
16556 return decode_mode_spec_buf;
16559 case ']':
16561 int i;
16562 char *p;
16564 if (command_loop_level > 5)
16565 return " ...]]]";
16566 p = decode_mode_spec_buf;
16567 for (i = 0; i < command_loop_level; i++)
16568 *p++ = ']';
16569 *p = 0;
16570 return decode_mode_spec_buf;
16573 case '-':
16575 register int i;
16577 /* Let lots_of_dashes be a string of infinite length. */
16578 if (!NILP (mode_line_string_list))
16579 return "--";
16580 if (field_width <= 0
16581 || field_width > sizeof (lots_of_dashes))
16583 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
16584 decode_mode_spec_buf[i] = '-';
16585 decode_mode_spec_buf[i] = '\0';
16586 return decode_mode_spec_buf;
16588 else
16589 return lots_of_dashes;
16592 case 'b':
16593 obj = b->name;
16594 break;
16596 case 'c':
16598 int col = (int) current_column (); /* iftc */
16599 w->column_number_displayed = make_number (col);
16600 pint2str (decode_mode_spec_buf, field_width, col);
16601 return decode_mode_spec_buf;
16604 case 'F':
16605 /* %F displays the frame name. */
16606 if (!NILP (f->title))
16607 return (char *) SDATA (f->title);
16608 if (f->explicit_name || ! FRAME_WINDOW_P (f))
16609 return (char *) SDATA (f->name);
16610 return "Emacs";
16612 case 'f':
16613 obj = b->filename;
16614 break;
16616 case 'i':
16618 int size = ZV - BEGV;
16619 pint2str (decode_mode_spec_buf, field_width, size);
16620 return decode_mode_spec_buf;
16623 case 'I':
16625 int size = ZV - BEGV;
16626 pint2hrstr (decode_mode_spec_buf, field_width, size);
16627 return decode_mode_spec_buf;
16630 case 'l':
16632 int startpos = XMARKER (w->start)->charpos;
16633 int startpos_byte = marker_byte_position (w->start);
16634 int line, linepos, linepos_byte, topline;
16635 int nlines, junk;
16636 int height = WINDOW_TOTAL_LINES (w);
16638 /* If we decided that this buffer isn't suitable for line numbers,
16639 don't forget that too fast. */
16640 if (EQ (w->base_line_pos, w->buffer))
16641 goto no_value;
16642 /* But do forget it, if the window shows a different buffer now. */
16643 else if (BUFFERP (w->base_line_pos))
16644 w->base_line_pos = Qnil;
16646 /* If the buffer is very big, don't waste time. */
16647 if (INTEGERP (Vline_number_display_limit)
16648 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
16650 w->base_line_pos = Qnil;
16651 w->base_line_number = Qnil;
16652 goto no_value;
16655 if (!NILP (w->base_line_number)
16656 && !NILP (w->base_line_pos)
16657 && XFASTINT (w->base_line_pos) <= startpos)
16659 line = XFASTINT (w->base_line_number);
16660 linepos = XFASTINT (w->base_line_pos);
16661 linepos_byte = buf_charpos_to_bytepos (b, linepos);
16663 else
16665 line = 1;
16666 linepos = BUF_BEGV (b);
16667 linepos_byte = BUF_BEGV_BYTE (b);
16670 /* Count lines from base line to window start position. */
16671 nlines = display_count_lines (linepos, linepos_byte,
16672 startpos_byte,
16673 startpos, &junk);
16675 topline = nlines + line;
16677 /* Determine a new base line, if the old one is too close
16678 or too far away, or if we did not have one.
16679 "Too close" means it's plausible a scroll-down would
16680 go back past it. */
16681 if (startpos == BUF_BEGV (b))
16683 w->base_line_number = make_number (topline);
16684 w->base_line_pos = make_number (BUF_BEGV (b));
16686 else if (nlines < height + 25 || nlines > height * 3 + 50
16687 || linepos == BUF_BEGV (b))
16689 int limit = BUF_BEGV (b);
16690 int limit_byte = BUF_BEGV_BYTE (b);
16691 int position;
16692 int distance = (height * 2 + 30) * line_number_display_limit_width;
16694 if (startpos - distance > limit)
16696 limit = startpos - distance;
16697 limit_byte = CHAR_TO_BYTE (limit);
16700 nlines = display_count_lines (startpos, startpos_byte,
16701 limit_byte,
16702 - (height * 2 + 30),
16703 &position);
16704 /* If we couldn't find the lines we wanted within
16705 line_number_display_limit_width chars per line,
16706 give up on line numbers for this window. */
16707 if (position == limit_byte && limit == startpos - distance)
16709 w->base_line_pos = w->buffer;
16710 w->base_line_number = Qnil;
16711 goto no_value;
16714 w->base_line_number = make_number (topline - nlines);
16715 w->base_line_pos = make_number (BYTE_TO_CHAR (position));
16718 /* Now count lines from the start pos to point. */
16719 nlines = display_count_lines (startpos, startpos_byte,
16720 PT_BYTE, PT, &junk);
16722 /* Record that we did display the line number. */
16723 line_number_displayed = 1;
16725 /* Make the string to show. */
16726 pint2str (decode_mode_spec_buf, field_width, topline + nlines);
16727 return decode_mode_spec_buf;
16728 no_value:
16730 char* p = decode_mode_spec_buf;
16731 int pad = field_width - 2;
16732 while (pad-- > 0)
16733 *p++ = ' ';
16734 *p++ = '?';
16735 *p++ = '?';
16736 *p = '\0';
16737 return decode_mode_spec_buf;
16740 break;
16742 case 'm':
16743 obj = b->mode_name;
16744 break;
16746 case 'n':
16747 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
16748 return " Narrow";
16749 break;
16751 case 'p':
16753 int pos = marker_position (w->start);
16754 int total = BUF_ZV (b) - BUF_BEGV (b);
16756 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
16758 if (pos <= BUF_BEGV (b))
16759 return "All";
16760 else
16761 return "Bottom";
16763 else if (pos <= BUF_BEGV (b))
16764 return "Top";
16765 else
16767 if (total > 1000000)
16768 /* Do it differently for a large value, to avoid overflow. */
16769 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
16770 else
16771 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
16772 /* We can't normally display a 3-digit number,
16773 so get us a 2-digit number that is close. */
16774 if (total == 100)
16775 total = 99;
16776 sprintf (decode_mode_spec_buf, "%2d%%", total);
16777 return decode_mode_spec_buf;
16781 /* Display percentage of size above the bottom of the screen. */
16782 case 'P':
16784 int toppos = marker_position (w->start);
16785 int botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
16786 int total = BUF_ZV (b) - BUF_BEGV (b);
16788 if (botpos >= BUF_ZV (b))
16790 if (toppos <= BUF_BEGV (b))
16791 return "All";
16792 else
16793 return "Bottom";
16795 else
16797 if (total > 1000000)
16798 /* Do it differently for a large value, to avoid overflow. */
16799 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
16800 else
16801 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
16802 /* We can't normally display a 3-digit number,
16803 so get us a 2-digit number that is close. */
16804 if (total == 100)
16805 total = 99;
16806 if (toppos <= BUF_BEGV (b))
16807 sprintf (decode_mode_spec_buf, "Top%2d%%", total);
16808 else
16809 sprintf (decode_mode_spec_buf, "%2d%%", total);
16810 return decode_mode_spec_buf;
16814 case 's':
16815 /* status of process */
16816 obj = Fget_buffer_process (Fcurrent_buffer ());
16817 if (NILP (obj))
16818 return "no process";
16819 #ifdef subprocesses
16820 obj = Fsymbol_name (Fprocess_status (obj));
16821 #endif
16822 break;
16824 case 't': /* indicate TEXT or BINARY */
16825 #ifdef MODE_LINE_BINARY_TEXT
16826 return MODE_LINE_BINARY_TEXT (b);
16827 #else
16828 return "T";
16829 #endif
16831 case 'z':
16832 /* coding-system (not including end-of-line format) */
16833 case 'Z':
16834 /* coding-system (including end-of-line type) */
16836 int eol_flag = (c == 'Z');
16837 char *p = decode_mode_spec_buf;
16839 if (! FRAME_WINDOW_P (f))
16841 /* No need to mention EOL here--the terminal never needs
16842 to do EOL conversion. */
16843 p = decode_mode_spec_coding (keyboard_coding.symbol, p, 0);
16844 p = decode_mode_spec_coding (terminal_coding.symbol, p, 0);
16846 p = decode_mode_spec_coding (b->buffer_file_coding_system,
16847 p, eol_flag);
16849 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
16850 #ifdef subprocesses
16851 obj = Fget_buffer_process (Fcurrent_buffer ());
16852 if (PROCESSP (obj))
16854 p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system,
16855 p, eol_flag);
16856 p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system,
16857 p, eol_flag);
16859 #endif /* subprocesses */
16860 #endif /* 0 */
16861 *p = 0;
16862 return decode_mode_spec_buf;
16866 if (STRINGP (obj))
16868 *multibyte = STRING_MULTIBYTE (obj);
16869 return (char *) SDATA (obj);
16871 else
16872 return "";
16876 /* Count up to COUNT lines starting from START / START_BYTE.
16877 But don't go beyond LIMIT_BYTE.
16878 Return the number of lines thus found (always nonnegative).
16880 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
16882 static int
16883 display_count_lines (start, start_byte, limit_byte, count, byte_pos_ptr)
16884 int start, start_byte, limit_byte, count;
16885 int *byte_pos_ptr;
16887 register unsigned char *cursor;
16888 unsigned char *base;
16890 register int ceiling;
16891 register unsigned char *ceiling_addr;
16892 int orig_count = count;
16894 /* If we are not in selective display mode,
16895 check only for newlines. */
16896 int selective_display = (!NILP (current_buffer->selective_display)
16897 && !INTEGERP (current_buffer->selective_display));
16899 if (count > 0)
16901 while (start_byte < limit_byte)
16903 ceiling = BUFFER_CEILING_OF (start_byte);
16904 ceiling = min (limit_byte - 1, ceiling);
16905 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
16906 base = (cursor = BYTE_POS_ADDR (start_byte));
16907 while (1)
16909 if (selective_display)
16910 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
16912 else
16913 while (*cursor != '\n' && ++cursor != ceiling_addr)
16916 if (cursor != ceiling_addr)
16918 if (--count == 0)
16920 start_byte += cursor - base + 1;
16921 *byte_pos_ptr = start_byte;
16922 return orig_count;
16924 else
16925 if (++cursor == ceiling_addr)
16926 break;
16928 else
16929 break;
16931 start_byte += cursor - base;
16934 else
16936 while (start_byte > limit_byte)
16938 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
16939 ceiling = max (limit_byte, ceiling);
16940 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1;
16941 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
16942 while (1)
16944 if (selective_display)
16945 while (--cursor != ceiling_addr
16946 && *cursor != '\n' && *cursor != 015)
16948 else
16949 while (--cursor != ceiling_addr && *cursor != '\n')
16952 if (cursor != ceiling_addr)
16954 if (++count == 0)
16956 start_byte += cursor - base + 1;
16957 *byte_pos_ptr = start_byte;
16958 /* When scanning backwards, we should
16959 not count the newline posterior to which we stop. */
16960 return - orig_count - 1;
16963 else
16964 break;
16966 /* Here we add 1 to compensate for the last decrement
16967 of CURSOR, which took it past the valid range. */
16968 start_byte += cursor - base + 1;
16972 *byte_pos_ptr = limit_byte;
16974 if (count < 0)
16975 return - orig_count + count;
16976 return orig_count - count;
16982 /***********************************************************************
16983 Displaying strings
16984 ***********************************************************************/
16986 /* Display a NUL-terminated string, starting with index START.
16988 If STRING is non-null, display that C string. Otherwise, the Lisp
16989 string LISP_STRING is displayed.
16991 If FACE_STRING is not nil, FACE_STRING_POS is a position in
16992 FACE_STRING. Display STRING or LISP_STRING with the face at
16993 FACE_STRING_POS in FACE_STRING:
16995 Display the string in the environment given by IT, but use the
16996 standard display table, temporarily.
16998 FIELD_WIDTH is the minimum number of output glyphs to produce.
16999 If STRING has fewer characters than FIELD_WIDTH, pad to the right
17000 with spaces. If STRING has more characters, more than FIELD_WIDTH
17001 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
17003 PRECISION is the maximum number of characters to output from
17004 STRING. PRECISION < 0 means don't truncate the string.
17006 This is roughly equivalent to printf format specifiers:
17008 FIELD_WIDTH PRECISION PRINTF
17009 ----------------------------------------
17010 -1 -1 %s
17011 -1 10 %.10s
17012 10 -1 %10s
17013 20 10 %20.10s
17015 MULTIBYTE zero means do not display multibyte chars, > 0 means do
17016 display them, and < 0 means obey the current buffer's value of
17017 enable_multibyte_characters.
17019 Value is the number of glyphs produced. */
17021 static int
17022 display_string (string, lisp_string, face_string, face_string_pos,
17023 start, it, field_width, precision, max_x, multibyte)
17024 unsigned char *string;
17025 Lisp_Object lisp_string;
17026 Lisp_Object face_string;
17027 int face_string_pos;
17028 int start;
17029 struct it *it;
17030 int field_width, precision, max_x;
17031 int multibyte;
17033 int hpos_at_start = it->hpos;
17034 int saved_face_id = it->face_id;
17035 struct glyph_row *row = it->glyph_row;
17037 /* Initialize the iterator IT for iteration over STRING beginning
17038 with index START. */
17039 reseat_to_string (it, string, lisp_string, start,
17040 precision, field_width, multibyte);
17042 /* If displaying STRING, set up the face of the iterator
17043 from LISP_STRING, if that's given. */
17044 if (STRINGP (face_string))
17046 int endptr;
17047 struct face *face;
17049 it->face_id
17050 = face_at_string_position (it->w, face_string, face_string_pos,
17051 0, it->region_beg_charpos,
17052 it->region_end_charpos,
17053 &endptr, it->base_face_id, 0);
17054 face = FACE_FROM_ID (it->f, it->face_id);
17055 it->face_box_p = face->box != FACE_NO_BOX;
17058 /* Set max_x to the maximum allowed X position. Don't let it go
17059 beyond the right edge of the window. */
17060 if (max_x <= 0)
17061 max_x = it->last_visible_x;
17062 else
17063 max_x = min (max_x, it->last_visible_x);
17065 /* Skip over display elements that are not visible. because IT->w is
17066 hscrolled. */
17067 if (it->current_x < it->first_visible_x)
17068 move_it_in_display_line_to (it, 100000, it->first_visible_x,
17069 MOVE_TO_POS | MOVE_TO_X);
17071 row->ascent = it->max_ascent;
17072 row->height = it->max_ascent + it->max_descent;
17073 row->phys_ascent = it->max_phys_ascent;
17074 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
17075 row->extra_line_spacing = it->max_extra_line_spacing;
17077 /* This condition is for the case that we are called with current_x
17078 past last_visible_x. */
17079 while (it->current_x < max_x)
17081 int x_before, x, n_glyphs_before, i, nglyphs;
17083 /* Get the next display element. */
17084 if (!get_next_display_element (it))
17085 break;
17087 /* Produce glyphs. */
17088 x_before = it->current_x;
17089 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
17090 PRODUCE_GLYPHS (it);
17092 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
17093 i = 0;
17094 x = x_before;
17095 while (i < nglyphs)
17097 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
17099 if (!it->truncate_lines_p
17100 && x + glyph->pixel_width > max_x)
17102 /* End of continued line or max_x reached. */
17103 if (CHAR_GLYPH_PADDING_P (*glyph))
17105 /* A wide character is unbreakable. */
17106 it->glyph_row->used[TEXT_AREA] = n_glyphs_before;
17107 it->current_x = x_before;
17109 else
17111 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
17112 it->current_x = x;
17114 break;
17116 else if (x + glyph->pixel_width > it->first_visible_x)
17118 /* Glyph is at least partially visible. */
17119 ++it->hpos;
17120 if (x < it->first_visible_x)
17121 it->glyph_row->x = x - it->first_visible_x;
17123 else
17125 /* Glyph is off the left margin of the display area.
17126 Should not happen. */
17127 abort ();
17130 row->ascent = max (row->ascent, it->max_ascent);
17131 row->height = max (row->height, it->max_ascent + it->max_descent);
17132 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
17133 row->phys_height = max (row->phys_height,
17134 it->max_phys_ascent + it->max_phys_descent);
17135 row->extra_line_spacing = max (row->extra_line_spacing,
17136 it->max_extra_line_spacing);
17137 x += glyph->pixel_width;
17138 ++i;
17141 /* Stop if max_x reached. */
17142 if (i < nglyphs)
17143 break;
17145 /* Stop at line ends. */
17146 if (ITERATOR_AT_END_OF_LINE_P (it))
17148 it->continuation_lines_width = 0;
17149 break;
17152 set_iterator_to_next (it, 1);
17154 /* Stop if truncating at the right edge. */
17155 if (it->truncate_lines_p
17156 && it->current_x >= it->last_visible_x)
17158 /* Add truncation mark, but don't do it if the line is
17159 truncated at a padding space. */
17160 if (IT_CHARPOS (*it) < it->string_nchars)
17162 if (!FRAME_WINDOW_P (it->f))
17164 int i, n;
17166 if (it->current_x > it->last_visible_x)
17168 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
17169 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
17170 break;
17171 for (n = row->used[TEXT_AREA]; i < n; ++i)
17173 row->used[TEXT_AREA] = i;
17174 produce_special_glyphs (it, IT_TRUNCATION);
17177 produce_special_glyphs (it, IT_TRUNCATION);
17179 it->glyph_row->truncated_on_right_p = 1;
17181 break;
17185 /* Maybe insert a truncation at the left. */
17186 if (it->first_visible_x
17187 && IT_CHARPOS (*it) > 0)
17189 if (!FRAME_WINDOW_P (it->f))
17190 insert_left_trunc_glyphs (it);
17191 it->glyph_row->truncated_on_left_p = 1;
17194 it->face_id = saved_face_id;
17196 /* Value is number of columns displayed. */
17197 return it->hpos - hpos_at_start;
17202 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
17203 appears as an element of LIST or as the car of an element of LIST.
17204 If PROPVAL is a list, compare each element against LIST in that
17205 way, and return 1/2 if any element of PROPVAL is found in LIST.
17206 Otherwise return 0. This function cannot quit.
17207 The return value is 2 if the text is invisible but with an ellipsis
17208 and 1 if it's invisible and without an ellipsis. */
17211 invisible_p (propval, list)
17212 register Lisp_Object propval;
17213 Lisp_Object list;
17215 register Lisp_Object tail, proptail;
17217 for (tail = list; CONSP (tail); tail = XCDR (tail))
17219 register Lisp_Object tem;
17220 tem = XCAR (tail);
17221 if (EQ (propval, tem))
17222 return 1;
17223 if (CONSP (tem) && EQ (propval, XCAR (tem)))
17224 return NILP (XCDR (tem)) ? 1 : 2;
17227 if (CONSP (propval))
17229 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
17231 Lisp_Object propelt;
17232 propelt = XCAR (proptail);
17233 for (tail = list; CONSP (tail); tail = XCDR (tail))
17235 register Lisp_Object tem;
17236 tem = XCAR (tail);
17237 if (EQ (propelt, tem))
17238 return 1;
17239 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
17240 return NILP (XCDR (tem)) ? 1 : 2;
17245 return 0;
17248 /* Calculate a width or height in pixels from a specification using
17249 the following elements:
17251 SPEC ::=
17252 NUM - a (fractional) multiple of the default font width/height
17253 (NUM) - specifies exactly NUM pixels
17254 UNIT - a fixed number of pixels, see below.
17255 ELEMENT - size of a display element in pixels, see below.
17256 (NUM . SPEC) - equals NUM * SPEC
17257 (+ SPEC SPEC ...) - add pixel values
17258 (- SPEC SPEC ...) - subtract pixel values
17259 (- SPEC) - negate pixel value
17261 NUM ::=
17262 INT or FLOAT - a number constant
17263 SYMBOL - use symbol's (buffer local) variable binding.
17265 UNIT ::=
17266 in - pixels per inch *)
17267 mm - pixels per 1/1000 meter *)
17268 cm - pixels per 1/100 meter *)
17269 width - width of current font in pixels.
17270 height - height of current font in pixels.
17272 *) using the ratio(s) defined in display-pixels-per-inch.
17274 ELEMENT ::=
17276 left-fringe - left fringe width in pixels
17277 right-fringe - right fringe width in pixels
17279 left-margin - left margin width in pixels
17280 right-margin - right margin width in pixels
17282 scroll-bar - scroll-bar area width in pixels
17284 Examples:
17286 Pixels corresponding to 5 inches:
17287 (5 . in)
17289 Total width of non-text areas on left side of window (if scroll-bar is on left):
17290 '(space :width (+ left-fringe left-margin scroll-bar))
17292 Align to first text column (in header line):
17293 '(space :align-to 0)
17295 Align to middle of text area minus half the width of variable `my-image'
17296 containing a loaded image:
17297 '(space :align-to (0.5 . (- text my-image)))
17299 Width of left margin minus width of 1 character in the default font:
17300 '(space :width (- left-margin 1))
17302 Width of left margin minus width of 2 characters in the current font:
17303 '(space :width (- left-margin (2 . width)))
17305 Center 1 character over left-margin (in header line):
17306 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
17308 Different ways to express width of left fringe plus left margin minus one pixel:
17309 '(space :width (- (+ left-fringe left-margin) (1)))
17310 '(space :width (+ left-fringe left-margin (- (1))))
17311 '(space :width (+ left-fringe left-margin (-1)))
17315 #define NUMVAL(X) \
17316 ((INTEGERP (X) || FLOATP (X)) \
17317 ? XFLOATINT (X) \
17318 : - 1)
17321 calc_pixel_width_or_height (res, it, prop, font, width_p, align_to)
17322 double *res;
17323 struct it *it;
17324 Lisp_Object prop;
17325 void *font;
17326 int width_p, *align_to;
17328 double pixels;
17330 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
17331 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
17333 if (NILP (prop))
17334 return OK_PIXELS (0);
17336 if (SYMBOLP (prop))
17338 if (SCHARS (SYMBOL_NAME (prop)) == 2)
17340 char *unit = SDATA (SYMBOL_NAME (prop));
17342 if (unit[0] == 'i' && unit[1] == 'n')
17343 pixels = 1.0;
17344 else if (unit[0] == 'm' && unit[1] == 'm')
17345 pixels = 25.4;
17346 else if (unit[0] == 'c' && unit[1] == 'm')
17347 pixels = 2.54;
17348 else
17349 pixels = 0;
17350 if (pixels > 0)
17352 double ppi;
17353 if ((ppi = NUMVAL (Vdisplay_pixels_per_inch), ppi > 0)
17354 || (CONSP (Vdisplay_pixels_per_inch)
17355 && (ppi = (width_p
17356 ? NUMVAL (XCAR (Vdisplay_pixels_per_inch))
17357 : NUMVAL (XCDR (Vdisplay_pixels_per_inch))),
17358 ppi > 0)))
17359 return OK_PIXELS (ppi / pixels);
17361 return 0;
17365 #ifdef HAVE_WINDOW_SYSTEM
17366 if (EQ (prop, Qheight))
17367 return OK_PIXELS (font ? FONT_HEIGHT ((XFontStruct *)font) : FRAME_LINE_HEIGHT (it->f));
17368 if (EQ (prop, Qwidth))
17369 return OK_PIXELS (font ? FONT_WIDTH ((XFontStruct *)font) : FRAME_COLUMN_WIDTH (it->f));
17370 #else
17371 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
17372 return OK_PIXELS (1);
17373 #endif
17375 if (EQ (prop, Qtext))
17376 return OK_PIXELS (width_p
17377 ? window_box_width (it->w, TEXT_AREA)
17378 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
17380 if (align_to && *align_to < 0)
17382 *res = 0;
17383 if (EQ (prop, Qleft))
17384 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA));
17385 if (EQ (prop, Qright))
17386 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
17387 if (EQ (prop, Qcenter))
17388 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
17389 + window_box_width (it->w, TEXT_AREA) / 2);
17390 if (EQ (prop, Qleft_fringe))
17391 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
17392 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
17393 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
17394 if (EQ (prop, Qright_fringe))
17395 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
17396 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
17397 : window_box_right_offset (it->w, TEXT_AREA));
17398 if (EQ (prop, Qleft_margin))
17399 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
17400 if (EQ (prop, Qright_margin))
17401 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
17402 if (EQ (prop, Qscroll_bar))
17403 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
17405 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
17406 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
17407 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
17408 : 0)));
17410 else
17412 if (EQ (prop, Qleft_fringe))
17413 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
17414 if (EQ (prop, Qright_fringe))
17415 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
17416 if (EQ (prop, Qleft_margin))
17417 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
17418 if (EQ (prop, Qright_margin))
17419 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
17420 if (EQ (prop, Qscroll_bar))
17421 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
17424 prop = Fbuffer_local_value (prop, it->w->buffer);
17427 if (INTEGERP (prop) || FLOATP (prop))
17429 int base_unit = (width_p
17430 ? FRAME_COLUMN_WIDTH (it->f)
17431 : FRAME_LINE_HEIGHT (it->f));
17432 return OK_PIXELS (XFLOATINT (prop) * base_unit);
17435 if (CONSP (prop))
17437 Lisp_Object car = XCAR (prop);
17438 Lisp_Object cdr = XCDR (prop);
17440 if (SYMBOLP (car))
17442 #ifdef HAVE_WINDOW_SYSTEM
17443 if (valid_image_p (prop))
17445 int id = lookup_image (it->f, prop);
17446 struct image *img = IMAGE_FROM_ID (it->f, id);
17448 return OK_PIXELS (width_p ? img->width : img->height);
17450 #endif
17451 if (EQ (car, Qplus) || EQ (car, Qminus))
17453 int first = 1;
17454 double px;
17456 pixels = 0;
17457 while (CONSP (cdr))
17459 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
17460 font, width_p, align_to))
17461 return 0;
17462 if (first)
17463 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
17464 else
17465 pixels += px;
17466 cdr = XCDR (cdr);
17468 if (EQ (car, Qminus))
17469 pixels = -pixels;
17470 return OK_PIXELS (pixels);
17473 car = Fbuffer_local_value (car, it->w->buffer);
17476 if (INTEGERP (car) || FLOATP (car))
17478 double fact;
17479 pixels = XFLOATINT (car);
17480 if (NILP (cdr))
17481 return OK_PIXELS (pixels);
17482 if (calc_pixel_width_or_height (&fact, it, cdr,
17483 font, width_p, align_to))
17484 return OK_PIXELS (pixels * fact);
17485 return 0;
17488 return 0;
17491 return 0;
17495 /***********************************************************************
17496 Glyph Display
17497 ***********************************************************************/
17499 #ifdef HAVE_WINDOW_SYSTEM
17501 #if GLYPH_DEBUG
17503 void
17504 dump_glyph_string (s)
17505 struct glyph_string *s;
17507 fprintf (stderr, "glyph string\n");
17508 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
17509 s->x, s->y, s->width, s->height);
17510 fprintf (stderr, " ybase = %d\n", s->ybase);
17511 fprintf (stderr, " hl = %d\n", s->hl);
17512 fprintf (stderr, " left overhang = %d, right = %d\n",
17513 s->left_overhang, s->right_overhang);
17514 fprintf (stderr, " nchars = %d\n", s->nchars);
17515 fprintf (stderr, " extends to end of line = %d\n",
17516 s->extends_to_end_of_line_p);
17517 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
17518 fprintf (stderr, " bg width = %d\n", s->background_width);
17521 #endif /* GLYPH_DEBUG */
17523 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
17524 of XChar2b structures for S; it can't be allocated in
17525 init_glyph_string because it must be allocated via `alloca'. W
17526 is the window on which S is drawn. ROW and AREA are the glyph row
17527 and area within the row from which S is constructed. START is the
17528 index of the first glyph structure covered by S. HL is a
17529 face-override for drawing S. */
17531 #ifdef HAVE_NTGUI
17532 #define OPTIONAL_HDC(hdc) hdc,
17533 #define DECLARE_HDC(hdc) HDC hdc;
17534 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
17535 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
17536 #endif
17538 #ifndef OPTIONAL_HDC
17539 #define OPTIONAL_HDC(hdc)
17540 #define DECLARE_HDC(hdc)
17541 #define ALLOCATE_HDC(hdc, f)
17542 #define RELEASE_HDC(hdc, f)
17543 #endif
17545 static void
17546 init_glyph_string (s, OPTIONAL_HDC (hdc) char2b, w, row, area, start, hl)
17547 struct glyph_string *s;
17548 DECLARE_HDC (hdc)
17549 XChar2b *char2b;
17550 struct window *w;
17551 struct glyph_row *row;
17552 enum glyph_row_area area;
17553 int start;
17554 enum draw_glyphs_face hl;
17556 bzero (s, sizeof *s);
17557 s->w = w;
17558 s->f = XFRAME (w->frame);
17559 #ifdef HAVE_NTGUI
17560 s->hdc = hdc;
17561 #endif
17562 s->display = FRAME_X_DISPLAY (s->f);
17563 s->window = FRAME_X_WINDOW (s->f);
17564 s->char2b = char2b;
17565 s->hl = hl;
17566 s->row = row;
17567 s->area = area;
17568 s->first_glyph = row->glyphs[area] + start;
17569 s->height = row->height;
17570 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
17572 /* Display the internal border below the tool-bar window. */
17573 if (WINDOWP (s->f->tool_bar_window)
17574 && s->w == XWINDOW (s->f->tool_bar_window))
17575 s->y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
17577 s->ybase = s->y + row->ascent;
17581 /* Append the list of glyph strings with head H and tail T to the list
17582 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
17584 static INLINE void
17585 append_glyph_string_lists (head, tail, h, t)
17586 struct glyph_string **head, **tail;
17587 struct glyph_string *h, *t;
17589 if (h)
17591 if (*head)
17592 (*tail)->next = h;
17593 else
17594 *head = h;
17595 h->prev = *tail;
17596 *tail = t;
17601 /* Prepend the list of glyph strings with head H and tail T to the
17602 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
17603 result. */
17605 static INLINE void
17606 prepend_glyph_string_lists (head, tail, h, t)
17607 struct glyph_string **head, **tail;
17608 struct glyph_string *h, *t;
17610 if (h)
17612 if (*head)
17613 (*head)->prev = t;
17614 else
17615 *tail = t;
17616 t->next = *head;
17617 *head = h;
17622 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
17623 Set *HEAD and *TAIL to the resulting list. */
17625 static INLINE void
17626 append_glyph_string (head, tail, s)
17627 struct glyph_string **head, **tail;
17628 struct glyph_string *s;
17630 s->next = s->prev = NULL;
17631 append_glyph_string_lists (head, tail, s, s);
17635 /* Get face and two-byte form of character glyph GLYPH on frame F.
17636 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
17637 a pointer to a realized face that is ready for display. */
17639 static INLINE struct face *
17640 get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
17641 struct frame *f;
17642 struct glyph *glyph;
17643 XChar2b *char2b;
17644 int *two_byte_p;
17646 struct face *face;
17648 xassert (glyph->type == CHAR_GLYPH);
17649 face = FACE_FROM_ID (f, glyph->face_id);
17651 if (two_byte_p)
17652 *two_byte_p = 0;
17654 if (!glyph->multibyte_p)
17656 /* Unibyte case. We don't have to encode, but we have to make
17657 sure to use a face suitable for unibyte. */
17658 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
17660 else if (glyph->u.ch < 128
17661 && glyph->face_id < BASIC_FACE_ID_SENTINEL)
17663 /* Case of ASCII in a face known to fit ASCII. */
17664 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
17666 else
17668 int c1, c2, charset;
17670 /* Split characters into bytes. If c2 is -1 afterwards, C is
17671 really a one-byte character so that byte1 is zero. */
17672 SPLIT_CHAR (glyph->u.ch, charset, c1, c2);
17673 if (c2 > 0)
17674 STORE_XCHAR2B (char2b, c1, c2);
17675 else
17676 STORE_XCHAR2B (char2b, 0, c1);
17678 /* Maybe encode the character in *CHAR2B. */
17679 if (charset != CHARSET_ASCII)
17681 struct font_info *font_info
17682 = FONT_INFO_FROM_ID (f, face->font_info_id);
17683 if (font_info)
17684 glyph->font_type
17685 = rif->encode_char (glyph->u.ch, char2b, font_info, two_byte_p);
17689 /* Make sure X resources of the face are allocated. */
17690 xassert (face != NULL);
17691 PREPARE_FACE_FOR_DISPLAY (f, face);
17692 return face;
17696 /* Fill glyph string S with composition components specified by S->cmp.
17698 FACES is an array of faces for all components of this composition.
17699 S->gidx is the index of the first component for S.
17700 OVERLAPS_P non-zero means S should draw the foreground only, and
17701 use its physical height for clipping.
17703 Value is the index of a component not in S. */
17705 static int
17706 fill_composite_glyph_string (s, faces, overlaps_p)
17707 struct glyph_string *s;
17708 struct face **faces;
17709 int overlaps_p;
17711 int i;
17713 xassert (s);
17715 s->for_overlaps_p = overlaps_p;
17717 s->face = faces[s->gidx];
17718 s->font = s->face->font;
17719 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
17721 /* For all glyphs of this composition, starting at the offset
17722 S->gidx, until we reach the end of the definition or encounter a
17723 glyph that requires the different face, add it to S. */
17724 ++s->nchars;
17725 for (i = s->gidx + 1; i < s->cmp->glyph_len && faces[i] == s->face; ++i)
17726 ++s->nchars;
17728 /* All glyph strings for the same composition has the same width,
17729 i.e. the width set for the first component of the composition. */
17731 s->width = s->first_glyph->pixel_width;
17733 /* If the specified font could not be loaded, use the frame's
17734 default font, but record the fact that we couldn't load it in
17735 the glyph string so that we can draw rectangles for the
17736 characters of the glyph string. */
17737 if (s->font == NULL)
17739 s->font_not_found_p = 1;
17740 s->font = FRAME_FONT (s->f);
17743 /* Adjust base line for subscript/superscript text. */
17744 s->ybase += s->first_glyph->voffset;
17746 xassert (s->face && s->face->gc);
17748 /* This glyph string must always be drawn with 16-bit functions. */
17749 s->two_byte_p = 1;
17751 return s->gidx + s->nchars;
17755 /* Fill glyph string S from a sequence of character glyphs.
17757 FACE_ID is the face id of the string. START is the index of the
17758 first glyph to consider, END is the index of the last + 1.
17759 OVERLAPS_P non-zero means S should draw the foreground only, and
17760 use its physical height for clipping.
17762 Value is the index of the first glyph not in S. */
17764 static int
17765 fill_glyph_string (s, face_id, start, end, overlaps_p)
17766 struct glyph_string *s;
17767 int face_id;
17768 int start, end, overlaps_p;
17770 struct glyph *glyph, *last;
17771 int voffset;
17772 int glyph_not_available_p;
17774 xassert (s->f == XFRAME (s->w->frame));
17775 xassert (s->nchars == 0);
17776 xassert (start >= 0 && end > start);
17778 s->for_overlaps_p = overlaps_p,
17779 glyph = s->row->glyphs[s->area] + start;
17780 last = s->row->glyphs[s->area] + end;
17781 voffset = glyph->voffset;
17783 glyph_not_available_p = glyph->glyph_not_available_p;
17785 while (glyph < last
17786 && glyph->type == CHAR_GLYPH
17787 && glyph->voffset == voffset
17788 /* Same face id implies same font, nowadays. */
17789 && glyph->face_id == face_id
17790 && glyph->glyph_not_available_p == glyph_not_available_p)
17792 int two_byte_p;
17794 s->face = get_glyph_face_and_encoding (s->f, glyph,
17795 s->char2b + s->nchars,
17796 &two_byte_p);
17797 s->two_byte_p = two_byte_p;
17798 ++s->nchars;
17799 xassert (s->nchars <= end - start);
17800 s->width += glyph->pixel_width;
17801 ++glyph;
17804 s->font = s->face->font;
17805 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
17807 /* If the specified font could not be loaded, use the frame's font,
17808 but record the fact that we couldn't load it in
17809 S->font_not_found_p so that we can draw rectangles for the
17810 characters of the glyph string. */
17811 if (s->font == NULL || glyph_not_available_p)
17813 s->font_not_found_p = 1;
17814 s->font = FRAME_FONT (s->f);
17817 /* Adjust base line for subscript/superscript text. */
17818 s->ybase += voffset;
17820 xassert (s->face && s->face->gc);
17821 return glyph - s->row->glyphs[s->area];
17825 /* Fill glyph string S from image glyph S->first_glyph. */
17827 static void
17828 fill_image_glyph_string (s)
17829 struct glyph_string *s;
17831 xassert (s->first_glyph->type == IMAGE_GLYPH);
17832 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
17833 xassert (s->img);
17834 s->slice = s->first_glyph->slice;
17835 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
17836 s->font = s->face->font;
17837 s->width = s->first_glyph->pixel_width;
17839 /* Adjust base line for subscript/superscript text. */
17840 s->ybase += s->first_glyph->voffset;
17844 /* Fill glyph string S from a sequence of stretch glyphs.
17846 ROW is the glyph row in which the glyphs are found, AREA is the
17847 area within the row. START is the index of the first glyph to
17848 consider, END is the index of the last + 1.
17850 Value is the index of the first glyph not in S. */
17852 static int
17853 fill_stretch_glyph_string (s, row, area, start, end)
17854 struct glyph_string *s;
17855 struct glyph_row *row;
17856 enum glyph_row_area area;
17857 int start, end;
17859 struct glyph *glyph, *last;
17860 int voffset, face_id;
17862 xassert (s->first_glyph->type == STRETCH_GLYPH);
17864 glyph = s->row->glyphs[s->area] + start;
17865 last = s->row->glyphs[s->area] + end;
17866 face_id = glyph->face_id;
17867 s->face = FACE_FROM_ID (s->f, face_id);
17868 s->font = s->face->font;
17869 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
17870 s->width = glyph->pixel_width;
17871 voffset = glyph->voffset;
17873 for (++glyph;
17874 (glyph < last
17875 && glyph->type == STRETCH_GLYPH
17876 && glyph->voffset == voffset
17877 && glyph->face_id == face_id);
17878 ++glyph)
17879 s->width += glyph->pixel_width;
17881 /* Adjust base line for subscript/superscript text. */
17882 s->ybase += voffset;
17884 /* The case that face->gc == 0 is handled when drawing the glyph
17885 string by calling PREPARE_FACE_FOR_DISPLAY. */
17886 xassert (s->face);
17887 return glyph - s->row->glyphs[s->area];
17891 /* EXPORT for RIF:
17892 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
17893 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
17894 assumed to be zero. */
17896 void
17897 x_get_glyph_overhangs (glyph, f, left, right)
17898 struct glyph *glyph;
17899 struct frame *f;
17900 int *left, *right;
17902 *left = *right = 0;
17904 if (glyph->type == CHAR_GLYPH)
17906 XFontStruct *font;
17907 struct face *face;
17908 struct font_info *font_info;
17909 XChar2b char2b;
17910 XCharStruct *pcm;
17912 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
17913 font = face->font;
17914 font_info = FONT_INFO_FROM_ID (f, face->font_info_id);
17915 if (font /* ++KFS: Should this be font_info ? */
17916 && (pcm = rif->per_char_metric (font, &char2b, glyph->font_type)))
17918 if (pcm->rbearing > pcm->width)
17919 *right = pcm->rbearing - pcm->width;
17920 if (pcm->lbearing < 0)
17921 *left = -pcm->lbearing;
17927 /* Return the index of the first glyph preceding glyph string S that
17928 is overwritten by S because of S's left overhang. Value is -1
17929 if no glyphs are overwritten. */
17931 static int
17932 left_overwritten (s)
17933 struct glyph_string *s;
17935 int k;
17937 if (s->left_overhang)
17939 int x = 0, i;
17940 struct glyph *glyphs = s->row->glyphs[s->area];
17941 int first = s->first_glyph - glyphs;
17943 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
17944 x -= glyphs[i].pixel_width;
17946 k = i + 1;
17948 else
17949 k = -1;
17951 return k;
17955 /* Return the index of the first glyph preceding glyph string S that
17956 is overwriting S because of its right overhang. Value is -1 if no
17957 glyph in front of S overwrites S. */
17959 static int
17960 left_overwriting (s)
17961 struct glyph_string *s;
17963 int i, k, x;
17964 struct glyph *glyphs = s->row->glyphs[s->area];
17965 int first = s->first_glyph - glyphs;
17967 k = -1;
17968 x = 0;
17969 for (i = first - 1; i >= 0; --i)
17971 int left, right;
17972 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
17973 if (x + right > 0)
17974 k = i;
17975 x -= glyphs[i].pixel_width;
17978 return k;
17982 /* Return the index of the last glyph following glyph string S that is
17983 not overwritten by S because of S's right overhang. Value is -1 if
17984 no such glyph is found. */
17986 static int
17987 right_overwritten (s)
17988 struct glyph_string *s;
17990 int k = -1;
17992 if (s->right_overhang)
17994 int x = 0, i;
17995 struct glyph *glyphs = s->row->glyphs[s->area];
17996 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
17997 int end = s->row->used[s->area];
17999 for (i = first; i < end && s->right_overhang > x; ++i)
18000 x += glyphs[i].pixel_width;
18002 k = i;
18005 return k;
18009 /* Return the index of the last glyph following glyph string S that
18010 overwrites S because of its left overhang. Value is negative
18011 if no such glyph is found. */
18013 static int
18014 right_overwriting (s)
18015 struct glyph_string *s;
18017 int i, k, x;
18018 int end = s->row->used[s->area];
18019 struct glyph *glyphs = s->row->glyphs[s->area];
18020 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
18022 k = -1;
18023 x = 0;
18024 for (i = first; i < end; ++i)
18026 int left, right;
18027 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
18028 if (x - left < 0)
18029 k = i;
18030 x += glyphs[i].pixel_width;
18033 return k;
18037 /* Get face and two-byte form of character C in face FACE_ID on frame
18038 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
18039 means we want to display multibyte text. DISPLAY_P non-zero means
18040 make sure that X resources for the face returned are allocated.
18041 Value is a pointer to a realized face that is ready for display if
18042 DISPLAY_P is non-zero. */
18044 static INLINE struct face *
18045 get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p, display_p)
18046 struct frame *f;
18047 int c, face_id;
18048 XChar2b *char2b;
18049 int multibyte_p, display_p;
18051 struct face *face = FACE_FROM_ID (f, face_id);
18053 if (!multibyte_p)
18055 /* Unibyte case. We don't have to encode, but we have to make
18056 sure to use a face suitable for unibyte. */
18057 STORE_XCHAR2B (char2b, 0, c);
18058 face_id = FACE_FOR_CHAR (f, face, c);
18059 face = FACE_FROM_ID (f, face_id);
18061 else if (c < 128 && face_id < BASIC_FACE_ID_SENTINEL)
18063 /* Case of ASCII in a face known to fit ASCII. */
18064 STORE_XCHAR2B (char2b, 0, c);
18066 else
18068 int c1, c2, charset;
18070 /* Split characters into bytes. If c2 is -1 afterwards, C is
18071 really a one-byte character so that byte1 is zero. */
18072 SPLIT_CHAR (c, charset, c1, c2);
18073 if (c2 > 0)
18074 STORE_XCHAR2B (char2b, c1, c2);
18075 else
18076 STORE_XCHAR2B (char2b, 0, c1);
18078 /* Maybe encode the character in *CHAR2B. */
18079 if (face->font != NULL)
18081 struct font_info *font_info
18082 = FONT_INFO_FROM_ID (f, face->font_info_id);
18083 if (font_info)
18084 rif->encode_char (c, char2b, font_info, 0);
18088 /* Make sure X resources of the face are allocated. */
18089 #ifdef HAVE_X_WINDOWS
18090 if (display_p)
18091 #endif
18093 xassert (face != NULL);
18094 PREPARE_FACE_FOR_DISPLAY (f, face);
18097 return face;
18101 /* Set background width of glyph string S. START is the index of the
18102 first glyph following S. LAST_X is the right-most x-position + 1
18103 in the drawing area. */
18105 static INLINE void
18106 set_glyph_string_background_width (s, start, last_x)
18107 struct glyph_string *s;
18108 int start;
18109 int last_x;
18111 /* If the face of this glyph string has to be drawn to the end of
18112 the drawing area, set S->extends_to_end_of_line_p. */
18113 struct face *default_face = FACE_FROM_ID (s->f, DEFAULT_FACE_ID);
18115 if (start == s->row->used[s->area]
18116 && s->area == TEXT_AREA
18117 && ((s->hl == DRAW_NORMAL_TEXT
18118 && (s->row->fill_line_p
18119 || s->face->background != default_face->background
18120 || s->face->stipple != default_face->stipple
18121 || s->row->mouse_face_p))
18122 || s->hl == DRAW_MOUSE_FACE
18123 || ((s->hl == DRAW_IMAGE_RAISED || s->hl == DRAW_IMAGE_SUNKEN)
18124 && s->row->fill_line_p)))
18125 s->extends_to_end_of_line_p = 1;
18127 /* If S extends its face to the end of the line, set its
18128 background_width to the distance to the right edge of the drawing
18129 area. */
18130 if (s->extends_to_end_of_line_p)
18131 s->background_width = last_x - s->x + 1;
18132 else
18133 s->background_width = s->width;
18137 /* Compute overhangs and x-positions for glyph string S and its
18138 predecessors, or successors. X is the starting x-position for S.
18139 BACKWARD_P non-zero means process predecessors. */
18141 static void
18142 compute_overhangs_and_x (s, x, backward_p)
18143 struct glyph_string *s;
18144 int x;
18145 int backward_p;
18147 if (backward_p)
18149 while (s)
18151 if (rif->compute_glyph_string_overhangs)
18152 rif->compute_glyph_string_overhangs (s);
18153 x -= s->width;
18154 s->x = x;
18155 s = s->prev;
18158 else
18160 while (s)
18162 if (rif->compute_glyph_string_overhangs)
18163 rif->compute_glyph_string_overhangs (s);
18164 s->x = x;
18165 x += s->width;
18166 s = s->next;
18173 /* The following macros are only called from draw_glyphs below.
18174 They reference the following parameters of that function directly:
18175 `w', `row', `area', and `overlap_p'
18176 as well as the following local variables:
18177 `s', `f', and `hdc' (in W32) */
18179 #ifdef HAVE_NTGUI
18180 /* On W32, silently add local `hdc' variable to argument list of
18181 init_glyph_string. */
18182 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
18183 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
18184 #else
18185 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
18186 init_glyph_string (s, char2b, w, row, area, start, hl)
18187 #endif
18189 /* Add a glyph string for a stretch glyph to the list of strings
18190 between HEAD and TAIL. START is the index of the stretch glyph in
18191 row area AREA of glyph row ROW. END is the index of the last glyph
18192 in that glyph row area. X is the current output position assigned
18193 to the new glyph string constructed. HL overrides that face of the
18194 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
18195 is the right-most x-position of the drawing area. */
18197 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
18198 and below -- keep them on one line. */
18199 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
18200 do \
18202 s = (struct glyph_string *) alloca (sizeof *s); \
18203 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
18204 START = fill_stretch_glyph_string (s, row, area, START, END); \
18205 append_glyph_string (&HEAD, &TAIL, s); \
18206 s->x = (X); \
18208 while (0)
18211 /* Add a glyph string for an image glyph to the list of strings
18212 between HEAD and TAIL. START is the index of the image glyph in
18213 row area AREA of glyph row ROW. END is the index of the last glyph
18214 in that glyph row area. X is the current output position assigned
18215 to the new glyph string constructed. HL overrides that face of the
18216 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
18217 is the right-most x-position of the drawing area. */
18219 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
18220 do \
18222 s = (struct glyph_string *) alloca (sizeof *s); \
18223 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
18224 fill_image_glyph_string (s); \
18225 append_glyph_string (&HEAD, &TAIL, s); \
18226 ++START; \
18227 s->x = (X); \
18229 while (0)
18232 /* Add a glyph string for a sequence of character glyphs to the list
18233 of strings between HEAD and TAIL. START is the index of the first
18234 glyph in row area AREA of glyph row ROW that is part of the new
18235 glyph string. END is the index of the last glyph in that glyph row
18236 area. X is the current output position assigned to the new glyph
18237 string constructed. HL overrides that face of the glyph; e.g. it
18238 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
18239 right-most x-position of the drawing area. */
18241 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
18242 do \
18244 int c, face_id; \
18245 XChar2b *char2b; \
18247 c = (row)->glyphs[area][START].u.ch; \
18248 face_id = (row)->glyphs[area][START].face_id; \
18250 s = (struct glyph_string *) alloca (sizeof *s); \
18251 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
18252 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
18253 append_glyph_string (&HEAD, &TAIL, s); \
18254 s->x = (X); \
18255 START = fill_glyph_string (s, face_id, START, END, overlaps_p); \
18257 while (0)
18260 /* Add a glyph string for a composite sequence to the list of strings
18261 between HEAD and TAIL. START is the index of the first glyph in
18262 row area AREA of glyph row ROW that is part of the new glyph
18263 string. END is the index of the last glyph in that glyph row area.
18264 X is the current output position assigned to the new glyph string
18265 constructed. HL overrides that face of the glyph; e.g. it is
18266 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
18267 x-position of the drawing area. */
18269 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
18270 do { \
18271 int cmp_id = (row)->glyphs[area][START].u.cmp_id; \
18272 int face_id = (row)->glyphs[area][START].face_id; \
18273 struct face *base_face = FACE_FROM_ID (f, face_id); \
18274 struct composition *cmp = composition_table[cmp_id]; \
18275 int glyph_len = cmp->glyph_len; \
18276 XChar2b *char2b; \
18277 struct face **faces; \
18278 struct glyph_string *first_s = NULL; \
18279 int n; \
18281 base_face = base_face->ascii_face; \
18282 char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len); \
18283 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
18284 /* At first, fill in `char2b' and `faces'. */ \
18285 for (n = 0; n < glyph_len; n++) \
18287 int c = COMPOSITION_GLYPH (cmp, n); \
18288 int this_face_id = FACE_FOR_CHAR (f, base_face, c); \
18289 faces[n] = FACE_FROM_ID (f, this_face_id); \
18290 get_char_face_and_encoding (f, c, this_face_id, \
18291 char2b + n, 1, 1); \
18294 /* Make glyph_strings for each glyph sequence that is drawable by \
18295 the same face, and append them to HEAD/TAIL. */ \
18296 for (n = 0; n < cmp->glyph_len;) \
18298 s = (struct glyph_string *) alloca (sizeof *s); \
18299 INIT_GLYPH_STRING (s, char2b + n, w, row, area, START, HL); \
18300 append_glyph_string (&(HEAD), &(TAIL), s); \
18301 s->cmp = cmp; \
18302 s->gidx = n; \
18303 s->x = (X); \
18305 if (n == 0) \
18306 first_s = s; \
18308 n = fill_composite_glyph_string (s, faces, overlaps_p); \
18311 ++START; \
18312 s = first_s; \
18313 } while (0)
18316 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
18317 of AREA of glyph row ROW on window W between indices START and END.
18318 HL overrides the face for drawing glyph strings, e.g. it is
18319 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
18320 x-positions of the drawing area.
18322 This is an ugly monster macro construct because we must use alloca
18323 to allocate glyph strings (because draw_glyphs can be called
18324 asynchronously). */
18326 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
18327 do \
18329 HEAD = TAIL = NULL; \
18330 while (START < END) \
18332 struct glyph *first_glyph = (row)->glyphs[area] + START; \
18333 switch (first_glyph->type) \
18335 case CHAR_GLYPH: \
18336 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
18337 HL, X, LAST_X); \
18338 break; \
18340 case COMPOSITE_GLYPH: \
18341 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
18342 HL, X, LAST_X); \
18343 break; \
18345 case STRETCH_GLYPH: \
18346 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
18347 HL, X, LAST_X); \
18348 break; \
18350 case IMAGE_GLYPH: \
18351 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
18352 HL, X, LAST_X); \
18353 break; \
18355 default: \
18356 abort (); \
18359 set_glyph_string_background_width (s, START, LAST_X); \
18360 (X) += s->width; \
18363 while (0)
18366 /* Draw glyphs between START and END in AREA of ROW on window W,
18367 starting at x-position X. X is relative to AREA in W. HL is a
18368 face-override with the following meaning:
18370 DRAW_NORMAL_TEXT draw normally
18371 DRAW_CURSOR draw in cursor face
18372 DRAW_MOUSE_FACE draw in mouse face.
18373 DRAW_INVERSE_VIDEO draw in mode line face
18374 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
18375 DRAW_IMAGE_RAISED draw an image with a raised relief around it
18377 If OVERLAPS_P is non-zero, draw only the foreground of characters
18378 and clip to the physical height of ROW.
18380 Value is the x-position reached, relative to AREA of W. */
18382 static int
18383 draw_glyphs (w, x, row, area, start, end, hl, overlaps_p)
18384 struct window *w;
18385 int x;
18386 struct glyph_row *row;
18387 enum glyph_row_area area;
18388 int start, end;
18389 enum draw_glyphs_face hl;
18390 int overlaps_p;
18392 struct glyph_string *head, *tail;
18393 struct glyph_string *s;
18394 struct glyph_string *clip_head = NULL, *clip_tail = NULL;
18395 int last_x, area_width;
18396 int x_reached;
18397 int i, j;
18398 struct frame *f = XFRAME (WINDOW_FRAME (w));
18399 DECLARE_HDC (hdc);
18401 ALLOCATE_HDC (hdc, f);
18403 /* Let's rather be paranoid than getting a SEGV. */
18404 end = min (end, row->used[area]);
18405 start = max (0, start);
18406 start = min (end, start);
18408 /* Translate X to frame coordinates. Set last_x to the right
18409 end of the drawing area. */
18410 if (row->full_width_p)
18412 /* X is relative to the left edge of W, without scroll bars
18413 or fringes. */
18414 x += WINDOW_LEFT_EDGE_X (w);
18415 last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
18417 else
18419 int area_left = window_box_left (w, area);
18420 x += area_left;
18421 area_width = window_box_width (w, area);
18422 last_x = area_left + area_width;
18425 /* Build a doubly-linked list of glyph_string structures between
18426 head and tail from what we have to draw. Note that the macro
18427 BUILD_GLYPH_STRINGS will modify its start parameter. That's
18428 the reason we use a separate variable `i'. */
18429 i = start;
18430 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
18431 if (tail)
18432 x_reached = tail->x + tail->background_width;
18433 else
18434 x_reached = x;
18436 /* If there are any glyphs with lbearing < 0 or rbearing > width in
18437 the row, redraw some glyphs in front or following the glyph
18438 strings built above. */
18439 if (head && !overlaps_p && row->contains_overlapping_glyphs_p)
18441 int dummy_x = 0;
18442 struct glyph_string *h, *t;
18444 /* Compute overhangs for all glyph strings. */
18445 if (rif->compute_glyph_string_overhangs)
18446 for (s = head; s; s = s->next)
18447 rif->compute_glyph_string_overhangs (s);
18449 /* Prepend glyph strings for glyphs in front of the first glyph
18450 string that are overwritten because of the first glyph
18451 string's left overhang. The background of all strings
18452 prepended must be drawn because the first glyph string
18453 draws over it. */
18454 i = left_overwritten (head);
18455 if (i >= 0)
18457 j = i;
18458 BUILD_GLYPH_STRINGS (j, start, h, t,
18459 DRAW_NORMAL_TEXT, dummy_x, last_x);
18460 start = i;
18461 compute_overhangs_and_x (t, head->x, 1);
18462 prepend_glyph_string_lists (&head, &tail, h, t);
18463 clip_head = head;
18466 /* Prepend glyph strings for glyphs in front of the first glyph
18467 string that overwrite that glyph string because of their
18468 right overhang. For these strings, only the foreground must
18469 be drawn, because it draws over the glyph string at `head'.
18470 The background must not be drawn because this would overwrite
18471 right overhangs of preceding glyphs for which no glyph
18472 strings exist. */
18473 i = left_overwriting (head);
18474 if (i >= 0)
18476 clip_head = head;
18477 BUILD_GLYPH_STRINGS (i, start, h, t,
18478 DRAW_NORMAL_TEXT, dummy_x, last_x);
18479 for (s = h; s; s = s->next)
18480 s->background_filled_p = 1;
18481 compute_overhangs_and_x (t, head->x, 1);
18482 prepend_glyph_string_lists (&head, &tail, h, t);
18485 /* Append glyphs strings for glyphs following the last glyph
18486 string tail that are overwritten by tail. The background of
18487 these strings has to be drawn because tail's foreground draws
18488 over it. */
18489 i = right_overwritten (tail);
18490 if (i >= 0)
18492 BUILD_GLYPH_STRINGS (end, i, h, t,
18493 DRAW_NORMAL_TEXT, x, last_x);
18494 compute_overhangs_and_x (h, tail->x + tail->width, 0);
18495 append_glyph_string_lists (&head, &tail, h, t);
18496 clip_tail = tail;
18499 /* Append glyph strings for glyphs following the last glyph
18500 string tail that overwrite tail. The foreground of such
18501 glyphs has to be drawn because it writes into the background
18502 of tail. The background must not be drawn because it could
18503 paint over the foreground of following glyphs. */
18504 i = right_overwriting (tail);
18505 if (i >= 0)
18507 clip_tail = tail;
18508 BUILD_GLYPH_STRINGS (end, i, h, t,
18509 DRAW_NORMAL_TEXT, x, last_x);
18510 for (s = h; s; s = s->next)
18511 s->background_filled_p = 1;
18512 compute_overhangs_and_x (h, tail->x + tail->width, 0);
18513 append_glyph_string_lists (&head, &tail, h, t);
18515 if (clip_head || clip_tail)
18516 for (s = head; s; s = s->next)
18518 s->clip_head = clip_head;
18519 s->clip_tail = clip_tail;
18523 /* Draw all strings. */
18524 for (s = head; s; s = s->next)
18525 rif->draw_glyph_string (s);
18527 if (area == TEXT_AREA
18528 && !row->full_width_p
18529 /* When drawing overlapping rows, only the glyph strings'
18530 foreground is drawn, which doesn't erase a cursor
18531 completely. */
18532 && !overlaps_p)
18534 int x0 = clip_head ? clip_head->x : (head ? head->x : x);
18535 int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width
18536 : (tail ? tail->x + tail->background_width : x));
18538 int text_left = window_box_left (w, TEXT_AREA);
18539 x0 -= text_left;
18540 x1 -= text_left;
18542 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
18543 row->y, MATRIX_ROW_BOTTOM_Y (row));
18546 /* Value is the x-position up to which drawn, relative to AREA of W.
18547 This doesn't include parts drawn because of overhangs. */
18548 if (row->full_width_p)
18549 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
18550 else
18551 x_reached -= window_box_left (w, area);
18553 RELEASE_HDC (hdc, f);
18555 return x_reached;
18558 /* Expand row matrix if too narrow. Don't expand if area
18559 is not present. */
18561 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
18563 if (!fonts_changed_p \
18564 && (it->glyph_row->glyphs[area] \
18565 < it->glyph_row->glyphs[area + 1])) \
18567 it->w->ncols_scale_factor++; \
18568 fonts_changed_p = 1; \
18572 /* Store one glyph for IT->char_to_display in IT->glyph_row.
18573 Called from x_produce_glyphs when IT->glyph_row is non-null. */
18575 static INLINE void
18576 append_glyph (it)
18577 struct it *it;
18579 struct glyph *glyph;
18580 enum glyph_row_area area = it->area;
18582 xassert (it->glyph_row);
18583 xassert (it->char_to_display != '\n' && it->char_to_display != '\t');
18585 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18586 if (glyph < it->glyph_row->glyphs[area + 1])
18588 glyph->charpos = CHARPOS (it->position);
18589 glyph->object = it->object;
18590 glyph->pixel_width = it->pixel_width;
18591 glyph->ascent = it->ascent;
18592 glyph->descent = it->descent;
18593 glyph->voffset = it->voffset;
18594 glyph->type = CHAR_GLYPH;
18595 glyph->multibyte_p = it->multibyte_p;
18596 glyph->left_box_line_p = it->start_of_box_run_p;
18597 glyph->right_box_line_p = it->end_of_box_run_p;
18598 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
18599 || it->phys_descent > it->descent);
18600 glyph->padding_p = 0;
18601 glyph->glyph_not_available_p = it->glyph_not_available_p;
18602 glyph->face_id = it->face_id;
18603 glyph->u.ch = it->char_to_display;
18604 glyph->slice = null_glyph_slice;
18605 glyph->font_type = FONT_TYPE_UNKNOWN;
18606 ++it->glyph_row->used[area];
18608 else
18609 IT_EXPAND_MATRIX_WIDTH (it, area);
18612 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
18613 Called from x_produce_glyphs when IT->glyph_row is non-null. */
18615 static INLINE void
18616 append_composite_glyph (it)
18617 struct it *it;
18619 struct glyph *glyph;
18620 enum glyph_row_area area = it->area;
18622 xassert (it->glyph_row);
18624 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18625 if (glyph < it->glyph_row->glyphs[area + 1])
18627 glyph->charpos = CHARPOS (it->position);
18628 glyph->object = it->object;
18629 glyph->pixel_width = it->pixel_width;
18630 glyph->ascent = it->ascent;
18631 glyph->descent = it->descent;
18632 glyph->voffset = it->voffset;
18633 glyph->type = COMPOSITE_GLYPH;
18634 glyph->multibyte_p = it->multibyte_p;
18635 glyph->left_box_line_p = it->start_of_box_run_p;
18636 glyph->right_box_line_p = it->end_of_box_run_p;
18637 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
18638 || it->phys_descent > it->descent);
18639 glyph->padding_p = 0;
18640 glyph->glyph_not_available_p = 0;
18641 glyph->face_id = it->face_id;
18642 glyph->u.cmp_id = it->cmp_id;
18643 glyph->slice = null_glyph_slice;
18644 glyph->font_type = FONT_TYPE_UNKNOWN;
18645 ++it->glyph_row->used[area];
18647 else
18648 IT_EXPAND_MATRIX_WIDTH (it, area);
18652 /* Change IT->ascent and IT->height according to the setting of
18653 IT->voffset. */
18655 static INLINE void
18656 take_vertical_position_into_account (it)
18657 struct it *it;
18659 if (it->voffset)
18661 if (it->voffset < 0)
18662 /* Increase the ascent so that we can display the text higher
18663 in the line. */
18664 it->ascent -= it->voffset;
18665 else
18666 /* Increase the descent so that we can display the text lower
18667 in the line. */
18668 it->descent += it->voffset;
18673 /* Produce glyphs/get display metrics for the image IT is loaded with.
18674 See the description of struct display_iterator in dispextern.h for
18675 an overview of struct display_iterator. */
18677 static void
18678 produce_image_glyph (it)
18679 struct it *it;
18681 struct image *img;
18682 struct face *face;
18683 int glyph_ascent;
18684 struct glyph_slice slice;
18686 xassert (it->what == IT_IMAGE);
18688 face = FACE_FROM_ID (it->f, it->face_id);
18689 xassert (face);
18690 /* Make sure X resources of the face is loaded. */
18691 PREPARE_FACE_FOR_DISPLAY (it->f, face);
18693 if (it->image_id < 0)
18695 /* Fringe bitmap. */
18696 it->ascent = it->phys_ascent = 0;
18697 it->descent = it->phys_descent = 0;
18698 it->pixel_width = 0;
18699 it->nglyphs = 0;
18700 return;
18703 img = IMAGE_FROM_ID (it->f, it->image_id);
18704 xassert (img);
18705 /* Make sure X resources of the image is loaded. */
18706 prepare_image_for_display (it->f, img);
18708 slice.x = slice.y = 0;
18709 slice.width = img->width;
18710 slice.height = img->height;
18712 if (INTEGERP (it->slice.x))
18713 slice.x = XINT (it->slice.x);
18714 else if (FLOATP (it->slice.x))
18715 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
18717 if (INTEGERP (it->slice.y))
18718 slice.y = XINT (it->slice.y);
18719 else if (FLOATP (it->slice.y))
18720 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
18722 if (INTEGERP (it->slice.width))
18723 slice.width = XINT (it->slice.width);
18724 else if (FLOATP (it->slice.width))
18725 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
18727 if (INTEGERP (it->slice.height))
18728 slice.height = XINT (it->slice.height);
18729 else if (FLOATP (it->slice.height))
18730 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
18732 if (slice.x >= img->width)
18733 slice.x = img->width;
18734 if (slice.y >= img->height)
18735 slice.y = img->height;
18736 if (slice.x + slice.width >= img->width)
18737 slice.width = img->width - slice.x;
18738 if (slice.y + slice.height > img->height)
18739 slice.height = img->height - slice.y;
18741 if (slice.width == 0 || slice.height == 0)
18742 return;
18744 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
18746 it->descent = slice.height - glyph_ascent;
18747 if (slice.y == 0)
18748 it->descent += img->vmargin;
18749 if (slice.y + slice.height == img->height)
18750 it->descent += img->vmargin;
18751 it->phys_descent = it->descent;
18753 it->pixel_width = slice.width;
18754 if (slice.x == 0)
18755 it->pixel_width += img->hmargin;
18756 if (slice.x + slice.width == img->width)
18757 it->pixel_width += img->hmargin;
18759 /* It's quite possible for images to have an ascent greater than
18760 their height, so don't get confused in that case. */
18761 if (it->descent < 0)
18762 it->descent = 0;
18764 #if 0 /* this breaks image tiling */
18765 /* If this glyph is alone on the last line, adjust it.ascent to minimum row ascent. */
18766 int face_ascent = face->font ? FONT_BASE (face->font) : FRAME_BASELINE_OFFSET (it->f);
18767 if (face_ascent > it->ascent)
18768 it->ascent = it->phys_ascent = face_ascent;
18769 #endif
18771 it->nglyphs = 1;
18773 if (face->box != FACE_NO_BOX)
18775 if (face->box_line_width > 0)
18777 if (slice.y == 0)
18778 it->ascent += face->box_line_width;
18779 if (slice.y + slice.height == img->height)
18780 it->descent += face->box_line_width;
18783 if (it->start_of_box_run_p && slice.x == 0)
18784 it->pixel_width += abs (face->box_line_width);
18785 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
18786 it->pixel_width += abs (face->box_line_width);
18789 take_vertical_position_into_account (it);
18791 if (it->glyph_row)
18793 struct glyph *glyph;
18794 enum glyph_row_area area = it->area;
18796 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18797 if (glyph < it->glyph_row->glyphs[area + 1])
18799 glyph->charpos = CHARPOS (it->position);
18800 glyph->object = it->object;
18801 glyph->pixel_width = it->pixel_width;
18802 glyph->ascent = glyph_ascent;
18803 glyph->descent = it->descent;
18804 glyph->voffset = it->voffset;
18805 glyph->type = IMAGE_GLYPH;
18806 glyph->multibyte_p = it->multibyte_p;
18807 glyph->left_box_line_p = it->start_of_box_run_p;
18808 glyph->right_box_line_p = it->end_of_box_run_p;
18809 glyph->overlaps_vertically_p = 0;
18810 glyph->padding_p = 0;
18811 glyph->glyph_not_available_p = 0;
18812 glyph->face_id = it->face_id;
18813 glyph->u.img_id = img->id;
18814 glyph->slice = slice;
18815 glyph->font_type = FONT_TYPE_UNKNOWN;
18816 ++it->glyph_row->used[area];
18818 else
18819 IT_EXPAND_MATRIX_WIDTH (it, area);
18824 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
18825 of the glyph, WIDTH and HEIGHT are the width and height of the
18826 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
18828 static void
18829 append_stretch_glyph (it, object, width, height, ascent)
18830 struct it *it;
18831 Lisp_Object object;
18832 int width, height;
18833 int ascent;
18835 struct glyph *glyph;
18836 enum glyph_row_area area = it->area;
18838 xassert (ascent >= 0 && ascent <= height);
18840 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18841 if (glyph < it->glyph_row->glyphs[area + 1])
18843 glyph->charpos = CHARPOS (it->position);
18844 glyph->object = object;
18845 glyph->pixel_width = width;
18846 glyph->ascent = ascent;
18847 glyph->descent = height - ascent;
18848 glyph->voffset = it->voffset;
18849 glyph->type = STRETCH_GLYPH;
18850 glyph->multibyte_p = it->multibyte_p;
18851 glyph->left_box_line_p = it->start_of_box_run_p;
18852 glyph->right_box_line_p = it->end_of_box_run_p;
18853 glyph->overlaps_vertically_p = 0;
18854 glyph->padding_p = 0;
18855 glyph->glyph_not_available_p = 0;
18856 glyph->face_id = it->face_id;
18857 glyph->u.stretch.ascent = ascent;
18858 glyph->u.stretch.height = height;
18859 glyph->slice = null_glyph_slice;
18860 glyph->font_type = FONT_TYPE_UNKNOWN;
18861 ++it->glyph_row->used[area];
18863 else
18864 IT_EXPAND_MATRIX_WIDTH (it, area);
18868 /* Produce a stretch glyph for iterator IT. IT->object is the value
18869 of the glyph property displayed. The value must be a list
18870 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
18871 being recognized:
18873 1. `:width WIDTH' specifies that the space should be WIDTH *
18874 canonical char width wide. WIDTH may be an integer or floating
18875 point number.
18877 2. `:relative-width FACTOR' specifies that the width of the stretch
18878 should be computed from the width of the first character having the
18879 `glyph' property, and should be FACTOR times that width.
18881 3. `:align-to HPOS' specifies that the space should be wide enough
18882 to reach HPOS, a value in canonical character units.
18884 Exactly one of the above pairs must be present.
18886 4. `:height HEIGHT' specifies that the height of the stretch produced
18887 should be HEIGHT, measured in canonical character units.
18889 5. `:relative-height FACTOR' specifies that the height of the
18890 stretch should be FACTOR times the height of the characters having
18891 the glyph property.
18893 Either none or exactly one of 4 or 5 must be present.
18895 6. `:ascent ASCENT' specifies that ASCENT percent of the height
18896 of the stretch should be used for the ascent of the stretch.
18897 ASCENT must be in the range 0 <= ASCENT <= 100. */
18899 static void
18900 produce_stretch_glyph (it)
18901 struct it *it;
18903 /* (space :width WIDTH :height HEIGHT ...) */
18904 Lisp_Object prop, plist;
18905 int width = 0, height = 0, align_to = -1;
18906 int zero_width_ok_p = 0, zero_height_ok_p = 0;
18907 int ascent = 0;
18908 double tem;
18909 struct face *face = FACE_FROM_ID (it->f, it->face_id);
18910 XFontStruct *font = face->font ? face->font : FRAME_FONT (it->f);
18912 PREPARE_FACE_FOR_DISPLAY (it->f, face);
18914 /* List should start with `space'. */
18915 xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
18916 plist = XCDR (it->object);
18918 /* Compute the width of the stretch. */
18919 if ((prop = Fsafe_plist_get (plist, QCwidth), !NILP (prop))
18920 && calc_pixel_width_or_height (&tem, it, prop, font, 1, 0))
18922 /* Absolute width `:width WIDTH' specified and valid. */
18923 zero_width_ok_p = 1;
18924 width = (int)tem;
18926 else if (prop = Fsafe_plist_get (plist, QCrelative_width),
18927 NUMVAL (prop) > 0)
18929 /* Relative width `:relative-width FACTOR' specified and valid.
18930 Compute the width of the characters having the `glyph'
18931 property. */
18932 struct it it2;
18933 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
18935 it2 = *it;
18936 if (it->multibyte_p)
18938 int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT)
18939 - IT_BYTEPOS (*it));
18940 it2.c = STRING_CHAR_AND_LENGTH (p, maxlen, it2.len);
18942 else
18943 it2.c = *p, it2.len = 1;
18945 it2.glyph_row = NULL;
18946 it2.what = IT_CHARACTER;
18947 x_produce_glyphs (&it2);
18948 width = NUMVAL (prop) * it2.pixel_width;
18950 else if ((prop = Fsafe_plist_get (plist, QCalign_to), !NILP (prop))
18951 && calc_pixel_width_or_height (&tem, it, prop, font, 1, &align_to))
18953 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
18954 align_to = (align_to < 0
18956 : align_to - window_box_left_offset (it->w, TEXT_AREA));
18957 else if (align_to < 0)
18958 align_to = window_box_left_offset (it->w, TEXT_AREA);
18959 width = max (0, (int)tem + align_to - it->current_x);
18960 zero_width_ok_p = 1;
18962 else
18963 /* Nothing specified -> width defaults to canonical char width. */
18964 width = FRAME_COLUMN_WIDTH (it->f);
18966 if (width <= 0 && (width < 0 || !zero_width_ok_p))
18967 width = 1;
18969 /* Compute height. */
18970 if ((prop = Fsafe_plist_get (plist, QCheight), !NILP (prop))
18971 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
18973 height = (int)tem;
18974 zero_height_ok_p = 1;
18976 else if (prop = Fsafe_plist_get (plist, QCrelative_height),
18977 NUMVAL (prop) > 0)
18978 height = FONT_HEIGHT (font) * NUMVAL (prop);
18979 else
18980 height = FONT_HEIGHT (font);
18982 if (height <= 0 && (height < 0 || !zero_height_ok_p))
18983 height = 1;
18985 /* Compute percentage of height used for ascent. If
18986 `:ascent ASCENT' is present and valid, use that. Otherwise,
18987 derive the ascent from the font in use. */
18988 if (prop = Fsafe_plist_get (plist, QCascent),
18989 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
18990 ascent = height * NUMVAL (prop) / 100.0;
18991 else if (!NILP (prop)
18992 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
18993 ascent = min (max (0, (int)tem), height);
18994 else
18995 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
18997 if (width > 0 && height > 0 && it->glyph_row)
18999 Lisp_Object object = it->stack[it->sp - 1].string;
19000 if (!STRINGP (object))
19001 object = it->w->buffer;
19002 append_stretch_glyph (it, object, width, height, ascent);
19005 it->pixel_width = width;
19006 it->ascent = it->phys_ascent = ascent;
19007 it->descent = it->phys_descent = height - it->ascent;
19008 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
19010 if (width > 0 && height > 0 && face->box != FACE_NO_BOX)
19012 if (face->box_line_width > 0)
19014 it->ascent += face->box_line_width;
19015 it->descent += face->box_line_width;
19018 if (it->start_of_box_run_p)
19019 it->pixel_width += abs (face->box_line_width);
19020 if (it->end_of_box_run_p)
19021 it->pixel_width += abs (face->box_line_width);
19024 take_vertical_position_into_account (it);
19027 /* Get line-height and line-spacing property at point.
19028 If line-height has format (HEIGHT TOTAL), return TOTAL
19029 in TOTAL_HEIGHT. */
19031 static Lisp_Object
19032 get_line_height_property (it, prop)
19033 struct it *it;
19034 Lisp_Object prop;
19036 Lisp_Object position, val;
19038 if (STRINGP (it->object))
19039 position = make_number (IT_STRING_CHARPOS (*it));
19040 else if (BUFFERP (it->object))
19041 position = make_number (IT_CHARPOS (*it));
19042 else
19043 return Qnil;
19045 return Fget_char_property (position, prop, it->object);
19048 /* Calculate line-height and line-spacing properties.
19049 An integer value specifies explicit pixel value.
19050 A float value specifies relative value to current face height.
19051 A cons (float . face-name) specifies relative value to
19052 height of specified face font.
19054 Returns height in pixels, or nil. */
19057 static Lisp_Object
19058 calc_line_height_property (it, val, font, boff, override)
19059 struct it *it;
19060 Lisp_Object val;
19061 XFontStruct *font;
19062 int boff, override;
19064 Lisp_Object face_name = Qnil;
19065 int ascent, descent, height;
19067 if (NILP (val) || INTEGERP (val) || (override && EQ (val, Qt)))
19068 return val;
19070 if (CONSP (val))
19072 face_name = XCAR (val);
19073 val = XCDR (val);
19074 if (!NUMBERP (val))
19075 val = make_number (1);
19076 if (NILP (face_name))
19078 height = it->ascent + it->descent;
19079 goto scale;
19083 if (NILP (face_name))
19085 font = FRAME_FONT (it->f);
19086 boff = FRAME_BASELINE_OFFSET (it->f);
19088 else if (EQ (face_name, Qt))
19090 override = 0;
19092 else
19094 int face_id;
19095 struct face *face;
19096 struct font_info *font_info;
19098 face_id = lookup_named_face (it->f, face_name, ' ', 0);
19099 if (face_id < 0)
19100 return make_number (-1);
19102 face = FACE_FROM_ID (it->f, face_id);
19103 font = face->font;
19104 if (font == NULL)
19105 return make_number (-1);
19107 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
19108 boff = font_info->baseline_offset;
19109 if (font_info->vertical_centering)
19110 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
19113 ascent = FONT_BASE (font) + boff;
19114 descent = FONT_DESCENT (font) - boff;
19116 if (override)
19118 it->override_ascent = ascent;
19119 it->override_descent = descent;
19120 it->override_boff = boff;
19123 height = ascent + descent;
19125 scale:
19126 if (FLOATP (val))
19127 height = (int)(XFLOAT_DATA (val) * height);
19128 else if (INTEGERP (val))
19129 height *= XINT (val);
19131 return make_number (height);
19135 /* RIF:
19136 Produce glyphs/get display metrics for the display element IT is
19137 loaded with. See the description of struct display_iterator in
19138 dispextern.h for an overview of struct display_iterator. */
19140 void
19141 x_produce_glyphs (it)
19142 struct it *it;
19144 int extra_line_spacing = it->extra_line_spacing;
19146 it->glyph_not_available_p = 0;
19148 if (it->what == IT_CHARACTER)
19150 XChar2b char2b;
19151 XFontStruct *font;
19152 struct face *face = FACE_FROM_ID (it->f, it->face_id);
19153 XCharStruct *pcm;
19154 int font_not_found_p;
19155 struct font_info *font_info;
19156 int boff; /* baseline offset */
19157 /* We may change it->multibyte_p upon unibyte<->multibyte
19158 conversion. So, save the current value now and restore it
19159 later.
19161 Note: It seems that we don't have to record multibyte_p in
19162 struct glyph because the character code itself tells if or
19163 not the character is multibyte. Thus, in the future, we must
19164 consider eliminating the field `multibyte_p' in the struct
19165 glyph. */
19166 int saved_multibyte_p = it->multibyte_p;
19168 /* Maybe translate single-byte characters to multibyte, or the
19169 other way. */
19170 it->char_to_display = it->c;
19171 if (!ASCII_BYTE_P (it->c))
19173 if (unibyte_display_via_language_environment
19174 && SINGLE_BYTE_CHAR_P (it->c)
19175 && (it->c >= 0240
19176 || !NILP (Vnonascii_translation_table)))
19178 it->char_to_display = unibyte_char_to_multibyte (it->c);
19179 it->multibyte_p = 1;
19180 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
19181 face = FACE_FROM_ID (it->f, it->face_id);
19183 else if (!SINGLE_BYTE_CHAR_P (it->c)
19184 && !it->multibyte_p)
19186 it->multibyte_p = 1;
19187 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
19188 face = FACE_FROM_ID (it->f, it->face_id);
19192 /* Get font to use. Encode IT->char_to_display. */
19193 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
19194 &char2b, it->multibyte_p, 0);
19195 font = face->font;
19197 /* When no suitable font found, use the default font. */
19198 font_not_found_p = font == NULL;
19199 if (font_not_found_p)
19201 font = FRAME_FONT (it->f);
19202 boff = FRAME_BASELINE_OFFSET (it->f);
19203 font_info = NULL;
19205 else
19207 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
19208 boff = font_info->baseline_offset;
19209 if (font_info->vertical_centering)
19210 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
19213 if (it->char_to_display >= ' '
19214 && (!it->multibyte_p || it->char_to_display < 128))
19216 /* Either unibyte or ASCII. */
19217 int stretched_p;
19219 it->nglyphs = 1;
19221 pcm = rif->per_char_metric (font, &char2b,
19222 FONT_TYPE_FOR_UNIBYTE (font, it->char_to_display));
19224 if (it->override_ascent >= 0)
19226 it->ascent = it->override_ascent;
19227 it->descent = it->override_descent;
19228 boff = it->override_boff;
19230 else
19232 it->ascent = FONT_BASE (font) + boff;
19233 it->descent = FONT_DESCENT (font) - boff;
19236 if (pcm)
19238 it->phys_ascent = pcm->ascent + boff;
19239 it->phys_descent = pcm->descent - boff;
19240 it->pixel_width = pcm->width;
19242 else
19244 it->glyph_not_available_p = 1;
19245 it->phys_ascent = it->ascent;
19246 it->phys_descent = it->descent;
19247 it->pixel_width = FONT_WIDTH (font);
19250 if (it->constrain_row_ascent_descent_p)
19252 if (it->descent > it->max_descent)
19254 it->ascent += it->descent - it->max_descent;
19255 it->descent = it->max_descent;
19257 if (it->ascent > it->max_ascent)
19259 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
19260 it->ascent = it->max_ascent;
19262 it->phys_ascent = min (it->phys_ascent, it->ascent);
19263 it->phys_descent = min (it->phys_descent, it->descent);
19264 extra_line_spacing = 0;
19267 /* If this is a space inside a region of text with
19268 `space-width' property, change its width. */
19269 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
19270 if (stretched_p)
19271 it->pixel_width *= XFLOATINT (it->space_width);
19273 /* If face has a box, add the box thickness to the character
19274 height. If character has a box line to the left and/or
19275 right, add the box line width to the character's width. */
19276 if (face->box != FACE_NO_BOX)
19278 int thick = face->box_line_width;
19280 if (thick > 0)
19282 it->ascent += thick;
19283 it->descent += thick;
19285 else
19286 thick = -thick;
19288 if (it->start_of_box_run_p)
19289 it->pixel_width += thick;
19290 if (it->end_of_box_run_p)
19291 it->pixel_width += thick;
19294 /* If face has an overline, add the height of the overline
19295 (1 pixel) and a 1 pixel margin to the character height. */
19296 if (face->overline_p)
19297 it->ascent += 2;
19299 if (it->constrain_row_ascent_descent_p)
19301 if (it->ascent > it->max_ascent)
19302 it->ascent = it->max_ascent;
19303 if (it->descent > it->max_descent)
19304 it->descent = it->max_descent;
19307 take_vertical_position_into_account (it);
19309 /* If we have to actually produce glyphs, do it. */
19310 if (it->glyph_row)
19312 if (stretched_p)
19314 /* Translate a space with a `space-width' property
19315 into a stretch glyph. */
19316 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
19317 / FONT_HEIGHT (font));
19318 append_stretch_glyph (it, it->object, it->pixel_width,
19319 it->ascent + it->descent, ascent);
19321 else
19322 append_glyph (it);
19324 /* If characters with lbearing or rbearing are displayed
19325 in this line, record that fact in a flag of the
19326 glyph row. This is used to optimize X output code. */
19327 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
19328 it->glyph_row->contains_overlapping_glyphs_p = 1;
19331 else if (it->char_to_display == '\n')
19333 /* A newline has no width but we need the height of the line.
19334 But if previous part of the line set a height, don't
19335 increase that height */
19337 Lisp_Object height;
19338 Lisp_Object total_height = Qnil;
19340 it->override_ascent = -1;
19341 it->pixel_width = 0;
19342 it->nglyphs = 0;
19344 height = get_line_height_property(it, Qline_height);
19345 /* Split (line-height total-height) list */
19346 if (CONSP (height)
19347 && CONSP (XCDR (height))
19348 && NILP (XCDR (XCDR (height))))
19350 total_height = XCAR (XCDR (height));
19351 height = XCAR (height);
19353 height = calc_line_height_property(it, height, font, boff, 1);
19355 if (it->override_ascent >= 0)
19357 it->ascent = it->override_ascent;
19358 it->descent = it->override_descent;
19359 boff = it->override_boff;
19361 else
19363 it->ascent = FONT_BASE (font) + boff;
19364 it->descent = FONT_DESCENT (font) - boff;
19367 if (EQ (height, Qt))
19369 if (it->descent > it->max_descent)
19371 it->ascent += it->descent - it->max_descent;
19372 it->descent = it->max_descent;
19374 if (it->ascent > it->max_ascent)
19376 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
19377 it->ascent = it->max_ascent;
19379 it->phys_ascent = min (it->phys_ascent, it->ascent);
19380 it->phys_descent = min (it->phys_descent, it->descent);
19381 it->constrain_row_ascent_descent_p = 1;
19382 extra_line_spacing = 0;
19384 else
19386 Lisp_Object spacing;
19387 int total = 0;
19389 it->phys_ascent = it->ascent;
19390 it->phys_descent = it->descent;
19392 if ((it->max_ascent > 0 || it->max_descent > 0)
19393 && face->box != FACE_NO_BOX
19394 && face->box_line_width > 0)
19396 it->ascent += face->box_line_width;
19397 it->descent += face->box_line_width;
19399 if (!NILP (height)
19400 && XINT (height) > it->ascent + it->descent)
19401 it->ascent = XINT (height) - it->descent;
19403 if (!NILP (total_height))
19404 spacing = calc_line_height_property(it, total_height, font, boff, 0);
19405 else
19407 spacing = get_line_height_property(it, Qline_spacing);
19408 spacing = calc_line_height_property(it, spacing, font, boff, 0);
19410 if (INTEGERP (spacing))
19412 extra_line_spacing = XINT (spacing);
19413 if (!NILP (total_height))
19414 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
19418 else if (it->char_to_display == '\t')
19420 int tab_width = it->tab_width * FRAME_SPACE_WIDTH (it->f);
19421 int x = it->current_x + it->continuation_lines_width;
19422 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
19424 /* If the distance from the current position to the next tab
19425 stop is less than a space character width, use the
19426 tab stop after that. */
19427 if (next_tab_x - x < FRAME_SPACE_WIDTH (it->f))
19428 next_tab_x += tab_width;
19430 it->pixel_width = next_tab_x - x;
19431 it->nglyphs = 1;
19432 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
19433 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
19435 if (it->glyph_row)
19437 append_stretch_glyph (it, it->object, it->pixel_width,
19438 it->ascent + it->descent, it->ascent);
19441 else
19443 /* A multi-byte character. Assume that the display width of the
19444 character is the width of the character multiplied by the
19445 width of the font. */
19447 /* If we found a font, this font should give us the right
19448 metrics. If we didn't find a font, use the frame's
19449 default font and calculate the width of the character
19450 from the charset width; this is what old redisplay code
19451 did. */
19453 pcm = rif->per_char_metric (font, &char2b,
19454 FONT_TYPE_FOR_MULTIBYTE (font, it->c));
19456 if (font_not_found_p || !pcm)
19458 int charset = CHAR_CHARSET (it->char_to_display);
19460 it->glyph_not_available_p = 1;
19461 it->pixel_width = (FRAME_COLUMN_WIDTH (it->f)
19462 * CHARSET_WIDTH (charset));
19463 it->phys_ascent = FONT_BASE (font) + boff;
19464 it->phys_descent = FONT_DESCENT (font) - boff;
19466 else
19468 it->pixel_width = pcm->width;
19469 it->phys_ascent = pcm->ascent + boff;
19470 it->phys_descent = pcm->descent - boff;
19471 if (it->glyph_row
19472 && (pcm->lbearing < 0
19473 || pcm->rbearing > pcm->width))
19474 it->glyph_row->contains_overlapping_glyphs_p = 1;
19476 it->nglyphs = 1;
19477 it->ascent = FONT_BASE (font) + boff;
19478 it->descent = FONT_DESCENT (font) - boff;
19479 if (face->box != FACE_NO_BOX)
19481 int thick = face->box_line_width;
19483 if (thick > 0)
19485 it->ascent += thick;
19486 it->descent += thick;
19488 else
19489 thick = - thick;
19491 if (it->start_of_box_run_p)
19492 it->pixel_width += thick;
19493 if (it->end_of_box_run_p)
19494 it->pixel_width += thick;
19497 /* If face has an overline, add the height of the overline
19498 (1 pixel) and a 1 pixel margin to the character height. */
19499 if (face->overline_p)
19500 it->ascent += 2;
19502 take_vertical_position_into_account (it);
19504 if (it->glyph_row)
19505 append_glyph (it);
19507 it->multibyte_p = saved_multibyte_p;
19509 else if (it->what == IT_COMPOSITION)
19511 /* Note: A composition is represented as one glyph in the
19512 glyph matrix. There are no padding glyphs. */
19513 XChar2b char2b;
19514 XFontStruct *font;
19515 struct face *face = FACE_FROM_ID (it->f, it->face_id);
19516 XCharStruct *pcm;
19517 int font_not_found_p;
19518 struct font_info *font_info;
19519 int boff; /* baseline offset */
19520 struct composition *cmp = composition_table[it->cmp_id];
19522 /* Maybe translate single-byte characters to multibyte. */
19523 it->char_to_display = it->c;
19524 if (unibyte_display_via_language_environment
19525 && SINGLE_BYTE_CHAR_P (it->c)
19526 && (it->c >= 0240
19527 || (it->c >= 0200
19528 && !NILP (Vnonascii_translation_table))))
19530 it->char_to_display = unibyte_char_to_multibyte (it->c);
19533 /* Get face and font to use. Encode IT->char_to_display. */
19534 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
19535 face = FACE_FROM_ID (it->f, it->face_id);
19536 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
19537 &char2b, it->multibyte_p, 0);
19538 font = face->font;
19540 /* When no suitable font found, use the default font. */
19541 font_not_found_p = font == NULL;
19542 if (font_not_found_p)
19544 font = FRAME_FONT (it->f);
19545 boff = FRAME_BASELINE_OFFSET (it->f);
19546 font_info = NULL;
19548 else
19550 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
19551 boff = font_info->baseline_offset;
19552 if (font_info->vertical_centering)
19553 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
19556 /* There are no padding glyphs, so there is only one glyph to
19557 produce for the composition. Important is that pixel_width,
19558 ascent and descent are the values of what is drawn by
19559 draw_glyphs (i.e. the values of the overall glyphs composed). */
19560 it->nglyphs = 1;
19562 /* If we have not yet calculated pixel size data of glyphs of
19563 the composition for the current face font, calculate them
19564 now. Theoretically, we have to check all fonts for the
19565 glyphs, but that requires much time and memory space. So,
19566 here we check only the font of the first glyph. This leads
19567 to incorrect display very rarely, and C-l (recenter) can
19568 correct the display anyway. */
19569 if (cmp->font != (void *) font)
19571 /* Ascent and descent of the font of the first character of
19572 this composition (adjusted by baseline offset). Ascent
19573 and descent of overall glyphs should not be less than
19574 them respectively. */
19575 int font_ascent = FONT_BASE (font) + boff;
19576 int font_descent = FONT_DESCENT (font) - boff;
19577 /* Bounding box of the overall glyphs. */
19578 int leftmost, rightmost, lowest, highest;
19579 int i, width, ascent, descent;
19581 cmp->font = (void *) font;
19583 /* Initialize the bounding box. */
19584 if (font_info
19585 && (pcm = rif->per_char_metric (font, &char2b,
19586 FONT_TYPE_FOR_MULTIBYTE (font, it->c))))
19588 width = pcm->width;
19589 ascent = pcm->ascent;
19590 descent = pcm->descent;
19592 else
19594 width = FONT_WIDTH (font);
19595 ascent = FONT_BASE (font);
19596 descent = FONT_DESCENT (font);
19599 rightmost = width;
19600 lowest = - descent + boff;
19601 highest = ascent + boff;
19602 leftmost = 0;
19604 if (font_info
19605 && font_info->default_ascent
19606 && CHAR_TABLE_P (Vuse_default_ascent)
19607 && !NILP (Faref (Vuse_default_ascent,
19608 make_number (it->char_to_display))))
19609 highest = font_info->default_ascent + boff;
19611 /* Draw the first glyph at the normal position. It may be
19612 shifted to right later if some other glyphs are drawn at
19613 the left. */
19614 cmp->offsets[0] = 0;
19615 cmp->offsets[1] = boff;
19617 /* Set cmp->offsets for the remaining glyphs. */
19618 for (i = 1; i < cmp->glyph_len; i++)
19620 int left, right, btm, top;
19621 int ch = COMPOSITION_GLYPH (cmp, i);
19622 int face_id = FACE_FOR_CHAR (it->f, face, ch);
19624 face = FACE_FROM_ID (it->f, face_id);
19625 get_char_face_and_encoding (it->f, ch, face->id,
19626 &char2b, it->multibyte_p, 0);
19627 font = face->font;
19628 if (font == NULL)
19630 font = FRAME_FONT (it->f);
19631 boff = FRAME_BASELINE_OFFSET (it->f);
19632 font_info = NULL;
19634 else
19636 font_info
19637 = FONT_INFO_FROM_ID (it->f, face->font_info_id);
19638 boff = font_info->baseline_offset;
19639 if (font_info->vertical_centering)
19640 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
19643 if (font_info
19644 && (pcm = rif->per_char_metric (font, &char2b,
19645 FONT_TYPE_FOR_MULTIBYTE (font, ch))))
19647 width = pcm->width;
19648 ascent = pcm->ascent;
19649 descent = pcm->descent;
19651 else
19653 width = FONT_WIDTH (font);
19654 ascent = 1;
19655 descent = 0;
19658 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
19660 /* Relative composition with or without
19661 alternate chars. */
19662 left = (leftmost + rightmost - width) / 2;
19663 btm = - descent + boff;
19664 if (font_info && font_info->relative_compose
19665 && (! CHAR_TABLE_P (Vignore_relative_composition)
19666 || NILP (Faref (Vignore_relative_composition,
19667 make_number (ch)))))
19670 if (- descent >= font_info->relative_compose)
19671 /* One extra pixel between two glyphs. */
19672 btm = highest + 1;
19673 else if (ascent <= 0)
19674 /* One extra pixel between two glyphs. */
19675 btm = lowest - 1 - ascent - descent;
19678 else
19680 /* A composition rule is specified by an integer
19681 value that encodes global and new reference
19682 points (GREF and NREF). GREF and NREF are
19683 specified by numbers as below:
19685 0---1---2 -- ascent
19689 9--10--11 -- center
19691 ---3---4---5--- baseline
19693 6---7---8 -- descent
19695 int rule = COMPOSITION_RULE (cmp, i);
19696 int gref, nref, grefx, grefy, nrefx, nrefy;
19698 COMPOSITION_DECODE_RULE (rule, gref, nref);
19699 grefx = gref % 3, nrefx = nref % 3;
19700 grefy = gref / 3, nrefy = nref / 3;
19702 left = (leftmost
19703 + grefx * (rightmost - leftmost) / 2
19704 - nrefx * width / 2);
19705 btm = ((grefy == 0 ? highest
19706 : grefy == 1 ? 0
19707 : grefy == 2 ? lowest
19708 : (highest + lowest) / 2)
19709 - (nrefy == 0 ? ascent + descent
19710 : nrefy == 1 ? descent - boff
19711 : nrefy == 2 ? 0
19712 : (ascent + descent) / 2));
19715 cmp->offsets[i * 2] = left;
19716 cmp->offsets[i * 2 + 1] = btm + descent;
19718 /* Update the bounding box of the overall glyphs. */
19719 right = left + width;
19720 top = btm + descent + ascent;
19721 if (left < leftmost)
19722 leftmost = left;
19723 if (right > rightmost)
19724 rightmost = right;
19725 if (top > highest)
19726 highest = top;
19727 if (btm < lowest)
19728 lowest = btm;
19731 /* If there are glyphs whose x-offsets are negative,
19732 shift all glyphs to the right and make all x-offsets
19733 non-negative. */
19734 if (leftmost < 0)
19736 for (i = 0; i < cmp->glyph_len; i++)
19737 cmp->offsets[i * 2] -= leftmost;
19738 rightmost -= leftmost;
19741 cmp->pixel_width = rightmost;
19742 cmp->ascent = highest;
19743 cmp->descent = - lowest;
19744 if (cmp->ascent < font_ascent)
19745 cmp->ascent = font_ascent;
19746 if (cmp->descent < font_descent)
19747 cmp->descent = font_descent;
19750 it->pixel_width = cmp->pixel_width;
19751 it->ascent = it->phys_ascent = cmp->ascent;
19752 it->descent = it->phys_descent = cmp->descent;
19754 if (face->box != FACE_NO_BOX)
19756 int thick = face->box_line_width;
19758 if (thick > 0)
19760 it->ascent += thick;
19761 it->descent += thick;
19763 else
19764 thick = - thick;
19766 if (it->start_of_box_run_p)
19767 it->pixel_width += thick;
19768 if (it->end_of_box_run_p)
19769 it->pixel_width += thick;
19772 /* If face has an overline, add the height of the overline
19773 (1 pixel) and a 1 pixel margin to the character height. */
19774 if (face->overline_p)
19775 it->ascent += 2;
19777 take_vertical_position_into_account (it);
19779 if (it->glyph_row)
19780 append_composite_glyph (it);
19782 else if (it->what == IT_IMAGE)
19783 produce_image_glyph (it);
19784 else if (it->what == IT_STRETCH)
19785 produce_stretch_glyph (it);
19787 /* Accumulate dimensions. Note: can't assume that it->descent > 0
19788 because this isn't true for images with `:ascent 100'. */
19789 xassert (it->ascent >= 0 && it->descent >= 0);
19790 if (it->area == TEXT_AREA)
19791 it->current_x += it->pixel_width;
19793 if (extra_line_spacing > 0)
19795 it->descent += extra_line_spacing;
19796 if (extra_line_spacing > it->max_extra_line_spacing)
19797 it->max_extra_line_spacing = extra_line_spacing;
19800 it->max_ascent = max (it->max_ascent, it->ascent);
19801 it->max_descent = max (it->max_descent, it->descent);
19802 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
19803 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
19806 /* EXPORT for RIF:
19807 Output LEN glyphs starting at START at the nominal cursor position.
19808 Advance the nominal cursor over the text. The global variable
19809 updated_window contains the window being updated, updated_row is
19810 the glyph row being updated, and updated_area is the area of that
19811 row being updated. */
19813 void
19814 x_write_glyphs (start, len)
19815 struct glyph *start;
19816 int len;
19818 int x, hpos;
19820 xassert (updated_window && updated_row);
19821 BLOCK_INPUT;
19823 /* Write glyphs. */
19825 hpos = start - updated_row->glyphs[updated_area];
19826 x = draw_glyphs (updated_window, output_cursor.x,
19827 updated_row, updated_area,
19828 hpos, hpos + len,
19829 DRAW_NORMAL_TEXT, 0);
19831 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
19832 if (updated_area == TEXT_AREA
19833 && updated_window->phys_cursor_on_p
19834 && updated_window->phys_cursor.vpos == output_cursor.vpos
19835 && updated_window->phys_cursor.hpos >= hpos
19836 && updated_window->phys_cursor.hpos < hpos + len)
19837 updated_window->phys_cursor_on_p = 0;
19839 UNBLOCK_INPUT;
19841 /* Advance the output cursor. */
19842 output_cursor.hpos += len;
19843 output_cursor.x = x;
19847 /* EXPORT for RIF:
19848 Insert LEN glyphs from START at the nominal cursor position. */
19850 void
19851 x_insert_glyphs (start, len)
19852 struct glyph *start;
19853 int len;
19855 struct frame *f;
19856 struct window *w;
19857 int line_height, shift_by_width, shifted_region_width;
19858 struct glyph_row *row;
19859 struct glyph *glyph;
19860 int frame_x, frame_y, hpos;
19862 xassert (updated_window && updated_row);
19863 BLOCK_INPUT;
19864 w = updated_window;
19865 f = XFRAME (WINDOW_FRAME (w));
19867 /* Get the height of the line we are in. */
19868 row = updated_row;
19869 line_height = row->height;
19871 /* Get the width of the glyphs to insert. */
19872 shift_by_width = 0;
19873 for (glyph = start; glyph < start + len; ++glyph)
19874 shift_by_width += glyph->pixel_width;
19876 /* Get the width of the region to shift right. */
19877 shifted_region_width = (window_box_width (w, updated_area)
19878 - output_cursor.x
19879 - shift_by_width);
19881 /* Shift right. */
19882 frame_x = window_box_left (w, updated_area) + output_cursor.x;
19883 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
19885 rif->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
19886 line_height, shift_by_width);
19888 /* Write the glyphs. */
19889 hpos = start - row->glyphs[updated_area];
19890 draw_glyphs (w, output_cursor.x, row, updated_area,
19891 hpos, hpos + len,
19892 DRAW_NORMAL_TEXT, 0);
19894 /* Advance the output cursor. */
19895 output_cursor.hpos += len;
19896 output_cursor.x += shift_by_width;
19897 UNBLOCK_INPUT;
19901 /* EXPORT for RIF:
19902 Erase the current text line from the nominal cursor position
19903 (inclusive) to pixel column TO_X (exclusive). The idea is that
19904 everything from TO_X onward is already erased.
19906 TO_X is a pixel position relative to updated_area of
19907 updated_window. TO_X == -1 means clear to the end of this area. */
19909 void
19910 x_clear_end_of_line (to_x)
19911 int to_x;
19913 struct frame *f;
19914 struct window *w = updated_window;
19915 int max_x, min_y, max_y;
19916 int from_x, from_y, to_y;
19918 xassert (updated_window && updated_row);
19919 f = XFRAME (w->frame);
19921 if (updated_row->full_width_p)
19922 max_x = WINDOW_TOTAL_WIDTH (w);
19923 else
19924 max_x = window_box_width (w, updated_area);
19925 max_y = window_text_bottom_y (w);
19927 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
19928 of window. For TO_X > 0, truncate to end of drawing area. */
19929 if (to_x == 0)
19930 return;
19931 else if (to_x < 0)
19932 to_x = max_x;
19933 else
19934 to_x = min (to_x, max_x);
19936 to_y = min (max_y, output_cursor.y + updated_row->height);
19938 /* Notice if the cursor will be cleared by this operation. */
19939 if (!updated_row->full_width_p)
19940 notice_overwritten_cursor (w, updated_area,
19941 output_cursor.x, -1,
19942 updated_row->y,
19943 MATRIX_ROW_BOTTOM_Y (updated_row));
19945 from_x = output_cursor.x;
19947 /* Translate to frame coordinates. */
19948 if (updated_row->full_width_p)
19950 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
19951 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
19953 else
19955 int area_left = window_box_left (w, updated_area);
19956 from_x += area_left;
19957 to_x += area_left;
19960 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
19961 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
19962 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
19964 /* Prevent inadvertently clearing to end of the X window. */
19965 if (to_x > from_x && to_y > from_y)
19967 BLOCK_INPUT;
19968 rif->clear_frame_area (f, from_x, from_y,
19969 to_x - from_x, to_y - from_y);
19970 UNBLOCK_INPUT;
19974 #endif /* HAVE_WINDOW_SYSTEM */
19978 /***********************************************************************
19979 Cursor types
19980 ***********************************************************************/
19982 /* Value is the internal representation of the specified cursor type
19983 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
19984 of the bar cursor. */
19986 static enum text_cursor_kinds
19987 get_specified_cursor_type (arg, width)
19988 Lisp_Object arg;
19989 int *width;
19991 enum text_cursor_kinds type;
19993 if (NILP (arg))
19994 return NO_CURSOR;
19996 if (EQ (arg, Qbox))
19997 return FILLED_BOX_CURSOR;
19999 if (EQ (arg, Qhollow))
20000 return HOLLOW_BOX_CURSOR;
20002 if (EQ (arg, Qbar))
20004 *width = 2;
20005 return BAR_CURSOR;
20008 if (CONSP (arg)
20009 && EQ (XCAR (arg), Qbar)
20010 && INTEGERP (XCDR (arg))
20011 && XINT (XCDR (arg)) >= 0)
20013 *width = XINT (XCDR (arg));
20014 return BAR_CURSOR;
20017 if (EQ (arg, Qhbar))
20019 *width = 2;
20020 return HBAR_CURSOR;
20023 if (CONSP (arg)
20024 && EQ (XCAR (arg), Qhbar)
20025 && INTEGERP (XCDR (arg))
20026 && XINT (XCDR (arg)) >= 0)
20028 *width = XINT (XCDR (arg));
20029 return HBAR_CURSOR;
20032 /* Treat anything unknown as "hollow box cursor".
20033 It was bad to signal an error; people have trouble fixing
20034 .Xdefaults with Emacs, when it has something bad in it. */
20035 type = HOLLOW_BOX_CURSOR;
20037 return type;
20040 /* Set the default cursor types for specified frame. */
20041 void
20042 set_frame_cursor_types (f, arg)
20043 struct frame *f;
20044 Lisp_Object arg;
20046 int width;
20047 Lisp_Object tem;
20049 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
20050 FRAME_CURSOR_WIDTH (f) = width;
20052 /* By default, set up the blink-off state depending on the on-state. */
20054 tem = Fassoc (arg, Vblink_cursor_alist);
20055 if (!NILP (tem))
20057 FRAME_BLINK_OFF_CURSOR (f)
20058 = get_specified_cursor_type (XCDR (tem), &width);
20059 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
20061 else
20062 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
20066 /* Return the cursor we want to be displayed in window W. Return
20067 width of bar/hbar cursor through WIDTH arg. Return with
20068 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
20069 (i.e. if the `system caret' should track this cursor).
20071 In a mini-buffer window, we want the cursor only to appear if we
20072 are reading input from this window. For the selected window, we
20073 want the cursor type given by the frame parameter or buffer local
20074 setting of cursor-type. If explicitly marked off, draw no cursor.
20075 In all other cases, we want a hollow box cursor. */
20077 static enum text_cursor_kinds
20078 get_window_cursor_type (w, glyph, width, active_cursor)
20079 struct window *w;
20080 struct glyph *glyph;
20081 int *width;
20082 int *active_cursor;
20084 struct frame *f = XFRAME (w->frame);
20085 struct buffer *b = XBUFFER (w->buffer);
20086 int cursor_type = DEFAULT_CURSOR;
20087 Lisp_Object alt_cursor;
20088 int non_selected = 0;
20090 *active_cursor = 1;
20092 /* Echo area */
20093 if (cursor_in_echo_area
20094 && FRAME_HAS_MINIBUF_P (f)
20095 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
20097 if (w == XWINDOW (echo_area_window))
20099 *width = FRAME_CURSOR_WIDTH (f);
20100 return FRAME_DESIRED_CURSOR (f);
20103 *active_cursor = 0;
20104 non_selected = 1;
20107 /* Nonselected window or nonselected frame. */
20108 else if (w != XWINDOW (f->selected_window)
20109 #ifdef HAVE_WINDOW_SYSTEM
20110 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame
20111 #endif
20114 *active_cursor = 0;
20116 if (MINI_WINDOW_P (w) && minibuf_level == 0)
20117 return NO_CURSOR;
20119 non_selected = 1;
20122 /* Never display a cursor in a window in which cursor-type is nil. */
20123 if (NILP (b->cursor_type))
20124 return NO_CURSOR;
20126 /* Use cursor-in-non-selected-windows for non-selected window or frame. */
20127 if (non_selected)
20129 alt_cursor = Fbuffer_local_value (Qcursor_in_non_selected_windows, w->buffer);
20130 return get_specified_cursor_type (alt_cursor, width);
20133 /* Get the normal cursor type for this window. */
20134 if (EQ (b->cursor_type, Qt))
20136 cursor_type = FRAME_DESIRED_CURSOR (f);
20137 *width = FRAME_CURSOR_WIDTH (f);
20139 else
20140 cursor_type = get_specified_cursor_type (b->cursor_type, width);
20142 /* Use normal cursor if not blinked off. */
20143 if (!w->cursor_off_p)
20145 if (glyph != NULL && glyph->type == IMAGE_GLYPH) {
20146 if (cursor_type == FILLED_BOX_CURSOR)
20147 cursor_type = HOLLOW_BOX_CURSOR;
20149 return cursor_type;
20152 /* Cursor is blinked off, so determine how to "toggle" it. */
20154 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
20155 if ((alt_cursor = Fassoc (b->cursor_type, Vblink_cursor_alist), !NILP (alt_cursor)))
20156 return get_specified_cursor_type (XCDR (alt_cursor), width);
20158 /* Then see if frame has specified a specific blink off cursor type. */
20159 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
20161 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
20162 return FRAME_BLINK_OFF_CURSOR (f);
20165 #if 0
20166 /* Some people liked having a permanently visible blinking cursor,
20167 while others had very strong opinions against it. So it was
20168 decided to remove it. KFS 2003-09-03 */
20170 /* Finally perform built-in cursor blinking:
20171 filled box <-> hollow box
20172 wide [h]bar <-> narrow [h]bar
20173 narrow [h]bar <-> no cursor
20174 other type <-> no cursor */
20176 if (cursor_type == FILLED_BOX_CURSOR)
20177 return HOLLOW_BOX_CURSOR;
20179 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
20181 *width = 1;
20182 return cursor_type;
20184 #endif
20186 return NO_CURSOR;
20190 #ifdef HAVE_WINDOW_SYSTEM
20192 /* Notice when the text cursor of window W has been completely
20193 overwritten by a drawing operation that outputs glyphs in AREA
20194 starting at X0 and ending at X1 in the line starting at Y0 and
20195 ending at Y1. X coordinates are area-relative. X1 < 0 means all
20196 the rest of the line after X0 has been written. Y coordinates
20197 are window-relative. */
20199 static void
20200 notice_overwritten_cursor (w, area, x0, x1, y0, y1)
20201 struct window *w;
20202 enum glyph_row_area area;
20203 int x0, y0, x1, y1;
20205 int cx0, cx1, cy0, cy1;
20206 struct glyph_row *row;
20208 if (!w->phys_cursor_on_p)
20209 return;
20210 if (area != TEXT_AREA)
20211 return;
20213 if (w->phys_cursor.vpos < 0
20214 || w->phys_cursor.vpos >= w->current_matrix->nrows
20215 || (row = w->current_matrix->rows + w->phys_cursor.vpos,
20216 !(row->enabled_p && row->displays_text_p)))
20217 return;
20219 if (row->cursor_in_fringe_p)
20221 row->cursor_in_fringe_p = 0;
20222 draw_fringe_bitmap (w, row, 0);
20223 w->phys_cursor_on_p = 0;
20224 return;
20227 cx0 = w->phys_cursor.x;
20228 cx1 = cx0 + w->phys_cursor_width;
20229 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
20230 return;
20232 /* The cursor image will be completely removed from the
20233 screen if the output area intersects the cursor area in
20234 y-direction. When we draw in [y0 y1[, and some part of
20235 the cursor is at y < y0, that part must have been drawn
20236 before. When scrolling, the cursor is erased before
20237 actually scrolling, so we don't come here. When not
20238 scrolling, the rows above the old cursor row must have
20239 changed, and in this case these rows must have written
20240 over the cursor image.
20242 Likewise if part of the cursor is below y1, with the
20243 exception of the cursor being in the first blank row at
20244 the buffer and window end because update_text_area
20245 doesn't draw that row. (Except when it does, but
20246 that's handled in update_text_area.) */
20248 cy0 = w->phys_cursor.y;
20249 cy1 = cy0 + w->phys_cursor_height;
20250 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
20251 return;
20253 w->phys_cursor_on_p = 0;
20256 #endif /* HAVE_WINDOW_SYSTEM */
20259 /************************************************************************
20260 Mouse Face
20261 ************************************************************************/
20263 #ifdef HAVE_WINDOW_SYSTEM
20265 /* EXPORT for RIF:
20266 Fix the display of area AREA of overlapping row ROW in window W. */
20268 void
20269 x_fix_overlapping_area (w, row, area)
20270 struct window *w;
20271 struct glyph_row *row;
20272 enum glyph_row_area area;
20274 int i, x;
20276 BLOCK_INPUT;
20278 x = 0;
20279 for (i = 0; i < row->used[area];)
20281 if (row->glyphs[area][i].overlaps_vertically_p)
20283 int start = i, start_x = x;
20287 x += row->glyphs[area][i].pixel_width;
20288 ++i;
20290 while (i < row->used[area]
20291 && row->glyphs[area][i].overlaps_vertically_p);
20293 draw_glyphs (w, start_x, row, area,
20294 start, i,
20295 DRAW_NORMAL_TEXT, 1);
20297 else
20299 x += row->glyphs[area][i].pixel_width;
20300 ++i;
20304 UNBLOCK_INPUT;
20308 /* EXPORT:
20309 Draw the cursor glyph of window W in glyph row ROW. See the
20310 comment of draw_glyphs for the meaning of HL. */
20312 void
20313 draw_phys_cursor_glyph (w, row, hl)
20314 struct window *w;
20315 struct glyph_row *row;
20316 enum draw_glyphs_face hl;
20318 /* If cursor hpos is out of bounds, don't draw garbage. This can
20319 happen in mini-buffer windows when switching between echo area
20320 glyphs and mini-buffer. */
20321 if (w->phys_cursor.hpos < row->used[TEXT_AREA])
20323 int on_p = w->phys_cursor_on_p;
20324 int x1;
20325 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
20326 w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
20327 hl, 0);
20328 w->phys_cursor_on_p = on_p;
20330 if (hl == DRAW_CURSOR)
20331 w->phys_cursor_width = x1 - w->phys_cursor.x;
20332 /* When we erase the cursor, and ROW is overlapped by other
20333 rows, make sure that these overlapping parts of other rows
20334 are redrawn. */
20335 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
20337 if (row > w->current_matrix->rows
20338 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
20339 x_fix_overlapping_area (w, row - 1, TEXT_AREA);
20341 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
20342 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
20343 x_fix_overlapping_area (w, row + 1, TEXT_AREA);
20349 /* EXPORT:
20350 Erase the image of a cursor of window W from the screen. */
20352 void
20353 erase_phys_cursor (w)
20354 struct window *w;
20356 struct frame *f = XFRAME (w->frame);
20357 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
20358 int hpos = w->phys_cursor.hpos;
20359 int vpos = w->phys_cursor.vpos;
20360 int mouse_face_here_p = 0;
20361 struct glyph_matrix *active_glyphs = w->current_matrix;
20362 struct glyph_row *cursor_row;
20363 struct glyph *cursor_glyph;
20364 enum draw_glyphs_face hl;
20366 /* No cursor displayed or row invalidated => nothing to do on the
20367 screen. */
20368 if (w->phys_cursor_type == NO_CURSOR)
20369 goto mark_cursor_off;
20371 /* VPOS >= active_glyphs->nrows means that window has been resized.
20372 Don't bother to erase the cursor. */
20373 if (vpos >= active_glyphs->nrows)
20374 goto mark_cursor_off;
20376 /* If row containing cursor is marked invalid, there is nothing we
20377 can do. */
20378 cursor_row = MATRIX_ROW (active_glyphs, vpos);
20379 if (!cursor_row->enabled_p)
20380 goto mark_cursor_off;
20382 /* If line spacing is > 0, old cursor may only be partially visible in
20383 window after split-window. So adjust visible height. */
20384 cursor_row->visible_height = min (cursor_row->visible_height,
20385 window_text_bottom_y (w) - cursor_row->y);
20387 /* If row is completely invisible, don't attempt to delete a cursor which
20388 isn't there. This can happen if cursor is at top of a window, and
20389 we switch to a buffer with a header line in that window. */
20390 if (cursor_row->visible_height <= 0)
20391 goto mark_cursor_off;
20393 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
20394 if (cursor_row->cursor_in_fringe_p)
20396 cursor_row->cursor_in_fringe_p = 0;
20397 draw_fringe_bitmap (w, cursor_row, 0);
20398 goto mark_cursor_off;
20401 /* This can happen when the new row is shorter than the old one.
20402 In this case, either draw_glyphs or clear_end_of_line
20403 should have cleared the cursor. Note that we wouldn't be
20404 able to erase the cursor in this case because we don't have a
20405 cursor glyph at hand. */
20406 if (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])
20407 goto mark_cursor_off;
20409 /* If the cursor is in the mouse face area, redisplay that when
20410 we clear the cursor. */
20411 if (! NILP (dpyinfo->mouse_face_window)
20412 && w == XWINDOW (dpyinfo->mouse_face_window)
20413 && (vpos > dpyinfo->mouse_face_beg_row
20414 || (vpos == dpyinfo->mouse_face_beg_row
20415 && hpos >= dpyinfo->mouse_face_beg_col))
20416 && (vpos < dpyinfo->mouse_face_end_row
20417 || (vpos == dpyinfo->mouse_face_end_row
20418 && hpos < dpyinfo->mouse_face_end_col))
20419 /* Don't redraw the cursor's spot in mouse face if it is at the
20420 end of a line (on a newline). The cursor appears there, but
20421 mouse highlighting does not. */
20422 && cursor_row->used[TEXT_AREA] > hpos)
20423 mouse_face_here_p = 1;
20425 /* Maybe clear the display under the cursor. */
20426 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
20428 int x, y;
20429 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
20430 int width;
20432 cursor_glyph = get_phys_cursor_glyph (w);
20433 if (cursor_glyph == NULL)
20434 goto mark_cursor_off;
20436 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
20437 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
20438 width = min (cursor_glyph->pixel_width,
20439 window_box_width (w, TEXT_AREA) - w->phys_cursor.x);
20441 rif->clear_frame_area (f, x, y, width, cursor_row->visible_height);
20444 /* Erase the cursor by redrawing the character underneath it. */
20445 if (mouse_face_here_p)
20446 hl = DRAW_MOUSE_FACE;
20447 else
20448 hl = DRAW_NORMAL_TEXT;
20449 draw_phys_cursor_glyph (w, cursor_row, hl);
20451 mark_cursor_off:
20452 w->phys_cursor_on_p = 0;
20453 w->phys_cursor_type = NO_CURSOR;
20457 /* EXPORT:
20458 Display or clear cursor of window W. If ON is zero, clear the
20459 cursor. If it is non-zero, display the cursor. If ON is nonzero,
20460 where to put the cursor is specified by HPOS, VPOS, X and Y. */
20462 void
20463 display_and_set_cursor (w, on, hpos, vpos, x, y)
20464 struct window *w;
20465 int on, hpos, vpos, x, y;
20467 struct frame *f = XFRAME (w->frame);
20468 int new_cursor_type;
20469 int new_cursor_width;
20470 int active_cursor;
20471 struct glyph_row *glyph_row;
20472 struct glyph *glyph;
20474 /* This is pointless on invisible frames, and dangerous on garbaged
20475 windows and frames; in the latter case, the frame or window may
20476 be in the midst of changing its size, and x and y may be off the
20477 window. */
20478 if (! FRAME_VISIBLE_P (f)
20479 || FRAME_GARBAGED_P (f)
20480 || vpos >= w->current_matrix->nrows
20481 || hpos >= w->current_matrix->matrix_w)
20482 return;
20484 /* If cursor is off and we want it off, return quickly. */
20485 if (!on && !w->phys_cursor_on_p)
20486 return;
20488 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
20489 /* If cursor row is not enabled, we don't really know where to
20490 display the cursor. */
20491 if (!glyph_row->enabled_p)
20493 w->phys_cursor_on_p = 0;
20494 return;
20497 glyph = NULL;
20498 if (!glyph_row->exact_window_width_line_p
20499 || hpos < glyph_row->used[TEXT_AREA])
20500 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
20502 xassert (interrupt_input_blocked);
20504 /* Set new_cursor_type to the cursor we want to be displayed. */
20505 new_cursor_type = get_window_cursor_type (w, glyph,
20506 &new_cursor_width, &active_cursor);
20508 /* If cursor is currently being shown and we don't want it to be or
20509 it is in the wrong place, or the cursor type is not what we want,
20510 erase it. */
20511 if (w->phys_cursor_on_p
20512 && (!on
20513 || w->phys_cursor.x != x
20514 || w->phys_cursor.y != y
20515 || new_cursor_type != w->phys_cursor_type
20516 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
20517 && new_cursor_width != w->phys_cursor_width)))
20518 erase_phys_cursor (w);
20520 /* Don't check phys_cursor_on_p here because that flag is only set
20521 to zero in some cases where we know that the cursor has been
20522 completely erased, to avoid the extra work of erasing the cursor
20523 twice. In other words, phys_cursor_on_p can be 1 and the cursor
20524 still not be visible, or it has only been partly erased. */
20525 if (on)
20527 w->phys_cursor_ascent = glyph_row->ascent;
20528 w->phys_cursor_height = glyph_row->height;
20530 /* Set phys_cursor_.* before x_draw_.* is called because some
20531 of them may need the information. */
20532 w->phys_cursor.x = x;
20533 w->phys_cursor.y = glyph_row->y;
20534 w->phys_cursor.hpos = hpos;
20535 w->phys_cursor.vpos = vpos;
20538 rif->draw_window_cursor (w, glyph_row, x, y,
20539 new_cursor_type, new_cursor_width,
20540 on, active_cursor);
20544 /* Switch the display of W's cursor on or off, according to the value
20545 of ON. */
20547 static void
20548 update_window_cursor (w, on)
20549 struct window *w;
20550 int on;
20552 /* Don't update cursor in windows whose frame is in the process
20553 of being deleted. */
20554 if (w->current_matrix)
20556 BLOCK_INPUT;
20557 display_and_set_cursor (w, on, w->phys_cursor.hpos, w->phys_cursor.vpos,
20558 w->phys_cursor.x, w->phys_cursor.y);
20559 UNBLOCK_INPUT;
20564 /* Call update_window_cursor with parameter ON_P on all leaf windows
20565 in the window tree rooted at W. */
20567 static void
20568 update_cursor_in_window_tree (w, on_p)
20569 struct window *w;
20570 int on_p;
20572 while (w)
20574 if (!NILP (w->hchild))
20575 update_cursor_in_window_tree (XWINDOW (w->hchild), on_p);
20576 else if (!NILP (w->vchild))
20577 update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
20578 else
20579 update_window_cursor (w, on_p);
20581 w = NILP (w->next) ? 0 : XWINDOW (w->next);
20586 /* EXPORT:
20587 Display the cursor on window W, or clear it, according to ON_P.
20588 Don't change the cursor's position. */
20590 void
20591 x_update_cursor (f, on_p)
20592 struct frame *f;
20593 int on_p;
20595 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
20599 /* EXPORT:
20600 Clear the cursor of window W to background color, and mark the
20601 cursor as not shown. This is used when the text where the cursor
20602 is is about to be rewritten. */
20604 void
20605 x_clear_cursor (w)
20606 struct window *w;
20608 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
20609 update_window_cursor (w, 0);
20613 /* EXPORT:
20614 Display the active region described by mouse_face_* according to DRAW. */
20616 void
20617 show_mouse_face (dpyinfo, draw)
20618 Display_Info *dpyinfo;
20619 enum draw_glyphs_face draw;
20621 struct window *w = XWINDOW (dpyinfo->mouse_face_window);
20622 struct frame *f = XFRAME (WINDOW_FRAME (w));
20624 if (/* If window is in the process of being destroyed, don't bother
20625 to do anything. */
20626 w->current_matrix != NULL
20627 /* Don't update mouse highlight if hidden */
20628 && (draw != DRAW_MOUSE_FACE || !dpyinfo->mouse_face_hidden)
20629 /* Recognize when we are called to operate on rows that don't exist
20630 anymore. This can happen when a window is split. */
20631 && dpyinfo->mouse_face_end_row < w->current_matrix->nrows)
20633 int phys_cursor_on_p = w->phys_cursor_on_p;
20634 struct glyph_row *row, *first, *last;
20636 first = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row);
20637 last = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row);
20639 for (row = first; row <= last && row->enabled_p; ++row)
20641 int start_hpos, end_hpos, start_x;
20643 /* For all but the first row, the highlight starts at column 0. */
20644 if (row == first)
20646 start_hpos = dpyinfo->mouse_face_beg_col;
20647 start_x = dpyinfo->mouse_face_beg_x;
20649 else
20651 start_hpos = 0;
20652 start_x = 0;
20655 if (row == last)
20656 end_hpos = dpyinfo->mouse_face_end_col;
20657 else
20658 end_hpos = row->used[TEXT_AREA];
20660 if (end_hpos > start_hpos)
20662 draw_glyphs (w, start_x, row, TEXT_AREA,
20663 start_hpos, end_hpos,
20664 draw, 0);
20666 row->mouse_face_p
20667 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
20671 /* When we've written over the cursor, arrange for it to
20672 be displayed again. */
20673 if (phys_cursor_on_p && !w->phys_cursor_on_p)
20675 BLOCK_INPUT;
20676 display_and_set_cursor (w, 1,
20677 w->phys_cursor.hpos, w->phys_cursor.vpos,
20678 w->phys_cursor.x, w->phys_cursor.y);
20679 UNBLOCK_INPUT;
20683 /* Change the mouse cursor. */
20684 if (draw == DRAW_NORMAL_TEXT)
20685 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
20686 else if (draw == DRAW_MOUSE_FACE)
20687 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
20688 else
20689 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
20692 /* EXPORT:
20693 Clear out the mouse-highlighted active region.
20694 Redraw it un-highlighted first. Value is non-zero if mouse
20695 face was actually drawn unhighlighted. */
20698 clear_mouse_face (dpyinfo)
20699 Display_Info *dpyinfo;
20701 int cleared = 0;
20703 if (!dpyinfo->mouse_face_hidden && !NILP (dpyinfo->mouse_face_window))
20705 show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT);
20706 cleared = 1;
20709 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
20710 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
20711 dpyinfo->mouse_face_window = Qnil;
20712 dpyinfo->mouse_face_overlay = Qnil;
20713 return cleared;
20717 /* EXPORT:
20718 Non-zero if physical cursor of window W is within mouse face. */
20721 cursor_in_mouse_face_p (w)
20722 struct window *w;
20724 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
20725 int in_mouse_face = 0;
20727 if (WINDOWP (dpyinfo->mouse_face_window)
20728 && XWINDOW (dpyinfo->mouse_face_window) == w)
20730 int hpos = w->phys_cursor.hpos;
20731 int vpos = w->phys_cursor.vpos;
20733 if (vpos >= dpyinfo->mouse_face_beg_row
20734 && vpos <= dpyinfo->mouse_face_end_row
20735 && (vpos > dpyinfo->mouse_face_beg_row
20736 || hpos >= dpyinfo->mouse_face_beg_col)
20737 && (vpos < dpyinfo->mouse_face_end_row
20738 || hpos < dpyinfo->mouse_face_end_col
20739 || dpyinfo->mouse_face_past_end))
20740 in_mouse_face = 1;
20743 return in_mouse_face;
20749 /* Find the glyph matrix position of buffer position CHARPOS in window
20750 *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's
20751 current glyphs must be up to date. If CHARPOS is above window
20752 start return (0, 0, 0, 0). If CHARPOS is after end of W, return end
20753 of last line in W. In the row containing CHARPOS, stop before glyphs
20754 having STOP as object. */
20756 #if 1 /* This is a version of fast_find_position that's more correct
20757 in the presence of hscrolling, for example. I didn't install
20758 it right away because the problem fixed is minor, it failed
20759 in 20.x as well, and I think it's too risky to install
20760 so near the release of 21.1. 2001-09-25 gerd. */
20762 static int
20763 fast_find_position (w, charpos, hpos, vpos, x, y, stop)
20764 struct window *w;
20765 int charpos;
20766 int *hpos, *vpos, *x, *y;
20767 Lisp_Object stop;
20769 struct glyph_row *row, *first;
20770 struct glyph *glyph, *end;
20771 int past_end = 0;
20773 first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
20774 if (charpos < MATRIX_ROW_START_CHARPOS (first))
20776 *x = first->x;
20777 *y = first->y;
20778 *hpos = 0;
20779 *vpos = MATRIX_ROW_VPOS (first, w->current_matrix);
20780 return 1;
20783 row = row_containing_pos (w, charpos, first, NULL, 0);
20784 if (row == NULL)
20786 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
20787 past_end = 1;
20790 /* If whole rows or last part of a row came from a display overlay,
20791 row_containing_pos will skip over such rows because their end pos
20792 equals the start pos of the overlay or interval.
20794 Move back if we have a STOP object and previous row's
20795 end glyph came from STOP. */
20796 if (!NILP (stop))
20798 struct glyph_row *prev;
20799 while ((prev = row - 1, prev >= first)
20800 && MATRIX_ROW_END_CHARPOS (prev) == charpos
20801 && prev->used[TEXT_AREA] > 0)
20803 struct glyph *beg = prev->glyphs[TEXT_AREA];
20804 glyph = beg + prev->used[TEXT_AREA];
20805 while (--glyph >= beg
20806 && INTEGERP (glyph->object));
20807 if (glyph < beg
20808 || !EQ (stop, glyph->object))
20809 break;
20810 row = prev;
20814 *x = row->x;
20815 *y = row->y;
20816 *vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
20818 glyph = row->glyphs[TEXT_AREA];
20819 end = glyph + row->used[TEXT_AREA];
20821 /* Skip over glyphs not having an object at the start of the row.
20822 These are special glyphs like truncation marks on terminal
20823 frames. */
20824 if (row->displays_text_p)
20825 while (glyph < end
20826 && INTEGERP (glyph->object)
20827 && !EQ (stop, glyph->object)
20828 && glyph->charpos < 0)
20830 *x += glyph->pixel_width;
20831 ++glyph;
20834 while (glyph < end
20835 && !INTEGERP (glyph->object)
20836 && !EQ (stop, glyph->object)
20837 && (!BUFFERP (glyph->object)
20838 || glyph->charpos < charpos))
20840 *x += glyph->pixel_width;
20841 ++glyph;
20844 *hpos = glyph - row->glyphs[TEXT_AREA];
20845 return !past_end;
20848 #else /* not 1 */
20850 static int
20851 fast_find_position (w, pos, hpos, vpos, x, y, stop)
20852 struct window *w;
20853 int pos;
20854 int *hpos, *vpos, *x, *y;
20855 Lisp_Object stop;
20857 int i;
20858 int lastcol;
20859 int maybe_next_line_p = 0;
20860 int line_start_position;
20861 int yb = window_text_bottom_y (w);
20862 struct glyph_row *row, *best_row;
20863 int row_vpos, best_row_vpos;
20864 int current_x;
20866 row = best_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
20867 row_vpos = best_row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
20869 while (row->y < yb)
20871 if (row->used[TEXT_AREA])
20872 line_start_position = row->glyphs[TEXT_AREA]->charpos;
20873 else
20874 line_start_position = 0;
20876 if (line_start_position > pos)
20877 break;
20878 /* If the position sought is the end of the buffer,
20879 don't include the blank lines at the bottom of the window. */
20880 else if (line_start_position == pos
20881 && pos == BUF_ZV (XBUFFER (w->buffer)))
20883 maybe_next_line_p = 1;
20884 break;
20886 else if (line_start_position > 0)
20888 best_row = row;
20889 best_row_vpos = row_vpos;
20892 if (row->y + row->height >= yb)
20893 break;
20895 ++row;
20896 ++row_vpos;
20899 /* Find the right column within BEST_ROW. */
20900 lastcol = 0;
20901 current_x = best_row->x;
20902 for (i = 0; i < best_row->used[TEXT_AREA]; i++)
20904 struct glyph *glyph = best_row->glyphs[TEXT_AREA] + i;
20905 int charpos = glyph->charpos;
20907 if (BUFFERP (glyph->object))
20909 if (charpos == pos)
20911 *hpos = i;
20912 *vpos = best_row_vpos;
20913 *x = current_x;
20914 *y = best_row->y;
20915 return 1;
20917 else if (charpos > pos)
20918 break;
20920 else if (EQ (glyph->object, stop))
20921 break;
20923 if (charpos > 0)
20924 lastcol = i;
20925 current_x += glyph->pixel_width;
20928 /* If we're looking for the end of the buffer,
20929 and we didn't find it in the line we scanned,
20930 use the start of the following line. */
20931 if (maybe_next_line_p)
20933 ++best_row;
20934 ++best_row_vpos;
20935 lastcol = 0;
20936 current_x = best_row->x;
20939 *vpos = best_row_vpos;
20940 *hpos = lastcol + 1;
20941 *x = current_x;
20942 *y = best_row->y;
20943 return 0;
20946 #endif /* not 1 */
20949 /* Find the position of the glyph for position POS in OBJECT in
20950 window W's current matrix, and return in *X, *Y the pixel
20951 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
20953 RIGHT_P non-zero means return the position of the right edge of the
20954 glyph, RIGHT_P zero means return the left edge position.
20956 If no glyph for POS exists in the matrix, return the position of
20957 the glyph with the next smaller position that is in the matrix, if
20958 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
20959 exists in the matrix, return the position of the glyph with the
20960 next larger position in OBJECT.
20962 Value is non-zero if a glyph was found. */
20964 static int
20965 fast_find_string_pos (w, pos, object, hpos, vpos, x, y, right_p)
20966 struct window *w;
20967 int pos;
20968 Lisp_Object object;
20969 int *hpos, *vpos, *x, *y;
20970 int right_p;
20972 int yb = window_text_bottom_y (w);
20973 struct glyph_row *r;
20974 struct glyph *best_glyph = NULL;
20975 struct glyph_row *best_row = NULL;
20976 int best_x = 0;
20978 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
20979 r->enabled_p && r->y < yb;
20980 ++r)
20982 struct glyph *g = r->glyphs[TEXT_AREA];
20983 struct glyph *e = g + r->used[TEXT_AREA];
20984 int gx;
20986 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
20987 if (EQ (g->object, object))
20989 if (g->charpos == pos)
20991 best_glyph = g;
20992 best_x = gx;
20993 best_row = r;
20994 goto found;
20996 else if (best_glyph == NULL
20997 || ((abs (g->charpos - pos)
20998 < abs (best_glyph->charpos - pos))
20999 && (right_p
21000 ? g->charpos < pos
21001 : g->charpos > pos)))
21003 best_glyph = g;
21004 best_x = gx;
21005 best_row = r;
21010 found:
21012 if (best_glyph)
21014 *x = best_x;
21015 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
21017 if (right_p)
21019 *x += best_glyph->pixel_width;
21020 ++*hpos;
21023 *y = best_row->y;
21024 *vpos = best_row - w->current_matrix->rows;
21027 return best_glyph != NULL;
21031 /* See if position X, Y is within a hot-spot of an image. */
21033 static int
21034 on_hot_spot_p (hot_spot, x, y)
21035 Lisp_Object hot_spot;
21036 int x, y;
21038 if (!CONSP (hot_spot))
21039 return 0;
21041 if (EQ (XCAR (hot_spot), Qrect))
21043 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
21044 Lisp_Object rect = XCDR (hot_spot);
21045 Lisp_Object tem;
21046 if (!CONSP (rect))
21047 return 0;
21048 if (!CONSP (XCAR (rect)))
21049 return 0;
21050 if (!CONSP (XCDR (rect)))
21051 return 0;
21052 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
21053 return 0;
21054 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
21055 return 0;
21056 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
21057 return 0;
21058 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
21059 return 0;
21060 return 1;
21062 else if (EQ (XCAR (hot_spot), Qcircle))
21064 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
21065 Lisp_Object circ = XCDR (hot_spot);
21066 Lisp_Object lr, lx0, ly0;
21067 if (CONSP (circ)
21068 && CONSP (XCAR (circ))
21069 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
21070 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
21071 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
21073 double r = XFLOATINT (lr);
21074 double dx = XINT (lx0) - x;
21075 double dy = XINT (ly0) - y;
21076 return (dx * dx + dy * dy <= r * r);
21079 else if (EQ (XCAR (hot_spot), Qpoly))
21081 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
21082 if (VECTORP (XCDR (hot_spot)))
21084 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
21085 Lisp_Object *poly = v->contents;
21086 int n = v->size;
21087 int i;
21088 int inside = 0;
21089 Lisp_Object lx, ly;
21090 int x0, y0;
21092 /* Need an even number of coordinates, and at least 3 edges. */
21093 if (n < 6 || n & 1)
21094 return 0;
21096 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
21097 If count is odd, we are inside polygon. Pixels on edges
21098 may or may not be included depending on actual geometry of the
21099 polygon. */
21100 if ((lx = poly[n-2], !INTEGERP (lx))
21101 || (ly = poly[n-1], !INTEGERP (lx)))
21102 return 0;
21103 x0 = XINT (lx), y0 = XINT (ly);
21104 for (i = 0; i < n; i += 2)
21106 int x1 = x0, y1 = y0;
21107 if ((lx = poly[i], !INTEGERP (lx))
21108 || (ly = poly[i+1], !INTEGERP (ly)))
21109 return 0;
21110 x0 = XINT (lx), y0 = XINT (ly);
21112 /* Does this segment cross the X line? */
21113 if (x0 >= x)
21115 if (x1 >= x)
21116 continue;
21118 else if (x1 < x)
21119 continue;
21120 if (y > y0 && y > y1)
21121 continue;
21122 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
21123 inside = !inside;
21125 return inside;
21128 /* If we don't understand the format, pretend we're not in the hot-spot. */
21129 return 0;
21132 Lisp_Object
21133 find_hot_spot (map, x, y)
21134 Lisp_Object map;
21135 int x, y;
21137 while (CONSP (map))
21139 if (CONSP (XCAR (map))
21140 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
21141 return XCAR (map);
21142 map = XCDR (map);
21145 return Qnil;
21148 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
21149 3, 3, 0,
21150 doc: /* Lookup in image map MAP coordinates X and Y.
21151 An image map is an alist where each element has the format (AREA ID PLIST).
21152 An AREA is specified as either a rectangle, a circle, or a polygon:
21153 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
21154 pixel coordinates of the upper left and bottom right corners.
21155 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
21156 and the radius of the circle; r may be a float or integer.
21157 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
21158 vector describes one corner in the polygon.
21159 Returns the alist element for the first matching AREA in MAP. */)
21160 (map, x, y)
21161 Lisp_Object map;
21162 Lisp_Object x, y;
21164 if (NILP (map))
21165 return Qnil;
21167 CHECK_NUMBER (x);
21168 CHECK_NUMBER (y);
21170 return find_hot_spot (map, XINT (x), XINT (y));
21174 /* Display frame CURSOR, optionally using shape defined by POINTER. */
21175 static void
21176 define_frame_cursor1 (f, cursor, pointer)
21177 struct frame *f;
21178 Cursor cursor;
21179 Lisp_Object pointer;
21181 /* Do not change cursor shape while dragging mouse. */
21182 if (!NILP (do_mouse_tracking))
21183 return;
21185 if (!NILP (pointer))
21187 if (EQ (pointer, Qarrow))
21188 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
21189 else if (EQ (pointer, Qhand))
21190 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
21191 else if (EQ (pointer, Qtext))
21192 cursor = FRAME_X_OUTPUT (f)->text_cursor;
21193 else if (EQ (pointer, intern ("hdrag")))
21194 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
21195 #ifdef HAVE_X_WINDOWS
21196 else if (EQ (pointer, intern ("vdrag")))
21197 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
21198 #endif
21199 else if (EQ (pointer, intern ("hourglass")))
21200 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
21201 else if (EQ (pointer, Qmodeline))
21202 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
21203 else
21204 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
21207 if (cursor != No_Cursor)
21208 rif->define_frame_cursor (f, cursor);
21211 /* Take proper action when mouse has moved to the mode or header line
21212 or marginal area AREA of window W, x-position X and y-position Y.
21213 X is relative to the start of the text display area of W, so the
21214 width of bitmap areas and scroll bars must be subtracted to get a
21215 position relative to the start of the mode line. */
21217 static void
21218 note_mode_line_or_margin_highlight (w, x, y, area)
21219 struct window *w;
21220 int x, y;
21221 enum window_part area;
21223 struct frame *f = XFRAME (w->frame);
21224 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
21225 Cursor cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
21226 Lisp_Object pointer = Qnil;
21227 int charpos, dx, dy, width, height;
21228 Lisp_Object string, object = Qnil;
21229 Lisp_Object pos, help;
21231 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
21232 string = mode_line_string (w, area, &x, &y, &charpos,
21233 &object, &dx, &dy, &width, &height);
21234 else
21236 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
21237 string = marginal_area_string (w, area, &x, &y, &charpos,
21238 &object, &dx, &dy, &width, &height);
21241 help = Qnil;
21243 if (IMAGEP (object))
21245 Lisp_Object image_map, hotspot;
21246 if ((image_map = Fsafe_plist_get (XCDR (object), QCmap),
21247 !NILP (image_map))
21248 && (hotspot = find_hot_spot (image_map, dx, dy),
21249 CONSP (hotspot))
21250 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
21252 Lisp_Object area_id, plist;
21254 area_id = XCAR (hotspot);
21255 /* Could check AREA_ID to see if we enter/leave this hot-spot.
21256 If so, we could look for mouse-enter, mouse-leave
21257 properties in PLIST (and do something...). */
21258 hotspot = XCDR (hotspot);
21259 if (CONSP (hotspot)
21260 && (plist = XCAR (hotspot), CONSP (plist)))
21262 pointer = Fsafe_plist_get (plist, Qpointer);
21263 if (NILP (pointer))
21264 pointer = Qhand;
21265 help = Fsafe_plist_get (plist, Qhelp_echo);
21266 if (!NILP (help))
21268 help_echo_string = help;
21269 /* Is this correct? ++kfs */
21270 XSETWINDOW (help_echo_window, w);
21271 help_echo_object = w->buffer;
21272 help_echo_pos = charpos;
21276 if (NILP (pointer))
21277 pointer = Fsafe_plist_get (XCDR (object), QCpointer);
21280 if (STRINGP (string))
21282 pos = make_number (charpos);
21283 /* If we're on a string with `help-echo' text property, arrange
21284 for the help to be displayed. This is done by setting the
21285 global variable help_echo_string to the help string. */
21286 if (NILP (help))
21288 help = Fget_text_property (pos, Qhelp_echo, string);
21289 if (!NILP (help))
21291 help_echo_string = help;
21292 XSETWINDOW (help_echo_window, w);
21293 help_echo_object = string;
21294 help_echo_pos = charpos;
21298 if (NILP (pointer))
21299 pointer = Fget_text_property (pos, Qpointer, string);
21301 /* Change the mouse pointer according to what is under X/Y. */
21302 if (NILP (pointer) && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
21304 Lisp_Object map;
21305 map = Fget_text_property (pos, Qlocal_map, string);
21306 if (!KEYMAPP (map))
21307 map = Fget_text_property (pos, Qkeymap, string);
21308 if (!KEYMAPP (map))
21309 cursor = dpyinfo->vertical_scroll_bar_cursor;
21313 define_frame_cursor1 (f, cursor, pointer);
21317 /* EXPORT:
21318 Take proper action when the mouse has moved to position X, Y on
21319 frame F as regards highlighting characters that have mouse-face
21320 properties. Also de-highlighting chars where the mouse was before.
21321 X and Y can be negative or out of range. */
21323 void
21324 note_mouse_highlight (f, x, y)
21325 struct frame *f;
21326 int x, y;
21328 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
21329 enum window_part part;
21330 Lisp_Object window;
21331 struct window *w;
21332 Cursor cursor = No_Cursor;
21333 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
21334 struct buffer *b;
21336 /* When a menu is active, don't highlight because this looks odd. */
21337 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NTGUI)
21338 if (popup_activated ())
21339 return;
21340 #endif
21342 if (NILP (Vmouse_highlight)
21343 || !f->glyphs_initialized_p)
21344 return;
21346 dpyinfo->mouse_face_mouse_x = x;
21347 dpyinfo->mouse_face_mouse_y = y;
21348 dpyinfo->mouse_face_mouse_frame = f;
21350 if (dpyinfo->mouse_face_defer)
21351 return;
21353 if (gc_in_progress)
21355 dpyinfo->mouse_face_deferred_gc = 1;
21356 return;
21359 /* Which window is that in? */
21360 window = window_from_coordinates (f, x, y, &part, 0, 0, 1);
21362 /* If we were displaying active text in another window, clear that.
21363 Also clear if we move out of text area in same window. */
21364 if (! EQ (window, dpyinfo->mouse_face_window)
21365 || (part != ON_TEXT && !NILP (dpyinfo->mouse_face_window)))
21366 clear_mouse_face (dpyinfo);
21368 /* Not on a window -> return. */
21369 if (!WINDOWP (window))
21370 return;
21372 /* Reset help_echo_string. It will get recomputed below. */
21373 help_echo_string = Qnil;
21375 /* Convert to window-relative pixel coordinates. */
21376 w = XWINDOW (window);
21377 frame_to_window_pixel_xy (w, &x, &y);
21379 /* Handle tool-bar window differently since it doesn't display a
21380 buffer. */
21381 if (EQ (window, f->tool_bar_window))
21383 note_tool_bar_highlight (f, x, y);
21384 return;
21387 /* Mouse is on the mode, header line or margin? */
21388 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
21389 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
21391 note_mode_line_or_margin_highlight (w, x, y, part);
21392 return;
21395 if (part == ON_VERTICAL_BORDER)
21396 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
21397 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
21398 || part == ON_SCROLL_BAR)
21399 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
21400 else
21401 cursor = FRAME_X_OUTPUT (f)->text_cursor;
21403 /* Are we in a window whose display is up to date?
21404 And verify the buffer's text has not changed. */
21405 b = XBUFFER (w->buffer);
21406 if (part == ON_TEXT
21407 && EQ (w->window_end_valid, w->buffer)
21408 && XFASTINT (w->last_modified) == BUF_MODIFF (b)
21409 && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
21411 int hpos, vpos, pos, i, dx, dy, area;
21412 struct glyph *glyph;
21413 Lisp_Object object;
21414 Lisp_Object mouse_face = Qnil, overlay = Qnil, position;
21415 Lisp_Object *overlay_vec = NULL;
21416 int noverlays;
21417 struct buffer *obuf;
21418 int obegv, ozv, same_region;
21420 /* Find the glyph under X/Y. */
21421 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
21423 /* Look for :pointer property on image. */
21424 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
21426 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
21427 if (img != NULL && IMAGEP (img->spec))
21429 Lisp_Object image_map, hotspot;
21430 if ((image_map = Fsafe_plist_get (XCDR (img->spec), QCmap),
21431 !NILP (image_map))
21432 && (hotspot = find_hot_spot (image_map,
21433 glyph->slice.x + dx,
21434 glyph->slice.y + dy),
21435 CONSP (hotspot))
21436 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
21438 Lisp_Object area_id, plist;
21440 area_id = XCAR (hotspot);
21441 /* Could check AREA_ID to see if we enter/leave this hot-spot.
21442 If so, we could look for mouse-enter, mouse-leave
21443 properties in PLIST (and do something...). */
21444 hotspot = XCDR (hotspot);
21445 if (CONSP (hotspot)
21446 && (plist = XCAR (hotspot), CONSP (plist)))
21448 pointer = Fsafe_plist_get (plist, Qpointer);
21449 if (NILP (pointer))
21450 pointer = Qhand;
21451 help_echo_string = Fsafe_plist_get (plist, Qhelp_echo);
21452 if (!NILP (help_echo_string))
21454 help_echo_window = window;
21455 help_echo_object = glyph->object;
21456 help_echo_pos = glyph->charpos;
21460 if (NILP (pointer))
21461 pointer = Fsafe_plist_get (XCDR (img->spec), QCpointer);
21465 /* Clear mouse face if X/Y not over text. */
21466 if (glyph == NULL
21467 || area != TEXT_AREA
21468 || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p)
21470 if (clear_mouse_face (dpyinfo))
21471 cursor = No_Cursor;
21472 if (NILP (pointer))
21474 if (area != TEXT_AREA)
21475 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
21476 else
21477 pointer = Vvoid_text_area_pointer;
21479 goto set_cursor;
21482 pos = glyph->charpos;
21483 object = glyph->object;
21484 if (!STRINGP (object) && !BUFFERP (object))
21485 goto set_cursor;
21487 /* If we get an out-of-range value, return now; avoid an error. */
21488 if (BUFFERP (object) && pos > BUF_Z (b))
21489 goto set_cursor;
21491 /* Make the window's buffer temporarily current for
21492 overlays_at and compute_char_face. */
21493 obuf = current_buffer;
21494 current_buffer = b;
21495 obegv = BEGV;
21496 ozv = ZV;
21497 BEGV = BEG;
21498 ZV = Z;
21500 /* Is this char mouse-active or does it have help-echo? */
21501 position = make_number (pos);
21503 if (BUFFERP (object))
21505 /* Put all the overlays we want in a vector in overlay_vec. */
21506 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
21507 /* Sort overlays into increasing priority order. */
21508 noverlays = sort_overlays (overlay_vec, noverlays, w);
21510 else
21511 noverlays = 0;
21513 same_region = (EQ (window, dpyinfo->mouse_face_window)
21514 && vpos >= dpyinfo->mouse_face_beg_row
21515 && vpos <= dpyinfo->mouse_face_end_row
21516 && (vpos > dpyinfo->mouse_face_beg_row
21517 || hpos >= dpyinfo->mouse_face_beg_col)
21518 && (vpos < dpyinfo->mouse_face_end_row
21519 || hpos < dpyinfo->mouse_face_end_col
21520 || dpyinfo->mouse_face_past_end));
21522 if (same_region)
21523 cursor = No_Cursor;
21525 /* Check mouse-face highlighting. */
21526 if (! same_region
21527 /* If there exists an overlay with mouse-face overlapping
21528 the one we are currently highlighting, we have to
21529 check if we enter the overlapping overlay, and then
21530 highlight only that. */
21531 || (OVERLAYP (dpyinfo->mouse_face_overlay)
21532 && mouse_face_overlay_overlaps (dpyinfo->mouse_face_overlay)))
21534 /* Find the highest priority overlay that has a mouse-face
21535 property. */
21536 overlay = Qnil;
21537 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
21539 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
21540 if (!NILP (mouse_face))
21541 overlay = overlay_vec[i];
21544 /* If we're actually highlighting the same overlay as
21545 before, there's no need to do that again. */
21546 if (!NILP (overlay)
21547 && EQ (overlay, dpyinfo->mouse_face_overlay))
21548 goto check_help_echo;
21550 dpyinfo->mouse_face_overlay = overlay;
21552 /* Clear the display of the old active region, if any. */
21553 if (clear_mouse_face (dpyinfo))
21554 cursor = No_Cursor;
21556 /* If no overlay applies, get a text property. */
21557 if (NILP (overlay))
21558 mouse_face = Fget_text_property (position, Qmouse_face, object);
21560 /* Handle the overlay case. */
21561 if (!NILP (overlay))
21563 /* Find the range of text around this char that
21564 should be active. */
21565 Lisp_Object before, after;
21566 int ignore;
21568 before = Foverlay_start (overlay);
21569 after = Foverlay_end (overlay);
21570 /* Record this as the current active region. */
21571 fast_find_position (w, XFASTINT (before),
21572 &dpyinfo->mouse_face_beg_col,
21573 &dpyinfo->mouse_face_beg_row,
21574 &dpyinfo->mouse_face_beg_x,
21575 &dpyinfo->mouse_face_beg_y, Qnil);
21577 dpyinfo->mouse_face_past_end
21578 = !fast_find_position (w, XFASTINT (after),
21579 &dpyinfo->mouse_face_end_col,
21580 &dpyinfo->mouse_face_end_row,
21581 &dpyinfo->mouse_face_end_x,
21582 &dpyinfo->mouse_face_end_y, Qnil);
21583 dpyinfo->mouse_face_window = window;
21585 dpyinfo->mouse_face_face_id
21586 = face_at_buffer_position (w, pos, 0, 0,
21587 &ignore, pos + 1,
21588 !dpyinfo->mouse_face_hidden);
21590 /* Display it as active. */
21591 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21592 cursor = No_Cursor;
21594 /* Handle the text property case. */
21595 else if (!NILP (mouse_face) && BUFFERP (object))
21597 /* Find the range of text around this char that
21598 should be active. */
21599 Lisp_Object before, after, beginning, end;
21600 int ignore;
21602 beginning = Fmarker_position (w->start);
21603 end = make_number (BUF_Z (XBUFFER (object))
21604 - XFASTINT (w->window_end_pos));
21605 before
21606 = Fprevious_single_property_change (make_number (pos + 1),
21607 Qmouse_face,
21608 object, beginning);
21609 after
21610 = Fnext_single_property_change (position, Qmouse_face,
21611 object, end);
21613 /* Record this as the current active region. */
21614 fast_find_position (w, XFASTINT (before),
21615 &dpyinfo->mouse_face_beg_col,
21616 &dpyinfo->mouse_face_beg_row,
21617 &dpyinfo->mouse_face_beg_x,
21618 &dpyinfo->mouse_face_beg_y, Qnil);
21619 dpyinfo->mouse_face_past_end
21620 = !fast_find_position (w, XFASTINT (after),
21621 &dpyinfo->mouse_face_end_col,
21622 &dpyinfo->mouse_face_end_row,
21623 &dpyinfo->mouse_face_end_x,
21624 &dpyinfo->mouse_face_end_y, Qnil);
21625 dpyinfo->mouse_face_window = window;
21627 if (BUFFERP (object))
21628 dpyinfo->mouse_face_face_id
21629 = face_at_buffer_position (w, pos, 0, 0,
21630 &ignore, pos + 1,
21631 !dpyinfo->mouse_face_hidden);
21633 /* Display it as active. */
21634 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21635 cursor = No_Cursor;
21637 else if (!NILP (mouse_face) && STRINGP (object))
21639 Lisp_Object b, e;
21640 int ignore;
21642 b = Fprevious_single_property_change (make_number (pos + 1),
21643 Qmouse_face,
21644 object, Qnil);
21645 e = Fnext_single_property_change (position, Qmouse_face,
21646 object, Qnil);
21647 if (NILP (b))
21648 b = make_number (0);
21649 if (NILP (e))
21650 e = make_number (SCHARS (object) - 1);
21651 fast_find_string_pos (w, XINT (b), object,
21652 &dpyinfo->mouse_face_beg_col,
21653 &dpyinfo->mouse_face_beg_row,
21654 &dpyinfo->mouse_face_beg_x,
21655 &dpyinfo->mouse_face_beg_y, 0);
21656 fast_find_string_pos (w, XINT (e), object,
21657 &dpyinfo->mouse_face_end_col,
21658 &dpyinfo->mouse_face_end_row,
21659 &dpyinfo->mouse_face_end_x,
21660 &dpyinfo->mouse_face_end_y, 1);
21661 dpyinfo->mouse_face_past_end = 0;
21662 dpyinfo->mouse_face_window = window;
21663 dpyinfo->mouse_face_face_id
21664 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
21665 glyph->face_id, 1);
21666 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21667 cursor = No_Cursor;
21669 else if (STRINGP (object) && NILP (mouse_face))
21671 /* A string which doesn't have mouse-face, but
21672 the text ``under'' it might have. */
21673 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
21674 int start = MATRIX_ROW_START_CHARPOS (r);
21676 pos = string_buffer_position (w, object, start);
21677 if (pos > 0)
21678 mouse_face = get_char_property_and_overlay (make_number (pos),
21679 Qmouse_face,
21680 w->buffer,
21681 &overlay);
21682 if (!NILP (mouse_face) && !NILP (overlay))
21684 Lisp_Object before = Foverlay_start (overlay);
21685 Lisp_Object after = Foverlay_end (overlay);
21686 int ignore;
21688 /* Note that we might not be able to find position
21689 BEFORE in the glyph matrix if the overlay is
21690 entirely covered by a `display' property. In
21691 this case, we overshoot. So let's stop in
21692 the glyph matrix before glyphs for OBJECT. */
21693 fast_find_position (w, XFASTINT (before),
21694 &dpyinfo->mouse_face_beg_col,
21695 &dpyinfo->mouse_face_beg_row,
21696 &dpyinfo->mouse_face_beg_x,
21697 &dpyinfo->mouse_face_beg_y,
21698 object);
21700 dpyinfo->mouse_face_past_end
21701 = !fast_find_position (w, XFASTINT (after),
21702 &dpyinfo->mouse_face_end_col,
21703 &dpyinfo->mouse_face_end_row,
21704 &dpyinfo->mouse_face_end_x,
21705 &dpyinfo->mouse_face_end_y,
21706 Qnil);
21707 dpyinfo->mouse_face_window = window;
21708 dpyinfo->mouse_face_face_id
21709 = face_at_buffer_position (w, pos, 0, 0,
21710 &ignore, pos + 1,
21711 !dpyinfo->mouse_face_hidden);
21713 /* Display it as active. */
21714 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21715 cursor = No_Cursor;
21720 check_help_echo:
21722 /* Look for a `help-echo' property. */
21723 if (NILP (help_echo_string)) {
21724 Lisp_Object help, overlay;
21726 /* Check overlays first. */
21727 help = overlay = Qnil;
21728 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
21730 overlay = overlay_vec[i];
21731 help = Foverlay_get (overlay, Qhelp_echo);
21734 if (!NILP (help))
21736 help_echo_string = help;
21737 help_echo_window = window;
21738 help_echo_object = overlay;
21739 help_echo_pos = pos;
21741 else
21743 Lisp_Object object = glyph->object;
21744 int charpos = glyph->charpos;
21746 /* Try text properties. */
21747 if (STRINGP (object)
21748 && charpos >= 0
21749 && charpos < SCHARS (object))
21751 help = Fget_text_property (make_number (charpos),
21752 Qhelp_echo, object);
21753 if (NILP (help))
21755 /* If the string itself doesn't specify a help-echo,
21756 see if the buffer text ``under'' it does. */
21757 struct glyph_row *r
21758 = MATRIX_ROW (w->current_matrix, vpos);
21759 int start = MATRIX_ROW_START_CHARPOS (r);
21760 int pos = string_buffer_position (w, object, start);
21761 if (pos > 0)
21763 help = Fget_char_property (make_number (pos),
21764 Qhelp_echo, w->buffer);
21765 if (!NILP (help))
21767 charpos = pos;
21768 object = w->buffer;
21773 else if (BUFFERP (object)
21774 && charpos >= BEGV
21775 && charpos < ZV)
21776 help = Fget_text_property (make_number (charpos), Qhelp_echo,
21777 object);
21779 if (!NILP (help))
21781 help_echo_string = help;
21782 help_echo_window = window;
21783 help_echo_object = object;
21784 help_echo_pos = charpos;
21789 /* Look for a `pointer' property. */
21790 if (NILP (pointer))
21792 /* Check overlays first. */
21793 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
21794 pointer = Foverlay_get (overlay_vec[i], Qpointer);
21796 if (NILP (pointer))
21798 Lisp_Object object = glyph->object;
21799 int charpos = glyph->charpos;
21801 /* Try text properties. */
21802 if (STRINGP (object)
21803 && charpos >= 0
21804 && charpos < SCHARS (object))
21806 pointer = Fget_text_property (make_number (charpos),
21807 Qpointer, object);
21808 if (NILP (pointer))
21810 /* If the string itself doesn't specify a pointer,
21811 see if the buffer text ``under'' it does. */
21812 struct glyph_row *r
21813 = MATRIX_ROW (w->current_matrix, vpos);
21814 int start = MATRIX_ROW_START_CHARPOS (r);
21815 int pos = string_buffer_position (w, object, start);
21816 if (pos > 0)
21817 pointer = Fget_char_property (make_number (pos),
21818 Qpointer, w->buffer);
21821 else if (BUFFERP (object)
21822 && charpos >= BEGV
21823 && charpos < ZV)
21824 pointer = Fget_text_property (make_number (charpos),
21825 Qpointer, object);
21829 BEGV = obegv;
21830 ZV = ozv;
21831 current_buffer = obuf;
21834 set_cursor:
21836 define_frame_cursor1 (f, cursor, pointer);
21840 /* EXPORT for RIF:
21841 Clear any mouse-face on window W. This function is part of the
21842 redisplay interface, and is called from try_window_id and similar
21843 functions to ensure the mouse-highlight is off. */
21845 void
21846 x_clear_window_mouse_face (w)
21847 struct window *w;
21849 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
21850 Lisp_Object window;
21852 BLOCK_INPUT;
21853 XSETWINDOW (window, w);
21854 if (EQ (window, dpyinfo->mouse_face_window))
21855 clear_mouse_face (dpyinfo);
21856 UNBLOCK_INPUT;
21860 /* EXPORT:
21861 Just discard the mouse face information for frame F, if any.
21862 This is used when the size of F is changed. */
21864 void
21865 cancel_mouse_face (f)
21866 struct frame *f;
21868 Lisp_Object window;
21869 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
21871 window = dpyinfo->mouse_face_window;
21872 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
21874 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
21875 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
21876 dpyinfo->mouse_face_window = Qnil;
21881 #endif /* HAVE_WINDOW_SYSTEM */
21884 /***********************************************************************
21885 Exposure Events
21886 ***********************************************************************/
21888 #ifdef HAVE_WINDOW_SYSTEM
21890 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
21891 which intersects rectangle R. R is in window-relative coordinates. */
21893 static void
21894 expose_area (w, row, r, area)
21895 struct window *w;
21896 struct glyph_row *row;
21897 XRectangle *r;
21898 enum glyph_row_area area;
21900 struct glyph *first = row->glyphs[area];
21901 struct glyph *end = row->glyphs[area] + row->used[area];
21902 struct glyph *last;
21903 int first_x, start_x, x;
21905 if (area == TEXT_AREA && row->fill_line_p)
21906 /* If row extends face to end of line write the whole line. */
21907 draw_glyphs (w, 0, row, area,
21908 0, row->used[area],
21909 DRAW_NORMAL_TEXT, 0);
21910 else
21912 /* Set START_X to the window-relative start position for drawing glyphs of
21913 AREA. The first glyph of the text area can be partially visible.
21914 The first glyphs of other areas cannot. */
21915 start_x = window_box_left_offset (w, area);
21916 x = start_x;
21917 if (area == TEXT_AREA)
21918 x += row->x;
21920 /* Find the first glyph that must be redrawn. */
21921 while (first < end
21922 && x + first->pixel_width < r->x)
21924 x += first->pixel_width;
21925 ++first;
21928 /* Find the last one. */
21929 last = first;
21930 first_x = x;
21931 while (last < end
21932 && x < r->x + r->width)
21934 x += last->pixel_width;
21935 ++last;
21938 /* Repaint. */
21939 if (last > first)
21940 draw_glyphs (w, first_x - start_x, row, area,
21941 first - row->glyphs[area], last - row->glyphs[area],
21942 DRAW_NORMAL_TEXT, 0);
21947 /* Redraw the parts of the glyph row ROW on window W intersecting
21948 rectangle R. R is in window-relative coordinates. Value is
21949 non-zero if mouse-face was overwritten. */
21951 static int
21952 expose_line (w, row, r)
21953 struct window *w;
21954 struct glyph_row *row;
21955 XRectangle *r;
21957 xassert (row->enabled_p);
21959 if (row->mode_line_p || w->pseudo_window_p)
21960 draw_glyphs (w, 0, row, TEXT_AREA,
21961 0, row->used[TEXT_AREA],
21962 DRAW_NORMAL_TEXT, 0);
21963 else
21965 if (row->used[LEFT_MARGIN_AREA])
21966 expose_area (w, row, r, LEFT_MARGIN_AREA);
21967 if (row->used[TEXT_AREA])
21968 expose_area (w, row, r, TEXT_AREA);
21969 if (row->used[RIGHT_MARGIN_AREA])
21970 expose_area (w, row, r, RIGHT_MARGIN_AREA);
21971 draw_row_fringe_bitmaps (w, row);
21974 return row->mouse_face_p;
21978 /* Redraw those parts of glyphs rows during expose event handling that
21979 overlap other rows. Redrawing of an exposed line writes over parts
21980 of lines overlapping that exposed line; this function fixes that.
21982 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
21983 row in W's current matrix that is exposed and overlaps other rows.
21984 LAST_OVERLAPPING_ROW is the last such row. */
21986 static void
21987 expose_overlaps (w, first_overlapping_row, last_overlapping_row)
21988 struct window *w;
21989 struct glyph_row *first_overlapping_row;
21990 struct glyph_row *last_overlapping_row;
21992 struct glyph_row *row;
21994 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
21995 if (row->overlapping_p)
21997 xassert (row->enabled_p && !row->mode_line_p);
21999 if (row->used[LEFT_MARGIN_AREA])
22000 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA);
22002 if (row->used[TEXT_AREA])
22003 x_fix_overlapping_area (w, row, TEXT_AREA);
22005 if (row->used[RIGHT_MARGIN_AREA])
22006 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA);
22011 /* Return non-zero if W's cursor intersects rectangle R. */
22013 static int
22014 phys_cursor_in_rect_p (w, r)
22015 struct window *w;
22016 XRectangle *r;
22018 XRectangle cr, result;
22019 struct glyph *cursor_glyph;
22021 cursor_glyph = get_phys_cursor_glyph (w);
22022 if (cursor_glyph)
22024 /* r is relative to W's box, but w->phys_cursor.x is relative
22025 to left edge of W's TEXT area. Adjust it. */
22026 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
22027 cr.y = w->phys_cursor.y;
22028 cr.width = cursor_glyph->pixel_width;
22029 cr.height = w->phys_cursor_height;
22030 /* ++KFS: W32 version used W32-specific IntersectRect here, but
22031 I assume the effect is the same -- and this is portable. */
22032 return x_intersect_rectangles (&cr, r, &result);
22034 else
22035 return 0;
22039 /* EXPORT:
22040 Draw a vertical window border to the right of window W if W doesn't
22041 have vertical scroll bars. */
22043 void
22044 x_draw_vertical_border (w)
22045 struct window *w;
22047 /* We could do better, if we knew what type of scroll-bar the adjacent
22048 windows (on either side) have... But we don't :-(
22049 However, I think this works ok. ++KFS 2003-04-25 */
22051 /* Redraw borders between horizontally adjacent windows. Don't
22052 do it for frames with vertical scroll bars because either the
22053 right scroll bar of a window, or the left scroll bar of its
22054 neighbor will suffice as a border. */
22055 if (FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (w->frame)))
22056 return;
22058 if (!WINDOW_RIGHTMOST_P (w)
22059 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
22061 int x0, x1, y0, y1;
22063 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
22064 y1 -= 1;
22066 rif->draw_vertical_window_border (w, x1, y0, y1);
22068 else if (!WINDOW_LEFTMOST_P (w)
22069 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
22071 int x0, x1, y0, y1;
22073 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
22074 y1 -= 1;
22076 rif->draw_vertical_window_border (w, x0, y0, y1);
22081 /* Redraw the part of window W intersection rectangle FR. Pixel
22082 coordinates in FR are frame-relative. Call this function with
22083 input blocked. Value is non-zero if the exposure overwrites
22084 mouse-face. */
22086 static int
22087 expose_window (w, fr)
22088 struct window *w;
22089 XRectangle *fr;
22091 struct frame *f = XFRAME (w->frame);
22092 XRectangle wr, r;
22093 int mouse_face_overwritten_p = 0;
22095 /* If window is not yet fully initialized, do nothing. This can
22096 happen when toolkit scroll bars are used and a window is split.
22097 Reconfiguring the scroll bar will generate an expose for a newly
22098 created window. */
22099 if (w->current_matrix == NULL)
22100 return 0;
22102 /* When we're currently updating the window, display and current
22103 matrix usually don't agree. Arrange for a thorough display
22104 later. */
22105 if (w == updated_window)
22107 SET_FRAME_GARBAGED (f);
22108 return 0;
22111 /* Frame-relative pixel rectangle of W. */
22112 wr.x = WINDOW_LEFT_EDGE_X (w);
22113 wr.y = WINDOW_TOP_EDGE_Y (w);
22114 wr.width = WINDOW_TOTAL_WIDTH (w);
22115 wr.height = WINDOW_TOTAL_HEIGHT (w);
22117 if (x_intersect_rectangles (fr, &wr, &r))
22119 int yb = window_text_bottom_y (w);
22120 struct glyph_row *row;
22121 int cursor_cleared_p;
22122 struct glyph_row *first_overlapping_row, *last_overlapping_row;
22124 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
22125 r.x, r.y, r.width, r.height));
22127 /* Convert to window coordinates. */
22128 r.x -= WINDOW_LEFT_EDGE_X (w);
22129 r.y -= WINDOW_TOP_EDGE_Y (w);
22131 /* Turn off the cursor. */
22132 if (!w->pseudo_window_p
22133 && phys_cursor_in_rect_p (w, &r))
22135 x_clear_cursor (w);
22136 cursor_cleared_p = 1;
22138 else
22139 cursor_cleared_p = 0;
22141 /* Update lines intersecting rectangle R. */
22142 first_overlapping_row = last_overlapping_row = NULL;
22143 for (row = w->current_matrix->rows;
22144 row->enabled_p;
22145 ++row)
22147 int y0 = row->y;
22148 int y1 = MATRIX_ROW_BOTTOM_Y (row);
22150 if ((y0 >= r.y && y0 < r.y + r.height)
22151 || (y1 > r.y && y1 < r.y + r.height)
22152 || (r.y >= y0 && r.y < y1)
22153 || (r.y + r.height > y0 && r.y + r.height < y1))
22155 /* A header line may be overlapping, but there is no need
22156 to fix overlapping areas for them. KFS 2005-02-12 */
22157 if (row->overlapping_p && !row->mode_line_p)
22159 if (first_overlapping_row == NULL)
22160 first_overlapping_row = row;
22161 last_overlapping_row = row;
22164 if (expose_line (w, row, &r))
22165 mouse_face_overwritten_p = 1;
22168 if (y1 >= yb)
22169 break;
22172 /* Display the mode line if there is one. */
22173 if (WINDOW_WANTS_MODELINE_P (w)
22174 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
22175 row->enabled_p)
22176 && row->y < r.y + r.height)
22178 if (expose_line (w, row, &r))
22179 mouse_face_overwritten_p = 1;
22182 if (!w->pseudo_window_p)
22184 /* Fix the display of overlapping rows. */
22185 if (first_overlapping_row)
22186 expose_overlaps (w, first_overlapping_row, last_overlapping_row);
22188 /* Draw border between windows. */
22189 x_draw_vertical_border (w);
22191 /* Turn the cursor on again. */
22192 if (cursor_cleared_p)
22193 update_window_cursor (w, 1);
22197 return mouse_face_overwritten_p;
22202 /* Redraw (parts) of all windows in the window tree rooted at W that
22203 intersect R. R contains frame pixel coordinates. Value is
22204 non-zero if the exposure overwrites mouse-face. */
22206 static int
22207 expose_window_tree (w, r)
22208 struct window *w;
22209 XRectangle *r;
22211 struct frame *f = XFRAME (w->frame);
22212 int mouse_face_overwritten_p = 0;
22214 while (w && !FRAME_GARBAGED_P (f))
22216 if (!NILP (w->hchild))
22217 mouse_face_overwritten_p
22218 |= expose_window_tree (XWINDOW (w->hchild), r);
22219 else if (!NILP (w->vchild))
22220 mouse_face_overwritten_p
22221 |= expose_window_tree (XWINDOW (w->vchild), r);
22222 else
22223 mouse_face_overwritten_p |= expose_window (w, r);
22225 w = NILP (w->next) ? NULL : XWINDOW (w->next);
22228 return mouse_face_overwritten_p;
22232 /* EXPORT:
22233 Redisplay an exposed area of frame F. X and Y are the upper-left
22234 corner of the exposed rectangle. W and H are width and height of
22235 the exposed area. All are pixel values. W or H zero means redraw
22236 the entire frame. */
22238 void
22239 expose_frame (f, x, y, w, h)
22240 struct frame *f;
22241 int x, y, w, h;
22243 XRectangle r;
22244 int mouse_face_overwritten_p = 0;
22246 TRACE ((stderr, "expose_frame "));
22248 /* No need to redraw if frame will be redrawn soon. */
22249 if (FRAME_GARBAGED_P (f))
22251 TRACE ((stderr, " garbaged\n"));
22252 return;
22255 /* If basic faces haven't been realized yet, there is no point in
22256 trying to redraw anything. This can happen when we get an expose
22257 event while Emacs is starting, e.g. by moving another window. */
22258 if (FRAME_FACE_CACHE (f) == NULL
22259 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
22261 TRACE ((stderr, " no faces\n"));
22262 return;
22265 if (w == 0 || h == 0)
22267 r.x = r.y = 0;
22268 r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f);
22269 r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f);
22271 else
22273 r.x = x;
22274 r.y = y;
22275 r.width = w;
22276 r.height = h;
22279 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
22280 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
22282 if (WINDOWP (f->tool_bar_window))
22283 mouse_face_overwritten_p
22284 |= expose_window (XWINDOW (f->tool_bar_window), &r);
22286 #ifdef HAVE_X_WINDOWS
22287 #ifndef MSDOS
22288 #ifndef USE_X_TOOLKIT
22289 if (WINDOWP (f->menu_bar_window))
22290 mouse_face_overwritten_p
22291 |= expose_window (XWINDOW (f->menu_bar_window), &r);
22292 #endif /* not USE_X_TOOLKIT */
22293 #endif
22294 #endif
22296 /* Some window managers support a focus-follows-mouse style with
22297 delayed raising of frames. Imagine a partially obscured frame,
22298 and moving the mouse into partially obscured mouse-face on that
22299 frame. The visible part of the mouse-face will be highlighted,
22300 then the WM raises the obscured frame. With at least one WM, KDE
22301 2.1, Emacs is not getting any event for the raising of the frame
22302 (even tried with SubstructureRedirectMask), only Expose events.
22303 These expose events will draw text normally, i.e. not
22304 highlighted. Which means we must redo the highlight here.
22305 Subsume it under ``we love X''. --gerd 2001-08-15 */
22306 /* Included in Windows version because Windows most likely does not
22307 do the right thing if any third party tool offers
22308 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
22309 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
22311 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
22312 if (f == dpyinfo->mouse_face_mouse_frame)
22314 int x = dpyinfo->mouse_face_mouse_x;
22315 int y = dpyinfo->mouse_face_mouse_y;
22316 clear_mouse_face (dpyinfo);
22317 note_mouse_highlight (f, x, y);
22323 /* EXPORT:
22324 Determine the intersection of two rectangles R1 and R2. Return
22325 the intersection in *RESULT. Value is non-zero if RESULT is not
22326 empty. */
22329 x_intersect_rectangles (r1, r2, result)
22330 XRectangle *r1, *r2, *result;
22332 XRectangle *left, *right;
22333 XRectangle *upper, *lower;
22334 int intersection_p = 0;
22336 /* Rearrange so that R1 is the left-most rectangle. */
22337 if (r1->x < r2->x)
22338 left = r1, right = r2;
22339 else
22340 left = r2, right = r1;
22342 /* X0 of the intersection is right.x0, if this is inside R1,
22343 otherwise there is no intersection. */
22344 if (right->x <= left->x + left->width)
22346 result->x = right->x;
22348 /* The right end of the intersection is the minimum of the
22349 the right ends of left and right. */
22350 result->width = (min (left->x + left->width, right->x + right->width)
22351 - result->x);
22353 /* Same game for Y. */
22354 if (r1->y < r2->y)
22355 upper = r1, lower = r2;
22356 else
22357 upper = r2, lower = r1;
22359 /* The upper end of the intersection is lower.y0, if this is inside
22360 of upper. Otherwise, there is no intersection. */
22361 if (lower->y <= upper->y + upper->height)
22363 result->y = lower->y;
22365 /* The lower end of the intersection is the minimum of the lower
22366 ends of upper and lower. */
22367 result->height = (min (lower->y + lower->height,
22368 upper->y + upper->height)
22369 - result->y);
22370 intersection_p = 1;
22374 return intersection_p;
22377 #endif /* HAVE_WINDOW_SYSTEM */
22380 /***********************************************************************
22381 Initialization
22382 ***********************************************************************/
22384 void
22385 syms_of_xdisp ()
22387 Vwith_echo_area_save_vector = Qnil;
22388 staticpro (&Vwith_echo_area_save_vector);
22390 Vmessage_stack = Qnil;
22391 staticpro (&Vmessage_stack);
22393 Qinhibit_redisplay = intern ("inhibit-redisplay");
22394 staticpro (&Qinhibit_redisplay);
22396 message_dolog_marker1 = Fmake_marker ();
22397 staticpro (&message_dolog_marker1);
22398 message_dolog_marker2 = Fmake_marker ();
22399 staticpro (&message_dolog_marker2);
22400 message_dolog_marker3 = Fmake_marker ();
22401 staticpro (&message_dolog_marker3);
22403 #if GLYPH_DEBUG
22404 defsubr (&Sdump_frame_glyph_matrix);
22405 defsubr (&Sdump_glyph_matrix);
22406 defsubr (&Sdump_glyph_row);
22407 defsubr (&Sdump_tool_bar_row);
22408 defsubr (&Strace_redisplay);
22409 defsubr (&Strace_to_stderr);
22410 #endif
22411 #ifdef HAVE_WINDOW_SYSTEM
22412 defsubr (&Stool_bar_lines_needed);
22413 defsubr (&Slookup_image_map);
22414 #endif
22415 defsubr (&Sformat_mode_line);
22417 staticpro (&Qmenu_bar_update_hook);
22418 Qmenu_bar_update_hook = intern ("menu-bar-update-hook");
22420 staticpro (&Qoverriding_terminal_local_map);
22421 Qoverriding_terminal_local_map = intern ("overriding-terminal-local-map");
22423 staticpro (&Qoverriding_local_map);
22424 Qoverriding_local_map = intern ("overriding-local-map");
22426 staticpro (&Qwindow_scroll_functions);
22427 Qwindow_scroll_functions = intern ("window-scroll-functions");
22429 staticpro (&Qredisplay_end_trigger_functions);
22430 Qredisplay_end_trigger_functions = intern ("redisplay-end-trigger-functions");
22432 staticpro (&Qinhibit_point_motion_hooks);
22433 Qinhibit_point_motion_hooks = intern ("inhibit-point-motion-hooks");
22435 QCdata = intern (":data");
22436 staticpro (&QCdata);
22437 Qdisplay = intern ("display");
22438 staticpro (&Qdisplay);
22439 Qspace_width = intern ("space-width");
22440 staticpro (&Qspace_width);
22441 Qraise = intern ("raise");
22442 staticpro (&Qraise);
22443 Qslice = intern ("slice");
22444 staticpro (&Qslice);
22445 Qspace = intern ("space");
22446 staticpro (&Qspace);
22447 Qmargin = intern ("margin");
22448 staticpro (&Qmargin);
22449 Qpointer = intern ("pointer");
22450 staticpro (&Qpointer);
22451 Qleft_margin = intern ("left-margin");
22452 staticpro (&Qleft_margin);
22453 Qright_margin = intern ("right-margin");
22454 staticpro (&Qright_margin);
22455 Qcenter = intern ("center");
22456 staticpro (&Qcenter);
22457 Qline_height = intern ("line-height");
22458 staticpro (&Qline_height);
22459 QCalign_to = intern (":align-to");
22460 staticpro (&QCalign_to);
22461 QCrelative_width = intern (":relative-width");
22462 staticpro (&QCrelative_width);
22463 QCrelative_height = intern (":relative-height");
22464 staticpro (&QCrelative_height);
22465 QCeval = intern (":eval");
22466 staticpro (&QCeval);
22467 QCpropertize = intern (":propertize");
22468 staticpro (&QCpropertize);
22469 QCfile = intern (":file");
22470 staticpro (&QCfile);
22471 Qfontified = intern ("fontified");
22472 staticpro (&Qfontified);
22473 Qfontification_functions = intern ("fontification-functions");
22474 staticpro (&Qfontification_functions);
22475 Qtrailing_whitespace = intern ("trailing-whitespace");
22476 staticpro (&Qtrailing_whitespace);
22477 Qescape_glyph = intern ("escape-glyph");
22478 staticpro (&Qescape_glyph);
22479 Qimage = intern ("image");
22480 staticpro (&Qimage);
22481 QCmap = intern (":map");
22482 staticpro (&QCmap);
22483 QCpointer = intern (":pointer");
22484 staticpro (&QCpointer);
22485 Qrect = intern ("rect");
22486 staticpro (&Qrect);
22487 Qcircle = intern ("circle");
22488 staticpro (&Qcircle);
22489 Qpoly = intern ("poly");
22490 staticpro (&Qpoly);
22491 Qmessage_truncate_lines = intern ("message-truncate-lines");
22492 staticpro (&Qmessage_truncate_lines);
22493 Qcursor_in_non_selected_windows = intern ("cursor-in-non-selected-windows");
22494 staticpro (&Qcursor_in_non_selected_windows);
22495 Qgrow_only = intern ("grow-only");
22496 staticpro (&Qgrow_only);
22497 Qinhibit_menubar_update = intern ("inhibit-menubar-update");
22498 staticpro (&Qinhibit_menubar_update);
22499 Qinhibit_eval_during_redisplay = intern ("inhibit-eval-during-redisplay");
22500 staticpro (&Qinhibit_eval_during_redisplay);
22501 Qposition = intern ("position");
22502 staticpro (&Qposition);
22503 Qbuffer_position = intern ("buffer-position");
22504 staticpro (&Qbuffer_position);
22505 Qobject = intern ("object");
22506 staticpro (&Qobject);
22507 Qbar = intern ("bar");
22508 staticpro (&Qbar);
22509 Qhbar = intern ("hbar");
22510 staticpro (&Qhbar);
22511 Qbox = intern ("box");
22512 staticpro (&Qbox);
22513 Qhollow = intern ("hollow");
22514 staticpro (&Qhollow);
22515 Qhand = intern ("hand");
22516 staticpro (&Qhand);
22517 Qarrow = intern ("arrow");
22518 staticpro (&Qarrow);
22519 Qtext = intern ("text");
22520 staticpro (&Qtext);
22521 Qrisky_local_variable = intern ("risky-local-variable");
22522 staticpro (&Qrisky_local_variable);
22523 Qinhibit_free_realized_faces = intern ("inhibit-free-realized-faces");
22524 staticpro (&Qinhibit_free_realized_faces);
22526 list_of_error = Fcons (Fcons (intern ("error"),
22527 Fcons (intern ("void-variable"), Qnil)),
22528 Qnil);
22529 staticpro (&list_of_error);
22531 Qlast_arrow_position = intern ("last-arrow-position");
22532 staticpro (&Qlast_arrow_position);
22533 Qlast_arrow_string = intern ("last-arrow-string");
22534 staticpro (&Qlast_arrow_string);
22536 Qoverlay_arrow_string = intern ("overlay-arrow-string");
22537 staticpro (&Qoverlay_arrow_string);
22538 Qoverlay_arrow_bitmap = intern ("overlay-arrow-bitmap");
22539 staticpro (&Qoverlay_arrow_bitmap);
22541 echo_buffer[0] = echo_buffer[1] = Qnil;
22542 staticpro (&echo_buffer[0]);
22543 staticpro (&echo_buffer[1]);
22545 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
22546 staticpro (&echo_area_buffer[0]);
22547 staticpro (&echo_area_buffer[1]);
22549 Vmessages_buffer_name = build_string ("*Messages*");
22550 staticpro (&Vmessages_buffer_name);
22552 mode_line_proptrans_alist = Qnil;
22553 staticpro (&mode_line_proptrans_alist);
22555 mode_line_string_list = Qnil;
22556 staticpro (&mode_line_string_list);
22558 help_echo_string = Qnil;
22559 staticpro (&help_echo_string);
22560 help_echo_object = Qnil;
22561 staticpro (&help_echo_object);
22562 help_echo_window = Qnil;
22563 staticpro (&help_echo_window);
22564 previous_help_echo_string = Qnil;
22565 staticpro (&previous_help_echo_string);
22566 help_echo_pos = -1;
22568 #ifdef HAVE_WINDOW_SYSTEM
22569 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p,
22570 doc: /* *Non-nil means draw block cursor as wide as the glyph under it.
22571 For example, if a block cursor is over a tab, it will be drawn as
22572 wide as that tab on the display. */);
22573 x_stretch_cursor_p = 0;
22574 #endif
22576 DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace,
22577 doc: /* *Non-nil means highlight trailing whitespace.
22578 The face used for trailing whitespace is `trailing-whitespace'. */);
22579 Vshow_trailing_whitespace = Qnil;
22581 DEFVAR_LISP ("show-nonbreak-escape", &Vshow_nonbreak_escape,
22582 doc: /* *Non-nil means display escape character before non-break space and hyphen. */);
22583 Vshow_nonbreak_escape = Qt;
22585 DEFVAR_LISP ("void-text-area-pointer", &Vvoid_text_area_pointer,
22586 doc: /* *The pointer shape to show in void text areas.
22587 Nil means to show the text pointer. Other options are `arrow', `text',
22588 `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
22589 Vvoid_text_area_pointer = Qarrow;
22591 DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay,
22592 doc: /* Non-nil means don't actually do any redisplay.
22593 This is used for internal purposes. */);
22594 Vinhibit_redisplay = Qnil;
22596 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string,
22597 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
22598 Vglobal_mode_string = Qnil;
22600 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position,
22601 doc: /* Marker for where to display an arrow on top of the buffer text.
22602 This must be the beginning of a line in order to work.
22603 See also `overlay-arrow-string'. */);
22604 Voverlay_arrow_position = Qnil;
22606 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string,
22607 doc: /* String to display as an arrow in non-window frames.
22608 See also `overlay-arrow-position'. */);
22609 Voverlay_arrow_string = build_string ("=>");
22611 DEFVAR_LISP ("overlay-arrow-variable-list", &Voverlay_arrow_variable_list,
22612 doc: /* List of variables (symbols) which hold markers for overlay arrows.
22613 The symbols on this list are examined during redisplay to determine
22614 where to display overlay arrows. */);
22615 Voverlay_arrow_variable_list
22616 = Fcons (intern ("overlay-arrow-position"), Qnil);
22618 DEFVAR_INT ("scroll-step", &scroll_step,
22619 doc: /* *The number of lines to try scrolling a window by when point moves out.
22620 If that fails to bring point back on frame, point is centered instead.
22621 If this is zero, point is always centered after it moves off frame.
22622 If you want scrolling to always be a line at a time, you should set
22623 `scroll-conservatively' to a large value rather than set this to 1. */);
22625 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively,
22626 doc: /* *Scroll up to this many lines, to bring point back on screen.
22627 A value of zero means to scroll the text to center point vertically
22628 in the window. */);
22629 scroll_conservatively = 0;
22631 DEFVAR_INT ("scroll-margin", &scroll_margin,
22632 doc: /* *Number of lines of margin at the top and bottom of a window.
22633 Recenter the window whenever point gets within this many lines
22634 of the top or bottom of the window. */);
22635 scroll_margin = 0;
22637 DEFVAR_LISP ("display-pixels-per-inch", &Vdisplay_pixels_per_inch,
22638 doc: /* Pixels per inch on current display.
22639 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
22640 Vdisplay_pixels_per_inch = make_float (72.0);
22642 #if GLYPH_DEBUG
22643 DEFVAR_INT ("debug-end-pos", &debug_end_pos, doc: /* Don't ask. */);
22644 #endif
22646 DEFVAR_BOOL ("truncate-partial-width-windows",
22647 &truncate_partial_width_windows,
22648 doc: /* *Non-nil means truncate lines in all windows less than full frame wide. */);
22649 truncate_partial_width_windows = 1;
22651 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video,
22652 doc: /* nil means display the mode-line/header-line/menu-bar in the default face.
22653 Any other value means to use the appropriate face, `mode-line',
22654 `header-line', or `menu' respectively. */);
22655 mode_line_inverse_video = 1;
22657 DEFVAR_LISP ("line-number-display-limit", &Vline_number_display_limit,
22658 doc: /* *Maximum buffer size for which line number should be displayed.
22659 If the buffer is bigger than this, the line number does not appear
22660 in the mode line. A value of nil means no limit. */);
22661 Vline_number_display_limit = Qnil;
22663 DEFVAR_INT ("line-number-display-limit-width",
22664 &line_number_display_limit_width,
22665 doc: /* *Maximum line width (in characters) for line number display.
22666 If the average length of the lines near point is bigger than this, then the
22667 line number may be omitted from the mode line. */);
22668 line_number_display_limit_width = 200;
22670 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows,
22671 doc: /* *Non-nil means highlight region even in nonselected windows. */);
22672 highlight_nonselected_windows = 0;
22674 DEFVAR_BOOL ("multiple-frames", &multiple_frames,
22675 doc: /* Non-nil if more than one frame is visible on this display.
22676 Minibuffer-only frames don't count, but iconified frames do.
22677 This variable is not guaranteed to be accurate except while processing
22678 `frame-title-format' and `icon-title-format'. */);
22680 DEFVAR_LISP ("frame-title-format", &Vframe_title_format,
22681 doc: /* Template for displaying the title bar of visible frames.
22682 \(Assuming the window manager supports this feature.)
22683 This variable has the same structure as `mode-line-format' (which see),
22684 and is used only on frames for which no explicit name has been set
22685 \(see `modify-frame-parameters'). */);
22687 DEFVAR_LISP ("icon-title-format", &Vicon_title_format,
22688 doc: /* Template for displaying the title bar of an iconified frame.
22689 \(Assuming the window manager supports this feature.)
22690 This variable has the same structure as `mode-line-format' (which see),
22691 and is used only on frames for which no explicit name has been set
22692 \(see `modify-frame-parameters'). */);
22693 Vicon_title_format
22694 = Vframe_title_format
22695 = Fcons (intern ("multiple-frames"),
22696 Fcons (build_string ("%b"),
22697 Fcons (Fcons (empty_string,
22698 Fcons (intern ("invocation-name"),
22699 Fcons (build_string ("@"),
22700 Fcons (intern ("system-name"),
22701 Qnil)))),
22702 Qnil)));
22704 DEFVAR_LISP ("message-log-max", &Vmessage_log_max,
22705 doc: /* Maximum number of lines to keep in the message log buffer.
22706 If nil, disable message logging. If t, log messages but don't truncate
22707 the buffer when it becomes large. */);
22708 Vmessage_log_max = make_number (50);
22710 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions,
22711 doc: /* Functions called before redisplay, if window sizes have changed.
22712 The value should be a list of functions that take one argument.
22713 Just before redisplay, for each frame, if any of its windows have changed
22714 size since the last redisplay, or have been split or deleted,
22715 all the functions in the list are called, with the frame as argument. */);
22716 Vwindow_size_change_functions = Qnil;
22718 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions,
22719 doc: /* List of functions to call before redisplaying a window with scrolling.
22720 Each function is called with two arguments, the window
22721 and its new display-start position. Note that the value of `window-end'
22722 is not valid when these functions are called. */);
22723 Vwindow_scroll_functions = Qnil;
22725 DEFVAR_BOOL ("mouse-autoselect-window", &mouse_autoselect_window,
22726 doc: /* *Non-nil means autoselect window with mouse pointer. */);
22727 mouse_autoselect_window = 0;
22729 DEFVAR_BOOL ("auto-resize-tool-bars", &auto_resize_tool_bars_p,
22730 doc: /* *Non-nil means automatically resize tool-bars.
22731 This increases a tool-bar's height if not all tool-bar items are visible.
22732 It decreases a tool-bar's height when it would display blank lines
22733 otherwise. */);
22734 auto_resize_tool_bars_p = 1;
22736 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", &auto_raise_tool_bar_buttons_p,
22737 doc: /* *Non-nil means raise tool-bar buttons when the mouse moves over them. */);
22738 auto_raise_tool_bar_buttons_p = 1;
22740 DEFVAR_BOOL ("make-cursor-line-fully-visible", &make_cursor_line_fully_visible_p,
22741 doc: /* *Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
22742 make_cursor_line_fully_visible_p = 1;
22744 DEFVAR_LISP ("tool-bar-button-margin", &Vtool_bar_button_margin,
22745 doc: /* *Margin around tool-bar buttons in pixels.
22746 If an integer, use that for both horizontal and vertical margins.
22747 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
22748 HORZ specifying the horizontal margin, and VERT specifying the
22749 vertical margin. */);
22750 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
22752 DEFVAR_INT ("tool-bar-button-relief", &tool_bar_button_relief,
22753 doc: /* *Relief thickness of tool-bar buttons. */);
22754 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
22756 DEFVAR_LISP ("fontification-functions", &Vfontification_functions,
22757 doc: /* List of functions to call to fontify regions of text.
22758 Each function is called with one argument POS. Functions must
22759 fontify a region starting at POS in the current buffer, and give
22760 fontified regions the property `fontified'. */);
22761 Vfontification_functions = Qnil;
22762 Fmake_variable_buffer_local (Qfontification_functions);
22764 DEFVAR_BOOL ("unibyte-display-via-language-environment",
22765 &unibyte_display_via_language_environment,
22766 doc: /* *Non-nil means display unibyte text according to language environment.
22767 Specifically this means that unibyte non-ASCII characters
22768 are displayed by converting them to the equivalent multibyte characters
22769 according to the current language environment. As a result, they are
22770 displayed according to the current fontset. */);
22771 unibyte_display_via_language_environment = 0;
22773 DEFVAR_LISP ("max-mini-window-height", &Vmax_mini_window_height,
22774 doc: /* *Maximum height for resizing mini-windows.
22775 If a float, it specifies a fraction of the mini-window frame's height.
22776 If an integer, it specifies a number of lines. */);
22777 Vmax_mini_window_height = make_float (0.25);
22779 DEFVAR_LISP ("resize-mini-windows", &Vresize_mini_windows,
22780 doc: /* *How to resize mini-windows.
22781 A value of nil means don't automatically resize mini-windows.
22782 A value of t means resize them to fit the text displayed in them.
22783 A value of `grow-only', the default, means let mini-windows grow
22784 only, until their display becomes empty, at which point the windows
22785 go back to their normal size. */);
22786 Vresize_mini_windows = Qgrow_only;
22788 DEFVAR_LISP ("cursor-in-non-selected-windows",
22789 &Vcursor_in_non_selected_windows,
22790 doc: /* *Cursor type to display in non-selected windows.
22791 t means to use hollow box cursor. See `cursor-type' for other values. */);
22792 Vcursor_in_non_selected_windows = Qt;
22794 DEFVAR_LISP ("blink-cursor-alist", &Vblink_cursor_alist,
22795 doc: /* Alist specifying how to blink the cursor off.
22796 Each element has the form (ON-STATE . OFF-STATE). Whenever the
22797 `cursor-type' frame-parameter or variable equals ON-STATE,
22798 comparing using `equal', Emacs uses OFF-STATE to specify
22799 how to blink it off. */);
22800 Vblink_cursor_alist = Qnil;
22802 DEFVAR_BOOL ("auto-hscroll-mode", &automatic_hscrolling_p,
22803 doc: /* *Non-nil means scroll the display automatically to make point visible. */);
22804 automatic_hscrolling_p = 1;
22806 DEFVAR_INT ("hscroll-margin", &hscroll_margin,
22807 doc: /* *How many columns away from the window edge point is allowed to get
22808 before automatic hscrolling will horizontally scroll the window. */);
22809 hscroll_margin = 5;
22811 DEFVAR_LISP ("hscroll-step", &Vhscroll_step,
22812 doc: /* *How many columns to scroll the window when point gets too close to the edge.
22813 When point is less than `automatic-hscroll-margin' columns from the window
22814 edge, automatic hscrolling will scroll the window by the amount of columns
22815 determined by this variable. If its value is a positive integer, scroll that
22816 many columns. If it's a positive floating-point number, it specifies the
22817 fraction of the window's width to scroll. If it's nil or zero, point will be
22818 centered horizontally after the scroll. Any other value, including negative
22819 numbers, are treated as if the value were zero.
22821 Automatic hscrolling always moves point outside the scroll margin, so if
22822 point was more than scroll step columns inside the margin, the window will
22823 scroll more than the value given by the scroll step.
22825 Note that the lower bound for automatic hscrolling specified by `scroll-left'
22826 and `scroll-right' overrides this variable's effect. */);
22827 Vhscroll_step = make_number (0);
22829 DEFVAR_BOOL ("message-truncate-lines", &message_truncate_lines,
22830 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
22831 Bind this around calls to `message' to let it take effect. */);
22832 message_truncate_lines = 0;
22834 DEFVAR_LISP ("menu-bar-update-hook", &Vmenu_bar_update_hook,
22835 doc: /* Normal hook run to update the menu bar definitions.
22836 Redisplay runs this hook before it redisplays the menu bar.
22837 This is used to update submenus such as Buffers,
22838 whose contents depend on various data. */);
22839 Vmenu_bar_update_hook = Qnil;
22841 DEFVAR_BOOL ("inhibit-menubar-update", &inhibit_menubar_update,
22842 doc: /* Non-nil means don't update menu bars. Internal use only. */);
22843 inhibit_menubar_update = 0;
22845 DEFVAR_BOOL ("inhibit-eval-during-redisplay", &inhibit_eval_during_redisplay,
22846 doc: /* Non-nil means don't eval Lisp during redisplay. */);
22847 inhibit_eval_during_redisplay = 0;
22849 DEFVAR_BOOL ("inhibit-free-realized-faces", &inhibit_free_realized_faces,
22850 doc: /* Non-nil means don't free realized faces. Internal use only. */);
22851 inhibit_free_realized_faces = 0;
22853 #if GLYPH_DEBUG
22854 DEFVAR_BOOL ("inhibit-try-window-id", &inhibit_try_window_id,
22855 doc: /* Inhibit try_window_id display optimization. */);
22856 inhibit_try_window_id = 0;
22858 DEFVAR_BOOL ("inhibit-try-window-reusing", &inhibit_try_window_reusing,
22859 doc: /* Inhibit try_window_reusing display optimization. */);
22860 inhibit_try_window_reusing = 0;
22862 DEFVAR_BOOL ("inhibit-try-cursor-movement", &inhibit_try_cursor_movement,
22863 doc: /* Inhibit try_cursor_movement display optimization. */);
22864 inhibit_try_cursor_movement = 0;
22865 #endif /* GLYPH_DEBUG */
22869 /* Initialize this module when Emacs starts. */
22871 void
22872 init_xdisp ()
22874 Lisp_Object root_window;
22875 struct window *mini_w;
22877 current_header_line_height = current_mode_line_height = -1;
22879 CHARPOS (this_line_start_pos) = 0;
22881 mini_w = XWINDOW (minibuf_window);
22882 root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w)));
22884 if (!noninteractive)
22886 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (root_window)));
22887 int i;
22889 XWINDOW (root_window)->top_line = make_number (FRAME_TOP_MARGIN (f));
22890 set_window_height (root_window,
22891 FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f),
22893 mini_w->top_line = make_number (FRAME_LINES (f) - 1);
22894 set_window_height (minibuf_window, 1, 0);
22896 XWINDOW (root_window)->total_cols = make_number (FRAME_COLS (f));
22897 mini_w->total_cols = make_number (FRAME_COLS (f));
22899 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
22900 scratch_glyph_row.glyphs[TEXT_AREA + 1]
22901 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
22903 /* The default ellipsis glyphs `...'. */
22904 for (i = 0; i < 3; ++i)
22905 default_invis_vector[i] = make_number ('.');
22909 /* Allocate the buffer for frame titles.
22910 Also used for `format-mode-line'. */
22911 int size = 100;
22912 frame_title_buf = (char *) xmalloc (size);
22913 frame_title_buf_end = frame_title_buf + size;
22914 frame_title_ptr = NULL;
22917 help_echo_showing_p = 0;
22921 /* arch-tag: eacc864d-bb6a-4b74-894a-1a4399a1358b
22922 (do not change this comment) */