(single_menu_item): Change last parameter to void* to
[emacs.git] / src / xdisp.c
blob18e57edb28fa65f5205ee6a82deb4032e8e52082
1 /* Display generation from window structure and buffer text.
2 Copyright (C) 1985,86,87,88,93,94,95,97,98,99, 2000, 2001, 2002, 2003
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"
202 Cursor No_Cursor;
203 #endif
205 #ifndef FRAME_X_OUTPUT
206 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
207 #endif
209 #define INFINITY 10000000
211 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
212 || defined (USE_GTK)
213 extern void set_frame_menubar P_ ((struct frame *f, int, int));
214 extern int pending_menu_activation;
215 #endif
217 extern int interrupt_input;
218 extern int command_loop_level;
220 extern int minibuffer_auto_raise;
221 extern Lisp_Object Vminibuffer_list;
223 extern Lisp_Object Qface;
224 extern Lisp_Object Qmode_line, Qmode_line_inactive, Qheader_line;
226 extern Lisp_Object Voverriding_local_map;
227 extern Lisp_Object Voverriding_local_map_menu_flag;
228 extern Lisp_Object Qmenu_item;
229 extern Lisp_Object Qwhen;
230 extern Lisp_Object Qhelp_echo;
232 Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
233 Lisp_Object Qwindow_scroll_functions, Vwindow_scroll_functions;
234 Lisp_Object Qredisplay_end_trigger_functions;
235 Lisp_Object Qinhibit_point_motion_hooks;
236 Lisp_Object QCeval, QCfile, QCdata, QCpropertize;
237 Lisp_Object Qfontified;
238 Lisp_Object Qgrow_only;
239 Lisp_Object Qinhibit_eval_during_redisplay;
240 Lisp_Object Qbuffer_position, Qposition, Qobject;
242 /* Cursor shapes */
243 Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
245 Lisp_Object Qrisky_local_variable;
247 /* Holds the list (error). */
248 Lisp_Object list_of_error;
250 /* Functions called to fontify regions of text. */
252 Lisp_Object Vfontification_functions;
253 Lisp_Object Qfontification_functions;
255 /* Non-zero means automatically select any window when the mouse
256 cursor moves into it. */
257 int mouse_autoselect_window;
259 /* Non-zero means draw tool bar buttons raised when the mouse moves
260 over them. */
262 int auto_raise_tool_bar_buttons_p;
264 /* Margin around tool bar buttons in pixels. */
266 Lisp_Object Vtool_bar_button_margin;
268 /* Thickness of shadow to draw around tool bar buttons. */
270 EMACS_INT tool_bar_button_relief;
272 /* Non-zero means automatically resize tool-bars so that all tool-bar
273 items are visible, and no blank lines remain. */
275 int auto_resize_tool_bars_p;
277 /* Non-zero means draw block and hollow cursor as wide as the glyph
278 under it. For example, if a block cursor is over a tab, it will be
279 drawn as wide as that tab on the display. */
281 int x_stretch_cursor_p;
283 /* Non-nil means don't actually do any redisplay. */
285 Lisp_Object Vinhibit_redisplay, Qinhibit_redisplay;
287 /* Non-zero means Lisp evaluation during redisplay is inhibited. */
289 int inhibit_eval_during_redisplay;
291 /* Names of text properties relevant for redisplay. */
293 Lisp_Object Qdisplay, Qrelative_width, Qalign_to;
294 extern Lisp_Object Qface, Qinvisible, Qwidth;
296 /* Symbols used in text property values. */
298 Lisp_Object Qspace, QCalign_to, QCrelative_width, QCrelative_height;
299 Lisp_Object Qleft_margin, Qright_margin, Qspace_width, Qraise;
300 Lisp_Object Qmargin;
301 extern Lisp_Object Qheight;
302 extern Lisp_Object QCwidth, QCheight, QCascent;
304 /* Non-nil means highlight trailing whitespace. */
306 Lisp_Object Vshow_trailing_whitespace;
308 /* Name of the face used to highlight trailing whitespace. */
310 Lisp_Object Qtrailing_whitespace;
312 /* The symbol `image' which is the car of the lists used to represent
313 images in Lisp. */
315 Lisp_Object Qimage;
317 /* Non-zero means print newline to stdout before next mini-buffer
318 message. */
320 int noninteractive_need_newline;
322 /* Non-zero means print newline to message log before next message. */
324 static int message_log_need_newline;
326 /* Three markers that message_dolog uses.
327 It could allocate them itself, but that causes trouble
328 in handling memory-full errors. */
329 static Lisp_Object message_dolog_marker1;
330 static Lisp_Object message_dolog_marker2;
331 static Lisp_Object message_dolog_marker3;
333 /* The buffer position of the first character appearing entirely or
334 partially on the line of the selected window which contains the
335 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
336 redisplay optimization in redisplay_internal. */
338 static struct text_pos this_line_start_pos;
340 /* Number of characters past the end of the line above, including the
341 terminating newline. */
343 static struct text_pos this_line_end_pos;
345 /* The vertical positions and the height of this line. */
347 static int this_line_vpos;
348 static int this_line_y;
349 static int this_line_pixel_height;
351 /* X position at which this display line starts. Usually zero;
352 negative if first character is partially visible. */
354 static int this_line_start_x;
356 /* Buffer that this_line_.* variables are referring to. */
358 static struct buffer *this_line_buffer;
360 /* Nonzero means truncate lines in all windows less wide than the
361 frame. */
363 int truncate_partial_width_windows;
365 /* A flag to control how to display unibyte 8-bit character. */
367 int unibyte_display_via_language_environment;
369 /* Nonzero means we have more than one non-mini-buffer-only frame.
370 Not guaranteed to be accurate except while parsing
371 frame-title-format. */
373 int multiple_frames;
375 Lisp_Object Vglobal_mode_string;
377 /* Marker for where to display an arrow on top of the buffer text. */
379 Lisp_Object Voverlay_arrow_position;
381 /* String to display for the arrow. Only used on terminal frames. */
383 Lisp_Object Voverlay_arrow_string;
385 /* Values of those variables at last redisplay. However, if
386 Voverlay_arrow_position is a marker, last_arrow_position is its
387 numerical position. */
389 static Lisp_Object last_arrow_position, last_arrow_string;
391 /* Like mode-line-format, but for the title bar on a visible frame. */
393 Lisp_Object Vframe_title_format;
395 /* Like mode-line-format, but for the title bar on an iconified frame. */
397 Lisp_Object Vicon_title_format;
399 /* List of functions to call when a window's size changes. These
400 functions get one arg, a frame on which one or more windows' sizes
401 have changed. */
403 static Lisp_Object Vwindow_size_change_functions;
405 Lisp_Object Qmenu_bar_update_hook, Vmenu_bar_update_hook;
407 /* Nonzero if overlay arrow has been displayed once in this window. */
409 static int overlay_arrow_seen;
411 /* Nonzero means highlight the region even in nonselected windows. */
413 int highlight_nonselected_windows;
415 /* If cursor motion alone moves point off frame, try scrolling this
416 many lines up or down if that will bring it back. */
418 static EMACS_INT scroll_step;
420 /* Nonzero means scroll just far enough to bring point back on the
421 screen, when appropriate. */
423 static EMACS_INT scroll_conservatively;
425 /* Recenter the window whenever point gets within this many lines of
426 the top or bottom of the window. This value is translated into a
427 pixel value by multiplying it with CANON_Y_UNIT, which means that
428 there is really a fixed pixel height scroll margin. */
430 EMACS_INT scroll_margin;
432 /* Number of windows showing the buffer of the selected window (or
433 another buffer with the same base buffer). keyboard.c refers to
434 this. */
436 int buffer_shared;
438 /* Vector containing glyphs for an ellipsis `...'. */
440 static Lisp_Object default_invis_vector[3];
442 /* Zero means display the mode-line/header-line/menu-bar in the default face
443 (this slightly odd definition is for compatibility with previous versions
444 of emacs), non-zero means display them using their respective faces.
446 This variable is deprecated. */
448 int mode_line_inverse_video;
450 /* Prompt to display in front of the mini-buffer contents. */
452 Lisp_Object minibuf_prompt;
454 /* Width of current mini-buffer prompt. Only set after display_line
455 of the line that contains the prompt. */
457 int minibuf_prompt_width;
459 /* This is the window where the echo area message was displayed. It
460 is always a mini-buffer window, but it may not be the same window
461 currently active as a mini-buffer. */
463 Lisp_Object echo_area_window;
465 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
466 pushes the current message and the value of
467 message_enable_multibyte on the stack, the function restore_message
468 pops the stack and displays MESSAGE again. */
470 Lisp_Object Vmessage_stack;
472 /* Nonzero means multibyte characters were enabled when the echo area
473 message was specified. */
475 int message_enable_multibyte;
477 /* Nonzero if we should redraw the mode lines on the next redisplay. */
479 int update_mode_lines;
481 /* Nonzero if window sizes or contents have changed since last
482 redisplay that finished. */
484 int windows_or_buffers_changed;
486 /* Nonzero means a frame's cursor type has been changed. */
488 int cursor_type_changed;
490 /* Nonzero after display_mode_line if %l was used and it displayed a
491 line number. */
493 int line_number_displayed;
495 /* Maximum buffer size for which to display line numbers. */
497 Lisp_Object Vline_number_display_limit;
499 /* Line width to consider when repositioning for line number display. */
501 static EMACS_INT line_number_display_limit_width;
503 /* Number of lines to keep in the message log buffer. t means
504 infinite. nil means don't log at all. */
506 Lisp_Object Vmessage_log_max;
508 /* The name of the *Messages* buffer, a string. */
510 static Lisp_Object Vmessages_buffer_name;
512 /* Current, index 0, and last displayed echo area message. Either
513 buffers from echo_buffers, or nil to indicate no message. */
515 Lisp_Object echo_area_buffer[2];
517 /* The buffers referenced from echo_area_buffer. */
519 static Lisp_Object echo_buffer[2];
521 /* A vector saved used in with_area_buffer to reduce consing. */
523 static Lisp_Object Vwith_echo_area_save_vector;
525 /* Non-zero means display_echo_area should display the last echo area
526 message again. Set by redisplay_preserve_echo_area. */
528 static int display_last_displayed_message_p;
530 /* Nonzero if echo area is being used by print; zero if being used by
531 message. */
533 int message_buf_print;
535 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
537 Lisp_Object Qinhibit_menubar_update;
538 int inhibit_menubar_update;
540 /* Maximum height for resizing mini-windows. Either a float
541 specifying a fraction of the available height, or an integer
542 specifying a number of lines. */
544 Lisp_Object Vmax_mini_window_height;
546 /* Non-zero means messages should be displayed with truncated
547 lines instead of being continued. */
549 int message_truncate_lines;
550 Lisp_Object Qmessage_truncate_lines;
552 /* Set to 1 in clear_message to make redisplay_internal aware
553 of an emptied echo area. */
555 static int message_cleared_p;
557 /* Non-zero means we want a hollow cursor in windows that are not
558 selected. Zero means there's no cursor in such windows. */
560 Lisp_Object Vcursor_in_non_selected_windows;
561 Lisp_Object Qcursor_in_non_selected_windows;
563 /* How to blink the default frame cursor off. */
564 Lisp_Object Vblink_cursor_alist;
566 /* A scratch glyph row with contents used for generating truncation
567 glyphs. Also used in direct_output_for_insert. */
569 #define MAX_SCRATCH_GLYPHS 100
570 struct glyph_row scratch_glyph_row;
571 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
573 /* Ascent and height of the last line processed by move_it_to. */
575 static int last_max_ascent, last_height;
577 /* Non-zero if there's a help-echo in the echo area. */
579 int help_echo_showing_p;
581 /* If >= 0, computed, exact values of mode-line and header-line height
582 to use in the macros CURRENT_MODE_LINE_HEIGHT and
583 CURRENT_HEADER_LINE_HEIGHT. */
585 int current_mode_line_height, current_header_line_height;
587 /* The maximum distance to look ahead for text properties. Values
588 that are too small let us call compute_char_face and similar
589 functions too often which is expensive. Values that are too large
590 let us call compute_char_face and alike too often because we
591 might not be interested in text properties that far away. */
593 #define TEXT_PROP_DISTANCE_LIMIT 100
595 #if GLYPH_DEBUG
597 /* Variables to turn off display optimizations from Lisp. */
599 int inhibit_try_window_id, inhibit_try_window_reusing;
600 int inhibit_try_cursor_movement;
602 /* Non-zero means print traces of redisplay if compiled with
603 GLYPH_DEBUG != 0. */
605 int trace_redisplay_p;
607 #endif /* GLYPH_DEBUG */
609 #ifdef DEBUG_TRACE_MOVE
610 /* Non-zero means trace with TRACE_MOVE to stderr. */
611 int trace_move;
613 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
614 #else
615 #define TRACE_MOVE(x) (void) 0
616 #endif
618 /* Non-zero means automatically scroll windows horizontally to make
619 point visible. */
621 int automatic_hscrolling_p;
623 /* How close to the margin can point get before the window is scrolled
624 horizontally. */
625 EMACS_INT hscroll_margin;
627 /* How much to scroll horizontally when point is inside the above margin. */
628 Lisp_Object Vhscroll_step;
630 /* A list of symbols, one for each supported image type. */
632 Lisp_Object Vimage_types;
634 /* The variable `resize-mini-windows'. If nil, don't resize
635 mini-windows. If t, always resize them to fit the text they
636 display. If `grow-only', let mini-windows grow only until they
637 become empty. */
639 Lisp_Object Vresize_mini_windows;
641 /* Buffer being redisplayed -- for redisplay_window_error. */
643 struct buffer *displayed_buffer;
645 /* Value returned from text property handlers (see below). */
647 enum prop_handled
649 HANDLED_NORMALLY,
650 HANDLED_RECOMPUTE_PROPS,
651 HANDLED_OVERLAY_STRING_CONSUMED,
652 HANDLED_RETURN
655 /* A description of text properties that redisplay is interested
656 in. */
658 struct props
660 /* The name of the property. */
661 Lisp_Object *name;
663 /* A unique index for the property. */
664 enum prop_idx idx;
666 /* A handler function called to set up iterator IT from the property
667 at IT's current position. Value is used to steer handle_stop. */
668 enum prop_handled (*handler) P_ ((struct it *it));
671 static enum prop_handled handle_face_prop P_ ((struct it *));
672 static enum prop_handled handle_invisible_prop P_ ((struct it *));
673 static enum prop_handled handle_display_prop P_ ((struct it *));
674 static enum prop_handled handle_composition_prop P_ ((struct it *));
675 static enum prop_handled handle_overlay_change P_ ((struct it *));
676 static enum prop_handled handle_fontified_prop P_ ((struct it *));
678 /* Properties handled by iterators. */
680 static struct props it_props[] =
682 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
683 /* Handle `face' before `display' because some sub-properties of
684 `display' need to know the face. */
685 {&Qface, FACE_PROP_IDX, handle_face_prop},
686 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
687 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
688 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
689 {NULL, 0, NULL}
692 /* Value is the position described by X. If X is a marker, value is
693 the marker_position of X. Otherwise, value is X. */
695 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
697 /* Enumeration returned by some move_it_.* functions internally. */
699 enum move_it_result
701 /* Not used. Undefined value. */
702 MOVE_UNDEFINED,
704 /* Move ended at the requested buffer position or ZV. */
705 MOVE_POS_MATCH_OR_ZV,
707 /* Move ended at the requested X pixel position. */
708 MOVE_X_REACHED,
710 /* Move within a line ended at the end of a line that must be
711 continued. */
712 MOVE_LINE_CONTINUED,
714 /* Move within a line ended at the end of a line that would
715 be displayed truncated. */
716 MOVE_LINE_TRUNCATED,
718 /* Move within a line ended at a line end. */
719 MOVE_NEWLINE_OR_CR
722 /* This counter is used to clear the face cache every once in a while
723 in redisplay_internal. It is incremented for each redisplay.
724 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
725 cleared. */
727 #define CLEAR_FACE_CACHE_COUNT 500
728 static int clear_face_cache_count;
730 /* Record the previous terminal frame we displayed. */
732 static struct frame *previous_terminal_frame;
734 /* Non-zero while redisplay_internal is in progress. */
736 int redisplaying_p;
738 /* Non-zero means don't free realized faces. Bound while freeing
739 realized faces is dangerous because glyph matrices might still
740 reference them. */
742 int inhibit_free_realized_faces;
743 Lisp_Object Qinhibit_free_realized_faces;
745 /* If a string, XTread_socket generates an event to display that string.
746 (The display is done in read_char.) */
748 Lisp_Object help_echo_string;
749 Lisp_Object help_echo_window;
750 Lisp_Object help_echo_object;
751 int help_echo_pos;
753 /* Temporary variable for XTread_socket. */
755 Lisp_Object previous_help_echo_string;
759 /* Function prototypes. */
761 static void setup_for_ellipsis P_ ((struct it *));
762 static void mark_window_display_accurate_1 P_ ((struct window *, int));
763 static int single_display_prop_string_p P_ ((Lisp_Object, Lisp_Object));
764 static int display_prop_string_p P_ ((Lisp_Object, Lisp_Object));
765 static int cursor_row_p P_ ((struct window *, struct glyph_row *));
766 static int redisplay_mode_lines P_ ((Lisp_Object, int));
767 static char *decode_mode_spec_coding P_ ((Lisp_Object, char *, int));
769 #if 0
770 static int invisible_text_between_p P_ ((struct it *, int, int));
771 #endif
773 static int next_element_from_ellipsis P_ ((struct it *));
774 static void pint2str P_ ((char *, int, int));
775 static struct text_pos run_window_scroll_functions P_ ((Lisp_Object,
776 struct text_pos));
777 static void reconsider_clip_changes P_ ((struct window *, struct buffer *));
778 static int text_outside_line_unchanged_p P_ ((struct window *, int, int));
779 static void store_frame_title_char P_ ((char));
780 static int store_frame_title P_ ((const unsigned char *, int, int));
781 static void x_consider_frame_title P_ ((Lisp_Object));
782 static void handle_stop P_ ((struct it *));
783 static int tool_bar_lines_needed P_ ((struct frame *));
784 static int single_display_prop_intangible_p P_ ((Lisp_Object));
785 static void ensure_echo_area_buffers P_ ((void));
786 static Lisp_Object unwind_with_echo_area_buffer P_ ((Lisp_Object));
787 static Lisp_Object with_echo_area_buffer_unwind_data P_ ((struct window *));
788 static int with_echo_area_buffer P_ ((struct window *, int,
789 int (*) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
790 EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
791 static void clear_garbaged_frames P_ ((void));
792 static int current_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
793 static int truncate_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
794 static int set_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
795 static int display_echo_area P_ ((struct window *));
796 static int display_echo_area_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
797 static int resize_mini_window_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
798 static Lisp_Object unwind_redisplay P_ ((Lisp_Object));
799 static int string_char_and_length P_ ((const unsigned char *, int, int *));
800 static struct text_pos display_prop_end P_ ((struct it *, Lisp_Object,
801 struct text_pos));
802 static int compute_window_start_on_continuation_line P_ ((struct window *));
803 static Lisp_Object safe_eval_handler P_ ((Lisp_Object));
804 static void insert_left_trunc_glyphs P_ ((struct it *));
805 static struct glyph_row *get_overlay_arrow_glyph_row P_ ((struct window *));
806 static void extend_face_to_end_of_line P_ ((struct it *));
807 static int append_space P_ ((struct it *, int));
808 static int make_cursor_line_fully_visible P_ ((struct window *));
809 static int try_scrolling P_ ((Lisp_Object, int, EMACS_INT, EMACS_INT, int, int));
810 static int try_cursor_movement P_ ((Lisp_Object, struct text_pos, int *));
811 static int trailing_whitespace_p P_ ((int));
812 static int message_log_check_duplicate P_ ((int, int, int, int));
813 static void push_it P_ ((struct it *));
814 static void pop_it P_ ((struct it *));
815 static void sync_frame_with_window_matrix_rows P_ ((struct window *));
816 static void redisplay_internal P_ ((int));
817 static int echo_area_display P_ ((int));
818 static void redisplay_windows P_ ((Lisp_Object));
819 static void redisplay_window P_ ((Lisp_Object, int));
820 static Lisp_Object redisplay_window_error ();
821 static Lisp_Object redisplay_window_0 P_ ((Lisp_Object));
822 static Lisp_Object redisplay_window_1 P_ ((Lisp_Object));
823 static void update_menu_bar P_ ((struct frame *, int));
824 static int try_window_reusing_current_matrix P_ ((struct window *));
825 static int try_window_id P_ ((struct window *));
826 static int display_line P_ ((struct it *));
827 static int display_mode_lines P_ ((struct window *));
828 static int display_mode_line P_ ((struct window *, enum face_id, Lisp_Object));
829 static int display_mode_element P_ ((struct it *, int, int, int, Lisp_Object, Lisp_Object, int));
830 static int store_mode_line_string P_ ((char *, Lisp_Object, int, int, int, Lisp_Object));
831 static char *decode_mode_spec P_ ((struct window *, int, int, int, int *));
832 static void display_menu_bar P_ ((struct window *));
833 static int display_count_lines P_ ((int, int, int, int, int *));
834 static int display_string P_ ((unsigned char *, Lisp_Object, Lisp_Object,
835 int, int, struct it *, int, int, int, int));
836 static void compute_line_metrics P_ ((struct it *));
837 static void run_redisplay_end_trigger_hook P_ ((struct it *));
838 static int get_overlay_strings P_ ((struct it *, int));
839 static void next_overlay_string P_ ((struct it *));
840 static void reseat P_ ((struct it *, struct text_pos, int));
841 static void reseat_1 P_ ((struct it *, struct text_pos, int));
842 static void back_to_previous_visible_line_start P_ ((struct it *));
843 static void reseat_at_previous_visible_line_start P_ ((struct it *));
844 static void reseat_at_next_visible_line_start P_ ((struct it *, int));
845 static int next_element_from_display_vector P_ ((struct it *));
846 static int next_element_from_string P_ ((struct it *));
847 static int next_element_from_c_string P_ ((struct it *));
848 static int next_element_from_buffer P_ ((struct it *));
849 static int next_element_from_composition P_ ((struct it *));
850 static int next_element_from_image P_ ((struct it *));
851 static int next_element_from_stretch P_ ((struct it *));
852 static void load_overlay_strings P_ ((struct it *, int));
853 static int init_from_display_pos P_ ((struct it *, struct window *,
854 struct display_pos *));
855 static void reseat_to_string P_ ((struct it *, unsigned char *,
856 Lisp_Object, int, int, int, int));
857 static enum move_it_result move_it_in_display_line_to P_ ((struct it *,
858 int, int, int));
859 void move_it_vertically_backward P_ ((struct it *, int));
860 static void init_to_row_start P_ ((struct it *, struct window *,
861 struct glyph_row *));
862 static int init_to_row_end P_ ((struct it *, struct window *,
863 struct glyph_row *));
864 static void back_to_previous_line_start P_ ((struct it *));
865 static int forward_to_next_line_start P_ ((struct it *, int *));
866 static struct text_pos string_pos_nchars_ahead P_ ((struct text_pos,
867 Lisp_Object, int));
868 static struct text_pos string_pos P_ ((int, Lisp_Object));
869 static struct text_pos c_string_pos P_ ((int, unsigned char *, int));
870 static int number_of_chars P_ ((unsigned char *, int));
871 static void compute_stop_pos P_ ((struct it *));
872 static void compute_string_pos P_ ((struct text_pos *, struct text_pos,
873 Lisp_Object));
874 static int face_before_or_after_it_pos P_ ((struct it *, int));
875 static int next_overlay_change P_ ((int));
876 static int handle_single_display_prop P_ ((struct it *, Lisp_Object,
877 Lisp_Object, struct text_pos *,
878 int));
879 static int underlying_face_id P_ ((struct it *));
880 static int in_ellipses_for_invisible_text_p P_ ((struct display_pos *,
881 struct window *));
883 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
884 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
886 #ifdef HAVE_WINDOW_SYSTEM
888 static void update_tool_bar P_ ((struct frame *, int));
889 static void build_desired_tool_bar_string P_ ((struct frame *f));
890 static int redisplay_tool_bar P_ ((struct frame *));
891 static void display_tool_bar_line P_ ((struct it *));
892 static void notice_overwritten_cursor P_ ((struct window *,
893 enum glyph_row_area,
894 int, int, int, int));
898 #endif /* HAVE_WINDOW_SYSTEM */
901 /***********************************************************************
902 Window display dimensions
903 ***********************************************************************/
905 /* Return the bottom boundary y-position for text lines in window W.
906 This is the first y position at which a line cannot start.
907 It is relative to the top of the window.
909 This is the height of W minus the height of a mode line, if any. */
911 INLINE int
912 window_text_bottom_y (w)
913 struct window *w;
915 struct frame *f = XFRAME (w->frame);
916 int height = XFASTINT (w->height) * CANON_Y_UNIT (f);
918 if (WINDOW_WANTS_MODELINE_P (w))
919 height -= CURRENT_MODE_LINE_HEIGHT (w);
920 return height;
924 /* Return the pixel width of display area AREA of window W. AREA < 0
925 means return the total width of W, not including fringes to
926 the left and right of the window. */
928 INLINE int
929 window_box_width (w, area)
930 struct window *w;
931 int area;
933 struct frame *f = XFRAME (w->frame);
934 int width = XFASTINT (w->width);
936 if (!w->pseudo_window_p)
938 width -= FRAME_SCROLL_BAR_WIDTH (f) + FRAME_FRINGE_COLS (f);
940 if (area == TEXT_AREA)
942 if (INTEGERP (w->left_margin_width))
943 width -= XFASTINT (w->left_margin_width);
944 if (INTEGERP (w->right_margin_width))
945 width -= XFASTINT (w->right_margin_width);
947 else if (area == LEFT_MARGIN_AREA)
948 width = (INTEGERP (w->left_margin_width)
949 ? XFASTINT (w->left_margin_width) : 0);
950 else if (area == RIGHT_MARGIN_AREA)
951 width = (INTEGERP (w->right_margin_width)
952 ? XFASTINT (w->right_margin_width) : 0);
955 return width * CANON_X_UNIT (f);
959 /* Return the pixel height of the display area of window W, not
960 including mode lines of W, if any. */
962 INLINE int
963 window_box_height (w)
964 struct window *w;
966 struct frame *f = XFRAME (w->frame);
967 int height = XFASTINT (w->height) * CANON_Y_UNIT (f);
969 xassert (height >= 0);
971 /* Note: the code below that determines the mode-line/header-line
972 height is essentially the same as that contained in the macro
973 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
974 the appropriate glyph row has its `mode_line_p' flag set,
975 and if it doesn't, uses estimate_mode_line_height instead. */
977 if (WINDOW_WANTS_MODELINE_P (w))
979 struct glyph_row *ml_row
980 = (w->current_matrix && w->current_matrix->rows
981 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
982 : 0);
983 if (ml_row && ml_row->mode_line_p)
984 height -= ml_row->height;
985 else
986 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
989 if (WINDOW_WANTS_HEADER_LINE_P (w))
991 struct glyph_row *hl_row
992 = (w->current_matrix && w->current_matrix->rows
993 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
994 : 0);
995 if (hl_row && hl_row->mode_line_p)
996 height -= hl_row->height;
997 else
998 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1001 /* With a very small font and a mode-line that's taller than
1002 default, we might end up with a negative height. */
1003 return max (0, height);
1007 /* Return the frame-relative coordinate of the left edge of display
1008 area AREA of window W. AREA < 0 means return the left edge of the
1009 whole window, to the right of the left fringe of W. */
1011 INLINE int
1012 window_box_left (w, area)
1013 struct window *w;
1014 int area;
1016 struct frame *f = XFRAME (w->frame);
1017 int x = FRAME_INTERNAL_BORDER_WIDTH_SAFE (f);
1019 if (!w->pseudo_window_p)
1021 x += (WINDOW_LEFT_MARGIN (w) * CANON_X_UNIT (f)
1022 + FRAME_LEFT_FRINGE_WIDTH (f));
1024 if (area == TEXT_AREA)
1025 x += window_box_width (w, LEFT_MARGIN_AREA);
1026 else if (area == RIGHT_MARGIN_AREA)
1027 x += (window_box_width (w, LEFT_MARGIN_AREA)
1028 + window_box_width (w, TEXT_AREA));
1031 return x;
1035 /* Return the frame-relative coordinate of the right edge of display
1036 area AREA of window W. AREA < 0 means return the left edge of the
1037 whole window, to the left of the right fringe of W. */
1039 INLINE int
1040 window_box_right (w, area)
1041 struct window *w;
1042 int area;
1044 return window_box_left (w, area) + window_box_width (w, area);
1048 /* Get the bounding box of the display area AREA of window W, without
1049 mode lines, in frame-relative coordinates. AREA < 0 means the
1050 whole window, not including the left and right fringes of
1051 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1052 coordinates of the upper-left corner of the box. Return in
1053 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1055 INLINE void
1056 window_box (w, area, box_x, box_y, box_width, box_height)
1057 struct window *w;
1058 int area;
1059 int *box_x, *box_y, *box_width, *box_height;
1061 struct frame *f = XFRAME (w->frame);
1063 *box_width = window_box_width (w, area);
1064 *box_height = window_box_height (w);
1065 *box_x = window_box_left (w, area);
1066 *box_y = (FRAME_INTERNAL_BORDER_WIDTH_SAFE (f)
1067 + XFASTINT (w->top) * CANON_Y_UNIT (f));
1068 if (WINDOW_WANTS_HEADER_LINE_P (w))
1069 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1073 /* Get the bounding box of the display area AREA of window W, without
1074 mode lines. AREA < 0 means the whole window, not including the
1075 left and right fringe of the window. Return in *TOP_LEFT_X
1076 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1077 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1078 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1079 box. */
1081 INLINE void
1082 window_box_edges (w, area, top_left_x, top_left_y,
1083 bottom_right_x, bottom_right_y)
1084 struct window *w;
1085 int area;
1086 int *top_left_x, *top_left_y, *bottom_right_x, *bottom_right_y;
1088 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
1089 bottom_right_y);
1090 *bottom_right_x += *top_left_x;
1091 *bottom_right_y += *top_left_y;
1096 /***********************************************************************
1097 Utilities
1098 ***********************************************************************/
1100 /* Return the bottom y-position of the line the iterator IT is in.
1101 This can modify IT's settings. */
1104 line_bottom_y (it)
1105 struct it *it;
1107 int line_height = it->max_ascent + it->max_descent;
1108 int line_top_y = it->current_y;
1110 if (line_height == 0)
1112 if (last_height)
1113 line_height = last_height;
1114 else if (IT_CHARPOS (*it) < ZV)
1116 move_it_by_lines (it, 1, 1);
1117 line_height = (it->max_ascent || it->max_descent
1118 ? it->max_ascent + it->max_descent
1119 : last_height);
1121 else
1123 struct glyph_row *row = it->glyph_row;
1125 /* Use the default character height. */
1126 it->glyph_row = NULL;
1127 it->what = IT_CHARACTER;
1128 it->c = ' ';
1129 it->len = 1;
1130 PRODUCE_GLYPHS (it);
1131 line_height = it->ascent + it->descent;
1132 it->glyph_row = row;
1136 return line_top_y + line_height;
1140 /* Return 1 if position CHARPOS is visible in window W. Set *FULLY to
1141 1 if POS is visible and the line containing POS is fully visible.
1142 EXACT_MODE_LINE_HEIGHTS_P non-zero means compute exact mode-line
1143 and header-lines heights. */
1146 pos_visible_p (w, charpos, fully, exact_mode_line_heights_p)
1147 struct window *w;
1148 int charpos, *fully, exact_mode_line_heights_p;
1150 struct it it;
1151 struct text_pos top;
1152 int visible_p;
1153 struct buffer *old_buffer = NULL;
1155 if (XBUFFER (w->buffer) != current_buffer)
1157 old_buffer = current_buffer;
1158 set_buffer_internal_1 (XBUFFER (w->buffer));
1161 *fully = visible_p = 0;
1162 SET_TEXT_POS_FROM_MARKER (top, w->start);
1164 /* Compute exact mode line heights, if requested. */
1165 if (exact_mode_line_heights_p)
1167 if (WINDOW_WANTS_MODELINE_P (w))
1168 current_mode_line_height
1169 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1170 current_buffer->mode_line_format);
1172 if (WINDOW_WANTS_HEADER_LINE_P (w))
1173 current_header_line_height
1174 = display_mode_line (w, HEADER_LINE_FACE_ID,
1175 current_buffer->header_line_format);
1178 start_display (&it, w, top);
1179 move_it_to (&it, charpos, 0, it.last_visible_y, -1,
1180 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
1182 /* Note that we may overshoot because of invisible text. */
1183 if (IT_CHARPOS (it) >= charpos)
1185 int top_y = it.current_y;
1186 int bottom_y = line_bottom_y (&it);
1187 int window_top_y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
1189 if (top_y < window_top_y)
1190 visible_p = bottom_y > window_top_y;
1191 else if (top_y < it.last_visible_y)
1193 visible_p = 1;
1194 *fully = bottom_y <= it.last_visible_y;
1197 else if (it.current_y + it.max_ascent + it.max_descent > it.last_visible_y)
1199 move_it_by_lines (&it, 1, 0);
1200 if (charpos < IT_CHARPOS (it))
1202 visible_p = 1;
1203 *fully = 0;
1207 if (old_buffer)
1208 set_buffer_internal_1 (old_buffer);
1210 current_header_line_height = current_mode_line_height = -1;
1211 return visible_p;
1215 /* Return the next character from STR which is MAXLEN bytes long.
1216 Return in *LEN the length of the character. This is like
1217 STRING_CHAR_AND_LENGTH but never returns an invalid character. If
1218 we find one, we return a `?', but with the length of the invalid
1219 character. */
1221 static INLINE int
1222 string_char_and_length (str, maxlen, len)
1223 const unsigned char *str;
1224 int maxlen, *len;
1226 int c;
1228 c = STRING_CHAR_AND_LENGTH (str, maxlen, *len);
1229 if (!CHAR_VALID_P (c, 1))
1230 /* We may not change the length here because other places in Emacs
1231 don't use this function, i.e. they silently accept invalid
1232 characters. */
1233 c = '?';
1235 return c;
1240 /* Given a position POS containing a valid character and byte position
1241 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1243 static struct text_pos
1244 string_pos_nchars_ahead (pos, string, nchars)
1245 struct text_pos pos;
1246 Lisp_Object string;
1247 int nchars;
1249 xassert (STRINGP (string) && nchars >= 0);
1251 if (STRING_MULTIBYTE (string))
1253 int rest = SBYTES (string) - BYTEPOS (pos);
1254 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1255 int len;
1257 while (nchars--)
1259 string_char_and_length (p, rest, &len);
1260 p += len, rest -= len;
1261 xassert (rest >= 0);
1262 CHARPOS (pos) += 1;
1263 BYTEPOS (pos) += len;
1266 else
1267 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1269 return pos;
1273 /* Value is the text position, i.e. character and byte position,
1274 for character position CHARPOS in STRING. */
1276 static INLINE struct text_pos
1277 string_pos (charpos, string)
1278 int charpos;
1279 Lisp_Object string;
1281 struct text_pos pos;
1282 xassert (STRINGP (string));
1283 xassert (charpos >= 0);
1284 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1285 return pos;
1289 /* Value is a text position, i.e. character and byte position, for
1290 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1291 means recognize multibyte characters. */
1293 static struct text_pos
1294 c_string_pos (charpos, s, multibyte_p)
1295 int charpos;
1296 unsigned char *s;
1297 int multibyte_p;
1299 struct text_pos pos;
1301 xassert (s != NULL);
1302 xassert (charpos >= 0);
1304 if (multibyte_p)
1306 int rest = strlen (s), len;
1308 SET_TEXT_POS (pos, 0, 0);
1309 while (charpos--)
1311 string_char_and_length (s, rest, &len);
1312 s += len, rest -= len;
1313 xassert (rest >= 0);
1314 CHARPOS (pos) += 1;
1315 BYTEPOS (pos) += len;
1318 else
1319 SET_TEXT_POS (pos, charpos, charpos);
1321 return pos;
1325 /* Value is the number of characters in C string S. MULTIBYTE_P
1326 non-zero means recognize multibyte characters. */
1328 static int
1329 number_of_chars (s, multibyte_p)
1330 unsigned char *s;
1331 int multibyte_p;
1333 int nchars;
1335 if (multibyte_p)
1337 int rest = strlen (s), len;
1338 unsigned char *p = (unsigned char *) s;
1340 for (nchars = 0; rest > 0; ++nchars)
1342 string_char_and_length (p, rest, &len);
1343 rest -= len, p += len;
1346 else
1347 nchars = strlen (s);
1349 return nchars;
1353 /* Compute byte position NEWPOS->bytepos corresponding to
1354 NEWPOS->charpos. POS is a known position in string STRING.
1355 NEWPOS->charpos must be >= POS.charpos. */
1357 static void
1358 compute_string_pos (newpos, pos, string)
1359 struct text_pos *newpos, pos;
1360 Lisp_Object string;
1362 xassert (STRINGP (string));
1363 xassert (CHARPOS (*newpos) >= CHARPOS (pos));
1365 if (STRING_MULTIBYTE (string))
1366 *newpos = string_pos_nchars_ahead (pos, string,
1367 CHARPOS (*newpos) - CHARPOS (pos));
1368 else
1369 BYTEPOS (*newpos) = CHARPOS (*newpos);
1372 /* EXPORT:
1373 Return an estimation of the pixel height of mode or top lines on
1374 frame F. FACE_ID specifies what line's height to estimate. */
1377 estimate_mode_line_height (f, face_id)
1378 struct frame *f;
1379 enum face_id face_id;
1381 #ifdef HAVE_WINDOW_SYSTEM
1382 if (FRAME_WINDOW_P (f))
1384 int height = FONT_HEIGHT (FRAME_FONT (f));
1386 /* This function is called so early when Emacs starts that the face
1387 cache and mode line face are not yet initialized. */
1388 if (FRAME_FACE_CACHE (f))
1390 struct face *face = FACE_FROM_ID (f, face_id);
1391 if (face)
1393 if (face->font)
1394 height = FONT_HEIGHT (face->font);
1395 if (face->box_line_width > 0)
1396 height += 2 * face->box_line_width;
1400 return height;
1402 #endif
1404 return 1;
1407 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1408 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1409 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1410 not force the value into range. */
1412 void
1413 pixel_to_glyph_coords (f, pix_x, pix_y, x, y, bounds, noclip)
1414 FRAME_PTR f;
1415 register int pix_x, pix_y;
1416 int *x, *y;
1417 NativeRectangle *bounds;
1418 int noclip;
1421 #ifdef HAVE_WINDOW_SYSTEM
1422 if (FRAME_WINDOW_P (f))
1424 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to round down
1425 even for negative values. */
1426 if (pix_x < 0)
1427 pix_x -= FONT_WIDTH (FRAME_FONT (f)) - 1;
1428 if (pix_y < 0)
1429 pix_y -= FRAME_X_OUTPUT(f)->line_height - 1;
1431 pix_x = PIXEL_TO_CHAR_COL (f, pix_x);
1432 pix_y = PIXEL_TO_CHAR_ROW (f, pix_y);
1434 if (bounds)
1435 STORE_NATIVE_RECT (*bounds,
1436 CHAR_TO_PIXEL_COL (f, pix_x),
1437 CHAR_TO_PIXEL_ROW (f, pix_y),
1438 FONT_WIDTH (FRAME_FONT (f)) - 1,
1439 FRAME_X_OUTPUT (f)->line_height - 1);
1441 if (!noclip)
1443 if (pix_x < 0)
1444 pix_x = 0;
1445 else if (pix_x > FRAME_WINDOW_WIDTH (f))
1446 pix_x = FRAME_WINDOW_WIDTH (f);
1448 if (pix_y < 0)
1449 pix_y = 0;
1450 else if (pix_y > f->height)
1451 pix_y = f->height;
1454 #endif
1456 *x = pix_x;
1457 *y = pix_y;
1461 /* Given HPOS/VPOS in the current matrix of W, return corresponding
1462 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
1463 can't tell the positions because W's display is not up to date,
1464 return 0. */
1467 glyph_to_pixel_coords (w, hpos, vpos, frame_x, frame_y)
1468 struct window *w;
1469 int hpos, vpos;
1470 int *frame_x, *frame_y;
1472 #ifdef HAVE_WINDOW_SYSTEM
1473 if (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w))))
1475 int success_p;
1477 xassert (hpos >= 0 && hpos < w->current_matrix->matrix_w);
1478 xassert (vpos >= 0 && vpos < w->current_matrix->matrix_h);
1480 if (display_completed)
1482 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
1483 struct glyph *glyph = row->glyphs[TEXT_AREA];
1484 struct glyph *end = glyph + min (hpos, row->used[TEXT_AREA]);
1486 hpos = row->x;
1487 vpos = row->y;
1488 while (glyph < end)
1490 hpos += glyph->pixel_width;
1491 ++glyph;
1494 success_p = 1;
1496 else
1498 hpos = vpos = 0;
1499 success_p = 0;
1502 *frame_x = WINDOW_TO_FRAME_PIXEL_X (w, hpos);
1503 *frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, vpos);
1504 return success_p;
1506 #endif
1508 *frame_x = hpos;
1509 *frame_y = vpos;
1510 return 1;
1514 #ifdef HAVE_WINDOW_SYSTEM
1516 /* Find the glyph under window-relative coordinates X/Y in window W.
1517 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1518 strings. Return in *HPOS and *VPOS the row and column number of
1519 the glyph found. Return in *AREA the glyph area containing X.
1520 Value is a pointer to the glyph found or null if X/Y is not on
1521 text, or we can't tell because W's current matrix is not up to
1522 date. */
1524 static struct glyph *
1525 x_y_to_hpos_vpos (w, x, y, hpos, vpos, area, buffer_only_p)
1526 struct window *w;
1527 int x, y;
1528 int *hpos, *vpos, *area;
1529 int buffer_only_p;
1531 struct glyph *glyph, *end;
1532 struct glyph_row *row = NULL;
1533 int x0, i, left_area_width;
1535 /* Find row containing Y. Give up if some row is not enabled. */
1536 for (i = 0; i < w->current_matrix->nrows; ++i)
1538 row = MATRIX_ROW (w->current_matrix, i);
1539 if (!row->enabled_p)
1540 return NULL;
1541 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1542 break;
1545 *vpos = i;
1546 *hpos = 0;
1548 /* Give up if Y is not in the window. */
1549 if (i == w->current_matrix->nrows)
1550 return NULL;
1552 /* Get the glyph area containing X. */
1553 if (w->pseudo_window_p)
1555 *area = TEXT_AREA;
1556 x0 = 0;
1558 else
1560 left_area_width = window_box_width (w, LEFT_MARGIN_AREA);
1561 if (x < left_area_width)
1563 *area = LEFT_MARGIN_AREA;
1564 x0 = 0;
1566 else if (x < left_area_width + window_box_width (w, TEXT_AREA))
1568 *area = TEXT_AREA;
1569 x0 = row->x + left_area_width;
1571 else
1573 *area = RIGHT_MARGIN_AREA;
1574 x0 = left_area_width + window_box_width (w, TEXT_AREA);
1578 /* Find glyph containing X. */
1579 glyph = row->glyphs[*area];
1580 end = glyph + row->used[*area];
1581 while (glyph < end)
1583 if (x < x0 + glyph->pixel_width)
1585 if (w->pseudo_window_p)
1586 break;
1587 else if (!buffer_only_p || BUFFERP (glyph->object))
1588 break;
1591 x0 += glyph->pixel_width;
1592 ++glyph;
1595 if (glyph == end)
1596 return NULL;
1598 *hpos = glyph - row->glyphs[*area];
1599 return glyph;
1603 /* EXPORT:
1604 Convert frame-relative x/y to coordinates relative to window W.
1605 Takes pseudo-windows into account. */
1607 void
1608 frame_to_window_pixel_xy (w, x, y)
1609 struct window *w;
1610 int *x, *y;
1612 if (w->pseudo_window_p)
1614 /* A pseudo-window is always full-width, and starts at the
1615 left edge of the frame, plus a frame border. */
1616 struct frame *f = XFRAME (w->frame);
1617 *x -= FRAME_INTERNAL_BORDER_WIDTH_SAFE (f);
1618 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1620 else
1622 *x = FRAME_TO_WINDOW_PIXEL_X (w, *x);
1623 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1627 /* EXPORT:
1628 Return in *R the clipping rectangle for glyph string S. */
1630 void
1631 get_glyph_string_clip_rect (s, nr)
1632 struct glyph_string *s;
1633 NativeRectangle *nr;
1635 XRectangle r;
1637 if (s->row->full_width_p)
1639 /* Draw full-width. X coordinates are relative to S->w->left. */
1640 int canon_x = CANON_X_UNIT (s->f);
1642 r.x = WINDOW_LEFT_MARGIN (s->w) * canon_x;
1643 r.width = XFASTINT (s->w->width) * canon_x;
1645 if (FRAME_HAS_VERTICAL_SCROLL_BARS (s->f))
1647 int width = FRAME_SCROLL_BAR_WIDTH (s->f) * canon_x;
1648 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (s->f))
1649 r.x -= width;
1652 r.x += FRAME_INTERNAL_BORDER_WIDTH (s->f);
1654 /* Unless displaying a mode or menu bar line, which are always
1655 fully visible, clip to the visible part of the row. */
1656 if (s->w->pseudo_window_p)
1657 r.height = s->row->visible_height;
1658 else
1659 r.height = s->height;
1661 else
1663 /* This is a text line that may be partially visible. */
1664 r.x = WINDOW_AREA_TO_FRAME_PIXEL_X (s->w, s->area, 0);
1665 r.width = window_box_width (s->w, s->area);
1666 r.height = s->row->visible_height;
1669 /* If S draws overlapping rows, it's sufficient to use the top and
1670 bottom of the window for clipping because this glyph string
1671 intentionally draws over other lines. */
1672 if (s->for_overlaps_p)
1674 r.y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s->w);
1675 r.height = window_text_bottom_y (s->w) - r.y;
1677 else
1679 /* Don't use S->y for clipping because it doesn't take partially
1680 visible lines into account. For example, it can be negative for
1681 partially visible lines at the top of a window. */
1682 if (!s->row->full_width_p
1683 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
1684 r.y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s->w);
1685 else
1686 r.y = max (0, s->row->y);
1688 /* If drawing a tool-bar window, draw it over the internal border
1689 at the top of the window. */
1690 if (s->w == XWINDOW (s->f->tool_bar_window))
1691 r.y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
1694 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
1696 #ifdef HAVE_NTGUI
1697 /* ++KFS: From W32 port, but it looks ok for all platforms to me. */
1698 /* If drawing the cursor, don't let glyph draw outside its
1699 advertised boundaries. Cleartype does this under some circumstances. */
1700 if (s->hl == DRAW_CURSOR)
1702 if (s->x > r.x)
1704 r.width -= s->x - r.x;
1705 r.x = s->x;
1707 r.width = min (r.width, s->first_glyph->pixel_width);
1709 #endif
1711 #ifdef CONVERT_FROM_XRECT
1712 CONVERT_FROM_XRECT (r, *nr);
1713 #else
1714 *nr = r;
1715 #endif
1718 #endif /* HAVE_WINDOW_SYSTEM */
1721 /***********************************************************************
1722 Lisp form evaluation
1723 ***********************************************************************/
1725 /* Error handler for safe_eval and safe_call. */
1727 static Lisp_Object
1728 safe_eval_handler (arg)
1729 Lisp_Object arg;
1731 add_to_log ("Error during redisplay: %s", arg, Qnil);
1732 return Qnil;
1736 /* Evaluate SEXPR and return the result, or nil if something went
1737 wrong. Prevent redisplay during the evaluation. */
1739 Lisp_Object
1740 safe_eval (sexpr)
1741 Lisp_Object sexpr;
1743 Lisp_Object val;
1745 if (inhibit_eval_during_redisplay)
1746 val = Qnil;
1747 else
1749 int count = SPECPDL_INDEX ();
1750 struct gcpro gcpro1;
1752 GCPRO1 (sexpr);
1753 specbind (Qinhibit_redisplay, Qt);
1754 /* Use Qt to ensure debugger does not run,
1755 so there is no possibility of wanting to redisplay. */
1756 val = internal_condition_case_1 (Feval, sexpr, Qt,
1757 safe_eval_handler);
1758 UNGCPRO;
1759 val = unbind_to (count, val);
1762 return val;
1766 /* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1].
1767 Return the result, or nil if something went wrong. Prevent
1768 redisplay during the evaluation. */
1770 Lisp_Object
1771 safe_call (nargs, args)
1772 int nargs;
1773 Lisp_Object *args;
1775 Lisp_Object val;
1777 if (inhibit_eval_during_redisplay)
1778 val = Qnil;
1779 else
1781 int count = SPECPDL_INDEX ();
1782 struct gcpro gcpro1;
1784 GCPRO1 (args[0]);
1785 gcpro1.nvars = nargs;
1786 specbind (Qinhibit_redisplay, Qt);
1787 /* Use Qt to ensure debugger does not run,
1788 so there is no possibility of wanting to redisplay. */
1789 val = internal_condition_case_2 (Ffuncall, nargs, args, Qt,
1790 safe_eval_handler);
1791 UNGCPRO;
1792 val = unbind_to (count, val);
1795 return val;
1799 /* Call function FN with one argument ARG.
1800 Return the result, or nil if something went wrong. */
1802 Lisp_Object
1803 safe_call1 (fn, arg)
1804 Lisp_Object fn, arg;
1806 Lisp_Object args[2];
1807 args[0] = fn;
1808 args[1] = arg;
1809 return safe_call (2, args);
1814 /***********************************************************************
1815 Debugging
1816 ***********************************************************************/
1818 #if 0
1820 /* Define CHECK_IT to perform sanity checks on iterators.
1821 This is for debugging. It is too slow to do unconditionally. */
1823 static void
1824 check_it (it)
1825 struct it *it;
1827 if (it->method == next_element_from_string)
1829 xassert (STRINGP (it->string));
1830 xassert (IT_STRING_CHARPOS (*it) >= 0);
1832 else if (it->method == next_element_from_buffer)
1834 /* Check that character and byte positions agree. */
1835 xassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
1838 if (it->dpvec)
1839 xassert (it->current.dpvec_index >= 0);
1840 else
1841 xassert (it->current.dpvec_index < 0);
1844 #define CHECK_IT(IT) check_it ((IT))
1846 #else /* not 0 */
1848 #define CHECK_IT(IT) (void) 0
1850 #endif /* not 0 */
1853 #if GLYPH_DEBUG
1855 /* Check that the window end of window W is what we expect it
1856 to be---the last row in the current matrix displaying text. */
1858 static void
1859 check_window_end (w)
1860 struct window *w;
1862 if (!MINI_WINDOW_P (w)
1863 && !NILP (w->window_end_valid))
1865 struct glyph_row *row;
1866 xassert ((row = MATRIX_ROW (w->current_matrix,
1867 XFASTINT (w->window_end_vpos)),
1868 !row->enabled_p
1869 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
1870 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
1874 #define CHECK_WINDOW_END(W) check_window_end ((W))
1876 #else /* not GLYPH_DEBUG */
1878 #define CHECK_WINDOW_END(W) (void) 0
1880 #endif /* not GLYPH_DEBUG */
1884 /***********************************************************************
1885 Iterator initialization
1886 ***********************************************************************/
1888 /* Initialize IT for displaying current_buffer in window W, starting
1889 at character position CHARPOS. CHARPOS < 0 means that no buffer
1890 position is specified which is useful when the iterator is assigned
1891 a position later. BYTEPOS is the byte position corresponding to
1892 CHARPOS. BYTEPOS < 0 means compute it from CHARPOS.
1894 If ROW is not null, calls to produce_glyphs with IT as parameter
1895 will produce glyphs in that row.
1897 BASE_FACE_ID is the id of a base face to use. It must be one of
1898 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
1899 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
1900 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
1902 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
1903 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
1904 will be initialized to use the corresponding mode line glyph row of
1905 the desired matrix of W. */
1907 void
1908 init_iterator (it, w, charpos, bytepos, row, base_face_id)
1909 struct it *it;
1910 struct window *w;
1911 int charpos, bytepos;
1912 struct glyph_row *row;
1913 enum face_id base_face_id;
1915 int highlight_region_p;
1917 /* Some precondition checks. */
1918 xassert (w != NULL && it != NULL);
1919 xassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
1920 && charpos <= ZV));
1922 /* If face attributes have been changed since the last redisplay,
1923 free realized faces now because they depend on face definitions
1924 that might have changed. Don't free faces while there might be
1925 desired matrices pending which reference these faces. */
1926 if (face_change_count && !inhibit_free_realized_faces)
1928 face_change_count = 0;
1929 free_all_realized_faces (Qnil);
1932 /* Use one of the mode line rows of W's desired matrix if
1933 appropriate. */
1934 if (row == NULL)
1936 if (base_face_id == MODE_LINE_FACE_ID
1937 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
1938 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
1939 else if (base_face_id == HEADER_LINE_FACE_ID)
1940 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
1943 /* Clear IT. */
1944 bzero (it, sizeof *it);
1945 it->current.overlay_string_index = -1;
1946 it->current.dpvec_index = -1;
1947 it->base_face_id = base_face_id;
1949 /* The window in which we iterate over current_buffer: */
1950 XSETWINDOW (it->window, w);
1951 it->w = w;
1952 it->f = XFRAME (w->frame);
1954 /* Extra space between lines (on window systems only). */
1955 if (base_face_id == DEFAULT_FACE_ID
1956 && FRAME_WINDOW_P (it->f))
1958 if (NATNUMP (current_buffer->extra_line_spacing))
1959 it->extra_line_spacing = XFASTINT (current_buffer->extra_line_spacing);
1960 else if (it->f->extra_line_spacing > 0)
1961 it->extra_line_spacing = it->f->extra_line_spacing;
1964 /* If realized faces have been removed, e.g. because of face
1965 attribute changes of named faces, recompute them. When running
1966 in batch mode, the face cache of Vterminal_frame is null. If
1967 we happen to get called, make a dummy face cache. */
1968 if (
1969 #ifndef WINDOWSNT
1970 noninteractive &&
1971 #endif
1972 FRAME_FACE_CACHE (it->f) == NULL)
1973 init_frame_faces (it->f);
1974 if (FRAME_FACE_CACHE (it->f)->used == 0)
1975 recompute_basic_faces (it->f);
1977 /* Current value of the `space-width', and 'height' properties. */
1978 it->space_width = Qnil;
1979 it->font_height = Qnil;
1981 /* Are control characters displayed as `^C'? */
1982 it->ctl_arrow_p = !NILP (current_buffer->ctl_arrow);
1984 /* -1 means everything between a CR and the following line end
1985 is invisible. >0 means lines indented more than this value are
1986 invisible. */
1987 it->selective = (INTEGERP (current_buffer->selective_display)
1988 ? XFASTINT (current_buffer->selective_display)
1989 : (!NILP (current_buffer->selective_display)
1990 ? -1 : 0));
1991 it->selective_display_ellipsis_p
1992 = !NILP (current_buffer->selective_display_ellipses);
1994 /* Display table to use. */
1995 it->dp = window_display_table (w);
1997 /* Are multibyte characters enabled in current_buffer? */
1998 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
2000 /* Non-zero if we should highlight the region. */
2001 highlight_region_p
2002 = (!NILP (Vtransient_mark_mode)
2003 && !NILP (current_buffer->mark_active)
2004 && XMARKER (current_buffer->mark)->buffer != 0);
2006 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
2007 start and end of a visible region in window IT->w. Set both to
2008 -1 to indicate no region. */
2009 if (highlight_region_p
2010 /* Maybe highlight only in selected window. */
2011 && (/* Either show region everywhere. */
2012 highlight_nonselected_windows
2013 /* Or show region in the selected window. */
2014 || w == XWINDOW (selected_window)
2015 /* Or show the region if we are in the mini-buffer and W is
2016 the window the mini-buffer refers to. */
2017 || (MINI_WINDOW_P (XWINDOW (selected_window))
2018 && WINDOWP (minibuf_selected_window)
2019 && w == XWINDOW (minibuf_selected_window))))
2021 int charpos = marker_position (current_buffer->mark);
2022 it->region_beg_charpos = min (PT, charpos);
2023 it->region_end_charpos = max (PT, charpos);
2025 else
2026 it->region_beg_charpos = it->region_end_charpos = -1;
2028 /* Get the position at which the redisplay_end_trigger hook should
2029 be run, if it is to be run at all. */
2030 if (MARKERP (w->redisplay_end_trigger)
2031 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2032 it->redisplay_end_trigger_charpos
2033 = marker_position (w->redisplay_end_trigger);
2034 else if (INTEGERP (w->redisplay_end_trigger))
2035 it->redisplay_end_trigger_charpos = XINT (w->redisplay_end_trigger);
2037 /* Correct bogus values of tab_width. */
2038 it->tab_width = XINT (current_buffer->tab_width);
2039 if (it->tab_width <= 0 || it->tab_width > 1000)
2040 it->tab_width = 8;
2042 /* Are lines in the display truncated? */
2043 it->truncate_lines_p
2044 = (base_face_id != DEFAULT_FACE_ID
2045 || XINT (it->w->hscroll)
2046 || (truncate_partial_width_windows
2047 && !WINDOW_FULL_WIDTH_P (it->w))
2048 || !NILP (current_buffer->truncate_lines));
2050 /* Get dimensions of truncation and continuation glyphs. These are
2051 displayed as fringe bitmaps under X, so we don't need them for such
2052 frames. */
2053 if (!FRAME_WINDOW_P (it->f))
2055 if (it->truncate_lines_p)
2057 /* We will need the truncation glyph. */
2058 xassert (it->glyph_row == NULL);
2059 produce_special_glyphs (it, IT_TRUNCATION);
2060 it->truncation_pixel_width = it->pixel_width;
2062 else
2064 /* We will need the continuation glyph. */
2065 xassert (it->glyph_row == NULL);
2066 produce_special_glyphs (it, IT_CONTINUATION);
2067 it->continuation_pixel_width = it->pixel_width;
2070 /* Reset these values to zero because the produce_special_glyphs
2071 above has changed them. */
2072 it->pixel_width = it->ascent = it->descent = 0;
2073 it->phys_ascent = it->phys_descent = 0;
2076 /* Set this after getting the dimensions of truncation and
2077 continuation glyphs, so that we don't produce glyphs when calling
2078 produce_special_glyphs, above. */
2079 it->glyph_row = row;
2080 it->area = TEXT_AREA;
2082 /* Get the dimensions of the display area. The display area
2083 consists of the visible window area plus a horizontally scrolled
2084 part to the left of the window. All x-values are relative to the
2085 start of this total display area. */
2086 if (base_face_id != DEFAULT_FACE_ID)
2088 /* Mode lines, menu bar in terminal frames. */
2089 it->first_visible_x = 0;
2090 it->last_visible_x = XFASTINT (w->width) * CANON_X_UNIT (it->f);
2092 else
2094 it->first_visible_x
2095 = XFASTINT (it->w->hscroll) * CANON_X_UNIT (it->f);
2096 it->last_visible_x = (it->first_visible_x
2097 + window_box_width (w, TEXT_AREA));
2099 /* If we truncate lines, leave room for the truncator glyph(s) at
2100 the right margin. Otherwise, leave room for the continuation
2101 glyph(s). Truncation and continuation glyphs are not inserted
2102 for window-based redisplay. */
2103 if (!FRAME_WINDOW_P (it->f))
2105 if (it->truncate_lines_p)
2106 it->last_visible_x -= it->truncation_pixel_width;
2107 else
2108 it->last_visible_x -= it->continuation_pixel_width;
2111 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
2112 it->current_y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w) + w->vscroll;
2115 /* Leave room for a border glyph. */
2116 if (!FRAME_WINDOW_P (it->f)
2117 && !WINDOW_RIGHTMOST_P (it->w))
2118 it->last_visible_x -= 1;
2120 it->last_visible_y = window_text_bottom_y (w);
2122 /* For mode lines and alike, arrange for the first glyph having a
2123 left box line if the face specifies a box. */
2124 if (base_face_id != DEFAULT_FACE_ID)
2126 struct face *face;
2128 it->face_id = base_face_id;
2130 /* If we have a boxed mode line, make the first character appear
2131 with a left box line. */
2132 face = FACE_FROM_ID (it->f, base_face_id);
2133 if (face->box != FACE_NO_BOX)
2134 it->start_of_box_run_p = 1;
2137 /* If a buffer position was specified, set the iterator there,
2138 getting overlays and face properties from that position. */
2139 if (charpos >= BUF_BEG (current_buffer))
2141 it->end_charpos = ZV;
2142 it->face_id = -1;
2143 IT_CHARPOS (*it) = charpos;
2145 /* Compute byte position if not specified. */
2146 if (bytepos < charpos)
2147 IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos);
2148 else
2149 IT_BYTEPOS (*it) = bytepos;
2151 /* Compute faces etc. */
2152 reseat (it, it->current.pos, 1);
2155 CHECK_IT (it);
2159 /* Initialize IT for the display of window W with window start POS. */
2161 void
2162 start_display (it, w, pos)
2163 struct it *it;
2164 struct window *w;
2165 struct text_pos pos;
2167 struct glyph_row *row;
2168 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
2170 row = w->desired_matrix->rows + first_vpos;
2171 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
2173 if (!it->truncate_lines_p)
2175 int start_at_line_beg_p;
2176 int first_y = it->current_y;
2178 /* If window start is not at a line start, skip forward to POS to
2179 get the correct continuation lines width. */
2180 start_at_line_beg_p = (CHARPOS (pos) == BEGV
2181 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
2182 if (!start_at_line_beg_p)
2184 int new_x;
2186 reseat_at_previous_visible_line_start (it);
2187 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
2189 new_x = it->current_x + it->pixel_width;
2191 /* If lines are continued, this line may end in the middle
2192 of a multi-glyph character (e.g. a control character
2193 displayed as \003, or in the middle of an overlay
2194 string). In this case move_it_to above will not have
2195 taken us to the start of the continuation line but to the
2196 end of the continued line. */
2197 if (it->current_x > 0
2198 && !it->truncate_lines_p /* Lines are continued. */
2199 && (/* And glyph doesn't fit on the line. */
2200 new_x > it->last_visible_x
2201 /* Or it fits exactly and we're on a window
2202 system frame. */
2203 || (new_x == it->last_visible_x
2204 && FRAME_WINDOW_P (it->f))))
2206 if (it->current.dpvec_index >= 0
2207 || it->current.overlay_string_index >= 0)
2209 set_iterator_to_next (it, 1);
2210 move_it_in_display_line_to (it, -1, -1, 0);
2213 it->continuation_lines_width += it->current_x;
2216 /* We're starting a new display line, not affected by the
2217 height of the continued line, so clear the appropriate
2218 fields in the iterator structure. */
2219 it->max_ascent = it->max_descent = 0;
2220 it->max_phys_ascent = it->max_phys_descent = 0;
2222 it->current_y = first_y;
2223 it->vpos = 0;
2224 it->current_x = it->hpos = 0;
2228 #if 0 /* Don't assert the following because start_display is sometimes
2229 called intentionally with a window start that is not at a
2230 line start. Please leave this code in as a comment. */
2232 /* Window start should be on a line start, now. */
2233 xassert (it->continuation_lines_width
2234 || IT_CHARPOS (it) == BEGV
2235 || FETCH_BYTE (IT_BYTEPOS (it) - 1) == '\n');
2236 #endif /* 0 */
2240 /* Return 1 if POS is a position in ellipses displayed for invisible
2241 text. W is the window we display, for text property lookup. */
2243 static int
2244 in_ellipses_for_invisible_text_p (pos, w)
2245 struct display_pos *pos;
2246 struct window *w;
2248 Lisp_Object prop, window;
2249 int ellipses_p = 0;
2250 int charpos = CHARPOS (pos->pos);
2252 /* If POS specifies a position in a display vector, this might
2253 be for an ellipsis displayed for invisible text. We won't
2254 get the iterator set up for delivering that ellipsis unless
2255 we make sure that it gets aware of the invisible text. */
2256 if (pos->dpvec_index >= 0
2257 && pos->overlay_string_index < 0
2258 && CHARPOS (pos->string_pos) < 0
2259 && charpos > BEGV
2260 && (XSETWINDOW (window, w),
2261 prop = Fget_char_property (make_number (charpos),
2262 Qinvisible, window),
2263 !TEXT_PROP_MEANS_INVISIBLE (prop)))
2265 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
2266 window);
2267 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
2270 return ellipses_p;
2274 /* Initialize IT for stepping through current_buffer in window W,
2275 starting at position POS that includes overlay string and display
2276 vector/ control character translation position information. Value
2277 is zero if there are overlay strings with newlines at POS. */
2279 static int
2280 init_from_display_pos (it, w, pos)
2281 struct it *it;
2282 struct window *w;
2283 struct display_pos *pos;
2285 int charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
2286 int i, overlay_strings_with_newlines = 0;
2288 /* If POS specifies a position in a display vector, this might
2289 be for an ellipsis displayed for invisible text. We won't
2290 get the iterator set up for delivering that ellipsis unless
2291 we make sure that it gets aware of the invisible text. */
2292 if (in_ellipses_for_invisible_text_p (pos, w))
2294 --charpos;
2295 bytepos = 0;
2298 /* Keep in mind: the call to reseat in init_iterator skips invisible
2299 text, so we might end up at a position different from POS. This
2300 is only a problem when POS is a row start after a newline and an
2301 overlay starts there with an after-string, and the overlay has an
2302 invisible property. Since we don't skip invisible text in
2303 display_line and elsewhere immediately after consuming the
2304 newline before the row start, such a POS will not be in a string,
2305 but the call to init_iterator below will move us to the
2306 after-string. */
2307 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
2309 for (i = 0; i < it->n_overlay_strings; ++i)
2311 const char *s = SDATA (it->overlay_strings[i]);
2312 const char *e = s + SBYTES (it->overlay_strings[i]);
2314 while (s < e && *s != '\n')
2315 ++s;
2317 if (s < e)
2319 overlay_strings_with_newlines = 1;
2320 break;
2324 /* If position is within an overlay string, set up IT to the right
2325 overlay string. */
2326 if (pos->overlay_string_index >= 0)
2328 int relative_index;
2330 /* If the first overlay string happens to have a `display'
2331 property for an image, the iterator will be set up for that
2332 image, and we have to undo that setup first before we can
2333 correct the overlay string index. */
2334 if (it->method == next_element_from_image)
2335 pop_it (it);
2337 /* We already have the first chunk of overlay strings in
2338 IT->overlay_strings. Load more until the one for
2339 pos->overlay_string_index is in IT->overlay_strings. */
2340 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
2342 int n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
2343 it->current.overlay_string_index = 0;
2344 while (n--)
2346 load_overlay_strings (it, 0);
2347 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
2351 it->current.overlay_string_index = pos->overlay_string_index;
2352 relative_index = (it->current.overlay_string_index
2353 % OVERLAY_STRING_CHUNK_SIZE);
2354 it->string = it->overlay_strings[relative_index];
2355 xassert (STRINGP (it->string));
2356 it->current.string_pos = pos->string_pos;
2357 it->method = next_element_from_string;
2360 #if 0 /* This is bogus because POS not having an overlay string
2361 position does not mean it's after the string. Example: A
2362 line starting with a before-string and initialization of IT
2363 to the previous row's end position. */
2364 else if (it->current.overlay_string_index >= 0)
2366 /* If POS says we're already after an overlay string ending at
2367 POS, make sure to pop the iterator because it will be in
2368 front of that overlay string. When POS is ZV, we've thereby
2369 also ``processed'' overlay strings at ZV. */
2370 while (it->sp)
2371 pop_it (it);
2372 it->current.overlay_string_index = -1;
2373 it->method = next_element_from_buffer;
2374 if (CHARPOS (pos->pos) == ZV)
2375 it->overlay_strings_at_end_processed_p = 1;
2377 #endif /* 0 */
2379 if (CHARPOS (pos->string_pos) >= 0)
2381 /* Recorded position is not in an overlay string, but in another
2382 string. This can only be a string from a `display' property.
2383 IT should already be filled with that string. */
2384 it->current.string_pos = pos->string_pos;
2385 xassert (STRINGP (it->string));
2388 /* Restore position in display vector translations, control
2389 character translations or ellipses. */
2390 if (pos->dpvec_index >= 0)
2392 if (it->dpvec == NULL)
2393 get_next_display_element (it);
2394 xassert (it->dpvec && it->current.dpvec_index == 0);
2395 it->current.dpvec_index = pos->dpvec_index;
2398 CHECK_IT (it);
2399 return !overlay_strings_with_newlines;
2403 /* Initialize IT for stepping through current_buffer in window W
2404 starting at ROW->start. */
2406 static void
2407 init_to_row_start (it, w, row)
2408 struct it *it;
2409 struct window *w;
2410 struct glyph_row *row;
2412 init_from_display_pos (it, w, &row->start);
2413 it->continuation_lines_width = row->continuation_lines_width;
2414 CHECK_IT (it);
2418 /* Initialize IT for stepping through current_buffer in window W
2419 starting in the line following ROW, i.e. starting at ROW->end.
2420 Value is zero if there are overlay strings with newlines at ROW's
2421 end position. */
2423 static int
2424 init_to_row_end (it, w, row)
2425 struct it *it;
2426 struct window *w;
2427 struct glyph_row *row;
2429 int success = 0;
2431 if (init_from_display_pos (it, w, &row->end))
2433 if (row->continued_p)
2434 it->continuation_lines_width
2435 = row->continuation_lines_width + row->pixel_width;
2436 CHECK_IT (it);
2437 success = 1;
2440 return success;
2446 /***********************************************************************
2447 Text properties
2448 ***********************************************************************/
2450 /* Called when IT reaches IT->stop_charpos. Handle text property and
2451 overlay changes. Set IT->stop_charpos to the next position where
2452 to stop. */
2454 static void
2455 handle_stop (it)
2456 struct it *it;
2458 enum prop_handled handled;
2459 int handle_overlay_change_p = 1;
2460 struct props *p;
2462 it->dpvec = NULL;
2463 it->current.dpvec_index = -1;
2467 handled = HANDLED_NORMALLY;
2469 /* Call text property handlers. */
2470 for (p = it_props; p->handler; ++p)
2472 handled = p->handler (it);
2474 if (handled == HANDLED_RECOMPUTE_PROPS)
2475 break;
2476 else if (handled == HANDLED_RETURN)
2477 return;
2478 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
2479 handle_overlay_change_p = 0;
2482 if (handled != HANDLED_RECOMPUTE_PROPS)
2484 /* Don't check for overlay strings below when set to deliver
2485 characters from a display vector. */
2486 if (it->method == next_element_from_display_vector)
2487 handle_overlay_change_p = 0;
2489 /* Handle overlay changes. */
2490 if (handle_overlay_change_p)
2491 handled = handle_overlay_change (it);
2493 /* Determine where to stop next. */
2494 if (handled == HANDLED_NORMALLY)
2495 compute_stop_pos (it);
2498 while (handled == HANDLED_RECOMPUTE_PROPS);
2502 /* Compute IT->stop_charpos from text property and overlay change
2503 information for IT's current position. */
2505 static void
2506 compute_stop_pos (it)
2507 struct it *it;
2509 register INTERVAL iv, next_iv;
2510 Lisp_Object object, limit, position;
2512 /* If nowhere else, stop at the end. */
2513 it->stop_charpos = it->end_charpos;
2515 if (STRINGP (it->string))
2517 /* Strings are usually short, so don't limit the search for
2518 properties. */
2519 object = it->string;
2520 limit = Qnil;
2521 position = make_number (IT_STRING_CHARPOS (*it));
2523 else
2525 int charpos;
2527 /* If next overlay change is in front of the current stop pos
2528 (which is IT->end_charpos), stop there. Note: value of
2529 next_overlay_change is point-max if no overlay change
2530 follows. */
2531 charpos = next_overlay_change (IT_CHARPOS (*it));
2532 if (charpos < it->stop_charpos)
2533 it->stop_charpos = charpos;
2535 /* If showing the region, we have to stop at the region
2536 start or end because the face might change there. */
2537 if (it->region_beg_charpos > 0)
2539 if (IT_CHARPOS (*it) < it->region_beg_charpos)
2540 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
2541 else if (IT_CHARPOS (*it) < it->region_end_charpos)
2542 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
2545 /* Set up variables for computing the stop position from text
2546 property changes. */
2547 XSETBUFFER (object, current_buffer);
2548 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
2549 position = make_number (IT_CHARPOS (*it));
2553 /* Get the interval containing IT's position. Value is a null
2554 interval if there isn't such an interval. */
2555 iv = validate_interval_range (object, &position, &position, 0);
2556 if (!NULL_INTERVAL_P (iv))
2558 Lisp_Object values_here[LAST_PROP_IDX];
2559 struct props *p;
2561 /* Get properties here. */
2562 for (p = it_props; p->handler; ++p)
2563 values_here[p->idx] = textget (iv->plist, *p->name);
2565 /* Look for an interval following iv that has different
2566 properties. */
2567 for (next_iv = next_interval (iv);
2568 (!NULL_INTERVAL_P (next_iv)
2569 && (NILP (limit)
2570 || XFASTINT (limit) > next_iv->position));
2571 next_iv = next_interval (next_iv))
2573 for (p = it_props; p->handler; ++p)
2575 Lisp_Object new_value;
2577 new_value = textget (next_iv->plist, *p->name);
2578 if (!EQ (values_here[p->idx], new_value))
2579 break;
2582 if (p->handler)
2583 break;
2586 if (!NULL_INTERVAL_P (next_iv))
2588 if (INTEGERP (limit)
2589 && next_iv->position >= XFASTINT (limit))
2590 /* No text property change up to limit. */
2591 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
2592 else
2593 /* Text properties change in next_iv. */
2594 it->stop_charpos = min (it->stop_charpos, next_iv->position);
2598 xassert (STRINGP (it->string)
2599 || (it->stop_charpos >= BEGV
2600 && it->stop_charpos >= IT_CHARPOS (*it)));
2604 /* Return the position of the next overlay change after POS in
2605 current_buffer. Value is point-max if no overlay change
2606 follows. This is like `next-overlay-change' but doesn't use
2607 xmalloc. */
2609 static int
2610 next_overlay_change (pos)
2611 int pos;
2613 int noverlays;
2614 int endpos;
2615 Lisp_Object *overlays;
2616 int len;
2617 int i;
2619 /* Get all overlays at the given position. */
2620 len = 10;
2621 overlays = (Lisp_Object *) alloca (len * sizeof *overlays);
2622 noverlays = overlays_at (pos, 0, &overlays, &len, &endpos, NULL, 1);
2623 if (noverlays > len)
2625 len = noverlays;
2626 overlays = (Lisp_Object *) alloca (len * sizeof *overlays);
2627 noverlays = overlays_at (pos, 0, &overlays, &len, &endpos, NULL, 1);
2630 /* If any of these overlays ends before endpos,
2631 use its ending point instead. */
2632 for (i = 0; i < noverlays; ++i)
2634 Lisp_Object oend;
2635 int oendpos;
2637 oend = OVERLAY_END (overlays[i]);
2638 oendpos = OVERLAY_POSITION (oend);
2639 endpos = min (endpos, oendpos);
2642 return endpos;
2647 /***********************************************************************
2648 Fontification
2649 ***********************************************************************/
2651 /* Handle changes in the `fontified' property of the current buffer by
2652 calling hook functions from Qfontification_functions to fontify
2653 regions of text. */
2655 static enum prop_handled
2656 handle_fontified_prop (it)
2657 struct it *it;
2659 Lisp_Object prop, pos;
2660 enum prop_handled handled = HANDLED_NORMALLY;
2662 /* Get the value of the `fontified' property at IT's current buffer
2663 position. (The `fontified' property doesn't have a special
2664 meaning in strings.) If the value is nil, call functions from
2665 Qfontification_functions. */
2666 if (!STRINGP (it->string)
2667 && it->s == NULL
2668 && !NILP (Vfontification_functions)
2669 && !NILP (Vrun_hooks)
2670 && (pos = make_number (IT_CHARPOS (*it)),
2671 prop = Fget_char_property (pos, Qfontified, Qnil),
2672 NILP (prop)))
2674 int count = SPECPDL_INDEX ();
2675 Lisp_Object val;
2677 val = Vfontification_functions;
2678 specbind (Qfontification_functions, Qnil);
2680 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
2681 safe_call1 (val, pos);
2682 else
2684 Lisp_Object globals, fn;
2685 struct gcpro gcpro1, gcpro2;
2687 globals = Qnil;
2688 GCPRO2 (val, globals);
2690 for (; CONSP (val); val = XCDR (val))
2692 fn = XCAR (val);
2694 if (EQ (fn, Qt))
2696 /* A value of t indicates this hook has a local
2697 binding; it means to run the global binding too.
2698 In a global value, t should not occur. If it
2699 does, we must ignore it to avoid an endless
2700 loop. */
2701 for (globals = Fdefault_value (Qfontification_functions);
2702 CONSP (globals);
2703 globals = XCDR (globals))
2705 fn = XCAR (globals);
2706 if (!EQ (fn, Qt))
2707 safe_call1 (fn, pos);
2710 else
2711 safe_call1 (fn, pos);
2714 UNGCPRO;
2717 unbind_to (count, Qnil);
2719 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
2720 something. This avoids an endless loop if they failed to
2721 fontify the text for which reason ever. */
2722 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
2723 handled = HANDLED_RECOMPUTE_PROPS;
2726 return handled;
2731 /***********************************************************************
2732 Faces
2733 ***********************************************************************/
2735 /* Set up iterator IT from face properties at its current position.
2736 Called from handle_stop. */
2738 static enum prop_handled
2739 handle_face_prop (it)
2740 struct it *it;
2742 int new_face_id, next_stop;
2744 if (!STRINGP (it->string))
2746 new_face_id
2747 = face_at_buffer_position (it->w,
2748 IT_CHARPOS (*it),
2749 it->region_beg_charpos,
2750 it->region_end_charpos,
2751 &next_stop,
2752 (IT_CHARPOS (*it)
2753 + TEXT_PROP_DISTANCE_LIMIT),
2756 /* Is this a start of a run of characters with box face?
2757 Caveat: this can be called for a freshly initialized
2758 iterator; face_id is -1 in this case. We know that the new
2759 face will not change until limit, i.e. if the new face has a
2760 box, all characters up to limit will have one. But, as
2761 usual, we don't know whether limit is really the end. */
2762 if (new_face_id != it->face_id)
2764 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
2766 /* If new face has a box but old face has not, this is
2767 the start of a run of characters with box, i.e. it has
2768 a shadow on the left side. The value of face_id of the
2769 iterator will be -1 if this is the initial call that gets
2770 the face. In this case, we have to look in front of IT's
2771 position and see whether there is a face != new_face_id. */
2772 it->start_of_box_run_p
2773 = (new_face->box != FACE_NO_BOX
2774 && (it->face_id >= 0
2775 || IT_CHARPOS (*it) == BEG
2776 || new_face_id != face_before_it_pos (it)));
2777 it->face_box_p = new_face->box != FACE_NO_BOX;
2780 else
2782 int base_face_id, bufpos;
2784 if (it->current.overlay_string_index >= 0)
2785 bufpos = IT_CHARPOS (*it);
2786 else
2787 bufpos = 0;
2789 /* For strings from a buffer, i.e. overlay strings or strings
2790 from a `display' property, use the face at IT's current
2791 buffer position as the base face to merge with, so that
2792 overlay strings appear in the same face as surrounding
2793 text, unless they specify their own faces. */
2794 base_face_id = underlying_face_id (it);
2796 new_face_id = face_at_string_position (it->w,
2797 it->string,
2798 IT_STRING_CHARPOS (*it),
2799 bufpos,
2800 it->region_beg_charpos,
2801 it->region_end_charpos,
2802 &next_stop,
2803 base_face_id, 0);
2805 #if 0 /* This shouldn't be neccessary. Let's check it. */
2806 /* If IT is used to display a mode line we would really like to
2807 use the mode line face instead of the frame's default face. */
2808 if (it->glyph_row == MATRIX_MODE_LINE_ROW (it->w->desired_matrix)
2809 && new_face_id == DEFAULT_FACE_ID)
2810 new_face_id = CURRENT_MODE_LINE_FACE_ID (it->w);
2811 #endif
2813 /* Is this a start of a run of characters with box? Caveat:
2814 this can be called for a freshly allocated iterator; face_id
2815 is -1 is this case. We know that the new face will not
2816 change until the next check pos, i.e. if the new face has a
2817 box, all characters up to that position will have a
2818 box. But, as usual, we don't know whether that position
2819 is really the end. */
2820 if (new_face_id != it->face_id)
2822 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
2823 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
2825 /* If new face has a box but old face hasn't, this is the
2826 start of a run of characters with box, i.e. it has a
2827 shadow on the left side. */
2828 it->start_of_box_run_p
2829 = new_face->box && (old_face == NULL || !old_face->box);
2830 it->face_box_p = new_face->box != FACE_NO_BOX;
2834 it->face_id = new_face_id;
2835 return HANDLED_NORMALLY;
2839 /* Return the ID of the face ``underlying'' IT's current position,
2840 which is in a string. If the iterator is associated with a
2841 buffer, return the face at IT's current buffer position.
2842 Otherwise, use the iterator's base_face_id. */
2844 static int
2845 underlying_face_id (it)
2846 struct it *it;
2848 int face_id = it->base_face_id, i;
2850 xassert (STRINGP (it->string));
2852 for (i = it->sp - 1; i >= 0; --i)
2853 if (NILP (it->stack[i].string))
2854 face_id = it->stack[i].face_id;
2856 return face_id;
2860 /* Compute the face one character before or after the current position
2861 of IT. BEFORE_P non-zero means get the face in front of IT's
2862 position. Value is the id of the face. */
2864 static int
2865 face_before_or_after_it_pos (it, before_p)
2866 struct it *it;
2867 int before_p;
2869 int face_id, limit;
2870 int next_check_charpos;
2871 struct text_pos pos;
2873 xassert (it->s == NULL);
2875 if (STRINGP (it->string))
2877 int bufpos, base_face_id;
2879 /* No face change past the end of the string (for the case
2880 we are padding with spaces). No face change before the
2881 string start. */
2882 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
2883 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
2884 return it->face_id;
2886 /* Set pos to the position before or after IT's current position. */
2887 if (before_p)
2888 pos = string_pos (IT_STRING_CHARPOS (*it) - 1, it->string);
2889 else
2890 /* For composition, we must check the character after the
2891 composition. */
2892 pos = (it->what == IT_COMPOSITION
2893 ? string_pos (IT_STRING_CHARPOS (*it) + it->cmp_len, it->string)
2894 : string_pos (IT_STRING_CHARPOS (*it) + 1, it->string));
2896 if (it->current.overlay_string_index >= 0)
2897 bufpos = IT_CHARPOS (*it);
2898 else
2899 bufpos = 0;
2901 base_face_id = underlying_face_id (it);
2903 /* Get the face for ASCII, or unibyte. */
2904 face_id = face_at_string_position (it->w,
2905 it->string,
2906 CHARPOS (pos),
2907 bufpos,
2908 it->region_beg_charpos,
2909 it->region_end_charpos,
2910 &next_check_charpos,
2911 base_face_id, 0);
2913 /* Correct the face for charsets different from ASCII. Do it
2914 for the multibyte case only. The face returned above is
2915 suitable for unibyte text if IT->string is unibyte. */
2916 if (STRING_MULTIBYTE (it->string))
2918 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos);
2919 int rest = SBYTES (it->string) - BYTEPOS (pos);
2920 int c, len;
2921 struct face *face = FACE_FROM_ID (it->f, face_id);
2923 c = string_char_and_length (p, rest, &len);
2924 face_id = FACE_FOR_CHAR (it->f, face, c);
2927 else
2929 if ((IT_CHARPOS (*it) >= ZV && !before_p)
2930 || (IT_CHARPOS (*it) <= BEGV && before_p))
2931 return it->face_id;
2933 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
2934 pos = it->current.pos;
2936 if (before_p)
2937 DEC_TEXT_POS (pos, it->multibyte_p);
2938 else
2940 if (it->what == IT_COMPOSITION)
2941 /* For composition, we must check the position after the
2942 composition. */
2943 pos.charpos += it->cmp_len, pos.bytepos += it->len;
2944 else
2945 INC_TEXT_POS (pos, it->multibyte_p);
2948 /* Determine face for CHARSET_ASCII, or unibyte. */
2949 face_id = face_at_buffer_position (it->w,
2950 CHARPOS (pos),
2951 it->region_beg_charpos,
2952 it->region_end_charpos,
2953 &next_check_charpos,
2954 limit, 0);
2956 /* Correct the face for charsets different from ASCII. Do it
2957 for the multibyte case only. The face returned above is
2958 suitable for unibyte text if current_buffer is unibyte. */
2959 if (it->multibyte_p)
2961 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
2962 struct face *face = FACE_FROM_ID (it->f, face_id);
2963 face_id = FACE_FOR_CHAR (it->f, face, c);
2967 return face_id;
2972 /***********************************************************************
2973 Invisible text
2974 ***********************************************************************/
2976 /* Set up iterator IT from invisible properties at its current
2977 position. Called from handle_stop. */
2979 static enum prop_handled
2980 handle_invisible_prop (it)
2981 struct it *it;
2983 enum prop_handled handled = HANDLED_NORMALLY;
2985 if (STRINGP (it->string))
2987 extern Lisp_Object Qinvisible;
2988 Lisp_Object prop, end_charpos, limit, charpos;
2990 /* Get the value of the invisible text property at the
2991 current position. Value will be nil if there is no such
2992 property. */
2993 charpos = make_number (IT_STRING_CHARPOS (*it));
2994 prop = Fget_text_property (charpos, Qinvisible, it->string);
2996 if (!NILP (prop)
2997 && IT_STRING_CHARPOS (*it) < it->end_charpos)
2999 handled = HANDLED_RECOMPUTE_PROPS;
3001 /* Get the position at which the next change of the
3002 invisible text property can be found in IT->string.
3003 Value will be nil if the property value is the same for
3004 all the rest of IT->string. */
3005 XSETINT (limit, SCHARS (it->string));
3006 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
3007 it->string, limit);
3009 /* Text at current position is invisible. The next
3010 change in the property is at position end_charpos.
3011 Move IT's current position to that position. */
3012 if (INTEGERP (end_charpos)
3013 && XFASTINT (end_charpos) < XFASTINT (limit))
3015 struct text_pos old;
3016 old = it->current.string_pos;
3017 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
3018 compute_string_pos (&it->current.string_pos, old, it->string);
3020 else
3022 /* The rest of the string is invisible. If this is an
3023 overlay string, proceed with the next overlay string
3024 or whatever comes and return a character from there. */
3025 if (it->current.overlay_string_index >= 0)
3027 next_overlay_string (it);
3028 /* Don't check for overlay strings when we just
3029 finished processing them. */
3030 handled = HANDLED_OVERLAY_STRING_CONSUMED;
3032 else
3034 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
3035 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
3040 else
3042 int invis_p, newpos, next_stop, start_charpos;
3043 Lisp_Object pos, prop, overlay;
3045 /* First of all, is there invisible text at this position? */
3046 start_charpos = IT_CHARPOS (*it);
3047 pos = make_number (IT_CHARPOS (*it));
3048 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
3049 &overlay);
3050 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3052 /* If we are on invisible text, skip over it. */
3053 if (invis_p && IT_CHARPOS (*it) < it->end_charpos)
3055 /* Record whether we have to display an ellipsis for the
3056 invisible text. */
3057 int display_ellipsis_p = invis_p == 2;
3059 handled = HANDLED_RECOMPUTE_PROPS;
3061 /* Loop skipping over invisible text. The loop is left at
3062 ZV or with IT on the first char being visible again. */
3065 /* Try to skip some invisible text. Return value is the
3066 position reached which can be equal to IT's position
3067 if there is nothing invisible here. This skips both
3068 over invisible text properties and overlays with
3069 invisible property. */
3070 newpos = skip_invisible (IT_CHARPOS (*it),
3071 &next_stop, ZV, it->window);
3073 /* If we skipped nothing at all we weren't at invisible
3074 text in the first place. If everything to the end of
3075 the buffer was skipped, end the loop. */
3076 if (newpos == IT_CHARPOS (*it) || newpos >= ZV)
3077 invis_p = 0;
3078 else
3080 /* We skipped some characters but not necessarily
3081 all there are. Check if we ended up on visible
3082 text. Fget_char_property returns the property of
3083 the char before the given position, i.e. if we
3084 get invis_p = 0, this means that the char at
3085 newpos is visible. */
3086 pos = make_number (newpos);
3087 prop = Fget_char_property (pos, Qinvisible, it->window);
3088 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3091 /* If we ended up on invisible text, proceed to
3092 skip starting with next_stop. */
3093 if (invis_p)
3094 IT_CHARPOS (*it) = next_stop;
3096 while (invis_p);
3098 /* The position newpos is now either ZV or on visible text. */
3099 IT_CHARPOS (*it) = newpos;
3100 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
3102 /* If there are before-strings at the start of invisible
3103 text, and the text is invisible because of a text
3104 property, arrange to show before-strings because 20.x did
3105 it that way. (If the text is invisible because of an
3106 overlay property instead of a text property, this is
3107 already handled in the overlay code.) */
3108 if (NILP (overlay)
3109 && get_overlay_strings (it, start_charpos))
3111 handled = HANDLED_RECOMPUTE_PROPS;
3112 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
3114 else if (display_ellipsis_p)
3115 setup_for_ellipsis (it);
3119 return handled;
3123 /* Make iterator IT return `...' next. */
3125 static void
3126 setup_for_ellipsis (it)
3127 struct it *it;
3129 if (it->dp
3130 && VECTORP (DISP_INVIS_VECTOR (it->dp)))
3132 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
3133 it->dpvec = v->contents;
3134 it->dpend = v->contents + v->size;
3136 else
3138 /* Default `...'. */
3139 it->dpvec = default_invis_vector;
3140 it->dpend = default_invis_vector + 3;
3143 /* The ellipsis display does not replace the display of the
3144 character at the new position. Indicate this by setting
3145 IT->dpvec_char_len to zero. */
3146 it->dpvec_char_len = 0;
3148 it->current.dpvec_index = 0;
3149 it->method = next_element_from_display_vector;
3154 /***********************************************************************
3155 'display' property
3156 ***********************************************************************/
3158 /* Set up iterator IT from `display' property at its current position.
3159 Called from handle_stop. */
3161 static enum prop_handled
3162 handle_display_prop (it)
3163 struct it *it;
3165 Lisp_Object prop, object;
3166 struct text_pos *position;
3167 int display_replaced_p = 0;
3169 if (STRINGP (it->string))
3171 object = it->string;
3172 position = &it->current.string_pos;
3174 else
3176 object = it->w->buffer;
3177 position = &it->current.pos;
3180 /* Reset those iterator values set from display property values. */
3181 it->font_height = Qnil;
3182 it->space_width = Qnil;
3183 it->voffset = 0;
3185 /* We don't support recursive `display' properties, i.e. string
3186 values that have a string `display' property, that have a string
3187 `display' property etc. */
3188 if (!it->string_from_display_prop_p)
3189 it->area = TEXT_AREA;
3191 prop = Fget_char_property (make_number (position->charpos),
3192 Qdisplay, object);
3193 if (NILP (prop))
3194 return HANDLED_NORMALLY;
3196 if (CONSP (prop)
3197 /* Simple properties. */
3198 && !EQ (XCAR (prop), Qimage)
3199 && !EQ (XCAR (prop), Qspace)
3200 && !EQ (XCAR (prop), Qwhen)
3201 && !EQ (XCAR (prop), Qspace_width)
3202 && !EQ (XCAR (prop), Qheight)
3203 && !EQ (XCAR (prop), Qraise)
3204 /* Marginal area specifications. */
3205 && !(CONSP (XCAR (prop)) && EQ (XCAR (XCAR (prop)), Qmargin))
3206 && !NILP (XCAR (prop)))
3208 for (; CONSP (prop); prop = XCDR (prop))
3210 if (handle_single_display_prop (it, XCAR (prop), object,
3211 position, display_replaced_p))
3212 display_replaced_p = 1;
3215 else if (VECTORP (prop))
3217 int i;
3218 for (i = 0; i < ASIZE (prop); ++i)
3219 if (handle_single_display_prop (it, AREF (prop, i), object,
3220 position, display_replaced_p))
3221 display_replaced_p = 1;
3223 else
3225 if (handle_single_display_prop (it, prop, object, position, 0))
3226 display_replaced_p = 1;
3229 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
3233 /* Value is the position of the end of the `display' property starting
3234 at START_POS in OBJECT. */
3236 static struct text_pos
3237 display_prop_end (it, object, start_pos)
3238 struct it *it;
3239 Lisp_Object object;
3240 struct text_pos start_pos;
3242 Lisp_Object end;
3243 struct text_pos end_pos;
3245 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
3246 Qdisplay, object, Qnil);
3247 CHARPOS (end_pos) = XFASTINT (end);
3248 if (STRINGP (object))
3249 compute_string_pos (&end_pos, start_pos, it->string);
3250 else
3251 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
3253 return end_pos;
3257 /* Set up IT from a single `display' sub-property value PROP. OBJECT
3258 is the object in which the `display' property was found. *POSITION
3259 is the position at which it was found. DISPLAY_REPLACED_P non-zero
3260 means that we previously saw a display sub-property which already
3261 replaced text display with something else, for example an image;
3262 ignore such properties after the first one has been processed.
3264 If PROP is a `space' or `image' sub-property, set *POSITION to the
3265 end position of the `display' property.
3267 Value is non-zero if something was found which replaces the display
3268 of buffer or string text. */
3270 static int
3271 handle_single_display_prop (it, prop, object, position,
3272 display_replaced_before_p)
3273 struct it *it;
3274 Lisp_Object prop;
3275 Lisp_Object object;
3276 struct text_pos *position;
3277 int display_replaced_before_p;
3279 Lisp_Object value;
3280 int replaces_text_display_p = 0;
3281 Lisp_Object form;
3283 /* If PROP is a list of the form `(when FORM . VALUE)', FORM is
3284 evaluated. If the result is nil, VALUE is ignored. */
3285 form = Qt;
3286 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3288 prop = XCDR (prop);
3289 if (!CONSP (prop))
3290 return 0;
3291 form = XCAR (prop);
3292 prop = XCDR (prop);
3295 if (!NILP (form) && !EQ (form, Qt))
3297 int count = SPECPDL_INDEX ();
3298 struct gcpro gcpro1;
3300 /* Bind `object' to the object having the `display' property, a
3301 buffer or string. Bind `position' to the position in the
3302 object where the property was found, and `buffer-position'
3303 to the current position in the buffer. */
3304 specbind (Qobject, object);
3305 specbind (Qposition, make_number (CHARPOS (*position)));
3306 specbind (Qbuffer_position,
3307 make_number (STRINGP (object)
3308 ? IT_CHARPOS (*it) : CHARPOS (*position)));
3309 GCPRO1 (form);
3310 form = safe_eval (form);
3311 UNGCPRO;
3312 unbind_to (count, Qnil);
3315 if (NILP (form))
3316 return 0;
3318 if (CONSP (prop)
3319 && EQ (XCAR (prop), Qheight)
3320 && CONSP (XCDR (prop)))
3322 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3323 return 0;
3325 /* `(height HEIGHT)'. */
3326 it->font_height = XCAR (XCDR (prop));
3327 if (!NILP (it->font_height))
3329 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3330 int new_height = -1;
3332 if (CONSP (it->font_height)
3333 && (EQ (XCAR (it->font_height), Qplus)
3334 || EQ (XCAR (it->font_height), Qminus))
3335 && CONSP (XCDR (it->font_height))
3336 && INTEGERP (XCAR (XCDR (it->font_height))))
3338 /* `(+ N)' or `(- N)' where N is an integer. */
3339 int steps = XINT (XCAR (XCDR (it->font_height)));
3340 if (EQ (XCAR (it->font_height), Qplus))
3341 steps = - steps;
3342 it->face_id = smaller_face (it->f, it->face_id, steps);
3344 else if (FUNCTIONP (it->font_height))
3346 /* Call function with current height as argument.
3347 Value is the new height. */
3348 Lisp_Object height;
3349 height = safe_call1 (it->font_height,
3350 face->lface[LFACE_HEIGHT_INDEX]);
3351 if (NUMBERP (height))
3352 new_height = XFLOATINT (height);
3354 else if (NUMBERP (it->font_height))
3356 /* Value is a multiple of the canonical char height. */
3357 struct face *face;
3359 face = FACE_FROM_ID (it->f, DEFAULT_FACE_ID);
3360 new_height = (XFLOATINT (it->font_height)
3361 * XINT (face->lface[LFACE_HEIGHT_INDEX]));
3363 else
3365 /* Evaluate IT->font_height with `height' bound to the
3366 current specified height to get the new height. */
3367 Lisp_Object value;
3368 int count = SPECPDL_INDEX ();
3370 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
3371 value = safe_eval (it->font_height);
3372 unbind_to (count, Qnil);
3374 if (NUMBERP (value))
3375 new_height = XFLOATINT (value);
3378 if (new_height > 0)
3379 it->face_id = face_with_height (it->f, it->face_id, new_height);
3382 else if (CONSP (prop)
3383 && EQ (XCAR (prop), Qspace_width)
3384 && CONSP (XCDR (prop)))
3386 /* `(space_width WIDTH)'. */
3387 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3388 return 0;
3390 value = XCAR (XCDR (prop));
3391 if (NUMBERP (value) && XFLOATINT (value) > 0)
3392 it->space_width = value;
3394 else if (CONSP (prop)
3395 && EQ (XCAR (prop), Qraise)
3396 && CONSP (XCDR (prop)))
3398 /* `(raise FACTOR)'. */
3399 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3400 return 0;
3402 #ifdef HAVE_WINDOW_SYSTEM
3403 value = XCAR (XCDR (prop));
3404 if (NUMBERP (value))
3406 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3407 it->voffset = - (XFLOATINT (value)
3408 * (FONT_HEIGHT (face->font)));
3410 #endif /* HAVE_WINDOW_SYSTEM */
3412 else if (!it->string_from_display_prop_p)
3414 /* `((margin left-margin) VALUE)' or `((margin right-margin)
3415 VALUE) or `((margin nil) VALUE)' or VALUE. */
3416 Lisp_Object location, value;
3417 struct text_pos start_pos;
3418 int valid_p;
3420 /* Characters having this form of property are not displayed, so
3421 we have to find the end of the property. */
3422 start_pos = *position;
3423 *position = display_prop_end (it, object, start_pos);
3424 value = Qnil;
3426 /* Let's stop at the new position and assume that all
3427 text properties change there. */
3428 it->stop_charpos = position->charpos;
3430 location = Qunbound;
3431 if (CONSP (prop) && CONSP (XCAR (prop)))
3433 Lisp_Object tem;
3435 value = XCDR (prop);
3436 if (CONSP (value))
3437 value = XCAR (value);
3439 tem = XCAR (prop);
3440 if (EQ (XCAR (tem), Qmargin)
3441 && (tem = XCDR (tem),
3442 tem = CONSP (tem) ? XCAR (tem) : Qnil,
3443 (NILP (tem)
3444 || EQ (tem, Qleft_margin)
3445 || EQ (tem, Qright_margin))))
3446 location = tem;
3449 if (EQ (location, Qunbound))
3451 location = Qnil;
3452 value = prop;
3455 #ifdef HAVE_WINDOW_SYSTEM
3456 if (FRAME_TERMCAP_P (it->f))
3457 valid_p = STRINGP (value);
3458 else
3459 valid_p = (STRINGP (value)
3460 || (CONSP (value) && EQ (XCAR (value), Qspace))
3461 || valid_image_p (value));
3462 #else /* not HAVE_WINDOW_SYSTEM */
3463 valid_p = STRINGP (value);
3464 #endif /* not HAVE_WINDOW_SYSTEM */
3466 if ((EQ (location, Qleft_margin)
3467 || EQ (location, Qright_margin)
3468 || NILP (location))
3469 && valid_p
3470 && !display_replaced_before_p)
3472 replaces_text_display_p = 1;
3474 /* Save current settings of IT so that we can restore them
3475 when we are finished with the glyph property value. */
3476 push_it (it);
3478 if (NILP (location))
3479 it->area = TEXT_AREA;
3480 else if (EQ (location, Qleft_margin))
3481 it->area = LEFT_MARGIN_AREA;
3482 else
3483 it->area = RIGHT_MARGIN_AREA;
3485 if (STRINGP (value))
3487 it->string = value;
3488 it->multibyte_p = STRING_MULTIBYTE (it->string);
3489 it->current.overlay_string_index = -1;
3490 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
3491 it->end_charpos = it->string_nchars = SCHARS (it->string);
3492 it->method = next_element_from_string;
3493 it->stop_charpos = 0;
3494 it->string_from_display_prop_p = 1;
3495 /* Say that we haven't consumed the characters with
3496 `display' property yet. The call to pop_it in
3497 set_iterator_to_next will clean this up. */
3498 *position = start_pos;
3500 else if (CONSP (value) && EQ (XCAR (value), Qspace))
3502 it->method = next_element_from_stretch;
3503 it->object = value;
3504 it->current.pos = it->position = start_pos;
3506 #ifdef HAVE_WINDOW_SYSTEM
3507 else
3509 it->what = IT_IMAGE;
3510 it->image_id = lookup_image (it->f, value);
3511 it->position = start_pos;
3512 it->object = NILP (object) ? it->w->buffer : object;
3513 it->method = next_element_from_image;
3515 /* Say that we haven't consumed the characters with
3516 `display' property yet. The call to pop_it in
3517 set_iterator_to_next will clean this up. */
3518 *position = start_pos;
3520 #endif /* HAVE_WINDOW_SYSTEM */
3522 else
3523 /* Invalid property or property not supported. Restore
3524 the position to what it was before. */
3525 *position = start_pos;
3528 return replaces_text_display_p;
3532 /* Check if PROP is a display sub-property value whose text should be
3533 treated as intangible. */
3535 static int
3536 single_display_prop_intangible_p (prop)
3537 Lisp_Object prop;
3539 /* Skip over `when FORM'. */
3540 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3542 prop = XCDR (prop);
3543 if (!CONSP (prop))
3544 return 0;
3545 prop = XCDR (prop);
3548 if (STRINGP (prop))
3549 return 1;
3551 if (!CONSP (prop))
3552 return 0;
3554 /* Skip over `margin LOCATION'. If LOCATION is in the margins,
3555 we don't need to treat text as intangible. */
3556 if (EQ (XCAR (prop), Qmargin))
3558 prop = XCDR (prop);
3559 if (!CONSP (prop))
3560 return 0;
3562 prop = XCDR (prop);
3563 if (!CONSP (prop)
3564 || EQ (XCAR (prop), Qleft_margin)
3565 || EQ (XCAR (prop), Qright_margin))
3566 return 0;
3569 return CONSP (prop) && EQ (XCAR (prop), Qimage);
3573 /* Check if PROP is a display property value whose text should be
3574 treated as intangible. */
3577 display_prop_intangible_p (prop)
3578 Lisp_Object prop;
3580 if (CONSP (prop)
3581 && CONSP (XCAR (prop))
3582 && !EQ (Qmargin, XCAR (XCAR (prop))))
3584 /* A list of sub-properties. */
3585 while (CONSP (prop))
3587 if (single_display_prop_intangible_p (XCAR (prop)))
3588 return 1;
3589 prop = XCDR (prop);
3592 else if (VECTORP (prop))
3594 /* A vector of sub-properties. */
3595 int i;
3596 for (i = 0; i < ASIZE (prop); ++i)
3597 if (single_display_prop_intangible_p (AREF (prop, i)))
3598 return 1;
3600 else
3601 return single_display_prop_intangible_p (prop);
3603 return 0;
3607 /* Return 1 if PROP is a display sub-property value containing STRING. */
3609 static int
3610 single_display_prop_string_p (prop, string)
3611 Lisp_Object prop, string;
3613 if (EQ (string, prop))
3614 return 1;
3616 /* Skip over `when FORM'. */
3617 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3619 prop = XCDR (prop);
3620 if (!CONSP (prop))
3621 return 0;
3622 prop = XCDR (prop);
3625 if (CONSP (prop))
3626 /* Skip over `margin LOCATION'. */
3627 if (EQ (XCAR (prop), Qmargin))
3629 prop = XCDR (prop);
3630 if (!CONSP (prop))
3631 return 0;
3633 prop = XCDR (prop);
3634 if (!CONSP (prop))
3635 return 0;
3638 return CONSP (prop) && EQ (XCAR (prop), string);
3642 /* Return 1 if STRING appears in the `display' property PROP. */
3644 static int
3645 display_prop_string_p (prop, string)
3646 Lisp_Object prop, string;
3648 if (CONSP (prop)
3649 && CONSP (XCAR (prop))
3650 && !EQ (Qmargin, XCAR (XCAR (prop))))
3652 /* A list of sub-properties. */
3653 while (CONSP (prop))
3655 if (single_display_prop_string_p (XCAR (prop), string))
3656 return 1;
3657 prop = XCDR (prop);
3660 else if (VECTORP (prop))
3662 /* A vector of sub-properties. */
3663 int i;
3664 for (i = 0; i < ASIZE (prop); ++i)
3665 if (single_display_prop_string_p (AREF (prop, i), string))
3666 return 1;
3668 else
3669 return single_display_prop_string_p (prop, string);
3671 return 0;
3675 /* Determine from which buffer position in W's buffer STRING comes
3676 from. AROUND_CHARPOS is an approximate position where it could
3677 be from. Value is the buffer position or 0 if it couldn't be
3678 determined.
3680 W's buffer must be current.
3682 This function is necessary because we don't record buffer positions
3683 in glyphs generated from strings (to keep struct glyph small).
3684 This function may only use code that doesn't eval because it is
3685 called asynchronously from note_mouse_highlight. */
3688 string_buffer_position (w, string, around_charpos)
3689 struct window *w;
3690 Lisp_Object string;
3691 int around_charpos;
3693 Lisp_Object limit, prop, pos;
3694 const int MAX_DISTANCE = 1000;
3695 int found = 0;
3697 pos = make_number (around_charpos);
3698 limit = make_number (min (XINT (pos) + MAX_DISTANCE, ZV));
3699 while (!found && !EQ (pos, limit))
3701 prop = Fget_char_property (pos, Qdisplay, Qnil);
3702 if (!NILP (prop) && display_prop_string_p (prop, string))
3703 found = 1;
3704 else
3705 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil, limit);
3708 if (!found)
3710 pos = make_number (around_charpos);
3711 limit = make_number (max (XINT (pos) - MAX_DISTANCE, BEGV));
3712 while (!found && !EQ (pos, limit))
3714 prop = Fget_char_property (pos, Qdisplay, Qnil);
3715 if (!NILP (prop) && display_prop_string_p (prop, string))
3716 found = 1;
3717 else
3718 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
3719 limit);
3723 return found ? XINT (pos) : 0;
3728 /***********************************************************************
3729 `composition' property
3730 ***********************************************************************/
3732 /* Set up iterator IT from `composition' property at its current
3733 position. Called from handle_stop. */
3735 static enum prop_handled
3736 handle_composition_prop (it)
3737 struct it *it;
3739 Lisp_Object prop, string;
3740 int pos, pos_byte, end;
3741 enum prop_handled handled = HANDLED_NORMALLY;
3743 if (STRINGP (it->string))
3745 pos = IT_STRING_CHARPOS (*it);
3746 pos_byte = IT_STRING_BYTEPOS (*it);
3747 string = it->string;
3749 else
3751 pos = IT_CHARPOS (*it);
3752 pos_byte = IT_BYTEPOS (*it);
3753 string = Qnil;
3756 /* If there's a valid composition and point is not inside of the
3757 composition (in the case that the composition is from the current
3758 buffer), draw a glyph composed from the composition components. */
3759 if (find_composition (pos, -1, &pos, &end, &prop, string)
3760 && COMPOSITION_VALID_P (pos, end, prop)
3761 && (STRINGP (it->string) || (PT <= pos || PT >= end)))
3763 int id = get_composition_id (pos, pos_byte, end - pos, prop, string);
3765 if (id >= 0)
3767 it->method = next_element_from_composition;
3768 it->cmp_id = id;
3769 it->cmp_len = COMPOSITION_LENGTH (prop);
3770 /* For a terminal, draw only the first character of the
3771 components. */
3772 it->c = COMPOSITION_GLYPH (composition_table[id], 0);
3773 it->len = (STRINGP (it->string)
3774 ? string_char_to_byte (it->string, end)
3775 : CHAR_TO_BYTE (end)) - pos_byte;
3776 it->stop_charpos = end;
3777 handled = HANDLED_RETURN;
3781 return handled;
3786 /***********************************************************************
3787 Overlay strings
3788 ***********************************************************************/
3790 /* The following structure is used to record overlay strings for
3791 later sorting in load_overlay_strings. */
3793 struct overlay_entry
3795 Lisp_Object overlay;
3796 Lisp_Object string;
3797 int priority;
3798 int after_string_p;
3802 /* Set up iterator IT from overlay strings at its current position.
3803 Called from handle_stop. */
3805 static enum prop_handled
3806 handle_overlay_change (it)
3807 struct it *it;
3809 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
3810 return HANDLED_RECOMPUTE_PROPS;
3811 else
3812 return HANDLED_NORMALLY;
3816 /* Set up the next overlay string for delivery by IT, if there is an
3817 overlay string to deliver. Called by set_iterator_to_next when the
3818 end of the current overlay string is reached. If there are more
3819 overlay strings to display, IT->string and
3820 IT->current.overlay_string_index are set appropriately here.
3821 Otherwise IT->string is set to nil. */
3823 static void
3824 next_overlay_string (it)
3825 struct it *it;
3827 ++it->current.overlay_string_index;
3828 if (it->current.overlay_string_index == it->n_overlay_strings)
3830 /* No more overlay strings. Restore IT's settings to what
3831 they were before overlay strings were processed, and
3832 continue to deliver from current_buffer. */
3833 int display_ellipsis_p = it->stack[it->sp - 1].display_ellipsis_p;
3835 pop_it (it);
3836 xassert (it->stop_charpos >= BEGV
3837 && it->stop_charpos <= it->end_charpos);
3838 it->string = Qnil;
3839 it->current.overlay_string_index = -1;
3840 SET_TEXT_POS (it->current.string_pos, -1, -1);
3841 it->n_overlay_strings = 0;
3842 it->method = next_element_from_buffer;
3844 /* If we're at the end of the buffer, record that we have
3845 processed the overlay strings there already, so that
3846 next_element_from_buffer doesn't try it again. */
3847 if (IT_CHARPOS (*it) >= it->end_charpos)
3848 it->overlay_strings_at_end_processed_p = 1;
3850 /* If we have to display `...' for invisible text, set
3851 the iterator up for that. */
3852 if (display_ellipsis_p)
3853 setup_for_ellipsis (it);
3855 else
3857 /* There are more overlay strings to process. If
3858 IT->current.overlay_string_index has advanced to a position
3859 where we must load IT->overlay_strings with more strings, do
3860 it. */
3861 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
3863 if (it->current.overlay_string_index && i == 0)
3864 load_overlay_strings (it, 0);
3866 /* Initialize IT to deliver display elements from the overlay
3867 string. */
3868 it->string = it->overlay_strings[i];
3869 it->multibyte_p = STRING_MULTIBYTE (it->string);
3870 SET_TEXT_POS (it->current.string_pos, 0, 0);
3871 it->method = next_element_from_string;
3872 it->stop_charpos = 0;
3875 CHECK_IT (it);
3879 /* Compare two overlay_entry structures E1 and E2. Used as a
3880 comparison function for qsort in load_overlay_strings. Overlay
3881 strings for the same position are sorted so that
3883 1. All after-strings come in front of before-strings, except
3884 when they come from the same overlay.
3886 2. Within after-strings, strings are sorted so that overlay strings
3887 from overlays with higher priorities come first.
3889 2. Within before-strings, strings are sorted so that overlay
3890 strings from overlays with higher priorities come last.
3892 Value is analogous to strcmp. */
3895 static int
3896 compare_overlay_entries (e1, e2)
3897 void *e1, *e2;
3899 struct overlay_entry *entry1 = (struct overlay_entry *) e1;
3900 struct overlay_entry *entry2 = (struct overlay_entry *) e2;
3901 int result;
3903 if (entry1->after_string_p != entry2->after_string_p)
3905 /* Let after-strings appear in front of before-strings if
3906 they come from different overlays. */
3907 if (EQ (entry1->overlay, entry2->overlay))
3908 result = entry1->after_string_p ? 1 : -1;
3909 else
3910 result = entry1->after_string_p ? -1 : 1;
3912 else if (entry1->after_string_p)
3913 /* After-strings sorted in order of decreasing priority. */
3914 result = entry2->priority - entry1->priority;
3915 else
3916 /* Before-strings sorted in order of increasing priority. */
3917 result = entry1->priority - entry2->priority;
3919 return result;
3923 /* Load the vector IT->overlay_strings with overlay strings from IT's
3924 current buffer position, or from CHARPOS if that is > 0. Set
3925 IT->n_overlays to the total number of overlay strings found.
3927 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
3928 a time. On entry into load_overlay_strings,
3929 IT->current.overlay_string_index gives the number of overlay
3930 strings that have already been loaded by previous calls to this
3931 function.
3933 IT->add_overlay_start contains an additional overlay start
3934 position to consider for taking overlay strings from, if non-zero.
3935 This position comes into play when the overlay has an `invisible'
3936 property, and both before and after-strings. When we've skipped to
3937 the end of the overlay, because of its `invisible' property, we
3938 nevertheless want its before-string to appear.
3939 IT->add_overlay_start will contain the overlay start position
3940 in this case.
3942 Overlay strings are sorted so that after-string strings come in
3943 front of before-string strings. Within before and after-strings,
3944 strings are sorted by overlay priority. See also function
3945 compare_overlay_entries. */
3947 static void
3948 load_overlay_strings (it, charpos)
3949 struct it *it;
3950 int charpos;
3952 extern Lisp_Object Qafter_string, Qbefore_string, Qwindow, Qpriority;
3953 Lisp_Object ov, overlay, window, str, invisible;
3954 int start, end;
3955 int size = 20;
3956 int n = 0, i, j, invis_p;
3957 struct overlay_entry *entries
3958 = (struct overlay_entry *) alloca (size * sizeof *entries);
3960 if (charpos <= 0)
3961 charpos = IT_CHARPOS (*it);
3963 /* Append the overlay string STRING of overlay OVERLAY to vector
3964 `entries' which has size `size' and currently contains `n'
3965 elements. AFTER_P non-zero means STRING is an after-string of
3966 OVERLAY. */
3967 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
3968 do \
3970 Lisp_Object priority; \
3972 if (n == size) \
3974 int new_size = 2 * size; \
3975 struct overlay_entry *old = entries; \
3976 entries = \
3977 (struct overlay_entry *) alloca (new_size \
3978 * sizeof *entries); \
3979 bcopy (old, entries, size * sizeof *entries); \
3980 size = new_size; \
3983 entries[n].string = (STRING); \
3984 entries[n].overlay = (OVERLAY); \
3985 priority = Foverlay_get ((OVERLAY), Qpriority); \
3986 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
3987 entries[n].after_string_p = (AFTER_P); \
3988 ++n; \
3990 while (0)
3992 /* Process overlay before the overlay center. */
3993 for (ov = current_buffer->overlays_before; CONSP (ov); ov = XCDR (ov))
3995 overlay = XCAR (ov);
3996 xassert (OVERLAYP (overlay));
3997 start = OVERLAY_POSITION (OVERLAY_START (overlay));
3998 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4000 if (end < charpos)
4001 break;
4003 /* Skip this overlay if it doesn't start or end at IT's current
4004 position. */
4005 if (end != charpos && start != charpos)
4006 continue;
4008 /* Skip this overlay if it doesn't apply to IT->w. */
4009 window = Foverlay_get (overlay, Qwindow);
4010 if (WINDOWP (window) && XWINDOW (window) != it->w)
4011 continue;
4013 /* If the text ``under'' the overlay is invisible, both before-
4014 and after-strings from this overlay are visible; start and
4015 end position are indistinguishable. */
4016 invisible = Foverlay_get (overlay, Qinvisible);
4017 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4019 /* If overlay has a non-empty before-string, record it. */
4020 if ((start == charpos || (end == charpos && invis_p))
4021 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4022 && SCHARS (str))
4023 RECORD_OVERLAY_STRING (overlay, str, 0);
4025 /* If overlay has a non-empty after-string, record it. */
4026 if ((end == charpos || (start == charpos && invis_p))
4027 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4028 && SCHARS (str))
4029 RECORD_OVERLAY_STRING (overlay, str, 1);
4032 /* Process overlays after the overlay center. */
4033 for (ov = current_buffer->overlays_after; CONSP (ov); ov = XCDR (ov))
4035 overlay = XCAR (ov);
4036 xassert (OVERLAYP (overlay));
4037 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4038 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4040 if (start > charpos)
4041 break;
4043 /* Skip this overlay if it doesn't start or end at IT's current
4044 position. */
4045 if (end != charpos && start != charpos)
4046 continue;
4048 /* Skip this overlay if it doesn't apply to IT->w. */
4049 window = Foverlay_get (overlay, Qwindow);
4050 if (WINDOWP (window) && XWINDOW (window) != it->w)
4051 continue;
4053 /* If the text ``under'' the overlay is invisible, it has a zero
4054 dimension, and both before- and after-strings apply. */
4055 invisible = Foverlay_get (overlay, Qinvisible);
4056 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4058 /* If overlay has a non-empty before-string, record it. */
4059 if ((start == charpos || (end == charpos && invis_p))
4060 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4061 && SCHARS (str))
4062 RECORD_OVERLAY_STRING (overlay, str, 0);
4064 /* If overlay has a non-empty after-string, record it. */
4065 if ((end == charpos || (start == charpos && invis_p))
4066 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4067 && SCHARS (str))
4068 RECORD_OVERLAY_STRING (overlay, str, 1);
4071 #undef RECORD_OVERLAY_STRING
4073 /* Sort entries. */
4074 if (n > 1)
4075 qsort (entries, n, sizeof *entries, compare_overlay_entries);
4077 /* Record the total number of strings to process. */
4078 it->n_overlay_strings = n;
4080 /* IT->current.overlay_string_index is the number of overlay strings
4081 that have already been consumed by IT. Copy some of the
4082 remaining overlay strings to IT->overlay_strings. */
4083 i = 0;
4084 j = it->current.overlay_string_index;
4085 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
4086 it->overlay_strings[i++] = entries[j++].string;
4088 CHECK_IT (it);
4092 /* Get the first chunk of overlay strings at IT's current buffer
4093 position, or at CHARPOS if that is > 0. Value is non-zero if at
4094 least one overlay string was found. */
4096 static int
4097 get_overlay_strings (it, charpos)
4098 struct it *it;
4099 int charpos;
4101 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
4102 process. This fills IT->overlay_strings with strings, and sets
4103 IT->n_overlay_strings to the total number of strings to process.
4104 IT->pos.overlay_string_index has to be set temporarily to zero
4105 because load_overlay_strings needs this; it must be set to -1
4106 when no overlay strings are found because a zero value would
4107 indicate a position in the first overlay string. */
4108 it->current.overlay_string_index = 0;
4109 load_overlay_strings (it, charpos);
4111 /* If we found overlay strings, set up IT to deliver display
4112 elements from the first one. Otherwise set up IT to deliver
4113 from current_buffer. */
4114 if (it->n_overlay_strings)
4116 /* Make sure we know settings in current_buffer, so that we can
4117 restore meaningful values when we're done with the overlay
4118 strings. */
4119 compute_stop_pos (it);
4120 xassert (it->face_id >= 0);
4122 /* Save IT's settings. They are restored after all overlay
4123 strings have been processed. */
4124 xassert (it->sp == 0);
4125 push_it (it);
4127 /* Set up IT to deliver display elements from the first overlay
4128 string. */
4129 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
4130 it->string = it->overlay_strings[0];
4131 it->stop_charpos = 0;
4132 xassert (STRINGP (it->string));
4133 it->end_charpos = SCHARS (it->string);
4134 it->multibyte_p = STRING_MULTIBYTE (it->string);
4135 it->method = next_element_from_string;
4137 else
4139 it->string = Qnil;
4140 it->current.overlay_string_index = -1;
4141 it->method = next_element_from_buffer;
4144 CHECK_IT (it);
4146 /* Value is non-zero if we found at least one overlay string. */
4147 return STRINGP (it->string);
4152 /***********************************************************************
4153 Saving and restoring state
4154 ***********************************************************************/
4156 /* Save current settings of IT on IT->stack. Called, for example,
4157 before setting up IT for an overlay string, to be able to restore
4158 IT's settings to what they were after the overlay string has been
4159 processed. */
4161 static void
4162 push_it (it)
4163 struct it *it;
4165 struct iterator_stack_entry *p;
4167 xassert (it->sp < 2);
4168 p = it->stack + it->sp;
4170 p->stop_charpos = it->stop_charpos;
4171 xassert (it->face_id >= 0);
4172 p->face_id = it->face_id;
4173 p->string = it->string;
4174 p->pos = it->current;
4175 p->end_charpos = it->end_charpos;
4176 p->string_nchars = it->string_nchars;
4177 p->area = it->area;
4178 p->multibyte_p = it->multibyte_p;
4179 p->space_width = it->space_width;
4180 p->font_height = it->font_height;
4181 p->voffset = it->voffset;
4182 p->string_from_display_prop_p = it->string_from_display_prop_p;
4183 p->display_ellipsis_p = 0;
4184 ++it->sp;
4188 /* Restore IT's settings from IT->stack. Called, for example, when no
4189 more overlay strings must be processed, and we return to delivering
4190 display elements from a buffer, or when the end of a string from a
4191 `display' property is reached and we return to delivering display
4192 elements from an overlay string, or from a buffer. */
4194 static void
4195 pop_it (it)
4196 struct it *it;
4198 struct iterator_stack_entry *p;
4200 xassert (it->sp > 0);
4201 --it->sp;
4202 p = it->stack + it->sp;
4203 it->stop_charpos = p->stop_charpos;
4204 it->face_id = p->face_id;
4205 it->string = p->string;
4206 it->current = p->pos;
4207 it->end_charpos = p->end_charpos;
4208 it->string_nchars = p->string_nchars;
4209 it->area = p->area;
4210 it->multibyte_p = p->multibyte_p;
4211 it->space_width = p->space_width;
4212 it->font_height = p->font_height;
4213 it->voffset = p->voffset;
4214 it->string_from_display_prop_p = p->string_from_display_prop_p;
4219 /***********************************************************************
4220 Moving over lines
4221 ***********************************************************************/
4223 /* Set IT's current position to the previous line start. */
4225 static void
4226 back_to_previous_line_start (it)
4227 struct it *it;
4229 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
4230 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
4234 /* Move IT to the next line start.
4236 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
4237 we skipped over part of the text (as opposed to moving the iterator
4238 continuously over the text). Otherwise, don't change the value
4239 of *SKIPPED_P.
4241 Newlines may come from buffer text, overlay strings, or strings
4242 displayed via the `display' property. That's the reason we can't
4243 simply use find_next_newline_no_quit.
4245 Note that this function may not skip over invisible text that is so
4246 because of text properties and immediately follows a newline. If
4247 it would, function reseat_at_next_visible_line_start, when called
4248 from set_iterator_to_next, would effectively make invisible
4249 characters following a newline part of the wrong glyph row, which
4250 leads to wrong cursor motion. */
4252 static int
4253 forward_to_next_line_start (it, skipped_p)
4254 struct it *it;
4255 int *skipped_p;
4257 int old_selective, newline_found_p, n;
4258 const int MAX_NEWLINE_DISTANCE = 500;
4260 /* If already on a newline, just consume it to avoid unintended
4261 skipping over invisible text below. */
4262 if (it->what == IT_CHARACTER
4263 && it->c == '\n'
4264 && CHARPOS (it->position) == IT_CHARPOS (*it))
4266 set_iterator_to_next (it, 0);
4267 it->c = 0;
4268 return 1;
4271 /* Don't handle selective display in the following. It's (a)
4272 unnecessary because it's done by the caller, and (b) leads to an
4273 infinite recursion because next_element_from_ellipsis indirectly
4274 calls this function. */
4275 old_selective = it->selective;
4276 it->selective = 0;
4278 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
4279 from buffer text. */
4280 for (n = newline_found_p = 0;
4281 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
4282 n += STRINGP (it->string) ? 0 : 1)
4284 if (!get_next_display_element (it))
4285 return 0;
4286 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
4287 set_iterator_to_next (it, 0);
4290 /* If we didn't find a newline near enough, see if we can use a
4291 short-cut. */
4292 if (!newline_found_p)
4294 int start = IT_CHARPOS (*it);
4295 int limit = find_next_newline_no_quit (start, 1);
4296 Lisp_Object pos;
4298 xassert (!STRINGP (it->string));
4300 /* If there isn't any `display' property in sight, and no
4301 overlays, we can just use the position of the newline in
4302 buffer text. */
4303 if (it->stop_charpos >= limit
4304 || ((pos = Fnext_single_property_change (make_number (start),
4305 Qdisplay,
4306 Qnil, make_number (limit)),
4307 NILP (pos))
4308 && next_overlay_change (start) == ZV))
4310 IT_CHARPOS (*it) = limit;
4311 IT_BYTEPOS (*it) = CHAR_TO_BYTE (limit);
4312 *skipped_p = newline_found_p = 1;
4314 else
4316 while (get_next_display_element (it)
4317 && !newline_found_p)
4319 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
4320 set_iterator_to_next (it, 0);
4325 it->selective = old_selective;
4326 return newline_found_p;
4330 /* Set IT's current position to the previous visible line start. Skip
4331 invisible text that is so either due to text properties or due to
4332 selective display. Caution: this does not change IT->current_x and
4333 IT->hpos. */
4335 static void
4336 back_to_previous_visible_line_start (it)
4337 struct it *it;
4339 int visible_p = 0;
4341 /* Go back one newline if not on BEGV already. */
4342 if (IT_CHARPOS (*it) > BEGV)
4343 back_to_previous_line_start (it);
4345 /* Move over lines that are invisible because of selective display
4346 or text properties. */
4347 while (IT_CHARPOS (*it) > BEGV
4348 && !visible_p)
4350 visible_p = 1;
4352 /* If selective > 0, then lines indented more than that values
4353 are invisible. */
4354 if (it->selective > 0
4355 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
4356 (double) it->selective)) /* iftc */
4357 visible_p = 0;
4358 else
4360 Lisp_Object prop;
4362 prop = Fget_char_property (make_number (IT_CHARPOS (*it)),
4363 Qinvisible, it->window);
4364 if (TEXT_PROP_MEANS_INVISIBLE (prop))
4365 visible_p = 0;
4368 /* Back one more newline if the current one is invisible. */
4369 if (!visible_p)
4370 back_to_previous_line_start (it);
4373 xassert (IT_CHARPOS (*it) >= BEGV);
4374 xassert (IT_CHARPOS (*it) == BEGV
4375 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
4376 CHECK_IT (it);
4380 /* Reseat iterator IT at the previous visible line start. Skip
4381 invisible text that is so either due to text properties or due to
4382 selective display. At the end, update IT's overlay information,
4383 face information etc. */
4385 static void
4386 reseat_at_previous_visible_line_start (it)
4387 struct it *it;
4389 back_to_previous_visible_line_start (it);
4390 reseat (it, it->current.pos, 1);
4391 CHECK_IT (it);
4395 /* Reseat iterator IT on the next visible line start in the current
4396 buffer. ON_NEWLINE_P non-zero means position IT on the newline
4397 preceding the line start. Skip over invisible text that is so
4398 because of selective display. Compute faces, overlays etc at the
4399 new position. Note that this function does not skip over text that
4400 is invisible because of text properties. */
4402 static void
4403 reseat_at_next_visible_line_start (it, on_newline_p)
4404 struct it *it;
4405 int on_newline_p;
4407 int newline_found_p, skipped_p = 0;
4409 newline_found_p = forward_to_next_line_start (it, &skipped_p);
4411 /* Skip over lines that are invisible because they are indented
4412 more than the value of IT->selective. */
4413 if (it->selective > 0)
4414 while (IT_CHARPOS (*it) < ZV
4415 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
4416 (double) it->selective)) /* iftc */
4418 xassert (FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
4419 newline_found_p = forward_to_next_line_start (it, &skipped_p);
4422 /* Position on the newline if that's what's requested. */
4423 if (on_newline_p && newline_found_p)
4425 if (STRINGP (it->string))
4427 if (IT_STRING_CHARPOS (*it) > 0)
4429 --IT_STRING_CHARPOS (*it);
4430 --IT_STRING_BYTEPOS (*it);
4433 else if (IT_CHARPOS (*it) > BEGV)
4435 --IT_CHARPOS (*it);
4436 --IT_BYTEPOS (*it);
4437 reseat (it, it->current.pos, 0);
4440 else if (skipped_p)
4441 reseat (it, it->current.pos, 0);
4443 CHECK_IT (it);
4448 /***********************************************************************
4449 Changing an iterator's position
4450 ***********************************************************************/
4452 /* Change IT's current position to POS in current_buffer. If FORCE_P
4453 is non-zero, always check for text properties at the new position.
4454 Otherwise, text properties are only looked up if POS >=
4455 IT->check_charpos of a property. */
4457 static void
4458 reseat (it, pos, force_p)
4459 struct it *it;
4460 struct text_pos pos;
4461 int force_p;
4463 int original_pos = IT_CHARPOS (*it);
4465 reseat_1 (it, pos, 0);
4467 /* Determine where to check text properties. Avoid doing it
4468 where possible because text property lookup is very expensive. */
4469 if (force_p
4470 || CHARPOS (pos) > it->stop_charpos
4471 || CHARPOS (pos) < original_pos)
4472 handle_stop (it);
4474 CHECK_IT (it);
4478 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
4479 IT->stop_pos to POS, also. */
4481 static void
4482 reseat_1 (it, pos, set_stop_p)
4483 struct it *it;
4484 struct text_pos pos;
4485 int set_stop_p;
4487 /* Don't call this function when scanning a C string. */
4488 xassert (it->s == NULL);
4490 /* POS must be a reasonable value. */
4491 xassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
4493 it->current.pos = it->position = pos;
4494 XSETBUFFER (it->object, current_buffer);
4495 it->end_charpos = ZV;
4496 it->dpvec = NULL;
4497 it->current.dpvec_index = -1;
4498 it->current.overlay_string_index = -1;
4499 IT_STRING_CHARPOS (*it) = -1;
4500 IT_STRING_BYTEPOS (*it) = -1;
4501 it->string = Qnil;
4502 it->method = next_element_from_buffer;
4503 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
4504 it->sp = 0;
4505 it->face_before_selective_p = 0;
4507 if (set_stop_p)
4508 it->stop_charpos = CHARPOS (pos);
4512 /* Set up IT for displaying a string, starting at CHARPOS in window W.
4513 If S is non-null, it is a C string to iterate over. Otherwise,
4514 STRING gives a Lisp string to iterate over.
4516 If PRECISION > 0, don't return more then PRECISION number of
4517 characters from the string.
4519 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
4520 characters have been returned. FIELD_WIDTH < 0 means an infinite
4521 field width.
4523 MULTIBYTE = 0 means disable processing of multibyte characters,
4524 MULTIBYTE > 0 means enable it,
4525 MULTIBYTE < 0 means use IT->multibyte_p.
4527 IT must be initialized via a prior call to init_iterator before
4528 calling this function. */
4530 static void
4531 reseat_to_string (it, s, string, charpos, precision, field_width, multibyte)
4532 struct it *it;
4533 unsigned char *s;
4534 Lisp_Object string;
4535 int charpos;
4536 int precision, field_width, multibyte;
4538 /* No region in strings. */
4539 it->region_beg_charpos = it->region_end_charpos = -1;
4541 /* No text property checks performed by default, but see below. */
4542 it->stop_charpos = -1;
4544 /* Set iterator position and end position. */
4545 bzero (&it->current, sizeof it->current);
4546 it->current.overlay_string_index = -1;
4547 it->current.dpvec_index = -1;
4548 xassert (charpos >= 0);
4550 /* If STRING is specified, use its multibyteness, otherwise use the
4551 setting of MULTIBYTE, if specified. */
4552 if (multibyte >= 0)
4553 it->multibyte_p = multibyte > 0;
4555 if (s == NULL)
4557 xassert (STRINGP (string));
4558 it->string = string;
4559 it->s = NULL;
4560 it->end_charpos = it->string_nchars = SCHARS (string);
4561 it->method = next_element_from_string;
4562 it->current.string_pos = string_pos (charpos, string);
4564 else
4566 it->s = s;
4567 it->string = Qnil;
4569 /* Note that we use IT->current.pos, not it->current.string_pos,
4570 for displaying C strings. */
4571 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
4572 if (it->multibyte_p)
4574 it->current.pos = c_string_pos (charpos, s, 1);
4575 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
4577 else
4579 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
4580 it->end_charpos = it->string_nchars = strlen (s);
4583 it->method = next_element_from_c_string;
4586 /* PRECISION > 0 means don't return more than PRECISION characters
4587 from the string. */
4588 if (precision > 0 && it->end_charpos - charpos > precision)
4589 it->end_charpos = it->string_nchars = charpos + precision;
4591 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
4592 characters have been returned. FIELD_WIDTH == 0 means don't pad,
4593 FIELD_WIDTH < 0 means infinite field width. This is useful for
4594 padding with `-' at the end of a mode line. */
4595 if (field_width < 0)
4596 field_width = INFINITY;
4597 if (field_width > it->end_charpos - charpos)
4598 it->end_charpos = charpos + field_width;
4600 /* Use the standard display table for displaying strings. */
4601 if (DISP_TABLE_P (Vstandard_display_table))
4602 it->dp = XCHAR_TABLE (Vstandard_display_table);
4604 it->stop_charpos = charpos;
4605 CHECK_IT (it);
4610 /***********************************************************************
4611 Iteration
4612 ***********************************************************************/
4614 /* Load IT's display element fields with information about the next
4615 display element from the current position of IT. Value is zero if
4616 end of buffer (or C string) is reached. */
4619 get_next_display_element (it)
4620 struct it *it;
4622 /* Non-zero means that we found a display element. Zero means that
4623 we hit the end of what we iterate over. Performance note: the
4624 function pointer `method' used here turns out to be faster than
4625 using a sequence of if-statements. */
4626 int success_p = (*it->method) (it);
4628 if (it->what == IT_CHARACTER)
4630 /* Map via display table or translate control characters.
4631 IT->c, IT->len etc. have been set to the next character by
4632 the function call above. If we have a display table, and it
4633 contains an entry for IT->c, translate it. Don't do this if
4634 IT->c itself comes from a display table, otherwise we could
4635 end up in an infinite recursion. (An alternative could be to
4636 count the recursion depth of this function and signal an
4637 error when a certain maximum depth is reached.) Is it worth
4638 it? */
4639 if (success_p && it->dpvec == NULL)
4641 Lisp_Object dv;
4643 if (it->dp
4644 && (dv = DISP_CHAR_VECTOR (it->dp, it->c),
4645 VECTORP (dv)))
4647 struct Lisp_Vector *v = XVECTOR (dv);
4649 /* Return the first character from the display table
4650 entry, if not empty. If empty, don't display the
4651 current character. */
4652 if (v->size)
4654 it->dpvec_char_len = it->len;
4655 it->dpvec = v->contents;
4656 it->dpend = v->contents + v->size;
4657 it->current.dpvec_index = 0;
4658 it->method = next_element_from_display_vector;
4659 success_p = get_next_display_element (it);
4661 else
4663 set_iterator_to_next (it, 0);
4664 success_p = get_next_display_element (it);
4668 /* Translate control characters into `\003' or `^C' form.
4669 Control characters coming from a display table entry are
4670 currently not translated because we use IT->dpvec to hold
4671 the translation. This could easily be changed but I
4672 don't believe that it is worth doing.
4674 If it->multibyte_p is nonzero, eight-bit characters and
4675 non-printable multibyte characters are also translated to
4676 octal form.
4678 If it->multibyte_p is zero, eight-bit characters that
4679 don't have corresponding multibyte char code are also
4680 translated to octal form. */
4681 else if ((it->c < ' '
4682 && (it->area != TEXT_AREA
4683 || (it->c != '\n' && it->c != '\t')))
4684 || (it->multibyte_p
4685 ? ((it->c >= 127
4686 && it->len == 1)
4687 || !CHAR_PRINTABLE_P (it->c))
4688 : (it->c >= 127
4689 && it->c == unibyte_char_to_multibyte (it->c))))
4691 /* IT->c is a control character which must be displayed
4692 either as '\003' or as `^C' where the '\\' and '^'
4693 can be defined in the display table. Fill
4694 IT->ctl_chars with glyphs for what we have to
4695 display. Then, set IT->dpvec to these glyphs. */
4696 GLYPH g;
4698 if (it->c < 128 && it->ctl_arrow_p)
4700 /* Set IT->ctl_chars[0] to the glyph for `^'. */
4701 if (it->dp
4702 && INTEGERP (DISP_CTRL_GLYPH (it->dp))
4703 && GLYPH_CHAR_VALID_P (XINT (DISP_CTRL_GLYPH (it->dp))))
4704 g = XINT (DISP_CTRL_GLYPH (it->dp));
4705 else
4706 g = FAST_MAKE_GLYPH ('^', 0);
4707 XSETINT (it->ctl_chars[0], g);
4709 g = FAST_MAKE_GLYPH (it->c ^ 0100, 0);
4710 XSETINT (it->ctl_chars[1], g);
4712 /* Set up IT->dpvec and return first character from it. */
4713 it->dpvec_char_len = it->len;
4714 it->dpvec = it->ctl_chars;
4715 it->dpend = it->dpvec + 2;
4716 it->current.dpvec_index = 0;
4717 it->method = next_element_from_display_vector;
4718 get_next_display_element (it);
4720 else
4722 unsigned char str[MAX_MULTIBYTE_LENGTH];
4723 int len;
4724 int i;
4725 GLYPH escape_glyph;
4727 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
4728 if (it->dp
4729 && INTEGERP (DISP_ESCAPE_GLYPH (it->dp))
4730 && GLYPH_CHAR_VALID_P (XFASTINT (DISP_ESCAPE_GLYPH (it->dp))))
4731 escape_glyph = XFASTINT (DISP_ESCAPE_GLYPH (it->dp));
4732 else
4733 escape_glyph = FAST_MAKE_GLYPH ('\\', 0);
4735 if (SINGLE_BYTE_CHAR_P (it->c))
4736 str[0] = it->c, len = 1;
4737 else
4739 len = CHAR_STRING_NO_SIGNAL (it->c, str);
4740 if (len < 0)
4742 /* It's an invalid character, which
4743 shouldn't happen actually, but due to
4744 bugs it may happen. Let's print the char
4745 as is, there's not much meaningful we can
4746 do with it. */
4747 str[0] = it->c;
4748 str[1] = it->c >> 8;
4749 str[2] = it->c >> 16;
4750 str[3] = it->c >> 24;
4751 len = 4;
4755 for (i = 0; i < len; i++)
4757 XSETINT (it->ctl_chars[i * 4], escape_glyph);
4758 /* Insert three more glyphs into IT->ctl_chars for
4759 the octal display of the character. */
4760 g = FAST_MAKE_GLYPH (((str[i] >> 6) & 7) + '0', 0);
4761 XSETINT (it->ctl_chars[i * 4 + 1], g);
4762 g = FAST_MAKE_GLYPH (((str[i] >> 3) & 7) + '0', 0);
4763 XSETINT (it->ctl_chars[i * 4 + 2], g);
4764 g = FAST_MAKE_GLYPH ((str[i] & 7) + '0', 0);
4765 XSETINT (it->ctl_chars[i * 4 + 3], g);
4768 /* Set up IT->dpvec and return the first character
4769 from it. */
4770 it->dpvec_char_len = it->len;
4771 it->dpvec = it->ctl_chars;
4772 it->dpend = it->dpvec + len * 4;
4773 it->current.dpvec_index = 0;
4774 it->method = next_element_from_display_vector;
4775 get_next_display_element (it);
4780 /* Adjust face id for a multibyte character. There are no
4781 multibyte character in unibyte text. */
4782 if (it->multibyte_p
4783 && success_p
4784 && FRAME_WINDOW_P (it->f))
4786 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4787 it->face_id = FACE_FOR_CHAR (it->f, face, it->c);
4791 /* Is this character the last one of a run of characters with
4792 box? If yes, set IT->end_of_box_run_p to 1. */
4793 if (it->face_box_p
4794 && it->s == NULL)
4796 int face_id;
4797 struct face *face;
4799 it->end_of_box_run_p
4800 = ((face_id = face_after_it_pos (it),
4801 face_id != it->face_id)
4802 && (face = FACE_FROM_ID (it->f, face_id),
4803 face->box == FACE_NO_BOX));
4806 /* Value is 0 if end of buffer or string reached. */
4807 return success_p;
4811 /* Move IT to the next display element.
4813 RESEAT_P non-zero means if called on a newline in buffer text,
4814 skip to the next visible line start.
4816 Functions get_next_display_element and set_iterator_to_next are
4817 separate because I find this arrangement easier to handle than a
4818 get_next_display_element function that also increments IT's
4819 position. The way it is we can first look at an iterator's current
4820 display element, decide whether it fits on a line, and if it does,
4821 increment the iterator position. The other way around we probably
4822 would either need a flag indicating whether the iterator has to be
4823 incremented the next time, or we would have to implement a
4824 decrement position function which would not be easy to write. */
4826 void
4827 set_iterator_to_next (it, reseat_p)
4828 struct it *it;
4829 int reseat_p;
4831 /* Reset flags indicating start and end of a sequence of characters
4832 with box. Reset them at the start of this function because
4833 moving the iterator to a new position might set them. */
4834 it->start_of_box_run_p = it->end_of_box_run_p = 0;
4836 if (it->method == next_element_from_buffer)
4838 /* The current display element of IT is a character from
4839 current_buffer. Advance in the buffer, and maybe skip over
4840 invisible lines that are so because of selective display. */
4841 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
4842 reseat_at_next_visible_line_start (it, 0);
4843 else
4845 xassert (it->len != 0);
4846 IT_BYTEPOS (*it) += it->len;
4847 IT_CHARPOS (*it) += 1;
4848 xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
4851 else if (it->method == next_element_from_composition)
4853 xassert (it->cmp_id >= 0 && it ->cmp_id < n_compositions);
4854 if (STRINGP (it->string))
4856 IT_STRING_BYTEPOS (*it) += it->len;
4857 IT_STRING_CHARPOS (*it) += it->cmp_len;
4858 it->method = next_element_from_string;
4859 goto consider_string_end;
4861 else
4863 IT_BYTEPOS (*it) += it->len;
4864 IT_CHARPOS (*it) += it->cmp_len;
4865 it->method = next_element_from_buffer;
4868 else if (it->method == next_element_from_c_string)
4870 /* Current display element of IT is from a C string. */
4871 IT_BYTEPOS (*it) += it->len;
4872 IT_CHARPOS (*it) += 1;
4874 else if (it->method == next_element_from_display_vector)
4876 /* Current display element of IT is from a display table entry.
4877 Advance in the display table definition. Reset it to null if
4878 end reached, and continue with characters from buffers/
4879 strings. */
4880 ++it->current.dpvec_index;
4882 /* Restore face of the iterator to what they were before the
4883 display vector entry (these entries may contain faces). */
4884 it->face_id = it->saved_face_id;
4886 if (it->dpvec + it->current.dpvec_index == it->dpend)
4888 if (it->s)
4889 it->method = next_element_from_c_string;
4890 else if (STRINGP (it->string))
4891 it->method = next_element_from_string;
4892 else
4893 it->method = next_element_from_buffer;
4895 it->dpvec = NULL;
4896 it->current.dpvec_index = -1;
4898 /* Skip over characters which were displayed via IT->dpvec. */
4899 if (it->dpvec_char_len < 0)
4900 reseat_at_next_visible_line_start (it, 1);
4901 else if (it->dpvec_char_len > 0)
4903 it->len = it->dpvec_char_len;
4904 set_iterator_to_next (it, reseat_p);
4908 else if (it->method == next_element_from_string)
4910 /* Current display element is a character from a Lisp string. */
4911 xassert (it->s == NULL && STRINGP (it->string));
4912 IT_STRING_BYTEPOS (*it) += it->len;
4913 IT_STRING_CHARPOS (*it) += 1;
4915 consider_string_end:
4917 if (it->current.overlay_string_index >= 0)
4919 /* IT->string is an overlay string. Advance to the
4920 next, if there is one. */
4921 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
4922 next_overlay_string (it);
4924 else
4926 /* IT->string is not an overlay string. If we reached
4927 its end, and there is something on IT->stack, proceed
4928 with what is on the stack. This can be either another
4929 string, this time an overlay string, or a buffer. */
4930 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
4931 && it->sp > 0)
4933 pop_it (it);
4934 if (!STRINGP (it->string))
4935 it->method = next_element_from_buffer;
4936 else
4937 goto consider_string_end;
4941 else if (it->method == next_element_from_image
4942 || it->method == next_element_from_stretch)
4944 /* The position etc with which we have to proceed are on
4945 the stack. The position may be at the end of a string,
4946 if the `display' property takes up the whole string. */
4947 pop_it (it);
4948 it->image_id = 0;
4949 if (STRINGP (it->string))
4951 it->method = next_element_from_string;
4952 goto consider_string_end;
4954 else
4955 it->method = next_element_from_buffer;
4957 else
4958 /* There are no other methods defined, so this should be a bug. */
4959 abort ();
4961 xassert (it->method != next_element_from_string
4962 || (STRINGP (it->string)
4963 && IT_STRING_CHARPOS (*it) >= 0));
4967 /* Load IT's display element fields with information about the next
4968 display element which comes from a display table entry or from the
4969 result of translating a control character to one of the forms `^C'
4970 or `\003'. IT->dpvec holds the glyphs to return as characters. */
4972 static int
4973 next_element_from_display_vector (it)
4974 struct it *it;
4976 /* Precondition. */
4977 xassert (it->dpvec && it->current.dpvec_index >= 0);
4979 /* Remember the current face id in case glyphs specify faces.
4980 IT's face is restored in set_iterator_to_next. */
4981 it->saved_face_id = it->face_id;
4983 if (INTEGERP (*it->dpvec)
4984 && GLYPH_CHAR_VALID_P (XFASTINT (*it->dpvec)))
4986 int lface_id;
4987 GLYPH g;
4989 g = XFASTINT (it->dpvec[it->current.dpvec_index]);
4990 it->c = FAST_GLYPH_CHAR (g);
4991 it->len = CHAR_BYTES (it->c);
4993 /* The entry may contain a face id to use. Such a face id is
4994 the id of a Lisp face, not a realized face. A face id of
4995 zero means no face is specified. */
4996 lface_id = FAST_GLYPH_FACE (g);
4997 if (lface_id)
4999 /* The function returns -1 if lface_id is invalid. */
5000 int face_id = ascii_face_of_lisp_face (it->f, lface_id);
5001 if (face_id >= 0)
5002 it->face_id = face_id;
5005 else
5006 /* Display table entry is invalid. Return a space. */
5007 it->c = ' ', it->len = 1;
5009 /* Don't change position and object of the iterator here. They are
5010 still the values of the character that had this display table
5011 entry or was translated, and that's what we want. */
5012 it->what = IT_CHARACTER;
5013 return 1;
5017 /* Load IT with the next display element from Lisp string IT->string.
5018 IT->current.string_pos is the current position within the string.
5019 If IT->current.overlay_string_index >= 0, the Lisp string is an
5020 overlay string. */
5022 static int
5023 next_element_from_string (it)
5024 struct it *it;
5026 struct text_pos position;
5028 xassert (STRINGP (it->string));
5029 xassert (IT_STRING_CHARPOS (*it) >= 0);
5030 position = it->current.string_pos;
5032 /* Time to check for invisible text? */
5033 if (IT_STRING_CHARPOS (*it) < it->end_charpos
5034 && IT_STRING_CHARPOS (*it) == it->stop_charpos)
5036 handle_stop (it);
5038 /* Since a handler may have changed IT->method, we must
5039 recurse here. */
5040 return get_next_display_element (it);
5043 if (it->current.overlay_string_index >= 0)
5045 /* Get the next character from an overlay string. In overlay
5046 strings, There is no field width or padding with spaces to
5047 do. */
5048 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
5050 it->what = IT_EOB;
5051 return 0;
5053 else if (STRING_MULTIBYTE (it->string))
5055 int remaining = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
5056 const unsigned char *s = (SDATA (it->string)
5057 + IT_STRING_BYTEPOS (*it));
5058 it->c = string_char_and_length (s, remaining, &it->len);
5060 else
5062 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
5063 it->len = 1;
5066 else
5068 /* Get the next character from a Lisp string that is not an
5069 overlay string. Such strings come from the mode line, for
5070 example. We may have to pad with spaces, or truncate the
5071 string. See also next_element_from_c_string. */
5072 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
5074 it->what = IT_EOB;
5075 return 0;
5077 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
5079 /* Pad with spaces. */
5080 it->c = ' ', it->len = 1;
5081 CHARPOS (position) = BYTEPOS (position) = -1;
5083 else if (STRING_MULTIBYTE (it->string))
5085 int maxlen = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
5086 const unsigned char *s = (SDATA (it->string)
5087 + IT_STRING_BYTEPOS (*it));
5088 it->c = string_char_and_length (s, maxlen, &it->len);
5090 else
5092 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
5093 it->len = 1;
5097 /* Record what we have and where it came from. Note that we store a
5098 buffer position in IT->position although it could arguably be a
5099 string position. */
5100 it->what = IT_CHARACTER;
5101 it->object = it->string;
5102 it->position = position;
5103 return 1;
5107 /* Load IT with next display element from C string IT->s.
5108 IT->string_nchars is the maximum number of characters to return
5109 from the string. IT->end_charpos may be greater than
5110 IT->string_nchars when this function is called, in which case we
5111 may have to return padding spaces. Value is zero if end of string
5112 reached, including padding spaces. */
5114 static int
5115 next_element_from_c_string (it)
5116 struct it *it;
5118 int success_p = 1;
5120 xassert (it->s);
5121 it->what = IT_CHARACTER;
5122 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
5123 it->object = Qnil;
5125 /* IT's position can be greater IT->string_nchars in case a field
5126 width or precision has been specified when the iterator was
5127 initialized. */
5128 if (IT_CHARPOS (*it) >= it->end_charpos)
5130 /* End of the game. */
5131 it->what = IT_EOB;
5132 success_p = 0;
5134 else if (IT_CHARPOS (*it) >= it->string_nchars)
5136 /* Pad with spaces. */
5137 it->c = ' ', it->len = 1;
5138 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
5140 else if (it->multibyte_p)
5142 /* Implementation note: The calls to strlen apparently aren't a
5143 performance problem because there is no noticeable performance
5144 difference between Emacs running in unibyte or multibyte mode. */
5145 int maxlen = strlen (it->s) - IT_BYTEPOS (*it);
5146 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it),
5147 maxlen, &it->len);
5149 else
5150 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
5152 return success_p;
5156 /* Set up IT to return characters from an ellipsis, if appropriate.
5157 The definition of the ellipsis glyphs may come from a display table
5158 entry. This function Fills IT with the first glyph from the
5159 ellipsis if an ellipsis is to be displayed. */
5161 static int
5162 next_element_from_ellipsis (it)
5163 struct it *it;
5165 if (it->selective_display_ellipsis_p)
5167 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
5169 /* Use the display table definition for `...'. Invalid glyphs
5170 will be handled by the method returning elements from dpvec. */
5171 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
5172 it->dpvec_char_len = it->len;
5173 it->dpvec = v->contents;
5174 it->dpend = v->contents + v->size;
5175 it->current.dpvec_index = 0;
5176 it->method = next_element_from_display_vector;
5178 else
5180 /* Use default `...' which is stored in default_invis_vector. */
5181 it->dpvec_char_len = it->len;
5182 it->dpvec = default_invis_vector;
5183 it->dpend = default_invis_vector + 3;
5184 it->current.dpvec_index = 0;
5185 it->method = next_element_from_display_vector;
5188 else
5190 /* The face at the current position may be different from the
5191 face we find after the invisible text. Remember what it
5192 was in IT->saved_face_id, and signal that it's there by
5193 setting face_before_selective_p. */
5194 it->saved_face_id = it->face_id;
5195 it->method = next_element_from_buffer;
5196 reseat_at_next_visible_line_start (it, 1);
5197 it->face_before_selective_p = 1;
5200 return get_next_display_element (it);
5204 /* Deliver an image display element. The iterator IT is already
5205 filled with image information (done in handle_display_prop). Value
5206 is always 1. */
5209 static int
5210 next_element_from_image (it)
5211 struct it *it;
5213 it->what = IT_IMAGE;
5214 return 1;
5218 /* Fill iterator IT with next display element from a stretch glyph
5219 property. IT->object is the value of the text property. Value is
5220 always 1. */
5222 static int
5223 next_element_from_stretch (it)
5224 struct it *it;
5226 it->what = IT_STRETCH;
5227 return 1;
5231 /* Load IT with the next display element from current_buffer. Value
5232 is zero if end of buffer reached. IT->stop_charpos is the next
5233 position at which to stop and check for text properties or buffer
5234 end. */
5236 static int
5237 next_element_from_buffer (it)
5238 struct it *it;
5240 int success_p = 1;
5242 /* Check this assumption, otherwise, we would never enter the
5243 if-statement, below. */
5244 xassert (IT_CHARPOS (*it) >= BEGV
5245 && IT_CHARPOS (*it) <= it->stop_charpos);
5247 if (IT_CHARPOS (*it) >= it->stop_charpos)
5249 if (IT_CHARPOS (*it) >= it->end_charpos)
5251 int overlay_strings_follow_p;
5253 /* End of the game, except when overlay strings follow that
5254 haven't been returned yet. */
5255 if (it->overlay_strings_at_end_processed_p)
5256 overlay_strings_follow_p = 0;
5257 else
5259 it->overlay_strings_at_end_processed_p = 1;
5260 overlay_strings_follow_p = get_overlay_strings (it, 0);
5263 if (overlay_strings_follow_p)
5264 success_p = get_next_display_element (it);
5265 else
5267 it->what = IT_EOB;
5268 it->position = it->current.pos;
5269 success_p = 0;
5272 else
5274 handle_stop (it);
5275 return get_next_display_element (it);
5278 else
5280 /* No face changes, overlays etc. in sight, so just return a
5281 character from current_buffer. */
5282 unsigned char *p;
5284 /* Maybe run the redisplay end trigger hook. Performance note:
5285 This doesn't seem to cost measurable time. */
5286 if (it->redisplay_end_trigger_charpos
5287 && it->glyph_row
5288 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
5289 run_redisplay_end_trigger_hook (it);
5291 /* Get the next character, maybe multibyte. */
5292 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
5293 if (it->multibyte_p && !ASCII_BYTE_P (*p))
5295 int maxlen = ((IT_BYTEPOS (*it) >= GPT_BYTE ? ZV_BYTE : GPT_BYTE)
5296 - IT_BYTEPOS (*it));
5297 it->c = string_char_and_length (p, maxlen, &it->len);
5299 else
5300 it->c = *p, it->len = 1;
5302 /* Record what we have and where it came from. */
5303 it->what = IT_CHARACTER;;
5304 it->object = it->w->buffer;
5305 it->position = it->current.pos;
5307 /* Normally we return the character found above, except when we
5308 really want to return an ellipsis for selective display. */
5309 if (it->selective)
5311 if (it->c == '\n')
5313 /* A value of selective > 0 means hide lines indented more
5314 than that number of columns. */
5315 if (it->selective > 0
5316 && IT_CHARPOS (*it) + 1 < ZV
5317 && indented_beyond_p (IT_CHARPOS (*it) + 1,
5318 IT_BYTEPOS (*it) + 1,
5319 (double) it->selective)) /* iftc */
5321 success_p = next_element_from_ellipsis (it);
5322 it->dpvec_char_len = -1;
5325 else if (it->c == '\r' && it->selective == -1)
5327 /* A value of selective == -1 means that everything from the
5328 CR to the end of the line is invisible, with maybe an
5329 ellipsis displayed for it. */
5330 success_p = next_element_from_ellipsis (it);
5331 it->dpvec_char_len = -1;
5336 /* Value is zero if end of buffer reached. */
5337 xassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
5338 return success_p;
5342 /* Run the redisplay end trigger hook for IT. */
5344 static void
5345 run_redisplay_end_trigger_hook (it)
5346 struct it *it;
5348 Lisp_Object args[3];
5350 /* IT->glyph_row should be non-null, i.e. we should be actually
5351 displaying something, or otherwise we should not run the hook. */
5352 xassert (it->glyph_row);
5354 /* Set up hook arguments. */
5355 args[0] = Qredisplay_end_trigger_functions;
5356 args[1] = it->window;
5357 XSETINT (args[2], it->redisplay_end_trigger_charpos);
5358 it->redisplay_end_trigger_charpos = 0;
5360 /* Since we are *trying* to run these functions, don't try to run
5361 them again, even if they get an error. */
5362 it->w->redisplay_end_trigger = Qnil;
5363 Frun_hook_with_args (3, args);
5365 /* Notice if it changed the face of the character we are on. */
5366 handle_face_prop (it);
5370 /* Deliver a composition display element. The iterator IT is already
5371 filled with composition information (done in
5372 handle_composition_prop). Value is always 1. */
5374 static int
5375 next_element_from_composition (it)
5376 struct it *it;
5378 it->what = IT_COMPOSITION;
5379 it->position = (STRINGP (it->string)
5380 ? it->current.string_pos
5381 : it->current.pos);
5382 return 1;
5387 /***********************************************************************
5388 Moving an iterator without producing glyphs
5389 ***********************************************************************/
5391 /* Move iterator IT to a specified buffer or X position within one
5392 line on the display without producing glyphs.
5394 OP should be a bit mask including some or all of these bits:
5395 MOVE_TO_X: Stop on reaching x-position TO_X.
5396 MOVE_TO_POS: Stop on reaching buffer or string position TO_CHARPOS.
5397 Regardless of OP's value, stop in reaching the end of the display line.
5399 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
5400 This means, in particular, that TO_X includes window's horizontal
5401 scroll amount.
5403 The return value has several possible values that
5404 say what condition caused the scan to stop:
5406 MOVE_POS_MATCH_OR_ZV
5407 - when TO_POS or ZV was reached.
5409 MOVE_X_REACHED
5410 -when TO_X was reached before TO_POS or ZV were reached.
5412 MOVE_LINE_CONTINUED
5413 - when we reached the end of the display area and the line must
5414 be continued.
5416 MOVE_LINE_TRUNCATED
5417 - when we reached the end of the display area and the line is
5418 truncated.
5420 MOVE_NEWLINE_OR_CR
5421 - when we stopped at a line end, i.e. a newline or a CR and selective
5422 display is on. */
5424 static enum move_it_result
5425 move_it_in_display_line_to (it, to_charpos, to_x, op)
5426 struct it *it;
5427 int to_charpos, to_x, op;
5429 enum move_it_result result = MOVE_UNDEFINED;
5430 struct glyph_row *saved_glyph_row;
5432 /* Don't produce glyphs in produce_glyphs. */
5433 saved_glyph_row = it->glyph_row;
5434 it->glyph_row = NULL;
5436 while (1)
5438 int x, i, ascent = 0, descent = 0;
5440 /* Stop when ZV or TO_CHARPOS reached. */
5441 if (!get_next_display_element (it)
5442 || ((op & MOVE_TO_POS) != 0
5443 && BUFFERP (it->object)
5444 && IT_CHARPOS (*it) >= to_charpos))
5446 result = MOVE_POS_MATCH_OR_ZV;
5447 break;
5450 /* The call to produce_glyphs will get the metrics of the
5451 display element IT is loaded with. We record in x the
5452 x-position before this display element in case it does not
5453 fit on the line. */
5454 x = it->current_x;
5456 /* Remember the line height so far in case the next element doesn't
5457 fit on the line. */
5458 if (!it->truncate_lines_p)
5460 ascent = it->max_ascent;
5461 descent = it->max_descent;
5464 PRODUCE_GLYPHS (it);
5466 if (it->area != TEXT_AREA)
5468 set_iterator_to_next (it, 1);
5469 continue;
5472 /* The number of glyphs we get back in IT->nglyphs will normally
5473 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
5474 character on a terminal frame, or (iii) a line end. For the
5475 second case, IT->nglyphs - 1 padding glyphs will be present
5476 (on X frames, there is only one glyph produced for a
5477 composite character.
5479 The behavior implemented below means, for continuation lines,
5480 that as many spaces of a TAB as fit on the current line are
5481 displayed there. For terminal frames, as many glyphs of a
5482 multi-glyph character are displayed in the current line, too.
5483 This is what the old redisplay code did, and we keep it that
5484 way. Under X, the whole shape of a complex character must
5485 fit on the line or it will be completely displayed in the
5486 next line.
5488 Note that both for tabs and padding glyphs, all glyphs have
5489 the same width. */
5490 if (it->nglyphs)
5492 /* More than one glyph or glyph doesn't fit on line. All
5493 glyphs have the same width. */
5494 int single_glyph_width = it->pixel_width / it->nglyphs;
5495 int new_x;
5497 for (i = 0; i < it->nglyphs; ++i, x = new_x)
5499 new_x = x + single_glyph_width;
5501 /* We want to leave anything reaching TO_X to the caller. */
5502 if ((op & MOVE_TO_X) && new_x > to_x)
5504 it->current_x = x;
5505 result = MOVE_X_REACHED;
5506 break;
5508 else if (/* Lines are continued. */
5509 !it->truncate_lines_p
5510 && (/* And glyph doesn't fit on the line. */
5511 new_x > it->last_visible_x
5512 /* Or it fits exactly and we're on a window
5513 system frame. */
5514 || (new_x == it->last_visible_x
5515 && FRAME_WINDOW_P (it->f))))
5517 if (/* IT->hpos == 0 means the very first glyph
5518 doesn't fit on the line, e.g. a wide image. */
5519 it->hpos == 0
5520 || (new_x == it->last_visible_x
5521 && FRAME_WINDOW_P (it->f)))
5523 ++it->hpos;
5524 it->current_x = new_x;
5525 if (i == it->nglyphs - 1)
5526 set_iterator_to_next (it, 1);
5528 else
5530 it->current_x = x;
5531 it->max_ascent = ascent;
5532 it->max_descent = descent;
5535 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
5536 IT_CHARPOS (*it)));
5537 result = MOVE_LINE_CONTINUED;
5538 break;
5540 else if (new_x > it->first_visible_x)
5542 /* Glyph is visible. Increment number of glyphs that
5543 would be displayed. */
5544 ++it->hpos;
5546 else
5548 /* Glyph is completely off the left margin of the display
5549 area. Nothing to do. */
5553 if (result != MOVE_UNDEFINED)
5554 break;
5556 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
5558 /* Stop when TO_X specified and reached. This check is
5559 necessary here because of lines consisting of a line end,
5560 only. The line end will not produce any glyphs and we
5561 would never get MOVE_X_REACHED. */
5562 xassert (it->nglyphs == 0);
5563 result = MOVE_X_REACHED;
5564 break;
5567 /* Is this a line end? If yes, we're done. */
5568 if (ITERATOR_AT_END_OF_LINE_P (it))
5570 result = MOVE_NEWLINE_OR_CR;
5571 break;
5574 /* The current display element has been consumed. Advance
5575 to the next. */
5576 set_iterator_to_next (it, 1);
5578 /* Stop if lines are truncated and IT's current x-position is
5579 past the right edge of the window now. */
5580 if (it->truncate_lines_p
5581 && it->current_x >= it->last_visible_x)
5583 result = MOVE_LINE_TRUNCATED;
5584 break;
5588 /* Restore the iterator settings altered at the beginning of this
5589 function. */
5590 it->glyph_row = saved_glyph_row;
5591 return result;
5595 /* Move IT forward until it satisfies one or more of the criteria in
5596 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
5598 OP is a bit-mask that specifies where to stop, and in particular,
5599 which of those four position arguments makes a difference. See the
5600 description of enum move_operation_enum.
5602 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
5603 screen line, this function will set IT to the next position >
5604 TO_CHARPOS. */
5606 void
5607 move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
5608 struct it *it;
5609 int to_charpos, to_x, to_y, to_vpos;
5610 int op;
5612 enum move_it_result skip, skip2 = MOVE_X_REACHED;
5613 int line_height;
5614 int reached = 0;
5616 for (;;)
5618 if (op & MOVE_TO_VPOS)
5620 /* If no TO_CHARPOS and no TO_X specified, stop at the
5621 start of the line TO_VPOS. */
5622 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
5624 if (it->vpos == to_vpos)
5626 reached = 1;
5627 break;
5629 else
5630 skip = move_it_in_display_line_to (it, -1, -1, 0);
5632 else
5634 /* TO_VPOS >= 0 means stop at TO_X in the line at
5635 TO_VPOS, or at TO_POS, whichever comes first. */
5636 if (it->vpos == to_vpos)
5638 reached = 2;
5639 break;
5642 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
5644 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
5646 reached = 3;
5647 break;
5649 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
5651 /* We have reached TO_X but not in the line we want. */
5652 skip = move_it_in_display_line_to (it, to_charpos,
5653 -1, MOVE_TO_POS);
5654 if (skip == MOVE_POS_MATCH_OR_ZV)
5656 reached = 4;
5657 break;
5662 else if (op & MOVE_TO_Y)
5664 struct it it_backup;
5666 /* TO_Y specified means stop at TO_X in the line containing
5667 TO_Y---or at TO_CHARPOS if this is reached first. The
5668 problem is that we can't really tell whether the line
5669 contains TO_Y before we have completely scanned it, and
5670 this may skip past TO_X. What we do is to first scan to
5671 TO_X.
5673 If TO_X is not specified, use a TO_X of zero. The reason
5674 is to make the outcome of this function more predictable.
5675 If we didn't use TO_X == 0, we would stop at the end of
5676 the line which is probably not what a caller would expect
5677 to happen. */
5678 skip = move_it_in_display_line_to (it, to_charpos,
5679 ((op & MOVE_TO_X)
5680 ? to_x : 0),
5681 (MOVE_TO_X
5682 | (op & MOVE_TO_POS)));
5684 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
5685 if (skip == MOVE_POS_MATCH_OR_ZV)
5687 reached = 5;
5688 break;
5691 /* If TO_X was reached, we would like to know whether TO_Y
5692 is in the line. This can only be said if we know the
5693 total line height which requires us to scan the rest of
5694 the line. */
5695 if (skip == MOVE_X_REACHED)
5697 it_backup = *it;
5698 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
5699 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
5700 op & MOVE_TO_POS);
5701 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
5704 /* Now, decide whether TO_Y is in this line. */
5705 line_height = it->max_ascent + it->max_descent;
5706 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
5708 if (to_y >= it->current_y
5709 && to_y < it->current_y + line_height)
5711 if (skip == MOVE_X_REACHED)
5712 /* If TO_Y is in this line and TO_X was reached above,
5713 we scanned too far. We have to restore IT's settings
5714 to the ones before skipping. */
5715 *it = it_backup;
5716 reached = 6;
5718 else if (skip == MOVE_X_REACHED)
5720 skip = skip2;
5721 if (skip == MOVE_POS_MATCH_OR_ZV)
5722 reached = 7;
5725 if (reached)
5726 break;
5728 else
5729 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
5731 switch (skip)
5733 case MOVE_POS_MATCH_OR_ZV:
5734 reached = 8;
5735 goto out;
5737 case MOVE_NEWLINE_OR_CR:
5738 set_iterator_to_next (it, 1);
5739 it->continuation_lines_width = 0;
5740 break;
5742 case MOVE_LINE_TRUNCATED:
5743 it->continuation_lines_width = 0;
5744 reseat_at_next_visible_line_start (it, 0);
5745 if ((op & MOVE_TO_POS) != 0
5746 && IT_CHARPOS (*it) > to_charpos)
5748 reached = 9;
5749 goto out;
5751 break;
5753 case MOVE_LINE_CONTINUED:
5754 it->continuation_lines_width += it->current_x;
5755 break;
5757 default:
5758 abort ();
5761 /* Reset/increment for the next run. */
5762 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
5763 it->current_x = it->hpos = 0;
5764 it->current_y += it->max_ascent + it->max_descent;
5765 ++it->vpos;
5766 last_height = it->max_ascent + it->max_descent;
5767 last_max_ascent = it->max_ascent;
5768 it->max_ascent = it->max_descent = 0;
5771 out:
5773 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
5777 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
5779 If DY > 0, move IT backward at least that many pixels. DY = 0
5780 means move IT backward to the preceding line start or BEGV. This
5781 function may move over more than DY pixels if IT->current_y - DY
5782 ends up in the middle of a line; in this case IT->current_y will be
5783 set to the top of the line moved to. */
5785 void
5786 move_it_vertically_backward (it, dy)
5787 struct it *it;
5788 int dy;
5790 int nlines, h;
5791 struct it it2, it3;
5792 int start_pos = IT_CHARPOS (*it);
5794 xassert (dy >= 0);
5796 /* Estimate how many newlines we must move back. */
5797 nlines = max (1, dy / CANON_Y_UNIT (it->f));
5799 /* Set the iterator's position that many lines back. */
5800 while (nlines-- && IT_CHARPOS (*it) > BEGV)
5801 back_to_previous_visible_line_start (it);
5803 /* Reseat the iterator here. When moving backward, we don't want
5804 reseat to skip forward over invisible text, set up the iterator
5805 to deliver from overlay strings at the new position etc. So,
5806 use reseat_1 here. */
5807 reseat_1 (it, it->current.pos, 1);
5809 /* We are now surely at a line start. */
5810 it->current_x = it->hpos = 0;
5811 it->continuation_lines_width = 0;
5813 /* Move forward and see what y-distance we moved. First move to the
5814 start of the next line so that we get its height. We need this
5815 height to be able to tell whether we reached the specified
5816 y-distance. */
5817 it2 = *it;
5818 it2.max_ascent = it2.max_descent = 0;
5819 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
5820 MOVE_TO_POS | MOVE_TO_VPOS);
5821 xassert (IT_CHARPOS (*it) >= BEGV);
5822 it3 = it2;
5824 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
5825 xassert (IT_CHARPOS (*it) >= BEGV);
5826 /* H is the actual vertical distance from the position in *IT
5827 and the starting position. */
5828 h = it2.current_y - it->current_y;
5829 /* NLINES is the distance in number of lines. */
5830 nlines = it2.vpos - it->vpos;
5832 /* Correct IT's y and vpos position
5833 so that they are relative to the starting point. */
5834 it->vpos -= nlines;
5835 it->current_y -= h;
5837 if (dy == 0)
5839 /* DY == 0 means move to the start of the screen line. The
5840 value of nlines is > 0 if continuation lines were involved. */
5841 if (nlines > 0)
5842 move_it_by_lines (it, nlines, 1);
5843 xassert (IT_CHARPOS (*it) <= start_pos);
5845 else
5847 /* The y-position we try to reach, relative to *IT.
5848 Note that H has been subtracted in front of the if-statement. */
5849 int target_y = it->current_y + h - dy;
5850 int y0 = it3.current_y;
5851 int y1 = line_bottom_y (&it3);
5852 int line_height = y1 - y0;
5854 /* If we did not reach target_y, try to move further backward if
5855 we can. If we moved too far backward, try to move forward. */
5856 if (target_y < it->current_y
5857 /* This is heuristic. In a window that's 3 lines high, with
5858 a line height of 13 pixels each, recentering with point
5859 on the bottom line will try to move -39/2 = 19 pixels
5860 backward. Try to avoid moving into the first line. */
5861 && it->current_y - target_y > line_height / 3 * 2
5862 && IT_CHARPOS (*it) > BEGV)
5864 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
5865 target_y - it->current_y));
5866 move_it_vertically (it, target_y - it->current_y);
5867 xassert (IT_CHARPOS (*it) >= BEGV);
5869 else if (target_y >= it->current_y + line_height
5870 && IT_CHARPOS (*it) < ZV)
5872 /* Should move forward by at least one line, maybe more.
5874 Note: Calling move_it_by_lines can be expensive on
5875 terminal frames, where compute_motion is used (via
5876 vmotion) to do the job, when there are very long lines
5877 and truncate-lines is nil. That's the reason for
5878 treating terminal frames specially here. */
5880 if (!FRAME_WINDOW_P (it->f))
5881 move_it_vertically (it, target_y - (it->current_y + line_height));
5882 else
5886 move_it_by_lines (it, 1, 1);
5888 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
5891 xassert (IT_CHARPOS (*it) >= BEGV);
5897 /* Move IT by a specified amount of pixel lines DY. DY negative means
5898 move backwards. DY = 0 means move to start of screen line. At the
5899 end, IT will be on the start of a screen line. */
5901 void
5902 move_it_vertically (it, dy)
5903 struct it *it;
5904 int dy;
5906 if (dy <= 0)
5907 move_it_vertically_backward (it, -dy);
5908 else if (dy > 0)
5910 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
5911 move_it_to (it, ZV, -1, it->current_y + dy, -1,
5912 MOVE_TO_POS | MOVE_TO_Y);
5913 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
5915 /* If buffer ends in ZV without a newline, move to the start of
5916 the line to satisfy the post-condition. */
5917 if (IT_CHARPOS (*it) == ZV
5918 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
5919 move_it_by_lines (it, 0, 0);
5924 /* Move iterator IT past the end of the text line it is in. */
5926 void
5927 move_it_past_eol (it)
5928 struct it *it;
5930 enum move_it_result rc;
5932 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
5933 if (rc == MOVE_NEWLINE_OR_CR)
5934 set_iterator_to_next (it, 0);
5938 #if 0 /* Currently not used. */
5940 /* Return non-zero if some text between buffer positions START_CHARPOS
5941 and END_CHARPOS is invisible. IT->window is the window for text
5942 property lookup. */
5944 static int
5945 invisible_text_between_p (it, start_charpos, end_charpos)
5946 struct it *it;
5947 int start_charpos, end_charpos;
5949 Lisp_Object prop, limit;
5950 int invisible_found_p;
5952 xassert (it != NULL && start_charpos <= end_charpos);
5954 /* Is text at START invisible? */
5955 prop = Fget_char_property (make_number (start_charpos), Qinvisible,
5956 it->window);
5957 if (TEXT_PROP_MEANS_INVISIBLE (prop))
5958 invisible_found_p = 1;
5959 else
5961 limit = Fnext_single_char_property_change (make_number (start_charpos),
5962 Qinvisible, Qnil,
5963 make_number (end_charpos));
5964 invisible_found_p = XFASTINT (limit) < end_charpos;
5967 return invisible_found_p;
5970 #endif /* 0 */
5973 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
5974 negative means move up. DVPOS == 0 means move to the start of the
5975 screen line. NEED_Y_P non-zero means calculate IT->current_y. If
5976 NEED_Y_P is zero, IT->current_y will be left unchanged.
5978 Further optimization ideas: If we would know that IT->f doesn't use
5979 a face with proportional font, we could be faster for
5980 truncate-lines nil. */
5982 void
5983 move_it_by_lines (it, dvpos, need_y_p)
5984 struct it *it;
5985 int dvpos, need_y_p;
5987 struct position pos;
5989 if (!FRAME_WINDOW_P (it->f))
5991 struct text_pos textpos;
5993 /* We can use vmotion on frames without proportional fonts. */
5994 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
5995 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
5996 reseat (it, textpos, 1);
5997 it->vpos += pos.vpos;
5998 it->current_y += pos.vpos;
6000 else if (dvpos == 0)
6002 /* DVPOS == 0 means move to the start of the screen line. */
6003 move_it_vertically_backward (it, 0);
6004 xassert (it->current_x == 0 && it->hpos == 0);
6006 else if (dvpos > 0)
6007 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
6008 else
6010 struct it it2;
6011 int start_charpos, i;
6013 /* Start at the beginning of the screen line containing IT's
6014 position. */
6015 move_it_vertically_backward (it, 0);
6017 /* Go back -DVPOS visible lines and reseat the iterator there. */
6018 start_charpos = IT_CHARPOS (*it);
6019 for (i = -dvpos; i && IT_CHARPOS (*it) > BEGV; --i)
6020 back_to_previous_visible_line_start (it);
6021 reseat (it, it->current.pos, 1);
6022 it->current_x = it->hpos = 0;
6024 /* Above call may have moved too far if continuation lines
6025 are involved. Scan forward and see if it did. */
6026 it2 = *it;
6027 it2.vpos = it2.current_y = 0;
6028 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
6029 it->vpos -= it2.vpos;
6030 it->current_y -= it2.current_y;
6031 it->current_x = it->hpos = 0;
6033 /* If we moved too far, move IT some lines forward. */
6034 if (it2.vpos > -dvpos)
6036 int delta = it2.vpos + dvpos;
6037 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
6042 /* Return 1 if IT points into the middle of a display vector. */
6045 in_display_vector_p (it)
6046 struct it *it;
6048 return (it->method == next_element_from_display_vector
6049 && it->current.dpvec_index > 0
6050 && it->dpvec + it->current.dpvec_index != it->dpend);
6054 /***********************************************************************
6055 Messages
6056 ***********************************************************************/
6059 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
6060 to *Messages*. */
6062 void
6063 add_to_log (format, arg1, arg2)
6064 char *format;
6065 Lisp_Object arg1, arg2;
6067 Lisp_Object args[3];
6068 Lisp_Object msg, fmt;
6069 char *buffer;
6070 int len;
6071 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
6073 /* Do nothing if called asynchronously. Inserting text into
6074 a buffer may call after-change-functions and alike and
6075 that would means running Lisp asynchronously. */
6076 if (handling_signal)
6077 return;
6079 fmt = msg = Qnil;
6080 GCPRO4 (fmt, msg, arg1, arg2);
6082 args[0] = fmt = build_string (format);
6083 args[1] = arg1;
6084 args[2] = arg2;
6085 msg = Fformat (3, args);
6087 len = SBYTES (msg) + 1;
6088 buffer = (char *) alloca (len);
6089 bcopy (SDATA (msg), buffer, len);
6091 message_dolog (buffer, len - 1, 1, 0);
6092 UNGCPRO;
6096 /* Output a newline in the *Messages* buffer if "needs" one. */
6098 void
6099 message_log_maybe_newline ()
6101 if (message_log_need_newline)
6102 message_dolog ("", 0, 1, 0);
6106 /* Add a string M of length NBYTES to the message log, optionally
6107 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
6108 nonzero, means interpret the contents of M as multibyte. This
6109 function calls low-level routines in order to bypass text property
6110 hooks, etc. which might not be safe to run. */
6112 void
6113 message_dolog (m, nbytes, nlflag, multibyte)
6114 const char *m;
6115 int nbytes, nlflag, multibyte;
6117 if (!NILP (Vmemory_full))
6118 return;
6120 if (!NILP (Vmessage_log_max))
6122 struct buffer *oldbuf;
6123 Lisp_Object oldpoint, oldbegv, oldzv;
6124 int old_windows_or_buffers_changed = windows_or_buffers_changed;
6125 int point_at_end = 0;
6126 int zv_at_end = 0;
6127 Lisp_Object old_deactivate_mark, tem;
6128 struct gcpro gcpro1;
6130 old_deactivate_mark = Vdeactivate_mark;
6131 oldbuf = current_buffer;
6132 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
6133 current_buffer->undo_list = Qt;
6135 oldpoint = message_dolog_marker1;
6136 set_marker_restricted (oldpoint, make_number (PT), Qnil);
6137 oldbegv = message_dolog_marker2;
6138 set_marker_restricted (oldbegv, make_number (BEGV), Qnil);
6139 oldzv = message_dolog_marker3;
6140 set_marker_restricted (oldzv, make_number (ZV), Qnil);
6141 GCPRO1 (old_deactivate_mark);
6143 if (PT == Z)
6144 point_at_end = 1;
6145 if (ZV == Z)
6146 zv_at_end = 1;
6148 BEGV = BEG;
6149 BEGV_BYTE = BEG_BYTE;
6150 ZV = Z;
6151 ZV_BYTE = Z_BYTE;
6152 TEMP_SET_PT_BOTH (Z, Z_BYTE);
6154 /* Insert the string--maybe converting multibyte to single byte
6155 or vice versa, so that all the text fits the buffer. */
6156 if (multibyte
6157 && NILP (current_buffer->enable_multibyte_characters))
6159 int i, c, char_bytes;
6160 unsigned char work[1];
6162 /* Convert a multibyte string to single-byte
6163 for the *Message* buffer. */
6164 for (i = 0; i < nbytes; i += char_bytes)
6166 c = string_char_and_length (m + i, nbytes - i, &char_bytes);
6167 work[0] = (SINGLE_BYTE_CHAR_P (c)
6169 : multibyte_char_to_unibyte (c, Qnil));
6170 insert_1_both (work, 1, 1, 1, 0, 0);
6173 else if (! multibyte
6174 && ! NILP (current_buffer->enable_multibyte_characters))
6176 int i, c, char_bytes;
6177 unsigned char *msg = (unsigned char *) m;
6178 unsigned char str[MAX_MULTIBYTE_LENGTH];
6179 /* Convert a single-byte string to multibyte
6180 for the *Message* buffer. */
6181 for (i = 0; i < nbytes; i++)
6183 c = unibyte_char_to_multibyte (msg[i]);
6184 char_bytes = CHAR_STRING (c, str);
6185 insert_1_both (str, 1, char_bytes, 1, 0, 0);
6188 else if (nbytes)
6189 insert_1 (m, nbytes, 1, 0, 0);
6191 if (nlflag)
6193 int this_bol, this_bol_byte, prev_bol, prev_bol_byte, dup;
6194 insert_1 ("\n", 1, 1, 0, 0);
6196 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
6197 this_bol = PT;
6198 this_bol_byte = PT_BYTE;
6200 /* See if this line duplicates the previous one.
6201 If so, combine duplicates. */
6202 if (this_bol > BEG)
6204 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
6205 prev_bol = PT;
6206 prev_bol_byte = PT_BYTE;
6208 dup = message_log_check_duplicate (prev_bol, prev_bol_byte,
6209 this_bol, this_bol_byte);
6210 if (dup)
6212 del_range_both (prev_bol, prev_bol_byte,
6213 this_bol, this_bol_byte, 0);
6214 if (dup > 1)
6216 char dupstr[40];
6217 int duplen;
6219 /* If you change this format, don't forget to also
6220 change message_log_check_duplicate. */
6221 sprintf (dupstr, " [%d times]", dup);
6222 duplen = strlen (dupstr);
6223 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
6224 insert_1 (dupstr, duplen, 1, 0, 1);
6229 /* If we have more than the desired maximum number of lines
6230 in the *Messages* buffer now, delete the oldest ones.
6231 This is safe because we don't have undo in this buffer. */
6233 if (NATNUMP (Vmessage_log_max))
6235 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
6236 -XFASTINT (Vmessage_log_max) - 1, 0);
6237 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
6240 BEGV = XMARKER (oldbegv)->charpos;
6241 BEGV_BYTE = marker_byte_position (oldbegv);
6243 if (zv_at_end)
6245 ZV = Z;
6246 ZV_BYTE = Z_BYTE;
6248 else
6250 ZV = XMARKER (oldzv)->charpos;
6251 ZV_BYTE = marker_byte_position (oldzv);
6254 if (point_at_end)
6255 TEMP_SET_PT_BOTH (Z, Z_BYTE);
6256 else
6257 /* We can't do Fgoto_char (oldpoint) because it will run some
6258 Lisp code. */
6259 TEMP_SET_PT_BOTH (XMARKER (oldpoint)->charpos,
6260 XMARKER (oldpoint)->bytepos);
6262 UNGCPRO;
6263 unchain_marker (oldpoint);
6264 unchain_marker (oldbegv);
6265 unchain_marker (oldzv);
6267 tem = Fget_buffer_window (Fcurrent_buffer (), Qt);
6268 set_buffer_internal (oldbuf);
6269 if (NILP (tem))
6270 windows_or_buffers_changed = old_windows_or_buffers_changed;
6271 message_log_need_newline = !nlflag;
6272 Vdeactivate_mark = old_deactivate_mark;
6277 /* We are at the end of the buffer after just having inserted a newline.
6278 (Note: We depend on the fact we won't be crossing the gap.)
6279 Check to see if the most recent message looks a lot like the previous one.
6280 Return 0 if different, 1 if the new one should just replace it, or a
6281 value N > 1 if we should also append " [N times]". */
6283 static int
6284 message_log_check_duplicate (prev_bol, prev_bol_byte, this_bol, this_bol_byte)
6285 int prev_bol, this_bol;
6286 int prev_bol_byte, this_bol_byte;
6288 int i;
6289 int len = Z_BYTE - 1 - this_bol_byte;
6290 int seen_dots = 0;
6291 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
6292 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
6294 for (i = 0; i < len; i++)
6296 if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.')
6297 seen_dots = 1;
6298 if (p1[i] != p2[i])
6299 return seen_dots;
6301 p1 += len;
6302 if (*p1 == '\n')
6303 return 2;
6304 if (*p1++ == ' ' && *p1++ == '[')
6306 int n = 0;
6307 while (*p1 >= '0' && *p1 <= '9')
6308 n = n * 10 + *p1++ - '0';
6309 if (strncmp (p1, " times]\n", 8) == 0)
6310 return n+1;
6312 return 0;
6316 /* Display an echo area message M with a specified length of NBYTES
6317 bytes. The string may include null characters. If M is 0, clear
6318 out any existing message, and let the mini-buffer text show
6319 through.
6321 The buffer M must continue to exist until after the echo area gets
6322 cleared or some other message gets displayed there. This means do
6323 not pass text that is stored in a Lisp string; do not pass text in
6324 a buffer that was alloca'd. */
6326 void
6327 message2 (m, nbytes, multibyte)
6328 const char *m;
6329 int nbytes;
6330 int multibyte;
6332 /* First flush out any partial line written with print. */
6333 message_log_maybe_newline ();
6334 if (m)
6335 message_dolog (m, nbytes, 1, multibyte);
6336 message2_nolog (m, nbytes, multibyte);
6340 /* The non-logging counterpart of message2. */
6342 void
6343 message2_nolog (m, nbytes, multibyte)
6344 const char *m;
6345 int nbytes, multibyte;
6347 struct frame *sf = SELECTED_FRAME ();
6348 message_enable_multibyte = multibyte;
6350 if (noninteractive)
6352 if (noninteractive_need_newline)
6353 putc ('\n', stderr);
6354 noninteractive_need_newline = 0;
6355 if (m)
6356 fwrite (m, nbytes, 1, stderr);
6357 if (cursor_in_echo_area == 0)
6358 fprintf (stderr, "\n");
6359 fflush (stderr);
6361 /* A null message buffer means that the frame hasn't really been
6362 initialized yet. Error messages get reported properly by
6363 cmd_error, so this must be just an informative message; toss it. */
6364 else if (INTERACTIVE
6365 && sf->glyphs_initialized_p
6366 && FRAME_MESSAGE_BUF (sf))
6368 Lisp_Object mini_window;
6369 struct frame *f;
6371 /* Get the frame containing the mini-buffer
6372 that the selected frame is using. */
6373 mini_window = FRAME_MINIBUF_WINDOW (sf);
6374 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6376 FRAME_SAMPLE_VISIBILITY (f);
6377 if (FRAME_VISIBLE_P (sf)
6378 && ! FRAME_VISIBLE_P (f))
6379 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
6381 if (m)
6383 set_message (m, Qnil, nbytes, multibyte);
6384 if (minibuffer_auto_raise)
6385 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
6387 else
6388 clear_message (1, 1);
6390 do_pending_window_change (0);
6391 echo_area_display (1);
6392 do_pending_window_change (0);
6393 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
6394 (*frame_up_to_date_hook) (f);
6399 /* Display an echo area message M with a specified length of NBYTES
6400 bytes. The string may include null characters. If M is not a
6401 string, clear out any existing message, and let the mini-buffer
6402 text show through. */
6404 void
6405 message3 (m, nbytes, multibyte)
6406 Lisp_Object m;
6407 int nbytes;
6408 int multibyte;
6410 struct gcpro gcpro1;
6412 GCPRO1 (m);
6414 /* First flush out any partial line written with print. */
6415 message_log_maybe_newline ();
6416 if (STRINGP (m))
6417 message_dolog (SDATA (m), nbytes, 1, multibyte);
6418 message3_nolog (m, nbytes, multibyte);
6420 UNGCPRO;
6424 /* The non-logging version of message3. */
6426 void
6427 message3_nolog (m, nbytes, multibyte)
6428 Lisp_Object m;
6429 int nbytes, multibyte;
6431 struct frame *sf = SELECTED_FRAME ();
6432 message_enable_multibyte = multibyte;
6434 if (noninteractive)
6436 if (noninteractive_need_newline)
6437 putc ('\n', stderr);
6438 noninteractive_need_newline = 0;
6439 if (STRINGP (m))
6440 fwrite (SDATA (m), nbytes, 1, stderr);
6441 if (cursor_in_echo_area == 0)
6442 fprintf (stderr, "\n");
6443 fflush (stderr);
6445 /* A null message buffer means that the frame hasn't really been
6446 initialized yet. Error messages get reported properly by
6447 cmd_error, so this must be just an informative message; toss it. */
6448 else if (INTERACTIVE
6449 && sf->glyphs_initialized_p
6450 && FRAME_MESSAGE_BUF (sf))
6452 Lisp_Object mini_window;
6453 Lisp_Object frame;
6454 struct frame *f;
6456 /* Get the frame containing the mini-buffer
6457 that the selected frame is using. */
6458 mini_window = FRAME_MINIBUF_WINDOW (sf);
6459 frame = XWINDOW (mini_window)->frame;
6460 f = XFRAME (frame);
6462 FRAME_SAMPLE_VISIBILITY (f);
6463 if (FRAME_VISIBLE_P (sf)
6464 && !FRAME_VISIBLE_P (f))
6465 Fmake_frame_visible (frame);
6467 if (STRINGP (m) && SCHARS (m) > 0)
6469 set_message (NULL, m, nbytes, multibyte);
6470 if (minibuffer_auto_raise)
6471 Fraise_frame (frame);
6473 else
6474 clear_message (1, 1);
6476 do_pending_window_change (0);
6477 echo_area_display (1);
6478 do_pending_window_change (0);
6479 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
6480 (*frame_up_to_date_hook) (f);
6485 /* Display a null-terminated echo area message M. If M is 0, clear
6486 out any existing message, and let the mini-buffer text show through.
6488 The buffer M must continue to exist until after the echo area gets
6489 cleared or some other message gets displayed there. Do not pass
6490 text that is stored in a Lisp string. Do not pass text in a buffer
6491 that was alloca'd. */
6493 void
6494 message1 (m)
6495 char *m;
6497 message2 (m, (m ? strlen (m) : 0), 0);
6501 /* The non-logging counterpart of message1. */
6503 void
6504 message1_nolog (m)
6505 char *m;
6507 message2_nolog (m, (m ? strlen (m) : 0), 0);
6510 /* Display a message M which contains a single %s
6511 which gets replaced with STRING. */
6513 void
6514 message_with_string (m, string, log)
6515 char *m;
6516 Lisp_Object string;
6517 int log;
6519 CHECK_STRING (string);
6521 if (noninteractive)
6523 if (m)
6525 if (noninteractive_need_newline)
6526 putc ('\n', stderr);
6527 noninteractive_need_newline = 0;
6528 fprintf (stderr, m, SDATA (string));
6529 if (cursor_in_echo_area == 0)
6530 fprintf (stderr, "\n");
6531 fflush (stderr);
6534 else if (INTERACTIVE)
6536 /* The frame whose minibuffer we're going to display the message on.
6537 It may be larger than the selected frame, so we need
6538 to use its buffer, not the selected frame's buffer. */
6539 Lisp_Object mini_window;
6540 struct frame *f, *sf = SELECTED_FRAME ();
6542 /* Get the frame containing the minibuffer
6543 that the selected frame is using. */
6544 mini_window = FRAME_MINIBUF_WINDOW (sf);
6545 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6547 /* A null message buffer means that the frame hasn't really been
6548 initialized yet. Error messages get reported properly by
6549 cmd_error, so this must be just an informative message; toss it. */
6550 if (FRAME_MESSAGE_BUF (f))
6552 Lisp_Object args[2], message;
6553 struct gcpro gcpro1, gcpro2;
6555 args[0] = build_string (m);
6556 args[1] = message = string;
6557 GCPRO2 (args[0], message);
6558 gcpro1.nvars = 2;
6560 message = Fformat (2, args);
6562 if (log)
6563 message3 (message, SBYTES (message), STRING_MULTIBYTE (message));
6564 else
6565 message3_nolog (message, SBYTES (message), STRING_MULTIBYTE (message));
6567 UNGCPRO;
6569 /* Print should start at the beginning of the message
6570 buffer next time. */
6571 message_buf_print = 0;
6577 /* Dump an informative message to the minibuf. If M is 0, clear out
6578 any existing message, and let the mini-buffer text show through. */
6580 /* VARARGS 1 */
6581 void
6582 message (m, a1, a2, a3)
6583 char *m;
6584 EMACS_INT a1, a2, a3;
6586 if (noninteractive)
6588 if (m)
6590 if (noninteractive_need_newline)
6591 putc ('\n', stderr);
6592 noninteractive_need_newline = 0;
6593 fprintf (stderr, m, a1, a2, a3);
6594 if (cursor_in_echo_area == 0)
6595 fprintf (stderr, "\n");
6596 fflush (stderr);
6599 else if (INTERACTIVE)
6601 /* The frame whose mini-buffer we're going to display the message
6602 on. It may be larger than the selected frame, so we need to
6603 use its buffer, not the selected frame's buffer. */
6604 Lisp_Object mini_window;
6605 struct frame *f, *sf = SELECTED_FRAME ();
6607 /* Get the frame containing the mini-buffer
6608 that the selected frame is using. */
6609 mini_window = FRAME_MINIBUF_WINDOW (sf);
6610 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6612 /* A null message buffer means that the frame hasn't really been
6613 initialized yet. Error messages get reported properly by
6614 cmd_error, so this must be just an informative message; toss
6615 it. */
6616 if (FRAME_MESSAGE_BUF (f))
6618 if (m)
6620 int len;
6621 #ifdef NO_ARG_ARRAY
6622 char *a[3];
6623 a[0] = (char *) a1;
6624 a[1] = (char *) a2;
6625 a[2] = (char *) a3;
6627 len = doprnt (FRAME_MESSAGE_BUF (f),
6628 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
6629 #else
6630 len = doprnt (FRAME_MESSAGE_BUF (f),
6631 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3,
6632 (char **) &a1);
6633 #endif /* NO_ARG_ARRAY */
6635 message2 (FRAME_MESSAGE_BUF (f), len, 0);
6637 else
6638 message1 (0);
6640 /* Print should start at the beginning of the message
6641 buffer next time. */
6642 message_buf_print = 0;
6648 /* The non-logging version of message. */
6650 void
6651 message_nolog (m, a1, a2, a3)
6652 char *m;
6653 EMACS_INT a1, a2, a3;
6655 Lisp_Object old_log_max;
6656 old_log_max = Vmessage_log_max;
6657 Vmessage_log_max = Qnil;
6658 message (m, a1, a2, a3);
6659 Vmessage_log_max = old_log_max;
6663 /* Display the current message in the current mini-buffer. This is
6664 only called from error handlers in process.c, and is not time
6665 critical. */
6667 void
6668 update_echo_area ()
6670 if (!NILP (echo_area_buffer[0]))
6672 Lisp_Object string;
6673 string = Fcurrent_message ();
6674 message3 (string, SBYTES (string),
6675 !NILP (current_buffer->enable_multibyte_characters));
6680 /* Make sure echo area buffers in `echo_buffers' are live.
6681 If they aren't, make new ones. */
6683 static void
6684 ensure_echo_area_buffers ()
6686 int i;
6688 for (i = 0; i < 2; ++i)
6689 if (!BUFFERP (echo_buffer[i])
6690 || NILP (XBUFFER (echo_buffer[i])->name))
6692 char name[30];
6693 Lisp_Object old_buffer;
6694 int j;
6696 old_buffer = echo_buffer[i];
6697 sprintf (name, " *Echo Area %d*", i);
6698 echo_buffer[i] = Fget_buffer_create (build_string (name));
6699 XBUFFER (echo_buffer[i])->truncate_lines = Qnil;
6701 for (j = 0; j < 2; ++j)
6702 if (EQ (old_buffer, echo_area_buffer[j]))
6703 echo_area_buffer[j] = echo_buffer[i];
6708 /* Call FN with args A1..A4 with either the current or last displayed
6709 echo_area_buffer as current buffer.
6711 WHICH zero means use the current message buffer
6712 echo_area_buffer[0]. If that is nil, choose a suitable buffer
6713 from echo_buffer[] and clear it.
6715 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
6716 suitable buffer from echo_buffer[] and clear it.
6718 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
6719 that the current message becomes the last displayed one, make
6720 choose a suitable buffer for echo_area_buffer[0], and clear it.
6722 Value is what FN returns. */
6724 static int
6725 with_echo_area_buffer (w, which, fn, a1, a2, a3, a4)
6726 struct window *w;
6727 int which;
6728 int (*fn) P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
6729 EMACS_INT a1;
6730 Lisp_Object a2;
6731 EMACS_INT a3, a4;
6733 Lisp_Object buffer;
6734 int this_one, the_other, clear_buffer_p, rc;
6735 int count = SPECPDL_INDEX ();
6737 /* If buffers aren't live, make new ones. */
6738 ensure_echo_area_buffers ();
6740 clear_buffer_p = 0;
6742 if (which == 0)
6743 this_one = 0, the_other = 1;
6744 else if (which > 0)
6745 this_one = 1, the_other = 0;
6746 else
6748 this_one = 0, the_other = 1;
6749 clear_buffer_p = 1;
6751 /* We need a fresh one in case the current echo buffer equals
6752 the one containing the last displayed echo area message. */
6753 if (!NILP (echo_area_buffer[this_one])
6754 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
6755 echo_area_buffer[this_one] = Qnil;
6758 /* Choose a suitable buffer from echo_buffer[] is we don't
6759 have one. */
6760 if (NILP (echo_area_buffer[this_one]))
6762 echo_area_buffer[this_one]
6763 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
6764 ? echo_buffer[the_other]
6765 : echo_buffer[this_one]);
6766 clear_buffer_p = 1;
6769 buffer = echo_area_buffer[this_one];
6771 /* Don't get confused by reusing the buffer used for echoing
6772 for a different purpose. */
6773 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
6774 cancel_echoing ();
6776 record_unwind_protect (unwind_with_echo_area_buffer,
6777 with_echo_area_buffer_unwind_data (w));
6779 /* Make the echo area buffer current. Note that for display
6780 purposes, it is not necessary that the displayed window's buffer
6781 == current_buffer, except for text property lookup. So, let's
6782 only set that buffer temporarily here without doing a full
6783 Fset_window_buffer. We must also change w->pointm, though,
6784 because otherwise an assertions in unshow_buffer fails, and Emacs
6785 aborts. */
6786 set_buffer_internal_1 (XBUFFER (buffer));
6787 if (w)
6789 w->buffer = buffer;
6790 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
6793 current_buffer->undo_list = Qt;
6794 current_buffer->read_only = Qnil;
6795 specbind (Qinhibit_read_only, Qt);
6796 specbind (Qinhibit_modification_hooks, Qt);
6798 if (clear_buffer_p && Z > BEG)
6799 del_range (BEG, Z);
6801 xassert (BEGV >= BEG);
6802 xassert (ZV <= Z && ZV >= BEGV);
6804 rc = fn (a1, a2, a3, a4);
6806 xassert (BEGV >= BEG);
6807 xassert (ZV <= Z && ZV >= BEGV);
6809 unbind_to (count, Qnil);
6810 return rc;
6814 /* Save state that should be preserved around the call to the function
6815 FN called in with_echo_area_buffer. */
6817 static Lisp_Object
6818 with_echo_area_buffer_unwind_data (w)
6819 struct window *w;
6821 int i = 0;
6822 Lisp_Object vector;
6824 /* Reduce consing by keeping one vector in
6825 Vwith_echo_area_save_vector. */
6826 vector = Vwith_echo_area_save_vector;
6827 Vwith_echo_area_save_vector = Qnil;
6829 if (NILP (vector))
6830 vector = Fmake_vector (make_number (7), Qnil);
6832 XSETBUFFER (AREF (vector, i), current_buffer); ++i;
6833 AREF (vector, i) = Vdeactivate_mark, ++i;
6834 AREF (vector, i) = make_number (windows_or_buffers_changed), ++i;
6836 if (w)
6838 XSETWINDOW (AREF (vector, i), w); ++i;
6839 AREF (vector, i) = w->buffer; ++i;
6840 AREF (vector, i) = make_number (XMARKER (w->pointm)->charpos); ++i;
6841 AREF (vector, i) = make_number (XMARKER (w->pointm)->bytepos); ++i;
6843 else
6845 int end = i + 4;
6846 for (; i < end; ++i)
6847 AREF (vector, i) = Qnil;
6850 xassert (i == ASIZE (vector));
6851 return vector;
6855 /* Restore global state from VECTOR which was created by
6856 with_echo_area_buffer_unwind_data. */
6858 static Lisp_Object
6859 unwind_with_echo_area_buffer (vector)
6860 Lisp_Object vector;
6862 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
6863 Vdeactivate_mark = AREF (vector, 1);
6864 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
6866 if (WINDOWP (AREF (vector, 3)))
6868 struct window *w;
6869 Lisp_Object buffer, charpos, bytepos;
6871 w = XWINDOW (AREF (vector, 3));
6872 buffer = AREF (vector, 4);
6873 charpos = AREF (vector, 5);
6874 bytepos = AREF (vector, 6);
6876 w->buffer = buffer;
6877 set_marker_both (w->pointm, buffer,
6878 XFASTINT (charpos), XFASTINT (bytepos));
6881 Vwith_echo_area_save_vector = vector;
6882 return Qnil;
6886 /* Set up the echo area for use by print functions. MULTIBYTE_P
6887 non-zero means we will print multibyte. */
6889 void
6890 setup_echo_area_for_printing (multibyte_p)
6891 int multibyte_p;
6893 /* If we can't find an echo area any more, exit. */
6894 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
6895 Fkill_emacs (Qnil);
6897 ensure_echo_area_buffers ();
6899 if (!message_buf_print)
6901 /* A message has been output since the last time we printed.
6902 Choose a fresh echo area buffer. */
6903 if (EQ (echo_area_buffer[1], echo_buffer[0]))
6904 echo_area_buffer[0] = echo_buffer[1];
6905 else
6906 echo_area_buffer[0] = echo_buffer[0];
6908 /* Switch to that buffer and clear it. */
6909 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
6910 current_buffer->truncate_lines = Qnil;
6912 if (Z > BEG)
6914 int count = SPECPDL_INDEX ();
6915 specbind (Qinhibit_read_only, Qt);
6916 /* Note that undo recording is always disabled. */
6917 del_range (BEG, Z);
6918 unbind_to (count, Qnil);
6920 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
6922 /* Set up the buffer for the multibyteness we need. */
6923 if (multibyte_p
6924 != !NILP (current_buffer->enable_multibyte_characters))
6925 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
6927 /* Raise the frame containing the echo area. */
6928 if (minibuffer_auto_raise)
6930 struct frame *sf = SELECTED_FRAME ();
6931 Lisp_Object mini_window;
6932 mini_window = FRAME_MINIBUF_WINDOW (sf);
6933 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
6936 message_log_maybe_newline ();
6937 message_buf_print = 1;
6939 else
6941 if (NILP (echo_area_buffer[0]))
6943 if (EQ (echo_area_buffer[1], echo_buffer[0]))
6944 echo_area_buffer[0] = echo_buffer[1];
6945 else
6946 echo_area_buffer[0] = echo_buffer[0];
6949 if (current_buffer != XBUFFER (echo_area_buffer[0]))
6951 /* Someone switched buffers between print requests. */
6952 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
6953 current_buffer->truncate_lines = Qnil;
6959 /* Display an echo area message in window W. Value is non-zero if W's
6960 height is changed. If display_last_displayed_message_p is
6961 non-zero, display the message that was last displayed, otherwise
6962 display the current message. */
6964 static int
6965 display_echo_area (w)
6966 struct window *w;
6968 int i, no_message_p, window_height_changed_p, count;
6970 /* Temporarily disable garbage collections while displaying the echo
6971 area. This is done because a GC can print a message itself.
6972 That message would modify the echo area buffer's contents while a
6973 redisplay of the buffer is going on, and seriously confuse
6974 redisplay. */
6975 count = inhibit_garbage_collection ();
6977 /* If there is no message, we must call display_echo_area_1
6978 nevertheless because it resizes the window. But we will have to
6979 reset the echo_area_buffer in question to nil at the end because
6980 with_echo_area_buffer will sets it to an empty buffer. */
6981 i = display_last_displayed_message_p ? 1 : 0;
6982 no_message_p = NILP (echo_area_buffer[i]);
6984 window_height_changed_p
6985 = with_echo_area_buffer (w, display_last_displayed_message_p,
6986 display_echo_area_1,
6987 (EMACS_INT) w, Qnil, 0, 0);
6989 if (no_message_p)
6990 echo_area_buffer[i] = Qnil;
6992 unbind_to (count, Qnil);
6993 return window_height_changed_p;
6997 /* Helper for display_echo_area. Display the current buffer which
6998 contains the current echo area message in window W, a mini-window,
6999 a pointer to which is passed in A1. A2..A4 are currently not used.
7000 Change the height of W so that all of the message is displayed.
7001 Value is non-zero if height of W was changed. */
7003 static int
7004 display_echo_area_1 (a1, a2, a3, a4)
7005 EMACS_INT a1;
7006 Lisp_Object a2;
7007 EMACS_INT a3, a4;
7009 struct window *w = (struct window *) a1;
7010 Lisp_Object window;
7011 struct text_pos start;
7012 int window_height_changed_p = 0;
7014 /* Do this before displaying, so that we have a large enough glyph
7015 matrix for the display. */
7016 window_height_changed_p = resize_mini_window (w, 0);
7018 /* Display. */
7019 clear_glyph_matrix (w->desired_matrix);
7020 XSETWINDOW (window, w);
7021 SET_TEXT_POS (start, BEG, BEG_BYTE);
7022 try_window (window, start);
7024 return window_height_changed_p;
7028 /* Resize the echo area window to exactly the size needed for the
7029 currently displayed message, if there is one. If a mini-buffer
7030 is active, don't shrink it. */
7032 void
7033 resize_echo_area_exactly ()
7035 if (BUFFERP (echo_area_buffer[0])
7036 && WINDOWP (echo_area_window))
7038 struct window *w = XWINDOW (echo_area_window);
7039 int resized_p;
7040 Lisp_Object resize_exactly;
7042 if (minibuf_level == 0)
7043 resize_exactly = Qt;
7044 else
7045 resize_exactly = Qnil;
7047 resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
7048 (EMACS_INT) w, resize_exactly, 0, 0);
7049 if (resized_p)
7051 ++windows_or_buffers_changed;
7052 ++update_mode_lines;
7053 redisplay_internal (0);
7059 /* Callback function for with_echo_area_buffer, when used from
7060 resize_echo_area_exactly. A1 contains a pointer to the window to
7061 resize, EXACTLY non-nil means resize the mini-window exactly to the
7062 size of the text displayed. A3 and A4 are not used. Value is what
7063 resize_mini_window returns. */
7065 static int
7066 resize_mini_window_1 (a1, exactly, a3, a4)
7067 EMACS_INT a1;
7068 Lisp_Object exactly;
7069 EMACS_INT a3, a4;
7071 return resize_mini_window ((struct window *) a1, !NILP (exactly));
7075 /* Resize mini-window W to fit the size of its contents. EXACT:P
7076 means size the window exactly to the size needed. Otherwise, it's
7077 only enlarged until W's buffer is empty. Value is non-zero if
7078 the window height has been changed. */
7081 resize_mini_window (w, exact_p)
7082 struct window *w;
7083 int exact_p;
7085 struct frame *f = XFRAME (w->frame);
7086 int window_height_changed_p = 0;
7088 xassert (MINI_WINDOW_P (w));
7090 /* Don't resize windows while redisplaying a window; it would
7091 confuse redisplay functions when the size of the window they are
7092 displaying changes from under them. Such a resizing can happen,
7093 for instance, when which-func prints a long message while
7094 we are running fontification-functions. We're running these
7095 functions with safe_call which binds inhibit-redisplay to t. */
7096 if (!NILP (Vinhibit_redisplay))
7097 return 0;
7099 /* Nil means don't try to resize. */
7100 if (NILP (Vresize_mini_windows)
7101 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
7102 return 0;
7104 if (!FRAME_MINIBUF_ONLY_P (f))
7106 struct it it;
7107 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
7108 int total_height = XFASTINT (root->height) + XFASTINT (w->height);
7109 int height, max_height;
7110 int unit = CANON_Y_UNIT (f);
7111 struct text_pos start;
7112 struct buffer *old_current_buffer = NULL;
7114 if (current_buffer != XBUFFER (w->buffer))
7116 old_current_buffer = current_buffer;
7117 set_buffer_internal (XBUFFER (w->buffer));
7120 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
7122 /* Compute the max. number of lines specified by the user. */
7123 if (FLOATP (Vmax_mini_window_height))
7124 max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_HEIGHT (f);
7125 else if (INTEGERP (Vmax_mini_window_height))
7126 max_height = XINT (Vmax_mini_window_height);
7127 else
7128 max_height = total_height / 4;
7130 /* Correct that max. height if it's bogus. */
7131 max_height = max (1, max_height);
7132 max_height = min (total_height, max_height);
7134 /* Find out the height of the text in the window. */
7135 if (it.truncate_lines_p)
7136 height = 1;
7137 else
7139 last_height = 0;
7140 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
7141 if (it.max_ascent == 0 && it.max_descent == 0)
7142 height = it.current_y + last_height;
7143 else
7144 height = it.current_y + it.max_ascent + it.max_descent;
7145 height -= it.extra_line_spacing;
7146 height = (height + unit - 1) / unit;
7149 /* Compute a suitable window start. */
7150 if (height > max_height)
7152 height = max_height;
7153 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
7154 move_it_vertically_backward (&it, (height - 1) * unit);
7155 start = it.current.pos;
7157 else
7158 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
7159 SET_MARKER_FROM_TEXT_POS (w->start, start);
7161 if (EQ (Vresize_mini_windows, Qgrow_only))
7163 /* Let it grow only, until we display an empty message, in which
7164 case the window shrinks again. */
7165 if (height > XFASTINT (w->height))
7167 int old_height = XFASTINT (w->height);
7168 freeze_window_starts (f, 1);
7169 grow_mini_window (w, height - XFASTINT (w->height));
7170 window_height_changed_p = XFASTINT (w->height) != old_height;
7172 else if (height < XFASTINT (w->height)
7173 && (exact_p || BEGV == ZV))
7175 int old_height = XFASTINT (w->height);
7176 freeze_window_starts (f, 0);
7177 shrink_mini_window (w);
7178 window_height_changed_p = XFASTINT (w->height) != old_height;
7181 else
7183 /* Always resize to exact size needed. */
7184 if (height > XFASTINT (w->height))
7186 int old_height = XFASTINT (w->height);
7187 freeze_window_starts (f, 1);
7188 grow_mini_window (w, height - XFASTINT (w->height));
7189 window_height_changed_p = XFASTINT (w->height) != old_height;
7191 else if (height < XFASTINT (w->height))
7193 int old_height = XFASTINT (w->height);
7194 freeze_window_starts (f, 0);
7195 shrink_mini_window (w);
7197 if (height)
7199 freeze_window_starts (f, 1);
7200 grow_mini_window (w, height - XFASTINT (w->height));
7203 window_height_changed_p = XFASTINT (w->height) != old_height;
7207 if (old_current_buffer)
7208 set_buffer_internal (old_current_buffer);
7211 return window_height_changed_p;
7215 /* Value is the current message, a string, or nil if there is no
7216 current message. */
7218 Lisp_Object
7219 current_message ()
7221 Lisp_Object msg;
7223 if (NILP (echo_area_buffer[0]))
7224 msg = Qnil;
7225 else
7227 with_echo_area_buffer (0, 0, current_message_1,
7228 (EMACS_INT) &msg, Qnil, 0, 0);
7229 if (NILP (msg))
7230 echo_area_buffer[0] = Qnil;
7233 return msg;
7237 static int
7238 current_message_1 (a1, a2, a3, a4)
7239 EMACS_INT a1;
7240 Lisp_Object a2;
7241 EMACS_INT a3, a4;
7243 Lisp_Object *msg = (Lisp_Object *) a1;
7245 if (Z > BEG)
7246 *msg = make_buffer_string (BEG, Z, 1);
7247 else
7248 *msg = Qnil;
7249 return 0;
7253 /* Push the current message on Vmessage_stack for later restauration
7254 by restore_message. Value is non-zero if the current message isn't
7255 empty. This is a relatively infrequent operation, so it's not
7256 worth optimizing. */
7259 push_message ()
7261 Lisp_Object msg;
7262 msg = current_message ();
7263 Vmessage_stack = Fcons (msg, Vmessage_stack);
7264 return STRINGP (msg);
7268 /* Restore message display from the top of Vmessage_stack. */
7270 void
7271 restore_message ()
7273 Lisp_Object msg;
7275 xassert (CONSP (Vmessage_stack));
7276 msg = XCAR (Vmessage_stack);
7277 if (STRINGP (msg))
7278 message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
7279 else
7280 message3_nolog (msg, 0, 0);
7284 /* Handler for record_unwind_protect calling pop_message. */
7286 Lisp_Object
7287 pop_message_unwind (dummy)
7288 Lisp_Object dummy;
7290 pop_message ();
7291 return Qnil;
7294 /* Pop the top-most entry off Vmessage_stack. */
7296 void
7297 pop_message ()
7299 xassert (CONSP (Vmessage_stack));
7300 Vmessage_stack = XCDR (Vmessage_stack);
7304 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
7305 exits. If the stack is not empty, we have a missing pop_message
7306 somewhere. */
7308 void
7309 check_message_stack ()
7311 if (!NILP (Vmessage_stack))
7312 abort ();
7316 /* Truncate to NCHARS what will be displayed in the echo area the next
7317 time we display it---but don't redisplay it now. */
7319 void
7320 truncate_echo_area (nchars)
7321 int nchars;
7323 if (nchars == 0)
7324 echo_area_buffer[0] = Qnil;
7325 /* A null message buffer means that the frame hasn't really been
7326 initialized yet. Error messages get reported properly by
7327 cmd_error, so this must be just an informative message; toss it. */
7328 else if (!noninteractive
7329 && INTERACTIVE
7330 && !NILP (echo_area_buffer[0]))
7332 struct frame *sf = SELECTED_FRAME ();
7333 if (FRAME_MESSAGE_BUF (sf))
7334 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil, 0, 0);
7339 /* Helper function for truncate_echo_area. Truncate the current
7340 message to at most NCHARS characters. */
7342 static int
7343 truncate_message_1 (nchars, a2, a3, a4)
7344 EMACS_INT nchars;
7345 Lisp_Object a2;
7346 EMACS_INT a3, a4;
7348 if (BEG + nchars < Z)
7349 del_range (BEG + nchars, Z);
7350 if (Z == BEG)
7351 echo_area_buffer[0] = Qnil;
7352 return 0;
7356 /* Set the current message to a substring of S or STRING.
7358 If STRING is a Lisp string, set the message to the first NBYTES
7359 bytes from STRING. NBYTES zero means use the whole string. If
7360 STRING is multibyte, the message will be displayed multibyte.
7362 If S is not null, set the message to the first LEN bytes of S. LEN
7363 zero means use the whole string. MULTIBYTE_P non-zero means S is
7364 multibyte. Display the message multibyte in that case. */
7366 void
7367 set_message (s, string, nbytes, multibyte_p)
7368 const char *s;
7369 Lisp_Object string;
7370 int nbytes, multibyte_p;
7372 message_enable_multibyte
7373 = ((s && multibyte_p)
7374 || (STRINGP (string) && STRING_MULTIBYTE (string)));
7376 with_echo_area_buffer (0, -1, set_message_1,
7377 (EMACS_INT) s, string, nbytes, multibyte_p);
7378 message_buf_print = 0;
7379 help_echo_showing_p = 0;
7383 /* Helper function for set_message. Arguments have the same meaning
7384 as there, with A1 corresponding to S and A2 corresponding to STRING
7385 This function is called with the echo area buffer being
7386 current. */
7388 static int
7389 set_message_1 (a1, a2, nbytes, multibyte_p)
7390 EMACS_INT a1;
7391 Lisp_Object a2;
7392 EMACS_INT nbytes, multibyte_p;
7394 const char *s = (const char *) a1;
7395 Lisp_Object string = a2;
7397 xassert (BEG == Z);
7399 /* Change multibyteness of the echo buffer appropriately. */
7400 if (message_enable_multibyte
7401 != !NILP (current_buffer->enable_multibyte_characters))
7402 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
7404 current_buffer->truncate_lines = message_truncate_lines ? Qt : Qnil;
7406 /* Insert new message at BEG. */
7407 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
7409 if (STRINGP (string))
7411 int nchars;
7413 if (nbytes == 0)
7414 nbytes = SBYTES (string);
7415 nchars = string_byte_to_char (string, nbytes);
7417 /* This function takes care of single/multibyte conversion. We
7418 just have to ensure that the echo area buffer has the right
7419 setting of enable_multibyte_characters. */
7420 insert_from_string (string, 0, 0, nchars, nbytes, 1);
7422 else if (s)
7424 if (nbytes == 0)
7425 nbytes = strlen (s);
7427 if (multibyte_p && NILP (current_buffer->enable_multibyte_characters))
7429 /* Convert from multi-byte to single-byte. */
7430 int i, c, n;
7431 unsigned char work[1];
7433 /* Convert a multibyte string to single-byte. */
7434 for (i = 0; i < nbytes; i += n)
7436 c = string_char_and_length (s + i, nbytes - i, &n);
7437 work[0] = (SINGLE_BYTE_CHAR_P (c)
7439 : multibyte_char_to_unibyte (c, Qnil));
7440 insert_1_both (work, 1, 1, 1, 0, 0);
7443 else if (!multibyte_p
7444 && !NILP (current_buffer->enable_multibyte_characters))
7446 /* Convert from single-byte to multi-byte. */
7447 int i, c, n;
7448 const unsigned char *msg = (const unsigned char *) s;
7449 unsigned char str[MAX_MULTIBYTE_LENGTH];
7451 /* Convert a single-byte string to multibyte. */
7452 for (i = 0; i < nbytes; i++)
7454 c = unibyte_char_to_multibyte (msg[i]);
7455 n = CHAR_STRING (c, str);
7456 insert_1_both (str, 1, n, 1, 0, 0);
7459 else
7460 insert_1 (s, nbytes, 1, 0, 0);
7463 return 0;
7467 /* Clear messages. CURRENT_P non-zero means clear the current
7468 message. LAST_DISPLAYED_P non-zero means clear the message
7469 last displayed. */
7471 void
7472 clear_message (current_p, last_displayed_p)
7473 int current_p, last_displayed_p;
7475 if (current_p)
7477 echo_area_buffer[0] = Qnil;
7478 message_cleared_p = 1;
7481 if (last_displayed_p)
7482 echo_area_buffer[1] = Qnil;
7484 message_buf_print = 0;
7487 /* Clear garbaged frames.
7489 This function is used where the old redisplay called
7490 redraw_garbaged_frames which in turn called redraw_frame which in
7491 turn called clear_frame. The call to clear_frame was a source of
7492 flickering. I believe a clear_frame is not necessary. It should
7493 suffice in the new redisplay to invalidate all current matrices,
7494 and ensure a complete redisplay of all windows. */
7496 static void
7497 clear_garbaged_frames ()
7499 if (frame_garbaged)
7501 Lisp_Object tail, frame;
7502 int changed_count = 0;
7504 FOR_EACH_FRAME (tail, frame)
7506 struct frame *f = XFRAME (frame);
7508 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
7510 if (f->resized_p)
7511 Fredraw_frame (frame);
7512 clear_current_matrices (f);
7513 changed_count++;
7514 f->garbaged = 0;
7515 f->resized_p = 0;
7519 frame_garbaged = 0;
7520 if (changed_count)
7521 ++windows_or_buffers_changed;
7526 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
7527 is non-zero update selected_frame. Value is non-zero if the
7528 mini-windows height has been changed. */
7530 static int
7531 echo_area_display (update_frame_p)
7532 int update_frame_p;
7534 Lisp_Object mini_window;
7535 struct window *w;
7536 struct frame *f;
7537 int window_height_changed_p = 0;
7538 struct frame *sf = SELECTED_FRAME ();
7540 mini_window = FRAME_MINIBUF_WINDOW (sf);
7541 w = XWINDOW (mini_window);
7542 f = XFRAME (WINDOW_FRAME (w));
7544 /* Don't display if frame is invisible or not yet initialized. */
7545 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
7546 return 0;
7548 /* The terminal frame is used as the first Emacs frame on the Mac OS. */
7549 #ifndef MAC_OS8
7550 #ifdef HAVE_WINDOW_SYSTEM
7551 /* When Emacs starts, selected_frame may be a visible terminal
7552 frame, even if we run under a window system. If we let this
7553 through, a message would be displayed on the terminal. */
7554 if (EQ (selected_frame, Vterminal_frame)
7555 && !NILP (Vwindow_system))
7556 return 0;
7557 #endif /* HAVE_WINDOW_SYSTEM */
7558 #endif
7560 /* Redraw garbaged frames. */
7561 if (frame_garbaged)
7562 clear_garbaged_frames ();
7564 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
7566 echo_area_window = mini_window;
7567 window_height_changed_p = display_echo_area (w);
7568 w->must_be_updated_p = 1;
7570 /* Update the display, unless called from redisplay_internal.
7571 Also don't update the screen during redisplay itself. The
7572 update will happen at the end of redisplay, and an update
7573 here could cause confusion. */
7574 if (update_frame_p && !redisplaying_p)
7576 int n = 0;
7578 /* If the display update has been interrupted by pending
7579 input, update mode lines in the frame. Due to the
7580 pending input, it might have been that redisplay hasn't
7581 been called, so that mode lines above the echo area are
7582 garbaged. This looks odd, so we prevent it here. */
7583 if (!display_completed)
7584 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), 0);
7586 if (window_height_changed_p
7587 /* Don't do this if Emacs is shutting down. Redisplay
7588 needs to run hooks. */
7589 && !NILP (Vrun_hooks))
7591 /* Must update other windows. Likewise as in other
7592 cases, don't let this update be interrupted by
7593 pending input. */
7594 int count = SPECPDL_INDEX ();
7595 specbind (Qredisplay_dont_pause, Qt);
7596 windows_or_buffers_changed = 1;
7597 redisplay_internal (0);
7598 unbind_to (count, Qnil);
7600 else if (FRAME_WINDOW_P (f) && n == 0)
7602 /* Window configuration is the same as before.
7603 Can do with a display update of the echo area,
7604 unless we displayed some mode lines. */
7605 update_single_window (w, 1);
7606 rif->flush_display (f);
7608 else
7609 update_frame (f, 1, 1);
7611 /* If cursor is in the echo area, make sure that the next
7612 redisplay displays the minibuffer, so that the cursor will
7613 be replaced with what the minibuffer wants. */
7614 if (cursor_in_echo_area)
7615 ++windows_or_buffers_changed;
7618 else if (!EQ (mini_window, selected_window))
7619 windows_or_buffers_changed++;
7621 /* Last displayed message is now the current message. */
7622 echo_area_buffer[1] = echo_area_buffer[0];
7624 /* Prevent redisplay optimization in redisplay_internal by resetting
7625 this_line_start_pos. This is done because the mini-buffer now
7626 displays the message instead of its buffer text. */
7627 if (EQ (mini_window, selected_window))
7628 CHARPOS (this_line_start_pos) = 0;
7630 return window_height_changed_p;
7635 /***********************************************************************
7636 Frame Titles
7637 ***********************************************************************/
7640 /* The frame title buffering code is also used by Fformat_mode_line.
7641 So it is not conditioned by HAVE_WINDOW_SYSTEM. */
7643 /* A buffer for constructing frame titles in it; allocated from the
7644 heap in init_xdisp and resized as needed in store_frame_title_char. */
7646 static char *frame_title_buf;
7648 /* The buffer's end, and a current output position in it. */
7650 static char *frame_title_buf_end;
7651 static char *frame_title_ptr;
7654 /* Store a single character C for the frame title in frame_title_buf.
7655 Re-allocate frame_title_buf if necessary. */
7657 static void
7658 #ifdef PROTOTYPES
7659 store_frame_title_char (char c)
7660 #else
7661 store_frame_title_char (c)
7662 char c;
7663 #endif
7665 /* If output position has reached the end of the allocated buffer,
7666 double the buffer's size. */
7667 if (frame_title_ptr == frame_title_buf_end)
7669 int len = frame_title_ptr - frame_title_buf;
7670 int new_size = 2 * len * sizeof *frame_title_buf;
7671 frame_title_buf = (char *) xrealloc (frame_title_buf, new_size);
7672 frame_title_buf_end = frame_title_buf + new_size;
7673 frame_title_ptr = frame_title_buf + len;
7676 *frame_title_ptr++ = c;
7680 /* Store part of a frame title in frame_title_buf, beginning at
7681 frame_title_ptr. STR is the string to store. Do not copy
7682 characters that yield more columns than PRECISION; PRECISION <= 0
7683 means copy the whole string. Pad with spaces until FIELD_WIDTH
7684 number of characters have been copied; FIELD_WIDTH <= 0 means don't
7685 pad. Called from display_mode_element when it is used to build a
7686 frame title. */
7688 static int
7689 store_frame_title (str, field_width, precision)
7690 const unsigned char *str;
7691 int field_width, precision;
7693 int n = 0;
7694 int dummy, nbytes;
7696 /* Copy at most PRECISION chars from STR. */
7697 nbytes = strlen (str);
7698 n+= c_string_width (str, nbytes, precision, &dummy, &nbytes);
7699 while (nbytes--)
7700 store_frame_title_char (*str++);
7702 /* Fill up with spaces until FIELD_WIDTH reached. */
7703 while (field_width > 0
7704 && n < field_width)
7706 store_frame_title_char (' ');
7707 ++n;
7710 return n;
7713 #ifdef HAVE_WINDOW_SYSTEM
7715 /* Set the title of FRAME, if it has changed. The title format is
7716 Vicon_title_format if FRAME is iconified, otherwise it is
7717 frame_title_format. */
7719 static void
7720 x_consider_frame_title (frame)
7721 Lisp_Object frame;
7723 struct frame *f = XFRAME (frame);
7725 if (FRAME_WINDOW_P (f)
7726 || FRAME_MINIBUF_ONLY_P (f)
7727 || f->explicit_name)
7729 /* Do we have more than one visible frame on this X display? */
7730 Lisp_Object tail;
7731 Lisp_Object fmt;
7732 struct buffer *obuf;
7733 int len;
7734 struct it it;
7736 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
7738 Lisp_Object other_frame = XCAR (tail);
7739 struct frame *tf = XFRAME (other_frame);
7741 if (tf != f
7742 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
7743 && !FRAME_MINIBUF_ONLY_P (tf)
7744 && !EQ (other_frame, tip_frame)
7745 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
7746 break;
7749 /* Set global variable indicating that multiple frames exist. */
7750 multiple_frames = CONSP (tail);
7752 /* Switch to the buffer of selected window of the frame. Set up
7753 frame_title_ptr so that display_mode_element will output into it;
7754 then display the title. */
7755 obuf = current_buffer;
7756 set_buffer_internal_1 (XBUFFER (XWINDOW (f->selected_window)->buffer));
7757 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
7758 frame_title_ptr = frame_title_buf;
7759 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
7760 NULL, DEFAULT_FACE_ID);
7761 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
7762 len = frame_title_ptr - frame_title_buf;
7763 frame_title_ptr = NULL;
7764 set_buffer_internal_1 (obuf);
7766 /* Set the title only if it's changed. This avoids consing in
7767 the common case where it hasn't. (If it turns out that we've
7768 already wasted too much time by walking through the list with
7769 display_mode_element, then we might need to optimize at a
7770 higher level than this.) */
7771 if (! STRINGP (f->name)
7772 || SBYTES (f->name) != len
7773 || bcmp (frame_title_buf, SDATA (f->name), len) != 0)
7774 x_implicitly_set_name (f, make_string (frame_title_buf, len), Qnil);
7778 #endif /* not HAVE_WINDOW_SYSTEM */
7783 /***********************************************************************
7784 Menu Bars
7785 ***********************************************************************/
7788 /* Prepare for redisplay by updating menu-bar item lists when
7789 appropriate. This can call eval. */
7791 void
7792 prepare_menu_bars ()
7794 int all_windows;
7795 struct gcpro gcpro1, gcpro2;
7796 struct frame *f;
7797 Lisp_Object tooltip_frame;
7799 #ifdef HAVE_WINDOW_SYSTEM
7800 tooltip_frame = tip_frame;
7801 #else
7802 tooltip_frame = Qnil;
7803 #endif
7805 /* Update all frame titles based on their buffer names, etc. We do
7806 this before the menu bars so that the buffer-menu will show the
7807 up-to-date frame titles. */
7808 #ifdef HAVE_WINDOW_SYSTEM
7809 if (windows_or_buffers_changed || update_mode_lines)
7811 Lisp_Object tail, frame;
7813 FOR_EACH_FRAME (tail, frame)
7815 f = XFRAME (frame);
7816 if (!EQ (frame, tooltip_frame)
7817 && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)))
7818 x_consider_frame_title (frame);
7821 #endif /* HAVE_WINDOW_SYSTEM */
7823 /* Update the menu bar item lists, if appropriate. This has to be
7824 done before any actual redisplay or generation of display lines. */
7825 all_windows = (update_mode_lines
7826 || buffer_shared > 1
7827 || windows_or_buffers_changed);
7828 if (all_windows)
7830 Lisp_Object tail, frame;
7831 int count = SPECPDL_INDEX ();
7833 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
7835 FOR_EACH_FRAME (tail, frame)
7837 f = XFRAME (frame);
7839 /* Ignore tooltip frame. */
7840 if (EQ (frame, tooltip_frame))
7841 continue;
7843 /* If a window on this frame changed size, report that to
7844 the user and clear the size-change flag. */
7845 if (FRAME_WINDOW_SIZES_CHANGED (f))
7847 Lisp_Object functions;
7849 /* Clear flag first in case we get an error below. */
7850 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
7851 functions = Vwindow_size_change_functions;
7852 GCPRO2 (tail, functions);
7854 while (CONSP (functions))
7856 call1 (XCAR (functions), frame);
7857 functions = XCDR (functions);
7859 UNGCPRO;
7862 GCPRO1 (tail);
7863 update_menu_bar (f, 0);
7864 #ifdef HAVE_WINDOW_SYSTEM
7865 update_tool_bar (f, 0);
7866 #endif
7867 UNGCPRO;
7870 unbind_to (count, Qnil);
7872 else
7874 struct frame *sf = SELECTED_FRAME ();
7875 update_menu_bar (sf, 1);
7876 #ifdef HAVE_WINDOW_SYSTEM
7877 update_tool_bar (sf, 1);
7878 #endif
7881 /* Motif needs this. See comment in xmenu.c. Turn it off when
7882 pending_menu_activation is not defined. */
7883 #ifdef USE_X_TOOLKIT
7884 pending_menu_activation = 0;
7885 #endif
7889 /* Update the menu bar item list for frame F. This has to be done
7890 before we start to fill in any display lines, because it can call
7891 eval.
7893 If SAVE_MATCH_DATA is non-zero, we must save and restore it here. */
7895 static void
7896 update_menu_bar (f, save_match_data)
7897 struct frame *f;
7898 int save_match_data;
7900 Lisp_Object window;
7901 register struct window *w;
7903 /* If called recursively during a menu update, do nothing. This can
7904 happen when, for instance, an activate-menubar-hook causes a
7905 redisplay. */
7906 if (inhibit_menubar_update)
7907 return;
7909 window = FRAME_SELECTED_WINDOW (f);
7910 w = XWINDOW (window);
7912 #if 0 /* The if statement below this if statement used to include the
7913 condition !NILP (w->update_mode_line), rather than using
7914 update_mode_lines directly, and this if statement may have
7915 been added to make that condition work. Now the if
7916 statement below matches its comment, this isn't needed. */
7917 if (update_mode_lines)
7918 w->update_mode_line = Qt;
7919 #endif
7921 if (FRAME_WINDOW_P (f)
7923 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
7924 || defined (USE_GTK)
7925 FRAME_EXTERNAL_MENU_BAR (f)
7926 #else
7927 FRAME_MENU_BAR_LINES (f) > 0
7928 #endif
7929 : FRAME_MENU_BAR_LINES (f) > 0)
7931 /* If the user has switched buffers or windows, we need to
7932 recompute to reflect the new bindings. But we'll
7933 recompute when update_mode_lines is set too; that means
7934 that people can use force-mode-line-update to request
7935 that the menu bar be recomputed. The adverse effect on
7936 the rest of the redisplay algorithm is about the same as
7937 windows_or_buffers_changed anyway. */
7938 if (windows_or_buffers_changed
7939 /* This used to test w->update_mode_line, but we believe
7940 there is no need to recompute the menu in that case. */
7941 || update_mode_lines
7942 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
7943 < BUF_MODIFF (XBUFFER (w->buffer)))
7944 != !NILP (w->last_had_star))
7945 || ((!NILP (Vtransient_mark_mode)
7946 && !NILP (XBUFFER (w->buffer)->mark_active))
7947 != !NILP (w->region_showing)))
7949 struct buffer *prev = current_buffer;
7950 int count = SPECPDL_INDEX ();
7952 specbind (Qinhibit_menubar_update, Qt);
7954 set_buffer_internal_1 (XBUFFER (w->buffer));
7955 if (save_match_data)
7956 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
7957 if (NILP (Voverriding_local_map_menu_flag))
7959 specbind (Qoverriding_terminal_local_map, Qnil);
7960 specbind (Qoverriding_local_map, Qnil);
7963 /* Run the Lucid hook. */
7964 safe_run_hooks (Qactivate_menubar_hook);
7966 /* If it has changed current-menubar from previous value,
7967 really recompute the menu-bar from the value. */
7968 if (! NILP (Vlucid_menu_bar_dirty_flag))
7969 call0 (Qrecompute_lucid_menubar);
7971 safe_run_hooks (Qmenu_bar_update_hook);
7972 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
7974 /* Redisplay the menu bar in case we changed it. */
7975 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
7976 || defined (USE_GTK)
7977 if (FRAME_WINDOW_P (f)
7978 #if defined (MAC_OS)
7979 /* All frames on Mac OS share the same menubar. So only the
7980 selected frame should be allowed to set it. */
7981 && f == SELECTED_FRAME ()
7982 #endif
7984 set_frame_menubar (f, 0, 0);
7985 else
7986 /* On a terminal screen, the menu bar is an ordinary screen
7987 line, and this makes it get updated. */
7988 w->update_mode_line = Qt;
7989 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
7990 /* In the non-toolkit version, the menu bar is an ordinary screen
7991 line, and this makes it get updated. */
7992 w->update_mode_line = Qt;
7993 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
7995 unbind_to (count, Qnil);
7996 set_buffer_internal_1 (prev);
8003 /***********************************************************************
8004 Output Cursor
8005 ***********************************************************************/
8007 #ifdef HAVE_WINDOW_SYSTEM
8009 /* EXPORT:
8010 Nominal cursor position -- where to draw output.
8011 HPOS and VPOS are window relative glyph matrix coordinates.
8012 X and Y are window relative pixel coordinates. */
8014 struct cursor_pos output_cursor;
8017 /* EXPORT:
8018 Set the global variable output_cursor to CURSOR. All cursor
8019 positions are relative to updated_window. */
8021 void
8022 set_output_cursor (cursor)
8023 struct cursor_pos *cursor;
8025 output_cursor.hpos = cursor->hpos;
8026 output_cursor.vpos = cursor->vpos;
8027 output_cursor.x = cursor->x;
8028 output_cursor.y = cursor->y;
8032 /* EXPORT for RIF:
8033 Set a nominal cursor position.
8035 HPOS and VPOS are column/row positions in a window glyph matrix. X
8036 and Y are window text area relative pixel positions.
8038 If this is done during an update, updated_window will contain the
8039 window that is being updated and the position is the future output
8040 cursor position for that window. If updated_window is null, use
8041 selected_window and display the cursor at the given position. */
8043 void
8044 x_cursor_to (vpos, hpos, y, x)
8045 int vpos, hpos, y, x;
8047 struct window *w;
8049 /* If updated_window is not set, work on selected_window. */
8050 if (updated_window)
8051 w = updated_window;
8052 else
8053 w = XWINDOW (selected_window);
8055 /* Set the output cursor. */
8056 output_cursor.hpos = hpos;
8057 output_cursor.vpos = vpos;
8058 output_cursor.x = x;
8059 output_cursor.y = y;
8061 /* If not called as part of an update, really display the cursor.
8062 This will also set the cursor position of W. */
8063 if (updated_window == NULL)
8065 BLOCK_INPUT;
8066 display_and_set_cursor (w, 1, hpos, vpos, x, y);
8067 if (rif->flush_display_optional)
8068 rif->flush_display_optional (SELECTED_FRAME ());
8069 UNBLOCK_INPUT;
8073 #endif /* HAVE_WINDOW_SYSTEM */
8076 /***********************************************************************
8077 Tool-bars
8078 ***********************************************************************/
8080 #ifdef HAVE_WINDOW_SYSTEM
8082 /* Where the mouse was last time we reported a mouse event. */
8084 FRAME_PTR last_mouse_frame;
8086 /* Tool-bar item index of the item on which a mouse button was pressed
8087 or -1. */
8089 int last_tool_bar_item;
8092 /* Update the tool-bar item list for frame F. This has to be done
8093 before we start to fill in any display lines. Called from
8094 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
8095 and restore it here. */
8097 static void
8098 update_tool_bar (f, save_match_data)
8099 struct frame *f;
8100 int save_match_data;
8102 #ifdef USE_GTK
8103 int do_update = FRAME_EXTERNAL_TOOL_BAR(f);
8104 #else
8105 int do_update = WINDOWP (f->tool_bar_window)
8106 && XFASTINT (XWINDOW (f->tool_bar_window)->height) > 0;
8107 #endif
8109 if (do_update)
8111 Lisp_Object window;
8112 struct window *w;
8114 window = FRAME_SELECTED_WINDOW (f);
8115 w = XWINDOW (window);
8117 /* If the user has switched buffers or windows, we need to
8118 recompute to reflect the new bindings. But we'll
8119 recompute when update_mode_lines is set too; that means
8120 that people can use force-mode-line-update to request
8121 that the menu bar be recomputed. The adverse effect on
8122 the rest of the redisplay algorithm is about the same as
8123 windows_or_buffers_changed anyway. */
8124 if (windows_or_buffers_changed
8125 || !NILP (w->update_mode_line)
8126 || update_mode_lines
8127 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
8128 < BUF_MODIFF (XBUFFER (w->buffer)))
8129 != !NILP (w->last_had_star))
8130 || ((!NILP (Vtransient_mark_mode)
8131 && !NILP (XBUFFER (w->buffer)->mark_active))
8132 != !NILP (w->region_showing)))
8134 struct buffer *prev = current_buffer;
8135 int count = SPECPDL_INDEX ();
8136 Lisp_Object old_tool_bar;
8137 struct gcpro gcpro1;
8139 /* Set current_buffer to the buffer of the selected
8140 window of the frame, so that we get the right local
8141 keymaps. */
8142 set_buffer_internal_1 (XBUFFER (w->buffer));
8144 /* Save match data, if we must. */
8145 if (save_match_data)
8146 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
8148 /* Make sure that we don't accidentally use bogus keymaps. */
8149 if (NILP (Voverriding_local_map_menu_flag))
8151 specbind (Qoverriding_terminal_local_map, Qnil);
8152 specbind (Qoverriding_local_map, Qnil);
8155 old_tool_bar = f->tool_bar_items;
8156 GCPRO1 (old_tool_bar);
8158 /* Build desired tool-bar items from keymaps. */
8159 BLOCK_INPUT;
8160 f->tool_bar_items
8161 = tool_bar_items (f->tool_bar_items, &f->n_tool_bar_items);
8162 UNBLOCK_INPUT;
8164 /* Redisplay the tool-bar if we changed it. */
8165 if (! NILP (Fequal (old_tool_bar, f->tool_bar_items)))
8166 w->update_mode_line = Qt;
8168 unbind_to (count, Qnil);
8169 set_buffer_internal_1 (prev);
8175 /* Set F->desired_tool_bar_string to a Lisp string representing frame
8176 F's desired tool-bar contents. F->tool_bar_items must have
8177 been set up previously by calling prepare_menu_bars. */
8179 static void
8180 build_desired_tool_bar_string (f)
8181 struct frame *f;
8183 int i, size, size_needed;
8184 struct gcpro gcpro1, gcpro2, gcpro3;
8185 Lisp_Object image, plist, props;
8187 image = plist = props = Qnil;
8188 GCPRO3 (image, plist, props);
8190 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
8191 Otherwise, make a new string. */
8193 /* The size of the string we might be able to reuse. */
8194 size = (STRINGP (f->desired_tool_bar_string)
8195 ? SCHARS (f->desired_tool_bar_string)
8196 : 0);
8198 /* We need one space in the string for each image. */
8199 size_needed = f->n_tool_bar_items;
8201 /* Reuse f->desired_tool_bar_string, if possible. */
8202 if (size < size_needed || NILP (f->desired_tool_bar_string))
8203 f->desired_tool_bar_string = Fmake_string (make_number (size_needed),
8204 make_number (' '));
8205 else
8207 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
8208 Fremove_text_properties (make_number (0), make_number (size),
8209 props, f->desired_tool_bar_string);
8212 /* Put a `display' property on the string for the images to display,
8213 put a `menu_item' property on tool-bar items with a value that
8214 is the index of the item in F's tool-bar item vector. */
8215 for (i = 0; i < f->n_tool_bar_items; ++i)
8217 #define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
8219 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
8220 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
8221 int hmargin, vmargin, relief, idx, end;
8222 extern Lisp_Object QCrelief, QCmargin, QCconversion, Qimage;
8224 /* If image is a vector, choose the image according to the
8225 button state. */
8226 image = PROP (TOOL_BAR_ITEM_IMAGES);
8227 if (VECTORP (image))
8229 if (enabled_p)
8230 idx = (selected_p
8231 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
8232 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
8233 else
8234 idx = (selected_p
8235 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
8236 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
8238 xassert (ASIZE (image) >= idx);
8239 image = AREF (image, idx);
8241 else
8242 idx = -1;
8244 /* Ignore invalid image specifications. */
8245 if (!valid_image_p (image))
8246 continue;
8248 /* Display the tool-bar button pressed, or depressed. */
8249 plist = Fcopy_sequence (XCDR (image));
8251 /* Compute margin and relief to draw. */
8252 relief = (tool_bar_button_relief >= 0
8253 ? tool_bar_button_relief
8254 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
8255 hmargin = vmargin = relief;
8257 if (INTEGERP (Vtool_bar_button_margin)
8258 && XINT (Vtool_bar_button_margin) > 0)
8260 hmargin += XFASTINT (Vtool_bar_button_margin);
8261 vmargin += XFASTINT (Vtool_bar_button_margin);
8263 else if (CONSP (Vtool_bar_button_margin))
8265 if (INTEGERP (XCAR (Vtool_bar_button_margin))
8266 && XINT (XCAR (Vtool_bar_button_margin)) > 0)
8267 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
8269 if (INTEGERP (XCDR (Vtool_bar_button_margin))
8270 && XINT (XCDR (Vtool_bar_button_margin)) > 0)
8271 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
8274 if (auto_raise_tool_bar_buttons_p)
8276 /* Add a `:relief' property to the image spec if the item is
8277 selected. */
8278 if (selected_p)
8280 plist = Fplist_put (plist, QCrelief, make_number (-relief));
8281 hmargin -= relief;
8282 vmargin -= relief;
8285 else
8287 /* If image is selected, display it pressed, i.e. with a
8288 negative relief. If it's not selected, display it with a
8289 raised relief. */
8290 plist = Fplist_put (plist, QCrelief,
8291 (selected_p
8292 ? make_number (-relief)
8293 : make_number (relief)));
8294 hmargin -= relief;
8295 vmargin -= relief;
8298 /* Put a margin around the image. */
8299 if (hmargin || vmargin)
8301 if (hmargin == vmargin)
8302 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
8303 else
8304 plist = Fplist_put (plist, QCmargin,
8305 Fcons (make_number (hmargin),
8306 make_number (vmargin)));
8309 /* If button is not enabled, and we don't have special images
8310 for the disabled state, make the image appear disabled by
8311 applying an appropriate algorithm to it. */
8312 if (!enabled_p && idx < 0)
8313 plist = Fplist_put (plist, QCconversion, Qdisabled);
8315 /* Put a `display' text property on the string for the image to
8316 display. Put a `menu-item' property on the string that gives
8317 the start of this item's properties in the tool-bar items
8318 vector. */
8319 image = Fcons (Qimage, plist);
8320 props = list4 (Qdisplay, image,
8321 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS));
8323 /* Let the last image hide all remaining spaces in the tool bar
8324 string. The string can be longer than needed when we reuse a
8325 previous string. */
8326 if (i + 1 == f->n_tool_bar_items)
8327 end = SCHARS (f->desired_tool_bar_string);
8328 else
8329 end = i + 1;
8330 Fadd_text_properties (make_number (i), make_number (end),
8331 props, f->desired_tool_bar_string);
8332 #undef PROP
8335 UNGCPRO;
8339 /* Display one line of the tool-bar of frame IT->f. */
8341 static void
8342 display_tool_bar_line (it)
8343 struct it *it;
8345 struct glyph_row *row = it->glyph_row;
8346 int max_x = it->last_visible_x;
8347 struct glyph *last;
8349 prepare_desired_row (row);
8350 row->y = it->current_y;
8352 /* Note that this isn't made use of if the face hasn't a box,
8353 so there's no need to check the face here. */
8354 it->start_of_box_run_p = 1;
8356 while (it->current_x < max_x)
8358 int x_before, x, n_glyphs_before, i, nglyphs;
8360 /* Get the next display element. */
8361 if (!get_next_display_element (it))
8362 break;
8364 /* Produce glyphs. */
8365 x_before = it->current_x;
8366 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
8367 PRODUCE_GLYPHS (it);
8369 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
8370 i = 0;
8371 x = x_before;
8372 while (i < nglyphs)
8374 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
8376 if (x + glyph->pixel_width > max_x)
8378 /* Glyph doesn't fit on line. */
8379 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
8380 it->current_x = x;
8381 goto out;
8384 ++it->hpos;
8385 x += glyph->pixel_width;
8386 ++i;
8389 /* Stop at line ends. */
8390 if (ITERATOR_AT_END_OF_LINE_P (it))
8391 break;
8393 set_iterator_to_next (it, 1);
8396 out:;
8398 row->displays_text_p = row->used[TEXT_AREA] != 0;
8399 extend_face_to_end_of_line (it);
8400 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
8401 last->right_box_line_p = 1;
8402 if (last == row->glyphs[TEXT_AREA])
8403 last->left_box_line_p = 1;
8404 compute_line_metrics (it);
8406 /* If line is empty, make it occupy the rest of the tool-bar. */
8407 if (!row->displays_text_p)
8409 row->height = row->phys_height = it->last_visible_y - row->y;
8410 row->ascent = row->phys_ascent = 0;
8413 row->full_width_p = 1;
8414 row->continued_p = 0;
8415 row->truncated_on_left_p = 0;
8416 row->truncated_on_right_p = 0;
8418 it->current_x = it->hpos = 0;
8419 it->current_y += row->height;
8420 ++it->vpos;
8421 ++it->glyph_row;
8425 /* Value is the number of screen lines needed to make all tool-bar
8426 items of frame F visible. */
8428 static int
8429 tool_bar_lines_needed (f)
8430 struct frame *f;
8432 struct window *w = XWINDOW (f->tool_bar_window);
8433 struct it it;
8435 /* Initialize an iterator for iteration over
8436 F->desired_tool_bar_string in the tool-bar window of frame F. */
8437 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
8438 it.first_visible_x = 0;
8439 it.last_visible_x = FRAME_WINDOW_WIDTH (f) * CANON_X_UNIT (f);
8440 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
8442 while (!ITERATOR_AT_END_P (&it))
8444 it.glyph_row = w->desired_matrix->rows;
8445 clear_glyph_row (it.glyph_row);
8446 display_tool_bar_line (&it);
8449 return (it.current_y + CANON_Y_UNIT (f) - 1) / CANON_Y_UNIT (f);
8453 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
8454 0, 1, 0,
8455 doc: /* Return the number of lines occupied by the tool bar of FRAME. */)
8456 (frame)
8457 Lisp_Object frame;
8459 struct frame *f;
8460 struct window *w;
8461 int nlines = 0;
8463 if (NILP (frame))
8464 frame = selected_frame;
8465 else
8466 CHECK_FRAME (frame);
8467 f = XFRAME (frame);
8469 if (WINDOWP (f->tool_bar_window)
8470 || (w = XWINDOW (f->tool_bar_window),
8471 XFASTINT (w->height) > 0))
8473 update_tool_bar (f, 1);
8474 if (f->n_tool_bar_items)
8476 build_desired_tool_bar_string (f);
8477 nlines = tool_bar_lines_needed (f);
8481 return make_number (nlines);
8485 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
8486 height should be changed. */
8488 static int
8489 redisplay_tool_bar (f)
8490 struct frame *f;
8492 struct window *w;
8493 struct it it;
8494 struct glyph_row *row;
8495 int change_height_p = 0;
8497 #ifdef USE_GTK
8498 if (FRAME_EXTERNAL_TOOL_BAR(f))
8499 update_frame_tool_bar (f);
8500 return 0;
8501 #endif
8503 /* If frame hasn't a tool-bar window or if it is zero-height, don't
8504 do anything. This means you must start with tool-bar-lines
8505 non-zero to get the auto-sizing effect. Or in other words, you
8506 can turn off tool-bars by specifying tool-bar-lines zero. */
8507 if (!WINDOWP (f->tool_bar_window)
8508 || (w = XWINDOW (f->tool_bar_window),
8509 XFASTINT (w->height) == 0))
8510 return 0;
8512 /* Set up an iterator for the tool-bar window. */
8513 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
8514 it.first_visible_x = 0;
8515 it.last_visible_x = FRAME_WINDOW_WIDTH (f) * CANON_X_UNIT (f);
8516 row = it.glyph_row;
8518 /* Build a string that represents the contents of the tool-bar. */
8519 build_desired_tool_bar_string (f);
8520 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
8522 /* Display as many lines as needed to display all tool-bar items. */
8523 while (it.current_y < it.last_visible_y)
8524 display_tool_bar_line (&it);
8526 /* It doesn't make much sense to try scrolling in the tool-bar
8527 window, so don't do it. */
8528 w->desired_matrix->no_scrolling_p = 1;
8529 w->must_be_updated_p = 1;
8531 if (auto_resize_tool_bars_p)
8533 int nlines;
8535 /* If we couldn't display everything, change the tool-bar's
8536 height. */
8537 if (IT_STRING_CHARPOS (it) < it.end_charpos)
8538 change_height_p = 1;
8540 /* If there are blank lines at the end, except for a partially
8541 visible blank line at the end that is smaller than
8542 CANON_Y_UNIT, change the tool-bar's height. */
8543 row = it.glyph_row - 1;
8544 if (!row->displays_text_p
8545 && row->height >= CANON_Y_UNIT (f))
8546 change_height_p = 1;
8548 /* If row displays tool-bar items, but is partially visible,
8549 change the tool-bar's height. */
8550 if (row->displays_text_p
8551 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y)
8552 change_height_p = 1;
8554 /* Resize windows as needed by changing the `tool-bar-lines'
8555 frame parameter. */
8556 if (change_height_p
8557 && (nlines = tool_bar_lines_needed (f),
8558 nlines != XFASTINT (w->height)))
8560 extern Lisp_Object Qtool_bar_lines;
8561 Lisp_Object frame;
8562 int old_height = XFASTINT (w->height);
8564 XSETFRAME (frame, f);
8565 clear_glyph_matrix (w->desired_matrix);
8566 Fmodify_frame_parameters (frame,
8567 Fcons (Fcons (Qtool_bar_lines,
8568 make_number (nlines)),
8569 Qnil));
8570 if (XFASTINT (w->height) != old_height)
8571 fonts_changed_p = 1;
8575 return change_height_p;
8579 /* Get information about the tool-bar item which is displayed in GLYPH
8580 on frame F. Return in *PROP_IDX the index where tool-bar item
8581 properties start in F->tool_bar_items. Value is zero if
8582 GLYPH doesn't display a tool-bar item. */
8584 static int
8585 tool_bar_item_info (f, glyph, prop_idx)
8586 struct frame *f;
8587 struct glyph *glyph;
8588 int *prop_idx;
8590 Lisp_Object prop;
8591 int success_p;
8592 int charpos;
8594 /* This function can be called asynchronously, which means we must
8595 exclude any possibility that Fget_text_property signals an
8596 error. */
8597 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
8598 charpos = max (0, charpos);
8600 /* Get the text property `menu-item' at pos. The value of that
8601 property is the start index of this item's properties in
8602 F->tool_bar_items. */
8603 prop = Fget_text_property (make_number (charpos),
8604 Qmenu_item, f->current_tool_bar_string);
8605 if (INTEGERP (prop))
8607 *prop_idx = XINT (prop);
8608 success_p = 1;
8610 else
8611 success_p = 0;
8613 return success_p;
8617 /* Get information about the tool-bar item at position X/Y on frame F.
8618 Return in *GLYPH a pointer to the glyph of the tool-bar item in
8619 the current matrix of the tool-bar window of F, or NULL if not
8620 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
8621 item in F->tool_bar_items. Value is
8623 -1 if X/Y is not on a tool-bar item
8624 0 if X/Y is on the same item that was highlighted before.
8625 1 otherwise. */
8627 static int
8628 get_tool_bar_item (f, x, y, glyph, hpos, vpos, prop_idx)
8629 struct frame *f;
8630 int x, y;
8631 struct glyph **glyph;
8632 int *hpos, *vpos, *prop_idx;
8634 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
8635 struct window *w = XWINDOW (f->tool_bar_window);
8636 int area;
8638 /* Find the glyph under X/Y. */
8639 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, &area, 0);
8640 if (*glyph == NULL)
8641 return -1;
8643 /* Get the start of this tool-bar item's properties in
8644 f->tool_bar_items. */
8645 if (!tool_bar_item_info (f, *glyph, prop_idx))
8646 return -1;
8648 /* Is mouse on the highlighted item? */
8649 if (EQ (f->tool_bar_window, dpyinfo->mouse_face_window)
8650 && *vpos >= dpyinfo->mouse_face_beg_row
8651 && *vpos <= dpyinfo->mouse_face_end_row
8652 && (*vpos > dpyinfo->mouse_face_beg_row
8653 || *hpos >= dpyinfo->mouse_face_beg_col)
8654 && (*vpos < dpyinfo->mouse_face_end_row
8655 || *hpos < dpyinfo->mouse_face_end_col
8656 || dpyinfo->mouse_face_past_end))
8657 return 0;
8659 return 1;
8663 /* EXPORT:
8664 Handle mouse button event on the tool-bar of frame F, at
8665 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
8666 0 for button release. MODIFIERS is event modifiers for button
8667 release. */
8669 void
8670 handle_tool_bar_click (f, x, y, down_p, modifiers)
8671 struct frame *f;
8672 int x, y, down_p;
8673 unsigned int modifiers;
8675 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
8676 struct window *w = XWINDOW (f->tool_bar_window);
8677 int hpos, vpos, prop_idx;
8678 struct glyph *glyph;
8679 Lisp_Object enabled_p;
8681 /* If not on the highlighted tool-bar item, return. */
8682 frame_to_window_pixel_xy (w, &x, &y);
8683 if (get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0)
8684 return;
8686 /* If item is disabled, do nothing. */
8687 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
8688 if (NILP (enabled_p))
8689 return;
8691 if (down_p)
8693 /* Show item in pressed state. */
8694 show_mouse_face (dpyinfo, DRAW_IMAGE_SUNKEN);
8695 dpyinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN;
8696 last_tool_bar_item = prop_idx;
8698 else
8700 Lisp_Object key, frame;
8701 struct input_event event;
8703 /* Show item in released state. */
8704 show_mouse_face (dpyinfo, DRAW_IMAGE_RAISED);
8705 dpyinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
8707 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
8709 XSETFRAME (frame, f);
8710 event.kind = TOOL_BAR_EVENT;
8711 event.frame_or_window = frame;
8712 event.arg = frame;
8713 kbd_buffer_store_event (&event);
8715 event.kind = TOOL_BAR_EVENT;
8716 event.frame_or_window = frame;
8717 event.arg = key;
8718 event.modifiers = modifiers;
8719 kbd_buffer_store_event (&event);
8720 last_tool_bar_item = -1;
8725 /* Possibly highlight a tool-bar item on frame F when mouse moves to
8726 tool-bar window-relative coordinates X/Y. Called from
8727 note_mouse_highlight. */
8729 static void
8730 note_tool_bar_highlight (f, x, y)
8731 struct frame *f;
8732 int x, y;
8734 Lisp_Object window = f->tool_bar_window;
8735 struct window *w = XWINDOW (window);
8736 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
8737 int hpos, vpos;
8738 struct glyph *glyph;
8739 struct glyph_row *row;
8740 int i;
8741 Lisp_Object enabled_p;
8742 int prop_idx;
8743 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
8744 int mouse_down_p, rc;
8746 /* Function note_mouse_highlight is called with negative x(y
8747 values when mouse moves outside of the frame. */
8748 if (x <= 0 || y <= 0)
8750 clear_mouse_face (dpyinfo);
8751 return;
8754 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
8755 if (rc < 0)
8757 /* Not on tool-bar item. */
8758 clear_mouse_face (dpyinfo);
8759 return;
8761 else if (rc == 0)
8762 /* On same tool-bar item as before. */
8763 goto set_help_echo;
8765 clear_mouse_face (dpyinfo);
8767 /* Mouse is down, but on different tool-bar item? */
8768 mouse_down_p = (dpyinfo->grabbed
8769 && f == last_mouse_frame
8770 && FRAME_LIVE_P (f));
8771 if (mouse_down_p
8772 && last_tool_bar_item != prop_idx)
8773 return;
8775 dpyinfo->mouse_face_image_state = DRAW_NORMAL_TEXT;
8776 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
8778 /* If tool-bar item is not enabled, don't highlight it. */
8779 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
8780 if (!NILP (enabled_p))
8782 /* Compute the x-position of the glyph. In front and past the
8783 image is a space. We include this is the highlighted area. */
8784 row = MATRIX_ROW (w->current_matrix, vpos);
8785 for (i = x = 0; i < hpos; ++i)
8786 x += row->glyphs[TEXT_AREA][i].pixel_width;
8788 /* Record this as the current active region. */
8789 dpyinfo->mouse_face_beg_col = hpos;
8790 dpyinfo->mouse_face_beg_row = vpos;
8791 dpyinfo->mouse_face_beg_x = x;
8792 dpyinfo->mouse_face_beg_y = row->y;
8793 dpyinfo->mouse_face_past_end = 0;
8795 dpyinfo->mouse_face_end_col = hpos + 1;
8796 dpyinfo->mouse_face_end_row = vpos;
8797 dpyinfo->mouse_face_end_x = x + glyph->pixel_width;
8798 dpyinfo->mouse_face_end_y = row->y;
8799 dpyinfo->mouse_face_window = window;
8800 dpyinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
8802 /* Display it as active. */
8803 show_mouse_face (dpyinfo, draw);
8804 dpyinfo->mouse_face_image_state = draw;
8807 set_help_echo:
8809 /* Set help_echo_string to a help string to display for this tool-bar item.
8810 XTread_socket does the rest. */
8811 help_echo_object = help_echo_window = Qnil;
8812 help_echo_pos = -1;
8813 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
8814 if (NILP (help_echo_string))
8815 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
8818 #endif /* HAVE_WINDOW_SYSTEM */
8822 /***********************************************************************
8823 Fringes
8824 ***********************************************************************/
8826 #ifdef HAVE_WINDOW_SYSTEM
8828 /* An arrow like this: `<-'. */
8829 static unsigned char left_bits[] = {
8830 0x18, 0x0c, 0x06, 0x3f, 0x3f, 0x06, 0x0c, 0x18};
8832 /* Right truncation arrow bitmap `->'. */
8833 static unsigned char right_bits[] = {
8834 0x18, 0x30, 0x60, 0xfc, 0xfc, 0x60, 0x30, 0x18};
8836 /* Marker for continued lines. */
8837 static unsigned char continued_bits[] = {
8838 0x3c, 0x7c, 0xc0, 0xe4, 0xfc, 0x7c, 0x3c, 0x7c};
8840 /* Marker for continuation lines. */
8841 static unsigned char continuation_bits[] = {
8842 0x3c, 0x3e, 0x03, 0x27, 0x3f, 0x3e, 0x3c, 0x3e};
8844 /* Overlay arrow bitmap. A triangular arrow. */
8845 static unsigned char ov_bits[] = {
8846 0x03, 0x0f, 0x1f, 0x3f, 0x3f, 0x1f, 0x0f, 0x03};
8848 /* Bitmap drawn to indicate lines not displaying text if
8849 `indicate-empty-lines' is non-nil. */
8850 static unsigned char zv_bits[] = {
8851 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
8852 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
8853 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
8854 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
8855 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
8856 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
8857 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
8858 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00};
8860 struct fringe_bitmap fringe_bitmaps[MAX_FRINGE_BITMAPS] =
8862 { 0, 0, 0, NULL /* NO_FRINGE_BITMAP */ },
8863 { 8, sizeof (left_bits), 0, left_bits },
8864 { 8, sizeof (right_bits), 0, right_bits },
8865 { 8, sizeof (continued_bits), 0, continued_bits },
8866 { 8, sizeof (continuation_bits), 0, continuation_bits },
8867 { 8, sizeof (ov_bits), 0, ov_bits },
8868 { 8, sizeof (zv_bits), 3, zv_bits }
8872 /* Draw the bitmap WHICH in one of the left or right fringes of
8873 window W. ROW is the glyph row for which to display the bitmap; it
8874 determines the vertical position at which the bitmap has to be
8875 drawn. */
8877 static void
8878 draw_fringe_bitmap (w, row, which, left_p)
8879 struct window *w;
8880 struct glyph_row *row;
8881 enum fringe_bitmap_type which;
8882 int left_p;
8884 struct frame *f = XFRAME (WINDOW_FRAME (w));
8885 struct draw_fringe_bitmap_params p;
8887 /* Convert row to frame coordinates. */
8888 p.y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
8890 p.which = which;
8891 p.wd = fringe_bitmaps[which].width;
8893 p.h = fringe_bitmaps[which].height;
8894 p.dh = (fringe_bitmaps[which].period
8895 ? (p.y % fringe_bitmaps[which].period)
8896 : 0);
8897 p.h -= p.dh;
8898 /* Clip bitmap if too high. */
8899 if (p.h > row->height)
8900 p.h = row->height;
8902 p.face = FACE_FROM_ID (f, FRINGE_FACE_ID);
8903 PREPARE_FACE_FOR_DISPLAY (f, p.face);
8905 /* Clear left fringe if no bitmap to draw or if bitmap doesn't fill
8906 the fringe. */
8907 p.bx = -1;
8908 if (left_p)
8910 if (p.wd > FRAME_X_LEFT_FRINGE_WIDTH (f))
8911 p.wd = FRAME_X_LEFT_FRINGE_WIDTH (f);
8912 p.x = (WINDOW_TO_FRAME_PIXEL_X (w, 0)
8913 - p.wd
8914 - (FRAME_X_LEFT_FRINGE_WIDTH (f) - p.wd) / 2);
8915 if (p.wd < FRAME_X_LEFT_FRINGE_WIDTH (f) || row->height > p.h)
8917 /* If W has a vertical border to its left, don't draw over it. */
8918 int border = ((XFASTINT (w->left) > 0
8919 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f))
8920 ? 1 : 0);
8921 p.bx = (window_box_left (w, -1)
8922 - FRAME_X_LEFT_FRINGE_WIDTH (f)
8923 + border);
8924 p.nx = (FRAME_X_LEFT_FRINGE_WIDTH (f) - border);
8927 else
8929 if (p.wd > FRAME_X_RIGHT_FRINGE_WIDTH (f))
8930 p.wd = FRAME_X_RIGHT_FRINGE_WIDTH (f);
8931 p.x = (window_box_right (w, -1)
8932 + (FRAME_X_RIGHT_FRINGE_WIDTH (f) - p.wd) / 2);
8933 /* Clear right fringe if no bitmap to draw of if bitmap doesn't fill
8934 the fringe. */
8935 if (p.wd < FRAME_X_RIGHT_FRINGE_WIDTH (f) || row->height > p.h)
8937 p.bx = window_box_right (w, -1);
8938 p.nx = FRAME_X_RIGHT_FRINGE_WIDTH (f);
8942 if (p.bx >= 0)
8944 int header_line_height = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
8946 p.by = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, row->y));
8947 p.ny = row->visible_height;
8950 /* Adjust y to the offset in the row to start drawing the bitmap. */
8951 p.y += (row->height - p.h) / 2;
8953 rif->draw_fringe_bitmap (w, row, &p);
8956 /* Draw fringe bitmaps for glyph row ROW on window W. Call this
8957 function with input blocked. */
8959 void
8960 draw_row_fringe_bitmaps (w, row)
8961 struct window *w;
8962 struct glyph_row *row;
8964 struct frame *f = XFRAME (w->frame);
8965 enum fringe_bitmap_type bitmap;
8967 xassert (interrupt_input_blocked);
8969 /* If row is completely invisible, because of vscrolling, we
8970 don't have to draw anything. */
8971 if (row->visible_height <= 0)
8972 return;
8974 if (FRAME_X_LEFT_FRINGE_WIDTH (f) != 0)
8976 /* Decide which bitmap to draw in the left fringe. */
8977 if (row->overlay_arrow_p)
8978 bitmap = OVERLAY_ARROW_BITMAP;
8979 else if (row->truncated_on_left_p)
8980 bitmap = LEFT_TRUNCATION_BITMAP;
8981 else if (MATRIX_ROW_CONTINUATION_LINE_P (row))
8982 bitmap = CONTINUATION_LINE_BITMAP;
8983 else if (row->indicate_empty_line_p)
8984 bitmap = ZV_LINE_BITMAP;
8985 else
8986 bitmap = NO_FRINGE_BITMAP;
8988 draw_fringe_bitmap (w, row, bitmap, 1);
8991 if (FRAME_X_RIGHT_FRINGE_WIDTH (f) != 0)
8993 /* Decide which bitmap to draw in the right fringe. */
8994 if (row->truncated_on_right_p)
8995 bitmap = RIGHT_TRUNCATION_BITMAP;
8996 else if (row->continued_p)
8997 bitmap = CONTINUED_LINE_BITMAP;
8998 else if (row->indicate_empty_line_p && FRAME_X_LEFT_FRINGE_WIDTH (f) == 0)
8999 bitmap = ZV_LINE_BITMAP;
9000 else
9001 bitmap = NO_FRINGE_BITMAP;
9003 draw_fringe_bitmap (w, row, bitmap, 0);
9008 /* Compute actual fringe widths */
9010 void
9011 compute_fringe_widths (f, redraw)
9012 struct frame *f;
9013 int redraw;
9015 int o_left = FRAME_X_LEFT_FRINGE_WIDTH (f);
9016 int o_right = FRAME_X_RIGHT_FRINGE_WIDTH (f);
9017 int o_cols = FRAME_X_FRINGE_COLS (f);
9019 Lisp_Object left_fringe = Fassq (Qleft_fringe, f->param_alist);
9020 Lisp_Object right_fringe = Fassq (Qright_fringe, f->param_alist);
9021 int left_fringe_width, right_fringe_width;
9023 if (!NILP (left_fringe))
9024 left_fringe = Fcdr (left_fringe);
9025 if (!NILP (right_fringe))
9026 right_fringe = Fcdr (right_fringe);
9028 left_fringe_width = ((NILP (left_fringe) || !INTEGERP (left_fringe)) ? 8 :
9029 XINT (left_fringe));
9030 right_fringe_width = ((NILP (right_fringe) || !INTEGERP (right_fringe)) ? 8 :
9031 XINT (right_fringe));
9033 if (left_fringe_width || right_fringe_width)
9035 int left_wid = left_fringe_width >= 0 ? left_fringe_width : -left_fringe_width;
9036 int right_wid = right_fringe_width >= 0 ? right_fringe_width : -right_fringe_width;
9037 int conf_wid = left_wid + right_wid;
9038 int font_wid = FONT_WIDTH (FRAME_FONT (f));
9039 int cols = (left_wid + right_wid + font_wid-1) / font_wid;
9040 int real_wid = cols * font_wid;
9041 if (left_wid && right_wid)
9043 if (left_fringe_width < 0)
9045 /* Left fringe width is fixed, adjust right fringe if necessary */
9046 FRAME_X_LEFT_FRINGE_WIDTH (f) = left_wid;
9047 FRAME_X_RIGHT_FRINGE_WIDTH (f) = real_wid - left_wid;
9049 else if (right_fringe_width < 0)
9051 /* Right fringe width is fixed, adjust left fringe if necessary */
9052 FRAME_X_LEFT_FRINGE_WIDTH (f) = real_wid - right_wid;
9053 FRAME_X_RIGHT_FRINGE_WIDTH (f) = right_wid;
9055 else
9057 /* Adjust both fringes with an equal amount.
9058 Note that we are doing integer arithmetic here, so don't
9059 lose a pixel if the total width is an odd number. */
9060 int fill = real_wid - conf_wid;
9061 FRAME_X_LEFT_FRINGE_WIDTH (f) = left_wid + fill/2;
9062 FRAME_X_RIGHT_FRINGE_WIDTH (f) = right_wid + fill - fill/2;
9065 else if (left_fringe_width)
9067 FRAME_X_LEFT_FRINGE_WIDTH (f) = real_wid;
9068 FRAME_X_RIGHT_FRINGE_WIDTH (f) = 0;
9070 else
9072 FRAME_X_LEFT_FRINGE_WIDTH (f) = 0;
9073 FRAME_X_RIGHT_FRINGE_WIDTH (f) = real_wid;
9075 FRAME_X_FRINGE_COLS (f) = cols;
9076 FRAME_X_FRINGE_WIDTH (f) = real_wid;
9078 else
9080 FRAME_X_LEFT_FRINGE_WIDTH (f) = 0;
9081 FRAME_X_RIGHT_FRINGE_WIDTH (f) = 0;
9082 FRAME_X_FRINGE_COLS (f) = 0;
9083 FRAME_X_FRINGE_WIDTH (f) = 0;
9086 if (redraw && FRAME_VISIBLE_P (f))
9087 if (o_left != FRAME_X_LEFT_FRINGE_WIDTH (f) ||
9088 o_right != FRAME_X_RIGHT_FRINGE_WIDTH (f) ||
9089 o_cols != FRAME_X_FRINGE_COLS (f))
9090 redraw_frame (f);
9093 #endif /* HAVE_WINDOW_SYSTEM */
9097 /************************************************************************
9098 Horizontal scrolling
9099 ************************************************************************/
9101 static int hscroll_window_tree P_ ((Lisp_Object));
9102 static int hscroll_windows P_ ((Lisp_Object));
9104 /* For all leaf windows in the window tree rooted at WINDOW, set their
9105 hscroll value so that PT is (i) visible in the window, and (ii) so
9106 that it is not within a certain margin at the window's left and
9107 right border. Value is non-zero if any window's hscroll has been
9108 changed. */
9110 static int
9111 hscroll_window_tree (window)
9112 Lisp_Object window;
9114 int hscrolled_p = 0;
9115 int hscroll_relative_p = FLOATP (Vhscroll_step);
9116 int hscroll_step_abs = 0;
9117 double hscroll_step_rel = 0;
9119 if (hscroll_relative_p)
9121 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
9122 if (hscroll_step_rel < 0)
9124 hscroll_relative_p = 0;
9125 hscroll_step_abs = 0;
9128 else if (INTEGERP (Vhscroll_step))
9130 hscroll_step_abs = XINT (Vhscroll_step);
9131 if (hscroll_step_abs < 0)
9132 hscroll_step_abs = 0;
9134 else
9135 hscroll_step_abs = 0;
9137 while (WINDOWP (window))
9139 struct window *w = XWINDOW (window);
9141 if (WINDOWP (w->hchild))
9142 hscrolled_p |= hscroll_window_tree (w->hchild);
9143 else if (WINDOWP (w->vchild))
9144 hscrolled_p |= hscroll_window_tree (w->vchild);
9145 else if (w->cursor.vpos >= 0)
9147 int h_margin, text_area_x, text_area_y;
9148 int text_area_width, text_area_height;
9149 struct glyph_row *current_cursor_row
9150 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
9151 struct glyph_row *desired_cursor_row
9152 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
9153 struct glyph_row *cursor_row
9154 = (desired_cursor_row->enabled_p
9155 ? desired_cursor_row
9156 : current_cursor_row);
9158 window_box (w, TEXT_AREA, &text_area_x, &text_area_y,
9159 &text_area_width, &text_area_height);
9161 /* Scroll when cursor is inside this scroll margin. */
9162 h_margin = hscroll_margin * CANON_X_UNIT (XFRAME (w->frame));
9164 if ((XFASTINT (w->hscroll)
9165 && w->cursor.x <= h_margin)
9166 || (cursor_row->enabled_p
9167 && cursor_row->truncated_on_right_p
9168 && (w->cursor.x >= text_area_width - h_margin)))
9170 struct it it;
9171 int hscroll;
9172 struct buffer *saved_current_buffer;
9173 int pt;
9174 int wanted_x;
9176 /* Find point in a display of infinite width. */
9177 saved_current_buffer = current_buffer;
9178 current_buffer = XBUFFER (w->buffer);
9180 if (w == XWINDOW (selected_window))
9181 pt = BUF_PT (current_buffer);
9182 else
9184 pt = marker_position (w->pointm);
9185 pt = max (BEGV, pt);
9186 pt = min (ZV, pt);
9189 /* Move iterator to pt starting at cursor_row->start in
9190 a line with infinite width. */
9191 init_to_row_start (&it, w, cursor_row);
9192 it.last_visible_x = INFINITY;
9193 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
9194 current_buffer = saved_current_buffer;
9196 /* Position cursor in window. */
9197 if (!hscroll_relative_p && hscroll_step_abs == 0)
9198 hscroll = max (0, it.current_x - text_area_width / 2)
9199 / CANON_X_UNIT (it.f);
9200 else if (w->cursor.x >= text_area_width - h_margin)
9202 if (hscroll_relative_p)
9203 wanted_x = text_area_width * (1 - hscroll_step_rel)
9204 - h_margin;
9205 else
9206 wanted_x = text_area_width
9207 - hscroll_step_abs * CANON_X_UNIT (it.f)
9208 - h_margin;
9209 hscroll
9210 = max (0, it.current_x - wanted_x) / CANON_X_UNIT (it.f);
9212 else
9214 if (hscroll_relative_p)
9215 wanted_x = text_area_width * hscroll_step_rel
9216 + h_margin;
9217 else
9218 wanted_x = hscroll_step_abs * CANON_X_UNIT (it.f)
9219 + h_margin;
9220 hscroll
9221 = max (0, it.current_x - wanted_x) / CANON_X_UNIT (it.f);
9223 hscroll = max (hscroll, XFASTINT (w->min_hscroll));
9225 /* Don't call Fset_window_hscroll if value hasn't
9226 changed because it will prevent redisplay
9227 optimizations. */
9228 if (XFASTINT (w->hscroll) != hscroll)
9230 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
9231 w->hscroll = make_number (hscroll);
9232 hscrolled_p = 1;
9237 window = w->next;
9240 /* Value is non-zero if hscroll of any leaf window has been changed. */
9241 return hscrolled_p;
9245 /* Set hscroll so that cursor is visible and not inside horizontal
9246 scroll margins for all windows in the tree rooted at WINDOW. See
9247 also hscroll_window_tree above. Value is non-zero if any window's
9248 hscroll has been changed. If it has, desired matrices on the frame
9249 of WINDOW are cleared. */
9251 static int
9252 hscroll_windows (window)
9253 Lisp_Object window;
9255 int hscrolled_p;
9257 if (automatic_hscrolling_p)
9259 hscrolled_p = hscroll_window_tree (window);
9260 if (hscrolled_p)
9261 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
9263 else
9264 hscrolled_p = 0;
9265 return hscrolled_p;
9270 /************************************************************************
9271 Redisplay
9272 ************************************************************************/
9274 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
9275 to a non-zero value. This is sometimes handy to have in a debugger
9276 session. */
9278 #if GLYPH_DEBUG
9280 /* First and last unchanged row for try_window_id. */
9282 int debug_first_unchanged_at_end_vpos;
9283 int debug_last_unchanged_at_beg_vpos;
9285 /* Delta vpos and y. */
9287 int debug_dvpos, debug_dy;
9289 /* Delta in characters and bytes for try_window_id. */
9291 int debug_delta, debug_delta_bytes;
9293 /* Values of window_end_pos and window_end_vpos at the end of
9294 try_window_id. */
9296 EMACS_INT debug_end_pos, debug_end_vpos;
9298 /* Append a string to W->desired_matrix->method. FMT is a printf
9299 format string. A1...A9 are a supplement for a variable-length
9300 argument list. If trace_redisplay_p is non-zero also printf the
9301 resulting string to stderr. */
9303 static void
9304 debug_method_add (w, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
9305 struct window *w;
9306 char *fmt;
9307 int a1, a2, a3, a4, a5, a6, a7, a8, a9;
9309 char buffer[512];
9310 char *method = w->desired_matrix->method;
9311 int len = strlen (method);
9312 int size = sizeof w->desired_matrix->method;
9313 int remaining = size - len - 1;
9315 sprintf (buffer, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
9316 if (len && remaining)
9318 method[len] = '|';
9319 --remaining, ++len;
9322 strncpy (method + len, buffer, remaining);
9324 if (trace_redisplay_p)
9325 fprintf (stderr, "%p (%s): %s\n",
9327 ((BUFFERP (w->buffer)
9328 && STRINGP (XBUFFER (w->buffer)->name))
9329 ? (char *) SDATA (XBUFFER (w->buffer)->name)
9330 : "no buffer"),
9331 buffer);
9334 #endif /* GLYPH_DEBUG */
9337 /* Value is non-zero if all changes in window W, which displays
9338 current_buffer, are in the text between START and END. START is a
9339 buffer position, END is given as a distance from Z. Used in
9340 redisplay_internal for display optimization. */
9342 static INLINE int
9343 text_outside_line_unchanged_p (w, start, end)
9344 struct window *w;
9345 int start, end;
9347 int unchanged_p = 1;
9349 /* If text or overlays have changed, see where. */
9350 if (XFASTINT (w->last_modified) < MODIFF
9351 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
9353 /* Gap in the line? */
9354 if (GPT < start || Z - GPT < end)
9355 unchanged_p = 0;
9357 /* Changes start in front of the line, or end after it? */
9358 if (unchanged_p
9359 && (BEG_UNCHANGED < start - 1
9360 || END_UNCHANGED < end))
9361 unchanged_p = 0;
9363 /* If selective display, can't optimize if changes start at the
9364 beginning of the line. */
9365 if (unchanged_p
9366 && INTEGERP (current_buffer->selective_display)
9367 && XINT (current_buffer->selective_display) > 0
9368 && (BEG_UNCHANGED < start || GPT <= start))
9369 unchanged_p = 0;
9371 /* If there are overlays at the start or end of the line, these
9372 may have overlay strings with newlines in them. A change at
9373 START, for instance, may actually concern the display of such
9374 overlay strings as well, and they are displayed on different
9375 lines. So, quickly rule out this case. (For the future, it
9376 might be desirable to implement something more telling than
9377 just BEG/END_UNCHANGED.) */
9378 if (unchanged_p)
9380 if (BEG + BEG_UNCHANGED == start
9381 && overlay_touches_p (start))
9382 unchanged_p = 0;
9383 if (END_UNCHANGED == end
9384 && overlay_touches_p (Z - end))
9385 unchanged_p = 0;
9389 return unchanged_p;
9393 /* Do a frame update, taking possible shortcuts into account. This is
9394 the main external entry point for redisplay.
9396 If the last redisplay displayed an echo area message and that message
9397 is no longer requested, we clear the echo area or bring back the
9398 mini-buffer if that is in use. */
9400 void
9401 redisplay ()
9403 redisplay_internal (0);
9407 /* Return 1 if point moved out of or into a composition. Otherwise
9408 return 0. PREV_BUF and PREV_PT are the last point buffer and
9409 position. BUF and PT are the current point buffer and position. */
9412 check_point_in_composition (prev_buf, prev_pt, buf, pt)
9413 struct buffer *prev_buf, *buf;
9414 int prev_pt, pt;
9416 int start, end;
9417 Lisp_Object prop;
9418 Lisp_Object buffer;
9420 XSETBUFFER (buffer, buf);
9421 /* Check a composition at the last point if point moved within the
9422 same buffer. */
9423 if (prev_buf == buf)
9425 if (prev_pt == pt)
9426 /* Point didn't move. */
9427 return 0;
9429 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
9430 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
9431 && COMPOSITION_VALID_P (start, end, prop)
9432 && start < prev_pt && end > prev_pt)
9433 /* The last point was within the composition. Return 1 iff
9434 point moved out of the composition. */
9435 return (pt <= start || pt >= end);
9438 /* Check a composition at the current point. */
9439 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
9440 && find_composition (pt, -1, &start, &end, &prop, buffer)
9441 && COMPOSITION_VALID_P (start, end, prop)
9442 && start < pt && end > pt);
9446 /* Reconsider the setting of B->clip_changed which is displayed
9447 in window W. */
9449 static INLINE void
9450 reconsider_clip_changes (w, b)
9451 struct window *w;
9452 struct buffer *b;
9454 if (b->clip_changed
9455 && !NILP (w->window_end_valid)
9456 && w->current_matrix->buffer == b
9457 && w->current_matrix->zv == BUF_ZV (b)
9458 && w->current_matrix->begv == BUF_BEGV (b))
9459 b->clip_changed = 0;
9461 /* If display wasn't paused, and W is not a tool bar window, see if
9462 point has been moved into or out of a composition. In that case,
9463 we set b->clip_changed to 1 to force updating the screen. If
9464 b->clip_changed has already been set to 1, we can skip this
9465 check. */
9466 if (!b->clip_changed
9467 && BUFFERP (w->buffer) && !NILP (w->window_end_valid))
9469 int pt;
9471 if (w == XWINDOW (selected_window))
9472 pt = BUF_PT (current_buffer);
9473 else
9474 pt = marker_position (w->pointm);
9476 if ((w->current_matrix->buffer != XBUFFER (w->buffer)
9477 || pt != XINT (w->last_point))
9478 && check_point_in_composition (w->current_matrix->buffer,
9479 XINT (w->last_point),
9480 XBUFFER (w->buffer), pt))
9481 b->clip_changed = 1;
9485 #define STOP_POLLING \
9486 do { if (! polling_stopped_here) stop_polling (); \
9487 polling_stopped_here = 1; } while (0)
9489 #define RESUME_POLLING \
9490 do { if (polling_stopped_here) start_polling (); \
9491 polling_stopped_here = 0; } while (0)
9494 /* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
9495 response to any user action; therefore, we should preserve the echo
9496 area. (Actually, our caller does that job.) Perhaps in the future
9497 avoid recentering windows if it is not necessary; currently that
9498 causes some problems. */
9500 static void
9501 redisplay_internal (preserve_echo_area)
9502 int preserve_echo_area;
9504 struct window *w = XWINDOW (selected_window);
9505 struct frame *f = XFRAME (w->frame);
9506 int pause;
9507 int must_finish = 0;
9508 struct text_pos tlbufpos, tlendpos;
9509 int number_of_visible_frames;
9510 int count;
9511 struct frame *sf = SELECTED_FRAME ();
9512 int polling_stopped_here = 0;
9514 /* Non-zero means redisplay has to consider all windows on all
9515 frames. Zero means, only selected_window is considered. */
9516 int consider_all_windows_p;
9518 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
9520 /* No redisplay if running in batch mode or frame is not yet fully
9521 initialized, or redisplay is explicitly turned off by setting
9522 Vinhibit_redisplay. */
9523 if (noninteractive
9524 || !NILP (Vinhibit_redisplay)
9525 || !f->glyphs_initialized_p)
9526 return;
9528 /* The flag redisplay_performed_directly_p is set by
9529 direct_output_for_insert when it already did the whole screen
9530 update necessary. */
9531 if (redisplay_performed_directly_p)
9533 redisplay_performed_directly_p = 0;
9534 if (!hscroll_windows (selected_window))
9535 return;
9538 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
9539 if (popup_activated ())
9540 return;
9541 #endif
9543 /* I don't think this happens but let's be paranoid. */
9544 if (redisplaying_p)
9545 return;
9547 /* Record a function that resets redisplaying_p to its old value
9548 when we leave this function. */
9549 count = SPECPDL_INDEX ();
9550 record_unwind_protect (unwind_redisplay, make_number (redisplaying_p));
9551 ++redisplaying_p;
9552 specbind (Qinhibit_free_realized_faces, Qnil);
9554 retry:
9555 pause = 0;
9556 reconsider_clip_changes (w, current_buffer);
9558 /* If new fonts have been loaded that make a glyph matrix adjustment
9559 necessary, do it. */
9560 if (fonts_changed_p)
9562 adjust_glyphs (NULL);
9563 ++windows_or_buffers_changed;
9564 fonts_changed_p = 0;
9567 /* If face_change_count is non-zero, init_iterator will free all
9568 realized faces, which includes the faces referenced from current
9569 matrices. So, we can't reuse current matrices in this case. */
9570 if (face_change_count)
9571 ++windows_or_buffers_changed;
9573 if (! FRAME_WINDOW_P (sf)
9574 && previous_terminal_frame != sf)
9576 /* Since frames on an ASCII terminal share the same display
9577 area, displaying a different frame means redisplay the whole
9578 thing. */
9579 windows_or_buffers_changed++;
9580 SET_FRAME_GARBAGED (sf);
9581 XSETFRAME (Vterminal_frame, sf);
9583 previous_terminal_frame = sf;
9585 /* Set the visible flags for all frames. Do this before checking
9586 for resized or garbaged frames; they want to know if their frames
9587 are visible. See the comment in frame.h for
9588 FRAME_SAMPLE_VISIBILITY. */
9590 Lisp_Object tail, frame;
9592 number_of_visible_frames = 0;
9594 FOR_EACH_FRAME (tail, frame)
9596 struct frame *f = XFRAME (frame);
9598 FRAME_SAMPLE_VISIBILITY (f);
9599 if (FRAME_VISIBLE_P (f))
9600 ++number_of_visible_frames;
9601 clear_desired_matrices (f);
9605 /* Notice any pending interrupt request to change frame size. */
9606 do_pending_window_change (1);
9608 /* Clear frames marked as garbaged. */
9609 if (frame_garbaged)
9610 clear_garbaged_frames ();
9612 /* Build menubar and tool-bar items. */
9613 prepare_menu_bars ();
9615 if (windows_or_buffers_changed)
9616 update_mode_lines++;
9618 /* Detect case that we need to write or remove a star in the mode line. */
9619 if ((SAVE_MODIFF < MODIFF) != !NILP (w->last_had_star))
9621 w->update_mode_line = Qt;
9622 if (buffer_shared > 1)
9623 update_mode_lines++;
9626 /* If %c is in the mode line, update it if needed. */
9627 if (!NILP (w->column_number_displayed)
9628 /* This alternative quickly identifies a common case
9629 where no change is needed. */
9630 && !(PT == XFASTINT (w->last_point)
9631 && XFASTINT (w->last_modified) >= MODIFF
9632 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
9633 && (XFASTINT (w->column_number_displayed)
9634 != (int) current_column ())) /* iftc */
9635 w->update_mode_line = Qt;
9637 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
9639 /* The variable buffer_shared is set in redisplay_window and
9640 indicates that we redisplay a buffer in different windows. See
9641 there. */
9642 consider_all_windows_p = (update_mode_lines || buffer_shared > 1
9643 || cursor_type_changed);
9645 /* If specs for an arrow have changed, do thorough redisplay
9646 to ensure we remove any arrow that should no longer exist. */
9647 if (! EQ (COERCE_MARKER (Voverlay_arrow_position), last_arrow_position)
9648 || ! EQ (Voverlay_arrow_string, last_arrow_string))
9649 consider_all_windows_p = windows_or_buffers_changed = 1;
9651 /* Normally the message* functions will have already displayed and
9652 updated the echo area, but the frame may have been trashed, or
9653 the update may have been preempted, so display the echo area
9654 again here. Checking message_cleared_p captures the case that
9655 the echo area should be cleared. */
9656 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
9657 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
9658 || (message_cleared_p
9659 && minibuf_level == 0
9660 /* If the mini-window is currently selected, this means the
9661 echo-area doesn't show through. */
9662 && !MINI_WINDOW_P (XWINDOW (selected_window))))
9664 int window_height_changed_p = echo_area_display (0);
9665 must_finish = 1;
9667 /* If we don't display the current message, don't clear the
9668 message_cleared_p flag, because, if we did, we wouldn't clear
9669 the echo area in the next redisplay which doesn't preserve
9670 the echo area. */
9671 if (!display_last_displayed_message_p)
9672 message_cleared_p = 0;
9674 if (fonts_changed_p)
9675 goto retry;
9676 else if (window_height_changed_p)
9678 consider_all_windows_p = 1;
9679 ++update_mode_lines;
9680 ++windows_or_buffers_changed;
9682 /* If window configuration was changed, frames may have been
9683 marked garbaged. Clear them or we will experience
9684 surprises wrt scrolling. */
9685 if (frame_garbaged)
9686 clear_garbaged_frames ();
9689 else if (EQ (selected_window, minibuf_window)
9690 && (current_buffer->clip_changed
9691 || XFASTINT (w->last_modified) < MODIFF
9692 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
9693 && resize_mini_window (w, 0))
9695 /* Resized active mini-window to fit the size of what it is
9696 showing if its contents might have changed. */
9697 must_finish = 1;
9698 consider_all_windows_p = 1;
9699 ++windows_or_buffers_changed;
9700 ++update_mode_lines;
9702 /* If window configuration was changed, frames may have been
9703 marked garbaged. Clear them or we will experience
9704 surprises wrt scrolling. */
9705 if (frame_garbaged)
9706 clear_garbaged_frames ();
9710 /* If showing the region, and mark has changed, we must redisplay
9711 the whole window. The assignment to this_line_start_pos prevents
9712 the optimization directly below this if-statement. */
9713 if (((!NILP (Vtransient_mark_mode)
9714 && !NILP (XBUFFER (w->buffer)->mark_active))
9715 != !NILP (w->region_showing))
9716 || (!NILP (w->region_showing)
9717 && !EQ (w->region_showing,
9718 Fmarker_position (XBUFFER (w->buffer)->mark))))
9719 CHARPOS (this_line_start_pos) = 0;
9721 /* Optimize the case that only the line containing the cursor in the
9722 selected window has changed. Variables starting with this_ are
9723 set in display_line and record information about the line
9724 containing the cursor. */
9725 tlbufpos = this_line_start_pos;
9726 tlendpos = this_line_end_pos;
9727 if (!consider_all_windows_p
9728 && CHARPOS (tlbufpos) > 0
9729 && NILP (w->update_mode_line)
9730 && !current_buffer->clip_changed
9731 && !current_buffer->prevent_redisplay_optimizations_p
9732 && FRAME_VISIBLE_P (XFRAME (w->frame))
9733 && !FRAME_OBSCURED_P (XFRAME (w->frame))
9734 /* Make sure recorded data applies to current buffer, etc. */
9735 && this_line_buffer == current_buffer
9736 && current_buffer == XBUFFER (w->buffer)
9737 && NILP (w->force_start)
9738 && NILP (w->optional_new_start)
9739 /* Point must be on the line that we have info recorded about. */
9740 && PT >= CHARPOS (tlbufpos)
9741 && PT <= Z - CHARPOS (tlendpos)
9742 /* All text outside that line, including its final newline,
9743 must be unchanged */
9744 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
9745 CHARPOS (tlendpos)))
9747 if (CHARPOS (tlbufpos) > BEGV
9748 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
9749 && (CHARPOS (tlbufpos) == ZV
9750 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
9751 /* Former continuation line has disappeared by becoming empty */
9752 goto cancel;
9753 else if (XFASTINT (w->last_modified) < MODIFF
9754 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF
9755 || MINI_WINDOW_P (w))
9757 /* We have to handle the case of continuation around a
9758 wide-column character (See the comment in indent.c around
9759 line 885).
9761 For instance, in the following case:
9763 -------- Insert --------
9764 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
9765 J_I_ ==> J_I_ `^^' are cursors.
9766 ^^ ^^
9767 -------- --------
9769 As we have to redraw the line above, we should goto cancel. */
9771 struct it it;
9772 int line_height_before = this_line_pixel_height;
9774 /* Note that start_display will handle the case that the
9775 line starting at tlbufpos is a continuation lines. */
9776 start_display (&it, w, tlbufpos);
9778 /* Implementation note: It this still necessary? */
9779 if (it.current_x != this_line_start_x)
9780 goto cancel;
9782 TRACE ((stderr, "trying display optimization 1\n"));
9783 w->cursor.vpos = -1;
9784 overlay_arrow_seen = 0;
9785 it.vpos = this_line_vpos;
9786 it.current_y = this_line_y;
9787 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
9788 display_line (&it);
9790 /* If line contains point, is not continued,
9791 and ends at same distance from eob as before, we win */
9792 if (w->cursor.vpos >= 0
9793 /* Line is not continued, otherwise this_line_start_pos
9794 would have been set to 0 in display_line. */
9795 && CHARPOS (this_line_start_pos)
9796 /* Line ends as before. */
9797 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
9798 /* Line has same height as before. Otherwise other lines
9799 would have to be shifted up or down. */
9800 && this_line_pixel_height == line_height_before)
9802 /* If this is not the window's last line, we must adjust
9803 the charstarts of the lines below. */
9804 if (it.current_y < it.last_visible_y)
9806 struct glyph_row *row
9807 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
9808 int delta, delta_bytes;
9810 if (Z - CHARPOS (tlendpos) == ZV)
9812 /* This line ends at end of (accessible part of)
9813 buffer. There is no newline to count. */
9814 delta = (Z
9815 - CHARPOS (tlendpos)
9816 - MATRIX_ROW_START_CHARPOS (row));
9817 delta_bytes = (Z_BYTE
9818 - BYTEPOS (tlendpos)
9819 - MATRIX_ROW_START_BYTEPOS (row));
9821 else
9823 /* This line ends in a newline. Must take
9824 account of the newline and the rest of the
9825 text that follows. */
9826 delta = (Z
9827 - CHARPOS (tlendpos)
9828 - MATRIX_ROW_START_CHARPOS (row));
9829 delta_bytes = (Z_BYTE
9830 - BYTEPOS (tlendpos)
9831 - MATRIX_ROW_START_BYTEPOS (row));
9834 increment_matrix_positions (w->current_matrix,
9835 this_line_vpos + 1,
9836 w->current_matrix->nrows,
9837 delta, delta_bytes);
9840 /* If this row displays text now but previously didn't,
9841 or vice versa, w->window_end_vpos may have to be
9842 adjusted. */
9843 if ((it.glyph_row - 1)->displays_text_p)
9845 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
9846 XSETINT (w->window_end_vpos, this_line_vpos);
9848 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
9849 && this_line_vpos > 0)
9850 XSETINT (w->window_end_vpos, this_line_vpos - 1);
9851 w->window_end_valid = Qnil;
9853 /* Update hint: No need to try to scroll in update_window. */
9854 w->desired_matrix->no_scrolling_p = 1;
9856 #if GLYPH_DEBUG
9857 *w->desired_matrix->method = 0;
9858 debug_method_add (w, "optimization 1");
9859 #endif
9860 goto update;
9862 else
9863 goto cancel;
9865 else if (/* Cursor position hasn't changed. */
9866 PT == XFASTINT (w->last_point)
9867 /* Make sure the cursor was last displayed
9868 in this window. Otherwise we have to reposition it. */
9869 && 0 <= w->cursor.vpos
9870 && XINT (w->height) > w->cursor.vpos)
9872 if (!must_finish)
9874 do_pending_window_change (1);
9876 /* We used to always goto end_of_redisplay here, but this
9877 isn't enough if we have a blinking cursor. */
9878 if (w->cursor_off_p == w->last_cursor_off_p)
9879 goto end_of_redisplay;
9881 goto update;
9883 /* If highlighting the region, or if the cursor is in the echo area,
9884 then we can't just move the cursor. */
9885 else if (! (!NILP (Vtransient_mark_mode)
9886 && !NILP (current_buffer->mark_active))
9887 && (EQ (selected_window, current_buffer->last_selected_window)
9888 || highlight_nonselected_windows)
9889 && NILP (w->region_showing)
9890 && NILP (Vshow_trailing_whitespace)
9891 && !cursor_in_echo_area)
9893 struct it it;
9894 struct glyph_row *row;
9896 /* Skip from tlbufpos to PT and see where it is. Note that
9897 PT may be in invisible text. If so, we will end at the
9898 next visible position. */
9899 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
9900 NULL, DEFAULT_FACE_ID);
9901 it.current_x = this_line_start_x;
9902 it.current_y = this_line_y;
9903 it.vpos = this_line_vpos;
9905 /* The call to move_it_to stops in front of PT, but
9906 moves over before-strings. */
9907 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
9909 if (it.vpos == this_line_vpos
9910 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
9911 row->enabled_p))
9913 xassert (this_line_vpos == it.vpos);
9914 xassert (this_line_y == it.current_y);
9915 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
9916 #if GLYPH_DEBUG
9917 *w->desired_matrix->method = 0;
9918 debug_method_add (w, "optimization 3");
9919 #endif
9920 goto update;
9922 else
9923 goto cancel;
9926 cancel:
9927 /* Text changed drastically or point moved off of line. */
9928 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
9931 CHARPOS (this_line_start_pos) = 0;
9932 consider_all_windows_p |= buffer_shared > 1;
9933 ++clear_face_cache_count;
9936 /* Build desired matrices, and update the display. If
9937 consider_all_windows_p is non-zero, do it for all windows on all
9938 frames. Otherwise do it for selected_window, only. */
9940 if (consider_all_windows_p)
9942 Lisp_Object tail, frame;
9943 int i, n = 0, size = 50;
9944 struct frame **updated
9945 = (struct frame **) alloca (size * sizeof *updated);
9947 /* Clear the face cache eventually. */
9948 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
9950 clear_face_cache (0);
9951 clear_face_cache_count = 0;
9954 /* Recompute # windows showing selected buffer. This will be
9955 incremented each time such a window is displayed. */
9956 buffer_shared = 0;
9958 FOR_EACH_FRAME (tail, frame)
9960 struct frame *f = XFRAME (frame);
9962 if (FRAME_WINDOW_P (f) || f == sf)
9964 #ifdef HAVE_WINDOW_SYSTEM
9965 if (clear_face_cache_count % 50 == 0
9966 && FRAME_WINDOW_P (f))
9967 clear_image_cache (f, 0);
9968 #endif /* HAVE_WINDOW_SYSTEM */
9970 /* Mark all the scroll bars to be removed; we'll redeem
9971 the ones we want when we redisplay their windows. */
9972 if (condemn_scroll_bars_hook)
9973 condemn_scroll_bars_hook (f);
9975 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
9976 redisplay_windows (FRAME_ROOT_WINDOW (f));
9978 /* Any scroll bars which redisplay_windows should have
9979 nuked should now go away. */
9980 if (judge_scroll_bars_hook)
9981 judge_scroll_bars_hook (f);
9983 /* If fonts changed, display again. */
9984 /* ??? rms: I suspect it is a mistake to jump all the way
9985 back to retry here. It should just retry this frame. */
9986 if (fonts_changed_p)
9987 goto retry;
9989 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
9991 /* See if we have to hscroll. */
9992 if (hscroll_windows (f->root_window))
9993 goto retry;
9995 /* Prevent various kinds of signals during display
9996 update. stdio is not robust about handling
9997 signals, which can cause an apparent I/O
9998 error. */
9999 if (interrupt_input)
10000 unrequest_sigio ();
10001 STOP_POLLING;
10003 /* Update the display. */
10004 set_window_update_flags (XWINDOW (f->root_window), 1);
10005 pause |= update_frame (f, 0, 0);
10006 #if 0 /* Exiting the loop can leave the wrong value for buffer_shared. */
10007 if (pause)
10008 break;
10009 #endif
10011 if (n == size)
10013 int nbytes = size * sizeof *updated;
10014 struct frame **p = (struct frame **) alloca (2 * nbytes);
10015 bcopy (updated, p, nbytes);
10016 size *= 2;
10019 updated[n++] = f;
10024 /* Do the mark_window_display_accurate after all windows have
10025 been redisplayed because this call resets flags in buffers
10026 which are needed for proper redisplay. */
10027 for (i = 0; i < n; ++i)
10029 struct frame *f = updated[i];
10030 mark_window_display_accurate (f->root_window, 1);
10031 if (frame_up_to_date_hook)
10032 frame_up_to_date_hook (f);
10035 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
10037 Lisp_Object mini_window;
10038 struct frame *mini_frame;
10040 displayed_buffer = XBUFFER (XWINDOW (selected_window)->buffer);
10041 /* Use list_of_error, not Qerror, so that
10042 we catch only errors and don't run the debugger. */
10043 internal_condition_case_1 (redisplay_window_1, selected_window,
10044 list_of_error,
10045 redisplay_window_error);
10047 /* Compare desired and current matrices, perform output. */
10049 update:
10050 /* If fonts changed, display again. */
10051 if (fonts_changed_p)
10052 goto retry;
10054 /* Prevent various kinds of signals during display update.
10055 stdio is not robust about handling signals,
10056 which can cause an apparent I/O error. */
10057 if (interrupt_input)
10058 unrequest_sigio ();
10059 STOP_POLLING;
10061 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
10063 if (hscroll_windows (selected_window))
10064 goto retry;
10066 XWINDOW (selected_window)->must_be_updated_p = 1;
10067 pause = update_frame (sf, 0, 0);
10070 /* We may have called echo_area_display at the top of this
10071 function. If the echo area is on another frame, that may
10072 have put text on a frame other than the selected one, so the
10073 above call to update_frame would not have caught it. Catch
10074 it here. */
10075 mini_window = FRAME_MINIBUF_WINDOW (sf);
10076 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
10078 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
10080 XWINDOW (mini_window)->must_be_updated_p = 1;
10081 pause |= update_frame (mini_frame, 0, 0);
10082 if (!pause && hscroll_windows (mini_window))
10083 goto retry;
10087 /* If display was paused because of pending input, make sure we do a
10088 thorough update the next time. */
10089 if (pause)
10091 /* Prevent the optimization at the beginning of
10092 redisplay_internal that tries a single-line update of the
10093 line containing the cursor in the selected window. */
10094 CHARPOS (this_line_start_pos) = 0;
10096 /* Let the overlay arrow be updated the next time. */
10097 if (!NILP (last_arrow_position))
10099 last_arrow_position = Qt;
10100 last_arrow_string = Qt;
10103 /* If we pause after scrolling, some rows in the current
10104 matrices of some windows are not valid. */
10105 if (!WINDOW_FULL_WIDTH_P (w)
10106 && !FRAME_WINDOW_P (XFRAME (w->frame)))
10107 update_mode_lines = 1;
10109 else
10111 if (!consider_all_windows_p)
10113 /* This has already been done above if
10114 consider_all_windows_p is set. */
10115 mark_window_display_accurate_1 (w, 1);
10117 last_arrow_position = COERCE_MARKER (Voverlay_arrow_position);
10118 last_arrow_string = Voverlay_arrow_string;
10120 if (frame_up_to_date_hook != 0)
10121 frame_up_to_date_hook (sf);
10124 update_mode_lines = 0;
10125 windows_or_buffers_changed = 0;
10126 cursor_type_changed = 0;
10129 /* Start SIGIO interrupts coming again. Having them off during the
10130 code above makes it less likely one will discard output, but not
10131 impossible, since there might be stuff in the system buffer here.
10132 But it is much hairier to try to do anything about that. */
10133 if (interrupt_input)
10134 request_sigio ();
10135 RESUME_POLLING;
10137 /* If a frame has become visible which was not before, redisplay
10138 again, so that we display it. Expose events for such a frame
10139 (which it gets when becoming visible) don't call the parts of
10140 redisplay constructing glyphs, so simply exposing a frame won't
10141 display anything in this case. So, we have to display these
10142 frames here explicitly. */
10143 if (!pause)
10145 Lisp_Object tail, frame;
10146 int new_count = 0;
10148 FOR_EACH_FRAME (tail, frame)
10150 int this_is_visible = 0;
10152 if (XFRAME (frame)->visible)
10153 this_is_visible = 1;
10154 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
10155 if (XFRAME (frame)->visible)
10156 this_is_visible = 1;
10158 if (this_is_visible)
10159 new_count++;
10162 if (new_count != number_of_visible_frames)
10163 windows_or_buffers_changed++;
10166 /* Change frame size now if a change is pending. */
10167 do_pending_window_change (1);
10169 /* If we just did a pending size change, or have additional
10170 visible frames, redisplay again. */
10171 if (windows_or_buffers_changed && !pause)
10172 goto retry;
10174 end_of_redisplay:
10175 unbind_to (count, Qnil);
10176 RESUME_POLLING;
10180 /* Redisplay, but leave alone any recent echo area message unless
10181 another message has been requested in its place.
10183 This is useful in situations where you need to redisplay but no
10184 user action has occurred, making it inappropriate for the message
10185 area to be cleared. See tracking_off and
10186 wait_reading_process_input for examples of these situations.
10188 FROM_WHERE is an integer saying from where this function was
10189 called. This is useful for debugging. */
10191 void
10192 redisplay_preserve_echo_area (from_where)
10193 int from_where;
10195 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
10197 if (!NILP (echo_area_buffer[1]))
10199 /* We have a previously displayed message, but no current
10200 message. Redisplay the previous message. */
10201 display_last_displayed_message_p = 1;
10202 redisplay_internal (1);
10203 display_last_displayed_message_p = 0;
10205 else
10206 redisplay_internal (1);
10210 /* Function registered with record_unwind_protect in
10211 redisplay_internal. Reset redisplaying_p to the value it had
10212 before redisplay_internal was called, and clear
10213 prevent_freeing_realized_faces_p. */
10215 static Lisp_Object
10216 unwind_redisplay (old_redisplaying_p)
10217 Lisp_Object old_redisplaying_p;
10219 redisplaying_p = XFASTINT (old_redisplaying_p);
10220 return Qnil;
10224 /* Mark the display of window W as accurate or inaccurate. If
10225 ACCURATE_P is non-zero mark display of W as accurate. If
10226 ACCURATE_P is zero, arrange for W to be redisplayed the next time
10227 redisplay_internal is called. */
10229 static void
10230 mark_window_display_accurate_1 (w, accurate_p)
10231 struct window *w;
10232 int accurate_p;
10234 if (BUFFERP (w->buffer))
10236 struct buffer *b = XBUFFER (w->buffer);
10238 w->last_modified
10239 = make_number (accurate_p ? BUF_MODIFF (b) : 0);
10240 w->last_overlay_modified
10241 = make_number (accurate_p ? BUF_OVERLAY_MODIFF (b) : 0);
10242 w->last_had_star
10243 = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b) ? Qt : Qnil;
10245 if (accurate_p)
10247 b->clip_changed = 0;
10248 b->prevent_redisplay_optimizations_p = 0;
10250 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
10251 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
10252 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
10253 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
10255 w->current_matrix->buffer = b;
10256 w->current_matrix->begv = BUF_BEGV (b);
10257 w->current_matrix->zv = BUF_ZV (b);
10259 w->last_cursor = w->cursor;
10260 w->last_cursor_off_p = w->cursor_off_p;
10262 if (w == XWINDOW (selected_window))
10263 w->last_point = make_number (BUF_PT (b));
10264 else
10265 w->last_point = make_number (XMARKER (w->pointm)->charpos);
10269 if (accurate_p)
10271 w->window_end_valid = w->buffer;
10272 #if 0 /* This is incorrect with variable-height lines. */
10273 xassert (XINT (w->window_end_vpos)
10274 < (XINT (w->height)
10275 - (WINDOW_WANTS_MODELINE_P (w) ? 1 : 0)));
10276 #endif
10277 w->update_mode_line = Qnil;
10282 /* Mark the display of windows in the window tree rooted at WINDOW as
10283 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
10284 windows as accurate. If ACCURATE_P is zero, arrange for windows to
10285 be redisplayed the next time redisplay_internal is called. */
10287 void
10288 mark_window_display_accurate (window, accurate_p)
10289 Lisp_Object window;
10290 int accurate_p;
10292 struct window *w;
10294 for (; !NILP (window); window = w->next)
10296 w = XWINDOW (window);
10297 mark_window_display_accurate_1 (w, accurate_p);
10299 if (!NILP (w->vchild))
10300 mark_window_display_accurate (w->vchild, accurate_p);
10301 if (!NILP (w->hchild))
10302 mark_window_display_accurate (w->hchild, accurate_p);
10305 if (accurate_p)
10307 last_arrow_position = COERCE_MARKER (Voverlay_arrow_position);
10308 last_arrow_string = Voverlay_arrow_string;
10310 else
10312 /* Force a thorough redisplay the next time by setting
10313 last_arrow_position and last_arrow_string to t, which is
10314 unequal to any useful value of Voverlay_arrow_... */
10315 last_arrow_position = Qt;
10316 last_arrow_string = Qt;
10321 /* Return value in display table DP (Lisp_Char_Table *) for character
10322 C. Since a display table doesn't have any parent, we don't have to
10323 follow parent. Do not call this function directly but use the
10324 macro DISP_CHAR_VECTOR. */
10326 Lisp_Object
10327 disp_char_vector (dp, c)
10328 struct Lisp_Char_Table *dp;
10329 int c;
10331 int code[4], i;
10332 Lisp_Object val;
10334 if (SINGLE_BYTE_CHAR_P (c))
10335 return (dp->contents[c]);
10337 SPLIT_CHAR (c, code[0], code[1], code[2]);
10338 if (code[1] < 32)
10339 code[1] = -1;
10340 else if (code[2] < 32)
10341 code[2] = -1;
10343 /* Here, the possible range of code[0] (== charset ID) is
10344 128..max_charset. Since the top level char table contains data
10345 for multibyte characters after 256th element, we must increment
10346 code[0] by 128 to get a correct index. */
10347 code[0] += 128;
10348 code[3] = -1; /* anchor */
10350 for (i = 0; code[i] >= 0; i++, dp = XCHAR_TABLE (val))
10352 val = dp->contents[code[i]];
10353 if (!SUB_CHAR_TABLE_P (val))
10354 return (NILP (val) ? dp->defalt : val);
10357 /* Here, val is a sub char table. We return the default value of
10358 it. */
10359 return (dp->defalt);
10364 /***********************************************************************
10365 Window Redisplay
10366 ***********************************************************************/
10368 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
10370 static void
10371 redisplay_windows (window)
10372 Lisp_Object window;
10374 while (!NILP (window))
10376 struct window *w = XWINDOW (window);
10378 if (!NILP (w->hchild))
10379 redisplay_windows (w->hchild);
10380 else if (!NILP (w->vchild))
10381 redisplay_windows (w->vchild);
10382 else
10384 displayed_buffer = XBUFFER (w->buffer);
10385 /* Use list_of_error, not Qerror, so that
10386 we catch only errors and don't run the debugger. */
10387 internal_condition_case_1 (redisplay_window_0, window,
10388 list_of_error,
10389 redisplay_window_error);
10392 window = w->next;
10396 static Lisp_Object
10397 redisplay_window_error ()
10399 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
10400 return Qnil;
10403 static Lisp_Object
10404 redisplay_window_0 (window)
10405 Lisp_Object window;
10407 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
10408 redisplay_window (window, 0);
10409 return Qnil;
10412 static Lisp_Object
10413 redisplay_window_1 (window)
10414 Lisp_Object window;
10416 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
10417 redisplay_window (window, 1);
10418 return Qnil;
10422 /* Increment GLYPH until it reaches END or CONDITION fails while
10423 adding (GLYPH)->pixel_width to X. */
10425 #define SKIP_GLYPHS(glyph, end, x, condition) \
10426 do \
10428 (x) += (glyph)->pixel_width; \
10429 ++(glyph); \
10431 while ((glyph) < (end) && (condition))
10434 /* Set cursor position of W. PT is assumed to be displayed in ROW.
10435 DELTA is the number of bytes by which positions recorded in ROW
10436 differ from current buffer positions. */
10438 void
10439 set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
10440 struct window *w;
10441 struct glyph_row *row;
10442 struct glyph_matrix *matrix;
10443 int delta, delta_bytes, dy, dvpos;
10445 struct glyph *glyph = row->glyphs[TEXT_AREA];
10446 struct glyph *end = glyph + row->used[TEXT_AREA];
10447 /* The first glyph that starts a sequence of glyphs from string. */
10448 struct glyph *string_start;
10449 /* The X coordinate of string_start. */
10450 int string_start_x;
10451 /* The last known character position. */
10452 int last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
10453 /* The last known character position before string_start. */
10454 int string_before_pos;
10455 int x = row->x;
10456 int pt_old = PT - delta;
10458 /* Skip over glyphs not having an object at the start of the row.
10459 These are special glyphs like truncation marks on terminal
10460 frames. */
10461 if (row->displays_text_p)
10462 while (glyph < end
10463 && INTEGERP (glyph->object)
10464 && glyph->charpos < 0)
10466 x += glyph->pixel_width;
10467 ++glyph;
10470 string_start = NULL;
10471 while (glyph < end
10472 && !INTEGERP (glyph->object)
10473 && (!BUFFERP (glyph->object)
10474 || (last_pos = glyph->charpos) < pt_old))
10476 if (! STRINGP (glyph->object))
10478 string_start = NULL;
10479 x += glyph->pixel_width;
10480 ++glyph;
10482 else
10484 string_before_pos = last_pos;
10485 string_start = glyph;
10486 string_start_x = x;
10487 /* Skip all glyphs from string. */
10488 SKIP_GLYPHS (glyph, end, x, STRINGP (glyph->object));
10492 if (string_start
10493 && (glyph == end || !BUFFERP (glyph->object) || last_pos > pt_old))
10495 /* We may have skipped over point because the previous glyphs
10496 are from string. As there's no easy way to know the
10497 character position of the current glyph, find the correct
10498 glyph on point by scanning from string_start again. */
10499 Lisp_Object limit;
10500 Lisp_Object string;
10501 int pos;
10503 limit = make_number (pt_old + 1);
10504 end = glyph;
10505 glyph = string_start;
10506 x = string_start_x;
10507 string = glyph->object;
10508 pos = string_buffer_position (w, string, string_before_pos);
10509 /* If STRING is from overlay, LAST_POS == 0. We skip such glyphs
10510 because we always put cursor after overlay strings. */
10511 while (pos == 0 && glyph < end)
10513 string = glyph->object;
10514 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10515 if (glyph < end)
10516 pos = string_buffer_position (w, glyph->object, string_before_pos);
10519 while (glyph < end)
10521 pos = XINT (Fnext_single_char_property_change
10522 (make_number (pos), Qdisplay, Qnil, limit));
10523 if (pos > pt_old)
10524 break;
10525 /* Skip glyphs from the same string. */
10526 string = glyph->object;
10527 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10528 /* Skip glyphs from an overlay. */
10529 while (glyph < end
10530 && ! string_buffer_position (w, glyph->object, pos))
10532 string = glyph->object;
10533 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10538 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
10539 w->cursor.x = x;
10540 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
10541 w->cursor.y = row->y + dy;
10543 if (w == XWINDOW (selected_window))
10545 if (!row->continued_p
10546 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
10547 && row->x == 0)
10549 this_line_buffer = XBUFFER (w->buffer);
10551 CHARPOS (this_line_start_pos)
10552 = MATRIX_ROW_START_CHARPOS (row) + delta;
10553 BYTEPOS (this_line_start_pos)
10554 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
10556 CHARPOS (this_line_end_pos)
10557 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
10558 BYTEPOS (this_line_end_pos)
10559 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
10561 this_line_y = w->cursor.y;
10562 this_line_pixel_height = row->height;
10563 this_line_vpos = w->cursor.vpos;
10564 this_line_start_x = row->x;
10566 else
10567 CHARPOS (this_line_start_pos) = 0;
10572 /* Run window scroll functions, if any, for WINDOW with new window
10573 start STARTP. Sets the window start of WINDOW to that position.
10575 We assume that the window's buffer is really current. */
10577 static INLINE struct text_pos
10578 run_window_scroll_functions (window, startp)
10579 Lisp_Object window;
10580 struct text_pos startp;
10582 struct window *w = XWINDOW (window);
10583 SET_MARKER_FROM_TEXT_POS (w->start, startp);
10585 if (current_buffer != XBUFFER (w->buffer))
10586 abort ();
10588 if (!NILP (Vwindow_scroll_functions))
10590 run_hook_with_args_2 (Qwindow_scroll_functions, window,
10591 make_number (CHARPOS (startp)));
10592 SET_TEXT_POS_FROM_MARKER (startp, w->start);
10593 /* In case the hook functions switch buffers. */
10594 if (current_buffer != XBUFFER (w->buffer))
10595 set_buffer_internal_1 (XBUFFER (w->buffer));
10598 return startp;
10602 /* Make sure the line containing the cursor is fully visible.
10603 A value of 1 means there is nothing to be done.
10604 (Either the line is fully visible, or it cannot be made so,
10605 or we cannot tell.)
10606 A value of 0 means the caller should do scrolling
10607 as if point had gone off the screen. */
10609 static int
10610 make_cursor_line_fully_visible (w)
10611 struct window *w;
10613 struct glyph_matrix *matrix;
10614 struct glyph_row *row;
10615 int window_height;
10617 /* It's not always possible to find the cursor, e.g, when a window
10618 is full of overlay strings. Don't do anything in that case. */
10619 if (w->cursor.vpos < 0)
10620 return 1;
10622 matrix = w->desired_matrix;
10623 row = MATRIX_ROW (matrix, w->cursor.vpos);
10625 /* If the cursor row is not partially visible, there's nothing to do. */
10626 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (row))
10627 return 1;
10629 /* If the row the cursor is in is taller than the window's height,
10630 it's not clear what to do, so do nothing. */
10631 window_height = window_box_height (w);
10632 if (row->height >= window_height)
10633 return 1;
10635 return 0;
10637 #if 0
10638 /* This code used to try to scroll the window just enough to make
10639 the line visible. It returned 0 to say that the caller should
10640 allocate larger glyph matrices. */
10642 if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row))
10644 int dy = row->height - row->visible_height;
10645 w->vscroll = 0;
10646 w->cursor.y += dy;
10647 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
10649 else /* MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row)) */
10651 int dy = - (row->height - row->visible_height);
10652 w->vscroll = dy;
10653 w->cursor.y += dy;
10654 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
10657 /* When we change the cursor y-position of the selected window,
10658 change this_line_y as well so that the display optimization for
10659 the cursor line of the selected window in redisplay_internal uses
10660 the correct y-position. */
10661 if (w == XWINDOW (selected_window))
10662 this_line_y = w->cursor.y;
10664 /* If vscrolling requires a larger glyph matrix, arrange for a fresh
10665 redisplay with larger matrices. */
10666 if (matrix->nrows < required_matrix_height (w))
10668 fonts_changed_p = 1;
10669 return 0;
10672 return 1;
10673 #endif /* 0 */
10677 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
10678 non-zero means only WINDOW is redisplayed in redisplay_internal.
10679 TEMP_SCROLL_STEP has the same meaning as scroll_step, and is used
10680 in redisplay_window to bring a partially visible line into view in
10681 the case that only the cursor has moved.
10683 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
10684 last screen line's vertical height extends past the end of the screen.
10686 Value is
10688 1 if scrolling succeeded
10690 0 if scrolling didn't find point.
10692 -1 if new fonts have been loaded so that we must interrupt
10693 redisplay, adjust glyph matrices, and try again. */
10695 enum
10697 SCROLLING_SUCCESS,
10698 SCROLLING_FAILED,
10699 SCROLLING_NEED_LARGER_MATRICES
10702 static int
10703 try_scrolling (window, just_this_one_p, scroll_conservatively,
10704 scroll_step, temp_scroll_step, last_line_misfit)
10705 Lisp_Object window;
10706 int just_this_one_p;
10707 EMACS_INT scroll_conservatively, scroll_step;
10708 int temp_scroll_step;
10709 int last_line_misfit;
10711 struct window *w = XWINDOW (window);
10712 struct frame *f = XFRAME (w->frame);
10713 struct text_pos scroll_margin_pos;
10714 struct text_pos pos;
10715 struct text_pos startp;
10716 struct it it;
10717 Lisp_Object window_end;
10718 int this_scroll_margin;
10719 int dy = 0;
10720 int scroll_max;
10721 int rc;
10722 int amount_to_scroll = 0;
10723 Lisp_Object aggressive;
10724 int height;
10725 int end_scroll_margin;
10727 #if GLYPH_DEBUG
10728 debug_method_add (w, "try_scrolling");
10729 #endif
10731 SET_TEXT_POS_FROM_MARKER (startp, w->start);
10733 /* Compute scroll margin height in pixels. We scroll when point is
10734 within this distance from the top or bottom of the window. */
10735 if (scroll_margin > 0)
10737 this_scroll_margin = min (scroll_margin, XINT (w->height) / 4);
10738 this_scroll_margin *= CANON_Y_UNIT (f);
10740 else
10741 this_scroll_margin = 0;
10743 /* Compute how much we should try to scroll maximally to bring point
10744 into view. */
10745 if (scroll_step || scroll_conservatively || temp_scroll_step)
10746 scroll_max = max (scroll_step,
10747 max (scroll_conservatively, temp_scroll_step));
10748 else if (NUMBERP (current_buffer->scroll_down_aggressively)
10749 || NUMBERP (current_buffer->scroll_up_aggressively))
10750 /* We're trying to scroll because of aggressive scrolling
10751 but no scroll_step is set. Choose an arbitrary one. Maybe
10752 there should be a variable for this. */
10753 scroll_max = 10;
10754 else
10755 scroll_max = 0;
10756 scroll_max *= CANON_Y_UNIT (f);
10758 /* Decide whether we have to scroll down. Start at the window end
10759 and move this_scroll_margin up to find the position of the scroll
10760 margin. */
10761 window_end = Fwindow_end (window, Qt);
10763 too_near_end:
10765 CHARPOS (scroll_margin_pos) = XINT (window_end);
10766 BYTEPOS (scroll_margin_pos) = CHAR_TO_BYTE (CHARPOS (scroll_margin_pos));
10768 end_scroll_margin = this_scroll_margin + !!last_line_misfit;
10769 if (end_scroll_margin)
10771 start_display (&it, w, scroll_margin_pos);
10772 move_it_vertically (&it, - end_scroll_margin);
10773 scroll_margin_pos = it.current.pos;
10776 if (PT >= CHARPOS (scroll_margin_pos))
10778 int y0;
10780 /* Point is in the scroll margin at the bottom of the window, or
10781 below. Compute a new window start that makes point visible. */
10783 /* Compute the distance from the scroll margin to PT.
10784 Give up if the distance is greater than scroll_max. */
10785 start_display (&it, w, scroll_margin_pos);
10786 y0 = it.current_y;
10787 move_it_to (&it, PT, 0, it.last_visible_y, -1,
10788 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
10790 /* To make point visible, we have to move the window start
10791 down so that the line the cursor is in is visible, which
10792 means we have to add in the height of the cursor line. */
10793 dy = line_bottom_y (&it) - y0;
10795 if (dy > scroll_max)
10796 return SCROLLING_FAILED;
10798 /* Move the window start down. If scrolling conservatively,
10799 move it just enough down to make point visible. If
10800 scroll_step is set, move it down by scroll_step. */
10801 start_display (&it, w, startp);
10803 if (scroll_conservatively)
10804 /* Set AMOUNT_TO_SCROLL to at least one line,
10805 and at most scroll_conservatively lines. */
10806 amount_to_scroll
10807 = min (max (dy, CANON_Y_UNIT (f)),
10808 CANON_Y_UNIT (f) * scroll_conservatively);
10809 else if (scroll_step || temp_scroll_step)
10810 amount_to_scroll = scroll_max;
10811 else
10813 aggressive = current_buffer->scroll_up_aggressively;
10814 height = (WINDOW_DISPLAY_HEIGHT_NO_MODE_LINE (w)
10815 - WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w));
10816 if (NUMBERP (aggressive))
10817 amount_to_scroll = XFLOATINT (aggressive) * height;
10820 if (amount_to_scroll <= 0)
10821 return SCROLLING_FAILED;
10823 /* If moving by amount_to_scroll leaves STARTP unchanged,
10824 move it down one screen line. */
10826 move_it_vertically (&it, amount_to_scroll);
10827 if (CHARPOS (it.current.pos) == CHARPOS (startp))
10828 move_it_by_lines (&it, 1, 1);
10829 startp = it.current.pos;
10831 else
10833 /* See if point is inside the scroll margin at the top of the
10834 window. */
10835 scroll_margin_pos = startp;
10836 if (this_scroll_margin)
10838 start_display (&it, w, startp);
10839 move_it_vertically (&it, this_scroll_margin);
10840 scroll_margin_pos = it.current.pos;
10843 if (PT < CHARPOS (scroll_margin_pos))
10845 /* Point is in the scroll margin at the top of the window or
10846 above what is displayed in the window. */
10847 int y0;
10849 /* Compute the vertical distance from PT to the scroll
10850 margin position. Give up if distance is greater than
10851 scroll_max. */
10852 SET_TEXT_POS (pos, PT, PT_BYTE);
10853 start_display (&it, w, pos);
10854 y0 = it.current_y;
10855 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
10856 it.last_visible_y, -1,
10857 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
10858 dy = it.current_y - y0;
10859 if (dy > scroll_max)
10860 return SCROLLING_FAILED;
10862 /* Compute new window start. */
10863 start_display (&it, w, startp);
10865 if (scroll_conservatively)
10866 amount_to_scroll =
10867 max (dy, CANON_Y_UNIT (f) * max (scroll_step, temp_scroll_step));
10868 else if (scroll_step || temp_scroll_step)
10869 amount_to_scroll = scroll_max;
10870 else
10872 aggressive = current_buffer->scroll_down_aggressively;
10873 height = (WINDOW_DISPLAY_HEIGHT_NO_MODE_LINE (w)
10874 - WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w));
10875 if (NUMBERP (aggressive))
10876 amount_to_scroll = XFLOATINT (aggressive) * height;
10879 if (amount_to_scroll <= 0)
10880 return SCROLLING_FAILED;
10882 move_it_vertically (&it, - amount_to_scroll);
10883 startp = it.current.pos;
10887 /* Run window scroll functions. */
10888 startp = run_window_scroll_functions (window, startp);
10890 /* Display the window. Give up if new fonts are loaded, or if point
10891 doesn't appear. */
10892 if (!try_window (window, startp))
10893 rc = SCROLLING_NEED_LARGER_MATRICES;
10894 else if (w->cursor.vpos < 0)
10896 clear_glyph_matrix (w->desired_matrix);
10897 rc = SCROLLING_FAILED;
10899 else
10901 /* Maybe forget recorded base line for line number display. */
10902 if (!just_this_one_p
10903 || current_buffer->clip_changed
10904 || BEG_UNCHANGED < CHARPOS (startp))
10905 w->base_line_number = Qnil;
10907 /* If cursor ends up on a partially visible line,
10908 treat that as being off the bottom of the screen. */
10909 if (! make_cursor_line_fully_visible (w))
10911 clear_glyph_matrix (w->desired_matrix);
10912 last_line_misfit = 1;
10913 goto too_near_end;
10915 rc = SCROLLING_SUCCESS;
10918 return rc;
10922 /* Compute a suitable window start for window W if display of W starts
10923 on a continuation line. Value is non-zero if a new window start
10924 was computed.
10926 The new window start will be computed, based on W's width, starting
10927 from the start of the continued line. It is the start of the
10928 screen line with the minimum distance from the old start W->start. */
10930 static int
10931 compute_window_start_on_continuation_line (w)
10932 struct window *w;
10934 struct text_pos pos, start_pos;
10935 int window_start_changed_p = 0;
10937 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
10939 /* If window start is on a continuation line... Window start may be
10940 < BEGV in case there's invisible text at the start of the
10941 buffer (M-x rmail, for example). */
10942 if (CHARPOS (start_pos) > BEGV
10943 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
10945 struct it it;
10946 struct glyph_row *row;
10948 /* Handle the case that the window start is out of range. */
10949 if (CHARPOS (start_pos) < BEGV)
10950 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
10951 else if (CHARPOS (start_pos) > ZV)
10952 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
10954 /* Find the start of the continued line. This should be fast
10955 because scan_buffer is fast (newline cache). */
10956 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
10957 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
10958 row, DEFAULT_FACE_ID);
10959 reseat_at_previous_visible_line_start (&it);
10961 /* If the line start is "too far" away from the window start,
10962 say it takes too much time to compute a new window start. */
10963 if (CHARPOS (start_pos) - IT_CHARPOS (it)
10964 < XFASTINT (w->height) * XFASTINT (w->width))
10966 int min_distance, distance;
10968 /* Move forward by display lines to find the new window
10969 start. If window width was enlarged, the new start can
10970 be expected to be > the old start. If window width was
10971 decreased, the new window start will be < the old start.
10972 So, we're looking for the display line start with the
10973 minimum distance from the old window start. */
10974 pos = it.current.pos;
10975 min_distance = INFINITY;
10976 while ((distance = abs (CHARPOS (start_pos) - IT_CHARPOS (it))),
10977 distance < min_distance)
10979 min_distance = distance;
10980 pos = it.current.pos;
10981 move_it_by_lines (&it, 1, 0);
10984 /* Set the window start there. */
10985 SET_MARKER_FROM_TEXT_POS (w->start, pos);
10986 window_start_changed_p = 1;
10990 return window_start_changed_p;
10994 /* Try cursor movement in case text has not changed in window WINDOW,
10995 with window start STARTP. Value is
10997 CURSOR_MOVEMENT_SUCCESS if successful
10999 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
11001 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
11002 display. *SCROLL_STEP is set to 1, under certain circumstances, if
11003 we want to scroll as if scroll-step were set to 1. See the code.
11005 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
11006 which case we have to abort this redisplay, and adjust matrices
11007 first. */
11009 enum
11011 CURSOR_MOVEMENT_SUCCESS,
11012 CURSOR_MOVEMENT_CANNOT_BE_USED,
11013 CURSOR_MOVEMENT_MUST_SCROLL,
11014 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
11017 static int
11018 try_cursor_movement (window, startp, scroll_step)
11019 Lisp_Object window;
11020 struct text_pos startp;
11021 int *scroll_step;
11023 struct window *w = XWINDOW (window);
11024 struct frame *f = XFRAME (w->frame);
11025 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
11027 #if GLYPH_DEBUG
11028 if (inhibit_try_cursor_movement)
11029 return rc;
11030 #endif
11032 /* Handle case where text has not changed, only point, and it has
11033 not moved off the frame. */
11034 if (/* Point may be in this window. */
11035 PT >= CHARPOS (startp)
11036 /* Selective display hasn't changed. */
11037 && !current_buffer->clip_changed
11038 /* Function force-mode-line-update is used to force a thorough
11039 redisplay. It sets either windows_or_buffers_changed or
11040 update_mode_lines. So don't take a shortcut here for these
11041 cases. */
11042 && !update_mode_lines
11043 && !windows_or_buffers_changed
11044 && !cursor_type_changed
11045 /* Can't use this case if highlighting a region. When a
11046 region exists, cursor movement has to do more than just
11047 set the cursor. */
11048 && !(!NILP (Vtransient_mark_mode)
11049 && !NILP (current_buffer->mark_active))
11050 && NILP (w->region_showing)
11051 && NILP (Vshow_trailing_whitespace)
11052 /* Right after splitting windows, last_point may be nil. */
11053 && INTEGERP (w->last_point)
11054 /* This code is not used for mini-buffer for the sake of the case
11055 of redisplaying to replace an echo area message; since in
11056 that case the mini-buffer contents per se are usually
11057 unchanged. This code is of no real use in the mini-buffer
11058 since the handling of this_line_start_pos, etc., in redisplay
11059 handles the same cases. */
11060 && !EQ (window, minibuf_window)
11061 /* When splitting windows or for new windows, it happens that
11062 redisplay is called with a nil window_end_vpos or one being
11063 larger than the window. This should really be fixed in
11064 window.c. I don't have this on my list, now, so we do
11065 approximately the same as the old redisplay code. --gerd. */
11066 && INTEGERP (w->window_end_vpos)
11067 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
11068 && (FRAME_WINDOW_P (f)
11069 || !MARKERP (Voverlay_arrow_position)
11070 || current_buffer != XMARKER (Voverlay_arrow_position)->buffer))
11072 int this_scroll_margin;
11073 struct glyph_row *row = NULL;
11075 #if GLYPH_DEBUG
11076 debug_method_add (w, "cursor movement");
11077 #endif
11079 /* Scroll if point within this distance from the top or bottom
11080 of the window. This is a pixel value. */
11081 this_scroll_margin = max (0, scroll_margin);
11082 this_scroll_margin = min (this_scroll_margin, XFASTINT (w->height) / 4);
11083 this_scroll_margin *= CANON_Y_UNIT (f);
11085 /* Start with the row the cursor was displayed during the last
11086 not paused redisplay. Give up if that row is not valid. */
11087 if (w->last_cursor.vpos < 0
11088 || w->last_cursor.vpos >= w->current_matrix->nrows)
11089 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11090 else
11092 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
11093 if (row->mode_line_p)
11094 ++row;
11095 if (!row->enabled_p)
11096 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11099 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
11101 int scroll_p = 0;
11102 int last_y = window_text_bottom_y (w) - this_scroll_margin;
11104 if (PT > XFASTINT (w->last_point))
11106 /* Point has moved forward. */
11107 while (MATRIX_ROW_END_CHARPOS (row) < PT
11108 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
11110 xassert (row->enabled_p);
11111 ++row;
11114 /* The end position of a row equals the start position
11115 of the next row. If PT is there, we would rather
11116 display it in the next line. */
11117 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
11118 && MATRIX_ROW_END_CHARPOS (row) == PT
11119 && !cursor_row_p (w, row))
11120 ++row;
11122 /* If within the scroll margin, scroll. Note that
11123 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
11124 the next line would be drawn, and that
11125 this_scroll_margin can be zero. */
11126 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
11127 || PT > MATRIX_ROW_END_CHARPOS (row)
11128 /* Line is completely visible last line in window
11129 and PT is to be set in the next line. */
11130 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
11131 && PT == MATRIX_ROW_END_CHARPOS (row)
11132 && !row->ends_at_zv_p
11133 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
11134 scroll_p = 1;
11136 else if (PT < XFASTINT (w->last_point))
11138 /* Cursor has to be moved backward. Note that PT >=
11139 CHARPOS (startp) because of the outer
11140 if-statement. */
11141 while (!row->mode_line_p
11142 && (MATRIX_ROW_START_CHARPOS (row) > PT
11143 || (MATRIX_ROW_START_CHARPOS (row) == PT
11144 && MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)))
11145 && (row->y > this_scroll_margin
11146 || CHARPOS (startp) == BEGV))
11148 xassert (row->enabled_p);
11149 --row;
11152 /* Consider the following case: Window starts at BEGV,
11153 there is invisible, intangible text at BEGV, so that
11154 display starts at some point START > BEGV. It can
11155 happen that we are called with PT somewhere between
11156 BEGV and START. Try to handle that case. */
11157 if (row < w->current_matrix->rows
11158 || row->mode_line_p)
11160 row = w->current_matrix->rows;
11161 if (row->mode_line_p)
11162 ++row;
11165 /* Due to newlines in overlay strings, we may have to
11166 skip forward over overlay strings. */
11167 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
11168 && MATRIX_ROW_END_CHARPOS (row) == PT
11169 && !cursor_row_p (w, row))
11170 ++row;
11172 /* If within the scroll margin, scroll. */
11173 if (row->y < this_scroll_margin
11174 && CHARPOS (startp) != BEGV)
11175 scroll_p = 1;
11178 if (PT < MATRIX_ROW_START_CHARPOS (row)
11179 || PT > MATRIX_ROW_END_CHARPOS (row))
11181 /* if PT is not in the glyph row, give up. */
11182 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11184 else if (MATRIX_ROW_PARTIALLY_VISIBLE_P (row))
11186 if (PT == MATRIX_ROW_END_CHARPOS (row)
11187 && !row->ends_at_zv_p
11188 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
11189 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11190 else if (row->height > window_box_height (w))
11192 /* If we end up in a partially visible line, let's
11193 make it fully visible, except when it's taller
11194 than the window, in which case we can't do much
11195 about it. */
11196 *scroll_step = 1;
11197 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11199 else
11201 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11202 if (!make_cursor_line_fully_visible (w))
11203 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11204 else
11205 rc = CURSOR_MOVEMENT_SUCCESS;
11208 else if (scroll_p)
11209 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11210 else
11212 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11213 rc = CURSOR_MOVEMENT_SUCCESS;
11218 return rc;
11221 void
11222 set_vertical_scroll_bar (w)
11223 struct window *w;
11225 int start, end, whole;
11227 /* Calculate the start and end positions for the current window.
11228 At some point, it would be nice to choose between scrollbars
11229 which reflect the whole buffer size, with special markers
11230 indicating narrowing, and scrollbars which reflect only the
11231 visible region.
11233 Note that mini-buffers sometimes aren't displaying any text. */
11234 if (!MINI_WINDOW_P (w)
11235 || (w == XWINDOW (minibuf_window)
11236 && NILP (echo_area_buffer[0])))
11238 struct buffer *buf = XBUFFER (w->buffer);
11239 whole = BUF_ZV (buf) - BUF_BEGV (buf);
11240 start = marker_position (w->start) - BUF_BEGV (buf);
11241 /* I don't think this is guaranteed to be right. For the
11242 moment, we'll pretend it is. */
11243 end = BUF_Z (buf) - XFASTINT (w->window_end_pos) - BUF_BEGV (buf);
11245 if (end < start)
11246 end = start;
11247 if (whole < (end - start))
11248 whole = end - start;
11250 else
11251 start = end = whole = 0;
11253 /* Indicate what this scroll bar ought to be displaying now. */
11254 set_vertical_scroll_bar_hook (w, end - start, whole, start);
11257 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
11258 selected_window is redisplayed.
11260 We can return without actually redisplaying the window if
11261 fonts_changed_p is nonzero. In that case, redisplay_internal will
11262 retry. */
11264 static void
11265 redisplay_window (window, just_this_one_p)
11266 Lisp_Object window;
11267 int just_this_one_p;
11269 struct window *w = XWINDOW (window);
11270 struct frame *f = XFRAME (w->frame);
11271 struct buffer *buffer = XBUFFER (w->buffer);
11272 struct buffer *old = current_buffer;
11273 struct text_pos lpoint, opoint, startp;
11274 int update_mode_line;
11275 int tem;
11276 struct it it;
11277 /* Record it now because it's overwritten. */
11278 int current_matrix_up_to_date_p = 0;
11279 /* This is less strict than current_matrix_up_to_date_p.
11280 It indictes that the buffer contents and narrowing are unchanged. */
11281 int buffer_unchanged_p = 0;
11282 int temp_scroll_step = 0;
11283 int count = SPECPDL_INDEX ();
11284 int rc;
11285 int centering_position;
11286 int last_line_misfit = 0;
11288 SET_TEXT_POS (lpoint, PT, PT_BYTE);
11289 opoint = lpoint;
11291 /* W must be a leaf window here. */
11292 xassert (!NILP (w->buffer));
11293 #if GLYPH_DEBUG
11294 *w->desired_matrix->method = 0;
11295 #endif
11297 specbind (Qinhibit_point_motion_hooks, Qt);
11299 reconsider_clip_changes (w, buffer);
11301 /* Has the mode line to be updated? */
11302 update_mode_line = (!NILP (w->update_mode_line)
11303 || update_mode_lines
11304 || buffer->clip_changed
11305 || buffer->prevent_redisplay_optimizations_p);
11307 if (MINI_WINDOW_P (w))
11309 if (w == XWINDOW (echo_area_window)
11310 && !NILP (echo_area_buffer[0]))
11312 if (update_mode_line)
11313 /* We may have to update a tty frame's menu bar or a
11314 tool-bar. Example `M-x C-h C-h C-g'. */
11315 goto finish_menu_bars;
11316 else
11317 /* We've already displayed the echo area glyphs in this window. */
11318 goto finish_scroll_bars;
11320 else if ((w != XWINDOW (minibuf_window)
11321 || minibuf_level == 0)
11322 /* When buffer is nonempty, redisplay window normally. */
11323 && BUF_Z (XBUFFER (w->buffer)) == BUF_BEG (XBUFFER (w->buffer))
11324 /* Quail displays non-mini buffers in minibuffer window.
11325 In that case, redisplay the window normally. */
11326 && !NILP (Fmemq (w->buffer, Vminibuffer_list)))
11328 /* W is a mini-buffer window, but it's not active, so clear
11329 it. */
11330 int yb = window_text_bottom_y (w);
11331 struct glyph_row *row;
11332 int y;
11334 for (y = 0, row = w->desired_matrix->rows;
11335 y < yb;
11336 y += row->height, ++row)
11337 blank_row (w, row, y);
11338 goto finish_scroll_bars;
11341 clear_glyph_matrix (w->desired_matrix);
11344 /* Otherwise set up data on this window; select its buffer and point
11345 value. */
11346 /* Really select the buffer, for the sake of buffer-local
11347 variables. */
11348 set_buffer_internal_1 (XBUFFER (w->buffer));
11349 SET_TEXT_POS (opoint, PT, PT_BYTE);
11351 current_matrix_up_to_date_p
11352 = (!NILP (w->window_end_valid)
11353 && !current_buffer->clip_changed
11354 && !current_buffer->prevent_redisplay_optimizations_p
11355 && XFASTINT (w->last_modified) >= MODIFF
11356 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
11358 buffer_unchanged_p
11359 = (!NILP (w->window_end_valid)
11360 && !current_buffer->clip_changed
11361 && XFASTINT (w->last_modified) >= MODIFF
11362 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
11364 /* When windows_or_buffers_changed is non-zero, we can't rely on
11365 the window end being valid, so set it to nil there. */
11366 if (windows_or_buffers_changed)
11368 /* If window starts on a continuation line, maybe adjust the
11369 window start in case the window's width changed. */
11370 if (XMARKER (w->start)->buffer == current_buffer)
11371 compute_window_start_on_continuation_line (w);
11373 w->window_end_valid = Qnil;
11376 /* Some sanity checks. */
11377 CHECK_WINDOW_END (w);
11378 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
11379 abort ();
11380 if (BYTEPOS (opoint) < CHARPOS (opoint))
11381 abort ();
11383 /* If %c is in mode line, update it if needed. */
11384 if (!NILP (w->column_number_displayed)
11385 /* This alternative quickly identifies a common case
11386 where no change is needed. */
11387 && !(PT == XFASTINT (w->last_point)
11388 && XFASTINT (w->last_modified) >= MODIFF
11389 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
11390 && (XFASTINT (w->column_number_displayed)
11391 != (int) current_column ())) /* iftc */
11392 update_mode_line = 1;
11394 /* Count number of windows showing the selected buffer. An indirect
11395 buffer counts as its base buffer. */
11396 if (!just_this_one_p)
11398 struct buffer *current_base, *window_base;
11399 current_base = current_buffer;
11400 window_base = XBUFFER (XWINDOW (selected_window)->buffer);
11401 if (current_base->base_buffer)
11402 current_base = current_base->base_buffer;
11403 if (window_base->base_buffer)
11404 window_base = window_base->base_buffer;
11405 if (current_base == window_base)
11406 buffer_shared++;
11409 /* Point refers normally to the selected window. For any other
11410 window, set up appropriate value. */
11411 if (!EQ (window, selected_window))
11413 int new_pt = XMARKER (w->pointm)->charpos;
11414 int new_pt_byte = marker_byte_position (w->pointm);
11415 if (new_pt < BEGV)
11417 new_pt = BEGV;
11418 new_pt_byte = BEGV_BYTE;
11419 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
11421 else if (new_pt > (ZV - 1))
11423 new_pt = ZV;
11424 new_pt_byte = ZV_BYTE;
11425 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
11428 /* We don't use SET_PT so that the point-motion hooks don't run. */
11429 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
11432 /* If any of the character widths specified in the display table
11433 have changed, invalidate the width run cache. It's true that
11434 this may be a bit late to catch such changes, but the rest of
11435 redisplay goes (non-fatally) haywire when the display table is
11436 changed, so why should we worry about doing any better? */
11437 if (current_buffer->width_run_cache)
11439 struct Lisp_Char_Table *disptab = buffer_display_table ();
11441 if (! disptab_matches_widthtab (disptab,
11442 XVECTOR (current_buffer->width_table)))
11444 invalidate_region_cache (current_buffer,
11445 current_buffer->width_run_cache,
11446 BEG, Z);
11447 recompute_width_table (current_buffer, disptab);
11451 /* If window-start is screwed up, choose a new one. */
11452 if (XMARKER (w->start)->buffer != current_buffer)
11453 goto recenter;
11455 SET_TEXT_POS_FROM_MARKER (startp, w->start);
11457 /* If someone specified a new starting point but did not insist,
11458 check whether it can be used. */
11459 if (!NILP (w->optional_new_start)
11460 && CHARPOS (startp) >= BEGV
11461 && CHARPOS (startp) <= ZV)
11463 w->optional_new_start = Qnil;
11464 start_display (&it, w, startp);
11465 move_it_to (&it, PT, 0, it.last_visible_y, -1,
11466 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
11467 if (IT_CHARPOS (it) == PT)
11468 w->force_start = Qt;
11471 /* Handle case where place to start displaying has been specified,
11472 unless the specified location is outside the accessible range. */
11473 if (!NILP (w->force_start)
11474 || w->frozen_window_start_p)
11476 /* We set this later on if we have to adjust point. */
11477 int new_vpos = -1;
11479 w->force_start = Qnil;
11480 w->vscroll = 0;
11481 w->window_end_valid = Qnil;
11483 /* Forget any recorded base line for line number display. */
11484 if (!buffer_unchanged_p)
11485 w->base_line_number = Qnil;
11487 /* Redisplay the mode line. Select the buffer properly for that.
11488 Also, run the hook window-scroll-functions
11489 because we have scrolled. */
11490 /* Note, we do this after clearing force_start because
11491 if there's an error, it is better to forget about force_start
11492 than to get into an infinite loop calling the hook functions
11493 and having them get more errors. */
11494 if (!update_mode_line
11495 || ! NILP (Vwindow_scroll_functions))
11497 update_mode_line = 1;
11498 w->update_mode_line = Qt;
11499 startp = run_window_scroll_functions (window, startp);
11502 w->last_modified = make_number (0);
11503 w->last_overlay_modified = make_number (0);
11504 if (CHARPOS (startp) < BEGV)
11505 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
11506 else if (CHARPOS (startp) > ZV)
11507 SET_TEXT_POS (startp, ZV, ZV_BYTE);
11509 /* Redisplay, then check if cursor has been set during the
11510 redisplay. Give up if new fonts were loaded. */
11511 if (!try_window (window, startp))
11513 w->force_start = Qt;
11514 clear_glyph_matrix (w->desired_matrix);
11515 goto need_larger_matrices;
11518 if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
11520 /* If point does not appear, try to move point so it does
11521 appear. The desired matrix has been built above, so we
11522 can use it here. */
11523 new_vpos = window_box_height (w) / 2;
11526 if (!make_cursor_line_fully_visible (w))
11528 /* Point does appear, but on a line partly visible at end of window.
11529 Move it back to a fully-visible line. */
11530 new_vpos = window_box_height (w);
11533 /* If we need to move point for either of the above reasons,
11534 now actually do it. */
11535 if (new_vpos >= 0)
11537 struct glyph_row *row;
11539 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
11540 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
11541 ++row;
11543 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
11544 MATRIX_ROW_START_BYTEPOS (row));
11546 if (w != XWINDOW (selected_window))
11547 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
11548 else if (current_buffer == old)
11549 SET_TEXT_POS (lpoint, PT, PT_BYTE);
11551 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
11553 /* If we are highlighting the region, then we just changed
11554 the region, so redisplay to show it. */
11555 if (!NILP (Vtransient_mark_mode)
11556 && !NILP (current_buffer->mark_active))
11558 clear_glyph_matrix (w->desired_matrix);
11559 if (!try_window (window, startp))
11560 goto need_larger_matrices;
11564 #if GLYPH_DEBUG
11565 debug_method_add (w, "forced window start");
11566 #endif
11567 goto done;
11570 /* Handle case where text has not changed, only point, and it has
11571 not moved off the frame, and we are not retrying after hscroll.
11572 (current_matrix_up_to_date_p is nonzero when retrying.) */
11573 if (current_matrix_up_to_date_p
11574 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
11575 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
11577 switch (rc)
11579 case CURSOR_MOVEMENT_SUCCESS:
11580 goto done;
11582 #if 0 /* try_cursor_movement never returns this value. */
11583 case CURSOR_MOVEMENT_NEED_LARGER_MATRICES:
11584 goto need_larger_matrices;
11585 #endif
11587 case CURSOR_MOVEMENT_MUST_SCROLL:
11588 goto try_to_scroll;
11590 default:
11591 abort ();
11594 /* If current starting point was originally the beginning of a line
11595 but no longer is, find a new starting point. */
11596 else if (!NILP (w->start_at_line_beg)
11597 && !(CHARPOS (startp) <= BEGV
11598 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
11600 #if GLYPH_DEBUG
11601 debug_method_add (w, "recenter 1");
11602 #endif
11603 goto recenter;
11606 /* Try scrolling with try_window_id. Value is > 0 if update has
11607 been done, it is -1 if we know that the same window start will
11608 not work. It is 0 if unsuccessful for some other reason. */
11609 else if ((tem = try_window_id (w)) != 0)
11611 #if GLYPH_DEBUG
11612 debug_method_add (w, "try_window_id %d", tem);
11613 #endif
11615 if (fonts_changed_p)
11616 goto need_larger_matrices;
11617 if (tem > 0)
11618 goto done;
11620 /* Otherwise try_window_id has returned -1 which means that we
11621 don't want the alternative below this comment to execute. */
11623 else if (CHARPOS (startp) >= BEGV
11624 && CHARPOS (startp) <= ZV
11625 && PT >= CHARPOS (startp)
11626 && (CHARPOS (startp) < ZV
11627 /* Avoid starting at end of buffer. */
11628 || CHARPOS (startp) == BEGV
11629 || (XFASTINT (w->last_modified) >= MODIFF
11630 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)))
11632 #if GLYPH_DEBUG
11633 debug_method_add (w, "same window start");
11634 #endif
11636 /* Try to redisplay starting at same place as before.
11637 If point has not moved off frame, accept the results. */
11638 if (!current_matrix_up_to_date_p
11639 /* Don't use try_window_reusing_current_matrix in this case
11640 because a window scroll function can have changed the
11641 buffer. */
11642 || !NILP (Vwindow_scroll_functions)
11643 || MINI_WINDOW_P (w)
11644 || !try_window_reusing_current_matrix (w))
11646 IF_DEBUG (debug_method_add (w, "1"));
11647 try_window (window, startp);
11650 if (fonts_changed_p)
11651 goto need_larger_matrices;
11653 if (w->cursor.vpos >= 0)
11655 if (!just_this_one_p
11656 || current_buffer->clip_changed
11657 || BEG_UNCHANGED < CHARPOS (startp))
11658 /* Forget any recorded base line for line number display. */
11659 w->base_line_number = Qnil;
11661 if (!make_cursor_line_fully_visible (w))
11663 clear_glyph_matrix (w->desired_matrix);
11664 last_line_misfit = 1;
11666 /* Drop through and scroll. */
11667 else
11668 goto done;
11670 else
11671 clear_glyph_matrix (w->desired_matrix);
11674 try_to_scroll:
11676 w->last_modified = make_number (0);
11677 w->last_overlay_modified = make_number (0);
11679 /* Redisplay the mode line. Select the buffer properly for that. */
11680 if (!update_mode_line)
11682 update_mode_line = 1;
11683 w->update_mode_line = Qt;
11686 /* Try to scroll by specified few lines. */
11687 if ((scroll_conservatively
11688 || scroll_step
11689 || temp_scroll_step
11690 || NUMBERP (current_buffer->scroll_up_aggressively)
11691 || NUMBERP (current_buffer->scroll_down_aggressively))
11692 && !current_buffer->clip_changed
11693 && CHARPOS (startp) >= BEGV
11694 && CHARPOS (startp) <= ZV)
11696 /* The function returns -1 if new fonts were loaded, 1 if
11697 successful, 0 if not successful. */
11698 int rc = try_scrolling (window, just_this_one_p,
11699 scroll_conservatively,
11700 scroll_step,
11701 temp_scroll_step, last_line_misfit);
11702 switch (rc)
11704 case SCROLLING_SUCCESS:
11705 goto done;
11707 case SCROLLING_NEED_LARGER_MATRICES:
11708 goto need_larger_matrices;
11710 case SCROLLING_FAILED:
11711 break;
11713 default:
11714 abort ();
11718 /* Finally, just choose place to start which centers point */
11720 recenter:
11721 centering_position = window_box_height (w) / 2;
11723 point_at_top:
11724 /* Jump here with centering_position already set to 0. */
11726 #if GLYPH_DEBUG
11727 debug_method_add (w, "recenter");
11728 #endif
11730 /* w->vscroll = 0; */
11732 /* Forget any previously recorded base line for line number display. */
11733 if (!buffer_unchanged_p)
11734 w->base_line_number = Qnil;
11736 /* Move backward half the height of the window. */
11737 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
11738 it.current_y = it.last_visible_y;
11739 move_it_vertically_backward (&it, centering_position);
11740 xassert (IT_CHARPOS (it) >= BEGV);
11742 /* The function move_it_vertically_backward may move over more
11743 than the specified y-distance. If it->w is small, e.g. a
11744 mini-buffer window, we may end up in front of the window's
11745 display area. Start displaying at the start of the line
11746 containing PT in this case. */
11747 if (it.current_y <= 0)
11749 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
11750 move_it_vertically (&it, 0);
11751 xassert (IT_CHARPOS (it) <= PT);
11752 it.current_y = 0;
11755 it.current_x = it.hpos = 0;
11757 /* Set startp here explicitly in case that helps avoid an infinite loop
11758 in case the window-scroll-functions functions get errors. */
11759 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
11761 /* Run scroll hooks. */
11762 startp = run_window_scroll_functions (window, it.current.pos);
11764 /* Redisplay the window. */
11765 if (!current_matrix_up_to_date_p
11766 || windows_or_buffers_changed
11767 || cursor_type_changed
11768 /* Don't use try_window_reusing_current_matrix in this case
11769 because it can have changed the buffer. */
11770 || !NILP (Vwindow_scroll_functions)
11771 || !just_this_one_p
11772 || MINI_WINDOW_P (w)
11773 || !try_window_reusing_current_matrix (w))
11774 try_window (window, startp);
11776 /* If new fonts have been loaded (due to fontsets), give up. We
11777 have to start a new redisplay since we need to re-adjust glyph
11778 matrices. */
11779 if (fonts_changed_p)
11780 goto need_larger_matrices;
11782 /* If cursor did not appear assume that the middle of the window is
11783 in the first line of the window. Do it again with the next line.
11784 (Imagine a window of height 100, displaying two lines of height
11785 60. Moving back 50 from it->last_visible_y will end in the first
11786 line.) */
11787 if (w->cursor.vpos < 0)
11789 if (!NILP (w->window_end_valid)
11790 && PT >= Z - XFASTINT (w->window_end_pos))
11792 clear_glyph_matrix (w->desired_matrix);
11793 move_it_by_lines (&it, 1, 0);
11794 try_window (window, it.current.pos);
11796 else if (PT < IT_CHARPOS (it))
11798 clear_glyph_matrix (w->desired_matrix);
11799 move_it_by_lines (&it, -1, 0);
11800 try_window (window, it.current.pos);
11802 else
11804 /* Not much we can do about it. */
11808 /* Consider the following case: Window starts at BEGV, there is
11809 invisible, intangible text at BEGV, so that display starts at
11810 some point START > BEGV. It can happen that we are called with
11811 PT somewhere between BEGV and START. Try to handle that case. */
11812 if (w->cursor.vpos < 0)
11814 struct glyph_row *row = w->current_matrix->rows;
11815 if (row->mode_line_p)
11816 ++row;
11817 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11820 if (!make_cursor_line_fully_visible (w))
11822 /* If vscroll is enabled, disable it and try again. */
11823 if (w->vscroll)
11825 w->vscroll = 0;
11826 clear_glyph_matrix (w->desired_matrix);
11827 goto recenter;
11830 /* If centering point failed to make the whole line visible,
11831 put point at the top instead. That has to make the whole line
11832 visible, if it can be done. */
11833 centering_position = 0;
11834 goto point_at_top;
11837 done:
11839 SET_TEXT_POS_FROM_MARKER (startp, w->start);
11840 w->start_at_line_beg = ((CHARPOS (startp) == BEGV
11841 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n')
11842 ? Qt : Qnil);
11844 /* Display the mode line, if we must. */
11845 if ((update_mode_line
11846 /* If window not full width, must redo its mode line
11847 if (a) the window to its side is being redone and
11848 (b) we do a frame-based redisplay. This is a consequence
11849 of how inverted lines are drawn in frame-based redisplay. */
11850 || (!just_this_one_p
11851 && !FRAME_WINDOW_P (f)
11852 && !WINDOW_FULL_WIDTH_P (w))
11853 /* Line number to display. */
11854 || INTEGERP (w->base_line_pos)
11855 /* Column number is displayed and different from the one displayed. */
11856 || (!NILP (w->column_number_displayed)
11857 && (XFASTINT (w->column_number_displayed)
11858 != (int) current_column ()))) /* iftc */
11859 /* This means that the window has a mode line. */
11860 && (WINDOW_WANTS_MODELINE_P (w)
11861 || WINDOW_WANTS_HEADER_LINE_P (w)))
11863 display_mode_lines (w);
11865 /* If mode line height has changed, arrange for a thorough
11866 immediate redisplay using the correct mode line height. */
11867 if (WINDOW_WANTS_MODELINE_P (w)
11868 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
11870 fonts_changed_p = 1;
11871 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
11872 = DESIRED_MODE_LINE_HEIGHT (w);
11875 /* If top line height has changed, arrange for a thorough
11876 immediate redisplay using the correct mode line height. */
11877 if (WINDOW_WANTS_HEADER_LINE_P (w)
11878 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
11880 fonts_changed_p = 1;
11881 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
11882 = DESIRED_HEADER_LINE_HEIGHT (w);
11885 if (fonts_changed_p)
11886 goto need_larger_matrices;
11889 if (!line_number_displayed
11890 && !BUFFERP (w->base_line_pos))
11892 w->base_line_pos = Qnil;
11893 w->base_line_number = Qnil;
11896 finish_menu_bars:
11898 /* When we reach a frame's selected window, redo the frame's menu bar. */
11899 if (update_mode_line
11900 && EQ (FRAME_SELECTED_WINDOW (f), window))
11902 int redisplay_menu_p = 0;
11903 int redisplay_tool_bar_p = 0;
11905 if (FRAME_WINDOW_P (f))
11907 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
11908 || defined (USE_GTK)
11909 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
11910 #else
11911 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
11912 #endif
11914 else
11915 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
11917 if (redisplay_menu_p)
11918 display_menu_bar (w);
11920 #ifdef HAVE_WINDOW_SYSTEM
11921 #ifdef USE_GTK
11922 redisplay_tool_bar_p = FRAME_EXTERNAL_TOOL_BAR (f);
11923 #else
11924 redisplay_tool_bar_p = WINDOWP (f->tool_bar_window)
11925 && (FRAME_TOOL_BAR_LINES (f) > 0
11926 || auto_resize_tool_bars_p);
11928 #endif
11930 if (redisplay_tool_bar_p)
11931 redisplay_tool_bar (f);
11932 #endif
11935 /* We go to this label, with fonts_changed_p nonzero,
11936 if it is necessary to try again using larger glyph matrices.
11937 We have to redeem the scroll bar even in this case,
11938 because the loop in redisplay_internal expects that. */
11939 need_larger_matrices:
11941 finish_scroll_bars:
11943 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f))
11945 /* Set the thumb's position and size. */
11946 set_vertical_scroll_bar (w);
11948 /* Note that we actually used the scroll bar attached to this
11949 window, so it shouldn't be deleted at the end of redisplay. */
11950 redeem_scroll_bar_hook (w);
11953 /* Restore current_buffer and value of point in it. */
11954 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
11955 set_buffer_internal_1 (old);
11956 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
11958 unbind_to (count, Qnil);
11962 /* Build the complete desired matrix of WINDOW with a window start
11963 buffer position POS. Value is non-zero if successful. It is zero
11964 if fonts were loaded during redisplay which makes re-adjusting
11965 glyph matrices necessary. */
11968 try_window (window, pos)
11969 Lisp_Object window;
11970 struct text_pos pos;
11972 struct window *w = XWINDOW (window);
11973 struct it it;
11974 struct glyph_row *last_text_row = NULL;
11976 /* Make POS the new window start. */
11977 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
11979 /* Mark cursor position as unknown. No overlay arrow seen. */
11980 w->cursor.vpos = -1;
11981 overlay_arrow_seen = 0;
11983 /* Initialize iterator and info to start at POS. */
11984 start_display (&it, w, pos);
11986 /* Display all lines of W. */
11987 while (it.current_y < it.last_visible_y)
11989 if (display_line (&it))
11990 last_text_row = it.glyph_row - 1;
11991 if (fonts_changed_p)
11992 return 0;
11995 /* If bottom moved off end of frame, change mode line percentage. */
11996 if (XFASTINT (w->window_end_pos) <= 0
11997 && Z != IT_CHARPOS (it))
11998 w->update_mode_line = Qt;
12000 /* Set window_end_pos to the offset of the last character displayed
12001 on the window from the end of current_buffer. Set
12002 window_end_vpos to its row number. */
12003 if (last_text_row)
12005 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
12006 w->window_end_bytepos
12007 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12008 w->window_end_pos
12009 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12010 w->window_end_vpos
12011 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12012 xassert (MATRIX_ROW (w->desired_matrix, XFASTINT (w->window_end_vpos))
12013 ->displays_text_p);
12015 else
12017 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
12018 w->window_end_pos = make_number (Z - ZV);
12019 w->window_end_vpos = make_number (0);
12022 /* But that is not valid info until redisplay finishes. */
12023 w->window_end_valid = Qnil;
12024 return 1;
12029 /************************************************************************
12030 Window redisplay reusing current matrix when buffer has not changed
12031 ************************************************************************/
12033 /* Try redisplay of window W showing an unchanged buffer with a
12034 different window start than the last time it was displayed by
12035 reusing its current matrix. Value is non-zero if successful.
12036 W->start is the new window start. */
12038 static int
12039 try_window_reusing_current_matrix (w)
12040 struct window *w;
12042 struct frame *f = XFRAME (w->frame);
12043 struct glyph_row *row, *bottom_row;
12044 struct it it;
12045 struct run run;
12046 struct text_pos start, new_start;
12047 int nrows_scrolled, i;
12048 struct glyph_row *last_text_row;
12049 struct glyph_row *last_reused_text_row;
12050 struct glyph_row *start_row;
12051 int start_vpos, min_y, max_y;
12053 #if GLYPH_DEBUG
12054 if (inhibit_try_window_reusing)
12055 return 0;
12056 #endif
12058 if (/* This function doesn't handle terminal frames. */
12059 !FRAME_WINDOW_P (f)
12060 /* Don't try to reuse the display if windows have been split
12061 or such. */
12062 || windows_or_buffers_changed
12063 || cursor_type_changed)
12064 return 0;
12066 /* Can't do this if region may have changed. */
12067 if ((!NILP (Vtransient_mark_mode)
12068 && !NILP (current_buffer->mark_active))
12069 || !NILP (w->region_showing)
12070 || !NILP (Vshow_trailing_whitespace))
12071 return 0;
12073 /* If top-line visibility has changed, give up. */
12074 if (WINDOW_WANTS_HEADER_LINE_P (w)
12075 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
12076 return 0;
12078 /* Give up if old or new display is scrolled vertically. We could
12079 make this function handle this, but right now it doesn't. */
12080 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12081 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (start_row))
12082 return 0;
12084 /* The variable new_start now holds the new window start. The old
12085 start `start' can be determined from the current matrix. */
12086 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
12087 start = start_row->start.pos;
12088 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
12090 /* Clear the desired matrix for the display below. */
12091 clear_glyph_matrix (w->desired_matrix);
12093 if (CHARPOS (new_start) <= CHARPOS (start))
12095 int first_row_y;
12097 /* Don't use this method if the display starts with an ellipsis
12098 displayed for invisible text. It's not easy to handle that case
12099 below, and it's certainly not worth the effort since this is
12100 not a frequent case. */
12101 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
12102 return 0;
12104 IF_DEBUG (debug_method_add (w, "twu1"));
12106 /* Display up to a row that can be reused. The variable
12107 last_text_row is set to the last row displayed that displays
12108 text. Note that it.vpos == 0 if or if not there is a
12109 header-line; it's not the same as the MATRIX_ROW_VPOS! */
12110 start_display (&it, w, new_start);
12111 first_row_y = it.current_y;
12112 w->cursor.vpos = -1;
12113 last_text_row = last_reused_text_row = NULL;
12115 while (it.current_y < it.last_visible_y
12116 && IT_CHARPOS (it) < CHARPOS (start)
12117 && !fonts_changed_p)
12118 if (display_line (&it))
12119 last_text_row = it.glyph_row - 1;
12121 /* A value of current_y < last_visible_y means that we stopped
12122 at the previous window start, which in turn means that we
12123 have at least one reusable row. */
12124 if (it.current_y < it.last_visible_y)
12126 /* IT.vpos always starts from 0; it counts text lines. */
12127 nrows_scrolled = it.vpos;
12129 /* Find PT if not already found in the lines displayed. */
12130 if (w->cursor.vpos < 0)
12132 int dy = it.current_y - first_row_y;
12134 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12135 row = row_containing_pos (w, PT, row, NULL, dy);
12136 if (row)
12137 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
12138 dy, nrows_scrolled);
12139 else
12141 clear_glyph_matrix (w->desired_matrix);
12142 return 0;
12146 /* Scroll the display. Do it before the current matrix is
12147 changed. The problem here is that update has not yet
12148 run, i.e. part of the current matrix is not up to date.
12149 scroll_run_hook will clear the cursor, and use the
12150 current matrix to get the height of the row the cursor is
12151 in. */
12152 run.current_y = first_row_y;
12153 run.desired_y = it.current_y;
12154 run.height = it.last_visible_y - it.current_y;
12156 if (run.height > 0 && run.current_y != run.desired_y)
12158 update_begin (f);
12159 rif->update_window_begin_hook (w);
12160 rif->clear_window_mouse_face (w);
12161 rif->scroll_run_hook (w, &run);
12162 rif->update_window_end_hook (w, 0, 0);
12163 update_end (f);
12166 /* Shift current matrix down by nrows_scrolled lines. */
12167 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
12168 rotate_matrix (w->current_matrix,
12169 start_vpos,
12170 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
12171 nrows_scrolled);
12173 /* Disable lines that must be updated. */
12174 for (i = 0; i < it.vpos; ++i)
12175 (start_row + i)->enabled_p = 0;
12177 /* Re-compute Y positions. */
12178 min_y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
12179 max_y = it.last_visible_y;
12180 for (row = start_row + nrows_scrolled;
12181 row < bottom_row;
12182 ++row)
12184 row->y = it.current_y;
12185 row->visible_height = row->height;
12187 if (row->y < min_y)
12188 row->visible_height -= min_y - row->y;
12189 if (row->y + row->height > max_y)
12190 row->visible_height -= row->y + row->height - max_y;
12192 it.current_y += row->height;
12194 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
12195 last_reused_text_row = row;
12196 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
12197 break;
12200 /* Disable lines in the current matrix which are now
12201 below the window. */
12202 for (++row; row < bottom_row; ++row)
12203 row->enabled_p = 0;
12206 /* Update window_end_pos etc.; last_reused_text_row is the last
12207 reused row from the current matrix containing text, if any.
12208 The value of last_text_row is the last displayed line
12209 containing text. */
12210 if (last_reused_text_row)
12212 w->window_end_bytepos
12213 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
12214 w->window_end_pos
12215 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_reused_text_row));
12216 w->window_end_vpos
12217 = make_number (MATRIX_ROW_VPOS (last_reused_text_row,
12218 w->current_matrix));
12220 else if (last_text_row)
12222 w->window_end_bytepos
12223 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12224 w->window_end_pos
12225 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12226 w->window_end_vpos
12227 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12229 else
12231 /* This window must be completely empty. */
12232 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
12233 w->window_end_pos = make_number (Z - ZV);
12234 w->window_end_vpos = make_number (0);
12236 w->window_end_valid = Qnil;
12238 /* Update hint: don't try scrolling again in update_window. */
12239 w->desired_matrix->no_scrolling_p = 1;
12241 #if GLYPH_DEBUG
12242 debug_method_add (w, "try_window_reusing_current_matrix 1");
12243 #endif
12244 return 1;
12246 else if (CHARPOS (new_start) > CHARPOS (start))
12248 struct glyph_row *pt_row, *row;
12249 struct glyph_row *first_reusable_row;
12250 struct glyph_row *first_row_to_display;
12251 int dy;
12252 int yb = window_text_bottom_y (w);
12254 /* Find the row starting at new_start, if there is one. Don't
12255 reuse a partially visible line at the end. */
12256 first_reusable_row = start_row;
12257 while (first_reusable_row->enabled_p
12258 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
12259 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
12260 < CHARPOS (new_start)))
12261 ++first_reusable_row;
12263 /* Give up if there is no row to reuse. */
12264 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
12265 || !first_reusable_row->enabled_p
12266 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
12267 != CHARPOS (new_start)))
12268 return 0;
12270 /* We can reuse fully visible rows beginning with
12271 first_reusable_row to the end of the window. Set
12272 first_row_to_display to the first row that cannot be reused.
12273 Set pt_row to the row containing point, if there is any. */
12274 pt_row = NULL;
12275 for (first_row_to_display = first_reusable_row;
12276 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
12277 ++first_row_to_display)
12279 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
12280 && PT < MATRIX_ROW_END_CHARPOS (first_row_to_display))
12281 pt_row = first_row_to_display;
12284 /* Start displaying at the start of first_row_to_display. */
12285 xassert (first_row_to_display->y < yb);
12286 init_to_row_start (&it, w, first_row_to_display);
12288 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
12289 - start_vpos);
12290 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
12291 - nrows_scrolled);
12292 it.current_y = (first_row_to_display->y - first_reusable_row->y
12293 + WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w));
12295 /* Display lines beginning with first_row_to_display in the
12296 desired matrix. Set last_text_row to the last row displayed
12297 that displays text. */
12298 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
12299 if (pt_row == NULL)
12300 w->cursor.vpos = -1;
12301 last_text_row = NULL;
12302 while (it.current_y < it.last_visible_y && !fonts_changed_p)
12303 if (display_line (&it))
12304 last_text_row = it.glyph_row - 1;
12306 /* Give up If point isn't in a row displayed or reused. */
12307 if (w->cursor.vpos < 0)
12309 clear_glyph_matrix (w->desired_matrix);
12310 return 0;
12313 /* If point is in a reused row, adjust y and vpos of the cursor
12314 position. */
12315 if (pt_row)
12317 w->cursor.vpos -= MATRIX_ROW_VPOS (first_reusable_row,
12318 w->current_matrix);
12319 w->cursor.y -= first_reusable_row->y;
12322 /* Scroll the display. */
12323 run.current_y = first_reusable_row->y;
12324 run.desired_y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
12325 run.height = it.last_visible_y - run.current_y;
12326 dy = run.current_y - run.desired_y;
12328 if (run.height)
12330 struct frame *f = XFRAME (WINDOW_FRAME (w));
12331 update_begin (f);
12332 rif->update_window_begin_hook (w);
12333 rif->clear_window_mouse_face (w);
12334 rif->scroll_run_hook (w, &run);
12335 rif->update_window_end_hook (w, 0, 0);
12336 update_end (f);
12339 /* Adjust Y positions of reused rows. */
12340 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
12341 min_y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
12342 max_y = it.last_visible_y;
12343 for (row = first_reusable_row; row < first_row_to_display; ++row)
12345 row->y -= dy;
12346 row->visible_height = row->height;
12347 if (row->y < min_y)
12348 row->visible_height -= min_y - row->y;
12349 if (row->y + row->height > max_y)
12350 row->visible_height -= row->y + row->height - max_y;
12353 /* Scroll the current matrix. */
12354 xassert (nrows_scrolled > 0);
12355 rotate_matrix (w->current_matrix,
12356 start_vpos,
12357 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
12358 -nrows_scrolled);
12360 /* Disable rows not reused. */
12361 for (row -= nrows_scrolled; row < bottom_row; ++row)
12362 row->enabled_p = 0;
12364 /* Adjust window end. A null value of last_text_row means that
12365 the window end is in reused rows which in turn means that
12366 only its vpos can have changed. */
12367 if (last_text_row)
12369 w->window_end_bytepos
12370 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12371 w->window_end_pos
12372 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12373 w->window_end_vpos
12374 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12376 else
12378 w->window_end_vpos
12379 = make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled);
12382 w->window_end_valid = Qnil;
12383 w->desired_matrix->no_scrolling_p = 1;
12385 #if GLYPH_DEBUG
12386 debug_method_add (w, "try_window_reusing_current_matrix 2");
12387 #endif
12388 return 1;
12391 return 0;
12396 /************************************************************************
12397 Window redisplay reusing current matrix when buffer has changed
12398 ************************************************************************/
12400 static struct glyph_row *find_last_unchanged_at_beg_row P_ ((struct window *));
12401 static struct glyph_row *find_first_unchanged_at_end_row P_ ((struct window *,
12402 int *, int *));
12403 static struct glyph_row *
12404 find_last_row_displaying_text P_ ((struct glyph_matrix *, struct it *,
12405 struct glyph_row *));
12408 /* Return the last row in MATRIX displaying text. If row START is
12409 non-null, start searching with that row. IT gives the dimensions
12410 of the display. Value is null if matrix is empty; otherwise it is
12411 a pointer to the row found. */
12413 static struct glyph_row *
12414 find_last_row_displaying_text (matrix, it, start)
12415 struct glyph_matrix *matrix;
12416 struct it *it;
12417 struct glyph_row *start;
12419 struct glyph_row *row, *row_found;
12421 /* Set row_found to the last row in IT->w's current matrix
12422 displaying text. The loop looks funny but think of partially
12423 visible lines. */
12424 row_found = NULL;
12425 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
12426 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
12428 xassert (row->enabled_p);
12429 row_found = row;
12430 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
12431 break;
12432 ++row;
12435 return row_found;
12439 /* Return the last row in the current matrix of W that is not affected
12440 by changes at the start of current_buffer that occurred since W's
12441 current matrix was built. Value is null if no such row exists.
12443 BEG_UNCHANGED us the number of characters unchanged at the start of
12444 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
12445 first changed character in current_buffer. Characters at positions <
12446 BEG + BEG_UNCHANGED are at the same buffer positions as they were
12447 when the current matrix was built. */
12449 static struct glyph_row *
12450 find_last_unchanged_at_beg_row (w)
12451 struct window *w;
12453 int first_changed_pos = BEG + BEG_UNCHANGED;
12454 struct glyph_row *row;
12455 struct glyph_row *row_found = NULL;
12456 int yb = window_text_bottom_y (w);
12458 /* Find the last row displaying unchanged text. */
12459 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12460 while (MATRIX_ROW_DISPLAYS_TEXT_P (row)
12461 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos)
12463 if (/* If row ends before first_changed_pos, it is unchanged,
12464 except in some case. */
12465 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
12466 /* When row ends in ZV and we write at ZV it is not
12467 unchanged. */
12468 && !row->ends_at_zv_p
12469 /* When first_changed_pos is the end of a continued line,
12470 row is not unchanged because it may be no longer
12471 continued. */
12472 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
12473 && row->continued_p))
12474 row_found = row;
12476 /* Stop if last visible row. */
12477 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
12478 break;
12480 ++row;
12483 return row_found;
12487 /* Find the first glyph row in the current matrix of W that is not
12488 affected by changes at the end of current_buffer since the
12489 time W's current matrix was built.
12491 Return in *DELTA the number of chars by which buffer positions in
12492 unchanged text at the end of current_buffer must be adjusted.
12494 Return in *DELTA_BYTES the corresponding number of bytes.
12496 Value is null if no such row exists, i.e. all rows are affected by
12497 changes. */
12499 static struct glyph_row *
12500 find_first_unchanged_at_end_row (w, delta, delta_bytes)
12501 struct window *w;
12502 int *delta, *delta_bytes;
12504 struct glyph_row *row;
12505 struct glyph_row *row_found = NULL;
12507 *delta = *delta_bytes = 0;
12509 /* Display must not have been paused, otherwise the current matrix
12510 is not up to date. */
12511 if (NILP (w->window_end_valid))
12512 abort ();
12514 /* A value of window_end_pos >= END_UNCHANGED means that the window
12515 end is in the range of changed text. If so, there is no
12516 unchanged row at the end of W's current matrix. */
12517 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
12518 return NULL;
12520 /* Set row to the last row in W's current matrix displaying text. */
12521 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
12523 /* If matrix is entirely empty, no unchanged row exists. */
12524 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
12526 /* The value of row is the last glyph row in the matrix having a
12527 meaningful buffer position in it. The end position of row
12528 corresponds to window_end_pos. This allows us to translate
12529 buffer positions in the current matrix to current buffer
12530 positions for characters not in changed text. */
12531 int Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
12532 int Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
12533 int last_unchanged_pos, last_unchanged_pos_old;
12534 struct glyph_row *first_text_row
12535 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12537 *delta = Z - Z_old;
12538 *delta_bytes = Z_BYTE - Z_BYTE_old;
12540 /* Set last_unchanged_pos to the buffer position of the last
12541 character in the buffer that has not been changed. Z is the
12542 index + 1 of the last character in current_buffer, i.e. by
12543 subtracting END_UNCHANGED we get the index of the last
12544 unchanged character, and we have to add BEG to get its buffer
12545 position. */
12546 last_unchanged_pos = Z - END_UNCHANGED + BEG;
12547 last_unchanged_pos_old = last_unchanged_pos - *delta;
12549 /* Search backward from ROW for a row displaying a line that
12550 starts at a minimum position >= last_unchanged_pos_old. */
12551 for (; row > first_text_row; --row)
12553 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
12554 abort ();
12556 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
12557 row_found = row;
12561 if (row_found && !MATRIX_ROW_DISPLAYS_TEXT_P (row_found))
12562 abort ();
12564 return row_found;
12568 /* Make sure that glyph rows in the current matrix of window W
12569 reference the same glyph memory as corresponding rows in the
12570 frame's frame matrix. This function is called after scrolling W's
12571 current matrix on a terminal frame in try_window_id and
12572 try_window_reusing_current_matrix. */
12574 static void
12575 sync_frame_with_window_matrix_rows (w)
12576 struct window *w;
12578 struct frame *f = XFRAME (w->frame);
12579 struct glyph_row *window_row, *window_row_end, *frame_row;
12581 /* Preconditions: W must be a leaf window and full-width. Its frame
12582 must have a frame matrix. */
12583 xassert (NILP (w->hchild) && NILP (w->vchild));
12584 xassert (WINDOW_FULL_WIDTH_P (w));
12585 xassert (!FRAME_WINDOW_P (f));
12587 /* If W is a full-width window, glyph pointers in W's current matrix
12588 have, by definition, to be the same as glyph pointers in the
12589 corresponding frame matrix. Note that frame matrices have no
12590 marginal areas (see build_frame_matrix). */
12591 window_row = w->current_matrix->rows;
12592 window_row_end = window_row + w->current_matrix->nrows;
12593 frame_row = f->current_matrix->rows + XFASTINT (w->top);
12594 while (window_row < window_row_end)
12596 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
12597 struct glyph *end = window_row->glyphs[LAST_AREA];
12599 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
12600 frame_row->glyphs[TEXT_AREA] = start;
12601 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
12602 frame_row->glyphs[LAST_AREA] = end;
12604 /* Disable frame rows whose corresponding window rows have
12605 been disabled in try_window_id. */
12606 if (!window_row->enabled_p)
12607 frame_row->enabled_p = 0;
12609 ++window_row, ++frame_row;
12614 /* Find the glyph row in window W containing CHARPOS. Consider all
12615 rows between START and END (not inclusive). END null means search
12616 all rows to the end of the display area of W. Value is the row
12617 containing CHARPOS or null. */
12619 struct glyph_row *
12620 row_containing_pos (w, charpos, start, end, dy)
12621 struct window *w;
12622 int charpos;
12623 struct glyph_row *start, *end;
12624 int dy;
12626 struct glyph_row *row = start;
12627 int last_y;
12629 /* If we happen to start on a header-line, skip that. */
12630 if (row->mode_line_p)
12631 ++row;
12633 if ((end && row >= end) || !row->enabled_p)
12634 return NULL;
12636 last_y = window_text_bottom_y (w) - dy;
12638 while (1)
12640 /* Give up if we have gone too far. */
12641 if (end && row >= end)
12642 return NULL;
12643 /* This formerly returned if they were equal.
12644 I think that both quantities are of a "last plus one" type;
12645 if so, when they are equal, the row is within the screen. -- rms. */
12646 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
12647 return NULL;
12649 /* If it is in this row, return this row. */
12650 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
12651 || (MATRIX_ROW_END_CHARPOS (row) == charpos
12652 /* The end position of a row equals the start
12653 position of the next row. If CHARPOS is there, we
12654 would rather display it in the next line, except
12655 when this line ends in ZV. */
12656 && !row->ends_at_zv_p
12657 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
12658 && charpos >= MATRIX_ROW_START_CHARPOS (row))
12659 return row;
12660 ++row;
12665 /* Try to redisplay window W by reusing its existing display. W's
12666 current matrix must be up to date when this function is called,
12667 i.e. window_end_valid must not be nil.
12669 Value is
12671 1 if display has been updated
12672 0 if otherwise unsuccessful
12673 -1 if redisplay with same window start is known not to succeed
12675 The following steps are performed:
12677 1. Find the last row in the current matrix of W that is not
12678 affected by changes at the start of current_buffer. If no such row
12679 is found, give up.
12681 2. Find the first row in W's current matrix that is not affected by
12682 changes at the end of current_buffer. Maybe there is no such row.
12684 3. Display lines beginning with the row + 1 found in step 1 to the
12685 row found in step 2 or, if step 2 didn't find a row, to the end of
12686 the window.
12688 4. If cursor is not known to appear on the window, give up.
12690 5. If display stopped at the row found in step 2, scroll the
12691 display and current matrix as needed.
12693 6. Maybe display some lines at the end of W, if we must. This can
12694 happen under various circumstances, like a partially visible line
12695 becoming fully visible, or because newly displayed lines are displayed
12696 in smaller font sizes.
12698 7. Update W's window end information. */
12700 static int
12701 try_window_id (w)
12702 struct window *w;
12704 struct frame *f = XFRAME (w->frame);
12705 struct glyph_matrix *current_matrix = w->current_matrix;
12706 struct glyph_matrix *desired_matrix = w->desired_matrix;
12707 struct glyph_row *last_unchanged_at_beg_row;
12708 struct glyph_row *first_unchanged_at_end_row;
12709 struct glyph_row *row;
12710 struct glyph_row *bottom_row;
12711 int bottom_vpos;
12712 struct it it;
12713 int delta = 0, delta_bytes = 0, stop_pos, dvpos, dy;
12714 struct text_pos start_pos;
12715 struct run run;
12716 int first_unchanged_at_end_vpos = 0;
12717 struct glyph_row *last_text_row, *last_text_row_at_end;
12718 struct text_pos start;
12719 int first_changed_charpos, last_changed_charpos;
12721 #if GLYPH_DEBUG
12722 if (inhibit_try_window_id)
12723 return 0;
12724 #endif
12726 /* This is handy for debugging. */
12727 #if 0
12728 #define GIVE_UP(X) \
12729 do { \
12730 fprintf (stderr, "try_window_id give up %d\n", (X)); \
12731 return 0; \
12732 } while (0)
12733 #else
12734 #define GIVE_UP(X) return 0
12735 #endif
12737 SET_TEXT_POS_FROM_MARKER (start, w->start);
12739 /* Don't use this for mini-windows because these can show
12740 messages and mini-buffers, and we don't handle that here. */
12741 if (MINI_WINDOW_P (w))
12742 GIVE_UP (1);
12744 /* This flag is used to prevent redisplay optimizations. */
12745 if (windows_or_buffers_changed || cursor_type_changed)
12746 GIVE_UP (2);
12748 /* Verify that narrowing has not changed.
12749 Also verify that we were not told to prevent redisplay optimizations.
12750 It would be nice to further
12751 reduce the number of cases where this prevents try_window_id. */
12752 if (current_buffer->clip_changed
12753 || current_buffer->prevent_redisplay_optimizations_p)
12754 GIVE_UP (3);
12756 /* Window must either use window-based redisplay or be full width. */
12757 if (!FRAME_WINDOW_P (f)
12758 && (!line_ins_del_ok
12759 || !WINDOW_FULL_WIDTH_P (w)))
12760 GIVE_UP (4);
12762 /* Give up if point is not known NOT to appear in W. */
12763 if (PT < CHARPOS (start))
12764 GIVE_UP (5);
12766 /* Another way to prevent redisplay optimizations. */
12767 if (XFASTINT (w->last_modified) == 0)
12768 GIVE_UP (6);
12770 /* Verify that window is not hscrolled. */
12771 if (XFASTINT (w->hscroll) != 0)
12772 GIVE_UP (7);
12774 /* Verify that display wasn't paused. */
12775 if (NILP (w->window_end_valid))
12776 GIVE_UP (8);
12778 /* Can't use this if highlighting a region because a cursor movement
12779 will do more than just set the cursor. */
12780 if (!NILP (Vtransient_mark_mode)
12781 && !NILP (current_buffer->mark_active))
12782 GIVE_UP (9);
12784 /* Likewise if highlighting trailing whitespace. */
12785 if (!NILP (Vshow_trailing_whitespace))
12786 GIVE_UP (11);
12788 /* Likewise if showing a region. */
12789 if (!NILP (w->region_showing))
12790 GIVE_UP (10);
12792 /* Can use this if overlay arrow position and or string have changed. */
12793 if (!EQ (last_arrow_position, COERCE_MARKER (Voverlay_arrow_position))
12794 || !EQ (last_arrow_string, Voverlay_arrow_string))
12795 GIVE_UP (12);
12798 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
12799 only if buffer has really changed. The reason is that the gap is
12800 initially at Z for freshly visited files. The code below would
12801 set end_unchanged to 0 in that case. */
12802 if (MODIFF > SAVE_MODIFF
12803 /* This seems to happen sometimes after saving a buffer. */
12804 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
12806 if (GPT - BEG < BEG_UNCHANGED)
12807 BEG_UNCHANGED = GPT - BEG;
12808 if (Z - GPT < END_UNCHANGED)
12809 END_UNCHANGED = Z - GPT;
12812 /* The position of the first and last character that has been changed. */
12813 first_changed_charpos = BEG + BEG_UNCHANGED;
12814 last_changed_charpos = Z - END_UNCHANGED;
12816 /* If window starts after a line end, and the last change is in
12817 front of that newline, then changes don't affect the display.
12818 This case happens with stealth-fontification. Note that although
12819 the display is unchanged, glyph positions in the matrix have to
12820 be adjusted, of course. */
12821 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
12822 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
12823 && ((last_changed_charpos < CHARPOS (start)
12824 && CHARPOS (start) == BEGV)
12825 || (last_changed_charpos < CHARPOS (start) - 1
12826 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
12828 int Z_old, delta, Z_BYTE_old, delta_bytes;
12829 struct glyph_row *r0;
12831 /* Compute how many chars/bytes have been added to or removed
12832 from the buffer. */
12833 Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
12834 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
12835 delta = Z - Z_old;
12836 delta_bytes = Z_BYTE - Z_BYTE_old;
12838 /* Give up if PT is not in the window. Note that it already has
12839 been checked at the start of try_window_id that PT is not in
12840 front of the window start. */
12841 if (PT >= MATRIX_ROW_END_CHARPOS (row) + delta)
12842 GIVE_UP (13);
12844 /* If window start is unchanged, we can reuse the whole matrix
12845 as is, after adjusting glyph positions. No need to compute
12846 the window end again, since its offset from Z hasn't changed. */
12847 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
12848 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + delta
12849 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + delta_bytes)
12851 /* Adjust positions in the glyph matrix. */
12852 if (delta || delta_bytes)
12854 struct glyph_row *r1
12855 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
12856 increment_matrix_positions (w->current_matrix,
12857 MATRIX_ROW_VPOS (r0, current_matrix),
12858 MATRIX_ROW_VPOS (r1, current_matrix),
12859 delta, delta_bytes);
12862 /* Set the cursor. */
12863 row = row_containing_pos (w, PT, r0, NULL, 0);
12864 if (row)
12865 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
12866 else
12867 abort ();
12868 return 1;
12872 /* Handle the case that changes are all below what is displayed in
12873 the window, and that PT is in the window. This shortcut cannot
12874 be taken if ZV is visible in the window, and text has been added
12875 there that is visible in the window. */
12876 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
12877 /* ZV is not visible in the window, or there are no
12878 changes at ZV, actually. */
12879 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
12880 || first_changed_charpos == last_changed_charpos))
12882 struct glyph_row *r0;
12884 /* Give up if PT is not in the window. Note that it already has
12885 been checked at the start of try_window_id that PT is not in
12886 front of the window start. */
12887 if (PT >= MATRIX_ROW_END_CHARPOS (row))
12888 GIVE_UP (14);
12890 /* If window start is unchanged, we can reuse the whole matrix
12891 as is, without changing glyph positions since no text has
12892 been added/removed in front of the window end. */
12893 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
12894 if (TEXT_POS_EQUAL_P (start, r0->start.pos))
12896 /* We have to compute the window end anew since text
12897 can have been added/removed after it. */
12898 w->window_end_pos
12899 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
12900 w->window_end_bytepos
12901 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
12903 /* Set the cursor. */
12904 row = row_containing_pos (w, PT, r0, NULL, 0);
12905 if (row)
12906 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
12907 else
12908 abort ();
12909 return 2;
12913 /* Give up if window start is in the changed area.
12915 The condition used to read
12917 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
12919 but why that was tested escapes me at the moment. */
12920 if (CHARPOS (start) >= first_changed_charpos
12921 && CHARPOS (start) <= last_changed_charpos)
12922 GIVE_UP (15);
12924 /* Check that window start agrees with the start of the first glyph
12925 row in its current matrix. Check this after we know the window
12926 start is not in changed text, otherwise positions would not be
12927 comparable. */
12928 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
12929 if (!TEXT_POS_EQUAL_P (start, row->start.pos))
12930 GIVE_UP (16);
12932 /* Give up if the window ends in strings. Overlay strings
12933 at the end are difficult to handle, so don't try. */
12934 row = MATRIX_ROW (current_matrix, XFASTINT (w->window_end_vpos));
12935 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
12936 GIVE_UP (20);
12938 /* Compute the position at which we have to start displaying new
12939 lines. Some of the lines at the top of the window might be
12940 reusable because they are not displaying changed text. Find the
12941 last row in W's current matrix not affected by changes at the
12942 start of current_buffer. Value is null if changes start in the
12943 first line of window. */
12944 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
12945 if (last_unchanged_at_beg_row)
12947 /* Avoid starting to display in the moddle of a character, a TAB
12948 for instance. This is easier than to set up the iterator
12949 exactly, and it's not a frequent case, so the additional
12950 effort wouldn't really pay off. */
12951 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
12952 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
12953 && last_unchanged_at_beg_row > w->current_matrix->rows)
12954 --last_unchanged_at_beg_row;
12956 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
12957 GIVE_UP (17);
12959 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
12960 GIVE_UP (18);
12961 start_pos = it.current.pos;
12963 /* Start displaying new lines in the desired matrix at the same
12964 vpos we would use in the current matrix, i.e. below
12965 last_unchanged_at_beg_row. */
12966 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
12967 current_matrix);
12968 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
12969 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
12971 xassert (it.hpos == 0 && it.current_x == 0);
12973 else
12975 /* There are no reusable lines at the start of the window.
12976 Start displaying in the first line. */
12977 start_display (&it, w, start);
12978 start_pos = it.current.pos;
12981 /* Find the first row that is not affected by changes at the end of
12982 the buffer. Value will be null if there is no unchanged row, in
12983 which case we must redisplay to the end of the window. delta
12984 will be set to the value by which buffer positions beginning with
12985 first_unchanged_at_end_row have to be adjusted due to text
12986 changes. */
12987 first_unchanged_at_end_row
12988 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
12989 IF_DEBUG (debug_delta = delta);
12990 IF_DEBUG (debug_delta_bytes = delta_bytes);
12992 /* Set stop_pos to the buffer position up to which we will have to
12993 display new lines. If first_unchanged_at_end_row != NULL, this
12994 is the buffer position of the start of the line displayed in that
12995 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
12996 that we don't stop at a buffer position. */
12997 stop_pos = 0;
12998 if (first_unchanged_at_end_row)
13000 xassert (last_unchanged_at_beg_row == NULL
13001 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
13003 /* If this is a continuation line, move forward to the next one
13004 that isn't. Changes in lines above affect this line.
13005 Caution: this may move first_unchanged_at_end_row to a row
13006 not displaying text. */
13007 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
13008 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
13009 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
13010 < it.last_visible_y))
13011 ++first_unchanged_at_end_row;
13013 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
13014 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
13015 >= it.last_visible_y))
13016 first_unchanged_at_end_row = NULL;
13017 else
13019 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
13020 + delta);
13021 first_unchanged_at_end_vpos
13022 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
13023 xassert (stop_pos >= Z - END_UNCHANGED);
13026 else if (last_unchanged_at_beg_row == NULL)
13027 GIVE_UP (19);
13030 #if GLYPH_DEBUG
13032 /* Either there is no unchanged row at the end, or the one we have
13033 now displays text. This is a necessary condition for the window
13034 end pos calculation at the end of this function. */
13035 xassert (first_unchanged_at_end_row == NULL
13036 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
13038 debug_last_unchanged_at_beg_vpos
13039 = (last_unchanged_at_beg_row
13040 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
13041 : -1);
13042 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
13044 #endif /* GLYPH_DEBUG != 0 */
13047 /* Display new lines. Set last_text_row to the last new line
13048 displayed which has text on it, i.e. might end up as being the
13049 line where the window_end_vpos is. */
13050 w->cursor.vpos = -1;
13051 last_text_row = NULL;
13052 overlay_arrow_seen = 0;
13053 while (it.current_y < it.last_visible_y
13054 && !fonts_changed_p
13055 && (first_unchanged_at_end_row == NULL
13056 || IT_CHARPOS (it) < stop_pos))
13058 if (display_line (&it))
13059 last_text_row = it.glyph_row - 1;
13062 if (fonts_changed_p)
13063 return -1;
13066 /* Compute differences in buffer positions, y-positions etc. for
13067 lines reused at the bottom of the window. Compute what we can
13068 scroll. */
13069 if (first_unchanged_at_end_row
13070 /* No lines reused because we displayed everything up to the
13071 bottom of the window. */
13072 && it.current_y < it.last_visible_y)
13074 dvpos = (it.vpos
13075 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
13076 current_matrix));
13077 dy = it.current_y - first_unchanged_at_end_row->y;
13078 run.current_y = first_unchanged_at_end_row->y;
13079 run.desired_y = run.current_y + dy;
13080 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
13082 else
13084 delta = dvpos = dy = run.current_y = run.desired_y = run.height = 0;
13085 first_unchanged_at_end_row = NULL;
13087 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
13090 /* Find the cursor if not already found. We have to decide whether
13091 PT will appear on this window (it sometimes doesn't, but this is
13092 not a very frequent case.) This decision has to be made before
13093 the current matrix is altered. A value of cursor.vpos < 0 means
13094 that PT is either in one of the lines beginning at
13095 first_unchanged_at_end_row or below the window. Don't care for
13096 lines that might be displayed later at the window end; as
13097 mentioned, this is not a frequent case. */
13098 if (w->cursor.vpos < 0)
13100 /* Cursor in unchanged rows at the top? */
13101 if (PT < CHARPOS (start_pos)
13102 && last_unchanged_at_beg_row)
13104 row = row_containing_pos (w, PT,
13105 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
13106 last_unchanged_at_beg_row + 1, 0);
13107 if (row)
13108 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
13111 /* Start from first_unchanged_at_end_row looking for PT. */
13112 else if (first_unchanged_at_end_row)
13114 row = row_containing_pos (w, PT - delta,
13115 first_unchanged_at_end_row, NULL, 0);
13116 if (row)
13117 set_cursor_from_row (w, row, w->current_matrix, delta,
13118 delta_bytes, dy, dvpos);
13121 /* Give up if cursor was not found. */
13122 if (w->cursor.vpos < 0)
13124 clear_glyph_matrix (w->desired_matrix);
13125 return -1;
13129 /* Don't let the cursor end in the scroll margins. */
13131 int this_scroll_margin, cursor_height;
13133 this_scroll_margin = max (0, scroll_margin);
13134 this_scroll_margin = min (this_scroll_margin,
13135 XFASTINT (w->height) / 4);
13136 this_scroll_margin *= CANON_Y_UNIT (it.f);
13137 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
13139 if ((w->cursor.y < this_scroll_margin
13140 && CHARPOS (start) > BEGV)
13141 /* Don't take scroll margin into account at the bottom because
13142 old redisplay didn't do it either. */
13143 || w->cursor.y + cursor_height > it.last_visible_y)
13145 w->cursor.vpos = -1;
13146 clear_glyph_matrix (w->desired_matrix);
13147 return -1;
13151 /* Scroll the display. Do it before changing the current matrix so
13152 that xterm.c doesn't get confused about where the cursor glyph is
13153 found. */
13154 if (dy && run.height)
13156 update_begin (f);
13158 if (FRAME_WINDOW_P (f))
13160 rif->update_window_begin_hook (w);
13161 rif->clear_window_mouse_face (w);
13162 rif->scroll_run_hook (w, &run);
13163 rif->update_window_end_hook (w, 0, 0);
13165 else
13167 /* Terminal frame. In this case, dvpos gives the number of
13168 lines to scroll by; dvpos < 0 means scroll up. */
13169 int first_unchanged_at_end_vpos
13170 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
13171 int from = XFASTINT (w->top) + first_unchanged_at_end_vpos;
13172 int end = (XFASTINT (w->top)
13173 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
13174 + window_internal_height (w));
13176 /* Perform the operation on the screen. */
13177 if (dvpos > 0)
13179 /* Scroll last_unchanged_at_beg_row to the end of the
13180 window down dvpos lines. */
13181 set_terminal_window (end);
13183 /* On dumb terminals delete dvpos lines at the end
13184 before inserting dvpos empty lines. */
13185 if (!scroll_region_ok)
13186 ins_del_lines (end - dvpos, -dvpos);
13188 /* Insert dvpos empty lines in front of
13189 last_unchanged_at_beg_row. */
13190 ins_del_lines (from, dvpos);
13192 else if (dvpos < 0)
13194 /* Scroll up last_unchanged_at_beg_vpos to the end of
13195 the window to last_unchanged_at_beg_vpos - |dvpos|. */
13196 set_terminal_window (end);
13198 /* Delete dvpos lines in front of
13199 last_unchanged_at_beg_vpos. ins_del_lines will set
13200 the cursor to the given vpos and emit |dvpos| delete
13201 line sequences. */
13202 ins_del_lines (from + dvpos, dvpos);
13204 /* On a dumb terminal insert dvpos empty lines at the
13205 end. */
13206 if (!scroll_region_ok)
13207 ins_del_lines (end + dvpos, -dvpos);
13210 set_terminal_window (0);
13213 update_end (f);
13216 /* Shift reused rows of the current matrix to the right position.
13217 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
13218 text. */
13219 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
13220 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
13221 if (dvpos < 0)
13223 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
13224 bottom_vpos, dvpos);
13225 enable_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
13226 bottom_vpos, 0);
13228 else if (dvpos > 0)
13230 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
13231 bottom_vpos, dvpos);
13232 enable_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
13233 first_unchanged_at_end_vpos + dvpos, 0);
13236 /* For frame-based redisplay, make sure that current frame and window
13237 matrix are in sync with respect to glyph memory. */
13238 if (!FRAME_WINDOW_P (f))
13239 sync_frame_with_window_matrix_rows (w);
13241 /* Adjust buffer positions in reused rows. */
13242 if (delta)
13243 increment_matrix_positions (current_matrix,
13244 first_unchanged_at_end_vpos + dvpos,
13245 bottom_vpos, delta, delta_bytes);
13247 /* Adjust Y positions. */
13248 if (dy)
13249 shift_glyph_matrix (w, current_matrix,
13250 first_unchanged_at_end_vpos + dvpos,
13251 bottom_vpos, dy);
13253 if (first_unchanged_at_end_row)
13254 first_unchanged_at_end_row += dvpos;
13256 /* If scrolling up, there may be some lines to display at the end of
13257 the window. */
13258 last_text_row_at_end = NULL;
13259 if (dy < 0)
13261 /* Scrolling up can leave for example a partially visible line
13262 at the end of the window to be redisplayed. */
13263 /* Set last_row to the glyph row in the current matrix where the
13264 window end line is found. It has been moved up or down in
13265 the matrix by dvpos. */
13266 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
13267 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
13269 /* If last_row is the window end line, it should display text. */
13270 xassert (last_row->displays_text_p);
13272 /* If window end line was partially visible before, begin
13273 displaying at that line. Otherwise begin displaying with the
13274 line following it. */
13275 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
13277 init_to_row_start (&it, w, last_row);
13278 it.vpos = last_vpos;
13279 it.current_y = last_row->y;
13281 else
13283 init_to_row_end (&it, w, last_row);
13284 it.vpos = 1 + last_vpos;
13285 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
13286 ++last_row;
13289 /* We may start in a continuation line. If so, we have to
13290 get the right continuation_lines_width and current_x. */
13291 it.continuation_lines_width = last_row->continuation_lines_width;
13292 it.hpos = it.current_x = 0;
13294 /* Display the rest of the lines at the window end. */
13295 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
13296 while (it.current_y < it.last_visible_y
13297 && !fonts_changed_p)
13299 /* Is it always sure that the display agrees with lines in
13300 the current matrix? I don't think so, so we mark rows
13301 displayed invalid in the current matrix by setting their
13302 enabled_p flag to zero. */
13303 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
13304 if (display_line (&it))
13305 last_text_row_at_end = it.glyph_row - 1;
13309 /* Update window_end_pos and window_end_vpos. */
13310 if (first_unchanged_at_end_row
13311 && first_unchanged_at_end_row->y < it.last_visible_y
13312 && !last_text_row_at_end)
13314 /* Window end line if one of the preserved rows from the current
13315 matrix. Set row to the last row displaying text in current
13316 matrix starting at first_unchanged_at_end_row, after
13317 scrolling. */
13318 xassert (first_unchanged_at_end_row->displays_text_p);
13319 row = find_last_row_displaying_text (w->current_matrix, &it,
13320 first_unchanged_at_end_row);
13321 xassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
13323 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13324 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13325 w->window_end_vpos
13326 = make_number (MATRIX_ROW_VPOS (row, w->current_matrix));
13327 xassert (w->window_end_bytepos >= 0);
13328 IF_DEBUG (debug_method_add (w, "A"));
13330 else if (last_text_row_at_end)
13332 w->window_end_pos
13333 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end));
13334 w->window_end_bytepos
13335 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
13336 w->window_end_vpos
13337 = make_number (MATRIX_ROW_VPOS (last_text_row_at_end, desired_matrix));
13338 xassert (w->window_end_bytepos >= 0);
13339 IF_DEBUG (debug_method_add (w, "B"));
13341 else if (last_text_row)
13343 /* We have displayed either to the end of the window or at the
13344 end of the window, i.e. the last row with text is to be found
13345 in the desired matrix. */
13346 w->window_end_pos
13347 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
13348 w->window_end_bytepos
13349 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
13350 w->window_end_vpos
13351 = make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix));
13352 xassert (w->window_end_bytepos >= 0);
13354 else if (first_unchanged_at_end_row == NULL
13355 && last_text_row == NULL
13356 && last_text_row_at_end == NULL)
13358 /* Displayed to end of window, but no line containing text was
13359 displayed. Lines were deleted at the end of the window. */
13360 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
13361 int vpos = XFASTINT (w->window_end_vpos);
13362 struct glyph_row *current_row = current_matrix->rows + vpos;
13363 struct glyph_row *desired_row = desired_matrix->rows + vpos;
13365 for (row = NULL;
13366 row == NULL && vpos >= first_vpos;
13367 --vpos, --current_row, --desired_row)
13369 if (desired_row->enabled_p)
13371 if (desired_row->displays_text_p)
13372 row = desired_row;
13374 else if (current_row->displays_text_p)
13375 row = current_row;
13378 xassert (row != NULL);
13379 w->window_end_vpos = make_number (vpos + 1);
13380 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13381 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13382 xassert (w->window_end_bytepos >= 0);
13383 IF_DEBUG (debug_method_add (w, "C"));
13385 else
13386 abort ();
13388 #if 0 /* This leads to problems, for instance when the cursor is
13389 at ZV, and the cursor line displays no text. */
13390 /* Disable rows below what's displayed in the window. This makes
13391 debugging easier. */
13392 enable_glyph_matrix_rows (current_matrix,
13393 XFASTINT (w->window_end_vpos) + 1,
13394 bottom_vpos, 0);
13395 #endif
13397 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
13398 debug_end_vpos = XFASTINT (w->window_end_vpos));
13400 /* Record that display has not been completed. */
13401 w->window_end_valid = Qnil;
13402 w->desired_matrix->no_scrolling_p = 1;
13403 return 3;
13405 #undef GIVE_UP
13410 /***********************************************************************
13411 More debugging support
13412 ***********************************************************************/
13414 #if GLYPH_DEBUG
13416 void dump_glyph_row P_ ((struct glyph_row *, int, int));
13417 void dump_glyph_matrix P_ ((struct glyph_matrix *, int));
13418 void dump_glyph P_ ((struct glyph_row *, struct glyph *, int));
13421 /* Dump the contents of glyph matrix MATRIX on stderr.
13423 GLYPHS 0 means don't show glyph contents.
13424 GLYPHS 1 means show glyphs in short form
13425 GLYPHS > 1 means show glyphs in long form. */
13427 void
13428 dump_glyph_matrix (matrix, glyphs)
13429 struct glyph_matrix *matrix;
13430 int glyphs;
13432 int i;
13433 for (i = 0; i < matrix->nrows; ++i)
13434 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
13438 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
13439 the glyph row and area where the glyph comes from. */
13441 void
13442 dump_glyph (row, glyph, area)
13443 struct glyph_row *row;
13444 struct glyph *glyph;
13445 int area;
13447 if (glyph->type == CHAR_GLYPH)
13449 fprintf (stderr,
13450 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13451 glyph - row->glyphs[TEXT_AREA],
13452 'C',
13453 glyph->charpos,
13454 (BUFFERP (glyph->object)
13455 ? 'B'
13456 : (STRINGP (glyph->object)
13457 ? 'S'
13458 : '-')),
13459 glyph->pixel_width,
13460 glyph->u.ch,
13461 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
13462 ? glyph->u.ch
13463 : '.'),
13464 glyph->face_id,
13465 glyph->left_box_line_p,
13466 glyph->right_box_line_p);
13468 else if (glyph->type == STRETCH_GLYPH)
13470 fprintf (stderr,
13471 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13472 glyph - row->glyphs[TEXT_AREA],
13473 'S',
13474 glyph->charpos,
13475 (BUFFERP (glyph->object)
13476 ? 'B'
13477 : (STRINGP (glyph->object)
13478 ? 'S'
13479 : '-')),
13480 glyph->pixel_width,
13482 '.',
13483 glyph->face_id,
13484 glyph->left_box_line_p,
13485 glyph->right_box_line_p);
13487 else if (glyph->type == IMAGE_GLYPH)
13489 fprintf (stderr,
13490 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13491 glyph - row->glyphs[TEXT_AREA],
13492 'I',
13493 glyph->charpos,
13494 (BUFFERP (glyph->object)
13495 ? 'B'
13496 : (STRINGP (glyph->object)
13497 ? 'S'
13498 : '-')),
13499 glyph->pixel_width,
13500 glyph->u.img_id,
13501 '.',
13502 glyph->face_id,
13503 glyph->left_box_line_p,
13504 glyph->right_box_line_p);
13509 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
13510 GLYPHS 0 means don't show glyph contents.
13511 GLYPHS 1 means show glyphs in short form
13512 GLYPHS > 1 means show glyphs in long form. */
13514 void
13515 dump_glyph_row (row, vpos, glyphs)
13516 struct glyph_row *row;
13517 int vpos, glyphs;
13519 if (glyphs != 1)
13521 fprintf (stderr, "Row Start End Used oEI><O\\CTZFesm X Y W H V A P\n");
13522 fprintf (stderr, "=======================================================================\n");
13524 fprintf (stderr, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d%1.1d\
13525 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
13526 vpos,
13527 MATRIX_ROW_START_CHARPOS (row),
13528 MATRIX_ROW_END_CHARPOS (row),
13529 row->used[TEXT_AREA],
13530 row->contains_overlapping_glyphs_p,
13531 row->enabled_p,
13532 row->truncated_on_left_p,
13533 row->truncated_on_right_p,
13534 row->overlay_arrow_p,
13535 row->continued_p,
13536 MATRIX_ROW_CONTINUATION_LINE_P (row),
13537 row->displays_text_p,
13538 row->ends_at_zv_p,
13539 row->fill_line_p,
13540 row->ends_in_middle_of_char_p,
13541 row->starts_in_middle_of_char_p,
13542 row->mouse_face_p,
13543 row->x,
13544 row->y,
13545 row->pixel_width,
13546 row->height,
13547 row->visible_height,
13548 row->ascent,
13549 row->phys_ascent);
13550 fprintf (stderr, "%9d %5d\t%5d\n", row->start.overlay_string_index,
13551 row->end.overlay_string_index,
13552 row->continuation_lines_width);
13553 fprintf (stderr, "%9d %5d\n",
13554 CHARPOS (row->start.string_pos),
13555 CHARPOS (row->end.string_pos));
13556 fprintf (stderr, "%9d %5d\n", row->start.dpvec_index,
13557 row->end.dpvec_index);
13560 if (glyphs > 1)
13562 int area;
13564 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
13566 struct glyph *glyph = row->glyphs[area];
13567 struct glyph *glyph_end = glyph + row->used[area];
13569 /* Glyph for a line end in text. */
13570 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
13571 ++glyph_end;
13573 if (glyph < glyph_end)
13574 fprintf (stderr, " Glyph Type Pos O W Code C Face LR\n");
13576 for (; glyph < glyph_end; ++glyph)
13577 dump_glyph (row, glyph, area);
13580 else if (glyphs == 1)
13582 int area;
13584 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
13586 char *s = (char *) alloca (row->used[area] + 1);
13587 int i;
13589 for (i = 0; i < row->used[area]; ++i)
13591 struct glyph *glyph = row->glyphs[area] + i;
13592 if (glyph->type == CHAR_GLYPH
13593 && glyph->u.ch < 0x80
13594 && glyph->u.ch >= ' ')
13595 s[i] = glyph->u.ch;
13596 else
13597 s[i] = '.';
13600 s[i] = '\0';
13601 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
13607 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
13608 Sdump_glyph_matrix, 0, 1, "p",
13609 doc: /* Dump the current matrix of the selected window to stderr.
13610 Shows contents of glyph row structures. With non-nil
13611 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
13612 glyphs in short form, otherwise show glyphs in long form. */)
13613 (glyphs)
13614 Lisp_Object glyphs;
13616 struct window *w = XWINDOW (selected_window);
13617 struct buffer *buffer = XBUFFER (w->buffer);
13619 fprintf (stderr, "PT = %d, BEGV = %d. ZV = %d\n",
13620 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
13621 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
13622 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
13623 fprintf (stderr, "=============================================\n");
13624 dump_glyph_matrix (w->current_matrix,
13625 NILP (glyphs) ? 0 : XINT (glyphs));
13626 return Qnil;
13630 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
13631 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
13634 struct frame *f = XFRAME (selected_frame);
13635 dump_glyph_matrix (f->current_matrix, 1);
13636 return Qnil;
13640 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
13641 doc: /* Dump glyph row ROW to stderr.
13642 GLYPH 0 means don't dump glyphs.
13643 GLYPH 1 means dump glyphs in short form.
13644 GLYPH > 1 or omitted means dump glyphs in long form. */)
13645 (row, glyphs)
13646 Lisp_Object row, glyphs;
13648 struct glyph_matrix *matrix;
13649 int vpos;
13651 CHECK_NUMBER (row);
13652 matrix = XWINDOW (selected_window)->current_matrix;
13653 vpos = XINT (row);
13654 if (vpos >= 0 && vpos < matrix->nrows)
13655 dump_glyph_row (MATRIX_ROW (matrix, vpos),
13656 vpos,
13657 INTEGERP (glyphs) ? XINT (glyphs) : 2);
13658 return Qnil;
13662 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
13663 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
13664 GLYPH 0 means don't dump glyphs.
13665 GLYPH 1 means dump glyphs in short form.
13666 GLYPH > 1 or omitted means dump glyphs in long form. */)
13667 (row, glyphs)
13668 Lisp_Object row, glyphs;
13670 struct frame *sf = SELECTED_FRAME ();
13671 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
13672 int vpos;
13674 CHECK_NUMBER (row);
13675 vpos = XINT (row);
13676 if (vpos >= 0 && vpos < m->nrows)
13677 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
13678 INTEGERP (glyphs) ? XINT (glyphs) : 2);
13679 return Qnil;
13683 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
13684 doc: /* Toggle tracing of redisplay.
13685 With ARG, turn tracing on if and only if ARG is positive. */)
13686 (arg)
13687 Lisp_Object arg;
13689 if (NILP (arg))
13690 trace_redisplay_p = !trace_redisplay_p;
13691 else
13693 arg = Fprefix_numeric_value (arg);
13694 trace_redisplay_p = XINT (arg) > 0;
13697 return Qnil;
13701 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
13702 doc: /* Like `format', but print result to stderr.
13703 usage: (trace-to-stderr STRING &rest OBJECTS) */)
13704 (nargs, args)
13705 int nargs;
13706 Lisp_Object *args;
13708 Lisp_Object s = Fformat (nargs, args);
13709 fprintf (stderr, "%s", SDATA (s));
13710 return Qnil;
13713 #endif /* GLYPH_DEBUG */
13717 /***********************************************************************
13718 Building Desired Matrix Rows
13719 ***********************************************************************/
13721 /* Return a temporary glyph row holding the glyphs of an overlay
13722 arrow. Only used for non-window-redisplay windows. */
13724 static struct glyph_row *
13725 get_overlay_arrow_glyph_row (w)
13726 struct window *w;
13728 struct frame *f = XFRAME (WINDOW_FRAME (w));
13729 struct buffer *buffer = XBUFFER (w->buffer);
13730 struct buffer *old = current_buffer;
13731 const unsigned char *arrow_string = SDATA (Voverlay_arrow_string);
13732 int arrow_len = SCHARS (Voverlay_arrow_string);
13733 const unsigned char *arrow_end = arrow_string + arrow_len;
13734 const unsigned char *p;
13735 struct it it;
13736 int multibyte_p;
13737 int n_glyphs_before;
13739 set_buffer_temp (buffer);
13740 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
13741 it.glyph_row->used[TEXT_AREA] = 0;
13742 SET_TEXT_POS (it.position, 0, 0);
13744 multibyte_p = !NILP (buffer->enable_multibyte_characters);
13745 p = arrow_string;
13746 while (p < arrow_end)
13748 Lisp_Object face, ilisp;
13750 /* Get the next character. */
13751 if (multibyte_p)
13752 it.c = string_char_and_length (p, arrow_len, &it.len);
13753 else
13754 it.c = *p, it.len = 1;
13755 p += it.len;
13757 /* Get its face. */
13758 ilisp = make_number (p - arrow_string);
13759 face = Fget_text_property (ilisp, Qface, Voverlay_arrow_string);
13760 it.face_id = compute_char_face (f, it.c, face);
13762 /* Compute its width, get its glyphs. */
13763 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
13764 SET_TEXT_POS (it.position, -1, -1);
13765 PRODUCE_GLYPHS (&it);
13767 /* If this character doesn't fit any more in the line, we have
13768 to remove some glyphs. */
13769 if (it.current_x > it.last_visible_x)
13771 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
13772 break;
13776 set_buffer_temp (old);
13777 return it.glyph_row;
13781 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
13782 glyphs are only inserted for terminal frames since we can't really
13783 win with truncation glyphs when partially visible glyphs are
13784 involved. Which glyphs to insert is determined by
13785 produce_special_glyphs. */
13787 static void
13788 insert_left_trunc_glyphs (it)
13789 struct it *it;
13791 struct it truncate_it;
13792 struct glyph *from, *end, *to, *toend;
13794 xassert (!FRAME_WINDOW_P (it->f));
13796 /* Get the truncation glyphs. */
13797 truncate_it = *it;
13798 truncate_it.current_x = 0;
13799 truncate_it.face_id = DEFAULT_FACE_ID;
13800 truncate_it.glyph_row = &scratch_glyph_row;
13801 truncate_it.glyph_row->used[TEXT_AREA] = 0;
13802 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
13803 truncate_it.object = make_number (0);
13804 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
13806 /* Overwrite glyphs from IT with truncation glyphs. */
13807 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
13808 end = from + truncate_it.glyph_row->used[TEXT_AREA];
13809 to = it->glyph_row->glyphs[TEXT_AREA];
13810 toend = to + it->glyph_row->used[TEXT_AREA];
13812 while (from < end)
13813 *to++ = *from++;
13815 /* There may be padding glyphs left over. Overwrite them too. */
13816 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
13818 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
13819 while (from < end)
13820 *to++ = *from++;
13823 if (to > toend)
13824 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
13828 /* Compute the pixel height and width of IT->glyph_row.
13830 Most of the time, ascent and height of a display line will be equal
13831 to the max_ascent and max_height values of the display iterator
13832 structure. This is not the case if
13834 1. We hit ZV without displaying anything. In this case, max_ascent
13835 and max_height will be zero.
13837 2. We have some glyphs that don't contribute to the line height.
13838 (The glyph row flag contributes_to_line_height_p is for future
13839 pixmap extensions).
13841 The first case is easily covered by using default values because in
13842 these cases, the line height does not really matter, except that it
13843 must not be zero. */
13845 static void
13846 compute_line_metrics (it)
13847 struct it *it;
13849 struct glyph_row *row = it->glyph_row;
13850 int area, i;
13852 if (FRAME_WINDOW_P (it->f))
13854 int i, min_y, max_y;
13856 /* The line may consist of one space only, that was added to
13857 place the cursor on it. If so, the row's height hasn't been
13858 computed yet. */
13859 if (row->height == 0)
13861 if (it->max_ascent + it->max_descent == 0)
13862 it->max_descent = it->max_phys_descent = CANON_Y_UNIT (it->f);
13863 row->ascent = it->max_ascent;
13864 row->height = it->max_ascent + it->max_descent;
13865 row->phys_ascent = it->max_phys_ascent;
13866 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
13869 /* Compute the width of this line. */
13870 row->pixel_width = row->x;
13871 for (i = 0; i < row->used[TEXT_AREA]; ++i)
13872 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
13874 xassert (row->pixel_width >= 0);
13875 xassert (row->ascent >= 0 && row->height > 0);
13877 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
13878 || MATRIX_ROW_OVERLAPS_PRED_P (row));
13880 /* If first line's physical ascent is larger than its logical
13881 ascent, use the physical ascent, and make the row taller.
13882 This makes accented characters fully visible. */
13883 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
13884 && row->phys_ascent > row->ascent)
13886 row->height += row->phys_ascent - row->ascent;
13887 row->ascent = row->phys_ascent;
13890 /* Compute how much of the line is visible. */
13891 row->visible_height = row->height;
13893 min_y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (it->w);
13894 max_y = WINDOW_DISPLAY_HEIGHT_NO_MODE_LINE (it->w);
13896 if (row->y < min_y)
13897 row->visible_height -= min_y - row->y;
13898 if (row->y + row->height > max_y)
13899 row->visible_height -= row->y + row->height - max_y;
13901 else
13903 row->pixel_width = row->used[TEXT_AREA];
13904 if (row->continued_p)
13905 row->pixel_width -= it->continuation_pixel_width;
13906 else if (row->truncated_on_right_p)
13907 row->pixel_width -= it->truncation_pixel_width;
13908 row->ascent = row->phys_ascent = 0;
13909 row->height = row->phys_height = row->visible_height = 1;
13912 /* Compute a hash code for this row. */
13913 row->hash = 0;
13914 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
13915 for (i = 0; i < row->used[area]; ++i)
13916 row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff)
13917 + row->glyphs[area][i].u.val
13918 + row->glyphs[area][i].face_id
13919 + row->glyphs[area][i].padding_p
13920 + (row->glyphs[area][i].type << 2));
13922 it->max_ascent = it->max_descent = 0;
13923 it->max_phys_ascent = it->max_phys_descent = 0;
13927 /* Append one space to the glyph row of iterator IT if doing a
13928 window-based redisplay. DEFAULT_FACE_P non-zero means let the
13929 space have the default face, otherwise let it have the same face as
13930 IT->face_id. Value is non-zero if a space was added.
13932 This function is called to make sure that there is always one glyph
13933 at the end of a glyph row that the cursor can be set on under
13934 window-systems. (If there weren't such a glyph we would not know
13935 how wide and tall a box cursor should be displayed).
13937 At the same time this space let's a nicely handle clearing to the
13938 end of the line if the row ends in italic text. */
13940 static int
13941 append_space (it, default_face_p)
13942 struct it *it;
13943 int default_face_p;
13945 if (FRAME_WINDOW_P (it->f))
13947 int n = it->glyph_row->used[TEXT_AREA];
13949 if (it->glyph_row->glyphs[TEXT_AREA] + n
13950 < it->glyph_row->glyphs[1 + TEXT_AREA])
13952 /* Save some values that must not be changed.
13953 Must save IT->c and IT->len because otherwise
13954 ITERATOR_AT_END_P wouldn't work anymore after
13955 append_space has been called. */
13956 enum display_element_type saved_what = it->what;
13957 int saved_c = it->c, saved_len = it->len;
13958 int saved_x = it->current_x;
13959 int saved_face_id = it->face_id;
13960 struct text_pos saved_pos;
13961 Lisp_Object saved_object;
13962 struct face *face;
13964 saved_object = it->object;
13965 saved_pos = it->position;
13967 it->what = IT_CHARACTER;
13968 bzero (&it->position, sizeof it->position);
13969 it->object = make_number (0);
13970 it->c = ' ';
13971 it->len = 1;
13973 if (default_face_p)
13974 it->face_id = DEFAULT_FACE_ID;
13975 else if (it->face_before_selective_p)
13976 it->face_id = it->saved_face_id;
13977 face = FACE_FROM_ID (it->f, it->face_id);
13978 it->face_id = FACE_FOR_CHAR (it->f, face, 0);
13980 PRODUCE_GLYPHS (it);
13982 it->current_x = saved_x;
13983 it->object = saved_object;
13984 it->position = saved_pos;
13985 it->what = saved_what;
13986 it->face_id = saved_face_id;
13987 it->len = saved_len;
13988 it->c = saved_c;
13989 return 1;
13993 return 0;
13997 /* Extend the face of the last glyph in the text area of IT->glyph_row
13998 to the end of the display line. Called from display_line.
13999 If the glyph row is empty, add a space glyph to it so that we
14000 know the face to draw. Set the glyph row flag fill_line_p. */
14002 static void
14003 extend_face_to_end_of_line (it)
14004 struct it *it;
14006 struct face *face;
14007 struct frame *f = it->f;
14009 /* If line is already filled, do nothing. */
14010 if (it->current_x >= it->last_visible_x)
14011 return;
14013 /* Face extension extends the background and box of IT->face_id
14014 to the end of the line. If the background equals the background
14015 of the frame, we don't have to do anything. */
14016 if (it->face_before_selective_p)
14017 face = FACE_FROM_ID (it->f, it->saved_face_id);
14018 else
14019 face = FACE_FROM_ID (f, it->face_id);
14021 if (FRAME_WINDOW_P (f)
14022 && face->box == FACE_NO_BOX
14023 && face->background == FRAME_BACKGROUND_PIXEL (f)
14024 && !face->stipple)
14025 return;
14027 /* Set the glyph row flag indicating that the face of the last glyph
14028 in the text area has to be drawn to the end of the text area. */
14029 it->glyph_row->fill_line_p = 1;
14031 /* If current character of IT is not ASCII, make sure we have the
14032 ASCII face. This will be automatically undone the next time
14033 get_next_display_element returns a multibyte character. Note
14034 that the character will always be single byte in unibyte text. */
14035 if (!SINGLE_BYTE_CHAR_P (it->c))
14037 it->face_id = FACE_FOR_CHAR (f, face, 0);
14040 if (FRAME_WINDOW_P (f))
14042 /* If the row is empty, add a space with the current face of IT,
14043 so that we know which face to draw. */
14044 if (it->glyph_row->used[TEXT_AREA] == 0)
14046 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
14047 it->glyph_row->glyphs[TEXT_AREA][0].face_id = it->face_id;
14048 it->glyph_row->used[TEXT_AREA] = 1;
14051 else
14053 /* Save some values that must not be changed. */
14054 int saved_x = it->current_x;
14055 struct text_pos saved_pos;
14056 Lisp_Object saved_object;
14057 enum display_element_type saved_what = it->what;
14058 int saved_face_id = it->face_id;
14060 saved_object = it->object;
14061 saved_pos = it->position;
14063 it->what = IT_CHARACTER;
14064 bzero (&it->position, sizeof it->position);
14065 it->object = make_number (0);
14066 it->c = ' ';
14067 it->len = 1;
14068 it->face_id = face->id;
14070 PRODUCE_GLYPHS (it);
14072 while (it->current_x <= it->last_visible_x)
14073 PRODUCE_GLYPHS (it);
14075 /* Don't count these blanks really. It would let us insert a left
14076 truncation glyph below and make us set the cursor on them, maybe. */
14077 it->current_x = saved_x;
14078 it->object = saved_object;
14079 it->position = saved_pos;
14080 it->what = saved_what;
14081 it->face_id = saved_face_id;
14086 /* Value is non-zero if text starting at CHARPOS in current_buffer is
14087 trailing whitespace. */
14089 static int
14090 trailing_whitespace_p (charpos)
14091 int charpos;
14093 int bytepos = CHAR_TO_BYTE (charpos);
14094 int c = 0;
14096 while (bytepos < ZV_BYTE
14097 && (c = FETCH_CHAR (bytepos),
14098 c == ' ' || c == '\t'))
14099 ++bytepos;
14101 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
14103 if (bytepos != PT_BYTE)
14104 return 1;
14106 return 0;
14110 /* Highlight trailing whitespace, if any, in ROW. */
14112 void
14113 highlight_trailing_whitespace (f, row)
14114 struct frame *f;
14115 struct glyph_row *row;
14117 int used = row->used[TEXT_AREA];
14119 if (used)
14121 struct glyph *start = row->glyphs[TEXT_AREA];
14122 struct glyph *glyph = start + used - 1;
14124 /* Skip over glyphs inserted to display the cursor at the
14125 end of a line, for extending the face of the last glyph
14126 to the end of the line on terminals, and for truncation
14127 and continuation glyphs. */
14128 while (glyph >= start
14129 && glyph->type == CHAR_GLYPH
14130 && INTEGERP (glyph->object))
14131 --glyph;
14133 /* If last glyph is a space or stretch, and it's trailing
14134 whitespace, set the face of all trailing whitespace glyphs in
14135 IT->glyph_row to `trailing-whitespace'. */
14136 if (glyph >= start
14137 && BUFFERP (glyph->object)
14138 && (glyph->type == STRETCH_GLYPH
14139 || (glyph->type == CHAR_GLYPH
14140 && glyph->u.ch == ' '))
14141 && trailing_whitespace_p (glyph->charpos))
14143 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0);
14145 while (glyph >= start
14146 && BUFFERP (glyph->object)
14147 && (glyph->type == STRETCH_GLYPH
14148 || (glyph->type == CHAR_GLYPH
14149 && glyph->u.ch == ' ')))
14150 (glyph--)->face_id = face_id;
14156 /* Value is non-zero if glyph row ROW in window W should be
14157 used to hold the cursor. */
14159 static int
14160 cursor_row_p (w, row)
14161 struct window *w;
14162 struct glyph_row *row;
14164 int cursor_row_p = 1;
14166 if (PT == MATRIX_ROW_END_CHARPOS (row))
14168 /* If the row ends with a newline from a string, we don't want
14169 the cursor there (if the row is continued it doesn't end in a
14170 newline). */
14171 if (CHARPOS (row->end.string_pos) >= 0
14172 || MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
14173 cursor_row_p = row->continued_p;
14175 /* If the row ends at ZV, display the cursor at the end of that
14176 row instead of at the start of the row below. */
14177 else if (row->ends_at_zv_p)
14178 cursor_row_p = 1;
14179 else
14180 cursor_row_p = 0;
14183 return cursor_row_p;
14187 /* Construct the glyph row IT->glyph_row in the desired matrix of
14188 IT->w from text at the current position of IT. See dispextern.h
14189 for an overview of struct it. Value is non-zero if
14190 IT->glyph_row displays text, as opposed to a line displaying ZV
14191 only. */
14193 static int
14194 display_line (it)
14195 struct it *it;
14197 struct glyph_row *row = it->glyph_row;
14199 /* We always start displaying at hpos zero even if hscrolled. */
14200 xassert (it->hpos == 0 && it->current_x == 0);
14202 /* We must not display in a row that's not a text row. */
14203 xassert (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
14204 < it->w->desired_matrix->nrows);
14206 /* Is IT->w showing the region? */
14207 it->w->region_showing = it->region_beg_charpos > 0 ? Qt : Qnil;
14209 /* Clear the result glyph row and enable it. */
14210 prepare_desired_row (row);
14212 row->y = it->current_y;
14213 row->start = it->current;
14214 row->continuation_lines_width = it->continuation_lines_width;
14215 row->displays_text_p = 1;
14216 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
14217 it->starts_in_middle_of_char_p = 0;
14219 /* Arrange the overlays nicely for our purposes. Usually, we call
14220 display_line on only one line at a time, in which case this
14221 can't really hurt too much, or we call it on lines which appear
14222 one after another in the buffer, in which case all calls to
14223 recenter_overlay_lists but the first will be pretty cheap. */
14224 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
14226 /* Move over display elements that are not visible because we are
14227 hscrolled. This may stop at an x-position < IT->first_visible_x
14228 if the first glyph is partially visible or if we hit a line end. */
14229 if (it->current_x < it->first_visible_x)
14230 move_it_in_display_line_to (it, ZV, it->first_visible_x,
14231 MOVE_TO_POS | MOVE_TO_X);
14233 /* Get the initial row height. This is either the height of the
14234 text hscrolled, if there is any, or zero. */
14235 row->ascent = it->max_ascent;
14236 row->height = it->max_ascent + it->max_descent;
14237 row->phys_ascent = it->max_phys_ascent;
14238 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
14240 /* Loop generating characters. The loop is left with IT on the next
14241 character to display. */
14242 while (1)
14244 int n_glyphs_before, hpos_before, x_before;
14245 int x, i, nglyphs;
14246 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
14248 /* Retrieve the next thing to display. Value is zero if end of
14249 buffer reached. */
14250 if (!get_next_display_element (it))
14252 /* Maybe add a space at the end of this line that is used to
14253 display the cursor there under X. Set the charpos of the
14254 first glyph of blank lines not corresponding to any text
14255 to -1. */
14256 if ((append_space (it, 1) && row->used[TEXT_AREA] == 1)
14257 || row->used[TEXT_AREA] == 0)
14259 row->glyphs[TEXT_AREA]->charpos = -1;
14260 row->displays_text_p = 0;
14262 if (!NILP (XBUFFER (it->w->buffer)->indicate_empty_lines)
14263 && (!MINI_WINDOW_P (it->w)
14264 || (minibuf_level && EQ (it->window, minibuf_window))))
14265 row->indicate_empty_line_p = 1;
14268 it->continuation_lines_width = 0;
14269 row->ends_at_zv_p = 1;
14270 break;
14273 /* Now, get the metrics of what we want to display. This also
14274 generates glyphs in `row' (which is IT->glyph_row). */
14275 n_glyphs_before = row->used[TEXT_AREA];
14276 x = it->current_x;
14278 /* Remember the line height so far in case the next element doesn't
14279 fit on the line. */
14280 if (!it->truncate_lines_p)
14282 ascent = it->max_ascent;
14283 descent = it->max_descent;
14284 phys_ascent = it->max_phys_ascent;
14285 phys_descent = it->max_phys_descent;
14288 PRODUCE_GLYPHS (it);
14290 /* If this display element was in marginal areas, continue with
14291 the next one. */
14292 if (it->area != TEXT_AREA)
14294 row->ascent = max (row->ascent, it->max_ascent);
14295 row->height = max (row->height, it->max_ascent + it->max_descent);
14296 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14297 row->phys_height = max (row->phys_height,
14298 it->max_phys_ascent + it->max_phys_descent);
14299 set_iterator_to_next (it, 1);
14300 continue;
14303 /* Does the display element fit on the line? If we truncate
14304 lines, we should draw past the right edge of the window. If
14305 we don't truncate, we want to stop so that we can display the
14306 continuation glyph before the right margin. If lines are
14307 continued, there are two possible strategies for characters
14308 resulting in more than 1 glyph (e.g. tabs): Display as many
14309 glyphs as possible in this line and leave the rest for the
14310 continuation line, or display the whole element in the next
14311 line. Original redisplay did the former, so we do it also. */
14312 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
14313 hpos_before = it->hpos;
14314 x_before = x;
14316 if (/* Not a newline. */
14317 nglyphs > 0
14318 /* Glyphs produced fit entirely in the line. */
14319 && it->current_x < it->last_visible_x)
14321 it->hpos += nglyphs;
14322 row->ascent = max (row->ascent, it->max_ascent);
14323 row->height = max (row->height, it->max_ascent + it->max_descent);
14324 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14325 row->phys_height = max (row->phys_height,
14326 it->max_phys_ascent + it->max_phys_descent);
14327 if (it->current_x - it->pixel_width < it->first_visible_x)
14328 row->x = x - it->first_visible_x;
14330 else
14332 int new_x;
14333 struct glyph *glyph;
14335 for (i = 0; i < nglyphs; ++i, x = new_x)
14337 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
14338 new_x = x + glyph->pixel_width;
14340 if (/* Lines are continued. */
14341 !it->truncate_lines_p
14342 && (/* Glyph doesn't fit on the line. */
14343 new_x > it->last_visible_x
14344 /* Or it fits exactly on a window system frame. */
14345 || (new_x == it->last_visible_x
14346 && FRAME_WINDOW_P (it->f))))
14348 /* End of a continued line. */
14350 if (it->hpos == 0
14351 || (new_x == it->last_visible_x
14352 && FRAME_WINDOW_P (it->f)))
14354 /* Current glyph is the only one on the line or
14355 fits exactly on the line. We must continue
14356 the line because we can't draw the cursor
14357 after the glyph. */
14358 row->continued_p = 1;
14359 it->current_x = new_x;
14360 it->continuation_lines_width += new_x;
14361 ++it->hpos;
14362 if (i == nglyphs - 1)
14363 set_iterator_to_next (it, 1);
14365 else if (CHAR_GLYPH_PADDING_P (*glyph)
14366 && !FRAME_WINDOW_P (it->f))
14368 /* A padding glyph that doesn't fit on this line.
14369 This means the whole character doesn't fit
14370 on the line. */
14371 row->used[TEXT_AREA] = n_glyphs_before;
14373 /* Fill the rest of the row with continuation
14374 glyphs like in 20.x. */
14375 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
14376 < row->glyphs[1 + TEXT_AREA])
14377 produce_special_glyphs (it, IT_CONTINUATION);
14379 row->continued_p = 1;
14380 it->current_x = x_before;
14381 it->continuation_lines_width += x_before;
14383 /* Restore the height to what it was before the
14384 element not fitting on the line. */
14385 it->max_ascent = ascent;
14386 it->max_descent = descent;
14387 it->max_phys_ascent = phys_ascent;
14388 it->max_phys_descent = phys_descent;
14390 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
14392 /* A TAB that extends past the right edge of the
14393 window. This produces a single glyph on
14394 window system frames. We leave the glyph in
14395 this row and let it fill the row, but don't
14396 consume the TAB. */
14397 it->continuation_lines_width += it->last_visible_x;
14398 row->ends_in_middle_of_char_p = 1;
14399 row->continued_p = 1;
14400 glyph->pixel_width = it->last_visible_x - x;
14401 it->starts_in_middle_of_char_p = 1;
14403 else
14405 /* Something other than a TAB that draws past
14406 the right edge of the window. Restore
14407 positions to values before the element. */
14408 row->used[TEXT_AREA] = n_glyphs_before + i;
14410 /* Display continuation glyphs. */
14411 if (!FRAME_WINDOW_P (it->f))
14412 produce_special_glyphs (it, IT_CONTINUATION);
14413 row->continued_p = 1;
14415 it->continuation_lines_width += x;
14417 if (nglyphs > 1 && i > 0)
14419 row->ends_in_middle_of_char_p = 1;
14420 it->starts_in_middle_of_char_p = 1;
14423 /* Restore the height to what it was before the
14424 element not fitting on the line. */
14425 it->max_ascent = ascent;
14426 it->max_descent = descent;
14427 it->max_phys_ascent = phys_ascent;
14428 it->max_phys_descent = phys_descent;
14431 break;
14433 else if (new_x > it->first_visible_x)
14435 /* Increment number of glyphs actually displayed. */
14436 ++it->hpos;
14438 if (x < it->first_visible_x)
14439 /* Glyph is partially visible, i.e. row starts at
14440 negative X position. */
14441 row->x = x - it->first_visible_x;
14443 else
14445 /* Glyph is completely off the left margin of the
14446 window. This should not happen because of the
14447 move_it_in_display_line at the start of this
14448 function, unless the text display area of the
14449 window is empty. */
14450 xassert (it->first_visible_x <= it->last_visible_x);
14454 row->ascent = max (row->ascent, it->max_ascent);
14455 row->height = max (row->height, it->max_ascent + it->max_descent);
14456 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14457 row->phys_height = max (row->phys_height,
14458 it->max_phys_ascent + it->max_phys_descent);
14460 /* End of this display line if row is continued. */
14461 if (row->continued_p)
14462 break;
14465 /* Is this a line end? If yes, we're also done, after making
14466 sure that a non-default face is extended up to the right
14467 margin of the window. */
14468 if (ITERATOR_AT_END_OF_LINE_P (it))
14470 int used_before = row->used[TEXT_AREA];
14472 row->ends_in_newline_from_string_p = STRINGP (it->object);
14474 /* Add a space at the end of the line that is used to
14475 display the cursor there. */
14476 append_space (it, 0);
14478 /* Extend the face to the end of the line. */
14479 extend_face_to_end_of_line (it);
14481 /* Make sure we have the position. */
14482 if (used_before == 0)
14483 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
14485 /* Consume the line end. This skips over invisible lines. */
14486 set_iterator_to_next (it, 1);
14487 it->continuation_lines_width = 0;
14488 break;
14491 /* Proceed with next display element. Note that this skips
14492 over lines invisible because of selective display. */
14493 set_iterator_to_next (it, 1);
14495 /* If we truncate lines, we are done when the last displayed
14496 glyphs reach past the right margin of the window. */
14497 if (it->truncate_lines_p
14498 && (FRAME_WINDOW_P (it->f)
14499 ? (it->current_x >= it->last_visible_x)
14500 : (it->current_x > it->last_visible_x)))
14502 /* Maybe add truncation glyphs. */
14503 if (!FRAME_WINDOW_P (it->f))
14505 int i, n;
14507 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
14508 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
14509 break;
14511 for (n = row->used[TEXT_AREA]; i < n; ++i)
14513 row->used[TEXT_AREA] = i;
14514 produce_special_glyphs (it, IT_TRUNCATION);
14518 row->truncated_on_right_p = 1;
14519 it->continuation_lines_width = 0;
14520 reseat_at_next_visible_line_start (it, 0);
14521 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
14522 it->hpos = hpos_before;
14523 it->current_x = x_before;
14524 break;
14528 /* If line is not empty and hscrolled, maybe insert truncation glyphs
14529 at the left window margin. */
14530 if (it->first_visible_x
14531 && IT_CHARPOS (*it) != MATRIX_ROW_START_CHARPOS (row))
14533 if (!FRAME_WINDOW_P (it->f))
14534 insert_left_trunc_glyphs (it);
14535 row->truncated_on_left_p = 1;
14538 /* If the start of this line is the overlay arrow-position, then
14539 mark this glyph row as the one containing the overlay arrow.
14540 This is clearly a mess with variable size fonts. It would be
14541 better to let it be displayed like cursors under X. */
14542 if (MARKERP (Voverlay_arrow_position)
14543 && current_buffer == XMARKER (Voverlay_arrow_position)->buffer
14544 && (MATRIX_ROW_START_CHARPOS (row)
14545 == marker_position (Voverlay_arrow_position))
14546 && STRINGP (Voverlay_arrow_string)
14547 && ! overlay_arrow_seen)
14549 /* Overlay arrow in window redisplay is a fringe bitmap. */
14550 if (!FRAME_WINDOW_P (it->f))
14552 struct glyph_row *arrow_row = get_overlay_arrow_glyph_row (it->w);
14553 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
14554 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
14555 struct glyph *p = row->glyphs[TEXT_AREA];
14556 struct glyph *p2, *end;
14558 /* Copy the arrow glyphs. */
14559 while (glyph < arrow_end)
14560 *p++ = *glyph++;
14562 /* Throw away padding glyphs. */
14563 p2 = p;
14564 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
14565 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
14566 ++p2;
14567 if (p2 > p)
14569 while (p2 < end)
14570 *p++ = *p2++;
14571 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
14575 overlay_arrow_seen = 1;
14576 row->overlay_arrow_p = 1;
14579 /* Compute pixel dimensions of this line. */
14580 compute_line_metrics (it);
14582 /* Remember the position at which this line ends. */
14583 row->end = it->current;
14585 /* Maybe set the cursor. */
14586 if (it->w->cursor.vpos < 0
14587 && PT >= MATRIX_ROW_START_CHARPOS (row)
14588 && PT <= MATRIX_ROW_END_CHARPOS (row)
14589 && cursor_row_p (it->w, row))
14590 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
14592 /* Highlight trailing whitespace. */
14593 if (!NILP (Vshow_trailing_whitespace))
14594 highlight_trailing_whitespace (it->f, it->glyph_row);
14596 /* Prepare for the next line. This line starts horizontally at (X
14597 HPOS) = (0 0). Vertical positions are incremented. As a
14598 convenience for the caller, IT->glyph_row is set to the next
14599 row to be used. */
14600 it->current_x = it->hpos = 0;
14601 it->current_y += row->height;
14602 ++it->vpos;
14603 ++it->glyph_row;
14604 return row->displays_text_p;
14609 /***********************************************************************
14610 Menu Bar
14611 ***********************************************************************/
14613 /* Redisplay the menu bar in the frame for window W.
14615 The menu bar of X frames that don't have X toolkit support is
14616 displayed in a special window W->frame->menu_bar_window.
14618 The menu bar of terminal frames is treated specially as far as
14619 glyph matrices are concerned. Menu bar lines are not part of
14620 windows, so the update is done directly on the frame matrix rows
14621 for the menu bar. */
14623 static void
14624 display_menu_bar (w)
14625 struct window *w;
14627 struct frame *f = XFRAME (WINDOW_FRAME (w));
14628 struct it it;
14629 Lisp_Object items;
14630 int i;
14632 /* Don't do all this for graphical frames. */
14633 #ifdef HAVE_NTGUI
14634 if (!NILP (Vwindow_system))
14635 return;
14636 #endif
14637 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
14638 if (FRAME_X_P (f))
14639 return;
14640 #endif
14641 #ifdef MAC_OS
14642 if (FRAME_MAC_P (f))
14643 return;
14644 #endif
14646 #ifdef USE_X_TOOLKIT
14647 xassert (!FRAME_WINDOW_P (f));
14648 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
14649 it.first_visible_x = 0;
14650 it.last_visible_x = FRAME_WINDOW_WIDTH (f) * CANON_X_UNIT (f);
14651 #else /* not USE_X_TOOLKIT */
14652 if (FRAME_WINDOW_P (f))
14654 /* Menu bar lines are displayed in the desired matrix of the
14655 dummy window menu_bar_window. */
14656 struct window *menu_w;
14657 xassert (WINDOWP (f->menu_bar_window));
14658 menu_w = XWINDOW (f->menu_bar_window);
14659 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
14660 MENU_FACE_ID);
14661 it.first_visible_x = 0;
14662 it.last_visible_x = FRAME_WINDOW_WIDTH (f) * CANON_X_UNIT (f);
14664 else
14666 /* This is a TTY frame, i.e. character hpos/vpos are used as
14667 pixel x/y. */
14668 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
14669 MENU_FACE_ID);
14670 it.first_visible_x = 0;
14671 it.last_visible_x = FRAME_WIDTH (f);
14673 #endif /* not USE_X_TOOLKIT */
14675 if (! mode_line_inverse_video)
14676 /* Force the menu-bar to be displayed in the default face. */
14677 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
14679 /* Clear all rows of the menu bar. */
14680 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
14682 struct glyph_row *row = it.glyph_row + i;
14683 clear_glyph_row (row);
14684 row->enabled_p = 1;
14685 row->full_width_p = 1;
14688 /* Display all items of the menu bar. */
14689 items = FRAME_MENU_BAR_ITEMS (it.f);
14690 for (i = 0; i < XVECTOR (items)->size; i += 4)
14692 Lisp_Object string;
14694 /* Stop at nil string. */
14695 string = AREF (items, i + 1);
14696 if (NILP (string))
14697 break;
14699 /* Remember where item was displayed. */
14700 AREF (items, i + 3) = make_number (it.hpos);
14702 /* Display the item, pad with one space. */
14703 if (it.current_x < it.last_visible_x)
14704 display_string (NULL, string, Qnil, 0, 0, &it,
14705 SCHARS (string) + 1, 0, 0, -1);
14708 /* Fill out the line with spaces. */
14709 if (it.current_x < it.last_visible_x)
14710 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
14712 /* Compute the total height of the lines. */
14713 compute_line_metrics (&it);
14718 /***********************************************************************
14719 Mode Line
14720 ***********************************************************************/
14722 /* Redisplay mode lines in the window tree whose root is WINDOW. If
14723 FORCE is non-zero, redisplay mode lines unconditionally.
14724 Otherwise, redisplay only mode lines that are garbaged. Value is
14725 the number of windows whose mode lines were redisplayed. */
14727 static int
14728 redisplay_mode_lines (window, force)
14729 Lisp_Object window;
14730 int force;
14732 int nwindows = 0;
14734 while (!NILP (window))
14736 struct window *w = XWINDOW (window);
14738 if (WINDOWP (w->hchild))
14739 nwindows += redisplay_mode_lines (w->hchild, force);
14740 else if (WINDOWP (w->vchild))
14741 nwindows += redisplay_mode_lines (w->vchild, force);
14742 else if (force
14743 || FRAME_GARBAGED_P (XFRAME (w->frame))
14744 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
14746 struct text_pos lpoint;
14747 struct buffer *old = current_buffer;
14749 /* Set the window's buffer for the mode line display. */
14750 SET_TEXT_POS (lpoint, PT, PT_BYTE);
14751 set_buffer_internal_1 (XBUFFER (w->buffer));
14753 /* Point refers normally to the selected window. For any
14754 other window, set up appropriate value. */
14755 if (!EQ (window, selected_window))
14757 struct text_pos pt;
14759 SET_TEXT_POS_FROM_MARKER (pt, w->pointm);
14760 if (CHARPOS (pt) < BEGV)
14761 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
14762 else if (CHARPOS (pt) > (ZV - 1))
14763 TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
14764 else
14765 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
14768 /* Display mode lines. */
14769 clear_glyph_matrix (w->desired_matrix);
14770 if (display_mode_lines (w))
14772 ++nwindows;
14773 w->must_be_updated_p = 1;
14776 /* Restore old settings. */
14777 set_buffer_internal_1 (old);
14778 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
14781 window = w->next;
14784 return nwindows;
14788 /* Display the mode and/or top line of window W. Value is the number
14789 of mode lines displayed. */
14791 static int
14792 display_mode_lines (w)
14793 struct window *w;
14795 Lisp_Object old_selected_window, old_selected_frame;
14796 int n = 0;
14798 old_selected_frame = selected_frame;
14799 selected_frame = w->frame;
14800 old_selected_window = selected_window;
14801 XSETWINDOW (selected_window, w);
14803 /* These will be set while the mode line specs are processed. */
14804 line_number_displayed = 0;
14805 w->column_number_displayed = Qnil;
14807 if (WINDOW_WANTS_MODELINE_P (w))
14809 struct window *sel_w = XWINDOW (old_selected_window);
14811 /* Select mode line face based on the real selected window. */
14812 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
14813 current_buffer->mode_line_format);
14814 ++n;
14817 if (WINDOW_WANTS_HEADER_LINE_P (w))
14819 display_mode_line (w, HEADER_LINE_FACE_ID,
14820 current_buffer->header_line_format);
14821 ++n;
14824 selected_frame = old_selected_frame;
14825 selected_window = old_selected_window;
14826 return n;
14830 /* Display mode or top line of window W. FACE_ID specifies which line
14831 to display; it is either MODE_LINE_FACE_ID or HEADER_LINE_FACE_ID.
14832 FORMAT is the mode line format to display. Value is the pixel
14833 height of the mode line displayed. */
14835 static int
14836 display_mode_line (w, face_id, format)
14837 struct window *w;
14838 enum face_id face_id;
14839 Lisp_Object format;
14841 struct it it;
14842 struct face *face;
14844 init_iterator (&it, w, -1, -1, NULL, face_id);
14845 prepare_desired_row (it.glyph_row);
14847 if (! mode_line_inverse_video)
14848 /* Force the mode-line to be displayed in the default face. */
14849 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
14851 /* Temporarily make frame's keyboard the current kboard so that
14852 kboard-local variables in the mode_line_format will get the right
14853 values. */
14854 push_frame_kboard (it.f);
14855 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
14856 pop_frame_kboard ();
14858 /* Fill up with spaces. */
14859 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
14861 compute_line_metrics (&it);
14862 it.glyph_row->full_width_p = 1;
14863 it.glyph_row->mode_line_p = 1;
14864 it.glyph_row->continued_p = 0;
14865 it.glyph_row->truncated_on_left_p = 0;
14866 it.glyph_row->truncated_on_right_p = 0;
14868 /* Make a 3D mode-line have a shadow at its right end. */
14869 face = FACE_FROM_ID (it.f, face_id);
14870 extend_face_to_end_of_line (&it);
14871 if (face->box != FACE_NO_BOX)
14873 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
14874 + it.glyph_row->used[TEXT_AREA] - 1);
14875 last->right_box_line_p = 1;
14878 return it.glyph_row->height;
14881 /* Alist that caches the results of :propertize.
14882 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
14883 Lisp_Object mode_line_proptrans_alist;
14885 /* List of strings making up the mode-line. */
14886 Lisp_Object mode_line_string_list;
14888 /* Base face property when building propertized mode line string. */
14889 static Lisp_Object mode_line_string_face;
14890 static Lisp_Object mode_line_string_face_prop;
14893 /* Contribute ELT to the mode line for window IT->w. How it
14894 translates into text depends on its data type.
14896 IT describes the display environment in which we display, as usual.
14898 DEPTH is the depth in recursion. It is used to prevent
14899 infinite recursion here.
14901 FIELD_WIDTH is the number of characters the display of ELT should
14902 occupy in the mode line, and PRECISION is the maximum number of
14903 characters to display from ELT's representation. See
14904 display_string for details.
14906 Returns the hpos of the end of the text generated by ELT.
14908 PROPS is a property list to add to any string we encounter.
14910 If RISKY is nonzero, remove (disregard) any properties in any string
14911 we encounter, and ignore :eval and :propertize.
14913 If the global variable `frame_title_ptr' is non-NULL, then the output
14914 is passed to `store_frame_title' instead of `display_string'. */
14916 static int
14917 display_mode_element (it, depth, field_width, precision, elt, props, risky)
14918 struct it *it;
14919 int depth;
14920 int field_width, precision;
14921 Lisp_Object elt, props;
14922 int risky;
14924 int n = 0, field, prec;
14925 int literal = 0;
14927 tail_recurse:
14928 if (depth > 10)
14929 goto invalid;
14931 depth++;
14933 switch (SWITCH_ENUM_CAST (XTYPE (elt)))
14935 case Lisp_String:
14937 /* A string: output it and check for %-constructs within it. */
14938 unsigned char c;
14939 const unsigned char *this, *lisp_string;
14941 if (!NILP (props) || risky)
14943 Lisp_Object oprops, aelt;
14944 oprops = Ftext_properties_at (make_number (0), elt);
14946 if (NILP (Fequal (props, oprops)) || risky)
14948 /* If the starting string has properties,
14949 merge the specified ones onto the existing ones. */
14950 if (! NILP (oprops) && !risky)
14952 Lisp_Object tem;
14954 oprops = Fcopy_sequence (oprops);
14955 tem = props;
14956 while (CONSP (tem))
14958 oprops = Fplist_put (oprops, XCAR (tem),
14959 XCAR (XCDR (tem)));
14960 tem = XCDR (XCDR (tem));
14962 props = oprops;
14965 aelt = Fassoc (elt, mode_line_proptrans_alist);
14966 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
14968 mode_line_proptrans_alist
14969 = Fcons (aelt, Fdelq (aelt, mode_line_proptrans_alist));
14970 elt = XCAR (aelt);
14972 else
14974 Lisp_Object tem;
14976 elt = Fcopy_sequence (elt);
14977 Fset_text_properties (make_number (0), Flength (elt),
14978 props, elt);
14979 /* Add this item to mode_line_proptrans_alist. */
14980 mode_line_proptrans_alist
14981 = Fcons (Fcons (elt, props),
14982 mode_line_proptrans_alist);
14983 /* Truncate mode_line_proptrans_alist
14984 to at most 50 elements. */
14985 tem = Fnthcdr (make_number (50),
14986 mode_line_proptrans_alist);
14987 if (! NILP (tem))
14988 XSETCDR (tem, Qnil);
14993 this = SDATA (elt);
14994 lisp_string = this;
14996 if (literal)
14998 prec = precision - n;
14999 if (frame_title_ptr)
15000 n += store_frame_title (SDATA (elt), -1, prec);
15001 else if (!NILP (mode_line_string_list))
15002 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
15003 else
15004 n += display_string (NULL, elt, Qnil, 0, 0, it,
15005 0, prec, 0, STRING_MULTIBYTE (elt));
15007 break;
15010 while ((precision <= 0 || n < precision)
15011 && *this
15012 && (frame_title_ptr
15013 || !NILP (mode_line_string_list)
15014 || it->current_x < it->last_visible_x))
15016 const unsigned char *last = this;
15018 /* Advance to end of string or next format specifier. */
15019 while ((c = *this++) != '\0' && c != '%')
15022 if (this - 1 != last)
15024 /* Output to end of string or up to '%'. Field width
15025 is length of string. Don't output more than
15026 PRECISION allows us. */
15027 --this;
15029 prec = chars_in_text (last, this - last);
15030 if (precision > 0 && prec > precision - n)
15031 prec = precision - n;
15033 if (frame_title_ptr)
15034 n += store_frame_title (last, 0, prec);
15035 else if (!NILP (mode_line_string_list))
15037 int bytepos = last - lisp_string;
15038 int charpos = string_byte_to_char (elt, bytepos);
15039 n += store_mode_line_string (NULL,
15040 Fsubstring (elt, make_number (charpos),
15041 make_number (charpos + prec)),
15042 0, 0, 0, Qnil);
15044 else
15046 int bytepos = last - lisp_string;
15047 int charpos = string_byte_to_char (elt, bytepos);
15048 n += display_string (NULL, elt, Qnil, 0, charpos,
15049 it, 0, prec, 0,
15050 STRING_MULTIBYTE (elt));
15053 else /* c == '%' */
15055 const unsigned char *percent_position = this;
15057 /* Get the specified minimum width. Zero means
15058 don't pad. */
15059 field = 0;
15060 while ((c = *this++) >= '0' && c <= '9')
15061 field = field * 10 + c - '0';
15063 /* Don't pad beyond the total padding allowed. */
15064 if (field_width - n > 0 && field > field_width - n)
15065 field = field_width - n;
15067 /* Note that either PRECISION <= 0 or N < PRECISION. */
15068 prec = precision - n;
15070 if (c == 'M')
15071 n += display_mode_element (it, depth, field, prec,
15072 Vglobal_mode_string, props,
15073 risky);
15074 else if (c != 0)
15076 int multibyte;
15077 int bytepos, charpos;
15078 unsigned char *spec;
15080 bytepos = percent_position - lisp_string;
15081 charpos = (STRING_MULTIBYTE (elt)
15082 ? string_byte_to_char (elt, bytepos)
15083 : bytepos);
15085 spec
15086 = decode_mode_spec (it->w, c, field, prec, &multibyte);
15088 if (frame_title_ptr)
15089 n += store_frame_title (spec, field, prec);
15090 else if (!NILP (mode_line_string_list))
15092 int len = strlen (spec);
15093 Lisp_Object tem = make_string (spec, len);
15094 props = Ftext_properties_at (make_number (charpos), elt);
15095 /* Should only keep face property in props */
15096 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
15098 else
15100 int nglyphs_before, nwritten;
15102 nglyphs_before = it->glyph_row->used[TEXT_AREA];
15103 nwritten = display_string (spec, Qnil, elt,
15104 charpos, 0, it,
15105 field, prec, 0,
15106 multibyte);
15108 /* Assign to the glyphs written above the
15109 string where the `%x' came from, position
15110 of the `%'. */
15111 if (nwritten > 0)
15113 struct glyph *glyph
15114 = (it->glyph_row->glyphs[TEXT_AREA]
15115 + nglyphs_before);
15116 int i;
15118 for (i = 0; i < nwritten; ++i)
15120 glyph[i].object = elt;
15121 glyph[i].charpos = charpos;
15124 n += nwritten;
15128 else /* c == 0 */
15129 break;
15133 break;
15135 case Lisp_Symbol:
15136 /* A symbol: process the value of the symbol recursively
15137 as if it appeared here directly. Avoid error if symbol void.
15138 Special case: if value of symbol is a string, output the string
15139 literally. */
15141 register Lisp_Object tem;
15143 /* If the variable is not marked as risky to set
15144 then its contents are risky to use. */
15145 if (NILP (Fget (elt, Qrisky_local_variable)))
15146 risky = 1;
15148 tem = Fboundp (elt);
15149 if (!NILP (tem))
15151 tem = Fsymbol_value (elt);
15152 /* If value is a string, output that string literally:
15153 don't check for % within it. */
15154 if (STRINGP (tem))
15155 literal = 1;
15157 if (!EQ (tem, elt))
15159 /* Give up right away for nil or t. */
15160 elt = tem;
15161 goto tail_recurse;
15165 break;
15167 case Lisp_Cons:
15169 register Lisp_Object car, tem;
15171 /* A cons cell: five distinct cases.
15172 If first element is :eval or :propertize, do something special.
15173 If first element is a string or a cons, process all the elements
15174 and effectively concatenate them.
15175 If first element is a negative number, truncate displaying cdr to
15176 at most that many characters. If positive, pad (with spaces)
15177 to at least that many characters.
15178 If first element is a symbol, process the cadr or caddr recursively
15179 according to whether the symbol's value is non-nil or nil. */
15180 car = XCAR (elt);
15181 if (EQ (car, QCeval))
15183 /* An element of the form (:eval FORM) means evaluate FORM
15184 and use the result as mode line elements. */
15186 if (risky)
15187 break;
15189 if (CONSP (XCDR (elt)))
15191 Lisp_Object spec;
15192 spec = safe_eval (XCAR (XCDR (elt)));
15193 n += display_mode_element (it, depth, field_width - n,
15194 precision - n, spec, props,
15195 risky);
15198 else if (EQ (car, QCpropertize))
15200 /* An element of the form (:propertize ELT PROPS...)
15201 means display ELT but applying properties PROPS. */
15203 if (risky)
15204 break;
15206 if (CONSP (XCDR (elt)))
15207 n += display_mode_element (it, depth, field_width - n,
15208 precision - n, XCAR (XCDR (elt)),
15209 XCDR (XCDR (elt)), risky);
15211 else if (SYMBOLP (car))
15213 tem = Fboundp (car);
15214 elt = XCDR (elt);
15215 if (!CONSP (elt))
15216 goto invalid;
15217 /* elt is now the cdr, and we know it is a cons cell.
15218 Use its car if CAR has a non-nil value. */
15219 if (!NILP (tem))
15221 tem = Fsymbol_value (car);
15222 if (!NILP (tem))
15224 elt = XCAR (elt);
15225 goto tail_recurse;
15228 /* Symbol's value is nil (or symbol is unbound)
15229 Get the cddr of the original list
15230 and if possible find the caddr and use that. */
15231 elt = XCDR (elt);
15232 if (NILP (elt))
15233 break;
15234 else if (!CONSP (elt))
15235 goto invalid;
15236 elt = XCAR (elt);
15237 goto tail_recurse;
15239 else if (INTEGERP (car))
15241 register int lim = XINT (car);
15242 elt = XCDR (elt);
15243 if (lim < 0)
15245 /* Negative int means reduce maximum width. */
15246 if (precision <= 0)
15247 precision = -lim;
15248 else
15249 precision = min (precision, -lim);
15251 else if (lim > 0)
15253 /* Padding specified. Don't let it be more than
15254 current maximum. */
15255 if (precision > 0)
15256 lim = min (precision, lim);
15258 /* If that's more padding than already wanted, queue it.
15259 But don't reduce padding already specified even if
15260 that is beyond the current truncation point. */
15261 field_width = max (lim, field_width);
15263 goto tail_recurse;
15265 else if (STRINGP (car) || CONSP (car))
15267 register int limit = 50;
15268 /* Limit is to protect against circular lists. */
15269 while (CONSP (elt)
15270 && --limit > 0
15271 && (precision <= 0 || n < precision))
15273 n += display_mode_element (it, depth, field_width - n,
15274 precision - n, XCAR (elt),
15275 props, risky);
15276 elt = XCDR (elt);
15280 break;
15282 default:
15283 invalid:
15284 if (frame_title_ptr)
15285 n += store_frame_title ("*invalid*", 0, precision - n);
15286 else if (!NILP (mode_line_string_list))
15287 n += store_mode_line_string ("*invalid*", Qnil, 0, 0, precision - n, Qnil);
15288 else
15289 n += display_string ("*invalid*", Qnil, Qnil, 0, 0, it, 0,
15290 precision - n, 0, 0);
15291 return n;
15294 /* Pad to FIELD_WIDTH. */
15295 if (field_width > 0 && n < field_width)
15297 if (frame_title_ptr)
15298 n += store_frame_title ("", field_width - n, 0);
15299 else if (!NILP (mode_line_string_list))
15300 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
15301 else
15302 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
15303 0, 0, 0);
15306 return n;
15309 /* Store a mode-line string element in mode_line_string_list.
15311 If STRING is non-null, display that C string. Otherwise, the Lisp
15312 string LISP_STRING is displayed.
15314 FIELD_WIDTH is the minimum number of output glyphs to produce.
15315 If STRING has fewer characters than FIELD_WIDTH, pad to the right
15316 with spaces. FIELD_WIDTH <= 0 means don't pad.
15318 PRECISION is the maximum number of characters to output from
15319 STRING. PRECISION <= 0 means don't truncate the string.
15321 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
15322 properties to the string.
15324 PROPS are the properties to add to the string.
15325 The mode_line_string_face face property is always added to the string.
15328 static int store_mode_line_string (string, lisp_string, copy_string, field_width, precision, props)
15329 char *string;
15330 Lisp_Object lisp_string;
15331 int copy_string;
15332 int field_width;
15333 int precision;
15334 Lisp_Object props;
15336 int len;
15337 int n = 0;
15339 if (string != NULL)
15341 len = strlen (string);
15342 if (precision > 0 && len > precision)
15343 len = precision;
15344 lisp_string = make_string (string, len);
15345 if (NILP (props))
15346 props = mode_line_string_face_prop;
15347 else if (!NILP (mode_line_string_face))
15349 Lisp_Object face = Fplist_get (props, Qface);
15350 props = Fcopy_sequence (props);
15351 if (NILP (face))
15352 face = mode_line_string_face;
15353 else
15354 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
15355 props = Fplist_put (props, Qface, face);
15357 Fadd_text_properties (make_number (0), make_number (len),
15358 props, lisp_string);
15360 else
15362 len = XFASTINT (Flength (lisp_string));
15363 if (precision > 0 && len > precision)
15365 len = precision;
15366 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
15367 precision = -1;
15369 if (!NILP (mode_line_string_face))
15371 Lisp_Object face;
15372 if (NILP (props))
15373 props = Ftext_properties_at (make_number (0), lisp_string);
15374 face = Fplist_get (props, Qface);
15375 if (NILP (face))
15376 face = mode_line_string_face;
15377 else
15378 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
15379 props = Fcons (Qface, Fcons (face, Qnil));
15380 if (copy_string)
15381 lisp_string = Fcopy_sequence (lisp_string);
15383 if (!NILP (props))
15384 Fadd_text_properties (make_number (0), make_number (len),
15385 props, lisp_string);
15388 if (len > 0)
15390 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
15391 n += len;
15394 if (field_width > len)
15396 field_width -= len;
15397 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
15398 if (!NILP (props))
15399 Fadd_text_properties (make_number (0), make_number (field_width),
15400 props, lisp_string);
15401 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
15402 n += field_width;
15405 return n;
15409 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
15410 0, 3, 0,
15411 doc: /* Return the mode-line of selected window as a string.
15412 First optional arg FORMAT specifies a different format string (see
15413 `mode-line-format' for details) to use. If FORMAT is t, return
15414 the buffer's header-line. Second optional arg WINDOW specifies a
15415 different window to use as the context for the formatting.
15416 If third optional arg NO-PROPS is non-nil, string is not propertized. */)
15417 (format, window, no_props)
15418 Lisp_Object format, window, no_props;
15420 struct it it;
15421 int len;
15422 struct window *w;
15423 struct buffer *old_buffer = NULL;
15424 enum face_id face_id = DEFAULT_FACE_ID;
15426 if (NILP (window))
15427 window = selected_window;
15428 CHECK_WINDOW (window);
15429 w = XWINDOW (window);
15430 CHECK_BUFFER (w->buffer);
15432 if (XBUFFER (w->buffer) != current_buffer)
15434 old_buffer = current_buffer;
15435 set_buffer_internal_1 (XBUFFER (w->buffer));
15438 if (NILP (format) || EQ (format, Qt))
15440 face_id = NILP (format)
15441 ? CURRENT_MODE_LINE_FACE_ID (w) :
15442 HEADER_LINE_FACE_ID;
15443 format = NILP (format)
15444 ? current_buffer->mode_line_format
15445 : current_buffer->header_line_format;
15448 init_iterator (&it, w, -1, -1, NULL, face_id);
15450 if (NILP (no_props))
15452 mode_line_string_face =
15453 (face_id == MODE_LINE_FACE_ID ? Qmode_line :
15454 face_id == MODE_LINE_INACTIVE_FACE_ID ? Qmode_line_inactive :
15455 face_id == HEADER_LINE_FACE_ID ? Qheader_line : Qnil);
15457 mode_line_string_face_prop =
15458 NILP (mode_line_string_face) ? Qnil :
15459 Fcons (Qface, Fcons (mode_line_string_face, Qnil));
15461 /* We need a dummy last element in mode_line_string_list to
15462 indicate we are building the propertized mode-line string.
15463 Using mode_line_string_face_prop here GC protects it. */
15464 mode_line_string_list =
15465 Fcons (mode_line_string_face_prop, Qnil);
15466 frame_title_ptr = NULL;
15468 else
15470 mode_line_string_face_prop = Qnil;
15471 mode_line_string_list = Qnil;
15472 frame_title_ptr = frame_title_buf;
15475 push_frame_kboard (it.f);
15476 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
15477 pop_frame_kboard ();
15479 if (old_buffer)
15480 set_buffer_internal_1 (old_buffer);
15482 if (NILP (no_props))
15484 Lisp_Object str;
15485 mode_line_string_list = Fnreverse (mode_line_string_list);
15486 str = Fmapconcat (intern ("identity"), XCDR (mode_line_string_list),
15487 make_string ("", 0));
15488 mode_line_string_face_prop = Qnil;
15489 mode_line_string_list = Qnil;
15490 return str;
15493 len = frame_title_ptr - frame_title_buf;
15494 if (len > 0 && frame_title_ptr[-1] == '-')
15496 /* Mode lines typically ends with numerous dashes; reduce to two dashes. */
15497 while (frame_title_ptr > frame_title_buf && *--frame_title_ptr == '-')
15499 frame_title_ptr += 3; /* restore last non-dash + two dashes */
15500 if (len > frame_title_ptr - frame_title_buf)
15501 len = frame_title_ptr - frame_title_buf;
15504 frame_title_ptr = NULL;
15505 return make_string (frame_title_buf, len);
15508 /* Write a null-terminated, right justified decimal representation of
15509 the positive integer D to BUF using a minimal field width WIDTH. */
15511 static void
15512 pint2str (buf, width, d)
15513 register char *buf;
15514 register int width;
15515 register int d;
15517 register char *p = buf;
15519 if (d <= 0)
15520 *p++ = '0';
15521 else
15523 while (d > 0)
15525 *p++ = d % 10 + '0';
15526 d /= 10;
15530 for (width -= (int) (p - buf); width > 0; --width)
15531 *p++ = ' ';
15532 *p-- = '\0';
15533 while (p > buf)
15535 d = *buf;
15536 *buf++ = *p;
15537 *p-- = d;
15541 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
15542 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
15543 type of CODING_SYSTEM. Return updated pointer into BUF. */
15545 static unsigned char invalid_eol_type[] = "(*invalid*)";
15547 static char *
15548 decode_mode_spec_coding (coding_system, buf, eol_flag)
15549 Lisp_Object coding_system;
15550 register char *buf;
15551 int eol_flag;
15553 Lisp_Object val;
15554 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
15555 const unsigned char *eol_str;
15556 int eol_str_len;
15557 /* The EOL conversion we are using. */
15558 Lisp_Object eoltype;
15560 val = Fget (coding_system, Qcoding_system);
15561 eoltype = Qnil;
15563 if (!VECTORP (val)) /* Not yet decided. */
15565 if (multibyte)
15566 *buf++ = '-';
15567 if (eol_flag)
15568 eoltype = eol_mnemonic_undecided;
15569 /* Don't mention EOL conversion if it isn't decided. */
15571 else
15573 Lisp_Object eolvalue;
15575 eolvalue = Fget (coding_system, Qeol_type);
15577 if (multibyte)
15578 *buf++ = XFASTINT (AREF (val, 1));
15580 if (eol_flag)
15582 /* The EOL conversion that is normal on this system. */
15584 if (NILP (eolvalue)) /* Not yet decided. */
15585 eoltype = eol_mnemonic_undecided;
15586 else if (VECTORP (eolvalue)) /* Not yet decided. */
15587 eoltype = eol_mnemonic_undecided;
15588 else /* INTEGERP (eolvalue) -- 0:LF, 1:CRLF, 2:CR */
15589 eoltype = (XFASTINT (eolvalue) == 0
15590 ? eol_mnemonic_unix
15591 : (XFASTINT (eolvalue) == 1
15592 ? eol_mnemonic_dos : eol_mnemonic_mac));
15596 if (eol_flag)
15598 /* Mention the EOL conversion if it is not the usual one. */
15599 if (STRINGP (eoltype))
15601 eol_str = SDATA (eoltype);
15602 eol_str_len = SBYTES (eoltype);
15604 else if (INTEGERP (eoltype)
15605 && CHAR_VALID_P (XINT (eoltype), 0))
15607 unsigned char *tmp = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
15608 eol_str_len = CHAR_STRING (XINT (eoltype), tmp);
15609 eol_str = tmp;
15611 else
15613 eol_str = invalid_eol_type;
15614 eol_str_len = sizeof (invalid_eol_type) - 1;
15616 bcopy (eol_str, buf, eol_str_len);
15617 buf += eol_str_len;
15620 return buf;
15623 /* Return a string for the output of a mode line %-spec for window W,
15624 generated by character C. PRECISION >= 0 means don't return a
15625 string longer than that value. FIELD_WIDTH > 0 means pad the
15626 string returned with spaces to that value. Return 1 in *MULTIBYTE
15627 if the result is multibyte text. */
15629 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
15631 static char *
15632 decode_mode_spec (w, c, field_width, precision, multibyte)
15633 struct window *w;
15634 register int c;
15635 int field_width, precision;
15636 int *multibyte;
15638 Lisp_Object obj;
15639 struct frame *f = XFRAME (WINDOW_FRAME (w));
15640 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
15641 struct buffer *b = XBUFFER (w->buffer);
15643 obj = Qnil;
15644 *multibyte = 0;
15646 switch (c)
15648 case '*':
15649 if (!NILP (b->read_only))
15650 return "%";
15651 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
15652 return "*";
15653 return "-";
15655 case '+':
15656 /* This differs from %* only for a modified read-only buffer. */
15657 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
15658 return "*";
15659 if (!NILP (b->read_only))
15660 return "%";
15661 return "-";
15663 case '&':
15664 /* This differs from %* in ignoring read-only-ness. */
15665 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
15666 return "*";
15667 return "-";
15669 case '%':
15670 return "%";
15672 case '[':
15674 int i;
15675 char *p;
15677 if (command_loop_level > 5)
15678 return "[[[... ";
15679 p = decode_mode_spec_buf;
15680 for (i = 0; i < command_loop_level; i++)
15681 *p++ = '[';
15682 *p = 0;
15683 return decode_mode_spec_buf;
15686 case ']':
15688 int i;
15689 char *p;
15691 if (command_loop_level > 5)
15692 return " ...]]]";
15693 p = decode_mode_spec_buf;
15694 for (i = 0; i < command_loop_level; i++)
15695 *p++ = ']';
15696 *p = 0;
15697 return decode_mode_spec_buf;
15700 case '-':
15702 register int i;
15704 /* Let lots_of_dashes be a string of infinite length. */
15705 if (!NILP (mode_line_string_list))
15706 return "--";
15707 if (field_width <= 0
15708 || field_width > sizeof (lots_of_dashes))
15710 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
15711 decode_mode_spec_buf[i] = '-';
15712 decode_mode_spec_buf[i] = '\0';
15713 return decode_mode_spec_buf;
15715 else
15716 return lots_of_dashes;
15719 case 'b':
15720 obj = b->name;
15721 break;
15723 case 'c':
15725 int col = (int) current_column (); /* iftc */
15726 w->column_number_displayed = make_number (col);
15727 pint2str (decode_mode_spec_buf, field_width, col);
15728 return decode_mode_spec_buf;
15731 case 'F':
15732 /* %F displays the frame name. */
15733 if (!NILP (f->title))
15734 return (char *) SDATA (f->title);
15735 if (f->explicit_name || ! FRAME_WINDOW_P (f))
15736 return (char *) SDATA (f->name);
15737 return "Emacs";
15739 case 'f':
15740 obj = b->filename;
15741 break;
15743 case 'l':
15745 int startpos = XMARKER (w->start)->charpos;
15746 int startpos_byte = marker_byte_position (w->start);
15747 int line, linepos, linepos_byte, topline;
15748 int nlines, junk;
15749 int height = XFASTINT (w->height);
15751 /* If we decided that this buffer isn't suitable for line numbers,
15752 don't forget that too fast. */
15753 if (EQ (w->base_line_pos, w->buffer))
15754 goto no_value;
15755 /* But do forget it, if the window shows a different buffer now. */
15756 else if (BUFFERP (w->base_line_pos))
15757 w->base_line_pos = Qnil;
15759 /* If the buffer is very big, don't waste time. */
15760 if (INTEGERP (Vline_number_display_limit)
15761 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
15763 w->base_line_pos = Qnil;
15764 w->base_line_number = Qnil;
15765 goto no_value;
15768 if (!NILP (w->base_line_number)
15769 && !NILP (w->base_line_pos)
15770 && XFASTINT (w->base_line_pos) <= startpos)
15772 line = XFASTINT (w->base_line_number);
15773 linepos = XFASTINT (w->base_line_pos);
15774 linepos_byte = buf_charpos_to_bytepos (b, linepos);
15776 else
15778 line = 1;
15779 linepos = BUF_BEGV (b);
15780 linepos_byte = BUF_BEGV_BYTE (b);
15783 /* Count lines from base line to window start position. */
15784 nlines = display_count_lines (linepos, linepos_byte,
15785 startpos_byte,
15786 startpos, &junk);
15788 topline = nlines + line;
15790 /* Determine a new base line, if the old one is too close
15791 or too far away, or if we did not have one.
15792 "Too close" means it's plausible a scroll-down would
15793 go back past it. */
15794 if (startpos == BUF_BEGV (b))
15796 w->base_line_number = make_number (topline);
15797 w->base_line_pos = make_number (BUF_BEGV (b));
15799 else if (nlines < height + 25 || nlines > height * 3 + 50
15800 || linepos == BUF_BEGV (b))
15802 int limit = BUF_BEGV (b);
15803 int limit_byte = BUF_BEGV_BYTE (b);
15804 int position;
15805 int distance = (height * 2 + 30) * line_number_display_limit_width;
15807 if (startpos - distance > limit)
15809 limit = startpos - distance;
15810 limit_byte = CHAR_TO_BYTE (limit);
15813 nlines = display_count_lines (startpos, startpos_byte,
15814 limit_byte,
15815 - (height * 2 + 30),
15816 &position);
15817 /* If we couldn't find the lines we wanted within
15818 line_number_display_limit_width chars per line,
15819 give up on line numbers for this window. */
15820 if (position == limit_byte && limit == startpos - distance)
15822 w->base_line_pos = w->buffer;
15823 w->base_line_number = Qnil;
15824 goto no_value;
15827 w->base_line_number = make_number (topline - nlines);
15828 w->base_line_pos = make_number (BYTE_TO_CHAR (position));
15831 /* Now count lines from the start pos to point. */
15832 nlines = display_count_lines (startpos, startpos_byte,
15833 PT_BYTE, PT, &junk);
15835 /* Record that we did display the line number. */
15836 line_number_displayed = 1;
15838 /* Make the string to show. */
15839 pint2str (decode_mode_spec_buf, field_width, topline + nlines);
15840 return decode_mode_spec_buf;
15841 no_value:
15843 char* p = decode_mode_spec_buf;
15844 int pad = field_width - 2;
15845 while (pad-- > 0)
15846 *p++ = ' ';
15847 *p++ = '?';
15848 *p++ = '?';
15849 *p = '\0';
15850 return decode_mode_spec_buf;
15853 break;
15855 case 'm':
15856 obj = b->mode_name;
15857 break;
15859 case 'n':
15860 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
15861 return " Narrow";
15862 break;
15864 case 'p':
15866 int pos = marker_position (w->start);
15867 int total = BUF_ZV (b) - BUF_BEGV (b);
15869 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
15871 if (pos <= BUF_BEGV (b))
15872 return "All";
15873 else
15874 return "Bottom";
15876 else if (pos <= BUF_BEGV (b))
15877 return "Top";
15878 else
15880 if (total > 1000000)
15881 /* Do it differently for a large value, to avoid overflow. */
15882 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
15883 else
15884 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
15885 /* We can't normally display a 3-digit number,
15886 so get us a 2-digit number that is close. */
15887 if (total == 100)
15888 total = 99;
15889 sprintf (decode_mode_spec_buf, "%2d%%", total);
15890 return decode_mode_spec_buf;
15894 /* Display percentage of size above the bottom of the screen. */
15895 case 'P':
15897 int toppos = marker_position (w->start);
15898 int botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
15899 int total = BUF_ZV (b) - BUF_BEGV (b);
15901 if (botpos >= BUF_ZV (b))
15903 if (toppos <= BUF_BEGV (b))
15904 return "All";
15905 else
15906 return "Bottom";
15908 else
15910 if (total > 1000000)
15911 /* Do it differently for a large value, to avoid overflow. */
15912 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
15913 else
15914 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
15915 /* We can't normally display a 3-digit number,
15916 so get us a 2-digit number that is close. */
15917 if (total == 100)
15918 total = 99;
15919 if (toppos <= BUF_BEGV (b))
15920 sprintf (decode_mode_spec_buf, "Top%2d%%", total);
15921 else
15922 sprintf (decode_mode_spec_buf, "%2d%%", total);
15923 return decode_mode_spec_buf;
15927 case 's':
15928 /* status of process */
15929 obj = Fget_buffer_process (w->buffer);
15930 if (NILP (obj))
15931 return "no process";
15932 #ifdef subprocesses
15933 obj = Fsymbol_name (Fprocess_status (obj));
15934 #endif
15935 break;
15937 case 't': /* indicate TEXT or BINARY */
15938 #ifdef MODE_LINE_BINARY_TEXT
15939 return MODE_LINE_BINARY_TEXT (b);
15940 #else
15941 return "T";
15942 #endif
15944 case 'z':
15945 /* coding-system (not including end-of-line format) */
15946 case 'Z':
15947 /* coding-system (including end-of-line type) */
15949 int eol_flag = (c == 'Z');
15950 char *p = decode_mode_spec_buf;
15952 if (! FRAME_WINDOW_P (f))
15954 /* No need to mention EOL here--the terminal never needs
15955 to do EOL conversion. */
15956 p = decode_mode_spec_coding (keyboard_coding.symbol, p, 0);
15957 p = decode_mode_spec_coding (terminal_coding.symbol, p, 0);
15959 p = decode_mode_spec_coding (b->buffer_file_coding_system,
15960 p, eol_flag);
15962 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
15963 #ifdef subprocesses
15964 obj = Fget_buffer_process (Fcurrent_buffer ());
15965 if (PROCESSP (obj))
15967 p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system,
15968 p, eol_flag);
15969 p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system,
15970 p, eol_flag);
15972 #endif /* subprocesses */
15973 #endif /* 0 */
15974 *p = 0;
15975 return decode_mode_spec_buf;
15979 if (STRINGP (obj))
15981 *multibyte = STRING_MULTIBYTE (obj);
15982 return (char *) SDATA (obj);
15984 else
15985 return "";
15989 /* Count up to COUNT lines starting from START / START_BYTE.
15990 But don't go beyond LIMIT_BYTE.
15991 Return the number of lines thus found (always nonnegative).
15993 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
15995 static int
15996 display_count_lines (start, start_byte, limit_byte, count, byte_pos_ptr)
15997 int start, start_byte, limit_byte, count;
15998 int *byte_pos_ptr;
16000 register unsigned char *cursor;
16001 unsigned char *base;
16003 register int ceiling;
16004 register unsigned char *ceiling_addr;
16005 int orig_count = count;
16007 /* If we are not in selective display mode,
16008 check only for newlines. */
16009 int selective_display = (!NILP (current_buffer->selective_display)
16010 && !INTEGERP (current_buffer->selective_display));
16012 if (count > 0)
16014 while (start_byte < limit_byte)
16016 ceiling = BUFFER_CEILING_OF (start_byte);
16017 ceiling = min (limit_byte - 1, ceiling);
16018 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
16019 base = (cursor = BYTE_POS_ADDR (start_byte));
16020 while (1)
16022 if (selective_display)
16023 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
16025 else
16026 while (*cursor != '\n' && ++cursor != ceiling_addr)
16029 if (cursor != ceiling_addr)
16031 if (--count == 0)
16033 start_byte += cursor - base + 1;
16034 *byte_pos_ptr = start_byte;
16035 return orig_count;
16037 else
16038 if (++cursor == ceiling_addr)
16039 break;
16041 else
16042 break;
16044 start_byte += cursor - base;
16047 else
16049 while (start_byte > limit_byte)
16051 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
16052 ceiling = max (limit_byte, ceiling);
16053 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1;
16054 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
16055 while (1)
16057 if (selective_display)
16058 while (--cursor != ceiling_addr
16059 && *cursor != '\n' && *cursor != 015)
16061 else
16062 while (--cursor != ceiling_addr && *cursor != '\n')
16065 if (cursor != ceiling_addr)
16067 if (++count == 0)
16069 start_byte += cursor - base + 1;
16070 *byte_pos_ptr = start_byte;
16071 /* When scanning backwards, we should
16072 not count the newline posterior to which we stop. */
16073 return - orig_count - 1;
16076 else
16077 break;
16079 /* Here we add 1 to compensate for the last decrement
16080 of CURSOR, which took it past the valid range. */
16081 start_byte += cursor - base + 1;
16085 *byte_pos_ptr = limit_byte;
16087 if (count < 0)
16088 return - orig_count + count;
16089 return orig_count - count;
16095 /***********************************************************************
16096 Displaying strings
16097 ***********************************************************************/
16099 /* Display a NUL-terminated string, starting with index START.
16101 If STRING is non-null, display that C string. Otherwise, the Lisp
16102 string LISP_STRING is displayed.
16104 If FACE_STRING is not nil, FACE_STRING_POS is a position in
16105 FACE_STRING. Display STRING or LISP_STRING with the face at
16106 FACE_STRING_POS in FACE_STRING:
16108 Display the string in the environment given by IT, but use the
16109 standard display table, temporarily.
16111 FIELD_WIDTH is the minimum number of output glyphs to produce.
16112 If STRING has fewer characters than FIELD_WIDTH, pad to the right
16113 with spaces. If STRING has more characters, more than FIELD_WIDTH
16114 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
16116 PRECISION is the maximum number of characters to output from
16117 STRING. PRECISION < 0 means don't truncate the string.
16119 This is roughly equivalent to printf format specifiers:
16121 FIELD_WIDTH PRECISION PRINTF
16122 ----------------------------------------
16123 -1 -1 %s
16124 -1 10 %.10s
16125 10 -1 %10s
16126 20 10 %20.10s
16128 MULTIBYTE zero means do not display multibyte chars, > 0 means do
16129 display them, and < 0 means obey the current buffer's value of
16130 enable_multibyte_characters.
16132 Value is the number of glyphs produced. */
16134 static int
16135 display_string (string, lisp_string, face_string, face_string_pos,
16136 start, it, field_width, precision, max_x, multibyte)
16137 unsigned char *string;
16138 Lisp_Object lisp_string;
16139 Lisp_Object face_string;
16140 int face_string_pos;
16141 int start;
16142 struct it *it;
16143 int field_width, precision, max_x;
16144 int multibyte;
16146 int hpos_at_start = it->hpos;
16147 int saved_face_id = it->face_id;
16148 struct glyph_row *row = it->glyph_row;
16150 /* Initialize the iterator IT for iteration over STRING beginning
16151 with index START. */
16152 reseat_to_string (it, string, lisp_string, start,
16153 precision, field_width, multibyte);
16155 /* If displaying STRING, set up the face of the iterator
16156 from LISP_STRING, if that's given. */
16157 if (STRINGP (face_string))
16159 int endptr;
16160 struct face *face;
16162 it->face_id
16163 = face_at_string_position (it->w, face_string, face_string_pos,
16164 0, it->region_beg_charpos,
16165 it->region_end_charpos,
16166 &endptr, it->base_face_id, 0);
16167 face = FACE_FROM_ID (it->f, it->face_id);
16168 it->face_box_p = face->box != FACE_NO_BOX;
16171 /* Set max_x to the maximum allowed X position. Don't let it go
16172 beyond the right edge of the window. */
16173 if (max_x <= 0)
16174 max_x = it->last_visible_x;
16175 else
16176 max_x = min (max_x, it->last_visible_x);
16178 /* Skip over display elements that are not visible. because IT->w is
16179 hscrolled. */
16180 if (it->current_x < it->first_visible_x)
16181 move_it_in_display_line_to (it, 100000, it->first_visible_x,
16182 MOVE_TO_POS | MOVE_TO_X);
16184 row->ascent = it->max_ascent;
16185 row->height = it->max_ascent + it->max_descent;
16186 row->phys_ascent = it->max_phys_ascent;
16187 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
16189 /* This condition is for the case that we are called with current_x
16190 past last_visible_x. */
16191 while (it->current_x < max_x)
16193 int x_before, x, n_glyphs_before, i, nglyphs;
16195 /* Get the next display element. */
16196 if (!get_next_display_element (it))
16197 break;
16199 /* Produce glyphs. */
16200 x_before = it->current_x;
16201 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
16202 PRODUCE_GLYPHS (it);
16204 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
16205 i = 0;
16206 x = x_before;
16207 while (i < nglyphs)
16209 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
16211 if (!it->truncate_lines_p
16212 && x + glyph->pixel_width > max_x)
16214 /* End of continued line or max_x reached. */
16215 if (CHAR_GLYPH_PADDING_P (*glyph))
16217 /* A wide character is unbreakable. */
16218 it->glyph_row->used[TEXT_AREA] = n_glyphs_before;
16219 it->current_x = x_before;
16221 else
16223 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
16224 it->current_x = x;
16226 break;
16228 else if (x + glyph->pixel_width > it->first_visible_x)
16230 /* Glyph is at least partially visible. */
16231 ++it->hpos;
16232 if (x < it->first_visible_x)
16233 it->glyph_row->x = x - it->first_visible_x;
16235 else
16237 /* Glyph is off the left margin of the display area.
16238 Should not happen. */
16239 abort ();
16242 row->ascent = max (row->ascent, it->max_ascent);
16243 row->height = max (row->height, it->max_ascent + it->max_descent);
16244 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
16245 row->phys_height = max (row->phys_height,
16246 it->max_phys_ascent + it->max_phys_descent);
16247 x += glyph->pixel_width;
16248 ++i;
16251 /* Stop if max_x reached. */
16252 if (i < nglyphs)
16253 break;
16255 /* Stop at line ends. */
16256 if (ITERATOR_AT_END_OF_LINE_P (it))
16258 it->continuation_lines_width = 0;
16259 break;
16262 set_iterator_to_next (it, 1);
16264 /* Stop if truncating at the right edge. */
16265 if (it->truncate_lines_p
16266 && it->current_x >= it->last_visible_x)
16268 /* Add truncation mark, but don't do it if the line is
16269 truncated at a padding space. */
16270 if (IT_CHARPOS (*it) < it->string_nchars)
16272 if (!FRAME_WINDOW_P (it->f))
16274 int i, n;
16276 if (it->current_x > it->last_visible_x)
16278 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
16279 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
16280 break;
16281 for (n = row->used[TEXT_AREA]; i < n; ++i)
16283 row->used[TEXT_AREA] = i;
16284 produce_special_glyphs (it, IT_TRUNCATION);
16287 produce_special_glyphs (it, IT_TRUNCATION);
16289 it->glyph_row->truncated_on_right_p = 1;
16291 break;
16295 /* Maybe insert a truncation at the left. */
16296 if (it->first_visible_x
16297 && IT_CHARPOS (*it) > 0)
16299 if (!FRAME_WINDOW_P (it->f))
16300 insert_left_trunc_glyphs (it);
16301 it->glyph_row->truncated_on_left_p = 1;
16304 it->face_id = saved_face_id;
16306 /* Value is number of columns displayed. */
16307 return it->hpos - hpos_at_start;
16312 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
16313 appears as an element of LIST or as the car of an element of LIST.
16314 If PROPVAL is a list, compare each element against LIST in that
16315 way, and return 1/2 if any element of PROPVAL is found in LIST.
16316 Otherwise return 0. This function cannot quit.
16317 The return value is 2 if the text is invisible but with an ellipsis
16318 and 1 if it's invisible and without an ellipsis. */
16321 invisible_p (propval, list)
16322 register Lisp_Object propval;
16323 Lisp_Object list;
16325 register Lisp_Object tail, proptail;
16327 for (tail = list; CONSP (tail); tail = XCDR (tail))
16329 register Lisp_Object tem;
16330 tem = XCAR (tail);
16331 if (EQ (propval, tem))
16332 return 1;
16333 if (CONSP (tem) && EQ (propval, XCAR (tem)))
16334 return NILP (XCDR (tem)) ? 1 : 2;
16337 if (CONSP (propval))
16339 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
16341 Lisp_Object propelt;
16342 propelt = XCAR (proptail);
16343 for (tail = list; CONSP (tail); tail = XCDR (tail))
16345 register Lisp_Object tem;
16346 tem = XCAR (tail);
16347 if (EQ (propelt, tem))
16348 return 1;
16349 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
16350 return NILP (XCDR (tem)) ? 1 : 2;
16355 return 0;
16359 /***********************************************************************
16360 Glyph Display
16361 ***********************************************************************/
16363 #ifdef HAVE_WINDOW_SYSTEM
16365 #if GLYPH_DEBUG
16367 void
16368 dump_glyph_string (s)
16369 struct glyph_string *s;
16371 fprintf (stderr, "glyph string\n");
16372 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
16373 s->x, s->y, s->width, s->height);
16374 fprintf (stderr, " ybase = %d\n", s->ybase);
16375 fprintf (stderr, " hl = %d\n", s->hl);
16376 fprintf (stderr, " left overhang = %d, right = %d\n",
16377 s->left_overhang, s->right_overhang);
16378 fprintf (stderr, " nchars = %d\n", s->nchars);
16379 fprintf (stderr, " extends to end of line = %d\n",
16380 s->extends_to_end_of_line_p);
16381 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
16382 fprintf (stderr, " bg width = %d\n", s->background_width);
16385 #endif /* GLYPH_DEBUG */
16387 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
16388 of XChar2b structures for S; it can't be allocated in
16389 init_glyph_string because it must be allocated via `alloca'. W
16390 is the window on which S is drawn. ROW and AREA are the glyph row
16391 and area within the row from which S is constructed. START is the
16392 index of the first glyph structure covered by S. HL is a
16393 face-override for drawing S. */
16395 #ifdef HAVE_NTGUI
16396 #define OPTIONAL_HDC(hdc) hdc,
16397 #define DECLARE_HDC(hdc) HDC hdc;
16398 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
16399 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
16400 #endif
16402 #ifndef OPTIONAL_HDC
16403 #define OPTIONAL_HDC(hdc)
16404 #define DECLARE_HDC(hdc)
16405 #define ALLOCATE_HDC(hdc, f)
16406 #define RELEASE_HDC(hdc, f)
16407 #endif
16409 static void
16410 init_glyph_string (s, OPTIONAL_HDC (hdc) char2b, w, row, area, start, hl)
16411 struct glyph_string *s;
16412 DECLARE_HDC (hdc)
16413 XChar2b *char2b;
16414 struct window *w;
16415 struct glyph_row *row;
16416 enum glyph_row_area area;
16417 int start;
16418 enum draw_glyphs_face hl;
16420 bzero (s, sizeof *s);
16421 s->w = w;
16422 s->f = XFRAME (w->frame);
16423 #ifdef HAVE_NTGUI
16424 s->hdc = hdc;
16425 #endif
16426 s->display = FRAME_X_DISPLAY (s->f);
16427 s->window = FRAME_X_WINDOW (s->f);
16428 s->char2b = char2b;
16429 s->hl = hl;
16430 s->row = row;
16431 s->area = area;
16432 s->first_glyph = row->glyphs[area] + start;
16433 s->height = row->height;
16434 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
16436 /* Display the internal border below the tool-bar window. */
16437 if (s->w == XWINDOW (s->f->tool_bar_window))
16438 s->y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
16440 s->ybase = s->y + row->ascent;
16444 /* Append the list of glyph strings with head H and tail T to the list
16445 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
16447 static INLINE void
16448 append_glyph_string_lists (head, tail, h, t)
16449 struct glyph_string **head, **tail;
16450 struct glyph_string *h, *t;
16452 if (h)
16454 if (*head)
16455 (*tail)->next = h;
16456 else
16457 *head = h;
16458 h->prev = *tail;
16459 *tail = t;
16464 /* Prepend the list of glyph strings with head H and tail T to the
16465 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
16466 result. */
16468 static INLINE void
16469 prepend_glyph_string_lists (head, tail, h, t)
16470 struct glyph_string **head, **tail;
16471 struct glyph_string *h, *t;
16473 if (h)
16475 if (*head)
16476 (*head)->prev = t;
16477 else
16478 *tail = t;
16479 t->next = *head;
16480 *head = h;
16485 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
16486 Set *HEAD and *TAIL to the resulting list. */
16488 static INLINE void
16489 append_glyph_string (head, tail, s)
16490 struct glyph_string **head, **tail;
16491 struct glyph_string *s;
16493 s->next = s->prev = NULL;
16494 append_glyph_string_lists (head, tail, s, s);
16498 /* Get face and two-byte form of character glyph GLYPH on frame F.
16499 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
16500 a pointer to a realized face that is ready for display. */
16502 static INLINE struct face *
16503 get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
16504 struct frame *f;
16505 struct glyph *glyph;
16506 XChar2b *char2b;
16507 int *two_byte_p;
16509 struct face *face;
16511 xassert (glyph->type == CHAR_GLYPH);
16512 face = FACE_FROM_ID (f, glyph->face_id);
16514 if (two_byte_p)
16515 *two_byte_p = 0;
16517 if (!glyph->multibyte_p)
16519 /* Unibyte case. We don't have to encode, but we have to make
16520 sure to use a face suitable for unibyte. */
16521 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
16523 else if (glyph->u.ch < 128
16524 && glyph->face_id < BASIC_FACE_ID_SENTINEL)
16526 /* Case of ASCII in a face known to fit ASCII. */
16527 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
16529 else
16531 int c1, c2, charset;
16533 /* Split characters into bytes. If c2 is -1 afterwards, C is
16534 really a one-byte character so that byte1 is zero. */
16535 SPLIT_CHAR (glyph->u.ch, charset, c1, c2);
16536 if (c2 > 0)
16537 STORE_XCHAR2B (char2b, c1, c2);
16538 else
16539 STORE_XCHAR2B (char2b, 0, c1);
16541 /* Maybe encode the character in *CHAR2B. */
16542 if (charset != CHARSET_ASCII)
16544 struct font_info *font_info
16545 = FONT_INFO_FROM_ID (f, face->font_info_id);
16546 if (font_info)
16547 glyph->font_type
16548 = rif->encode_char (glyph->u.ch, char2b, font_info, two_byte_p);
16552 /* Make sure X resources of the face are allocated. */
16553 xassert (face != NULL);
16554 PREPARE_FACE_FOR_DISPLAY (f, face);
16555 return face;
16559 /* Fill glyph string S with composition components specified by S->cmp.
16561 FACES is an array of faces for all components of this composition.
16562 S->gidx is the index of the first component for S.
16563 OVERLAPS_P non-zero means S should draw the foreground only, and
16564 use its physical height for clipping.
16566 Value is the index of a component not in S. */
16568 static int
16569 fill_composite_glyph_string (s, faces, overlaps_p)
16570 struct glyph_string *s;
16571 struct face **faces;
16572 int overlaps_p;
16574 int i;
16576 xassert (s);
16578 s->for_overlaps_p = overlaps_p;
16580 s->face = faces[s->gidx];
16581 s->font = s->face->font;
16582 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
16584 /* For all glyphs of this composition, starting at the offset
16585 S->gidx, until we reach the end of the definition or encounter a
16586 glyph that requires the different face, add it to S. */
16587 ++s->nchars;
16588 for (i = s->gidx + 1; i < s->cmp->glyph_len && faces[i] == s->face; ++i)
16589 ++s->nchars;
16591 /* All glyph strings for the same composition has the same width,
16592 i.e. the width set for the first component of the composition. */
16594 s->width = s->first_glyph->pixel_width;
16596 /* If the specified font could not be loaded, use the frame's
16597 default font, but record the fact that we couldn't load it in
16598 the glyph string so that we can draw rectangles for the
16599 characters of the glyph string. */
16600 if (s->font == NULL)
16602 s->font_not_found_p = 1;
16603 s->font = FRAME_FONT (s->f);
16606 /* Adjust base line for subscript/superscript text. */
16607 s->ybase += s->first_glyph->voffset;
16609 xassert (s->face && s->face->gc);
16611 /* This glyph string must always be drawn with 16-bit functions. */
16612 s->two_byte_p = 1;
16614 return s->gidx + s->nchars;
16618 /* Fill glyph string S from a sequence of character glyphs.
16620 FACE_ID is the face id of the string. START is the index of the
16621 first glyph to consider, END is the index of the last + 1.
16622 OVERLAPS_P non-zero means S should draw the foreground only, and
16623 use its physical height for clipping.
16625 Value is the index of the first glyph not in S. */
16627 static int
16628 fill_glyph_string (s, face_id, start, end, overlaps_p)
16629 struct glyph_string *s;
16630 int face_id;
16631 int start, end, overlaps_p;
16633 struct glyph *glyph, *last;
16634 int voffset;
16635 int glyph_not_available_p;
16637 xassert (s->f == XFRAME (s->w->frame));
16638 xassert (s->nchars == 0);
16639 xassert (start >= 0 && end > start);
16641 s->for_overlaps_p = overlaps_p,
16642 glyph = s->row->glyphs[s->area] + start;
16643 last = s->row->glyphs[s->area] + end;
16644 voffset = glyph->voffset;
16646 glyph_not_available_p = glyph->glyph_not_available_p;
16648 while (glyph < last
16649 && glyph->type == CHAR_GLYPH
16650 && glyph->voffset == voffset
16651 /* Same face id implies same font, nowadays. */
16652 && glyph->face_id == face_id
16653 && glyph->glyph_not_available_p == glyph_not_available_p)
16655 int two_byte_p;
16657 s->face = get_glyph_face_and_encoding (s->f, glyph,
16658 s->char2b + s->nchars,
16659 &two_byte_p);
16660 s->two_byte_p = two_byte_p;
16661 ++s->nchars;
16662 xassert (s->nchars <= end - start);
16663 s->width += glyph->pixel_width;
16664 ++glyph;
16667 s->font = s->face->font;
16668 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
16670 /* If the specified font could not be loaded, use the frame's font,
16671 but record the fact that we couldn't load it in
16672 S->font_not_found_p so that we can draw rectangles for the
16673 characters of the glyph string. */
16674 if (s->font == NULL || glyph_not_available_p)
16676 s->font_not_found_p = 1;
16677 s->font = FRAME_FONT (s->f);
16680 /* Adjust base line for subscript/superscript text. */
16681 s->ybase += voffset;
16683 xassert (s->face && s->face->gc);
16684 return glyph - s->row->glyphs[s->area];
16688 /* Fill glyph string S from image glyph S->first_glyph. */
16690 static void
16691 fill_image_glyph_string (s)
16692 struct glyph_string *s;
16694 xassert (s->first_glyph->type == IMAGE_GLYPH);
16695 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
16696 xassert (s->img);
16697 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
16698 s->font = s->face->font;
16699 s->width = s->first_glyph->pixel_width;
16701 /* Adjust base line for subscript/superscript text. */
16702 s->ybase += s->first_glyph->voffset;
16706 /* Fill glyph string S from a sequence of stretch glyphs.
16708 ROW is the glyph row in which the glyphs are found, AREA is the
16709 area within the row. START is the index of the first glyph to
16710 consider, END is the index of the last + 1.
16712 Value is the index of the first glyph not in S. */
16714 static int
16715 fill_stretch_glyph_string (s, row, area, start, end)
16716 struct glyph_string *s;
16717 struct glyph_row *row;
16718 enum glyph_row_area area;
16719 int start, end;
16721 struct glyph *glyph, *last;
16722 int voffset, face_id;
16724 xassert (s->first_glyph->type == STRETCH_GLYPH);
16726 glyph = s->row->glyphs[s->area] + start;
16727 last = s->row->glyphs[s->area] + end;
16728 face_id = glyph->face_id;
16729 s->face = FACE_FROM_ID (s->f, face_id);
16730 s->font = s->face->font;
16731 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
16732 s->width = glyph->pixel_width;
16733 voffset = glyph->voffset;
16735 for (++glyph;
16736 (glyph < last
16737 && glyph->type == STRETCH_GLYPH
16738 && glyph->voffset == voffset
16739 && glyph->face_id == face_id);
16740 ++glyph)
16741 s->width += glyph->pixel_width;
16743 /* Adjust base line for subscript/superscript text. */
16744 s->ybase += voffset;
16746 /* The case that face->gc == 0 is handled when drawing the glyph
16747 string by calling PREPARE_FACE_FOR_DISPLAY. */
16748 xassert (s->face);
16749 return glyph - s->row->glyphs[s->area];
16753 /* EXPORT for RIF:
16754 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
16755 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
16756 assumed to be zero. */
16758 void
16759 x_get_glyph_overhangs (glyph, f, left, right)
16760 struct glyph *glyph;
16761 struct frame *f;
16762 int *left, *right;
16764 *left = *right = 0;
16766 if (glyph->type == CHAR_GLYPH)
16768 XFontStruct *font;
16769 struct face *face;
16770 struct font_info *font_info;
16771 XChar2b char2b;
16772 XCharStruct *pcm;
16774 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
16775 font = face->font;
16776 font_info = FONT_INFO_FROM_ID (f, face->font_info_id);
16777 if (font /* ++KFS: Should this be font_info ? */
16778 && (pcm = rif->per_char_metric (font, &char2b, glyph->font_type)))
16780 if (pcm->rbearing > pcm->width)
16781 *right = pcm->rbearing - pcm->width;
16782 if (pcm->lbearing < 0)
16783 *left = -pcm->lbearing;
16789 /* Return the index of the first glyph preceding glyph string S that
16790 is overwritten by S because of S's left overhang. Value is -1
16791 if no glyphs are overwritten. */
16793 static int
16794 left_overwritten (s)
16795 struct glyph_string *s;
16797 int k;
16799 if (s->left_overhang)
16801 int x = 0, i;
16802 struct glyph *glyphs = s->row->glyphs[s->area];
16803 int first = s->first_glyph - glyphs;
16805 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
16806 x -= glyphs[i].pixel_width;
16808 k = i + 1;
16810 else
16811 k = -1;
16813 return k;
16817 /* Return the index of the first glyph preceding glyph string S that
16818 is overwriting S because of its right overhang. Value is -1 if no
16819 glyph in front of S overwrites S. */
16821 static int
16822 left_overwriting (s)
16823 struct glyph_string *s;
16825 int i, k, x;
16826 struct glyph *glyphs = s->row->glyphs[s->area];
16827 int first = s->first_glyph - glyphs;
16829 k = -1;
16830 x = 0;
16831 for (i = first - 1; i >= 0; --i)
16833 int left, right;
16834 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
16835 if (x + right > 0)
16836 k = i;
16837 x -= glyphs[i].pixel_width;
16840 return k;
16844 /* Return the index of the last glyph following glyph string S that is
16845 not overwritten by S because of S's right overhang. Value is -1 if
16846 no such glyph is found. */
16848 static int
16849 right_overwritten (s)
16850 struct glyph_string *s;
16852 int k = -1;
16854 if (s->right_overhang)
16856 int x = 0, i;
16857 struct glyph *glyphs = s->row->glyphs[s->area];
16858 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
16859 int end = s->row->used[s->area];
16861 for (i = first; i < end && s->right_overhang > x; ++i)
16862 x += glyphs[i].pixel_width;
16864 k = i;
16867 return k;
16871 /* Return the index of the last glyph following glyph string S that
16872 overwrites S because of its left overhang. Value is negative
16873 if no such glyph is found. */
16875 static int
16876 right_overwriting (s)
16877 struct glyph_string *s;
16879 int i, k, x;
16880 int end = s->row->used[s->area];
16881 struct glyph *glyphs = s->row->glyphs[s->area];
16882 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
16884 k = -1;
16885 x = 0;
16886 for (i = first; i < end; ++i)
16888 int left, right;
16889 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
16890 if (x - left < 0)
16891 k = i;
16892 x += glyphs[i].pixel_width;
16895 return k;
16899 /* Get face and two-byte form of character C in face FACE_ID on frame
16900 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
16901 means we want to display multibyte text. DISPLAY_P non-zero means
16902 make sure that X resources for the face returned are allocated.
16903 Value is a pointer to a realized face that is ready for display if
16904 DISPLAY_P is non-zero. */
16906 static INLINE struct face *
16907 get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p, display_p)
16908 struct frame *f;
16909 int c, face_id;
16910 XChar2b *char2b;
16911 int multibyte_p, display_p;
16913 struct face *face = FACE_FROM_ID (f, face_id);
16915 if (!multibyte_p)
16917 /* Unibyte case. We don't have to encode, but we have to make
16918 sure to use a face suitable for unibyte. */
16919 STORE_XCHAR2B (char2b, 0, c);
16920 face_id = FACE_FOR_CHAR (f, face, c);
16921 face = FACE_FROM_ID (f, face_id);
16923 else if (c < 128 && face_id < BASIC_FACE_ID_SENTINEL)
16925 /* Case of ASCII in a face known to fit ASCII. */
16926 STORE_XCHAR2B (char2b, 0, c);
16928 else
16930 int c1, c2, charset;
16932 /* Split characters into bytes. If c2 is -1 afterwards, C is
16933 really a one-byte character so that byte1 is zero. */
16934 SPLIT_CHAR (c, charset, c1, c2);
16935 if (c2 > 0)
16936 STORE_XCHAR2B (char2b, c1, c2);
16937 else
16938 STORE_XCHAR2B (char2b, 0, c1);
16940 /* Maybe encode the character in *CHAR2B. */
16941 if (face->font != NULL)
16943 struct font_info *font_info
16944 = FONT_INFO_FROM_ID (f, face->font_info_id);
16945 if (font_info)
16946 rif->encode_char (c, char2b, font_info, 0);
16950 /* Make sure X resources of the face are allocated. */
16951 #ifdef HAVE_X_WINDOWS
16952 if (display_p)
16953 #endif
16955 xassert (face != NULL);
16956 PREPARE_FACE_FOR_DISPLAY (f, face);
16959 return face;
16963 /* Set background width of glyph string S. START is the index of the
16964 first glyph following S. LAST_X is the right-most x-position + 1
16965 in the drawing area. */
16967 static INLINE void
16968 set_glyph_string_background_width (s, start, last_x)
16969 struct glyph_string *s;
16970 int start;
16971 int last_x;
16973 /* If the face of this glyph string has to be drawn to the end of
16974 the drawing area, set S->extends_to_end_of_line_p. */
16975 struct face *default_face = FACE_FROM_ID (s->f, DEFAULT_FACE_ID);
16977 if (start == s->row->used[s->area]
16978 && s->area == TEXT_AREA
16979 && ((s->hl == DRAW_NORMAL_TEXT
16980 && (s->row->fill_line_p
16981 || s->face->background != default_face->background
16982 || s->face->stipple != default_face->stipple
16983 || s->row->mouse_face_p))
16984 || s->hl == DRAW_MOUSE_FACE
16985 || ((s->hl == DRAW_IMAGE_RAISED || s->hl == DRAW_IMAGE_SUNKEN)
16986 && s->row->fill_line_p)))
16987 s->extends_to_end_of_line_p = 1;
16989 /* If S extends its face to the end of the line, set its
16990 background_width to the distance to the right edge of the drawing
16991 area. */
16992 if (s->extends_to_end_of_line_p)
16993 s->background_width = last_x - s->x + 1;
16994 else
16995 s->background_width = s->width;
16999 /* Compute overhangs and x-positions for glyph string S and its
17000 predecessors, or successors. X is the starting x-position for S.
17001 BACKWARD_P non-zero means process predecessors. */
17003 static void
17004 compute_overhangs_and_x (s, x, backward_p)
17005 struct glyph_string *s;
17006 int x;
17007 int backward_p;
17009 if (backward_p)
17011 while (s)
17013 if (rif->compute_glyph_string_overhangs)
17014 rif->compute_glyph_string_overhangs (s);
17015 x -= s->width;
17016 s->x = x;
17017 s = s->prev;
17020 else
17022 while (s)
17024 if (rif->compute_glyph_string_overhangs)
17025 rif->compute_glyph_string_overhangs (s);
17026 s->x = x;
17027 x += s->width;
17028 s = s->next;
17035 /* The following macros are only called from draw_glyphs below.
17036 They reference the following parameters of that function directly:
17037 `w', `row', `area', and `overlap_p'
17038 as well as the following local variables:
17039 `s', `f', and `hdc' (in W32) */
17041 #ifdef HAVE_NTGUI
17042 /* On W32, silently add local `hdc' variable to argument list of
17043 init_glyph_string. */
17044 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
17045 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
17046 #else
17047 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
17048 init_glyph_string (s, char2b, w, row, area, start, hl)
17049 #endif
17051 /* Add a glyph string for a stretch glyph to the list of strings
17052 between HEAD and TAIL. START is the index of the stretch glyph in
17053 row area AREA of glyph row ROW. END is the index of the last glyph
17054 in that glyph row area. X is the current output position assigned
17055 to the new glyph string constructed. HL overrides that face of the
17056 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
17057 is the right-most x-position of the drawing area. */
17059 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
17060 and below -- keep them on one line. */
17061 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17062 do \
17064 s = (struct glyph_string *) alloca (sizeof *s); \
17065 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
17066 START = fill_stretch_glyph_string (s, row, area, START, END); \
17067 append_glyph_string (&HEAD, &TAIL, s); \
17068 s->x = (X); \
17070 while (0)
17073 /* Add a glyph string for an image glyph to the list of strings
17074 between HEAD and TAIL. START is the index of the image glyph in
17075 row area AREA of glyph row ROW. END is the index of the last glyph
17076 in that glyph row area. X is the current output position assigned
17077 to the new glyph string constructed. HL overrides that face of the
17078 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
17079 is the right-most x-position of the drawing area. */
17081 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17082 do \
17084 s = (struct glyph_string *) alloca (sizeof *s); \
17085 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
17086 fill_image_glyph_string (s); \
17087 append_glyph_string (&HEAD, &TAIL, s); \
17088 ++START; \
17089 s->x = (X); \
17091 while (0)
17094 /* Add a glyph string for a sequence of character glyphs to the list
17095 of strings between HEAD and TAIL. START is the index of the first
17096 glyph in row area AREA of glyph row ROW that is part of the new
17097 glyph string. END is the index of the last glyph in that glyph row
17098 area. X is the current output position assigned to the new glyph
17099 string constructed. HL overrides that face of the glyph; e.g. it
17100 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
17101 right-most x-position of the drawing area. */
17103 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
17104 do \
17106 int c, face_id; \
17107 XChar2b *char2b; \
17109 c = (row)->glyphs[area][START].u.ch; \
17110 face_id = (row)->glyphs[area][START].face_id; \
17112 s = (struct glyph_string *) alloca (sizeof *s); \
17113 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
17114 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
17115 append_glyph_string (&HEAD, &TAIL, s); \
17116 s->x = (X); \
17117 START = fill_glyph_string (s, face_id, START, END, overlaps_p); \
17119 while (0)
17122 /* Add a glyph string for a composite sequence to the list of strings
17123 between HEAD and TAIL. START is the index of the first glyph in
17124 row area AREA of glyph row ROW that is part of the new glyph
17125 string. END is the index of the last glyph in that glyph row area.
17126 X is the current output position assigned to the new glyph string
17127 constructed. HL overrides that face of the glyph; e.g. it is
17128 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
17129 x-position of the drawing area. */
17131 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17132 do { \
17133 int cmp_id = (row)->glyphs[area][START].u.cmp_id; \
17134 int face_id = (row)->glyphs[area][START].face_id; \
17135 struct face *base_face = FACE_FROM_ID (f, face_id); \
17136 struct composition *cmp = composition_table[cmp_id]; \
17137 int glyph_len = cmp->glyph_len; \
17138 XChar2b *char2b; \
17139 struct face **faces; \
17140 struct glyph_string *first_s = NULL; \
17141 int n; \
17143 base_face = base_face->ascii_face; \
17144 char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len); \
17145 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
17146 /* At first, fill in `char2b' and `faces'. */ \
17147 for (n = 0; n < glyph_len; n++) \
17149 int c = COMPOSITION_GLYPH (cmp, n); \
17150 int this_face_id = FACE_FOR_CHAR (f, base_face, c); \
17151 faces[n] = FACE_FROM_ID (f, this_face_id); \
17152 get_char_face_and_encoding (f, c, this_face_id, \
17153 char2b + n, 1, 1); \
17156 /* Make glyph_strings for each glyph sequence that is drawable by \
17157 the same face, and append them to HEAD/TAIL. */ \
17158 for (n = 0; n < cmp->glyph_len;) \
17160 s = (struct glyph_string *) alloca (sizeof *s); \
17161 INIT_GLYPH_STRING (s, char2b + n, w, row, area, START, HL); \
17162 append_glyph_string (&(HEAD), &(TAIL), s); \
17163 s->cmp = cmp; \
17164 s->gidx = n; \
17165 s->x = (X); \
17167 if (n == 0) \
17168 first_s = s; \
17170 n = fill_composite_glyph_string (s, faces, overlaps_p); \
17173 ++START; \
17174 s = first_s; \
17175 } while (0)
17178 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
17179 of AREA of glyph row ROW on window W between indices START and END.
17180 HL overrides the face for drawing glyph strings, e.g. it is
17181 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
17182 x-positions of the drawing area.
17184 This is an ugly monster macro construct because we must use alloca
17185 to allocate glyph strings (because draw_glyphs can be called
17186 asynchronously). */
17188 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
17189 do \
17191 HEAD = TAIL = NULL; \
17192 while (START < END) \
17194 struct glyph *first_glyph = (row)->glyphs[area] + START; \
17195 switch (first_glyph->type) \
17197 case CHAR_GLYPH: \
17198 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
17199 HL, X, LAST_X); \
17200 break; \
17202 case COMPOSITE_GLYPH: \
17203 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
17204 HL, X, LAST_X); \
17205 break; \
17207 case STRETCH_GLYPH: \
17208 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
17209 HL, X, LAST_X); \
17210 break; \
17212 case IMAGE_GLYPH: \
17213 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
17214 HL, X, LAST_X); \
17215 break; \
17217 default: \
17218 abort (); \
17221 set_glyph_string_background_width (s, START, LAST_X); \
17222 (X) += s->width; \
17225 while (0)
17228 /* Draw glyphs between START and END in AREA of ROW on window W,
17229 starting at x-position X. X is relative to AREA in W. HL is a
17230 face-override with the following meaning:
17232 DRAW_NORMAL_TEXT draw normally
17233 DRAW_CURSOR draw in cursor face
17234 DRAW_MOUSE_FACE draw in mouse face.
17235 DRAW_INVERSE_VIDEO draw in mode line face
17236 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
17237 DRAW_IMAGE_RAISED draw an image with a raised relief around it
17239 If OVERLAPS_P is non-zero, draw only the foreground of characters
17240 and clip to the physical height of ROW.
17242 Value is the x-position reached, relative to AREA of W. */
17244 static int
17245 draw_glyphs (w, x, row, area, start, end, hl, overlaps_p)
17246 struct window *w;
17247 int x;
17248 struct glyph_row *row;
17249 enum glyph_row_area area;
17250 int start, end;
17251 enum draw_glyphs_face hl;
17252 int overlaps_p;
17254 struct glyph_string *head, *tail;
17255 struct glyph_string *s;
17256 int last_x, area_width;
17257 int x_reached;
17258 int i, j;
17259 struct frame *f = XFRAME (WINDOW_FRAME (w));
17260 DECLARE_HDC (hdc);
17262 ALLOCATE_HDC (hdc, f);
17264 /* Let's rather be paranoid than getting a SEGV. */
17265 end = min (end, row->used[area]);
17266 start = max (0, start);
17267 start = min (end, start);
17269 /* Translate X to frame coordinates. Set last_x to the right
17270 end of the drawing area. */
17271 if (row->full_width_p)
17273 /* X is relative to the left edge of W, without scroll bars
17274 or fringes. */
17275 int window_left_x = WINDOW_LEFT_MARGIN (w) * CANON_X_UNIT (f);
17277 x += window_left_x;
17278 area_width = XFASTINT (w->width) * CANON_X_UNIT (f);
17279 last_x = window_left_x + area_width;
17281 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f))
17283 int width = FRAME_SCROLL_BAR_WIDTH (f) * CANON_X_UNIT (f);
17284 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f))
17285 last_x += width;
17286 else
17287 x -= width;
17290 x += FRAME_INTERNAL_BORDER_WIDTH (f);
17291 /* ++KFS: W32 and MAC versions had -= in next line (bug??) */
17292 last_x += FRAME_INTERNAL_BORDER_WIDTH (f);
17294 else
17296 x = WINDOW_AREA_TO_FRAME_PIXEL_X (w, area, x);
17297 area_width = window_box_width (w, area);
17298 last_x = WINDOW_AREA_TO_FRAME_PIXEL_X (w, area, area_width);
17301 /* Build a doubly-linked list of glyph_string structures between
17302 head and tail from what we have to draw. Note that the macro
17303 BUILD_GLYPH_STRINGS will modify its start parameter. That's
17304 the reason we use a separate variable `i'. */
17305 i = start;
17306 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
17307 if (tail)
17308 x_reached = tail->x + tail->background_width;
17309 else
17310 x_reached = x;
17312 /* If there are any glyphs with lbearing < 0 or rbearing > width in
17313 the row, redraw some glyphs in front or following the glyph
17314 strings built above. */
17315 if (head && !overlaps_p && row->contains_overlapping_glyphs_p)
17317 int dummy_x = 0;
17318 struct glyph_string *h, *t;
17320 /* Compute overhangs for all glyph strings. */
17321 if (rif->compute_glyph_string_overhangs)
17322 for (s = head; s; s = s->next)
17323 rif->compute_glyph_string_overhangs (s);
17325 /* Prepend glyph strings for glyphs in front of the first glyph
17326 string that are overwritten because of the first glyph
17327 string's left overhang. The background of all strings
17328 prepended must be drawn because the first glyph string
17329 draws over it. */
17330 i = left_overwritten (head);
17331 if (i >= 0)
17333 j = i;
17334 BUILD_GLYPH_STRINGS (j, start, h, t,
17335 DRAW_NORMAL_TEXT, dummy_x, last_x);
17336 start = i;
17337 compute_overhangs_and_x (t, head->x, 1);
17338 prepend_glyph_string_lists (&head, &tail, h, t);
17341 /* Prepend glyph strings for glyphs in front of the first glyph
17342 string that overwrite that glyph string because of their
17343 right overhang. For these strings, only the foreground must
17344 be drawn, because it draws over the glyph string at `head'.
17345 The background must not be drawn because this would overwrite
17346 right overhangs of preceding glyphs for which no glyph
17347 strings exist. */
17348 i = left_overwriting (head);
17349 if (i >= 0)
17351 BUILD_GLYPH_STRINGS (i, start, h, t,
17352 DRAW_NORMAL_TEXT, dummy_x, last_x);
17353 for (s = h; s; s = s->next)
17354 s->background_filled_p = 1;
17355 compute_overhangs_and_x (t, head->x, 1);
17356 prepend_glyph_string_lists (&head, &tail, h, t);
17359 /* Append glyphs strings for glyphs following the last glyph
17360 string tail that are overwritten by tail. The background of
17361 these strings has to be drawn because tail's foreground draws
17362 over it. */
17363 i = right_overwritten (tail);
17364 if (i >= 0)
17366 BUILD_GLYPH_STRINGS (end, i, h, t,
17367 DRAW_NORMAL_TEXT, x, last_x);
17368 compute_overhangs_and_x (h, tail->x + tail->width, 0);
17369 append_glyph_string_lists (&head, &tail, h, t);
17372 /* Append glyph strings for glyphs following the last glyph
17373 string tail that overwrite tail. The foreground of such
17374 glyphs has to be drawn because it writes into the background
17375 of tail. The background must not be drawn because it could
17376 paint over the foreground of following glyphs. */
17377 i = right_overwriting (tail);
17378 if (i >= 0)
17380 BUILD_GLYPH_STRINGS (end, i, h, t,
17381 DRAW_NORMAL_TEXT, x, last_x);
17382 for (s = h; s; s = s->next)
17383 s->background_filled_p = 1;
17384 compute_overhangs_and_x (h, tail->x + tail->width, 0);
17385 append_glyph_string_lists (&head, &tail, h, t);
17389 /* Draw all strings. */
17390 for (s = head; s; s = s->next)
17391 rif->draw_glyph_string (s);
17393 if (area == TEXT_AREA
17394 && !row->full_width_p
17395 /* When drawing overlapping rows, only the glyph strings'
17396 foreground is drawn, which doesn't erase a cursor
17397 completely. */
17398 && !overlaps_p)
17400 int x0 = head ? head->x : x;
17401 int x1 = tail ? tail->x + tail->background_width : x;
17403 x0 = FRAME_TO_WINDOW_PIXEL_X (w, x0);
17404 x1 = FRAME_TO_WINDOW_PIXEL_X (w, x1);
17406 /* ++KFS: W32 and MAC versions had following test here:
17407 if (!row->full_width_p && XFASTINT (w->left_margin_width) != 0)
17410 if (XFASTINT (w->left_margin_width) != 0)
17412 int left_area_width = window_box_width (w, LEFT_MARGIN_AREA);
17413 x0 -= left_area_width;
17414 x1 -= left_area_width;
17417 notice_overwritten_cursor (w, area, x0, x1,
17418 row->y, MATRIX_ROW_BOTTOM_Y (row));
17421 /* Value is the x-position up to which drawn, relative to AREA of W.
17422 This doesn't include parts drawn because of overhangs. */
17423 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
17424 if (!row->full_width_p)
17426 /* ++KFS: W32 and MAC versions only had this test here:
17427 if (area > LEFT_MARGIN_AREA)
17430 if (area > LEFT_MARGIN_AREA && XFASTINT (w->left_margin_width) != 0)
17431 x_reached -= window_box_width (w, LEFT_MARGIN_AREA);
17432 if (area > TEXT_AREA)
17433 x_reached -= window_box_width (w, TEXT_AREA);
17436 RELEASE_HDC (hdc, f);
17438 return x_reached;
17442 /* Store one glyph for IT->char_to_display in IT->glyph_row.
17443 Called from x_produce_glyphs when IT->glyph_row is non-null. */
17445 static INLINE void
17446 append_glyph (it)
17447 struct it *it;
17449 struct glyph *glyph;
17450 enum glyph_row_area area = it->area;
17452 xassert (it->glyph_row);
17453 xassert (it->char_to_display != '\n' && it->char_to_display != '\t');
17455 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
17456 if (glyph < it->glyph_row->glyphs[area + 1])
17458 glyph->charpos = CHARPOS (it->position);
17459 glyph->object = it->object;
17460 glyph->pixel_width = it->pixel_width;
17461 glyph->voffset = it->voffset;
17462 glyph->type = CHAR_GLYPH;
17463 glyph->multibyte_p = it->multibyte_p;
17464 glyph->left_box_line_p = it->start_of_box_run_p;
17465 glyph->right_box_line_p = it->end_of_box_run_p;
17466 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
17467 || it->phys_descent > it->descent);
17468 glyph->padding_p = 0;
17469 glyph->glyph_not_available_p = it->glyph_not_available_p;
17470 glyph->face_id = it->face_id;
17471 glyph->u.ch = it->char_to_display;
17472 glyph->font_type = FONT_TYPE_UNKNOWN;
17473 ++it->glyph_row->used[area];
17477 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
17478 Called from x_produce_glyphs when IT->glyph_row is non-null. */
17480 static INLINE void
17481 append_composite_glyph (it)
17482 struct it *it;
17484 struct glyph *glyph;
17485 enum glyph_row_area area = it->area;
17487 xassert (it->glyph_row);
17489 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
17490 if (glyph < it->glyph_row->glyphs[area + 1])
17492 glyph->charpos = CHARPOS (it->position);
17493 glyph->object = it->object;
17494 glyph->pixel_width = it->pixel_width;
17495 glyph->voffset = it->voffset;
17496 glyph->type = COMPOSITE_GLYPH;
17497 glyph->multibyte_p = it->multibyte_p;
17498 glyph->left_box_line_p = it->start_of_box_run_p;
17499 glyph->right_box_line_p = it->end_of_box_run_p;
17500 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
17501 || it->phys_descent > it->descent);
17502 glyph->padding_p = 0;
17503 glyph->glyph_not_available_p = 0;
17504 glyph->face_id = it->face_id;
17505 glyph->u.cmp_id = it->cmp_id;
17506 glyph->font_type = FONT_TYPE_UNKNOWN;
17507 ++it->glyph_row->used[area];
17512 /* Change IT->ascent and IT->height according to the setting of
17513 IT->voffset. */
17515 static INLINE void
17516 take_vertical_position_into_account (it)
17517 struct it *it;
17519 if (it->voffset)
17521 if (it->voffset < 0)
17522 /* Increase the ascent so that we can display the text higher
17523 in the line. */
17524 it->ascent += abs (it->voffset);
17525 else
17526 /* Increase the descent so that we can display the text lower
17527 in the line. */
17528 it->descent += it->voffset;
17533 /* Produce glyphs/get display metrics for the image IT is loaded with.
17534 See the description of struct display_iterator in dispextern.h for
17535 an overview of struct display_iterator. */
17537 static void
17538 produce_image_glyph (it)
17539 struct it *it;
17541 struct image *img;
17542 struct face *face;
17544 xassert (it->what == IT_IMAGE);
17546 face = FACE_FROM_ID (it->f, it->face_id);
17547 img = IMAGE_FROM_ID (it->f, it->image_id);
17548 xassert (img);
17550 /* Make sure X resources of the face and image are loaded. */
17551 PREPARE_FACE_FOR_DISPLAY (it->f, face);
17552 prepare_image_for_display (it->f, img);
17554 it->ascent = it->phys_ascent = image_ascent (img, face);
17555 it->descent = it->phys_descent = img->height + 2 * img->vmargin - it->ascent;
17556 it->pixel_width = img->width + 2 * img->hmargin;
17558 it->nglyphs = 1;
17560 if (face->box != FACE_NO_BOX)
17562 if (face->box_line_width > 0)
17564 it->ascent += face->box_line_width;
17565 it->descent += face->box_line_width;
17568 if (it->start_of_box_run_p)
17569 it->pixel_width += abs (face->box_line_width);
17570 if (it->end_of_box_run_p)
17571 it->pixel_width += abs (face->box_line_width);
17574 take_vertical_position_into_account (it);
17576 if (it->glyph_row)
17578 struct glyph *glyph;
17579 enum glyph_row_area area = it->area;
17581 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
17582 if (glyph < it->glyph_row->glyphs[area + 1])
17584 glyph->charpos = CHARPOS (it->position);
17585 glyph->object = it->object;
17586 glyph->pixel_width = it->pixel_width;
17587 glyph->voffset = it->voffset;
17588 glyph->type = IMAGE_GLYPH;
17589 glyph->multibyte_p = it->multibyte_p;
17590 glyph->left_box_line_p = it->start_of_box_run_p;
17591 glyph->right_box_line_p = it->end_of_box_run_p;
17592 glyph->overlaps_vertically_p = 0;
17593 glyph->padding_p = 0;
17594 glyph->glyph_not_available_p = 0;
17595 glyph->face_id = it->face_id;
17596 glyph->u.img_id = img->id;
17597 glyph->font_type = FONT_TYPE_UNKNOWN;
17598 ++it->glyph_row->used[area];
17604 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
17605 of the glyph, WIDTH and HEIGHT are the width and height of the
17606 stretch. ASCENT is the percentage/100 of HEIGHT to use for the
17607 ascent of the glyph (0 <= ASCENT <= 1). */
17609 static void
17610 append_stretch_glyph (it, object, width, height, ascent)
17611 struct it *it;
17612 Lisp_Object object;
17613 int width, height;
17614 double ascent;
17616 struct glyph *glyph;
17617 enum glyph_row_area area = it->area;
17619 xassert (ascent >= 0 && ascent <= 1);
17621 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
17622 if (glyph < it->glyph_row->glyphs[area + 1])
17624 glyph->charpos = CHARPOS (it->position);
17625 glyph->object = object;
17626 glyph->pixel_width = width;
17627 glyph->voffset = it->voffset;
17628 glyph->type = STRETCH_GLYPH;
17629 glyph->multibyte_p = it->multibyte_p;
17630 glyph->left_box_line_p = it->start_of_box_run_p;
17631 glyph->right_box_line_p = it->end_of_box_run_p;
17632 glyph->overlaps_vertically_p = 0;
17633 glyph->padding_p = 0;
17634 glyph->glyph_not_available_p = 0;
17635 glyph->face_id = it->face_id;
17636 glyph->u.stretch.ascent = height * ascent;
17637 glyph->u.stretch.height = height;
17638 glyph->font_type = FONT_TYPE_UNKNOWN;
17639 ++it->glyph_row->used[area];
17644 /* Produce a stretch glyph for iterator IT. IT->object is the value
17645 of the glyph property displayed. The value must be a list
17646 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
17647 being recognized:
17649 1. `:width WIDTH' specifies that the space should be WIDTH *
17650 canonical char width wide. WIDTH may be an integer or floating
17651 point number.
17653 2. `:relative-width FACTOR' specifies that the width of the stretch
17654 should be computed from the width of the first character having the
17655 `glyph' property, and should be FACTOR times that width.
17657 3. `:align-to HPOS' specifies that the space should be wide enough
17658 to reach HPOS, a value in canonical character units.
17660 Exactly one of the above pairs must be present.
17662 4. `:height HEIGHT' specifies that the height of the stretch produced
17663 should be HEIGHT, measured in canonical character units.
17665 5. `:relative-height FACTOR' specifies that the height of the
17666 stretch should be FACTOR times the height of the characters having
17667 the glyph property.
17669 Either none or exactly one of 4 or 5 must be present.
17671 6. `:ascent ASCENT' specifies that ASCENT percent of the height
17672 of the stretch should be used for the ascent of the stretch.
17673 ASCENT must be in the range 0 <= ASCENT <= 100. */
17675 #define NUMVAL(X) \
17676 ((INTEGERP (X) || FLOATP (X)) \
17677 ? XFLOATINT (X) \
17678 : - 1)
17681 static void
17682 produce_stretch_glyph (it)
17683 struct it *it;
17685 /* (space :width WIDTH :height HEIGHT. */
17686 Lisp_Object prop, plist;
17687 int width = 0, height = 0;
17688 double ascent = 0;
17689 struct face *face = FACE_FROM_ID (it->f, it->face_id);
17690 XFontStruct *font = face->font ? face->font : FRAME_FONT (it->f);
17692 PREPARE_FACE_FOR_DISPLAY (it->f, face);
17694 /* List should start with `space'. */
17695 xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
17696 plist = XCDR (it->object);
17698 /* Compute the width of the stretch. */
17699 if (prop = Fplist_get (plist, QCwidth),
17700 NUMVAL (prop) > 0)
17701 /* Absolute width `:width WIDTH' specified and valid. */
17702 width = NUMVAL (prop) * CANON_X_UNIT (it->f);
17703 else if (prop = Fplist_get (plist, QCrelative_width),
17704 NUMVAL (prop) > 0)
17706 /* Relative width `:relative-width FACTOR' specified and valid.
17707 Compute the width of the characters having the `glyph'
17708 property. */
17709 struct it it2;
17710 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
17712 it2 = *it;
17713 if (it->multibyte_p)
17715 int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT)
17716 - IT_BYTEPOS (*it));
17717 it2.c = STRING_CHAR_AND_LENGTH (p, maxlen, it2.len);
17719 else
17720 it2.c = *p, it2.len = 1;
17722 it2.glyph_row = NULL;
17723 it2.what = IT_CHARACTER;
17724 x_produce_glyphs (&it2);
17725 width = NUMVAL (prop) * it2.pixel_width;
17727 else if (prop = Fplist_get (plist, QCalign_to),
17728 NUMVAL (prop) > 0)
17729 width = NUMVAL (prop) * CANON_X_UNIT (it->f) - it->current_x;
17730 else
17731 /* Nothing specified -> width defaults to canonical char width. */
17732 width = CANON_X_UNIT (it->f);
17734 /* Compute height. */
17735 if (prop = Fplist_get (plist, QCheight),
17736 NUMVAL (prop) > 0)
17737 height = NUMVAL (prop) * CANON_Y_UNIT (it->f);
17738 else if (prop = Fplist_get (plist, QCrelative_height),
17739 NUMVAL (prop) > 0)
17740 height = FONT_HEIGHT (font) * NUMVAL (prop);
17741 else
17742 height = FONT_HEIGHT (font);
17744 /* Compute percentage of height used for ascent. If
17745 `:ascent ASCENT' is present and valid, use that. Otherwise,
17746 derive the ascent from the font in use. */
17747 if (prop = Fplist_get (plist, QCascent),
17748 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
17749 ascent = NUMVAL (prop) / 100.0;
17750 else
17751 ascent = (double) FONT_BASE (font) / FONT_HEIGHT (font);
17753 if (width <= 0)
17754 width = 1;
17755 if (height <= 0)
17756 height = 1;
17758 if (it->glyph_row)
17760 Lisp_Object object = it->stack[it->sp - 1].string;
17761 if (!STRINGP (object))
17762 object = it->w->buffer;
17763 append_stretch_glyph (it, object, width, height, ascent);
17766 it->pixel_width = width;
17767 it->ascent = it->phys_ascent = height * ascent;
17768 it->descent = it->phys_descent = height - it->ascent;
17769 it->nglyphs = 1;
17771 if (face->box != FACE_NO_BOX)
17773 if (face->box_line_width > 0)
17775 it->ascent += face->box_line_width;
17776 it->descent += face->box_line_width;
17779 if (it->start_of_box_run_p)
17780 it->pixel_width += abs (face->box_line_width);
17781 if (it->end_of_box_run_p)
17782 it->pixel_width += abs (face->box_line_width);
17785 take_vertical_position_into_account (it);
17788 /* RIF:
17789 Produce glyphs/get display metrics for the display element IT is
17790 loaded with. See the description of struct display_iterator in
17791 dispextern.h for an overview of struct display_iterator. */
17793 void
17794 x_produce_glyphs (it)
17795 struct it *it;
17797 it->glyph_not_available_p = 0;
17799 if (it->what == IT_CHARACTER)
17801 XChar2b char2b;
17802 XFontStruct *font;
17803 struct face *face = FACE_FROM_ID (it->f, it->face_id);
17804 XCharStruct *pcm;
17805 int font_not_found_p;
17806 struct font_info *font_info;
17807 int boff; /* baseline offset */
17808 /* We may change it->multibyte_p upon unibyte<->multibyte
17809 conversion. So, save the current value now and restore it
17810 later.
17812 Note: It seems that we don't have to record multibyte_p in
17813 struct glyph because the character code itself tells if or
17814 not the character is multibyte. Thus, in the future, we must
17815 consider eliminating the field `multibyte_p' in the struct
17816 glyph. */
17817 int saved_multibyte_p = it->multibyte_p;
17819 /* Maybe translate single-byte characters to multibyte, or the
17820 other way. */
17821 it->char_to_display = it->c;
17822 if (!ASCII_BYTE_P (it->c))
17824 if (unibyte_display_via_language_environment
17825 && SINGLE_BYTE_CHAR_P (it->c)
17826 && (it->c >= 0240
17827 || !NILP (Vnonascii_translation_table)))
17829 it->char_to_display = unibyte_char_to_multibyte (it->c);
17830 it->multibyte_p = 1;
17831 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
17832 face = FACE_FROM_ID (it->f, it->face_id);
17834 else if (!SINGLE_BYTE_CHAR_P (it->c)
17835 && !it->multibyte_p)
17837 it->multibyte_p = 1;
17838 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
17839 face = FACE_FROM_ID (it->f, it->face_id);
17843 /* Get font to use. Encode IT->char_to_display. */
17844 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
17845 &char2b, it->multibyte_p, 0);
17846 font = face->font;
17848 /* When no suitable font found, use the default font. */
17849 font_not_found_p = font == NULL;
17850 if (font_not_found_p)
17852 font = FRAME_FONT (it->f);
17853 boff = FRAME_BASELINE_OFFSET (it->f);
17854 font_info = NULL;
17856 else
17858 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
17859 boff = font_info->baseline_offset;
17860 if (font_info->vertical_centering)
17861 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
17864 if (it->char_to_display >= ' '
17865 && (!it->multibyte_p || it->char_to_display < 128))
17867 /* Either unibyte or ASCII. */
17868 int stretched_p;
17870 it->nglyphs = 1;
17872 pcm = rif->per_char_metric (font, &char2b,
17873 FONT_TYPE_FOR_UNIBYTE (font, it->char_to_display));
17874 it->ascent = FONT_BASE (font) + boff;
17875 it->descent = FONT_DESCENT (font) - boff;
17877 if (pcm)
17879 it->phys_ascent = pcm->ascent + boff;
17880 it->phys_descent = pcm->descent - boff;
17881 it->pixel_width = pcm->width;
17883 else
17885 it->glyph_not_available_p = 1;
17886 it->phys_ascent = FONT_BASE (font) + boff;
17887 it->phys_descent = FONT_DESCENT (font) - boff;
17888 it->pixel_width = FONT_WIDTH (font);
17891 /* If this is a space inside a region of text with
17892 `space-width' property, change its width. */
17893 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
17894 if (stretched_p)
17895 it->pixel_width *= XFLOATINT (it->space_width);
17897 /* If face has a box, add the box thickness to the character
17898 height. If character has a box line to the left and/or
17899 right, add the box line width to the character's width. */
17900 if (face->box != FACE_NO_BOX)
17902 int thick = face->box_line_width;
17904 if (thick > 0)
17906 it->ascent += thick;
17907 it->descent += thick;
17909 else
17910 thick = -thick;
17912 if (it->start_of_box_run_p)
17913 it->pixel_width += thick;
17914 if (it->end_of_box_run_p)
17915 it->pixel_width += thick;
17918 /* If face has an overline, add the height of the overline
17919 (1 pixel) and a 1 pixel margin to the character height. */
17920 if (face->overline_p)
17921 it->ascent += 2;
17923 take_vertical_position_into_account (it);
17925 /* If we have to actually produce glyphs, do it. */
17926 if (it->glyph_row)
17928 if (stretched_p)
17930 /* Translate a space with a `space-width' property
17931 into a stretch glyph. */
17932 double ascent = (double) FONT_BASE (font)
17933 / FONT_HEIGHT (font);
17934 append_stretch_glyph (it, it->object, it->pixel_width,
17935 it->ascent + it->descent, ascent);
17937 else
17938 append_glyph (it);
17940 /* If characters with lbearing or rbearing are displayed
17941 in this line, record that fact in a flag of the
17942 glyph row. This is used to optimize X output code. */
17943 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
17944 it->glyph_row->contains_overlapping_glyphs_p = 1;
17947 else if (it->char_to_display == '\n')
17949 /* A newline has no width but we need the height of the line. */
17950 it->pixel_width = 0;
17951 it->nglyphs = 0;
17952 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
17953 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
17955 if (face->box != FACE_NO_BOX
17956 && face->box_line_width > 0)
17958 it->ascent += face->box_line_width;
17959 it->descent += face->box_line_width;
17962 else if (it->char_to_display == '\t')
17964 int tab_width = it->tab_width * CANON_X_UNIT (it->f);
17965 int x = it->current_x + it->continuation_lines_width;
17966 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
17968 /* If the distance from the current position to the next tab
17969 stop is less than a canonical character width, use the
17970 tab stop after that. */
17971 if (next_tab_x - x < CANON_X_UNIT (it->f))
17972 next_tab_x += tab_width;
17974 it->pixel_width = next_tab_x - x;
17975 it->nglyphs = 1;
17976 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
17977 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
17979 if (it->glyph_row)
17981 double ascent = (double) it->ascent / (it->ascent + it->descent);
17982 append_stretch_glyph (it, it->object, it->pixel_width,
17983 it->ascent + it->descent, ascent);
17986 else
17988 /* A multi-byte character. Assume that the display width of the
17989 character is the width of the character multiplied by the
17990 width of the font. */
17992 /* If we found a font, this font should give us the right
17993 metrics. If we didn't find a font, use the frame's
17994 default font and calculate the width of the character
17995 from the charset width; this is what old redisplay code
17996 did. */
17998 pcm = rif->per_char_metric (font, &char2b,
17999 FONT_TYPE_FOR_MULTIBYTE (font, it->c));
18001 if (font_not_found_p || !pcm)
18003 int charset = CHAR_CHARSET (it->char_to_display);
18005 it->glyph_not_available_p = 1;
18006 it->pixel_width = (FONT_WIDTH (FRAME_FONT (it->f))
18007 * CHARSET_WIDTH (charset));
18008 it->phys_ascent = FONT_BASE (font) + boff;
18009 it->phys_descent = FONT_DESCENT (font) - boff;
18011 else
18013 it->pixel_width = pcm->width;
18014 it->phys_ascent = pcm->ascent + boff;
18015 it->phys_descent = pcm->descent - boff;
18016 if (it->glyph_row
18017 && (pcm->lbearing < 0
18018 || pcm->rbearing > pcm->width))
18019 it->glyph_row->contains_overlapping_glyphs_p = 1;
18021 it->nglyphs = 1;
18022 it->ascent = FONT_BASE (font) + boff;
18023 it->descent = FONT_DESCENT (font) - boff;
18024 if (face->box != FACE_NO_BOX)
18026 int thick = face->box_line_width;
18028 if (thick > 0)
18030 it->ascent += thick;
18031 it->descent += thick;
18033 else
18034 thick = - thick;
18036 if (it->start_of_box_run_p)
18037 it->pixel_width += thick;
18038 if (it->end_of_box_run_p)
18039 it->pixel_width += thick;
18042 /* If face has an overline, add the height of the overline
18043 (1 pixel) and a 1 pixel margin to the character height. */
18044 if (face->overline_p)
18045 it->ascent += 2;
18047 take_vertical_position_into_account (it);
18049 if (it->glyph_row)
18050 append_glyph (it);
18052 it->multibyte_p = saved_multibyte_p;
18054 else if (it->what == IT_COMPOSITION)
18056 /* Note: A composition is represented as one glyph in the
18057 glyph matrix. There are no padding glyphs. */
18058 XChar2b char2b;
18059 XFontStruct *font;
18060 struct face *face = FACE_FROM_ID (it->f, it->face_id);
18061 XCharStruct *pcm;
18062 int font_not_found_p;
18063 struct font_info *font_info;
18064 int boff; /* baseline offset */
18065 struct composition *cmp = composition_table[it->cmp_id];
18067 /* Maybe translate single-byte characters to multibyte. */
18068 it->char_to_display = it->c;
18069 if (unibyte_display_via_language_environment
18070 && SINGLE_BYTE_CHAR_P (it->c)
18071 && (it->c >= 0240
18072 || (it->c >= 0200
18073 && !NILP (Vnonascii_translation_table))))
18075 it->char_to_display = unibyte_char_to_multibyte (it->c);
18078 /* Get face and font to use. Encode IT->char_to_display. */
18079 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
18080 face = FACE_FROM_ID (it->f, it->face_id);
18081 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
18082 &char2b, it->multibyte_p, 0);
18083 font = face->font;
18085 /* When no suitable font found, use the default font. */
18086 font_not_found_p = font == NULL;
18087 if (font_not_found_p)
18089 font = FRAME_FONT (it->f);
18090 boff = FRAME_BASELINE_OFFSET (it->f);
18091 font_info = NULL;
18093 else
18095 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
18096 boff = font_info->baseline_offset;
18097 if (font_info->vertical_centering)
18098 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
18101 /* There are no padding glyphs, so there is only one glyph to
18102 produce for the composition. Important is that pixel_width,
18103 ascent and descent are the values of what is drawn by
18104 draw_glyphs (i.e. the values of the overall glyphs composed). */
18105 it->nglyphs = 1;
18107 /* If we have not yet calculated pixel size data of glyphs of
18108 the composition for the current face font, calculate them
18109 now. Theoretically, we have to check all fonts for the
18110 glyphs, but that requires much time and memory space. So,
18111 here we check only the font of the first glyph. This leads
18112 to incorrect display very rarely, and C-l (recenter) can
18113 correct the display anyway. */
18114 if (cmp->font != (void *) font)
18116 /* Ascent and descent of the font of the first character of
18117 this composition (adjusted by baseline offset). Ascent
18118 and descent of overall glyphs should not be less than
18119 them respectively. */
18120 int font_ascent = FONT_BASE (font) + boff;
18121 int font_descent = FONT_DESCENT (font) - boff;
18122 /* Bounding box of the overall glyphs. */
18123 int leftmost, rightmost, lowest, highest;
18124 int i, width, ascent, descent;
18126 cmp->font = (void *) font;
18128 /* Initialize the bounding box. */
18129 if (font_info
18130 && (pcm = rif->per_char_metric (font, &char2b,
18131 FONT_TYPE_FOR_MULTIBYTE (font, it->c))))
18133 width = pcm->width;
18134 ascent = pcm->ascent;
18135 descent = pcm->descent;
18137 else
18139 width = FONT_WIDTH (font);
18140 ascent = FONT_BASE (font);
18141 descent = FONT_DESCENT (font);
18144 rightmost = width;
18145 lowest = - descent + boff;
18146 highest = ascent + boff;
18147 leftmost = 0;
18149 if (font_info
18150 && font_info->default_ascent
18151 && CHAR_TABLE_P (Vuse_default_ascent)
18152 && !NILP (Faref (Vuse_default_ascent,
18153 make_number (it->char_to_display))))
18154 highest = font_info->default_ascent + boff;
18156 /* Draw the first glyph at the normal position. It may be
18157 shifted to right later if some other glyphs are drawn at
18158 the left. */
18159 cmp->offsets[0] = 0;
18160 cmp->offsets[1] = boff;
18162 /* Set cmp->offsets for the remaining glyphs. */
18163 for (i = 1; i < cmp->glyph_len; i++)
18165 int left, right, btm, top;
18166 int ch = COMPOSITION_GLYPH (cmp, i);
18167 int face_id = FACE_FOR_CHAR (it->f, face, ch);
18169 face = FACE_FROM_ID (it->f, face_id);
18170 get_char_face_and_encoding (it->f, ch, face->id,
18171 &char2b, it->multibyte_p, 0);
18172 font = face->font;
18173 if (font == NULL)
18175 font = FRAME_FONT (it->f);
18176 boff = FRAME_BASELINE_OFFSET (it->f);
18177 font_info = NULL;
18179 else
18181 font_info
18182 = FONT_INFO_FROM_ID (it->f, face->font_info_id);
18183 boff = font_info->baseline_offset;
18184 if (font_info->vertical_centering)
18185 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
18188 if (font_info
18189 && (pcm = rif->per_char_metric (font, &char2b,
18190 FONT_TYPE_FOR_MULTIBYTE (font, ch))))
18192 width = pcm->width;
18193 ascent = pcm->ascent;
18194 descent = pcm->descent;
18196 else
18198 width = FONT_WIDTH (font);
18199 ascent = 1;
18200 descent = 0;
18203 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
18205 /* Relative composition with or without
18206 alternate chars. */
18207 left = (leftmost + rightmost - width) / 2;
18208 btm = - descent + boff;
18209 if (font_info && font_info->relative_compose
18210 && (! CHAR_TABLE_P (Vignore_relative_composition)
18211 || NILP (Faref (Vignore_relative_composition,
18212 make_number (ch)))))
18215 if (- descent >= font_info->relative_compose)
18216 /* One extra pixel between two glyphs. */
18217 btm = highest + 1;
18218 else if (ascent <= 0)
18219 /* One extra pixel between two glyphs. */
18220 btm = lowest - 1 - ascent - descent;
18223 else
18225 /* A composition rule is specified by an integer
18226 value that encodes global and new reference
18227 points (GREF and NREF). GREF and NREF are
18228 specified by numbers as below:
18230 0---1---2 -- ascent
18234 9--10--11 -- center
18236 ---3---4---5--- baseline
18238 6---7---8 -- descent
18240 int rule = COMPOSITION_RULE (cmp, i);
18241 int gref, nref, grefx, grefy, nrefx, nrefy;
18243 COMPOSITION_DECODE_RULE (rule, gref, nref);
18244 grefx = gref % 3, nrefx = nref % 3;
18245 grefy = gref / 3, nrefy = nref / 3;
18247 left = (leftmost
18248 + grefx * (rightmost - leftmost) / 2
18249 - nrefx * width / 2);
18250 btm = ((grefy == 0 ? highest
18251 : grefy == 1 ? 0
18252 : grefy == 2 ? lowest
18253 : (highest + lowest) / 2)
18254 - (nrefy == 0 ? ascent + descent
18255 : nrefy == 1 ? descent - boff
18256 : nrefy == 2 ? 0
18257 : (ascent + descent) / 2));
18260 cmp->offsets[i * 2] = left;
18261 cmp->offsets[i * 2 + 1] = btm + descent;
18263 /* Update the bounding box of the overall glyphs. */
18264 right = left + width;
18265 top = btm + descent + ascent;
18266 if (left < leftmost)
18267 leftmost = left;
18268 if (right > rightmost)
18269 rightmost = right;
18270 if (top > highest)
18271 highest = top;
18272 if (btm < lowest)
18273 lowest = btm;
18276 /* If there are glyphs whose x-offsets are negative,
18277 shift all glyphs to the right and make all x-offsets
18278 non-negative. */
18279 if (leftmost < 0)
18281 for (i = 0; i < cmp->glyph_len; i++)
18282 cmp->offsets[i * 2] -= leftmost;
18283 rightmost -= leftmost;
18286 cmp->pixel_width = rightmost;
18287 cmp->ascent = highest;
18288 cmp->descent = - lowest;
18289 if (cmp->ascent < font_ascent)
18290 cmp->ascent = font_ascent;
18291 if (cmp->descent < font_descent)
18292 cmp->descent = font_descent;
18295 it->pixel_width = cmp->pixel_width;
18296 it->ascent = it->phys_ascent = cmp->ascent;
18297 it->descent = it->phys_descent = cmp->descent;
18299 if (face->box != FACE_NO_BOX)
18301 int thick = face->box_line_width;
18303 if (thick > 0)
18305 it->ascent += thick;
18306 it->descent += thick;
18308 else
18309 thick = - thick;
18311 if (it->start_of_box_run_p)
18312 it->pixel_width += thick;
18313 if (it->end_of_box_run_p)
18314 it->pixel_width += thick;
18317 /* If face has an overline, add the height of the overline
18318 (1 pixel) and a 1 pixel margin to the character height. */
18319 if (face->overline_p)
18320 it->ascent += 2;
18322 take_vertical_position_into_account (it);
18324 if (it->glyph_row)
18325 append_composite_glyph (it);
18327 else if (it->what == IT_IMAGE)
18328 produce_image_glyph (it);
18329 else if (it->what == IT_STRETCH)
18330 produce_stretch_glyph (it);
18332 /* Accumulate dimensions. Note: can't assume that it->descent > 0
18333 because this isn't true for images with `:ascent 100'. */
18334 xassert (it->ascent >= 0 && it->descent >= 0);
18335 if (it->area == TEXT_AREA)
18336 it->current_x += it->pixel_width;
18338 it->descent += it->extra_line_spacing;
18340 it->max_ascent = max (it->max_ascent, it->ascent);
18341 it->max_descent = max (it->max_descent, it->descent);
18342 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
18343 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
18346 /* EXPORT for RIF:
18347 Output LEN glyphs starting at START at the nominal cursor position.
18348 Advance the nominal cursor over the text. The global variable
18349 updated_window contains the window being updated, updated_row is
18350 the glyph row being updated, and updated_area is the area of that
18351 row being updated. */
18353 void
18354 x_write_glyphs (start, len)
18355 struct glyph *start;
18356 int len;
18358 int x, hpos;
18360 xassert (updated_window && updated_row);
18361 BLOCK_INPUT;
18363 /* Write glyphs. */
18365 hpos = start - updated_row->glyphs[updated_area];
18366 x = draw_glyphs (updated_window, output_cursor.x,
18367 updated_row, updated_area,
18368 hpos, hpos + len,
18369 DRAW_NORMAL_TEXT, 0);
18371 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
18372 if (updated_area == TEXT_AREA
18373 && updated_window->phys_cursor_on_p
18374 && updated_window->phys_cursor.vpos == output_cursor.vpos
18375 && updated_window->phys_cursor.hpos >= hpos
18376 && updated_window->phys_cursor.hpos < hpos + len)
18377 updated_window->phys_cursor_on_p = 0;
18379 UNBLOCK_INPUT;
18381 /* Advance the output cursor. */
18382 output_cursor.hpos += len;
18383 output_cursor.x = x;
18387 /* EXPORT for RIF:
18388 Insert LEN glyphs from START at the nominal cursor position. */
18390 void
18391 x_insert_glyphs (start, len)
18392 struct glyph *start;
18393 int len;
18395 struct frame *f;
18396 struct window *w;
18397 int line_height, shift_by_width, shifted_region_width;
18398 struct glyph_row *row;
18399 struct glyph *glyph;
18400 int frame_x, frame_y, hpos;
18402 xassert (updated_window && updated_row);
18403 BLOCK_INPUT;
18404 w = updated_window;
18405 f = XFRAME (WINDOW_FRAME (w));
18407 /* Get the height of the line we are in. */
18408 row = updated_row;
18409 line_height = row->height;
18411 /* Get the width of the glyphs to insert. */
18412 shift_by_width = 0;
18413 for (glyph = start; glyph < start + len; ++glyph)
18414 shift_by_width += glyph->pixel_width;
18416 /* Get the width of the region to shift right. */
18417 shifted_region_width = (window_box_width (w, updated_area)
18418 - output_cursor.x
18419 - shift_by_width);
18421 /* Shift right. */
18422 frame_x = window_box_left (w, updated_area) + output_cursor.x;
18423 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
18425 rif->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
18426 line_height, shift_by_width);
18428 /* Write the glyphs. */
18429 hpos = start - row->glyphs[updated_area];
18430 draw_glyphs (w, output_cursor.x, row, updated_area,
18431 hpos, hpos + len,
18432 DRAW_NORMAL_TEXT, 0);
18434 /* Advance the output cursor. */
18435 output_cursor.hpos += len;
18436 output_cursor.x += shift_by_width;
18437 UNBLOCK_INPUT;
18441 /* EXPORT for RIF:
18442 Erase the current text line from the nominal cursor position
18443 (inclusive) to pixel column TO_X (exclusive). The idea is that
18444 everything from TO_X onward is already erased.
18446 TO_X is a pixel position relative to updated_area of
18447 updated_window. TO_X == -1 means clear to the end of this area. */
18449 void
18450 x_clear_end_of_line (to_x)
18451 int to_x;
18453 struct frame *f;
18454 struct window *w = updated_window;
18455 int max_x, min_y, max_y;
18456 int from_x, from_y, to_y;
18458 xassert (updated_window && updated_row);
18459 f = XFRAME (w->frame);
18461 if (updated_row->full_width_p)
18463 max_x = XFASTINT (w->width) * CANON_X_UNIT (f);
18464 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f)
18465 && !w->pseudo_window_p)
18466 max_x += FRAME_SCROLL_BAR_WIDTH (f) * CANON_X_UNIT (f);
18468 else
18469 max_x = window_box_width (w, updated_area);
18470 max_y = window_text_bottom_y (w);
18472 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
18473 of window. For TO_X > 0, truncate to end of drawing area. */
18474 if (to_x == 0)
18475 return;
18476 else if (to_x < 0)
18477 to_x = max_x;
18478 else
18479 to_x = min (to_x, max_x);
18481 to_y = min (max_y, output_cursor.y + updated_row->height);
18483 /* Notice if the cursor will be cleared by this operation. */
18484 if (!updated_row->full_width_p)
18485 notice_overwritten_cursor (w, updated_area,
18486 output_cursor.x, -1,
18487 updated_row->y,
18488 MATRIX_ROW_BOTTOM_Y (updated_row));
18490 from_x = output_cursor.x;
18492 /* Translate to frame coordinates. */
18493 if (updated_row->full_width_p)
18495 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
18496 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
18498 else
18500 from_x = WINDOW_AREA_TO_FRAME_PIXEL_X (w, updated_area, from_x);
18501 to_x = WINDOW_AREA_TO_FRAME_PIXEL_X (w, updated_area, to_x);
18504 min_y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
18505 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
18506 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
18508 /* Prevent inadvertently clearing to end of the X window. */
18509 if (to_x > from_x && to_y > from_y)
18511 BLOCK_INPUT;
18512 rif->clear_frame_area (f, from_x, from_y,
18513 to_x - from_x, to_y - from_y);
18514 UNBLOCK_INPUT;
18518 #endif /* HAVE_WINDOW_SYSTEM */
18522 /***********************************************************************
18523 Cursor types
18524 ***********************************************************************/
18526 /* Value is the internal representation of the specified cursor type
18527 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
18528 of the bar cursor. */
18530 enum text_cursor_kinds
18531 get_specified_cursor_type (arg, width)
18532 Lisp_Object arg;
18533 int *width;
18535 enum text_cursor_kinds type;
18537 if (NILP (arg))
18538 return NO_CURSOR;
18540 if (EQ (arg, Qbox))
18541 return FILLED_BOX_CURSOR;
18543 if (EQ (arg, Qhollow))
18544 return HOLLOW_BOX_CURSOR;
18546 if (EQ (arg, Qbar))
18548 *width = 2;
18549 return BAR_CURSOR;
18552 if (CONSP (arg)
18553 && EQ (XCAR (arg), Qbar)
18554 && INTEGERP (XCDR (arg))
18555 && XINT (XCDR (arg)) >= 0)
18557 *width = XINT (XCDR (arg));
18558 return BAR_CURSOR;
18561 if (EQ (arg, Qhbar))
18563 *width = 2;
18564 return HBAR_CURSOR;
18567 if (CONSP (arg)
18568 && EQ (XCAR (arg), Qhbar)
18569 && INTEGERP (XCDR (arg))
18570 && XINT (XCDR (arg)) >= 0)
18572 *width = XINT (XCDR (arg));
18573 return HBAR_CURSOR;
18576 /* Treat anything unknown as "hollow box cursor".
18577 It was bad to signal an error; people have trouble fixing
18578 .Xdefaults with Emacs, when it has something bad in it. */
18579 type = HOLLOW_BOX_CURSOR;
18581 return type;
18584 /* Set the default cursor types for specified frame. */
18585 void
18586 set_frame_cursor_types (f, arg)
18587 struct frame *f;
18588 Lisp_Object arg;
18590 int width;
18591 Lisp_Object tem;
18593 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
18594 FRAME_CURSOR_WIDTH (f) = width;
18596 /* By default, set up the blink-off state depending on the on-state. */
18598 tem = Fassoc (arg, Vblink_cursor_alist);
18599 if (!NILP (tem))
18601 FRAME_BLINK_OFF_CURSOR (f)
18602 = get_specified_cursor_type (XCDR (tem), &width);
18603 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
18605 else
18606 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
18610 /* Return the cursor we want to be displayed in window W. Return
18611 width of bar/hbar cursor through WIDTH arg. Return with
18612 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
18613 (i.e. if the `system caret' should track this cursor).
18615 In a mini-buffer window, we want the cursor only to appear if we
18616 are reading input from this window. For the selected window, we
18617 want the cursor type given by the frame parameter or buffer local
18618 setting of cursor-type. If explicitly marked off, draw no cursor.
18619 In all other cases, we want a hollow box cursor. */
18621 enum text_cursor_kinds
18622 get_window_cursor_type (w, width, active_cursor)
18623 struct window *w;
18624 int *width;
18625 int *active_cursor;
18627 struct frame *f = XFRAME (w->frame);
18628 struct buffer *b = XBUFFER (w->buffer);
18629 int cursor_type = DEFAULT_CURSOR;
18630 Lisp_Object alt_cursor;
18631 int non_selected = 0;
18633 *active_cursor = 1;
18635 /* Echo area */
18636 if (cursor_in_echo_area
18637 && FRAME_HAS_MINIBUF_P (f)
18638 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
18640 if (w == XWINDOW (echo_area_window))
18642 *width = FRAME_CURSOR_WIDTH (f);
18643 return FRAME_DESIRED_CURSOR (f);
18646 *active_cursor = 0;
18647 non_selected = 1;
18650 /* Nonselected window or nonselected frame. */
18651 else if (w != XWINDOW (f->selected_window)
18652 #ifdef HAVE_WINDOW_SYSTEM
18653 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame
18654 #endif
18657 *active_cursor = 0;
18659 if (MINI_WINDOW_P (w) && minibuf_level == 0)
18660 return NO_CURSOR;
18662 non_selected = 1;
18665 /* Never display a cursor in a window in which cursor-type is nil. */
18666 if (NILP (b->cursor_type))
18667 return NO_CURSOR;
18669 /* Use cursor-in-non-selected-windows for non-selected window or frame. */
18670 if (non_selected)
18672 alt_cursor = Fbuffer_local_value (Qcursor_in_non_selected_windows, w->buffer);
18673 return get_specified_cursor_type (alt_cursor, width);
18676 /* Get the normal cursor type for this window. */
18677 if (EQ (b->cursor_type, Qt))
18679 cursor_type = FRAME_DESIRED_CURSOR (f);
18680 *width = FRAME_CURSOR_WIDTH (f);
18682 else
18683 cursor_type = get_specified_cursor_type (b->cursor_type, width);
18685 /* Use normal cursor if not blinked off. */
18686 if (!w->cursor_off_p)
18687 return cursor_type;
18689 /* Cursor is blinked off, so determine how to "toggle" it. */
18691 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
18692 if ((alt_cursor = Fassoc (b->cursor_type, Vblink_cursor_alist), !NILP (alt_cursor)))
18693 return get_specified_cursor_type (XCDR (alt_cursor), width);
18695 /* Then see if frame has specified a specific blink off cursor type. */
18696 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
18698 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
18699 return FRAME_BLINK_OFF_CURSOR (f);
18702 /* Finally perform built-in cursor blinking:
18703 filled box <-> hollow box
18704 wide [h]bar <-> narrow [h]bar
18705 narrow [h]bar <-> no cursor
18706 other type <-> no cursor */
18708 if (cursor_type == FILLED_BOX_CURSOR)
18709 return HOLLOW_BOX_CURSOR;
18711 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
18713 *width = 1;
18714 return cursor_type;
18717 return NO_CURSOR;
18721 #ifdef HAVE_WINDOW_SYSTEM
18723 /* Notice when the text cursor of window W has been completely
18724 overwritten by a drawing operation that outputs glyphs in AREA
18725 starting at X0 and ending at X1 in the line starting at Y0 and
18726 ending at Y1. X coordinates are area-relative. X1 < 0 means all
18727 the rest of the line after X0 has been written. Y coordinates
18728 are window-relative. */
18730 static void
18731 notice_overwritten_cursor (w, area, x0, x1, y0, y1)
18732 struct window *w;
18733 enum glyph_row_area area;
18734 int x0, y0, x1, y1;
18736 if (area == TEXT_AREA && w->phys_cursor_on_p)
18738 int cx0 = w->phys_cursor.x;
18739 int cx1 = cx0 + w->phys_cursor_width;
18740 int cy0 = w->phys_cursor.y;
18741 int cy1 = cy0 + w->phys_cursor_height;
18743 if (x0 <= cx0 && (x1 < 0 || x1 >= cx1))
18745 /* The cursor image will be completely removed from the
18746 screen if the output area intersects the cursor area in
18747 y-direction. When we draw in [y0 y1[, and some part of
18748 the cursor is at y < y0, that part must have been drawn
18749 before. When scrolling, the cursor is erased before
18750 actually scrolling, so we don't come here. When not
18751 scrolling, the rows above the old cursor row must have
18752 changed, and in this case these rows must have written
18753 over the cursor image.
18755 Likewise if part of the cursor is below y1, with the
18756 exception of the cursor being in the first blank row at
18757 the buffer and window end because update_text_area
18758 doesn't draw that row. (Except when it does, but
18759 that's handled in update_text_area.) */
18761 if (((y0 >= cy0 && y0 < cy1) || (y1 > cy0 && y1 < cy1))
18762 && w->current_matrix->rows[w->phys_cursor.vpos].displays_text_p)
18763 w->phys_cursor_on_p = 0;
18768 #endif /* HAVE_WINDOW_SYSTEM */
18771 /************************************************************************
18772 Mouse Face
18773 ************************************************************************/
18775 #ifdef HAVE_WINDOW_SYSTEM
18777 /* EXPORT for RIF:
18778 Fix the display of area AREA of overlapping row ROW in window W. */
18780 void
18781 x_fix_overlapping_area (w, row, area)
18782 struct window *w;
18783 struct glyph_row *row;
18784 enum glyph_row_area area;
18786 int i, x;
18788 BLOCK_INPUT;
18790 if (area == LEFT_MARGIN_AREA)
18791 x = 0;
18792 else if (area == TEXT_AREA)
18793 x = row->x + window_box_width (w, LEFT_MARGIN_AREA);
18794 else
18795 x = (window_box_width (w, LEFT_MARGIN_AREA)
18796 + window_box_width (w, TEXT_AREA));
18798 for (i = 0; i < row->used[area];)
18800 if (row->glyphs[area][i].overlaps_vertically_p)
18802 int start = i, start_x = x;
18806 x += row->glyphs[area][i].pixel_width;
18807 ++i;
18809 while (i < row->used[area]
18810 && row->glyphs[area][i].overlaps_vertically_p);
18812 draw_glyphs (w, start_x, row, area,
18813 start, i,
18814 DRAW_NORMAL_TEXT, 1);
18816 else
18818 x += row->glyphs[area][i].pixel_width;
18819 ++i;
18823 UNBLOCK_INPUT;
18827 /* EXPORT:
18828 Draw the cursor glyph of window W in glyph row ROW. See the
18829 comment of draw_glyphs for the meaning of HL. */
18831 void
18832 draw_phys_cursor_glyph (w, row, hl)
18833 struct window *w;
18834 struct glyph_row *row;
18835 enum draw_glyphs_face hl;
18837 /* If cursor hpos is out of bounds, don't draw garbage. This can
18838 happen in mini-buffer windows when switching between echo area
18839 glyphs and mini-buffer. */
18840 if (w->phys_cursor.hpos < row->used[TEXT_AREA])
18842 int on_p = w->phys_cursor_on_p;
18843 int x1;
18844 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
18845 w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
18846 hl, 0);
18847 w->phys_cursor_on_p = on_p;
18849 if (hl == DRAW_CURSOR)
18850 w->phys_cursor_width = x1 - w->phys_cursor.x;
18851 /* When we erase the cursor, and ROW is overlapped by other
18852 rows, make sure that these overlapping parts of other rows
18853 are redrawn. */
18854 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
18856 if (row > w->current_matrix->rows
18857 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
18858 x_fix_overlapping_area (w, row - 1, TEXT_AREA);
18860 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
18861 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
18862 x_fix_overlapping_area (w, row + 1, TEXT_AREA);
18868 /* EXPORT:
18869 Erase the image of a cursor of window W from the screen. */
18871 void
18872 erase_phys_cursor (w)
18873 struct window *w;
18875 struct frame *f = XFRAME (w->frame);
18876 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
18877 int hpos = w->phys_cursor.hpos;
18878 int vpos = w->phys_cursor.vpos;
18879 int mouse_face_here_p = 0;
18880 struct glyph_matrix *active_glyphs = w->current_matrix;
18881 struct glyph_row *cursor_row;
18882 struct glyph *cursor_glyph;
18883 enum draw_glyphs_face hl;
18885 /* No cursor displayed or row invalidated => nothing to do on the
18886 screen. */
18887 if (w->phys_cursor_type == NO_CURSOR)
18888 goto mark_cursor_off;
18890 /* VPOS >= active_glyphs->nrows means that window has been resized.
18891 Don't bother to erase the cursor. */
18892 if (vpos >= active_glyphs->nrows)
18893 goto mark_cursor_off;
18895 /* If row containing cursor is marked invalid, there is nothing we
18896 can do. */
18897 cursor_row = MATRIX_ROW (active_glyphs, vpos);
18898 if (!cursor_row->enabled_p)
18899 goto mark_cursor_off;
18901 /* If row is completely invisible, don't attempt to delete a cursor which
18902 isn't there. This can happen if cursor is at top of a window, and
18903 we switch to a buffer with a header line in that window. */
18904 if (cursor_row->visible_height <= 0)
18905 goto mark_cursor_off;
18907 /* This can happen when the new row is shorter than the old one.
18908 In this case, either draw_glyphs or clear_end_of_line
18909 should have cleared the cursor. Note that we wouldn't be
18910 able to erase the cursor in this case because we don't have a
18911 cursor glyph at hand. */
18912 if (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])
18913 goto mark_cursor_off;
18915 /* If the cursor is in the mouse face area, redisplay that when
18916 we clear the cursor. */
18917 if (! NILP (dpyinfo->mouse_face_window)
18918 && w == XWINDOW (dpyinfo->mouse_face_window)
18919 && (vpos > dpyinfo->mouse_face_beg_row
18920 || (vpos == dpyinfo->mouse_face_beg_row
18921 && hpos >= dpyinfo->mouse_face_beg_col))
18922 && (vpos < dpyinfo->mouse_face_end_row
18923 || (vpos == dpyinfo->mouse_face_end_row
18924 && hpos < dpyinfo->mouse_face_end_col))
18925 /* Don't redraw the cursor's spot in mouse face if it is at the
18926 end of a line (on a newline). The cursor appears there, but
18927 mouse highlighting does not. */
18928 && cursor_row->used[TEXT_AREA] > hpos)
18929 mouse_face_here_p = 1;
18931 /* Maybe clear the display under the cursor. */
18932 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
18934 int x, y;
18935 int header_line_height = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
18937 cursor_glyph = get_phys_cursor_glyph (w);
18938 if (cursor_glyph == NULL)
18939 goto mark_cursor_off;
18941 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
18942 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
18944 rif->clear_frame_area (f, x, y,
18945 cursor_glyph->pixel_width, cursor_row->visible_height);
18948 /* Erase the cursor by redrawing the character underneath it. */
18949 if (mouse_face_here_p)
18950 hl = DRAW_MOUSE_FACE;
18951 else
18952 hl = DRAW_NORMAL_TEXT;
18953 draw_phys_cursor_glyph (w, cursor_row, hl);
18955 mark_cursor_off:
18956 w->phys_cursor_on_p = 0;
18957 w->phys_cursor_type = NO_CURSOR;
18961 /* EXPORT:
18962 Display or clear cursor of window W. If ON is zero, clear the
18963 cursor. If it is non-zero, display the cursor. If ON is nonzero,
18964 where to put the cursor is specified by HPOS, VPOS, X and Y. */
18966 void
18967 display_and_set_cursor (w, on, hpos, vpos, x, y)
18968 struct window *w;
18969 int on, hpos, vpos, x, y;
18971 struct frame *f = XFRAME (w->frame);
18972 int new_cursor_type;
18973 int new_cursor_width;
18974 int active_cursor;
18975 struct glyph_matrix *current_glyphs;
18976 struct glyph_row *glyph_row;
18977 struct glyph *glyph;
18979 /* This is pointless on invisible frames, and dangerous on garbaged
18980 windows and frames; in the latter case, the frame or window may
18981 be in the midst of changing its size, and x and y may be off the
18982 window. */
18983 if (! FRAME_VISIBLE_P (f)
18984 || FRAME_GARBAGED_P (f)
18985 || vpos >= w->current_matrix->nrows
18986 || hpos >= w->current_matrix->matrix_w)
18987 return;
18989 /* If cursor is off and we want it off, return quickly. */
18990 if (!on && !w->phys_cursor_on_p)
18991 return;
18993 current_glyphs = w->current_matrix;
18994 glyph_row = MATRIX_ROW (current_glyphs, vpos);
18995 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
18997 /* If cursor row is not enabled, we don't really know where to
18998 display the cursor. */
18999 if (!glyph_row->enabled_p)
19001 w->phys_cursor_on_p = 0;
19002 return;
19005 xassert (interrupt_input_blocked);
19007 /* Set new_cursor_type to the cursor we want to be displayed. */
19008 new_cursor_type = get_window_cursor_type (w, &new_cursor_width, &active_cursor);
19010 /* If cursor is currently being shown and we don't want it to be or
19011 it is in the wrong place, or the cursor type is not what we want,
19012 erase it. */
19013 if (w->phys_cursor_on_p
19014 && (!on
19015 || w->phys_cursor.x != x
19016 || w->phys_cursor.y != y
19017 || new_cursor_type != w->phys_cursor_type
19018 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
19019 && new_cursor_width != w->phys_cursor_width)))
19020 erase_phys_cursor (w);
19022 /* Don't check phys_cursor_on_p here because that flag is only set
19023 to zero in some cases where we know that the cursor has been
19024 completely erased, to avoid the extra work of erasing the cursor
19025 twice. In other words, phys_cursor_on_p can be 1 and the cursor
19026 still not be visible, or it has only been partly erased. */
19027 if (on)
19029 w->phys_cursor_ascent = glyph_row->ascent;
19030 w->phys_cursor_height = glyph_row->height;
19032 /* Set phys_cursor_.* before x_draw_.* is called because some
19033 of them may need the information. */
19034 w->phys_cursor.x = x;
19035 w->phys_cursor.y = glyph_row->y;
19036 w->phys_cursor.hpos = hpos;
19037 w->phys_cursor.vpos = vpos;
19040 rif->draw_window_cursor (w, glyph_row, x, y,
19041 new_cursor_type, new_cursor_width,
19042 on, active_cursor);
19046 /* Switch the display of W's cursor on or off, according to the value
19047 of ON. */
19049 static void
19050 update_window_cursor (w, on)
19051 struct window *w;
19052 int on;
19054 /* Don't update cursor in windows whose frame is in the process
19055 of being deleted. */
19056 if (w->current_matrix)
19058 BLOCK_INPUT;
19059 display_and_set_cursor (w, on, w->phys_cursor.hpos, w->phys_cursor.vpos,
19060 w->phys_cursor.x, w->phys_cursor.y);
19061 UNBLOCK_INPUT;
19066 /* Call update_window_cursor with parameter ON_P on all leaf windows
19067 in the window tree rooted at W. */
19069 static void
19070 update_cursor_in_window_tree (w, on_p)
19071 struct window *w;
19072 int on_p;
19074 while (w)
19076 if (!NILP (w->hchild))
19077 update_cursor_in_window_tree (XWINDOW (w->hchild), on_p);
19078 else if (!NILP (w->vchild))
19079 update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
19080 else
19081 update_window_cursor (w, on_p);
19083 w = NILP (w->next) ? 0 : XWINDOW (w->next);
19088 /* EXPORT:
19089 Display the cursor on window W, or clear it, according to ON_P.
19090 Don't change the cursor's position. */
19092 void
19093 x_update_cursor (f, on_p)
19094 struct frame *f;
19095 int on_p;
19097 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
19101 /* EXPORT:
19102 Clear the cursor of window W to background color, and mark the
19103 cursor as not shown. This is used when the text where the cursor
19104 is is about to be rewritten. */
19106 void
19107 x_clear_cursor (w)
19108 struct window *w;
19110 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
19111 update_window_cursor (w, 0);
19115 /* EXPORT:
19116 Display the active region described by mouse_face_* according to DRAW. */
19118 void
19119 show_mouse_face (dpyinfo, draw)
19120 Display_Info *dpyinfo;
19121 enum draw_glyphs_face draw;
19123 struct window *w = XWINDOW (dpyinfo->mouse_face_window);
19124 struct frame *f = XFRAME (WINDOW_FRAME (w));
19126 if (/* If window is in the process of being destroyed, don't bother
19127 to do anything. */
19128 w->current_matrix != NULL
19129 /* Don't update mouse highlight if hidden */
19130 && (draw != DRAW_MOUSE_FACE || !dpyinfo->mouse_face_hidden)
19131 /* Recognize when we are called to operate on rows that don't exist
19132 anymore. This can happen when a window is split. */
19133 && dpyinfo->mouse_face_end_row < w->current_matrix->nrows)
19135 int phys_cursor_on_p = w->phys_cursor_on_p;
19136 struct glyph_row *row, *first, *last;
19138 first = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row);
19139 last = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row);
19141 for (row = first; row <= last && row->enabled_p; ++row)
19143 int start_hpos, end_hpos, start_x;
19145 /* For all but the first row, the highlight starts at column 0. */
19146 if (row == first)
19148 start_hpos = dpyinfo->mouse_face_beg_col;
19149 start_x = dpyinfo->mouse_face_beg_x;
19151 else
19153 start_hpos = 0;
19154 start_x = 0;
19157 if (row == last)
19158 end_hpos = dpyinfo->mouse_face_end_col;
19159 else
19160 end_hpos = row->used[TEXT_AREA];
19162 if (end_hpos > start_hpos)
19164 draw_glyphs (w, start_x, row, TEXT_AREA,
19165 start_hpos, end_hpos,
19166 draw, 0);
19168 row->mouse_face_p
19169 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
19173 /* When we've written over the cursor, arrange for it to
19174 be displayed again. */
19175 if (phys_cursor_on_p && !w->phys_cursor_on_p)
19177 BLOCK_INPUT;
19178 display_and_set_cursor (w, 1,
19179 w->phys_cursor.hpos, w->phys_cursor.vpos,
19180 w->phys_cursor.x, w->phys_cursor.y);
19181 UNBLOCK_INPUT;
19185 /* Change the mouse cursor. */
19186 if (draw == DRAW_NORMAL_TEXT)
19187 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
19188 else if (draw == DRAW_MOUSE_FACE)
19189 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
19190 else
19191 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
19194 /* EXPORT:
19195 Clear out the mouse-highlighted active region.
19196 Redraw it un-highlighted first. Value is non-zero if mouse
19197 face was actually drawn unhighlighted. */
19200 clear_mouse_face (dpyinfo)
19201 Display_Info *dpyinfo;
19203 int cleared = 0;
19205 if (!NILP (dpyinfo->mouse_face_window))
19207 show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT);
19208 cleared = 1;
19211 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
19212 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
19213 dpyinfo->mouse_face_window = Qnil;
19214 dpyinfo->mouse_face_overlay = Qnil;
19215 return cleared;
19219 /* EXPORT:
19220 Non-zero if physical cursor of window W is within mouse face. */
19223 cursor_in_mouse_face_p (w)
19224 struct window *w;
19226 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
19227 int in_mouse_face = 0;
19229 if (WINDOWP (dpyinfo->mouse_face_window)
19230 && XWINDOW (dpyinfo->mouse_face_window) == w)
19232 int hpos = w->phys_cursor.hpos;
19233 int vpos = w->phys_cursor.vpos;
19235 if (vpos >= dpyinfo->mouse_face_beg_row
19236 && vpos <= dpyinfo->mouse_face_end_row
19237 && (vpos > dpyinfo->mouse_face_beg_row
19238 || hpos >= dpyinfo->mouse_face_beg_col)
19239 && (vpos < dpyinfo->mouse_face_end_row
19240 || hpos < dpyinfo->mouse_face_end_col
19241 || dpyinfo->mouse_face_past_end))
19242 in_mouse_face = 1;
19245 return in_mouse_face;
19251 /* Find the glyph matrix position of buffer position CHARPOS in window
19252 *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's
19253 current glyphs must be up to date. If CHARPOS is above window
19254 start return (0, 0, 0, 0). If CHARPOS is after end of W, return end
19255 of last line in W. In the row containing CHARPOS, stop before glyphs
19256 having STOP as object. */
19258 #if 0 /* This is a version of fast_find_position that's more correct
19259 in the presence of hscrolling, for example. I didn't install
19260 it right away because the problem fixed is minor, it failed
19261 in 20.x as well, and I think it's too risky to install
19262 so near the release of 21.1. 2001-09-25 gerd. */
19264 static int
19265 fast_find_position (w, charpos, hpos, vpos, x, y, stop)
19266 struct window *w;
19267 int charpos;
19268 int *hpos, *vpos, *x, *y;
19269 Lisp_Object stop;
19271 struct glyph_row *row, *first;
19272 struct glyph *glyph, *end;
19273 int i, past_end = 0;
19275 first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
19276 row = row_containing_pos (w, charpos, first, NULL, 0);
19277 if (row == NULL)
19279 if (charpos < MATRIX_ROW_START_CHARPOS (first))
19281 *x = *y = *hpos = *vpos = 0;
19282 return 0;
19284 else
19286 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
19287 past_end = 1;
19291 *x = row->x;
19292 *y = row->y;
19293 *vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
19295 glyph = row->glyphs[TEXT_AREA];
19296 end = glyph + row->used[TEXT_AREA];
19298 /* Skip over glyphs not having an object at the start of the row.
19299 These are special glyphs like truncation marks on terminal
19300 frames. */
19301 if (row->displays_text_p)
19302 while (glyph < end
19303 && INTEGERP (glyph->object)
19304 && !EQ (stop, glyph->object)
19305 && glyph->charpos < 0)
19307 *x += glyph->pixel_width;
19308 ++glyph;
19311 while (glyph < end
19312 && !INTEGERP (glyph->object)
19313 && !EQ (stop, glyph->object)
19314 && (!BUFFERP (glyph->object)
19315 || glyph->charpos < charpos))
19317 *x += glyph->pixel_width;
19318 ++glyph;
19321 *hpos = glyph - row->glyphs[TEXT_AREA];
19322 return past_end;
19325 #else /* not 0 */
19327 static int
19328 fast_find_position (w, pos, hpos, vpos, x, y, stop)
19329 struct window *w;
19330 int pos;
19331 int *hpos, *vpos, *x, *y;
19332 Lisp_Object stop;
19334 int i;
19335 int lastcol;
19336 int maybe_next_line_p = 0;
19337 int line_start_position;
19338 int yb = window_text_bottom_y (w);
19339 struct glyph_row *row, *best_row;
19340 int row_vpos, best_row_vpos;
19341 int current_x;
19343 row = best_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
19344 row_vpos = best_row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
19346 while (row->y < yb)
19348 if (row->used[TEXT_AREA])
19349 line_start_position = row->glyphs[TEXT_AREA]->charpos;
19350 else
19351 line_start_position = 0;
19353 if (line_start_position > pos)
19354 break;
19355 /* If the position sought is the end of the buffer,
19356 don't include the blank lines at the bottom of the window. */
19357 else if (line_start_position == pos
19358 && pos == BUF_ZV (XBUFFER (w->buffer)))
19360 maybe_next_line_p = 1;
19361 break;
19363 else if (line_start_position > 0)
19365 best_row = row;
19366 best_row_vpos = row_vpos;
19369 if (row->y + row->height >= yb)
19370 break;
19372 ++row;
19373 ++row_vpos;
19376 /* Find the right column within BEST_ROW. */
19377 lastcol = 0;
19378 current_x = best_row->x;
19379 for (i = 0; i < best_row->used[TEXT_AREA]; i++)
19381 struct glyph *glyph = best_row->glyphs[TEXT_AREA] + i;
19382 int charpos = glyph->charpos;
19384 if (BUFFERP (glyph->object))
19386 if (charpos == pos)
19388 *hpos = i;
19389 *vpos = best_row_vpos;
19390 *x = current_x;
19391 *y = best_row->y;
19392 return 1;
19394 else if (charpos > pos)
19395 break;
19397 else if (EQ (glyph->object, stop))
19398 break;
19400 if (charpos > 0)
19401 lastcol = i;
19402 current_x += glyph->pixel_width;
19405 /* If we're looking for the end of the buffer,
19406 and we didn't find it in the line we scanned,
19407 use the start of the following line. */
19408 if (maybe_next_line_p)
19410 ++best_row;
19411 ++best_row_vpos;
19412 lastcol = 0;
19413 current_x = best_row->x;
19416 *vpos = best_row_vpos;
19417 *hpos = lastcol + 1;
19418 *x = current_x;
19419 *y = best_row->y;
19420 return 0;
19423 #endif /* not 0 */
19426 /* Find the position of the glyph for position POS in OBJECT in
19427 window W's current matrix, and return in *X, *Y the pixel
19428 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
19430 RIGHT_P non-zero means return the position of the right edge of the
19431 glyph, RIGHT_P zero means return the left edge position.
19433 If no glyph for POS exists in the matrix, return the position of
19434 the glyph with the next smaller position that is in the matrix, if
19435 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
19436 exists in the matrix, return the position of the glyph with the
19437 next larger position in OBJECT.
19439 Value is non-zero if a glyph was found. */
19441 static int
19442 fast_find_string_pos (w, pos, object, hpos, vpos, x, y, right_p)
19443 struct window *w;
19444 int pos;
19445 Lisp_Object object;
19446 int *hpos, *vpos, *x, *y;
19447 int right_p;
19449 int yb = window_text_bottom_y (w);
19450 struct glyph_row *r;
19451 struct glyph *best_glyph = NULL;
19452 struct glyph_row *best_row = NULL;
19453 int best_x = 0;
19455 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
19456 r->enabled_p && r->y < yb;
19457 ++r)
19459 struct glyph *g = r->glyphs[TEXT_AREA];
19460 struct glyph *e = g + r->used[TEXT_AREA];
19461 int gx;
19463 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
19464 if (EQ (g->object, object))
19466 if (g->charpos == pos)
19468 best_glyph = g;
19469 best_x = gx;
19470 best_row = r;
19471 goto found;
19473 else if (best_glyph == NULL
19474 || ((abs (g->charpos - pos)
19475 < abs (best_glyph->charpos - pos))
19476 && (right_p
19477 ? g->charpos < pos
19478 : g->charpos > pos)))
19480 best_glyph = g;
19481 best_x = gx;
19482 best_row = r;
19487 found:
19489 if (best_glyph)
19491 *x = best_x;
19492 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
19494 if (right_p)
19496 *x += best_glyph->pixel_width;
19497 ++*hpos;
19500 *y = best_row->y;
19501 *vpos = best_row - w->current_matrix->rows;
19504 return best_glyph != NULL;
19508 /* Take proper action when mouse has moved to the mode or header line
19509 or marginal area AREA of window W, x-position X and y-position Y.
19510 X is relative to the start of the text display area of W, so the
19511 width of bitmap areas and scroll bars must be subtracted to get a
19512 position relative to the start of the mode line. */
19514 static void
19515 note_mode_line_or_margin_highlight (w, x, y, area)
19516 struct window *w;
19517 int x, y;
19518 enum window_part area;
19520 struct frame *f = XFRAME (w->frame);
19521 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
19522 Cursor cursor = dpyinfo->vertical_scroll_bar_cursor;
19523 int charpos;
19524 Lisp_Object string, help, map, pos;
19526 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
19527 string = mode_line_string (w, x, y, area, &charpos);
19528 else
19529 string = marginal_area_string (w, x, y, area, &charpos);
19531 if (STRINGP (string))
19533 pos = make_number (charpos);
19535 /* If we're on a string with `help-echo' text property, arrange
19536 for the help to be displayed. This is done by setting the
19537 global variable help_echo_string to the help string. */
19538 help = Fget_text_property (pos, Qhelp_echo, string);
19539 if (!NILP (help))
19541 help_echo_string = help;
19542 XSETWINDOW (help_echo_window, w);
19543 help_echo_object = string;
19544 help_echo_pos = charpos;
19547 /* Change the mouse pointer according to what is under X/Y. */
19548 map = Fget_text_property (pos, Qlocal_map, string);
19549 if (!KEYMAPP (map))
19550 map = Fget_text_property (pos, Qkeymap, string);
19551 if (KEYMAPP (map))
19552 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
19555 rif->define_frame_cursor (f, cursor);
19559 /* EXPORT:
19560 Take proper action when the mouse has moved to position X, Y on
19561 frame F as regards highlighting characters that have mouse-face
19562 properties. Also de-highlighting chars where the mouse was before.
19563 X and Y can be negative or out of range. */
19565 void
19566 note_mouse_highlight (f, x, y)
19567 struct frame *f;
19568 int x, y;
19570 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
19571 enum window_part part;
19572 Lisp_Object window;
19573 struct window *w;
19574 Cursor cursor = No_Cursor;
19575 struct buffer *b;
19577 /* When a menu is active, don't highlight because this looks odd. */
19578 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NTGUI)
19579 if (popup_activated ())
19580 return;
19581 #endif
19583 if (NILP (Vmouse_highlight)
19584 || !f->glyphs_initialized_p)
19585 return;
19587 dpyinfo->mouse_face_mouse_x = x;
19588 dpyinfo->mouse_face_mouse_y = y;
19589 dpyinfo->mouse_face_mouse_frame = f;
19591 if (dpyinfo->mouse_face_defer)
19592 return;
19594 if (gc_in_progress)
19596 dpyinfo->mouse_face_deferred_gc = 1;
19597 return;
19600 /* Which window is that in? */
19601 window = window_from_coordinates (f, x, y, &part, 1);
19603 /* If we were displaying active text in another window, clear that. */
19604 if (! EQ (window, dpyinfo->mouse_face_window))
19605 clear_mouse_face (dpyinfo);
19607 /* Not on a window -> return. */
19608 if (!WINDOWP (window))
19609 return;
19611 /* Reset help_echo_string. It will get recomputed below. */
19612 /* ++KFS: X version didn't do this, but it looks harmless. */
19613 help_echo_string = Qnil;
19615 /* Convert to window-relative pixel coordinates. */
19616 w = XWINDOW (window);
19617 frame_to_window_pixel_xy (w, &x, &y);
19619 /* Handle tool-bar window differently since it doesn't display a
19620 buffer. */
19621 if (EQ (window, f->tool_bar_window))
19623 note_tool_bar_highlight (f, x, y);
19624 return;
19627 /* Mouse is on the mode, header line or margin? */
19628 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
19629 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
19631 note_mode_line_or_margin_highlight (w, x, y, part);
19632 return;
19635 if (part == ON_VERTICAL_BORDER)
19636 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
19637 else
19638 cursor = FRAME_X_OUTPUT (f)->text_cursor;
19640 /* Are we in a window whose display is up to date?
19641 And verify the buffer's text has not changed. */
19642 b = XBUFFER (w->buffer);
19643 if (part == ON_TEXT
19644 && EQ (w->window_end_valid, w->buffer)
19645 && XFASTINT (w->last_modified) == BUF_MODIFF (b)
19646 && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
19648 int hpos, vpos, pos, i, area;
19649 struct glyph *glyph;
19650 Lisp_Object object;
19651 Lisp_Object mouse_face = Qnil, overlay = Qnil, position;
19652 Lisp_Object *overlay_vec = NULL;
19653 int len, noverlays;
19654 struct buffer *obuf;
19655 int obegv, ozv, same_region;
19657 /* Find the glyph under X/Y. */
19658 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &area, 0);
19660 /* Clear mouse face if X/Y not over text. */
19661 if (glyph == NULL
19662 || area != TEXT_AREA
19663 || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p)
19665 #if defined (HAVE_NTGUI)
19666 /* ++KFS: Why is this necessary on W32 ? */
19667 clear_mouse_face (dpyinfo);
19668 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
19669 #else
19670 if (clear_mouse_face (dpyinfo))
19671 cursor = No_Cursor;
19672 #endif
19673 goto set_cursor;
19676 pos = glyph->charpos;
19677 object = glyph->object;
19678 if (!STRINGP (object) && !BUFFERP (object))
19679 goto set_cursor;
19681 /* If we get an out-of-range value, return now; avoid an error. */
19682 if (BUFFERP (object) && pos > BUF_Z (b))
19683 goto set_cursor;
19685 /* Make the window's buffer temporarily current for
19686 overlays_at and compute_char_face. */
19687 obuf = current_buffer;
19688 current_buffer = b;
19689 obegv = BEGV;
19690 ozv = ZV;
19691 BEGV = BEG;
19692 ZV = Z;
19694 /* Is this char mouse-active or does it have help-echo? */
19695 position = make_number (pos);
19697 if (BUFFERP (object))
19699 /* Put all the overlays we want in a vector in overlay_vec.
19700 Store the length in len. If there are more than 10, make
19701 enough space for all, and try again. */
19702 len = 10;
19703 overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
19704 noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL, 0);
19705 if (noverlays > len)
19707 len = noverlays;
19708 overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
19709 noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL,0);
19712 /* Sort overlays into increasing priority order. */
19713 noverlays = sort_overlays (overlay_vec, noverlays, w);
19715 else
19716 noverlays = 0;
19718 same_region = (EQ (window, dpyinfo->mouse_face_window)
19719 && vpos >= dpyinfo->mouse_face_beg_row
19720 && vpos <= dpyinfo->mouse_face_end_row
19721 && (vpos > dpyinfo->mouse_face_beg_row
19722 || hpos >= dpyinfo->mouse_face_beg_col)
19723 && (vpos < dpyinfo->mouse_face_end_row
19724 || hpos < dpyinfo->mouse_face_end_col
19725 || dpyinfo->mouse_face_past_end));
19727 if (same_region)
19728 cursor = No_Cursor;
19730 /* Check mouse-face highlighting. */
19731 if (! same_region
19732 /* If there exists an overlay with mouse-face overlapping
19733 the one we are currently highlighting, we have to
19734 check if we enter the overlapping overlay, and then
19735 highlight only that. */
19736 || (OVERLAYP (dpyinfo->mouse_face_overlay)
19737 && mouse_face_overlay_overlaps (dpyinfo->mouse_face_overlay)))
19739 /* Find the highest priority overlay that has a mouse-face
19740 property. */
19741 overlay = Qnil;
19742 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
19744 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
19745 if (!NILP (mouse_face))
19746 overlay = overlay_vec[i];
19749 /* If we're actually highlighting the same overlay as
19750 before, there's no need to do that again. */
19751 if (!NILP (overlay)
19752 && EQ (overlay, dpyinfo->mouse_face_overlay))
19753 goto check_help_echo;
19755 dpyinfo->mouse_face_overlay = overlay;
19757 /* Clear the display of the old active region, if any. */
19758 if (clear_mouse_face (dpyinfo))
19759 cursor = No_Cursor;
19761 /* If no overlay applies, get a text property. */
19762 if (NILP (overlay))
19763 mouse_face = Fget_text_property (position, Qmouse_face, object);
19765 /* Handle the overlay case. */
19766 if (!NILP (overlay))
19768 /* Find the range of text around this char that
19769 should be active. */
19770 Lisp_Object before, after;
19771 int ignore;
19773 before = Foverlay_start (overlay);
19774 after = Foverlay_end (overlay);
19775 /* Record this as the current active region. */
19776 fast_find_position (w, XFASTINT (before),
19777 &dpyinfo->mouse_face_beg_col,
19778 &dpyinfo->mouse_face_beg_row,
19779 &dpyinfo->mouse_face_beg_x,
19780 &dpyinfo->mouse_face_beg_y, Qnil);
19782 dpyinfo->mouse_face_past_end
19783 = !fast_find_position (w, XFASTINT (after),
19784 &dpyinfo->mouse_face_end_col,
19785 &dpyinfo->mouse_face_end_row,
19786 &dpyinfo->mouse_face_end_x,
19787 &dpyinfo->mouse_face_end_y, Qnil);
19788 dpyinfo->mouse_face_window = window;
19790 dpyinfo->mouse_face_face_id
19791 = face_at_buffer_position (w, pos, 0, 0,
19792 &ignore, pos + 1,
19793 !dpyinfo->mouse_face_hidden);
19795 /* Display it as active. */
19796 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
19797 cursor = No_Cursor;
19799 /* Handle the text property case. */
19800 else if (!NILP (mouse_face) && BUFFERP (object))
19802 /* Find the range of text around this char that
19803 should be active. */
19804 Lisp_Object before, after, beginning, end;
19805 int ignore;
19807 beginning = Fmarker_position (w->start);
19808 end = make_number (BUF_Z (XBUFFER (object))
19809 - XFASTINT (w->window_end_pos));
19810 before
19811 = Fprevious_single_property_change (make_number (pos + 1),
19812 Qmouse_face,
19813 object, beginning);
19814 after
19815 = Fnext_single_property_change (position, Qmouse_face,
19816 object, end);
19818 /* Record this as the current active region. */
19819 fast_find_position (w, XFASTINT (before),
19820 &dpyinfo->mouse_face_beg_col,
19821 &dpyinfo->mouse_face_beg_row,
19822 &dpyinfo->mouse_face_beg_x,
19823 &dpyinfo->mouse_face_beg_y, Qnil);
19824 dpyinfo->mouse_face_past_end
19825 = !fast_find_position (w, XFASTINT (after),
19826 &dpyinfo->mouse_face_end_col,
19827 &dpyinfo->mouse_face_end_row,
19828 &dpyinfo->mouse_face_end_x,
19829 &dpyinfo->mouse_face_end_y, Qnil);
19830 dpyinfo->mouse_face_window = window;
19832 if (BUFFERP (object))
19833 dpyinfo->mouse_face_face_id
19834 = face_at_buffer_position (w, pos, 0, 0,
19835 &ignore, pos + 1,
19836 !dpyinfo->mouse_face_hidden);
19838 /* Display it as active. */
19839 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
19840 cursor = No_Cursor;
19842 else if (!NILP (mouse_face) && STRINGP (object))
19844 Lisp_Object b, e;
19845 int ignore;
19847 b = Fprevious_single_property_change (make_number (pos + 1),
19848 Qmouse_face,
19849 object, Qnil);
19850 e = Fnext_single_property_change (position, Qmouse_face,
19851 object, Qnil);
19852 if (NILP (b))
19853 b = make_number (0);
19854 if (NILP (e))
19855 e = make_number (SCHARS (object) - 1);
19856 fast_find_string_pos (w, XINT (b), object,
19857 &dpyinfo->mouse_face_beg_col,
19858 &dpyinfo->mouse_face_beg_row,
19859 &dpyinfo->mouse_face_beg_x,
19860 &dpyinfo->mouse_face_beg_y, 0);
19861 fast_find_string_pos (w, XINT (e), object,
19862 &dpyinfo->mouse_face_end_col,
19863 &dpyinfo->mouse_face_end_row,
19864 &dpyinfo->mouse_face_end_x,
19865 &dpyinfo->mouse_face_end_y, 1);
19866 dpyinfo->mouse_face_past_end = 0;
19867 dpyinfo->mouse_face_window = window;
19868 dpyinfo->mouse_face_face_id
19869 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
19870 glyph->face_id, 1);
19871 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
19872 cursor = No_Cursor;
19874 else if (STRINGP (object) && NILP (mouse_face))
19876 /* A string which doesn't have mouse-face, but
19877 the text ``under'' it might have. */
19878 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
19879 int start = MATRIX_ROW_START_CHARPOS (r);
19881 pos = string_buffer_position (w, object, start);
19882 if (pos > 0)
19883 mouse_face = get_char_property_and_overlay (make_number (pos),
19884 Qmouse_face,
19885 w->buffer,
19886 &overlay);
19887 if (!NILP (mouse_face) && !NILP (overlay))
19889 Lisp_Object before = Foverlay_start (overlay);
19890 Lisp_Object after = Foverlay_end (overlay);
19891 int ignore;
19893 /* Note that we might not be able to find position
19894 BEFORE in the glyph matrix if the overlay is
19895 entirely covered by a `display' property. In
19896 this case, we overshoot. So let's stop in
19897 the glyph matrix before glyphs for OBJECT. */
19898 fast_find_position (w, XFASTINT (before),
19899 &dpyinfo->mouse_face_beg_col,
19900 &dpyinfo->mouse_face_beg_row,
19901 &dpyinfo->mouse_face_beg_x,
19902 &dpyinfo->mouse_face_beg_y,
19903 object);
19905 dpyinfo->mouse_face_past_end
19906 = !fast_find_position (w, XFASTINT (after),
19907 &dpyinfo->mouse_face_end_col,
19908 &dpyinfo->mouse_face_end_row,
19909 &dpyinfo->mouse_face_end_x,
19910 &dpyinfo->mouse_face_end_y,
19911 Qnil);
19912 dpyinfo->mouse_face_window = window;
19913 dpyinfo->mouse_face_face_id
19914 = face_at_buffer_position (w, pos, 0, 0,
19915 &ignore, pos + 1,
19916 !dpyinfo->mouse_face_hidden);
19918 /* Display it as active. */
19919 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
19920 cursor = No_Cursor;
19925 check_help_echo:
19927 /* Look for a `help-echo' property. */
19929 Lisp_Object help, overlay;
19931 /* Check overlays first. */
19932 help = overlay = Qnil;
19933 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
19935 overlay = overlay_vec[i];
19936 help = Foverlay_get (overlay, Qhelp_echo);
19939 if (!NILP (help))
19941 help_echo_string = help;
19942 help_echo_window = window;
19943 help_echo_object = overlay;
19944 help_echo_pos = pos;
19946 else
19948 Lisp_Object object = glyph->object;
19949 int charpos = glyph->charpos;
19951 /* Try text properties. */
19952 if (STRINGP (object)
19953 && charpos >= 0
19954 && charpos < SCHARS (object))
19956 help = Fget_text_property (make_number (charpos),
19957 Qhelp_echo, object);
19958 if (NILP (help))
19960 /* If the string itself doesn't specify a help-echo,
19961 see if the buffer text ``under'' it does. */
19962 struct glyph_row *r
19963 = MATRIX_ROW (w->current_matrix, vpos);
19964 int start = MATRIX_ROW_START_CHARPOS (r);
19965 int pos = string_buffer_position (w, object, start);
19966 if (pos > 0)
19968 help = Fget_char_property (make_number (pos),
19969 Qhelp_echo, w->buffer);
19970 if (!NILP (help))
19972 charpos = pos;
19973 object = w->buffer;
19978 else if (BUFFERP (object)
19979 && charpos >= BEGV
19980 && charpos < ZV)
19981 help = Fget_text_property (make_number (charpos), Qhelp_echo,
19982 object);
19984 if (!NILP (help))
19986 help_echo_string = help;
19987 help_echo_window = window;
19988 help_echo_object = object;
19989 help_echo_pos = charpos;
19994 BEGV = obegv;
19995 ZV = ozv;
19996 current_buffer = obuf;
19999 set_cursor:
20001 #ifndef HAVE_CARBON
20002 if (cursor != No_Cursor)
20003 #else
20004 if (bcmp (&cursor, &No_Cursor, sizeof (Cursor)))
20005 #endif
20006 rif->define_frame_cursor (f, cursor);
20010 /* EXPORT for RIF:
20011 Clear any mouse-face on window W. This function is part of the
20012 redisplay interface, and is called from try_window_id and similar
20013 functions to ensure the mouse-highlight is off. */
20015 void
20016 x_clear_window_mouse_face (w)
20017 struct window *w;
20019 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
20020 Lisp_Object window;
20022 BLOCK_INPUT;
20023 XSETWINDOW (window, w);
20024 if (EQ (window, dpyinfo->mouse_face_window))
20025 clear_mouse_face (dpyinfo);
20026 UNBLOCK_INPUT;
20030 /* EXPORT:
20031 Just discard the mouse face information for frame F, if any.
20032 This is used when the size of F is changed. */
20034 void
20035 cancel_mouse_face (f)
20036 struct frame *f;
20038 Lisp_Object window;
20039 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
20041 window = dpyinfo->mouse_face_window;
20042 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
20044 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
20045 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
20046 dpyinfo->mouse_face_window = Qnil;
20051 #endif /* HAVE_WINDOW_SYSTEM */
20054 /***********************************************************************
20055 Exposure Events
20056 ***********************************************************************/
20058 #ifdef HAVE_WINDOW_SYSTEM
20060 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
20061 which intersects rectangle R. R is in window-relative coordinates. */
20063 static void
20064 expose_area (w, row, r, area)
20065 struct window *w;
20066 struct glyph_row *row;
20067 XRectangle *r;
20068 enum glyph_row_area area;
20070 struct glyph *first = row->glyphs[area];
20071 struct glyph *end = row->glyphs[area] + row->used[area];
20072 struct glyph *last;
20073 int first_x, start_x, x;
20075 if (area == TEXT_AREA && row->fill_line_p)
20076 /* If row extends face to end of line write the whole line. */
20077 draw_glyphs (w, 0, row, area,
20078 0, row->used[area],
20079 DRAW_NORMAL_TEXT, 0);
20080 else
20082 /* Set START_X to the window-relative start position for drawing glyphs of
20083 AREA. The first glyph of the text area can be partially visible.
20084 The first glyphs of other areas cannot. */
20085 if (area == LEFT_MARGIN_AREA)
20086 start_x = 0;
20087 else if (area == TEXT_AREA)
20088 start_x = row->x + window_box_width (w, LEFT_MARGIN_AREA);
20089 else
20090 start_x = (window_box_width (w, LEFT_MARGIN_AREA)
20091 + window_box_width (w, TEXT_AREA));
20092 x = start_x;
20094 /* Find the first glyph that must be redrawn. */
20095 while (first < end
20096 && x + first->pixel_width < r->x)
20098 x += first->pixel_width;
20099 ++first;
20102 /* Find the last one. */
20103 last = first;
20104 first_x = x;
20105 while (last < end
20106 && x < r->x + r->width)
20108 x += last->pixel_width;
20109 ++last;
20112 /* Repaint. */
20113 if (last > first)
20114 draw_glyphs (w, first_x - start_x, row, area,
20115 first - row->glyphs[area], last - row->glyphs[area],
20116 DRAW_NORMAL_TEXT, 0);
20121 /* Redraw the parts of the glyph row ROW on window W intersecting
20122 rectangle R. R is in window-relative coordinates. Value is
20123 non-zero if mouse-face was overwritten. */
20125 static int
20126 expose_line (w, row, r)
20127 struct window *w;
20128 struct glyph_row *row;
20129 XRectangle *r;
20131 xassert (row->enabled_p);
20133 if (row->mode_line_p || w->pseudo_window_p)
20134 draw_glyphs (w, 0, row, TEXT_AREA,
20135 0, row->used[TEXT_AREA],
20136 DRAW_NORMAL_TEXT, 0);
20137 else
20139 if (row->used[LEFT_MARGIN_AREA])
20140 expose_area (w, row, r, LEFT_MARGIN_AREA);
20141 if (row->used[TEXT_AREA])
20142 expose_area (w, row, r, TEXT_AREA);
20143 if (row->used[RIGHT_MARGIN_AREA])
20144 expose_area (w, row, r, RIGHT_MARGIN_AREA);
20145 draw_row_fringe_bitmaps (w, row);
20148 return row->mouse_face_p;
20152 /* Redraw those parts of glyphs rows during expose event handling that
20153 overlap other rows. Redrawing of an exposed line writes over parts
20154 of lines overlapping that exposed line; this function fixes that.
20156 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
20157 row in W's current matrix that is exposed and overlaps other rows.
20158 LAST_OVERLAPPING_ROW is the last such row. */
20160 static void
20161 expose_overlaps (w, first_overlapping_row, last_overlapping_row)
20162 struct window *w;
20163 struct glyph_row *first_overlapping_row;
20164 struct glyph_row *last_overlapping_row;
20166 struct glyph_row *row;
20168 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
20169 if (row->overlapping_p)
20171 xassert (row->enabled_p && !row->mode_line_p);
20173 if (row->used[LEFT_MARGIN_AREA])
20174 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA);
20176 if (row->used[TEXT_AREA])
20177 x_fix_overlapping_area (w, row, TEXT_AREA);
20179 if (row->used[RIGHT_MARGIN_AREA])
20180 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA);
20185 /* Return non-zero if W's cursor intersects rectangle R. */
20187 static int
20188 phys_cursor_in_rect_p (w, r)
20189 struct window *w;
20190 XRectangle *r;
20192 XRectangle cr, result;
20193 struct glyph *cursor_glyph;
20195 cursor_glyph = get_phys_cursor_glyph (w);
20196 if (cursor_glyph)
20198 cr.x = w->phys_cursor.x;
20199 cr.y = w->phys_cursor.y;
20200 cr.width = cursor_glyph->pixel_width;
20201 cr.height = w->phys_cursor_height;
20202 /* ++KFS: W32 version used W32-specific IntersectRect here, but
20203 I assume the effect is the same -- and this is portable. */
20204 return x_intersect_rectangles (&cr, r, &result);
20206 else
20207 return 0;
20211 /* EXPORT:
20212 Draw a vertical window border to the right of window W if W doesn't
20213 have vertical scroll bars. */
20215 void
20216 x_draw_vertical_border (w)
20217 struct window *w;
20219 struct frame *f = XFRAME (WINDOW_FRAME (w));
20221 /* Redraw borders between horizontally adjacent windows. Don't
20222 do it for frames with vertical scroll bars because either the
20223 right scroll bar of a window, or the left scroll bar of its
20224 neighbor will suffice as a border. */
20225 if (!WINDOW_RIGHTMOST_P (w)
20226 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f))
20228 int x0, x1, y0, y1;
20230 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
20231 x1 += FRAME_X_RIGHT_FRINGE_WIDTH (f);
20232 y1 -= 1;
20234 rif->draw_vertical_window_border (w, x1, y0, y1);
20239 /* Redraw the part of window W intersection rectangle FR. Pixel
20240 coordinates in FR are frame-relative. Call this function with
20241 input blocked. Value is non-zero if the exposure overwrites
20242 mouse-face. */
20244 static int
20245 expose_window (w, fr)
20246 struct window *w;
20247 XRectangle *fr;
20249 struct frame *f = XFRAME (w->frame);
20250 XRectangle wr, r;
20251 int mouse_face_overwritten_p = 0;
20253 /* If window is not yet fully initialized, do nothing. This can
20254 happen when toolkit scroll bars are used and a window is split.
20255 Reconfiguring the scroll bar will generate an expose for a newly
20256 created window. */
20257 if (w->current_matrix == NULL)
20258 return 0;
20260 /* When we're currently updating the window, display and current
20261 matrix usually don't agree. Arrange for a thorough display
20262 later. */
20263 if (w == updated_window)
20265 SET_FRAME_GARBAGED (f);
20266 return 0;
20269 /* Frame-relative pixel rectangle of W. */
20270 wr.x = XFASTINT (w->left) * CANON_X_UNIT (f);
20271 wr.y = XFASTINT (w->top) * CANON_Y_UNIT (f);
20272 wr.width = XFASTINT (w->width) * CANON_X_UNIT (f);
20273 wr.height = XFASTINT (w->height) * CANON_Y_UNIT (f);
20275 if (x_intersect_rectangles (fr, &wr, &r))
20277 int yb = window_text_bottom_y (w);
20278 struct glyph_row *row;
20279 int cursor_cleared_p;
20280 struct glyph_row *first_overlapping_row, *last_overlapping_row;
20282 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
20283 r.x, r.y, r.width, r.height));
20285 /* Convert to window coordinates. */
20286 r.x = FRAME_TO_WINDOW_PIXEL_X (w, r.x);
20287 r.y = FRAME_TO_WINDOW_PIXEL_Y (w, r.y);
20289 /* Turn off the cursor. */
20290 if (!w->pseudo_window_p
20291 && phys_cursor_in_rect_p (w, &r))
20293 x_clear_cursor (w);
20294 cursor_cleared_p = 1;
20296 else
20297 cursor_cleared_p = 0;
20299 /* Update lines intersecting rectangle R. */
20300 first_overlapping_row = last_overlapping_row = NULL;
20301 for (row = w->current_matrix->rows;
20302 row->enabled_p;
20303 ++row)
20305 int y0 = row->y;
20306 int y1 = MATRIX_ROW_BOTTOM_Y (row);
20308 if ((y0 >= r.y && y0 < r.y + r.height)
20309 || (y1 > r.y && y1 < r.y + r.height)
20310 || (r.y >= y0 && r.y < y1)
20311 || (r.y + r.height > y0 && r.y + r.height < y1))
20313 if (row->overlapping_p)
20315 if (first_overlapping_row == NULL)
20316 first_overlapping_row = row;
20317 last_overlapping_row = row;
20320 if (expose_line (w, row, &r))
20321 mouse_face_overwritten_p = 1;
20324 if (y1 >= yb)
20325 break;
20328 /* Display the mode line if there is one. */
20329 if (WINDOW_WANTS_MODELINE_P (w)
20330 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
20331 row->enabled_p)
20332 && row->y < r.y + r.height)
20334 if (expose_line (w, row, &r))
20335 mouse_face_overwritten_p = 1;
20338 if (!w->pseudo_window_p)
20340 /* Fix the display of overlapping rows. */
20341 if (first_overlapping_row)
20342 expose_overlaps (w, first_overlapping_row, last_overlapping_row);
20344 /* Draw border between windows. */
20345 x_draw_vertical_border (w);
20347 /* Turn the cursor on again. */
20348 if (cursor_cleared_p)
20349 update_window_cursor (w, 1);
20353 #ifdef HAVE_CARBON
20354 /* Display scroll bar for this window. */
20355 if (!NILP (w->vertical_scroll_bar))
20357 /* ++KFS:
20358 If this doesn't work here (maybe some header files are missing),
20359 make a function in macterm.c and call it to do the job! */
20360 ControlHandle ch
20361 = SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (w->vertical_scroll_bar));
20363 Draw1Control (ch);
20365 #endif
20367 return mouse_face_overwritten_p;
20372 /* Redraw (parts) of all windows in the window tree rooted at W that
20373 intersect R. R contains frame pixel coordinates. Value is
20374 non-zero if the exposure overwrites mouse-face. */
20376 static int
20377 expose_window_tree (w, r)
20378 struct window *w;
20379 XRectangle *r;
20381 struct frame *f = XFRAME (w->frame);
20382 int mouse_face_overwritten_p = 0;
20384 while (w && !FRAME_GARBAGED_P (f))
20386 if (!NILP (w->hchild))
20387 mouse_face_overwritten_p
20388 |= expose_window_tree (XWINDOW (w->hchild), r);
20389 else if (!NILP (w->vchild))
20390 mouse_face_overwritten_p
20391 |= expose_window_tree (XWINDOW (w->vchild), r);
20392 else
20393 mouse_face_overwritten_p |= expose_window (w, r);
20395 w = NILP (w->next) ? NULL : XWINDOW (w->next);
20398 return mouse_face_overwritten_p;
20402 /* EXPORT:
20403 Redisplay an exposed area of frame F. X and Y are the upper-left
20404 corner of the exposed rectangle. W and H are width and height of
20405 the exposed area. All are pixel values. W or H zero means redraw
20406 the entire frame. */
20408 void
20409 expose_frame (f, x, y, w, h)
20410 struct frame *f;
20411 int x, y, w, h;
20413 XRectangle r;
20414 int mouse_face_overwritten_p = 0;
20416 TRACE ((stderr, "expose_frame "));
20418 /* No need to redraw if frame will be redrawn soon. */
20419 if (FRAME_GARBAGED_P (f))
20421 TRACE ((stderr, " garbaged\n"));
20422 return;
20425 #ifdef HAVE_CARBON
20426 /* MAC_TODO: this is a kludge, but if scroll bars are not activated
20427 or deactivated here, for unknown reasons, activated scroll bars
20428 are shown in deactivated frames in some instances. */
20429 if (f == FRAME_MAC_DISPLAY_INFO (f)->x_focus_frame)
20430 activate_scroll_bars (f);
20431 else
20432 deactivate_scroll_bars (f);
20433 #endif
20435 /* If basic faces haven't been realized yet, there is no point in
20436 trying to redraw anything. This can happen when we get an expose
20437 event while Emacs is starting, e.g. by moving another window. */
20438 if (FRAME_FACE_CACHE (f) == NULL
20439 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
20441 TRACE ((stderr, " no faces\n"));
20442 return;
20445 if (w == 0 || h == 0)
20447 r.x = r.y = 0;
20448 r.width = CANON_X_UNIT (f) * f->width;
20449 r.height = CANON_Y_UNIT (f) * f->height;
20451 else
20453 r.x = x;
20454 r.y = y;
20455 r.width = w;
20456 r.height = h;
20459 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
20460 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
20462 if (WINDOWP (f->tool_bar_window))
20463 mouse_face_overwritten_p
20464 |= expose_window (XWINDOW (f->tool_bar_window), &r);
20466 #ifdef HAVE_X_WINDOWS
20467 #ifndef MSDOS
20468 #ifndef USE_X_TOOLKIT
20469 if (WINDOWP (f->menu_bar_window))
20470 mouse_face_overwritten_p
20471 |= expose_window (XWINDOW (f->menu_bar_window), &r);
20472 #endif /* not USE_X_TOOLKIT */
20473 #endif
20474 #endif
20476 /* Some window managers support a focus-follows-mouse style with
20477 delayed raising of frames. Imagine a partially obscured frame,
20478 and moving the mouse into partially obscured mouse-face on that
20479 frame. The visible part of the mouse-face will be highlighted,
20480 then the WM raises the obscured frame. With at least one WM, KDE
20481 2.1, Emacs is not getting any event for the raising of the frame
20482 (even tried with SubstructureRedirectMask), only Expose events.
20483 These expose events will draw text normally, i.e. not
20484 highlighted. Which means we must redo the highlight here.
20485 Subsume it under ``we love X''. --gerd 2001-08-15 */
20486 /* Included in Windows version because Windows most likely does not
20487 do the right thing if any third party tool offers
20488 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
20489 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
20491 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
20492 if (f == dpyinfo->mouse_face_mouse_frame)
20494 int x = dpyinfo->mouse_face_mouse_x;
20495 int y = dpyinfo->mouse_face_mouse_y;
20496 clear_mouse_face (dpyinfo);
20497 note_mouse_highlight (f, x, y);
20503 /* EXPORT:
20504 Determine the intersection of two rectangles R1 and R2. Return
20505 the intersection in *RESULT. Value is non-zero if RESULT is not
20506 empty. */
20509 x_intersect_rectangles (r1, r2, result)
20510 XRectangle *r1, *r2, *result;
20512 XRectangle *left, *right;
20513 XRectangle *upper, *lower;
20514 int intersection_p = 0;
20516 /* Rearrange so that R1 is the left-most rectangle. */
20517 if (r1->x < r2->x)
20518 left = r1, right = r2;
20519 else
20520 left = r2, right = r1;
20522 /* X0 of the intersection is right.x0, if this is inside R1,
20523 otherwise there is no intersection. */
20524 if (right->x <= left->x + left->width)
20526 result->x = right->x;
20528 /* The right end of the intersection is the minimum of the
20529 the right ends of left and right. */
20530 result->width = (min (left->x + left->width, right->x + right->width)
20531 - result->x);
20533 /* Same game for Y. */
20534 if (r1->y < r2->y)
20535 upper = r1, lower = r2;
20536 else
20537 upper = r2, lower = r1;
20539 /* The upper end of the intersection is lower.y0, if this is inside
20540 of upper. Otherwise, there is no intersection. */
20541 if (lower->y <= upper->y + upper->height)
20543 result->y = lower->y;
20545 /* The lower end of the intersection is the minimum of the lower
20546 ends of upper and lower. */
20547 result->height = (min (lower->y + lower->height,
20548 upper->y + upper->height)
20549 - result->y);
20550 intersection_p = 1;
20554 return intersection_p;
20557 #endif /* HAVE_WINDOW_SYSTEM */
20560 /***********************************************************************
20561 Initialization
20562 ***********************************************************************/
20564 void
20565 syms_of_xdisp ()
20567 Vwith_echo_area_save_vector = Qnil;
20568 staticpro (&Vwith_echo_area_save_vector);
20570 Vmessage_stack = Qnil;
20571 staticpro (&Vmessage_stack);
20573 Qinhibit_redisplay = intern ("inhibit-redisplay");
20574 staticpro (&Qinhibit_redisplay);
20576 message_dolog_marker1 = Fmake_marker ();
20577 staticpro (&message_dolog_marker1);
20578 message_dolog_marker2 = Fmake_marker ();
20579 staticpro (&message_dolog_marker2);
20580 message_dolog_marker3 = Fmake_marker ();
20581 staticpro (&message_dolog_marker3);
20583 #if GLYPH_DEBUG
20584 defsubr (&Sdump_frame_glyph_matrix);
20585 defsubr (&Sdump_glyph_matrix);
20586 defsubr (&Sdump_glyph_row);
20587 defsubr (&Sdump_tool_bar_row);
20588 defsubr (&Strace_redisplay);
20589 defsubr (&Strace_to_stderr);
20590 #endif
20591 #ifdef HAVE_WINDOW_SYSTEM
20592 defsubr (&Stool_bar_lines_needed);
20593 #endif
20594 defsubr (&Sformat_mode_line);
20596 staticpro (&Qmenu_bar_update_hook);
20597 Qmenu_bar_update_hook = intern ("menu-bar-update-hook");
20599 staticpro (&Qoverriding_terminal_local_map);
20600 Qoverriding_terminal_local_map = intern ("overriding-terminal-local-map");
20602 staticpro (&Qoverriding_local_map);
20603 Qoverriding_local_map = intern ("overriding-local-map");
20605 staticpro (&Qwindow_scroll_functions);
20606 Qwindow_scroll_functions = intern ("window-scroll-functions");
20608 staticpro (&Qredisplay_end_trigger_functions);
20609 Qredisplay_end_trigger_functions = intern ("redisplay-end-trigger-functions");
20611 staticpro (&Qinhibit_point_motion_hooks);
20612 Qinhibit_point_motion_hooks = intern ("inhibit-point-motion-hooks");
20614 QCdata = intern (":data");
20615 staticpro (&QCdata);
20616 Qdisplay = intern ("display");
20617 staticpro (&Qdisplay);
20618 Qspace_width = intern ("space-width");
20619 staticpro (&Qspace_width);
20620 Qraise = intern ("raise");
20621 staticpro (&Qraise);
20622 Qspace = intern ("space");
20623 staticpro (&Qspace);
20624 Qmargin = intern ("margin");
20625 staticpro (&Qmargin);
20626 Qleft_margin = intern ("left-margin");
20627 staticpro (&Qleft_margin);
20628 Qright_margin = intern ("right-margin");
20629 staticpro (&Qright_margin);
20630 Qalign_to = intern ("align-to");
20631 staticpro (&Qalign_to);
20632 QCalign_to = intern (":align-to");
20633 staticpro (&QCalign_to);
20634 Qrelative_width = intern ("relative-width");
20635 staticpro (&Qrelative_width);
20636 QCrelative_width = intern (":relative-width");
20637 staticpro (&QCrelative_width);
20638 QCrelative_height = intern (":relative-height");
20639 staticpro (&QCrelative_height);
20640 QCeval = intern (":eval");
20641 staticpro (&QCeval);
20642 QCpropertize = intern (":propertize");
20643 staticpro (&QCpropertize);
20644 QCfile = intern (":file");
20645 staticpro (&QCfile);
20646 Qfontified = intern ("fontified");
20647 staticpro (&Qfontified);
20648 Qfontification_functions = intern ("fontification-functions");
20649 staticpro (&Qfontification_functions);
20650 Qtrailing_whitespace = intern ("trailing-whitespace");
20651 staticpro (&Qtrailing_whitespace);
20652 Qimage = intern ("image");
20653 staticpro (&Qimage);
20654 Qmessage_truncate_lines = intern ("message-truncate-lines");
20655 staticpro (&Qmessage_truncate_lines);
20656 Qcursor_in_non_selected_windows = intern ("cursor-in-non-selected-windows");
20657 staticpro (&Qcursor_in_non_selected_windows);
20658 Qgrow_only = intern ("grow-only");
20659 staticpro (&Qgrow_only);
20660 Qinhibit_menubar_update = intern ("inhibit-menubar-update");
20661 staticpro (&Qinhibit_menubar_update);
20662 Qinhibit_eval_during_redisplay = intern ("inhibit-eval-during-redisplay");
20663 staticpro (&Qinhibit_eval_during_redisplay);
20664 Qposition = intern ("position");
20665 staticpro (&Qposition);
20666 Qbuffer_position = intern ("buffer-position");
20667 staticpro (&Qbuffer_position);
20668 Qobject = intern ("object");
20669 staticpro (&Qobject);
20670 Qbar = intern ("bar");
20671 staticpro (&Qbar);
20672 Qhbar = intern ("hbar");
20673 staticpro (&Qhbar);
20674 Qbox = intern ("box");
20675 staticpro (&Qbox);
20676 Qhollow = intern ("hollow");
20677 staticpro (&Qhollow);
20678 Qrisky_local_variable = intern ("risky-local-variable");
20679 staticpro (&Qrisky_local_variable);
20680 Qinhibit_free_realized_faces = intern ("inhibit-free-realized-faces");
20681 staticpro (&Qinhibit_free_realized_faces);
20683 list_of_error = Fcons (intern ("error"), Qnil);
20684 staticpro (&list_of_error);
20686 last_arrow_position = Qnil;
20687 last_arrow_string = Qnil;
20688 staticpro (&last_arrow_position);
20689 staticpro (&last_arrow_string);
20691 echo_buffer[0] = echo_buffer[1] = Qnil;
20692 staticpro (&echo_buffer[0]);
20693 staticpro (&echo_buffer[1]);
20695 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
20696 staticpro (&echo_area_buffer[0]);
20697 staticpro (&echo_area_buffer[1]);
20699 Vmessages_buffer_name = build_string ("*Messages*");
20700 staticpro (&Vmessages_buffer_name);
20702 mode_line_proptrans_alist = Qnil;
20703 staticpro (&mode_line_proptrans_alist);
20705 mode_line_string_list = Qnil;
20706 staticpro (&mode_line_string_list);
20708 help_echo_string = Qnil;
20709 staticpro (&help_echo_string);
20710 help_echo_object = Qnil;
20711 staticpro (&help_echo_object);
20712 help_echo_window = Qnil;
20713 staticpro (&help_echo_window);
20714 previous_help_echo_string = Qnil;
20715 staticpro (&previous_help_echo_string);
20716 help_echo_pos = -1;
20718 #ifdef HAVE_WINDOW_SYSTEM
20719 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p,
20720 doc: /* *Non-nil means draw block cursor as wide as the glyph under it.
20721 For example, if a block cursor is over a tab, it will be drawn as
20722 wide as that tab on the display. */);
20723 x_stretch_cursor_p = 0;
20724 #endif
20726 DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace,
20727 doc: /* Non-nil means highlight trailing whitespace.
20728 The face used for trailing whitespace is `trailing-whitespace'. */);
20729 Vshow_trailing_whitespace = Qnil;
20731 DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay,
20732 doc: /* Non-nil means don't actually do any redisplay.
20733 This is used for internal purposes. */);
20734 Vinhibit_redisplay = Qnil;
20736 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string,
20737 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
20738 Vglobal_mode_string = Qnil;
20740 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position,
20741 doc: /* Marker for where to display an arrow on top of the buffer text.
20742 This must be the beginning of a line in order to work.
20743 See also `overlay-arrow-string'. */);
20744 Voverlay_arrow_position = Qnil;
20746 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string,
20747 doc: /* String to display as an arrow. See also `overlay-arrow-position'. */);
20748 Voverlay_arrow_string = Qnil;
20750 DEFVAR_INT ("scroll-step", &scroll_step,
20751 doc: /* *The number of lines to try scrolling a window by when point moves out.
20752 If that fails to bring point back on frame, point is centered instead.
20753 If this is zero, point is always centered after it moves off frame.
20754 If you want scrolling to always be a line at a time, you should set
20755 `scroll-conservatively' to a large value rather than set this to 1. */);
20757 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively,
20758 doc: /* *Scroll up to this many lines, to bring point back on screen.
20759 A value of zero means to scroll the text to center point vertically
20760 in the window. */);
20761 scroll_conservatively = 0;
20763 DEFVAR_INT ("scroll-margin", &scroll_margin,
20764 doc: /* *Number of lines of margin at the top and bottom of a window.
20765 Recenter the window whenever point gets within this many lines
20766 of the top or bottom of the window. */);
20767 scroll_margin = 0;
20769 #if GLYPH_DEBUG
20770 DEFVAR_INT ("debug-end-pos", &debug_end_pos, doc: /* Don't ask. */);
20771 #endif
20773 DEFVAR_BOOL ("truncate-partial-width-windows",
20774 &truncate_partial_width_windows,
20775 doc: /* *Non-nil means truncate lines in all windows less than full frame wide. */);
20776 truncate_partial_width_windows = 1;
20778 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video,
20779 doc: /* nil means display the mode-line/header-line/menu-bar in the default face.
20780 Any other value means to use the appropriate face, `mode-line',
20781 `header-line', or `menu' respectively. */);
20782 mode_line_inverse_video = 1;
20784 DEFVAR_LISP ("line-number-display-limit", &Vline_number_display_limit,
20785 doc: /* *Maximum buffer size for which line number should be displayed.
20786 If the buffer is bigger than this, the line number does not appear
20787 in the mode line. A value of nil means no limit. */);
20788 Vline_number_display_limit = Qnil;
20790 DEFVAR_INT ("line-number-display-limit-width",
20791 &line_number_display_limit_width,
20792 doc: /* *Maximum line width (in characters) for line number display.
20793 If the average length of the lines near point is bigger than this, then the
20794 line number may be omitted from the mode line. */);
20795 line_number_display_limit_width = 200;
20797 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows,
20798 doc: /* *Non-nil means highlight region even in nonselected windows. */);
20799 highlight_nonselected_windows = 0;
20801 DEFVAR_BOOL ("multiple-frames", &multiple_frames,
20802 doc: /* Non-nil if more than one frame is visible on this display.
20803 Minibuffer-only frames don't count, but iconified frames do.
20804 This variable is not guaranteed to be accurate except while processing
20805 `frame-title-format' and `icon-title-format'. */);
20807 DEFVAR_LISP ("frame-title-format", &Vframe_title_format,
20808 doc: /* Template for displaying the title bar of visible frames.
20809 \(Assuming the window manager supports this feature.)
20810 This variable has the same structure as `mode-line-format' (which see),
20811 and is used only on frames for which no explicit name has been set
20812 \(see `modify-frame-parameters'). */);
20813 DEFVAR_LISP ("icon-title-format", &Vicon_title_format,
20814 doc: /* Template for displaying the title bar of an iconified frame.
20815 \(Assuming the window manager supports this feature.)
20816 This variable has the same structure as `mode-line-format' (which see),
20817 and is used only on frames for which no explicit name has been set
20818 \(see `modify-frame-parameters'). */);
20819 Vicon_title_format
20820 = Vframe_title_format
20821 = Fcons (intern ("multiple-frames"),
20822 Fcons (build_string ("%b"),
20823 Fcons (Fcons (empty_string,
20824 Fcons (intern ("invocation-name"),
20825 Fcons (build_string ("@"),
20826 Fcons (intern ("system-name"),
20827 Qnil)))),
20828 Qnil)));
20830 DEFVAR_LISP ("message-log-max", &Vmessage_log_max,
20831 doc: /* Maximum number of lines to keep in the message log buffer.
20832 If nil, disable message logging. If t, log messages but don't truncate
20833 the buffer when it becomes large. */);
20834 Vmessage_log_max = make_number (50);
20836 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions,
20837 doc: /* Functions called before redisplay, if window sizes have changed.
20838 The value should be a list of functions that take one argument.
20839 Just before redisplay, for each frame, if any of its windows have changed
20840 size since the last redisplay, or have been split or deleted,
20841 all the functions in the list are called, with the frame as argument. */);
20842 Vwindow_size_change_functions = Qnil;
20844 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions,
20845 doc: /* List of Functions to call before redisplaying a window with scrolling.
20846 Each function is called with two arguments, the window
20847 and its new display-start position. Note that the value of `window-end'
20848 is not valid when these functions are called. */);
20849 Vwindow_scroll_functions = Qnil;
20851 DEFVAR_BOOL ("mouse-autoselect-window", &mouse_autoselect_window,
20852 doc: /* *Non-nil means autoselect window with mouse pointer. */);
20853 mouse_autoselect_window = 0;
20855 DEFVAR_BOOL ("auto-resize-tool-bars", &auto_resize_tool_bars_p,
20856 doc: /* *Non-nil means automatically resize tool-bars.
20857 This increases a tool-bar's height if not all tool-bar items are visible.
20858 It decreases a tool-bar's height when it would display blank lines
20859 otherwise. */);
20860 auto_resize_tool_bars_p = 1;
20862 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", &auto_raise_tool_bar_buttons_p,
20863 doc: /* *Non-nil means raise tool-bar buttons when the mouse moves over them. */);
20864 auto_raise_tool_bar_buttons_p = 1;
20866 DEFVAR_LISP ("tool-bar-button-margin", &Vtool_bar_button_margin,
20867 doc: /* *Margin around tool-bar buttons in pixels.
20868 If an integer, use that for both horizontal and vertical margins.
20869 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
20870 HORZ specifying the horizontal margin, and VERT specifying the
20871 vertical margin. */);
20872 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
20874 DEFVAR_INT ("tool-bar-button-relief", &tool_bar_button_relief,
20875 doc: /* *Relief thickness of tool-bar buttons. */);
20876 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
20878 DEFVAR_LISP ("fontification-functions", &Vfontification_functions,
20879 doc: /* List of functions to call to fontify regions of text.
20880 Each function is called with one argument POS. Functions must
20881 fontify a region starting at POS in the current buffer, and give
20882 fontified regions the property `fontified'. */);
20883 Vfontification_functions = Qnil;
20884 Fmake_variable_buffer_local (Qfontification_functions);
20886 DEFVAR_BOOL ("unibyte-display-via-language-environment",
20887 &unibyte_display_via_language_environment,
20888 doc: /* *Non-nil means display unibyte text according to language environment.
20889 Specifically this means that unibyte non-ASCII characters
20890 are displayed by converting them to the equivalent multibyte characters
20891 according to the current language environment. As a result, they are
20892 displayed according to the current fontset. */);
20893 unibyte_display_via_language_environment = 0;
20895 DEFVAR_LISP ("max-mini-window-height", &Vmax_mini_window_height,
20896 doc: /* *Maximum height for resizing mini-windows.
20897 If a float, it specifies a fraction of the mini-window frame's height.
20898 If an integer, it specifies a number of lines. */);
20899 Vmax_mini_window_height = make_float (0.25);
20901 DEFVAR_LISP ("resize-mini-windows", &Vresize_mini_windows,
20902 doc: /* *How to resize mini-windows.
20903 A value of nil means don't automatically resize mini-windows.
20904 A value of t means resize them to fit the text displayed in them.
20905 A value of `grow-only', the default, means let mini-windows grow
20906 only, until their display becomes empty, at which point the windows
20907 go back to their normal size. */);
20908 Vresize_mini_windows = Qgrow_only;
20910 DEFVAR_LISP ("cursor-in-non-selected-windows",
20911 &Vcursor_in_non_selected_windows,
20912 doc: /* *Cursor type to display in non-selected windows.
20913 t means to use hollow box cursor. See `cursor-type' for other values. */);
20914 Vcursor_in_non_selected_windows = Qt;
20916 DEFVAR_LISP ("blink-cursor-alist", &Vblink_cursor_alist,
20917 doc: /* Alist specifying how to blink the cursor off.
20918 Each element has the form (ON-STATE . OFF-STATE). Whenever the
20919 `cursor-type' frame-parameter or variable equals ON-STATE,
20920 comparing using `equal', Emacs uses OFF-STATE to specify
20921 how to blink it off. */);
20922 Vblink_cursor_alist = Qnil;
20924 DEFVAR_BOOL ("auto-hscroll-mode", &automatic_hscrolling_p,
20925 doc: /* *Non-nil means scroll the display automatically to make point visible. */);
20926 automatic_hscrolling_p = 1;
20928 DEFVAR_INT ("hscroll-margin", &hscroll_margin,
20929 doc: /* *How many columns away from the window edge point is allowed to get
20930 before automatic hscrolling will horizontally scroll the window. */);
20931 hscroll_margin = 5;
20933 DEFVAR_LISP ("hscroll-step", &Vhscroll_step,
20934 doc: /* *How many columns to scroll the window when point gets too close to the edge.
20935 When point is less than `automatic-hscroll-margin' columns from the window
20936 edge, automatic hscrolling will scroll the window by the amount of columns
20937 determined by this variable. If its value is a positive integer, scroll that
20938 many columns. If it's a positive floating-point number, it specifies the
20939 fraction of the window's width to scroll. If it's nil or zero, point will be
20940 centered horizontally after the scroll. Any other value, including negative
20941 numbers, are treated as if the value were zero.
20943 Automatic hscrolling always moves point outside the scroll margin, so if
20944 point was more than scroll step columns inside the margin, the window will
20945 scroll more than the value given by the scroll step.
20947 Note that the lower bound for automatic hscrolling specified by `scroll-left'
20948 and `scroll-right' overrides this variable's effect. */);
20949 Vhscroll_step = make_number (0);
20951 DEFVAR_LISP ("image-types", &Vimage_types,
20952 doc: /* List of supported image types.
20953 Each element of the list is a symbol for a supported image type. */);
20954 Vimage_types = Qnil;
20956 DEFVAR_BOOL ("message-truncate-lines", &message_truncate_lines,
20957 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
20958 Bind this around calls to `message' to let it take effect. */);
20959 message_truncate_lines = 0;
20961 DEFVAR_LISP ("menu-bar-update-hook", &Vmenu_bar_update_hook,
20962 doc: /* Normal hook run for clicks on menu bar, before displaying a submenu.
20963 Can be used to update submenus whose contents should vary. */);
20964 Vmenu_bar_update_hook = Qnil;
20966 DEFVAR_BOOL ("inhibit-menubar-update", &inhibit_menubar_update,
20967 doc: /* Non-nil means don't update menu bars. Internal use only. */);
20968 inhibit_menubar_update = 0;
20970 DEFVAR_BOOL ("inhibit-eval-during-redisplay", &inhibit_eval_during_redisplay,
20971 doc: /* Non-nil means don't eval Lisp during redisplay. */);
20972 inhibit_eval_during_redisplay = 0;
20974 DEFVAR_BOOL ("inhibit-free-realized-faces", &inhibit_free_realized_faces,
20975 doc: /* Non-nil means don't free realized faces. Internal use only. */);
20976 inhibit_free_realized_faces = 0;
20978 #if GLYPH_DEBUG
20979 DEFVAR_BOOL ("inhibit-try-window-id", &inhibit_try_window_id,
20980 doc: /* Inhibit try_window_id display optimization. */);
20981 inhibit_try_window_id = 0;
20983 DEFVAR_BOOL ("inhibit-try-window-reusing", &inhibit_try_window_reusing,
20984 doc: /* Inhibit try_window_reusing display optimization. */);
20985 inhibit_try_window_reusing = 0;
20987 DEFVAR_BOOL ("inhibit-try-cursor-movement", &inhibit_try_cursor_movement,
20988 doc: /* Inhibit try_cursor_movement display optimization. */);
20989 inhibit_try_cursor_movement = 0;
20990 #endif /* GLYPH_DEBUG */
20994 /* Initialize this module when Emacs starts. */
20996 void
20997 init_xdisp ()
20999 Lisp_Object root_window;
21000 struct window *mini_w;
21002 current_header_line_height = current_mode_line_height = -1;
21004 CHARPOS (this_line_start_pos) = 0;
21006 mini_w = XWINDOW (minibuf_window);
21007 root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w)));
21009 if (!noninteractive)
21011 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (root_window)));
21012 int i;
21014 XWINDOW (root_window)->top = make_number (FRAME_TOP_MARGIN (f));
21015 set_window_height (root_window,
21016 FRAME_HEIGHT (f) - 1 - FRAME_TOP_MARGIN (f),
21018 mini_w->top = make_number (FRAME_HEIGHT (f) - 1);
21019 set_window_height (minibuf_window, 1, 0);
21021 XWINDOW (root_window)->width = make_number (FRAME_WIDTH (f));
21022 mini_w->width = make_number (FRAME_WIDTH (f));
21024 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
21025 scratch_glyph_row.glyphs[TEXT_AREA + 1]
21026 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
21028 /* The default ellipsis glyphs `...'. */
21029 for (i = 0; i < 3; ++i)
21030 default_invis_vector[i] = make_number ('.');
21034 /* Allocate the buffer for frame titles.
21035 Also used for `format-mode-line'. */
21036 int size = 100;
21037 frame_title_buf = (char *) xmalloc (size);
21038 frame_title_buf_end = frame_title_buf + size;
21039 frame_title_ptr = NULL;
21042 help_echo_showing_p = 0;