(Buffer Internals): Describe new auto_save_file_format field of the
[emacs.git] / src / xdisp.c
blob4de7166589d8bdd38fe07a19177d2b97e8bc01e7
1 /* Display generation from window structure and buffer text.
2 Copyright (C) 1985,86,87,88,93,94,95,97,98,99,2000,01,02,03,04
3 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 int minibuffer_auto_raise;
219 extern Lisp_Object Vminibuffer_list;
221 extern Lisp_Object Qface;
222 extern Lisp_Object Qmode_line, Qmode_line_inactive, Qheader_line;
224 extern Lisp_Object Voverriding_local_map;
225 extern Lisp_Object Voverriding_local_map_menu_flag;
226 extern Lisp_Object Qmenu_item;
227 extern Lisp_Object Qwhen;
228 extern Lisp_Object Qhelp_echo;
230 Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
231 Lisp_Object Qwindow_scroll_functions, Vwindow_scroll_functions;
232 Lisp_Object Qredisplay_end_trigger_functions;
233 Lisp_Object Qinhibit_point_motion_hooks;
234 Lisp_Object QCeval, QCfile, QCdata, QCpropertize;
235 Lisp_Object Qfontified;
236 Lisp_Object Qgrow_only;
237 Lisp_Object Qinhibit_eval_during_redisplay;
238 Lisp_Object Qbuffer_position, Qposition, Qobject;
240 /* Cursor shapes */
241 Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
243 /* Pointer shapes */
244 Lisp_Object Qarrow, Qhand, Qtext;
246 Lisp_Object Qrisky_local_variable;
248 /* Holds the list (error). */
249 Lisp_Object list_of_error;
251 /* Functions called to fontify regions of text. */
253 Lisp_Object Vfontification_functions;
254 Lisp_Object Qfontification_functions;
256 /* Non-zero means automatically select any window when the mouse
257 cursor moves into it. */
258 int mouse_autoselect_window;
260 /* Non-zero means draw tool bar buttons raised when the mouse moves
261 over them. */
263 int auto_raise_tool_bar_buttons_p;
265 /* Margin around tool bar buttons in pixels. */
267 Lisp_Object Vtool_bar_button_margin;
269 /* Thickness of shadow to draw around tool bar buttons. */
271 EMACS_INT tool_bar_button_relief;
273 /* Non-zero means automatically resize tool-bars so that all tool-bar
274 items are visible, and no blank lines remain. */
276 int auto_resize_tool_bars_p;
278 /* Non-zero means draw block and hollow cursor as wide as the glyph
279 under it. For example, if a block cursor is over a tab, it will be
280 drawn as wide as that tab on the display. */
282 int x_stretch_cursor_p;
284 /* Non-nil means don't actually do any redisplay. */
286 Lisp_Object Vinhibit_redisplay, Qinhibit_redisplay;
288 /* Non-zero means Lisp evaluation during redisplay is inhibited. */
290 int inhibit_eval_during_redisplay;
292 /* Names of text properties relevant for redisplay. */
294 Lisp_Object Qdisplay;
295 extern Lisp_Object Qface, Qinvisible, Qwidth;
297 /* Symbols used in text property values. */
299 Lisp_Object Vdisplay_pixels_per_inch;
300 Lisp_Object Qspace, QCalign_to, QCrelative_width, QCrelative_height;
301 Lisp_Object Qleft_margin, Qright_margin, Qspace_width, Qraise;
302 Lisp_Object Qslice;
303 Lisp_Object Qcenter;
304 Lisp_Object Qmargin, Qpointer;
305 Lisp_Object Qline_height, Qtotal;
306 extern Lisp_Object Qheight;
307 extern Lisp_Object QCwidth, QCheight, QCascent;
308 extern Lisp_Object Qscroll_bar;
309 extern Lisp_Object Qcursor;
311 /* Non-nil means highlight trailing whitespace. */
313 Lisp_Object Vshow_trailing_whitespace;
315 #ifdef HAVE_WINDOW_SYSTEM
316 extern Lisp_Object Voverflow_newline_into_fringe;
318 /* Test if overflow newline into fringe. Called with iterator IT
319 at or past right window margin, and with IT->current_x set. */
321 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) \
322 (!NILP (Voverflow_newline_into_fringe) \
323 && FRAME_WINDOW_P (it->f) \
324 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) > 0 \
325 && it->current_x == it->last_visible_x)
327 #endif /* HAVE_WINDOW_SYSTEM */
329 /* Non-nil means show the text cursor in void text areas
330 i.e. in blank areas after eol and eob. This used to be
331 the default in 21.3. */
333 Lisp_Object Vvoid_text_area_pointer;
335 /* Name of the face used to highlight trailing whitespace. */
337 Lisp_Object Qtrailing_whitespace;
339 /* The symbol `image' which is the car of the lists used to represent
340 images in Lisp. */
342 Lisp_Object Qimage;
344 /* The image map types. */
345 Lisp_Object QCmap, QCpointer;
346 Lisp_Object Qrect, Qcircle, Qpoly;
348 /* Non-zero means print newline to stdout before next mini-buffer
349 message. */
351 int noninteractive_need_newline;
353 /* Non-zero means print newline to message log before next message. */
355 static int message_log_need_newline;
357 /* Three markers that message_dolog uses.
358 It could allocate them itself, but that causes trouble
359 in handling memory-full errors. */
360 static Lisp_Object message_dolog_marker1;
361 static Lisp_Object message_dolog_marker2;
362 static Lisp_Object message_dolog_marker3;
364 /* The buffer position of the first character appearing entirely or
365 partially on the line of the selected window which contains the
366 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
367 redisplay optimization in redisplay_internal. */
369 static struct text_pos this_line_start_pos;
371 /* Number of characters past the end of the line above, including the
372 terminating newline. */
374 static struct text_pos this_line_end_pos;
376 /* The vertical positions and the height of this line. */
378 static int this_line_vpos;
379 static int this_line_y;
380 static int this_line_pixel_height;
382 /* X position at which this display line starts. Usually zero;
383 negative if first character is partially visible. */
385 static int this_line_start_x;
387 /* Buffer that this_line_.* variables are referring to. */
389 static struct buffer *this_line_buffer;
391 /* Nonzero means truncate lines in all windows less wide than the
392 frame. */
394 int truncate_partial_width_windows;
396 /* A flag to control how to display unibyte 8-bit character. */
398 int unibyte_display_via_language_environment;
400 /* Nonzero means we have more than one non-mini-buffer-only frame.
401 Not guaranteed to be accurate except while parsing
402 frame-title-format. */
404 int multiple_frames;
406 Lisp_Object Vglobal_mode_string;
409 /* List of variables (symbols) which hold markers for overlay arrows.
410 The symbols on this list are examined during redisplay to determine
411 where to display overlay arrows. */
413 Lisp_Object Voverlay_arrow_variable_list;
415 /* Marker for where to display an arrow on top of the buffer text. */
417 Lisp_Object Voverlay_arrow_position;
419 /* String to display for the arrow. Only used on terminal frames. */
421 Lisp_Object Voverlay_arrow_string;
423 /* Values of those variables at last redisplay are stored as
424 properties on `overlay-arrow-position' symbol. However, if
425 Voverlay_arrow_position is a marker, last-arrow-position is its
426 numerical position. */
428 Lisp_Object Qlast_arrow_position, Qlast_arrow_string;
430 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
431 properties on a symbol in overlay-arrow-variable-list. */
433 Lisp_Object Qoverlay_arrow_string, Qoverlay_arrow_bitmap;
435 /* Like mode-line-format, but for the title bar on a visible frame. */
437 Lisp_Object Vframe_title_format;
439 /* Like mode-line-format, but for the title bar on an iconified frame. */
441 Lisp_Object Vicon_title_format;
443 /* List of functions to call when a window's size changes. These
444 functions get one arg, a frame on which one or more windows' sizes
445 have changed. */
447 static Lisp_Object Vwindow_size_change_functions;
449 Lisp_Object Qmenu_bar_update_hook, Vmenu_bar_update_hook;
451 /* Nonzero if overlay arrow has been displayed once in this window. */
453 static int overlay_arrow_seen;
455 /* Nonzero means highlight the region even in nonselected windows. */
457 int highlight_nonselected_windows;
459 /* If cursor motion alone moves point off frame, try scrolling this
460 many lines up or down if that will bring it back. */
462 static EMACS_INT scroll_step;
464 /* Nonzero means scroll just far enough to bring point back on the
465 screen, when appropriate. */
467 static EMACS_INT scroll_conservatively;
469 /* Recenter the window whenever point gets within this many lines of
470 the top or bottom of the window. This value is translated into a
471 pixel value by multiplying it with FRAME_LINE_HEIGHT, which means
472 that there is really a fixed pixel height scroll margin. */
474 EMACS_INT scroll_margin;
476 /* Number of windows showing the buffer of the selected window (or
477 another buffer with the same base buffer). keyboard.c refers to
478 this. */
480 int buffer_shared;
482 /* Vector containing glyphs for an ellipsis `...'. */
484 static Lisp_Object default_invis_vector[3];
486 /* Zero means display the mode-line/header-line/menu-bar in the default face
487 (this slightly odd definition is for compatibility with previous versions
488 of emacs), non-zero means display them using their respective faces.
490 This variable is deprecated. */
492 int mode_line_inverse_video;
494 /* Prompt to display in front of the mini-buffer contents. */
496 Lisp_Object minibuf_prompt;
498 /* Width of current mini-buffer prompt. Only set after display_line
499 of the line that contains the prompt. */
501 int minibuf_prompt_width;
503 /* This is the window where the echo area message was displayed. It
504 is always a mini-buffer window, but it may not be the same window
505 currently active as a mini-buffer. */
507 Lisp_Object echo_area_window;
509 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
510 pushes the current message and the value of
511 message_enable_multibyte on the stack, the function restore_message
512 pops the stack and displays MESSAGE again. */
514 Lisp_Object Vmessage_stack;
516 /* Nonzero means multibyte characters were enabled when the echo area
517 message was specified. */
519 int message_enable_multibyte;
521 /* Nonzero if we should redraw the mode lines on the next redisplay. */
523 int update_mode_lines;
525 /* Nonzero if window sizes or contents have changed since last
526 redisplay that finished. */
528 int windows_or_buffers_changed;
530 /* Nonzero means a frame's cursor type has been changed. */
532 int cursor_type_changed;
534 /* Nonzero after display_mode_line if %l was used and it displayed a
535 line number. */
537 int line_number_displayed;
539 /* Maximum buffer size for which to display line numbers. */
541 Lisp_Object Vline_number_display_limit;
543 /* Line width to consider when repositioning for line number display. */
545 static EMACS_INT line_number_display_limit_width;
547 /* Number of lines to keep in the message log buffer. t means
548 infinite. nil means don't log at all. */
550 Lisp_Object Vmessage_log_max;
552 /* The name of the *Messages* buffer, a string. */
554 static Lisp_Object Vmessages_buffer_name;
556 /* Current, index 0, and last displayed echo area message. Either
557 buffers from echo_buffers, or nil to indicate no message. */
559 Lisp_Object echo_area_buffer[2];
561 /* The buffers referenced from echo_area_buffer. */
563 static Lisp_Object echo_buffer[2];
565 /* A vector saved used in with_area_buffer to reduce consing. */
567 static Lisp_Object Vwith_echo_area_save_vector;
569 /* Non-zero means display_echo_area should display the last echo area
570 message again. Set by redisplay_preserve_echo_area. */
572 static int display_last_displayed_message_p;
574 /* Nonzero if echo area is being used by print; zero if being used by
575 message. */
577 int message_buf_print;
579 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
581 Lisp_Object Qinhibit_menubar_update;
582 int inhibit_menubar_update;
584 /* Maximum height for resizing mini-windows. Either a float
585 specifying a fraction of the available height, or an integer
586 specifying a number of lines. */
588 Lisp_Object Vmax_mini_window_height;
590 /* Non-zero means messages should be displayed with truncated
591 lines instead of being continued. */
593 int message_truncate_lines;
594 Lisp_Object Qmessage_truncate_lines;
596 /* Set to 1 in clear_message to make redisplay_internal aware
597 of an emptied echo area. */
599 static int message_cleared_p;
601 /* Non-zero means we want a hollow cursor in windows that are not
602 selected. Zero means there's no cursor in such windows. */
604 Lisp_Object Vcursor_in_non_selected_windows;
605 Lisp_Object Qcursor_in_non_selected_windows;
607 /* How to blink the default frame cursor off. */
608 Lisp_Object Vblink_cursor_alist;
610 /* A scratch glyph row with contents used for generating truncation
611 glyphs. Also used in direct_output_for_insert. */
613 #define MAX_SCRATCH_GLYPHS 100
614 struct glyph_row scratch_glyph_row;
615 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
617 /* Ascent and height of the last line processed by move_it_to. */
619 static int last_max_ascent, last_height;
621 /* Non-zero if there's a help-echo in the echo area. */
623 int help_echo_showing_p;
625 /* If >= 0, computed, exact values of mode-line and header-line height
626 to use in the macros CURRENT_MODE_LINE_HEIGHT and
627 CURRENT_HEADER_LINE_HEIGHT. */
629 int current_mode_line_height, current_header_line_height;
631 /* The maximum distance to look ahead for text properties. Values
632 that are too small let us call compute_char_face and similar
633 functions too often which is expensive. Values that are too large
634 let us call compute_char_face and alike too often because we
635 might not be interested in text properties that far away. */
637 #define TEXT_PROP_DISTANCE_LIMIT 100
639 #if GLYPH_DEBUG
641 /* Variables to turn off display optimizations from Lisp. */
643 int inhibit_try_window_id, inhibit_try_window_reusing;
644 int inhibit_try_cursor_movement;
646 /* Non-zero means print traces of redisplay if compiled with
647 GLYPH_DEBUG != 0. */
649 int trace_redisplay_p;
651 #endif /* GLYPH_DEBUG */
653 #ifdef DEBUG_TRACE_MOVE
654 /* Non-zero means trace with TRACE_MOVE to stderr. */
655 int trace_move;
657 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
658 #else
659 #define TRACE_MOVE(x) (void) 0
660 #endif
662 /* Non-zero means automatically scroll windows horizontally to make
663 point visible. */
665 int automatic_hscrolling_p;
667 /* How close to the margin can point get before the window is scrolled
668 horizontally. */
669 EMACS_INT hscroll_margin;
671 /* How much to scroll horizontally when point is inside the above margin. */
672 Lisp_Object Vhscroll_step;
674 /* The variable `resize-mini-windows'. If nil, don't resize
675 mini-windows. If t, always resize them to fit the text they
676 display. If `grow-only', let mini-windows grow only until they
677 become empty. */
679 Lisp_Object Vresize_mini_windows;
681 /* Buffer being redisplayed -- for redisplay_window_error. */
683 struct buffer *displayed_buffer;
685 /* Value returned from text property handlers (see below). */
687 enum prop_handled
689 HANDLED_NORMALLY,
690 HANDLED_RECOMPUTE_PROPS,
691 HANDLED_OVERLAY_STRING_CONSUMED,
692 HANDLED_RETURN
695 /* A description of text properties that redisplay is interested
696 in. */
698 struct props
700 /* The name of the property. */
701 Lisp_Object *name;
703 /* A unique index for the property. */
704 enum prop_idx idx;
706 /* A handler function called to set up iterator IT from the property
707 at IT's current position. Value is used to steer handle_stop. */
708 enum prop_handled (*handler) P_ ((struct it *it));
711 static enum prop_handled handle_face_prop P_ ((struct it *));
712 static enum prop_handled handle_invisible_prop P_ ((struct it *));
713 static enum prop_handled handle_display_prop P_ ((struct it *));
714 static enum prop_handled handle_composition_prop P_ ((struct it *));
715 static enum prop_handled handle_overlay_change P_ ((struct it *));
716 static enum prop_handled handle_fontified_prop P_ ((struct it *));
718 /* Properties handled by iterators. */
720 static struct props it_props[] =
722 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
723 /* Handle `face' before `display' because some sub-properties of
724 `display' need to know the face. */
725 {&Qface, FACE_PROP_IDX, handle_face_prop},
726 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
727 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
728 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
729 {NULL, 0, NULL}
732 /* Value is the position described by X. If X is a marker, value is
733 the marker_position of X. Otherwise, value is X. */
735 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
737 /* Enumeration returned by some move_it_.* functions internally. */
739 enum move_it_result
741 /* Not used. Undefined value. */
742 MOVE_UNDEFINED,
744 /* Move ended at the requested buffer position or ZV. */
745 MOVE_POS_MATCH_OR_ZV,
747 /* Move ended at the requested X pixel position. */
748 MOVE_X_REACHED,
750 /* Move within a line ended at the end of a line that must be
751 continued. */
752 MOVE_LINE_CONTINUED,
754 /* Move within a line ended at the end of a line that would
755 be displayed truncated. */
756 MOVE_LINE_TRUNCATED,
758 /* Move within a line ended at a line end. */
759 MOVE_NEWLINE_OR_CR
762 /* This counter is used to clear the face cache every once in a while
763 in redisplay_internal. It is incremented for each redisplay.
764 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
765 cleared. */
767 #define CLEAR_FACE_CACHE_COUNT 500
768 static int clear_face_cache_count;
770 /* Record the previous terminal frame we displayed. */
772 static struct frame *previous_terminal_frame;
774 /* Non-zero while redisplay_internal is in progress. */
776 int redisplaying_p;
778 /* Non-zero means don't free realized faces. Bound while freeing
779 realized faces is dangerous because glyph matrices might still
780 reference them. */
782 int inhibit_free_realized_faces;
783 Lisp_Object Qinhibit_free_realized_faces;
785 /* If a string, XTread_socket generates an event to display that string.
786 (The display is done in read_char.) */
788 Lisp_Object help_echo_string;
789 Lisp_Object help_echo_window;
790 Lisp_Object help_echo_object;
791 int help_echo_pos;
793 /* Temporary variable for XTread_socket. */
795 Lisp_Object previous_help_echo_string;
797 /* Null glyph slice */
799 static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 };
802 /* Function prototypes. */
804 static void setup_for_ellipsis P_ ((struct it *));
805 static void mark_window_display_accurate_1 P_ ((struct window *, int));
806 static int single_display_prop_string_p P_ ((Lisp_Object, Lisp_Object));
807 static int display_prop_string_p P_ ((Lisp_Object, Lisp_Object));
808 static int cursor_row_p P_ ((struct window *, struct glyph_row *));
809 static int redisplay_mode_lines P_ ((Lisp_Object, int));
810 static char *decode_mode_spec_coding P_ ((Lisp_Object, char *, int));
812 #if 0
813 static int invisible_text_between_p P_ ((struct it *, int, int));
814 #endif
816 static int next_element_from_ellipsis P_ ((struct it *));
817 static void pint2str P_ ((char *, int, int));
818 static void pint2hrstr P_ ((char *, int, int));
819 static struct text_pos run_window_scroll_functions P_ ((Lisp_Object,
820 struct text_pos));
821 static void reconsider_clip_changes P_ ((struct window *, struct buffer *));
822 static int text_outside_line_unchanged_p P_ ((struct window *, int, int));
823 static void store_frame_title_char P_ ((char));
824 static int store_frame_title P_ ((const unsigned char *, int, int));
825 static void x_consider_frame_title P_ ((Lisp_Object));
826 static void handle_stop P_ ((struct it *));
827 static int tool_bar_lines_needed P_ ((struct frame *));
828 static int single_display_prop_intangible_p P_ ((Lisp_Object));
829 static void ensure_echo_area_buffers P_ ((void));
830 static Lisp_Object unwind_with_echo_area_buffer P_ ((Lisp_Object));
831 static Lisp_Object with_echo_area_buffer_unwind_data P_ ((struct window *));
832 static int with_echo_area_buffer P_ ((struct window *, int,
833 int (*) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
834 EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
835 static void clear_garbaged_frames P_ ((void));
836 static int current_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
837 static int truncate_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
838 static int set_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
839 static int display_echo_area P_ ((struct window *));
840 static int display_echo_area_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
841 static int resize_mini_window_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
842 static Lisp_Object unwind_redisplay P_ ((Lisp_Object));
843 static int string_char_and_length P_ ((const unsigned char *, int, int *));
844 static struct text_pos display_prop_end P_ ((struct it *, Lisp_Object,
845 struct text_pos));
846 static int compute_window_start_on_continuation_line P_ ((struct window *));
847 static Lisp_Object safe_eval_handler P_ ((Lisp_Object));
848 static void insert_left_trunc_glyphs P_ ((struct it *));
849 static struct glyph_row *get_overlay_arrow_glyph_row P_ ((struct window *,
850 Lisp_Object));
851 static void extend_face_to_end_of_line P_ ((struct it *));
852 static int append_space_for_newline P_ ((struct it *, int));
853 static int make_cursor_line_fully_visible P_ ((struct window *, int));
854 static int try_scrolling P_ ((Lisp_Object, int, EMACS_INT, EMACS_INT, int, int));
855 static int try_cursor_movement P_ ((Lisp_Object, struct text_pos, int *));
856 static int trailing_whitespace_p P_ ((int));
857 static int message_log_check_duplicate P_ ((int, int, int, int));
858 static void push_it P_ ((struct it *));
859 static void pop_it P_ ((struct it *));
860 static void sync_frame_with_window_matrix_rows P_ ((struct window *));
861 static void select_frame_for_redisplay P_ ((Lisp_Object));
862 static void redisplay_internal P_ ((int));
863 static int echo_area_display P_ ((int));
864 static void redisplay_windows P_ ((Lisp_Object));
865 static void redisplay_window P_ ((Lisp_Object, int));
866 static Lisp_Object redisplay_window_error ();
867 static Lisp_Object redisplay_window_0 P_ ((Lisp_Object));
868 static Lisp_Object redisplay_window_1 P_ ((Lisp_Object));
869 static void update_menu_bar P_ ((struct frame *, int));
870 static int try_window_reusing_current_matrix P_ ((struct window *));
871 static int try_window_id P_ ((struct window *));
872 static int display_line P_ ((struct it *));
873 static int display_mode_lines P_ ((struct window *));
874 static int display_mode_line P_ ((struct window *, enum face_id, Lisp_Object));
875 static int display_mode_element P_ ((struct it *, int, int, int, Lisp_Object, Lisp_Object, int));
876 static int store_mode_line_string P_ ((char *, Lisp_Object, int, int, int, Lisp_Object));
877 static char *decode_mode_spec P_ ((struct window *, int, int, int, int *));
878 static void display_menu_bar P_ ((struct window *));
879 static int display_count_lines P_ ((int, int, int, int, int *));
880 static int display_string P_ ((unsigned char *, Lisp_Object, Lisp_Object,
881 int, int, struct it *, int, int, int, int));
882 static void compute_line_metrics P_ ((struct it *));
883 static void run_redisplay_end_trigger_hook P_ ((struct it *));
884 static int get_overlay_strings P_ ((struct it *, int));
885 static void next_overlay_string P_ ((struct it *));
886 static void reseat P_ ((struct it *, struct text_pos, int));
887 static void reseat_1 P_ ((struct it *, struct text_pos, int));
888 static void back_to_previous_visible_line_start P_ ((struct it *));
889 static void reseat_at_previous_visible_line_start P_ ((struct it *));
890 static void reseat_at_next_visible_line_start P_ ((struct it *, int));
891 static int next_element_from_display_vector P_ ((struct it *));
892 static int next_element_from_string P_ ((struct it *));
893 static int next_element_from_c_string P_ ((struct it *));
894 static int next_element_from_buffer P_ ((struct it *));
895 static int next_element_from_composition P_ ((struct it *));
896 static int next_element_from_image P_ ((struct it *));
897 static int next_element_from_stretch P_ ((struct it *));
898 static void load_overlay_strings P_ ((struct it *, int));
899 static int init_from_display_pos P_ ((struct it *, struct window *,
900 struct display_pos *));
901 static void reseat_to_string P_ ((struct it *, unsigned char *,
902 Lisp_Object, int, int, int, int));
903 static enum move_it_result move_it_in_display_line_to P_ ((struct it *,
904 int, int, int));
905 void move_it_vertically_backward P_ ((struct it *, int));
906 static void init_to_row_start P_ ((struct it *, struct window *,
907 struct glyph_row *));
908 static int init_to_row_end P_ ((struct it *, struct window *,
909 struct glyph_row *));
910 static void back_to_previous_line_start P_ ((struct it *));
911 static int forward_to_next_line_start P_ ((struct it *, int *));
912 static struct text_pos string_pos_nchars_ahead P_ ((struct text_pos,
913 Lisp_Object, int));
914 static struct text_pos string_pos P_ ((int, Lisp_Object));
915 static struct text_pos c_string_pos P_ ((int, unsigned char *, int));
916 static int number_of_chars P_ ((unsigned char *, int));
917 static void compute_stop_pos P_ ((struct it *));
918 static void compute_string_pos P_ ((struct text_pos *, struct text_pos,
919 Lisp_Object));
920 static int face_before_or_after_it_pos P_ ((struct it *, int));
921 static int next_overlay_change P_ ((int));
922 static int handle_single_display_prop P_ ((struct it *, Lisp_Object,
923 Lisp_Object, struct text_pos *,
924 int));
925 static int underlying_face_id P_ ((struct it *));
926 static int in_ellipses_for_invisible_text_p P_ ((struct display_pos *,
927 struct window *));
929 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
930 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
932 #ifdef HAVE_WINDOW_SYSTEM
934 static void update_tool_bar P_ ((struct frame *, int));
935 static void build_desired_tool_bar_string P_ ((struct frame *f));
936 static int redisplay_tool_bar P_ ((struct frame *));
937 static void display_tool_bar_line P_ ((struct it *));
938 static void notice_overwritten_cursor P_ ((struct window *,
939 enum glyph_row_area,
940 int, int, int, int));
944 #endif /* HAVE_WINDOW_SYSTEM */
947 /***********************************************************************
948 Window display dimensions
949 ***********************************************************************/
951 /* Return the bottom boundary y-position for text lines in window W.
952 This is the first y position at which a line cannot start.
953 It is relative to the top of the window.
955 This is the height of W minus the height of a mode line, if any. */
957 INLINE int
958 window_text_bottom_y (w)
959 struct window *w;
961 int height = WINDOW_TOTAL_HEIGHT (w);
963 if (WINDOW_WANTS_MODELINE_P (w))
964 height -= CURRENT_MODE_LINE_HEIGHT (w);
965 return height;
968 /* Return the pixel width of display area AREA of window W. AREA < 0
969 means return the total width of W, not including fringes to
970 the left and right of the window. */
972 INLINE int
973 window_box_width (w, area)
974 struct window *w;
975 int area;
977 int cols = XFASTINT (w->total_cols);
978 int pixels = 0;
980 if (!w->pseudo_window_p)
982 cols -= WINDOW_SCROLL_BAR_COLS (w);
984 if (area == TEXT_AREA)
986 if (INTEGERP (w->left_margin_cols))
987 cols -= XFASTINT (w->left_margin_cols);
988 if (INTEGERP (w->right_margin_cols))
989 cols -= XFASTINT (w->right_margin_cols);
990 pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w);
992 else if (area == LEFT_MARGIN_AREA)
994 cols = (INTEGERP (w->left_margin_cols)
995 ? XFASTINT (w->left_margin_cols) : 0);
996 pixels = 0;
998 else if (area == RIGHT_MARGIN_AREA)
1000 cols = (INTEGERP (w->right_margin_cols)
1001 ? XFASTINT (w->right_margin_cols) : 0);
1002 pixels = 0;
1006 return cols * WINDOW_FRAME_COLUMN_WIDTH (w) + pixels;
1010 /* Return the pixel height of the display area of window W, not
1011 including mode lines of W, if any. */
1013 INLINE int
1014 window_box_height (w)
1015 struct window *w;
1017 struct frame *f = XFRAME (w->frame);
1018 int height = WINDOW_TOTAL_HEIGHT (w);
1020 xassert (height >= 0);
1022 /* Note: the code below that determines the mode-line/header-line
1023 height is essentially the same as that contained in the macro
1024 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1025 the appropriate glyph row has its `mode_line_p' flag set,
1026 and if it doesn't, uses estimate_mode_line_height instead. */
1028 if (WINDOW_WANTS_MODELINE_P (w))
1030 struct glyph_row *ml_row
1031 = (w->current_matrix && w->current_matrix->rows
1032 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
1033 : 0);
1034 if (ml_row && ml_row->mode_line_p)
1035 height -= ml_row->height;
1036 else
1037 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
1040 if (WINDOW_WANTS_HEADER_LINE_P (w))
1042 struct glyph_row *hl_row
1043 = (w->current_matrix && w->current_matrix->rows
1044 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
1045 : 0);
1046 if (hl_row && hl_row->mode_line_p)
1047 height -= hl_row->height;
1048 else
1049 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1052 /* With a very small font and a mode-line that's taller than
1053 default, we might end up with a negative height. */
1054 return max (0, height);
1057 /* Return the window-relative coordinate of the left edge of display
1058 area AREA of window W. AREA < 0 means return the left edge of the
1059 whole window, to the right of the left fringe of W. */
1061 INLINE int
1062 window_box_left_offset (w, area)
1063 struct window *w;
1064 int area;
1066 int x;
1068 if (w->pseudo_window_p)
1069 return 0;
1071 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
1073 if (area == TEXT_AREA)
1074 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1075 + window_box_width (w, LEFT_MARGIN_AREA));
1076 else if (area == RIGHT_MARGIN_AREA)
1077 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1078 + window_box_width (w, LEFT_MARGIN_AREA)
1079 + window_box_width (w, TEXT_AREA)
1080 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1082 : WINDOW_RIGHT_FRINGE_WIDTH (w)));
1083 else if (area == LEFT_MARGIN_AREA
1084 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1085 x += WINDOW_LEFT_FRINGE_WIDTH (w);
1087 return x;
1091 /* Return the window-relative coordinate of the right edge of display
1092 area AREA of window W. AREA < 0 means return the left edge of the
1093 whole window, to the left of the right fringe of W. */
1095 INLINE int
1096 window_box_right_offset (w, area)
1097 struct window *w;
1098 int area;
1100 return window_box_left_offset (w, area) + window_box_width (w, area);
1103 /* Return the frame-relative coordinate of the left edge of display
1104 area AREA of window W. AREA < 0 means return the left edge of the
1105 whole window, to the right of the left fringe of W. */
1107 INLINE int
1108 window_box_left (w, area)
1109 struct window *w;
1110 int area;
1112 struct frame *f = XFRAME (w->frame);
1113 int x;
1115 if (w->pseudo_window_p)
1116 return FRAME_INTERNAL_BORDER_WIDTH (f);
1118 x = (WINDOW_LEFT_EDGE_X (w)
1119 + window_box_left_offset (w, area));
1121 return x;
1125 /* Return the frame-relative coordinate of the right edge of display
1126 area AREA of window W. AREA < 0 means return the left edge of the
1127 whole window, to the left of the right fringe of W. */
1129 INLINE int
1130 window_box_right (w, area)
1131 struct window *w;
1132 int area;
1134 return window_box_left (w, area) + window_box_width (w, area);
1137 /* Get the bounding box of the display area AREA of window W, without
1138 mode lines, in frame-relative coordinates. AREA < 0 means the
1139 whole window, not including the left and right fringes of
1140 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1141 coordinates of the upper-left corner of the box. Return in
1142 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1144 INLINE void
1145 window_box (w, area, box_x, box_y, box_width, box_height)
1146 struct window *w;
1147 int area;
1148 int *box_x, *box_y, *box_width, *box_height;
1150 if (box_width)
1151 *box_width = window_box_width (w, area);
1152 if (box_height)
1153 *box_height = window_box_height (w);
1154 if (box_x)
1155 *box_x = window_box_left (w, area);
1156 if (box_y)
1158 *box_y = WINDOW_TOP_EDGE_Y (w);
1159 if (WINDOW_WANTS_HEADER_LINE_P (w))
1160 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1165 /* Get the bounding box of the display area AREA of window W, without
1166 mode lines. AREA < 0 means the whole window, not including the
1167 left and right fringe of the window. Return in *TOP_LEFT_X
1168 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1169 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1170 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1171 box. */
1173 INLINE void
1174 window_box_edges (w, area, top_left_x, top_left_y,
1175 bottom_right_x, bottom_right_y)
1176 struct window *w;
1177 int area;
1178 int *top_left_x, *top_left_y, *bottom_right_x, *bottom_right_y;
1180 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
1181 bottom_right_y);
1182 *bottom_right_x += *top_left_x;
1183 *bottom_right_y += *top_left_y;
1188 /***********************************************************************
1189 Utilities
1190 ***********************************************************************/
1192 /* Return the bottom y-position of the line the iterator IT is in.
1193 This can modify IT's settings. */
1196 line_bottom_y (it)
1197 struct it *it;
1199 int line_height = it->max_ascent + it->max_descent;
1200 int line_top_y = it->current_y;
1202 if (line_height == 0)
1204 if (last_height)
1205 line_height = last_height;
1206 else if (IT_CHARPOS (*it) < ZV)
1208 move_it_by_lines (it, 1, 1);
1209 line_height = (it->max_ascent || it->max_descent
1210 ? it->max_ascent + it->max_descent
1211 : last_height);
1213 else
1215 struct glyph_row *row = it->glyph_row;
1217 /* Use the default character height. */
1218 it->glyph_row = NULL;
1219 it->what = IT_CHARACTER;
1220 it->c = ' ';
1221 it->len = 1;
1222 PRODUCE_GLYPHS (it);
1223 line_height = it->ascent + it->descent;
1224 it->glyph_row = row;
1228 return line_top_y + line_height;
1232 /* Return 1 if position CHARPOS is visible in window W. Set *FULLY to
1233 1 if POS is visible and the line containing POS is fully visible.
1234 EXACT_MODE_LINE_HEIGHTS_P non-zero means compute exact mode-line
1235 and header-lines heights. */
1238 pos_visible_p (w, charpos, fully, x, y, exact_mode_line_heights_p)
1239 struct window *w;
1240 int charpos, *fully, *x, *y, exact_mode_line_heights_p;
1242 struct it it;
1243 struct text_pos top;
1244 int visible_p;
1245 struct buffer *old_buffer = NULL;
1247 if (XBUFFER (w->buffer) != current_buffer)
1249 old_buffer = current_buffer;
1250 set_buffer_internal_1 (XBUFFER (w->buffer));
1253 *fully = visible_p = 0;
1254 SET_TEXT_POS_FROM_MARKER (top, w->start);
1256 /* Compute exact mode line heights, if requested. */
1257 if (exact_mode_line_heights_p)
1259 if (WINDOW_WANTS_MODELINE_P (w))
1260 current_mode_line_height
1261 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1262 current_buffer->mode_line_format);
1264 if (WINDOW_WANTS_HEADER_LINE_P (w))
1265 current_header_line_height
1266 = display_mode_line (w, HEADER_LINE_FACE_ID,
1267 current_buffer->header_line_format);
1270 start_display (&it, w, top);
1271 move_it_to (&it, charpos, 0, it.last_visible_y, -1,
1272 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
1274 /* Note that we may overshoot because of invisible text. */
1275 if (IT_CHARPOS (it) >= charpos)
1277 int top_y = it.current_y;
1278 int bottom_y = line_bottom_y (&it);
1279 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1281 if (top_y < window_top_y)
1282 visible_p = bottom_y > window_top_y;
1283 else if (top_y < it.last_visible_y)
1285 visible_p = 1;
1286 *fully = bottom_y <= it.last_visible_y;
1288 if (visible_p && x)
1290 *x = it.current_x;
1291 *y = max (top_y + it.max_ascent - it.ascent, window_top_y);
1294 else if (it.current_y + it.max_ascent + it.max_descent > it.last_visible_y)
1296 struct it it2;
1298 it2 = it;
1299 move_it_by_lines (&it, 1, 0);
1300 if (charpos < IT_CHARPOS (it))
1302 visible_p = 1;
1303 if (x)
1305 move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
1306 *x = it2.current_x;
1307 *y = it2.current_y + it2.max_ascent - it2.ascent;
1312 if (old_buffer)
1313 set_buffer_internal_1 (old_buffer);
1315 current_header_line_height = current_mode_line_height = -1;
1317 return visible_p;
1321 /* Return the next character from STR which is MAXLEN bytes long.
1322 Return in *LEN the length of the character. This is like
1323 STRING_CHAR_AND_LENGTH but never returns an invalid character. If
1324 we find one, we return a `?', but with the length of the invalid
1325 character. */
1327 static INLINE int
1328 string_char_and_length (str, maxlen, len)
1329 const unsigned char *str;
1330 int maxlen, *len;
1332 int c;
1334 c = STRING_CHAR_AND_LENGTH (str, maxlen, *len);
1335 if (!CHAR_VALID_P (c, 1))
1336 /* We may not change the length here because other places in Emacs
1337 don't use this function, i.e. they silently accept invalid
1338 characters. */
1339 c = '?';
1341 return c;
1346 /* Given a position POS containing a valid character and byte position
1347 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1349 static struct text_pos
1350 string_pos_nchars_ahead (pos, string, nchars)
1351 struct text_pos pos;
1352 Lisp_Object string;
1353 int nchars;
1355 xassert (STRINGP (string) && nchars >= 0);
1357 if (STRING_MULTIBYTE (string))
1359 int rest = SBYTES (string) - BYTEPOS (pos);
1360 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1361 int len;
1363 while (nchars--)
1365 string_char_and_length (p, rest, &len);
1366 p += len, rest -= len;
1367 xassert (rest >= 0);
1368 CHARPOS (pos) += 1;
1369 BYTEPOS (pos) += len;
1372 else
1373 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1375 return pos;
1379 /* Value is the text position, i.e. character and byte position,
1380 for character position CHARPOS in STRING. */
1382 static INLINE struct text_pos
1383 string_pos (charpos, string)
1384 int charpos;
1385 Lisp_Object string;
1387 struct text_pos pos;
1388 xassert (STRINGP (string));
1389 xassert (charpos >= 0);
1390 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1391 return pos;
1395 /* Value is a text position, i.e. character and byte position, for
1396 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1397 means recognize multibyte characters. */
1399 static struct text_pos
1400 c_string_pos (charpos, s, multibyte_p)
1401 int charpos;
1402 unsigned char *s;
1403 int multibyte_p;
1405 struct text_pos pos;
1407 xassert (s != NULL);
1408 xassert (charpos >= 0);
1410 if (multibyte_p)
1412 int rest = strlen (s), len;
1414 SET_TEXT_POS (pos, 0, 0);
1415 while (charpos--)
1417 string_char_and_length (s, rest, &len);
1418 s += len, rest -= len;
1419 xassert (rest >= 0);
1420 CHARPOS (pos) += 1;
1421 BYTEPOS (pos) += len;
1424 else
1425 SET_TEXT_POS (pos, charpos, charpos);
1427 return pos;
1431 /* Value is the number of characters in C string S. MULTIBYTE_P
1432 non-zero means recognize multibyte characters. */
1434 static int
1435 number_of_chars (s, multibyte_p)
1436 unsigned char *s;
1437 int multibyte_p;
1439 int nchars;
1441 if (multibyte_p)
1443 int rest = strlen (s), len;
1444 unsigned char *p = (unsigned char *) s;
1446 for (nchars = 0; rest > 0; ++nchars)
1448 string_char_and_length (p, rest, &len);
1449 rest -= len, p += len;
1452 else
1453 nchars = strlen (s);
1455 return nchars;
1459 /* Compute byte position NEWPOS->bytepos corresponding to
1460 NEWPOS->charpos. POS is a known position in string STRING.
1461 NEWPOS->charpos must be >= POS.charpos. */
1463 static void
1464 compute_string_pos (newpos, pos, string)
1465 struct text_pos *newpos, pos;
1466 Lisp_Object string;
1468 xassert (STRINGP (string));
1469 xassert (CHARPOS (*newpos) >= CHARPOS (pos));
1471 if (STRING_MULTIBYTE (string))
1472 *newpos = string_pos_nchars_ahead (pos, string,
1473 CHARPOS (*newpos) - CHARPOS (pos));
1474 else
1475 BYTEPOS (*newpos) = CHARPOS (*newpos);
1478 /* EXPORT:
1479 Return an estimation of the pixel height of mode or top lines on
1480 frame F. FACE_ID specifies what line's height to estimate. */
1483 estimate_mode_line_height (f, face_id)
1484 struct frame *f;
1485 enum face_id face_id;
1487 #ifdef HAVE_WINDOW_SYSTEM
1488 if (FRAME_WINDOW_P (f))
1490 int height = FONT_HEIGHT (FRAME_FONT (f));
1492 /* This function is called so early when Emacs starts that the face
1493 cache and mode line face are not yet initialized. */
1494 if (FRAME_FACE_CACHE (f))
1496 struct face *face = FACE_FROM_ID (f, face_id);
1497 if (face)
1499 if (face->font)
1500 height = FONT_HEIGHT (face->font);
1501 if (face->box_line_width > 0)
1502 height += 2 * face->box_line_width;
1506 return height;
1508 #endif
1510 return 1;
1513 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1514 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1515 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1516 not force the value into range. */
1518 void
1519 pixel_to_glyph_coords (f, pix_x, pix_y, x, y, bounds, noclip)
1520 FRAME_PTR f;
1521 register int pix_x, pix_y;
1522 int *x, *y;
1523 NativeRectangle *bounds;
1524 int noclip;
1527 #ifdef HAVE_WINDOW_SYSTEM
1528 if (FRAME_WINDOW_P (f))
1530 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1531 even for negative values. */
1532 if (pix_x < 0)
1533 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1534 if (pix_y < 0)
1535 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1537 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1538 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1540 if (bounds)
1541 STORE_NATIVE_RECT (*bounds,
1542 FRAME_COL_TO_PIXEL_X (f, pix_x),
1543 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1544 FRAME_COLUMN_WIDTH (f) - 1,
1545 FRAME_LINE_HEIGHT (f) - 1);
1547 if (!noclip)
1549 if (pix_x < 0)
1550 pix_x = 0;
1551 else if (pix_x > FRAME_TOTAL_COLS (f))
1552 pix_x = FRAME_TOTAL_COLS (f);
1554 if (pix_y < 0)
1555 pix_y = 0;
1556 else if (pix_y > FRAME_LINES (f))
1557 pix_y = FRAME_LINES (f);
1560 #endif
1562 *x = pix_x;
1563 *y = pix_y;
1567 /* Given HPOS/VPOS in the current matrix of W, return corresponding
1568 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
1569 can't tell the positions because W's display is not up to date,
1570 return 0. */
1573 glyph_to_pixel_coords (w, hpos, vpos, frame_x, frame_y)
1574 struct window *w;
1575 int hpos, vpos;
1576 int *frame_x, *frame_y;
1578 #ifdef HAVE_WINDOW_SYSTEM
1579 if (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w))))
1581 int success_p;
1583 xassert (hpos >= 0 && hpos < w->current_matrix->matrix_w);
1584 xassert (vpos >= 0 && vpos < w->current_matrix->matrix_h);
1586 if (display_completed)
1588 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
1589 struct glyph *glyph = row->glyphs[TEXT_AREA];
1590 struct glyph *end = glyph + min (hpos, row->used[TEXT_AREA]);
1592 hpos = row->x;
1593 vpos = row->y;
1594 while (glyph < end)
1596 hpos += glyph->pixel_width;
1597 ++glyph;
1600 /* If first glyph is partially visible, its first visible position is still 0. */
1601 if (hpos < 0)
1602 hpos = 0;
1604 success_p = 1;
1606 else
1608 hpos = vpos = 0;
1609 success_p = 0;
1612 *frame_x = WINDOW_TO_FRAME_PIXEL_X (w, hpos);
1613 *frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, vpos);
1614 return success_p;
1616 #endif
1618 *frame_x = hpos;
1619 *frame_y = vpos;
1620 return 1;
1624 #ifdef HAVE_WINDOW_SYSTEM
1626 /* Find the glyph under window-relative coordinates X/Y in window W.
1627 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1628 strings. Return in *HPOS and *VPOS the row and column number of
1629 the glyph found. Return in *AREA the glyph area containing X.
1630 Value is a pointer to the glyph found or null if X/Y is not on
1631 text, or we can't tell because W's current matrix is not up to
1632 date. */
1634 static struct glyph *
1635 x_y_to_hpos_vpos (w, x, y, hpos, vpos, dx, dy, area)
1636 struct window *w;
1637 int x, y;
1638 int *hpos, *vpos, *dx, *dy, *area;
1640 struct glyph *glyph, *end;
1641 struct glyph_row *row = NULL;
1642 int x0, i;
1644 /* Find row containing Y. Give up if some row is not enabled. */
1645 for (i = 0; i < w->current_matrix->nrows; ++i)
1647 row = MATRIX_ROW (w->current_matrix, i);
1648 if (!row->enabled_p)
1649 return NULL;
1650 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1651 break;
1654 *vpos = i;
1655 *hpos = 0;
1657 /* Give up if Y is not in the window. */
1658 if (i == w->current_matrix->nrows)
1659 return NULL;
1661 /* Get the glyph area containing X. */
1662 if (w->pseudo_window_p)
1664 *area = TEXT_AREA;
1665 x0 = 0;
1667 else
1669 if (x < window_box_left_offset (w, TEXT_AREA))
1671 *area = LEFT_MARGIN_AREA;
1672 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
1674 else if (x < window_box_right_offset (w, TEXT_AREA))
1676 *area = TEXT_AREA;
1677 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
1679 else
1681 *area = RIGHT_MARGIN_AREA;
1682 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
1686 /* Find glyph containing X. */
1687 glyph = row->glyphs[*area];
1688 end = glyph + row->used[*area];
1689 x -= x0;
1690 while (glyph < end && x >= glyph->pixel_width)
1692 x -= glyph->pixel_width;
1693 ++glyph;
1696 if (glyph == end)
1697 return NULL;
1699 if (dx)
1701 *dx = x;
1702 *dy = y - (row->y + row->ascent - glyph->ascent);
1705 *hpos = glyph - row->glyphs[*area];
1706 return glyph;
1710 /* EXPORT:
1711 Convert frame-relative x/y to coordinates relative to window W.
1712 Takes pseudo-windows into account. */
1714 void
1715 frame_to_window_pixel_xy (w, x, y)
1716 struct window *w;
1717 int *x, *y;
1719 if (w->pseudo_window_p)
1721 /* A pseudo-window is always full-width, and starts at the
1722 left edge of the frame, plus a frame border. */
1723 struct frame *f = XFRAME (w->frame);
1724 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
1725 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1727 else
1729 *x -= WINDOW_LEFT_EDGE_X (w);
1730 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1734 /* EXPORT:
1735 Return in *R the clipping rectangle for glyph string S. */
1737 void
1738 get_glyph_string_clip_rect (s, nr)
1739 struct glyph_string *s;
1740 NativeRectangle *nr;
1742 XRectangle r;
1744 if (s->row->full_width_p)
1746 /* Draw full-width. X coordinates are relative to S->w->left_col. */
1747 r.x = WINDOW_LEFT_EDGE_X (s->w);
1748 r.width = WINDOW_TOTAL_WIDTH (s->w);
1750 /* Unless displaying a mode or menu bar line, which are always
1751 fully visible, clip to the visible part of the row. */
1752 if (s->w->pseudo_window_p)
1753 r.height = s->row->visible_height;
1754 else
1755 r.height = s->height;
1757 else
1759 /* This is a text line that may be partially visible. */
1760 r.x = window_box_left (s->w, s->area);
1761 r.width = window_box_width (s->w, s->area);
1762 r.height = s->row->visible_height;
1765 /* If S draws overlapping rows, it's sufficient to use the top and
1766 bottom of the window for clipping because this glyph string
1767 intentionally draws over other lines. */
1768 if (s->for_overlaps_p)
1770 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1771 r.height = window_text_bottom_y (s->w) - r.y;
1773 else
1775 /* Don't use S->y for clipping because it doesn't take partially
1776 visible lines into account. For example, it can be negative for
1777 partially visible lines at the top of a window. */
1778 if (!s->row->full_width_p
1779 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
1780 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1781 else
1782 r.y = max (0, s->row->y);
1784 /* If drawing a tool-bar window, draw it over the internal border
1785 at the top of the window. */
1786 if (s->w == XWINDOW (s->f->tool_bar_window))
1787 r.y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
1790 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
1792 /* If drawing the cursor, don't let glyph draw outside its
1793 advertised boundaries. Cleartype does this under some circumstances. */
1794 if (s->hl == DRAW_CURSOR)
1796 struct glyph *glyph = s->first_glyph;
1797 int height;
1799 if (s->x > r.x)
1801 r.width -= s->x - r.x;
1802 r.x = s->x;
1804 r.width = min (r.width, glyph->pixel_width);
1806 /* Don't draw cursor glyph taller than our actual glyph. */
1807 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
1808 if (height < r.height)
1810 int max_y = r.y + r.height;
1811 r.y = min (max_y, s->ybase + glyph->descent - height);
1812 r.height = min (max_y - r.y, height);
1816 #ifdef CONVERT_FROM_XRECT
1817 CONVERT_FROM_XRECT (r, *nr);
1818 #else
1819 *nr = r;
1820 #endif
1823 #endif /* HAVE_WINDOW_SYSTEM */
1826 /***********************************************************************
1827 Lisp form evaluation
1828 ***********************************************************************/
1830 /* Error handler for safe_eval and safe_call. */
1832 static Lisp_Object
1833 safe_eval_handler (arg)
1834 Lisp_Object arg;
1836 add_to_log ("Error during redisplay: %s", arg, Qnil);
1837 return Qnil;
1841 /* Evaluate SEXPR and return the result, or nil if something went
1842 wrong. Prevent redisplay during the evaluation. */
1844 Lisp_Object
1845 safe_eval (sexpr)
1846 Lisp_Object sexpr;
1848 Lisp_Object val;
1850 if (inhibit_eval_during_redisplay)
1851 val = Qnil;
1852 else
1854 int count = SPECPDL_INDEX ();
1855 struct gcpro gcpro1;
1857 GCPRO1 (sexpr);
1858 specbind (Qinhibit_redisplay, Qt);
1859 /* Use Qt to ensure debugger does not run,
1860 so there is no possibility of wanting to redisplay. */
1861 val = internal_condition_case_1 (Feval, sexpr, Qt,
1862 safe_eval_handler);
1863 UNGCPRO;
1864 val = unbind_to (count, val);
1867 return val;
1871 /* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1].
1872 Return the result, or nil if something went wrong. Prevent
1873 redisplay during the evaluation. */
1875 Lisp_Object
1876 safe_call (nargs, args)
1877 int nargs;
1878 Lisp_Object *args;
1880 Lisp_Object val;
1882 if (inhibit_eval_during_redisplay)
1883 val = Qnil;
1884 else
1886 int count = SPECPDL_INDEX ();
1887 struct gcpro gcpro1;
1889 GCPRO1 (args[0]);
1890 gcpro1.nvars = nargs;
1891 specbind (Qinhibit_redisplay, Qt);
1892 /* Use Qt to ensure debugger does not run,
1893 so there is no possibility of wanting to redisplay. */
1894 val = internal_condition_case_2 (Ffuncall, nargs, args, Qt,
1895 safe_eval_handler);
1896 UNGCPRO;
1897 val = unbind_to (count, val);
1900 return val;
1904 /* Call function FN with one argument ARG.
1905 Return the result, or nil if something went wrong. */
1907 Lisp_Object
1908 safe_call1 (fn, arg)
1909 Lisp_Object fn, arg;
1911 Lisp_Object args[2];
1912 args[0] = fn;
1913 args[1] = arg;
1914 return safe_call (2, args);
1919 /***********************************************************************
1920 Debugging
1921 ***********************************************************************/
1923 #if 0
1925 /* Define CHECK_IT to perform sanity checks on iterators.
1926 This is for debugging. It is too slow to do unconditionally. */
1928 static void
1929 check_it (it)
1930 struct it *it;
1932 if (it->method == next_element_from_string)
1934 xassert (STRINGP (it->string));
1935 xassert (IT_STRING_CHARPOS (*it) >= 0);
1937 else
1939 xassert (IT_STRING_CHARPOS (*it) < 0);
1940 if (it->method == next_element_from_buffer)
1942 /* Check that character and byte positions agree. */
1943 xassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
1947 if (it->dpvec)
1948 xassert (it->current.dpvec_index >= 0);
1949 else
1950 xassert (it->current.dpvec_index < 0);
1953 #define CHECK_IT(IT) check_it ((IT))
1955 #else /* not 0 */
1957 #define CHECK_IT(IT) (void) 0
1959 #endif /* not 0 */
1962 #if GLYPH_DEBUG
1964 /* Check that the window end of window W is what we expect it
1965 to be---the last row in the current matrix displaying text. */
1967 static void
1968 check_window_end (w)
1969 struct window *w;
1971 if (!MINI_WINDOW_P (w)
1972 && !NILP (w->window_end_valid))
1974 struct glyph_row *row;
1975 xassert ((row = MATRIX_ROW (w->current_matrix,
1976 XFASTINT (w->window_end_vpos)),
1977 !row->enabled_p
1978 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
1979 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
1983 #define CHECK_WINDOW_END(W) check_window_end ((W))
1985 #else /* not GLYPH_DEBUG */
1987 #define CHECK_WINDOW_END(W) (void) 0
1989 #endif /* not GLYPH_DEBUG */
1993 /***********************************************************************
1994 Iterator initialization
1995 ***********************************************************************/
1997 /* Initialize IT for displaying current_buffer in window W, starting
1998 at character position CHARPOS. CHARPOS < 0 means that no buffer
1999 position is specified which is useful when the iterator is assigned
2000 a position later. BYTEPOS is the byte position corresponding to
2001 CHARPOS. BYTEPOS < 0 means compute it from CHARPOS.
2003 If ROW is not null, calls to produce_glyphs with IT as parameter
2004 will produce glyphs in that row.
2006 BASE_FACE_ID is the id of a base face to use. It must be one of
2007 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2008 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2009 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2011 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2012 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2013 will be initialized to use the corresponding mode line glyph row of
2014 the desired matrix of W. */
2016 void
2017 init_iterator (it, w, charpos, bytepos, row, base_face_id)
2018 struct it *it;
2019 struct window *w;
2020 int charpos, bytepos;
2021 struct glyph_row *row;
2022 enum face_id base_face_id;
2024 int highlight_region_p;
2026 /* Some precondition checks. */
2027 xassert (w != NULL && it != NULL);
2028 xassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
2029 && charpos <= ZV));
2031 /* If face attributes have been changed since the last redisplay,
2032 free realized faces now because they depend on face definitions
2033 that might have changed. Don't free faces while there might be
2034 desired matrices pending which reference these faces. */
2035 if (face_change_count && !inhibit_free_realized_faces)
2037 face_change_count = 0;
2038 free_all_realized_faces (Qnil);
2041 /* Use one of the mode line rows of W's desired matrix if
2042 appropriate. */
2043 if (row == NULL)
2045 if (base_face_id == MODE_LINE_FACE_ID
2046 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
2047 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
2048 else if (base_face_id == HEADER_LINE_FACE_ID)
2049 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
2052 /* Clear IT. */
2053 bzero (it, sizeof *it);
2054 it->current.overlay_string_index = -1;
2055 it->current.dpvec_index = -1;
2056 it->base_face_id = base_face_id;
2057 it->string = Qnil;
2058 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
2060 /* The window in which we iterate over current_buffer: */
2061 XSETWINDOW (it->window, w);
2062 it->w = w;
2063 it->f = XFRAME (w->frame);
2065 /* Extra space between lines (on window systems only). */
2066 if (base_face_id == DEFAULT_FACE_ID
2067 && FRAME_WINDOW_P (it->f))
2069 if (NATNUMP (current_buffer->extra_line_spacing))
2070 it->extra_line_spacing = XFASTINT (current_buffer->extra_line_spacing);
2071 else if (FLOATP (current_buffer->extra_line_spacing))
2072 it->extra_line_spacing = (XFLOAT_DATA (current_buffer->extra_line_spacing)
2073 * FRAME_LINE_HEIGHT (it->f));
2074 else if (it->f->extra_line_spacing > 0)
2075 it->extra_line_spacing = it->f->extra_line_spacing;
2078 /* If realized faces have been removed, e.g. because of face
2079 attribute changes of named faces, recompute them. When running
2080 in batch mode, the face cache of Vterminal_frame is null. If
2081 we happen to get called, make a dummy face cache. */
2082 if (noninteractive && FRAME_FACE_CACHE (it->f) == NULL)
2083 init_frame_faces (it->f);
2084 if (FRAME_FACE_CACHE (it->f)->used == 0)
2085 recompute_basic_faces (it->f);
2087 /* Current value of the `slice', `space-width', and 'height' properties. */
2088 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
2089 it->space_width = Qnil;
2090 it->font_height = Qnil;
2091 it->override_ascent = -1;
2093 /* Are control characters displayed as `^C'? */
2094 it->ctl_arrow_p = !NILP (current_buffer->ctl_arrow);
2096 /* -1 means everything between a CR and the following line end
2097 is invisible. >0 means lines indented more than this value are
2098 invisible. */
2099 it->selective = (INTEGERP (current_buffer->selective_display)
2100 ? XFASTINT (current_buffer->selective_display)
2101 : (!NILP (current_buffer->selective_display)
2102 ? -1 : 0));
2103 it->selective_display_ellipsis_p
2104 = !NILP (current_buffer->selective_display_ellipses);
2106 /* Display table to use. */
2107 it->dp = window_display_table (w);
2109 /* Are multibyte characters enabled in current_buffer? */
2110 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
2112 /* Non-zero if we should highlight the region. */
2113 highlight_region_p
2114 = (!NILP (Vtransient_mark_mode)
2115 && !NILP (current_buffer->mark_active)
2116 && XMARKER (current_buffer->mark)->buffer != 0);
2118 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
2119 start and end of a visible region in window IT->w. Set both to
2120 -1 to indicate no region. */
2121 if (highlight_region_p
2122 /* Maybe highlight only in selected window. */
2123 && (/* Either show region everywhere. */
2124 highlight_nonselected_windows
2125 /* Or show region in the selected window. */
2126 || w == XWINDOW (selected_window)
2127 /* Or show the region if we are in the mini-buffer and W is
2128 the window the mini-buffer refers to. */
2129 || (MINI_WINDOW_P (XWINDOW (selected_window))
2130 && WINDOWP (minibuf_selected_window)
2131 && w == XWINDOW (minibuf_selected_window))))
2133 int charpos = marker_position (current_buffer->mark);
2134 it->region_beg_charpos = min (PT, charpos);
2135 it->region_end_charpos = max (PT, charpos);
2137 else
2138 it->region_beg_charpos = it->region_end_charpos = -1;
2140 /* Get the position at which the redisplay_end_trigger hook should
2141 be run, if it is to be run at all. */
2142 if (MARKERP (w->redisplay_end_trigger)
2143 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2144 it->redisplay_end_trigger_charpos
2145 = marker_position (w->redisplay_end_trigger);
2146 else if (INTEGERP (w->redisplay_end_trigger))
2147 it->redisplay_end_trigger_charpos = XINT (w->redisplay_end_trigger);
2149 /* Correct bogus values of tab_width. */
2150 it->tab_width = XINT (current_buffer->tab_width);
2151 if (it->tab_width <= 0 || it->tab_width > 1000)
2152 it->tab_width = 8;
2154 /* Are lines in the display truncated? */
2155 it->truncate_lines_p
2156 = (base_face_id != DEFAULT_FACE_ID
2157 || XINT (it->w->hscroll)
2158 || (truncate_partial_width_windows
2159 && !WINDOW_FULL_WIDTH_P (it->w))
2160 || !NILP (current_buffer->truncate_lines));
2162 /* Get dimensions of truncation and continuation glyphs. These are
2163 displayed as fringe bitmaps under X, so we don't need them for such
2164 frames. */
2165 if (!FRAME_WINDOW_P (it->f))
2167 if (it->truncate_lines_p)
2169 /* We will need the truncation glyph. */
2170 xassert (it->glyph_row == NULL);
2171 produce_special_glyphs (it, IT_TRUNCATION);
2172 it->truncation_pixel_width = it->pixel_width;
2174 else
2176 /* We will need the continuation glyph. */
2177 xassert (it->glyph_row == NULL);
2178 produce_special_glyphs (it, IT_CONTINUATION);
2179 it->continuation_pixel_width = it->pixel_width;
2182 /* Reset these values to zero because the produce_special_glyphs
2183 above has changed them. */
2184 it->pixel_width = it->ascent = it->descent = 0;
2185 it->phys_ascent = it->phys_descent = 0;
2188 /* Set this after getting the dimensions of truncation and
2189 continuation glyphs, so that we don't produce glyphs when calling
2190 produce_special_glyphs, above. */
2191 it->glyph_row = row;
2192 it->area = TEXT_AREA;
2194 /* Get the dimensions of the display area. The display area
2195 consists of the visible window area plus a horizontally scrolled
2196 part to the left of the window. All x-values are relative to the
2197 start of this total display area. */
2198 if (base_face_id != DEFAULT_FACE_ID)
2200 /* Mode lines, menu bar in terminal frames. */
2201 it->first_visible_x = 0;
2202 it->last_visible_x = WINDOW_TOTAL_WIDTH (w);
2204 else
2206 it->first_visible_x
2207 = XFASTINT (it->w->hscroll) * FRAME_COLUMN_WIDTH (it->f);
2208 it->last_visible_x = (it->first_visible_x
2209 + window_box_width (w, TEXT_AREA));
2211 /* If we truncate lines, leave room for the truncator glyph(s) at
2212 the right margin. Otherwise, leave room for the continuation
2213 glyph(s). Truncation and continuation glyphs are not inserted
2214 for window-based redisplay. */
2215 if (!FRAME_WINDOW_P (it->f))
2217 if (it->truncate_lines_p)
2218 it->last_visible_x -= it->truncation_pixel_width;
2219 else
2220 it->last_visible_x -= it->continuation_pixel_width;
2223 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
2224 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
2227 /* Leave room for a border glyph. */
2228 if (!FRAME_WINDOW_P (it->f)
2229 && !WINDOW_RIGHTMOST_P (it->w))
2230 it->last_visible_x -= 1;
2232 it->last_visible_y = window_text_bottom_y (w);
2234 /* For mode lines and alike, arrange for the first glyph having a
2235 left box line if the face specifies a box. */
2236 if (base_face_id != DEFAULT_FACE_ID)
2238 struct face *face;
2240 it->face_id = base_face_id;
2242 /* If we have a boxed mode line, make the first character appear
2243 with a left box line. */
2244 face = FACE_FROM_ID (it->f, base_face_id);
2245 if (face->box != FACE_NO_BOX)
2246 it->start_of_box_run_p = 1;
2249 /* If a buffer position was specified, set the iterator there,
2250 getting overlays and face properties from that position. */
2251 if (charpos >= BUF_BEG (current_buffer))
2253 it->end_charpos = ZV;
2254 it->face_id = -1;
2255 IT_CHARPOS (*it) = charpos;
2257 /* Compute byte position if not specified. */
2258 if (bytepos < charpos)
2259 IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos);
2260 else
2261 IT_BYTEPOS (*it) = bytepos;
2263 it->start = it->current;
2265 /* Compute faces etc. */
2266 reseat (it, it->current.pos, 1);
2269 CHECK_IT (it);
2273 /* Initialize IT for the display of window W with window start POS. */
2275 void
2276 start_display (it, w, pos)
2277 struct it *it;
2278 struct window *w;
2279 struct text_pos pos;
2281 struct glyph_row *row;
2282 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
2284 row = w->desired_matrix->rows + first_vpos;
2285 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
2286 it->first_vpos = first_vpos;
2288 if (!it->truncate_lines_p)
2290 int start_at_line_beg_p;
2291 int first_y = it->current_y;
2293 /* If window start is not at a line start, skip forward to POS to
2294 get the correct continuation lines width. */
2295 start_at_line_beg_p = (CHARPOS (pos) == BEGV
2296 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
2297 if (!start_at_line_beg_p)
2299 int new_x;
2301 reseat_at_previous_visible_line_start (it);
2302 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
2304 new_x = it->current_x + it->pixel_width;
2306 /* If lines are continued, this line may end in the middle
2307 of a multi-glyph character (e.g. a control character
2308 displayed as \003, or in the middle of an overlay
2309 string). In this case move_it_to above will not have
2310 taken us to the start of the continuation line but to the
2311 end of the continued line. */
2312 if (it->current_x > 0
2313 && !it->truncate_lines_p /* Lines are continued. */
2314 && (/* And glyph doesn't fit on the line. */
2315 new_x > it->last_visible_x
2316 /* Or it fits exactly and we're on a window
2317 system frame. */
2318 || (new_x == it->last_visible_x
2319 && FRAME_WINDOW_P (it->f))))
2321 if (it->current.dpvec_index >= 0
2322 || it->current.overlay_string_index >= 0)
2324 set_iterator_to_next (it, 1);
2325 move_it_in_display_line_to (it, -1, -1, 0);
2328 it->continuation_lines_width += it->current_x;
2331 /* We're starting a new display line, not affected by the
2332 height of the continued line, so clear the appropriate
2333 fields in the iterator structure. */
2334 it->max_ascent = it->max_descent = 0;
2335 it->max_phys_ascent = it->max_phys_descent = 0;
2337 it->current_y = first_y;
2338 it->vpos = 0;
2339 it->current_x = it->hpos = 0;
2343 #if 0 /* Don't assert the following because start_display is sometimes
2344 called intentionally with a window start that is not at a
2345 line start. Please leave this code in as a comment. */
2347 /* Window start should be on a line start, now. */
2348 xassert (it->continuation_lines_width
2349 || IT_CHARPOS (it) == BEGV
2350 || FETCH_BYTE (IT_BYTEPOS (it) - 1) == '\n');
2351 #endif /* 0 */
2355 /* Return 1 if POS is a position in ellipses displayed for invisible
2356 text. W is the window we display, for text property lookup. */
2358 static int
2359 in_ellipses_for_invisible_text_p (pos, w)
2360 struct display_pos *pos;
2361 struct window *w;
2363 Lisp_Object prop, window;
2364 int ellipses_p = 0;
2365 int charpos = CHARPOS (pos->pos);
2367 /* If POS specifies a position in a display vector, this might
2368 be for an ellipsis displayed for invisible text. We won't
2369 get the iterator set up for delivering that ellipsis unless
2370 we make sure that it gets aware of the invisible text. */
2371 if (pos->dpvec_index >= 0
2372 && pos->overlay_string_index < 0
2373 && CHARPOS (pos->string_pos) < 0
2374 && charpos > BEGV
2375 && (XSETWINDOW (window, w),
2376 prop = Fget_char_property (make_number (charpos),
2377 Qinvisible, window),
2378 !TEXT_PROP_MEANS_INVISIBLE (prop)))
2380 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
2381 window);
2382 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
2385 return ellipses_p;
2389 /* Initialize IT for stepping through current_buffer in window W,
2390 starting at position POS that includes overlay string and display
2391 vector/ control character translation position information. Value
2392 is zero if there are overlay strings with newlines at POS. */
2394 static int
2395 init_from_display_pos (it, w, pos)
2396 struct it *it;
2397 struct window *w;
2398 struct display_pos *pos;
2400 int charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
2401 int i, overlay_strings_with_newlines = 0;
2403 /* If POS specifies a position in a display vector, this might
2404 be for an ellipsis displayed for invisible text. We won't
2405 get the iterator set up for delivering that ellipsis unless
2406 we make sure that it gets aware of the invisible text. */
2407 if (in_ellipses_for_invisible_text_p (pos, w))
2409 --charpos;
2410 bytepos = 0;
2413 /* Keep in mind: the call to reseat in init_iterator skips invisible
2414 text, so we might end up at a position different from POS. This
2415 is only a problem when POS is a row start after a newline and an
2416 overlay starts there with an after-string, and the overlay has an
2417 invisible property. Since we don't skip invisible text in
2418 display_line and elsewhere immediately after consuming the
2419 newline before the row start, such a POS will not be in a string,
2420 but the call to init_iterator below will move us to the
2421 after-string. */
2422 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
2424 for (i = 0; i < it->n_overlay_strings; ++i)
2426 const char *s = SDATA (it->overlay_strings[i]);
2427 const char *e = s + SBYTES (it->overlay_strings[i]);
2429 while (s < e && *s != '\n')
2430 ++s;
2432 if (s < e)
2434 overlay_strings_with_newlines = 1;
2435 break;
2439 /* If position is within an overlay string, set up IT to the right
2440 overlay string. */
2441 if (pos->overlay_string_index >= 0)
2443 int relative_index;
2445 /* If the first overlay string happens to have a `display'
2446 property for an image, the iterator will be set up for that
2447 image, and we have to undo that setup first before we can
2448 correct the overlay string index. */
2449 if (it->method == next_element_from_image)
2450 pop_it (it);
2452 /* We already have the first chunk of overlay strings in
2453 IT->overlay_strings. Load more until the one for
2454 pos->overlay_string_index is in IT->overlay_strings. */
2455 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
2457 int n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
2458 it->current.overlay_string_index = 0;
2459 while (n--)
2461 load_overlay_strings (it, 0);
2462 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
2466 it->current.overlay_string_index = pos->overlay_string_index;
2467 relative_index = (it->current.overlay_string_index
2468 % OVERLAY_STRING_CHUNK_SIZE);
2469 it->string = it->overlay_strings[relative_index];
2470 xassert (STRINGP (it->string));
2471 it->current.string_pos = pos->string_pos;
2472 it->method = next_element_from_string;
2475 #if 0 /* This is bogus because POS not having an overlay string
2476 position does not mean it's after the string. Example: A
2477 line starting with a before-string and initialization of IT
2478 to the previous row's end position. */
2479 else if (it->current.overlay_string_index >= 0)
2481 /* If POS says we're already after an overlay string ending at
2482 POS, make sure to pop the iterator because it will be in
2483 front of that overlay string. When POS is ZV, we've thereby
2484 also ``processed'' overlay strings at ZV. */
2485 while (it->sp)
2486 pop_it (it);
2487 it->current.overlay_string_index = -1;
2488 it->method = next_element_from_buffer;
2489 if (CHARPOS (pos->pos) == ZV)
2490 it->overlay_strings_at_end_processed_p = 1;
2492 #endif /* 0 */
2494 if (CHARPOS (pos->string_pos) >= 0)
2496 /* Recorded position is not in an overlay string, but in another
2497 string. This can only be a string from a `display' property.
2498 IT should already be filled with that string. */
2499 it->current.string_pos = pos->string_pos;
2500 xassert (STRINGP (it->string));
2503 /* Restore position in display vector translations, control
2504 character translations or ellipses. */
2505 if (pos->dpvec_index >= 0)
2507 if (it->dpvec == NULL)
2508 get_next_display_element (it);
2509 xassert (it->dpvec && it->current.dpvec_index == 0);
2510 it->current.dpvec_index = pos->dpvec_index;
2513 CHECK_IT (it);
2514 return !overlay_strings_with_newlines;
2518 /* Initialize IT for stepping through current_buffer in window W
2519 starting at ROW->start. */
2521 static void
2522 init_to_row_start (it, w, row)
2523 struct it *it;
2524 struct window *w;
2525 struct glyph_row *row;
2527 init_from_display_pos (it, w, &row->start);
2528 it->start = row->start;
2529 it->continuation_lines_width = row->continuation_lines_width;
2530 CHECK_IT (it);
2534 /* Initialize IT for stepping through current_buffer in window W
2535 starting in the line following ROW, i.e. starting at ROW->end.
2536 Value is zero if there are overlay strings with newlines at ROW's
2537 end position. */
2539 static int
2540 init_to_row_end (it, w, row)
2541 struct it *it;
2542 struct window *w;
2543 struct glyph_row *row;
2545 int success = 0;
2547 if (init_from_display_pos (it, w, &row->end))
2549 if (row->continued_p)
2550 it->continuation_lines_width
2551 = row->continuation_lines_width + row->pixel_width;
2552 CHECK_IT (it);
2553 success = 1;
2556 return success;
2562 /***********************************************************************
2563 Text properties
2564 ***********************************************************************/
2566 /* Called when IT reaches IT->stop_charpos. Handle text property and
2567 overlay changes. Set IT->stop_charpos to the next position where
2568 to stop. */
2570 static void
2571 handle_stop (it)
2572 struct it *it;
2574 enum prop_handled handled;
2575 int handle_overlay_change_p = 1;
2576 struct props *p;
2578 it->dpvec = NULL;
2579 it->current.dpvec_index = -1;
2583 handled = HANDLED_NORMALLY;
2585 /* Call text property handlers. */
2586 for (p = it_props; p->handler; ++p)
2588 handled = p->handler (it);
2590 if (handled == HANDLED_RECOMPUTE_PROPS)
2591 break;
2592 else if (handled == HANDLED_RETURN)
2593 return;
2594 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
2595 handle_overlay_change_p = 0;
2598 if (handled != HANDLED_RECOMPUTE_PROPS)
2600 /* Don't check for overlay strings below when set to deliver
2601 characters from a display vector. */
2602 if (it->method == next_element_from_display_vector)
2603 handle_overlay_change_p = 0;
2605 /* Handle overlay changes. */
2606 if (handle_overlay_change_p)
2607 handled = handle_overlay_change (it);
2609 /* Determine where to stop next. */
2610 if (handled == HANDLED_NORMALLY)
2611 compute_stop_pos (it);
2614 while (handled == HANDLED_RECOMPUTE_PROPS);
2618 /* Compute IT->stop_charpos from text property and overlay change
2619 information for IT's current position. */
2621 static void
2622 compute_stop_pos (it)
2623 struct it *it;
2625 register INTERVAL iv, next_iv;
2626 Lisp_Object object, limit, position;
2628 /* If nowhere else, stop at the end. */
2629 it->stop_charpos = it->end_charpos;
2631 if (STRINGP (it->string))
2633 /* Strings are usually short, so don't limit the search for
2634 properties. */
2635 object = it->string;
2636 limit = Qnil;
2637 position = make_number (IT_STRING_CHARPOS (*it));
2639 else
2641 int charpos;
2643 /* If next overlay change is in front of the current stop pos
2644 (which is IT->end_charpos), stop there. Note: value of
2645 next_overlay_change is point-max if no overlay change
2646 follows. */
2647 charpos = next_overlay_change (IT_CHARPOS (*it));
2648 if (charpos < it->stop_charpos)
2649 it->stop_charpos = charpos;
2651 /* If showing the region, we have to stop at the region
2652 start or end because the face might change there. */
2653 if (it->region_beg_charpos > 0)
2655 if (IT_CHARPOS (*it) < it->region_beg_charpos)
2656 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
2657 else if (IT_CHARPOS (*it) < it->region_end_charpos)
2658 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
2661 /* Set up variables for computing the stop position from text
2662 property changes. */
2663 XSETBUFFER (object, current_buffer);
2664 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
2665 position = make_number (IT_CHARPOS (*it));
2669 /* Get the interval containing IT's position. Value is a null
2670 interval if there isn't such an interval. */
2671 iv = validate_interval_range (object, &position, &position, 0);
2672 if (!NULL_INTERVAL_P (iv))
2674 Lisp_Object values_here[LAST_PROP_IDX];
2675 struct props *p;
2677 /* Get properties here. */
2678 for (p = it_props; p->handler; ++p)
2679 values_here[p->idx] = textget (iv->plist, *p->name);
2681 /* Look for an interval following iv that has different
2682 properties. */
2683 for (next_iv = next_interval (iv);
2684 (!NULL_INTERVAL_P (next_iv)
2685 && (NILP (limit)
2686 || XFASTINT (limit) > next_iv->position));
2687 next_iv = next_interval (next_iv))
2689 for (p = it_props; p->handler; ++p)
2691 Lisp_Object new_value;
2693 new_value = textget (next_iv->plist, *p->name);
2694 if (!EQ (values_here[p->idx], new_value))
2695 break;
2698 if (p->handler)
2699 break;
2702 if (!NULL_INTERVAL_P (next_iv))
2704 if (INTEGERP (limit)
2705 && next_iv->position >= XFASTINT (limit))
2706 /* No text property change up to limit. */
2707 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
2708 else
2709 /* Text properties change in next_iv. */
2710 it->stop_charpos = min (it->stop_charpos, next_iv->position);
2714 xassert (STRINGP (it->string)
2715 || (it->stop_charpos >= BEGV
2716 && it->stop_charpos >= IT_CHARPOS (*it)));
2720 /* Return the position of the next overlay change after POS in
2721 current_buffer. Value is point-max if no overlay change
2722 follows. This is like `next-overlay-change' but doesn't use
2723 xmalloc. */
2725 static int
2726 next_overlay_change (pos)
2727 int pos;
2729 int noverlays;
2730 int endpos;
2731 Lisp_Object *overlays;
2732 int i;
2734 /* Get all overlays at the given position. */
2735 GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, 1);
2737 /* If any of these overlays ends before endpos,
2738 use its ending point instead. */
2739 for (i = 0; i < noverlays; ++i)
2741 Lisp_Object oend;
2742 int oendpos;
2744 oend = OVERLAY_END (overlays[i]);
2745 oendpos = OVERLAY_POSITION (oend);
2746 endpos = min (endpos, oendpos);
2749 return endpos;
2754 /***********************************************************************
2755 Fontification
2756 ***********************************************************************/
2758 /* Handle changes in the `fontified' property of the current buffer by
2759 calling hook functions from Qfontification_functions to fontify
2760 regions of text. */
2762 static enum prop_handled
2763 handle_fontified_prop (it)
2764 struct it *it;
2766 Lisp_Object prop, pos;
2767 enum prop_handled handled = HANDLED_NORMALLY;
2769 /* Get the value of the `fontified' property at IT's current buffer
2770 position. (The `fontified' property doesn't have a special
2771 meaning in strings.) If the value is nil, call functions from
2772 Qfontification_functions. */
2773 if (!STRINGP (it->string)
2774 && it->s == NULL
2775 && !NILP (Vfontification_functions)
2776 && !NILP (Vrun_hooks)
2777 && (pos = make_number (IT_CHARPOS (*it)),
2778 prop = Fget_char_property (pos, Qfontified, Qnil),
2779 NILP (prop)))
2781 int count = SPECPDL_INDEX ();
2782 Lisp_Object val;
2784 val = Vfontification_functions;
2785 specbind (Qfontification_functions, Qnil);
2787 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
2788 safe_call1 (val, pos);
2789 else
2791 Lisp_Object globals, fn;
2792 struct gcpro gcpro1, gcpro2;
2794 globals = Qnil;
2795 GCPRO2 (val, globals);
2797 for (; CONSP (val); val = XCDR (val))
2799 fn = XCAR (val);
2801 if (EQ (fn, Qt))
2803 /* A value of t indicates this hook has a local
2804 binding; it means to run the global binding too.
2805 In a global value, t should not occur. If it
2806 does, we must ignore it to avoid an endless
2807 loop. */
2808 for (globals = Fdefault_value (Qfontification_functions);
2809 CONSP (globals);
2810 globals = XCDR (globals))
2812 fn = XCAR (globals);
2813 if (!EQ (fn, Qt))
2814 safe_call1 (fn, pos);
2817 else
2818 safe_call1 (fn, pos);
2821 UNGCPRO;
2824 unbind_to (count, Qnil);
2826 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
2827 something. This avoids an endless loop if they failed to
2828 fontify the text for which reason ever. */
2829 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
2830 handled = HANDLED_RECOMPUTE_PROPS;
2833 return handled;
2838 /***********************************************************************
2839 Faces
2840 ***********************************************************************/
2842 /* Set up iterator IT from face properties at its current position.
2843 Called from handle_stop. */
2845 static enum prop_handled
2846 handle_face_prop (it)
2847 struct it *it;
2849 int new_face_id, next_stop;
2851 if (!STRINGP (it->string))
2853 new_face_id
2854 = face_at_buffer_position (it->w,
2855 IT_CHARPOS (*it),
2856 it->region_beg_charpos,
2857 it->region_end_charpos,
2858 &next_stop,
2859 (IT_CHARPOS (*it)
2860 + TEXT_PROP_DISTANCE_LIMIT),
2863 /* Is this a start of a run of characters with box face?
2864 Caveat: this can be called for a freshly initialized
2865 iterator; face_id is -1 in this case. We know that the new
2866 face will not change until limit, i.e. if the new face has a
2867 box, all characters up to limit will have one. But, as
2868 usual, we don't know whether limit is really the end. */
2869 if (new_face_id != it->face_id)
2871 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
2873 /* If new face has a box but old face has not, this is
2874 the start of a run of characters with box, i.e. it has
2875 a shadow on the left side. The value of face_id of the
2876 iterator will be -1 if this is the initial call that gets
2877 the face. In this case, we have to look in front of IT's
2878 position and see whether there is a face != new_face_id. */
2879 it->start_of_box_run_p
2880 = (new_face->box != FACE_NO_BOX
2881 && (it->face_id >= 0
2882 || IT_CHARPOS (*it) == BEG
2883 || new_face_id != face_before_it_pos (it)));
2884 it->face_box_p = new_face->box != FACE_NO_BOX;
2887 else
2889 int base_face_id, bufpos;
2891 if (it->current.overlay_string_index >= 0)
2892 bufpos = IT_CHARPOS (*it);
2893 else
2894 bufpos = 0;
2896 /* For strings from a buffer, i.e. overlay strings or strings
2897 from a `display' property, use the face at IT's current
2898 buffer position as the base face to merge with, so that
2899 overlay strings appear in the same face as surrounding
2900 text, unless they specify their own faces. */
2901 base_face_id = underlying_face_id (it);
2903 new_face_id = face_at_string_position (it->w,
2904 it->string,
2905 IT_STRING_CHARPOS (*it),
2906 bufpos,
2907 it->region_beg_charpos,
2908 it->region_end_charpos,
2909 &next_stop,
2910 base_face_id, 0);
2912 #if 0 /* This shouldn't be neccessary. Let's check it. */
2913 /* If IT is used to display a mode line we would really like to
2914 use the mode line face instead of the frame's default face. */
2915 if (it->glyph_row == MATRIX_MODE_LINE_ROW (it->w->desired_matrix)
2916 && new_face_id == DEFAULT_FACE_ID)
2917 new_face_id = CURRENT_MODE_LINE_FACE_ID (it->w);
2918 #endif
2920 /* Is this a start of a run of characters with box? Caveat:
2921 this can be called for a freshly allocated iterator; face_id
2922 is -1 is this case. We know that the new face will not
2923 change until the next check pos, i.e. if the new face has a
2924 box, all characters up to that position will have a
2925 box. But, as usual, we don't know whether that position
2926 is really the end. */
2927 if (new_face_id != it->face_id)
2929 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
2930 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
2932 /* If new face has a box but old face hasn't, this is the
2933 start of a run of characters with box, i.e. it has a
2934 shadow on the left side. */
2935 it->start_of_box_run_p
2936 = new_face->box && (old_face == NULL || !old_face->box);
2937 it->face_box_p = new_face->box != FACE_NO_BOX;
2941 it->face_id = new_face_id;
2942 return HANDLED_NORMALLY;
2946 /* Return the ID of the face ``underlying'' IT's current position,
2947 which is in a string. If the iterator is associated with a
2948 buffer, return the face at IT's current buffer position.
2949 Otherwise, use the iterator's base_face_id. */
2951 static int
2952 underlying_face_id (it)
2953 struct it *it;
2955 int face_id = it->base_face_id, i;
2957 xassert (STRINGP (it->string));
2959 for (i = it->sp - 1; i >= 0; --i)
2960 if (NILP (it->stack[i].string))
2961 face_id = it->stack[i].face_id;
2963 return face_id;
2967 /* Compute the face one character before or after the current position
2968 of IT. BEFORE_P non-zero means get the face in front of IT's
2969 position. Value is the id of the face. */
2971 static int
2972 face_before_or_after_it_pos (it, before_p)
2973 struct it *it;
2974 int before_p;
2976 int face_id, limit;
2977 int next_check_charpos;
2978 struct text_pos pos;
2980 xassert (it->s == NULL);
2982 if (STRINGP (it->string))
2984 int bufpos, base_face_id;
2986 /* No face change past the end of the string (for the case
2987 we are padding with spaces). No face change before the
2988 string start. */
2989 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
2990 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
2991 return it->face_id;
2993 /* Set pos to the position before or after IT's current position. */
2994 if (before_p)
2995 pos = string_pos (IT_STRING_CHARPOS (*it) - 1, it->string);
2996 else
2997 /* For composition, we must check the character after the
2998 composition. */
2999 pos = (it->what == IT_COMPOSITION
3000 ? string_pos (IT_STRING_CHARPOS (*it) + it->cmp_len, it->string)
3001 : string_pos (IT_STRING_CHARPOS (*it) + 1, it->string));
3003 if (it->current.overlay_string_index >= 0)
3004 bufpos = IT_CHARPOS (*it);
3005 else
3006 bufpos = 0;
3008 base_face_id = underlying_face_id (it);
3010 /* Get the face for ASCII, or unibyte. */
3011 face_id = face_at_string_position (it->w,
3012 it->string,
3013 CHARPOS (pos),
3014 bufpos,
3015 it->region_beg_charpos,
3016 it->region_end_charpos,
3017 &next_check_charpos,
3018 base_face_id, 0);
3020 /* Correct the face for charsets different from ASCII. Do it
3021 for the multibyte case only. The face returned above is
3022 suitable for unibyte text if IT->string is unibyte. */
3023 if (STRING_MULTIBYTE (it->string))
3025 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos);
3026 int rest = SBYTES (it->string) - BYTEPOS (pos);
3027 int c, len;
3028 struct face *face = FACE_FROM_ID (it->f, face_id);
3030 c = string_char_and_length (p, rest, &len);
3031 face_id = FACE_FOR_CHAR (it->f, face, c);
3034 else
3036 if ((IT_CHARPOS (*it) >= ZV && !before_p)
3037 || (IT_CHARPOS (*it) <= BEGV && before_p))
3038 return it->face_id;
3040 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
3041 pos = it->current.pos;
3043 if (before_p)
3044 DEC_TEXT_POS (pos, it->multibyte_p);
3045 else
3047 if (it->what == IT_COMPOSITION)
3048 /* For composition, we must check the position after the
3049 composition. */
3050 pos.charpos += it->cmp_len, pos.bytepos += it->len;
3051 else
3052 INC_TEXT_POS (pos, it->multibyte_p);
3055 /* Determine face for CHARSET_ASCII, or unibyte. */
3056 face_id = face_at_buffer_position (it->w,
3057 CHARPOS (pos),
3058 it->region_beg_charpos,
3059 it->region_end_charpos,
3060 &next_check_charpos,
3061 limit, 0);
3063 /* Correct the face for charsets different from ASCII. Do it
3064 for the multibyte case only. The face returned above is
3065 suitable for unibyte text if current_buffer is unibyte. */
3066 if (it->multibyte_p)
3068 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
3069 struct face *face = FACE_FROM_ID (it->f, face_id);
3070 face_id = FACE_FOR_CHAR (it->f, face, c);
3074 return face_id;
3079 /***********************************************************************
3080 Invisible text
3081 ***********************************************************************/
3083 /* Set up iterator IT from invisible properties at its current
3084 position. Called from handle_stop. */
3086 static enum prop_handled
3087 handle_invisible_prop (it)
3088 struct it *it;
3090 enum prop_handled handled = HANDLED_NORMALLY;
3092 if (STRINGP (it->string))
3094 extern Lisp_Object Qinvisible;
3095 Lisp_Object prop, end_charpos, limit, charpos;
3097 /* Get the value of the invisible text property at the
3098 current position. Value will be nil if there is no such
3099 property. */
3100 charpos = make_number (IT_STRING_CHARPOS (*it));
3101 prop = Fget_text_property (charpos, Qinvisible, it->string);
3103 if (!NILP (prop)
3104 && IT_STRING_CHARPOS (*it) < it->end_charpos)
3106 handled = HANDLED_RECOMPUTE_PROPS;
3108 /* Get the position at which the next change of the
3109 invisible text property can be found in IT->string.
3110 Value will be nil if the property value is the same for
3111 all the rest of IT->string. */
3112 XSETINT (limit, SCHARS (it->string));
3113 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
3114 it->string, limit);
3116 /* Text at current position is invisible. The next
3117 change in the property is at position end_charpos.
3118 Move IT's current position to that position. */
3119 if (INTEGERP (end_charpos)
3120 && XFASTINT (end_charpos) < XFASTINT (limit))
3122 struct text_pos old;
3123 old = it->current.string_pos;
3124 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
3125 compute_string_pos (&it->current.string_pos, old, it->string);
3127 else
3129 /* The rest of the string is invisible. If this is an
3130 overlay string, proceed with the next overlay string
3131 or whatever comes and return a character from there. */
3132 if (it->current.overlay_string_index >= 0)
3134 next_overlay_string (it);
3135 /* Don't check for overlay strings when we just
3136 finished processing them. */
3137 handled = HANDLED_OVERLAY_STRING_CONSUMED;
3139 else
3141 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
3142 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
3147 else
3149 int invis_p, newpos, next_stop, start_charpos;
3150 Lisp_Object pos, prop, overlay;
3152 /* First of all, is there invisible text at this position? */
3153 start_charpos = IT_CHARPOS (*it);
3154 pos = make_number (IT_CHARPOS (*it));
3155 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
3156 &overlay);
3157 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3159 /* If we are on invisible text, skip over it. */
3160 if (invis_p && IT_CHARPOS (*it) < it->end_charpos)
3162 /* Record whether we have to display an ellipsis for the
3163 invisible text. */
3164 int display_ellipsis_p = invis_p == 2;
3166 handled = HANDLED_RECOMPUTE_PROPS;
3168 /* Loop skipping over invisible text. The loop is left at
3169 ZV or with IT on the first char being visible again. */
3172 /* Try to skip some invisible text. Return value is the
3173 position reached which can be equal to IT's position
3174 if there is nothing invisible here. This skips both
3175 over invisible text properties and overlays with
3176 invisible property. */
3177 newpos = skip_invisible (IT_CHARPOS (*it),
3178 &next_stop, ZV, it->window);
3180 /* If we skipped nothing at all we weren't at invisible
3181 text in the first place. If everything to the end of
3182 the buffer was skipped, end the loop. */
3183 if (newpos == IT_CHARPOS (*it) || newpos >= ZV)
3184 invis_p = 0;
3185 else
3187 /* We skipped some characters but not necessarily
3188 all there are. Check if we ended up on visible
3189 text. Fget_char_property returns the property of
3190 the char before the given position, i.e. if we
3191 get invis_p = 0, this means that the char at
3192 newpos is visible. */
3193 pos = make_number (newpos);
3194 prop = Fget_char_property (pos, Qinvisible, it->window);
3195 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3198 /* If we ended up on invisible text, proceed to
3199 skip starting with next_stop. */
3200 if (invis_p)
3201 IT_CHARPOS (*it) = next_stop;
3203 while (invis_p);
3205 /* The position newpos is now either ZV or on visible text. */
3206 IT_CHARPOS (*it) = newpos;
3207 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
3209 /* If there are before-strings at the start of invisible
3210 text, and the text is invisible because of a text
3211 property, arrange to show before-strings because 20.x did
3212 it that way. (If the text is invisible because of an
3213 overlay property instead of a text property, this is
3214 already handled in the overlay code.) */
3215 if (NILP (overlay)
3216 && get_overlay_strings (it, start_charpos))
3218 handled = HANDLED_RECOMPUTE_PROPS;
3219 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
3221 else if (display_ellipsis_p)
3222 setup_for_ellipsis (it);
3226 return handled;
3230 /* Make iterator IT return `...' next. */
3232 static void
3233 setup_for_ellipsis (it)
3234 struct it *it;
3236 if (it->dp
3237 && VECTORP (DISP_INVIS_VECTOR (it->dp)))
3239 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
3240 it->dpvec = v->contents;
3241 it->dpend = v->contents + v->size;
3243 else
3245 /* Default `...'. */
3246 it->dpvec = default_invis_vector;
3247 it->dpend = default_invis_vector + 3;
3250 /* The ellipsis display does not replace the display of the
3251 character at the new position. Indicate this by setting
3252 IT->dpvec_char_len to zero. */
3253 it->dpvec_char_len = 0;
3255 it->current.dpvec_index = 0;
3256 it->method = next_element_from_display_vector;
3261 /***********************************************************************
3262 'display' property
3263 ***********************************************************************/
3265 /* Set up iterator IT from `display' property at its current position.
3266 Called from handle_stop. */
3268 static enum prop_handled
3269 handle_display_prop (it)
3270 struct it *it;
3272 Lisp_Object prop, object;
3273 struct text_pos *position;
3274 int display_replaced_p = 0;
3276 if (STRINGP (it->string))
3278 object = it->string;
3279 position = &it->current.string_pos;
3281 else
3283 object = it->w->buffer;
3284 position = &it->current.pos;
3287 /* Reset those iterator values set from display property values. */
3288 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
3289 it->space_width = Qnil;
3290 it->font_height = Qnil;
3291 it->voffset = 0;
3293 /* We don't support recursive `display' properties, i.e. string
3294 values that have a string `display' property, that have a string
3295 `display' property etc. */
3296 if (!it->string_from_display_prop_p)
3297 it->area = TEXT_AREA;
3299 prop = Fget_char_property (make_number (position->charpos),
3300 Qdisplay, object);
3301 if (NILP (prop))
3302 return HANDLED_NORMALLY;
3304 if (CONSP (prop)
3305 /* Simple properties. */
3306 && !EQ (XCAR (prop), Qimage)
3307 && !EQ (XCAR (prop), Qspace)
3308 && !EQ (XCAR (prop), Qwhen)
3309 && !EQ (XCAR (prop), Qslice)
3310 && !EQ (XCAR (prop), Qspace_width)
3311 && !EQ (XCAR (prop), Qheight)
3312 && !EQ (XCAR (prop), Qraise)
3313 /* Marginal area specifications. */
3314 && !(CONSP (XCAR (prop)) && EQ (XCAR (XCAR (prop)), Qmargin))
3315 && !EQ (XCAR (prop), Qleft_fringe)
3316 && !EQ (XCAR (prop), Qright_fringe)
3317 && !NILP (XCAR (prop)))
3319 for (; CONSP (prop); prop = XCDR (prop))
3321 if (handle_single_display_prop (it, XCAR (prop), object,
3322 position, display_replaced_p))
3323 display_replaced_p = 1;
3326 else if (VECTORP (prop))
3328 int i;
3329 for (i = 0; i < ASIZE (prop); ++i)
3330 if (handle_single_display_prop (it, AREF (prop, i), object,
3331 position, display_replaced_p))
3332 display_replaced_p = 1;
3334 else
3336 if (handle_single_display_prop (it, prop, object, position, 0))
3337 display_replaced_p = 1;
3340 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
3344 /* Value is the position of the end of the `display' property starting
3345 at START_POS in OBJECT. */
3347 static struct text_pos
3348 display_prop_end (it, object, start_pos)
3349 struct it *it;
3350 Lisp_Object object;
3351 struct text_pos start_pos;
3353 Lisp_Object end;
3354 struct text_pos end_pos;
3356 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
3357 Qdisplay, object, Qnil);
3358 CHARPOS (end_pos) = XFASTINT (end);
3359 if (STRINGP (object))
3360 compute_string_pos (&end_pos, start_pos, it->string);
3361 else
3362 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
3364 return end_pos;
3368 /* Set up IT from a single `display' sub-property value PROP. OBJECT
3369 is the object in which the `display' property was found. *POSITION
3370 is the position at which it was found. DISPLAY_REPLACED_P non-zero
3371 means that we previously saw a display sub-property which already
3372 replaced text display with something else, for example an image;
3373 ignore such properties after the first one has been processed.
3375 If PROP is a `space' or `image' sub-property, set *POSITION to the
3376 end position of the `display' property.
3378 Value is non-zero if something was found which replaces the display
3379 of buffer or string text. */
3381 static int
3382 handle_single_display_prop (it, prop, object, position,
3383 display_replaced_before_p)
3384 struct it *it;
3385 Lisp_Object prop;
3386 Lisp_Object object;
3387 struct text_pos *position;
3388 int display_replaced_before_p;
3390 Lisp_Object value;
3391 int replaces_text_display_p = 0;
3392 Lisp_Object form;
3394 /* If PROP is a list of the form `(when FORM . VALUE)', FORM is
3395 evaluated. If the result is nil, VALUE is ignored. */
3396 form = Qt;
3397 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3399 prop = XCDR (prop);
3400 if (!CONSP (prop))
3401 return 0;
3402 form = XCAR (prop);
3403 prop = XCDR (prop);
3406 if (!NILP (form) && !EQ (form, Qt))
3408 int count = SPECPDL_INDEX ();
3409 struct gcpro gcpro1;
3411 /* Bind `object' to the object having the `display' property, a
3412 buffer or string. Bind `position' to the position in the
3413 object where the property was found, and `buffer-position'
3414 to the current position in the buffer. */
3415 specbind (Qobject, object);
3416 specbind (Qposition, make_number (CHARPOS (*position)));
3417 specbind (Qbuffer_position,
3418 make_number (STRINGP (object)
3419 ? IT_CHARPOS (*it) : CHARPOS (*position)));
3420 GCPRO1 (form);
3421 form = safe_eval (form);
3422 UNGCPRO;
3423 unbind_to (count, Qnil);
3426 if (NILP (form))
3427 return 0;
3429 if (CONSP (prop)
3430 && EQ (XCAR (prop), Qheight)
3431 && CONSP (XCDR (prop)))
3433 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3434 return 0;
3436 /* `(height HEIGHT)'. */
3437 it->font_height = XCAR (XCDR (prop));
3438 if (!NILP (it->font_height))
3440 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3441 int new_height = -1;
3443 if (CONSP (it->font_height)
3444 && (EQ (XCAR (it->font_height), Qplus)
3445 || EQ (XCAR (it->font_height), Qminus))
3446 && CONSP (XCDR (it->font_height))
3447 && INTEGERP (XCAR (XCDR (it->font_height))))
3449 /* `(+ N)' or `(- N)' where N is an integer. */
3450 int steps = XINT (XCAR (XCDR (it->font_height)));
3451 if (EQ (XCAR (it->font_height), Qplus))
3452 steps = - steps;
3453 it->face_id = smaller_face (it->f, it->face_id, steps);
3455 else if (FUNCTIONP (it->font_height))
3457 /* Call function with current height as argument.
3458 Value is the new height. */
3459 Lisp_Object height;
3460 height = safe_call1 (it->font_height,
3461 face->lface[LFACE_HEIGHT_INDEX]);
3462 if (NUMBERP (height))
3463 new_height = XFLOATINT (height);
3465 else if (NUMBERP (it->font_height))
3467 /* Value is a multiple of the canonical char height. */
3468 struct face *face;
3470 face = FACE_FROM_ID (it->f, DEFAULT_FACE_ID);
3471 new_height = (XFLOATINT (it->font_height)
3472 * XINT (face->lface[LFACE_HEIGHT_INDEX]));
3474 else
3476 /* Evaluate IT->font_height with `height' bound to the
3477 current specified height to get the new height. */
3478 Lisp_Object value;
3479 int count = SPECPDL_INDEX ();
3481 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
3482 value = safe_eval (it->font_height);
3483 unbind_to (count, Qnil);
3485 if (NUMBERP (value))
3486 new_height = XFLOATINT (value);
3489 if (new_height > 0)
3490 it->face_id = face_with_height (it->f, it->face_id, new_height);
3493 else if (CONSP (prop)
3494 && EQ (XCAR (prop), Qspace_width)
3495 && CONSP (XCDR (prop)))
3497 /* `(space_width WIDTH)'. */
3498 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3499 return 0;
3501 value = XCAR (XCDR (prop));
3502 if (NUMBERP (value) && XFLOATINT (value) > 0)
3503 it->space_width = value;
3505 else if (CONSP (prop)
3506 && EQ (XCAR (prop), Qslice))
3508 /* `(slice X Y WIDTH HEIGHT)'. */
3509 Lisp_Object tem;
3511 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3512 return 0;
3514 if (tem = XCDR (prop), CONSP (tem))
3516 it->slice.x = XCAR (tem);
3517 if (tem = XCDR (tem), CONSP (tem))
3519 it->slice.y = XCAR (tem);
3520 if (tem = XCDR (tem), CONSP (tem))
3522 it->slice.width = XCAR (tem);
3523 if (tem = XCDR (tem), CONSP (tem))
3524 it->slice.height = XCAR (tem);
3529 else if (CONSP (prop)
3530 && EQ (XCAR (prop), Qraise)
3531 && CONSP (XCDR (prop)))
3533 /* `(raise FACTOR)'. */
3534 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3535 return 0;
3537 #ifdef HAVE_WINDOW_SYSTEM
3538 value = XCAR (XCDR (prop));
3539 if (NUMBERP (value))
3541 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3542 it->voffset = - (XFLOATINT (value)
3543 * (FONT_HEIGHT (face->font)));
3545 #endif /* HAVE_WINDOW_SYSTEM */
3547 else if (!it->string_from_display_prop_p)
3549 /* `((margin left-margin) VALUE)' or `((margin right-margin)
3550 VALUE) or `((margin nil) VALUE)' or VALUE. */
3551 Lisp_Object location, value;
3552 struct text_pos start_pos;
3553 int valid_p;
3555 /* Characters having this form of property are not displayed, so
3556 we have to find the end of the property. */
3557 start_pos = *position;
3558 *position = display_prop_end (it, object, start_pos);
3559 value = Qnil;
3561 /* Let's stop at the new position and assume that all
3562 text properties change there. */
3563 it->stop_charpos = position->charpos;
3565 if (CONSP (prop)
3566 && (EQ (XCAR (prop), Qleft_fringe)
3567 || EQ (XCAR (prop), Qright_fringe))
3568 && CONSP (XCDR (prop)))
3570 unsigned face_id = DEFAULT_FACE_ID;
3572 /* Save current settings of IT so that we can restore them
3573 when we are finished with the glyph property value. */
3575 /* `(left-fringe BITMAP FACE)'. */
3576 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3577 return 0;
3579 #ifdef HAVE_WINDOW_SYSTEM
3580 value = XCAR (XCDR (prop));
3581 if (!NUMBERP (value)
3582 || !valid_fringe_bitmap_id_p (XINT (value)))
3583 return 0;
3585 if (CONSP (XCDR (XCDR (prop))))
3587 Lisp_Object face_name = XCAR (XCDR (XCDR (prop)));
3589 face_id = lookup_named_face (it->f, face_name, 'A');
3590 if (face_id < 0)
3591 return 0;
3594 push_it (it);
3596 it->area = TEXT_AREA;
3597 it->what = IT_IMAGE;
3598 it->image_id = -1; /* no image */
3599 it->position = start_pos;
3600 it->object = NILP (object) ? it->w->buffer : object;
3601 it->method = next_element_from_image;
3602 it->face_id = face_id;
3604 /* Say that we haven't consumed the characters with
3605 `display' property yet. The call to pop_it in
3606 set_iterator_to_next will clean this up. */
3607 *position = start_pos;
3609 if (EQ (XCAR (prop), Qleft_fringe))
3611 it->left_user_fringe_bitmap = XINT (value);
3612 it->left_user_fringe_face_id = face_id;
3614 else
3616 it->right_user_fringe_bitmap = XINT (value);
3617 it->right_user_fringe_face_id = face_id;
3619 #endif /* HAVE_WINDOW_SYSTEM */
3620 return 1;
3623 location = Qunbound;
3624 if (CONSP (prop) && CONSP (XCAR (prop)))
3626 Lisp_Object tem;
3628 value = XCDR (prop);
3629 if (CONSP (value))
3630 value = XCAR (value);
3632 tem = XCAR (prop);
3633 if (EQ (XCAR (tem), Qmargin)
3634 && (tem = XCDR (tem),
3635 tem = CONSP (tem) ? XCAR (tem) : Qnil,
3636 (NILP (tem)
3637 || EQ (tem, Qleft_margin)
3638 || EQ (tem, Qright_margin))))
3639 location = tem;
3642 if (EQ (location, Qunbound))
3644 location = Qnil;
3645 value = prop;
3648 valid_p = (STRINGP (value)
3649 #ifdef HAVE_WINDOW_SYSTEM
3650 || (!FRAME_TERMCAP_P (it->f) && valid_image_p (value))
3651 #endif /* not HAVE_WINDOW_SYSTEM */
3652 || (CONSP (value) && EQ (XCAR (value), Qspace)));
3654 if ((EQ (location, Qleft_margin)
3655 || EQ (location, Qright_margin)
3656 || NILP (location))
3657 && valid_p
3658 && !display_replaced_before_p)
3660 replaces_text_display_p = 1;
3662 /* Save current settings of IT so that we can restore them
3663 when we are finished with the glyph property value. */
3664 push_it (it);
3666 if (NILP (location))
3667 it->area = TEXT_AREA;
3668 else if (EQ (location, Qleft_margin))
3669 it->area = LEFT_MARGIN_AREA;
3670 else
3671 it->area = RIGHT_MARGIN_AREA;
3673 if (STRINGP (value))
3675 it->string = value;
3676 it->multibyte_p = STRING_MULTIBYTE (it->string);
3677 it->current.overlay_string_index = -1;
3678 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
3679 it->end_charpos = it->string_nchars = SCHARS (it->string);
3680 it->method = next_element_from_string;
3681 it->stop_charpos = 0;
3682 it->string_from_display_prop_p = 1;
3683 /* Say that we haven't consumed the characters with
3684 `display' property yet. The call to pop_it in
3685 set_iterator_to_next will clean this up. */
3686 *position = start_pos;
3688 else if (CONSP (value) && EQ (XCAR (value), Qspace))
3690 it->method = next_element_from_stretch;
3691 it->object = value;
3692 it->current.pos = it->position = start_pos;
3694 #ifdef HAVE_WINDOW_SYSTEM
3695 else
3697 it->what = IT_IMAGE;
3698 it->image_id = lookup_image (it->f, value);
3699 it->position = start_pos;
3700 it->object = NILP (object) ? it->w->buffer : object;
3701 it->method = next_element_from_image;
3703 /* Say that we haven't consumed the characters with
3704 `display' property yet. The call to pop_it in
3705 set_iterator_to_next will clean this up. */
3706 *position = start_pos;
3708 #endif /* HAVE_WINDOW_SYSTEM */
3710 else
3711 /* Invalid property or property not supported. Restore
3712 the position to what it was before. */
3713 *position = start_pos;
3716 return replaces_text_display_p;
3720 /* Check if PROP is a display sub-property value whose text should be
3721 treated as intangible. */
3723 static int
3724 single_display_prop_intangible_p (prop)
3725 Lisp_Object prop;
3727 /* Skip over `when FORM'. */
3728 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3730 prop = XCDR (prop);
3731 if (!CONSP (prop))
3732 return 0;
3733 prop = XCDR (prop);
3736 if (STRINGP (prop))
3737 return 1;
3739 if (!CONSP (prop))
3740 return 0;
3742 /* Skip over `margin LOCATION'. If LOCATION is in the margins,
3743 we don't need to treat text as intangible. */
3744 if (EQ (XCAR (prop), Qmargin))
3746 prop = XCDR (prop);
3747 if (!CONSP (prop))
3748 return 0;
3750 prop = XCDR (prop);
3751 if (!CONSP (prop)
3752 || EQ (XCAR (prop), Qleft_margin)
3753 || EQ (XCAR (prop), Qright_margin))
3754 return 0;
3757 return (CONSP (prop)
3758 && (EQ (XCAR (prop), Qimage)
3759 || EQ (XCAR (prop), Qspace)));
3763 /* Check if PROP is a display property value whose text should be
3764 treated as intangible. */
3767 display_prop_intangible_p (prop)
3768 Lisp_Object prop;
3770 if (CONSP (prop)
3771 && CONSP (XCAR (prop))
3772 && !EQ (Qmargin, XCAR (XCAR (prop))))
3774 /* A list of sub-properties. */
3775 while (CONSP (prop))
3777 if (single_display_prop_intangible_p (XCAR (prop)))
3778 return 1;
3779 prop = XCDR (prop);
3782 else if (VECTORP (prop))
3784 /* A vector of sub-properties. */
3785 int i;
3786 for (i = 0; i < ASIZE (prop); ++i)
3787 if (single_display_prop_intangible_p (AREF (prop, i)))
3788 return 1;
3790 else
3791 return single_display_prop_intangible_p (prop);
3793 return 0;
3797 /* Return 1 if PROP is a display sub-property value containing STRING. */
3799 static int
3800 single_display_prop_string_p (prop, string)
3801 Lisp_Object prop, string;
3803 if (EQ (string, prop))
3804 return 1;
3806 /* Skip over `when FORM'. */
3807 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3809 prop = XCDR (prop);
3810 if (!CONSP (prop))
3811 return 0;
3812 prop = XCDR (prop);
3815 if (CONSP (prop))
3816 /* Skip over `margin LOCATION'. */
3817 if (EQ (XCAR (prop), Qmargin))
3819 prop = XCDR (prop);
3820 if (!CONSP (prop))
3821 return 0;
3823 prop = XCDR (prop);
3824 if (!CONSP (prop))
3825 return 0;
3828 return CONSP (prop) && EQ (XCAR (prop), string);
3832 /* Return 1 if STRING appears in the `display' property PROP. */
3834 static int
3835 display_prop_string_p (prop, string)
3836 Lisp_Object prop, string;
3838 if (CONSP (prop)
3839 && CONSP (XCAR (prop))
3840 && !EQ (Qmargin, XCAR (XCAR (prop))))
3842 /* A list of sub-properties. */
3843 while (CONSP (prop))
3845 if (single_display_prop_string_p (XCAR (prop), string))
3846 return 1;
3847 prop = XCDR (prop);
3850 else if (VECTORP (prop))
3852 /* A vector of sub-properties. */
3853 int i;
3854 for (i = 0; i < ASIZE (prop); ++i)
3855 if (single_display_prop_string_p (AREF (prop, i), string))
3856 return 1;
3858 else
3859 return single_display_prop_string_p (prop, string);
3861 return 0;
3865 /* Determine from which buffer position in W's buffer STRING comes
3866 from. AROUND_CHARPOS is an approximate position where it could
3867 be from. Value is the buffer position or 0 if it couldn't be
3868 determined.
3870 W's buffer must be current.
3872 This function is necessary because we don't record buffer positions
3873 in glyphs generated from strings (to keep struct glyph small).
3874 This function may only use code that doesn't eval because it is
3875 called asynchronously from note_mouse_highlight. */
3878 string_buffer_position (w, string, around_charpos)
3879 struct window *w;
3880 Lisp_Object string;
3881 int around_charpos;
3883 Lisp_Object limit, prop, pos;
3884 const int MAX_DISTANCE = 1000;
3885 int found = 0;
3887 pos = make_number (around_charpos);
3888 limit = make_number (min (XINT (pos) + MAX_DISTANCE, ZV));
3889 while (!found && !EQ (pos, limit))
3891 prop = Fget_char_property (pos, Qdisplay, Qnil);
3892 if (!NILP (prop) && display_prop_string_p (prop, string))
3893 found = 1;
3894 else
3895 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil, limit);
3898 if (!found)
3900 pos = make_number (around_charpos);
3901 limit = make_number (max (XINT (pos) - MAX_DISTANCE, BEGV));
3902 while (!found && !EQ (pos, limit))
3904 prop = Fget_char_property (pos, Qdisplay, Qnil);
3905 if (!NILP (prop) && display_prop_string_p (prop, string))
3906 found = 1;
3907 else
3908 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
3909 limit);
3913 return found ? XINT (pos) : 0;
3918 /***********************************************************************
3919 `composition' property
3920 ***********************************************************************/
3922 /* Set up iterator IT from `composition' property at its current
3923 position. Called from handle_stop. */
3925 static enum prop_handled
3926 handle_composition_prop (it)
3927 struct it *it;
3929 Lisp_Object prop, string;
3930 int pos, pos_byte, end;
3931 enum prop_handled handled = HANDLED_NORMALLY;
3933 if (STRINGP (it->string))
3935 pos = IT_STRING_CHARPOS (*it);
3936 pos_byte = IT_STRING_BYTEPOS (*it);
3937 string = it->string;
3939 else
3941 pos = IT_CHARPOS (*it);
3942 pos_byte = IT_BYTEPOS (*it);
3943 string = Qnil;
3946 /* If there's a valid composition and point is not inside of the
3947 composition (in the case that the composition is from the current
3948 buffer), draw a glyph composed from the composition components. */
3949 if (find_composition (pos, -1, &pos, &end, &prop, string)
3950 && COMPOSITION_VALID_P (pos, end, prop)
3951 && (STRINGP (it->string) || (PT <= pos || PT >= end)))
3953 int id = get_composition_id (pos, pos_byte, end - pos, prop, string);
3955 if (id >= 0)
3957 it->method = next_element_from_composition;
3958 it->cmp_id = id;
3959 it->cmp_len = COMPOSITION_LENGTH (prop);
3960 /* For a terminal, draw only the first character of the
3961 components. */
3962 it->c = COMPOSITION_GLYPH (composition_table[id], 0);
3963 it->len = (STRINGP (it->string)
3964 ? string_char_to_byte (it->string, end)
3965 : CHAR_TO_BYTE (end)) - pos_byte;
3966 it->stop_charpos = end;
3967 handled = HANDLED_RETURN;
3971 return handled;
3976 /***********************************************************************
3977 Overlay strings
3978 ***********************************************************************/
3980 /* The following structure is used to record overlay strings for
3981 later sorting in load_overlay_strings. */
3983 struct overlay_entry
3985 Lisp_Object overlay;
3986 Lisp_Object string;
3987 int priority;
3988 int after_string_p;
3992 /* Set up iterator IT from overlay strings at its current position.
3993 Called from handle_stop. */
3995 static enum prop_handled
3996 handle_overlay_change (it)
3997 struct it *it;
3999 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
4000 return HANDLED_RECOMPUTE_PROPS;
4001 else
4002 return HANDLED_NORMALLY;
4006 /* Set up the next overlay string for delivery by IT, if there is an
4007 overlay string to deliver. Called by set_iterator_to_next when the
4008 end of the current overlay string is reached. If there are more
4009 overlay strings to display, IT->string and
4010 IT->current.overlay_string_index are set appropriately here.
4011 Otherwise IT->string is set to nil. */
4013 static void
4014 next_overlay_string (it)
4015 struct it *it;
4017 ++it->current.overlay_string_index;
4018 if (it->current.overlay_string_index == it->n_overlay_strings)
4020 /* No more overlay strings. Restore IT's settings to what
4021 they were before overlay strings were processed, and
4022 continue to deliver from current_buffer. */
4023 int display_ellipsis_p = it->stack[it->sp - 1].display_ellipsis_p;
4025 pop_it (it);
4026 xassert (it->stop_charpos >= BEGV
4027 && it->stop_charpos <= it->end_charpos);
4028 it->string = Qnil;
4029 it->current.overlay_string_index = -1;
4030 SET_TEXT_POS (it->current.string_pos, -1, -1);
4031 it->n_overlay_strings = 0;
4032 it->method = next_element_from_buffer;
4034 /* If we're at the end of the buffer, record that we have
4035 processed the overlay strings there already, so that
4036 next_element_from_buffer doesn't try it again. */
4037 if (IT_CHARPOS (*it) >= it->end_charpos)
4038 it->overlay_strings_at_end_processed_p = 1;
4040 /* If we have to display `...' for invisible text, set
4041 the iterator up for that. */
4042 if (display_ellipsis_p)
4043 setup_for_ellipsis (it);
4045 else
4047 /* There are more overlay strings to process. If
4048 IT->current.overlay_string_index has advanced to a position
4049 where we must load IT->overlay_strings with more strings, do
4050 it. */
4051 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
4053 if (it->current.overlay_string_index && i == 0)
4054 load_overlay_strings (it, 0);
4056 /* Initialize IT to deliver display elements from the overlay
4057 string. */
4058 it->string = it->overlay_strings[i];
4059 it->multibyte_p = STRING_MULTIBYTE (it->string);
4060 SET_TEXT_POS (it->current.string_pos, 0, 0);
4061 it->method = next_element_from_string;
4062 it->stop_charpos = 0;
4065 CHECK_IT (it);
4069 /* Compare two overlay_entry structures E1 and E2. Used as a
4070 comparison function for qsort in load_overlay_strings. Overlay
4071 strings for the same position are sorted so that
4073 1. All after-strings come in front of before-strings, except
4074 when they come from the same overlay.
4076 2. Within after-strings, strings are sorted so that overlay strings
4077 from overlays with higher priorities come first.
4079 2. Within before-strings, strings are sorted so that overlay
4080 strings from overlays with higher priorities come last.
4082 Value is analogous to strcmp. */
4085 static int
4086 compare_overlay_entries (e1, e2)
4087 void *e1, *e2;
4089 struct overlay_entry *entry1 = (struct overlay_entry *) e1;
4090 struct overlay_entry *entry2 = (struct overlay_entry *) e2;
4091 int result;
4093 if (entry1->after_string_p != entry2->after_string_p)
4095 /* Let after-strings appear in front of before-strings if
4096 they come from different overlays. */
4097 if (EQ (entry1->overlay, entry2->overlay))
4098 result = entry1->after_string_p ? 1 : -1;
4099 else
4100 result = entry1->after_string_p ? -1 : 1;
4102 else if (entry1->after_string_p)
4103 /* After-strings sorted in order of decreasing priority. */
4104 result = entry2->priority - entry1->priority;
4105 else
4106 /* Before-strings sorted in order of increasing priority. */
4107 result = entry1->priority - entry2->priority;
4109 return result;
4113 /* Load the vector IT->overlay_strings with overlay strings from IT's
4114 current buffer position, or from CHARPOS if that is > 0. Set
4115 IT->n_overlays to the total number of overlay strings found.
4117 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
4118 a time. On entry into load_overlay_strings,
4119 IT->current.overlay_string_index gives the number of overlay
4120 strings that have already been loaded by previous calls to this
4121 function.
4123 IT->add_overlay_start contains an additional overlay start
4124 position to consider for taking overlay strings from, if non-zero.
4125 This position comes into play when the overlay has an `invisible'
4126 property, and both before and after-strings. When we've skipped to
4127 the end of the overlay, because of its `invisible' property, we
4128 nevertheless want its before-string to appear.
4129 IT->add_overlay_start will contain the overlay start position
4130 in this case.
4132 Overlay strings are sorted so that after-string strings come in
4133 front of before-string strings. Within before and after-strings,
4134 strings are sorted by overlay priority. See also function
4135 compare_overlay_entries. */
4137 static void
4138 load_overlay_strings (it, charpos)
4139 struct it *it;
4140 int charpos;
4142 extern Lisp_Object Qafter_string, Qbefore_string, Qwindow, Qpriority;
4143 Lisp_Object overlay, window, str, invisible;
4144 struct Lisp_Overlay *ov;
4145 int start, end;
4146 int size = 20;
4147 int n = 0, i, j, invis_p;
4148 struct overlay_entry *entries
4149 = (struct overlay_entry *) alloca (size * sizeof *entries);
4151 if (charpos <= 0)
4152 charpos = IT_CHARPOS (*it);
4154 /* Append the overlay string STRING of overlay OVERLAY to vector
4155 `entries' which has size `size' and currently contains `n'
4156 elements. AFTER_P non-zero means STRING is an after-string of
4157 OVERLAY. */
4158 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
4159 do \
4161 Lisp_Object priority; \
4163 if (n == size) \
4165 int new_size = 2 * size; \
4166 struct overlay_entry *old = entries; \
4167 entries = \
4168 (struct overlay_entry *) alloca (new_size \
4169 * sizeof *entries); \
4170 bcopy (old, entries, size * sizeof *entries); \
4171 size = new_size; \
4174 entries[n].string = (STRING); \
4175 entries[n].overlay = (OVERLAY); \
4176 priority = Foverlay_get ((OVERLAY), Qpriority); \
4177 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
4178 entries[n].after_string_p = (AFTER_P); \
4179 ++n; \
4181 while (0)
4183 /* Process overlay before the overlay center. */
4184 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
4186 XSETMISC (overlay, ov);
4187 xassert (OVERLAYP (overlay));
4188 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4189 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4191 if (end < charpos)
4192 break;
4194 /* Skip this overlay if it doesn't start or end at IT's current
4195 position. */
4196 if (end != charpos && start != charpos)
4197 continue;
4199 /* Skip this overlay if it doesn't apply to IT->w. */
4200 window = Foverlay_get (overlay, Qwindow);
4201 if (WINDOWP (window) && XWINDOW (window) != it->w)
4202 continue;
4204 /* If the text ``under'' the overlay is invisible, both before-
4205 and after-strings from this overlay are visible; start and
4206 end position are indistinguishable. */
4207 invisible = Foverlay_get (overlay, Qinvisible);
4208 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4210 /* If overlay has a non-empty before-string, record it. */
4211 if ((start == charpos || (end == charpos && invis_p))
4212 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4213 && SCHARS (str))
4214 RECORD_OVERLAY_STRING (overlay, str, 0);
4216 /* If overlay has a non-empty after-string, record it. */
4217 if ((end == charpos || (start == charpos && invis_p))
4218 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4219 && SCHARS (str))
4220 RECORD_OVERLAY_STRING (overlay, str, 1);
4223 /* Process overlays after the overlay center. */
4224 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
4226 XSETMISC (overlay, ov);
4227 xassert (OVERLAYP (overlay));
4228 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4229 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4231 if (start > charpos)
4232 break;
4234 /* Skip this overlay if it doesn't start or end at IT's current
4235 position. */
4236 if (end != charpos && start != charpos)
4237 continue;
4239 /* Skip this overlay if it doesn't apply to IT->w. */
4240 window = Foverlay_get (overlay, Qwindow);
4241 if (WINDOWP (window) && XWINDOW (window) != it->w)
4242 continue;
4244 /* If the text ``under'' the overlay is invisible, it has a zero
4245 dimension, and both before- and after-strings apply. */
4246 invisible = Foverlay_get (overlay, Qinvisible);
4247 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4249 /* If overlay has a non-empty before-string, record it. */
4250 if ((start == charpos || (end == charpos && invis_p))
4251 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4252 && SCHARS (str))
4253 RECORD_OVERLAY_STRING (overlay, str, 0);
4255 /* If overlay has a non-empty after-string, record it. */
4256 if ((end == charpos || (start == charpos && invis_p))
4257 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4258 && SCHARS (str))
4259 RECORD_OVERLAY_STRING (overlay, str, 1);
4262 #undef RECORD_OVERLAY_STRING
4264 /* Sort entries. */
4265 if (n > 1)
4266 qsort (entries, n, sizeof *entries, compare_overlay_entries);
4268 /* Record the total number of strings to process. */
4269 it->n_overlay_strings = n;
4271 /* IT->current.overlay_string_index is the number of overlay strings
4272 that have already been consumed by IT. Copy some of the
4273 remaining overlay strings to IT->overlay_strings. */
4274 i = 0;
4275 j = it->current.overlay_string_index;
4276 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
4277 it->overlay_strings[i++] = entries[j++].string;
4279 CHECK_IT (it);
4283 /* Get the first chunk of overlay strings at IT's current buffer
4284 position, or at CHARPOS if that is > 0. Value is non-zero if at
4285 least one overlay string was found. */
4287 static int
4288 get_overlay_strings (it, charpos)
4289 struct it *it;
4290 int charpos;
4292 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
4293 process. This fills IT->overlay_strings with strings, and sets
4294 IT->n_overlay_strings to the total number of strings to process.
4295 IT->pos.overlay_string_index has to be set temporarily to zero
4296 because load_overlay_strings needs this; it must be set to -1
4297 when no overlay strings are found because a zero value would
4298 indicate a position in the first overlay string. */
4299 it->current.overlay_string_index = 0;
4300 load_overlay_strings (it, charpos);
4302 /* If we found overlay strings, set up IT to deliver display
4303 elements from the first one. Otherwise set up IT to deliver
4304 from current_buffer. */
4305 if (it->n_overlay_strings)
4307 /* Make sure we know settings in current_buffer, so that we can
4308 restore meaningful values when we're done with the overlay
4309 strings. */
4310 compute_stop_pos (it);
4311 xassert (it->face_id >= 0);
4313 /* Save IT's settings. They are restored after all overlay
4314 strings have been processed. */
4315 xassert (it->sp == 0);
4316 push_it (it);
4318 /* Set up IT to deliver display elements from the first overlay
4319 string. */
4320 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
4321 it->string = it->overlay_strings[0];
4322 it->stop_charpos = 0;
4323 xassert (STRINGP (it->string));
4324 it->end_charpos = SCHARS (it->string);
4325 it->multibyte_p = STRING_MULTIBYTE (it->string);
4326 it->method = next_element_from_string;
4328 else
4330 it->string = Qnil;
4331 it->current.overlay_string_index = -1;
4332 it->method = next_element_from_buffer;
4335 CHECK_IT (it);
4337 /* Value is non-zero if we found at least one overlay string. */
4338 return STRINGP (it->string);
4343 /***********************************************************************
4344 Saving and restoring state
4345 ***********************************************************************/
4347 /* Save current settings of IT on IT->stack. Called, for example,
4348 before setting up IT for an overlay string, to be able to restore
4349 IT's settings to what they were after the overlay string has been
4350 processed. */
4352 static void
4353 push_it (it)
4354 struct it *it;
4356 struct iterator_stack_entry *p;
4358 xassert (it->sp < 2);
4359 p = it->stack + it->sp;
4361 p->stop_charpos = it->stop_charpos;
4362 xassert (it->face_id >= 0);
4363 p->face_id = it->face_id;
4364 p->string = it->string;
4365 p->pos = it->current;
4366 p->end_charpos = it->end_charpos;
4367 p->string_nchars = it->string_nchars;
4368 p->area = it->area;
4369 p->multibyte_p = it->multibyte_p;
4370 p->slice = it->slice;
4371 p->space_width = it->space_width;
4372 p->font_height = it->font_height;
4373 p->voffset = it->voffset;
4374 p->string_from_display_prop_p = it->string_from_display_prop_p;
4375 p->display_ellipsis_p = 0;
4376 ++it->sp;
4380 /* Restore IT's settings from IT->stack. Called, for example, when no
4381 more overlay strings must be processed, and we return to delivering
4382 display elements from a buffer, or when the end of a string from a
4383 `display' property is reached and we return to delivering display
4384 elements from an overlay string, or from a buffer. */
4386 static void
4387 pop_it (it)
4388 struct it *it;
4390 struct iterator_stack_entry *p;
4392 xassert (it->sp > 0);
4393 --it->sp;
4394 p = it->stack + it->sp;
4395 it->stop_charpos = p->stop_charpos;
4396 it->face_id = p->face_id;
4397 it->string = p->string;
4398 it->current = p->pos;
4399 it->end_charpos = p->end_charpos;
4400 it->string_nchars = p->string_nchars;
4401 it->area = p->area;
4402 it->multibyte_p = p->multibyte_p;
4403 it->slice = p->slice;
4404 it->space_width = p->space_width;
4405 it->font_height = p->font_height;
4406 it->voffset = p->voffset;
4407 it->string_from_display_prop_p = p->string_from_display_prop_p;
4412 /***********************************************************************
4413 Moving over lines
4414 ***********************************************************************/
4416 /* Set IT's current position to the previous line start. */
4418 static void
4419 back_to_previous_line_start (it)
4420 struct it *it;
4422 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
4423 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
4427 /* Move IT to the next line start.
4429 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
4430 we skipped over part of the text (as opposed to moving the iterator
4431 continuously over the text). Otherwise, don't change the value
4432 of *SKIPPED_P.
4434 Newlines may come from buffer text, overlay strings, or strings
4435 displayed via the `display' property. That's the reason we can't
4436 simply use find_next_newline_no_quit.
4438 Note that this function may not skip over invisible text that is so
4439 because of text properties and immediately follows a newline. If
4440 it would, function reseat_at_next_visible_line_start, when called
4441 from set_iterator_to_next, would effectively make invisible
4442 characters following a newline part of the wrong glyph row, which
4443 leads to wrong cursor motion. */
4445 static int
4446 forward_to_next_line_start (it, skipped_p)
4447 struct it *it;
4448 int *skipped_p;
4450 int old_selective, newline_found_p, n;
4451 const int MAX_NEWLINE_DISTANCE = 500;
4453 /* If already on a newline, just consume it to avoid unintended
4454 skipping over invisible text below. */
4455 if (it->what == IT_CHARACTER
4456 && it->c == '\n'
4457 && CHARPOS (it->position) == IT_CHARPOS (*it))
4459 set_iterator_to_next (it, 0);
4460 it->c = 0;
4461 return 1;
4464 /* Don't handle selective display in the following. It's (a)
4465 unnecessary because it's done by the caller, and (b) leads to an
4466 infinite recursion because next_element_from_ellipsis indirectly
4467 calls this function. */
4468 old_selective = it->selective;
4469 it->selective = 0;
4471 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
4472 from buffer text. */
4473 for (n = newline_found_p = 0;
4474 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
4475 n += STRINGP (it->string) ? 0 : 1)
4477 if (!get_next_display_element (it))
4478 return 0;
4479 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
4480 set_iterator_to_next (it, 0);
4483 /* If we didn't find a newline near enough, see if we can use a
4484 short-cut. */
4485 if (!newline_found_p)
4487 int start = IT_CHARPOS (*it);
4488 int limit = find_next_newline_no_quit (start, 1);
4489 Lisp_Object pos;
4491 xassert (!STRINGP (it->string));
4493 /* If there isn't any `display' property in sight, and no
4494 overlays, we can just use the position of the newline in
4495 buffer text. */
4496 if (it->stop_charpos >= limit
4497 || ((pos = Fnext_single_property_change (make_number (start),
4498 Qdisplay,
4499 Qnil, make_number (limit)),
4500 NILP (pos))
4501 && next_overlay_change (start) == ZV))
4503 IT_CHARPOS (*it) = limit;
4504 IT_BYTEPOS (*it) = CHAR_TO_BYTE (limit);
4505 *skipped_p = newline_found_p = 1;
4507 else
4509 while (get_next_display_element (it)
4510 && !newline_found_p)
4512 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
4513 set_iterator_to_next (it, 0);
4518 it->selective = old_selective;
4519 return newline_found_p;
4523 /* Set IT's current position to the previous visible line start. Skip
4524 invisible text that is so either due to text properties or due to
4525 selective display. Caution: this does not change IT->current_x and
4526 IT->hpos. */
4528 static void
4529 back_to_previous_visible_line_start (it)
4530 struct it *it;
4532 int visible_p = 0;
4534 /* Go back one newline if not on BEGV already. */
4535 if (IT_CHARPOS (*it) > BEGV)
4536 back_to_previous_line_start (it);
4538 /* Move over lines that are invisible because of selective display
4539 or text properties. */
4540 while (IT_CHARPOS (*it) > BEGV
4541 && !visible_p)
4543 visible_p = 1;
4545 /* If selective > 0, then lines indented more than that values
4546 are invisible. */
4547 if (it->selective > 0
4548 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
4549 (double) it->selective)) /* iftc */
4550 visible_p = 0;
4551 else
4553 Lisp_Object prop;
4555 prop = Fget_char_property (make_number (IT_CHARPOS (*it)),
4556 Qinvisible, it->window);
4557 if (TEXT_PROP_MEANS_INVISIBLE (prop))
4558 visible_p = 0;
4561 if (visible_p)
4563 struct it it2 = *it;
4565 if (handle_display_prop (&it2) == HANDLED_RETURN)
4566 visible_p = 0;
4569 /* Back one more newline if the current one is invisible. */
4570 if (!visible_p)
4571 back_to_previous_line_start (it);
4574 xassert (IT_CHARPOS (*it) >= BEGV);
4575 xassert (IT_CHARPOS (*it) == BEGV
4576 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
4577 CHECK_IT (it);
4581 /* Reseat iterator IT at the previous visible line start. Skip
4582 invisible text that is so either due to text properties or due to
4583 selective display. At the end, update IT's overlay information,
4584 face information etc. */
4586 static void
4587 reseat_at_previous_visible_line_start (it)
4588 struct it *it;
4590 back_to_previous_visible_line_start (it);
4591 reseat (it, it->current.pos, 1);
4592 CHECK_IT (it);
4596 /* Reseat iterator IT on the next visible line start in the current
4597 buffer. ON_NEWLINE_P non-zero means position IT on the newline
4598 preceding the line start. Skip over invisible text that is so
4599 because of selective display. Compute faces, overlays etc at the
4600 new position. Note that this function does not skip over text that
4601 is invisible because of text properties. */
4603 static void
4604 reseat_at_next_visible_line_start (it, on_newline_p)
4605 struct it *it;
4606 int on_newline_p;
4608 int newline_found_p, skipped_p = 0;
4610 newline_found_p = forward_to_next_line_start (it, &skipped_p);
4612 /* Skip over lines that are invisible because they are indented
4613 more than the value of IT->selective. */
4614 if (it->selective > 0)
4615 while (IT_CHARPOS (*it) < ZV
4616 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
4617 (double) it->selective)) /* iftc */
4619 xassert (FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
4620 newline_found_p = forward_to_next_line_start (it, &skipped_p);
4623 /* Position on the newline if that's what's requested. */
4624 if (on_newline_p && newline_found_p)
4626 if (STRINGP (it->string))
4628 if (IT_STRING_CHARPOS (*it) > 0)
4630 --IT_STRING_CHARPOS (*it);
4631 --IT_STRING_BYTEPOS (*it);
4634 else if (IT_CHARPOS (*it) > BEGV)
4636 --IT_CHARPOS (*it);
4637 --IT_BYTEPOS (*it);
4638 reseat (it, it->current.pos, 0);
4641 else if (skipped_p)
4642 reseat (it, it->current.pos, 0);
4644 CHECK_IT (it);
4649 /***********************************************************************
4650 Changing an iterator's position
4651 ***********************************************************************/
4653 /* Change IT's current position to POS in current_buffer. If FORCE_P
4654 is non-zero, always check for text properties at the new position.
4655 Otherwise, text properties are only looked up if POS >=
4656 IT->check_charpos of a property. */
4658 static void
4659 reseat (it, pos, force_p)
4660 struct it *it;
4661 struct text_pos pos;
4662 int force_p;
4664 int original_pos = IT_CHARPOS (*it);
4666 reseat_1 (it, pos, 0);
4668 /* Determine where to check text properties. Avoid doing it
4669 where possible because text property lookup is very expensive. */
4670 if (force_p
4671 || CHARPOS (pos) > it->stop_charpos
4672 || CHARPOS (pos) < original_pos)
4673 handle_stop (it);
4675 CHECK_IT (it);
4679 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
4680 IT->stop_pos to POS, also. */
4682 static void
4683 reseat_1 (it, pos, set_stop_p)
4684 struct it *it;
4685 struct text_pos pos;
4686 int set_stop_p;
4688 /* Don't call this function when scanning a C string. */
4689 xassert (it->s == NULL);
4691 /* POS must be a reasonable value. */
4692 xassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
4694 it->current.pos = it->position = pos;
4695 XSETBUFFER (it->object, current_buffer);
4696 it->end_charpos = ZV;
4697 it->dpvec = NULL;
4698 it->current.dpvec_index = -1;
4699 it->current.overlay_string_index = -1;
4700 IT_STRING_CHARPOS (*it) = -1;
4701 IT_STRING_BYTEPOS (*it) = -1;
4702 it->string = Qnil;
4703 it->method = next_element_from_buffer;
4704 /* RMS: I added this to fix a bug in move_it_vertically_backward
4705 where it->area continued to relate to the starting point
4706 for the backward motion. Bug report from
4707 Nick Roberts <nick@nick.uklinux.net> on 19 May 2003.
4708 However, I am not sure whether reseat still does the right thing
4709 in general after this change. */
4710 it->area = TEXT_AREA;
4711 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
4712 it->sp = 0;
4713 it->face_before_selective_p = 0;
4715 if (set_stop_p)
4716 it->stop_charpos = CHARPOS (pos);
4720 /* Set up IT for displaying a string, starting at CHARPOS in window W.
4721 If S is non-null, it is a C string to iterate over. Otherwise,
4722 STRING gives a Lisp string to iterate over.
4724 If PRECISION > 0, don't return more then PRECISION number of
4725 characters from the string.
4727 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
4728 characters have been returned. FIELD_WIDTH < 0 means an infinite
4729 field width.
4731 MULTIBYTE = 0 means disable processing of multibyte characters,
4732 MULTIBYTE > 0 means enable it,
4733 MULTIBYTE < 0 means use IT->multibyte_p.
4735 IT must be initialized via a prior call to init_iterator before
4736 calling this function. */
4738 static void
4739 reseat_to_string (it, s, string, charpos, precision, field_width, multibyte)
4740 struct it *it;
4741 unsigned char *s;
4742 Lisp_Object string;
4743 int charpos;
4744 int precision, field_width, multibyte;
4746 /* No region in strings. */
4747 it->region_beg_charpos = it->region_end_charpos = -1;
4749 /* No text property checks performed by default, but see below. */
4750 it->stop_charpos = -1;
4752 /* Set iterator position and end position. */
4753 bzero (&it->current, sizeof it->current);
4754 it->current.overlay_string_index = -1;
4755 it->current.dpvec_index = -1;
4756 xassert (charpos >= 0);
4758 /* If STRING is specified, use its multibyteness, otherwise use the
4759 setting of MULTIBYTE, if specified. */
4760 if (multibyte >= 0)
4761 it->multibyte_p = multibyte > 0;
4763 if (s == NULL)
4765 xassert (STRINGP (string));
4766 it->string = string;
4767 it->s = NULL;
4768 it->end_charpos = it->string_nchars = SCHARS (string);
4769 it->method = next_element_from_string;
4770 it->current.string_pos = string_pos (charpos, string);
4772 else
4774 it->s = s;
4775 it->string = Qnil;
4777 /* Note that we use IT->current.pos, not it->current.string_pos,
4778 for displaying C strings. */
4779 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
4780 if (it->multibyte_p)
4782 it->current.pos = c_string_pos (charpos, s, 1);
4783 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
4785 else
4787 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
4788 it->end_charpos = it->string_nchars = strlen (s);
4791 it->method = next_element_from_c_string;
4794 /* PRECISION > 0 means don't return more than PRECISION characters
4795 from the string. */
4796 if (precision > 0 && it->end_charpos - charpos > precision)
4797 it->end_charpos = it->string_nchars = charpos + precision;
4799 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
4800 characters have been returned. FIELD_WIDTH == 0 means don't pad,
4801 FIELD_WIDTH < 0 means infinite field width. This is useful for
4802 padding with `-' at the end of a mode line. */
4803 if (field_width < 0)
4804 field_width = INFINITY;
4805 if (field_width > it->end_charpos - charpos)
4806 it->end_charpos = charpos + field_width;
4808 /* Use the standard display table for displaying strings. */
4809 if (DISP_TABLE_P (Vstandard_display_table))
4810 it->dp = XCHAR_TABLE (Vstandard_display_table);
4812 it->stop_charpos = charpos;
4813 CHECK_IT (it);
4818 /***********************************************************************
4819 Iteration
4820 ***********************************************************************/
4822 /* Load IT's display element fields with information about the next
4823 display element from the current position of IT. Value is zero if
4824 end of buffer (or C string) is reached. */
4827 get_next_display_element (it)
4828 struct it *it;
4830 /* Non-zero means that we found a display element. Zero means that
4831 we hit the end of what we iterate over. Performance note: the
4832 function pointer `method' used here turns out to be faster than
4833 using a sequence of if-statements. */
4834 int success_p = (*it->method) (it);
4836 if (it->what == IT_CHARACTER)
4838 /* Map via display table or translate control characters.
4839 IT->c, IT->len etc. have been set to the next character by
4840 the function call above. If we have a display table, and it
4841 contains an entry for IT->c, translate it. Don't do this if
4842 IT->c itself comes from a display table, otherwise we could
4843 end up in an infinite recursion. (An alternative could be to
4844 count the recursion depth of this function and signal an
4845 error when a certain maximum depth is reached.) Is it worth
4846 it? */
4847 if (success_p && it->dpvec == NULL)
4849 Lisp_Object dv;
4851 if (it->dp
4852 && (dv = DISP_CHAR_VECTOR (it->dp, it->c),
4853 VECTORP (dv)))
4855 struct Lisp_Vector *v = XVECTOR (dv);
4857 /* Return the first character from the display table
4858 entry, if not empty. If empty, don't display the
4859 current character. */
4860 if (v->size)
4862 it->dpvec_char_len = it->len;
4863 it->dpvec = v->contents;
4864 it->dpend = v->contents + v->size;
4865 it->current.dpvec_index = 0;
4866 it->method = next_element_from_display_vector;
4867 success_p = get_next_display_element (it);
4869 else
4871 set_iterator_to_next (it, 0);
4872 success_p = get_next_display_element (it);
4876 /* Translate control characters into `\003' or `^C' form.
4877 Control characters coming from a display table entry are
4878 currently not translated because we use IT->dpvec to hold
4879 the translation. This could easily be changed but I
4880 don't believe that it is worth doing.
4882 If it->multibyte_p is nonzero, eight-bit characters and
4883 non-printable multibyte characters are also translated to
4884 octal form.
4886 If it->multibyte_p is zero, eight-bit characters that
4887 don't have corresponding multibyte char code are also
4888 translated to octal form. */
4889 else if ((it->c < ' '
4890 && (it->area != TEXT_AREA
4891 || (it->c != '\n' && it->c != '\t')))
4892 || (it->multibyte_p
4893 ? ((it->c >= 127
4894 && it->len == 1)
4895 || !CHAR_PRINTABLE_P (it->c))
4896 : (it->c >= 127
4897 && it->c == unibyte_char_to_multibyte (it->c))))
4899 /* IT->c is a control character which must be displayed
4900 either as '\003' or as `^C' where the '\\' and '^'
4901 can be defined in the display table. Fill
4902 IT->ctl_chars with glyphs for what we have to
4903 display. Then, set IT->dpvec to these glyphs. */
4904 GLYPH g;
4906 if (it->c < 128 && it->ctl_arrow_p)
4908 /* Set IT->ctl_chars[0] to the glyph for `^'. */
4909 if (it->dp
4910 && INTEGERP (DISP_CTRL_GLYPH (it->dp))
4911 && GLYPH_CHAR_VALID_P (XINT (DISP_CTRL_GLYPH (it->dp))))
4912 g = XINT (DISP_CTRL_GLYPH (it->dp));
4913 else
4914 g = FAST_MAKE_GLYPH ('^', 0);
4915 XSETINT (it->ctl_chars[0], g);
4917 g = FAST_MAKE_GLYPH (it->c ^ 0100, 0);
4918 XSETINT (it->ctl_chars[1], g);
4920 /* Set up IT->dpvec and return first character from it. */
4921 it->dpvec_char_len = it->len;
4922 it->dpvec = it->ctl_chars;
4923 it->dpend = it->dpvec + 2;
4924 it->current.dpvec_index = 0;
4925 it->method = next_element_from_display_vector;
4926 get_next_display_element (it);
4928 else
4930 unsigned char str[MAX_MULTIBYTE_LENGTH];
4931 int len;
4932 int i;
4933 GLYPH escape_glyph;
4935 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
4936 if (it->dp
4937 && INTEGERP (DISP_ESCAPE_GLYPH (it->dp))
4938 && GLYPH_CHAR_VALID_P (XFASTINT (DISP_ESCAPE_GLYPH (it->dp))))
4939 escape_glyph = XFASTINT (DISP_ESCAPE_GLYPH (it->dp));
4940 else
4941 escape_glyph = FAST_MAKE_GLYPH ('\\', 0);
4943 if (SINGLE_BYTE_CHAR_P (it->c))
4944 str[0] = it->c, len = 1;
4945 else
4947 len = CHAR_STRING_NO_SIGNAL (it->c, str);
4948 if (len < 0)
4950 /* It's an invalid character, which
4951 shouldn't happen actually, but due to
4952 bugs it may happen. Let's print the char
4953 as is, there's not much meaningful we can
4954 do with it. */
4955 str[0] = it->c;
4956 str[1] = it->c >> 8;
4957 str[2] = it->c >> 16;
4958 str[3] = it->c >> 24;
4959 len = 4;
4963 for (i = 0; i < len; i++)
4965 XSETINT (it->ctl_chars[i * 4], escape_glyph);
4966 /* Insert three more glyphs into IT->ctl_chars for
4967 the octal display of the character. */
4968 g = FAST_MAKE_GLYPH (((str[i] >> 6) & 7) + '0', 0);
4969 XSETINT (it->ctl_chars[i * 4 + 1], g);
4970 g = FAST_MAKE_GLYPH (((str[i] >> 3) & 7) + '0', 0);
4971 XSETINT (it->ctl_chars[i * 4 + 2], g);
4972 g = FAST_MAKE_GLYPH ((str[i] & 7) + '0', 0);
4973 XSETINT (it->ctl_chars[i * 4 + 3], g);
4976 /* Set up IT->dpvec and return the first character
4977 from it. */
4978 it->dpvec_char_len = it->len;
4979 it->dpvec = it->ctl_chars;
4980 it->dpend = it->dpvec + len * 4;
4981 it->current.dpvec_index = 0;
4982 it->method = next_element_from_display_vector;
4983 get_next_display_element (it);
4988 /* Adjust face id for a multibyte character. There are no
4989 multibyte character in unibyte text. */
4990 if (it->multibyte_p
4991 && success_p
4992 && FRAME_WINDOW_P (it->f))
4994 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4995 it->face_id = FACE_FOR_CHAR (it->f, face, it->c);
4999 /* Is this character the last one of a run of characters with
5000 box? If yes, set IT->end_of_box_run_p to 1. */
5001 if (it->face_box_p
5002 && it->s == NULL)
5004 int face_id;
5005 struct face *face;
5007 it->end_of_box_run_p
5008 = ((face_id = face_after_it_pos (it),
5009 face_id != it->face_id)
5010 && (face = FACE_FROM_ID (it->f, face_id),
5011 face->box == FACE_NO_BOX));
5014 /* Value is 0 if end of buffer or string reached. */
5015 return success_p;
5019 /* Move IT to the next display element.
5021 RESEAT_P non-zero means if called on a newline in buffer text,
5022 skip to the next visible line start.
5024 Functions get_next_display_element and set_iterator_to_next are
5025 separate because I find this arrangement easier to handle than a
5026 get_next_display_element function that also increments IT's
5027 position. The way it is we can first look at an iterator's current
5028 display element, decide whether it fits on a line, and if it does,
5029 increment the iterator position. The other way around we probably
5030 would either need a flag indicating whether the iterator has to be
5031 incremented the next time, or we would have to implement a
5032 decrement position function which would not be easy to write. */
5034 void
5035 set_iterator_to_next (it, reseat_p)
5036 struct it *it;
5037 int reseat_p;
5039 /* Reset flags indicating start and end of a sequence of characters
5040 with box. Reset them at the start of this function because
5041 moving the iterator to a new position might set them. */
5042 it->start_of_box_run_p = it->end_of_box_run_p = 0;
5044 if (it->method == next_element_from_buffer)
5046 /* The current display element of IT is a character from
5047 current_buffer. Advance in the buffer, and maybe skip over
5048 invisible lines that are so because of selective display. */
5049 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
5050 reseat_at_next_visible_line_start (it, 0);
5051 else
5053 xassert (it->len != 0);
5054 IT_BYTEPOS (*it) += it->len;
5055 IT_CHARPOS (*it) += 1;
5056 xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
5059 else if (it->method == next_element_from_composition)
5061 xassert (it->cmp_id >= 0 && it ->cmp_id < n_compositions);
5062 if (STRINGP (it->string))
5064 IT_STRING_BYTEPOS (*it) += it->len;
5065 IT_STRING_CHARPOS (*it) += it->cmp_len;
5066 it->method = next_element_from_string;
5067 goto consider_string_end;
5069 else
5071 IT_BYTEPOS (*it) += it->len;
5072 IT_CHARPOS (*it) += it->cmp_len;
5073 it->method = next_element_from_buffer;
5076 else if (it->method == next_element_from_c_string)
5078 /* Current display element of IT is from a C string. */
5079 IT_BYTEPOS (*it) += it->len;
5080 IT_CHARPOS (*it) += 1;
5082 else if (it->method == next_element_from_display_vector)
5084 /* Current display element of IT is from a display table entry.
5085 Advance in the display table definition. Reset it to null if
5086 end reached, and continue with characters from buffers/
5087 strings. */
5088 ++it->current.dpvec_index;
5090 /* Restore face of the iterator to what they were before the
5091 display vector entry (these entries may contain faces). */
5092 it->face_id = it->saved_face_id;
5094 if (it->dpvec + it->current.dpvec_index == it->dpend)
5096 if (it->s)
5097 it->method = next_element_from_c_string;
5098 else if (STRINGP (it->string))
5099 it->method = next_element_from_string;
5100 else
5101 it->method = next_element_from_buffer;
5103 it->dpvec = NULL;
5104 it->current.dpvec_index = -1;
5106 /* Skip over characters which were displayed via IT->dpvec. */
5107 if (it->dpvec_char_len < 0)
5108 reseat_at_next_visible_line_start (it, 1);
5109 else if (it->dpvec_char_len > 0)
5111 it->len = it->dpvec_char_len;
5112 set_iterator_to_next (it, reseat_p);
5116 else if (it->method == next_element_from_string)
5118 /* Current display element is a character from a Lisp string. */
5119 xassert (it->s == NULL && STRINGP (it->string));
5120 IT_STRING_BYTEPOS (*it) += it->len;
5121 IT_STRING_CHARPOS (*it) += 1;
5123 consider_string_end:
5125 if (it->current.overlay_string_index >= 0)
5127 /* IT->string is an overlay string. Advance to the
5128 next, if there is one. */
5129 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
5130 next_overlay_string (it);
5132 else
5134 /* IT->string is not an overlay string. If we reached
5135 its end, and there is something on IT->stack, proceed
5136 with what is on the stack. This can be either another
5137 string, this time an overlay string, or a buffer. */
5138 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
5139 && it->sp > 0)
5141 pop_it (it);
5142 if (!STRINGP (it->string))
5143 it->method = next_element_from_buffer;
5144 else
5145 goto consider_string_end;
5149 else if (it->method == next_element_from_image
5150 || it->method == next_element_from_stretch)
5152 /* The position etc with which we have to proceed are on
5153 the stack. The position may be at the end of a string,
5154 if the `display' property takes up the whole string. */
5155 pop_it (it);
5156 it->image_id = 0;
5157 if (STRINGP (it->string))
5159 it->method = next_element_from_string;
5160 goto consider_string_end;
5162 else
5163 it->method = next_element_from_buffer;
5165 else
5166 /* There are no other methods defined, so this should be a bug. */
5167 abort ();
5169 xassert (it->method != next_element_from_string
5170 || (STRINGP (it->string)
5171 && IT_STRING_CHARPOS (*it) >= 0));
5175 /* Load IT's display element fields with information about the next
5176 display element which comes from a display table entry or from the
5177 result of translating a control character to one of the forms `^C'
5178 or `\003'. IT->dpvec holds the glyphs to return as characters. */
5180 static int
5181 next_element_from_display_vector (it)
5182 struct it *it;
5184 /* Precondition. */
5185 xassert (it->dpvec && it->current.dpvec_index >= 0);
5187 /* Remember the current face id in case glyphs specify faces.
5188 IT's face is restored in set_iterator_to_next. */
5189 it->saved_face_id = it->face_id;
5191 if (INTEGERP (*it->dpvec)
5192 && GLYPH_CHAR_VALID_P (XFASTINT (*it->dpvec)))
5194 int lface_id;
5195 GLYPH g;
5197 g = XFASTINT (it->dpvec[it->current.dpvec_index]);
5198 it->c = FAST_GLYPH_CHAR (g);
5199 it->len = CHAR_BYTES (it->c);
5201 /* The entry may contain a face id to use. Such a face id is
5202 the id of a Lisp face, not a realized face. A face id of
5203 zero means no face is specified. */
5204 lface_id = FAST_GLYPH_FACE (g);
5205 if (lface_id)
5207 /* The function returns -1 if lface_id is invalid. */
5208 int face_id = ascii_face_of_lisp_face (it->f, lface_id);
5209 if (face_id >= 0)
5210 it->face_id = face_id;
5213 else
5214 /* Display table entry is invalid. Return a space. */
5215 it->c = ' ', it->len = 1;
5217 /* Don't change position and object of the iterator here. They are
5218 still the values of the character that had this display table
5219 entry or was translated, and that's what we want. */
5220 it->what = IT_CHARACTER;
5221 return 1;
5225 /* Load IT with the next display element from Lisp string IT->string.
5226 IT->current.string_pos is the current position within the string.
5227 If IT->current.overlay_string_index >= 0, the Lisp string is an
5228 overlay string. */
5230 static int
5231 next_element_from_string (it)
5232 struct it *it;
5234 struct text_pos position;
5236 xassert (STRINGP (it->string));
5237 xassert (IT_STRING_CHARPOS (*it) >= 0);
5238 position = it->current.string_pos;
5240 /* Time to check for invisible text? */
5241 if (IT_STRING_CHARPOS (*it) < it->end_charpos
5242 && IT_STRING_CHARPOS (*it) == it->stop_charpos)
5244 handle_stop (it);
5246 /* Since a handler may have changed IT->method, we must
5247 recurse here. */
5248 return get_next_display_element (it);
5251 if (it->current.overlay_string_index >= 0)
5253 /* Get the next character from an overlay string. In overlay
5254 strings, There is no field width or padding with spaces to
5255 do. */
5256 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
5258 it->what = IT_EOB;
5259 return 0;
5261 else if (STRING_MULTIBYTE (it->string))
5263 int remaining = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
5264 const unsigned char *s = (SDATA (it->string)
5265 + IT_STRING_BYTEPOS (*it));
5266 it->c = string_char_and_length (s, remaining, &it->len);
5268 else
5270 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
5271 it->len = 1;
5274 else
5276 /* Get the next character from a Lisp string that is not an
5277 overlay string. Such strings come from the mode line, for
5278 example. We may have to pad with spaces, or truncate the
5279 string. See also next_element_from_c_string. */
5280 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
5282 it->what = IT_EOB;
5283 return 0;
5285 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
5287 /* Pad with spaces. */
5288 it->c = ' ', it->len = 1;
5289 CHARPOS (position) = BYTEPOS (position) = -1;
5291 else if (STRING_MULTIBYTE (it->string))
5293 int maxlen = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
5294 const unsigned char *s = (SDATA (it->string)
5295 + IT_STRING_BYTEPOS (*it));
5296 it->c = string_char_and_length (s, maxlen, &it->len);
5298 else
5300 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
5301 it->len = 1;
5305 /* Record what we have and where it came from. Note that we store a
5306 buffer position in IT->position although it could arguably be a
5307 string position. */
5308 it->what = IT_CHARACTER;
5309 it->object = it->string;
5310 it->position = position;
5311 return 1;
5315 /* Load IT with next display element from C string IT->s.
5316 IT->string_nchars is the maximum number of characters to return
5317 from the string. IT->end_charpos may be greater than
5318 IT->string_nchars when this function is called, in which case we
5319 may have to return padding spaces. Value is zero if end of string
5320 reached, including padding spaces. */
5322 static int
5323 next_element_from_c_string (it)
5324 struct it *it;
5326 int success_p = 1;
5328 xassert (it->s);
5329 it->what = IT_CHARACTER;
5330 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
5331 it->object = Qnil;
5333 /* IT's position can be greater IT->string_nchars in case a field
5334 width or precision has been specified when the iterator was
5335 initialized. */
5336 if (IT_CHARPOS (*it) >= it->end_charpos)
5338 /* End of the game. */
5339 it->what = IT_EOB;
5340 success_p = 0;
5342 else if (IT_CHARPOS (*it) >= it->string_nchars)
5344 /* Pad with spaces. */
5345 it->c = ' ', it->len = 1;
5346 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
5348 else if (it->multibyte_p)
5350 /* Implementation note: The calls to strlen apparently aren't a
5351 performance problem because there is no noticeable performance
5352 difference between Emacs running in unibyte or multibyte mode. */
5353 int maxlen = strlen (it->s) - IT_BYTEPOS (*it);
5354 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it),
5355 maxlen, &it->len);
5357 else
5358 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
5360 return success_p;
5364 /* Set up IT to return characters from an ellipsis, if appropriate.
5365 The definition of the ellipsis glyphs may come from a display table
5366 entry. This function Fills IT with the first glyph from the
5367 ellipsis if an ellipsis is to be displayed. */
5369 static int
5370 next_element_from_ellipsis (it)
5371 struct it *it;
5373 if (it->selective_display_ellipsis_p)
5375 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
5377 /* Use the display table definition for `...'. Invalid glyphs
5378 will be handled by the method returning elements from dpvec. */
5379 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
5380 it->dpvec_char_len = it->len;
5381 it->dpvec = v->contents;
5382 it->dpend = v->contents + v->size;
5383 it->current.dpvec_index = 0;
5384 it->method = next_element_from_display_vector;
5386 else
5388 /* Use default `...' which is stored in default_invis_vector. */
5389 it->dpvec_char_len = it->len;
5390 it->dpvec = default_invis_vector;
5391 it->dpend = default_invis_vector + 3;
5392 it->current.dpvec_index = 0;
5393 it->method = next_element_from_display_vector;
5396 else
5398 /* The face at the current position may be different from the
5399 face we find after the invisible text. Remember what it
5400 was in IT->saved_face_id, and signal that it's there by
5401 setting face_before_selective_p. */
5402 it->saved_face_id = it->face_id;
5403 it->method = next_element_from_buffer;
5404 reseat_at_next_visible_line_start (it, 1);
5405 it->face_before_selective_p = 1;
5408 return get_next_display_element (it);
5412 /* Deliver an image display element. The iterator IT is already
5413 filled with image information (done in handle_display_prop). Value
5414 is always 1. */
5417 static int
5418 next_element_from_image (it)
5419 struct it *it;
5421 it->what = IT_IMAGE;
5422 return 1;
5426 /* Fill iterator IT with next display element from a stretch glyph
5427 property. IT->object is the value of the text property. Value is
5428 always 1. */
5430 static int
5431 next_element_from_stretch (it)
5432 struct it *it;
5434 it->what = IT_STRETCH;
5435 return 1;
5439 /* Load IT with the next display element from current_buffer. Value
5440 is zero if end of buffer reached. IT->stop_charpos is the next
5441 position at which to stop and check for text properties or buffer
5442 end. */
5444 static int
5445 next_element_from_buffer (it)
5446 struct it *it;
5448 int success_p = 1;
5450 /* Check this assumption, otherwise, we would never enter the
5451 if-statement, below. */
5452 xassert (IT_CHARPOS (*it) >= BEGV
5453 && IT_CHARPOS (*it) <= it->stop_charpos);
5455 if (IT_CHARPOS (*it) >= it->stop_charpos)
5457 if (IT_CHARPOS (*it) >= it->end_charpos)
5459 int overlay_strings_follow_p;
5461 /* End of the game, except when overlay strings follow that
5462 haven't been returned yet. */
5463 if (it->overlay_strings_at_end_processed_p)
5464 overlay_strings_follow_p = 0;
5465 else
5467 it->overlay_strings_at_end_processed_p = 1;
5468 overlay_strings_follow_p = get_overlay_strings (it, 0);
5471 if (overlay_strings_follow_p)
5472 success_p = get_next_display_element (it);
5473 else
5475 it->what = IT_EOB;
5476 it->position = it->current.pos;
5477 success_p = 0;
5480 else
5482 handle_stop (it);
5483 return get_next_display_element (it);
5486 else
5488 /* No face changes, overlays etc. in sight, so just return a
5489 character from current_buffer. */
5490 unsigned char *p;
5492 /* Maybe run the redisplay end trigger hook. Performance note:
5493 This doesn't seem to cost measurable time. */
5494 if (it->redisplay_end_trigger_charpos
5495 && it->glyph_row
5496 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
5497 run_redisplay_end_trigger_hook (it);
5499 /* Get the next character, maybe multibyte. */
5500 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
5501 if (it->multibyte_p && !ASCII_BYTE_P (*p))
5503 int maxlen = ((IT_BYTEPOS (*it) >= GPT_BYTE ? ZV_BYTE : GPT_BYTE)
5504 - IT_BYTEPOS (*it));
5505 it->c = string_char_and_length (p, maxlen, &it->len);
5507 else
5508 it->c = *p, it->len = 1;
5510 /* Record what we have and where it came from. */
5511 it->what = IT_CHARACTER;;
5512 it->object = it->w->buffer;
5513 it->position = it->current.pos;
5515 /* Normally we return the character found above, except when we
5516 really want to return an ellipsis for selective display. */
5517 if (it->selective)
5519 if (it->c == '\n')
5521 /* A value of selective > 0 means hide lines indented more
5522 than that number of columns. */
5523 if (it->selective > 0
5524 && IT_CHARPOS (*it) + 1 < ZV
5525 && indented_beyond_p (IT_CHARPOS (*it) + 1,
5526 IT_BYTEPOS (*it) + 1,
5527 (double) it->selective)) /* iftc */
5529 success_p = next_element_from_ellipsis (it);
5530 it->dpvec_char_len = -1;
5533 else if (it->c == '\r' && it->selective == -1)
5535 /* A value of selective == -1 means that everything from the
5536 CR to the end of the line is invisible, with maybe an
5537 ellipsis displayed for it. */
5538 success_p = next_element_from_ellipsis (it);
5539 it->dpvec_char_len = -1;
5544 /* Value is zero if end of buffer reached. */
5545 xassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
5546 return success_p;
5550 /* Run the redisplay end trigger hook for IT. */
5552 static void
5553 run_redisplay_end_trigger_hook (it)
5554 struct it *it;
5556 Lisp_Object args[3];
5558 /* IT->glyph_row should be non-null, i.e. we should be actually
5559 displaying something, or otherwise we should not run the hook. */
5560 xassert (it->glyph_row);
5562 /* Set up hook arguments. */
5563 args[0] = Qredisplay_end_trigger_functions;
5564 args[1] = it->window;
5565 XSETINT (args[2], it->redisplay_end_trigger_charpos);
5566 it->redisplay_end_trigger_charpos = 0;
5568 /* Since we are *trying* to run these functions, don't try to run
5569 them again, even if they get an error. */
5570 it->w->redisplay_end_trigger = Qnil;
5571 Frun_hook_with_args (3, args);
5573 /* Notice if it changed the face of the character we are on. */
5574 handle_face_prop (it);
5578 /* Deliver a composition display element. The iterator IT is already
5579 filled with composition information (done in
5580 handle_composition_prop). Value is always 1. */
5582 static int
5583 next_element_from_composition (it)
5584 struct it *it;
5586 it->what = IT_COMPOSITION;
5587 it->position = (STRINGP (it->string)
5588 ? it->current.string_pos
5589 : it->current.pos);
5590 return 1;
5595 /***********************************************************************
5596 Moving an iterator without producing glyphs
5597 ***********************************************************************/
5599 /* Move iterator IT to a specified buffer or X position within one
5600 line on the display without producing glyphs.
5602 OP should be a bit mask including some or all of these bits:
5603 MOVE_TO_X: Stop on reaching x-position TO_X.
5604 MOVE_TO_POS: Stop on reaching buffer or string position TO_CHARPOS.
5605 Regardless of OP's value, stop in reaching the end of the display line.
5607 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
5608 This means, in particular, that TO_X includes window's horizontal
5609 scroll amount.
5611 The return value has several possible values that
5612 say what condition caused the scan to stop:
5614 MOVE_POS_MATCH_OR_ZV
5615 - when TO_POS or ZV was reached.
5617 MOVE_X_REACHED
5618 -when TO_X was reached before TO_POS or ZV were reached.
5620 MOVE_LINE_CONTINUED
5621 - when we reached the end of the display area and the line must
5622 be continued.
5624 MOVE_LINE_TRUNCATED
5625 - when we reached the end of the display area and the line is
5626 truncated.
5628 MOVE_NEWLINE_OR_CR
5629 - when we stopped at a line end, i.e. a newline or a CR and selective
5630 display is on. */
5632 static enum move_it_result
5633 move_it_in_display_line_to (it, to_charpos, to_x, op)
5634 struct it *it;
5635 int to_charpos, to_x, op;
5637 enum move_it_result result = MOVE_UNDEFINED;
5638 struct glyph_row *saved_glyph_row;
5640 /* Don't produce glyphs in produce_glyphs. */
5641 saved_glyph_row = it->glyph_row;
5642 it->glyph_row = NULL;
5644 #define BUFFER_POS_REACHED_P() \
5645 ((op & MOVE_TO_POS) != 0 \
5646 && BUFFERP (it->object) \
5647 && IT_CHARPOS (*it) >= to_charpos)
5649 while (1)
5651 int x, i, ascent = 0, descent = 0;
5653 /* Stop when ZV reached.
5654 We used to stop here when TO_CHARPOS reached as well, but that is
5655 too soon if this glyph does not fit on this line. So we handle it
5656 explicitly below. */
5657 if (!get_next_display_element (it)
5658 || (it->truncate_lines_p
5659 && BUFFER_POS_REACHED_P ()))
5661 result = MOVE_POS_MATCH_OR_ZV;
5662 break;
5665 /* The call to produce_glyphs will get the metrics of the
5666 display element IT is loaded with. We record in x the
5667 x-position before this display element in case it does not
5668 fit on the line. */
5669 x = it->current_x;
5671 /* Remember the line height so far in case the next element doesn't
5672 fit on the line. */
5673 if (!it->truncate_lines_p)
5675 ascent = it->max_ascent;
5676 descent = it->max_descent;
5679 PRODUCE_GLYPHS (it);
5681 if (it->area != TEXT_AREA)
5683 set_iterator_to_next (it, 1);
5684 continue;
5687 /* The number of glyphs we get back in IT->nglyphs will normally
5688 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
5689 character on a terminal frame, or (iii) a line end. For the
5690 second case, IT->nglyphs - 1 padding glyphs will be present
5691 (on X frames, there is only one glyph produced for a
5692 composite character.
5694 The behavior implemented below means, for continuation lines,
5695 that as many spaces of a TAB as fit on the current line are
5696 displayed there. For terminal frames, as many glyphs of a
5697 multi-glyph character are displayed in the current line, too.
5698 This is what the old redisplay code did, and we keep it that
5699 way. Under X, the whole shape of a complex character must
5700 fit on the line or it will be completely displayed in the
5701 next line.
5703 Note that both for tabs and padding glyphs, all glyphs have
5704 the same width. */
5705 if (it->nglyphs)
5707 /* More than one glyph or glyph doesn't fit on line. All
5708 glyphs have the same width. */
5709 int single_glyph_width = it->pixel_width / it->nglyphs;
5710 int new_x;
5712 for (i = 0; i < it->nglyphs; ++i, x = new_x)
5714 new_x = x + single_glyph_width;
5716 /* We want to leave anything reaching TO_X to the caller. */
5717 if ((op & MOVE_TO_X) && new_x > to_x)
5719 if (BUFFER_POS_REACHED_P ())
5720 goto buffer_pos_reached;
5721 it->current_x = x;
5722 result = MOVE_X_REACHED;
5723 break;
5725 else if (/* Lines are continued. */
5726 !it->truncate_lines_p
5727 && (/* And glyph doesn't fit on the line. */
5728 new_x > it->last_visible_x
5729 /* Or it fits exactly and we're on a window
5730 system frame. */
5731 || (new_x == it->last_visible_x
5732 && FRAME_WINDOW_P (it->f))))
5734 if (/* IT->hpos == 0 means the very first glyph
5735 doesn't fit on the line, e.g. a wide image. */
5736 it->hpos == 0
5737 || (new_x == it->last_visible_x
5738 && FRAME_WINDOW_P (it->f)))
5740 ++it->hpos;
5741 it->current_x = new_x;
5742 if (i == it->nglyphs - 1)
5744 set_iterator_to_next (it, 1);
5745 #ifdef HAVE_WINDOW_SYSTEM
5746 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
5748 if (!get_next_display_element (it))
5750 result = MOVE_POS_MATCH_OR_ZV;
5751 break;
5753 if (BUFFER_POS_REACHED_P ())
5755 if (ITERATOR_AT_END_OF_LINE_P (it))
5756 result = MOVE_POS_MATCH_OR_ZV;
5757 else
5758 result = MOVE_LINE_CONTINUED;
5759 break;
5761 if (ITERATOR_AT_END_OF_LINE_P (it))
5763 result = MOVE_NEWLINE_OR_CR;
5764 break;
5767 #endif /* HAVE_WINDOW_SYSTEM */
5770 else
5772 it->current_x = x;
5773 it->max_ascent = ascent;
5774 it->max_descent = descent;
5777 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
5778 IT_CHARPOS (*it)));
5779 result = MOVE_LINE_CONTINUED;
5780 break;
5782 else if (BUFFER_POS_REACHED_P ())
5783 goto buffer_pos_reached;
5784 else if (new_x > it->first_visible_x)
5786 /* Glyph is visible. Increment number of glyphs that
5787 would be displayed. */
5788 ++it->hpos;
5790 else
5792 /* Glyph is completely off the left margin of the display
5793 area. Nothing to do. */
5797 if (result != MOVE_UNDEFINED)
5798 break;
5800 else if (BUFFER_POS_REACHED_P ())
5802 buffer_pos_reached:
5803 it->current_x = x;
5804 it->max_ascent = ascent;
5805 it->max_descent = descent;
5806 result = MOVE_POS_MATCH_OR_ZV;
5807 break;
5809 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
5811 /* Stop when TO_X specified and reached. This check is
5812 necessary here because of lines consisting of a line end,
5813 only. The line end will not produce any glyphs and we
5814 would never get MOVE_X_REACHED. */
5815 xassert (it->nglyphs == 0);
5816 result = MOVE_X_REACHED;
5817 break;
5820 /* Is this a line end? If yes, we're done. */
5821 if (ITERATOR_AT_END_OF_LINE_P (it))
5823 result = MOVE_NEWLINE_OR_CR;
5824 break;
5827 /* The current display element has been consumed. Advance
5828 to the next. */
5829 set_iterator_to_next (it, 1);
5831 /* Stop if lines are truncated and IT's current x-position is
5832 past the right edge of the window now. */
5833 if (it->truncate_lines_p
5834 && it->current_x >= it->last_visible_x)
5836 #ifdef HAVE_WINDOW_SYSTEM
5837 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
5839 if (!get_next_display_element (it)
5840 || BUFFER_POS_REACHED_P ())
5842 result = MOVE_POS_MATCH_OR_ZV;
5843 break;
5845 if (ITERATOR_AT_END_OF_LINE_P (it))
5847 result = MOVE_NEWLINE_OR_CR;
5848 break;
5851 #endif /* HAVE_WINDOW_SYSTEM */
5852 result = MOVE_LINE_TRUNCATED;
5853 break;
5857 #undef BUFFER_POS_REACHED_P
5859 /* Restore the iterator settings altered at the beginning of this
5860 function. */
5861 it->glyph_row = saved_glyph_row;
5862 return result;
5866 /* Move IT forward until it satisfies one or more of the criteria in
5867 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
5869 OP is a bit-mask that specifies where to stop, and in particular,
5870 which of those four position arguments makes a difference. See the
5871 description of enum move_operation_enum.
5873 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
5874 screen line, this function will set IT to the next position >
5875 TO_CHARPOS. */
5877 void
5878 move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
5879 struct it *it;
5880 int to_charpos, to_x, to_y, to_vpos;
5881 int op;
5883 enum move_it_result skip, skip2 = MOVE_X_REACHED;
5884 int line_height;
5885 int reached = 0;
5887 for (;;)
5889 if (op & MOVE_TO_VPOS)
5891 /* If no TO_CHARPOS and no TO_X specified, stop at the
5892 start of the line TO_VPOS. */
5893 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
5895 if (it->vpos == to_vpos)
5897 reached = 1;
5898 break;
5900 else
5901 skip = move_it_in_display_line_to (it, -1, -1, 0);
5903 else
5905 /* TO_VPOS >= 0 means stop at TO_X in the line at
5906 TO_VPOS, or at TO_POS, whichever comes first. */
5907 if (it->vpos == to_vpos)
5909 reached = 2;
5910 break;
5913 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
5915 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
5917 reached = 3;
5918 break;
5920 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
5922 /* We have reached TO_X but not in the line we want. */
5923 skip = move_it_in_display_line_to (it, to_charpos,
5924 -1, MOVE_TO_POS);
5925 if (skip == MOVE_POS_MATCH_OR_ZV)
5927 reached = 4;
5928 break;
5933 else if (op & MOVE_TO_Y)
5935 struct it it_backup;
5937 /* TO_Y specified means stop at TO_X in the line containing
5938 TO_Y---or at TO_CHARPOS if this is reached first. The
5939 problem is that we can't really tell whether the line
5940 contains TO_Y before we have completely scanned it, and
5941 this may skip past TO_X. What we do is to first scan to
5942 TO_X.
5944 If TO_X is not specified, use a TO_X of zero. The reason
5945 is to make the outcome of this function more predictable.
5946 If we didn't use TO_X == 0, we would stop at the end of
5947 the line which is probably not what a caller would expect
5948 to happen. */
5949 skip = move_it_in_display_line_to (it, to_charpos,
5950 ((op & MOVE_TO_X)
5951 ? to_x : 0),
5952 (MOVE_TO_X
5953 | (op & MOVE_TO_POS)));
5955 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
5956 if (skip == MOVE_POS_MATCH_OR_ZV)
5958 reached = 5;
5959 break;
5962 /* If TO_X was reached, we would like to know whether TO_Y
5963 is in the line. This can only be said if we know the
5964 total line height which requires us to scan the rest of
5965 the line. */
5966 if (skip == MOVE_X_REACHED)
5968 it_backup = *it;
5969 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
5970 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
5971 op & MOVE_TO_POS);
5972 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
5975 /* Now, decide whether TO_Y is in this line. */
5976 line_height = it->max_ascent + it->max_descent;
5977 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
5979 if (to_y >= it->current_y
5980 && to_y < it->current_y + line_height)
5982 if (skip == MOVE_X_REACHED)
5983 /* If TO_Y is in this line and TO_X was reached above,
5984 we scanned too far. We have to restore IT's settings
5985 to the ones before skipping. */
5986 *it = it_backup;
5987 reached = 6;
5989 else if (skip == MOVE_X_REACHED)
5991 skip = skip2;
5992 if (skip == MOVE_POS_MATCH_OR_ZV)
5993 reached = 7;
5996 if (reached)
5997 break;
5999 else
6000 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
6002 switch (skip)
6004 case MOVE_POS_MATCH_OR_ZV:
6005 reached = 8;
6006 goto out;
6008 case MOVE_NEWLINE_OR_CR:
6009 set_iterator_to_next (it, 1);
6010 it->continuation_lines_width = 0;
6011 break;
6013 case MOVE_LINE_TRUNCATED:
6014 it->continuation_lines_width = 0;
6015 reseat_at_next_visible_line_start (it, 0);
6016 if ((op & MOVE_TO_POS) != 0
6017 && IT_CHARPOS (*it) > to_charpos)
6019 reached = 9;
6020 goto out;
6022 break;
6024 case MOVE_LINE_CONTINUED:
6025 it->continuation_lines_width += it->current_x;
6026 break;
6028 default:
6029 abort ();
6032 /* Reset/increment for the next run. */
6033 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
6034 it->current_x = it->hpos = 0;
6035 it->current_y += it->max_ascent + it->max_descent;
6036 ++it->vpos;
6037 last_height = it->max_ascent + it->max_descent;
6038 last_max_ascent = it->max_ascent;
6039 it->max_ascent = it->max_descent = 0;
6042 out:
6044 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
6048 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
6050 If DY > 0, move IT backward at least that many pixels. DY = 0
6051 means move IT backward to the preceding line start or BEGV. This
6052 function may move over more than DY pixels if IT->current_y - DY
6053 ends up in the middle of a line; in this case IT->current_y will be
6054 set to the top of the line moved to. */
6056 void
6057 move_it_vertically_backward (it, dy)
6058 struct it *it;
6059 int dy;
6061 int nlines, h;
6062 struct it it2, it3;
6063 int start_pos = IT_CHARPOS (*it);
6065 xassert (dy >= 0);
6067 /* Estimate how many newlines we must move back. */
6068 nlines = max (1, dy / FRAME_LINE_HEIGHT (it->f));
6070 /* Set the iterator's position that many lines back. */
6071 while (nlines-- && IT_CHARPOS (*it) > BEGV)
6072 back_to_previous_visible_line_start (it);
6074 /* Reseat the iterator here. When moving backward, we don't want
6075 reseat to skip forward over invisible text, set up the iterator
6076 to deliver from overlay strings at the new position etc. So,
6077 use reseat_1 here. */
6078 reseat_1 (it, it->current.pos, 1);
6080 /* We are now surely at a line start. */
6081 it->current_x = it->hpos = 0;
6082 it->continuation_lines_width = 0;
6084 /* Move forward and see what y-distance we moved. First move to the
6085 start of the next line so that we get its height. We need this
6086 height to be able to tell whether we reached the specified
6087 y-distance. */
6088 it2 = *it;
6089 it2.max_ascent = it2.max_descent = 0;
6090 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
6091 MOVE_TO_POS | MOVE_TO_VPOS);
6092 xassert (IT_CHARPOS (*it) >= BEGV);
6093 it3 = it2;
6095 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
6096 xassert (IT_CHARPOS (*it) >= BEGV);
6097 /* H is the actual vertical distance from the position in *IT
6098 and the starting position. */
6099 h = it2.current_y - it->current_y;
6100 /* NLINES is the distance in number of lines. */
6101 nlines = it2.vpos - it->vpos;
6103 /* Correct IT's y and vpos position
6104 so that they are relative to the starting point. */
6105 it->vpos -= nlines;
6106 it->current_y -= h;
6108 if (dy == 0)
6110 /* DY == 0 means move to the start of the screen line. The
6111 value of nlines is > 0 if continuation lines were involved. */
6112 if (nlines > 0)
6113 move_it_by_lines (it, nlines, 1);
6114 xassert (IT_CHARPOS (*it) <= start_pos);
6116 else
6118 /* The y-position we try to reach, relative to *IT.
6119 Note that H has been subtracted in front of the if-statement. */
6120 int target_y = it->current_y + h - dy;
6121 int y0 = it3.current_y;
6122 int y1 = line_bottom_y (&it3);
6123 int line_height = y1 - y0;
6125 /* If we did not reach target_y, try to move further backward if
6126 we can. If we moved too far backward, try to move forward. */
6127 if (target_y < it->current_y
6128 /* This is heuristic. In a window that's 3 lines high, with
6129 a line height of 13 pixels each, recentering with point
6130 on the bottom line will try to move -39/2 = 19 pixels
6131 backward. Try to avoid moving into the first line. */
6132 && it->current_y - target_y > line_height / 3 * 2
6133 && IT_CHARPOS (*it) > BEGV)
6135 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
6136 target_y - it->current_y));
6137 move_it_vertically (it, target_y - it->current_y);
6138 xassert (IT_CHARPOS (*it) >= BEGV);
6140 else if (target_y >= it->current_y + line_height
6141 && IT_CHARPOS (*it) < ZV)
6143 /* Should move forward by at least one line, maybe more.
6145 Note: Calling move_it_by_lines can be expensive on
6146 terminal frames, where compute_motion is used (via
6147 vmotion) to do the job, when there are very long lines
6148 and truncate-lines is nil. That's the reason for
6149 treating terminal frames specially here. */
6151 if (!FRAME_WINDOW_P (it->f))
6152 move_it_vertically (it, target_y - (it->current_y + line_height));
6153 else
6157 move_it_by_lines (it, 1, 1);
6159 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
6162 xassert (IT_CHARPOS (*it) >= BEGV);
6168 /* Move IT by a specified amount of pixel lines DY. DY negative means
6169 move backwards. DY = 0 means move to start of screen line. At the
6170 end, IT will be on the start of a screen line. */
6172 void
6173 move_it_vertically (it, dy)
6174 struct it *it;
6175 int dy;
6177 if (dy <= 0)
6178 move_it_vertically_backward (it, -dy);
6179 else if (dy > 0)
6181 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
6182 move_it_to (it, ZV, -1, it->current_y + dy, -1,
6183 MOVE_TO_POS | MOVE_TO_Y);
6184 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
6186 /* If buffer ends in ZV without a newline, move to the start of
6187 the line to satisfy the post-condition. */
6188 if (IT_CHARPOS (*it) == ZV
6189 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
6190 move_it_by_lines (it, 0, 0);
6195 /* Move iterator IT past the end of the text line it is in. */
6197 void
6198 move_it_past_eol (it)
6199 struct it *it;
6201 enum move_it_result rc;
6203 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
6204 if (rc == MOVE_NEWLINE_OR_CR)
6205 set_iterator_to_next (it, 0);
6209 #if 0 /* Currently not used. */
6211 /* Return non-zero if some text between buffer positions START_CHARPOS
6212 and END_CHARPOS is invisible. IT->window is the window for text
6213 property lookup. */
6215 static int
6216 invisible_text_between_p (it, start_charpos, end_charpos)
6217 struct it *it;
6218 int start_charpos, end_charpos;
6220 Lisp_Object prop, limit;
6221 int invisible_found_p;
6223 xassert (it != NULL && start_charpos <= end_charpos);
6225 /* Is text at START invisible? */
6226 prop = Fget_char_property (make_number (start_charpos), Qinvisible,
6227 it->window);
6228 if (TEXT_PROP_MEANS_INVISIBLE (prop))
6229 invisible_found_p = 1;
6230 else
6232 limit = Fnext_single_char_property_change (make_number (start_charpos),
6233 Qinvisible, Qnil,
6234 make_number (end_charpos));
6235 invisible_found_p = XFASTINT (limit) < end_charpos;
6238 return invisible_found_p;
6241 #endif /* 0 */
6244 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
6245 negative means move up. DVPOS == 0 means move to the start of the
6246 screen line. NEED_Y_P non-zero means calculate IT->current_y. If
6247 NEED_Y_P is zero, IT->current_y will be left unchanged.
6249 Further optimization ideas: If we would know that IT->f doesn't use
6250 a face with proportional font, we could be faster for
6251 truncate-lines nil. */
6253 void
6254 move_it_by_lines (it, dvpos, need_y_p)
6255 struct it *it;
6256 int dvpos, need_y_p;
6258 struct position pos;
6260 if (!FRAME_WINDOW_P (it->f))
6262 struct text_pos textpos;
6264 /* We can use vmotion on frames without proportional fonts. */
6265 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
6266 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
6267 reseat (it, textpos, 1);
6268 it->vpos += pos.vpos;
6269 it->current_y += pos.vpos;
6271 else if (dvpos == 0)
6273 /* DVPOS == 0 means move to the start of the screen line. */
6274 move_it_vertically_backward (it, 0);
6275 xassert (it->current_x == 0 && it->hpos == 0);
6277 else if (dvpos > 0)
6278 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
6279 else
6281 struct it it2;
6282 int start_charpos, i;
6284 /* Start at the beginning of the screen line containing IT's
6285 position. */
6286 move_it_vertically_backward (it, 0);
6288 /* Go back -DVPOS visible lines and reseat the iterator there. */
6289 start_charpos = IT_CHARPOS (*it);
6290 for (i = -dvpos; i && IT_CHARPOS (*it) > BEGV; --i)
6291 back_to_previous_visible_line_start (it);
6292 reseat (it, it->current.pos, 1);
6293 it->current_x = it->hpos = 0;
6295 /* Above call may have moved too far if continuation lines
6296 are involved. Scan forward and see if it did. */
6297 it2 = *it;
6298 it2.vpos = it2.current_y = 0;
6299 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
6300 it->vpos -= it2.vpos;
6301 it->current_y -= it2.current_y;
6302 it->current_x = it->hpos = 0;
6304 /* If we moved too far, move IT some lines forward. */
6305 if (it2.vpos > -dvpos)
6307 int delta = it2.vpos + dvpos;
6308 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
6313 /* Return 1 if IT points into the middle of a display vector. */
6316 in_display_vector_p (it)
6317 struct it *it;
6319 return (it->method == next_element_from_display_vector
6320 && it->current.dpvec_index > 0
6321 && it->dpvec + it->current.dpvec_index != it->dpend);
6325 /***********************************************************************
6326 Messages
6327 ***********************************************************************/
6330 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
6331 to *Messages*. */
6333 void
6334 add_to_log (format, arg1, arg2)
6335 char *format;
6336 Lisp_Object arg1, arg2;
6338 Lisp_Object args[3];
6339 Lisp_Object msg, fmt;
6340 char *buffer;
6341 int len;
6342 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
6343 USE_SAFE_ALLOCA;
6345 /* Do nothing if called asynchronously. Inserting text into
6346 a buffer may call after-change-functions and alike and
6347 that would means running Lisp asynchronously. */
6348 if (handling_signal)
6349 return;
6351 fmt = msg = Qnil;
6352 GCPRO4 (fmt, msg, arg1, arg2);
6354 args[0] = fmt = build_string (format);
6355 args[1] = arg1;
6356 args[2] = arg2;
6357 msg = Fformat (3, args);
6359 len = SBYTES (msg) + 1;
6360 SAFE_ALLOCA (buffer, char *, len);
6361 bcopy (SDATA (msg), buffer, len);
6363 message_dolog (buffer, len - 1, 1, 0);
6364 SAFE_FREE (len);
6366 UNGCPRO;
6370 /* Output a newline in the *Messages* buffer if "needs" one. */
6372 void
6373 message_log_maybe_newline ()
6375 if (message_log_need_newline)
6376 message_dolog ("", 0, 1, 0);
6380 /* Add a string M of length NBYTES to the message log, optionally
6381 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
6382 nonzero, means interpret the contents of M as multibyte. This
6383 function calls low-level routines in order to bypass text property
6384 hooks, etc. which might not be safe to run. */
6386 void
6387 message_dolog (m, nbytes, nlflag, multibyte)
6388 const char *m;
6389 int nbytes, nlflag, multibyte;
6391 if (!NILP (Vmemory_full))
6392 return;
6394 if (!NILP (Vmessage_log_max))
6396 struct buffer *oldbuf;
6397 Lisp_Object oldpoint, oldbegv, oldzv;
6398 int old_windows_or_buffers_changed = windows_or_buffers_changed;
6399 int point_at_end = 0;
6400 int zv_at_end = 0;
6401 Lisp_Object old_deactivate_mark, tem;
6402 struct gcpro gcpro1;
6404 old_deactivate_mark = Vdeactivate_mark;
6405 oldbuf = current_buffer;
6406 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
6407 current_buffer->undo_list = Qt;
6409 oldpoint = message_dolog_marker1;
6410 set_marker_restricted (oldpoint, make_number (PT), Qnil);
6411 oldbegv = message_dolog_marker2;
6412 set_marker_restricted (oldbegv, make_number (BEGV), Qnil);
6413 oldzv = message_dolog_marker3;
6414 set_marker_restricted (oldzv, make_number (ZV), Qnil);
6415 GCPRO1 (old_deactivate_mark);
6417 if (PT == Z)
6418 point_at_end = 1;
6419 if (ZV == Z)
6420 zv_at_end = 1;
6422 BEGV = BEG;
6423 BEGV_BYTE = BEG_BYTE;
6424 ZV = Z;
6425 ZV_BYTE = Z_BYTE;
6426 TEMP_SET_PT_BOTH (Z, Z_BYTE);
6428 /* Insert the string--maybe converting multibyte to single byte
6429 or vice versa, so that all the text fits the buffer. */
6430 if (multibyte
6431 && NILP (current_buffer->enable_multibyte_characters))
6433 int i, c, char_bytes;
6434 unsigned char work[1];
6436 /* Convert a multibyte string to single-byte
6437 for the *Message* buffer. */
6438 for (i = 0; i < nbytes; i += char_bytes)
6440 c = string_char_and_length (m + i, nbytes - i, &char_bytes);
6441 work[0] = (SINGLE_BYTE_CHAR_P (c)
6443 : multibyte_char_to_unibyte (c, Qnil));
6444 insert_1_both (work, 1, 1, 1, 0, 0);
6447 else if (! multibyte
6448 && ! NILP (current_buffer->enable_multibyte_characters))
6450 int i, c, char_bytes;
6451 unsigned char *msg = (unsigned char *) m;
6452 unsigned char str[MAX_MULTIBYTE_LENGTH];
6453 /* Convert a single-byte string to multibyte
6454 for the *Message* buffer. */
6455 for (i = 0; i < nbytes; i++)
6457 c = unibyte_char_to_multibyte (msg[i]);
6458 char_bytes = CHAR_STRING (c, str);
6459 insert_1_both (str, 1, char_bytes, 1, 0, 0);
6462 else if (nbytes)
6463 insert_1 (m, nbytes, 1, 0, 0);
6465 if (nlflag)
6467 int this_bol, this_bol_byte, prev_bol, prev_bol_byte, dup;
6468 insert_1 ("\n", 1, 1, 0, 0);
6470 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
6471 this_bol = PT;
6472 this_bol_byte = PT_BYTE;
6474 /* See if this line duplicates the previous one.
6475 If so, combine duplicates. */
6476 if (this_bol > BEG)
6478 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
6479 prev_bol = PT;
6480 prev_bol_byte = PT_BYTE;
6482 dup = message_log_check_duplicate (prev_bol, prev_bol_byte,
6483 this_bol, this_bol_byte);
6484 if (dup)
6486 del_range_both (prev_bol, prev_bol_byte,
6487 this_bol, this_bol_byte, 0);
6488 if (dup > 1)
6490 char dupstr[40];
6491 int duplen;
6493 /* If you change this format, don't forget to also
6494 change message_log_check_duplicate. */
6495 sprintf (dupstr, " [%d times]", dup);
6496 duplen = strlen (dupstr);
6497 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
6498 insert_1 (dupstr, duplen, 1, 0, 1);
6503 /* If we have more than the desired maximum number of lines
6504 in the *Messages* buffer now, delete the oldest ones.
6505 This is safe because we don't have undo in this buffer. */
6507 if (NATNUMP (Vmessage_log_max))
6509 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
6510 -XFASTINT (Vmessage_log_max) - 1, 0);
6511 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
6514 BEGV = XMARKER (oldbegv)->charpos;
6515 BEGV_BYTE = marker_byte_position (oldbegv);
6517 if (zv_at_end)
6519 ZV = Z;
6520 ZV_BYTE = Z_BYTE;
6522 else
6524 ZV = XMARKER (oldzv)->charpos;
6525 ZV_BYTE = marker_byte_position (oldzv);
6528 if (point_at_end)
6529 TEMP_SET_PT_BOTH (Z, Z_BYTE);
6530 else
6531 /* We can't do Fgoto_char (oldpoint) because it will run some
6532 Lisp code. */
6533 TEMP_SET_PT_BOTH (XMARKER (oldpoint)->charpos,
6534 XMARKER (oldpoint)->bytepos);
6536 UNGCPRO;
6537 unchain_marker (XMARKER (oldpoint));
6538 unchain_marker (XMARKER (oldbegv));
6539 unchain_marker (XMARKER (oldzv));
6541 tem = Fget_buffer_window (Fcurrent_buffer (), Qt);
6542 set_buffer_internal (oldbuf);
6543 if (NILP (tem))
6544 windows_or_buffers_changed = old_windows_or_buffers_changed;
6545 message_log_need_newline = !nlflag;
6546 Vdeactivate_mark = old_deactivate_mark;
6551 /* We are at the end of the buffer after just having inserted a newline.
6552 (Note: We depend on the fact we won't be crossing the gap.)
6553 Check to see if the most recent message looks a lot like the previous one.
6554 Return 0 if different, 1 if the new one should just replace it, or a
6555 value N > 1 if we should also append " [N times]". */
6557 static int
6558 message_log_check_duplicate (prev_bol, prev_bol_byte, this_bol, this_bol_byte)
6559 int prev_bol, this_bol;
6560 int prev_bol_byte, this_bol_byte;
6562 int i;
6563 int len = Z_BYTE - 1 - this_bol_byte;
6564 int seen_dots = 0;
6565 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
6566 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
6568 for (i = 0; i < len; i++)
6570 if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.')
6571 seen_dots = 1;
6572 if (p1[i] != p2[i])
6573 return seen_dots;
6575 p1 += len;
6576 if (*p1 == '\n')
6577 return 2;
6578 if (*p1++ == ' ' && *p1++ == '[')
6580 int n = 0;
6581 while (*p1 >= '0' && *p1 <= '9')
6582 n = n * 10 + *p1++ - '0';
6583 if (strncmp (p1, " times]\n", 8) == 0)
6584 return n+1;
6586 return 0;
6590 /* Display an echo area message M with a specified length of NBYTES
6591 bytes. The string may include null characters. If M is 0, clear
6592 out any existing message, and let the mini-buffer text show
6593 through.
6595 The buffer M must continue to exist until after the echo area gets
6596 cleared or some other message gets displayed there. This means do
6597 not pass text that is stored in a Lisp string; do not pass text in
6598 a buffer that was alloca'd. */
6600 void
6601 message2 (m, nbytes, multibyte)
6602 const char *m;
6603 int nbytes;
6604 int multibyte;
6606 /* First flush out any partial line written with print. */
6607 message_log_maybe_newline ();
6608 if (m)
6609 message_dolog (m, nbytes, 1, multibyte);
6610 message2_nolog (m, nbytes, multibyte);
6614 /* The non-logging counterpart of message2. */
6616 void
6617 message2_nolog (m, nbytes, multibyte)
6618 const char *m;
6619 int nbytes, multibyte;
6621 struct frame *sf = SELECTED_FRAME ();
6622 message_enable_multibyte = multibyte;
6624 if (noninteractive)
6626 if (noninteractive_need_newline)
6627 putc ('\n', stderr);
6628 noninteractive_need_newline = 0;
6629 if (m)
6630 fwrite (m, nbytes, 1, stderr);
6631 if (cursor_in_echo_area == 0)
6632 fprintf (stderr, "\n");
6633 fflush (stderr);
6635 /* A null message buffer means that the frame hasn't really been
6636 initialized yet. Error messages get reported properly by
6637 cmd_error, so this must be just an informative message; toss it. */
6638 else if (INTERACTIVE
6639 && sf->glyphs_initialized_p
6640 && FRAME_MESSAGE_BUF (sf))
6642 Lisp_Object mini_window;
6643 struct frame *f;
6645 /* Get the frame containing the mini-buffer
6646 that the selected frame is using. */
6647 mini_window = FRAME_MINIBUF_WINDOW (sf);
6648 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6650 FRAME_SAMPLE_VISIBILITY (f);
6651 if (FRAME_VISIBLE_P (sf)
6652 && ! FRAME_VISIBLE_P (f))
6653 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
6655 if (m)
6657 set_message (m, Qnil, nbytes, multibyte);
6658 if (minibuffer_auto_raise)
6659 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
6661 else
6662 clear_message (1, 1);
6664 do_pending_window_change (0);
6665 echo_area_display (1);
6666 do_pending_window_change (0);
6667 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
6668 (*frame_up_to_date_hook) (f);
6673 /* Display an echo area message M with a specified length of NBYTES
6674 bytes. The string may include null characters. If M is not a
6675 string, clear out any existing message, and let the mini-buffer
6676 text show through. */
6678 void
6679 message3 (m, nbytes, multibyte)
6680 Lisp_Object m;
6681 int nbytes;
6682 int multibyte;
6684 struct gcpro gcpro1;
6686 GCPRO1 (m);
6688 /* First flush out any partial line written with print. */
6689 message_log_maybe_newline ();
6690 if (STRINGP (m))
6691 message_dolog (SDATA (m), nbytes, 1, multibyte);
6692 message3_nolog (m, nbytes, multibyte);
6694 UNGCPRO;
6698 /* The non-logging version of message3. */
6700 void
6701 message3_nolog (m, nbytes, multibyte)
6702 Lisp_Object m;
6703 int nbytes, multibyte;
6705 struct frame *sf = SELECTED_FRAME ();
6706 message_enable_multibyte = multibyte;
6708 if (noninteractive)
6710 if (noninteractive_need_newline)
6711 putc ('\n', stderr);
6712 noninteractive_need_newline = 0;
6713 if (STRINGP (m))
6714 fwrite (SDATA (m), nbytes, 1, stderr);
6715 if (cursor_in_echo_area == 0)
6716 fprintf (stderr, "\n");
6717 fflush (stderr);
6719 /* A null message buffer means that the frame hasn't really been
6720 initialized yet. Error messages get reported properly by
6721 cmd_error, so this must be just an informative message; toss it. */
6722 else if (INTERACTIVE
6723 && sf->glyphs_initialized_p
6724 && FRAME_MESSAGE_BUF (sf))
6726 Lisp_Object mini_window;
6727 Lisp_Object frame;
6728 struct frame *f;
6730 /* Get the frame containing the mini-buffer
6731 that the selected frame is using. */
6732 mini_window = FRAME_MINIBUF_WINDOW (sf);
6733 frame = XWINDOW (mini_window)->frame;
6734 f = XFRAME (frame);
6736 FRAME_SAMPLE_VISIBILITY (f);
6737 if (FRAME_VISIBLE_P (sf)
6738 && !FRAME_VISIBLE_P (f))
6739 Fmake_frame_visible (frame);
6741 if (STRINGP (m) && SCHARS (m) > 0)
6743 set_message (NULL, m, nbytes, multibyte);
6744 if (minibuffer_auto_raise)
6745 Fraise_frame (frame);
6747 else
6748 clear_message (1, 1);
6750 do_pending_window_change (0);
6751 echo_area_display (1);
6752 do_pending_window_change (0);
6753 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
6754 (*frame_up_to_date_hook) (f);
6759 /* Display a null-terminated echo area message M. If M is 0, clear
6760 out any existing message, and let the mini-buffer text show through.
6762 The buffer M must continue to exist until after the echo area gets
6763 cleared or some other message gets displayed there. Do not pass
6764 text that is stored in a Lisp string. Do not pass text in a buffer
6765 that was alloca'd. */
6767 void
6768 message1 (m)
6769 char *m;
6771 message2 (m, (m ? strlen (m) : 0), 0);
6775 /* The non-logging counterpart of message1. */
6777 void
6778 message1_nolog (m)
6779 char *m;
6781 message2_nolog (m, (m ? strlen (m) : 0), 0);
6784 /* Display a message M which contains a single %s
6785 which gets replaced with STRING. */
6787 void
6788 message_with_string (m, string, log)
6789 char *m;
6790 Lisp_Object string;
6791 int log;
6793 CHECK_STRING (string);
6795 if (noninteractive)
6797 if (m)
6799 if (noninteractive_need_newline)
6800 putc ('\n', stderr);
6801 noninteractive_need_newline = 0;
6802 fprintf (stderr, m, SDATA (string));
6803 if (cursor_in_echo_area == 0)
6804 fprintf (stderr, "\n");
6805 fflush (stderr);
6808 else if (INTERACTIVE)
6810 /* The frame whose minibuffer we're going to display the message on.
6811 It may be larger than the selected frame, so we need
6812 to use its buffer, not the selected frame's buffer. */
6813 Lisp_Object mini_window;
6814 struct frame *f, *sf = SELECTED_FRAME ();
6816 /* Get the frame containing the minibuffer
6817 that the selected frame is using. */
6818 mini_window = FRAME_MINIBUF_WINDOW (sf);
6819 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6821 /* A null message buffer means that the frame hasn't really been
6822 initialized yet. Error messages get reported properly by
6823 cmd_error, so this must be just an informative message; toss it. */
6824 if (FRAME_MESSAGE_BUF (f))
6826 Lisp_Object args[2], message;
6827 struct gcpro gcpro1, gcpro2;
6829 args[0] = build_string (m);
6830 args[1] = message = string;
6831 GCPRO2 (args[0], message);
6832 gcpro1.nvars = 2;
6834 message = Fformat (2, args);
6836 if (log)
6837 message3 (message, SBYTES (message), STRING_MULTIBYTE (message));
6838 else
6839 message3_nolog (message, SBYTES (message), STRING_MULTIBYTE (message));
6841 UNGCPRO;
6843 /* Print should start at the beginning of the message
6844 buffer next time. */
6845 message_buf_print = 0;
6851 /* Dump an informative message to the minibuf. If M is 0, clear out
6852 any existing message, and let the mini-buffer text show through. */
6854 /* VARARGS 1 */
6855 void
6856 message (m, a1, a2, a3)
6857 char *m;
6858 EMACS_INT a1, a2, a3;
6860 if (noninteractive)
6862 if (m)
6864 if (noninteractive_need_newline)
6865 putc ('\n', stderr);
6866 noninteractive_need_newline = 0;
6867 fprintf (stderr, m, a1, a2, a3);
6868 if (cursor_in_echo_area == 0)
6869 fprintf (stderr, "\n");
6870 fflush (stderr);
6873 else if (INTERACTIVE)
6875 /* The frame whose mini-buffer we're going to display the message
6876 on. It may be larger than the selected frame, so we need to
6877 use its buffer, not the selected frame's buffer. */
6878 Lisp_Object mini_window;
6879 struct frame *f, *sf = SELECTED_FRAME ();
6881 /* Get the frame containing the mini-buffer
6882 that the selected frame is using. */
6883 mini_window = FRAME_MINIBUF_WINDOW (sf);
6884 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6886 /* A null message buffer means that the frame hasn't really been
6887 initialized yet. Error messages get reported properly by
6888 cmd_error, so this must be just an informative message; toss
6889 it. */
6890 if (FRAME_MESSAGE_BUF (f))
6892 if (m)
6894 int len;
6895 #ifdef NO_ARG_ARRAY
6896 char *a[3];
6897 a[0] = (char *) a1;
6898 a[1] = (char *) a2;
6899 a[2] = (char *) a3;
6901 len = doprnt (FRAME_MESSAGE_BUF (f),
6902 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
6903 #else
6904 len = doprnt (FRAME_MESSAGE_BUF (f),
6905 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3,
6906 (char **) &a1);
6907 #endif /* NO_ARG_ARRAY */
6909 message2 (FRAME_MESSAGE_BUF (f), len, 0);
6911 else
6912 message1 (0);
6914 /* Print should start at the beginning of the message
6915 buffer next time. */
6916 message_buf_print = 0;
6922 /* The non-logging version of message. */
6924 void
6925 message_nolog (m, a1, a2, a3)
6926 char *m;
6927 EMACS_INT a1, a2, a3;
6929 Lisp_Object old_log_max;
6930 old_log_max = Vmessage_log_max;
6931 Vmessage_log_max = Qnil;
6932 message (m, a1, a2, a3);
6933 Vmessage_log_max = old_log_max;
6937 /* Display the current message in the current mini-buffer. This is
6938 only called from error handlers in process.c, and is not time
6939 critical. */
6941 void
6942 update_echo_area ()
6944 if (!NILP (echo_area_buffer[0]))
6946 Lisp_Object string;
6947 string = Fcurrent_message ();
6948 message3 (string, SBYTES (string),
6949 !NILP (current_buffer->enable_multibyte_characters));
6954 /* Make sure echo area buffers in `echo_buffers' are live.
6955 If they aren't, make new ones. */
6957 static void
6958 ensure_echo_area_buffers ()
6960 int i;
6962 for (i = 0; i < 2; ++i)
6963 if (!BUFFERP (echo_buffer[i])
6964 || NILP (XBUFFER (echo_buffer[i])->name))
6966 char name[30];
6967 Lisp_Object old_buffer;
6968 int j;
6970 old_buffer = echo_buffer[i];
6971 sprintf (name, " *Echo Area %d*", i);
6972 echo_buffer[i] = Fget_buffer_create (build_string (name));
6973 XBUFFER (echo_buffer[i])->truncate_lines = Qnil;
6975 for (j = 0; j < 2; ++j)
6976 if (EQ (old_buffer, echo_area_buffer[j]))
6977 echo_area_buffer[j] = echo_buffer[i];
6982 /* Call FN with args A1..A4 with either the current or last displayed
6983 echo_area_buffer as current buffer.
6985 WHICH zero means use the current message buffer
6986 echo_area_buffer[0]. If that is nil, choose a suitable buffer
6987 from echo_buffer[] and clear it.
6989 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
6990 suitable buffer from echo_buffer[] and clear it.
6992 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
6993 that the current message becomes the last displayed one, make
6994 choose a suitable buffer for echo_area_buffer[0], and clear it.
6996 Value is what FN returns. */
6998 static int
6999 with_echo_area_buffer (w, which, fn, a1, a2, a3, a4)
7000 struct window *w;
7001 int which;
7002 int (*fn) P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
7003 EMACS_INT a1;
7004 Lisp_Object a2;
7005 EMACS_INT a3, a4;
7007 Lisp_Object buffer;
7008 int this_one, the_other, clear_buffer_p, rc;
7009 int count = SPECPDL_INDEX ();
7011 /* If buffers aren't live, make new ones. */
7012 ensure_echo_area_buffers ();
7014 clear_buffer_p = 0;
7016 if (which == 0)
7017 this_one = 0, the_other = 1;
7018 else if (which > 0)
7019 this_one = 1, the_other = 0;
7020 else
7022 this_one = 0, the_other = 1;
7023 clear_buffer_p = 1;
7025 /* We need a fresh one in case the current echo buffer equals
7026 the one containing the last displayed echo area message. */
7027 if (!NILP (echo_area_buffer[this_one])
7028 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
7029 echo_area_buffer[this_one] = Qnil;
7032 /* Choose a suitable buffer from echo_buffer[] is we don't
7033 have one. */
7034 if (NILP (echo_area_buffer[this_one]))
7036 echo_area_buffer[this_one]
7037 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
7038 ? echo_buffer[the_other]
7039 : echo_buffer[this_one]);
7040 clear_buffer_p = 1;
7043 buffer = echo_area_buffer[this_one];
7045 /* Don't get confused by reusing the buffer used for echoing
7046 for a different purpose. */
7047 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
7048 cancel_echoing ();
7050 record_unwind_protect (unwind_with_echo_area_buffer,
7051 with_echo_area_buffer_unwind_data (w));
7053 /* Make the echo area buffer current. Note that for display
7054 purposes, it is not necessary that the displayed window's buffer
7055 == current_buffer, except for text property lookup. So, let's
7056 only set that buffer temporarily here without doing a full
7057 Fset_window_buffer. We must also change w->pointm, though,
7058 because otherwise an assertions in unshow_buffer fails, and Emacs
7059 aborts. */
7060 set_buffer_internal_1 (XBUFFER (buffer));
7061 if (w)
7063 w->buffer = buffer;
7064 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
7067 current_buffer->undo_list = Qt;
7068 current_buffer->read_only = Qnil;
7069 specbind (Qinhibit_read_only, Qt);
7070 specbind (Qinhibit_modification_hooks, Qt);
7072 if (clear_buffer_p && Z > BEG)
7073 del_range (BEG, Z);
7075 xassert (BEGV >= BEG);
7076 xassert (ZV <= Z && ZV >= BEGV);
7078 rc = fn (a1, a2, a3, a4);
7080 xassert (BEGV >= BEG);
7081 xassert (ZV <= Z && ZV >= BEGV);
7083 unbind_to (count, Qnil);
7084 return rc;
7088 /* Save state that should be preserved around the call to the function
7089 FN called in with_echo_area_buffer. */
7091 static Lisp_Object
7092 with_echo_area_buffer_unwind_data (w)
7093 struct window *w;
7095 int i = 0;
7096 Lisp_Object vector;
7098 /* Reduce consing by keeping one vector in
7099 Vwith_echo_area_save_vector. */
7100 vector = Vwith_echo_area_save_vector;
7101 Vwith_echo_area_save_vector = Qnil;
7103 if (NILP (vector))
7104 vector = Fmake_vector (make_number (7), Qnil);
7106 XSETBUFFER (AREF (vector, i), current_buffer); ++i;
7107 AREF (vector, i) = Vdeactivate_mark, ++i;
7108 AREF (vector, i) = make_number (windows_or_buffers_changed), ++i;
7110 if (w)
7112 XSETWINDOW (AREF (vector, i), w); ++i;
7113 AREF (vector, i) = w->buffer; ++i;
7114 AREF (vector, i) = make_number (XMARKER (w->pointm)->charpos); ++i;
7115 AREF (vector, i) = make_number (XMARKER (w->pointm)->bytepos); ++i;
7117 else
7119 int end = i + 4;
7120 for (; i < end; ++i)
7121 AREF (vector, i) = Qnil;
7124 xassert (i == ASIZE (vector));
7125 return vector;
7129 /* Restore global state from VECTOR which was created by
7130 with_echo_area_buffer_unwind_data. */
7132 static Lisp_Object
7133 unwind_with_echo_area_buffer (vector)
7134 Lisp_Object vector;
7136 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
7137 Vdeactivate_mark = AREF (vector, 1);
7138 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
7140 if (WINDOWP (AREF (vector, 3)))
7142 struct window *w;
7143 Lisp_Object buffer, charpos, bytepos;
7145 w = XWINDOW (AREF (vector, 3));
7146 buffer = AREF (vector, 4);
7147 charpos = AREF (vector, 5);
7148 bytepos = AREF (vector, 6);
7150 w->buffer = buffer;
7151 set_marker_both (w->pointm, buffer,
7152 XFASTINT (charpos), XFASTINT (bytepos));
7155 Vwith_echo_area_save_vector = vector;
7156 return Qnil;
7160 /* Set up the echo area for use by print functions. MULTIBYTE_P
7161 non-zero means we will print multibyte. */
7163 void
7164 setup_echo_area_for_printing (multibyte_p)
7165 int multibyte_p;
7167 /* If we can't find an echo area any more, exit. */
7168 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
7169 Fkill_emacs (Qnil);
7171 ensure_echo_area_buffers ();
7173 if (!message_buf_print)
7175 /* A message has been output since the last time we printed.
7176 Choose a fresh echo area buffer. */
7177 if (EQ (echo_area_buffer[1], echo_buffer[0]))
7178 echo_area_buffer[0] = echo_buffer[1];
7179 else
7180 echo_area_buffer[0] = echo_buffer[0];
7182 /* Switch to that buffer and clear it. */
7183 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
7184 current_buffer->truncate_lines = Qnil;
7186 if (Z > BEG)
7188 int count = SPECPDL_INDEX ();
7189 specbind (Qinhibit_read_only, Qt);
7190 /* Note that undo recording is always disabled. */
7191 del_range (BEG, Z);
7192 unbind_to (count, Qnil);
7194 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
7196 /* Set up the buffer for the multibyteness we need. */
7197 if (multibyte_p
7198 != !NILP (current_buffer->enable_multibyte_characters))
7199 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
7201 /* Raise the frame containing the echo area. */
7202 if (minibuffer_auto_raise)
7204 struct frame *sf = SELECTED_FRAME ();
7205 Lisp_Object mini_window;
7206 mini_window = FRAME_MINIBUF_WINDOW (sf);
7207 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
7210 message_log_maybe_newline ();
7211 message_buf_print = 1;
7213 else
7215 if (NILP (echo_area_buffer[0]))
7217 if (EQ (echo_area_buffer[1], echo_buffer[0]))
7218 echo_area_buffer[0] = echo_buffer[1];
7219 else
7220 echo_area_buffer[0] = echo_buffer[0];
7223 if (current_buffer != XBUFFER (echo_area_buffer[0]))
7225 /* Someone switched buffers between print requests. */
7226 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
7227 current_buffer->truncate_lines = Qnil;
7233 /* Display an echo area message in window W. Value is non-zero if W's
7234 height is changed. If display_last_displayed_message_p is
7235 non-zero, display the message that was last displayed, otherwise
7236 display the current message. */
7238 static int
7239 display_echo_area (w)
7240 struct window *w;
7242 int i, no_message_p, window_height_changed_p, count;
7244 /* Temporarily disable garbage collections while displaying the echo
7245 area. This is done because a GC can print a message itself.
7246 That message would modify the echo area buffer's contents while a
7247 redisplay of the buffer is going on, and seriously confuse
7248 redisplay. */
7249 count = inhibit_garbage_collection ();
7251 /* If there is no message, we must call display_echo_area_1
7252 nevertheless because it resizes the window. But we will have to
7253 reset the echo_area_buffer in question to nil at the end because
7254 with_echo_area_buffer will sets it to an empty buffer. */
7255 i = display_last_displayed_message_p ? 1 : 0;
7256 no_message_p = NILP (echo_area_buffer[i]);
7258 window_height_changed_p
7259 = with_echo_area_buffer (w, display_last_displayed_message_p,
7260 display_echo_area_1,
7261 (EMACS_INT) w, Qnil, 0, 0);
7263 if (no_message_p)
7264 echo_area_buffer[i] = Qnil;
7266 unbind_to (count, Qnil);
7267 return window_height_changed_p;
7271 /* Helper for display_echo_area. Display the current buffer which
7272 contains the current echo area message in window W, a mini-window,
7273 a pointer to which is passed in A1. A2..A4 are currently not used.
7274 Change the height of W so that all of the message is displayed.
7275 Value is non-zero if height of W was changed. */
7277 static int
7278 display_echo_area_1 (a1, a2, a3, a4)
7279 EMACS_INT a1;
7280 Lisp_Object a2;
7281 EMACS_INT a3, a4;
7283 struct window *w = (struct window *) a1;
7284 Lisp_Object window;
7285 struct text_pos start;
7286 int window_height_changed_p = 0;
7288 /* Do this before displaying, so that we have a large enough glyph
7289 matrix for the display. */
7290 window_height_changed_p = resize_mini_window (w, 0);
7292 /* Display. */
7293 clear_glyph_matrix (w->desired_matrix);
7294 XSETWINDOW (window, w);
7295 SET_TEXT_POS (start, BEG, BEG_BYTE);
7296 try_window (window, start);
7298 return window_height_changed_p;
7302 /* Resize the echo area window to exactly the size needed for the
7303 currently displayed message, if there is one. If a mini-buffer
7304 is active, don't shrink it. */
7306 void
7307 resize_echo_area_exactly ()
7309 if (BUFFERP (echo_area_buffer[0])
7310 && WINDOWP (echo_area_window))
7312 struct window *w = XWINDOW (echo_area_window);
7313 int resized_p;
7314 Lisp_Object resize_exactly;
7316 if (minibuf_level == 0)
7317 resize_exactly = Qt;
7318 else
7319 resize_exactly = Qnil;
7321 resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
7322 (EMACS_INT) w, resize_exactly, 0, 0);
7323 if (resized_p)
7325 ++windows_or_buffers_changed;
7326 ++update_mode_lines;
7327 redisplay_internal (0);
7333 /* Callback function for with_echo_area_buffer, when used from
7334 resize_echo_area_exactly. A1 contains a pointer to the window to
7335 resize, EXACTLY non-nil means resize the mini-window exactly to the
7336 size of the text displayed. A3 and A4 are not used. Value is what
7337 resize_mini_window returns. */
7339 static int
7340 resize_mini_window_1 (a1, exactly, a3, a4)
7341 EMACS_INT a1;
7342 Lisp_Object exactly;
7343 EMACS_INT a3, a4;
7345 return resize_mini_window ((struct window *) a1, !NILP (exactly));
7349 /* Resize mini-window W to fit the size of its contents. EXACT:P
7350 means size the window exactly to the size needed. Otherwise, it's
7351 only enlarged until W's buffer is empty. Value is non-zero if
7352 the window height has been changed. */
7355 resize_mini_window (w, exact_p)
7356 struct window *w;
7357 int exact_p;
7359 struct frame *f = XFRAME (w->frame);
7360 int window_height_changed_p = 0;
7362 xassert (MINI_WINDOW_P (w));
7364 /* Don't resize windows while redisplaying a window; it would
7365 confuse redisplay functions when the size of the window they are
7366 displaying changes from under them. Such a resizing can happen,
7367 for instance, when which-func prints a long message while
7368 we are running fontification-functions. We're running these
7369 functions with safe_call which binds inhibit-redisplay to t. */
7370 if (!NILP (Vinhibit_redisplay))
7371 return 0;
7373 /* Nil means don't try to resize. */
7374 if (NILP (Vresize_mini_windows)
7375 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
7376 return 0;
7378 if (!FRAME_MINIBUF_ONLY_P (f))
7380 struct it it;
7381 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
7382 int total_height = WINDOW_TOTAL_LINES (root) + WINDOW_TOTAL_LINES (w);
7383 int height, max_height;
7384 int unit = FRAME_LINE_HEIGHT (f);
7385 struct text_pos start;
7386 struct buffer *old_current_buffer = NULL;
7388 if (current_buffer != XBUFFER (w->buffer))
7390 old_current_buffer = current_buffer;
7391 set_buffer_internal (XBUFFER (w->buffer));
7394 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
7396 /* Compute the max. number of lines specified by the user. */
7397 if (FLOATP (Vmax_mini_window_height))
7398 max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_LINES (f);
7399 else if (INTEGERP (Vmax_mini_window_height))
7400 max_height = XINT (Vmax_mini_window_height);
7401 else
7402 max_height = total_height / 4;
7404 /* Correct that max. height if it's bogus. */
7405 max_height = max (1, max_height);
7406 max_height = min (total_height, max_height);
7408 /* Find out the height of the text in the window. */
7409 if (it.truncate_lines_p)
7410 height = 1;
7411 else
7413 last_height = 0;
7414 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
7415 if (it.max_ascent == 0 && it.max_descent == 0)
7416 height = it.current_y + last_height;
7417 else
7418 height = it.current_y + it.max_ascent + it.max_descent;
7419 height -= it.extra_line_spacing;
7420 height = (height + unit - 1) / unit;
7423 /* Compute a suitable window start. */
7424 if (height > max_height)
7426 height = max_height;
7427 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
7428 move_it_vertically_backward (&it, (height - 1) * unit);
7429 start = it.current.pos;
7431 else
7432 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
7433 SET_MARKER_FROM_TEXT_POS (w->start, start);
7435 if (EQ (Vresize_mini_windows, Qgrow_only))
7437 /* Let it grow only, until we display an empty message, in which
7438 case the window shrinks again. */
7439 if (height > WINDOW_TOTAL_LINES (w))
7441 int old_height = WINDOW_TOTAL_LINES (w);
7442 freeze_window_starts (f, 1);
7443 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7444 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7446 else if (height < WINDOW_TOTAL_LINES (w)
7447 && (exact_p || BEGV == ZV))
7449 int old_height = WINDOW_TOTAL_LINES (w);
7450 freeze_window_starts (f, 0);
7451 shrink_mini_window (w);
7452 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7455 else
7457 /* Always resize to exact size needed. */
7458 if (height > WINDOW_TOTAL_LINES (w))
7460 int old_height = WINDOW_TOTAL_LINES (w);
7461 freeze_window_starts (f, 1);
7462 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7463 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7465 else if (height < WINDOW_TOTAL_LINES (w))
7467 int old_height = WINDOW_TOTAL_LINES (w);
7468 freeze_window_starts (f, 0);
7469 shrink_mini_window (w);
7471 if (height)
7473 freeze_window_starts (f, 1);
7474 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7477 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7481 if (old_current_buffer)
7482 set_buffer_internal (old_current_buffer);
7485 return window_height_changed_p;
7489 /* Value is the current message, a string, or nil if there is no
7490 current message. */
7492 Lisp_Object
7493 current_message ()
7495 Lisp_Object msg;
7497 if (NILP (echo_area_buffer[0]))
7498 msg = Qnil;
7499 else
7501 with_echo_area_buffer (0, 0, current_message_1,
7502 (EMACS_INT) &msg, Qnil, 0, 0);
7503 if (NILP (msg))
7504 echo_area_buffer[0] = Qnil;
7507 return msg;
7511 static int
7512 current_message_1 (a1, a2, a3, a4)
7513 EMACS_INT a1;
7514 Lisp_Object a2;
7515 EMACS_INT a3, a4;
7517 Lisp_Object *msg = (Lisp_Object *) a1;
7519 if (Z > BEG)
7520 *msg = make_buffer_string (BEG, Z, 1);
7521 else
7522 *msg = Qnil;
7523 return 0;
7527 /* Push the current message on Vmessage_stack for later restauration
7528 by restore_message. Value is non-zero if the current message isn't
7529 empty. This is a relatively infrequent operation, so it's not
7530 worth optimizing. */
7533 push_message ()
7535 Lisp_Object msg;
7536 msg = current_message ();
7537 Vmessage_stack = Fcons (msg, Vmessage_stack);
7538 return STRINGP (msg);
7542 /* Restore message display from the top of Vmessage_stack. */
7544 void
7545 restore_message ()
7547 Lisp_Object msg;
7549 xassert (CONSP (Vmessage_stack));
7550 msg = XCAR (Vmessage_stack);
7551 if (STRINGP (msg))
7552 message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
7553 else
7554 message3_nolog (msg, 0, 0);
7558 /* Handler for record_unwind_protect calling pop_message. */
7560 Lisp_Object
7561 pop_message_unwind (dummy)
7562 Lisp_Object dummy;
7564 pop_message ();
7565 return Qnil;
7568 /* Pop the top-most entry off Vmessage_stack. */
7570 void
7571 pop_message ()
7573 xassert (CONSP (Vmessage_stack));
7574 Vmessage_stack = XCDR (Vmessage_stack);
7578 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
7579 exits. If the stack is not empty, we have a missing pop_message
7580 somewhere. */
7582 void
7583 check_message_stack ()
7585 if (!NILP (Vmessage_stack))
7586 abort ();
7590 /* Truncate to NCHARS what will be displayed in the echo area the next
7591 time we display it---but don't redisplay it now. */
7593 void
7594 truncate_echo_area (nchars)
7595 int nchars;
7597 if (nchars == 0)
7598 echo_area_buffer[0] = Qnil;
7599 /* A null message buffer means that the frame hasn't really been
7600 initialized yet. Error messages get reported properly by
7601 cmd_error, so this must be just an informative message; toss it. */
7602 else if (!noninteractive
7603 && INTERACTIVE
7604 && !NILP (echo_area_buffer[0]))
7606 struct frame *sf = SELECTED_FRAME ();
7607 if (FRAME_MESSAGE_BUF (sf))
7608 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil, 0, 0);
7613 /* Helper function for truncate_echo_area. Truncate the current
7614 message to at most NCHARS characters. */
7616 static int
7617 truncate_message_1 (nchars, a2, a3, a4)
7618 EMACS_INT nchars;
7619 Lisp_Object a2;
7620 EMACS_INT a3, a4;
7622 if (BEG + nchars < Z)
7623 del_range (BEG + nchars, Z);
7624 if (Z == BEG)
7625 echo_area_buffer[0] = Qnil;
7626 return 0;
7630 /* Set the current message to a substring of S or STRING.
7632 If STRING is a Lisp string, set the message to the first NBYTES
7633 bytes from STRING. NBYTES zero means use the whole string. If
7634 STRING is multibyte, the message will be displayed multibyte.
7636 If S is not null, set the message to the first LEN bytes of S. LEN
7637 zero means use the whole string. MULTIBYTE_P non-zero means S is
7638 multibyte. Display the message multibyte in that case. */
7640 void
7641 set_message (s, string, nbytes, multibyte_p)
7642 const char *s;
7643 Lisp_Object string;
7644 int nbytes, multibyte_p;
7646 message_enable_multibyte
7647 = ((s && multibyte_p)
7648 || (STRINGP (string) && STRING_MULTIBYTE (string)));
7650 with_echo_area_buffer (0, -1, set_message_1,
7651 (EMACS_INT) s, string, nbytes, multibyte_p);
7652 message_buf_print = 0;
7653 help_echo_showing_p = 0;
7657 /* Helper function for set_message. Arguments have the same meaning
7658 as there, with A1 corresponding to S and A2 corresponding to STRING
7659 This function is called with the echo area buffer being
7660 current. */
7662 static int
7663 set_message_1 (a1, a2, nbytes, multibyte_p)
7664 EMACS_INT a1;
7665 Lisp_Object a2;
7666 EMACS_INT nbytes, multibyte_p;
7668 const char *s = (const char *) a1;
7669 Lisp_Object string = a2;
7671 xassert (BEG == Z);
7673 /* Change multibyteness of the echo buffer appropriately. */
7674 if (message_enable_multibyte
7675 != !NILP (current_buffer->enable_multibyte_characters))
7676 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
7678 current_buffer->truncate_lines = message_truncate_lines ? Qt : Qnil;
7680 /* Insert new message at BEG. */
7681 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
7683 if (STRINGP (string))
7685 int nchars;
7687 if (nbytes == 0)
7688 nbytes = SBYTES (string);
7689 nchars = string_byte_to_char (string, nbytes);
7691 /* This function takes care of single/multibyte conversion. We
7692 just have to ensure that the echo area buffer has the right
7693 setting of enable_multibyte_characters. */
7694 insert_from_string (string, 0, 0, nchars, nbytes, 1);
7696 else if (s)
7698 if (nbytes == 0)
7699 nbytes = strlen (s);
7701 if (multibyte_p && NILP (current_buffer->enable_multibyte_characters))
7703 /* Convert from multi-byte to single-byte. */
7704 int i, c, n;
7705 unsigned char work[1];
7707 /* Convert a multibyte string to single-byte. */
7708 for (i = 0; i < nbytes; i += n)
7710 c = string_char_and_length (s + i, nbytes - i, &n);
7711 work[0] = (SINGLE_BYTE_CHAR_P (c)
7713 : multibyte_char_to_unibyte (c, Qnil));
7714 insert_1_both (work, 1, 1, 1, 0, 0);
7717 else if (!multibyte_p
7718 && !NILP (current_buffer->enable_multibyte_characters))
7720 /* Convert from single-byte to multi-byte. */
7721 int i, c, n;
7722 const unsigned char *msg = (const unsigned char *) s;
7723 unsigned char str[MAX_MULTIBYTE_LENGTH];
7725 /* Convert a single-byte string to multibyte. */
7726 for (i = 0; i < nbytes; i++)
7728 c = unibyte_char_to_multibyte (msg[i]);
7729 n = CHAR_STRING (c, str);
7730 insert_1_both (str, 1, n, 1, 0, 0);
7733 else
7734 insert_1 (s, nbytes, 1, 0, 0);
7737 return 0;
7741 /* Clear messages. CURRENT_P non-zero means clear the current
7742 message. LAST_DISPLAYED_P non-zero means clear the message
7743 last displayed. */
7745 void
7746 clear_message (current_p, last_displayed_p)
7747 int current_p, last_displayed_p;
7749 if (current_p)
7751 echo_area_buffer[0] = Qnil;
7752 message_cleared_p = 1;
7755 if (last_displayed_p)
7756 echo_area_buffer[1] = Qnil;
7758 message_buf_print = 0;
7761 /* Clear garbaged frames.
7763 This function is used where the old redisplay called
7764 redraw_garbaged_frames which in turn called redraw_frame which in
7765 turn called clear_frame. The call to clear_frame was a source of
7766 flickering. I believe a clear_frame is not necessary. It should
7767 suffice in the new redisplay to invalidate all current matrices,
7768 and ensure a complete redisplay of all windows. */
7770 static void
7771 clear_garbaged_frames ()
7773 if (frame_garbaged)
7775 Lisp_Object tail, frame;
7776 int changed_count = 0;
7778 FOR_EACH_FRAME (tail, frame)
7780 struct frame *f = XFRAME (frame);
7782 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
7784 if (f->resized_p)
7786 Fredraw_frame (frame);
7787 f->force_flush_display_p = 1;
7789 clear_current_matrices (f);
7790 changed_count++;
7791 f->garbaged = 0;
7792 f->resized_p = 0;
7796 frame_garbaged = 0;
7797 if (changed_count)
7798 ++windows_or_buffers_changed;
7803 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
7804 is non-zero update selected_frame. Value is non-zero if the
7805 mini-windows height has been changed. */
7807 static int
7808 echo_area_display (update_frame_p)
7809 int update_frame_p;
7811 Lisp_Object mini_window;
7812 struct window *w;
7813 struct frame *f;
7814 int window_height_changed_p = 0;
7815 struct frame *sf = SELECTED_FRAME ();
7817 mini_window = FRAME_MINIBUF_WINDOW (sf);
7818 w = XWINDOW (mini_window);
7819 f = XFRAME (WINDOW_FRAME (w));
7821 /* Don't display if frame is invisible or not yet initialized. */
7822 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
7823 return 0;
7825 /* The terminal frame is used as the first Emacs frame on the Mac OS. */
7826 #ifndef MAC_OS8
7827 #ifdef HAVE_WINDOW_SYSTEM
7828 /* When Emacs starts, selected_frame may be a visible terminal
7829 frame, even if we run under a window system. If we let this
7830 through, a message would be displayed on the terminal. */
7831 if (EQ (selected_frame, Vterminal_frame)
7832 && !NILP (Vwindow_system))
7833 return 0;
7834 #endif /* HAVE_WINDOW_SYSTEM */
7835 #endif
7837 /* Redraw garbaged frames. */
7838 if (frame_garbaged)
7839 clear_garbaged_frames ();
7841 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
7843 echo_area_window = mini_window;
7844 window_height_changed_p = display_echo_area (w);
7845 w->must_be_updated_p = 1;
7847 /* Update the display, unless called from redisplay_internal.
7848 Also don't update the screen during redisplay itself. The
7849 update will happen at the end of redisplay, and an update
7850 here could cause confusion. */
7851 if (update_frame_p && !redisplaying_p)
7853 int n = 0;
7855 /* If the display update has been interrupted by pending
7856 input, update mode lines in the frame. Due to the
7857 pending input, it might have been that redisplay hasn't
7858 been called, so that mode lines above the echo area are
7859 garbaged. This looks odd, so we prevent it here. */
7860 if (!display_completed)
7861 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), 0);
7863 if (window_height_changed_p
7864 /* Don't do this if Emacs is shutting down. Redisplay
7865 needs to run hooks. */
7866 && !NILP (Vrun_hooks))
7868 /* Must update other windows. Likewise as in other
7869 cases, don't let this update be interrupted by
7870 pending input. */
7871 int count = SPECPDL_INDEX ();
7872 specbind (Qredisplay_dont_pause, Qt);
7873 windows_or_buffers_changed = 1;
7874 redisplay_internal (0);
7875 unbind_to (count, Qnil);
7877 else if (FRAME_WINDOW_P (f) && n == 0)
7879 /* Window configuration is the same as before.
7880 Can do with a display update of the echo area,
7881 unless we displayed some mode lines. */
7882 update_single_window (w, 1);
7883 rif->flush_display (f);
7885 else
7886 update_frame (f, 1, 1);
7888 /* If cursor is in the echo area, make sure that the next
7889 redisplay displays the minibuffer, so that the cursor will
7890 be replaced with what the minibuffer wants. */
7891 if (cursor_in_echo_area)
7892 ++windows_or_buffers_changed;
7895 else if (!EQ (mini_window, selected_window))
7896 windows_or_buffers_changed++;
7898 /* Last displayed message is now the current message. */
7899 echo_area_buffer[1] = echo_area_buffer[0];
7901 /* Prevent redisplay optimization in redisplay_internal by resetting
7902 this_line_start_pos. This is done because the mini-buffer now
7903 displays the message instead of its buffer text. */
7904 if (EQ (mini_window, selected_window))
7905 CHARPOS (this_line_start_pos) = 0;
7907 return window_height_changed_p;
7912 /***********************************************************************
7913 Frame Titles
7914 ***********************************************************************/
7917 /* The frame title buffering code is also used by Fformat_mode_line.
7918 So it is not conditioned by HAVE_WINDOW_SYSTEM. */
7920 /* A buffer for constructing frame titles in it; allocated from the
7921 heap in init_xdisp and resized as needed in store_frame_title_char. */
7923 static char *frame_title_buf;
7925 /* The buffer's end, and a current output position in it. */
7927 static char *frame_title_buf_end;
7928 static char *frame_title_ptr;
7931 /* Store a single character C for the frame title in frame_title_buf.
7932 Re-allocate frame_title_buf if necessary. */
7934 static void
7935 #ifdef PROTOTYPES
7936 store_frame_title_char (char c)
7937 #else
7938 store_frame_title_char (c)
7939 char c;
7940 #endif
7942 /* If output position has reached the end of the allocated buffer,
7943 double the buffer's size. */
7944 if (frame_title_ptr == frame_title_buf_end)
7946 int len = frame_title_ptr - frame_title_buf;
7947 int new_size = 2 * len * sizeof *frame_title_buf;
7948 frame_title_buf = (char *) xrealloc (frame_title_buf, new_size);
7949 frame_title_buf_end = frame_title_buf + new_size;
7950 frame_title_ptr = frame_title_buf + len;
7953 *frame_title_ptr++ = c;
7957 /* Store part of a frame title in frame_title_buf, beginning at
7958 frame_title_ptr. STR is the string to store. Do not copy
7959 characters that yield more columns than PRECISION; PRECISION <= 0
7960 means copy the whole string. Pad with spaces until FIELD_WIDTH
7961 number of characters have been copied; FIELD_WIDTH <= 0 means don't
7962 pad. Called from display_mode_element when it is used to build a
7963 frame title. */
7965 static int
7966 store_frame_title (str, field_width, precision)
7967 const unsigned char *str;
7968 int field_width, precision;
7970 int n = 0;
7971 int dummy, nbytes;
7973 /* Copy at most PRECISION chars from STR. */
7974 nbytes = strlen (str);
7975 n+= c_string_width (str, nbytes, precision, &dummy, &nbytes);
7976 while (nbytes--)
7977 store_frame_title_char (*str++);
7979 /* Fill up with spaces until FIELD_WIDTH reached. */
7980 while (field_width > 0
7981 && n < field_width)
7983 store_frame_title_char (' ');
7984 ++n;
7987 return n;
7990 #ifdef HAVE_WINDOW_SYSTEM
7992 /* Set the title of FRAME, if it has changed. The title format is
7993 Vicon_title_format if FRAME is iconified, otherwise it is
7994 frame_title_format. */
7996 static void
7997 x_consider_frame_title (frame)
7998 Lisp_Object frame;
8000 struct frame *f = XFRAME (frame);
8002 if (FRAME_WINDOW_P (f)
8003 || FRAME_MINIBUF_ONLY_P (f)
8004 || f->explicit_name)
8006 /* Do we have more than one visible frame on this X display? */
8007 Lisp_Object tail;
8008 Lisp_Object fmt;
8009 struct buffer *obuf;
8010 int len;
8011 struct it it;
8013 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
8015 Lisp_Object other_frame = XCAR (tail);
8016 struct frame *tf = XFRAME (other_frame);
8018 if (tf != f
8019 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
8020 && !FRAME_MINIBUF_ONLY_P (tf)
8021 && !EQ (other_frame, tip_frame)
8022 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
8023 break;
8026 /* Set global variable indicating that multiple frames exist. */
8027 multiple_frames = CONSP (tail);
8029 /* Switch to the buffer of selected window of the frame. Set up
8030 frame_title_ptr so that display_mode_element will output into it;
8031 then display the title. */
8032 obuf = current_buffer;
8033 set_buffer_internal_1 (XBUFFER (XWINDOW (f->selected_window)->buffer));
8034 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
8035 frame_title_ptr = frame_title_buf;
8036 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
8037 NULL, DEFAULT_FACE_ID);
8038 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
8039 len = frame_title_ptr - frame_title_buf;
8040 frame_title_ptr = NULL;
8041 set_buffer_internal_1 (obuf);
8043 /* Set the title only if it's changed. This avoids consing in
8044 the common case where it hasn't. (If it turns out that we've
8045 already wasted too much time by walking through the list with
8046 display_mode_element, then we might need to optimize at a
8047 higher level than this.) */
8048 if (! STRINGP (f->name)
8049 || SBYTES (f->name) != len
8050 || bcmp (frame_title_buf, SDATA (f->name), len) != 0)
8051 x_implicitly_set_name (f, make_string (frame_title_buf, len), Qnil);
8055 #endif /* not HAVE_WINDOW_SYSTEM */
8060 /***********************************************************************
8061 Menu Bars
8062 ***********************************************************************/
8065 /* Prepare for redisplay by updating menu-bar item lists when
8066 appropriate. This can call eval. */
8068 void
8069 prepare_menu_bars ()
8071 int all_windows;
8072 struct gcpro gcpro1, gcpro2;
8073 struct frame *f;
8074 Lisp_Object tooltip_frame;
8076 #ifdef HAVE_WINDOW_SYSTEM
8077 tooltip_frame = tip_frame;
8078 #else
8079 tooltip_frame = Qnil;
8080 #endif
8082 /* Update all frame titles based on their buffer names, etc. We do
8083 this before the menu bars so that the buffer-menu will show the
8084 up-to-date frame titles. */
8085 #ifdef HAVE_WINDOW_SYSTEM
8086 if (windows_or_buffers_changed || update_mode_lines)
8088 Lisp_Object tail, frame;
8090 FOR_EACH_FRAME (tail, frame)
8092 f = XFRAME (frame);
8093 if (!EQ (frame, tooltip_frame)
8094 && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)))
8095 x_consider_frame_title (frame);
8098 #endif /* HAVE_WINDOW_SYSTEM */
8100 /* Update the menu bar item lists, if appropriate. This has to be
8101 done before any actual redisplay or generation of display lines. */
8102 all_windows = (update_mode_lines
8103 || buffer_shared > 1
8104 || windows_or_buffers_changed);
8105 if (all_windows)
8107 Lisp_Object tail, frame;
8108 int count = SPECPDL_INDEX ();
8110 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
8112 FOR_EACH_FRAME (tail, frame)
8114 f = XFRAME (frame);
8116 /* Ignore tooltip frame. */
8117 if (EQ (frame, tooltip_frame))
8118 continue;
8120 /* If a window on this frame changed size, report that to
8121 the user and clear the size-change flag. */
8122 if (FRAME_WINDOW_SIZES_CHANGED (f))
8124 Lisp_Object functions;
8126 /* Clear flag first in case we get an error below. */
8127 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
8128 functions = Vwindow_size_change_functions;
8129 GCPRO2 (tail, functions);
8131 while (CONSP (functions))
8133 call1 (XCAR (functions), frame);
8134 functions = XCDR (functions);
8136 UNGCPRO;
8139 GCPRO1 (tail);
8140 update_menu_bar (f, 0);
8141 #ifdef HAVE_WINDOW_SYSTEM
8142 update_tool_bar (f, 0);
8143 #endif
8144 UNGCPRO;
8147 unbind_to (count, Qnil);
8149 else
8151 struct frame *sf = SELECTED_FRAME ();
8152 update_menu_bar (sf, 1);
8153 #ifdef HAVE_WINDOW_SYSTEM
8154 update_tool_bar (sf, 1);
8155 #endif
8158 /* Motif needs this. See comment in xmenu.c. Turn it off when
8159 pending_menu_activation is not defined. */
8160 #ifdef USE_X_TOOLKIT
8161 pending_menu_activation = 0;
8162 #endif
8166 /* Update the menu bar item list for frame F. This has to be done
8167 before we start to fill in any display lines, because it can call
8168 eval.
8170 If SAVE_MATCH_DATA is non-zero, we must save and restore it here. */
8172 static void
8173 update_menu_bar (f, save_match_data)
8174 struct frame *f;
8175 int save_match_data;
8177 Lisp_Object window;
8178 register struct window *w;
8180 /* If called recursively during a menu update, do nothing. This can
8181 happen when, for instance, an activate-menubar-hook causes a
8182 redisplay. */
8183 if (inhibit_menubar_update)
8184 return;
8186 window = FRAME_SELECTED_WINDOW (f);
8187 w = XWINDOW (window);
8189 #if 0 /* The if statement below this if statement used to include the
8190 condition !NILP (w->update_mode_line), rather than using
8191 update_mode_lines directly, and this if statement may have
8192 been added to make that condition work. Now the if
8193 statement below matches its comment, this isn't needed. */
8194 if (update_mode_lines)
8195 w->update_mode_line = Qt;
8196 #endif
8198 if (FRAME_WINDOW_P (f)
8200 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
8201 || defined (USE_GTK)
8202 FRAME_EXTERNAL_MENU_BAR (f)
8203 #else
8204 FRAME_MENU_BAR_LINES (f) > 0
8205 #endif
8206 : FRAME_MENU_BAR_LINES (f) > 0)
8208 /* If the user has switched buffers or windows, we need to
8209 recompute to reflect the new bindings. But we'll
8210 recompute when update_mode_lines is set too; that means
8211 that people can use force-mode-line-update to request
8212 that the menu bar be recomputed. The adverse effect on
8213 the rest of the redisplay algorithm is about the same as
8214 windows_or_buffers_changed anyway. */
8215 if (windows_or_buffers_changed
8216 /* This used to test w->update_mode_line, but we believe
8217 there is no need to recompute the menu in that case. */
8218 || update_mode_lines
8219 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
8220 < BUF_MODIFF (XBUFFER (w->buffer)))
8221 != !NILP (w->last_had_star))
8222 || ((!NILP (Vtransient_mark_mode)
8223 && !NILP (XBUFFER (w->buffer)->mark_active))
8224 != !NILP (w->region_showing)))
8226 struct buffer *prev = current_buffer;
8227 int count = SPECPDL_INDEX ();
8229 specbind (Qinhibit_menubar_update, Qt);
8231 set_buffer_internal_1 (XBUFFER (w->buffer));
8232 if (save_match_data)
8233 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
8234 if (NILP (Voverriding_local_map_menu_flag))
8236 specbind (Qoverriding_terminal_local_map, Qnil);
8237 specbind (Qoverriding_local_map, Qnil);
8240 /* Run the Lucid hook. */
8241 safe_run_hooks (Qactivate_menubar_hook);
8243 /* If it has changed current-menubar from previous value,
8244 really recompute the menu-bar from the value. */
8245 if (! NILP (Vlucid_menu_bar_dirty_flag))
8246 call0 (Qrecompute_lucid_menubar);
8248 safe_run_hooks (Qmenu_bar_update_hook);
8249 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
8251 /* Redisplay the menu bar in case we changed it. */
8252 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
8253 || defined (USE_GTK)
8254 if (FRAME_WINDOW_P (f)
8255 #if defined (MAC_OS)
8256 /* All frames on Mac OS share the same menubar. So only the
8257 selected frame should be allowed to set it. */
8258 && f == SELECTED_FRAME ()
8259 #endif
8261 set_frame_menubar (f, 0, 0);
8262 else
8263 /* On a terminal screen, the menu bar is an ordinary screen
8264 line, and this makes it get updated. */
8265 w->update_mode_line = Qt;
8266 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
8267 /* In the non-toolkit version, the menu bar is an ordinary screen
8268 line, and this makes it get updated. */
8269 w->update_mode_line = Qt;
8270 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
8272 unbind_to (count, Qnil);
8273 set_buffer_internal_1 (prev);
8280 /***********************************************************************
8281 Output Cursor
8282 ***********************************************************************/
8284 #ifdef HAVE_WINDOW_SYSTEM
8286 /* EXPORT:
8287 Nominal cursor position -- where to draw output.
8288 HPOS and VPOS are window relative glyph matrix coordinates.
8289 X and Y are window relative pixel coordinates. */
8291 struct cursor_pos output_cursor;
8294 /* EXPORT:
8295 Set the global variable output_cursor to CURSOR. All cursor
8296 positions are relative to updated_window. */
8298 void
8299 set_output_cursor (cursor)
8300 struct cursor_pos *cursor;
8302 output_cursor.hpos = cursor->hpos;
8303 output_cursor.vpos = cursor->vpos;
8304 output_cursor.x = cursor->x;
8305 output_cursor.y = cursor->y;
8309 /* EXPORT for RIF:
8310 Set a nominal cursor position.
8312 HPOS and VPOS are column/row positions in a window glyph matrix. X
8313 and Y are window text area relative pixel positions.
8315 If this is done during an update, updated_window will contain the
8316 window that is being updated and the position is the future output
8317 cursor position for that window. If updated_window is null, use
8318 selected_window and display the cursor at the given position. */
8320 void
8321 x_cursor_to (vpos, hpos, y, x)
8322 int vpos, hpos, y, x;
8324 struct window *w;
8326 /* If updated_window is not set, work on selected_window. */
8327 if (updated_window)
8328 w = updated_window;
8329 else
8330 w = XWINDOW (selected_window);
8332 /* Set the output cursor. */
8333 output_cursor.hpos = hpos;
8334 output_cursor.vpos = vpos;
8335 output_cursor.x = x;
8336 output_cursor.y = y;
8338 /* If not called as part of an update, really display the cursor.
8339 This will also set the cursor position of W. */
8340 if (updated_window == NULL)
8342 BLOCK_INPUT;
8343 display_and_set_cursor (w, 1, hpos, vpos, x, y);
8344 if (rif->flush_display_optional)
8345 rif->flush_display_optional (SELECTED_FRAME ());
8346 UNBLOCK_INPUT;
8350 #endif /* HAVE_WINDOW_SYSTEM */
8353 /***********************************************************************
8354 Tool-bars
8355 ***********************************************************************/
8357 #ifdef HAVE_WINDOW_SYSTEM
8359 /* Where the mouse was last time we reported a mouse event. */
8361 FRAME_PTR last_mouse_frame;
8363 /* Tool-bar item index of the item on which a mouse button was pressed
8364 or -1. */
8366 int last_tool_bar_item;
8369 /* Update the tool-bar item list for frame F. This has to be done
8370 before we start to fill in any display lines. Called from
8371 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
8372 and restore it here. */
8374 static void
8375 update_tool_bar (f, save_match_data)
8376 struct frame *f;
8377 int save_match_data;
8379 #ifdef USE_GTK
8380 int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
8381 #else
8382 int do_update = WINDOWP (f->tool_bar_window)
8383 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0;
8384 #endif
8386 if (do_update)
8388 Lisp_Object window;
8389 struct window *w;
8391 window = FRAME_SELECTED_WINDOW (f);
8392 w = XWINDOW (window);
8394 /* If the user has switched buffers or windows, we need to
8395 recompute to reflect the new bindings. But we'll
8396 recompute when update_mode_lines is set too; that means
8397 that people can use force-mode-line-update to request
8398 that the menu bar be recomputed. The adverse effect on
8399 the rest of the redisplay algorithm is about the same as
8400 windows_or_buffers_changed anyway. */
8401 if (windows_or_buffers_changed
8402 || !NILP (w->update_mode_line)
8403 || update_mode_lines
8404 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
8405 < BUF_MODIFF (XBUFFER (w->buffer)))
8406 != !NILP (w->last_had_star))
8407 || ((!NILP (Vtransient_mark_mode)
8408 && !NILP (XBUFFER (w->buffer)->mark_active))
8409 != !NILP (w->region_showing)))
8411 struct buffer *prev = current_buffer;
8412 int count = SPECPDL_INDEX ();
8413 Lisp_Object old_tool_bar;
8414 struct gcpro gcpro1;
8416 /* Set current_buffer to the buffer of the selected
8417 window of the frame, so that we get the right local
8418 keymaps. */
8419 set_buffer_internal_1 (XBUFFER (w->buffer));
8421 /* Save match data, if we must. */
8422 if (save_match_data)
8423 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
8425 /* Make sure that we don't accidentally use bogus keymaps. */
8426 if (NILP (Voverriding_local_map_menu_flag))
8428 specbind (Qoverriding_terminal_local_map, Qnil);
8429 specbind (Qoverriding_local_map, Qnil);
8432 old_tool_bar = f->tool_bar_items;
8433 GCPRO1 (old_tool_bar);
8435 /* Build desired tool-bar items from keymaps. */
8436 BLOCK_INPUT;
8437 f->tool_bar_items
8438 = tool_bar_items (f->tool_bar_items, &f->n_tool_bar_items);
8439 UNBLOCK_INPUT;
8441 /* Redisplay the tool-bar if we changed it. */
8442 if (! NILP (Fequal (old_tool_bar, f->tool_bar_items)))
8443 w->update_mode_line = Qt;
8445 UNGCPRO;
8447 unbind_to (count, Qnil);
8448 set_buffer_internal_1 (prev);
8454 /* Set F->desired_tool_bar_string to a Lisp string representing frame
8455 F's desired tool-bar contents. F->tool_bar_items must have
8456 been set up previously by calling prepare_menu_bars. */
8458 static void
8459 build_desired_tool_bar_string (f)
8460 struct frame *f;
8462 int i, size, size_needed;
8463 struct gcpro gcpro1, gcpro2, gcpro3;
8464 Lisp_Object image, plist, props;
8466 image = plist = props = Qnil;
8467 GCPRO3 (image, plist, props);
8469 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
8470 Otherwise, make a new string. */
8472 /* The size of the string we might be able to reuse. */
8473 size = (STRINGP (f->desired_tool_bar_string)
8474 ? SCHARS (f->desired_tool_bar_string)
8475 : 0);
8477 /* We need one space in the string for each image. */
8478 size_needed = f->n_tool_bar_items;
8480 /* Reuse f->desired_tool_bar_string, if possible. */
8481 if (size < size_needed || NILP (f->desired_tool_bar_string))
8482 f->desired_tool_bar_string = Fmake_string (make_number (size_needed),
8483 make_number (' '));
8484 else
8486 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
8487 Fremove_text_properties (make_number (0), make_number (size),
8488 props, f->desired_tool_bar_string);
8491 /* Put a `display' property on the string for the images to display,
8492 put a `menu_item' property on tool-bar items with a value that
8493 is the index of the item in F's tool-bar item vector. */
8494 for (i = 0; i < f->n_tool_bar_items; ++i)
8496 #define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
8498 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
8499 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
8500 int hmargin, vmargin, relief, idx, end;
8501 extern Lisp_Object QCrelief, QCmargin, QCconversion;
8503 /* If image is a vector, choose the image according to the
8504 button state. */
8505 image = PROP (TOOL_BAR_ITEM_IMAGES);
8506 if (VECTORP (image))
8508 if (enabled_p)
8509 idx = (selected_p
8510 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
8511 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
8512 else
8513 idx = (selected_p
8514 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
8515 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
8517 xassert (ASIZE (image) >= idx);
8518 image = AREF (image, idx);
8520 else
8521 idx = -1;
8523 /* Ignore invalid image specifications. */
8524 if (!valid_image_p (image))
8525 continue;
8527 /* Display the tool-bar button pressed, or depressed. */
8528 plist = Fcopy_sequence (XCDR (image));
8530 /* Compute margin and relief to draw. */
8531 relief = (tool_bar_button_relief >= 0
8532 ? tool_bar_button_relief
8533 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
8534 hmargin = vmargin = relief;
8536 if (INTEGERP (Vtool_bar_button_margin)
8537 && XINT (Vtool_bar_button_margin) > 0)
8539 hmargin += XFASTINT (Vtool_bar_button_margin);
8540 vmargin += XFASTINT (Vtool_bar_button_margin);
8542 else if (CONSP (Vtool_bar_button_margin))
8544 if (INTEGERP (XCAR (Vtool_bar_button_margin))
8545 && XINT (XCAR (Vtool_bar_button_margin)) > 0)
8546 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
8548 if (INTEGERP (XCDR (Vtool_bar_button_margin))
8549 && XINT (XCDR (Vtool_bar_button_margin)) > 0)
8550 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
8553 if (auto_raise_tool_bar_buttons_p)
8555 /* Add a `:relief' property to the image spec if the item is
8556 selected. */
8557 if (selected_p)
8559 plist = Fplist_put (plist, QCrelief, make_number (-relief));
8560 hmargin -= relief;
8561 vmargin -= relief;
8564 else
8566 /* If image is selected, display it pressed, i.e. with a
8567 negative relief. If it's not selected, display it with a
8568 raised relief. */
8569 plist = Fplist_put (plist, QCrelief,
8570 (selected_p
8571 ? make_number (-relief)
8572 : make_number (relief)));
8573 hmargin -= relief;
8574 vmargin -= relief;
8577 /* Put a margin around the image. */
8578 if (hmargin || vmargin)
8580 if (hmargin == vmargin)
8581 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
8582 else
8583 plist = Fplist_put (plist, QCmargin,
8584 Fcons (make_number (hmargin),
8585 make_number (vmargin)));
8588 /* If button is not enabled, and we don't have special images
8589 for the disabled state, make the image appear disabled by
8590 applying an appropriate algorithm to it. */
8591 if (!enabled_p && idx < 0)
8592 plist = Fplist_put (plist, QCconversion, Qdisabled);
8594 /* Put a `display' text property on the string for the image to
8595 display. Put a `menu-item' property on the string that gives
8596 the start of this item's properties in the tool-bar items
8597 vector. */
8598 image = Fcons (Qimage, plist);
8599 props = list4 (Qdisplay, image,
8600 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS));
8602 /* Let the last image hide all remaining spaces in the tool bar
8603 string. The string can be longer than needed when we reuse a
8604 previous string. */
8605 if (i + 1 == f->n_tool_bar_items)
8606 end = SCHARS (f->desired_tool_bar_string);
8607 else
8608 end = i + 1;
8609 Fadd_text_properties (make_number (i), make_number (end),
8610 props, f->desired_tool_bar_string);
8611 #undef PROP
8614 UNGCPRO;
8618 /* Display one line of the tool-bar of frame IT->f. */
8620 static void
8621 display_tool_bar_line (it)
8622 struct it *it;
8624 struct glyph_row *row = it->glyph_row;
8625 int max_x = it->last_visible_x;
8626 struct glyph *last;
8628 prepare_desired_row (row);
8629 row->y = it->current_y;
8631 /* Note that this isn't made use of if the face hasn't a box,
8632 so there's no need to check the face here. */
8633 it->start_of_box_run_p = 1;
8635 while (it->current_x < max_x)
8637 int x_before, x, n_glyphs_before, i, nglyphs;
8639 /* Get the next display element. */
8640 if (!get_next_display_element (it))
8641 break;
8643 /* Produce glyphs. */
8644 x_before = it->current_x;
8645 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
8646 PRODUCE_GLYPHS (it);
8648 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
8649 i = 0;
8650 x = x_before;
8651 while (i < nglyphs)
8653 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
8655 if (x + glyph->pixel_width > max_x)
8657 /* Glyph doesn't fit on line. */
8658 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
8659 it->current_x = x;
8660 goto out;
8663 ++it->hpos;
8664 x += glyph->pixel_width;
8665 ++i;
8668 /* Stop at line ends. */
8669 if (ITERATOR_AT_END_OF_LINE_P (it))
8670 break;
8672 set_iterator_to_next (it, 1);
8675 out:;
8677 row->displays_text_p = row->used[TEXT_AREA] != 0;
8678 extend_face_to_end_of_line (it);
8679 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
8680 last->right_box_line_p = 1;
8681 if (last == row->glyphs[TEXT_AREA])
8682 last->left_box_line_p = 1;
8683 compute_line_metrics (it);
8685 /* If line is empty, make it occupy the rest of the tool-bar. */
8686 if (!row->displays_text_p)
8688 row->height = row->phys_height = it->last_visible_y - row->y;
8689 row->ascent = row->phys_ascent = 0;
8692 row->full_width_p = 1;
8693 row->continued_p = 0;
8694 row->truncated_on_left_p = 0;
8695 row->truncated_on_right_p = 0;
8697 it->current_x = it->hpos = 0;
8698 it->current_y += row->height;
8699 ++it->vpos;
8700 ++it->glyph_row;
8704 /* Value is the number of screen lines needed to make all tool-bar
8705 items of frame F visible. */
8707 static int
8708 tool_bar_lines_needed (f)
8709 struct frame *f;
8711 struct window *w = XWINDOW (f->tool_bar_window);
8712 struct it it;
8714 /* Initialize an iterator for iteration over
8715 F->desired_tool_bar_string in the tool-bar window of frame F. */
8716 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
8717 it.first_visible_x = 0;
8718 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
8719 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
8721 while (!ITERATOR_AT_END_P (&it))
8723 it.glyph_row = w->desired_matrix->rows;
8724 clear_glyph_row (it.glyph_row);
8725 display_tool_bar_line (&it);
8728 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
8732 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
8733 0, 1, 0,
8734 doc: /* Return the number of lines occupied by the tool bar of FRAME. */)
8735 (frame)
8736 Lisp_Object frame;
8738 struct frame *f;
8739 struct window *w;
8740 int nlines = 0;
8742 if (NILP (frame))
8743 frame = selected_frame;
8744 else
8745 CHECK_FRAME (frame);
8746 f = XFRAME (frame);
8748 if (WINDOWP (f->tool_bar_window)
8749 || (w = XWINDOW (f->tool_bar_window),
8750 WINDOW_TOTAL_LINES (w) > 0))
8752 update_tool_bar (f, 1);
8753 if (f->n_tool_bar_items)
8755 build_desired_tool_bar_string (f);
8756 nlines = tool_bar_lines_needed (f);
8760 return make_number (nlines);
8764 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
8765 height should be changed. */
8767 static int
8768 redisplay_tool_bar (f)
8769 struct frame *f;
8771 struct window *w;
8772 struct it it;
8773 struct glyph_row *row;
8774 int change_height_p = 0;
8776 #ifdef USE_GTK
8777 if (FRAME_EXTERNAL_TOOL_BAR (f))
8778 update_frame_tool_bar (f);
8779 return 0;
8780 #endif
8782 /* If frame hasn't a tool-bar window or if it is zero-height, don't
8783 do anything. This means you must start with tool-bar-lines
8784 non-zero to get the auto-sizing effect. Or in other words, you
8785 can turn off tool-bars by specifying tool-bar-lines zero. */
8786 if (!WINDOWP (f->tool_bar_window)
8787 || (w = XWINDOW (f->tool_bar_window),
8788 WINDOW_TOTAL_LINES (w) == 0))
8789 return 0;
8791 /* Set up an iterator for the tool-bar window. */
8792 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
8793 it.first_visible_x = 0;
8794 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
8795 row = it.glyph_row;
8797 /* Build a string that represents the contents of the tool-bar. */
8798 build_desired_tool_bar_string (f);
8799 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
8801 /* Display as many lines as needed to display all tool-bar items. */
8802 while (it.current_y < it.last_visible_y)
8803 display_tool_bar_line (&it);
8805 /* It doesn't make much sense to try scrolling in the tool-bar
8806 window, so don't do it. */
8807 w->desired_matrix->no_scrolling_p = 1;
8808 w->must_be_updated_p = 1;
8810 if (auto_resize_tool_bars_p)
8812 int nlines;
8814 /* If we couldn't display everything, change the tool-bar's
8815 height. */
8816 if (IT_STRING_CHARPOS (it) < it.end_charpos)
8817 change_height_p = 1;
8819 /* If there are blank lines at the end, except for a partially
8820 visible blank line at the end that is smaller than
8821 FRAME_LINE_HEIGHT, change the tool-bar's height. */
8822 row = it.glyph_row - 1;
8823 if (!row->displays_text_p
8824 && row->height >= FRAME_LINE_HEIGHT (f))
8825 change_height_p = 1;
8827 /* If row displays tool-bar items, but is partially visible,
8828 change the tool-bar's height. */
8829 if (row->displays_text_p
8830 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y)
8831 change_height_p = 1;
8833 /* Resize windows as needed by changing the `tool-bar-lines'
8834 frame parameter. */
8835 if (change_height_p
8836 && (nlines = tool_bar_lines_needed (f),
8837 nlines != WINDOW_TOTAL_LINES (w)))
8839 extern Lisp_Object Qtool_bar_lines;
8840 Lisp_Object frame;
8841 int old_height = WINDOW_TOTAL_LINES (w);
8843 XSETFRAME (frame, f);
8844 clear_glyph_matrix (w->desired_matrix);
8845 Fmodify_frame_parameters (frame,
8846 Fcons (Fcons (Qtool_bar_lines,
8847 make_number (nlines)),
8848 Qnil));
8849 if (WINDOW_TOTAL_LINES (w) != old_height)
8850 fonts_changed_p = 1;
8854 return change_height_p;
8858 /* Get information about the tool-bar item which is displayed in GLYPH
8859 on frame F. Return in *PROP_IDX the index where tool-bar item
8860 properties start in F->tool_bar_items. Value is zero if
8861 GLYPH doesn't display a tool-bar item. */
8863 static int
8864 tool_bar_item_info (f, glyph, prop_idx)
8865 struct frame *f;
8866 struct glyph *glyph;
8867 int *prop_idx;
8869 Lisp_Object prop;
8870 int success_p;
8871 int charpos;
8873 /* This function can be called asynchronously, which means we must
8874 exclude any possibility that Fget_text_property signals an
8875 error. */
8876 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
8877 charpos = max (0, charpos);
8879 /* Get the text property `menu-item' at pos. The value of that
8880 property is the start index of this item's properties in
8881 F->tool_bar_items. */
8882 prop = Fget_text_property (make_number (charpos),
8883 Qmenu_item, f->current_tool_bar_string);
8884 if (INTEGERP (prop))
8886 *prop_idx = XINT (prop);
8887 success_p = 1;
8889 else
8890 success_p = 0;
8892 return success_p;
8896 /* Get information about the tool-bar item at position X/Y on frame F.
8897 Return in *GLYPH a pointer to the glyph of the tool-bar item in
8898 the current matrix of the tool-bar window of F, or NULL if not
8899 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
8900 item in F->tool_bar_items. Value is
8902 -1 if X/Y is not on a tool-bar item
8903 0 if X/Y is on the same item that was highlighted before.
8904 1 otherwise. */
8906 static int
8907 get_tool_bar_item (f, x, y, glyph, hpos, vpos, prop_idx)
8908 struct frame *f;
8909 int x, y;
8910 struct glyph **glyph;
8911 int *hpos, *vpos, *prop_idx;
8913 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
8914 struct window *w = XWINDOW (f->tool_bar_window);
8915 int area;
8917 /* Find the glyph under X/Y. */
8918 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
8919 if (*glyph == NULL)
8920 return -1;
8922 /* Get the start of this tool-bar item's properties in
8923 f->tool_bar_items. */
8924 if (!tool_bar_item_info (f, *glyph, prop_idx))
8925 return -1;
8927 /* Is mouse on the highlighted item? */
8928 if (EQ (f->tool_bar_window, dpyinfo->mouse_face_window)
8929 && *vpos >= dpyinfo->mouse_face_beg_row
8930 && *vpos <= dpyinfo->mouse_face_end_row
8931 && (*vpos > dpyinfo->mouse_face_beg_row
8932 || *hpos >= dpyinfo->mouse_face_beg_col)
8933 && (*vpos < dpyinfo->mouse_face_end_row
8934 || *hpos < dpyinfo->mouse_face_end_col
8935 || dpyinfo->mouse_face_past_end))
8936 return 0;
8938 return 1;
8942 /* EXPORT:
8943 Handle mouse button event on the tool-bar of frame F, at
8944 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
8945 0 for button release. MODIFIERS is event modifiers for button
8946 release. */
8948 void
8949 handle_tool_bar_click (f, x, y, down_p, modifiers)
8950 struct frame *f;
8951 int x, y, down_p;
8952 unsigned int modifiers;
8954 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
8955 struct window *w = XWINDOW (f->tool_bar_window);
8956 int hpos, vpos, prop_idx;
8957 struct glyph *glyph;
8958 Lisp_Object enabled_p;
8960 /* If not on the highlighted tool-bar item, return. */
8961 frame_to_window_pixel_xy (w, &x, &y);
8962 if (get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0)
8963 return;
8965 /* If item is disabled, do nothing. */
8966 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
8967 if (NILP (enabled_p))
8968 return;
8970 if (down_p)
8972 /* Show item in pressed state. */
8973 show_mouse_face (dpyinfo, DRAW_IMAGE_SUNKEN);
8974 dpyinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN;
8975 last_tool_bar_item = prop_idx;
8977 else
8979 Lisp_Object key, frame;
8980 struct input_event event;
8981 EVENT_INIT (event);
8983 /* Show item in released state. */
8984 show_mouse_face (dpyinfo, DRAW_IMAGE_RAISED);
8985 dpyinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
8987 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
8989 XSETFRAME (frame, f);
8990 event.kind = TOOL_BAR_EVENT;
8991 event.frame_or_window = frame;
8992 event.arg = frame;
8993 kbd_buffer_store_event (&event);
8995 event.kind = TOOL_BAR_EVENT;
8996 event.frame_or_window = frame;
8997 event.arg = key;
8998 event.modifiers = modifiers;
8999 kbd_buffer_store_event (&event);
9000 last_tool_bar_item = -1;
9005 /* Possibly highlight a tool-bar item on frame F when mouse moves to
9006 tool-bar window-relative coordinates X/Y. Called from
9007 note_mouse_highlight. */
9009 static void
9010 note_tool_bar_highlight (f, x, y)
9011 struct frame *f;
9012 int x, y;
9014 Lisp_Object window = f->tool_bar_window;
9015 struct window *w = XWINDOW (window);
9016 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
9017 int hpos, vpos;
9018 struct glyph *glyph;
9019 struct glyph_row *row;
9020 int i;
9021 Lisp_Object enabled_p;
9022 int prop_idx;
9023 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
9024 int mouse_down_p, rc;
9026 /* Function note_mouse_highlight is called with negative x(y
9027 values when mouse moves outside of the frame. */
9028 if (x <= 0 || y <= 0)
9030 clear_mouse_face (dpyinfo);
9031 return;
9034 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
9035 if (rc < 0)
9037 /* Not on tool-bar item. */
9038 clear_mouse_face (dpyinfo);
9039 return;
9041 else if (rc == 0)
9042 /* On same tool-bar item as before. */
9043 goto set_help_echo;
9045 clear_mouse_face (dpyinfo);
9047 /* Mouse is down, but on different tool-bar item? */
9048 mouse_down_p = (dpyinfo->grabbed
9049 && f == last_mouse_frame
9050 && FRAME_LIVE_P (f));
9051 if (mouse_down_p
9052 && last_tool_bar_item != prop_idx)
9053 return;
9055 dpyinfo->mouse_face_image_state = DRAW_NORMAL_TEXT;
9056 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
9058 /* If tool-bar item is not enabled, don't highlight it. */
9059 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
9060 if (!NILP (enabled_p))
9062 /* Compute the x-position of the glyph. In front and past the
9063 image is a space. We include this in the highlighted area. */
9064 row = MATRIX_ROW (w->current_matrix, vpos);
9065 for (i = x = 0; i < hpos; ++i)
9066 x += row->glyphs[TEXT_AREA][i].pixel_width;
9068 /* Record this as the current active region. */
9069 dpyinfo->mouse_face_beg_col = hpos;
9070 dpyinfo->mouse_face_beg_row = vpos;
9071 dpyinfo->mouse_face_beg_x = x;
9072 dpyinfo->mouse_face_beg_y = row->y;
9073 dpyinfo->mouse_face_past_end = 0;
9075 dpyinfo->mouse_face_end_col = hpos + 1;
9076 dpyinfo->mouse_face_end_row = vpos;
9077 dpyinfo->mouse_face_end_x = x + glyph->pixel_width;
9078 dpyinfo->mouse_face_end_y = row->y;
9079 dpyinfo->mouse_face_window = window;
9080 dpyinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
9082 /* Display it as active. */
9083 show_mouse_face (dpyinfo, draw);
9084 dpyinfo->mouse_face_image_state = draw;
9087 set_help_echo:
9089 /* Set help_echo_string to a help string to display for this tool-bar item.
9090 XTread_socket does the rest. */
9091 help_echo_object = help_echo_window = Qnil;
9092 help_echo_pos = -1;
9093 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
9094 if (NILP (help_echo_string))
9095 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
9098 #endif /* HAVE_WINDOW_SYSTEM */
9102 /************************************************************************
9103 Horizontal scrolling
9104 ************************************************************************/
9106 static int hscroll_window_tree P_ ((Lisp_Object));
9107 static int hscroll_windows P_ ((Lisp_Object));
9109 /* For all leaf windows in the window tree rooted at WINDOW, set their
9110 hscroll value so that PT is (i) visible in the window, and (ii) so
9111 that it is not within a certain margin at the window's left and
9112 right border. Value is non-zero if any window's hscroll has been
9113 changed. */
9115 static int
9116 hscroll_window_tree (window)
9117 Lisp_Object window;
9119 int hscrolled_p = 0;
9120 int hscroll_relative_p = FLOATP (Vhscroll_step);
9121 int hscroll_step_abs = 0;
9122 double hscroll_step_rel = 0;
9124 if (hscroll_relative_p)
9126 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
9127 if (hscroll_step_rel < 0)
9129 hscroll_relative_p = 0;
9130 hscroll_step_abs = 0;
9133 else if (INTEGERP (Vhscroll_step))
9135 hscroll_step_abs = XINT (Vhscroll_step);
9136 if (hscroll_step_abs < 0)
9137 hscroll_step_abs = 0;
9139 else
9140 hscroll_step_abs = 0;
9142 while (WINDOWP (window))
9144 struct window *w = XWINDOW (window);
9146 if (WINDOWP (w->hchild))
9147 hscrolled_p |= hscroll_window_tree (w->hchild);
9148 else if (WINDOWP (w->vchild))
9149 hscrolled_p |= hscroll_window_tree (w->vchild);
9150 else if (w->cursor.vpos >= 0)
9152 int h_margin;
9153 int text_area_width;
9154 struct glyph_row *current_cursor_row
9155 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
9156 struct glyph_row *desired_cursor_row
9157 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
9158 struct glyph_row *cursor_row
9159 = (desired_cursor_row->enabled_p
9160 ? desired_cursor_row
9161 : current_cursor_row);
9163 text_area_width = window_box_width (w, TEXT_AREA);
9165 /* Scroll when cursor is inside this scroll margin. */
9166 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
9168 if ((XFASTINT (w->hscroll)
9169 && w->cursor.x <= h_margin)
9170 || (cursor_row->enabled_p
9171 && cursor_row->truncated_on_right_p
9172 && (w->cursor.x >= text_area_width - h_margin)))
9174 struct it it;
9175 int hscroll;
9176 struct buffer *saved_current_buffer;
9177 int pt;
9178 int wanted_x;
9180 /* Find point in a display of infinite width. */
9181 saved_current_buffer = current_buffer;
9182 current_buffer = XBUFFER (w->buffer);
9184 if (w == XWINDOW (selected_window))
9185 pt = BUF_PT (current_buffer);
9186 else
9188 pt = marker_position (w->pointm);
9189 pt = max (BEGV, pt);
9190 pt = min (ZV, pt);
9193 /* Move iterator to pt starting at cursor_row->start in
9194 a line with infinite width. */
9195 init_to_row_start (&it, w, cursor_row);
9196 it.last_visible_x = INFINITY;
9197 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
9198 current_buffer = saved_current_buffer;
9200 /* Position cursor in window. */
9201 if (!hscroll_relative_p && hscroll_step_abs == 0)
9202 hscroll = max (0, (it.current_x
9203 - (ITERATOR_AT_END_OF_LINE_P (&it)
9204 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
9205 : (text_area_width / 2))))
9206 / FRAME_COLUMN_WIDTH (it.f);
9207 else if (w->cursor.x >= text_area_width - h_margin)
9209 if (hscroll_relative_p)
9210 wanted_x = text_area_width * (1 - hscroll_step_rel)
9211 - h_margin;
9212 else
9213 wanted_x = text_area_width
9214 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
9215 - h_margin;
9216 hscroll
9217 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
9219 else
9221 if (hscroll_relative_p)
9222 wanted_x = text_area_width * hscroll_step_rel
9223 + h_margin;
9224 else
9225 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
9226 + h_margin;
9227 hscroll
9228 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
9230 hscroll = max (hscroll, XFASTINT (w->min_hscroll));
9232 /* Don't call Fset_window_hscroll if value hasn't
9233 changed because it will prevent redisplay
9234 optimizations. */
9235 if (XFASTINT (w->hscroll) != hscroll)
9237 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
9238 w->hscroll = make_number (hscroll);
9239 hscrolled_p = 1;
9244 window = w->next;
9247 /* Value is non-zero if hscroll of any leaf window has been changed. */
9248 return hscrolled_p;
9252 /* Set hscroll so that cursor is visible and not inside horizontal
9253 scroll margins for all windows in the tree rooted at WINDOW. See
9254 also hscroll_window_tree above. Value is non-zero if any window's
9255 hscroll has been changed. If it has, desired matrices on the frame
9256 of WINDOW are cleared. */
9258 static int
9259 hscroll_windows (window)
9260 Lisp_Object window;
9262 int hscrolled_p;
9264 if (automatic_hscrolling_p)
9266 hscrolled_p = hscroll_window_tree (window);
9267 if (hscrolled_p)
9268 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
9270 else
9271 hscrolled_p = 0;
9272 return hscrolled_p;
9277 /************************************************************************
9278 Redisplay
9279 ************************************************************************/
9281 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
9282 to a non-zero value. This is sometimes handy to have in a debugger
9283 session. */
9285 #if GLYPH_DEBUG
9287 /* First and last unchanged row for try_window_id. */
9289 int debug_first_unchanged_at_end_vpos;
9290 int debug_last_unchanged_at_beg_vpos;
9292 /* Delta vpos and y. */
9294 int debug_dvpos, debug_dy;
9296 /* Delta in characters and bytes for try_window_id. */
9298 int debug_delta, debug_delta_bytes;
9300 /* Values of window_end_pos and window_end_vpos at the end of
9301 try_window_id. */
9303 EMACS_INT debug_end_pos, debug_end_vpos;
9305 /* Append a string to W->desired_matrix->method. FMT is a printf
9306 format string. A1...A9 are a supplement for a variable-length
9307 argument list. If trace_redisplay_p is non-zero also printf the
9308 resulting string to stderr. */
9310 static void
9311 debug_method_add (w, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
9312 struct window *w;
9313 char *fmt;
9314 int a1, a2, a3, a4, a5, a6, a7, a8, a9;
9316 char buffer[512];
9317 char *method = w->desired_matrix->method;
9318 int len = strlen (method);
9319 int size = sizeof w->desired_matrix->method;
9320 int remaining = size - len - 1;
9322 sprintf (buffer, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
9323 if (len && remaining)
9325 method[len] = '|';
9326 --remaining, ++len;
9329 strncpy (method + len, buffer, remaining);
9331 if (trace_redisplay_p)
9332 fprintf (stderr, "%p (%s): %s\n",
9334 ((BUFFERP (w->buffer)
9335 && STRINGP (XBUFFER (w->buffer)->name))
9336 ? (char *) SDATA (XBUFFER (w->buffer)->name)
9337 : "no buffer"),
9338 buffer);
9341 #endif /* GLYPH_DEBUG */
9344 /* Value is non-zero if all changes in window W, which displays
9345 current_buffer, are in the text between START and END. START is a
9346 buffer position, END is given as a distance from Z. Used in
9347 redisplay_internal for display optimization. */
9349 static INLINE int
9350 text_outside_line_unchanged_p (w, start, end)
9351 struct window *w;
9352 int start, end;
9354 int unchanged_p = 1;
9356 /* If text or overlays have changed, see where. */
9357 if (XFASTINT (w->last_modified) < MODIFF
9358 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
9360 /* Gap in the line? */
9361 if (GPT < start || Z - GPT < end)
9362 unchanged_p = 0;
9364 /* Changes start in front of the line, or end after it? */
9365 if (unchanged_p
9366 && (BEG_UNCHANGED < start - 1
9367 || END_UNCHANGED < end))
9368 unchanged_p = 0;
9370 /* If selective display, can't optimize if changes start at the
9371 beginning of the line. */
9372 if (unchanged_p
9373 && INTEGERP (current_buffer->selective_display)
9374 && XINT (current_buffer->selective_display) > 0
9375 && (BEG_UNCHANGED < start || GPT <= start))
9376 unchanged_p = 0;
9378 /* If there are overlays at the start or end of the line, these
9379 may have overlay strings with newlines in them. A change at
9380 START, for instance, may actually concern the display of such
9381 overlay strings as well, and they are displayed on different
9382 lines. So, quickly rule out this case. (For the future, it
9383 might be desirable to implement something more telling than
9384 just BEG/END_UNCHANGED.) */
9385 if (unchanged_p)
9387 if (BEG + BEG_UNCHANGED == start
9388 && overlay_touches_p (start))
9389 unchanged_p = 0;
9390 if (END_UNCHANGED == end
9391 && overlay_touches_p (Z - end))
9392 unchanged_p = 0;
9396 return unchanged_p;
9400 /* Do a frame update, taking possible shortcuts into account. This is
9401 the main external entry point for redisplay.
9403 If the last redisplay displayed an echo area message and that message
9404 is no longer requested, we clear the echo area or bring back the
9405 mini-buffer if that is in use. */
9407 void
9408 redisplay ()
9410 redisplay_internal (0);
9414 static Lisp_Object
9415 overlay_arrow_string_or_property (var, pbitmap)
9416 Lisp_Object var;
9417 int *pbitmap;
9419 Lisp_Object pstr = Fget (var, Qoverlay_arrow_string);
9420 Lisp_Object bitmap;
9422 if (pbitmap)
9424 *pbitmap = 0;
9425 if (bitmap = Fget (var, Qoverlay_arrow_bitmap), INTEGERP (bitmap))
9426 *pbitmap = XINT (bitmap);
9429 if (!NILP (pstr))
9430 return pstr;
9431 return Voverlay_arrow_string;
9434 /* Return 1 if there are any overlay-arrows in current_buffer. */
9435 static int
9436 overlay_arrow_in_current_buffer_p ()
9438 Lisp_Object vlist;
9440 for (vlist = Voverlay_arrow_variable_list;
9441 CONSP (vlist);
9442 vlist = XCDR (vlist))
9444 Lisp_Object var = XCAR (vlist);
9445 Lisp_Object val;
9447 if (!SYMBOLP (var))
9448 continue;
9449 val = find_symbol_value (var);
9450 if (MARKERP (val)
9451 && current_buffer == XMARKER (val)->buffer)
9452 return 1;
9454 return 0;
9458 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
9459 has changed. */
9461 static int
9462 overlay_arrows_changed_p ()
9464 Lisp_Object vlist;
9466 for (vlist = Voverlay_arrow_variable_list;
9467 CONSP (vlist);
9468 vlist = XCDR (vlist))
9470 Lisp_Object var = XCAR (vlist);
9471 Lisp_Object val, pstr;
9473 if (!SYMBOLP (var))
9474 continue;
9475 val = find_symbol_value (var);
9476 if (!MARKERP (val))
9477 continue;
9478 if (! EQ (COERCE_MARKER (val),
9479 Fget (var, Qlast_arrow_position))
9480 || ! (pstr = overlay_arrow_string_or_property (var, 0),
9481 EQ (pstr, Fget (var, Qlast_arrow_string))))
9482 return 1;
9484 return 0;
9487 /* Mark overlay arrows to be updated on next redisplay. */
9489 static void
9490 update_overlay_arrows (up_to_date)
9491 int up_to_date;
9493 Lisp_Object vlist;
9495 for (vlist = Voverlay_arrow_variable_list;
9496 CONSP (vlist);
9497 vlist = XCDR (vlist))
9499 Lisp_Object var = XCAR (vlist);
9501 if (!SYMBOLP (var))
9502 continue;
9504 if (up_to_date > 0)
9506 Lisp_Object val = find_symbol_value (var);
9507 Fput (var, Qlast_arrow_position,
9508 COERCE_MARKER (val));
9509 Fput (var, Qlast_arrow_string,
9510 overlay_arrow_string_or_property (var, 0));
9512 else if (up_to_date < 0
9513 || !NILP (Fget (var, Qlast_arrow_position)))
9515 Fput (var, Qlast_arrow_position, Qt);
9516 Fput (var, Qlast_arrow_string, Qt);
9522 /* Return overlay arrow string at row, or nil. */
9524 static Lisp_Object
9525 overlay_arrow_at_row (f, row, pbitmap)
9526 struct frame *f;
9527 struct glyph_row *row;
9528 int *pbitmap;
9530 Lisp_Object vlist;
9532 for (vlist = Voverlay_arrow_variable_list;
9533 CONSP (vlist);
9534 vlist = XCDR (vlist))
9536 Lisp_Object var = XCAR (vlist);
9537 Lisp_Object val;
9539 if (!SYMBOLP (var))
9540 continue;
9542 val = find_symbol_value (var);
9544 if (MARKERP (val)
9545 && current_buffer == XMARKER (val)->buffer
9546 && (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
9548 val = overlay_arrow_string_or_property (var, pbitmap);
9549 if (FRAME_WINDOW_P (f))
9550 return Qt;
9551 else if (STRINGP (val))
9552 return val;
9553 break;
9557 *pbitmap = 0;
9558 return Qnil;
9561 /* Return 1 if point moved out of or into a composition. Otherwise
9562 return 0. PREV_BUF and PREV_PT are the last point buffer and
9563 position. BUF and PT are the current point buffer and position. */
9566 check_point_in_composition (prev_buf, prev_pt, buf, pt)
9567 struct buffer *prev_buf, *buf;
9568 int prev_pt, pt;
9570 int start, end;
9571 Lisp_Object prop;
9572 Lisp_Object buffer;
9574 XSETBUFFER (buffer, buf);
9575 /* Check a composition at the last point if point moved within the
9576 same buffer. */
9577 if (prev_buf == buf)
9579 if (prev_pt == pt)
9580 /* Point didn't move. */
9581 return 0;
9583 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
9584 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
9585 && COMPOSITION_VALID_P (start, end, prop)
9586 && start < prev_pt && end > prev_pt)
9587 /* The last point was within the composition. Return 1 iff
9588 point moved out of the composition. */
9589 return (pt <= start || pt >= end);
9592 /* Check a composition at the current point. */
9593 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
9594 && find_composition (pt, -1, &start, &end, &prop, buffer)
9595 && COMPOSITION_VALID_P (start, end, prop)
9596 && start < pt && end > pt);
9600 /* Reconsider the setting of B->clip_changed which is displayed
9601 in window W. */
9603 static INLINE void
9604 reconsider_clip_changes (w, b)
9605 struct window *w;
9606 struct buffer *b;
9608 if (b->clip_changed
9609 && !NILP (w->window_end_valid)
9610 && w->current_matrix->buffer == b
9611 && w->current_matrix->zv == BUF_ZV (b)
9612 && w->current_matrix->begv == BUF_BEGV (b))
9613 b->clip_changed = 0;
9615 /* If display wasn't paused, and W is not a tool bar window, see if
9616 point has been moved into or out of a composition. In that case,
9617 we set b->clip_changed to 1 to force updating the screen. If
9618 b->clip_changed has already been set to 1, we can skip this
9619 check. */
9620 if (!b->clip_changed
9621 && BUFFERP (w->buffer) && !NILP (w->window_end_valid))
9623 int pt;
9625 if (w == XWINDOW (selected_window))
9626 pt = BUF_PT (current_buffer);
9627 else
9628 pt = marker_position (w->pointm);
9630 if ((w->current_matrix->buffer != XBUFFER (w->buffer)
9631 || pt != XINT (w->last_point))
9632 && check_point_in_composition (w->current_matrix->buffer,
9633 XINT (w->last_point),
9634 XBUFFER (w->buffer), pt))
9635 b->clip_changed = 1;
9640 /* Select FRAME to forward the values of frame-local variables into C
9641 variables so that the redisplay routines can access those values
9642 directly. */
9644 static void
9645 select_frame_for_redisplay (frame)
9646 Lisp_Object frame;
9648 Lisp_Object tail, sym, val;
9649 Lisp_Object old = selected_frame;
9651 selected_frame = frame;
9653 for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail))
9654 if (CONSP (XCAR (tail))
9655 && (sym = XCAR (XCAR (tail)),
9656 SYMBOLP (sym))
9657 && (sym = indirect_variable (sym),
9658 val = SYMBOL_VALUE (sym),
9659 (BUFFER_LOCAL_VALUEP (val)
9660 || SOME_BUFFER_LOCAL_VALUEP (val)))
9661 && XBUFFER_LOCAL_VALUE (val)->check_frame)
9662 Fsymbol_value (sym);
9664 for (tail = XFRAME (old)->param_alist; CONSP (tail); tail = XCDR (tail))
9665 if (CONSP (XCAR (tail))
9666 && (sym = XCAR (XCAR (tail)),
9667 SYMBOLP (sym))
9668 && (sym = indirect_variable (sym),
9669 val = SYMBOL_VALUE (sym),
9670 (BUFFER_LOCAL_VALUEP (val)
9671 || SOME_BUFFER_LOCAL_VALUEP (val)))
9672 && XBUFFER_LOCAL_VALUE (val)->check_frame)
9673 Fsymbol_value (sym);
9677 #define STOP_POLLING \
9678 do { if (! polling_stopped_here) stop_polling (); \
9679 polling_stopped_here = 1; } while (0)
9681 #define RESUME_POLLING \
9682 do { if (polling_stopped_here) start_polling (); \
9683 polling_stopped_here = 0; } while (0)
9686 /* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
9687 response to any user action; therefore, we should preserve the echo
9688 area. (Actually, our caller does that job.) Perhaps in the future
9689 avoid recentering windows if it is not necessary; currently that
9690 causes some problems. */
9692 static void
9693 redisplay_internal (preserve_echo_area)
9694 int preserve_echo_area;
9696 struct window *w = XWINDOW (selected_window);
9697 struct frame *f = XFRAME (w->frame);
9698 int pause;
9699 int must_finish = 0;
9700 struct text_pos tlbufpos, tlendpos;
9701 int number_of_visible_frames;
9702 int count;
9703 struct frame *sf = SELECTED_FRAME ();
9704 int polling_stopped_here = 0;
9706 /* Non-zero means redisplay has to consider all windows on all
9707 frames. Zero means, only selected_window is considered. */
9708 int consider_all_windows_p;
9710 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
9712 /* No redisplay if running in batch mode or frame is not yet fully
9713 initialized, or redisplay is explicitly turned off by setting
9714 Vinhibit_redisplay. */
9715 if (noninteractive
9716 || !NILP (Vinhibit_redisplay)
9717 || !f->glyphs_initialized_p)
9718 return;
9720 /* The flag redisplay_performed_directly_p is set by
9721 direct_output_for_insert when it already did the whole screen
9722 update necessary. */
9723 if (redisplay_performed_directly_p)
9725 redisplay_performed_directly_p = 0;
9726 if (!hscroll_windows (selected_window))
9727 return;
9730 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
9731 if (popup_activated ())
9732 return;
9733 #endif
9735 /* I don't think this happens but let's be paranoid. */
9736 if (redisplaying_p)
9737 return;
9739 /* Record a function that resets redisplaying_p to its old value
9740 when we leave this function. */
9741 count = SPECPDL_INDEX ();
9742 record_unwind_protect (unwind_redisplay,
9743 Fcons (make_number (redisplaying_p), selected_frame));
9744 ++redisplaying_p;
9745 specbind (Qinhibit_free_realized_faces, Qnil);
9747 retry:
9748 pause = 0;
9749 reconsider_clip_changes (w, current_buffer);
9751 /* If new fonts have been loaded that make a glyph matrix adjustment
9752 necessary, do it. */
9753 if (fonts_changed_p)
9755 adjust_glyphs (NULL);
9756 ++windows_or_buffers_changed;
9757 fonts_changed_p = 0;
9760 /* If face_change_count is non-zero, init_iterator will free all
9761 realized faces, which includes the faces referenced from current
9762 matrices. So, we can't reuse current matrices in this case. */
9763 if (face_change_count)
9764 ++windows_or_buffers_changed;
9766 if (! FRAME_WINDOW_P (sf)
9767 && previous_terminal_frame != sf)
9769 /* Since frames on an ASCII terminal share the same display
9770 area, displaying a different frame means redisplay the whole
9771 thing. */
9772 windows_or_buffers_changed++;
9773 SET_FRAME_GARBAGED (sf);
9774 XSETFRAME (Vterminal_frame, sf);
9776 previous_terminal_frame = sf;
9778 /* Set the visible flags for all frames. Do this before checking
9779 for resized or garbaged frames; they want to know if their frames
9780 are visible. See the comment in frame.h for
9781 FRAME_SAMPLE_VISIBILITY. */
9783 Lisp_Object tail, frame;
9785 number_of_visible_frames = 0;
9787 FOR_EACH_FRAME (tail, frame)
9789 struct frame *f = XFRAME (frame);
9791 FRAME_SAMPLE_VISIBILITY (f);
9792 if (FRAME_VISIBLE_P (f))
9793 ++number_of_visible_frames;
9794 clear_desired_matrices (f);
9798 /* Notice any pending interrupt request to change frame size. */
9799 do_pending_window_change (1);
9801 /* Clear frames marked as garbaged. */
9802 if (frame_garbaged)
9803 clear_garbaged_frames ();
9805 /* Build menubar and tool-bar items. */
9806 prepare_menu_bars ();
9808 if (windows_or_buffers_changed)
9809 update_mode_lines++;
9811 /* Detect case that we need to write or remove a star in the mode line. */
9812 if ((SAVE_MODIFF < MODIFF) != !NILP (w->last_had_star))
9814 w->update_mode_line = Qt;
9815 if (buffer_shared > 1)
9816 update_mode_lines++;
9819 /* If %c is in the mode line, update it if needed. */
9820 if (!NILP (w->column_number_displayed)
9821 /* This alternative quickly identifies a common case
9822 where no change is needed. */
9823 && !(PT == XFASTINT (w->last_point)
9824 && XFASTINT (w->last_modified) >= MODIFF
9825 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
9826 && (XFASTINT (w->column_number_displayed)
9827 != (int) current_column ())) /* iftc */
9828 w->update_mode_line = Qt;
9830 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
9832 /* The variable buffer_shared is set in redisplay_window and
9833 indicates that we redisplay a buffer in different windows. See
9834 there. */
9835 consider_all_windows_p = (update_mode_lines || buffer_shared > 1
9836 || cursor_type_changed);
9838 /* If specs for an arrow have changed, do thorough redisplay
9839 to ensure we remove any arrow that should no longer exist. */
9840 if (overlay_arrows_changed_p ())
9841 consider_all_windows_p = windows_or_buffers_changed = 1;
9843 /* Normally the message* functions will have already displayed and
9844 updated the echo area, but the frame may have been trashed, or
9845 the update may have been preempted, so display the echo area
9846 again here. Checking message_cleared_p captures the case that
9847 the echo area should be cleared. */
9848 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
9849 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
9850 || (message_cleared_p
9851 && minibuf_level == 0
9852 /* If the mini-window is currently selected, this means the
9853 echo-area doesn't show through. */
9854 && !MINI_WINDOW_P (XWINDOW (selected_window))))
9856 int window_height_changed_p = echo_area_display (0);
9857 must_finish = 1;
9859 /* If we don't display the current message, don't clear the
9860 message_cleared_p flag, because, if we did, we wouldn't clear
9861 the echo area in the next redisplay which doesn't preserve
9862 the echo area. */
9863 if (!display_last_displayed_message_p)
9864 message_cleared_p = 0;
9866 if (fonts_changed_p)
9867 goto retry;
9868 else if (window_height_changed_p)
9870 consider_all_windows_p = 1;
9871 ++update_mode_lines;
9872 ++windows_or_buffers_changed;
9874 /* If window configuration was changed, frames may have been
9875 marked garbaged. Clear them or we will experience
9876 surprises wrt scrolling. */
9877 if (frame_garbaged)
9878 clear_garbaged_frames ();
9881 else if (EQ (selected_window, minibuf_window)
9882 && (current_buffer->clip_changed
9883 || XFASTINT (w->last_modified) < MODIFF
9884 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
9885 && resize_mini_window (w, 0))
9887 /* Resized active mini-window to fit the size of what it is
9888 showing if its contents might have changed. */
9889 must_finish = 1;
9890 consider_all_windows_p = 1;
9891 ++windows_or_buffers_changed;
9892 ++update_mode_lines;
9894 /* If window configuration was changed, frames may have been
9895 marked garbaged. Clear them or we will experience
9896 surprises wrt scrolling. */
9897 if (frame_garbaged)
9898 clear_garbaged_frames ();
9902 /* If showing the region, and mark has changed, we must redisplay
9903 the whole window. The assignment to this_line_start_pos prevents
9904 the optimization directly below this if-statement. */
9905 if (((!NILP (Vtransient_mark_mode)
9906 && !NILP (XBUFFER (w->buffer)->mark_active))
9907 != !NILP (w->region_showing))
9908 || (!NILP (w->region_showing)
9909 && !EQ (w->region_showing,
9910 Fmarker_position (XBUFFER (w->buffer)->mark))))
9911 CHARPOS (this_line_start_pos) = 0;
9913 /* Optimize the case that only the line containing the cursor in the
9914 selected window has changed. Variables starting with this_ are
9915 set in display_line and record information about the line
9916 containing the cursor. */
9917 tlbufpos = this_line_start_pos;
9918 tlendpos = this_line_end_pos;
9919 if (!consider_all_windows_p
9920 && CHARPOS (tlbufpos) > 0
9921 && NILP (w->update_mode_line)
9922 && !current_buffer->clip_changed
9923 && !current_buffer->prevent_redisplay_optimizations_p
9924 && FRAME_VISIBLE_P (XFRAME (w->frame))
9925 && !FRAME_OBSCURED_P (XFRAME (w->frame))
9926 /* Make sure recorded data applies to current buffer, etc. */
9927 && this_line_buffer == current_buffer
9928 && current_buffer == XBUFFER (w->buffer)
9929 && NILP (w->force_start)
9930 && NILP (w->optional_new_start)
9931 /* Point must be on the line that we have info recorded about. */
9932 && PT >= CHARPOS (tlbufpos)
9933 && PT <= Z - CHARPOS (tlendpos)
9934 /* All text outside that line, including its final newline,
9935 must be unchanged */
9936 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
9937 CHARPOS (tlendpos)))
9939 if (CHARPOS (tlbufpos) > BEGV
9940 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
9941 && (CHARPOS (tlbufpos) == ZV
9942 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
9943 /* Former continuation line has disappeared by becoming empty */
9944 goto cancel;
9945 else if (XFASTINT (w->last_modified) < MODIFF
9946 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF
9947 || MINI_WINDOW_P (w))
9949 /* We have to handle the case of continuation around a
9950 wide-column character (See the comment in indent.c around
9951 line 885).
9953 For instance, in the following case:
9955 -------- Insert --------
9956 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
9957 J_I_ ==> J_I_ `^^' are cursors.
9958 ^^ ^^
9959 -------- --------
9961 As we have to redraw the line above, we should goto cancel. */
9963 struct it it;
9964 int line_height_before = this_line_pixel_height;
9966 /* Note that start_display will handle the case that the
9967 line starting at tlbufpos is a continuation lines. */
9968 start_display (&it, w, tlbufpos);
9970 /* Implementation note: It this still necessary? */
9971 if (it.current_x != this_line_start_x)
9972 goto cancel;
9974 TRACE ((stderr, "trying display optimization 1\n"));
9975 w->cursor.vpos = -1;
9976 overlay_arrow_seen = 0;
9977 it.vpos = this_line_vpos;
9978 it.current_y = this_line_y;
9979 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
9980 display_line (&it);
9982 /* If line contains point, is not continued,
9983 and ends at same distance from eob as before, we win */
9984 if (w->cursor.vpos >= 0
9985 /* Line is not continued, otherwise this_line_start_pos
9986 would have been set to 0 in display_line. */
9987 && CHARPOS (this_line_start_pos)
9988 /* Line ends as before. */
9989 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
9990 /* Line has same height as before. Otherwise other lines
9991 would have to be shifted up or down. */
9992 && this_line_pixel_height == line_height_before)
9994 /* If this is not the window's last line, we must adjust
9995 the charstarts of the lines below. */
9996 if (it.current_y < it.last_visible_y)
9998 struct glyph_row *row
9999 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
10000 int delta, delta_bytes;
10002 if (Z - CHARPOS (tlendpos) == ZV)
10004 /* This line ends at end of (accessible part of)
10005 buffer. There is no newline to count. */
10006 delta = (Z
10007 - CHARPOS (tlendpos)
10008 - MATRIX_ROW_START_CHARPOS (row));
10009 delta_bytes = (Z_BYTE
10010 - BYTEPOS (tlendpos)
10011 - MATRIX_ROW_START_BYTEPOS (row));
10013 else
10015 /* This line ends in a newline. Must take
10016 account of the newline and the rest of the
10017 text that follows. */
10018 delta = (Z
10019 - CHARPOS (tlendpos)
10020 - MATRIX_ROW_START_CHARPOS (row));
10021 delta_bytes = (Z_BYTE
10022 - BYTEPOS (tlendpos)
10023 - MATRIX_ROW_START_BYTEPOS (row));
10026 increment_matrix_positions (w->current_matrix,
10027 this_line_vpos + 1,
10028 w->current_matrix->nrows,
10029 delta, delta_bytes);
10032 /* If this row displays text now but previously didn't,
10033 or vice versa, w->window_end_vpos may have to be
10034 adjusted. */
10035 if ((it.glyph_row - 1)->displays_text_p)
10037 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
10038 XSETINT (w->window_end_vpos, this_line_vpos);
10040 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
10041 && this_line_vpos > 0)
10042 XSETINT (w->window_end_vpos, this_line_vpos - 1);
10043 w->window_end_valid = Qnil;
10045 /* Update hint: No need to try to scroll in update_window. */
10046 w->desired_matrix->no_scrolling_p = 1;
10048 #if GLYPH_DEBUG
10049 *w->desired_matrix->method = 0;
10050 debug_method_add (w, "optimization 1");
10051 #endif
10052 #ifdef HAVE_WINDOW_SYSTEM
10053 update_window_fringes (w, 0);
10054 #endif
10055 goto update;
10057 else
10058 goto cancel;
10060 else if (/* Cursor position hasn't changed. */
10061 PT == XFASTINT (w->last_point)
10062 /* Make sure the cursor was last displayed
10063 in this window. Otherwise we have to reposition it. */
10064 && 0 <= w->cursor.vpos
10065 && WINDOW_TOTAL_LINES (w) > w->cursor.vpos)
10067 if (!must_finish)
10069 do_pending_window_change (1);
10071 /* We used to always goto end_of_redisplay here, but this
10072 isn't enough if we have a blinking cursor. */
10073 if (w->cursor_off_p == w->last_cursor_off_p)
10074 goto end_of_redisplay;
10076 goto update;
10078 /* If highlighting the region, or if the cursor is in the echo area,
10079 then we can't just move the cursor. */
10080 else if (! (!NILP (Vtransient_mark_mode)
10081 && !NILP (current_buffer->mark_active))
10082 && (EQ (selected_window, current_buffer->last_selected_window)
10083 || highlight_nonselected_windows)
10084 && NILP (w->region_showing)
10085 && NILP (Vshow_trailing_whitespace)
10086 && !cursor_in_echo_area)
10088 struct it it;
10089 struct glyph_row *row;
10091 /* Skip from tlbufpos to PT and see where it is. Note that
10092 PT may be in invisible text. If so, we will end at the
10093 next visible position. */
10094 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
10095 NULL, DEFAULT_FACE_ID);
10096 it.current_x = this_line_start_x;
10097 it.current_y = this_line_y;
10098 it.vpos = this_line_vpos;
10100 /* The call to move_it_to stops in front of PT, but
10101 moves over before-strings. */
10102 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
10104 if (it.vpos == this_line_vpos
10105 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
10106 row->enabled_p))
10108 xassert (this_line_vpos == it.vpos);
10109 xassert (this_line_y == it.current_y);
10110 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
10111 #if GLYPH_DEBUG
10112 *w->desired_matrix->method = 0;
10113 debug_method_add (w, "optimization 3");
10114 #endif
10115 goto update;
10117 else
10118 goto cancel;
10121 cancel:
10122 /* Text changed drastically or point moved off of line. */
10123 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
10126 CHARPOS (this_line_start_pos) = 0;
10127 consider_all_windows_p |= buffer_shared > 1;
10128 ++clear_face_cache_count;
10131 /* Build desired matrices, and update the display. If
10132 consider_all_windows_p is non-zero, do it for all windows on all
10133 frames. Otherwise do it for selected_window, only. */
10135 if (consider_all_windows_p)
10137 Lisp_Object tail, frame;
10138 int i, n = 0, size = 50;
10139 struct frame **updated
10140 = (struct frame **) alloca (size * sizeof *updated);
10142 /* Clear the face cache eventually. */
10143 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
10145 clear_face_cache (0);
10146 clear_face_cache_count = 0;
10149 /* Recompute # windows showing selected buffer. This will be
10150 incremented each time such a window is displayed. */
10151 buffer_shared = 0;
10153 FOR_EACH_FRAME (tail, frame)
10155 struct frame *f = XFRAME (frame);
10157 if (FRAME_WINDOW_P (f) || f == sf)
10159 if (! EQ (frame, selected_frame))
10160 /* Select the frame, for the sake of frame-local
10161 variables. */
10162 select_frame_for_redisplay (frame);
10164 #ifdef HAVE_WINDOW_SYSTEM
10165 if (clear_face_cache_count % 50 == 0
10166 && FRAME_WINDOW_P (f))
10167 clear_image_cache (f, 0);
10168 #endif /* HAVE_WINDOW_SYSTEM */
10170 /* Mark all the scroll bars to be removed; we'll redeem
10171 the ones we want when we redisplay their windows. */
10172 if (condemn_scroll_bars_hook)
10173 condemn_scroll_bars_hook (f);
10175 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
10176 redisplay_windows (FRAME_ROOT_WINDOW (f));
10178 /* Any scroll bars which redisplay_windows should have
10179 nuked should now go away. */
10180 if (judge_scroll_bars_hook)
10181 judge_scroll_bars_hook (f);
10183 /* If fonts changed, display again. */
10184 /* ??? rms: I suspect it is a mistake to jump all the way
10185 back to retry here. It should just retry this frame. */
10186 if (fonts_changed_p)
10187 goto retry;
10189 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
10191 /* See if we have to hscroll. */
10192 if (hscroll_windows (f->root_window))
10193 goto retry;
10195 /* Prevent various kinds of signals during display
10196 update. stdio is not robust about handling
10197 signals, which can cause an apparent I/O
10198 error. */
10199 if (interrupt_input)
10200 unrequest_sigio ();
10201 STOP_POLLING;
10203 /* Update the display. */
10204 set_window_update_flags (XWINDOW (f->root_window), 1);
10205 pause |= update_frame (f, 0, 0);
10206 #if 0 /* Exiting the loop can leave the wrong value for buffer_shared. */
10207 if (pause)
10208 break;
10209 #endif
10211 if (n == size)
10213 int nbytes = size * sizeof *updated;
10214 struct frame **p = (struct frame **) alloca (2 * nbytes);
10215 bcopy (updated, p, nbytes);
10216 size *= 2;
10219 updated[n++] = f;
10224 if (!pause)
10226 /* Do the mark_window_display_accurate after all windows have
10227 been redisplayed because this call resets flags in buffers
10228 which are needed for proper redisplay. */
10229 for (i = 0; i < n; ++i)
10231 struct frame *f = updated[i];
10232 mark_window_display_accurate (f->root_window, 1);
10233 if (frame_up_to_date_hook)
10234 frame_up_to_date_hook (f);
10238 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
10240 Lisp_Object mini_window;
10241 struct frame *mini_frame;
10243 displayed_buffer = XBUFFER (XWINDOW (selected_window)->buffer);
10244 /* Use list_of_error, not Qerror, so that
10245 we catch only errors and don't run the debugger. */
10246 internal_condition_case_1 (redisplay_window_1, selected_window,
10247 list_of_error,
10248 redisplay_window_error);
10250 /* Compare desired and current matrices, perform output. */
10252 update:
10253 /* If fonts changed, display again. */
10254 if (fonts_changed_p)
10255 goto retry;
10257 /* Prevent various kinds of signals during display update.
10258 stdio is not robust about handling signals,
10259 which can cause an apparent I/O error. */
10260 if (interrupt_input)
10261 unrequest_sigio ();
10262 STOP_POLLING;
10264 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
10266 if (hscroll_windows (selected_window))
10267 goto retry;
10269 XWINDOW (selected_window)->must_be_updated_p = 1;
10270 pause = update_frame (sf, 0, 0);
10273 /* We may have called echo_area_display at the top of this
10274 function. If the echo area is on another frame, that may
10275 have put text on a frame other than the selected one, so the
10276 above call to update_frame would not have caught it. Catch
10277 it here. */
10278 mini_window = FRAME_MINIBUF_WINDOW (sf);
10279 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
10281 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
10283 XWINDOW (mini_window)->must_be_updated_p = 1;
10284 pause |= update_frame (mini_frame, 0, 0);
10285 if (!pause && hscroll_windows (mini_window))
10286 goto retry;
10290 /* If display was paused because of pending input, make sure we do a
10291 thorough update the next time. */
10292 if (pause)
10294 /* Prevent the optimization at the beginning of
10295 redisplay_internal that tries a single-line update of the
10296 line containing the cursor in the selected window. */
10297 CHARPOS (this_line_start_pos) = 0;
10299 /* Let the overlay arrow be updated the next time. */
10300 update_overlay_arrows (0);
10302 /* If we pause after scrolling, some rows in the current
10303 matrices of some windows are not valid. */
10304 if (!WINDOW_FULL_WIDTH_P (w)
10305 && !FRAME_WINDOW_P (XFRAME (w->frame)))
10306 update_mode_lines = 1;
10308 else
10310 if (!consider_all_windows_p)
10312 /* This has already been done above if
10313 consider_all_windows_p is set. */
10314 mark_window_display_accurate_1 (w, 1);
10316 /* Say overlay arrows are up to date. */
10317 update_overlay_arrows (1);
10319 if (frame_up_to_date_hook != 0)
10320 frame_up_to_date_hook (sf);
10323 update_mode_lines = 0;
10324 windows_or_buffers_changed = 0;
10325 cursor_type_changed = 0;
10328 /* Start SIGIO interrupts coming again. Having them off during the
10329 code above makes it less likely one will discard output, but not
10330 impossible, since there might be stuff in the system buffer here.
10331 But it is much hairier to try to do anything about that. */
10332 if (interrupt_input)
10333 request_sigio ();
10334 RESUME_POLLING;
10336 /* If a frame has become visible which was not before, redisplay
10337 again, so that we display it. Expose events for such a frame
10338 (which it gets when becoming visible) don't call the parts of
10339 redisplay constructing glyphs, so simply exposing a frame won't
10340 display anything in this case. So, we have to display these
10341 frames here explicitly. */
10342 if (!pause)
10344 Lisp_Object tail, frame;
10345 int new_count = 0;
10347 FOR_EACH_FRAME (tail, frame)
10349 int this_is_visible = 0;
10351 if (XFRAME (frame)->visible)
10352 this_is_visible = 1;
10353 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
10354 if (XFRAME (frame)->visible)
10355 this_is_visible = 1;
10357 if (this_is_visible)
10358 new_count++;
10361 if (new_count != number_of_visible_frames)
10362 windows_or_buffers_changed++;
10365 /* Change frame size now if a change is pending. */
10366 do_pending_window_change (1);
10368 /* If we just did a pending size change, or have additional
10369 visible frames, redisplay again. */
10370 if (windows_or_buffers_changed && !pause)
10371 goto retry;
10373 end_of_redisplay:
10374 unbind_to (count, Qnil);
10375 RESUME_POLLING;
10379 /* Redisplay, but leave alone any recent echo area message unless
10380 another message has been requested in its place.
10382 This is useful in situations where you need to redisplay but no
10383 user action has occurred, making it inappropriate for the message
10384 area to be cleared. See tracking_off and
10385 wait_reading_process_output for examples of these situations.
10387 FROM_WHERE is an integer saying from where this function was
10388 called. This is useful for debugging. */
10390 void
10391 redisplay_preserve_echo_area (from_where)
10392 int from_where;
10394 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
10396 if (!NILP (echo_area_buffer[1]))
10398 /* We have a previously displayed message, but no current
10399 message. Redisplay the previous message. */
10400 display_last_displayed_message_p = 1;
10401 redisplay_internal (1);
10402 display_last_displayed_message_p = 0;
10404 else
10405 redisplay_internal (1);
10409 /* Function registered with record_unwind_protect in
10410 redisplay_internal. Reset redisplaying_p to the value it had
10411 before redisplay_internal was called, and clear
10412 prevent_freeing_realized_faces_p. It also selects the previously
10413 selected frame. */
10415 static Lisp_Object
10416 unwind_redisplay (val)
10417 Lisp_Object val;
10419 Lisp_Object old_redisplaying_p, old_frame;
10421 old_redisplaying_p = XCAR (val);
10422 redisplaying_p = XFASTINT (old_redisplaying_p);
10423 old_frame = XCDR (val);
10424 if (! EQ (old_frame, selected_frame))
10425 select_frame_for_redisplay (old_frame);
10426 return Qnil;
10430 /* Mark the display of window W as accurate or inaccurate. If
10431 ACCURATE_P is non-zero mark display of W as accurate. If
10432 ACCURATE_P is zero, arrange for W to be redisplayed the next time
10433 redisplay_internal is called. */
10435 static void
10436 mark_window_display_accurate_1 (w, accurate_p)
10437 struct window *w;
10438 int accurate_p;
10440 if (BUFFERP (w->buffer))
10442 struct buffer *b = XBUFFER (w->buffer);
10444 w->last_modified
10445 = make_number (accurate_p ? BUF_MODIFF (b) : 0);
10446 w->last_overlay_modified
10447 = make_number (accurate_p ? BUF_OVERLAY_MODIFF (b) : 0);
10448 w->last_had_star
10449 = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b) ? Qt : Qnil;
10451 if (accurate_p)
10453 b->clip_changed = 0;
10454 b->prevent_redisplay_optimizations_p = 0;
10456 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
10457 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
10458 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
10459 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
10461 w->current_matrix->buffer = b;
10462 w->current_matrix->begv = BUF_BEGV (b);
10463 w->current_matrix->zv = BUF_ZV (b);
10465 w->last_cursor = w->cursor;
10466 w->last_cursor_off_p = w->cursor_off_p;
10468 if (w == XWINDOW (selected_window))
10469 w->last_point = make_number (BUF_PT (b));
10470 else
10471 w->last_point = make_number (XMARKER (w->pointm)->charpos);
10475 if (accurate_p)
10477 w->window_end_valid = w->buffer;
10478 #if 0 /* This is incorrect with variable-height lines. */
10479 xassert (XINT (w->window_end_vpos)
10480 < (WINDOW_TOTAL_LINES (w)
10481 - (WINDOW_WANTS_MODELINE_P (w) ? 1 : 0)));
10482 #endif
10483 w->update_mode_line = Qnil;
10488 /* Mark the display of windows in the window tree rooted at WINDOW as
10489 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
10490 windows as accurate. If ACCURATE_P is zero, arrange for windows to
10491 be redisplayed the next time redisplay_internal is called. */
10493 void
10494 mark_window_display_accurate (window, accurate_p)
10495 Lisp_Object window;
10496 int accurate_p;
10498 struct window *w;
10500 for (; !NILP (window); window = w->next)
10502 w = XWINDOW (window);
10503 mark_window_display_accurate_1 (w, accurate_p);
10505 if (!NILP (w->vchild))
10506 mark_window_display_accurate (w->vchild, accurate_p);
10507 if (!NILP (w->hchild))
10508 mark_window_display_accurate (w->hchild, accurate_p);
10511 if (accurate_p)
10513 update_overlay_arrows (1);
10515 else
10517 /* Force a thorough redisplay the next time by setting
10518 last_arrow_position and last_arrow_string to t, which is
10519 unequal to any useful value of Voverlay_arrow_... */
10520 update_overlay_arrows (-1);
10525 /* Return value in display table DP (Lisp_Char_Table *) for character
10526 C. Since a display table doesn't have any parent, we don't have to
10527 follow parent. Do not call this function directly but use the
10528 macro DISP_CHAR_VECTOR. */
10530 Lisp_Object
10531 disp_char_vector (dp, c)
10532 struct Lisp_Char_Table *dp;
10533 int c;
10535 int code[4], i;
10536 Lisp_Object val;
10538 if (SINGLE_BYTE_CHAR_P (c))
10539 return (dp->contents[c]);
10541 SPLIT_CHAR (c, code[0], code[1], code[2]);
10542 if (code[1] < 32)
10543 code[1] = -1;
10544 else if (code[2] < 32)
10545 code[2] = -1;
10547 /* Here, the possible range of code[0] (== charset ID) is
10548 128..max_charset. Since the top level char table contains data
10549 for multibyte characters after 256th element, we must increment
10550 code[0] by 128 to get a correct index. */
10551 code[0] += 128;
10552 code[3] = -1; /* anchor */
10554 for (i = 0; code[i] >= 0; i++, dp = XCHAR_TABLE (val))
10556 val = dp->contents[code[i]];
10557 if (!SUB_CHAR_TABLE_P (val))
10558 return (NILP (val) ? dp->defalt : val);
10561 /* Here, val is a sub char table. We return the default value of
10562 it. */
10563 return (dp->defalt);
10568 /***********************************************************************
10569 Window Redisplay
10570 ***********************************************************************/
10572 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
10574 static void
10575 redisplay_windows (window)
10576 Lisp_Object window;
10578 while (!NILP (window))
10580 struct window *w = XWINDOW (window);
10582 if (!NILP (w->hchild))
10583 redisplay_windows (w->hchild);
10584 else if (!NILP (w->vchild))
10585 redisplay_windows (w->vchild);
10586 else
10588 displayed_buffer = XBUFFER (w->buffer);
10589 /* Use list_of_error, not Qerror, so that
10590 we catch only errors and don't run the debugger. */
10591 internal_condition_case_1 (redisplay_window_0, window,
10592 list_of_error,
10593 redisplay_window_error);
10596 window = w->next;
10600 static Lisp_Object
10601 redisplay_window_error ()
10603 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
10604 return Qnil;
10607 static Lisp_Object
10608 redisplay_window_0 (window)
10609 Lisp_Object window;
10611 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
10612 redisplay_window (window, 0);
10613 return Qnil;
10616 static Lisp_Object
10617 redisplay_window_1 (window)
10618 Lisp_Object window;
10620 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
10621 redisplay_window (window, 1);
10622 return Qnil;
10626 /* Increment GLYPH until it reaches END or CONDITION fails while
10627 adding (GLYPH)->pixel_width to X. */
10629 #define SKIP_GLYPHS(glyph, end, x, condition) \
10630 do \
10632 (x) += (glyph)->pixel_width; \
10633 ++(glyph); \
10635 while ((glyph) < (end) && (condition))
10638 /* Set cursor position of W. PT is assumed to be displayed in ROW.
10639 DELTA is the number of bytes by which positions recorded in ROW
10640 differ from current buffer positions. */
10642 void
10643 set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
10644 struct window *w;
10645 struct glyph_row *row;
10646 struct glyph_matrix *matrix;
10647 int delta, delta_bytes, dy, dvpos;
10649 struct glyph *glyph = row->glyphs[TEXT_AREA];
10650 struct glyph *end = glyph + row->used[TEXT_AREA];
10651 struct glyph *cursor = NULL;
10652 /* The first glyph that starts a sequence of glyphs from string. */
10653 struct glyph *string_start;
10654 /* The X coordinate of string_start. */
10655 int string_start_x;
10656 /* The last known character position. */
10657 int last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
10658 /* The last known character position before string_start. */
10659 int string_before_pos;
10660 int x = row->x;
10661 int cursor_x = x;
10662 int cursor_from_overlay_pos = 0;
10663 int pt_old = PT - delta;
10665 /* Skip over glyphs not having an object at the start of the row.
10666 These are special glyphs like truncation marks on terminal
10667 frames. */
10668 if (row->displays_text_p)
10669 while (glyph < end
10670 && INTEGERP (glyph->object)
10671 && glyph->charpos < 0)
10673 x += glyph->pixel_width;
10674 ++glyph;
10677 string_start = NULL;
10678 while (glyph < end
10679 && !INTEGERP (glyph->object)
10680 && (!BUFFERP (glyph->object)
10681 || (last_pos = glyph->charpos) < pt_old))
10683 if (! STRINGP (glyph->object))
10685 string_start = NULL;
10686 x += glyph->pixel_width;
10687 ++glyph;
10688 if (cursor_from_overlay_pos
10689 && last_pos > cursor_from_overlay_pos)
10691 cursor_from_overlay_pos = 0;
10692 cursor = 0;
10695 else
10697 string_before_pos = last_pos;
10698 string_start = glyph;
10699 string_start_x = x;
10700 /* Skip all glyphs from string. */
10703 int pos;
10704 if ((cursor == NULL || glyph > cursor)
10705 && !NILP (Fget_char_property (make_number ((glyph)->charpos),
10706 Qcursor, (glyph)->object))
10707 && (pos = string_buffer_position (w, glyph->object,
10708 string_before_pos),
10709 (pos == 0 /* From overlay */
10710 || pos == pt_old)))
10712 cursor_from_overlay_pos = pos == 0 ? last_pos : 0;
10713 cursor = glyph;
10714 cursor_x = x;
10716 x += glyph->pixel_width;
10717 ++glyph;
10719 while (glyph < end && STRINGP (glyph->object));
10723 if (cursor != NULL)
10725 glyph = cursor;
10726 x = cursor_x;
10728 else if (string_start
10729 && (glyph == end || !BUFFERP (glyph->object) || last_pos > pt_old))
10731 /* We may have skipped over point because the previous glyphs
10732 are from string. As there's no easy way to know the
10733 character position of the current glyph, find the correct
10734 glyph on point by scanning from string_start again. */
10735 Lisp_Object limit;
10736 Lisp_Object string;
10737 int pos;
10739 limit = make_number (pt_old + 1);
10740 end = glyph;
10741 glyph = string_start;
10742 x = string_start_x;
10743 string = glyph->object;
10744 pos = string_buffer_position (w, string, string_before_pos);
10745 /* If STRING is from overlay, LAST_POS == 0. We skip such glyphs
10746 because we always put cursor after overlay strings. */
10747 while (pos == 0 && glyph < end)
10749 string = glyph->object;
10750 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10751 if (glyph < end)
10752 pos = string_buffer_position (w, glyph->object, string_before_pos);
10755 while (glyph < end)
10757 pos = XINT (Fnext_single_char_property_change
10758 (make_number (pos), Qdisplay, Qnil, limit));
10759 if (pos > pt_old)
10760 break;
10761 /* Skip glyphs from the same string. */
10762 string = glyph->object;
10763 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10764 /* Skip glyphs from an overlay. */
10765 while (glyph < end
10766 && ! string_buffer_position (w, glyph->object, pos))
10768 string = glyph->object;
10769 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10774 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
10775 w->cursor.x = x;
10776 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
10777 w->cursor.y = row->y + dy;
10779 if (w == XWINDOW (selected_window))
10781 if (!row->continued_p
10782 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
10783 && row->x == 0)
10785 this_line_buffer = XBUFFER (w->buffer);
10787 CHARPOS (this_line_start_pos)
10788 = MATRIX_ROW_START_CHARPOS (row) + delta;
10789 BYTEPOS (this_line_start_pos)
10790 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
10792 CHARPOS (this_line_end_pos)
10793 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
10794 BYTEPOS (this_line_end_pos)
10795 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
10797 this_line_y = w->cursor.y;
10798 this_line_pixel_height = row->height;
10799 this_line_vpos = w->cursor.vpos;
10800 this_line_start_x = row->x;
10802 else
10803 CHARPOS (this_line_start_pos) = 0;
10808 /* Run window scroll functions, if any, for WINDOW with new window
10809 start STARTP. Sets the window start of WINDOW to that position.
10811 We assume that the window's buffer is really current. */
10813 static INLINE struct text_pos
10814 run_window_scroll_functions (window, startp)
10815 Lisp_Object window;
10816 struct text_pos startp;
10818 struct window *w = XWINDOW (window);
10819 SET_MARKER_FROM_TEXT_POS (w->start, startp);
10821 if (current_buffer != XBUFFER (w->buffer))
10822 abort ();
10824 if (!NILP (Vwindow_scroll_functions))
10826 run_hook_with_args_2 (Qwindow_scroll_functions, window,
10827 make_number (CHARPOS (startp)));
10828 SET_TEXT_POS_FROM_MARKER (startp, w->start);
10829 /* In case the hook functions switch buffers. */
10830 if (current_buffer != XBUFFER (w->buffer))
10831 set_buffer_internal_1 (XBUFFER (w->buffer));
10834 return startp;
10838 /* Make sure the line containing the cursor is fully visible.
10839 A value of 1 means there is nothing to be done.
10840 (Either the line is fully visible, or it cannot be made so,
10841 or we cannot tell.)
10843 If FORCE_P is non-zero, return 0 even if partial visible cursor row
10844 is higher than window.
10846 A value of 0 means the caller should do scrolling
10847 as if point had gone off the screen. */
10849 static int
10850 make_cursor_line_fully_visible (w, force_p)
10851 struct window *w;
10852 int force_p;
10854 struct glyph_matrix *matrix;
10855 struct glyph_row *row;
10856 int window_height;
10858 /* It's not always possible to find the cursor, e.g, when a window
10859 is full of overlay strings. Don't do anything in that case. */
10860 if (w->cursor.vpos < 0)
10861 return 1;
10863 matrix = w->desired_matrix;
10864 row = MATRIX_ROW (matrix, w->cursor.vpos);
10866 /* If the cursor row is not partially visible, there's nothing to do. */
10867 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (row))
10868 return 1;
10870 /* If the row the cursor is in is taller than the window's height,
10871 it's not clear what to do, so do nothing. */
10872 window_height = window_box_height (w);
10873 if (row->height >= window_height)
10875 if (!force_p || w->vscroll)
10876 return 1;
10878 return 0;
10880 #if 0
10881 /* This code used to try to scroll the window just enough to make
10882 the line visible. It returned 0 to say that the caller should
10883 allocate larger glyph matrices. */
10885 if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row))
10887 int dy = row->height - row->visible_height;
10888 w->vscroll = 0;
10889 w->cursor.y += dy;
10890 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
10892 else /* MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row)) */
10894 int dy = - (row->height - row->visible_height);
10895 w->vscroll = dy;
10896 w->cursor.y += dy;
10897 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
10900 /* When we change the cursor y-position of the selected window,
10901 change this_line_y as well so that the display optimization for
10902 the cursor line of the selected window in redisplay_internal uses
10903 the correct y-position. */
10904 if (w == XWINDOW (selected_window))
10905 this_line_y = w->cursor.y;
10907 /* If vscrolling requires a larger glyph matrix, arrange for a fresh
10908 redisplay with larger matrices. */
10909 if (matrix->nrows < required_matrix_height (w))
10911 fonts_changed_p = 1;
10912 return 0;
10915 return 1;
10916 #endif /* 0 */
10920 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
10921 non-zero means only WINDOW is redisplayed in redisplay_internal.
10922 TEMP_SCROLL_STEP has the same meaning as scroll_step, and is used
10923 in redisplay_window to bring a partially visible line into view in
10924 the case that only the cursor has moved.
10926 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
10927 last screen line's vertical height extends past the end of the screen.
10929 Value is
10931 1 if scrolling succeeded
10933 0 if scrolling didn't find point.
10935 -1 if new fonts have been loaded so that we must interrupt
10936 redisplay, adjust glyph matrices, and try again. */
10938 enum
10940 SCROLLING_SUCCESS,
10941 SCROLLING_FAILED,
10942 SCROLLING_NEED_LARGER_MATRICES
10945 static int
10946 try_scrolling (window, just_this_one_p, scroll_conservatively,
10947 scroll_step, temp_scroll_step, last_line_misfit)
10948 Lisp_Object window;
10949 int just_this_one_p;
10950 EMACS_INT scroll_conservatively, scroll_step;
10951 int temp_scroll_step;
10952 int last_line_misfit;
10954 struct window *w = XWINDOW (window);
10955 struct frame *f = XFRAME (w->frame);
10956 struct text_pos scroll_margin_pos;
10957 struct text_pos pos;
10958 struct text_pos startp;
10959 struct it it;
10960 Lisp_Object window_end;
10961 int this_scroll_margin;
10962 int dy = 0;
10963 int scroll_max;
10964 int rc;
10965 int amount_to_scroll = 0;
10966 Lisp_Object aggressive;
10967 int height;
10968 int extra_scroll_margin_lines = last_line_misfit ? 1 : 0;
10970 #if GLYPH_DEBUG
10971 debug_method_add (w, "try_scrolling");
10972 #endif
10974 SET_TEXT_POS_FROM_MARKER (startp, w->start);
10976 /* Compute scroll margin height in pixels. We scroll when point is
10977 within this distance from the top or bottom of the window. */
10978 if (scroll_margin > 0)
10980 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
10981 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
10983 else
10984 this_scroll_margin = 0;
10986 /* Force scroll_conservatively to have a reasonable value so it doesn't
10987 cause an overflow while computing how much to scroll. */
10988 if (scroll_conservatively)
10989 scroll_conservatively = min (scroll_conservatively,
10990 MOST_POSITIVE_FIXNUM / FRAME_LINE_HEIGHT (f));
10992 /* Compute how much we should try to scroll maximally to bring point
10993 into view. */
10994 if (scroll_step || scroll_conservatively || temp_scroll_step)
10995 scroll_max = max (scroll_step,
10996 max (scroll_conservatively, temp_scroll_step));
10997 else if (NUMBERP (current_buffer->scroll_down_aggressively)
10998 || NUMBERP (current_buffer->scroll_up_aggressively))
10999 /* We're trying to scroll because of aggressive scrolling
11000 but no scroll_step is set. Choose an arbitrary one. Maybe
11001 there should be a variable for this. */
11002 scroll_max = 10;
11003 else
11004 scroll_max = 0;
11005 scroll_max *= FRAME_LINE_HEIGHT (f);
11007 /* Decide whether we have to scroll down. Start at the window end
11008 and move this_scroll_margin up to find the position of the scroll
11009 margin. */
11010 window_end = Fwindow_end (window, Qt);
11012 too_near_end:
11014 CHARPOS (scroll_margin_pos) = XINT (window_end);
11015 BYTEPOS (scroll_margin_pos) = CHAR_TO_BYTE (CHARPOS (scroll_margin_pos));
11017 if (this_scroll_margin || extra_scroll_margin_lines)
11019 start_display (&it, w, scroll_margin_pos);
11020 if (this_scroll_margin)
11021 move_it_vertically (&it, - this_scroll_margin);
11022 if (extra_scroll_margin_lines)
11023 move_it_by_lines (&it, - extra_scroll_margin_lines, 0);
11024 scroll_margin_pos = it.current.pos;
11027 if (PT >= CHARPOS (scroll_margin_pos))
11029 int y0;
11031 /* Point is in the scroll margin at the bottom of the window, or
11032 below. Compute a new window start that makes point visible. */
11034 /* Compute the distance from the scroll margin to PT.
11035 Give up if the distance is greater than scroll_max. */
11036 start_display (&it, w, scroll_margin_pos);
11037 y0 = it.current_y;
11038 move_it_to (&it, PT, 0, it.last_visible_y, -1,
11039 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
11041 /* To make point visible, we have to move the window start
11042 down so that the line the cursor is in is visible, which
11043 means we have to add in the height of the cursor line. */
11044 dy = line_bottom_y (&it) - y0;
11046 if (dy > scroll_max)
11047 return SCROLLING_FAILED;
11049 /* Move the window start down. If scrolling conservatively,
11050 move it just enough down to make point visible. If
11051 scroll_step is set, move it down by scroll_step. */
11052 start_display (&it, w, startp);
11054 if (scroll_conservatively)
11055 /* Set AMOUNT_TO_SCROLL to at least one line,
11056 and at most scroll_conservatively lines. */
11057 amount_to_scroll
11058 = min (max (dy, FRAME_LINE_HEIGHT (f)),
11059 FRAME_LINE_HEIGHT (f) * scroll_conservatively);
11060 else if (scroll_step || temp_scroll_step)
11061 amount_to_scroll = scroll_max;
11062 else
11064 aggressive = current_buffer->scroll_up_aggressively;
11065 height = WINDOW_BOX_TEXT_HEIGHT (w);
11066 if (NUMBERP (aggressive))
11068 double float_amount = XFLOATINT (aggressive) * height;
11069 amount_to_scroll = float_amount;
11070 if (amount_to_scroll == 0 && float_amount > 0)
11071 amount_to_scroll = 1;
11075 if (amount_to_scroll <= 0)
11076 return SCROLLING_FAILED;
11078 /* If moving by amount_to_scroll leaves STARTP unchanged,
11079 move it down one screen line. */
11081 move_it_vertically (&it, amount_to_scroll);
11082 if (CHARPOS (it.current.pos) == CHARPOS (startp))
11083 move_it_by_lines (&it, 1, 1);
11084 startp = it.current.pos;
11086 else
11088 /* See if point is inside the scroll margin at the top of the
11089 window. */
11090 scroll_margin_pos = startp;
11091 if (this_scroll_margin)
11093 start_display (&it, w, startp);
11094 move_it_vertically (&it, this_scroll_margin);
11095 scroll_margin_pos = it.current.pos;
11098 if (PT < CHARPOS (scroll_margin_pos))
11100 /* Point is in the scroll margin at the top of the window or
11101 above what is displayed in the window. */
11102 int y0;
11104 /* Compute the vertical distance from PT to the scroll
11105 margin position. Give up if distance is greater than
11106 scroll_max. */
11107 SET_TEXT_POS (pos, PT, PT_BYTE);
11108 start_display (&it, w, pos);
11109 y0 = it.current_y;
11110 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
11111 it.last_visible_y, -1,
11112 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
11113 dy = it.current_y - y0;
11114 if (dy > scroll_max)
11115 return SCROLLING_FAILED;
11117 /* Compute new window start. */
11118 start_display (&it, w, startp);
11120 if (scroll_conservatively)
11121 amount_to_scroll
11122 = max (dy, FRAME_LINE_HEIGHT (f) * max (scroll_step, temp_scroll_step));
11123 else if (scroll_step || temp_scroll_step)
11124 amount_to_scroll = scroll_max;
11125 else
11127 aggressive = current_buffer->scroll_down_aggressively;
11128 height = WINDOW_BOX_TEXT_HEIGHT (w);
11129 if (NUMBERP (aggressive))
11131 double float_amount = XFLOATINT (aggressive) * height;
11132 amount_to_scroll = float_amount;
11133 if (amount_to_scroll == 0 && float_amount > 0)
11134 amount_to_scroll = 1;
11138 if (amount_to_scroll <= 0)
11139 return SCROLLING_FAILED;
11141 move_it_vertically (&it, - amount_to_scroll);
11142 startp = it.current.pos;
11146 /* Run window scroll functions. */
11147 startp = run_window_scroll_functions (window, startp);
11149 /* Display the window. Give up if new fonts are loaded, or if point
11150 doesn't appear. */
11151 if (!try_window (window, startp))
11152 rc = SCROLLING_NEED_LARGER_MATRICES;
11153 else if (w->cursor.vpos < 0)
11155 clear_glyph_matrix (w->desired_matrix);
11156 rc = SCROLLING_FAILED;
11158 else
11160 /* Maybe forget recorded base line for line number display. */
11161 if (!just_this_one_p
11162 || current_buffer->clip_changed
11163 || BEG_UNCHANGED < CHARPOS (startp))
11164 w->base_line_number = Qnil;
11166 /* If cursor ends up on a partially visible line,
11167 treat that as being off the bottom of the screen. */
11168 if (! make_cursor_line_fully_visible (w, extra_scroll_margin_lines <= 1))
11170 clear_glyph_matrix (w->desired_matrix);
11171 ++extra_scroll_margin_lines;
11172 goto too_near_end;
11174 rc = SCROLLING_SUCCESS;
11177 return rc;
11181 /* Compute a suitable window start for window W if display of W starts
11182 on a continuation line. Value is non-zero if a new window start
11183 was computed.
11185 The new window start will be computed, based on W's width, starting
11186 from the start of the continued line. It is the start of the
11187 screen line with the minimum distance from the old start W->start. */
11189 static int
11190 compute_window_start_on_continuation_line (w)
11191 struct window *w;
11193 struct text_pos pos, start_pos;
11194 int window_start_changed_p = 0;
11196 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
11198 /* If window start is on a continuation line... Window start may be
11199 < BEGV in case there's invisible text at the start of the
11200 buffer (M-x rmail, for example). */
11201 if (CHARPOS (start_pos) > BEGV
11202 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
11204 struct it it;
11205 struct glyph_row *row;
11207 /* Handle the case that the window start is out of range. */
11208 if (CHARPOS (start_pos) < BEGV)
11209 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
11210 else if (CHARPOS (start_pos) > ZV)
11211 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
11213 /* Find the start of the continued line. This should be fast
11214 because scan_buffer is fast (newline cache). */
11215 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
11216 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
11217 row, DEFAULT_FACE_ID);
11218 reseat_at_previous_visible_line_start (&it);
11220 /* If the line start is "too far" away from the window start,
11221 say it takes too much time to compute a new window start. */
11222 if (CHARPOS (start_pos) - IT_CHARPOS (it)
11223 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
11225 int min_distance, distance;
11227 /* Move forward by display lines to find the new window
11228 start. If window width was enlarged, the new start can
11229 be expected to be > the old start. If window width was
11230 decreased, the new window start will be < the old start.
11231 So, we're looking for the display line start with the
11232 minimum distance from the old window start. */
11233 pos = it.current.pos;
11234 min_distance = INFINITY;
11235 while ((distance = abs (CHARPOS (start_pos) - IT_CHARPOS (it))),
11236 distance < min_distance)
11238 min_distance = distance;
11239 pos = it.current.pos;
11240 move_it_by_lines (&it, 1, 0);
11243 /* Set the window start there. */
11244 SET_MARKER_FROM_TEXT_POS (w->start, pos);
11245 window_start_changed_p = 1;
11249 return window_start_changed_p;
11253 /* Try cursor movement in case text has not changed in window WINDOW,
11254 with window start STARTP. Value is
11256 CURSOR_MOVEMENT_SUCCESS if successful
11258 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
11260 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
11261 display. *SCROLL_STEP is set to 1, under certain circumstances, if
11262 we want to scroll as if scroll-step were set to 1. See the code.
11264 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
11265 which case we have to abort this redisplay, and adjust matrices
11266 first. */
11268 enum
11270 CURSOR_MOVEMENT_SUCCESS,
11271 CURSOR_MOVEMENT_CANNOT_BE_USED,
11272 CURSOR_MOVEMENT_MUST_SCROLL,
11273 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
11276 static int
11277 try_cursor_movement (window, startp, scroll_step)
11278 Lisp_Object window;
11279 struct text_pos startp;
11280 int *scroll_step;
11282 struct window *w = XWINDOW (window);
11283 struct frame *f = XFRAME (w->frame);
11284 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
11286 #if GLYPH_DEBUG
11287 if (inhibit_try_cursor_movement)
11288 return rc;
11289 #endif
11291 /* Handle case where text has not changed, only point, and it has
11292 not moved off the frame. */
11293 if (/* Point may be in this window. */
11294 PT >= CHARPOS (startp)
11295 /* Selective display hasn't changed. */
11296 && !current_buffer->clip_changed
11297 /* Function force-mode-line-update is used to force a thorough
11298 redisplay. It sets either windows_or_buffers_changed or
11299 update_mode_lines. So don't take a shortcut here for these
11300 cases. */
11301 && !update_mode_lines
11302 && !windows_or_buffers_changed
11303 && !cursor_type_changed
11304 /* Can't use this case if highlighting a region. When a
11305 region exists, cursor movement has to do more than just
11306 set the cursor. */
11307 && !(!NILP (Vtransient_mark_mode)
11308 && !NILP (current_buffer->mark_active))
11309 && NILP (w->region_showing)
11310 && NILP (Vshow_trailing_whitespace)
11311 /* Right after splitting windows, last_point may be nil. */
11312 && INTEGERP (w->last_point)
11313 /* This code is not used for mini-buffer for the sake of the case
11314 of redisplaying to replace an echo area message; since in
11315 that case the mini-buffer contents per se are usually
11316 unchanged. This code is of no real use in the mini-buffer
11317 since the handling of this_line_start_pos, etc., in redisplay
11318 handles the same cases. */
11319 && !EQ (window, minibuf_window)
11320 /* When splitting windows or for new windows, it happens that
11321 redisplay is called with a nil window_end_vpos or one being
11322 larger than the window. This should really be fixed in
11323 window.c. I don't have this on my list, now, so we do
11324 approximately the same as the old redisplay code. --gerd. */
11325 && INTEGERP (w->window_end_vpos)
11326 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
11327 && (FRAME_WINDOW_P (f)
11328 || !overlay_arrow_in_current_buffer_p ()))
11330 int this_scroll_margin, top_scroll_margin;
11331 struct glyph_row *row = NULL;
11333 #if GLYPH_DEBUG
11334 debug_method_add (w, "cursor movement");
11335 #endif
11337 /* Scroll if point within this distance from the top or bottom
11338 of the window. This is a pixel value. */
11339 this_scroll_margin = max (0, scroll_margin);
11340 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
11341 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
11343 top_scroll_margin = this_scroll_margin;
11344 if (WINDOW_WANTS_HEADER_LINE_P (w))
11345 top_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w);
11347 /* Start with the row the cursor was displayed during the last
11348 not paused redisplay. Give up if that row is not valid. */
11349 if (w->last_cursor.vpos < 0
11350 || w->last_cursor.vpos >= w->current_matrix->nrows)
11351 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11352 else
11354 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
11355 if (row->mode_line_p)
11356 ++row;
11357 if (!row->enabled_p)
11358 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11361 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
11363 int scroll_p = 0;
11364 int last_y = window_text_bottom_y (w) - this_scroll_margin;
11366 if (PT > XFASTINT (w->last_point))
11368 /* Point has moved forward. */
11369 while (MATRIX_ROW_END_CHARPOS (row) < PT
11370 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
11372 xassert (row->enabled_p);
11373 ++row;
11376 /* The end position of a row equals the start position
11377 of the next row. If PT is there, we would rather
11378 display it in the next line. */
11379 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
11380 && MATRIX_ROW_END_CHARPOS (row) == PT
11381 && !cursor_row_p (w, row))
11382 ++row;
11384 /* If within the scroll margin, scroll. Note that
11385 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
11386 the next line would be drawn, and that
11387 this_scroll_margin can be zero. */
11388 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
11389 || PT > MATRIX_ROW_END_CHARPOS (row)
11390 /* Line is completely visible last line in window
11391 and PT is to be set in the next line. */
11392 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
11393 && PT == MATRIX_ROW_END_CHARPOS (row)
11394 && !row->ends_at_zv_p
11395 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
11396 scroll_p = 1;
11398 else if (PT < XFASTINT (w->last_point))
11400 /* Cursor has to be moved backward. Note that PT >=
11401 CHARPOS (startp) because of the outer if-statement. */
11402 while (!row->mode_line_p
11403 && (MATRIX_ROW_START_CHARPOS (row) > PT
11404 || (MATRIX_ROW_START_CHARPOS (row) == PT
11405 && MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)))
11406 && (row->y > top_scroll_margin
11407 || CHARPOS (startp) == BEGV))
11409 xassert (row->enabled_p);
11410 --row;
11413 /* Consider the following case: Window starts at BEGV,
11414 there is invisible, intangible text at BEGV, so that
11415 display starts at some point START > BEGV. It can
11416 happen that we are called with PT somewhere between
11417 BEGV and START. Try to handle that case. */
11418 if (row < w->current_matrix->rows
11419 || row->mode_line_p)
11421 row = w->current_matrix->rows;
11422 if (row->mode_line_p)
11423 ++row;
11426 /* Due to newlines in overlay strings, we may have to
11427 skip forward over overlay strings. */
11428 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
11429 && MATRIX_ROW_END_CHARPOS (row) == PT
11430 && !cursor_row_p (w, row))
11431 ++row;
11433 /* If within the scroll margin, scroll. */
11434 if (row->y < top_scroll_margin
11435 && CHARPOS (startp) != BEGV)
11436 scroll_p = 1;
11439 if (PT < MATRIX_ROW_START_CHARPOS (row)
11440 || PT > MATRIX_ROW_END_CHARPOS (row))
11442 /* if PT is not in the glyph row, give up. */
11443 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11445 else if (MATRIX_ROW_PARTIALLY_VISIBLE_P (row))
11447 if (PT == MATRIX_ROW_END_CHARPOS (row)
11448 && !row->ends_at_zv_p
11449 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
11450 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11451 else if (row->height > window_box_height (w))
11453 /* If we end up in a partially visible line, let's
11454 make it fully visible, except when it's taller
11455 than the window, in which case we can't do much
11456 about it. */
11457 *scroll_step = 1;
11458 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11460 else
11462 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11463 if (!make_cursor_line_fully_visible (w, 0))
11464 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11465 else
11466 rc = CURSOR_MOVEMENT_SUCCESS;
11469 else if (scroll_p)
11470 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11471 else
11473 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11474 rc = CURSOR_MOVEMENT_SUCCESS;
11479 return rc;
11482 void
11483 set_vertical_scroll_bar (w)
11484 struct window *w;
11486 int start, end, whole;
11488 /* Calculate the start and end positions for the current window.
11489 At some point, it would be nice to choose between scrollbars
11490 which reflect the whole buffer size, with special markers
11491 indicating narrowing, and scrollbars which reflect only the
11492 visible region.
11494 Note that mini-buffers sometimes aren't displaying any text. */
11495 if (!MINI_WINDOW_P (w)
11496 || (w == XWINDOW (minibuf_window)
11497 && NILP (echo_area_buffer[0])))
11499 struct buffer *buf = XBUFFER (w->buffer);
11500 whole = BUF_ZV (buf) - BUF_BEGV (buf);
11501 start = marker_position (w->start) - BUF_BEGV (buf);
11502 /* I don't think this is guaranteed to be right. For the
11503 moment, we'll pretend it is. */
11504 end = BUF_Z (buf) - XFASTINT (w->window_end_pos) - BUF_BEGV (buf);
11506 if (end < start)
11507 end = start;
11508 if (whole < (end - start))
11509 whole = end - start;
11511 else
11512 start = end = whole = 0;
11514 /* Indicate what this scroll bar ought to be displaying now. */
11515 set_vertical_scroll_bar_hook (w, end - start, whole, start);
11519 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
11520 selected_window is redisplayed.
11522 We can return without actually redisplaying the window if
11523 fonts_changed_p is nonzero. In that case, redisplay_internal will
11524 retry. */
11526 static void
11527 redisplay_window (window, just_this_one_p)
11528 Lisp_Object window;
11529 int just_this_one_p;
11531 struct window *w = XWINDOW (window);
11532 struct frame *f = XFRAME (w->frame);
11533 struct buffer *buffer = XBUFFER (w->buffer);
11534 struct buffer *old = current_buffer;
11535 struct text_pos lpoint, opoint, startp;
11536 int update_mode_line;
11537 int tem;
11538 struct it it;
11539 /* Record it now because it's overwritten. */
11540 int current_matrix_up_to_date_p = 0;
11541 int used_current_matrix_p = 0;
11542 /* This is less strict than current_matrix_up_to_date_p.
11543 It indictes that the buffer contents and narrowing are unchanged. */
11544 int buffer_unchanged_p = 0;
11545 int temp_scroll_step = 0;
11546 int count = SPECPDL_INDEX ();
11547 int rc;
11548 int centering_position;
11549 int last_line_misfit = 0;
11551 SET_TEXT_POS (lpoint, PT, PT_BYTE);
11552 opoint = lpoint;
11554 /* W must be a leaf window here. */
11555 xassert (!NILP (w->buffer));
11556 #if GLYPH_DEBUG
11557 *w->desired_matrix->method = 0;
11558 #endif
11560 specbind (Qinhibit_point_motion_hooks, Qt);
11562 reconsider_clip_changes (w, buffer);
11564 /* Has the mode line to be updated? */
11565 update_mode_line = (!NILP (w->update_mode_line)
11566 || update_mode_lines
11567 || buffer->clip_changed
11568 || buffer->prevent_redisplay_optimizations_p);
11570 if (MINI_WINDOW_P (w))
11572 if (w == XWINDOW (echo_area_window)
11573 && !NILP (echo_area_buffer[0]))
11575 if (update_mode_line)
11576 /* We may have to update a tty frame's menu bar or a
11577 tool-bar. Example `M-x C-h C-h C-g'. */
11578 goto finish_menu_bars;
11579 else
11580 /* We've already displayed the echo area glyphs in this window. */
11581 goto finish_scroll_bars;
11583 else if ((w != XWINDOW (minibuf_window)
11584 || minibuf_level == 0)
11585 /* When buffer is nonempty, redisplay window normally. */
11586 && BUF_Z (XBUFFER (w->buffer)) == BUF_BEG (XBUFFER (w->buffer))
11587 /* Quail displays non-mini buffers in minibuffer window.
11588 In that case, redisplay the window normally. */
11589 && !NILP (Fmemq (w->buffer, Vminibuffer_list)))
11591 /* W is a mini-buffer window, but it's not active, so clear
11592 it. */
11593 int yb = window_text_bottom_y (w);
11594 struct glyph_row *row;
11595 int y;
11597 for (y = 0, row = w->desired_matrix->rows;
11598 y < yb;
11599 y += row->height, ++row)
11600 blank_row (w, row, y);
11601 goto finish_scroll_bars;
11604 clear_glyph_matrix (w->desired_matrix);
11607 /* Otherwise set up data on this window; select its buffer and point
11608 value. */
11609 /* Really select the buffer, for the sake of buffer-local
11610 variables. */
11611 set_buffer_internal_1 (XBUFFER (w->buffer));
11612 SET_TEXT_POS (opoint, PT, PT_BYTE);
11614 current_matrix_up_to_date_p
11615 = (!NILP (w->window_end_valid)
11616 && !current_buffer->clip_changed
11617 && !current_buffer->prevent_redisplay_optimizations_p
11618 && XFASTINT (w->last_modified) >= MODIFF
11619 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
11621 buffer_unchanged_p
11622 = (!NILP (w->window_end_valid)
11623 && !current_buffer->clip_changed
11624 && XFASTINT (w->last_modified) >= MODIFF
11625 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
11627 /* When windows_or_buffers_changed is non-zero, we can't rely on
11628 the window end being valid, so set it to nil there. */
11629 if (windows_or_buffers_changed)
11631 /* If window starts on a continuation line, maybe adjust the
11632 window start in case the window's width changed. */
11633 if (XMARKER (w->start)->buffer == current_buffer)
11634 compute_window_start_on_continuation_line (w);
11636 w->window_end_valid = Qnil;
11639 /* Some sanity checks. */
11640 CHECK_WINDOW_END (w);
11641 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
11642 abort ();
11643 if (BYTEPOS (opoint) < CHARPOS (opoint))
11644 abort ();
11646 /* If %c is in mode line, update it if needed. */
11647 if (!NILP (w->column_number_displayed)
11648 /* This alternative quickly identifies a common case
11649 where no change is needed. */
11650 && !(PT == XFASTINT (w->last_point)
11651 && XFASTINT (w->last_modified) >= MODIFF
11652 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
11653 && (XFASTINT (w->column_number_displayed)
11654 != (int) current_column ())) /* iftc */
11655 update_mode_line = 1;
11657 /* Count number of windows showing the selected buffer. An indirect
11658 buffer counts as its base buffer. */
11659 if (!just_this_one_p)
11661 struct buffer *current_base, *window_base;
11662 current_base = current_buffer;
11663 window_base = XBUFFER (XWINDOW (selected_window)->buffer);
11664 if (current_base->base_buffer)
11665 current_base = current_base->base_buffer;
11666 if (window_base->base_buffer)
11667 window_base = window_base->base_buffer;
11668 if (current_base == window_base)
11669 buffer_shared++;
11672 /* Point refers normally to the selected window. For any other
11673 window, set up appropriate value. */
11674 if (!EQ (window, selected_window))
11676 int new_pt = XMARKER (w->pointm)->charpos;
11677 int new_pt_byte = marker_byte_position (w->pointm);
11678 if (new_pt < BEGV)
11680 new_pt = BEGV;
11681 new_pt_byte = BEGV_BYTE;
11682 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
11684 else if (new_pt > (ZV - 1))
11686 new_pt = ZV;
11687 new_pt_byte = ZV_BYTE;
11688 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
11691 /* We don't use SET_PT so that the point-motion hooks don't run. */
11692 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
11695 /* If any of the character widths specified in the display table
11696 have changed, invalidate the width run cache. It's true that
11697 this may be a bit late to catch such changes, but the rest of
11698 redisplay goes (non-fatally) haywire when the display table is
11699 changed, so why should we worry about doing any better? */
11700 if (current_buffer->width_run_cache)
11702 struct Lisp_Char_Table *disptab = buffer_display_table ();
11704 if (! disptab_matches_widthtab (disptab,
11705 XVECTOR (current_buffer->width_table)))
11707 invalidate_region_cache (current_buffer,
11708 current_buffer->width_run_cache,
11709 BEG, Z);
11710 recompute_width_table (current_buffer, disptab);
11714 /* If window-start is screwed up, choose a new one. */
11715 if (XMARKER (w->start)->buffer != current_buffer)
11716 goto recenter;
11718 SET_TEXT_POS_FROM_MARKER (startp, w->start);
11720 /* If someone specified a new starting point but did not insist,
11721 check whether it can be used. */
11722 if (!NILP (w->optional_new_start)
11723 && CHARPOS (startp) >= BEGV
11724 && CHARPOS (startp) <= ZV)
11726 w->optional_new_start = Qnil;
11727 start_display (&it, w, startp);
11728 move_it_to (&it, PT, 0, it.last_visible_y, -1,
11729 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
11730 if (IT_CHARPOS (it) == PT)
11731 w->force_start = Qt;
11732 /* IT may overshoot PT if text at PT is invisible. */
11733 else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT)
11734 w->force_start = Qt;
11739 /* Handle case where place to start displaying has been specified,
11740 unless the specified location is outside the accessible range. */
11741 if (!NILP (w->force_start)
11742 || w->frozen_window_start_p)
11744 /* We set this later on if we have to adjust point. */
11745 int new_vpos = -1;
11747 w->force_start = Qnil;
11748 w->vscroll = 0;
11749 w->window_end_valid = Qnil;
11751 /* Forget any recorded base line for line number display. */
11752 if (!buffer_unchanged_p)
11753 w->base_line_number = Qnil;
11755 /* Redisplay the mode line. Select the buffer properly for that.
11756 Also, run the hook window-scroll-functions
11757 because we have scrolled. */
11758 /* Note, we do this after clearing force_start because
11759 if there's an error, it is better to forget about force_start
11760 than to get into an infinite loop calling the hook functions
11761 and having them get more errors. */
11762 if (!update_mode_line
11763 || ! NILP (Vwindow_scroll_functions))
11765 update_mode_line = 1;
11766 w->update_mode_line = Qt;
11767 startp = run_window_scroll_functions (window, startp);
11770 w->last_modified = make_number (0);
11771 w->last_overlay_modified = make_number (0);
11772 if (CHARPOS (startp) < BEGV)
11773 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
11774 else if (CHARPOS (startp) > ZV)
11775 SET_TEXT_POS (startp, ZV, ZV_BYTE);
11777 /* Redisplay, then check if cursor has been set during the
11778 redisplay. Give up if new fonts were loaded. */
11779 if (!try_window (window, startp))
11781 w->force_start = Qt;
11782 clear_glyph_matrix (w->desired_matrix);
11783 goto need_larger_matrices;
11786 if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
11788 /* If point does not appear, try to move point so it does
11789 appear. The desired matrix has been built above, so we
11790 can use it here. */
11791 new_vpos = window_box_height (w) / 2;
11794 if (!make_cursor_line_fully_visible (w, 0))
11796 /* Point does appear, but on a line partly visible at end of window.
11797 Move it back to a fully-visible line. */
11798 new_vpos = window_box_height (w);
11801 /* If we need to move point for either of the above reasons,
11802 now actually do it. */
11803 if (new_vpos >= 0)
11805 struct glyph_row *row;
11807 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
11808 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
11809 ++row;
11811 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
11812 MATRIX_ROW_START_BYTEPOS (row));
11814 if (w != XWINDOW (selected_window))
11815 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
11816 else if (current_buffer == old)
11817 SET_TEXT_POS (lpoint, PT, PT_BYTE);
11819 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
11821 /* If we are highlighting the region, then we just changed
11822 the region, so redisplay to show it. */
11823 if (!NILP (Vtransient_mark_mode)
11824 && !NILP (current_buffer->mark_active))
11826 clear_glyph_matrix (w->desired_matrix);
11827 if (!try_window (window, startp))
11828 goto need_larger_matrices;
11832 #if GLYPH_DEBUG
11833 debug_method_add (w, "forced window start");
11834 #endif
11835 goto done;
11838 /* Handle case where text has not changed, only point, and it has
11839 not moved off the frame, and we are not retrying after hscroll.
11840 (current_matrix_up_to_date_p is nonzero when retrying.) */
11841 if (current_matrix_up_to_date_p
11842 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
11843 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
11845 switch (rc)
11847 case CURSOR_MOVEMENT_SUCCESS:
11848 used_current_matrix_p = 1;
11849 goto done;
11851 #if 0 /* try_cursor_movement never returns this value. */
11852 case CURSOR_MOVEMENT_NEED_LARGER_MATRICES:
11853 goto need_larger_matrices;
11854 #endif
11856 case CURSOR_MOVEMENT_MUST_SCROLL:
11857 goto try_to_scroll;
11859 default:
11860 abort ();
11863 /* If current starting point was originally the beginning of a line
11864 but no longer is, find a new starting point. */
11865 else if (!NILP (w->start_at_line_beg)
11866 && !(CHARPOS (startp) <= BEGV
11867 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
11869 #if GLYPH_DEBUG
11870 debug_method_add (w, "recenter 1");
11871 #endif
11872 goto recenter;
11875 /* Try scrolling with try_window_id. Value is > 0 if update has
11876 been done, it is -1 if we know that the same window start will
11877 not work. It is 0 if unsuccessful for some other reason. */
11878 else if ((tem = try_window_id (w)) != 0)
11880 #if GLYPH_DEBUG
11881 debug_method_add (w, "try_window_id %d", tem);
11882 #endif
11884 if (fonts_changed_p)
11885 goto need_larger_matrices;
11886 if (tem > 0)
11887 goto done;
11889 /* Otherwise try_window_id has returned -1 which means that we
11890 don't want the alternative below this comment to execute. */
11892 else if (CHARPOS (startp) >= BEGV
11893 && CHARPOS (startp) <= ZV
11894 && PT >= CHARPOS (startp)
11895 && (CHARPOS (startp) < ZV
11896 /* Avoid starting at end of buffer. */
11897 || CHARPOS (startp) == BEGV
11898 || (XFASTINT (w->last_modified) >= MODIFF
11899 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)))
11901 #if GLYPH_DEBUG
11902 debug_method_add (w, "same window start");
11903 #endif
11905 /* Try to redisplay starting at same place as before.
11906 If point has not moved off frame, accept the results. */
11907 if (!current_matrix_up_to_date_p
11908 /* Don't use try_window_reusing_current_matrix in this case
11909 because a window scroll function can have changed the
11910 buffer. */
11911 || !NILP (Vwindow_scroll_functions)
11912 || MINI_WINDOW_P (w)
11913 || !(used_current_matrix_p
11914 = try_window_reusing_current_matrix (w)))
11916 IF_DEBUG (debug_method_add (w, "1"));
11917 try_window (window, startp);
11920 if (fonts_changed_p)
11921 goto need_larger_matrices;
11923 if (w->cursor.vpos >= 0)
11925 if (!just_this_one_p
11926 || current_buffer->clip_changed
11927 || BEG_UNCHANGED < CHARPOS (startp))
11928 /* Forget any recorded base line for line number display. */
11929 w->base_line_number = Qnil;
11931 if (!make_cursor_line_fully_visible (w, 1))
11933 clear_glyph_matrix (w->desired_matrix);
11934 last_line_misfit = 1;
11936 /* Drop through and scroll. */
11937 else
11938 goto done;
11940 else
11941 clear_glyph_matrix (w->desired_matrix);
11944 try_to_scroll:
11946 w->last_modified = make_number (0);
11947 w->last_overlay_modified = make_number (0);
11949 /* Redisplay the mode line. Select the buffer properly for that. */
11950 if (!update_mode_line)
11952 update_mode_line = 1;
11953 w->update_mode_line = Qt;
11956 /* Try to scroll by specified few lines. */
11957 if ((scroll_conservatively
11958 || scroll_step
11959 || temp_scroll_step
11960 || NUMBERP (current_buffer->scroll_up_aggressively)
11961 || NUMBERP (current_buffer->scroll_down_aggressively))
11962 && !current_buffer->clip_changed
11963 && CHARPOS (startp) >= BEGV
11964 && CHARPOS (startp) <= ZV)
11966 /* The function returns -1 if new fonts were loaded, 1 if
11967 successful, 0 if not successful. */
11968 int rc = try_scrolling (window, just_this_one_p,
11969 scroll_conservatively,
11970 scroll_step,
11971 temp_scroll_step, last_line_misfit);
11972 switch (rc)
11974 case SCROLLING_SUCCESS:
11975 goto done;
11977 case SCROLLING_NEED_LARGER_MATRICES:
11978 goto need_larger_matrices;
11980 case SCROLLING_FAILED:
11981 break;
11983 default:
11984 abort ();
11988 /* Finally, just choose place to start which centers point */
11990 recenter:
11991 centering_position = window_box_height (w) / 2;
11993 point_at_top:
11994 /* Jump here with centering_position already set to 0. */
11996 #if GLYPH_DEBUG
11997 debug_method_add (w, "recenter");
11998 #endif
12000 /* w->vscroll = 0; */
12002 /* Forget any previously recorded base line for line number display. */
12003 if (!buffer_unchanged_p)
12004 w->base_line_number = Qnil;
12006 /* Move backward half the height of the window. */
12007 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
12008 it.current_y = it.last_visible_y;
12009 move_it_vertically_backward (&it, centering_position);
12010 xassert (IT_CHARPOS (it) >= BEGV);
12012 /* The function move_it_vertically_backward may move over more
12013 than the specified y-distance. If it->w is small, e.g. a
12014 mini-buffer window, we may end up in front of the window's
12015 display area. Start displaying at the start of the line
12016 containing PT in this case. */
12017 if (it.current_y <= 0)
12019 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
12020 move_it_vertically (&it, 0);
12021 xassert (IT_CHARPOS (it) <= PT);
12022 it.current_y = 0;
12025 it.current_x = it.hpos = 0;
12027 /* Set startp here explicitly in case that helps avoid an infinite loop
12028 in case the window-scroll-functions functions get errors. */
12029 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
12031 /* Run scroll hooks. */
12032 startp = run_window_scroll_functions (window, it.current.pos);
12034 /* Redisplay the window. */
12035 if (!current_matrix_up_to_date_p
12036 || windows_or_buffers_changed
12037 || cursor_type_changed
12038 /* Don't use try_window_reusing_current_matrix in this case
12039 because it can have changed the buffer. */
12040 || !NILP (Vwindow_scroll_functions)
12041 || !just_this_one_p
12042 || MINI_WINDOW_P (w)
12043 || !(used_current_matrix_p
12044 = try_window_reusing_current_matrix (w)))
12045 try_window (window, startp);
12047 /* If new fonts have been loaded (due to fontsets), give up. We
12048 have to start a new redisplay since we need to re-adjust glyph
12049 matrices. */
12050 if (fonts_changed_p)
12051 goto need_larger_matrices;
12053 /* If cursor did not appear assume that the middle of the window is
12054 in the first line of the window. Do it again with the next line.
12055 (Imagine a window of height 100, displaying two lines of height
12056 60. Moving back 50 from it->last_visible_y will end in the first
12057 line.) */
12058 if (w->cursor.vpos < 0)
12060 if (!NILP (w->window_end_valid)
12061 && PT >= Z - XFASTINT (w->window_end_pos))
12063 clear_glyph_matrix (w->desired_matrix);
12064 move_it_by_lines (&it, 1, 0);
12065 try_window (window, it.current.pos);
12067 else if (PT < IT_CHARPOS (it))
12069 clear_glyph_matrix (w->desired_matrix);
12070 move_it_by_lines (&it, -1, 0);
12071 try_window (window, it.current.pos);
12073 else
12075 /* Not much we can do about it. */
12079 /* Consider the following case: Window starts at BEGV, there is
12080 invisible, intangible text at BEGV, so that display starts at
12081 some point START > BEGV. It can happen that we are called with
12082 PT somewhere between BEGV and START. Try to handle that case. */
12083 if (w->cursor.vpos < 0)
12085 struct glyph_row *row = w->current_matrix->rows;
12086 if (row->mode_line_p)
12087 ++row;
12088 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
12091 if (!make_cursor_line_fully_visible (w, centering_position > 0))
12093 /* If vscroll is enabled, disable it and try again. */
12094 if (w->vscroll)
12096 w->vscroll = 0;
12097 clear_glyph_matrix (w->desired_matrix);
12098 goto recenter;
12101 /* If centering point failed to make the whole line visible,
12102 put point at the top instead. That has to make the whole line
12103 visible, if it can be done. */
12104 clear_glyph_matrix (w->desired_matrix);
12105 centering_position = 0;
12106 goto point_at_top;
12109 done:
12111 SET_TEXT_POS_FROM_MARKER (startp, w->start);
12112 w->start_at_line_beg = ((CHARPOS (startp) == BEGV
12113 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n')
12114 ? Qt : Qnil);
12116 /* Display the mode line, if we must. */
12117 if ((update_mode_line
12118 /* If window not full width, must redo its mode line
12119 if (a) the window to its side is being redone and
12120 (b) we do a frame-based redisplay. This is a consequence
12121 of how inverted lines are drawn in frame-based redisplay. */
12122 || (!just_this_one_p
12123 && !FRAME_WINDOW_P (f)
12124 && !WINDOW_FULL_WIDTH_P (w))
12125 /* Line number to display. */
12126 || INTEGERP (w->base_line_pos)
12127 /* Column number is displayed and different from the one displayed. */
12128 || (!NILP (w->column_number_displayed)
12129 && (XFASTINT (w->column_number_displayed)
12130 != (int) current_column ()))) /* iftc */
12131 /* This means that the window has a mode line. */
12132 && (WINDOW_WANTS_MODELINE_P (w)
12133 || WINDOW_WANTS_HEADER_LINE_P (w)))
12135 display_mode_lines (w);
12137 /* If mode line height has changed, arrange for a thorough
12138 immediate redisplay using the correct mode line height. */
12139 if (WINDOW_WANTS_MODELINE_P (w)
12140 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
12142 fonts_changed_p = 1;
12143 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
12144 = DESIRED_MODE_LINE_HEIGHT (w);
12147 /* If top line height has changed, arrange for a thorough
12148 immediate redisplay using the correct mode line height. */
12149 if (WINDOW_WANTS_HEADER_LINE_P (w)
12150 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
12152 fonts_changed_p = 1;
12153 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
12154 = DESIRED_HEADER_LINE_HEIGHT (w);
12157 if (fonts_changed_p)
12158 goto need_larger_matrices;
12161 if (!line_number_displayed
12162 && !BUFFERP (w->base_line_pos))
12164 w->base_line_pos = Qnil;
12165 w->base_line_number = Qnil;
12168 finish_menu_bars:
12170 /* When we reach a frame's selected window, redo the frame's menu bar. */
12171 if (update_mode_line
12172 && EQ (FRAME_SELECTED_WINDOW (f), window))
12174 int redisplay_menu_p = 0;
12175 int redisplay_tool_bar_p = 0;
12177 if (FRAME_WINDOW_P (f))
12179 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
12180 || defined (USE_GTK)
12181 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
12182 #else
12183 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
12184 #endif
12186 else
12187 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
12189 if (redisplay_menu_p)
12190 display_menu_bar (w);
12192 #ifdef HAVE_WINDOW_SYSTEM
12193 #ifdef USE_GTK
12194 redisplay_tool_bar_p = FRAME_EXTERNAL_TOOL_BAR (f);
12195 #else
12196 redisplay_tool_bar_p = WINDOWP (f->tool_bar_window)
12197 && (FRAME_TOOL_BAR_LINES (f) > 0
12198 || auto_resize_tool_bars_p);
12200 #endif
12202 if (redisplay_tool_bar_p)
12203 redisplay_tool_bar (f);
12204 #endif
12207 #ifdef HAVE_WINDOW_SYSTEM
12208 if (update_window_fringes (w, 0)
12209 && !just_this_one_p
12210 && (used_current_matrix_p || overlay_arrow_seen)
12211 && !w->pseudo_window_p)
12213 update_begin (f);
12214 BLOCK_INPUT;
12215 draw_window_fringes (w);
12216 UNBLOCK_INPUT;
12217 update_end (f);
12219 #endif /* HAVE_WINDOW_SYSTEM */
12221 /* We go to this label, with fonts_changed_p nonzero,
12222 if it is necessary to try again using larger glyph matrices.
12223 We have to redeem the scroll bar even in this case,
12224 because the loop in redisplay_internal expects that. */
12225 need_larger_matrices:
12227 finish_scroll_bars:
12229 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
12231 /* Set the thumb's position and size. */
12232 set_vertical_scroll_bar (w);
12234 /* Note that we actually used the scroll bar attached to this
12235 window, so it shouldn't be deleted at the end of redisplay. */
12236 redeem_scroll_bar_hook (w);
12239 /* Restore current_buffer and value of point in it. */
12240 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
12241 set_buffer_internal_1 (old);
12242 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
12244 unbind_to (count, Qnil);
12248 /* Build the complete desired matrix of WINDOW with a window start
12249 buffer position POS. Value is non-zero if successful. It is zero
12250 if fonts were loaded during redisplay which makes re-adjusting
12251 glyph matrices necessary. */
12254 try_window (window, pos)
12255 Lisp_Object window;
12256 struct text_pos pos;
12258 struct window *w = XWINDOW (window);
12259 struct it it;
12260 struct glyph_row *last_text_row = NULL;
12262 /* Make POS the new window start. */
12263 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
12265 /* Mark cursor position as unknown. No overlay arrow seen. */
12266 w->cursor.vpos = -1;
12267 overlay_arrow_seen = 0;
12269 /* Initialize iterator and info to start at POS. */
12270 start_display (&it, w, pos);
12272 /* Display all lines of W. */
12273 while (it.current_y < it.last_visible_y)
12275 if (display_line (&it))
12276 last_text_row = it.glyph_row - 1;
12277 if (fonts_changed_p)
12278 return 0;
12281 /* If bottom moved off end of frame, change mode line percentage. */
12282 if (XFASTINT (w->window_end_pos) <= 0
12283 && Z != IT_CHARPOS (it))
12284 w->update_mode_line = Qt;
12286 /* Set window_end_pos to the offset of the last character displayed
12287 on the window from the end of current_buffer. Set
12288 window_end_vpos to its row number. */
12289 if (last_text_row)
12291 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
12292 w->window_end_bytepos
12293 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12294 w->window_end_pos
12295 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12296 w->window_end_vpos
12297 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12298 xassert (MATRIX_ROW (w->desired_matrix, XFASTINT (w->window_end_vpos))
12299 ->displays_text_p);
12301 else
12303 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
12304 w->window_end_pos = make_number (Z - ZV);
12305 w->window_end_vpos = make_number (0);
12308 /* But that is not valid info until redisplay finishes. */
12309 w->window_end_valid = Qnil;
12310 return 1;
12315 /************************************************************************
12316 Window redisplay reusing current matrix when buffer has not changed
12317 ************************************************************************/
12319 /* Try redisplay of window W showing an unchanged buffer with a
12320 different window start than the last time it was displayed by
12321 reusing its current matrix. Value is non-zero if successful.
12322 W->start is the new window start. */
12324 static int
12325 try_window_reusing_current_matrix (w)
12326 struct window *w;
12328 struct frame *f = XFRAME (w->frame);
12329 struct glyph_row *row, *bottom_row;
12330 struct it it;
12331 struct run run;
12332 struct text_pos start, new_start;
12333 int nrows_scrolled, i;
12334 struct glyph_row *last_text_row;
12335 struct glyph_row *last_reused_text_row;
12336 struct glyph_row *start_row;
12337 int start_vpos, min_y, max_y;
12339 #if GLYPH_DEBUG
12340 if (inhibit_try_window_reusing)
12341 return 0;
12342 #endif
12344 if (/* This function doesn't handle terminal frames. */
12345 !FRAME_WINDOW_P (f)
12346 /* Don't try to reuse the display if windows have been split
12347 or such. */
12348 || windows_or_buffers_changed
12349 || cursor_type_changed)
12350 return 0;
12352 /* Can't do this if region may have changed. */
12353 if ((!NILP (Vtransient_mark_mode)
12354 && !NILP (current_buffer->mark_active))
12355 || !NILP (w->region_showing)
12356 || !NILP (Vshow_trailing_whitespace))
12357 return 0;
12359 /* If top-line visibility has changed, give up. */
12360 if (WINDOW_WANTS_HEADER_LINE_P (w)
12361 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
12362 return 0;
12364 /* Give up if old or new display is scrolled vertically. We could
12365 make this function handle this, but right now it doesn't. */
12366 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12367 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (start_row))
12368 return 0;
12370 /* The variable new_start now holds the new window start. The old
12371 start `start' can be determined from the current matrix. */
12372 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
12373 start = start_row->start.pos;
12374 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
12376 /* Clear the desired matrix for the display below. */
12377 clear_glyph_matrix (w->desired_matrix);
12379 if (CHARPOS (new_start) <= CHARPOS (start))
12381 int first_row_y;
12383 /* Don't use this method if the display starts with an ellipsis
12384 displayed for invisible text. It's not easy to handle that case
12385 below, and it's certainly not worth the effort since this is
12386 not a frequent case. */
12387 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
12388 return 0;
12390 IF_DEBUG (debug_method_add (w, "twu1"));
12392 /* Display up to a row that can be reused. The variable
12393 last_text_row is set to the last row displayed that displays
12394 text. Note that it.vpos == 0 if or if not there is a
12395 header-line; it's not the same as the MATRIX_ROW_VPOS! */
12396 start_display (&it, w, new_start);
12397 first_row_y = it.current_y;
12398 w->cursor.vpos = -1;
12399 last_text_row = last_reused_text_row = NULL;
12401 while (it.current_y < it.last_visible_y
12402 && IT_CHARPOS (it) < CHARPOS (start)
12403 && !fonts_changed_p)
12404 if (display_line (&it))
12405 last_text_row = it.glyph_row - 1;
12407 /* A value of current_y < last_visible_y means that we stopped
12408 at the previous window start, which in turn means that we
12409 have at least one reusable row. */
12410 if (it.current_y < it.last_visible_y)
12412 /* IT.vpos always starts from 0; it counts text lines. */
12413 nrows_scrolled = it.vpos;
12415 /* Find PT if not already found in the lines displayed. */
12416 if (w->cursor.vpos < 0)
12418 int dy = it.current_y - first_row_y;
12420 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12421 row = row_containing_pos (w, PT, row, NULL, dy);
12422 if (row)
12423 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
12424 dy, nrows_scrolled);
12425 else
12427 clear_glyph_matrix (w->desired_matrix);
12428 return 0;
12432 /* Scroll the display. Do it before the current matrix is
12433 changed. The problem here is that update has not yet
12434 run, i.e. part of the current matrix is not up to date.
12435 scroll_run_hook will clear the cursor, and use the
12436 current matrix to get the height of the row the cursor is
12437 in. */
12438 run.current_y = first_row_y;
12439 run.desired_y = it.current_y;
12440 run.height = it.last_visible_y - it.current_y;
12442 if (run.height > 0 && run.current_y != run.desired_y)
12444 update_begin (f);
12445 rif->update_window_begin_hook (w);
12446 rif->clear_window_mouse_face (w);
12447 rif->scroll_run_hook (w, &run);
12448 rif->update_window_end_hook (w, 0, 0);
12449 update_end (f);
12452 /* Shift current matrix down by nrows_scrolled lines. */
12453 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
12454 rotate_matrix (w->current_matrix,
12455 start_vpos,
12456 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
12457 nrows_scrolled);
12459 /* Disable lines that must be updated. */
12460 for (i = 0; i < it.vpos; ++i)
12461 (start_row + i)->enabled_p = 0;
12463 /* Re-compute Y positions. */
12464 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
12465 max_y = it.last_visible_y;
12466 for (row = start_row + nrows_scrolled;
12467 row < bottom_row;
12468 ++row)
12470 row->y = it.current_y;
12471 row->visible_height = row->height;
12473 if (row->y < min_y)
12474 row->visible_height -= min_y - row->y;
12475 if (row->y + row->height > max_y)
12476 row->visible_height -= row->y + row->height - max_y;
12477 row->redraw_fringe_bitmaps_p = 1;
12479 it.current_y += row->height;
12481 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
12482 last_reused_text_row = row;
12483 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
12484 break;
12487 /* Disable lines in the current matrix which are now
12488 below the window. */
12489 for (++row; row < bottom_row; ++row)
12490 row->enabled_p = 0;
12493 /* Update window_end_pos etc.; last_reused_text_row is the last
12494 reused row from the current matrix containing text, if any.
12495 The value of last_text_row is the last displayed line
12496 containing text. */
12497 if (last_reused_text_row)
12499 w->window_end_bytepos
12500 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
12501 w->window_end_pos
12502 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_reused_text_row));
12503 w->window_end_vpos
12504 = make_number (MATRIX_ROW_VPOS (last_reused_text_row,
12505 w->current_matrix));
12507 else if (last_text_row)
12509 w->window_end_bytepos
12510 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12511 w->window_end_pos
12512 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12513 w->window_end_vpos
12514 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12516 else
12518 /* This window must be completely empty. */
12519 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
12520 w->window_end_pos = make_number (Z - ZV);
12521 w->window_end_vpos = make_number (0);
12523 w->window_end_valid = Qnil;
12525 /* Update hint: don't try scrolling again in update_window. */
12526 w->desired_matrix->no_scrolling_p = 1;
12528 #if GLYPH_DEBUG
12529 debug_method_add (w, "try_window_reusing_current_matrix 1");
12530 #endif
12531 return 1;
12533 else if (CHARPOS (new_start) > CHARPOS (start))
12535 struct glyph_row *pt_row, *row;
12536 struct glyph_row *first_reusable_row;
12537 struct glyph_row *first_row_to_display;
12538 int dy;
12539 int yb = window_text_bottom_y (w);
12541 /* Find the row starting at new_start, if there is one. Don't
12542 reuse a partially visible line at the end. */
12543 first_reusable_row = start_row;
12544 while (first_reusable_row->enabled_p
12545 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
12546 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
12547 < CHARPOS (new_start)))
12548 ++first_reusable_row;
12550 /* Give up if there is no row to reuse. */
12551 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
12552 || !first_reusable_row->enabled_p
12553 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
12554 != CHARPOS (new_start)))
12555 return 0;
12557 /* We can reuse fully visible rows beginning with
12558 first_reusable_row to the end of the window. Set
12559 first_row_to_display to the first row that cannot be reused.
12560 Set pt_row to the row containing point, if there is any. */
12561 pt_row = NULL;
12562 for (first_row_to_display = first_reusable_row;
12563 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
12564 ++first_row_to_display)
12566 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
12567 && PT < MATRIX_ROW_END_CHARPOS (first_row_to_display))
12568 pt_row = first_row_to_display;
12571 /* Start displaying at the start of first_row_to_display. */
12572 xassert (first_row_to_display->y < yb);
12573 init_to_row_start (&it, w, first_row_to_display);
12575 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
12576 - start_vpos);
12577 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
12578 - nrows_scrolled);
12579 it.current_y = (first_row_to_display->y - first_reusable_row->y
12580 + WINDOW_HEADER_LINE_HEIGHT (w));
12582 /* Display lines beginning with first_row_to_display in the
12583 desired matrix. Set last_text_row to the last row displayed
12584 that displays text. */
12585 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
12586 if (pt_row == NULL)
12587 w->cursor.vpos = -1;
12588 last_text_row = NULL;
12589 while (it.current_y < it.last_visible_y && !fonts_changed_p)
12590 if (display_line (&it))
12591 last_text_row = it.glyph_row - 1;
12593 /* Give up If point isn't in a row displayed or reused. */
12594 if (w->cursor.vpos < 0)
12596 clear_glyph_matrix (w->desired_matrix);
12597 return 0;
12600 /* If point is in a reused row, adjust y and vpos of the cursor
12601 position. */
12602 if (pt_row)
12604 w->cursor.vpos -= nrows_scrolled;
12605 w->cursor.y -= first_reusable_row->y - start_row->y;
12608 /* Scroll the display. */
12609 run.current_y = first_reusable_row->y;
12610 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
12611 run.height = it.last_visible_y - run.current_y;
12612 dy = run.current_y - run.desired_y;
12614 if (run.height)
12616 update_begin (f);
12617 rif->update_window_begin_hook (w);
12618 rif->clear_window_mouse_face (w);
12619 rif->scroll_run_hook (w, &run);
12620 rif->update_window_end_hook (w, 0, 0);
12621 update_end (f);
12624 /* Adjust Y positions of reused rows. */
12625 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
12626 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
12627 max_y = it.last_visible_y;
12628 for (row = first_reusable_row; row < first_row_to_display; ++row)
12630 row->y -= dy;
12631 row->visible_height = row->height;
12632 if (row->y < min_y)
12633 row->visible_height -= min_y - row->y;
12634 if (row->y + row->height > max_y)
12635 row->visible_height -= row->y + row->height - max_y;
12636 row->redraw_fringe_bitmaps_p = 1;
12639 /* Scroll the current matrix. */
12640 xassert (nrows_scrolled > 0);
12641 rotate_matrix (w->current_matrix,
12642 start_vpos,
12643 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
12644 -nrows_scrolled);
12646 /* Disable rows not reused. */
12647 for (row -= nrows_scrolled; row < bottom_row; ++row)
12648 row->enabled_p = 0;
12650 /* Point may have moved to a different line, so we cannot assume that
12651 the previous cursor position is valid; locate the correct row. */
12652 if (pt_row)
12654 for (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
12655 row < bottom_row && PT >= MATRIX_ROW_END_CHARPOS (row);
12656 row++)
12658 w->cursor.vpos++;
12659 w->cursor.y = row->y;
12661 if (row < bottom_row)
12663 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
12664 while (glyph->charpos < PT)
12666 w->cursor.hpos++;
12667 w->cursor.x += glyph->pixel_width;
12668 glyph++;
12673 /* Adjust window end. A null value of last_text_row means that
12674 the window end is in reused rows which in turn means that
12675 only its vpos can have changed. */
12676 if (last_text_row)
12678 w->window_end_bytepos
12679 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12680 w->window_end_pos
12681 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12682 w->window_end_vpos
12683 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12685 else
12687 w->window_end_vpos
12688 = make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled);
12691 w->window_end_valid = Qnil;
12692 w->desired_matrix->no_scrolling_p = 1;
12694 #if GLYPH_DEBUG
12695 debug_method_add (w, "try_window_reusing_current_matrix 2");
12696 #endif
12697 return 1;
12700 return 0;
12705 /************************************************************************
12706 Window redisplay reusing current matrix when buffer has changed
12707 ************************************************************************/
12709 static struct glyph_row *find_last_unchanged_at_beg_row P_ ((struct window *));
12710 static struct glyph_row *find_first_unchanged_at_end_row P_ ((struct window *,
12711 int *, int *));
12712 static struct glyph_row *
12713 find_last_row_displaying_text P_ ((struct glyph_matrix *, struct it *,
12714 struct glyph_row *));
12717 /* Return the last row in MATRIX displaying text. If row START is
12718 non-null, start searching with that row. IT gives the dimensions
12719 of the display. Value is null if matrix is empty; otherwise it is
12720 a pointer to the row found. */
12722 static struct glyph_row *
12723 find_last_row_displaying_text (matrix, it, start)
12724 struct glyph_matrix *matrix;
12725 struct it *it;
12726 struct glyph_row *start;
12728 struct glyph_row *row, *row_found;
12730 /* Set row_found to the last row in IT->w's current matrix
12731 displaying text. The loop looks funny but think of partially
12732 visible lines. */
12733 row_found = NULL;
12734 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
12735 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
12737 xassert (row->enabled_p);
12738 row_found = row;
12739 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
12740 break;
12741 ++row;
12744 return row_found;
12748 /* Return the last row in the current matrix of W that is not affected
12749 by changes at the start of current_buffer that occurred since W's
12750 current matrix was built. Value is null if no such row exists.
12752 BEG_UNCHANGED us the number of characters unchanged at the start of
12753 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
12754 first changed character in current_buffer. Characters at positions <
12755 BEG + BEG_UNCHANGED are at the same buffer positions as they were
12756 when the current matrix was built. */
12758 static struct glyph_row *
12759 find_last_unchanged_at_beg_row (w)
12760 struct window *w;
12762 int first_changed_pos = BEG + BEG_UNCHANGED;
12763 struct glyph_row *row;
12764 struct glyph_row *row_found = NULL;
12765 int yb = window_text_bottom_y (w);
12767 /* Find the last row displaying unchanged text. */
12768 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12769 while (MATRIX_ROW_DISPLAYS_TEXT_P (row)
12770 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos)
12772 if (/* If row ends before first_changed_pos, it is unchanged,
12773 except in some case. */
12774 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
12775 /* When row ends in ZV and we write at ZV it is not
12776 unchanged. */
12777 && !row->ends_at_zv_p
12778 /* When first_changed_pos is the end of a continued line,
12779 row is not unchanged because it may be no longer
12780 continued. */
12781 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
12782 && (row->continued_p
12783 || row->exact_window_width_line_p)))
12784 row_found = row;
12786 /* Stop if last visible row. */
12787 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
12788 break;
12790 ++row;
12793 return row_found;
12797 /* Find the first glyph row in the current matrix of W that is not
12798 affected by changes at the end of current_buffer since the
12799 time W's current matrix was built.
12801 Return in *DELTA the number of chars by which buffer positions in
12802 unchanged text at the end of current_buffer must be adjusted.
12804 Return in *DELTA_BYTES the corresponding number of bytes.
12806 Value is null if no such row exists, i.e. all rows are affected by
12807 changes. */
12809 static struct glyph_row *
12810 find_first_unchanged_at_end_row (w, delta, delta_bytes)
12811 struct window *w;
12812 int *delta, *delta_bytes;
12814 struct glyph_row *row;
12815 struct glyph_row *row_found = NULL;
12817 *delta = *delta_bytes = 0;
12819 /* Display must not have been paused, otherwise the current matrix
12820 is not up to date. */
12821 if (NILP (w->window_end_valid))
12822 abort ();
12824 /* A value of window_end_pos >= END_UNCHANGED means that the window
12825 end is in the range of changed text. If so, there is no
12826 unchanged row at the end of W's current matrix. */
12827 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
12828 return NULL;
12830 /* Set row to the last row in W's current matrix displaying text. */
12831 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
12833 /* If matrix is entirely empty, no unchanged row exists. */
12834 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
12836 /* The value of row is the last glyph row in the matrix having a
12837 meaningful buffer position in it. The end position of row
12838 corresponds to window_end_pos. This allows us to translate
12839 buffer positions in the current matrix to current buffer
12840 positions for characters not in changed text. */
12841 int Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
12842 int Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
12843 int last_unchanged_pos, last_unchanged_pos_old;
12844 struct glyph_row *first_text_row
12845 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12847 *delta = Z - Z_old;
12848 *delta_bytes = Z_BYTE - Z_BYTE_old;
12850 /* Set last_unchanged_pos to the buffer position of the last
12851 character in the buffer that has not been changed. Z is the
12852 index + 1 of the last character in current_buffer, i.e. by
12853 subtracting END_UNCHANGED we get the index of the last
12854 unchanged character, and we have to add BEG to get its buffer
12855 position. */
12856 last_unchanged_pos = Z - END_UNCHANGED + BEG;
12857 last_unchanged_pos_old = last_unchanged_pos - *delta;
12859 /* Search backward from ROW for a row displaying a line that
12860 starts at a minimum position >= last_unchanged_pos_old. */
12861 for (; row > first_text_row; --row)
12863 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
12864 abort ();
12866 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
12867 row_found = row;
12871 if (row_found && !MATRIX_ROW_DISPLAYS_TEXT_P (row_found))
12872 abort ();
12874 return row_found;
12878 /* Make sure that glyph rows in the current matrix of window W
12879 reference the same glyph memory as corresponding rows in the
12880 frame's frame matrix. This function is called after scrolling W's
12881 current matrix on a terminal frame in try_window_id and
12882 try_window_reusing_current_matrix. */
12884 static void
12885 sync_frame_with_window_matrix_rows (w)
12886 struct window *w;
12888 struct frame *f = XFRAME (w->frame);
12889 struct glyph_row *window_row, *window_row_end, *frame_row;
12891 /* Preconditions: W must be a leaf window and full-width. Its frame
12892 must have a frame matrix. */
12893 xassert (NILP (w->hchild) && NILP (w->vchild));
12894 xassert (WINDOW_FULL_WIDTH_P (w));
12895 xassert (!FRAME_WINDOW_P (f));
12897 /* If W is a full-width window, glyph pointers in W's current matrix
12898 have, by definition, to be the same as glyph pointers in the
12899 corresponding frame matrix. Note that frame matrices have no
12900 marginal areas (see build_frame_matrix). */
12901 window_row = w->current_matrix->rows;
12902 window_row_end = window_row + w->current_matrix->nrows;
12903 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
12904 while (window_row < window_row_end)
12906 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
12907 struct glyph *end = window_row->glyphs[LAST_AREA];
12909 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
12910 frame_row->glyphs[TEXT_AREA] = start;
12911 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
12912 frame_row->glyphs[LAST_AREA] = end;
12914 /* Disable frame rows whose corresponding window rows have
12915 been disabled in try_window_id. */
12916 if (!window_row->enabled_p)
12917 frame_row->enabled_p = 0;
12919 ++window_row, ++frame_row;
12924 /* Find the glyph row in window W containing CHARPOS. Consider all
12925 rows between START and END (not inclusive). END null means search
12926 all rows to the end of the display area of W. Value is the row
12927 containing CHARPOS or null. */
12929 struct glyph_row *
12930 row_containing_pos (w, charpos, start, end, dy)
12931 struct window *w;
12932 int charpos;
12933 struct glyph_row *start, *end;
12934 int dy;
12936 struct glyph_row *row = start;
12937 int last_y;
12939 /* If we happen to start on a header-line, skip that. */
12940 if (row->mode_line_p)
12941 ++row;
12943 if ((end && row >= end) || !row->enabled_p)
12944 return NULL;
12946 last_y = window_text_bottom_y (w) - dy;
12948 while (1)
12950 /* Give up if we have gone too far. */
12951 if (end && row >= end)
12952 return NULL;
12953 /* This formerly returned if they were equal.
12954 I think that both quantities are of a "last plus one" type;
12955 if so, when they are equal, the row is within the screen. -- rms. */
12956 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
12957 return NULL;
12959 /* If it is in this row, return this row. */
12960 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
12961 || (MATRIX_ROW_END_CHARPOS (row) == charpos
12962 /* The end position of a row equals the start
12963 position of the next row. If CHARPOS is there, we
12964 would rather display it in the next line, except
12965 when this line ends in ZV. */
12966 && !row->ends_at_zv_p
12967 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
12968 && charpos >= MATRIX_ROW_START_CHARPOS (row))
12969 return row;
12970 ++row;
12975 /* Try to redisplay window W by reusing its existing display. W's
12976 current matrix must be up to date when this function is called,
12977 i.e. window_end_valid must not be nil.
12979 Value is
12981 1 if display has been updated
12982 0 if otherwise unsuccessful
12983 -1 if redisplay with same window start is known not to succeed
12985 The following steps are performed:
12987 1. Find the last row in the current matrix of W that is not
12988 affected by changes at the start of current_buffer. If no such row
12989 is found, give up.
12991 2. Find the first row in W's current matrix that is not affected by
12992 changes at the end of current_buffer. Maybe there is no such row.
12994 3. Display lines beginning with the row + 1 found in step 1 to the
12995 row found in step 2 or, if step 2 didn't find a row, to the end of
12996 the window.
12998 4. If cursor is not known to appear on the window, give up.
13000 5. If display stopped at the row found in step 2, scroll the
13001 display and current matrix as needed.
13003 6. Maybe display some lines at the end of W, if we must. This can
13004 happen under various circumstances, like a partially visible line
13005 becoming fully visible, or because newly displayed lines are displayed
13006 in smaller font sizes.
13008 7. Update W's window end information. */
13010 static int
13011 try_window_id (w)
13012 struct window *w;
13014 struct frame *f = XFRAME (w->frame);
13015 struct glyph_matrix *current_matrix = w->current_matrix;
13016 struct glyph_matrix *desired_matrix = w->desired_matrix;
13017 struct glyph_row *last_unchanged_at_beg_row;
13018 struct glyph_row *first_unchanged_at_end_row;
13019 struct glyph_row *row;
13020 struct glyph_row *bottom_row;
13021 int bottom_vpos;
13022 struct it it;
13023 int delta = 0, delta_bytes = 0, stop_pos, dvpos, dy;
13024 struct text_pos start_pos;
13025 struct run run;
13026 int first_unchanged_at_end_vpos = 0;
13027 struct glyph_row *last_text_row, *last_text_row_at_end;
13028 struct text_pos start;
13029 int first_changed_charpos, last_changed_charpos;
13031 #if GLYPH_DEBUG
13032 if (inhibit_try_window_id)
13033 return 0;
13034 #endif
13036 /* This is handy for debugging. */
13037 #if 0
13038 #define GIVE_UP(X) \
13039 do { \
13040 fprintf (stderr, "try_window_id give up %d\n", (X)); \
13041 return 0; \
13042 } while (0)
13043 #else
13044 #define GIVE_UP(X) return 0
13045 #endif
13047 SET_TEXT_POS_FROM_MARKER (start, w->start);
13049 /* Don't use this for mini-windows because these can show
13050 messages and mini-buffers, and we don't handle that here. */
13051 if (MINI_WINDOW_P (w))
13052 GIVE_UP (1);
13054 /* This flag is used to prevent redisplay optimizations. */
13055 if (windows_or_buffers_changed || cursor_type_changed)
13056 GIVE_UP (2);
13058 /* Verify that narrowing has not changed.
13059 Also verify that we were not told to prevent redisplay optimizations.
13060 It would be nice to further
13061 reduce the number of cases where this prevents try_window_id. */
13062 if (current_buffer->clip_changed
13063 || current_buffer->prevent_redisplay_optimizations_p)
13064 GIVE_UP (3);
13066 /* Window must either use window-based redisplay or be full width. */
13067 if (!FRAME_WINDOW_P (f)
13068 && (!line_ins_del_ok
13069 || !WINDOW_FULL_WIDTH_P (w)))
13070 GIVE_UP (4);
13072 /* Give up if point is not known NOT to appear in W. */
13073 if (PT < CHARPOS (start))
13074 GIVE_UP (5);
13076 /* Another way to prevent redisplay optimizations. */
13077 if (XFASTINT (w->last_modified) == 0)
13078 GIVE_UP (6);
13080 /* Verify that window is not hscrolled. */
13081 if (XFASTINT (w->hscroll) != 0)
13082 GIVE_UP (7);
13084 /* Verify that display wasn't paused. */
13085 if (NILP (w->window_end_valid))
13086 GIVE_UP (8);
13088 /* Can't use this if highlighting a region because a cursor movement
13089 will do more than just set the cursor. */
13090 if (!NILP (Vtransient_mark_mode)
13091 && !NILP (current_buffer->mark_active))
13092 GIVE_UP (9);
13094 /* Likewise if highlighting trailing whitespace. */
13095 if (!NILP (Vshow_trailing_whitespace))
13096 GIVE_UP (11);
13098 /* Likewise if showing a region. */
13099 if (!NILP (w->region_showing))
13100 GIVE_UP (10);
13102 /* Can use this if overlay arrow position and or string have changed. */
13103 if (overlay_arrows_changed_p ())
13104 GIVE_UP (12);
13107 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
13108 only if buffer has really changed. The reason is that the gap is
13109 initially at Z for freshly visited files. The code below would
13110 set end_unchanged to 0 in that case. */
13111 if (MODIFF > SAVE_MODIFF
13112 /* This seems to happen sometimes after saving a buffer. */
13113 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
13115 if (GPT - BEG < BEG_UNCHANGED)
13116 BEG_UNCHANGED = GPT - BEG;
13117 if (Z - GPT < END_UNCHANGED)
13118 END_UNCHANGED = Z - GPT;
13121 /* The position of the first and last character that has been changed. */
13122 first_changed_charpos = BEG + BEG_UNCHANGED;
13123 last_changed_charpos = Z - END_UNCHANGED;
13125 /* If window starts after a line end, and the last change is in
13126 front of that newline, then changes don't affect the display.
13127 This case happens with stealth-fontification. Note that although
13128 the display is unchanged, glyph positions in the matrix have to
13129 be adjusted, of course. */
13130 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
13131 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
13132 && ((last_changed_charpos < CHARPOS (start)
13133 && CHARPOS (start) == BEGV)
13134 || (last_changed_charpos < CHARPOS (start) - 1
13135 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
13137 int Z_old, delta, Z_BYTE_old, delta_bytes;
13138 struct glyph_row *r0;
13140 /* Compute how many chars/bytes have been added to or removed
13141 from the buffer. */
13142 Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
13143 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
13144 delta = Z - Z_old;
13145 delta_bytes = Z_BYTE - Z_BYTE_old;
13147 /* Give up if PT is not in the window. Note that it already has
13148 been checked at the start of try_window_id that PT is not in
13149 front of the window start. */
13150 if (PT >= MATRIX_ROW_END_CHARPOS (row) + delta)
13151 GIVE_UP (13);
13153 /* If window start is unchanged, we can reuse the whole matrix
13154 as is, after adjusting glyph positions. No need to compute
13155 the window end again, since its offset from Z hasn't changed. */
13156 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
13157 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + delta
13158 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + delta_bytes
13159 /* PT must not be in a partially visible line. */
13160 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + delta
13161 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
13163 /* Adjust positions in the glyph matrix. */
13164 if (delta || delta_bytes)
13166 struct glyph_row *r1
13167 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
13168 increment_matrix_positions (w->current_matrix,
13169 MATRIX_ROW_VPOS (r0, current_matrix),
13170 MATRIX_ROW_VPOS (r1, current_matrix),
13171 delta, delta_bytes);
13174 /* Set the cursor. */
13175 row = row_containing_pos (w, PT, r0, NULL, 0);
13176 if (row)
13177 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
13178 else
13179 abort ();
13180 return 1;
13184 /* Handle the case that changes are all below what is displayed in
13185 the window, and that PT is in the window. This shortcut cannot
13186 be taken if ZV is visible in the window, and text has been added
13187 there that is visible in the window. */
13188 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
13189 /* ZV is not visible in the window, or there are no
13190 changes at ZV, actually. */
13191 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
13192 || first_changed_charpos == last_changed_charpos))
13194 struct glyph_row *r0;
13196 /* Give up if PT is not in the window. Note that it already has
13197 been checked at the start of try_window_id that PT is not in
13198 front of the window start. */
13199 if (PT >= MATRIX_ROW_END_CHARPOS (row))
13200 GIVE_UP (14);
13202 /* If window start is unchanged, we can reuse the whole matrix
13203 as is, without changing glyph positions since no text has
13204 been added/removed in front of the window end. */
13205 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
13206 if (TEXT_POS_EQUAL_P (start, r0->start.pos)
13207 /* PT must not be in a partially visible line. */
13208 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
13209 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
13211 /* We have to compute the window end anew since text
13212 can have been added/removed after it. */
13213 w->window_end_pos
13214 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13215 w->window_end_bytepos
13216 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13218 /* Set the cursor. */
13219 row = row_containing_pos (w, PT, r0, NULL, 0);
13220 if (row)
13221 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
13222 else
13223 abort ();
13224 return 2;
13228 /* Give up if window start is in the changed area.
13230 The condition used to read
13232 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
13234 but why that was tested escapes me at the moment. */
13235 if (CHARPOS (start) >= first_changed_charpos
13236 && CHARPOS (start) <= last_changed_charpos)
13237 GIVE_UP (15);
13239 /* Check that window start agrees with the start of the first glyph
13240 row in its current matrix. Check this after we know the window
13241 start is not in changed text, otherwise positions would not be
13242 comparable. */
13243 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
13244 if (!TEXT_POS_EQUAL_P (start, row->start.pos))
13245 GIVE_UP (16);
13247 /* Give up if the window ends in strings. Overlay strings
13248 at the end are difficult to handle, so don't try. */
13249 row = MATRIX_ROW (current_matrix, XFASTINT (w->window_end_vpos));
13250 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
13251 GIVE_UP (20);
13253 /* Compute the position at which we have to start displaying new
13254 lines. Some of the lines at the top of the window might be
13255 reusable because they are not displaying changed text. Find the
13256 last row in W's current matrix not affected by changes at the
13257 start of current_buffer. Value is null if changes start in the
13258 first line of window. */
13259 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
13260 if (last_unchanged_at_beg_row)
13262 /* Avoid starting to display in the moddle of a character, a TAB
13263 for instance. This is easier than to set up the iterator
13264 exactly, and it's not a frequent case, so the additional
13265 effort wouldn't really pay off. */
13266 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
13267 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
13268 && last_unchanged_at_beg_row > w->current_matrix->rows)
13269 --last_unchanged_at_beg_row;
13271 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
13272 GIVE_UP (17);
13274 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
13275 GIVE_UP (18);
13276 start_pos = it.current.pos;
13278 /* Start displaying new lines in the desired matrix at the same
13279 vpos we would use in the current matrix, i.e. below
13280 last_unchanged_at_beg_row. */
13281 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
13282 current_matrix);
13283 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
13284 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
13286 xassert (it.hpos == 0 && it.current_x == 0);
13288 else
13290 /* There are no reusable lines at the start of the window.
13291 Start displaying in the first text line. */
13292 start_display (&it, w, start);
13293 it.vpos = it.first_vpos;
13294 start_pos = it.current.pos;
13297 /* Find the first row that is not affected by changes at the end of
13298 the buffer. Value will be null if there is no unchanged row, in
13299 which case we must redisplay to the end of the window. delta
13300 will be set to the value by which buffer positions beginning with
13301 first_unchanged_at_end_row have to be adjusted due to text
13302 changes. */
13303 first_unchanged_at_end_row
13304 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
13305 IF_DEBUG (debug_delta = delta);
13306 IF_DEBUG (debug_delta_bytes = delta_bytes);
13308 /* Set stop_pos to the buffer position up to which we will have to
13309 display new lines. If first_unchanged_at_end_row != NULL, this
13310 is the buffer position of the start of the line displayed in that
13311 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
13312 that we don't stop at a buffer position. */
13313 stop_pos = 0;
13314 if (first_unchanged_at_end_row)
13316 xassert (last_unchanged_at_beg_row == NULL
13317 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
13319 /* If this is a continuation line, move forward to the next one
13320 that isn't. Changes in lines above affect this line.
13321 Caution: this may move first_unchanged_at_end_row to a row
13322 not displaying text. */
13323 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
13324 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
13325 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
13326 < it.last_visible_y))
13327 ++first_unchanged_at_end_row;
13329 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
13330 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
13331 >= it.last_visible_y))
13332 first_unchanged_at_end_row = NULL;
13333 else
13335 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
13336 + delta);
13337 first_unchanged_at_end_vpos
13338 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
13339 xassert (stop_pos >= Z - END_UNCHANGED);
13342 else if (last_unchanged_at_beg_row == NULL)
13343 GIVE_UP (19);
13346 #if GLYPH_DEBUG
13348 /* Either there is no unchanged row at the end, or the one we have
13349 now displays text. This is a necessary condition for the window
13350 end pos calculation at the end of this function. */
13351 xassert (first_unchanged_at_end_row == NULL
13352 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
13354 debug_last_unchanged_at_beg_vpos
13355 = (last_unchanged_at_beg_row
13356 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
13357 : -1);
13358 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
13360 #endif /* GLYPH_DEBUG != 0 */
13363 /* Display new lines. Set last_text_row to the last new line
13364 displayed which has text on it, i.e. might end up as being the
13365 line where the window_end_vpos is. */
13366 w->cursor.vpos = -1;
13367 last_text_row = NULL;
13368 overlay_arrow_seen = 0;
13369 while (it.current_y < it.last_visible_y
13370 && !fonts_changed_p
13371 && (first_unchanged_at_end_row == NULL
13372 || IT_CHARPOS (it) < stop_pos))
13374 if (display_line (&it))
13375 last_text_row = it.glyph_row - 1;
13378 if (fonts_changed_p)
13379 return -1;
13382 /* Compute differences in buffer positions, y-positions etc. for
13383 lines reused at the bottom of the window. Compute what we can
13384 scroll. */
13385 if (first_unchanged_at_end_row
13386 /* No lines reused because we displayed everything up to the
13387 bottom of the window. */
13388 && it.current_y < it.last_visible_y)
13390 dvpos = (it.vpos
13391 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
13392 current_matrix));
13393 dy = it.current_y - first_unchanged_at_end_row->y;
13394 run.current_y = first_unchanged_at_end_row->y;
13395 run.desired_y = run.current_y + dy;
13396 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
13398 else
13400 delta = dvpos = dy = run.current_y = run.desired_y = run.height = 0;
13401 first_unchanged_at_end_row = NULL;
13403 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
13406 /* Find the cursor if not already found. We have to decide whether
13407 PT will appear on this window (it sometimes doesn't, but this is
13408 not a very frequent case.) This decision has to be made before
13409 the current matrix is altered. A value of cursor.vpos < 0 means
13410 that PT is either in one of the lines beginning at
13411 first_unchanged_at_end_row or below the window. Don't care for
13412 lines that might be displayed later at the window end; as
13413 mentioned, this is not a frequent case. */
13414 if (w->cursor.vpos < 0)
13416 /* Cursor in unchanged rows at the top? */
13417 if (PT < CHARPOS (start_pos)
13418 && last_unchanged_at_beg_row)
13420 row = row_containing_pos (w, PT,
13421 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
13422 last_unchanged_at_beg_row + 1, 0);
13423 if (row)
13424 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
13427 /* Start from first_unchanged_at_end_row looking for PT. */
13428 else if (first_unchanged_at_end_row)
13430 row = row_containing_pos (w, PT - delta,
13431 first_unchanged_at_end_row, NULL, 0);
13432 if (row)
13433 set_cursor_from_row (w, row, w->current_matrix, delta,
13434 delta_bytes, dy, dvpos);
13437 /* Give up if cursor was not found. */
13438 if (w->cursor.vpos < 0)
13440 clear_glyph_matrix (w->desired_matrix);
13441 return -1;
13445 /* Don't let the cursor end in the scroll margins. */
13447 int this_scroll_margin, cursor_height;
13449 this_scroll_margin = max (0, scroll_margin);
13450 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
13451 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
13452 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
13454 if ((w->cursor.y < this_scroll_margin
13455 && CHARPOS (start) > BEGV)
13456 /* Old redisplay didn't take scroll margin into account at the bottom,
13457 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
13458 || w->cursor.y + cursor_height + this_scroll_margin > it.last_visible_y)
13460 w->cursor.vpos = -1;
13461 clear_glyph_matrix (w->desired_matrix);
13462 return -1;
13466 /* Scroll the display. Do it before changing the current matrix so
13467 that xterm.c doesn't get confused about where the cursor glyph is
13468 found. */
13469 if (dy && run.height)
13471 update_begin (f);
13473 if (FRAME_WINDOW_P (f))
13475 rif->update_window_begin_hook (w);
13476 rif->clear_window_mouse_face (w);
13477 rif->scroll_run_hook (w, &run);
13478 rif->update_window_end_hook (w, 0, 0);
13480 else
13482 /* Terminal frame. In this case, dvpos gives the number of
13483 lines to scroll by; dvpos < 0 means scroll up. */
13484 int first_unchanged_at_end_vpos
13485 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
13486 int from = WINDOW_TOP_EDGE_LINE (w) + first_unchanged_at_end_vpos;
13487 int end = (WINDOW_TOP_EDGE_LINE (w)
13488 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
13489 + window_internal_height (w));
13491 /* Perform the operation on the screen. */
13492 if (dvpos > 0)
13494 /* Scroll last_unchanged_at_beg_row to the end of the
13495 window down dvpos lines. */
13496 set_terminal_window (end);
13498 /* On dumb terminals delete dvpos lines at the end
13499 before inserting dvpos empty lines. */
13500 if (!scroll_region_ok)
13501 ins_del_lines (end - dvpos, -dvpos);
13503 /* Insert dvpos empty lines in front of
13504 last_unchanged_at_beg_row. */
13505 ins_del_lines (from, dvpos);
13507 else if (dvpos < 0)
13509 /* Scroll up last_unchanged_at_beg_vpos to the end of
13510 the window to last_unchanged_at_beg_vpos - |dvpos|. */
13511 set_terminal_window (end);
13513 /* Delete dvpos lines in front of
13514 last_unchanged_at_beg_vpos. ins_del_lines will set
13515 the cursor to the given vpos and emit |dvpos| delete
13516 line sequences. */
13517 ins_del_lines (from + dvpos, dvpos);
13519 /* On a dumb terminal insert dvpos empty lines at the
13520 end. */
13521 if (!scroll_region_ok)
13522 ins_del_lines (end + dvpos, -dvpos);
13525 set_terminal_window (0);
13528 update_end (f);
13531 /* Shift reused rows of the current matrix to the right position.
13532 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
13533 text. */
13534 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
13535 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
13536 if (dvpos < 0)
13538 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
13539 bottom_vpos, dvpos);
13540 enable_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
13541 bottom_vpos, 0);
13543 else if (dvpos > 0)
13545 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
13546 bottom_vpos, dvpos);
13547 enable_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
13548 first_unchanged_at_end_vpos + dvpos, 0);
13551 /* For frame-based redisplay, make sure that current frame and window
13552 matrix are in sync with respect to glyph memory. */
13553 if (!FRAME_WINDOW_P (f))
13554 sync_frame_with_window_matrix_rows (w);
13556 /* Adjust buffer positions in reused rows. */
13557 if (delta)
13558 increment_matrix_positions (current_matrix,
13559 first_unchanged_at_end_vpos + dvpos,
13560 bottom_vpos, delta, delta_bytes);
13562 /* Adjust Y positions. */
13563 if (dy)
13564 shift_glyph_matrix (w, current_matrix,
13565 first_unchanged_at_end_vpos + dvpos,
13566 bottom_vpos, dy);
13568 if (first_unchanged_at_end_row)
13569 first_unchanged_at_end_row += dvpos;
13571 /* If scrolling up, there may be some lines to display at the end of
13572 the window. */
13573 last_text_row_at_end = NULL;
13574 if (dy < 0)
13576 /* Scrolling up can leave for example a partially visible line
13577 at the end of the window to be redisplayed. */
13578 /* Set last_row to the glyph row in the current matrix where the
13579 window end line is found. It has been moved up or down in
13580 the matrix by dvpos. */
13581 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
13582 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
13584 /* If last_row is the window end line, it should display text. */
13585 xassert (last_row->displays_text_p);
13587 /* If window end line was partially visible before, begin
13588 displaying at that line. Otherwise begin displaying with the
13589 line following it. */
13590 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
13592 init_to_row_start (&it, w, last_row);
13593 it.vpos = last_vpos;
13594 it.current_y = last_row->y;
13596 else
13598 init_to_row_end (&it, w, last_row);
13599 it.vpos = 1 + last_vpos;
13600 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
13601 ++last_row;
13604 /* We may start in a continuation line. If so, we have to
13605 get the right continuation_lines_width and current_x. */
13606 it.continuation_lines_width = last_row->continuation_lines_width;
13607 it.hpos = it.current_x = 0;
13609 /* Display the rest of the lines at the window end. */
13610 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
13611 while (it.current_y < it.last_visible_y
13612 && !fonts_changed_p)
13614 /* Is it always sure that the display agrees with lines in
13615 the current matrix? I don't think so, so we mark rows
13616 displayed invalid in the current matrix by setting their
13617 enabled_p flag to zero. */
13618 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
13619 if (display_line (&it))
13620 last_text_row_at_end = it.glyph_row - 1;
13624 /* Update window_end_pos and window_end_vpos. */
13625 if (first_unchanged_at_end_row
13626 && first_unchanged_at_end_row->y < it.last_visible_y
13627 && !last_text_row_at_end)
13629 /* Window end line if one of the preserved rows from the current
13630 matrix. Set row to the last row displaying text in current
13631 matrix starting at first_unchanged_at_end_row, after
13632 scrolling. */
13633 xassert (first_unchanged_at_end_row->displays_text_p);
13634 row = find_last_row_displaying_text (w->current_matrix, &it,
13635 first_unchanged_at_end_row);
13636 xassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
13638 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13639 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13640 w->window_end_vpos
13641 = make_number (MATRIX_ROW_VPOS (row, w->current_matrix));
13642 xassert (w->window_end_bytepos >= 0);
13643 IF_DEBUG (debug_method_add (w, "A"));
13645 else if (last_text_row_at_end)
13647 w->window_end_pos
13648 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end));
13649 w->window_end_bytepos
13650 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
13651 w->window_end_vpos
13652 = make_number (MATRIX_ROW_VPOS (last_text_row_at_end, desired_matrix));
13653 xassert (w->window_end_bytepos >= 0);
13654 IF_DEBUG (debug_method_add (w, "B"));
13656 else if (last_text_row)
13658 /* We have displayed either to the end of the window or at the
13659 end of the window, i.e. the last row with text is to be found
13660 in the desired matrix. */
13661 w->window_end_pos
13662 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
13663 w->window_end_bytepos
13664 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
13665 w->window_end_vpos
13666 = make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix));
13667 xassert (w->window_end_bytepos >= 0);
13669 else if (first_unchanged_at_end_row == NULL
13670 && last_text_row == NULL
13671 && last_text_row_at_end == NULL)
13673 /* Displayed to end of window, but no line containing text was
13674 displayed. Lines were deleted at the end of the window. */
13675 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
13676 int vpos = XFASTINT (w->window_end_vpos);
13677 struct glyph_row *current_row = current_matrix->rows + vpos;
13678 struct glyph_row *desired_row = desired_matrix->rows + vpos;
13680 for (row = NULL;
13681 row == NULL && vpos >= first_vpos;
13682 --vpos, --current_row, --desired_row)
13684 if (desired_row->enabled_p)
13686 if (desired_row->displays_text_p)
13687 row = desired_row;
13689 else if (current_row->displays_text_p)
13690 row = current_row;
13693 xassert (row != NULL);
13694 w->window_end_vpos = make_number (vpos + 1);
13695 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13696 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13697 xassert (w->window_end_bytepos >= 0);
13698 IF_DEBUG (debug_method_add (w, "C"));
13700 else
13701 abort ();
13703 #if 0 /* This leads to problems, for instance when the cursor is
13704 at ZV, and the cursor line displays no text. */
13705 /* Disable rows below what's displayed in the window. This makes
13706 debugging easier. */
13707 enable_glyph_matrix_rows (current_matrix,
13708 XFASTINT (w->window_end_vpos) + 1,
13709 bottom_vpos, 0);
13710 #endif
13712 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
13713 debug_end_vpos = XFASTINT (w->window_end_vpos));
13715 /* Record that display has not been completed. */
13716 w->window_end_valid = Qnil;
13717 w->desired_matrix->no_scrolling_p = 1;
13718 return 3;
13720 #undef GIVE_UP
13725 /***********************************************************************
13726 More debugging support
13727 ***********************************************************************/
13729 #if GLYPH_DEBUG
13731 void dump_glyph_row P_ ((struct glyph_row *, int, int));
13732 void dump_glyph_matrix P_ ((struct glyph_matrix *, int));
13733 void dump_glyph P_ ((struct glyph_row *, struct glyph *, int));
13736 /* Dump the contents of glyph matrix MATRIX on stderr.
13738 GLYPHS 0 means don't show glyph contents.
13739 GLYPHS 1 means show glyphs in short form
13740 GLYPHS > 1 means show glyphs in long form. */
13742 void
13743 dump_glyph_matrix (matrix, glyphs)
13744 struct glyph_matrix *matrix;
13745 int glyphs;
13747 int i;
13748 for (i = 0; i < matrix->nrows; ++i)
13749 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
13753 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
13754 the glyph row and area where the glyph comes from. */
13756 void
13757 dump_glyph (row, glyph, area)
13758 struct glyph_row *row;
13759 struct glyph *glyph;
13760 int area;
13762 if (glyph->type == CHAR_GLYPH)
13764 fprintf (stderr,
13765 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13766 glyph - row->glyphs[TEXT_AREA],
13767 'C',
13768 glyph->charpos,
13769 (BUFFERP (glyph->object)
13770 ? 'B'
13771 : (STRINGP (glyph->object)
13772 ? 'S'
13773 : '-')),
13774 glyph->pixel_width,
13775 glyph->u.ch,
13776 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
13777 ? glyph->u.ch
13778 : '.'),
13779 glyph->face_id,
13780 glyph->left_box_line_p,
13781 glyph->right_box_line_p);
13783 else if (glyph->type == STRETCH_GLYPH)
13785 fprintf (stderr,
13786 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13787 glyph - row->glyphs[TEXT_AREA],
13788 'S',
13789 glyph->charpos,
13790 (BUFFERP (glyph->object)
13791 ? 'B'
13792 : (STRINGP (glyph->object)
13793 ? 'S'
13794 : '-')),
13795 glyph->pixel_width,
13797 '.',
13798 glyph->face_id,
13799 glyph->left_box_line_p,
13800 glyph->right_box_line_p);
13802 else if (glyph->type == IMAGE_GLYPH)
13804 fprintf (stderr,
13805 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13806 glyph - row->glyphs[TEXT_AREA],
13807 'I',
13808 glyph->charpos,
13809 (BUFFERP (glyph->object)
13810 ? 'B'
13811 : (STRINGP (glyph->object)
13812 ? 'S'
13813 : '-')),
13814 glyph->pixel_width,
13815 glyph->u.img_id,
13816 '.',
13817 glyph->face_id,
13818 glyph->left_box_line_p,
13819 glyph->right_box_line_p);
13824 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
13825 GLYPHS 0 means don't show glyph contents.
13826 GLYPHS 1 means show glyphs in short form
13827 GLYPHS > 1 means show glyphs in long form. */
13829 void
13830 dump_glyph_row (row, vpos, glyphs)
13831 struct glyph_row *row;
13832 int vpos, glyphs;
13834 if (glyphs != 1)
13836 fprintf (stderr, "Row Start End Used oEI><O\\CTZFesm X Y W H V A P\n");
13837 fprintf (stderr, "=======================================================================\n");
13839 fprintf (stderr, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d%1.1d\
13840 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
13841 vpos,
13842 MATRIX_ROW_START_CHARPOS (row),
13843 MATRIX_ROW_END_CHARPOS (row),
13844 row->used[TEXT_AREA],
13845 row->contains_overlapping_glyphs_p,
13846 row->enabled_p,
13847 row->truncated_on_left_p,
13848 row->truncated_on_right_p,
13849 row->overlay_arrow_p,
13850 row->continued_p,
13851 MATRIX_ROW_CONTINUATION_LINE_P (row),
13852 row->displays_text_p,
13853 row->ends_at_zv_p,
13854 row->fill_line_p,
13855 row->ends_in_middle_of_char_p,
13856 row->starts_in_middle_of_char_p,
13857 row->mouse_face_p,
13858 row->x,
13859 row->y,
13860 row->pixel_width,
13861 row->height,
13862 row->visible_height,
13863 row->ascent,
13864 row->phys_ascent);
13865 fprintf (stderr, "%9d %5d\t%5d\n", row->start.overlay_string_index,
13866 row->end.overlay_string_index,
13867 row->continuation_lines_width);
13868 fprintf (stderr, "%9d %5d\n",
13869 CHARPOS (row->start.string_pos),
13870 CHARPOS (row->end.string_pos));
13871 fprintf (stderr, "%9d %5d\n", row->start.dpvec_index,
13872 row->end.dpvec_index);
13875 if (glyphs > 1)
13877 int area;
13879 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
13881 struct glyph *glyph = row->glyphs[area];
13882 struct glyph *glyph_end = glyph + row->used[area];
13884 /* Glyph for a line end in text. */
13885 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
13886 ++glyph_end;
13888 if (glyph < glyph_end)
13889 fprintf (stderr, " Glyph Type Pos O W Code C Face LR\n");
13891 for (; glyph < glyph_end; ++glyph)
13892 dump_glyph (row, glyph, area);
13895 else if (glyphs == 1)
13897 int area;
13899 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
13901 char *s = (char *) alloca (row->used[area] + 1);
13902 int i;
13904 for (i = 0; i < row->used[area]; ++i)
13906 struct glyph *glyph = row->glyphs[area] + i;
13907 if (glyph->type == CHAR_GLYPH
13908 && glyph->u.ch < 0x80
13909 && glyph->u.ch >= ' ')
13910 s[i] = glyph->u.ch;
13911 else
13912 s[i] = '.';
13915 s[i] = '\0';
13916 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
13922 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
13923 Sdump_glyph_matrix, 0, 1, "p",
13924 doc: /* Dump the current matrix of the selected window to stderr.
13925 Shows contents of glyph row structures. With non-nil
13926 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
13927 glyphs in short form, otherwise show glyphs in long form. */)
13928 (glyphs)
13929 Lisp_Object glyphs;
13931 struct window *w = XWINDOW (selected_window);
13932 struct buffer *buffer = XBUFFER (w->buffer);
13934 fprintf (stderr, "PT = %d, BEGV = %d. ZV = %d\n",
13935 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
13936 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
13937 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
13938 fprintf (stderr, "=============================================\n");
13939 dump_glyph_matrix (w->current_matrix,
13940 NILP (glyphs) ? 0 : XINT (glyphs));
13941 return Qnil;
13945 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
13946 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
13949 struct frame *f = XFRAME (selected_frame);
13950 dump_glyph_matrix (f->current_matrix, 1);
13951 return Qnil;
13955 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
13956 doc: /* Dump glyph row ROW to stderr.
13957 GLYPH 0 means don't dump glyphs.
13958 GLYPH 1 means dump glyphs in short form.
13959 GLYPH > 1 or omitted means dump glyphs in long form. */)
13960 (row, glyphs)
13961 Lisp_Object row, glyphs;
13963 struct glyph_matrix *matrix;
13964 int vpos;
13966 CHECK_NUMBER (row);
13967 matrix = XWINDOW (selected_window)->current_matrix;
13968 vpos = XINT (row);
13969 if (vpos >= 0 && vpos < matrix->nrows)
13970 dump_glyph_row (MATRIX_ROW (matrix, vpos),
13971 vpos,
13972 INTEGERP (glyphs) ? XINT (glyphs) : 2);
13973 return Qnil;
13977 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
13978 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
13979 GLYPH 0 means don't dump glyphs.
13980 GLYPH 1 means dump glyphs in short form.
13981 GLYPH > 1 or omitted means dump glyphs in long form. */)
13982 (row, glyphs)
13983 Lisp_Object row, glyphs;
13985 struct frame *sf = SELECTED_FRAME ();
13986 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
13987 int vpos;
13989 CHECK_NUMBER (row);
13990 vpos = XINT (row);
13991 if (vpos >= 0 && vpos < m->nrows)
13992 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
13993 INTEGERP (glyphs) ? XINT (glyphs) : 2);
13994 return Qnil;
13998 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
13999 doc: /* Toggle tracing of redisplay.
14000 With ARG, turn tracing on if and only if ARG is positive. */)
14001 (arg)
14002 Lisp_Object arg;
14004 if (NILP (arg))
14005 trace_redisplay_p = !trace_redisplay_p;
14006 else
14008 arg = Fprefix_numeric_value (arg);
14009 trace_redisplay_p = XINT (arg) > 0;
14012 return Qnil;
14016 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
14017 doc: /* Like `format', but print result to stderr.
14018 usage: (trace-to-stderr STRING &rest OBJECTS) */)
14019 (nargs, args)
14020 int nargs;
14021 Lisp_Object *args;
14023 Lisp_Object s = Fformat (nargs, args);
14024 fprintf (stderr, "%s", SDATA (s));
14025 return Qnil;
14028 #endif /* GLYPH_DEBUG */
14032 /***********************************************************************
14033 Building Desired Matrix Rows
14034 ***********************************************************************/
14036 /* Return a temporary glyph row holding the glyphs of an overlay
14037 arrow. Only used for non-window-redisplay windows. */
14039 static struct glyph_row *
14040 get_overlay_arrow_glyph_row (w, overlay_arrow_string)
14041 struct window *w;
14042 Lisp_Object overlay_arrow_string;
14044 struct frame *f = XFRAME (WINDOW_FRAME (w));
14045 struct buffer *buffer = XBUFFER (w->buffer);
14046 struct buffer *old = current_buffer;
14047 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
14048 int arrow_len = SCHARS (overlay_arrow_string);
14049 const unsigned char *arrow_end = arrow_string + arrow_len;
14050 const unsigned char *p;
14051 struct it it;
14052 int multibyte_p;
14053 int n_glyphs_before;
14055 set_buffer_temp (buffer);
14056 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
14057 it.glyph_row->used[TEXT_AREA] = 0;
14058 SET_TEXT_POS (it.position, 0, 0);
14060 multibyte_p = !NILP (buffer->enable_multibyte_characters);
14061 p = arrow_string;
14062 while (p < arrow_end)
14064 Lisp_Object face, ilisp;
14066 /* Get the next character. */
14067 if (multibyte_p)
14068 it.c = string_char_and_length (p, arrow_len, &it.len);
14069 else
14070 it.c = *p, it.len = 1;
14071 p += it.len;
14073 /* Get its face. */
14074 ilisp = make_number (p - arrow_string);
14075 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
14076 it.face_id = compute_char_face (f, it.c, face);
14078 /* Compute its width, get its glyphs. */
14079 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
14080 SET_TEXT_POS (it.position, -1, -1);
14081 PRODUCE_GLYPHS (&it);
14083 /* If this character doesn't fit any more in the line, we have
14084 to remove some glyphs. */
14085 if (it.current_x > it.last_visible_x)
14087 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
14088 break;
14092 set_buffer_temp (old);
14093 return it.glyph_row;
14097 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
14098 glyphs are only inserted for terminal frames since we can't really
14099 win with truncation glyphs when partially visible glyphs are
14100 involved. Which glyphs to insert is determined by
14101 produce_special_glyphs. */
14103 static void
14104 insert_left_trunc_glyphs (it)
14105 struct it *it;
14107 struct it truncate_it;
14108 struct glyph *from, *end, *to, *toend;
14110 xassert (!FRAME_WINDOW_P (it->f));
14112 /* Get the truncation glyphs. */
14113 truncate_it = *it;
14114 truncate_it.current_x = 0;
14115 truncate_it.face_id = DEFAULT_FACE_ID;
14116 truncate_it.glyph_row = &scratch_glyph_row;
14117 truncate_it.glyph_row->used[TEXT_AREA] = 0;
14118 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
14119 truncate_it.object = make_number (0);
14120 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
14122 /* Overwrite glyphs from IT with truncation glyphs. */
14123 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
14124 end = from + truncate_it.glyph_row->used[TEXT_AREA];
14125 to = it->glyph_row->glyphs[TEXT_AREA];
14126 toend = to + it->glyph_row->used[TEXT_AREA];
14128 while (from < end)
14129 *to++ = *from++;
14131 /* There may be padding glyphs left over. Overwrite them too. */
14132 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
14134 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
14135 while (from < end)
14136 *to++ = *from++;
14139 if (to > toend)
14140 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
14144 /* Compute the pixel height and width of IT->glyph_row.
14146 Most of the time, ascent and height of a display line will be equal
14147 to the max_ascent and max_height values of the display iterator
14148 structure. This is not the case if
14150 1. We hit ZV without displaying anything. In this case, max_ascent
14151 and max_height will be zero.
14153 2. We have some glyphs that don't contribute to the line height.
14154 (The glyph row flag contributes_to_line_height_p is for future
14155 pixmap extensions).
14157 The first case is easily covered by using default values because in
14158 these cases, the line height does not really matter, except that it
14159 must not be zero. */
14161 static void
14162 compute_line_metrics (it)
14163 struct it *it;
14165 struct glyph_row *row = it->glyph_row;
14166 int area, i;
14168 if (FRAME_WINDOW_P (it->f))
14170 int i, min_y, max_y;
14172 /* The line may consist of one space only, that was added to
14173 place the cursor on it. If so, the row's height hasn't been
14174 computed yet. */
14175 if (row->height == 0)
14177 if (it->max_ascent + it->max_descent == 0)
14178 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
14179 row->ascent = it->max_ascent;
14180 row->height = it->max_ascent + it->max_descent;
14181 row->phys_ascent = it->max_phys_ascent;
14182 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
14185 /* Compute the width of this line. */
14186 row->pixel_width = row->x;
14187 for (i = 0; i < row->used[TEXT_AREA]; ++i)
14188 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
14190 xassert (row->pixel_width >= 0);
14191 xassert (row->ascent >= 0 && row->height > 0);
14193 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
14194 || MATRIX_ROW_OVERLAPS_PRED_P (row));
14196 /* If first line's physical ascent is larger than its logical
14197 ascent, use the physical ascent, and make the row taller.
14198 This makes accented characters fully visible. */
14199 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
14200 && row->phys_ascent > row->ascent)
14202 row->height += row->phys_ascent - row->ascent;
14203 row->ascent = row->phys_ascent;
14206 /* Compute how much of the line is visible. */
14207 row->visible_height = row->height;
14209 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
14210 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
14212 if (row->y < min_y)
14213 row->visible_height -= min_y - row->y;
14214 if (row->y + row->height > max_y)
14215 row->visible_height -= row->y + row->height - max_y;
14217 else
14219 row->pixel_width = row->used[TEXT_AREA];
14220 if (row->continued_p)
14221 row->pixel_width -= it->continuation_pixel_width;
14222 else if (row->truncated_on_right_p)
14223 row->pixel_width -= it->truncation_pixel_width;
14224 row->ascent = row->phys_ascent = 0;
14225 row->height = row->phys_height = row->visible_height = 1;
14228 /* Compute a hash code for this row. */
14229 row->hash = 0;
14230 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
14231 for (i = 0; i < row->used[area]; ++i)
14232 row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff)
14233 + row->glyphs[area][i].u.val
14234 + row->glyphs[area][i].face_id
14235 + row->glyphs[area][i].padding_p
14236 + (row->glyphs[area][i].type << 2));
14238 it->max_ascent = it->max_descent = 0;
14239 it->max_phys_ascent = it->max_phys_descent = 0;
14243 /* Append one space to the glyph row of iterator IT if doing a
14244 window-based redisplay. The space has the same face as
14245 IT->face_id. Value is non-zero if a space was added.
14247 This function is called to make sure that there is always one glyph
14248 at the end of a glyph row that the cursor can be set on under
14249 window-systems. (If there weren't such a glyph we would not know
14250 how wide and tall a box cursor should be displayed).
14252 At the same time this space let's a nicely handle clearing to the
14253 end of the line if the row ends in italic text. */
14255 static int
14256 append_space_for_newline (it, default_face_p)
14257 struct it *it;
14258 int default_face_p;
14260 if (FRAME_WINDOW_P (it->f))
14262 int n = it->glyph_row->used[TEXT_AREA];
14264 if (it->glyph_row->glyphs[TEXT_AREA] + n
14265 < it->glyph_row->glyphs[1 + TEXT_AREA])
14267 /* Save some values that must not be changed.
14268 Must save IT->c and IT->len because otherwise
14269 ITERATOR_AT_END_P wouldn't work anymore after
14270 append_space_for_newline has been called. */
14271 enum display_element_type saved_what = it->what;
14272 int saved_c = it->c, saved_len = it->len;
14273 int saved_x = it->current_x;
14274 int saved_face_id = it->face_id;
14275 struct text_pos saved_pos;
14276 Lisp_Object saved_object;
14277 struct face *face;
14279 saved_object = it->object;
14280 saved_pos = it->position;
14282 it->what = IT_CHARACTER;
14283 bzero (&it->position, sizeof it->position);
14284 it->object = make_number (0);
14285 it->c = ' ';
14286 it->len = 1;
14288 if (default_face_p)
14289 it->face_id = DEFAULT_FACE_ID;
14290 else if (it->face_before_selective_p)
14291 it->face_id = it->saved_face_id;
14292 face = FACE_FROM_ID (it->f, it->face_id);
14293 it->face_id = FACE_FOR_CHAR (it->f, face, 0);
14295 PRODUCE_GLYPHS (it);
14297 it->override_ascent = -1;
14298 it->constrain_row_ascent_descent_p = 0;
14299 it->current_x = saved_x;
14300 it->object = saved_object;
14301 it->position = saved_pos;
14302 it->what = saved_what;
14303 it->face_id = saved_face_id;
14304 it->len = saved_len;
14305 it->c = saved_c;
14306 return 1;
14310 return 0;
14314 /* Extend the face of the last glyph in the text area of IT->glyph_row
14315 to the end of the display line. Called from display_line.
14316 If the glyph row is empty, add a space glyph to it so that we
14317 know the face to draw. Set the glyph row flag fill_line_p. */
14319 static void
14320 extend_face_to_end_of_line (it)
14321 struct it *it;
14323 struct face *face;
14324 struct frame *f = it->f;
14326 /* If line is already filled, do nothing. */
14327 if (it->current_x >= it->last_visible_x)
14328 return;
14330 /* Face extension extends the background and box of IT->face_id
14331 to the end of the line. If the background equals the background
14332 of the frame, we don't have to do anything. */
14333 if (it->face_before_selective_p)
14334 face = FACE_FROM_ID (it->f, it->saved_face_id);
14335 else
14336 face = FACE_FROM_ID (f, it->face_id);
14338 if (FRAME_WINDOW_P (f)
14339 && face->box == FACE_NO_BOX
14340 && face->background == FRAME_BACKGROUND_PIXEL (f)
14341 && !face->stipple)
14342 return;
14344 /* Set the glyph row flag indicating that the face of the last glyph
14345 in the text area has to be drawn to the end of the text area. */
14346 it->glyph_row->fill_line_p = 1;
14348 /* If current character of IT is not ASCII, make sure we have the
14349 ASCII face. This will be automatically undone the next time
14350 get_next_display_element returns a multibyte character. Note
14351 that the character will always be single byte in unibyte text. */
14352 if (!SINGLE_BYTE_CHAR_P (it->c))
14354 it->face_id = FACE_FOR_CHAR (f, face, 0);
14357 if (FRAME_WINDOW_P (f))
14359 /* If the row is empty, add a space with the current face of IT,
14360 so that we know which face to draw. */
14361 if (it->glyph_row->used[TEXT_AREA] == 0)
14363 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
14364 it->glyph_row->glyphs[TEXT_AREA][0].face_id = it->face_id;
14365 it->glyph_row->used[TEXT_AREA] = 1;
14368 else
14370 /* Save some values that must not be changed. */
14371 int saved_x = it->current_x;
14372 struct text_pos saved_pos;
14373 Lisp_Object saved_object;
14374 enum display_element_type saved_what = it->what;
14375 int saved_face_id = it->face_id;
14377 saved_object = it->object;
14378 saved_pos = it->position;
14380 it->what = IT_CHARACTER;
14381 bzero (&it->position, sizeof it->position);
14382 it->object = make_number (0);
14383 it->c = ' ';
14384 it->len = 1;
14385 it->face_id = face->id;
14387 PRODUCE_GLYPHS (it);
14389 while (it->current_x <= it->last_visible_x)
14390 PRODUCE_GLYPHS (it);
14392 /* Don't count these blanks really. It would let us insert a left
14393 truncation glyph below and make us set the cursor on them, maybe. */
14394 it->current_x = saved_x;
14395 it->object = saved_object;
14396 it->position = saved_pos;
14397 it->what = saved_what;
14398 it->face_id = saved_face_id;
14403 /* Value is non-zero if text starting at CHARPOS in current_buffer is
14404 trailing whitespace. */
14406 static int
14407 trailing_whitespace_p (charpos)
14408 int charpos;
14410 int bytepos = CHAR_TO_BYTE (charpos);
14411 int c = 0;
14413 while (bytepos < ZV_BYTE
14414 && (c = FETCH_CHAR (bytepos),
14415 c == ' ' || c == '\t'))
14416 ++bytepos;
14418 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
14420 if (bytepos != PT_BYTE)
14421 return 1;
14423 return 0;
14427 /* Highlight trailing whitespace, if any, in ROW. */
14429 void
14430 highlight_trailing_whitespace (f, row)
14431 struct frame *f;
14432 struct glyph_row *row;
14434 int used = row->used[TEXT_AREA];
14436 if (used)
14438 struct glyph *start = row->glyphs[TEXT_AREA];
14439 struct glyph *glyph = start + used - 1;
14441 /* Skip over glyphs inserted to display the cursor at the
14442 end of a line, for extending the face of the last glyph
14443 to the end of the line on terminals, and for truncation
14444 and continuation glyphs. */
14445 while (glyph >= start
14446 && glyph->type == CHAR_GLYPH
14447 && INTEGERP (glyph->object))
14448 --glyph;
14450 /* If last glyph is a space or stretch, and it's trailing
14451 whitespace, set the face of all trailing whitespace glyphs in
14452 IT->glyph_row to `trailing-whitespace'. */
14453 if (glyph >= start
14454 && BUFFERP (glyph->object)
14455 && (glyph->type == STRETCH_GLYPH
14456 || (glyph->type == CHAR_GLYPH
14457 && glyph->u.ch == ' '))
14458 && trailing_whitespace_p (glyph->charpos))
14460 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0);
14462 while (glyph >= start
14463 && BUFFERP (glyph->object)
14464 && (glyph->type == STRETCH_GLYPH
14465 || (glyph->type == CHAR_GLYPH
14466 && glyph->u.ch == ' ')))
14467 (glyph--)->face_id = face_id;
14473 /* Value is non-zero if glyph row ROW in window W should be
14474 used to hold the cursor. */
14476 static int
14477 cursor_row_p (w, row)
14478 struct window *w;
14479 struct glyph_row *row;
14481 int cursor_row_p = 1;
14483 if (PT == MATRIX_ROW_END_CHARPOS (row))
14485 /* If the row ends with a newline from a string, we don't want
14486 the cursor there (if the row is continued it doesn't end in a
14487 newline). */
14488 if (CHARPOS (row->end.string_pos) >= 0
14489 || MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
14490 cursor_row_p = row->continued_p;
14492 /* If the row ends at ZV, display the cursor at the end of that
14493 row instead of at the start of the row below. */
14494 else if (row->ends_at_zv_p)
14495 cursor_row_p = 1;
14496 else
14497 cursor_row_p = 0;
14500 return cursor_row_p;
14504 /* Construct the glyph row IT->glyph_row in the desired matrix of
14505 IT->w from text at the current position of IT. See dispextern.h
14506 for an overview of struct it. Value is non-zero if
14507 IT->glyph_row displays text, as opposed to a line displaying ZV
14508 only. */
14510 static int
14511 display_line (it)
14512 struct it *it;
14514 struct glyph_row *row = it->glyph_row;
14515 int overlay_arrow_bitmap;
14516 Lisp_Object overlay_arrow_string;
14518 /* We always start displaying at hpos zero even if hscrolled. */
14519 xassert (it->hpos == 0 && it->current_x == 0);
14521 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
14522 >= it->w->desired_matrix->nrows)
14524 it->w->nrows_scale_factor++;
14525 fonts_changed_p = 1;
14526 return 0;
14529 /* Is IT->w showing the region? */
14530 it->w->region_showing = it->region_beg_charpos > 0 ? Qt : Qnil;
14532 /* Clear the result glyph row and enable it. */
14533 prepare_desired_row (row);
14535 row->y = it->current_y;
14536 row->start = it->start;
14537 row->continuation_lines_width = it->continuation_lines_width;
14538 row->displays_text_p = 1;
14539 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
14540 it->starts_in_middle_of_char_p = 0;
14542 /* Arrange the overlays nicely for our purposes. Usually, we call
14543 display_line on only one line at a time, in which case this
14544 can't really hurt too much, or we call it on lines which appear
14545 one after another in the buffer, in which case all calls to
14546 recenter_overlay_lists but the first will be pretty cheap. */
14547 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
14549 /* Move over display elements that are not visible because we are
14550 hscrolled. This may stop at an x-position < IT->first_visible_x
14551 if the first glyph is partially visible or if we hit a line end. */
14552 if (it->current_x < it->first_visible_x)
14553 move_it_in_display_line_to (it, ZV, it->first_visible_x,
14554 MOVE_TO_POS | MOVE_TO_X);
14556 /* Get the initial row height. This is either the height of the
14557 text hscrolled, if there is any, or zero. */
14558 row->ascent = it->max_ascent;
14559 row->height = it->max_ascent + it->max_descent;
14560 row->phys_ascent = it->max_phys_ascent;
14561 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
14563 /* Loop generating characters. The loop is left with IT on the next
14564 character to display. */
14565 while (1)
14567 int n_glyphs_before, hpos_before, x_before;
14568 int x, i, nglyphs;
14569 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
14571 /* Retrieve the next thing to display. Value is zero if end of
14572 buffer reached. */
14573 if (!get_next_display_element (it))
14575 /* Maybe add a space at the end of this line that is used to
14576 display the cursor there under X. Set the charpos of the
14577 first glyph of blank lines not corresponding to any text
14578 to -1. */
14579 #ifdef HAVE_WINDOW_SYSTEM
14580 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14581 row->exact_window_width_line_p = 1;
14582 else
14583 #endif /* HAVE_WINDOW_SYSTEM */
14584 if ((append_space_for_newline (it, 1) && row->used[TEXT_AREA] == 1)
14585 || row->used[TEXT_AREA] == 0)
14587 row->glyphs[TEXT_AREA]->charpos = -1;
14588 row->displays_text_p = 0;
14590 if (!NILP (XBUFFER (it->w->buffer)->indicate_empty_lines)
14591 && (!MINI_WINDOW_P (it->w)
14592 || (minibuf_level && EQ (it->window, minibuf_window))))
14593 row->indicate_empty_line_p = 1;
14596 it->continuation_lines_width = 0;
14597 row->ends_at_zv_p = 1;
14598 break;
14601 /* Now, get the metrics of what we want to display. This also
14602 generates glyphs in `row' (which is IT->glyph_row). */
14603 n_glyphs_before = row->used[TEXT_AREA];
14604 x = it->current_x;
14606 /* Remember the line height so far in case the next element doesn't
14607 fit on the line. */
14608 if (!it->truncate_lines_p)
14610 ascent = it->max_ascent;
14611 descent = it->max_descent;
14612 phys_ascent = it->max_phys_ascent;
14613 phys_descent = it->max_phys_descent;
14616 PRODUCE_GLYPHS (it);
14618 /* If this display element was in marginal areas, continue with
14619 the next one. */
14620 if (it->area != TEXT_AREA)
14622 row->ascent = max (row->ascent, it->max_ascent);
14623 row->height = max (row->height, it->max_ascent + it->max_descent);
14624 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14625 row->phys_height = max (row->phys_height,
14626 it->max_phys_ascent + it->max_phys_descent);
14627 set_iterator_to_next (it, 1);
14628 continue;
14631 /* Does the display element fit on the line? If we truncate
14632 lines, we should draw past the right edge of the window. If
14633 we don't truncate, we want to stop so that we can display the
14634 continuation glyph before the right margin. If lines are
14635 continued, there are two possible strategies for characters
14636 resulting in more than 1 glyph (e.g. tabs): Display as many
14637 glyphs as possible in this line and leave the rest for the
14638 continuation line, or display the whole element in the next
14639 line. Original redisplay did the former, so we do it also. */
14640 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
14641 hpos_before = it->hpos;
14642 x_before = x;
14644 if (/* Not a newline. */
14645 nglyphs > 0
14646 /* Glyphs produced fit entirely in the line. */
14647 && it->current_x < it->last_visible_x)
14649 it->hpos += nglyphs;
14650 row->ascent = max (row->ascent, it->max_ascent);
14651 row->height = max (row->height, it->max_ascent + it->max_descent);
14652 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14653 row->phys_height = max (row->phys_height,
14654 it->max_phys_ascent + it->max_phys_descent);
14655 if (it->current_x - it->pixel_width < it->first_visible_x)
14656 row->x = x - it->first_visible_x;
14658 else
14660 int new_x;
14661 struct glyph *glyph;
14663 for (i = 0; i < nglyphs; ++i, x = new_x)
14665 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
14666 new_x = x + glyph->pixel_width;
14668 if (/* Lines are continued. */
14669 !it->truncate_lines_p
14670 && (/* Glyph doesn't fit on the line. */
14671 new_x > it->last_visible_x
14672 /* Or it fits exactly on a window system frame. */
14673 || (new_x == it->last_visible_x
14674 && FRAME_WINDOW_P (it->f))))
14676 /* End of a continued line. */
14678 if (it->hpos == 0
14679 || (new_x == it->last_visible_x
14680 && FRAME_WINDOW_P (it->f)))
14682 /* Current glyph is the only one on the line or
14683 fits exactly on the line. We must continue
14684 the line because we can't draw the cursor
14685 after the glyph. */
14686 row->continued_p = 1;
14687 it->current_x = new_x;
14688 it->continuation_lines_width += new_x;
14689 ++it->hpos;
14690 if (i == nglyphs - 1)
14692 set_iterator_to_next (it, 1);
14693 #ifdef HAVE_WINDOW_SYSTEM
14694 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14696 if (!get_next_display_element (it))
14698 row->exact_window_width_line_p = 1;
14699 it->continuation_lines_width = 0;
14700 row->continued_p = 0;
14701 row->ends_at_zv_p = 1;
14703 else if (ITERATOR_AT_END_OF_LINE_P (it))
14705 row->continued_p = 0;
14706 row->exact_window_width_line_p = 1;
14709 #endif /* HAVE_WINDOW_SYSTEM */
14712 else if (CHAR_GLYPH_PADDING_P (*glyph)
14713 && !FRAME_WINDOW_P (it->f))
14715 /* A padding glyph that doesn't fit on this line.
14716 This means the whole character doesn't fit
14717 on the line. */
14718 row->used[TEXT_AREA] = n_glyphs_before;
14720 /* Fill the rest of the row with continuation
14721 glyphs like in 20.x. */
14722 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
14723 < row->glyphs[1 + TEXT_AREA])
14724 produce_special_glyphs (it, IT_CONTINUATION);
14726 row->continued_p = 1;
14727 it->current_x = x_before;
14728 it->continuation_lines_width += x_before;
14730 /* Restore the height to what it was before the
14731 element not fitting on the line. */
14732 it->max_ascent = ascent;
14733 it->max_descent = descent;
14734 it->max_phys_ascent = phys_ascent;
14735 it->max_phys_descent = phys_descent;
14737 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
14739 /* A TAB that extends past the right edge of the
14740 window. This produces a single glyph on
14741 window system frames. We leave the glyph in
14742 this row and let it fill the row, but don't
14743 consume the TAB. */
14744 it->continuation_lines_width += it->last_visible_x;
14745 row->ends_in_middle_of_char_p = 1;
14746 row->continued_p = 1;
14747 glyph->pixel_width = it->last_visible_x - x;
14748 it->starts_in_middle_of_char_p = 1;
14750 else
14752 /* Something other than a TAB that draws past
14753 the right edge of the window. Restore
14754 positions to values before the element. */
14755 row->used[TEXT_AREA] = n_glyphs_before + i;
14757 /* Display continuation glyphs. */
14758 if (!FRAME_WINDOW_P (it->f))
14759 produce_special_glyphs (it, IT_CONTINUATION);
14760 row->continued_p = 1;
14762 it->continuation_lines_width += x;
14764 if (nglyphs > 1 && i > 0)
14766 row->ends_in_middle_of_char_p = 1;
14767 it->starts_in_middle_of_char_p = 1;
14770 /* Restore the height to what it was before the
14771 element not fitting on the line. */
14772 it->max_ascent = ascent;
14773 it->max_descent = descent;
14774 it->max_phys_ascent = phys_ascent;
14775 it->max_phys_descent = phys_descent;
14778 break;
14780 else if (new_x > it->first_visible_x)
14782 /* Increment number of glyphs actually displayed. */
14783 ++it->hpos;
14785 if (x < it->first_visible_x)
14786 /* Glyph is partially visible, i.e. row starts at
14787 negative X position. */
14788 row->x = x - it->first_visible_x;
14790 else
14792 /* Glyph is completely off the left margin of the
14793 window. This should not happen because of the
14794 move_it_in_display_line at the start of this
14795 function, unless the text display area of the
14796 window is empty. */
14797 xassert (it->first_visible_x <= it->last_visible_x);
14801 row->ascent = max (row->ascent, it->max_ascent);
14802 row->height = max (row->height, it->max_ascent + it->max_descent);
14803 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14804 row->phys_height = max (row->phys_height,
14805 it->max_phys_ascent + it->max_phys_descent);
14807 /* End of this display line if row is continued. */
14808 if (row->continued_p || row->ends_at_zv_p)
14809 break;
14812 at_end_of_line:
14813 /* Is this a line end? If yes, we're also done, after making
14814 sure that a non-default face is extended up to the right
14815 margin of the window. */
14816 if (ITERATOR_AT_END_OF_LINE_P (it))
14818 int used_before = row->used[TEXT_AREA];
14820 row->ends_in_newline_from_string_p = STRINGP (it->object);
14822 #ifdef HAVE_WINDOW_SYSTEM
14823 /* Add a space at the end of the line that is used to
14824 display the cursor there. */
14825 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14826 append_space_for_newline (it, 0);
14827 #endif /* HAVE_WINDOW_SYSTEM */
14829 /* Extend the face to the end of the line. */
14830 extend_face_to_end_of_line (it);
14832 /* Make sure we have the position. */
14833 if (used_before == 0)
14834 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
14836 /* Consume the line end. This skips over invisible lines. */
14837 set_iterator_to_next (it, 1);
14838 it->continuation_lines_width = 0;
14839 break;
14842 /* Proceed with next display element. Note that this skips
14843 over lines invisible because of selective display. */
14844 set_iterator_to_next (it, 1);
14846 /* If we truncate lines, we are done when the last displayed
14847 glyphs reach past the right margin of the window. */
14848 if (it->truncate_lines_p
14849 && (FRAME_WINDOW_P (it->f)
14850 ? (it->current_x >= it->last_visible_x)
14851 : (it->current_x > it->last_visible_x)))
14853 /* Maybe add truncation glyphs. */
14854 if (!FRAME_WINDOW_P (it->f))
14856 int i, n;
14858 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
14859 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
14860 break;
14862 for (n = row->used[TEXT_AREA]; i < n; ++i)
14864 row->used[TEXT_AREA] = i;
14865 produce_special_glyphs (it, IT_TRUNCATION);
14868 #ifdef HAVE_WINDOW_SYSTEM
14869 else
14871 /* Don't truncate if we can overflow newline into fringe. */
14872 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14874 if (!get_next_display_element (it))
14876 #ifdef HAVE_WINDOW_SYSTEM
14877 it->continuation_lines_width = 0;
14878 row->ends_at_zv_p = 1;
14879 row->exact_window_width_line_p = 1;
14880 break;
14881 #endif /* HAVE_WINDOW_SYSTEM */
14883 if (ITERATOR_AT_END_OF_LINE_P (it))
14885 row->exact_window_width_line_p = 1;
14886 goto at_end_of_line;
14890 #endif /* HAVE_WINDOW_SYSTEM */
14892 row->truncated_on_right_p = 1;
14893 it->continuation_lines_width = 0;
14894 reseat_at_next_visible_line_start (it, 0);
14895 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
14896 it->hpos = hpos_before;
14897 it->current_x = x_before;
14898 break;
14902 /* If line is not empty and hscrolled, maybe insert truncation glyphs
14903 at the left window margin. */
14904 if (it->first_visible_x
14905 && IT_CHARPOS (*it) != MATRIX_ROW_START_CHARPOS (row))
14907 if (!FRAME_WINDOW_P (it->f))
14908 insert_left_trunc_glyphs (it);
14909 row->truncated_on_left_p = 1;
14912 /* If the start of this line is the overlay arrow-position, then
14913 mark this glyph row as the one containing the overlay arrow.
14914 This is clearly a mess with variable size fonts. It would be
14915 better to let it be displayed like cursors under X. */
14916 if (! overlay_arrow_seen
14917 && (overlay_arrow_string
14918 = overlay_arrow_at_row (it->f, row, &overlay_arrow_bitmap),
14919 !NILP (overlay_arrow_string)))
14921 /* Overlay arrow in window redisplay is a fringe bitmap. */
14922 if (!FRAME_WINDOW_P (it->f))
14924 struct glyph_row *arrow_row
14925 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
14926 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
14927 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
14928 struct glyph *p = row->glyphs[TEXT_AREA];
14929 struct glyph *p2, *end;
14931 /* Copy the arrow glyphs. */
14932 while (glyph < arrow_end)
14933 *p++ = *glyph++;
14935 /* Throw away padding glyphs. */
14936 p2 = p;
14937 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
14938 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
14939 ++p2;
14940 if (p2 > p)
14942 while (p2 < end)
14943 *p++ = *p2++;
14944 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
14948 overlay_arrow_seen = 1;
14949 it->w->overlay_arrow_bitmap = overlay_arrow_bitmap;
14950 row->overlay_arrow_p = 1;
14953 /* Compute pixel dimensions of this line. */
14954 compute_line_metrics (it);
14956 /* Remember the position at which this line ends. */
14957 row->end = it->current;
14959 /* Save fringe bitmaps in this row. */
14960 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
14961 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
14962 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
14963 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
14965 it->left_user_fringe_bitmap = 0;
14966 it->left_user_fringe_face_id = 0;
14967 it->right_user_fringe_bitmap = 0;
14968 it->right_user_fringe_face_id = 0;
14970 /* Maybe set the cursor. */
14971 if (it->w->cursor.vpos < 0
14972 && PT >= MATRIX_ROW_START_CHARPOS (row)
14973 && PT <= MATRIX_ROW_END_CHARPOS (row)
14974 && cursor_row_p (it->w, row))
14975 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
14977 /* Highlight trailing whitespace. */
14978 if (!NILP (Vshow_trailing_whitespace))
14979 highlight_trailing_whitespace (it->f, it->glyph_row);
14981 /* Prepare for the next line. This line starts horizontally at (X
14982 HPOS) = (0 0). Vertical positions are incremented. As a
14983 convenience for the caller, IT->glyph_row is set to the next
14984 row to be used. */
14985 it->current_x = it->hpos = 0;
14986 it->current_y += row->height;
14987 ++it->vpos;
14988 ++it->glyph_row;
14989 it->start = it->current;
14990 return row->displays_text_p;
14995 /***********************************************************************
14996 Menu Bar
14997 ***********************************************************************/
14999 /* Redisplay the menu bar in the frame for window W.
15001 The menu bar of X frames that don't have X toolkit support is
15002 displayed in a special window W->frame->menu_bar_window.
15004 The menu bar of terminal frames is treated specially as far as
15005 glyph matrices are concerned. Menu bar lines are not part of
15006 windows, so the update is done directly on the frame matrix rows
15007 for the menu bar. */
15009 static void
15010 display_menu_bar (w)
15011 struct window *w;
15013 struct frame *f = XFRAME (WINDOW_FRAME (w));
15014 struct it it;
15015 Lisp_Object items;
15016 int i;
15018 /* Don't do all this for graphical frames. */
15019 #ifdef HAVE_NTGUI
15020 if (!NILP (Vwindow_system))
15021 return;
15022 #endif
15023 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
15024 if (FRAME_X_P (f))
15025 return;
15026 #endif
15027 #ifdef MAC_OS
15028 if (FRAME_MAC_P (f))
15029 return;
15030 #endif
15032 #ifdef USE_X_TOOLKIT
15033 xassert (!FRAME_WINDOW_P (f));
15034 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
15035 it.first_visible_x = 0;
15036 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
15037 #else /* not USE_X_TOOLKIT */
15038 if (FRAME_WINDOW_P (f))
15040 /* Menu bar lines are displayed in the desired matrix of the
15041 dummy window menu_bar_window. */
15042 struct window *menu_w;
15043 xassert (WINDOWP (f->menu_bar_window));
15044 menu_w = XWINDOW (f->menu_bar_window);
15045 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
15046 MENU_FACE_ID);
15047 it.first_visible_x = 0;
15048 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
15050 else
15052 /* This is a TTY frame, i.e. character hpos/vpos are used as
15053 pixel x/y. */
15054 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
15055 MENU_FACE_ID);
15056 it.first_visible_x = 0;
15057 it.last_visible_x = FRAME_COLS (f);
15059 #endif /* not USE_X_TOOLKIT */
15061 if (! mode_line_inverse_video)
15062 /* Force the menu-bar to be displayed in the default face. */
15063 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
15065 /* Clear all rows of the menu bar. */
15066 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
15068 struct glyph_row *row = it.glyph_row + i;
15069 clear_glyph_row (row);
15070 row->enabled_p = 1;
15071 row->full_width_p = 1;
15074 /* Display all items of the menu bar. */
15075 items = FRAME_MENU_BAR_ITEMS (it.f);
15076 for (i = 0; i < XVECTOR (items)->size; i += 4)
15078 Lisp_Object string;
15080 /* Stop at nil string. */
15081 string = AREF (items, i + 1);
15082 if (NILP (string))
15083 break;
15085 /* Remember where item was displayed. */
15086 AREF (items, i + 3) = make_number (it.hpos);
15088 /* Display the item, pad with one space. */
15089 if (it.current_x < it.last_visible_x)
15090 display_string (NULL, string, Qnil, 0, 0, &it,
15091 SCHARS (string) + 1, 0, 0, -1);
15094 /* Fill out the line with spaces. */
15095 if (it.current_x < it.last_visible_x)
15096 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
15098 /* Compute the total height of the lines. */
15099 compute_line_metrics (&it);
15104 /***********************************************************************
15105 Mode Line
15106 ***********************************************************************/
15108 /* Redisplay mode lines in the window tree whose root is WINDOW. If
15109 FORCE is non-zero, redisplay mode lines unconditionally.
15110 Otherwise, redisplay only mode lines that are garbaged. Value is
15111 the number of windows whose mode lines were redisplayed. */
15113 static int
15114 redisplay_mode_lines (window, force)
15115 Lisp_Object window;
15116 int force;
15118 int nwindows = 0;
15120 while (!NILP (window))
15122 struct window *w = XWINDOW (window);
15124 if (WINDOWP (w->hchild))
15125 nwindows += redisplay_mode_lines (w->hchild, force);
15126 else if (WINDOWP (w->vchild))
15127 nwindows += redisplay_mode_lines (w->vchild, force);
15128 else if (force
15129 || FRAME_GARBAGED_P (XFRAME (w->frame))
15130 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
15132 struct text_pos lpoint;
15133 struct buffer *old = current_buffer;
15135 /* Set the window's buffer for the mode line display. */
15136 SET_TEXT_POS (lpoint, PT, PT_BYTE);
15137 set_buffer_internal_1 (XBUFFER (w->buffer));
15139 /* Point refers normally to the selected window. For any
15140 other window, set up appropriate value. */
15141 if (!EQ (window, selected_window))
15143 struct text_pos pt;
15145 SET_TEXT_POS_FROM_MARKER (pt, w->pointm);
15146 if (CHARPOS (pt) < BEGV)
15147 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
15148 else if (CHARPOS (pt) > (ZV - 1))
15149 TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
15150 else
15151 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
15154 /* Display mode lines. */
15155 clear_glyph_matrix (w->desired_matrix);
15156 if (display_mode_lines (w))
15158 ++nwindows;
15159 w->must_be_updated_p = 1;
15162 /* Restore old settings. */
15163 set_buffer_internal_1 (old);
15164 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
15167 window = w->next;
15170 return nwindows;
15174 /* Display the mode and/or top line of window W. Value is the number
15175 of mode lines displayed. */
15177 static int
15178 display_mode_lines (w)
15179 struct window *w;
15181 Lisp_Object old_selected_window, old_selected_frame;
15182 int n = 0;
15184 old_selected_frame = selected_frame;
15185 selected_frame = w->frame;
15186 old_selected_window = selected_window;
15187 XSETWINDOW (selected_window, w);
15189 /* These will be set while the mode line specs are processed. */
15190 line_number_displayed = 0;
15191 w->column_number_displayed = Qnil;
15193 if (WINDOW_WANTS_MODELINE_P (w))
15195 struct window *sel_w = XWINDOW (old_selected_window);
15197 /* Select mode line face based on the real selected window. */
15198 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
15199 current_buffer->mode_line_format);
15200 ++n;
15203 if (WINDOW_WANTS_HEADER_LINE_P (w))
15205 display_mode_line (w, HEADER_LINE_FACE_ID,
15206 current_buffer->header_line_format);
15207 ++n;
15210 selected_frame = old_selected_frame;
15211 selected_window = old_selected_window;
15212 return n;
15216 /* Display mode or top line of window W. FACE_ID specifies which line
15217 to display; it is either MODE_LINE_FACE_ID or HEADER_LINE_FACE_ID.
15218 FORMAT is the mode line format to display. Value is the pixel
15219 height of the mode line displayed. */
15221 static int
15222 display_mode_line (w, face_id, format)
15223 struct window *w;
15224 enum face_id face_id;
15225 Lisp_Object format;
15227 struct it it;
15228 struct face *face;
15230 init_iterator (&it, w, -1, -1, NULL, face_id);
15231 prepare_desired_row (it.glyph_row);
15233 it.glyph_row->mode_line_p = 1;
15235 if (! mode_line_inverse_video)
15236 /* Force the mode-line to be displayed in the default face. */
15237 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
15239 /* Temporarily make frame's keyboard the current kboard so that
15240 kboard-local variables in the mode_line_format will get the right
15241 values. */
15242 push_frame_kboard (it.f);
15243 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
15244 pop_frame_kboard ();
15246 /* Fill up with spaces. */
15247 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
15249 compute_line_metrics (&it);
15250 it.glyph_row->full_width_p = 1;
15251 it.glyph_row->continued_p = 0;
15252 it.glyph_row->truncated_on_left_p = 0;
15253 it.glyph_row->truncated_on_right_p = 0;
15255 /* Make a 3D mode-line have a shadow at its right end. */
15256 face = FACE_FROM_ID (it.f, face_id);
15257 extend_face_to_end_of_line (&it);
15258 if (face->box != FACE_NO_BOX)
15260 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
15261 + it.glyph_row->used[TEXT_AREA] - 1);
15262 last->right_box_line_p = 1;
15265 return it.glyph_row->height;
15268 /* Alist that caches the results of :propertize.
15269 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
15270 Lisp_Object mode_line_proptrans_alist;
15272 /* List of strings making up the mode-line. */
15273 Lisp_Object mode_line_string_list;
15275 /* Base face property when building propertized mode line string. */
15276 static Lisp_Object mode_line_string_face;
15277 static Lisp_Object mode_line_string_face_prop;
15280 /* Contribute ELT to the mode line for window IT->w. How it
15281 translates into text depends on its data type.
15283 IT describes the display environment in which we display, as usual.
15285 DEPTH is the depth in recursion. It is used to prevent
15286 infinite recursion here.
15288 FIELD_WIDTH is the number of characters the display of ELT should
15289 occupy in the mode line, and PRECISION is the maximum number of
15290 characters to display from ELT's representation. See
15291 display_string for details.
15293 Returns the hpos of the end of the text generated by ELT.
15295 PROPS is a property list to add to any string we encounter.
15297 If RISKY is nonzero, remove (disregard) any properties in any string
15298 we encounter, and ignore :eval and :propertize.
15300 If the global variable `frame_title_ptr' is non-NULL, then the output
15301 is passed to `store_frame_title' instead of `display_string'. */
15303 static int
15304 display_mode_element (it, depth, field_width, precision, elt, props, risky)
15305 struct it *it;
15306 int depth;
15307 int field_width, precision;
15308 Lisp_Object elt, props;
15309 int risky;
15311 int n = 0, field, prec;
15312 int literal = 0;
15314 tail_recurse:
15315 if (depth > 100)
15316 elt = build_string ("*too-deep*");
15318 depth++;
15320 switch (SWITCH_ENUM_CAST (XTYPE (elt)))
15322 case Lisp_String:
15324 /* A string: output it and check for %-constructs within it. */
15325 unsigned char c;
15326 const unsigned char *this, *lisp_string;
15328 if (!NILP (props) || risky)
15330 Lisp_Object oprops, aelt;
15331 oprops = Ftext_properties_at (make_number (0), elt);
15333 if (NILP (Fequal (props, oprops)) || risky)
15335 /* If the starting string has properties,
15336 merge the specified ones onto the existing ones. */
15337 if (! NILP (oprops) && !risky)
15339 Lisp_Object tem;
15341 oprops = Fcopy_sequence (oprops);
15342 tem = props;
15343 while (CONSP (tem))
15345 oprops = Fplist_put (oprops, XCAR (tem),
15346 XCAR (XCDR (tem)));
15347 tem = XCDR (XCDR (tem));
15349 props = oprops;
15352 aelt = Fassoc (elt, mode_line_proptrans_alist);
15353 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
15355 mode_line_proptrans_alist
15356 = Fcons (aelt, Fdelq (aelt, mode_line_proptrans_alist));
15357 elt = XCAR (aelt);
15359 else
15361 Lisp_Object tem;
15363 elt = Fcopy_sequence (elt);
15364 Fset_text_properties (make_number (0), Flength (elt),
15365 props, elt);
15366 /* Add this item to mode_line_proptrans_alist. */
15367 mode_line_proptrans_alist
15368 = Fcons (Fcons (elt, props),
15369 mode_line_proptrans_alist);
15370 /* Truncate mode_line_proptrans_alist
15371 to at most 50 elements. */
15372 tem = Fnthcdr (make_number (50),
15373 mode_line_proptrans_alist);
15374 if (! NILP (tem))
15375 XSETCDR (tem, Qnil);
15380 this = SDATA (elt);
15381 lisp_string = this;
15383 if (literal)
15385 prec = precision - n;
15386 if (frame_title_ptr)
15387 n += store_frame_title (SDATA (elt), -1, prec);
15388 else if (!NILP (mode_line_string_list))
15389 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
15390 else
15391 n += display_string (NULL, elt, Qnil, 0, 0, it,
15392 0, prec, 0, STRING_MULTIBYTE (elt));
15394 break;
15397 while ((precision <= 0 || n < precision)
15398 && *this
15399 && (frame_title_ptr
15400 || !NILP (mode_line_string_list)
15401 || it->current_x < it->last_visible_x))
15403 const unsigned char *last = this;
15405 /* Advance to end of string or next format specifier. */
15406 while ((c = *this++) != '\0' && c != '%')
15409 if (this - 1 != last)
15411 /* Output to end of string or up to '%'. Field width
15412 is length of string. Don't output more than
15413 PRECISION allows us. */
15414 --this;
15416 prec = chars_in_text (last, this - last);
15417 if (precision > 0 && prec > precision - n)
15418 prec = precision - n;
15420 if (frame_title_ptr)
15421 n += store_frame_title (last, 0, prec);
15422 else if (!NILP (mode_line_string_list))
15424 int bytepos = last - lisp_string;
15425 int charpos = string_byte_to_char (elt, bytepos);
15426 n += store_mode_line_string (NULL,
15427 Fsubstring (elt, make_number (charpos),
15428 make_number (charpos + prec)),
15429 0, 0, 0, Qnil);
15431 else
15433 int bytepos = last - lisp_string;
15434 int charpos = string_byte_to_char (elt, bytepos);
15435 n += display_string (NULL, elt, Qnil, 0, charpos,
15436 it, 0, prec, 0,
15437 STRING_MULTIBYTE (elt));
15440 else /* c == '%' */
15442 const unsigned char *percent_position = this;
15444 /* Get the specified minimum width. Zero means
15445 don't pad. */
15446 field = 0;
15447 while ((c = *this++) >= '0' && c <= '9')
15448 field = field * 10 + c - '0';
15450 /* Don't pad beyond the total padding allowed. */
15451 if (field_width - n > 0 && field > field_width - n)
15452 field = field_width - n;
15454 /* Note that either PRECISION <= 0 or N < PRECISION. */
15455 prec = precision - n;
15457 if (c == 'M')
15458 n += display_mode_element (it, depth, field, prec,
15459 Vglobal_mode_string, props,
15460 risky);
15461 else if (c != 0)
15463 int multibyte;
15464 int bytepos, charpos;
15465 unsigned char *spec;
15467 bytepos = percent_position - lisp_string;
15468 charpos = (STRING_MULTIBYTE (elt)
15469 ? string_byte_to_char (elt, bytepos)
15470 : bytepos);
15472 spec
15473 = decode_mode_spec (it->w, c, field, prec, &multibyte);
15475 if (frame_title_ptr)
15476 n += store_frame_title (spec, field, prec);
15477 else if (!NILP (mode_line_string_list))
15479 int len = strlen (spec);
15480 Lisp_Object tem = make_string (spec, len);
15481 props = Ftext_properties_at (make_number (charpos), elt);
15482 /* Should only keep face property in props */
15483 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
15485 else
15487 int nglyphs_before, nwritten;
15489 nglyphs_before = it->glyph_row->used[TEXT_AREA];
15490 nwritten = display_string (spec, Qnil, elt,
15491 charpos, 0, it,
15492 field, prec, 0,
15493 multibyte);
15495 /* Assign to the glyphs written above the
15496 string where the `%x' came from, position
15497 of the `%'. */
15498 if (nwritten > 0)
15500 struct glyph *glyph
15501 = (it->glyph_row->glyphs[TEXT_AREA]
15502 + nglyphs_before);
15503 int i;
15505 for (i = 0; i < nwritten; ++i)
15507 glyph[i].object = elt;
15508 glyph[i].charpos = charpos;
15511 n += nwritten;
15515 else /* c == 0 */
15516 break;
15520 break;
15522 case Lisp_Symbol:
15523 /* A symbol: process the value of the symbol recursively
15524 as if it appeared here directly. Avoid error if symbol void.
15525 Special case: if value of symbol is a string, output the string
15526 literally. */
15528 register Lisp_Object tem;
15530 /* If the variable is not marked as risky to set
15531 then its contents are risky to use. */
15532 if (NILP (Fget (elt, Qrisky_local_variable)))
15533 risky = 1;
15535 tem = Fboundp (elt);
15536 if (!NILP (tem))
15538 tem = Fsymbol_value (elt);
15539 /* If value is a string, output that string literally:
15540 don't check for % within it. */
15541 if (STRINGP (tem))
15542 literal = 1;
15544 if (!EQ (tem, elt))
15546 /* Give up right away for nil or t. */
15547 elt = tem;
15548 goto tail_recurse;
15552 break;
15554 case Lisp_Cons:
15556 register Lisp_Object car, tem;
15558 /* A cons cell: five distinct cases.
15559 If first element is :eval or :propertize, do something special.
15560 If first element is a string or a cons, process all the elements
15561 and effectively concatenate them.
15562 If first element is a negative number, truncate displaying cdr to
15563 at most that many characters. If positive, pad (with spaces)
15564 to at least that many characters.
15565 If first element is a symbol, process the cadr or caddr recursively
15566 according to whether the symbol's value is non-nil or nil. */
15567 car = XCAR (elt);
15568 if (EQ (car, QCeval))
15570 /* An element of the form (:eval FORM) means evaluate FORM
15571 and use the result as mode line elements. */
15573 if (risky)
15574 break;
15576 if (CONSP (XCDR (elt)))
15578 Lisp_Object spec;
15579 spec = safe_eval (XCAR (XCDR (elt)));
15580 n += display_mode_element (it, depth, field_width - n,
15581 precision - n, spec, props,
15582 risky);
15585 else if (EQ (car, QCpropertize))
15587 /* An element of the form (:propertize ELT PROPS...)
15588 means display ELT but applying properties PROPS. */
15590 if (risky)
15591 break;
15593 if (CONSP (XCDR (elt)))
15594 n += display_mode_element (it, depth, field_width - n,
15595 precision - n, XCAR (XCDR (elt)),
15596 XCDR (XCDR (elt)), risky);
15598 else if (SYMBOLP (car))
15600 tem = Fboundp (car);
15601 elt = XCDR (elt);
15602 if (!CONSP (elt))
15603 goto invalid;
15604 /* elt is now the cdr, and we know it is a cons cell.
15605 Use its car if CAR has a non-nil value. */
15606 if (!NILP (tem))
15608 tem = Fsymbol_value (car);
15609 if (!NILP (tem))
15611 elt = XCAR (elt);
15612 goto tail_recurse;
15615 /* Symbol's value is nil (or symbol is unbound)
15616 Get the cddr of the original list
15617 and if possible find the caddr and use that. */
15618 elt = XCDR (elt);
15619 if (NILP (elt))
15620 break;
15621 else if (!CONSP (elt))
15622 goto invalid;
15623 elt = XCAR (elt);
15624 goto tail_recurse;
15626 else if (INTEGERP (car))
15628 register int lim = XINT (car);
15629 elt = XCDR (elt);
15630 if (lim < 0)
15632 /* Negative int means reduce maximum width. */
15633 if (precision <= 0)
15634 precision = -lim;
15635 else
15636 precision = min (precision, -lim);
15638 else if (lim > 0)
15640 /* Padding specified. Don't let it be more than
15641 current maximum. */
15642 if (precision > 0)
15643 lim = min (precision, lim);
15645 /* If that's more padding than already wanted, queue it.
15646 But don't reduce padding already specified even if
15647 that is beyond the current truncation point. */
15648 field_width = max (lim, field_width);
15650 goto tail_recurse;
15652 else if (STRINGP (car) || CONSP (car))
15654 register int limit = 50;
15655 /* Limit is to protect against circular lists. */
15656 while (CONSP (elt)
15657 && --limit > 0
15658 && (precision <= 0 || n < precision))
15660 n += display_mode_element (it, depth, field_width - n,
15661 precision - n, XCAR (elt),
15662 props, risky);
15663 elt = XCDR (elt);
15667 break;
15669 default:
15670 invalid:
15671 elt = build_string ("*invalid*");
15672 goto tail_recurse;
15675 /* Pad to FIELD_WIDTH. */
15676 if (field_width > 0 && n < field_width)
15678 if (frame_title_ptr)
15679 n += store_frame_title ("", field_width - n, 0);
15680 else if (!NILP (mode_line_string_list))
15681 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
15682 else
15683 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
15684 0, 0, 0);
15687 return n;
15690 /* Store a mode-line string element in mode_line_string_list.
15692 If STRING is non-null, display that C string. Otherwise, the Lisp
15693 string LISP_STRING is displayed.
15695 FIELD_WIDTH is the minimum number of output glyphs to produce.
15696 If STRING has fewer characters than FIELD_WIDTH, pad to the right
15697 with spaces. FIELD_WIDTH <= 0 means don't pad.
15699 PRECISION is the maximum number of characters to output from
15700 STRING. PRECISION <= 0 means don't truncate the string.
15702 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
15703 properties to the string.
15705 PROPS are the properties to add to the string.
15706 The mode_line_string_face face property is always added to the string.
15709 static int
15710 store_mode_line_string (string, lisp_string, copy_string, field_width, precision, props)
15711 char *string;
15712 Lisp_Object lisp_string;
15713 int copy_string;
15714 int field_width;
15715 int precision;
15716 Lisp_Object props;
15718 int len;
15719 int n = 0;
15721 if (string != NULL)
15723 len = strlen (string);
15724 if (precision > 0 && len > precision)
15725 len = precision;
15726 lisp_string = make_string (string, len);
15727 if (NILP (props))
15728 props = mode_line_string_face_prop;
15729 else if (!NILP (mode_line_string_face))
15731 Lisp_Object face = Fplist_get (props, Qface);
15732 props = Fcopy_sequence (props);
15733 if (NILP (face))
15734 face = mode_line_string_face;
15735 else
15736 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
15737 props = Fplist_put (props, Qface, face);
15739 Fadd_text_properties (make_number (0), make_number (len),
15740 props, lisp_string);
15742 else
15744 len = XFASTINT (Flength (lisp_string));
15745 if (precision > 0 && len > precision)
15747 len = precision;
15748 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
15749 precision = -1;
15751 if (!NILP (mode_line_string_face))
15753 Lisp_Object face;
15754 if (NILP (props))
15755 props = Ftext_properties_at (make_number (0), lisp_string);
15756 face = Fplist_get (props, Qface);
15757 if (NILP (face))
15758 face = mode_line_string_face;
15759 else
15760 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
15761 props = Fcons (Qface, Fcons (face, Qnil));
15762 if (copy_string)
15763 lisp_string = Fcopy_sequence (lisp_string);
15765 if (!NILP (props))
15766 Fadd_text_properties (make_number (0), make_number (len),
15767 props, lisp_string);
15770 if (len > 0)
15772 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
15773 n += len;
15776 if (field_width > len)
15778 field_width -= len;
15779 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
15780 if (!NILP (props))
15781 Fadd_text_properties (make_number (0), make_number (field_width),
15782 props, lisp_string);
15783 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
15784 n += field_width;
15787 return n;
15791 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
15792 0, 3, 0,
15793 doc: /* Return the mode-line of selected window as a string.
15794 First optional arg FORMAT specifies a different format string (see
15795 `mode-line-format' for details) to use. If FORMAT is t, return
15796 the buffer's header-line. Second optional arg WINDOW specifies a
15797 different window to use as the context for the formatting.
15798 If third optional arg NO-PROPS is non-nil, string is not propertized. */)
15799 (format, window, no_props)
15800 Lisp_Object format, window, no_props;
15802 struct it it;
15803 int len;
15804 struct window *w;
15805 struct buffer *old_buffer = NULL;
15806 enum face_id face_id = DEFAULT_FACE_ID;
15808 if (NILP (window))
15809 window = selected_window;
15810 CHECK_WINDOW (window);
15811 w = XWINDOW (window);
15812 CHECK_BUFFER (w->buffer);
15814 if (XBUFFER (w->buffer) != current_buffer)
15816 old_buffer = current_buffer;
15817 set_buffer_internal_1 (XBUFFER (w->buffer));
15820 if (NILP (format) || EQ (format, Qt))
15822 face_id = (NILP (format)
15823 ? CURRENT_MODE_LINE_FACE_ID (w)
15824 : HEADER_LINE_FACE_ID);
15825 format = (NILP (format)
15826 ? current_buffer->mode_line_format
15827 : current_buffer->header_line_format);
15830 init_iterator (&it, w, -1, -1, NULL, face_id);
15832 if (NILP (no_props))
15834 mode_line_string_face
15835 = (face_id == MODE_LINE_FACE_ID ? Qmode_line
15836 : face_id == MODE_LINE_INACTIVE_FACE_ID ? Qmode_line_inactive
15837 : face_id == HEADER_LINE_FACE_ID ? Qheader_line : Qnil);
15839 mode_line_string_face_prop
15840 = (NILP (mode_line_string_face) ? Qnil
15841 : Fcons (Qface, Fcons (mode_line_string_face, Qnil)));
15843 /* We need a dummy last element in mode_line_string_list to
15844 indicate we are building the propertized mode-line string.
15845 Using mode_line_string_face_prop here GC protects it. */
15846 mode_line_string_list
15847 = Fcons (mode_line_string_face_prop, Qnil);
15848 frame_title_ptr = NULL;
15850 else
15852 mode_line_string_face_prop = Qnil;
15853 mode_line_string_list = Qnil;
15854 frame_title_ptr = frame_title_buf;
15857 push_frame_kboard (it.f);
15858 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
15859 pop_frame_kboard ();
15861 if (old_buffer)
15862 set_buffer_internal_1 (old_buffer);
15864 if (NILP (no_props))
15866 Lisp_Object str;
15867 mode_line_string_list = Fnreverse (mode_line_string_list);
15868 str = Fmapconcat (intern ("identity"), XCDR (mode_line_string_list),
15869 make_string ("", 0));
15870 mode_line_string_face_prop = Qnil;
15871 mode_line_string_list = Qnil;
15872 return str;
15875 len = frame_title_ptr - frame_title_buf;
15876 if (len > 0 && frame_title_ptr[-1] == '-')
15878 /* Mode lines typically ends with numerous dashes; reduce to two dashes. */
15879 while (frame_title_ptr > frame_title_buf && *--frame_title_ptr == '-')
15881 frame_title_ptr += 3; /* restore last non-dash + two dashes */
15882 if (len > frame_title_ptr - frame_title_buf)
15883 len = frame_title_ptr - frame_title_buf;
15886 frame_title_ptr = NULL;
15887 return make_string (frame_title_buf, len);
15890 /* Write a null-terminated, right justified decimal representation of
15891 the positive integer D to BUF using a minimal field width WIDTH. */
15893 static void
15894 pint2str (buf, width, d)
15895 register char *buf;
15896 register int width;
15897 register int d;
15899 register char *p = buf;
15901 if (d <= 0)
15902 *p++ = '0';
15903 else
15905 while (d > 0)
15907 *p++ = d % 10 + '0';
15908 d /= 10;
15912 for (width -= (int) (p - buf); width > 0; --width)
15913 *p++ = ' ';
15914 *p-- = '\0';
15915 while (p > buf)
15917 d = *buf;
15918 *buf++ = *p;
15919 *p-- = d;
15923 /* Write a null-terminated, right justified decimal and "human
15924 readable" representation of the nonnegative integer D to BUF using
15925 a minimal field width WIDTH. D should be smaller than 999.5e24. */
15927 static const char power_letter[] =
15929 0, /* not used */
15930 'k', /* kilo */
15931 'M', /* mega */
15932 'G', /* giga */
15933 'T', /* tera */
15934 'P', /* peta */
15935 'E', /* exa */
15936 'Z', /* zetta */
15937 'Y' /* yotta */
15940 static void
15941 pint2hrstr (buf, width, d)
15942 char *buf;
15943 int width;
15944 int d;
15946 /* We aim to represent the nonnegative integer D as
15947 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
15948 int quotient = d;
15949 int remainder = 0;
15950 /* -1 means: do not use TENTHS. */
15951 int tenths = -1;
15952 int exponent = 0;
15954 /* Length of QUOTIENT.TENTHS as a string. */
15955 int length;
15957 char * psuffix;
15958 char * p;
15960 if (1000 <= quotient)
15962 /* Scale to the appropriate EXPONENT. */
15965 remainder = quotient % 1000;
15966 quotient /= 1000;
15967 exponent++;
15969 while (1000 <= quotient);
15971 /* Round to nearest and decide whether to use TENTHS or not. */
15972 if (quotient <= 9)
15974 tenths = remainder / 100;
15975 if (50 <= remainder % 100)
15976 if (tenths < 9)
15977 tenths++;
15978 else
15980 quotient++;
15981 if (quotient == 10)
15982 tenths = -1;
15983 else
15984 tenths = 0;
15987 else
15988 if (500 <= remainder)
15989 if (quotient < 999)
15990 quotient++;
15991 else
15993 quotient = 1;
15994 exponent++;
15995 tenths = 0;
15999 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
16000 if (tenths == -1 && quotient <= 99)
16001 if (quotient <= 9)
16002 length = 1;
16003 else
16004 length = 2;
16005 else
16006 length = 3;
16007 p = psuffix = buf + max (width, length);
16009 /* Print EXPONENT. */
16010 if (exponent)
16011 *psuffix++ = power_letter[exponent];
16012 *psuffix = '\0';
16014 /* Print TENTHS. */
16015 if (tenths >= 0)
16017 *--p = '0' + tenths;
16018 *--p = '.';
16021 /* Print QUOTIENT. */
16024 int digit = quotient % 10;
16025 *--p = '0' + digit;
16027 while ((quotient /= 10) != 0);
16029 /* Print leading spaces. */
16030 while (buf < p)
16031 *--p = ' ';
16034 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
16035 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
16036 type of CODING_SYSTEM. Return updated pointer into BUF. */
16038 static unsigned char invalid_eol_type[] = "(*invalid*)";
16040 static char *
16041 decode_mode_spec_coding (coding_system, buf, eol_flag)
16042 Lisp_Object coding_system;
16043 register char *buf;
16044 int eol_flag;
16046 Lisp_Object val;
16047 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
16048 const unsigned char *eol_str;
16049 int eol_str_len;
16050 /* The EOL conversion we are using. */
16051 Lisp_Object eoltype;
16053 val = Fget (coding_system, Qcoding_system);
16054 eoltype = Qnil;
16056 if (!VECTORP (val)) /* Not yet decided. */
16058 if (multibyte)
16059 *buf++ = '-';
16060 if (eol_flag)
16061 eoltype = eol_mnemonic_undecided;
16062 /* Don't mention EOL conversion if it isn't decided. */
16064 else
16066 Lisp_Object eolvalue;
16068 eolvalue = Fget (coding_system, Qeol_type);
16070 if (multibyte)
16071 *buf++ = XFASTINT (AREF (val, 1));
16073 if (eol_flag)
16075 /* The EOL conversion that is normal on this system. */
16077 if (NILP (eolvalue)) /* Not yet decided. */
16078 eoltype = eol_mnemonic_undecided;
16079 else if (VECTORP (eolvalue)) /* Not yet decided. */
16080 eoltype = eol_mnemonic_undecided;
16081 else /* INTEGERP (eolvalue) -- 0:LF, 1:CRLF, 2:CR */
16082 eoltype = (XFASTINT (eolvalue) == 0
16083 ? eol_mnemonic_unix
16084 : (XFASTINT (eolvalue) == 1
16085 ? eol_mnemonic_dos : eol_mnemonic_mac));
16089 if (eol_flag)
16091 /* Mention the EOL conversion if it is not the usual one. */
16092 if (STRINGP (eoltype))
16094 eol_str = SDATA (eoltype);
16095 eol_str_len = SBYTES (eoltype);
16097 else if (INTEGERP (eoltype)
16098 && CHAR_VALID_P (XINT (eoltype), 0))
16100 unsigned char *tmp = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
16101 eol_str_len = CHAR_STRING (XINT (eoltype), tmp);
16102 eol_str = tmp;
16104 else
16106 eol_str = invalid_eol_type;
16107 eol_str_len = sizeof (invalid_eol_type) - 1;
16109 bcopy (eol_str, buf, eol_str_len);
16110 buf += eol_str_len;
16113 return buf;
16116 /* Return a string for the output of a mode line %-spec for window W,
16117 generated by character C. PRECISION >= 0 means don't return a
16118 string longer than that value. FIELD_WIDTH > 0 means pad the
16119 string returned with spaces to that value. Return 1 in *MULTIBYTE
16120 if the result is multibyte text. */
16122 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
16124 static char *
16125 decode_mode_spec (w, c, field_width, precision, multibyte)
16126 struct window *w;
16127 register int c;
16128 int field_width, precision;
16129 int *multibyte;
16131 Lisp_Object obj;
16132 struct frame *f = XFRAME (WINDOW_FRAME (w));
16133 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
16134 struct buffer *b = XBUFFER (w->buffer);
16136 obj = Qnil;
16137 *multibyte = 0;
16139 switch (c)
16141 case '*':
16142 if (!NILP (b->read_only))
16143 return "%";
16144 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
16145 return "*";
16146 return "-";
16148 case '+':
16149 /* This differs from %* only for a modified read-only buffer. */
16150 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
16151 return "*";
16152 if (!NILP (b->read_only))
16153 return "%";
16154 return "-";
16156 case '&':
16157 /* This differs from %* in ignoring read-only-ness. */
16158 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
16159 return "*";
16160 return "-";
16162 case '%':
16163 return "%";
16165 case '[':
16167 int i;
16168 char *p;
16170 if (command_loop_level > 5)
16171 return "[[[... ";
16172 p = decode_mode_spec_buf;
16173 for (i = 0; i < command_loop_level; i++)
16174 *p++ = '[';
16175 *p = 0;
16176 return decode_mode_spec_buf;
16179 case ']':
16181 int i;
16182 char *p;
16184 if (command_loop_level > 5)
16185 return " ...]]]";
16186 p = decode_mode_spec_buf;
16187 for (i = 0; i < command_loop_level; i++)
16188 *p++ = ']';
16189 *p = 0;
16190 return decode_mode_spec_buf;
16193 case '-':
16195 register int i;
16197 /* Let lots_of_dashes be a string of infinite length. */
16198 if (!NILP (mode_line_string_list))
16199 return "--";
16200 if (field_width <= 0
16201 || field_width > sizeof (lots_of_dashes))
16203 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
16204 decode_mode_spec_buf[i] = '-';
16205 decode_mode_spec_buf[i] = '\0';
16206 return decode_mode_spec_buf;
16208 else
16209 return lots_of_dashes;
16212 case 'b':
16213 obj = b->name;
16214 break;
16216 case 'c':
16218 int col = (int) current_column (); /* iftc */
16219 w->column_number_displayed = make_number (col);
16220 pint2str (decode_mode_spec_buf, field_width, col);
16221 return decode_mode_spec_buf;
16224 case 'F':
16225 /* %F displays the frame name. */
16226 if (!NILP (f->title))
16227 return (char *) SDATA (f->title);
16228 if (f->explicit_name || ! FRAME_WINDOW_P (f))
16229 return (char *) SDATA (f->name);
16230 return "Emacs";
16232 case 'f':
16233 obj = b->filename;
16234 break;
16236 case 'i':
16238 int size = ZV - BEGV;
16239 pint2str (decode_mode_spec_buf, field_width, size);
16240 return decode_mode_spec_buf;
16243 case 'I':
16245 int size = ZV - BEGV;
16246 pint2hrstr (decode_mode_spec_buf, field_width, size);
16247 return decode_mode_spec_buf;
16250 case 'l':
16252 int startpos = XMARKER (w->start)->charpos;
16253 int startpos_byte = marker_byte_position (w->start);
16254 int line, linepos, linepos_byte, topline;
16255 int nlines, junk;
16256 int height = WINDOW_TOTAL_LINES (w);
16258 /* If we decided that this buffer isn't suitable for line numbers,
16259 don't forget that too fast. */
16260 if (EQ (w->base_line_pos, w->buffer))
16261 goto no_value;
16262 /* But do forget it, if the window shows a different buffer now. */
16263 else if (BUFFERP (w->base_line_pos))
16264 w->base_line_pos = Qnil;
16266 /* If the buffer is very big, don't waste time. */
16267 if (INTEGERP (Vline_number_display_limit)
16268 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
16270 w->base_line_pos = Qnil;
16271 w->base_line_number = Qnil;
16272 goto no_value;
16275 if (!NILP (w->base_line_number)
16276 && !NILP (w->base_line_pos)
16277 && XFASTINT (w->base_line_pos) <= startpos)
16279 line = XFASTINT (w->base_line_number);
16280 linepos = XFASTINT (w->base_line_pos);
16281 linepos_byte = buf_charpos_to_bytepos (b, linepos);
16283 else
16285 line = 1;
16286 linepos = BUF_BEGV (b);
16287 linepos_byte = BUF_BEGV_BYTE (b);
16290 /* Count lines from base line to window start position. */
16291 nlines = display_count_lines (linepos, linepos_byte,
16292 startpos_byte,
16293 startpos, &junk);
16295 topline = nlines + line;
16297 /* Determine a new base line, if the old one is too close
16298 or too far away, or if we did not have one.
16299 "Too close" means it's plausible a scroll-down would
16300 go back past it. */
16301 if (startpos == BUF_BEGV (b))
16303 w->base_line_number = make_number (topline);
16304 w->base_line_pos = make_number (BUF_BEGV (b));
16306 else if (nlines < height + 25 || nlines > height * 3 + 50
16307 || linepos == BUF_BEGV (b))
16309 int limit = BUF_BEGV (b);
16310 int limit_byte = BUF_BEGV_BYTE (b);
16311 int position;
16312 int distance = (height * 2 + 30) * line_number_display_limit_width;
16314 if (startpos - distance > limit)
16316 limit = startpos - distance;
16317 limit_byte = CHAR_TO_BYTE (limit);
16320 nlines = display_count_lines (startpos, startpos_byte,
16321 limit_byte,
16322 - (height * 2 + 30),
16323 &position);
16324 /* If we couldn't find the lines we wanted within
16325 line_number_display_limit_width chars per line,
16326 give up on line numbers for this window. */
16327 if (position == limit_byte && limit == startpos - distance)
16329 w->base_line_pos = w->buffer;
16330 w->base_line_number = Qnil;
16331 goto no_value;
16334 w->base_line_number = make_number (topline - nlines);
16335 w->base_line_pos = make_number (BYTE_TO_CHAR (position));
16338 /* Now count lines from the start pos to point. */
16339 nlines = display_count_lines (startpos, startpos_byte,
16340 PT_BYTE, PT, &junk);
16342 /* Record that we did display the line number. */
16343 line_number_displayed = 1;
16345 /* Make the string to show. */
16346 pint2str (decode_mode_spec_buf, field_width, topline + nlines);
16347 return decode_mode_spec_buf;
16348 no_value:
16350 char* p = decode_mode_spec_buf;
16351 int pad = field_width - 2;
16352 while (pad-- > 0)
16353 *p++ = ' ';
16354 *p++ = '?';
16355 *p++ = '?';
16356 *p = '\0';
16357 return decode_mode_spec_buf;
16360 break;
16362 case 'm':
16363 obj = b->mode_name;
16364 break;
16366 case 'n':
16367 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
16368 return " Narrow";
16369 break;
16371 case 'p':
16373 int pos = marker_position (w->start);
16374 int total = BUF_ZV (b) - BUF_BEGV (b);
16376 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
16378 if (pos <= BUF_BEGV (b))
16379 return "All";
16380 else
16381 return "Bottom";
16383 else if (pos <= BUF_BEGV (b))
16384 return "Top";
16385 else
16387 if (total > 1000000)
16388 /* Do it differently for a large value, to avoid overflow. */
16389 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
16390 else
16391 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
16392 /* We can't normally display a 3-digit number,
16393 so get us a 2-digit number that is close. */
16394 if (total == 100)
16395 total = 99;
16396 sprintf (decode_mode_spec_buf, "%2d%%", total);
16397 return decode_mode_spec_buf;
16401 /* Display percentage of size above the bottom of the screen. */
16402 case 'P':
16404 int toppos = marker_position (w->start);
16405 int botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
16406 int total = BUF_ZV (b) - BUF_BEGV (b);
16408 if (botpos >= BUF_ZV (b))
16410 if (toppos <= BUF_BEGV (b))
16411 return "All";
16412 else
16413 return "Bottom";
16415 else
16417 if (total > 1000000)
16418 /* Do it differently for a large value, to avoid overflow. */
16419 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
16420 else
16421 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
16422 /* We can't normally display a 3-digit number,
16423 so get us a 2-digit number that is close. */
16424 if (total == 100)
16425 total = 99;
16426 if (toppos <= BUF_BEGV (b))
16427 sprintf (decode_mode_spec_buf, "Top%2d%%", total);
16428 else
16429 sprintf (decode_mode_spec_buf, "%2d%%", total);
16430 return decode_mode_spec_buf;
16434 case 's':
16435 /* status of process */
16436 obj = Fget_buffer_process (w->buffer);
16437 if (NILP (obj))
16438 return "no process";
16439 #ifdef subprocesses
16440 obj = Fsymbol_name (Fprocess_status (obj));
16441 #endif
16442 break;
16444 case 't': /* indicate TEXT or BINARY */
16445 #ifdef MODE_LINE_BINARY_TEXT
16446 return MODE_LINE_BINARY_TEXT (b);
16447 #else
16448 return "T";
16449 #endif
16451 case 'z':
16452 /* coding-system (not including end-of-line format) */
16453 case 'Z':
16454 /* coding-system (including end-of-line type) */
16456 int eol_flag = (c == 'Z');
16457 char *p = decode_mode_spec_buf;
16459 if (! FRAME_WINDOW_P (f))
16461 /* No need to mention EOL here--the terminal never needs
16462 to do EOL conversion. */
16463 p = decode_mode_spec_coding (keyboard_coding.symbol, p, 0);
16464 p = decode_mode_spec_coding (terminal_coding.symbol, p, 0);
16466 p = decode_mode_spec_coding (b->buffer_file_coding_system,
16467 p, eol_flag);
16469 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
16470 #ifdef subprocesses
16471 obj = Fget_buffer_process (Fcurrent_buffer ());
16472 if (PROCESSP (obj))
16474 p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system,
16475 p, eol_flag);
16476 p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system,
16477 p, eol_flag);
16479 #endif /* subprocesses */
16480 #endif /* 0 */
16481 *p = 0;
16482 return decode_mode_spec_buf;
16486 if (STRINGP (obj))
16488 *multibyte = STRING_MULTIBYTE (obj);
16489 return (char *) SDATA (obj);
16491 else
16492 return "";
16496 /* Count up to COUNT lines starting from START / START_BYTE.
16497 But don't go beyond LIMIT_BYTE.
16498 Return the number of lines thus found (always nonnegative).
16500 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
16502 static int
16503 display_count_lines (start, start_byte, limit_byte, count, byte_pos_ptr)
16504 int start, start_byte, limit_byte, count;
16505 int *byte_pos_ptr;
16507 register unsigned char *cursor;
16508 unsigned char *base;
16510 register int ceiling;
16511 register unsigned char *ceiling_addr;
16512 int orig_count = count;
16514 /* If we are not in selective display mode,
16515 check only for newlines. */
16516 int selective_display = (!NILP (current_buffer->selective_display)
16517 && !INTEGERP (current_buffer->selective_display));
16519 if (count > 0)
16521 while (start_byte < limit_byte)
16523 ceiling = BUFFER_CEILING_OF (start_byte);
16524 ceiling = min (limit_byte - 1, ceiling);
16525 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
16526 base = (cursor = BYTE_POS_ADDR (start_byte));
16527 while (1)
16529 if (selective_display)
16530 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
16532 else
16533 while (*cursor != '\n' && ++cursor != ceiling_addr)
16536 if (cursor != ceiling_addr)
16538 if (--count == 0)
16540 start_byte += cursor - base + 1;
16541 *byte_pos_ptr = start_byte;
16542 return orig_count;
16544 else
16545 if (++cursor == ceiling_addr)
16546 break;
16548 else
16549 break;
16551 start_byte += cursor - base;
16554 else
16556 while (start_byte > limit_byte)
16558 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
16559 ceiling = max (limit_byte, ceiling);
16560 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1;
16561 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
16562 while (1)
16564 if (selective_display)
16565 while (--cursor != ceiling_addr
16566 && *cursor != '\n' && *cursor != 015)
16568 else
16569 while (--cursor != ceiling_addr && *cursor != '\n')
16572 if (cursor != ceiling_addr)
16574 if (++count == 0)
16576 start_byte += cursor - base + 1;
16577 *byte_pos_ptr = start_byte;
16578 /* When scanning backwards, we should
16579 not count the newline posterior to which we stop. */
16580 return - orig_count - 1;
16583 else
16584 break;
16586 /* Here we add 1 to compensate for the last decrement
16587 of CURSOR, which took it past the valid range. */
16588 start_byte += cursor - base + 1;
16592 *byte_pos_ptr = limit_byte;
16594 if (count < 0)
16595 return - orig_count + count;
16596 return orig_count - count;
16602 /***********************************************************************
16603 Displaying strings
16604 ***********************************************************************/
16606 /* Display a NUL-terminated string, starting with index START.
16608 If STRING is non-null, display that C string. Otherwise, the Lisp
16609 string LISP_STRING is displayed.
16611 If FACE_STRING is not nil, FACE_STRING_POS is a position in
16612 FACE_STRING. Display STRING or LISP_STRING with the face at
16613 FACE_STRING_POS in FACE_STRING:
16615 Display the string in the environment given by IT, but use the
16616 standard display table, temporarily.
16618 FIELD_WIDTH is the minimum number of output glyphs to produce.
16619 If STRING has fewer characters than FIELD_WIDTH, pad to the right
16620 with spaces. If STRING has more characters, more than FIELD_WIDTH
16621 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
16623 PRECISION is the maximum number of characters to output from
16624 STRING. PRECISION < 0 means don't truncate the string.
16626 This is roughly equivalent to printf format specifiers:
16628 FIELD_WIDTH PRECISION PRINTF
16629 ----------------------------------------
16630 -1 -1 %s
16631 -1 10 %.10s
16632 10 -1 %10s
16633 20 10 %20.10s
16635 MULTIBYTE zero means do not display multibyte chars, > 0 means do
16636 display them, and < 0 means obey the current buffer's value of
16637 enable_multibyte_characters.
16639 Value is the number of glyphs produced. */
16641 static int
16642 display_string (string, lisp_string, face_string, face_string_pos,
16643 start, it, field_width, precision, max_x, multibyte)
16644 unsigned char *string;
16645 Lisp_Object lisp_string;
16646 Lisp_Object face_string;
16647 int face_string_pos;
16648 int start;
16649 struct it *it;
16650 int field_width, precision, max_x;
16651 int multibyte;
16653 int hpos_at_start = it->hpos;
16654 int saved_face_id = it->face_id;
16655 struct glyph_row *row = it->glyph_row;
16657 /* Initialize the iterator IT for iteration over STRING beginning
16658 with index START. */
16659 reseat_to_string (it, string, lisp_string, start,
16660 precision, field_width, multibyte);
16662 /* If displaying STRING, set up the face of the iterator
16663 from LISP_STRING, if that's given. */
16664 if (STRINGP (face_string))
16666 int endptr;
16667 struct face *face;
16669 it->face_id
16670 = face_at_string_position (it->w, face_string, face_string_pos,
16671 0, it->region_beg_charpos,
16672 it->region_end_charpos,
16673 &endptr, it->base_face_id, 0);
16674 face = FACE_FROM_ID (it->f, it->face_id);
16675 it->face_box_p = face->box != FACE_NO_BOX;
16678 /* Set max_x to the maximum allowed X position. Don't let it go
16679 beyond the right edge of the window. */
16680 if (max_x <= 0)
16681 max_x = it->last_visible_x;
16682 else
16683 max_x = min (max_x, it->last_visible_x);
16685 /* Skip over display elements that are not visible. because IT->w is
16686 hscrolled. */
16687 if (it->current_x < it->first_visible_x)
16688 move_it_in_display_line_to (it, 100000, it->first_visible_x,
16689 MOVE_TO_POS | MOVE_TO_X);
16691 row->ascent = it->max_ascent;
16692 row->height = it->max_ascent + it->max_descent;
16693 row->phys_ascent = it->max_phys_ascent;
16694 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
16696 /* This condition is for the case that we are called with current_x
16697 past last_visible_x. */
16698 while (it->current_x < max_x)
16700 int x_before, x, n_glyphs_before, i, nglyphs;
16702 /* Get the next display element. */
16703 if (!get_next_display_element (it))
16704 break;
16706 /* Produce glyphs. */
16707 x_before = it->current_x;
16708 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
16709 PRODUCE_GLYPHS (it);
16711 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
16712 i = 0;
16713 x = x_before;
16714 while (i < nglyphs)
16716 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
16718 if (!it->truncate_lines_p
16719 && x + glyph->pixel_width > max_x)
16721 /* End of continued line or max_x reached. */
16722 if (CHAR_GLYPH_PADDING_P (*glyph))
16724 /* A wide character is unbreakable. */
16725 it->glyph_row->used[TEXT_AREA] = n_glyphs_before;
16726 it->current_x = x_before;
16728 else
16730 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
16731 it->current_x = x;
16733 break;
16735 else if (x + glyph->pixel_width > it->first_visible_x)
16737 /* Glyph is at least partially visible. */
16738 ++it->hpos;
16739 if (x < it->first_visible_x)
16740 it->glyph_row->x = x - it->first_visible_x;
16742 else
16744 /* Glyph is off the left margin of the display area.
16745 Should not happen. */
16746 abort ();
16749 row->ascent = max (row->ascent, it->max_ascent);
16750 row->height = max (row->height, it->max_ascent + it->max_descent);
16751 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
16752 row->phys_height = max (row->phys_height,
16753 it->max_phys_ascent + it->max_phys_descent);
16754 x += glyph->pixel_width;
16755 ++i;
16758 /* Stop if max_x reached. */
16759 if (i < nglyphs)
16760 break;
16762 /* Stop at line ends. */
16763 if (ITERATOR_AT_END_OF_LINE_P (it))
16765 it->continuation_lines_width = 0;
16766 break;
16769 set_iterator_to_next (it, 1);
16771 /* Stop if truncating at the right edge. */
16772 if (it->truncate_lines_p
16773 && it->current_x >= it->last_visible_x)
16775 /* Add truncation mark, but don't do it if the line is
16776 truncated at a padding space. */
16777 if (IT_CHARPOS (*it) < it->string_nchars)
16779 if (!FRAME_WINDOW_P (it->f))
16781 int i, n;
16783 if (it->current_x > it->last_visible_x)
16785 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
16786 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
16787 break;
16788 for (n = row->used[TEXT_AREA]; i < n; ++i)
16790 row->used[TEXT_AREA] = i;
16791 produce_special_glyphs (it, IT_TRUNCATION);
16794 produce_special_glyphs (it, IT_TRUNCATION);
16796 it->glyph_row->truncated_on_right_p = 1;
16798 break;
16802 /* Maybe insert a truncation at the left. */
16803 if (it->first_visible_x
16804 && IT_CHARPOS (*it) > 0)
16806 if (!FRAME_WINDOW_P (it->f))
16807 insert_left_trunc_glyphs (it);
16808 it->glyph_row->truncated_on_left_p = 1;
16811 it->face_id = saved_face_id;
16813 /* Value is number of columns displayed. */
16814 return it->hpos - hpos_at_start;
16819 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
16820 appears as an element of LIST or as the car of an element of LIST.
16821 If PROPVAL is a list, compare each element against LIST in that
16822 way, and return 1/2 if any element of PROPVAL is found in LIST.
16823 Otherwise return 0. This function cannot quit.
16824 The return value is 2 if the text is invisible but with an ellipsis
16825 and 1 if it's invisible and without an ellipsis. */
16828 invisible_p (propval, list)
16829 register Lisp_Object propval;
16830 Lisp_Object list;
16832 register Lisp_Object tail, proptail;
16834 for (tail = list; CONSP (tail); tail = XCDR (tail))
16836 register Lisp_Object tem;
16837 tem = XCAR (tail);
16838 if (EQ (propval, tem))
16839 return 1;
16840 if (CONSP (tem) && EQ (propval, XCAR (tem)))
16841 return NILP (XCDR (tem)) ? 1 : 2;
16844 if (CONSP (propval))
16846 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
16848 Lisp_Object propelt;
16849 propelt = XCAR (proptail);
16850 for (tail = list; CONSP (tail); tail = XCDR (tail))
16852 register Lisp_Object tem;
16853 tem = XCAR (tail);
16854 if (EQ (propelt, tem))
16855 return 1;
16856 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
16857 return NILP (XCDR (tem)) ? 1 : 2;
16862 return 0;
16865 /* Calculate a width or height in pixels from a specification using
16866 the following elements:
16868 SPEC ::=
16869 NUM - a (fractional) multiple of the default font width/height
16870 (NUM) - specifies exactly NUM pixels
16871 UNIT - a fixed number of pixels, see below.
16872 ELEMENT - size of a display element in pixels, see below.
16873 (NUM . SPEC) - equals NUM * SPEC
16874 (+ SPEC SPEC ...) - add pixel values
16875 (- SPEC SPEC ...) - subtract pixel values
16876 (- SPEC) - negate pixel value
16878 NUM ::=
16879 INT or FLOAT - a number constant
16880 SYMBOL - use symbol's (buffer local) variable binding.
16882 UNIT ::=
16883 in - pixels per inch *)
16884 mm - pixels per 1/1000 meter *)
16885 cm - pixels per 1/100 meter *)
16886 width - width of current font in pixels.
16887 height - height of current font in pixels.
16889 *) using the ratio(s) defined in display-pixels-per-inch.
16891 ELEMENT ::=
16893 left-fringe - left fringe width in pixels
16894 right-fringe - right fringe width in pixels
16896 left-margin - left margin width in pixels
16897 right-margin - right margin width in pixels
16899 scroll-bar - scroll-bar area width in pixels
16901 Examples:
16903 Pixels corresponding to 5 inches:
16904 (5 . in)
16906 Total width of non-text areas on left side of window (if scroll-bar is on left):
16907 '(space :width (+ left-fringe left-margin scroll-bar))
16909 Align to first text column (in header line):
16910 '(space :align-to 0)
16912 Align to middle of text area minus half the width of variable `my-image'
16913 containing a loaded image:
16914 '(space :align-to (0.5 . (- text my-image)))
16916 Width of left margin minus width of 1 character in the default font:
16917 '(space :width (- left-margin 1))
16919 Width of left margin minus width of 2 characters in the current font:
16920 '(space :width (- left-margin (2 . width)))
16922 Center 1 character over left-margin (in header line):
16923 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
16925 Different ways to express width of left fringe plus left margin minus one pixel:
16926 '(space :width (- (+ left-fringe left-margin) (1)))
16927 '(space :width (+ left-fringe left-margin (- (1))))
16928 '(space :width (+ left-fringe left-margin (-1)))
16932 #define NUMVAL(X) \
16933 ((INTEGERP (X) || FLOATP (X)) \
16934 ? XFLOATINT (X) \
16935 : - 1)
16938 calc_pixel_width_or_height (res, it, prop, font, width_p, align_to)
16939 double *res;
16940 struct it *it;
16941 Lisp_Object prop;
16942 void *font;
16943 int width_p, *align_to;
16945 double pixels;
16947 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
16948 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
16950 if (NILP (prop))
16951 return OK_PIXELS (0);
16953 if (SYMBOLP (prop))
16955 if (SCHARS (SYMBOL_NAME (prop)) == 2)
16957 char *unit = SDATA (SYMBOL_NAME (prop));
16959 if (unit[0] == 'i' && unit[1] == 'n')
16960 pixels = 1.0;
16961 else if (unit[0] == 'm' && unit[1] == 'm')
16962 pixels = 25.4;
16963 else if (unit[0] == 'c' && unit[1] == 'm')
16964 pixels = 2.54;
16965 else
16966 pixels = 0;
16967 if (pixels > 0)
16969 double ppi;
16970 if ((ppi = NUMVAL (Vdisplay_pixels_per_inch), ppi > 0)
16971 || (CONSP (Vdisplay_pixels_per_inch)
16972 && (ppi = (width_p
16973 ? NUMVAL (XCAR (Vdisplay_pixels_per_inch))
16974 : NUMVAL (XCDR (Vdisplay_pixels_per_inch))),
16975 ppi > 0)))
16976 return OK_PIXELS (ppi / pixels);
16978 return 0;
16982 #ifdef HAVE_WINDOW_SYSTEM
16983 if (EQ (prop, Qheight))
16984 return OK_PIXELS (font ? FONT_HEIGHT ((XFontStruct *)font) : FRAME_LINE_HEIGHT (it->f));
16985 if (EQ (prop, Qwidth))
16986 return OK_PIXELS (font ? FONT_WIDTH ((XFontStruct *)font) : FRAME_COLUMN_WIDTH (it->f));
16987 #else
16988 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
16989 return OK_PIXELS (1);
16990 #endif
16992 if (EQ (prop, Qtext))
16993 return OK_PIXELS (width_p
16994 ? window_box_width (it->w, TEXT_AREA)
16995 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
16997 if (align_to && *align_to < 0)
16999 *res = 0;
17000 if (EQ (prop, Qleft))
17001 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA));
17002 if (EQ (prop, Qright))
17003 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
17004 if (EQ (prop, Qcenter))
17005 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
17006 + window_box_width (it->w, TEXT_AREA) / 2);
17007 if (EQ (prop, Qleft_fringe))
17008 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
17009 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
17010 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
17011 if (EQ (prop, Qright_fringe))
17012 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
17013 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
17014 : window_box_right_offset (it->w, TEXT_AREA));
17015 if (EQ (prop, Qleft_margin))
17016 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
17017 if (EQ (prop, Qright_margin))
17018 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
17019 if (EQ (prop, Qscroll_bar))
17020 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
17022 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
17023 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
17024 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
17025 : 0)));
17027 else
17029 if (EQ (prop, Qleft_fringe))
17030 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
17031 if (EQ (prop, Qright_fringe))
17032 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
17033 if (EQ (prop, Qleft_margin))
17034 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
17035 if (EQ (prop, Qright_margin))
17036 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
17037 if (EQ (prop, Qscroll_bar))
17038 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
17041 prop = Fbuffer_local_value (prop, it->w->buffer);
17044 if (INTEGERP (prop) || FLOATP (prop))
17046 int base_unit = (width_p
17047 ? FRAME_COLUMN_WIDTH (it->f)
17048 : FRAME_LINE_HEIGHT (it->f));
17049 return OK_PIXELS (XFLOATINT (prop) * base_unit);
17052 if (CONSP (prop))
17054 Lisp_Object car = XCAR (prop);
17055 Lisp_Object cdr = XCDR (prop);
17057 if (SYMBOLP (car))
17059 #ifdef HAVE_WINDOW_SYSTEM
17060 if (valid_image_p (prop))
17062 int id = lookup_image (it->f, prop);
17063 struct image *img = IMAGE_FROM_ID (it->f, id);
17065 return OK_PIXELS (width_p ? img->width : img->height);
17067 #endif
17068 if (EQ (car, Qplus) || EQ (car, Qminus))
17070 int first = 1;
17071 double px;
17073 pixels = 0;
17074 while (CONSP (cdr))
17076 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
17077 font, width_p, align_to))
17078 return 0;
17079 if (first)
17080 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
17081 else
17082 pixels += px;
17083 cdr = XCDR (cdr);
17085 if (EQ (car, Qminus))
17086 pixels = -pixels;
17087 return OK_PIXELS (pixels);
17090 car = Fbuffer_local_value (car, it->w->buffer);
17093 if (INTEGERP (car) || FLOATP (car))
17095 double fact;
17096 pixels = XFLOATINT (car);
17097 if (NILP (cdr))
17098 return OK_PIXELS (pixels);
17099 if (calc_pixel_width_or_height (&fact, it, cdr,
17100 font, width_p, align_to))
17101 return OK_PIXELS (pixels * fact);
17102 return 0;
17105 return 0;
17108 return 0;
17112 /***********************************************************************
17113 Glyph Display
17114 ***********************************************************************/
17116 #ifdef HAVE_WINDOW_SYSTEM
17118 #if GLYPH_DEBUG
17120 void
17121 dump_glyph_string (s)
17122 struct glyph_string *s;
17124 fprintf (stderr, "glyph string\n");
17125 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
17126 s->x, s->y, s->width, s->height);
17127 fprintf (stderr, " ybase = %d\n", s->ybase);
17128 fprintf (stderr, " hl = %d\n", s->hl);
17129 fprintf (stderr, " left overhang = %d, right = %d\n",
17130 s->left_overhang, s->right_overhang);
17131 fprintf (stderr, " nchars = %d\n", s->nchars);
17132 fprintf (stderr, " extends to end of line = %d\n",
17133 s->extends_to_end_of_line_p);
17134 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
17135 fprintf (stderr, " bg width = %d\n", s->background_width);
17138 #endif /* GLYPH_DEBUG */
17140 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
17141 of XChar2b structures for S; it can't be allocated in
17142 init_glyph_string because it must be allocated via `alloca'. W
17143 is the window on which S is drawn. ROW and AREA are the glyph row
17144 and area within the row from which S is constructed. START is the
17145 index of the first glyph structure covered by S. HL is a
17146 face-override for drawing S. */
17148 #ifdef HAVE_NTGUI
17149 #define OPTIONAL_HDC(hdc) hdc,
17150 #define DECLARE_HDC(hdc) HDC hdc;
17151 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
17152 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
17153 #endif
17155 #ifndef OPTIONAL_HDC
17156 #define OPTIONAL_HDC(hdc)
17157 #define DECLARE_HDC(hdc)
17158 #define ALLOCATE_HDC(hdc, f)
17159 #define RELEASE_HDC(hdc, f)
17160 #endif
17162 static void
17163 init_glyph_string (s, OPTIONAL_HDC (hdc) char2b, w, row, area, start, hl)
17164 struct glyph_string *s;
17165 DECLARE_HDC (hdc)
17166 XChar2b *char2b;
17167 struct window *w;
17168 struct glyph_row *row;
17169 enum glyph_row_area area;
17170 int start;
17171 enum draw_glyphs_face hl;
17173 bzero (s, sizeof *s);
17174 s->w = w;
17175 s->f = XFRAME (w->frame);
17176 #ifdef HAVE_NTGUI
17177 s->hdc = hdc;
17178 #endif
17179 s->display = FRAME_X_DISPLAY (s->f);
17180 s->window = FRAME_X_WINDOW (s->f);
17181 s->char2b = char2b;
17182 s->hl = hl;
17183 s->row = row;
17184 s->area = area;
17185 s->first_glyph = row->glyphs[area] + start;
17186 s->height = row->height;
17187 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
17189 /* Display the internal border below the tool-bar window. */
17190 if (s->w == XWINDOW (s->f->tool_bar_window))
17191 s->y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
17193 s->ybase = s->y + row->ascent;
17197 /* Append the list of glyph strings with head H and tail T to the list
17198 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
17200 static INLINE void
17201 append_glyph_string_lists (head, tail, h, t)
17202 struct glyph_string **head, **tail;
17203 struct glyph_string *h, *t;
17205 if (h)
17207 if (*head)
17208 (*tail)->next = h;
17209 else
17210 *head = h;
17211 h->prev = *tail;
17212 *tail = t;
17217 /* Prepend the list of glyph strings with head H and tail T to the
17218 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
17219 result. */
17221 static INLINE void
17222 prepend_glyph_string_lists (head, tail, h, t)
17223 struct glyph_string **head, **tail;
17224 struct glyph_string *h, *t;
17226 if (h)
17228 if (*head)
17229 (*head)->prev = t;
17230 else
17231 *tail = t;
17232 t->next = *head;
17233 *head = h;
17238 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
17239 Set *HEAD and *TAIL to the resulting list. */
17241 static INLINE void
17242 append_glyph_string (head, tail, s)
17243 struct glyph_string **head, **tail;
17244 struct glyph_string *s;
17246 s->next = s->prev = NULL;
17247 append_glyph_string_lists (head, tail, s, s);
17251 /* Get face and two-byte form of character glyph GLYPH on frame F.
17252 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
17253 a pointer to a realized face that is ready for display. */
17255 static INLINE struct face *
17256 get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
17257 struct frame *f;
17258 struct glyph *glyph;
17259 XChar2b *char2b;
17260 int *two_byte_p;
17262 struct face *face;
17264 xassert (glyph->type == CHAR_GLYPH);
17265 face = FACE_FROM_ID (f, glyph->face_id);
17267 if (two_byte_p)
17268 *two_byte_p = 0;
17270 if (!glyph->multibyte_p)
17272 /* Unibyte case. We don't have to encode, but we have to make
17273 sure to use a face suitable for unibyte. */
17274 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
17276 else if (glyph->u.ch < 128
17277 && glyph->face_id < BASIC_FACE_ID_SENTINEL)
17279 /* Case of ASCII in a face known to fit ASCII. */
17280 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
17282 else
17284 int c1, c2, charset;
17286 /* Split characters into bytes. If c2 is -1 afterwards, C is
17287 really a one-byte character so that byte1 is zero. */
17288 SPLIT_CHAR (glyph->u.ch, charset, c1, c2);
17289 if (c2 > 0)
17290 STORE_XCHAR2B (char2b, c1, c2);
17291 else
17292 STORE_XCHAR2B (char2b, 0, c1);
17294 /* Maybe encode the character in *CHAR2B. */
17295 if (charset != CHARSET_ASCII)
17297 struct font_info *font_info
17298 = FONT_INFO_FROM_ID (f, face->font_info_id);
17299 if (font_info)
17300 glyph->font_type
17301 = rif->encode_char (glyph->u.ch, char2b, font_info, two_byte_p);
17305 /* Make sure X resources of the face are allocated. */
17306 xassert (face != NULL);
17307 PREPARE_FACE_FOR_DISPLAY (f, face);
17308 return face;
17312 /* Fill glyph string S with composition components specified by S->cmp.
17314 FACES is an array of faces for all components of this composition.
17315 S->gidx is the index of the first component for S.
17316 OVERLAPS_P non-zero means S should draw the foreground only, and
17317 use its physical height for clipping.
17319 Value is the index of a component not in S. */
17321 static int
17322 fill_composite_glyph_string (s, faces, overlaps_p)
17323 struct glyph_string *s;
17324 struct face **faces;
17325 int overlaps_p;
17327 int i;
17329 xassert (s);
17331 s->for_overlaps_p = overlaps_p;
17333 s->face = faces[s->gidx];
17334 s->font = s->face->font;
17335 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
17337 /* For all glyphs of this composition, starting at the offset
17338 S->gidx, until we reach the end of the definition or encounter a
17339 glyph that requires the different face, add it to S. */
17340 ++s->nchars;
17341 for (i = s->gidx + 1; i < s->cmp->glyph_len && faces[i] == s->face; ++i)
17342 ++s->nchars;
17344 /* All glyph strings for the same composition has the same width,
17345 i.e. the width set for the first component of the composition. */
17347 s->width = s->first_glyph->pixel_width;
17349 /* If the specified font could not be loaded, use the frame's
17350 default font, but record the fact that we couldn't load it in
17351 the glyph string so that we can draw rectangles for the
17352 characters of the glyph string. */
17353 if (s->font == NULL)
17355 s->font_not_found_p = 1;
17356 s->font = FRAME_FONT (s->f);
17359 /* Adjust base line for subscript/superscript text. */
17360 s->ybase += s->first_glyph->voffset;
17362 xassert (s->face && s->face->gc);
17364 /* This glyph string must always be drawn with 16-bit functions. */
17365 s->two_byte_p = 1;
17367 return s->gidx + s->nchars;
17371 /* Fill glyph string S from a sequence of character glyphs.
17373 FACE_ID is the face id of the string. START is the index of the
17374 first glyph to consider, END is the index of the last + 1.
17375 OVERLAPS_P non-zero means S should draw the foreground only, and
17376 use its physical height for clipping.
17378 Value is the index of the first glyph not in S. */
17380 static int
17381 fill_glyph_string (s, face_id, start, end, overlaps_p)
17382 struct glyph_string *s;
17383 int face_id;
17384 int start, end, overlaps_p;
17386 struct glyph *glyph, *last;
17387 int voffset;
17388 int glyph_not_available_p;
17390 xassert (s->f == XFRAME (s->w->frame));
17391 xassert (s->nchars == 0);
17392 xassert (start >= 0 && end > start);
17394 s->for_overlaps_p = overlaps_p,
17395 glyph = s->row->glyphs[s->area] + start;
17396 last = s->row->glyphs[s->area] + end;
17397 voffset = glyph->voffset;
17399 glyph_not_available_p = glyph->glyph_not_available_p;
17401 while (glyph < last
17402 && glyph->type == CHAR_GLYPH
17403 && glyph->voffset == voffset
17404 /* Same face id implies same font, nowadays. */
17405 && glyph->face_id == face_id
17406 && glyph->glyph_not_available_p == glyph_not_available_p)
17408 int two_byte_p;
17410 s->face = get_glyph_face_and_encoding (s->f, glyph,
17411 s->char2b + s->nchars,
17412 &two_byte_p);
17413 s->two_byte_p = two_byte_p;
17414 ++s->nchars;
17415 xassert (s->nchars <= end - start);
17416 s->width += glyph->pixel_width;
17417 ++glyph;
17420 s->font = s->face->font;
17421 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
17423 /* If the specified font could not be loaded, use the frame's font,
17424 but record the fact that we couldn't load it in
17425 S->font_not_found_p so that we can draw rectangles for the
17426 characters of the glyph string. */
17427 if (s->font == NULL || glyph_not_available_p)
17429 s->font_not_found_p = 1;
17430 s->font = FRAME_FONT (s->f);
17433 /* Adjust base line for subscript/superscript text. */
17434 s->ybase += voffset;
17436 xassert (s->face && s->face->gc);
17437 return glyph - s->row->glyphs[s->area];
17441 /* Fill glyph string S from image glyph S->first_glyph. */
17443 static void
17444 fill_image_glyph_string (s)
17445 struct glyph_string *s;
17447 xassert (s->first_glyph->type == IMAGE_GLYPH);
17448 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
17449 xassert (s->img);
17450 s->slice = s->first_glyph->slice;
17451 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
17452 s->font = s->face->font;
17453 s->width = s->first_glyph->pixel_width;
17455 /* Adjust base line for subscript/superscript text. */
17456 s->ybase += s->first_glyph->voffset;
17460 /* Fill glyph string S from a sequence of stretch glyphs.
17462 ROW is the glyph row in which the glyphs are found, AREA is the
17463 area within the row. START is the index of the first glyph to
17464 consider, END is the index of the last + 1.
17466 Value is the index of the first glyph not in S. */
17468 static int
17469 fill_stretch_glyph_string (s, row, area, start, end)
17470 struct glyph_string *s;
17471 struct glyph_row *row;
17472 enum glyph_row_area area;
17473 int start, end;
17475 struct glyph *glyph, *last;
17476 int voffset, face_id;
17478 xassert (s->first_glyph->type == STRETCH_GLYPH);
17480 glyph = s->row->glyphs[s->area] + start;
17481 last = s->row->glyphs[s->area] + end;
17482 face_id = glyph->face_id;
17483 s->face = FACE_FROM_ID (s->f, face_id);
17484 s->font = s->face->font;
17485 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
17486 s->width = glyph->pixel_width;
17487 voffset = glyph->voffset;
17489 for (++glyph;
17490 (glyph < last
17491 && glyph->type == STRETCH_GLYPH
17492 && glyph->voffset == voffset
17493 && glyph->face_id == face_id);
17494 ++glyph)
17495 s->width += glyph->pixel_width;
17497 /* Adjust base line for subscript/superscript text. */
17498 s->ybase += voffset;
17500 /* The case that face->gc == 0 is handled when drawing the glyph
17501 string by calling PREPARE_FACE_FOR_DISPLAY. */
17502 xassert (s->face);
17503 return glyph - s->row->glyphs[s->area];
17507 /* EXPORT for RIF:
17508 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
17509 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
17510 assumed to be zero. */
17512 void
17513 x_get_glyph_overhangs (glyph, f, left, right)
17514 struct glyph *glyph;
17515 struct frame *f;
17516 int *left, *right;
17518 *left = *right = 0;
17520 if (glyph->type == CHAR_GLYPH)
17522 XFontStruct *font;
17523 struct face *face;
17524 struct font_info *font_info;
17525 XChar2b char2b;
17526 XCharStruct *pcm;
17528 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
17529 font = face->font;
17530 font_info = FONT_INFO_FROM_ID (f, face->font_info_id);
17531 if (font /* ++KFS: Should this be font_info ? */
17532 && (pcm = rif->per_char_metric (font, &char2b, glyph->font_type)))
17534 if (pcm->rbearing > pcm->width)
17535 *right = pcm->rbearing - pcm->width;
17536 if (pcm->lbearing < 0)
17537 *left = -pcm->lbearing;
17543 /* Return the index of the first glyph preceding glyph string S that
17544 is overwritten by S because of S's left overhang. Value is -1
17545 if no glyphs are overwritten. */
17547 static int
17548 left_overwritten (s)
17549 struct glyph_string *s;
17551 int k;
17553 if (s->left_overhang)
17555 int x = 0, i;
17556 struct glyph *glyphs = s->row->glyphs[s->area];
17557 int first = s->first_glyph - glyphs;
17559 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
17560 x -= glyphs[i].pixel_width;
17562 k = i + 1;
17564 else
17565 k = -1;
17567 return k;
17571 /* Return the index of the first glyph preceding glyph string S that
17572 is overwriting S because of its right overhang. Value is -1 if no
17573 glyph in front of S overwrites S. */
17575 static int
17576 left_overwriting (s)
17577 struct glyph_string *s;
17579 int i, k, x;
17580 struct glyph *glyphs = s->row->glyphs[s->area];
17581 int first = s->first_glyph - glyphs;
17583 k = -1;
17584 x = 0;
17585 for (i = first - 1; i >= 0; --i)
17587 int left, right;
17588 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
17589 if (x + right > 0)
17590 k = i;
17591 x -= glyphs[i].pixel_width;
17594 return k;
17598 /* Return the index of the last glyph following glyph string S that is
17599 not overwritten by S because of S's right overhang. Value is -1 if
17600 no such glyph is found. */
17602 static int
17603 right_overwritten (s)
17604 struct glyph_string *s;
17606 int k = -1;
17608 if (s->right_overhang)
17610 int x = 0, i;
17611 struct glyph *glyphs = s->row->glyphs[s->area];
17612 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
17613 int end = s->row->used[s->area];
17615 for (i = first; i < end && s->right_overhang > x; ++i)
17616 x += glyphs[i].pixel_width;
17618 k = i;
17621 return k;
17625 /* Return the index of the last glyph following glyph string S that
17626 overwrites S because of its left overhang. Value is negative
17627 if no such glyph is found. */
17629 static int
17630 right_overwriting (s)
17631 struct glyph_string *s;
17633 int i, k, x;
17634 int end = s->row->used[s->area];
17635 struct glyph *glyphs = s->row->glyphs[s->area];
17636 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
17638 k = -1;
17639 x = 0;
17640 for (i = first; i < end; ++i)
17642 int left, right;
17643 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
17644 if (x - left < 0)
17645 k = i;
17646 x += glyphs[i].pixel_width;
17649 return k;
17653 /* Get face and two-byte form of character C in face FACE_ID on frame
17654 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
17655 means we want to display multibyte text. DISPLAY_P non-zero means
17656 make sure that X resources for the face returned are allocated.
17657 Value is a pointer to a realized face that is ready for display if
17658 DISPLAY_P is non-zero. */
17660 static INLINE struct face *
17661 get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p, display_p)
17662 struct frame *f;
17663 int c, face_id;
17664 XChar2b *char2b;
17665 int multibyte_p, display_p;
17667 struct face *face = FACE_FROM_ID (f, face_id);
17669 if (!multibyte_p)
17671 /* Unibyte case. We don't have to encode, but we have to make
17672 sure to use a face suitable for unibyte. */
17673 STORE_XCHAR2B (char2b, 0, c);
17674 face_id = FACE_FOR_CHAR (f, face, c);
17675 face = FACE_FROM_ID (f, face_id);
17677 else if (c < 128 && face_id < BASIC_FACE_ID_SENTINEL)
17679 /* Case of ASCII in a face known to fit ASCII. */
17680 STORE_XCHAR2B (char2b, 0, c);
17682 else
17684 int c1, c2, charset;
17686 /* Split characters into bytes. If c2 is -1 afterwards, C is
17687 really a one-byte character so that byte1 is zero. */
17688 SPLIT_CHAR (c, charset, c1, c2);
17689 if (c2 > 0)
17690 STORE_XCHAR2B (char2b, c1, c2);
17691 else
17692 STORE_XCHAR2B (char2b, 0, c1);
17694 /* Maybe encode the character in *CHAR2B. */
17695 if (face->font != NULL)
17697 struct font_info *font_info
17698 = FONT_INFO_FROM_ID (f, face->font_info_id);
17699 if (font_info)
17700 rif->encode_char (c, char2b, font_info, 0);
17704 /* Make sure X resources of the face are allocated. */
17705 #ifdef HAVE_X_WINDOWS
17706 if (display_p)
17707 #endif
17709 xassert (face != NULL);
17710 PREPARE_FACE_FOR_DISPLAY (f, face);
17713 return face;
17717 /* Set background width of glyph string S. START is the index of the
17718 first glyph following S. LAST_X is the right-most x-position + 1
17719 in the drawing area. */
17721 static INLINE void
17722 set_glyph_string_background_width (s, start, last_x)
17723 struct glyph_string *s;
17724 int start;
17725 int last_x;
17727 /* If the face of this glyph string has to be drawn to the end of
17728 the drawing area, set S->extends_to_end_of_line_p. */
17729 struct face *default_face = FACE_FROM_ID (s->f, DEFAULT_FACE_ID);
17731 if (start == s->row->used[s->area]
17732 && s->area == TEXT_AREA
17733 && ((s->hl == DRAW_NORMAL_TEXT
17734 && (s->row->fill_line_p
17735 || s->face->background != default_face->background
17736 || s->face->stipple != default_face->stipple
17737 || s->row->mouse_face_p))
17738 || s->hl == DRAW_MOUSE_FACE
17739 || ((s->hl == DRAW_IMAGE_RAISED || s->hl == DRAW_IMAGE_SUNKEN)
17740 && s->row->fill_line_p)))
17741 s->extends_to_end_of_line_p = 1;
17743 /* If S extends its face to the end of the line, set its
17744 background_width to the distance to the right edge of the drawing
17745 area. */
17746 if (s->extends_to_end_of_line_p)
17747 s->background_width = last_x - s->x + 1;
17748 else
17749 s->background_width = s->width;
17753 /* Compute overhangs and x-positions for glyph string S and its
17754 predecessors, or successors. X is the starting x-position for S.
17755 BACKWARD_P non-zero means process predecessors. */
17757 static void
17758 compute_overhangs_and_x (s, x, backward_p)
17759 struct glyph_string *s;
17760 int x;
17761 int backward_p;
17763 if (backward_p)
17765 while (s)
17767 if (rif->compute_glyph_string_overhangs)
17768 rif->compute_glyph_string_overhangs (s);
17769 x -= s->width;
17770 s->x = x;
17771 s = s->prev;
17774 else
17776 while (s)
17778 if (rif->compute_glyph_string_overhangs)
17779 rif->compute_glyph_string_overhangs (s);
17780 s->x = x;
17781 x += s->width;
17782 s = s->next;
17789 /* The following macros are only called from draw_glyphs below.
17790 They reference the following parameters of that function directly:
17791 `w', `row', `area', and `overlap_p'
17792 as well as the following local variables:
17793 `s', `f', and `hdc' (in W32) */
17795 #ifdef HAVE_NTGUI
17796 /* On W32, silently add local `hdc' variable to argument list of
17797 init_glyph_string. */
17798 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
17799 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
17800 #else
17801 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
17802 init_glyph_string (s, char2b, w, row, area, start, hl)
17803 #endif
17805 /* Add a glyph string for a stretch glyph to the list of strings
17806 between HEAD and TAIL. START is the index of the stretch glyph in
17807 row area AREA of glyph row ROW. END is the index of the last glyph
17808 in that glyph row area. X is the current output position assigned
17809 to the new glyph string constructed. HL overrides that face of the
17810 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
17811 is the right-most x-position of the drawing area. */
17813 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
17814 and below -- keep them on one line. */
17815 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17816 do \
17818 s = (struct glyph_string *) alloca (sizeof *s); \
17819 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
17820 START = fill_stretch_glyph_string (s, row, area, START, END); \
17821 append_glyph_string (&HEAD, &TAIL, s); \
17822 s->x = (X); \
17824 while (0)
17827 /* Add a glyph string for an image glyph to the list of strings
17828 between HEAD and TAIL. START is the index of the image glyph in
17829 row area AREA of glyph row ROW. END is the index of the last glyph
17830 in that glyph row area. X is the current output position assigned
17831 to the new glyph string constructed. HL overrides that face of the
17832 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
17833 is the right-most x-position of the drawing area. */
17835 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17836 do \
17838 s = (struct glyph_string *) alloca (sizeof *s); \
17839 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
17840 fill_image_glyph_string (s); \
17841 append_glyph_string (&HEAD, &TAIL, s); \
17842 ++START; \
17843 s->x = (X); \
17845 while (0)
17848 /* Add a glyph string for a sequence of character glyphs to the list
17849 of strings between HEAD and TAIL. START is the index of the first
17850 glyph in row area AREA of glyph row ROW that is part of the new
17851 glyph string. END is the index of the last glyph in that glyph row
17852 area. X is the current output position assigned to the new glyph
17853 string constructed. HL overrides that face of the glyph; e.g. it
17854 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
17855 right-most x-position of the drawing area. */
17857 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
17858 do \
17860 int c, face_id; \
17861 XChar2b *char2b; \
17863 c = (row)->glyphs[area][START].u.ch; \
17864 face_id = (row)->glyphs[area][START].face_id; \
17866 s = (struct glyph_string *) alloca (sizeof *s); \
17867 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
17868 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
17869 append_glyph_string (&HEAD, &TAIL, s); \
17870 s->x = (X); \
17871 START = fill_glyph_string (s, face_id, START, END, overlaps_p); \
17873 while (0)
17876 /* Add a glyph string for a composite sequence to the list of strings
17877 between HEAD and TAIL. START is the index of the first glyph in
17878 row area AREA of glyph row ROW that is part of the new glyph
17879 string. END is the index of the last glyph in that glyph row area.
17880 X is the current output position assigned to the new glyph string
17881 constructed. HL overrides that face of the glyph; e.g. it is
17882 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
17883 x-position of the drawing area. */
17885 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17886 do { \
17887 int cmp_id = (row)->glyphs[area][START].u.cmp_id; \
17888 int face_id = (row)->glyphs[area][START].face_id; \
17889 struct face *base_face = FACE_FROM_ID (f, face_id); \
17890 struct composition *cmp = composition_table[cmp_id]; \
17891 int glyph_len = cmp->glyph_len; \
17892 XChar2b *char2b; \
17893 struct face **faces; \
17894 struct glyph_string *first_s = NULL; \
17895 int n; \
17897 base_face = base_face->ascii_face; \
17898 char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len); \
17899 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
17900 /* At first, fill in `char2b' and `faces'. */ \
17901 for (n = 0; n < glyph_len; n++) \
17903 int c = COMPOSITION_GLYPH (cmp, n); \
17904 int this_face_id = FACE_FOR_CHAR (f, base_face, c); \
17905 faces[n] = FACE_FROM_ID (f, this_face_id); \
17906 get_char_face_and_encoding (f, c, this_face_id, \
17907 char2b + n, 1, 1); \
17910 /* Make glyph_strings for each glyph sequence that is drawable by \
17911 the same face, and append them to HEAD/TAIL. */ \
17912 for (n = 0; n < cmp->glyph_len;) \
17914 s = (struct glyph_string *) alloca (sizeof *s); \
17915 INIT_GLYPH_STRING (s, char2b + n, w, row, area, START, HL); \
17916 append_glyph_string (&(HEAD), &(TAIL), s); \
17917 s->cmp = cmp; \
17918 s->gidx = n; \
17919 s->x = (X); \
17921 if (n == 0) \
17922 first_s = s; \
17924 n = fill_composite_glyph_string (s, faces, overlaps_p); \
17927 ++START; \
17928 s = first_s; \
17929 } while (0)
17932 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
17933 of AREA of glyph row ROW on window W between indices START and END.
17934 HL overrides the face for drawing glyph strings, e.g. it is
17935 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
17936 x-positions of the drawing area.
17938 This is an ugly monster macro construct because we must use alloca
17939 to allocate glyph strings (because draw_glyphs can be called
17940 asynchronously). */
17942 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
17943 do \
17945 HEAD = TAIL = NULL; \
17946 while (START < END) \
17948 struct glyph *first_glyph = (row)->glyphs[area] + START; \
17949 switch (first_glyph->type) \
17951 case CHAR_GLYPH: \
17952 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
17953 HL, X, LAST_X); \
17954 break; \
17956 case COMPOSITE_GLYPH: \
17957 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
17958 HL, X, LAST_X); \
17959 break; \
17961 case STRETCH_GLYPH: \
17962 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
17963 HL, X, LAST_X); \
17964 break; \
17966 case IMAGE_GLYPH: \
17967 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
17968 HL, X, LAST_X); \
17969 break; \
17971 default: \
17972 abort (); \
17975 set_glyph_string_background_width (s, START, LAST_X); \
17976 (X) += s->width; \
17979 while (0)
17982 /* Draw glyphs between START and END in AREA of ROW on window W,
17983 starting at x-position X. X is relative to AREA in W. HL is a
17984 face-override with the following meaning:
17986 DRAW_NORMAL_TEXT draw normally
17987 DRAW_CURSOR draw in cursor face
17988 DRAW_MOUSE_FACE draw in mouse face.
17989 DRAW_INVERSE_VIDEO draw in mode line face
17990 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
17991 DRAW_IMAGE_RAISED draw an image with a raised relief around it
17993 If OVERLAPS_P is non-zero, draw only the foreground of characters
17994 and clip to the physical height of ROW.
17996 Value is the x-position reached, relative to AREA of W. */
17998 static int
17999 draw_glyphs (w, x, row, area, start, end, hl, overlaps_p)
18000 struct window *w;
18001 int x;
18002 struct glyph_row *row;
18003 enum glyph_row_area area;
18004 int start, end;
18005 enum draw_glyphs_face hl;
18006 int overlaps_p;
18008 struct glyph_string *head, *tail;
18009 struct glyph_string *s;
18010 int last_x, area_width;
18011 int x_reached;
18012 int i, j;
18013 struct frame *f = XFRAME (WINDOW_FRAME (w));
18014 DECLARE_HDC (hdc);
18016 ALLOCATE_HDC (hdc, f);
18018 /* Let's rather be paranoid than getting a SEGV. */
18019 end = min (end, row->used[area]);
18020 start = max (0, start);
18021 start = min (end, start);
18023 /* Translate X to frame coordinates. Set last_x to the right
18024 end of the drawing area. */
18025 if (row->full_width_p)
18027 /* X is relative to the left edge of W, without scroll bars
18028 or fringes. */
18029 x += WINDOW_LEFT_EDGE_X (w);
18030 last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
18032 else
18034 int area_left = window_box_left (w, area);
18035 x += area_left;
18036 area_width = window_box_width (w, area);
18037 last_x = area_left + area_width;
18040 /* Build a doubly-linked list of glyph_string structures between
18041 head and tail from what we have to draw. Note that the macro
18042 BUILD_GLYPH_STRINGS will modify its start parameter. That's
18043 the reason we use a separate variable `i'. */
18044 i = start;
18045 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
18046 if (tail)
18047 x_reached = tail->x + tail->background_width;
18048 else
18049 x_reached = x;
18051 /* If there are any glyphs with lbearing < 0 or rbearing > width in
18052 the row, redraw some glyphs in front or following the glyph
18053 strings built above. */
18054 if (head && !overlaps_p && row->contains_overlapping_glyphs_p)
18056 int dummy_x = 0;
18057 struct glyph_string *h, *t;
18059 /* Compute overhangs for all glyph strings. */
18060 if (rif->compute_glyph_string_overhangs)
18061 for (s = head; s; s = s->next)
18062 rif->compute_glyph_string_overhangs (s);
18064 /* Prepend glyph strings for glyphs in front of the first glyph
18065 string that are overwritten because of the first glyph
18066 string's left overhang. The background of all strings
18067 prepended must be drawn because the first glyph string
18068 draws over it. */
18069 i = left_overwritten (head);
18070 if (i >= 0)
18072 j = i;
18073 BUILD_GLYPH_STRINGS (j, start, h, t,
18074 DRAW_NORMAL_TEXT, dummy_x, last_x);
18075 start = i;
18076 compute_overhangs_and_x (t, head->x, 1);
18077 prepend_glyph_string_lists (&head, &tail, h, t);
18080 /* Prepend glyph strings for glyphs in front of the first glyph
18081 string that overwrite that glyph string because of their
18082 right overhang. For these strings, only the foreground must
18083 be drawn, because it draws over the glyph string at `head'.
18084 The background must not be drawn because this would overwrite
18085 right overhangs of preceding glyphs for which no glyph
18086 strings exist. */
18087 i = left_overwriting (head);
18088 if (i >= 0)
18090 BUILD_GLYPH_STRINGS (i, start, h, t,
18091 DRAW_NORMAL_TEXT, dummy_x, last_x);
18092 for (s = h; s; s = s->next)
18093 s->background_filled_p = 1;
18094 compute_overhangs_and_x (t, head->x, 1);
18095 prepend_glyph_string_lists (&head, &tail, h, t);
18098 /* Append glyphs strings for glyphs following the last glyph
18099 string tail that are overwritten by tail. The background of
18100 these strings has to be drawn because tail's foreground draws
18101 over it. */
18102 i = right_overwritten (tail);
18103 if (i >= 0)
18105 BUILD_GLYPH_STRINGS (end, i, h, t,
18106 DRAW_NORMAL_TEXT, x, last_x);
18107 compute_overhangs_and_x (h, tail->x + tail->width, 0);
18108 append_glyph_string_lists (&head, &tail, h, t);
18111 /* Append glyph strings for glyphs following the last glyph
18112 string tail that overwrite tail. The foreground of such
18113 glyphs has to be drawn because it writes into the background
18114 of tail. The background must not be drawn because it could
18115 paint over the foreground of following glyphs. */
18116 i = right_overwriting (tail);
18117 if (i >= 0)
18119 BUILD_GLYPH_STRINGS (end, i, h, t,
18120 DRAW_NORMAL_TEXT, x, last_x);
18121 for (s = h; s; s = s->next)
18122 s->background_filled_p = 1;
18123 compute_overhangs_and_x (h, tail->x + tail->width, 0);
18124 append_glyph_string_lists (&head, &tail, h, t);
18128 /* Draw all strings. */
18129 for (s = head; s; s = s->next)
18130 rif->draw_glyph_string (s);
18132 if (area == TEXT_AREA
18133 && !row->full_width_p
18134 /* When drawing overlapping rows, only the glyph strings'
18135 foreground is drawn, which doesn't erase a cursor
18136 completely. */
18137 && !overlaps_p)
18139 int x0 = head ? head->x : x;
18140 int x1 = tail ? tail->x + tail->background_width : x;
18142 int text_left = window_box_left (w, TEXT_AREA);
18143 x0 -= text_left;
18144 x1 -= text_left;
18146 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
18147 row->y, MATRIX_ROW_BOTTOM_Y (row));
18150 /* Value is the x-position up to which drawn, relative to AREA of W.
18151 This doesn't include parts drawn because of overhangs. */
18152 if (row->full_width_p)
18153 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
18154 else
18155 x_reached -= window_box_left (w, area);
18157 RELEASE_HDC (hdc, f);
18159 return x_reached;
18163 /* Store one glyph for IT->char_to_display in IT->glyph_row.
18164 Called from x_produce_glyphs when IT->glyph_row is non-null. */
18166 static INLINE void
18167 append_glyph (it)
18168 struct it *it;
18170 struct glyph *glyph;
18171 enum glyph_row_area area = it->area;
18173 xassert (it->glyph_row);
18174 xassert (it->char_to_display != '\n' && it->char_to_display != '\t');
18176 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18177 if (glyph < it->glyph_row->glyphs[area + 1])
18179 glyph->charpos = CHARPOS (it->position);
18180 glyph->object = it->object;
18181 glyph->pixel_width = it->pixel_width;
18182 glyph->ascent = it->ascent;
18183 glyph->descent = it->descent;
18184 glyph->voffset = it->voffset;
18185 glyph->type = CHAR_GLYPH;
18186 glyph->multibyte_p = it->multibyte_p;
18187 glyph->left_box_line_p = it->start_of_box_run_p;
18188 glyph->right_box_line_p = it->end_of_box_run_p;
18189 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
18190 || it->phys_descent > it->descent);
18191 glyph->padding_p = 0;
18192 glyph->glyph_not_available_p = it->glyph_not_available_p;
18193 glyph->face_id = it->face_id;
18194 glyph->u.ch = it->char_to_display;
18195 glyph->slice = null_glyph_slice;
18196 glyph->font_type = FONT_TYPE_UNKNOWN;
18197 ++it->glyph_row->used[area];
18199 else if (!fonts_changed_p)
18201 it->w->ncols_scale_factor++;
18202 fonts_changed_p = 1;
18206 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
18207 Called from x_produce_glyphs when IT->glyph_row is non-null. */
18209 static INLINE void
18210 append_composite_glyph (it)
18211 struct it *it;
18213 struct glyph *glyph;
18214 enum glyph_row_area area = it->area;
18216 xassert (it->glyph_row);
18218 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18219 if (glyph < it->glyph_row->glyphs[area + 1])
18221 glyph->charpos = CHARPOS (it->position);
18222 glyph->object = it->object;
18223 glyph->pixel_width = it->pixel_width;
18224 glyph->ascent = it->ascent;
18225 glyph->descent = it->descent;
18226 glyph->voffset = it->voffset;
18227 glyph->type = COMPOSITE_GLYPH;
18228 glyph->multibyte_p = it->multibyte_p;
18229 glyph->left_box_line_p = it->start_of_box_run_p;
18230 glyph->right_box_line_p = it->end_of_box_run_p;
18231 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
18232 || it->phys_descent > it->descent);
18233 glyph->padding_p = 0;
18234 glyph->glyph_not_available_p = 0;
18235 glyph->face_id = it->face_id;
18236 glyph->u.cmp_id = it->cmp_id;
18237 glyph->slice = null_glyph_slice;
18238 glyph->font_type = FONT_TYPE_UNKNOWN;
18239 ++it->glyph_row->used[area];
18241 else if (!fonts_changed_p)
18243 it->w->ncols_scale_factor++;
18244 fonts_changed_p = 1;
18249 /* Change IT->ascent and IT->height according to the setting of
18250 IT->voffset. */
18252 static INLINE void
18253 take_vertical_position_into_account (it)
18254 struct it *it;
18256 if (it->voffset)
18258 if (it->voffset < 0)
18259 /* Increase the ascent so that we can display the text higher
18260 in the line. */
18261 it->ascent -= it->voffset;
18262 else
18263 /* Increase the descent so that we can display the text lower
18264 in the line. */
18265 it->descent += it->voffset;
18270 /* Produce glyphs/get display metrics for the image IT is loaded with.
18271 See the description of struct display_iterator in dispextern.h for
18272 an overview of struct display_iterator. */
18274 static void
18275 produce_image_glyph (it)
18276 struct it *it;
18278 struct image *img;
18279 struct face *face;
18280 int face_ascent, glyph_ascent;
18281 struct glyph_slice slice;
18283 xassert (it->what == IT_IMAGE);
18285 face = FACE_FROM_ID (it->f, it->face_id);
18286 xassert (face);
18287 /* Make sure X resources of the face is loaded. */
18288 PREPARE_FACE_FOR_DISPLAY (it->f, face);
18290 if (it->image_id < 0)
18292 /* Fringe bitmap. */
18293 it->ascent = it->phys_ascent = 0;
18294 it->descent = it->phys_descent = 0;
18295 it->pixel_width = 0;
18296 it->nglyphs = 0;
18297 return;
18300 img = IMAGE_FROM_ID (it->f, it->image_id);
18301 xassert (img);
18302 /* Make sure X resources of the image is loaded. */
18303 prepare_image_for_display (it->f, img);
18305 slice.x = slice.y = 0;
18306 slice.width = img->width;
18307 slice.height = img->height;
18309 if (INTEGERP (it->slice.x))
18310 slice.x = XINT (it->slice.x);
18311 else if (FLOATP (it->slice.x))
18312 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
18314 if (INTEGERP (it->slice.y))
18315 slice.y = XINT (it->slice.y);
18316 else if (FLOATP (it->slice.y))
18317 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
18319 if (INTEGERP (it->slice.width))
18320 slice.width = XINT (it->slice.width);
18321 else if (FLOATP (it->slice.width))
18322 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
18324 if (INTEGERP (it->slice.height))
18325 slice.height = XINT (it->slice.height);
18326 else if (FLOATP (it->slice.height))
18327 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
18329 if (slice.x >= img->width)
18330 slice.x = img->width;
18331 if (slice.y >= img->height)
18332 slice.y = img->height;
18333 if (slice.x + slice.width >= img->width)
18334 slice.width = img->width - slice.x;
18335 if (slice.y + slice.height > img->height)
18336 slice.height = img->height - slice.y;
18338 if (slice.width == 0 || slice.height == 0)
18339 return;
18341 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
18343 it->descent = slice.height - glyph_ascent;
18344 if (slice.y == 0)
18345 it->descent += img->vmargin;
18346 if (slice.y + slice.height == img->height)
18347 it->descent += img->vmargin;
18348 it->phys_descent = it->descent;
18350 it->pixel_width = slice.width;
18351 if (slice.x == 0)
18352 it->pixel_width += img->hmargin;
18353 if (slice.x + slice.width == img->width)
18354 it->pixel_width += img->hmargin;
18356 /* It's quite possible for images to have an ascent greater than
18357 their height, so don't get confused in that case. */
18358 if (it->descent < 0)
18359 it->descent = 0;
18361 #if 0 /* this breaks image tiling */
18362 /* If this glyph is alone on the last line, adjust it.ascent to minimum row ascent. */
18363 face_ascent = face->font ? FONT_BASE (face->font) : FRAME_BASELINE_OFFSET (it->f);
18364 if (face_ascent > it->ascent)
18365 it->ascent = it->phys_ascent = face_ascent;
18366 #endif
18368 it->nglyphs = 1;
18370 if (face->box != FACE_NO_BOX)
18372 if (face->box_line_width > 0)
18374 if (slice.y == 0)
18375 it->ascent += face->box_line_width;
18376 if (slice.y + slice.height == img->height)
18377 it->descent += face->box_line_width;
18380 if (it->start_of_box_run_p && slice.x == 0)
18381 it->pixel_width += abs (face->box_line_width);
18382 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
18383 it->pixel_width += abs (face->box_line_width);
18386 take_vertical_position_into_account (it);
18388 if (it->glyph_row)
18390 struct glyph *glyph;
18391 enum glyph_row_area area = it->area;
18393 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18394 if (glyph < it->glyph_row->glyphs[area + 1])
18396 glyph->charpos = CHARPOS (it->position);
18397 glyph->object = it->object;
18398 glyph->pixel_width = it->pixel_width;
18399 glyph->ascent = glyph_ascent;
18400 glyph->descent = it->descent;
18401 glyph->voffset = it->voffset;
18402 glyph->type = IMAGE_GLYPH;
18403 glyph->multibyte_p = it->multibyte_p;
18404 glyph->left_box_line_p = it->start_of_box_run_p;
18405 glyph->right_box_line_p = it->end_of_box_run_p;
18406 glyph->overlaps_vertically_p = 0;
18407 glyph->padding_p = 0;
18408 glyph->glyph_not_available_p = 0;
18409 glyph->face_id = it->face_id;
18410 glyph->u.img_id = img->id;
18411 glyph->slice = slice;
18412 glyph->font_type = FONT_TYPE_UNKNOWN;
18413 ++it->glyph_row->used[area];
18415 else if (!fonts_changed_p)
18417 it->w->ncols_scale_factor++;
18418 fonts_changed_p = 1;
18424 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
18425 of the glyph, WIDTH and HEIGHT are the width and height of the
18426 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
18428 static void
18429 append_stretch_glyph (it, object, width, height, ascent)
18430 struct it *it;
18431 Lisp_Object object;
18432 int width, height;
18433 int ascent;
18435 struct glyph *glyph;
18436 enum glyph_row_area area = it->area;
18438 xassert (ascent >= 0 && ascent <= height);
18440 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18441 if (glyph < it->glyph_row->glyphs[area + 1])
18443 glyph->charpos = CHARPOS (it->position);
18444 glyph->object = object;
18445 glyph->pixel_width = width;
18446 glyph->ascent = ascent;
18447 glyph->descent = height - ascent;
18448 glyph->voffset = it->voffset;
18449 glyph->type = STRETCH_GLYPH;
18450 glyph->multibyte_p = it->multibyte_p;
18451 glyph->left_box_line_p = it->start_of_box_run_p;
18452 glyph->right_box_line_p = it->end_of_box_run_p;
18453 glyph->overlaps_vertically_p = 0;
18454 glyph->padding_p = 0;
18455 glyph->glyph_not_available_p = 0;
18456 glyph->face_id = it->face_id;
18457 glyph->u.stretch.ascent = ascent;
18458 glyph->u.stretch.height = height;
18459 glyph->slice = null_glyph_slice;
18460 glyph->font_type = FONT_TYPE_UNKNOWN;
18461 ++it->glyph_row->used[area];
18463 else if (!fonts_changed_p)
18465 it->w->ncols_scale_factor++;
18466 fonts_changed_p = 1;
18471 /* Produce a stretch glyph for iterator IT. IT->object is the value
18472 of the glyph property displayed. The value must be a list
18473 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
18474 being recognized:
18476 1. `:width WIDTH' specifies that the space should be WIDTH *
18477 canonical char width wide. WIDTH may be an integer or floating
18478 point number.
18480 2. `:relative-width FACTOR' specifies that the width of the stretch
18481 should be computed from the width of the first character having the
18482 `glyph' property, and should be FACTOR times that width.
18484 3. `:align-to HPOS' specifies that the space should be wide enough
18485 to reach HPOS, a value in canonical character units.
18487 Exactly one of the above pairs must be present.
18489 4. `:height HEIGHT' specifies that the height of the stretch produced
18490 should be HEIGHT, measured in canonical character units.
18492 5. `:relative-height FACTOR' specifies that the height of the
18493 stretch should be FACTOR times the height of the characters having
18494 the glyph property.
18496 Either none or exactly one of 4 or 5 must be present.
18498 6. `:ascent ASCENT' specifies that ASCENT percent of the height
18499 of the stretch should be used for the ascent of the stretch.
18500 ASCENT must be in the range 0 <= ASCENT <= 100. */
18502 static void
18503 produce_stretch_glyph (it)
18504 struct it *it;
18506 /* (space :width WIDTH :height HEIGHT ...) */
18507 Lisp_Object prop, plist;
18508 int width = 0, height = 0, align_to = -1;
18509 int zero_width_ok_p = 0, zero_height_ok_p = 0;
18510 int ascent = 0;
18511 double tem;
18512 struct face *face = FACE_FROM_ID (it->f, it->face_id);
18513 XFontStruct *font = face->font ? face->font : FRAME_FONT (it->f);
18515 PREPARE_FACE_FOR_DISPLAY (it->f, face);
18517 /* List should start with `space'. */
18518 xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
18519 plist = XCDR (it->object);
18521 /* Compute the width of the stretch. */
18522 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
18523 && calc_pixel_width_or_height (&tem, it, prop, font, 1, 0))
18525 /* Absolute width `:width WIDTH' specified and valid. */
18526 zero_width_ok_p = 1;
18527 width = (int)tem;
18529 else if (prop = Fplist_get (plist, QCrelative_width),
18530 NUMVAL (prop) > 0)
18532 /* Relative width `:relative-width FACTOR' specified and valid.
18533 Compute the width of the characters having the `glyph'
18534 property. */
18535 struct it it2;
18536 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
18538 it2 = *it;
18539 if (it->multibyte_p)
18541 int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT)
18542 - IT_BYTEPOS (*it));
18543 it2.c = STRING_CHAR_AND_LENGTH (p, maxlen, it2.len);
18545 else
18546 it2.c = *p, it2.len = 1;
18548 it2.glyph_row = NULL;
18549 it2.what = IT_CHARACTER;
18550 x_produce_glyphs (&it2);
18551 width = NUMVAL (prop) * it2.pixel_width;
18553 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
18554 && calc_pixel_width_or_height (&tem, it, prop, font, 1, &align_to))
18556 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
18557 align_to = (align_to < 0
18559 : align_to - window_box_left_offset (it->w, TEXT_AREA));
18560 else if (align_to < 0)
18561 align_to = window_box_left_offset (it->w, TEXT_AREA);
18562 width = max (0, (int)tem + align_to - it->current_x);
18563 zero_width_ok_p = 1;
18565 else
18566 /* Nothing specified -> width defaults to canonical char width. */
18567 width = FRAME_COLUMN_WIDTH (it->f);
18569 if (width <= 0 && (width < 0 || !zero_width_ok_p))
18570 width = 1;
18572 /* Compute height. */
18573 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
18574 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
18576 height = (int)tem;
18577 zero_height_ok_p = 1;
18579 else if (prop = Fplist_get (plist, QCrelative_height),
18580 NUMVAL (prop) > 0)
18581 height = FONT_HEIGHT (font) * NUMVAL (prop);
18582 else
18583 height = FONT_HEIGHT (font);
18585 if (height <= 0 && (height < 0 || !zero_height_ok_p))
18586 height = 1;
18588 /* Compute percentage of height used for ascent. If
18589 `:ascent ASCENT' is present and valid, use that. Otherwise,
18590 derive the ascent from the font in use. */
18591 if (prop = Fplist_get (plist, QCascent),
18592 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
18593 ascent = height * NUMVAL (prop) / 100.0;
18594 else if (!NILP (prop)
18595 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
18596 ascent = min (max (0, (int)tem), height);
18597 else
18598 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
18600 if (width > 0 && height > 0 && it->glyph_row)
18602 Lisp_Object object = it->stack[it->sp - 1].string;
18603 if (!STRINGP (object))
18604 object = it->w->buffer;
18605 append_stretch_glyph (it, object, width, height, ascent);
18608 it->pixel_width = width;
18609 it->ascent = it->phys_ascent = ascent;
18610 it->descent = it->phys_descent = height - it->ascent;
18611 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
18613 if (width > 0 && height > 0 && face->box != FACE_NO_BOX)
18615 if (face->box_line_width > 0)
18617 it->ascent += face->box_line_width;
18618 it->descent += face->box_line_width;
18621 if (it->start_of_box_run_p)
18622 it->pixel_width += abs (face->box_line_width);
18623 if (it->end_of_box_run_p)
18624 it->pixel_width += abs (face->box_line_width);
18627 take_vertical_position_into_account (it);
18630 /* Calculate line-height and line-spacing properties.
18631 An integer value specifies explicit pixel value.
18632 A float value specifies relative value to current face height.
18633 A cons (float . face-name) specifies relative value to
18634 height of specified face font.
18636 Returns height in pixels, or nil. */
18638 static Lisp_Object
18639 calc_line_height_property (it, prop, font, boff, total)
18640 struct it *it;
18641 Lisp_Object prop;
18642 XFontStruct *font;
18643 int boff, *total;
18645 Lisp_Object position, val;
18646 Lisp_Object face_name = Qnil;
18647 int ascent, descent, height, override;
18649 if (STRINGP (it->object))
18650 position = make_number (IT_STRING_CHARPOS (*it));
18651 else
18652 position = make_number (IT_CHARPOS (*it));
18654 val = Fget_char_property (position, prop, it->object);
18656 if (NILP (val))
18657 return val;
18659 if (total && CONSP (val) && EQ (XCAR (val), Qtotal))
18661 *total = 1;
18662 val = XCDR (val);
18665 if (INTEGERP (val))
18666 return val;
18668 if (CONSP (val))
18670 face_name = XCDR (val);
18671 val = XCAR (val);
18673 else if (SYMBOLP (val))
18675 face_name = val;
18676 val = Qnil;
18679 override = EQ (prop, Qline_height);
18681 if (NILP (face_name))
18683 font = FRAME_FONT (it->f);
18684 boff = FRAME_BASELINE_OFFSET (it->f);
18686 else if (EQ (face_name, Qt))
18688 override = 0;
18690 else
18692 int face_id;
18693 struct face *face;
18694 struct font_info *font_info;
18696 face_id = lookup_named_face (it->f, face_name, ' ');
18697 if (face_id < 0)
18698 return make_number (-1);
18700 face = FACE_FROM_ID (it->f, face_id);
18701 font = face->font;
18702 if (font == NULL)
18703 return make_number (-1);
18705 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
18706 boff = font_info->baseline_offset;
18707 if (font_info->vertical_centering)
18708 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
18711 ascent = FONT_BASE (font) + boff;
18712 descent = FONT_DESCENT (font) - boff;
18714 if (override)
18716 it->override_ascent = ascent;
18717 it->override_descent = descent;
18718 it->override_boff = boff;
18721 height = ascent + descent;
18722 if (FLOATP (val))
18723 height = (int)(XFLOAT_DATA (val) * height);
18724 else if (INTEGERP (val))
18725 height *= XINT (val);
18727 return make_number (height);
18731 /* RIF:
18732 Produce glyphs/get display metrics for the display element IT is
18733 loaded with. See the description of struct display_iterator in
18734 dispextern.h for an overview of struct display_iterator. */
18736 void
18737 x_produce_glyphs (it)
18738 struct it *it;
18740 int extra_line_spacing = it->extra_line_spacing;
18742 it->glyph_not_available_p = 0;
18744 if (it->what == IT_CHARACTER)
18746 XChar2b char2b;
18747 XFontStruct *font;
18748 struct face *face = FACE_FROM_ID (it->f, it->face_id);
18749 XCharStruct *pcm;
18750 int font_not_found_p;
18751 struct font_info *font_info;
18752 int boff; /* baseline offset */
18753 /* We may change it->multibyte_p upon unibyte<->multibyte
18754 conversion. So, save the current value now and restore it
18755 later.
18757 Note: It seems that we don't have to record multibyte_p in
18758 struct glyph because the character code itself tells if or
18759 not the character is multibyte. Thus, in the future, we must
18760 consider eliminating the field `multibyte_p' in the struct
18761 glyph. */
18762 int saved_multibyte_p = it->multibyte_p;
18764 /* Maybe translate single-byte characters to multibyte, or the
18765 other way. */
18766 it->char_to_display = it->c;
18767 if (!ASCII_BYTE_P (it->c))
18769 if (unibyte_display_via_language_environment
18770 && SINGLE_BYTE_CHAR_P (it->c)
18771 && (it->c >= 0240
18772 || !NILP (Vnonascii_translation_table)))
18774 it->char_to_display = unibyte_char_to_multibyte (it->c);
18775 it->multibyte_p = 1;
18776 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
18777 face = FACE_FROM_ID (it->f, it->face_id);
18779 else if (!SINGLE_BYTE_CHAR_P (it->c)
18780 && !it->multibyte_p)
18782 it->multibyte_p = 1;
18783 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
18784 face = FACE_FROM_ID (it->f, it->face_id);
18788 /* Get font to use. Encode IT->char_to_display. */
18789 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
18790 &char2b, it->multibyte_p, 0);
18791 font = face->font;
18793 /* When no suitable font found, use the default font. */
18794 font_not_found_p = font == NULL;
18795 if (font_not_found_p)
18797 font = FRAME_FONT (it->f);
18798 boff = FRAME_BASELINE_OFFSET (it->f);
18799 font_info = NULL;
18801 else
18803 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
18804 boff = font_info->baseline_offset;
18805 if (font_info->vertical_centering)
18806 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
18809 if (it->char_to_display >= ' '
18810 && (!it->multibyte_p || it->char_to_display < 128))
18812 /* Either unibyte or ASCII. */
18813 int stretched_p;
18815 it->nglyphs = 1;
18817 pcm = rif->per_char_metric (font, &char2b,
18818 FONT_TYPE_FOR_UNIBYTE (font, it->char_to_display));
18820 if (it->override_ascent >= 0)
18822 it->ascent = it->override_ascent;
18823 it->descent = it->override_descent;
18824 boff = it->override_boff;
18826 else
18828 it->ascent = FONT_BASE (font) + boff;
18829 it->descent = FONT_DESCENT (font) - boff;
18832 if (pcm)
18834 it->phys_ascent = pcm->ascent + boff;
18835 it->phys_descent = pcm->descent - boff;
18836 it->pixel_width = pcm->width;
18838 else
18840 it->glyph_not_available_p = 1;
18841 it->phys_ascent = it->ascent;
18842 it->phys_descent = it->descent;
18843 it->pixel_width = FONT_WIDTH (font);
18846 if (it->constrain_row_ascent_descent_p)
18848 if (it->descent > it->max_descent)
18850 it->ascent += it->descent - it->max_descent;
18851 it->descent = it->max_descent;
18853 if (it->ascent > it->max_ascent)
18855 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
18856 it->ascent = it->max_ascent;
18858 it->phys_ascent = min (it->phys_ascent, it->ascent);
18859 it->phys_descent = min (it->phys_descent, it->descent);
18860 extra_line_spacing = 0;
18863 /* If this is a space inside a region of text with
18864 `space-width' property, change its width. */
18865 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
18866 if (stretched_p)
18867 it->pixel_width *= XFLOATINT (it->space_width);
18869 /* If face has a box, add the box thickness to the character
18870 height. If character has a box line to the left and/or
18871 right, add the box line width to the character's width. */
18872 if (face->box != FACE_NO_BOX)
18874 int thick = face->box_line_width;
18876 if (thick > 0)
18878 it->ascent += thick;
18879 it->descent += thick;
18881 else
18882 thick = -thick;
18884 if (it->start_of_box_run_p)
18885 it->pixel_width += thick;
18886 if (it->end_of_box_run_p)
18887 it->pixel_width += thick;
18890 /* If face has an overline, add the height of the overline
18891 (1 pixel) and a 1 pixel margin to the character height. */
18892 if (face->overline_p)
18893 it->ascent += 2;
18895 if (it->constrain_row_ascent_descent_p)
18897 if (it->ascent > it->max_ascent)
18898 it->ascent = it->max_ascent;
18899 if (it->descent > it->max_descent)
18900 it->descent = it->max_descent;
18903 take_vertical_position_into_account (it);
18905 /* If we have to actually produce glyphs, do it. */
18906 if (it->glyph_row)
18908 if (stretched_p)
18910 /* Translate a space with a `space-width' property
18911 into a stretch glyph. */
18912 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
18913 / FONT_HEIGHT (font));
18914 append_stretch_glyph (it, it->object, it->pixel_width,
18915 it->ascent + it->descent, ascent);
18917 else
18918 append_glyph (it);
18920 /* If characters with lbearing or rbearing are displayed
18921 in this line, record that fact in a flag of the
18922 glyph row. This is used to optimize X output code. */
18923 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
18924 it->glyph_row->contains_overlapping_glyphs_p = 1;
18927 else if (it->char_to_display == '\n')
18929 /* A newline has no width but we need the height of the line.
18930 But if previous part of the line set a height, don't
18931 increase that height */
18933 Lisp_Object height;
18935 it->override_ascent = -1;
18936 it->pixel_width = 0;
18937 it->nglyphs = 0;
18939 height = calc_line_height_property(it, Qline_height, font, boff, 0);
18941 if (it->override_ascent >= 0)
18943 it->ascent = it->override_ascent;
18944 it->descent = it->override_descent;
18945 boff = it->override_boff;
18947 else
18949 it->ascent = FONT_BASE (font) + boff;
18950 it->descent = FONT_DESCENT (font) - boff;
18953 if (EQ (height, make_number(0)))
18955 if (it->descent > it->max_descent)
18957 it->ascent += it->descent - it->max_descent;
18958 it->descent = it->max_descent;
18960 if (it->ascent > it->max_ascent)
18962 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
18963 it->ascent = it->max_ascent;
18965 it->phys_ascent = min (it->phys_ascent, it->ascent);
18966 it->phys_descent = min (it->phys_descent, it->descent);
18967 it->constrain_row_ascent_descent_p = 1;
18968 extra_line_spacing = 0;
18970 else
18972 Lisp_Object spacing;
18973 int total = 0;
18975 it->phys_ascent = it->ascent;
18976 it->phys_descent = it->descent;
18978 if ((it->max_ascent > 0 || it->max_descent > 0)
18979 && face->box != FACE_NO_BOX
18980 && face->box_line_width > 0)
18982 it->ascent += face->box_line_width;
18983 it->descent += face->box_line_width;
18985 if (!NILP (height)
18986 && XINT (height) > it->ascent + it->descent)
18987 it->ascent = XINT (height) - it->descent;
18989 spacing = calc_line_height_property(it, Qline_spacing, font, boff, &total);
18990 if (INTEGERP (spacing))
18992 extra_line_spacing = XINT (spacing);
18993 if (total)
18994 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
18998 else if (it->char_to_display == '\t')
19000 int tab_width = it->tab_width * FRAME_COLUMN_WIDTH (it->f);
19001 int x = it->current_x + it->continuation_lines_width;
19002 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
19004 /* If the distance from the current position to the next tab
19005 stop is less than a canonical character width, use the
19006 tab stop after that. */
19007 if (next_tab_x - x < FRAME_COLUMN_WIDTH (it->f))
19008 next_tab_x += tab_width;
19010 it->pixel_width = next_tab_x - x;
19011 it->nglyphs = 1;
19012 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
19013 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
19015 if (it->glyph_row)
19017 append_stretch_glyph (it, it->object, it->pixel_width,
19018 it->ascent + it->descent, it->ascent);
19021 else
19023 /* A multi-byte character. Assume that the display width of the
19024 character is the width of the character multiplied by the
19025 width of the font. */
19027 /* If we found a font, this font should give us the right
19028 metrics. If we didn't find a font, use the frame's
19029 default font and calculate the width of the character
19030 from the charset width; this is what old redisplay code
19031 did. */
19033 pcm = rif->per_char_metric (font, &char2b,
19034 FONT_TYPE_FOR_MULTIBYTE (font, it->c));
19036 if (font_not_found_p || !pcm)
19038 int charset = CHAR_CHARSET (it->char_to_display);
19040 it->glyph_not_available_p = 1;
19041 it->pixel_width = (FRAME_COLUMN_WIDTH (it->f)
19042 * CHARSET_WIDTH (charset));
19043 it->phys_ascent = FONT_BASE (font) + boff;
19044 it->phys_descent = FONT_DESCENT (font) - boff;
19046 else
19048 it->pixel_width = pcm->width;
19049 it->phys_ascent = pcm->ascent + boff;
19050 it->phys_descent = pcm->descent - boff;
19051 if (it->glyph_row
19052 && (pcm->lbearing < 0
19053 || pcm->rbearing > pcm->width))
19054 it->glyph_row->contains_overlapping_glyphs_p = 1;
19056 it->nglyphs = 1;
19057 it->ascent = FONT_BASE (font) + boff;
19058 it->descent = FONT_DESCENT (font) - boff;
19059 if (face->box != FACE_NO_BOX)
19061 int thick = face->box_line_width;
19063 if (thick > 0)
19065 it->ascent += thick;
19066 it->descent += thick;
19068 else
19069 thick = - thick;
19071 if (it->start_of_box_run_p)
19072 it->pixel_width += thick;
19073 if (it->end_of_box_run_p)
19074 it->pixel_width += thick;
19077 /* If face has an overline, add the height of the overline
19078 (1 pixel) and a 1 pixel margin to the character height. */
19079 if (face->overline_p)
19080 it->ascent += 2;
19082 take_vertical_position_into_account (it);
19084 if (it->glyph_row)
19085 append_glyph (it);
19087 it->multibyte_p = saved_multibyte_p;
19089 else if (it->what == IT_COMPOSITION)
19091 /* Note: A composition is represented as one glyph in the
19092 glyph matrix. There are no padding glyphs. */
19093 XChar2b char2b;
19094 XFontStruct *font;
19095 struct face *face = FACE_FROM_ID (it->f, it->face_id);
19096 XCharStruct *pcm;
19097 int font_not_found_p;
19098 struct font_info *font_info;
19099 int boff; /* baseline offset */
19100 struct composition *cmp = composition_table[it->cmp_id];
19102 /* Maybe translate single-byte characters to multibyte. */
19103 it->char_to_display = it->c;
19104 if (unibyte_display_via_language_environment
19105 && SINGLE_BYTE_CHAR_P (it->c)
19106 && (it->c >= 0240
19107 || (it->c >= 0200
19108 && !NILP (Vnonascii_translation_table))))
19110 it->char_to_display = unibyte_char_to_multibyte (it->c);
19113 /* Get face and font to use. Encode IT->char_to_display. */
19114 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
19115 face = FACE_FROM_ID (it->f, it->face_id);
19116 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
19117 &char2b, it->multibyte_p, 0);
19118 font = face->font;
19120 /* When no suitable font found, use the default font. */
19121 font_not_found_p = font == NULL;
19122 if (font_not_found_p)
19124 font = FRAME_FONT (it->f);
19125 boff = FRAME_BASELINE_OFFSET (it->f);
19126 font_info = NULL;
19128 else
19130 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
19131 boff = font_info->baseline_offset;
19132 if (font_info->vertical_centering)
19133 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
19136 /* There are no padding glyphs, so there is only one glyph to
19137 produce for the composition. Important is that pixel_width,
19138 ascent and descent are the values of what is drawn by
19139 draw_glyphs (i.e. the values of the overall glyphs composed). */
19140 it->nglyphs = 1;
19142 /* If we have not yet calculated pixel size data of glyphs of
19143 the composition for the current face font, calculate them
19144 now. Theoretically, we have to check all fonts for the
19145 glyphs, but that requires much time and memory space. So,
19146 here we check only the font of the first glyph. This leads
19147 to incorrect display very rarely, and C-l (recenter) can
19148 correct the display anyway. */
19149 if (cmp->font != (void *) font)
19151 /* Ascent and descent of the font of the first character of
19152 this composition (adjusted by baseline offset). Ascent
19153 and descent of overall glyphs should not be less than
19154 them respectively. */
19155 int font_ascent = FONT_BASE (font) + boff;
19156 int font_descent = FONT_DESCENT (font) - boff;
19157 /* Bounding box of the overall glyphs. */
19158 int leftmost, rightmost, lowest, highest;
19159 int i, width, ascent, descent;
19161 cmp->font = (void *) font;
19163 /* Initialize the bounding box. */
19164 if (font_info
19165 && (pcm = rif->per_char_metric (font, &char2b,
19166 FONT_TYPE_FOR_MULTIBYTE (font, it->c))))
19168 width = pcm->width;
19169 ascent = pcm->ascent;
19170 descent = pcm->descent;
19172 else
19174 width = FONT_WIDTH (font);
19175 ascent = FONT_BASE (font);
19176 descent = FONT_DESCENT (font);
19179 rightmost = width;
19180 lowest = - descent + boff;
19181 highest = ascent + boff;
19182 leftmost = 0;
19184 if (font_info
19185 && font_info->default_ascent
19186 && CHAR_TABLE_P (Vuse_default_ascent)
19187 && !NILP (Faref (Vuse_default_ascent,
19188 make_number (it->char_to_display))))
19189 highest = font_info->default_ascent + boff;
19191 /* Draw the first glyph at the normal position. It may be
19192 shifted to right later if some other glyphs are drawn at
19193 the left. */
19194 cmp->offsets[0] = 0;
19195 cmp->offsets[1] = boff;
19197 /* Set cmp->offsets for the remaining glyphs. */
19198 for (i = 1; i < cmp->glyph_len; i++)
19200 int left, right, btm, top;
19201 int ch = COMPOSITION_GLYPH (cmp, i);
19202 int face_id = FACE_FOR_CHAR (it->f, face, ch);
19204 face = FACE_FROM_ID (it->f, face_id);
19205 get_char_face_and_encoding (it->f, ch, face->id,
19206 &char2b, it->multibyte_p, 0);
19207 font = face->font;
19208 if (font == NULL)
19210 font = FRAME_FONT (it->f);
19211 boff = FRAME_BASELINE_OFFSET (it->f);
19212 font_info = NULL;
19214 else
19216 font_info
19217 = FONT_INFO_FROM_ID (it->f, face->font_info_id);
19218 boff = font_info->baseline_offset;
19219 if (font_info->vertical_centering)
19220 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
19223 if (font_info
19224 && (pcm = rif->per_char_metric (font, &char2b,
19225 FONT_TYPE_FOR_MULTIBYTE (font, ch))))
19227 width = pcm->width;
19228 ascent = pcm->ascent;
19229 descent = pcm->descent;
19231 else
19233 width = FONT_WIDTH (font);
19234 ascent = 1;
19235 descent = 0;
19238 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
19240 /* Relative composition with or without
19241 alternate chars. */
19242 left = (leftmost + rightmost - width) / 2;
19243 btm = - descent + boff;
19244 if (font_info && font_info->relative_compose
19245 && (! CHAR_TABLE_P (Vignore_relative_composition)
19246 || NILP (Faref (Vignore_relative_composition,
19247 make_number (ch)))))
19250 if (- descent >= font_info->relative_compose)
19251 /* One extra pixel between two glyphs. */
19252 btm = highest + 1;
19253 else if (ascent <= 0)
19254 /* One extra pixel between two glyphs. */
19255 btm = lowest - 1 - ascent - descent;
19258 else
19260 /* A composition rule is specified by an integer
19261 value that encodes global and new reference
19262 points (GREF and NREF). GREF and NREF are
19263 specified by numbers as below:
19265 0---1---2 -- ascent
19269 9--10--11 -- center
19271 ---3---4---5--- baseline
19273 6---7---8 -- descent
19275 int rule = COMPOSITION_RULE (cmp, i);
19276 int gref, nref, grefx, grefy, nrefx, nrefy;
19278 COMPOSITION_DECODE_RULE (rule, gref, nref);
19279 grefx = gref % 3, nrefx = nref % 3;
19280 grefy = gref / 3, nrefy = nref / 3;
19282 left = (leftmost
19283 + grefx * (rightmost - leftmost) / 2
19284 - nrefx * width / 2);
19285 btm = ((grefy == 0 ? highest
19286 : grefy == 1 ? 0
19287 : grefy == 2 ? lowest
19288 : (highest + lowest) / 2)
19289 - (nrefy == 0 ? ascent + descent
19290 : nrefy == 1 ? descent - boff
19291 : nrefy == 2 ? 0
19292 : (ascent + descent) / 2));
19295 cmp->offsets[i * 2] = left;
19296 cmp->offsets[i * 2 + 1] = btm + descent;
19298 /* Update the bounding box of the overall glyphs. */
19299 right = left + width;
19300 top = btm + descent + ascent;
19301 if (left < leftmost)
19302 leftmost = left;
19303 if (right > rightmost)
19304 rightmost = right;
19305 if (top > highest)
19306 highest = top;
19307 if (btm < lowest)
19308 lowest = btm;
19311 /* If there are glyphs whose x-offsets are negative,
19312 shift all glyphs to the right and make all x-offsets
19313 non-negative. */
19314 if (leftmost < 0)
19316 for (i = 0; i < cmp->glyph_len; i++)
19317 cmp->offsets[i * 2] -= leftmost;
19318 rightmost -= leftmost;
19321 cmp->pixel_width = rightmost;
19322 cmp->ascent = highest;
19323 cmp->descent = - lowest;
19324 if (cmp->ascent < font_ascent)
19325 cmp->ascent = font_ascent;
19326 if (cmp->descent < font_descent)
19327 cmp->descent = font_descent;
19330 it->pixel_width = cmp->pixel_width;
19331 it->ascent = it->phys_ascent = cmp->ascent;
19332 it->descent = it->phys_descent = cmp->descent;
19334 if (face->box != FACE_NO_BOX)
19336 int thick = face->box_line_width;
19338 if (thick > 0)
19340 it->ascent += thick;
19341 it->descent += thick;
19343 else
19344 thick = - thick;
19346 if (it->start_of_box_run_p)
19347 it->pixel_width += thick;
19348 if (it->end_of_box_run_p)
19349 it->pixel_width += thick;
19352 /* If face has an overline, add the height of the overline
19353 (1 pixel) and a 1 pixel margin to the character height. */
19354 if (face->overline_p)
19355 it->ascent += 2;
19357 take_vertical_position_into_account (it);
19359 if (it->glyph_row)
19360 append_composite_glyph (it);
19362 else if (it->what == IT_IMAGE)
19363 produce_image_glyph (it);
19364 else if (it->what == IT_STRETCH)
19365 produce_stretch_glyph (it);
19367 /* Accumulate dimensions. Note: can't assume that it->descent > 0
19368 because this isn't true for images with `:ascent 100'. */
19369 xassert (it->ascent >= 0 && it->descent >= 0);
19370 if (it->area == TEXT_AREA)
19371 it->current_x += it->pixel_width;
19373 if (extra_line_spacing > 0)
19374 it->descent += extra_line_spacing;
19376 it->max_ascent = max (it->max_ascent, it->ascent);
19377 it->max_descent = max (it->max_descent, it->descent);
19378 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
19379 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
19382 /* EXPORT for RIF:
19383 Output LEN glyphs starting at START at the nominal cursor position.
19384 Advance the nominal cursor over the text. The global variable
19385 updated_window contains the window being updated, updated_row is
19386 the glyph row being updated, and updated_area is the area of that
19387 row being updated. */
19389 void
19390 x_write_glyphs (start, len)
19391 struct glyph *start;
19392 int len;
19394 int x, hpos;
19396 xassert (updated_window && updated_row);
19397 BLOCK_INPUT;
19399 /* Write glyphs. */
19401 hpos = start - updated_row->glyphs[updated_area];
19402 x = draw_glyphs (updated_window, output_cursor.x,
19403 updated_row, updated_area,
19404 hpos, hpos + len,
19405 DRAW_NORMAL_TEXT, 0);
19407 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
19408 if (updated_area == TEXT_AREA
19409 && updated_window->phys_cursor_on_p
19410 && updated_window->phys_cursor.vpos == output_cursor.vpos
19411 && updated_window->phys_cursor.hpos >= hpos
19412 && updated_window->phys_cursor.hpos < hpos + len)
19413 updated_window->phys_cursor_on_p = 0;
19415 UNBLOCK_INPUT;
19417 /* Advance the output cursor. */
19418 output_cursor.hpos += len;
19419 output_cursor.x = x;
19423 /* EXPORT for RIF:
19424 Insert LEN glyphs from START at the nominal cursor position. */
19426 void
19427 x_insert_glyphs (start, len)
19428 struct glyph *start;
19429 int len;
19431 struct frame *f;
19432 struct window *w;
19433 int line_height, shift_by_width, shifted_region_width;
19434 struct glyph_row *row;
19435 struct glyph *glyph;
19436 int frame_x, frame_y, hpos;
19438 xassert (updated_window && updated_row);
19439 BLOCK_INPUT;
19440 w = updated_window;
19441 f = XFRAME (WINDOW_FRAME (w));
19443 /* Get the height of the line we are in. */
19444 row = updated_row;
19445 line_height = row->height;
19447 /* Get the width of the glyphs to insert. */
19448 shift_by_width = 0;
19449 for (glyph = start; glyph < start + len; ++glyph)
19450 shift_by_width += glyph->pixel_width;
19452 /* Get the width of the region to shift right. */
19453 shifted_region_width = (window_box_width (w, updated_area)
19454 - output_cursor.x
19455 - shift_by_width);
19457 /* Shift right. */
19458 frame_x = window_box_left (w, updated_area) + output_cursor.x;
19459 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
19461 rif->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
19462 line_height, shift_by_width);
19464 /* Write the glyphs. */
19465 hpos = start - row->glyphs[updated_area];
19466 draw_glyphs (w, output_cursor.x, row, updated_area,
19467 hpos, hpos + len,
19468 DRAW_NORMAL_TEXT, 0);
19470 /* Advance the output cursor. */
19471 output_cursor.hpos += len;
19472 output_cursor.x += shift_by_width;
19473 UNBLOCK_INPUT;
19477 /* EXPORT for RIF:
19478 Erase the current text line from the nominal cursor position
19479 (inclusive) to pixel column TO_X (exclusive). The idea is that
19480 everything from TO_X onward is already erased.
19482 TO_X is a pixel position relative to updated_area of
19483 updated_window. TO_X == -1 means clear to the end of this area. */
19485 void
19486 x_clear_end_of_line (to_x)
19487 int to_x;
19489 struct frame *f;
19490 struct window *w = updated_window;
19491 int max_x, min_y, max_y;
19492 int from_x, from_y, to_y;
19494 xassert (updated_window && updated_row);
19495 f = XFRAME (w->frame);
19497 if (updated_row->full_width_p)
19498 max_x = WINDOW_TOTAL_WIDTH (w);
19499 else
19500 max_x = window_box_width (w, updated_area);
19501 max_y = window_text_bottom_y (w);
19503 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
19504 of window. For TO_X > 0, truncate to end of drawing area. */
19505 if (to_x == 0)
19506 return;
19507 else if (to_x < 0)
19508 to_x = max_x;
19509 else
19510 to_x = min (to_x, max_x);
19512 to_y = min (max_y, output_cursor.y + updated_row->height);
19514 /* Notice if the cursor will be cleared by this operation. */
19515 if (!updated_row->full_width_p)
19516 notice_overwritten_cursor (w, updated_area,
19517 output_cursor.x, -1,
19518 updated_row->y,
19519 MATRIX_ROW_BOTTOM_Y (updated_row));
19521 from_x = output_cursor.x;
19523 /* Translate to frame coordinates. */
19524 if (updated_row->full_width_p)
19526 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
19527 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
19529 else
19531 int area_left = window_box_left (w, updated_area);
19532 from_x += area_left;
19533 to_x += area_left;
19536 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
19537 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
19538 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
19540 /* Prevent inadvertently clearing to end of the X window. */
19541 if (to_x > from_x && to_y > from_y)
19543 BLOCK_INPUT;
19544 rif->clear_frame_area (f, from_x, from_y,
19545 to_x - from_x, to_y - from_y);
19546 UNBLOCK_INPUT;
19550 #endif /* HAVE_WINDOW_SYSTEM */
19554 /***********************************************************************
19555 Cursor types
19556 ***********************************************************************/
19558 /* Value is the internal representation of the specified cursor type
19559 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
19560 of the bar cursor. */
19562 static enum text_cursor_kinds
19563 get_specified_cursor_type (arg, width)
19564 Lisp_Object arg;
19565 int *width;
19567 enum text_cursor_kinds type;
19569 if (NILP (arg))
19570 return NO_CURSOR;
19572 if (EQ (arg, Qbox))
19573 return FILLED_BOX_CURSOR;
19575 if (EQ (arg, Qhollow))
19576 return HOLLOW_BOX_CURSOR;
19578 if (EQ (arg, Qbar))
19580 *width = 2;
19581 return BAR_CURSOR;
19584 if (CONSP (arg)
19585 && EQ (XCAR (arg), Qbar)
19586 && INTEGERP (XCDR (arg))
19587 && XINT (XCDR (arg)) >= 0)
19589 *width = XINT (XCDR (arg));
19590 return BAR_CURSOR;
19593 if (EQ (arg, Qhbar))
19595 *width = 2;
19596 return HBAR_CURSOR;
19599 if (CONSP (arg)
19600 && EQ (XCAR (arg), Qhbar)
19601 && INTEGERP (XCDR (arg))
19602 && XINT (XCDR (arg)) >= 0)
19604 *width = XINT (XCDR (arg));
19605 return HBAR_CURSOR;
19608 /* Treat anything unknown as "hollow box cursor".
19609 It was bad to signal an error; people have trouble fixing
19610 .Xdefaults with Emacs, when it has something bad in it. */
19611 type = HOLLOW_BOX_CURSOR;
19613 return type;
19616 /* Set the default cursor types for specified frame. */
19617 void
19618 set_frame_cursor_types (f, arg)
19619 struct frame *f;
19620 Lisp_Object arg;
19622 int width;
19623 Lisp_Object tem;
19625 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
19626 FRAME_CURSOR_WIDTH (f) = width;
19628 /* By default, set up the blink-off state depending on the on-state. */
19630 tem = Fassoc (arg, Vblink_cursor_alist);
19631 if (!NILP (tem))
19633 FRAME_BLINK_OFF_CURSOR (f)
19634 = get_specified_cursor_type (XCDR (tem), &width);
19635 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
19637 else
19638 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
19642 /* Return the cursor we want to be displayed in window W. Return
19643 width of bar/hbar cursor through WIDTH arg. Return with
19644 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
19645 (i.e. if the `system caret' should track this cursor).
19647 In a mini-buffer window, we want the cursor only to appear if we
19648 are reading input from this window. For the selected window, we
19649 want the cursor type given by the frame parameter or buffer local
19650 setting of cursor-type. If explicitly marked off, draw no cursor.
19651 In all other cases, we want a hollow box cursor. */
19653 static enum text_cursor_kinds
19654 get_window_cursor_type (w, glyph, width, active_cursor)
19655 struct window *w;
19656 struct glyph *glyph;
19657 int *width;
19658 int *active_cursor;
19660 struct frame *f = XFRAME (w->frame);
19661 struct buffer *b = XBUFFER (w->buffer);
19662 int cursor_type = DEFAULT_CURSOR;
19663 Lisp_Object alt_cursor;
19664 int non_selected = 0;
19666 *active_cursor = 1;
19668 /* Echo area */
19669 if (cursor_in_echo_area
19670 && FRAME_HAS_MINIBUF_P (f)
19671 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
19673 if (w == XWINDOW (echo_area_window))
19675 *width = FRAME_CURSOR_WIDTH (f);
19676 return FRAME_DESIRED_CURSOR (f);
19679 *active_cursor = 0;
19680 non_selected = 1;
19683 /* Nonselected window or nonselected frame. */
19684 else if (w != XWINDOW (f->selected_window)
19685 #ifdef HAVE_WINDOW_SYSTEM
19686 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame
19687 #endif
19690 *active_cursor = 0;
19692 if (MINI_WINDOW_P (w) && minibuf_level == 0)
19693 return NO_CURSOR;
19695 non_selected = 1;
19698 /* Never display a cursor in a window in which cursor-type is nil. */
19699 if (NILP (b->cursor_type))
19700 return NO_CURSOR;
19702 /* Use cursor-in-non-selected-windows for non-selected window or frame. */
19703 if (non_selected)
19705 alt_cursor = Fbuffer_local_value (Qcursor_in_non_selected_windows, w->buffer);
19706 return get_specified_cursor_type (alt_cursor, width);
19709 /* Get the normal cursor type for this window. */
19710 if (EQ (b->cursor_type, Qt))
19712 cursor_type = FRAME_DESIRED_CURSOR (f);
19713 *width = FRAME_CURSOR_WIDTH (f);
19715 else
19716 cursor_type = get_specified_cursor_type (b->cursor_type, width);
19718 /* Use normal cursor if not blinked off. */
19719 if (!w->cursor_off_p)
19721 if (glyph != NULL && glyph->type == IMAGE_GLYPH) {
19722 if (cursor_type == FILLED_BOX_CURSOR)
19723 cursor_type = HOLLOW_BOX_CURSOR;
19725 return cursor_type;
19728 /* Cursor is blinked off, so determine how to "toggle" it. */
19730 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
19731 if ((alt_cursor = Fassoc (b->cursor_type, Vblink_cursor_alist), !NILP (alt_cursor)))
19732 return get_specified_cursor_type (XCDR (alt_cursor), width);
19734 /* Then see if frame has specified a specific blink off cursor type. */
19735 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
19737 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
19738 return FRAME_BLINK_OFF_CURSOR (f);
19741 #if 0
19742 /* Some people liked having a permanently visible blinking cursor,
19743 while others had very strong opinions against it. So it was
19744 decided to remove it. KFS 2003-09-03 */
19746 /* Finally perform built-in cursor blinking:
19747 filled box <-> hollow box
19748 wide [h]bar <-> narrow [h]bar
19749 narrow [h]bar <-> no cursor
19750 other type <-> no cursor */
19752 if (cursor_type == FILLED_BOX_CURSOR)
19753 return HOLLOW_BOX_CURSOR;
19755 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
19757 *width = 1;
19758 return cursor_type;
19760 #endif
19762 return NO_CURSOR;
19766 #ifdef HAVE_WINDOW_SYSTEM
19768 /* Notice when the text cursor of window W has been completely
19769 overwritten by a drawing operation that outputs glyphs in AREA
19770 starting at X0 and ending at X1 in the line starting at Y0 and
19771 ending at Y1. X coordinates are area-relative. X1 < 0 means all
19772 the rest of the line after X0 has been written. Y coordinates
19773 are window-relative. */
19775 static void
19776 notice_overwritten_cursor (w, area, x0, x1, y0, y1)
19777 struct window *w;
19778 enum glyph_row_area area;
19779 int x0, y0, x1, y1;
19781 int cx0, cx1, cy0, cy1;
19782 struct glyph_row *row;
19784 if (!w->phys_cursor_on_p)
19785 return;
19786 if (area != TEXT_AREA)
19787 return;
19789 row = w->current_matrix->rows + w->phys_cursor.vpos;
19790 if (!row->displays_text_p)
19791 return;
19793 if (row->cursor_in_fringe_p)
19795 row->cursor_in_fringe_p = 0;
19796 draw_fringe_bitmap (w, row, 0);
19797 w->phys_cursor_on_p = 0;
19798 return;
19801 cx0 = w->phys_cursor.x;
19802 cx1 = cx0 + w->phys_cursor_width;
19803 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
19804 return;
19806 /* The cursor image will be completely removed from the
19807 screen if the output area intersects the cursor area in
19808 y-direction. When we draw in [y0 y1[, and some part of
19809 the cursor is at y < y0, that part must have been drawn
19810 before. When scrolling, the cursor is erased before
19811 actually scrolling, so we don't come here. When not
19812 scrolling, the rows above the old cursor row must have
19813 changed, and in this case these rows must have written
19814 over the cursor image.
19816 Likewise if part of the cursor is below y1, with the
19817 exception of the cursor being in the first blank row at
19818 the buffer and window end because update_text_area
19819 doesn't draw that row. (Except when it does, but
19820 that's handled in update_text_area.) */
19822 cy0 = w->phys_cursor.y;
19823 cy1 = cy0 + w->phys_cursor_height;
19824 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
19825 return;
19827 w->phys_cursor_on_p = 0;
19830 #endif /* HAVE_WINDOW_SYSTEM */
19833 /************************************************************************
19834 Mouse Face
19835 ************************************************************************/
19837 #ifdef HAVE_WINDOW_SYSTEM
19839 /* EXPORT for RIF:
19840 Fix the display of area AREA of overlapping row ROW in window W. */
19842 void
19843 x_fix_overlapping_area (w, row, area)
19844 struct window *w;
19845 struct glyph_row *row;
19846 enum glyph_row_area area;
19848 int i, x;
19850 BLOCK_INPUT;
19852 x = 0;
19853 for (i = 0; i < row->used[area];)
19855 if (row->glyphs[area][i].overlaps_vertically_p)
19857 int start = i, start_x = x;
19861 x += row->glyphs[area][i].pixel_width;
19862 ++i;
19864 while (i < row->used[area]
19865 && row->glyphs[area][i].overlaps_vertically_p);
19867 draw_glyphs (w, start_x, row, area,
19868 start, i,
19869 DRAW_NORMAL_TEXT, 1);
19871 else
19873 x += row->glyphs[area][i].pixel_width;
19874 ++i;
19878 UNBLOCK_INPUT;
19882 /* EXPORT:
19883 Draw the cursor glyph of window W in glyph row ROW. See the
19884 comment of draw_glyphs for the meaning of HL. */
19886 void
19887 draw_phys_cursor_glyph (w, row, hl)
19888 struct window *w;
19889 struct glyph_row *row;
19890 enum draw_glyphs_face hl;
19892 /* If cursor hpos is out of bounds, don't draw garbage. This can
19893 happen in mini-buffer windows when switching between echo area
19894 glyphs and mini-buffer. */
19895 if (w->phys_cursor.hpos < row->used[TEXT_AREA])
19897 int on_p = w->phys_cursor_on_p;
19898 int x1;
19899 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
19900 w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
19901 hl, 0);
19902 w->phys_cursor_on_p = on_p;
19904 if (hl == DRAW_CURSOR)
19905 w->phys_cursor_width = x1 - w->phys_cursor.x;
19906 /* When we erase the cursor, and ROW is overlapped by other
19907 rows, make sure that these overlapping parts of other rows
19908 are redrawn. */
19909 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
19911 if (row > w->current_matrix->rows
19912 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
19913 x_fix_overlapping_area (w, row - 1, TEXT_AREA);
19915 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
19916 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
19917 x_fix_overlapping_area (w, row + 1, TEXT_AREA);
19923 /* EXPORT:
19924 Erase the image of a cursor of window W from the screen. */
19926 void
19927 erase_phys_cursor (w)
19928 struct window *w;
19930 struct frame *f = XFRAME (w->frame);
19931 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
19932 int hpos = w->phys_cursor.hpos;
19933 int vpos = w->phys_cursor.vpos;
19934 int mouse_face_here_p = 0;
19935 struct glyph_matrix *active_glyphs = w->current_matrix;
19936 struct glyph_row *cursor_row;
19937 struct glyph *cursor_glyph;
19938 enum draw_glyphs_face hl;
19940 /* No cursor displayed or row invalidated => nothing to do on the
19941 screen. */
19942 if (w->phys_cursor_type == NO_CURSOR)
19943 goto mark_cursor_off;
19945 /* VPOS >= active_glyphs->nrows means that window has been resized.
19946 Don't bother to erase the cursor. */
19947 if (vpos >= active_glyphs->nrows)
19948 goto mark_cursor_off;
19950 /* If row containing cursor is marked invalid, there is nothing we
19951 can do. */
19952 cursor_row = MATRIX_ROW (active_glyphs, vpos);
19953 if (!cursor_row->enabled_p)
19954 goto mark_cursor_off;
19956 /* If row is completely invisible, don't attempt to delete a cursor which
19957 isn't there. This can happen if cursor is at top of a window, and
19958 we switch to a buffer with a header line in that window. */
19959 if (cursor_row->visible_height <= 0)
19960 goto mark_cursor_off;
19962 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
19963 if (cursor_row->cursor_in_fringe_p)
19965 cursor_row->cursor_in_fringe_p = 0;
19966 draw_fringe_bitmap (w, cursor_row, 0);
19967 goto mark_cursor_off;
19970 /* This can happen when the new row is shorter than the old one.
19971 In this case, either draw_glyphs or clear_end_of_line
19972 should have cleared the cursor. Note that we wouldn't be
19973 able to erase the cursor in this case because we don't have a
19974 cursor glyph at hand. */
19975 if (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])
19976 goto mark_cursor_off;
19978 /* If the cursor is in the mouse face area, redisplay that when
19979 we clear the cursor. */
19980 if (! NILP (dpyinfo->mouse_face_window)
19981 && w == XWINDOW (dpyinfo->mouse_face_window)
19982 && (vpos > dpyinfo->mouse_face_beg_row
19983 || (vpos == dpyinfo->mouse_face_beg_row
19984 && hpos >= dpyinfo->mouse_face_beg_col))
19985 && (vpos < dpyinfo->mouse_face_end_row
19986 || (vpos == dpyinfo->mouse_face_end_row
19987 && hpos < dpyinfo->mouse_face_end_col))
19988 /* Don't redraw the cursor's spot in mouse face if it is at the
19989 end of a line (on a newline). The cursor appears there, but
19990 mouse highlighting does not. */
19991 && cursor_row->used[TEXT_AREA] > hpos)
19992 mouse_face_here_p = 1;
19994 /* Maybe clear the display under the cursor. */
19995 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
19997 int x, y;
19998 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
20000 cursor_glyph = get_phys_cursor_glyph (w);
20001 if (cursor_glyph == NULL)
20002 goto mark_cursor_off;
20004 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
20005 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
20007 rif->clear_frame_area (f, x, y,
20008 cursor_glyph->pixel_width, cursor_row->visible_height);
20011 /* Erase the cursor by redrawing the character underneath it. */
20012 if (mouse_face_here_p)
20013 hl = DRAW_MOUSE_FACE;
20014 else
20015 hl = DRAW_NORMAL_TEXT;
20016 draw_phys_cursor_glyph (w, cursor_row, hl);
20018 mark_cursor_off:
20019 w->phys_cursor_on_p = 0;
20020 w->phys_cursor_type = NO_CURSOR;
20024 /* EXPORT:
20025 Display or clear cursor of window W. If ON is zero, clear the
20026 cursor. If it is non-zero, display the cursor. If ON is nonzero,
20027 where to put the cursor is specified by HPOS, VPOS, X and Y. */
20029 void
20030 display_and_set_cursor (w, on, hpos, vpos, x, y)
20031 struct window *w;
20032 int on, hpos, vpos, x, y;
20034 struct frame *f = XFRAME (w->frame);
20035 int new_cursor_type;
20036 int new_cursor_width;
20037 int active_cursor;
20038 struct glyph_row *glyph_row;
20039 struct glyph *glyph;
20041 /* This is pointless on invisible frames, and dangerous on garbaged
20042 windows and frames; in the latter case, the frame or window may
20043 be in the midst of changing its size, and x and y may be off the
20044 window. */
20045 if (! FRAME_VISIBLE_P (f)
20046 || FRAME_GARBAGED_P (f)
20047 || vpos >= w->current_matrix->nrows
20048 || hpos >= w->current_matrix->matrix_w)
20049 return;
20051 /* If cursor is off and we want it off, return quickly. */
20052 if (!on && !w->phys_cursor_on_p)
20053 return;
20055 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
20056 /* If cursor row is not enabled, we don't really know where to
20057 display the cursor. */
20058 if (!glyph_row->enabled_p)
20060 w->phys_cursor_on_p = 0;
20061 return;
20064 glyph = NULL;
20065 if (!glyph_row->exact_window_width_line_p
20066 || hpos < glyph_row->used[TEXT_AREA])
20067 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
20069 xassert (interrupt_input_blocked);
20071 /* Set new_cursor_type to the cursor we want to be displayed. */
20072 new_cursor_type = get_window_cursor_type (w, glyph,
20073 &new_cursor_width, &active_cursor);
20075 /* If cursor is currently being shown and we don't want it to be or
20076 it is in the wrong place, or the cursor type is not what we want,
20077 erase it. */
20078 if (w->phys_cursor_on_p
20079 && (!on
20080 || w->phys_cursor.x != x
20081 || w->phys_cursor.y != y
20082 || new_cursor_type != w->phys_cursor_type
20083 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
20084 && new_cursor_width != w->phys_cursor_width)))
20085 erase_phys_cursor (w);
20087 /* Don't check phys_cursor_on_p here because that flag is only set
20088 to zero in some cases where we know that the cursor has been
20089 completely erased, to avoid the extra work of erasing the cursor
20090 twice. In other words, phys_cursor_on_p can be 1 and the cursor
20091 still not be visible, or it has only been partly erased. */
20092 if (on)
20094 w->phys_cursor_ascent = glyph_row->ascent;
20095 w->phys_cursor_height = glyph_row->height;
20097 /* Set phys_cursor_.* before x_draw_.* is called because some
20098 of them may need the information. */
20099 w->phys_cursor.x = x;
20100 w->phys_cursor.y = glyph_row->y;
20101 w->phys_cursor.hpos = hpos;
20102 w->phys_cursor.vpos = vpos;
20105 rif->draw_window_cursor (w, glyph_row, x, y,
20106 new_cursor_type, new_cursor_width,
20107 on, active_cursor);
20111 /* Switch the display of W's cursor on or off, according to the value
20112 of ON. */
20114 static void
20115 update_window_cursor (w, on)
20116 struct window *w;
20117 int on;
20119 /* Don't update cursor in windows whose frame is in the process
20120 of being deleted. */
20121 if (w->current_matrix)
20123 BLOCK_INPUT;
20124 display_and_set_cursor (w, on, w->phys_cursor.hpos, w->phys_cursor.vpos,
20125 w->phys_cursor.x, w->phys_cursor.y);
20126 UNBLOCK_INPUT;
20131 /* Call update_window_cursor with parameter ON_P on all leaf windows
20132 in the window tree rooted at W. */
20134 static void
20135 update_cursor_in_window_tree (w, on_p)
20136 struct window *w;
20137 int on_p;
20139 while (w)
20141 if (!NILP (w->hchild))
20142 update_cursor_in_window_tree (XWINDOW (w->hchild), on_p);
20143 else if (!NILP (w->vchild))
20144 update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
20145 else
20146 update_window_cursor (w, on_p);
20148 w = NILP (w->next) ? 0 : XWINDOW (w->next);
20153 /* EXPORT:
20154 Display the cursor on window W, or clear it, according to ON_P.
20155 Don't change the cursor's position. */
20157 void
20158 x_update_cursor (f, on_p)
20159 struct frame *f;
20160 int on_p;
20162 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
20166 /* EXPORT:
20167 Clear the cursor of window W to background color, and mark the
20168 cursor as not shown. This is used when the text where the cursor
20169 is is about to be rewritten. */
20171 void
20172 x_clear_cursor (w)
20173 struct window *w;
20175 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
20176 update_window_cursor (w, 0);
20180 /* EXPORT:
20181 Display the active region described by mouse_face_* according to DRAW. */
20183 void
20184 show_mouse_face (dpyinfo, draw)
20185 Display_Info *dpyinfo;
20186 enum draw_glyphs_face draw;
20188 struct window *w = XWINDOW (dpyinfo->mouse_face_window);
20189 struct frame *f = XFRAME (WINDOW_FRAME (w));
20191 if (/* If window is in the process of being destroyed, don't bother
20192 to do anything. */
20193 w->current_matrix != NULL
20194 /* Don't update mouse highlight if hidden */
20195 && (draw != DRAW_MOUSE_FACE || !dpyinfo->mouse_face_hidden)
20196 /* Recognize when we are called to operate on rows that don't exist
20197 anymore. This can happen when a window is split. */
20198 && dpyinfo->mouse_face_end_row < w->current_matrix->nrows)
20200 int phys_cursor_on_p = w->phys_cursor_on_p;
20201 struct glyph_row *row, *first, *last;
20203 first = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row);
20204 last = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row);
20206 for (row = first; row <= last && row->enabled_p; ++row)
20208 int start_hpos, end_hpos, start_x;
20210 /* For all but the first row, the highlight starts at column 0. */
20211 if (row == first)
20213 start_hpos = dpyinfo->mouse_face_beg_col;
20214 start_x = dpyinfo->mouse_face_beg_x;
20216 else
20218 start_hpos = 0;
20219 start_x = 0;
20222 if (row == last)
20223 end_hpos = dpyinfo->mouse_face_end_col;
20224 else
20225 end_hpos = row->used[TEXT_AREA];
20227 if (end_hpos > start_hpos)
20229 draw_glyphs (w, start_x, row, TEXT_AREA,
20230 start_hpos, end_hpos,
20231 draw, 0);
20233 row->mouse_face_p
20234 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
20238 /* When we've written over the cursor, arrange for it to
20239 be displayed again. */
20240 if (phys_cursor_on_p && !w->phys_cursor_on_p)
20242 BLOCK_INPUT;
20243 display_and_set_cursor (w, 1,
20244 w->phys_cursor.hpos, w->phys_cursor.vpos,
20245 w->phys_cursor.x, w->phys_cursor.y);
20246 UNBLOCK_INPUT;
20250 /* Change the mouse cursor. */
20251 if (draw == DRAW_NORMAL_TEXT)
20252 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
20253 else if (draw == DRAW_MOUSE_FACE)
20254 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
20255 else
20256 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
20259 /* EXPORT:
20260 Clear out the mouse-highlighted active region.
20261 Redraw it un-highlighted first. Value is non-zero if mouse
20262 face was actually drawn unhighlighted. */
20265 clear_mouse_face (dpyinfo)
20266 Display_Info *dpyinfo;
20268 int cleared = 0;
20270 if (!dpyinfo->mouse_face_hidden && !NILP (dpyinfo->mouse_face_window))
20272 show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT);
20273 cleared = 1;
20276 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
20277 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
20278 dpyinfo->mouse_face_window = Qnil;
20279 dpyinfo->mouse_face_overlay = Qnil;
20280 return cleared;
20284 /* EXPORT:
20285 Non-zero if physical cursor of window W is within mouse face. */
20288 cursor_in_mouse_face_p (w)
20289 struct window *w;
20291 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
20292 int in_mouse_face = 0;
20294 if (WINDOWP (dpyinfo->mouse_face_window)
20295 && XWINDOW (dpyinfo->mouse_face_window) == w)
20297 int hpos = w->phys_cursor.hpos;
20298 int vpos = w->phys_cursor.vpos;
20300 if (vpos >= dpyinfo->mouse_face_beg_row
20301 && vpos <= dpyinfo->mouse_face_end_row
20302 && (vpos > dpyinfo->mouse_face_beg_row
20303 || hpos >= dpyinfo->mouse_face_beg_col)
20304 && (vpos < dpyinfo->mouse_face_end_row
20305 || hpos < dpyinfo->mouse_face_end_col
20306 || dpyinfo->mouse_face_past_end))
20307 in_mouse_face = 1;
20310 return in_mouse_face;
20316 /* Find the glyph matrix position of buffer position CHARPOS in window
20317 *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's
20318 current glyphs must be up to date. If CHARPOS is above window
20319 start return (0, 0, 0, 0). If CHARPOS is after end of W, return end
20320 of last line in W. In the row containing CHARPOS, stop before glyphs
20321 having STOP as object. */
20323 #if 1 /* This is a version of fast_find_position that's more correct
20324 in the presence of hscrolling, for example. I didn't install
20325 it right away because the problem fixed is minor, it failed
20326 in 20.x as well, and I think it's too risky to install
20327 so near the release of 21.1. 2001-09-25 gerd. */
20329 static int
20330 fast_find_position (w, charpos, hpos, vpos, x, y, stop)
20331 struct window *w;
20332 int charpos;
20333 int *hpos, *vpos, *x, *y;
20334 Lisp_Object stop;
20336 struct glyph_row *row, *first;
20337 struct glyph *glyph, *end;
20338 int past_end = 0;
20340 first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
20341 row = row_containing_pos (w, charpos, first, NULL, 0);
20342 if (row == NULL)
20344 if (charpos < MATRIX_ROW_START_CHARPOS (first))
20346 *x = *y = *hpos = *vpos = 0;
20347 return 1;
20349 else
20351 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
20352 past_end = 1;
20356 *x = row->x;
20357 *y = row->y;
20358 *vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
20360 glyph = row->glyphs[TEXT_AREA];
20361 end = glyph + row->used[TEXT_AREA];
20363 /* Skip over glyphs not having an object at the start of the row.
20364 These are special glyphs like truncation marks on terminal
20365 frames. */
20366 if (row->displays_text_p)
20367 while (glyph < end
20368 && INTEGERP (glyph->object)
20369 && !EQ (stop, glyph->object)
20370 && glyph->charpos < 0)
20372 *x += glyph->pixel_width;
20373 ++glyph;
20376 while (glyph < end
20377 && !INTEGERP (glyph->object)
20378 && !EQ (stop, glyph->object)
20379 && (!BUFFERP (glyph->object)
20380 || glyph->charpos < charpos))
20382 *x += glyph->pixel_width;
20383 ++glyph;
20386 *hpos = glyph - row->glyphs[TEXT_AREA];
20387 return !past_end;
20390 #else /* not 1 */
20392 static int
20393 fast_find_position (w, pos, hpos, vpos, x, y, stop)
20394 struct window *w;
20395 int pos;
20396 int *hpos, *vpos, *x, *y;
20397 Lisp_Object stop;
20399 int i;
20400 int lastcol;
20401 int maybe_next_line_p = 0;
20402 int line_start_position;
20403 int yb = window_text_bottom_y (w);
20404 struct glyph_row *row, *best_row;
20405 int row_vpos, best_row_vpos;
20406 int current_x;
20408 row = best_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
20409 row_vpos = best_row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
20411 while (row->y < yb)
20413 if (row->used[TEXT_AREA])
20414 line_start_position = row->glyphs[TEXT_AREA]->charpos;
20415 else
20416 line_start_position = 0;
20418 if (line_start_position > pos)
20419 break;
20420 /* If the position sought is the end of the buffer,
20421 don't include the blank lines at the bottom of the window. */
20422 else if (line_start_position == pos
20423 && pos == BUF_ZV (XBUFFER (w->buffer)))
20425 maybe_next_line_p = 1;
20426 break;
20428 else if (line_start_position > 0)
20430 best_row = row;
20431 best_row_vpos = row_vpos;
20434 if (row->y + row->height >= yb)
20435 break;
20437 ++row;
20438 ++row_vpos;
20441 /* Find the right column within BEST_ROW. */
20442 lastcol = 0;
20443 current_x = best_row->x;
20444 for (i = 0; i < best_row->used[TEXT_AREA]; i++)
20446 struct glyph *glyph = best_row->glyphs[TEXT_AREA] + i;
20447 int charpos = glyph->charpos;
20449 if (BUFFERP (glyph->object))
20451 if (charpos == pos)
20453 *hpos = i;
20454 *vpos = best_row_vpos;
20455 *x = current_x;
20456 *y = best_row->y;
20457 return 1;
20459 else if (charpos > pos)
20460 break;
20462 else if (EQ (glyph->object, stop))
20463 break;
20465 if (charpos > 0)
20466 lastcol = i;
20467 current_x += glyph->pixel_width;
20470 /* If we're looking for the end of the buffer,
20471 and we didn't find it in the line we scanned,
20472 use the start of the following line. */
20473 if (maybe_next_line_p)
20475 ++best_row;
20476 ++best_row_vpos;
20477 lastcol = 0;
20478 current_x = best_row->x;
20481 *vpos = best_row_vpos;
20482 *hpos = lastcol + 1;
20483 *x = current_x;
20484 *y = best_row->y;
20485 return 0;
20488 #endif /* not 1 */
20491 /* Find the position of the glyph for position POS in OBJECT in
20492 window W's current matrix, and return in *X, *Y the pixel
20493 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
20495 RIGHT_P non-zero means return the position of the right edge of the
20496 glyph, RIGHT_P zero means return the left edge position.
20498 If no glyph for POS exists in the matrix, return the position of
20499 the glyph with the next smaller position that is in the matrix, if
20500 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
20501 exists in the matrix, return the position of the glyph with the
20502 next larger position in OBJECT.
20504 Value is non-zero if a glyph was found. */
20506 static int
20507 fast_find_string_pos (w, pos, object, hpos, vpos, x, y, right_p)
20508 struct window *w;
20509 int pos;
20510 Lisp_Object object;
20511 int *hpos, *vpos, *x, *y;
20512 int right_p;
20514 int yb = window_text_bottom_y (w);
20515 struct glyph_row *r;
20516 struct glyph *best_glyph = NULL;
20517 struct glyph_row *best_row = NULL;
20518 int best_x = 0;
20520 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
20521 r->enabled_p && r->y < yb;
20522 ++r)
20524 struct glyph *g = r->glyphs[TEXT_AREA];
20525 struct glyph *e = g + r->used[TEXT_AREA];
20526 int gx;
20528 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
20529 if (EQ (g->object, object))
20531 if (g->charpos == pos)
20533 best_glyph = g;
20534 best_x = gx;
20535 best_row = r;
20536 goto found;
20538 else if (best_glyph == NULL
20539 || ((abs (g->charpos - pos)
20540 < abs (best_glyph->charpos - pos))
20541 && (right_p
20542 ? g->charpos < pos
20543 : g->charpos > pos)))
20545 best_glyph = g;
20546 best_x = gx;
20547 best_row = r;
20552 found:
20554 if (best_glyph)
20556 *x = best_x;
20557 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
20559 if (right_p)
20561 *x += best_glyph->pixel_width;
20562 ++*hpos;
20565 *y = best_row->y;
20566 *vpos = best_row - w->current_matrix->rows;
20569 return best_glyph != NULL;
20573 /* See if position X, Y is within a hot-spot of an image. */
20575 static int
20576 on_hot_spot_p (hot_spot, x, y)
20577 Lisp_Object hot_spot;
20578 int x, y;
20580 if (!CONSP (hot_spot))
20581 return 0;
20583 if (EQ (XCAR (hot_spot), Qrect))
20585 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
20586 Lisp_Object rect = XCDR (hot_spot);
20587 Lisp_Object tem;
20588 if (!CONSP (rect))
20589 return 0;
20590 if (!CONSP (XCAR (rect)))
20591 return 0;
20592 if (!CONSP (XCDR (rect)))
20593 return 0;
20594 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
20595 return 0;
20596 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
20597 return 0;
20598 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
20599 return 0;
20600 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
20601 return 0;
20602 return 1;
20604 else if (EQ (XCAR (hot_spot), Qcircle))
20606 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
20607 Lisp_Object circ = XCDR (hot_spot);
20608 Lisp_Object lr, lx0, ly0;
20609 if (CONSP (circ)
20610 && CONSP (XCAR (circ))
20611 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
20612 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
20613 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
20615 double r = XFLOATINT (lr);
20616 double dx = XINT (lx0) - x;
20617 double dy = XINT (ly0) - y;
20618 return (dx * dx + dy * dy <= r * r);
20621 else if (EQ (XCAR (hot_spot), Qpoly))
20623 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
20624 if (VECTORP (XCDR (hot_spot)))
20626 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
20627 Lisp_Object *poly = v->contents;
20628 int n = v->size;
20629 int i;
20630 int inside = 0;
20631 Lisp_Object lx, ly;
20632 int x0, y0;
20634 /* Need an even number of coordinates, and at least 3 edges. */
20635 if (n < 6 || n & 1)
20636 return 0;
20638 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
20639 If count is odd, we are inside polygon. Pixels on edges
20640 may or may not be included depending on actual geometry of the
20641 polygon. */
20642 if ((lx = poly[n-2], !INTEGERP (lx))
20643 || (ly = poly[n-1], !INTEGERP (lx)))
20644 return 0;
20645 x0 = XINT (lx), y0 = XINT (ly);
20646 for (i = 0; i < n; i += 2)
20648 int x1 = x0, y1 = y0;
20649 if ((lx = poly[i], !INTEGERP (lx))
20650 || (ly = poly[i+1], !INTEGERP (ly)))
20651 return 0;
20652 x0 = XINT (lx), y0 = XINT (ly);
20654 /* Does this segment cross the X line? */
20655 if (x0 >= x)
20657 if (x1 >= x)
20658 continue;
20660 else if (x1 < x)
20661 continue;
20662 if (y > y0 && y > y1)
20663 continue;
20664 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
20665 inside = !inside;
20667 return inside;
20670 /* If we don't understand the format, pretend we're not in the hot-spot. */
20671 return 0;
20674 Lisp_Object
20675 find_hot_spot (map, x, y)
20676 Lisp_Object map;
20677 int x, y;
20679 while (CONSP (map))
20681 if (CONSP (XCAR (map))
20682 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
20683 return XCAR (map);
20684 map = XCDR (map);
20687 return Qnil;
20690 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
20691 3, 3, 0,
20692 doc: /* Lookup in image map MAP coordinates X and Y.
20693 An image map is an alist where each element has the format (AREA ID PLIST).
20694 An AREA is specified as either a rectangle, a circle, or a polygon:
20695 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
20696 pixel coordinates of the upper left and bottom right corners.
20697 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
20698 and the radius of the circle; r may be a float or integer.
20699 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
20700 vector describes one corner in the polygon.
20701 Returns the alist element for the first matching AREA in MAP. */)
20702 (map, x, y)
20703 Lisp_Object map;
20704 Lisp_Object x, y;
20706 if (NILP (map))
20707 return Qnil;
20709 CHECK_NUMBER (x);
20710 CHECK_NUMBER (y);
20712 return find_hot_spot (map, XINT (x), XINT (y));
20716 /* Display frame CURSOR, optionally using shape defined by POINTER. */
20717 static void
20718 define_frame_cursor1 (f, cursor, pointer)
20719 struct frame *f;
20720 Cursor cursor;
20721 Lisp_Object pointer;
20723 if (!NILP (pointer))
20725 if (EQ (pointer, Qarrow))
20726 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20727 else if (EQ (pointer, Qhand))
20728 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
20729 else if (EQ (pointer, Qtext))
20730 cursor = FRAME_X_OUTPUT (f)->text_cursor;
20731 else if (EQ (pointer, intern ("hdrag")))
20732 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
20733 #ifdef HAVE_X_WINDOWS
20734 else if (EQ (pointer, intern ("vdrag")))
20735 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
20736 #endif
20737 else if (EQ (pointer, intern ("hourglass")))
20738 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
20739 else if (EQ (pointer, Qmodeline))
20740 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
20741 else
20742 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20745 if (cursor != No_Cursor)
20746 rif->define_frame_cursor (f, cursor);
20749 /* Take proper action when mouse has moved to the mode or header line
20750 or marginal area AREA of window W, x-position X and y-position Y.
20751 X is relative to the start of the text display area of W, so the
20752 width of bitmap areas and scroll bars must be subtracted to get a
20753 position relative to the start of the mode line. */
20755 static void
20756 note_mode_line_or_margin_highlight (w, x, y, area)
20757 struct window *w;
20758 int x, y;
20759 enum window_part area;
20761 struct frame *f = XFRAME (w->frame);
20762 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
20763 Cursor cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20764 Lisp_Object pointer = Qnil;
20765 int charpos, dx, dy, width, height;
20766 Lisp_Object string, object = Qnil;
20767 Lisp_Object pos, help;
20769 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
20770 string = mode_line_string (w, area, &x, &y, &charpos,
20771 &object, &dx, &dy, &width, &height);
20772 else
20774 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
20775 string = marginal_area_string (w, area, &x, &y, &charpos,
20776 &object, &dx, &dy, &width, &height);
20779 help = Qnil;
20781 if (IMAGEP (object))
20783 Lisp_Object image_map, hotspot;
20784 if ((image_map = Fplist_get (XCDR (object), QCmap),
20785 !NILP (image_map))
20786 && (hotspot = find_hot_spot (image_map, dx, dy),
20787 CONSP (hotspot))
20788 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
20790 Lisp_Object area_id, plist;
20792 area_id = XCAR (hotspot);
20793 /* Could check AREA_ID to see if we enter/leave this hot-spot.
20794 If so, we could look for mouse-enter, mouse-leave
20795 properties in PLIST (and do something...). */
20796 if ((plist = XCDR (hotspot), CONSP (plist)))
20798 pointer = Fplist_get (plist, Qpointer);
20799 if (NILP (pointer))
20800 pointer = Qhand;
20801 help = Fplist_get (plist, Qhelp_echo);
20802 if (!NILP (help))
20804 help_echo_string = help;
20805 /* Is this correct? ++kfs */
20806 XSETWINDOW (help_echo_window, w);
20807 help_echo_object = w->buffer;
20808 help_echo_pos = charpos;
20811 if (NILP (pointer))
20812 pointer = Fplist_get (XCDR (object), QCpointer);
20816 if (STRINGP (string))
20818 pos = make_number (charpos);
20819 /* If we're on a string with `help-echo' text property, arrange
20820 for the help to be displayed. This is done by setting the
20821 global variable help_echo_string to the help string. */
20822 help = Fget_text_property (pos, Qhelp_echo, string);
20823 if (!NILP (help))
20825 help_echo_string = help;
20826 XSETWINDOW (help_echo_window, w);
20827 help_echo_object = string;
20828 help_echo_pos = charpos;
20831 if (NILP (pointer))
20832 pointer = Fget_text_property (pos, Qpointer, string);
20834 /* Change the mouse pointer according to what is under X/Y. */
20835 if (NILP (pointer) && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
20837 Lisp_Object map;
20838 map = Fget_text_property (pos, Qlocal_map, string);
20839 if (!KEYMAPP (map))
20840 map = Fget_text_property (pos, Qkeymap, string);
20841 if (!KEYMAPP (map))
20842 cursor = dpyinfo->vertical_scroll_bar_cursor;
20846 define_frame_cursor1 (f, cursor, pointer);
20850 /* EXPORT:
20851 Take proper action when the mouse has moved to position X, Y on
20852 frame F as regards highlighting characters that have mouse-face
20853 properties. Also de-highlighting chars where the mouse was before.
20854 X and Y can be negative or out of range. */
20856 void
20857 note_mouse_highlight (f, x, y)
20858 struct frame *f;
20859 int x, y;
20861 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
20862 enum window_part part;
20863 Lisp_Object window;
20864 struct window *w;
20865 Cursor cursor = No_Cursor;
20866 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
20867 struct buffer *b;
20869 /* When a menu is active, don't highlight because this looks odd. */
20870 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NTGUI)
20871 if (popup_activated ())
20872 return;
20873 #endif
20875 if (NILP (Vmouse_highlight)
20876 || !f->glyphs_initialized_p)
20877 return;
20879 dpyinfo->mouse_face_mouse_x = x;
20880 dpyinfo->mouse_face_mouse_y = y;
20881 dpyinfo->mouse_face_mouse_frame = f;
20883 if (dpyinfo->mouse_face_defer)
20884 return;
20886 if (gc_in_progress)
20888 dpyinfo->mouse_face_deferred_gc = 1;
20889 return;
20892 /* Which window is that in? */
20893 window = window_from_coordinates (f, x, y, &part, 0, 0, 1);
20895 /* If we were displaying active text in another window, clear that. */
20896 if (! EQ (window, dpyinfo->mouse_face_window))
20897 clear_mouse_face (dpyinfo);
20899 /* Not on a window -> return. */
20900 if (!WINDOWP (window))
20901 return;
20903 /* Reset help_echo_string. It will get recomputed below. */
20904 help_echo_string = Qnil;
20906 /* Convert to window-relative pixel coordinates. */
20907 w = XWINDOW (window);
20908 frame_to_window_pixel_xy (w, &x, &y);
20910 /* Handle tool-bar window differently since it doesn't display a
20911 buffer. */
20912 if (EQ (window, f->tool_bar_window))
20914 note_tool_bar_highlight (f, x, y);
20915 return;
20918 /* Mouse is on the mode, header line or margin? */
20919 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
20920 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
20922 note_mode_line_or_margin_highlight (w, x, y, part);
20923 return;
20926 if (part == ON_VERTICAL_BORDER)
20927 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
20928 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
20929 || part == ON_SCROLL_BAR)
20930 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20931 else
20932 cursor = FRAME_X_OUTPUT (f)->text_cursor;
20934 /* Are we in a window whose display is up to date?
20935 And verify the buffer's text has not changed. */
20936 b = XBUFFER (w->buffer);
20937 if (part == ON_TEXT
20938 && EQ (w->window_end_valid, w->buffer)
20939 && XFASTINT (w->last_modified) == BUF_MODIFF (b)
20940 && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
20942 int hpos, vpos, pos, i, dx, dy, area;
20943 struct glyph *glyph;
20944 Lisp_Object object;
20945 Lisp_Object mouse_face = Qnil, overlay = Qnil, position;
20946 Lisp_Object *overlay_vec = NULL;
20947 int noverlays;
20948 struct buffer *obuf;
20949 int obegv, ozv, same_region;
20951 /* Find the glyph under X/Y. */
20952 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
20954 /* Look for :pointer property on image. */
20955 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
20957 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
20958 if (img != NULL && IMAGEP (img->spec))
20960 Lisp_Object image_map, hotspot;
20961 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
20962 !NILP (image_map))
20963 && (hotspot = find_hot_spot (image_map,
20964 glyph->slice.x + dx,
20965 glyph->slice.y + dy),
20966 CONSP (hotspot))
20967 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
20969 Lisp_Object area_id, plist;
20971 area_id = XCAR (hotspot);
20972 /* Could check AREA_ID to see if we enter/leave this hot-spot.
20973 If so, we could look for mouse-enter, mouse-leave
20974 properties in PLIST (and do something...). */
20975 if ((plist = XCDR (hotspot), CONSP (plist)))
20977 pointer = Fplist_get (plist, Qpointer);
20978 if (NILP (pointer))
20979 pointer = Qhand;
20980 help_echo_string = Fplist_get (plist, Qhelp_echo);
20981 if (!NILP (help_echo_string))
20983 help_echo_window = window;
20984 help_echo_object = glyph->object;
20985 help_echo_pos = glyph->charpos;
20989 if (NILP (pointer))
20990 pointer = Fplist_get (XCDR (img->spec), QCpointer);
20994 /* Clear mouse face if X/Y not over text. */
20995 if (glyph == NULL
20996 || area != TEXT_AREA
20997 || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p)
20999 if (clear_mouse_face (dpyinfo))
21000 cursor = No_Cursor;
21001 if (NILP (pointer))
21003 if (area != TEXT_AREA)
21004 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
21005 else
21006 pointer = Vvoid_text_area_pointer;
21008 goto set_cursor;
21011 pos = glyph->charpos;
21012 object = glyph->object;
21013 if (!STRINGP (object) && !BUFFERP (object))
21014 goto set_cursor;
21016 /* If we get an out-of-range value, return now; avoid an error. */
21017 if (BUFFERP (object) && pos > BUF_Z (b))
21018 goto set_cursor;
21020 /* Make the window's buffer temporarily current for
21021 overlays_at and compute_char_face. */
21022 obuf = current_buffer;
21023 current_buffer = b;
21024 obegv = BEGV;
21025 ozv = ZV;
21026 BEGV = BEG;
21027 ZV = Z;
21029 /* Is this char mouse-active or does it have help-echo? */
21030 position = make_number (pos);
21032 if (BUFFERP (object))
21034 /* Put all the overlays we want in a vector in overlay_vec. */
21035 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
21036 /* Sort overlays into increasing priority order. */
21037 noverlays = sort_overlays (overlay_vec, noverlays, w);
21039 else
21040 noverlays = 0;
21042 same_region = (EQ (window, dpyinfo->mouse_face_window)
21043 && vpos >= dpyinfo->mouse_face_beg_row
21044 && vpos <= dpyinfo->mouse_face_end_row
21045 && (vpos > dpyinfo->mouse_face_beg_row
21046 || hpos >= dpyinfo->mouse_face_beg_col)
21047 && (vpos < dpyinfo->mouse_face_end_row
21048 || hpos < dpyinfo->mouse_face_end_col
21049 || dpyinfo->mouse_face_past_end));
21051 if (same_region)
21052 cursor = No_Cursor;
21054 /* Check mouse-face highlighting. */
21055 if (! same_region
21056 /* If there exists an overlay with mouse-face overlapping
21057 the one we are currently highlighting, we have to
21058 check if we enter the overlapping overlay, and then
21059 highlight only that. */
21060 || (OVERLAYP (dpyinfo->mouse_face_overlay)
21061 && mouse_face_overlay_overlaps (dpyinfo->mouse_face_overlay)))
21063 /* Find the highest priority overlay that has a mouse-face
21064 property. */
21065 overlay = Qnil;
21066 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
21068 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
21069 if (!NILP (mouse_face))
21070 overlay = overlay_vec[i];
21073 /* If we're actually highlighting the same overlay as
21074 before, there's no need to do that again. */
21075 if (!NILP (overlay)
21076 && EQ (overlay, dpyinfo->mouse_face_overlay))
21077 goto check_help_echo;
21079 dpyinfo->mouse_face_overlay = overlay;
21081 /* Clear the display of the old active region, if any. */
21082 if (clear_mouse_face (dpyinfo))
21083 cursor = No_Cursor;
21085 /* If no overlay applies, get a text property. */
21086 if (NILP (overlay))
21087 mouse_face = Fget_text_property (position, Qmouse_face, object);
21089 /* Handle the overlay case. */
21090 if (!NILP (overlay))
21092 /* Find the range of text around this char that
21093 should be active. */
21094 Lisp_Object before, after;
21095 int ignore;
21097 before = Foverlay_start (overlay);
21098 after = Foverlay_end (overlay);
21099 /* Record this as the current active region. */
21100 fast_find_position (w, XFASTINT (before),
21101 &dpyinfo->mouse_face_beg_col,
21102 &dpyinfo->mouse_face_beg_row,
21103 &dpyinfo->mouse_face_beg_x,
21104 &dpyinfo->mouse_face_beg_y, Qnil);
21106 dpyinfo->mouse_face_past_end
21107 = !fast_find_position (w, XFASTINT (after),
21108 &dpyinfo->mouse_face_end_col,
21109 &dpyinfo->mouse_face_end_row,
21110 &dpyinfo->mouse_face_end_x,
21111 &dpyinfo->mouse_face_end_y, Qnil);
21112 dpyinfo->mouse_face_window = window;
21114 dpyinfo->mouse_face_face_id
21115 = face_at_buffer_position (w, pos, 0, 0,
21116 &ignore, pos + 1,
21117 !dpyinfo->mouse_face_hidden);
21119 /* Display it as active. */
21120 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21121 cursor = No_Cursor;
21123 /* Handle the text property case. */
21124 else if (!NILP (mouse_face) && BUFFERP (object))
21126 /* Find the range of text around this char that
21127 should be active. */
21128 Lisp_Object before, after, beginning, end;
21129 int ignore;
21131 beginning = Fmarker_position (w->start);
21132 end = make_number (BUF_Z (XBUFFER (object))
21133 - XFASTINT (w->window_end_pos));
21134 before
21135 = Fprevious_single_property_change (make_number (pos + 1),
21136 Qmouse_face,
21137 object, beginning);
21138 after
21139 = Fnext_single_property_change (position, Qmouse_face,
21140 object, end);
21142 /* Record this as the current active region. */
21143 fast_find_position (w, XFASTINT (before),
21144 &dpyinfo->mouse_face_beg_col,
21145 &dpyinfo->mouse_face_beg_row,
21146 &dpyinfo->mouse_face_beg_x,
21147 &dpyinfo->mouse_face_beg_y, Qnil);
21148 dpyinfo->mouse_face_past_end
21149 = !fast_find_position (w, XFASTINT (after),
21150 &dpyinfo->mouse_face_end_col,
21151 &dpyinfo->mouse_face_end_row,
21152 &dpyinfo->mouse_face_end_x,
21153 &dpyinfo->mouse_face_end_y, Qnil);
21154 dpyinfo->mouse_face_window = window;
21156 if (BUFFERP (object))
21157 dpyinfo->mouse_face_face_id
21158 = face_at_buffer_position (w, pos, 0, 0,
21159 &ignore, pos + 1,
21160 !dpyinfo->mouse_face_hidden);
21162 /* Display it as active. */
21163 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21164 cursor = No_Cursor;
21166 else if (!NILP (mouse_face) && STRINGP (object))
21168 Lisp_Object b, e;
21169 int ignore;
21171 b = Fprevious_single_property_change (make_number (pos + 1),
21172 Qmouse_face,
21173 object, Qnil);
21174 e = Fnext_single_property_change (position, Qmouse_face,
21175 object, Qnil);
21176 if (NILP (b))
21177 b = make_number (0);
21178 if (NILP (e))
21179 e = make_number (SCHARS (object) - 1);
21180 fast_find_string_pos (w, XINT (b), object,
21181 &dpyinfo->mouse_face_beg_col,
21182 &dpyinfo->mouse_face_beg_row,
21183 &dpyinfo->mouse_face_beg_x,
21184 &dpyinfo->mouse_face_beg_y, 0);
21185 fast_find_string_pos (w, XINT (e), object,
21186 &dpyinfo->mouse_face_end_col,
21187 &dpyinfo->mouse_face_end_row,
21188 &dpyinfo->mouse_face_end_x,
21189 &dpyinfo->mouse_face_end_y, 1);
21190 dpyinfo->mouse_face_past_end = 0;
21191 dpyinfo->mouse_face_window = window;
21192 dpyinfo->mouse_face_face_id
21193 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
21194 glyph->face_id, 1);
21195 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21196 cursor = No_Cursor;
21198 else if (STRINGP (object) && NILP (mouse_face))
21200 /* A string which doesn't have mouse-face, but
21201 the text ``under'' it might have. */
21202 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
21203 int start = MATRIX_ROW_START_CHARPOS (r);
21205 pos = string_buffer_position (w, object, start);
21206 if (pos > 0)
21207 mouse_face = get_char_property_and_overlay (make_number (pos),
21208 Qmouse_face,
21209 w->buffer,
21210 &overlay);
21211 if (!NILP (mouse_face) && !NILP (overlay))
21213 Lisp_Object before = Foverlay_start (overlay);
21214 Lisp_Object after = Foverlay_end (overlay);
21215 int ignore;
21217 /* Note that we might not be able to find position
21218 BEFORE in the glyph matrix if the overlay is
21219 entirely covered by a `display' property. In
21220 this case, we overshoot. So let's stop in
21221 the glyph matrix before glyphs for OBJECT. */
21222 fast_find_position (w, XFASTINT (before),
21223 &dpyinfo->mouse_face_beg_col,
21224 &dpyinfo->mouse_face_beg_row,
21225 &dpyinfo->mouse_face_beg_x,
21226 &dpyinfo->mouse_face_beg_y,
21227 object);
21229 dpyinfo->mouse_face_past_end
21230 = !fast_find_position (w, XFASTINT (after),
21231 &dpyinfo->mouse_face_end_col,
21232 &dpyinfo->mouse_face_end_row,
21233 &dpyinfo->mouse_face_end_x,
21234 &dpyinfo->mouse_face_end_y,
21235 Qnil);
21236 dpyinfo->mouse_face_window = window;
21237 dpyinfo->mouse_face_face_id
21238 = face_at_buffer_position (w, pos, 0, 0,
21239 &ignore, pos + 1,
21240 !dpyinfo->mouse_face_hidden);
21242 /* Display it as active. */
21243 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21244 cursor = No_Cursor;
21249 check_help_echo:
21251 /* Look for a `help-echo' property. */
21252 if (NILP (help_echo_string)) {
21253 Lisp_Object help, overlay;
21255 /* Check overlays first. */
21256 help = overlay = Qnil;
21257 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
21259 overlay = overlay_vec[i];
21260 help = Foverlay_get (overlay, Qhelp_echo);
21263 if (!NILP (help))
21265 help_echo_string = help;
21266 help_echo_window = window;
21267 help_echo_object = overlay;
21268 help_echo_pos = pos;
21270 else
21272 Lisp_Object object = glyph->object;
21273 int charpos = glyph->charpos;
21275 /* Try text properties. */
21276 if (STRINGP (object)
21277 && charpos >= 0
21278 && charpos < SCHARS (object))
21280 help = Fget_text_property (make_number (charpos),
21281 Qhelp_echo, object);
21282 if (NILP (help))
21284 /* If the string itself doesn't specify a help-echo,
21285 see if the buffer text ``under'' it does. */
21286 struct glyph_row *r
21287 = MATRIX_ROW (w->current_matrix, vpos);
21288 int start = MATRIX_ROW_START_CHARPOS (r);
21289 int pos = string_buffer_position (w, object, start);
21290 if (pos > 0)
21292 help = Fget_char_property (make_number (pos),
21293 Qhelp_echo, w->buffer);
21294 if (!NILP (help))
21296 charpos = pos;
21297 object = w->buffer;
21302 else if (BUFFERP (object)
21303 && charpos >= BEGV
21304 && charpos < ZV)
21305 help = Fget_text_property (make_number (charpos), Qhelp_echo,
21306 object);
21308 if (!NILP (help))
21310 help_echo_string = help;
21311 help_echo_window = window;
21312 help_echo_object = object;
21313 help_echo_pos = charpos;
21318 /* Look for a `pointer' property. */
21319 if (NILP (pointer))
21321 /* Check overlays first. */
21322 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
21323 pointer = Foverlay_get (overlay_vec[i], Qpointer);
21325 if (NILP (pointer))
21327 Lisp_Object object = glyph->object;
21328 int charpos = glyph->charpos;
21330 /* Try text properties. */
21331 if (STRINGP (object)
21332 && charpos >= 0
21333 && charpos < SCHARS (object))
21335 pointer = Fget_text_property (make_number (charpos),
21336 Qpointer, object);
21337 if (NILP (pointer))
21339 /* If the string itself doesn't specify a pointer,
21340 see if the buffer text ``under'' it does. */
21341 struct glyph_row *r
21342 = MATRIX_ROW (w->current_matrix, vpos);
21343 int start = MATRIX_ROW_START_CHARPOS (r);
21344 int pos = string_buffer_position (w, object, start);
21345 if (pos > 0)
21346 pointer = Fget_char_property (make_number (pos),
21347 Qpointer, w->buffer);
21350 else if (BUFFERP (object)
21351 && charpos >= BEGV
21352 && charpos < ZV)
21353 pointer = Fget_text_property (make_number (charpos),
21354 Qpointer, object);
21358 BEGV = obegv;
21359 ZV = ozv;
21360 current_buffer = obuf;
21363 set_cursor:
21365 define_frame_cursor1 (f, cursor, pointer);
21369 /* EXPORT for RIF:
21370 Clear any mouse-face on window W. This function is part of the
21371 redisplay interface, and is called from try_window_id and similar
21372 functions to ensure the mouse-highlight is off. */
21374 void
21375 x_clear_window_mouse_face (w)
21376 struct window *w;
21378 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
21379 Lisp_Object window;
21381 BLOCK_INPUT;
21382 XSETWINDOW (window, w);
21383 if (EQ (window, dpyinfo->mouse_face_window))
21384 clear_mouse_face (dpyinfo);
21385 UNBLOCK_INPUT;
21389 /* EXPORT:
21390 Just discard the mouse face information for frame F, if any.
21391 This is used when the size of F is changed. */
21393 void
21394 cancel_mouse_face (f)
21395 struct frame *f;
21397 Lisp_Object window;
21398 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
21400 window = dpyinfo->mouse_face_window;
21401 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
21403 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
21404 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
21405 dpyinfo->mouse_face_window = Qnil;
21410 #endif /* HAVE_WINDOW_SYSTEM */
21413 /***********************************************************************
21414 Exposure Events
21415 ***********************************************************************/
21417 #ifdef HAVE_WINDOW_SYSTEM
21419 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
21420 which intersects rectangle R. R is in window-relative coordinates. */
21422 static void
21423 expose_area (w, row, r, area)
21424 struct window *w;
21425 struct glyph_row *row;
21426 XRectangle *r;
21427 enum glyph_row_area area;
21429 struct glyph *first = row->glyphs[area];
21430 struct glyph *end = row->glyphs[area] + row->used[area];
21431 struct glyph *last;
21432 int first_x, start_x, x;
21434 if (area == TEXT_AREA && row->fill_line_p)
21435 /* If row extends face to end of line write the whole line. */
21436 draw_glyphs (w, 0, row, area,
21437 0, row->used[area],
21438 DRAW_NORMAL_TEXT, 0);
21439 else
21441 /* Set START_X to the window-relative start position for drawing glyphs of
21442 AREA. The first glyph of the text area can be partially visible.
21443 The first glyphs of other areas cannot. */
21444 start_x = window_box_left_offset (w, area);
21445 x = start_x;
21446 if (area == TEXT_AREA)
21447 x += row->x;
21449 /* Find the first glyph that must be redrawn. */
21450 while (first < end
21451 && x + first->pixel_width < r->x)
21453 x += first->pixel_width;
21454 ++first;
21457 /* Find the last one. */
21458 last = first;
21459 first_x = x;
21460 while (last < end
21461 && x < r->x + r->width)
21463 x += last->pixel_width;
21464 ++last;
21467 /* Repaint. */
21468 if (last > first)
21469 draw_glyphs (w, first_x - start_x, row, area,
21470 first - row->glyphs[area], last - row->glyphs[area],
21471 DRAW_NORMAL_TEXT, 0);
21476 /* Redraw the parts of the glyph row ROW on window W intersecting
21477 rectangle R. R is in window-relative coordinates. Value is
21478 non-zero if mouse-face was overwritten. */
21480 static int
21481 expose_line (w, row, r)
21482 struct window *w;
21483 struct glyph_row *row;
21484 XRectangle *r;
21486 xassert (row->enabled_p);
21488 if (row->mode_line_p || w->pseudo_window_p)
21489 draw_glyphs (w, 0, row, TEXT_AREA,
21490 0, row->used[TEXT_AREA],
21491 DRAW_NORMAL_TEXT, 0);
21492 else
21494 if (row->used[LEFT_MARGIN_AREA])
21495 expose_area (w, row, r, LEFT_MARGIN_AREA);
21496 if (row->used[TEXT_AREA])
21497 expose_area (w, row, r, TEXT_AREA);
21498 if (row->used[RIGHT_MARGIN_AREA])
21499 expose_area (w, row, r, RIGHT_MARGIN_AREA);
21500 draw_row_fringe_bitmaps (w, row);
21503 return row->mouse_face_p;
21507 /* Redraw those parts of glyphs rows during expose event handling that
21508 overlap other rows. Redrawing of an exposed line writes over parts
21509 of lines overlapping that exposed line; this function fixes that.
21511 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
21512 row in W's current matrix that is exposed and overlaps other rows.
21513 LAST_OVERLAPPING_ROW is the last such row. */
21515 static void
21516 expose_overlaps (w, first_overlapping_row, last_overlapping_row)
21517 struct window *w;
21518 struct glyph_row *first_overlapping_row;
21519 struct glyph_row *last_overlapping_row;
21521 struct glyph_row *row;
21523 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
21524 if (row->overlapping_p)
21526 xassert (row->enabled_p && !row->mode_line_p);
21528 if (row->used[LEFT_MARGIN_AREA])
21529 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA);
21531 if (row->used[TEXT_AREA])
21532 x_fix_overlapping_area (w, row, TEXT_AREA);
21534 if (row->used[RIGHT_MARGIN_AREA])
21535 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA);
21540 /* Return non-zero if W's cursor intersects rectangle R. */
21542 static int
21543 phys_cursor_in_rect_p (w, r)
21544 struct window *w;
21545 XRectangle *r;
21547 XRectangle cr, result;
21548 struct glyph *cursor_glyph;
21550 cursor_glyph = get_phys_cursor_glyph (w);
21551 if (cursor_glyph)
21553 /* r is relative to W's box, but w->phys_cursor.x is relative
21554 to left edge of W's TEXT area. Adjust it. */
21555 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
21556 cr.y = w->phys_cursor.y;
21557 cr.width = cursor_glyph->pixel_width;
21558 cr.height = w->phys_cursor_height;
21559 /* ++KFS: W32 version used W32-specific IntersectRect here, but
21560 I assume the effect is the same -- and this is portable. */
21561 return x_intersect_rectangles (&cr, r, &result);
21563 else
21564 return 0;
21568 /* EXPORT:
21569 Draw a vertical window border to the right of window W if W doesn't
21570 have vertical scroll bars. */
21572 void
21573 x_draw_vertical_border (w)
21574 struct window *w;
21576 /* We could do better, if we knew what type of scroll-bar the adjacent
21577 windows (on either side) have... But we don't :-(
21578 However, I think this works ok. ++KFS 2003-04-25 */
21580 /* Redraw borders between horizontally adjacent windows. Don't
21581 do it for frames with vertical scroll bars because either the
21582 right scroll bar of a window, or the left scroll bar of its
21583 neighbor will suffice as a border. */
21584 if (!WINDOW_RIGHTMOST_P (w)
21585 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
21587 int x0, x1, y0, y1;
21589 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
21590 y1 -= 1;
21592 rif->draw_vertical_window_border (w, x1, y0, y1);
21594 else if (!WINDOW_LEFTMOST_P (w)
21595 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
21597 int x0, x1, y0, y1;
21599 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
21600 y1 -= 1;
21602 rif->draw_vertical_window_border (w, x0, y0, y1);
21607 /* Redraw the part of window W intersection rectangle FR. Pixel
21608 coordinates in FR are frame-relative. Call this function with
21609 input blocked. Value is non-zero if the exposure overwrites
21610 mouse-face. */
21612 static int
21613 expose_window (w, fr)
21614 struct window *w;
21615 XRectangle *fr;
21617 struct frame *f = XFRAME (w->frame);
21618 XRectangle wr, r;
21619 int mouse_face_overwritten_p = 0;
21621 /* If window is not yet fully initialized, do nothing. This can
21622 happen when toolkit scroll bars are used and a window is split.
21623 Reconfiguring the scroll bar will generate an expose for a newly
21624 created window. */
21625 if (w->current_matrix == NULL)
21626 return 0;
21628 /* When we're currently updating the window, display and current
21629 matrix usually don't agree. Arrange for a thorough display
21630 later. */
21631 if (w == updated_window)
21633 SET_FRAME_GARBAGED (f);
21634 return 0;
21637 /* Frame-relative pixel rectangle of W. */
21638 wr.x = WINDOW_LEFT_EDGE_X (w);
21639 wr.y = WINDOW_TOP_EDGE_Y (w);
21640 wr.width = WINDOW_TOTAL_WIDTH (w);
21641 wr.height = WINDOW_TOTAL_HEIGHT (w);
21643 if (x_intersect_rectangles (fr, &wr, &r))
21645 int yb = window_text_bottom_y (w);
21646 struct glyph_row *row;
21647 int cursor_cleared_p;
21648 struct glyph_row *first_overlapping_row, *last_overlapping_row;
21650 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
21651 r.x, r.y, r.width, r.height));
21653 /* Convert to window coordinates. */
21654 r.x -= WINDOW_LEFT_EDGE_X (w);
21655 r.y -= WINDOW_TOP_EDGE_Y (w);
21657 /* Turn off the cursor. */
21658 if (!w->pseudo_window_p
21659 && phys_cursor_in_rect_p (w, &r))
21661 x_clear_cursor (w);
21662 cursor_cleared_p = 1;
21664 else
21665 cursor_cleared_p = 0;
21667 /* Update lines intersecting rectangle R. */
21668 first_overlapping_row = last_overlapping_row = NULL;
21669 for (row = w->current_matrix->rows;
21670 row->enabled_p;
21671 ++row)
21673 int y0 = row->y;
21674 int y1 = MATRIX_ROW_BOTTOM_Y (row);
21676 if ((y0 >= r.y && y0 < r.y + r.height)
21677 || (y1 > r.y && y1 < r.y + r.height)
21678 || (r.y >= y0 && r.y < y1)
21679 || (r.y + r.height > y0 && r.y + r.height < y1))
21681 if (row->overlapping_p)
21683 if (first_overlapping_row == NULL)
21684 first_overlapping_row = row;
21685 last_overlapping_row = row;
21688 if (expose_line (w, row, &r))
21689 mouse_face_overwritten_p = 1;
21692 if (y1 >= yb)
21693 break;
21696 /* Display the mode line if there is one. */
21697 if (WINDOW_WANTS_MODELINE_P (w)
21698 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
21699 row->enabled_p)
21700 && row->y < r.y + r.height)
21702 if (expose_line (w, row, &r))
21703 mouse_face_overwritten_p = 1;
21706 if (!w->pseudo_window_p)
21708 /* Fix the display of overlapping rows. */
21709 if (first_overlapping_row)
21710 expose_overlaps (w, first_overlapping_row, last_overlapping_row);
21712 /* Draw border between windows. */
21713 x_draw_vertical_border (w);
21715 /* Turn the cursor on again. */
21716 if (cursor_cleared_p)
21717 update_window_cursor (w, 1);
21721 #ifdef HAVE_CARBON
21722 /* Display scroll bar for this window. */
21723 if (!NILP (w->vertical_scroll_bar))
21725 /* ++KFS:
21726 If this doesn't work here (maybe some header files are missing),
21727 make a function in macterm.c and call it to do the job! */
21728 ControlHandle ch
21729 = SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (w->vertical_scroll_bar));
21731 Draw1Control (ch);
21733 #endif
21735 return mouse_face_overwritten_p;
21740 /* Redraw (parts) of all windows in the window tree rooted at W that
21741 intersect R. R contains frame pixel coordinates. Value is
21742 non-zero if the exposure overwrites mouse-face. */
21744 static int
21745 expose_window_tree (w, r)
21746 struct window *w;
21747 XRectangle *r;
21749 struct frame *f = XFRAME (w->frame);
21750 int mouse_face_overwritten_p = 0;
21752 while (w && !FRAME_GARBAGED_P (f))
21754 if (!NILP (w->hchild))
21755 mouse_face_overwritten_p
21756 |= expose_window_tree (XWINDOW (w->hchild), r);
21757 else if (!NILP (w->vchild))
21758 mouse_face_overwritten_p
21759 |= expose_window_tree (XWINDOW (w->vchild), r);
21760 else
21761 mouse_face_overwritten_p |= expose_window (w, r);
21763 w = NILP (w->next) ? NULL : XWINDOW (w->next);
21766 return mouse_face_overwritten_p;
21770 /* EXPORT:
21771 Redisplay an exposed area of frame F. X and Y are the upper-left
21772 corner of the exposed rectangle. W and H are width and height of
21773 the exposed area. All are pixel values. W or H zero means redraw
21774 the entire frame. */
21776 void
21777 expose_frame (f, x, y, w, h)
21778 struct frame *f;
21779 int x, y, w, h;
21781 XRectangle r;
21782 int mouse_face_overwritten_p = 0;
21784 TRACE ((stderr, "expose_frame "));
21786 /* No need to redraw if frame will be redrawn soon. */
21787 if (FRAME_GARBAGED_P (f))
21789 TRACE ((stderr, " garbaged\n"));
21790 return;
21793 #ifdef HAVE_CARBON
21794 /* MAC_TODO: this is a kludge, but if scroll bars are not activated
21795 or deactivated here, for unknown reasons, activated scroll bars
21796 are shown in deactivated frames in some instances. */
21797 if (f == FRAME_MAC_DISPLAY_INFO (f)->x_focus_frame)
21798 activate_scroll_bars (f);
21799 else
21800 deactivate_scroll_bars (f);
21801 #endif
21803 /* If basic faces haven't been realized yet, there is no point in
21804 trying to redraw anything. This can happen when we get an expose
21805 event while Emacs is starting, e.g. by moving another window. */
21806 if (FRAME_FACE_CACHE (f) == NULL
21807 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
21809 TRACE ((stderr, " no faces\n"));
21810 return;
21813 if (w == 0 || h == 0)
21815 r.x = r.y = 0;
21816 r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f);
21817 r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f);
21819 else
21821 r.x = x;
21822 r.y = y;
21823 r.width = w;
21824 r.height = h;
21827 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
21828 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
21830 if (WINDOWP (f->tool_bar_window))
21831 mouse_face_overwritten_p
21832 |= expose_window (XWINDOW (f->tool_bar_window), &r);
21834 #ifdef HAVE_X_WINDOWS
21835 #ifndef MSDOS
21836 #ifndef USE_X_TOOLKIT
21837 if (WINDOWP (f->menu_bar_window))
21838 mouse_face_overwritten_p
21839 |= expose_window (XWINDOW (f->menu_bar_window), &r);
21840 #endif /* not USE_X_TOOLKIT */
21841 #endif
21842 #endif
21844 /* Some window managers support a focus-follows-mouse style with
21845 delayed raising of frames. Imagine a partially obscured frame,
21846 and moving the mouse into partially obscured mouse-face on that
21847 frame. The visible part of the mouse-face will be highlighted,
21848 then the WM raises the obscured frame. With at least one WM, KDE
21849 2.1, Emacs is not getting any event for the raising of the frame
21850 (even tried with SubstructureRedirectMask), only Expose events.
21851 These expose events will draw text normally, i.e. not
21852 highlighted. Which means we must redo the highlight here.
21853 Subsume it under ``we love X''. --gerd 2001-08-15 */
21854 /* Included in Windows version because Windows most likely does not
21855 do the right thing if any third party tool offers
21856 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
21857 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
21859 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
21860 if (f == dpyinfo->mouse_face_mouse_frame)
21862 int x = dpyinfo->mouse_face_mouse_x;
21863 int y = dpyinfo->mouse_face_mouse_y;
21864 clear_mouse_face (dpyinfo);
21865 note_mouse_highlight (f, x, y);
21871 /* EXPORT:
21872 Determine the intersection of two rectangles R1 and R2. Return
21873 the intersection in *RESULT. Value is non-zero if RESULT is not
21874 empty. */
21877 x_intersect_rectangles (r1, r2, result)
21878 XRectangle *r1, *r2, *result;
21880 XRectangle *left, *right;
21881 XRectangle *upper, *lower;
21882 int intersection_p = 0;
21884 /* Rearrange so that R1 is the left-most rectangle. */
21885 if (r1->x < r2->x)
21886 left = r1, right = r2;
21887 else
21888 left = r2, right = r1;
21890 /* X0 of the intersection is right.x0, if this is inside R1,
21891 otherwise there is no intersection. */
21892 if (right->x <= left->x + left->width)
21894 result->x = right->x;
21896 /* The right end of the intersection is the minimum of the
21897 the right ends of left and right. */
21898 result->width = (min (left->x + left->width, right->x + right->width)
21899 - result->x);
21901 /* Same game for Y. */
21902 if (r1->y < r2->y)
21903 upper = r1, lower = r2;
21904 else
21905 upper = r2, lower = r1;
21907 /* The upper end of the intersection is lower.y0, if this is inside
21908 of upper. Otherwise, there is no intersection. */
21909 if (lower->y <= upper->y + upper->height)
21911 result->y = lower->y;
21913 /* The lower end of the intersection is the minimum of the lower
21914 ends of upper and lower. */
21915 result->height = (min (lower->y + lower->height,
21916 upper->y + upper->height)
21917 - result->y);
21918 intersection_p = 1;
21922 return intersection_p;
21925 #endif /* HAVE_WINDOW_SYSTEM */
21928 /***********************************************************************
21929 Initialization
21930 ***********************************************************************/
21932 void
21933 syms_of_xdisp ()
21935 Vwith_echo_area_save_vector = Qnil;
21936 staticpro (&Vwith_echo_area_save_vector);
21938 Vmessage_stack = Qnil;
21939 staticpro (&Vmessage_stack);
21941 Qinhibit_redisplay = intern ("inhibit-redisplay");
21942 staticpro (&Qinhibit_redisplay);
21944 message_dolog_marker1 = Fmake_marker ();
21945 staticpro (&message_dolog_marker1);
21946 message_dolog_marker2 = Fmake_marker ();
21947 staticpro (&message_dolog_marker2);
21948 message_dolog_marker3 = Fmake_marker ();
21949 staticpro (&message_dolog_marker3);
21951 #if GLYPH_DEBUG
21952 defsubr (&Sdump_frame_glyph_matrix);
21953 defsubr (&Sdump_glyph_matrix);
21954 defsubr (&Sdump_glyph_row);
21955 defsubr (&Sdump_tool_bar_row);
21956 defsubr (&Strace_redisplay);
21957 defsubr (&Strace_to_stderr);
21958 #endif
21959 #ifdef HAVE_WINDOW_SYSTEM
21960 defsubr (&Stool_bar_lines_needed);
21961 defsubr (&Slookup_image_map);
21962 #endif
21963 defsubr (&Sformat_mode_line);
21965 staticpro (&Qmenu_bar_update_hook);
21966 Qmenu_bar_update_hook = intern ("menu-bar-update-hook");
21968 staticpro (&Qoverriding_terminal_local_map);
21969 Qoverriding_terminal_local_map = intern ("overriding-terminal-local-map");
21971 staticpro (&Qoverriding_local_map);
21972 Qoverriding_local_map = intern ("overriding-local-map");
21974 staticpro (&Qwindow_scroll_functions);
21975 Qwindow_scroll_functions = intern ("window-scroll-functions");
21977 staticpro (&Qredisplay_end_trigger_functions);
21978 Qredisplay_end_trigger_functions = intern ("redisplay-end-trigger-functions");
21980 staticpro (&Qinhibit_point_motion_hooks);
21981 Qinhibit_point_motion_hooks = intern ("inhibit-point-motion-hooks");
21983 QCdata = intern (":data");
21984 staticpro (&QCdata);
21985 Qdisplay = intern ("display");
21986 staticpro (&Qdisplay);
21987 Qspace_width = intern ("space-width");
21988 staticpro (&Qspace_width);
21989 Qraise = intern ("raise");
21990 staticpro (&Qraise);
21991 Qslice = intern ("slice");
21992 staticpro (&Qslice);
21993 Qspace = intern ("space");
21994 staticpro (&Qspace);
21995 Qmargin = intern ("margin");
21996 staticpro (&Qmargin);
21997 Qpointer = intern ("pointer");
21998 staticpro (&Qpointer);
21999 Qleft_margin = intern ("left-margin");
22000 staticpro (&Qleft_margin);
22001 Qright_margin = intern ("right-margin");
22002 staticpro (&Qright_margin);
22003 Qcenter = intern ("center");
22004 staticpro (&Qcenter);
22005 Qline_height = intern ("line-height");
22006 staticpro (&Qline_height);
22007 Qtotal = intern ("total");
22008 staticpro (&Qtotal);
22009 QCalign_to = intern (":align-to");
22010 staticpro (&QCalign_to);
22011 QCrelative_width = intern (":relative-width");
22012 staticpro (&QCrelative_width);
22013 QCrelative_height = intern (":relative-height");
22014 staticpro (&QCrelative_height);
22015 QCeval = intern (":eval");
22016 staticpro (&QCeval);
22017 QCpropertize = intern (":propertize");
22018 staticpro (&QCpropertize);
22019 QCfile = intern (":file");
22020 staticpro (&QCfile);
22021 Qfontified = intern ("fontified");
22022 staticpro (&Qfontified);
22023 Qfontification_functions = intern ("fontification-functions");
22024 staticpro (&Qfontification_functions);
22025 Qtrailing_whitespace = intern ("trailing-whitespace");
22026 staticpro (&Qtrailing_whitespace);
22027 Qimage = intern ("image");
22028 staticpro (&Qimage);
22029 QCmap = intern (":map");
22030 staticpro (&QCmap);
22031 QCpointer = intern (":pointer");
22032 staticpro (&QCpointer);
22033 Qrect = intern ("rect");
22034 staticpro (&Qrect);
22035 Qcircle = intern ("circle");
22036 staticpro (&Qcircle);
22037 Qpoly = intern ("poly");
22038 staticpro (&Qpoly);
22039 Qmessage_truncate_lines = intern ("message-truncate-lines");
22040 staticpro (&Qmessage_truncate_lines);
22041 Qcursor_in_non_selected_windows = intern ("cursor-in-non-selected-windows");
22042 staticpro (&Qcursor_in_non_selected_windows);
22043 Qgrow_only = intern ("grow-only");
22044 staticpro (&Qgrow_only);
22045 Qinhibit_menubar_update = intern ("inhibit-menubar-update");
22046 staticpro (&Qinhibit_menubar_update);
22047 Qinhibit_eval_during_redisplay = intern ("inhibit-eval-during-redisplay");
22048 staticpro (&Qinhibit_eval_during_redisplay);
22049 Qposition = intern ("position");
22050 staticpro (&Qposition);
22051 Qbuffer_position = intern ("buffer-position");
22052 staticpro (&Qbuffer_position);
22053 Qobject = intern ("object");
22054 staticpro (&Qobject);
22055 Qbar = intern ("bar");
22056 staticpro (&Qbar);
22057 Qhbar = intern ("hbar");
22058 staticpro (&Qhbar);
22059 Qbox = intern ("box");
22060 staticpro (&Qbox);
22061 Qhollow = intern ("hollow");
22062 staticpro (&Qhollow);
22063 Qhand = intern ("hand");
22064 staticpro (&Qhand);
22065 Qarrow = intern ("arrow");
22066 staticpro (&Qarrow);
22067 Qtext = intern ("text");
22068 staticpro (&Qtext);
22069 Qrisky_local_variable = intern ("risky-local-variable");
22070 staticpro (&Qrisky_local_variable);
22071 Qinhibit_free_realized_faces = intern ("inhibit-free-realized-faces");
22072 staticpro (&Qinhibit_free_realized_faces);
22074 list_of_error = Fcons (Fcons (intern ("error"),
22075 Fcons (intern ("void-variable"), Qnil)),
22076 Qnil);
22077 staticpro (&list_of_error);
22079 Qlast_arrow_position = intern ("last-arrow-position");
22080 staticpro (&Qlast_arrow_position);
22081 Qlast_arrow_string = intern ("last-arrow-string");
22082 staticpro (&Qlast_arrow_string);
22084 Qoverlay_arrow_string = intern ("overlay-arrow-string");
22085 staticpro (&Qoverlay_arrow_string);
22086 Qoverlay_arrow_bitmap = intern ("overlay-arrow-bitmap");
22087 staticpro (&Qoverlay_arrow_bitmap);
22089 echo_buffer[0] = echo_buffer[1] = Qnil;
22090 staticpro (&echo_buffer[0]);
22091 staticpro (&echo_buffer[1]);
22093 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
22094 staticpro (&echo_area_buffer[0]);
22095 staticpro (&echo_area_buffer[1]);
22097 Vmessages_buffer_name = build_string ("*Messages*");
22098 staticpro (&Vmessages_buffer_name);
22100 mode_line_proptrans_alist = Qnil;
22101 staticpro (&mode_line_proptrans_alist);
22103 mode_line_string_list = Qnil;
22104 staticpro (&mode_line_string_list);
22106 help_echo_string = Qnil;
22107 staticpro (&help_echo_string);
22108 help_echo_object = Qnil;
22109 staticpro (&help_echo_object);
22110 help_echo_window = Qnil;
22111 staticpro (&help_echo_window);
22112 previous_help_echo_string = Qnil;
22113 staticpro (&previous_help_echo_string);
22114 help_echo_pos = -1;
22116 #ifdef HAVE_WINDOW_SYSTEM
22117 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p,
22118 doc: /* *Non-nil means draw block cursor as wide as the glyph under it.
22119 For example, if a block cursor is over a tab, it will be drawn as
22120 wide as that tab on the display. */);
22121 x_stretch_cursor_p = 0;
22122 #endif
22124 DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace,
22125 doc: /* *Non-nil means highlight trailing whitespace.
22126 The face used for trailing whitespace is `trailing-whitespace'. */);
22127 Vshow_trailing_whitespace = Qnil;
22129 DEFVAR_LISP ("void-text-area-pointer", &Vvoid_text_area_pointer,
22130 doc: /* *The pointer shape to show in void text areas.
22131 Nil means to show the text pointer. Other options are `arrow', `text',
22132 `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
22133 Vvoid_text_area_pointer = Qarrow;
22135 DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay,
22136 doc: /* Non-nil means don't actually do any redisplay.
22137 This is used for internal purposes. */);
22138 Vinhibit_redisplay = Qnil;
22140 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string,
22141 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
22142 Vglobal_mode_string = Qnil;
22144 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position,
22145 doc: /* Marker for where to display an arrow on top of the buffer text.
22146 This must be the beginning of a line in order to work.
22147 See also `overlay-arrow-string'. */);
22148 Voverlay_arrow_position = Qnil;
22150 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string,
22151 doc: /* String to display as an arrow in non-window frames.
22152 See also `overlay-arrow-position'. */);
22153 Voverlay_arrow_string = Qnil;
22155 DEFVAR_LISP ("overlay-arrow-variable-list", &Voverlay_arrow_variable_list,
22156 doc: /* List of variables (symbols) which hold markers for overlay arrows.
22157 The symbols on this list are examined during redisplay to determine
22158 where to display overlay arrows. */);
22159 Voverlay_arrow_variable_list
22160 = Fcons (intern ("overlay-arrow-position"), Qnil);
22162 DEFVAR_INT ("scroll-step", &scroll_step,
22163 doc: /* *The number of lines to try scrolling a window by when point moves out.
22164 If that fails to bring point back on frame, point is centered instead.
22165 If this is zero, point is always centered after it moves off frame.
22166 If you want scrolling to always be a line at a time, you should set
22167 `scroll-conservatively' to a large value rather than set this to 1. */);
22169 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively,
22170 doc: /* *Scroll up to this many lines, to bring point back on screen.
22171 A value of zero means to scroll the text to center point vertically
22172 in the window. */);
22173 scroll_conservatively = 0;
22175 DEFVAR_INT ("scroll-margin", &scroll_margin,
22176 doc: /* *Number of lines of margin at the top and bottom of a window.
22177 Recenter the window whenever point gets within this many lines
22178 of the top or bottom of the window. */);
22179 scroll_margin = 0;
22181 DEFVAR_LISP ("display-pixels-per-inch", &Vdisplay_pixels_per_inch,
22182 doc: /* Pixels per inch on current display.
22183 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
22184 Vdisplay_pixels_per_inch = make_float (72.0);
22186 #if GLYPH_DEBUG
22187 DEFVAR_INT ("debug-end-pos", &debug_end_pos, doc: /* Don't ask. */);
22188 #endif
22190 DEFVAR_BOOL ("truncate-partial-width-windows",
22191 &truncate_partial_width_windows,
22192 doc: /* *Non-nil means truncate lines in all windows less than full frame wide. */);
22193 truncate_partial_width_windows = 1;
22195 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video,
22196 doc: /* nil means display the mode-line/header-line/menu-bar in the default face.
22197 Any other value means to use the appropriate face, `mode-line',
22198 `header-line', or `menu' respectively. */);
22199 mode_line_inverse_video = 1;
22201 DEFVAR_LISP ("line-number-display-limit", &Vline_number_display_limit,
22202 doc: /* *Maximum buffer size for which line number should be displayed.
22203 If the buffer is bigger than this, the line number does not appear
22204 in the mode line. A value of nil means no limit. */);
22205 Vline_number_display_limit = Qnil;
22207 DEFVAR_INT ("line-number-display-limit-width",
22208 &line_number_display_limit_width,
22209 doc: /* *Maximum line width (in characters) for line number display.
22210 If the average length of the lines near point is bigger than this, then the
22211 line number may be omitted from the mode line. */);
22212 line_number_display_limit_width = 200;
22214 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows,
22215 doc: /* *Non-nil means highlight region even in nonselected windows. */);
22216 highlight_nonselected_windows = 0;
22218 DEFVAR_BOOL ("multiple-frames", &multiple_frames,
22219 doc: /* Non-nil if more than one frame is visible on this display.
22220 Minibuffer-only frames don't count, but iconified frames do.
22221 This variable is not guaranteed to be accurate except while processing
22222 `frame-title-format' and `icon-title-format'. */);
22224 DEFVAR_LISP ("frame-title-format", &Vframe_title_format,
22225 doc: /* Template for displaying the title bar of visible frames.
22226 \(Assuming the window manager supports this feature.)
22227 This variable has the same structure as `mode-line-format' (which see),
22228 and is used only on frames for which no explicit name has been set
22229 \(see `modify-frame-parameters'). */);
22231 DEFVAR_LISP ("icon-title-format", &Vicon_title_format,
22232 doc: /* Template for displaying the title bar of an iconified frame.
22233 \(Assuming the window manager supports this feature.)
22234 This variable has the same structure as `mode-line-format' (which see),
22235 and is used only on frames for which no explicit name has been set
22236 \(see `modify-frame-parameters'). */);
22237 Vicon_title_format
22238 = Vframe_title_format
22239 = Fcons (intern ("multiple-frames"),
22240 Fcons (build_string ("%b"),
22241 Fcons (Fcons (empty_string,
22242 Fcons (intern ("invocation-name"),
22243 Fcons (build_string ("@"),
22244 Fcons (intern ("system-name"),
22245 Qnil)))),
22246 Qnil)));
22248 DEFVAR_LISP ("message-log-max", &Vmessage_log_max,
22249 doc: /* Maximum number of lines to keep in the message log buffer.
22250 If nil, disable message logging. If t, log messages but don't truncate
22251 the buffer when it becomes large. */);
22252 Vmessage_log_max = make_number (50);
22254 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions,
22255 doc: /* Functions called before redisplay, if window sizes have changed.
22256 The value should be a list of functions that take one argument.
22257 Just before redisplay, for each frame, if any of its windows have changed
22258 size since the last redisplay, or have been split or deleted,
22259 all the functions in the list are called, with the frame as argument. */);
22260 Vwindow_size_change_functions = Qnil;
22262 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions,
22263 doc: /* List of functions to call before redisplaying a window with scrolling.
22264 Each function is called with two arguments, the window
22265 and its new display-start position. Note that the value of `window-end'
22266 is not valid when these functions are called. */);
22267 Vwindow_scroll_functions = Qnil;
22269 DEFVAR_BOOL ("mouse-autoselect-window", &mouse_autoselect_window,
22270 doc: /* *Non-nil means autoselect window with mouse pointer. */);
22271 mouse_autoselect_window = 0;
22273 DEFVAR_BOOL ("auto-resize-tool-bars", &auto_resize_tool_bars_p,
22274 doc: /* *Non-nil means automatically resize tool-bars.
22275 This increases a tool-bar's height if not all tool-bar items are visible.
22276 It decreases a tool-bar's height when it would display blank lines
22277 otherwise. */);
22278 auto_resize_tool_bars_p = 1;
22280 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", &auto_raise_tool_bar_buttons_p,
22281 doc: /* *Non-nil means raise tool-bar buttons when the mouse moves over them. */);
22282 auto_raise_tool_bar_buttons_p = 1;
22284 DEFVAR_LISP ("tool-bar-button-margin", &Vtool_bar_button_margin,
22285 doc: /* *Margin around tool-bar buttons in pixels.
22286 If an integer, use that for both horizontal and vertical margins.
22287 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
22288 HORZ specifying the horizontal margin, and VERT specifying the
22289 vertical margin. */);
22290 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
22292 DEFVAR_INT ("tool-bar-button-relief", &tool_bar_button_relief,
22293 doc: /* *Relief thickness of tool-bar buttons. */);
22294 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
22296 DEFVAR_LISP ("fontification-functions", &Vfontification_functions,
22297 doc: /* List of functions to call to fontify regions of text.
22298 Each function is called with one argument POS. Functions must
22299 fontify a region starting at POS in the current buffer, and give
22300 fontified regions the property `fontified'. */);
22301 Vfontification_functions = Qnil;
22302 Fmake_variable_buffer_local (Qfontification_functions);
22304 DEFVAR_BOOL ("unibyte-display-via-language-environment",
22305 &unibyte_display_via_language_environment,
22306 doc: /* *Non-nil means display unibyte text according to language environment.
22307 Specifically this means that unibyte non-ASCII characters
22308 are displayed by converting them to the equivalent multibyte characters
22309 according to the current language environment. As a result, they are
22310 displayed according to the current fontset. */);
22311 unibyte_display_via_language_environment = 0;
22313 DEFVAR_LISP ("max-mini-window-height", &Vmax_mini_window_height,
22314 doc: /* *Maximum height for resizing mini-windows.
22315 If a float, it specifies a fraction of the mini-window frame's height.
22316 If an integer, it specifies a number of lines. */);
22317 Vmax_mini_window_height = make_float (0.25);
22319 DEFVAR_LISP ("resize-mini-windows", &Vresize_mini_windows,
22320 doc: /* *How to resize mini-windows.
22321 A value of nil means don't automatically resize mini-windows.
22322 A value of t means resize them to fit the text displayed in them.
22323 A value of `grow-only', the default, means let mini-windows grow
22324 only, until their display becomes empty, at which point the windows
22325 go back to their normal size. */);
22326 Vresize_mini_windows = Qgrow_only;
22328 DEFVAR_LISP ("cursor-in-non-selected-windows",
22329 &Vcursor_in_non_selected_windows,
22330 doc: /* *Cursor type to display in non-selected windows.
22331 t means to use hollow box cursor. See `cursor-type' for other values. */);
22332 Vcursor_in_non_selected_windows = Qt;
22334 DEFVAR_LISP ("blink-cursor-alist", &Vblink_cursor_alist,
22335 doc: /* Alist specifying how to blink the cursor off.
22336 Each element has the form (ON-STATE . OFF-STATE). Whenever the
22337 `cursor-type' frame-parameter or variable equals ON-STATE,
22338 comparing using `equal', Emacs uses OFF-STATE to specify
22339 how to blink it off. */);
22340 Vblink_cursor_alist = Qnil;
22342 DEFVAR_BOOL ("auto-hscroll-mode", &automatic_hscrolling_p,
22343 doc: /* *Non-nil means scroll the display automatically to make point visible. */);
22344 automatic_hscrolling_p = 1;
22346 DEFVAR_INT ("hscroll-margin", &hscroll_margin,
22347 doc: /* *How many columns away from the window edge point is allowed to get
22348 before automatic hscrolling will horizontally scroll the window. */);
22349 hscroll_margin = 5;
22351 DEFVAR_LISP ("hscroll-step", &Vhscroll_step,
22352 doc: /* *How many columns to scroll the window when point gets too close to the edge.
22353 When point is less than `automatic-hscroll-margin' columns from the window
22354 edge, automatic hscrolling will scroll the window by the amount of columns
22355 determined by this variable. If its value is a positive integer, scroll that
22356 many columns. If it's a positive floating-point number, it specifies the
22357 fraction of the window's width to scroll. If it's nil or zero, point will be
22358 centered horizontally after the scroll. Any other value, including negative
22359 numbers, are treated as if the value were zero.
22361 Automatic hscrolling always moves point outside the scroll margin, so if
22362 point was more than scroll step columns inside the margin, the window will
22363 scroll more than the value given by the scroll step.
22365 Note that the lower bound for automatic hscrolling specified by `scroll-left'
22366 and `scroll-right' overrides this variable's effect. */);
22367 Vhscroll_step = make_number (0);
22369 DEFVAR_BOOL ("message-truncate-lines", &message_truncate_lines,
22370 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
22371 Bind this around calls to `message' to let it take effect. */);
22372 message_truncate_lines = 0;
22374 DEFVAR_LISP ("menu-bar-update-hook", &Vmenu_bar_update_hook,
22375 doc: /* Normal hook run for clicks on menu bar, before displaying a submenu.
22376 Can be used to update submenus whose contents should vary. */);
22377 Vmenu_bar_update_hook = Qnil;
22379 DEFVAR_BOOL ("inhibit-menubar-update", &inhibit_menubar_update,
22380 doc: /* Non-nil means don't update menu bars. Internal use only. */);
22381 inhibit_menubar_update = 0;
22383 DEFVAR_BOOL ("inhibit-eval-during-redisplay", &inhibit_eval_during_redisplay,
22384 doc: /* Non-nil means don't eval Lisp during redisplay. */);
22385 inhibit_eval_during_redisplay = 0;
22387 DEFVAR_BOOL ("inhibit-free-realized-faces", &inhibit_free_realized_faces,
22388 doc: /* Non-nil means don't free realized faces. Internal use only. */);
22389 inhibit_free_realized_faces = 0;
22391 #if GLYPH_DEBUG
22392 DEFVAR_BOOL ("inhibit-try-window-id", &inhibit_try_window_id,
22393 doc: /* Inhibit try_window_id display optimization. */);
22394 inhibit_try_window_id = 0;
22396 DEFVAR_BOOL ("inhibit-try-window-reusing", &inhibit_try_window_reusing,
22397 doc: /* Inhibit try_window_reusing display optimization. */);
22398 inhibit_try_window_reusing = 0;
22400 DEFVAR_BOOL ("inhibit-try-cursor-movement", &inhibit_try_cursor_movement,
22401 doc: /* Inhibit try_cursor_movement display optimization. */);
22402 inhibit_try_cursor_movement = 0;
22403 #endif /* GLYPH_DEBUG */
22407 /* Initialize this module when Emacs starts. */
22409 void
22410 init_xdisp ()
22412 Lisp_Object root_window;
22413 struct window *mini_w;
22415 current_header_line_height = current_mode_line_height = -1;
22417 CHARPOS (this_line_start_pos) = 0;
22419 mini_w = XWINDOW (minibuf_window);
22420 root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w)));
22422 if (!noninteractive)
22424 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (root_window)));
22425 int i;
22427 XWINDOW (root_window)->top_line = make_number (FRAME_TOP_MARGIN (f));
22428 set_window_height (root_window,
22429 FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f),
22431 mini_w->top_line = make_number (FRAME_LINES (f) - 1);
22432 set_window_height (minibuf_window, 1, 0);
22434 XWINDOW (root_window)->total_cols = make_number (FRAME_COLS (f));
22435 mini_w->total_cols = make_number (FRAME_COLS (f));
22437 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
22438 scratch_glyph_row.glyphs[TEXT_AREA + 1]
22439 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
22441 /* The default ellipsis glyphs `...'. */
22442 for (i = 0; i < 3; ++i)
22443 default_invis_vector[i] = make_number ('.');
22447 /* Allocate the buffer for frame titles.
22448 Also used for `format-mode-line'. */
22449 int size = 100;
22450 frame_title_buf = (char *) xmalloc (size);
22451 frame_title_buf_end = frame_title_buf + size;
22452 frame_title_ptr = NULL;
22455 help_echo_showing_p = 0;
22459 /* arch-tag: eacc864d-bb6a-4b74-894a-1a4399a1358b
22460 (do not change this comment) */