Update copyright. Update commentary to mention rx syntax support.
[emacs.git] / src / xdisp.c
bloba7802d5321b7474ee675804240d401ace0cb10dd
1 /* Display generation from window structure and buffer text.
2 Copyright (C) 1985,86,87,88,93,94,95,97,98,99,2000,01,02,03,04
3 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
22 /* New redisplay written by Gerd Moellmann <gerd@gnu.org>.
24 Redisplay.
26 Emacs separates the task of updating the display from code
27 modifying global state, e.g. buffer text. This way functions
28 operating on buffers don't also have to be concerned with updating
29 the display.
31 Updating the display is triggered by the Lisp interpreter when it
32 decides it's time to do it. This is done either automatically for
33 you as part of the interpreter's command loop or as the result of
34 calling Lisp functions like `sit-for'. The C function `redisplay'
35 in xdisp.c is the only entry into the inner redisplay code. (Or,
36 let's say almost---see the description of direct update
37 operations, below.)
39 The following diagram shows how redisplay code is invoked. As you
40 can see, Lisp calls redisplay and vice versa. Under window systems
41 like X, some portions of the redisplay code are also called
42 asynchronously during mouse movement or expose events. It is very
43 important that these code parts do NOT use the C library (malloc,
44 free) because many C libraries under Unix are not reentrant. They
45 may also NOT call functions of the Lisp interpreter which could
46 change the interpreter's state. If you don't follow these rules,
47 you will encounter bugs which are very hard to explain.
49 (Direct functions, see below)
50 direct_output_for_insert,
51 direct_forward_char (dispnew.c)
52 +---------------------------------+
53 | |
54 | V
55 +--------------+ redisplay +----------------+
56 | Lisp machine |---------------->| Redisplay code |<--+
57 +--------------+ (xdisp.c) +----------------+ |
58 ^ | |
59 +----------------------------------+ |
60 Don't use this path when called |
61 asynchronously! |
63 expose_window (asynchronous) |
65 X expose events -----+
67 What does redisplay do? Obviously, it has to figure out somehow what
68 has been changed since the last time the display has been updated,
69 and to make these changes visible. Preferably it would do that in
70 a moderately intelligent way, i.e. fast.
72 Changes in buffer text can be deduced from window and buffer
73 structures, and from some global variables like `beg_unchanged' and
74 `end_unchanged'. The contents of the display are additionally
75 recorded in a `glyph matrix', a two-dimensional matrix of glyph
76 structures. Each row in such a matrix corresponds to a line on the
77 display, and each glyph in a row corresponds to a column displaying
78 a character, an image, or what else. This matrix is called the
79 `current glyph matrix' or `current matrix' in redisplay
80 terminology.
82 For buffer parts that have been changed since the last update, a
83 second glyph matrix is constructed, the so called `desired glyph
84 matrix' or short `desired matrix'. Current and desired matrix are
85 then compared to find a cheap way to update the display, e.g. by
86 reusing part of the display by scrolling lines.
89 Direct operations.
91 You will find a lot of redisplay optimizations when you start
92 looking at the innards of redisplay. The overall goal of all these
93 optimizations is to make redisplay fast because it is done
94 frequently.
96 Two optimizations are not found in xdisp.c. These are the direct
97 operations mentioned above. As the name suggests they follow a
98 different principle than the rest of redisplay. Instead of
99 building a desired matrix and then comparing it with the current
100 display, they perform their actions directly on the display and on
101 the current matrix.
103 One direct operation updates the display after one character has
104 been entered. The other one moves the cursor by one position
105 forward or backward. You find these functions under the names
106 `direct_output_for_insert' and `direct_output_forward_char' in
107 dispnew.c.
110 Desired matrices.
112 Desired matrices are always built per Emacs window. The function
113 `display_line' is the central function to look at if you are
114 interested. It constructs one row in a desired matrix given an
115 iterator structure containing both a buffer position and a
116 description of the environment in which the text is to be
117 displayed. But this is too early, read on.
119 Characters and pixmaps displayed for a range of buffer text depend
120 on various settings of buffers and windows, on overlays and text
121 properties, on display tables, on selective display. The good news
122 is that all this hairy stuff is hidden behind a small set of
123 interface functions taking an iterator structure (struct it)
124 argument.
126 Iteration over things to be displayed is then simple. It is
127 started by initializing an iterator with a call to init_iterator.
128 Calls to get_next_display_element fill the iterator structure with
129 relevant information about the next thing to display. Calls to
130 set_iterator_to_next move the iterator to the next thing.
132 Besides this, an iterator also contains information about the
133 display environment in which glyphs for display elements are to be
134 produced. It has fields for the width and height of the display,
135 the information whether long lines are truncated or continued, a
136 current X and Y position, and lots of other stuff you can better
137 see in dispextern.h.
139 Glyphs in a desired matrix are normally constructed in a loop
140 calling get_next_display_element and then produce_glyphs. The call
141 to produce_glyphs will fill the iterator structure with pixel
142 information about the element being displayed and at the same time
143 produce glyphs for it. If the display element fits on the line
144 being displayed, set_iterator_to_next is called next, otherwise the
145 glyphs produced are discarded.
148 Frame matrices.
150 That just couldn't be all, could it? What about terminal types not
151 supporting operations on sub-windows of the screen? To update the
152 display on such a terminal, window-based glyph matrices are not
153 well suited. To be able to reuse part of the display (scrolling
154 lines up and down), we must instead have a view of the whole
155 screen. This is what `frame matrices' are for. They are a trick.
157 Frames on terminals like above have a glyph pool. Windows on such
158 a frame sub-allocate their glyph memory from their frame's glyph
159 pool. The frame itself is given its own glyph matrices. By
160 coincidence---or maybe something else---rows in window glyph
161 matrices are slices of corresponding rows in frame matrices. Thus
162 writing to window matrices implicitly updates a frame matrix which
163 provides us with the view of the whole screen that we originally
164 wanted to have without having to move many bytes around. To be
165 honest, there is a little bit more done, but not much more. If you
166 plan to extend that code, take a look at dispnew.c. The function
167 build_frame_matrix is a good starting point. */
169 #include <config.h>
170 #include <stdio.h>
172 #include "lisp.h"
173 #include "keyboard.h"
174 #include "frame.h"
175 #include "window.h"
176 #include "termchar.h"
177 #include "dispextern.h"
178 #include "buffer.h"
179 #include "charset.h"
180 #include "indent.h"
181 #include "commands.h"
182 #include "keymap.h"
183 #include "macros.h"
184 #include "disptab.h"
185 #include "termhooks.h"
186 #include "intervals.h"
187 #include "coding.h"
188 #include "process.h"
189 #include "region-cache.h"
190 #include "fontset.h"
191 #include "blockinput.h"
193 #ifdef HAVE_X_WINDOWS
194 #include "xterm.h"
195 #endif
196 #ifdef WINDOWSNT
197 #include "w32term.h"
198 #endif
199 #ifdef MAC_OS
200 #include "macterm.h"
201 #endif
203 #ifndef FRAME_X_OUTPUT
204 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
205 #endif
207 #define INFINITY 10000000
209 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
210 || defined (USE_GTK)
211 extern void set_frame_menubar P_ ((struct frame *f, int, int));
212 extern int pending_menu_activation;
213 #endif
215 extern int interrupt_input;
216 extern int command_loop_level;
218 extern Lisp_Object do_mouse_tracking;
220 extern int minibuffer_auto_raise;
221 extern Lisp_Object Vminibuffer_list;
223 extern Lisp_Object Qface;
224 extern Lisp_Object Qmode_line, Qmode_line_inactive, Qheader_line;
226 extern Lisp_Object Voverriding_local_map;
227 extern Lisp_Object Voverriding_local_map_menu_flag;
228 extern Lisp_Object Qmenu_item;
229 extern Lisp_Object Qwhen;
230 extern Lisp_Object Qhelp_echo;
232 Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
233 Lisp_Object Qwindow_scroll_functions, Vwindow_scroll_functions;
234 Lisp_Object Qredisplay_end_trigger_functions;
235 Lisp_Object Qinhibit_point_motion_hooks;
236 Lisp_Object QCeval, QCfile, QCdata, QCpropertize;
237 Lisp_Object Qfontified;
238 Lisp_Object Qgrow_only;
239 Lisp_Object Qinhibit_eval_during_redisplay;
240 Lisp_Object Qbuffer_position, Qposition, Qobject;
242 /* Cursor shapes */
243 Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
245 /* Pointer shapes */
246 Lisp_Object Qarrow, Qhand, Qtext;
248 Lisp_Object Qrisky_local_variable;
250 /* Holds the list (error). */
251 Lisp_Object list_of_error;
253 /* Functions called to fontify regions of text. */
255 Lisp_Object Vfontification_functions;
256 Lisp_Object Qfontification_functions;
258 /* Non-zero means automatically select any window when the mouse
259 cursor moves into it. */
260 int mouse_autoselect_window;
262 /* Non-zero means draw tool bar buttons raised when the mouse moves
263 over them. */
265 int auto_raise_tool_bar_buttons_p;
267 /* Non-zero means to reposition window if cursor line is only partially visible. */
269 int make_cursor_line_fully_visible_p;
271 /* Margin around tool bar buttons in pixels. */
273 Lisp_Object Vtool_bar_button_margin;
275 /* Thickness of shadow to draw around tool bar buttons. */
277 EMACS_INT tool_bar_button_relief;
279 /* Non-zero means automatically resize tool-bars so that all tool-bar
280 items are visible, and no blank lines remain. */
282 int auto_resize_tool_bars_p;
284 /* Non-zero means draw block and hollow cursor as wide as the glyph
285 under it. For example, if a block cursor is over a tab, it will be
286 drawn as wide as that tab on the display. */
288 int x_stretch_cursor_p;
290 /* Non-nil means don't actually do any redisplay. */
292 Lisp_Object Vinhibit_redisplay, Qinhibit_redisplay;
294 /* Non-zero means Lisp evaluation during redisplay is inhibited. */
296 int inhibit_eval_during_redisplay;
298 /* Names of text properties relevant for redisplay. */
300 Lisp_Object Qdisplay;
301 extern Lisp_Object Qface, Qinvisible, Qwidth;
303 /* Symbols used in text property values. */
305 Lisp_Object Vdisplay_pixels_per_inch;
306 Lisp_Object Qspace, QCalign_to, QCrelative_width, QCrelative_height;
307 Lisp_Object Qleft_margin, Qright_margin, Qspace_width, Qraise;
308 Lisp_Object Qslice;
309 Lisp_Object Qcenter;
310 Lisp_Object Qmargin, Qpointer;
311 Lisp_Object Qline_height;
312 extern Lisp_Object Qheight;
313 extern Lisp_Object QCwidth, QCheight, QCascent;
314 extern Lisp_Object Qscroll_bar;
315 extern Lisp_Object Qcursor;
317 /* Non-nil means highlight trailing whitespace. */
319 Lisp_Object Vshow_trailing_whitespace;
321 #ifdef HAVE_WINDOW_SYSTEM
322 extern Lisp_Object Voverflow_newline_into_fringe;
324 /* Test if overflow newline into fringe. Called with iterator IT
325 at or past right window margin, and with IT->current_x set. */
327 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) \
328 (!NILP (Voverflow_newline_into_fringe) \
329 && FRAME_WINDOW_P (it->f) \
330 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) > 0 \
331 && it->current_x == it->last_visible_x)
333 #endif /* HAVE_WINDOW_SYSTEM */
335 /* Non-nil means show the text cursor in void text areas
336 i.e. in blank areas after eol and eob. This used to be
337 the default in 21.3. */
339 Lisp_Object Vvoid_text_area_pointer;
341 /* Name of the face used to highlight trailing whitespace. */
343 Lisp_Object Qtrailing_whitespace;
345 /* Name and number of the face used to highlight escape glyphs. */
347 Lisp_Object Qescape_glyph;
348 int escape_glyph_face;
350 /* The symbol `image' which is the car of the lists used to represent
351 images in Lisp. */
353 Lisp_Object Qimage;
355 /* The image map types. */
356 Lisp_Object QCmap, QCpointer;
357 Lisp_Object Qrect, Qcircle, Qpoly;
359 /* Non-zero means print newline to stdout before next mini-buffer
360 message. */
362 int noninteractive_need_newline;
364 /* Non-zero means print newline to message log before next message. */
366 static int message_log_need_newline;
368 /* Three markers that message_dolog uses.
369 It could allocate them itself, but that causes trouble
370 in handling memory-full errors. */
371 static Lisp_Object message_dolog_marker1;
372 static Lisp_Object message_dolog_marker2;
373 static Lisp_Object message_dolog_marker3;
375 /* The buffer position of the first character appearing entirely or
376 partially on the line of the selected window which contains the
377 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
378 redisplay optimization in redisplay_internal. */
380 static struct text_pos this_line_start_pos;
382 /* Number of characters past the end of the line above, including the
383 terminating newline. */
385 static struct text_pos this_line_end_pos;
387 /* The vertical positions and the height of this line. */
389 static int this_line_vpos;
390 static int this_line_y;
391 static int this_line_pixel_height;
393 /* X position at which this display line starts. Usually zero;
394 negative if first character is partially visible. */
396 static int this_line_start_x;
398 /* Buffer that this_line_.* variables are referring to. */
400 static struct buffer *this_line_buffer;
402 /* Nonzero means truncate lines in all windows less wide than the
403 frame. */
405 int truncate_partial_width_windows;
407 /* A flag to control how to display unibyte 8-bit character. */
409 int unibyte_display_via_language_environment;
411 /* Nonzero means we have more than one non-mini-buffer-only frame.
412 Not guaranteed to be accurate except while parsing
413 frame-title-format. */
415 int multiple_frames;
417 Lisp_Object Vglobal_mode_string;
420 /* List of variables (symbols) which hold markers for overlay arrows.
421 The symbols on this list are examined during redisplay to determine
422 where to display overlay arrows. */
424 Lisp_Object Voverlay_arrow_variable_list;
426 /* Marker for where to display an arrow on top of the buffer text. */
428 Lisp_Object Voverlay_arrow_position;
430 /* String to display for the arrow. Only used on terminal frames. */
432 Lisp_Object Voverlay_arrow_string;
434 /* Values of those variables at last redisplay are stored as
435 properties on `overlay-arrow-position' symbol. However, if
436 Voverlay_arrow_position is a marker, last-arrow-position is its
437 numerical position. */
439 Lisp_Object Qlast_arrow_position, Qlast_arrow_string;
441 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
442 properties on a symbol in overlay-arrow-variable-list. */
444 Lisp_Object Qoverlay_arrow_string, Qoverlay_arrow_bitmap;
446 /* Like mode-line-format, but for the title bar on a visible frame. */
448 Lisp_Object Vframe_title_format;
450 /* Like mode-line-format, but for the title bar on an iconified frame. */
452 Lisp_Object Vicon_title_format;
454 /* List of functions to call when a window's size changes. These
455 functions get one arg, a frame on which one or more windows' sizes
456 have changed. */
458 static Lisp_Object Vwindow_size_change_functions;
460 Lisp_Object Qmenu_bar_update_hook, Vmenu_bar_update_hook;
462 /* Nonzero if overlay arrow has been displayed once in this window. */
464 static int overlay_arrow_seen;
466 /* Nonzero means highlight the region even in nonselected windows. */
468 int highlight_nonselected_windows;
470 /* If cursor motion alone moves point off frame, try scrolling this
471 many lines up or down if that will bring it back. */
473 static EMACS_INT scroll_step;
475 /* Nonzero means scroll just far enough to bring point back on the
476 screen, when appropriate. */
478 static EMACS_INT scroll_conservatively;
480 /* Recenter the window whenever point gets within this many lines of
481 the top or bottom of the window. This value is translated into a
482 pixel value by multiplying it with FRAME_LINE_HEIGHT, which means
483 that there is really a fixed pixel height scroll margin. */
485 EMACS_INT scroll_margin;
487 /* Number of windows showing the buffer of the selected window (or
488 another buffer with the same base buffer). keyboard.c refers to
489 this. */
491 int buffer_shared;
493 /* Vector containing glyphs for an ellipsis `...'. */
495 static Lisp_Object default_invis_vector[3];
497 /* Zero means display the mode-line/header-line/menu-bar in the default face
498 (this slightly odd definition is for compatibility with previous versions
499 of emacs), non-zero means display them using their respective faces.
501 This variable is deprecated. */
503 int mode_line_inverse_video;
505 /* Prompt to display in front of the mini-buffer contents. */
507 Lisp_Object minibuf_prompt;
509 /* Width of current mini-buffer prompt. Only set after display_line
510 of the line that contains the prompt. */
512 int minibuf_prompt_width;
514 /* This is the window where the echo area message was displayed. It
515 is always a mini-buffer window, but it may not be the same window
516 currently active as a mini-buffer. */
518 Lisp_Object echo_area_window;
520 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
521 pushes the current message and the value of
522 message_enable_multibyte on the stack, the function restore_message
523 pops the stack and displays MESSAGE again. */
525 Lisp_Object Vmessage_stack;
527 /* Nonzero means multibyte characters were enabled when the echo area
528 message was specified. */
530 int message_enable_multibyte;
532 /* Nonzero if we should redraw the mode lines on the next redisplay. */
534 int update_mode_lines;
536 /* Nonzero if window sizes or contents have changed since last
537 redisplay that finished. */
539 int windows_or_buffers_changed;
541 /* Nonzero means a frame's cursor type has been changed. */
543 int cursor_type_changed;
545 /* Nonzero after display_mode_line if %l was used and it displayed a
546 line number. */
548 int line_number_displayed;
550 /* Maximum buffer size for which to display line numbers. */
552 Lisp_Object Vline_number_display_limit;
554 /* Line width to consider when repositioning for line number display. */
556 static EMACS_INT line_number_display_limit_width;
558 /* Number of lines to keep in the message log buffer. t means
559 infinite. nil means don't log at all. */
561 Lisp_Object Vmessage_log_max;
563 /* The name of the *Messages* buffer, a string. */
565 static Lisp_Object Vmessages_buffer_name;
567 /* Current, index 0, and last displayed echo area message. Either
568 buffers from echo_buffers, or nil to indicate no message. */
570 Lisp_Object echo_area_buffer[2];
572 /* The buffers referenced from echo_area_buffer. */
574 static Lisp_Object echo_buffer[2];
576 /* A vector saved used in with_area_buffer to reduce consing. */
578 static Lisp_Object Vwith_echo_area_save_vector;
580 /* Non-zero means display_echo_area should display the last echo area
581 message again. Set by redisplay_preserve_echo_area. */
583 static int display_last_displayed_message_p;
585 /* Nonzero if echo area is being used by print; zero if being used by
586 message. */
588 int message_buf_print;
590 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
592 Lisp_Object Qinhibit_menubar_update;
593 int inhibit_menubar_update;
595 /* Maximum height for resizing mini-windows. Either a float
596 specifying a fraction of the available height, or an integer
597 specifying a number of lines. */
599 Lisp_Object Vmax_mini_window_height;
601 /* Non-zero means messages should be displayed with truncated
602 lines instead of being continued. */
604 int message_truncate_lines;
605 Lisp_Object Qmessage_truncate_lines;
607 /* Set to 1 in clear_message to make redisplay_internal aware
608 of an emptied echo area. */
610 static int message_cleared_p;
612 /* Non-zero means we want a hollow cursor in windows that are not
613 selected. Zero means there's no cursor in such windows. */
615 Lisp_Object Vcursor_in_non_selected_windows;
616 Lisp_Object Qcursor_in_non_selected_windows;
618 /* How to blink the default frame cursor off. */
619 Lisp_Object Vblink_cursor_alist;
621 /* A scratch glyph row with contents used for generating truncation
622 glyphs. Also used in direct_output_for_insert. */
624 #define MAX_SCRATCH_GLYPHS 100
625 struct glyph_row scratch_glyph_row;
626 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
628 /* Ascent and height of the last line processed by move_it_to. */
630 static int last_max_ascent, last_height;
632 /* Non-zero if there's a help-echo in the echo area. */
634 int help_echo_showing_p;
636 /* If >= 0, computed, exact values of mode-line and header-line height
637 to use in the macros CURRENT_MODE_LINE_HEIGHT and
638 CURRENT_HEADER_LINE_HEIGHT. */
640 int current_mode_line_height, current_header_line_height;
642 /* The maximum distance to look ahead for text properties. Values
643 that are too small let us call compute_char_face and similar
644 functions too often which is expensive. Values that are too large
645 let us call compute_char_face and alike too often because we
646 might not be interested in text properties that far away. */
648 #define TEXT_PROP_DISTANCE_LIMIT 100
650 #if GLYPH_DEBUG
652 /* Variables to turn off display optimizations from Lisp. */
654 int inhibit_try_window_id, inhibit_try_window_reusing;
655 int inhibit_try_cursor_movement;
657 /* Non-zero means print traces of redisplay if compiled with
658 GLYPH_DEBUG != 0. */
660 int trace_redisplay_p;
662 #endif /* GLYPH_DEBUG */
664 #ifdef DEBUG_TRACE_MOVE
665 /* Non-zero means trace with TRACE_MOVE to stderr. */
666 int trace_move;
668 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
669 #else
670 #define TRACE_MOVE(x) (void) 0
671 #endif
673 /* Non-zero means automatically scroll windows horizontally to make
674 point visible. */
676 int automatic_hscrolling_p;
678 /* How close to the margin can point get before the window is scrolled
679 horizontally. */
680 EMACS_INT hscroll_margin;
682 /* How much to scroll horizontally when point is inside the above margin. */
683 Lisp_Object Vhscroll_step;
685 /* The variable `resize-mini-windows'. If nil, don't resize
686 mini-windows. If t, always resize them to fit the text they
687 display. If `grow-only', let mini-windows grow only until they
688 become empty. */
690 Lisp_Object Vresize_mini_windows;
692 /* Buffer being redisplayed -- for redisplay_window_error. */
694 struct buffer *displayed_buffer;
696 /* Value returned from text property handlers (see below). */
698 enum prop_handled
700 HANDLED_NORMALLY,
701 HANDLED_RECOMPUTE_PROPS,
702 HANDLED_OVERLAY_STRING_CONSUMED,
703 HANDLED_RETURN
706 /* A description of text properties that redisplay is interested
707 in. */
709 struct props
711 /* The name of the property. */
712 Lisp_Object *name;
714 /* A unique index for the property. */
715 enum prop_idx idx;
717 /* A handler function called to set up iterator IT from the property
718 at IT's current position. Value is used to steer handle_stop. */
719 enum prop_handled (*handler) P_ ((struct it *it));
722 static enum prop_handled handle_face_prop P_ ((struct it *));
723 static enum prop_handled handle_invisible_prop P_ ((struct it *));
724 static enum prop_handled handle_display_prop P_ ((struct it *));
725 static enum prop_handled handle_composition_prop P_ ((struct it *));
726 static enum prop_handled handle_overlay_change P_ ((struct it *));
727 static enum prop_handled handle_fontified_prop P_ ((struct it *));
729 /* Properties handled by iterators. */
731 static struct props it_props[] =
733 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
734 /* Handle `face' before `display' because some sub-properties of
735 `display' need to know the face. */
736 {&Qface, FACE_PROP_IDX, handle_face_prop},
737 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
738 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
739 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
740 {NULL, 0, NULL}
743 /* Value is the position described by X. If X is a marker, value is
744 the marker_position of X. Otherwise, value is X. */
746 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
748 /* Enumeration returned by some move_it_.* functions internally. */
750 enum move_it_result
752 /* Not used. Undefined value. */
753 MOVE_UNDEFINED,
755 /* Move ended at the requested buffer position or ZV. */
756 MOVE_POS_MATCH_OR_ZV,
758 /* Move ended at the requested X pixel position. */
759 MOVE_X_REACHED,
761 /* Move within a line ended at the end of a line that must be
762 continued. */
763 MOVE_LINE_CONTINUED,
765 /* Move within a line ended at the end of a line that would
766 be displayed truncated. */
767 MOVE_LINE_TRUNCATED,
769 /* Move within a line ended at a line end. */
770 MOVE_NEWLINE_OR_CR
773 /* This counter is used to clear the face cache every once in a while
774 in redisplay_internal. It is incremented for each redisplay.
775 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
776 cleared. */
778 #define CLEAR_FACE_CACHE_COUNT 500
779 static int clear_face_cache_count;
781 /* Record the previous terminal frame we displayed. */
783 static struct frame *previous_terminal_frame;
785 /* Non-zero while redisplay_internal is in progress. */
787 int redisplaying_p;
789 /* Non-zero means don't free realized faces. Bound while freeing
790 realized faces is dangerous because glyph matrices might still
791 reference them. */
793 int inhibit_free_realized_faces;
794 Lisp_Object Qinhibit_free_realized_faces;
796 /* If a string, XTread_socket generates an event to display that string.
797 (The display is done in read_char.) */
799 Lisp_Object help_echo_string;
800 Lisp_Object help_echo_window;
801 Lisp_Object help_echo_object;
802 int help_echo_pos;
804 /* Temporary variable for XTread_socket. */
806 Lisp_Object previous_help_echo_string;
808 /* Null glyph slice */
810 static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 };
813 /* Function prototypes. */
815 static void setup_for_ellipsis P_ ((struct it *, int));
816 static void mark_window_display_accurate_1 P_ ((struct window *, int));
817 static int single_display_spec_string_p P_ ((Lisp_Object, Lisp_Object));
818 static int display_prop_string_p P_ ((Lisp_Object, Lisp_Object));
819 static int cursor_row_p P_ ((struct window *, struct glyph_row *));
820 static int redisplay_mode_lines P_ ((Lisp_Object, int));
821 static char *decode_mode_spec_coding P_ ((Lisp_Object, char *, int));
823 #if 0
824 static int invisible_text_between_p P_ ((struct it *, int, int));
825 #endif
827 static int next_element_from_ellipsis P_ ((struct it *));
828 static void pint2str P_ ((char *, int, int));
829 static void pint2hrstr P_ ((char *, int, int));
830 static struct text_pos run_window_scroll_functions P_ ((Lisp_Object,
831 struct text_pos));
832 static void reconsider_clip_changes P_ ((struct window *, struct buffer *));
833 static int text_outside_line_unchanged_p P_ ((struct window *, int, int));
834 static void store_frame_title_char P_ ((char));
835 static int store_frame_title P_ ((const unsigned char *, int, int));
836 static void x_consider_frame_title P_ ((Lisp_Object));
837 static void handle_stop P_ ((struct it *));
838 static int tool_bar_lines_needed P_ ((struct frame *));
839 static int single_display_spec_intangible_p P_ ((Lisp_Object));
840 static void ensure_echo_area_buffers P_ ((void));
841 static Lisp_Object unwind_with_echo_area_buffer P_ ((Lisp_Object));
842 static Lisp_Object with_echo_area_buffer_unwind_data P_ ((struct window *));
843 static int with_echo_area_buffer P_ ((struct window *, int,
844 int (*) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
845 EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
846 static void clear_garbaged_frames P_ ((void));
847 static int current_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
848 static int truncate_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
849 static int set_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
850 static int display_echo_area P_ ((struct window *));
851 static int display_echo_area_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
852 static int resize_mini_window_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
853 static Lisp_Object unwind_redisplay P_ ((Lisp_Object));
854 static int string_char_and_length P_ ((const unsigned char *, int, int *));
855 static struct text_pos display_prop_end P_ ((struct it *, Lisp_Object,
856 struct text_pos));
857 static int compute_window_start_on_continuation_line P_ ((struct window *));
858 static Lisp_Object safe_eval_handler P_ ((Lisp_Object));
859 static void insert_left_trunc_glyphs P_ ((struct it *));
860 static struct glyph_row *get_overlay_arrow_glyph_row P_ ((struct window *,
861 Lisp_Object));
862 static void extend_face_to_end_of_line P_ ((struct it *));
863 static int append_space_for_newline P_ ((struct it *, int));
864 static int make_cursor_line_fully_visible P_ ((struct window *, int));
865 static int try_scrolling P_ ((Lisp_Object, int, EMACS_INT, EMACS_INT, int, int));
866 static int try_cursor_movement P_ ((Lisp_Object, struct text_pos, int *));
867 static int trailing_whitespace_p P_ ((int));
868 static int message_log_check_duplicate P_ ((int, int, int, int));
869 static void push_it P_ ((struct it *));
870 static void pop_it P_ ((struct it *));
871 static void sync_frame_with_window_matrix_rows P_ ((struct window *));
872 static void select_frame_for_redisplay P_ ((Lisp_Object));
873 static void redisplay_internal P_ ((int));
874 static int echo_area_display P_ ((int));
875 static void redisplay_windows P_ ((Lisp_Object));
876 static void redisplay_window P_ ((Lisp_Object, int));
877 static Lisp_Object redisplay_window_error ();
878 static Lisp_Object redisplay_window_0 P_ ((Lisp_Object));
879 static Lisp_Object redisplay_window_1 P_ ((Lisp_Object));
880 static void update_menu_bar P_ ((struct frame *, int));
881 static int try_window_reusing_current_matrix P_ ((struct window *));
882 static int try_window_id P_ ((struct window *));
883 static int display_line P_ ((struct it *));
884 static int display_mode_lines P_ ((struct window *));
885 static int display_mode_line P_ ((struct window *, enum face_id, Lisp_Object));
886 static int display_mode_element P_ ((struct it *, int, int, int, Lisp_Object, Lisp_Object, int));
887 static int store_mode_line_string P_ ((char *, Lisp_Object, int, int, int, Lisp_Object));
888 static char *decode_mode_spec P_ ((struct window *, int, int, int, int *));
889 static void display_menu_bar P_ ((struct window *));
890 static int display_count_lines P_ ((int, int, int, int, int *));
891 static int display_string P_ ((unsigned char *, Lisp_Object, Lisp_Object,
892 int, int, struct it *, int, int, int, int));
893 static void compute_line_metrics P_ ((struct it *));
894 static void run_redisplay_end_trigger_hook P_ ((struct it *));
895 static int get_overlay_strings P_ ((struct it *, int));
896 static void next_overlay_string P_ ((struct it *));
897 static void reseat P_ ((struct it *, struct text_pos, int));
898 static void reseat_1 P_ ((struct it *, struct text_pos, int));
899 static void back_to_previous_visible_line_start P_ ((struct it *));
900 void reseat_at_previous_visible_line_start P_ ((struct it *));
901 static void reseat_at_next_visible_line_start P_ ((struct it *, int));
902 static int next_element_from_display_vector P_ ((struct it *));
903 static int next_element_from_string P_ ((struct it *));
904 static int next_element_from_c_string P_ ((struct it *));
905 static int next_element_from_buffer P_ ((struct it *));
906 static int next_element_from_composition P_ ((struct it *));
907 static int next_element_from_image P_ ((struct it *));
908 static int next_element_from_stretch P_ ((struct it *));
909 static void load_overlay_strings P_ ((struct it *, int));
910 static int init_from_display_pos P_ ((struct it *, struct window *,
911 struct display_pos *));
912 static void reseat_to_string P_ ((struct it *, unsigned char *,
913 Lisp_Object, int, int, int, int));
914 static enum move_it_result move_it_in_display_line_to P_ ((struct it *,
915 int, int, int));
916 void move_it_vertically_backward P_ ((struct it *, int));
917 static void init_to_row_start P_ ((struct it *, struct window *,
918 struct glyph_row *));
919 static int init_to_row_end P_ ((struct it *, struct window *,
920 struct glyph_row *));
921 static void back_to_previous_line_start P_ ((struct it *));
922 static int forward_to_next_line_start P_ ((struct it *, int *));
923 static struct text_pos string_pos_nchars_ahead P_ ((struct text_pos,
924 Lisp_Object, int));
925 static struct text_pos string_pos P_ ((int, Lisp_Object));
926 static struct text_pos c_string_pos P_ ((int, unsigned char *, int));
927 static int number_of_chars P_ ((unsigned char *, int));
928 static void compute_stop_pos P_ ((struct it *));
929 static void compute_string_pos P_ ((struct text_pos *, struct text_pos,
930 Lisp_Object));
931 static int face_before_or_after_it_pos P_ ((struct it *, int));
932 static int next_overlay_change P_ ((int));
933 static int handle_single_display_spec P_ ((struct it *, Lisp_Object,
934 Lisp_Object, struct text_pos *,
935 int));
936 static int underlying_face_id P_ ((struct it *));
937 static int in_ellipses_for_invisible_text_p P_ ((struct display_pos *,
938 struct window *));
940 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
941 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
943 #ifdef HAVE_WINDOW_SYSTEM
945 static void update_tool_bar P_ ((struct frame *, int));
946 static void build_desired_tool_bar_string P_ ((struct frame *f));
947 static int redisplay_tool_bar P_ ((struct frame *));
948 static void display_tool_bar_line P_ ((struct it *));
949 static void notice_overwritten_cursor P_ ((struct window *,
950 enum glyph_row_area,
951 int, int, int, int));
955 #endif /* HAVE_WINDOW_SYSTEM */
958 /***********************************************************************
959 Window display dimensions
960 ***********************************************************************/
962 /* Return the bottom boundary y-position for text lines in window W.
963 This is the first y position at which a line cannot start.
964 It is relative to the top of the window.
966 This is the height of W minus the height of a mode line, if any. */
968 INLINE int
969 window_text_bottom_y (w)
970 struct window *w;
972 int height = WINDOW_TOTAL_HEIGHT (w);
974 if (WINDOW_WANTS_MODELINE_P (w))
975 height -= CURRENT_MODE_LINE_HEIGHT (w);
976 return height;
979 /* Return the pixel width of display area AREA of window W. AREA < 0
980 means return the total width of W, not including fringes to
981 the left and right of the window. */
983 INLINE int
984 window_box_width (w, area)
985 struct window *w;
986 int area;
988 int cols = XFASTINT (w->total_cols);
989 int pixels = 0;
991 if (!w->pseudo_window_p)
993 cols -= WINDOW_SCROLL_BAR_COLS (w);
995 if (area == TEXT_AREA)
997 if (INTEGERP (w->left_margin_cols))
998 cols -= XFASTINT (w->left_margin_cols);
999 if (INTEGERP (w->right_margin_cols))
1000 cols -= XFASTINT (w->right_margin_cols);
1001 pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w);
1003 else if (area == LEFT_MARGIN_AREA)
1005 cols = (INTEGERP (w->left_margin_cols)
1006 ? XFASTINT (w->left_margin_cols) : 0);
1007 pixels = 0;
1009 else if (area == RIGHT_MARGIN_AREA)
1011 cols = (INTEGERP (w->right_margin_cols)
1012 ? XFASTINT (w->right_margin_cols) : 0);
1013 pixels = 0;
1017 return cols * WINDOW_FRAME_COLUMN_WIDTH (w) + pixels;
1021 /* Return the pixel height of the display area of window W, not
1022 including mode lines of W, if any. */
1024 INLINE int
1025 window_box_height (w)
1026 struct window *w;
1028 struct frame *f = XFRAME (w->frame);
1029 int height = WINDOW_TOTAL_HEIGHT (w);
1031 xassert (height >= 0);
1033 /* Note: the code below that determines the mode-line/header-line
1034 height is essentially the same as that contained in the macro
1035 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1036 the appropriate glyph row has its `mode_line_p' flag set,
1037 and if it doesn't, uses estimate_mode_line_height instead. */
1039 if (WINDOW_WANTS_MODELINE_P (w))
1041 struct glyph_row *ml_row
1042 = (w->current_matrix && w->current_matrix->rows
1043 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
1044 : 0);
1045 if (ml_row && ml_row->mode_line_p)
1046 height -= ml_row->height;
1047 else
1048 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
1051 if (WINDOW_WANTS_HEADER_LINE_P (w))
1053 struct glyph_row *hl_row
1054 = (w->current_matrix && w->current_matrix->rows
1055 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
1056 : 0);
1057 if (hl_row && hl_row->mode_line_p)
1058 height -= hl_row->height;
1059 else
1060 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1063 /* With a very small font and a mode-line that's taller than
1064 default, we might end up with a negative height. */
1065 return max (0, height);
1068 /* Return the window-relative coordinate of the left edge of display
1069 area AREA of window W. AREA < 0 means return the left edge of the
1070 whole window, to the right of the left fringe of W. */
1072 INLINE int
1073 window_box_left_offset (w, area)
1074 struct window *w;
1075 int area;
1077 int x;
1079 if (w->pseudo_window_p)
1080 return 0;
1082 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
1084 if (area == TEXT_AREA)
1085 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1086 + window_box_width (w, LEFT_MARGIN_AREA));
1087 else if (area == RIGHT_MARGIN_AREA)
1088 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1089 + window_box_width (w, LEFT_MARGIN_AREA)
1090 + window_box_width (w, TEXT_AREA)
1091 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1093 : WINDOW_RIGHT_FRINGE_WIDTH (w)));
1094 else if (area == LEFT_MARGIN_AREA
1095 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1096 x += WINDOW_LEFT_FRINGE_WIDTH (w);
1098 return x;
1102 /* Return the window-relative coordinate of the right edge of display
1103 area AREA of window W. AREA < 0 means return the left edge of the
1104 whole window, to the left of the right fringe of W. */
1106 INLINE int
1107 window_box_right_offset (w, area)
1108 struct window *w;
1109 int area;
1111 return window_box_left_offset (w, area) + window_box_width (w, area);
1114 /* Return the frame-relative coordinate of the left edge of display
1115 area AREA of window W. AREA < 0 means return the left edge of the
1116 whole window, to the right of the left fringe of W. */
1118 INLINE int
1119 window_box_left (w, area)
1120 struct window *w;
1121 int area;
1123 struct frame *f = XFRAME (w->frame);
1124 int x;
1126 if (w->pseudo_window_p)
1127 return FRAME_INTERNAL_BORDER_WIDTH (f);
1129 x = (WINDOW_LEFT_EDGE_X (w)
1130 + window_box_left_offset (w, area));
1132 return x;
1136 /* Return the frame-relative coordinate of the right edge of display
1137 area AREA of window W. AREA < 0 means return the left edge of the
1138 whole window, to the left of the right fringe of W. */
1140 INLINE int
1141 window_box_right (w, area)
1142 struct window *w;
1143 int area;
1145 return window_box_left (w, area) + window_box_width (w, area);
1148 /* Get the bounding box of the display area AREA of window W, without
1149 mode lines, in frame-relative coordinates. AREA < 0 means the
1150 whole window, not including the left and right fringes of
1151 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1152 coordinates of the upper-left corner of the box. Return in
1153 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1155 INLINE void
1156 window_box (w, area, box_x, box_y, box_width, box_height)
1157 struct window *w;
1158 int area;
1159 int *box_x, *box_y, *box_width, *box_height;
1161 if (box_width)
1162 *box_width = window_box_width (w, area);
1163 if (box_height)
1164 *box_height = window_box_height (w);
1165 if (box_x)
1166 *box_x = window_box_left (w, area);
1167 if (box_y)
1169 *box_y = WINDOW_TOP_EDGE_Y (w);
1170 if (WINDOW_WANTS_HEADER_LINE_P (w))
1171 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1176 /* Get the bounding box of the display area AREA of window W, without
1177 mode lines. AREA < 0 means the whole window, not including the
1178 left and right fringe of the window. Return in *TOP_LEFT_X
1179 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1180 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1181 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1182 box. */
1184 INLINE void
1185 window_box_edges (w, area, top_left_x, top_left_y,
1186 bottom_right_x, bottom_right_y)
1187 struct window *w;
1188 int area;
1189 int *top_left_x, *top_left_y, *bottom_right_x, *bottom_right_y;
1191 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
1192 bottom_right_y);
1193 *bottom_right_x += *top_left_x;
1194 *bottom_right_y += *top_left_y;
1199 /***********************************************************************
1200 Utilities
1201 ***********************************************************************/
1203 /* Return the bottom y-position of the line the iterator IT is in.
1204 This can modify IT's settings. */
1207 line_bottom_y (it)
1208 struct it *it;
1210 int line_height = it->max_ascent + it->max_descent;
1211 int line_top_y = it->current_y;
1213 if (line_height == 0)
1215 if (last_height)
1216 line_height = last_height;
1217 else if (IT_CHARPOS (*it) < ZV)
1219 move_it_by_lines (it, 1, 1);
1220 line_height = (it->max_ascent || it->max_descent
1221 ? it->max_ascent + it->max_descent
1222 : last_height);
1224 else
1226 struct glyph_row *row = it->glyph_row;
1228 /* Use the default character height. */
1229 it->glyph_row = NULL;
1230 it->what = IT_CHARACTER;
1231 it->c = ' ';
1232 it->len = 1;
1233 PRODUCE_GLYPHS (it);
1234 line_height = it->ascent + it->descent;
1235 it->glyph_row = row;
1239 return line_top_y + line_height;
1243 /* Return 1 if position CHARPOS is visible in window W. Set *FULLY to
1244 1 if POS is visible and the line containing POS is fully visible.
1245 EXACT_MODE_LINE_HEIGHTS_P non-zero means compute exact mode-line
1246 and header-lines heights. */
1249 pos_visible_p (w, charpos, fully, x, y, exact_mode_line_heights_p)
1250 struct window *w;
1251 int charpos, *fully, *x, *y, exact_mode_line_heights_p;
1253 struct it it;
1254 struct text_pos top;
1255 int visible_p;
1256 struct buffer *old_buffer = NULL;
1258 if (XBUFFER (w->buffer) != current_buffer)
1260 old_buffer = current_buffer;
1261 set_buffer_internal_1 (XBUFFER (w->buffer));
1264 *fully = visible_p = 0;
1265 SET_TEXT_POS_FROM_MARKER (top, w->start);
1267 /* Compute exact mode line heights, if requested. */
1268 if (exact_mode_line_heights_p)
1270 if (WINDOW_WANTS_MODELINE_P (w))
1271 current_mode_line_height
1272 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1273 current_buffer->mode_line_format);
1275 if (WINDOW_WANTS_HEADER_LINE_P (w))
1276 current_header_line_height
1277 = display_mode_line (w, HEADER_LINE_FACE_ID,
1278 current_buffer->header_line_format);
1281 start_display (&it, w, top);
1282 move_it_to (&it, charpos, 0, it.last_visible_y, -1,
1283 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
1285 /* Note that we may overshoot because of invisible text. */
1286 if (IT_CHARPOS (it) >= charpos)
1288 int top_y = it.current_y;
1289 int bottom_y = line_bottom_y (&it);
1290 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1292 if (top_y < window_top_y)
1293 visible_p = bottom_y > window_top_y;
1294 else if (top_y < it.last_visible_y)
1296 visible_p = 1;
1297 *fully = bottom_y <= it.last_visible_y;
1299 if (visible_p && x)
1301 *x = it.current_x;
1302 *y = max (top_y + it.max_ascent - it.ascent, window_top_y);
1305 else if (it.current_y + it.max_ascent + it.max_descent > it.last_visible_y)
1307 struct it it2;
1309 it2 = it;
1310 move_it_by_lines (&it, 1, 0);
1311 if (charpos < IT_CHARPOS (it))
1313 visible_p = 1;
1314 if (x)
1316 move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
1317 *x = it2.current_x;
1318 *y = it2.current_y + it2.max_ascent - it2.ascent;
1323 if (old_buffer)
1324 set_buffer_internal_1 (old_buffer);
1326 current_header_line_height = current_mode_line_height = -1;
1328 return visible_p;
1332 /* Return the next character from STR which is MAXLEN bytes long.
1333 Return in *LEN the length of the character. This is like
1334 STRING_CHAR_AND_LENGTH but never returns an invalid character. If
1335 we find one, we return a `?', but with the length of the invalid
1336 character. */
1338 static INLINE int
1339 string_char_and_length (str, maxlen, len)
1340 const unsigned char *str;
1341 int maxlen, *len;
1343 int c;
1345 c = STRING_CHAR_AND_LENGTH (str, maxlen, *len);
1346 if (!CHAR_VALID_P (c, 1))
1347 /* We may not change the length here because other places in Emacs
1348 don't use this function, i.e. they silently accept invalid
1349 characters. */
1350 c = '?';
1352 return c;
1357 /* Given a position POS containing a valid character and byte position
1358 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1360 static struct text_pos
1361 string_pos_nchars_ahead (pos, string, nchars)
1362 struct text_pos pos;
1363 Lisp_Object string;
1364 int nchars;
1366 xassert (STRINGP (string) && nchars >= 0);
1368 if (STRING_MULTIBYTE (string))
1370 int rest = SBYTES (string) - BYTEPOS (pos);
1371 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1372 int len;
1374 while (nchars--)
1376 string_char_and_length (p, rest, &len);
1377 p += len, rest -= len;
1378 xassert (rest >= 0);
1379 CHARPOS (pos) += 1;
1380 BYTEPOS (pos) += len;
1383 else
1384 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1386 return pos;
1390 /* Value is the text position, i.e. character and byte position,
1391 for character position CHARPOS in STRING. */
1393 static INLINE struct text_pos
1394 string_pos (charpos, string)
1395 int charpos;
1396 Lisp_Object string;
1398 struct text_pos pos;
1399 xassert (STRINGP (string));
1400 xassert (charpos >= 0);
1401 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1402 return pos;
1406 /* Value is a text position, i.e. character and byte position, for
1407 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1408 means recognize multibyte characters. */
1410 static struct text_pos
1411 c_string_pos (charpos, s, multibyte_p)
1412 int charpos;
1413 unsigned char *s;
1414 int multibyte_p;
1416 struct text_pos pos;
1418 xassert (s != NULL);
1419 xassert (charpos >= 0);
1421 if (multibyte_p)
1423 int rest = strlen (s), len;
1425 SET_TEXT_POS (pos, 0, 0);
1426 while (charpos--)
1428 string_char_and_length (s, rest, &len);
1429 s += len, rest -= len;
1430 xassert (rest >= 0);
1431 CHARPOS (pos) += 1;
1432 BYTEPOS (pos) += len;
1435 else
1436 SET_TEXT_POS (pos, charpos, charpos);
1438 return pos;
1442 /* Value is the number of characters in C string S. MULTIBYTE_P
1443 non-zero means recognize multibyte characters. */
1445 static int
1446 number_of_chars (s, multibyte_p)
1447 unsigned char *s;
1448 int multibyte_p;
1450 int nchars;
1452 if (multibyte_p)
1454 int rest = strlen (s), len;
1455 unsigned char *p = (unsigned char *) s;
1457 for (nchars = 0; rest > 0; ++nchars)
1459 string_char_and_length (p, rest, &len);
1460 rest -= len, p += len;
1463 else
1464 nchars = strlen (s);
1466 return nchars;
1470 /* Compute byte position NEWPOS->bytepos corresponding to
1471 NEWPOS->charpos. POS is a known position in string STRING.
1472 NEWPOS->charpos must be >= POS.charpos. */
1474 static void
1475 compute_string_pos (newpos, pos, string)
1476 struct text_pos *newpos, pos;
1477 Lisp_Object string;
1479 xassert (STRINGP (string));
1480 xassert (CHARPOS (*newpos) >= CHARPOS (pos));
1482 if (STRING_MULTIBYTE (string))
1483 *newpos = string_pos_nchars_ahead (pos, string,
1484 CHARPOS (*newpos) - CHARPOS (pos));
1485 else
1486 BYTEPOS (*newpos) = CHARPOS (*newpos);
1489 /* EXPORT:
1490 Return an estimation of the pixel height of mode or top lines on
1491 frame F. FACE_ID specifies what line's height to estimate. */
1494 estimate_mode_line_height (f, face_id)
1495 struct frame *f;
1496 enum face_id face_id;
1498 #ifdef HAVE_WINDOW_SYSTEM
1499 if (FRAME_WINDOW_P (f))
1501 int height = FONT_HEIGHT (FRAME_FONT (f));
1503 /* This function is called so early when Emacs starts that the face
1504 cache and mode line face are not yet initialized. */
1505 if (FRAME_FACE_CACHE (f))
1507 struct face *face = FACE_FROM_ID (f, face_id);
1508 if (face)
1510 if (face->font)
1511 height = FONT_HEIGHT (face->font);
1512 if (face->box_line_width > 0)
1513 height += 2 * face->box_line_width;
1517 return height;
1519 #endif
1521 return 1;
1524 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1525 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1526 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1527 not force the value into range. */
1529 void
1530 pixel_to_glyph_coords (f, pix_x, pix_y, x, y, bounds, noclip)
1531 FRAME_PTR f;
1532 register int pix_x, pix_y;
1533 int *x, *y;
1534 NativeRectangle *bounds;
1535 int noclip;
1538 #ifdef HAVE_WINDOW_SYSTEM
1539 if (FRAME_WINDOW_P (f))
1541 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1542 even for negative values. */
1543 if (pix_x < 0)
1544 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1545 if (pix_y < 0)
1546 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1548 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1549 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1551 if (bounds)
1552 STORE_NATIVE_RECT (*bounds,
1553 FRAME_COL_TO_PIXEL_X (f, pix_x),
1554 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1555 FRAME_COLUMN_WIDTH (f) - 1,
1556 FRAME_LINE_HEIGHT (f) - 1);
1558 if (!noclip)
1560 if (pix_x < 0)
1561 pix_x = 0;
1562 else if (pix_x > FRAME_TOTAL_COLS (f))
1563 pix_x = FRAME_TOTAL_COLS (f);
1565 if (pix_y < 0)
1566 pix_y = 0;
1567 else if (pix_y > FRAME_LINES (f))
1568 pix_y = FRAME_LINES (f);
1571 #endif
1573 *x = pix_x;
1574 *y = pix_y;
1578 /* Given HPOS/VPOS in the current matrix of W, return corresponding
1579 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
1580 can't tell the positions because W's display is not up to date,
1581 return 0. */
1584 glyph_to_pixel_coords (w, hpos, vpos, frame_x, frame_y)
1585 struct window *w;
1586 int hpos, vpos;
1587 int *frame_x, *frame_y;
1589 #ifdef HAVE_WINDOW_SYSTEM
1590 if (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w))))
1592 int success_p;
1594 xassert (hpos >= 0 && hpos < w->current_matrix->matrix_w);
1595 xassert (vpos >= 0 && vpos < w->current_matrix->matrix_h);
1597 if (display_completed)
1599 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
1600 struct glyph *glyph = row->glyphs[TEXT_AREA];
1601 struct glyph *end = glyph + min (hpos, row->used[TEXT_AREA]);
1603 hpos = row->x;
1604 vpos = row->y;
1605 while (glyph < end)
1607 hpos += glyph->pixel_width;
1608 ++glyph;
1611 /* If first glyph is partially visible, its first visible position is still 0. */
1612 if (hpos < 0)
1613 hpos = 0;
1615 success_p = 1;
1617 else
1619 hpos = vpos = 0;
1620 success_p = 0;
1623 *frame_x = WINDOW_TO_FRAME_PIXEL_X (w, hpos);
1624 *frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, vpos);
1625 return success_p;
1627 #endif
1629 *frame_x = hpos;
1630 *frame_y = vpos;
1631 return 1;
1635 #ifdef HAVE_WINDOW_SYSTEM
1637 /* Find the glyph under window-relative coordinates X/Y in window W.
1638 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1639 strings. Return in *HPOS and *VPOS the row and column number of
1640 the glyph found. Return in *AREA the glyph area containing X.
1641 Value is a pointer to the glyph found or null if X/Y is not on
1642 text, or we can't tell because W's current matrix is not up to
1643 date. */
1645 static struct glyph *
1646 x_y_to_hpos_vpos (w, x, y, hpos, vpos, dx, dy, area)
1647 struct window *w;
1648 int x, y;
1649 int *hpos, *vpos, *dx, *dy, *area;
1651 struct glyph *glyph, *end;
1652 struct glyph_row *row = NULL;
1653 int x0, i;
1655 /* Find row containing Y. Give up if some row is not enabled. */
1656 for (i = 0; i < w->current_matrix->nrows; ++i)
1658 row = MATRIX_ROW (w->current_matrix, i);
1659 if (!row->enabled_p)
1660 return NULL;
1661 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1662 break;
1665 *vpos = i;
1666 *hpos = 0;
1668 /* Give up if Y is not in the window. */
1669 if (i == w->current_matrix->nrows)
1670 return NULL;
1672 /* Get the glyph area containing X. */
1673 if (w->pseudo_window_p)
1675 *area = TEXT_AREA;
1676 x0 = 0;
1678 else
1680 if (x < window_box_left_offset (w, TEXT_AREA))
1682 *area = LEFT_MARGIN_AREA;
1683 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
1685 else if (x < window_box_right_offset (w, TEXT_AREA))
1687 *area = TEXT_AREA;
1688 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
1690 else
1692 *area = RIGHT_MARGIN_AREA;
1693 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
1697 /* Find glyph containing X. */
1698 glyph = row->glyphs[*area];
1699 end = glyph + row->used[*area];
1700 x -= x0;
1701 while (glyph < end && x >= glyph->pixel_width)
1703 x -= glyph->pixel_width;
1704 ++glyph;
1707 if (glyph == end)
1708 return NULL;
1710 if (dx)
1712 *dx = x;
1713 *dy = y - (row->y + row->ascent - glyph->ascent);
1716 *hpos = glyph - row->glyphs[*area];
1717 return glyph;
1721 /* EXPORT:
1722 Convert frame-relative x/y to coordinates relative to window W.
1723 Takes pseudo-windows into account. */
1725 void
1726 frame_to_window_pixel_xy (w, x, y)
1727 struct window *w;
1728 int *x, *y;
1730 if (w->pseudo_window_p)
1732 /* A pseudo-window is always full-width, and starts at the
1733 left edge of the frame, plus a frame border. */
1734 struct frame *f = XFRAME (w->frame);
1735 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
1736 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1738 else
1740 *x -= WINDOW_LEFT_EDGE_X (w);
1741 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1745 /* EXPORT:
1746 Return in *R the clipping rectangle for glyph string S. */
1748 void
1749 get_glyph_string_clip_rect (s, nr)
1750 struct glyph_string *s;
1751 NativeRectangle *nr;
1753 XRectangle r;
1755 if (s->row->full_width_p)
1757 /* Draw full-width. X coordinates are relative to S->w->left_col. */
1758 r.x = WINDOW_LEFT_EDGE_X (s->w);
1759 r.width = WINDOW_TOTAL_WIDTH (s->w);
1761 /* Unless displaying a mode or menu bar line, which are always
1762 fully visible, clip to the visible part of the row. */
1763 if (s->w->pseudo_window_p)
1764 r.height = s->row->visible_height;
1765 else
1766 r.height = s->height;
1768 else
1770 /* This is a text line that may be partially visible. */
1771 r.x = window_box_left (s->w, s->area);
1772 r.width = window_box_width (s->w, s->area);
1773 r.height = s->row->visible_height;
1776 /* If S draws overlapping rows, it's sufficient to use the top and
1777 bottom of the window for clipping because this glyph string
1778 intentionally draws over other lines. */
1779 if (s->for_overlaps_p)
1781 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1782 r.height = window_text_bottom_y (s->w) - r.y;
1784 else
1786 /* Don't use S->y for clipping because it doesn't take partially
1787 visible lines into account. For example, it can be negative for
1788 partially visible lines at the top of a window. */
1789 if (!s->row->full_width_p
1790 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
1791 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1792 else
1793 r.y = max (0, s->row->y);
1795 /* If drawing a tool-bar window, draw it over the internal border
1796 at the top of the window. */
1797 if (WINDOWP (s->f->tool_bar_window)
1798 && s->w == XWINDOW (s->f->tool_bar_window))
1799 r.y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
1802 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
1804 /* If drawing the cursor, don't let glyph draw outside its
1805 advertised boundaries. Cleartype does this under some circumstances. */
1806 if (s->hl == DRAW_CURSOR)
1808 struct glyph *glyph = s->first_glyph;
1809 int height;
1811 if (s->x > r.x)
1813 r.width -= s->x - r.x;
1814 r.x = s->x;
1816 r.width = min (r.width, glyph->pixel_width);
1818 /* Don't draw cursor glyph taller than our actual glyph. */
1819 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
1820 if (height < r.height)
1822 int max_y = r.y + r.height;
1823 r.y = min (max_y, s->ybase + glyph->descent - height);
1824 r.height = min (max_y - r.y, height);
1828 #ifdef CONVERT_FROM_XRECT
1829 CONVERT_FROM_XRECT (r, *nr);
1830 #else
1831 *nr = r;
1832 #endif
1835 #endif /* HAVE_WINDOW_SYSTEM */
1838 /***********************************************************************
1839 Lisp form evaluation
1840 ***********************************************************************/
1842 /* Error handler for safe_eval and safe_call. */
1844 static Lisp_Object
1845 safe_eval_handler (arg)
1846 Lisp_Object arg;
1848 add_to_log ("Error during redisplay: %s", arg, Qnil);
1849 return Qnil;
1853 /* Evaluate SEXPR and return the result, or nil if something went
1854 wrong. Prevent redisplay during the evaluation. */
1856 Lisp_Object
1857 safe_eval (sexpr)
1858 Lisp_Object sexpr;
1860 Lisp_Object val;
1862 if (inhibit_eval_during_redisplay)
1863 val = Qnil;
1864 else
1866 int count = SPECPDL_INDEX ();
1867 struct gcpro gcpro1;
1869 GCPRO1 (sexpr);
1870 specbind (Qinhibit_redisplay, Qt);
1871 /* Use Qt to ensure debugger does not run,
1872 so there is no possibility of wanting to redisplay. */
1873 val = internal_condition_case_1 (Feval, sexpr, Qt,
1874 safe_eval_handler);
1875 UNGCPRO;
1876 val = unbind_to (count, val);
1879 return val;
1883 /* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1].
1884 Return the result, or nil if something went wrong. Prevent
1885 redisplay during the evaluation. */
1887 Lisp_Object
1888 safe_call (nargs, args)
1889 int nargs;
1890 Lisp_Object *args;
1892 Lisp_Object val;
1894 if (inhibit_eval_during_redisplay)
1895 val = Qnil;
1896 else
1898 int count = SPECPDL_INDEX ();
1899 struct gcpro gcpro1;
1901 GCPRO1 (args[0]);
1902 gcpro1.nvars = nargs;
1903 specbind (Qinhibit_redisplay, Qt);
1904 /* Use Qt to ensure debugger does not run,
1905 so there is no possibility of wanting to redisplay. */
1906 val = internal_condition_case_2 (Ffuncall, nargs, args, Qt,
1907 safe_eval_handler);
1908 UNGCPRO;
1909 val = unbind_to (count, val);
1912 return val;
1916 /* Call function FN with one argument ARG.
1917 Return the result, or nil if something went wrong. */
1919 Lisp_Object
1920 safe_call1 (fn, arg)
1921 Lisp_Object fn, arg;
1923 Lisp_Object args[2];
1924 args[0] = fn;
1925 args[1] = arg;
1926 return safe_call (2, args);
1931 /***********************************************************************
1932 Debugging
1933 ***********************************************************************/
1935 #if 0
1937 /* Define CHECK_IT to perform sanity checks on iterators.
1938 This is for debugging. It is too slow to do unconditionally. */
1940 static void
1941 check_it (it)
1942 struct it *it;
1944 if (it->method == next_element_from_string)
1946 xassert (STRINGP (it->string));
1947 xassert (IT_STRING_CHARPOS (*it) >= 0);
1949 else
1951 xassert (IT_STRING_CHARPOS (*it) < 0);
1952 if (it->method == next_element_from_buffer)
1954 /* Check that character and byte positions agree. */
1955 xassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
1959 if (it->dpvec)
1960 xassert (it->current.dpvec_index >= 0);
1961 else
1962 xassert (it->current.dpvec_index < 0);
1965 #define CHECK_IT(IT) check_it ((IT))
1967 #else /* not 0 */
1969 #define CHECK_IT(IT) (void) 0
1971 #endif /* not 0 */
1974 #if GLYPH_DEBUG
1976 /* Check that the window end of window W is what we expect it
1977 to be---the last row in the current matrix displaying text. */
1979 static void
1980 check_window_end (w)
1981 struct window *w;
1983 if (!MINI_WINDOW_P (w)
1984 && !NILP (w->window_end_valid))
1986 struct glyph_row *row;
1987 xassert ((row = MATRIX_ROW (w->current_matrix,
1988 XFASTINT (w->window_end_vpos)),
1989 !row->enabled_p
1990 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
1991 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
1995 #define CHECK_WINDOW_END(W) check_window_end ((W))
1997 #else /* not GLYPH_DEBUG */
1999 #define CHECK_WINDOW_END(W) (void) 0
2001 #endif /* not GLYPH_DEBUG */
2005 /***********************************************************************
2006 Iterator initialization
2007 ***********************************************************************/
2009 /* Initialize IT for displaying current_buffer in window W, starting
2010 at character position CHARPOS. CHARPOS < 0 means that no buffer
2011 position is specified which is useful when the iterator is assigned
2012 a position later. BYTEPOS is the byte position corresponding to
2013 CHARPOS. BYTEPOS < 0 means compute it from CHARPOS.
2015 If ROW is not null, calls to produce_glyphs with IT as parameter
2016 will produce glyphs in that row.
2018 BASE_FACE_ID is the id of a base face to use. It must be one of
2019 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2020 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2021 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2023 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2024 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2025 will be initialized to use the corresponding mode line glyph row of
2026 the desired matrix of W. */
2028 void
2029 init_iterator (it, w, charpos, bytepos, row, base_face_id)
2030 struct it *it;
2031 struct window *w;
2032 int charpos, bytepos;
2033 struct glyph_row *row;
2034 enum face_id base_face_id;
2036 int highlight_region_p;
2038 /* Some precondition checks. */
2039 xassert (w != NULL && it != NULL);
2040 xassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
2041 && charpos <= ZV));
2043 /* If face attributes have been changed since the last redisplay,
2044 free realized faces now because they depend on face definitions
2045 that might have changed. Don't free faces while there might be
2046 desired matrices pending which reference these faces. */
2047 if (face_change_count && !inhibit_free_realized_faces)
2049 face_change_count = 0;
2050 free_all_realized_faces (Qnil);
2053 /* Use one of the mode line rows of W's desired matrix if
2054 appropriate. */
2055 if (row == NULL)
2057 if (base_face_id == MODE_LINE_FACE_ID
2058 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
2059 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
2060 else if (base_face_id == HEADER_LINE_FACE_ID)
2061 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
2064 /* Clear IT. */
2065 bzero (it, sizeof *it);
2066 it->current.overlay_string_index = -1;
2067 it->current.dpvec_index = -1;
2068 it->base_face_id = base_face_id;
2069 it->string = Qnil;
2070 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
2072 /* The window in which we iterate over current_buffer: */
2073 XSETWINDOW (it->window, w);
2074 it->w = w;
2075 it->f = XFRAME (w->frame);
2077 /* Extra space between lines (on window systems only). */
2078 if (base_face_id == DEFAULT_FACE_ID
2079 && FRAME_WINDOW_P (it->f))
2081 if (NATNUMP (current_buffer->extra_line_spacing))
2082 it->extra_line_spacing = XFASTINT (current_buffer->extra_line_spacing);
2083 else if (FLOATP (current_buffer->extra_line_spacing))
2084 it->extra_line_spacing = (XFLOAT_DATA (current_buffer->extra_line_spacing)
2085 * FRAME_LINE_HEIGHT (it->f));
2086 else if (it->f->extra_line_spacing > 0)
2087 it->extra_line_spacing = it->f->extra_line_spacing;
2088 it->max_extra_line_spacing = 0;
2091 /* If realized faces have been removed, e.g. because of face
2092 attribute changes of named faces, recompute them. When running
2093 in batch mode, the face cache of Vterminal_frame is null. If
2094 we happen to get called, make a dummy face cache. */
2095 if (noninteractive && FRAME_FACE_CACHE (it->f) == NULL)
2096 init_frame_faces (it->f);
2097 if (FRAME_FACE_CACHE (it->f)->used == 0)
2098 recompute_basic_faces (it->f);
2100 /* Current value of the `slice', `space-width', and 'height' properties. */
2101 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
2102 it->space_width = Qnil;
2103 it->font_height = Qnil;
2104 it->override_ascent = -1;
2106 /* Are control characters displayed as `^C'? */
2107 it->ctl_arrow_p = !NILP (current_buffer->ctl_arrow);
2109 /* -1 means everything between a CR and the following line end
2110 is invisible. >0 means lines indented more than this value are
2111 invisible. */
2112 it->selective = (INTEGERP (current_buffer->selective_display)
2113 ? XFASTINT (current_buffer->selective_display)
2114 : (!NILP (current_buffer->selective_display)
2115 ? -1 : 0));
2116 it->selective_display_ellipsis_p
2117 = !NILP (current_buffer->selective_display_ellipses);
2119 /* Display table to use. */
2120 it->dp = window_display_table (w);
2122 /* Are multibyte characters enabled in current_buffer? */
2123 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
2125 /* Non-zero if we should highlight the region. */
2126 highlight_region_p
2127 = (!NILP (Vtransient_mark_mode)
2128 && !NILP (current_buffer->mark_active)
2129 && XMARKER (current_buffer->mark)->buffer != 0);
2131 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
2132 start and end of a visible region in window IT->w. Set both to
2133 -1 to indicate no region. */
2134 if (highlight_region_p
2135 /* Maybe highlight only in selected window. */
2136 && (/* Either show region everywhere. */
2137 highlight_nonselected_windows
2138 /* Or show region in the selected window. */
2139 || w == XWINDOW (selected_window)
2140 /* Or show the region if we are in the mini-buffer and W is
2141 the window the mini-buffer refers to. */
2142 || (MINI_WINDOW_P (XWINDOW (selected_window))
2143 && WINDOWP (minibuf_selected_window)
2144 && w == XWINDOW (minibuf_selected_window))))
2146 int charpos = marker_position (current_buffer->mark);
2147 it->region_beg_charpos = min (PT, charpos);
2148 it->region_end_charpos = max (PT, charpos);
2150 else
2151 it->region_beg_charpos = it->region_end_charpos = -1;
2153 /* Get the position at which the redisplay_end_trigger hook should
2154 be run, if it is to be run at all. */
2155 if (MARKERP (w->redisplay_end_trigger)
2156 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2157 it->redisplay_end_trigger_charpos
2158 = marker_position (w->redisplay_end_trigger);
2159 else if (INTEGERP (w->redisplay_end_trigger))
2160 it->redisplay_end_trigger_charpos = XINT (w->redisplay_end_trigger);
2162 /* Correct bogus values of tab_width. */
2163 it->tab_width = XINT (current_buffer->tab_width);
2164 if (it->tab_width <= 0 || it->tab_width > 1000)
2165 it->tab_width = 8;
2167 /* Are lines in the display truncated? */
2168 it->truncate_lines_p
2169 = (base_face_id != DEFAULT_FACE_ID
2170 || XINT (it->w->hscroll)
2171 || (truncate_partial_width_windows
2172 && !WINDOW_FULL_WIDTH_P (it->w))
2173 || !NILP (current_buffer->truncate_lines));
2175 /* Get dimensions of truncation and continuation glyphs. These are
2176 displayed as fringe bitmaps under X, so we don't need them for such
2177 frames. */
2178 if (!FRAME_WINDOW_P (it->f))
2180 if (it->truncate_lines_p)
2182 /* We will need the truncation glyph. */
2183 xassert (it->glyph_row == NULL);
2184 produce_special_glyphs (it, IT_TRUNCATION);
2185 it->truncation_pixel_width = it->pixel_width;
2187 else
2189 /* We will need the continuation glyph. */
2190 xassert (it->glyph_row == NULL);
2191 produce_special_glyphs (it, IT_CONTINUATION);
2192 it->continuation_pixel_width = it->pixel_width;
2195 /* Reset these values to zero because the produce_special_glyphs
2196 above has changed them. */
2197 it->pixel_width = it->ascent = it->descent = 0;
2198 it->phys_ascent = it->phys_descent = 0;
2201 /* Set this after getting the dimensions of truncation and
2202 continuation glyphs, so that we don't produce glyphs when calling
2203 produce_special_glyphs, above. */
2204 it->glyph_row = row;
2205 it->area = TEXT_AREA;
2207 /* Get the dimensions of the display area. The display area
2208 consists of the visible window area plus a horizontally scrolled
2209 part to the left of the window. All x-values are relative to the
2210 start of this total display area. */
2211 if (base_face_id != DEFAULT_FACE_ID)
2213 /* Mode lines, menu bar in terminal frames. */
2214 it->first_visible_x = 0;
2215 it->last_visible_x = WINDOW_TOTAL_WIDTH (w);
2217 else
2219 it->first_visible_x
2220 = XFASTINT (it->w->hscroll) * FRAME_COLUMN_WIDTH (it->f);
2221 it->last_visible_x = (it->first_visible_x
2222 + window_box_width (w, TEXT_AREA));
2224 /* If we truncate lines, leave room for the truncator glyph(s) at
2225 the right margin. Otherwise, leave room for the continuation
2226 glyph(s). Truncation and continuation glyphs are not inserted
2227 for window-based redisplay. */
2228 if (!FRAME_WINDOW_P (it->f))
2230 if (it->truncate_lines_p)
2231 it->last_visible_x -= it->truncation_pixel_width;
2232 else
2233 it->last_visible_x -= it->continuation_pixel_width;
2236 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
2237 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
2240 /* Leave room for a border glyph. */
2241 if (!FRAME_WINDOW_P (it->f)
2242 && !WINDOW_RIGHTMOST_P (it->w))
2243 it->last_visible_x -= 1;
2245 it->last_visible_y = window_text_bottom_y (w);
2247 /* For mode lines and alike, arrange for the first glyph having a
2248 left box line if the face specifies a box. */
2249 if (base_face_id != DEFAULT_FACE_ID)
2251 struct face *face;
2253 it->face_id = base_face_id;
2255 /* If we have a boxed mode line, make the first character appear
2256 with a left box line. */
2257 face = FACE_FROM_ID (it->f, base_face_id);
2258 if (face->box != FACE_NO_BOX)
2259 it->start_of_box_run_p = 1;
2262 /* If a buffer position was specified, set the iterator there,
2263 getting overlays and face properties from that position. */
2264 if (charpos >= BUF_BEG (current_buffer))
2266 it->end_charpos = ZV;
2267 it->face_id = -1;
2268 IT_CHARPOS (*it) = charpos;
2270 /* Compute byte position if not specified. */
2271 if (bytepos < charpos)
2272 IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos);
2273 else
2274 IT_BYTEPOS (*it) = bytepos;
2276 it->start = it->current;
2278 /* Compute faces etc. */
2279 reseat (it, it->current.pos, 1);
2282 CHECK_IT (it);
2286 /* Initialize IT for the display of window W with window start POS. */
2288 void
2289 start_display (it, w, pos)
2290 struct it *it;
2291 struct window *w;
2292 struct text_pos pos;
2294 struct glyph_row *row;
2295 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
2297 row = w->desired_matrix->rows + first_vpos;
2298 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
2299 it->first_vpos = first_vpos;
2301 if (!it->truncate_lines_p)
2303 int start_at_line_beg_p;
2304 int first_y = it->current_y;
2306 /* If window start is not at a line start, skip forward to POS to
2307 get the correct continuation lines width. */
2308 start_at_line_beg_p = (CHARPOS (pos) == BEGV
2309 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
2310 if (!start_at_line_beg_p)
2312 int new_x;
2314 reseat_at_previous_visible_line_start (it);
2315 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
2317 new_x = it->current_x + it->pixel_width;
2319 /* If lines are continued, this line may end in the middle
2320 of a multi-glyph character (e.g. a control character
2321 displayed as \003, or in the middle of an overlay
2322 string). In this case move_it_to above will not have
2323 taken us to the start of the continuation line but to the
2324 end of the continued line. */
2325 if (it->current_x > 0
2326 && !it->truncate_lines_p /* Lines are continued. */
2327 && (/* And glyph doesn't fit on the line. */
2328 new_x > it->last_visible_x
2329 /* Or it fits exactly and we're on a window
2330 system frame. */
2331 || (new_x == it->last_visible_x
2332 && FRAME_WINDOW_P (it->f))))
2334 if (it->current.dpvec_index >= 0
2335 || it->current.overlay_string_index >= 0)
2337 set_iterator_to_next (it, 1);
2338 move_it_in_display_line_to (it, -1, -1, 0);
2341 it->continuation_lines_width += it->current_x;
2344 /* We're starting a new display line, not affected by the
2345 height of the continued line, so clear the appropriate
2346 fields in the iterator structure. */
2347 it->max_ascent = it->max_descent = 0;
2348 it->max_phys_ascent = it->max_phys_descent = 0;
2350 it->current_y = first_y;
2351 it->vpos = 0;
2352 it->current_x = it->hpos = 0;
2356 #if 0 /* Don't assert the following because start_display is sometimes
2357 called intentionally with a window start that is not at a
2358 line start. Please leave this code in as a comment. */
2360 /* Window start should be on a line start, now. */
2361 xassert (it->continuation_lines_width
2362 || IT_CHARPOS (it) == BEGV
2363 || FETCH_BYTE (IT_BYTEPOS (it) - 1) == '\n');
2364 #endif /* 0 */
2368 /* Return 1 if POS is a position in ellipses displayed for invisible
2369 text. W is the window we display, for text property lookup. */
2371 static int
2372 in_ellipses_for_invisible_text_p (pos, w)
2373 struct display_pos *pos;
2374 struct window *w;
2376 Lisp_Object prop, window;
2377 int ellipses_p = 0;
2378 int charpos = CHARPOS (pos->pos);
2380 /* If POS specifies a position in a display vector, this might
2381 be for an ellipsis displayed for invisible text. We won't
2382 get the iterator set up for delivering that ellipsis unless
2383 we make sure that it gets aware of the invisible text. */
2384 if (pos->dpvec_index >= 0
2385 && pos->overlay_string_index < 0
2386 && CHARPOS (pos->string_pos) < 0
2387 && charpos > BEGV
2388 && (XSETWINDOW (window, w),
2389 prop = Fget_char_property (make_number (charpos),
2390 Qinvisible, window),
2391 !TEXT_PROP_MEANS_INVISIBLE (prop)))
2393 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
2394 window);
2395 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
2398 return ellipses_p;
2402 /* Initialize IT for stepping through current_buffer in window W,
2403 starting at position POS that includes overlay string and display
2404 vector/ control character translation position information. Value
2405 is zero if there are overlay strings with newlines at POS. */
2407 static int
2408 init_from_display_pos (it, w, pos)
2409 struct it *it;
2410 struct window *w;
2411 struct display_pos *pos;
2413 int charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
2414 int i, overlay_strings_with_newlines = 0;
2416 /* If POS specifies a position in a display vector, this might
2417 be for an ellipsis displayed for invisible text. We won't
2418 get the iterator set up for delivering that ellipsis unless
2419 we make sure that it gets aware of the invisible text. */
2420 if (in_ellipses_for_invisible_text_p (pos, w))
2422 --charpos;
2423 bytepos = 0;
2426 /* Keep in mind: the call to reseat in init_iterator skips invisible
2427 text, so we might end up at a position different from POS. This
2428 is only a problem when POS is a row start after a newline and an
2429 overlay starts there with an after-string, and the overlay has an
2430 invisible property. Since we don't skip invisible text in
2431 display_line and elsewhere immediately after consuming the
2432 newline before the row start, such a POS will not be in a string,
2433 but the call to init_iterator below will move us to the
2434 after-string. */
2435 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
2437 for (i = 0; i < it->n_overlay_strings; ++i)
2439 const char *s = SDATA (it->overlay_strings[i]);
2440 const char *e = s + SBYTES (it->overlay_strings[i]);
2442 while (s < e && *s != '\n')
2443 ++s;
2445 if (s < e)
2447 overlay_strings_with_newlines = 1;
2448 break;
2452 /* If position is within an overlay string, set up IT to the right
2453 overlay string. */
2454 if (pos->overlay_string_index >= 0)
2456 int relative_index;
2458 /* If the first overlay string happens to have a `display'
2459 property for an image, the iterator will be set up for that
2460 image, and we have to undo that setup first before we can
2461 correct the overlay string index. */
2462 if (it->method == next_element_from_image)
2463 pop_it (it);
2465 /* We already have the first chunk of overlay strings in
2466 IT->overlay_strings. Load more until the one for
2467 pos->overlay_string_index is in IT->overlay_strings. */
2468 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
2470 int n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
2471 it->current.overlay_string_index = 0;
2472 while (n--)
2474 load_overlay_strings (it, 0);
2475 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
2479 it->current.overlay_string_index = pos->overlay_string_index;
2480 relative_index = (it->current.overlay_string_index
2481 % OVERLAY_STRING_CHUNK_SIZE);
2482 it->string = it->overlay_strings[relative_index];
2483 xassert (STRINGP (it->string));
2484 it->current.string_pos = pos->string_pos;
2485 it->method = next_element_from_string;
2488 #if 0 /* This is bogus because POS not having an overlay string
2489 position does not mean it's after the string. Example: A
2490 line starting with a before-string and initialization of IT
2491 to the previous row's end position. */
2492 else if (it->current.overlay_string_index >= 0)
2494 /* If POS says we're already after an overlay string ending at
2495 POS, make sure to pop the iterator because it will be in
2496 front of that overlay string. When POS is ZV, we've thereby
2497 also ``processed'' overlay strings at ZV. */
2498 while (it->sp)
2499 pop_it (it);
2500 it->current.overlay_string_index = -1;
2501 it->method = next_element_from_buffer;
2502 if (CHARPOS (pos->pos) == ZV)
2503 it->overlay_strings_at_end_processed_p = 1;
2505 #endif /* 0 */
2507 if (CHARPOS (pos->string_pos) >= 0)
2509 /* Recorded position is not in an overlay string, but in another
2510 string. This can only be a string from a `display' property.
2511 IT should already be filled with that string. */
2512 it->current.string_pos = pos->string_pos;
2513 xassert (STRINGP (it->string));
2516 /* Restore position in display vector translations, control
2517 character translations or ellipses. */
2518 if (pos->dpvec_index >= 0)
2520 if (it->dpvec == NULL)
2521 get_next_display_element (it);
2522 xassert (it->dpvec && it->current.dpvec_index == 0);
2523 it->current.dpvec_index = pos->dpvec_index;
2526 CHECK_IT (it);
2527 return !overlay_strings_with_newlines;
2531 /* Initialize IT for stepping through current_buffer in window W
2532 starting at ROW->start. */
2534 static void
2535 init_to_row_start (it, w, row)
2536 struct it *it;
2537 struct window *w;
2538 struct glyph_row *row;
2540 init_from_display_pos (it, w, &row->start);
2541 it->start = row->start;
2542 it->continuation_lines_width = row->continuation_lines_width;
2543 CHECK_IT (it);
2547 /* Initialize IT for stepping through current_buffer in window W
2548 starting in the line following ROW, i.e. starting at ROW->end.
2549 Value is zero if there are overlay strings with newlines at ROW's
2550 end position. */
2552 static int
2553 init_to_row_end (it, w, row)
2554 struct it *it;
2555 struct window *w;
2556 struct glyph_row *row;
2558 int success = 0;
2560 if (init_from_display_pos (it, w, &row->end))
2562 if (row->continued_p)
2563 it->continuation_lines_width
2564 = row->continuation_lines_width + row->pixel_width;
2565 CHECK_IT (it);
2566 success = 1;
2569 return success;
2575 /***********************************************************************
2576 Text properties
2577 ***********************************************************************/
2579 /* Called when IT reaches IT->stop_charpos. Handle text property and
2580 overlay changes. Set IT->stop_charpos to the next position where
2581 to stop. */
2583 static void
2584 handle_stop (it)
2585 struct it *it;
2587 enum prop_handled handled;
2588 int handle_overlay_change_p = 1;
2589 struct props *p;
2591 it->dpvec = NULL;
2592 it->current.dpvec_index = -1;
2596 handled = HANDLED_NORMALLY;
2598 /* Call text property handlers. */
2599 for (p = it_props; p->handler; ++p)
2601 handled = p->handler (it);
2603 if (handled == HANDLED_RECOMPUTE_PROPS)
2604 break;
2605 else if (handled == HANDLED_RETURN)
2606 return;
2607 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
2608 handle_overlay_change_p = 0;
2611 if (handled != HANDLED_RECOMPUTE_PROPS)
2613 /* Don't check for overlay strings below when set to deliver
2614 characters from a display vector. */
2615 if (it->method == next_element_from_display_vector)
2616 handle_overlay_change_p = 0;
2618 /* Handle overlay changes. */
2619 if (handle_overlay_change_p)
2620 handled = handle_overlay_change (it);
2622 /* Determine where to stop next. */
2623 if (handled == HANDLED_NORMALLY)
2624 compute_stop_pos (it);
2627 while (handled == HANDLED_RECOMPUTE_PROPS);
2631 /* Compute IT->stop_charpos from text property and overlay change
2632 information for IT's current position. */
2634 static void
2635 compute_stop_pos (it)
2636 struct it *it;
2638 register INTERVAL iv, next_iv;
2639 Lisp_Object object, limit, position;
2641 /* If nowhere else, stop at the end. */
2642 it->stop_charpos = it->end_charpos;
2644 if (STRINGP (it->string))
2646 /* Strings are usually short, so don't limit the search for
2647 properties. */
2648 object = it->string;
2649 limit = Qnil;
2650 position = make_number (IT_STRING_CHARPOS (*it));
2652 else
2654 int charpos;
2656 /* If next overlay change is in front of the current stop pos
2657 (which is IT->end_charpos), stop there. Note: value of
2658 next_overlay_change is point-max if no overlay change
2659 follows. */
2660 charpos = next_overlay_change (IT_CHARPOS (*it));
2661 if (charpos < it->stop_charpos)
2662 it->stop_charpos = charpos;
2664 /* If showing the region, we have to stop at the region
2665 start or end because the face might change there. */
2666 if (it->region_beg_charpos > 0)
2668 if (IT_CHARPOS (*it) < it->region_beg_charpos)
2669 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
2670 else if (IT_CHARPOS (*it) < it->region_end_charpos)
2671 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
2674 /* Set up variables for computing the stop position from text
2675 property changes. */
2676 XSETBUFFER (object, current_buffer);
2677 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
2678 position = make_number (IT_CHARPOS (*it));
2682 /* Get the interval containing IT's position. Value is a null
2683 interval if there isn't such an interval. */
2684 iv = validate_interval_range (object, &position, &position, 0);
2685 if (!NULL_INTERVAL_P (iv))
2687 Lisp_Object values_here[LAST_PROP_IDX];
2688 struct props *p;
2690 /* Get properties here. */
2691 for (p = it_props; p->handler; ++p)
2692 values_here[p->idx] = textget (iv->plist, *p->name);
2694 /* Look for an interval following iv that has different
2695 properties. */
2696 for (next_iv = next_interval (iv);
2697 (!NULL_INTERVAL_P (next_iv)
2698 && (NILP (limit)
2699 || XFASTINT (limit) > next_iv->position));
2700 next_iv = next_interval (next_iv))
2702 for (p = it_props; p->handler; ++p)
2704 Lisp_Object new_value;
2706 new_value = textget (next_iv->plist, *p->name);
2707 if (!EQ (values_here[p->idx], new_value))
2708 break;
2711 if (p->handler)
2712 break;
2715 if (!NULL_INTERVAL_P (next_iv))
2717 if (INTEGERP (limit)
2718 && next_iv->position >= XFASTINT (limit))
2719 /* No text property change up to limit. */
2720 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
2721 else
2722 /* Text properties change in next_iv. */
2723 it->stop_charpos = min (it->stop_charpos, next_iv->position);
2727 xassert (STRINGP (it->string)
2728 || (it->stop_charpos >= BEGV
2729 && it->stop_charpos >= IT_CHARPOS (*it)));
2733 /* Return the position of the next overlay change after POS in
2734 current_buffer. Value is point-max if no overlay change
2735 follows. This is like `next-overlay-change' but doesn't use
2736 xmalloc. */
2738 static int
2739 next_overlay_change (pos)
2740 int pos;
2742 int noverlays;
2743 int endpos;
2744 Lisp_Object *overlays;
2745 int i;
2747 /* Get all overlays at the given position. */
2748 GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, 1);
2750 /* If any of these overlays ends before endpos,
2751 use its ending point instead. */
2752 for (i = 0; i < noverlays; ++i)
2754 Lisp_Object oend;
2755 int oendpos;
2757 oend = OVERLAY_END (overlays[i]);
2758 oendpos = OVERLAY_POSITION (oend);
2759 endpos = min (endpos, oendpos);
2762 return endpos;
2767 /***********************************************************************
2768 Fontification
2769 ***********************************************************************/
2771 /* Handle changes in the `fontified' property of the current buffer by
2772 calling hook functions from Qfontification_functions to fontify
2773 regions of text. */
2775 static enum prop_handled
2776 handle_fontified_prop (it)
2777 struct it *it;
2779 Lisp_Object prop, pos;
2780 enum prop_handled handled = HANDLED_NORMALLY;
2782 /* Get the value of the `fontified' property at IT's current buffer
2783 position. (The `fontified' property doesn't have a special
2784 meaning in strings.) If the value is nil, call functions from
2785 Qfontification_functions. */
2786 if (!STRINGP (it->string)
2787 && it->s == NULL
2788 && !NILP (Vfontification_functions)
2789 && !NILP (Vrun_hooks)
2790 && (pos = make_number (IT_CHARPOS (*it)),
2791 prop = Fget_char_property (pos, Qfontified, Qnil),
2792 NILP (prop)))
2794 int count = SPECPDL_INDEX ();
2795 Lisp_Object val;
2797 val = Vfontification_functions;
2798 specbind (Qfontification_functions, Qnil);
2800 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
2801 safe_call1 (val, pos);
2802 else
2804 Lisp_Object globals, fn;
2805 struct gcpro gcpro1, gcpro2;
2807 globals = Qnil;
2808 GCPRO2 (val, globals);
2810 for (; CONSP (val); val = XCDR (val))
2812 fn = XCAR (val);
2814 if (EQ (fn, Qt))
2816 /* A value of t indicates this hook has a local
2817 binding; it means to run the global binding too.
2818 In a global value, t should not occur. If it
2819 does, we must ignore it to avoid an endless
2820 loop. */
2821 for (globals = Fdefault_value (Qfontification_functions);
2822 CONSP (globals);
2823 globals = XCDR (globals))
2825 fn = XCAR (globals);
2826 if (!EQ (fn, Qt))
2827 safe_call1 (fn, pos);
2830 else
2831 safe_call1 (fn, pos);
2834 UNGCPRO;
2837 unbind_to (count, Qnil);
2839 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
2840 something. This avoids an endless loop if they failed to
2841 fontify the text for which reason ever. */
2842 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
2843 handled = HANDLED_RECOMPUTE_PROPS;
2846 return handled;
2851 /***********************************************************************
2852 Faces
2853 ***********************************************************************/
2855 /* Set up iterator IT from face properties at its current position.
2856 Called from handle_stop. */
2858 static enum prop_handled
2859 handle_face_prop (it)
2860 struct it *it;
2862 int new_face_id, next_stop;
2864 if (!STRINGP (it->string))
2866 new_face_id
2867 = face_at_buffer_position (it->w,
2868 IT_CHARPOS (*it),
2869 it->region_beg_charpos,
2870 it->region_end_charpos,
2871 &next_stop,
2872 (IT_CHARPOS (*it)
2873 + TEXT_PROP_DISTANCE_LIMIT),
2876 /* Is this a start of a run of characters with box face?
2877 Caveat: this can be called for a freshly initialized
2878 iterator; face_id is -1 in this case. We know that the new
2879 face will not change until limit, i.e. if the new face has a
2880 box, all characters up to limit will have one. But, as
2881 usual, we don't know whether limit is really the end. */
2882 if (new_face_id != it->face_id)
2884 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
2886 /* If new face has a box but old face has not, this is
2887 the start of a run of characters with box, i.e. it has
2888 a shadow on the left side. The value of face_id of the
2889 iterator will be -1 if this is the initial call that gets
2890 the face. In this case, we have to look in front of IT's
2891 position and see whether there is a face != new_face_id. */
2892 it->start_of_box_run_p
2893 = (new_face->box != FACE_NO_BOX
2894 && (it->face_id >= 0
2895 || IT_CHARPOS (*it) == BEG
2896 || new_face_id != face_before_it_pos (it)));
2897 it->face_box_p = new_face->box != FACE_NO_BOX;
2900 else
2902 int base_face_id, bufpos;
2904 if (it->current.overlay_string_index >= 0)
2905 bufpos = IT_CHARPOS (*it);
2906 else
2907 bufpos = 0;
2909 /* For strings from a buffer, i.e. overlay strings or strings
2910 from a `display' property, use the face at IT's current
2911 buffer position as the base face to merge with, so that
2912 overlay strings appear in the same face as surrounding
2913 text, unless they specify their own faces. */
2914 base_face_id = underlying_face_id (it);
2916 new_face_id = face_at_string_position (it->w,
2917 it->string,
2918 IT_STRING_CHARPOS (*it),
2919 bufpos,
2920 it->region_beg_charpos,
2921 it->region_end_charpos,
2922 &next_stop,
2923 base_face_id, 0);
2925 #if 0 /* This shouldn't be neccessary. Let's check it. */
2926 /* If IT is used to display a mode line we would really like to
2927 use the mode line face instead of the frame's default face. */
2928 if (it->glyph_row == MATRIX_MODE_LINE_ROW (it->w->desired_matrix)
2929 && new_face_id == DEFAULT_FACE_ID)
2930 new_face_id = CURRENT_MODE_LINE_FACE_ID (it->w);
2931 #endif
2933 /* Is this a start of a run of characters with box? Caveat:
2934 this can be called for a freshly allocated iterator; face_id
2935 is -1 is this case. We know that the new face will not
2936 change until the next check pos, i.e. if the new face has a
2937 box, all characters up to that position will have a
2938 box. But, as usual, we don't know whether that position
2939 is really the end. */
2940 if (new_face_id != it->face_id)
2942 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
2943 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
2945 /* If new face has a box but old face hasn't, this is the
2946 start of a run of characters with box, i.e. it has a
2947 shadow on the left side. */
2948 it->start_of_box_run_p
2949 = new_face->box && (old_face == NULL || !old_face->box);
2950 it->face_box_p = new_face->box != FACE_NO_BOX;
2954 it->face_id = new_face_id;
2955 return HANDLED_NORMALLY;
2959 /* Return the ID of the face ``underlying'' IT's current position,
2960 which is in a string. If the iterator is associated with a
2961 buffer, return the face at IT's current buffer position.
2962 Otherwise, use the iterator's base_face_id. */
2964 static int
2965 underlying_face_id (it)
2966 struct it *it;
2968 int face_id = it->base_face_id, i;
2970 xassert (STRINGP (it->string));
2972 for (i = it->sp - 1; i >= 0; --i)
2973 if (NILP (it->stack[i].string))
2974 face_id = it->stack[i].face_id;
2976 return face_id;
2980 /* Compute the face one character before or after the current position
2981 of IT. BEFORE_P non-zero means get the face in front of IT's
2982 position. Value is the id of the face. */
2984 static int
2985 face_before_or_after_it_pos (it, before_p)
2986 struct it *it;
2987 int before_p;
2989 int face_id, limit;
2990 int next_check_charpos;
2991 struct text_pos pos;
2993 xassert (it->s == NULL);
2995 if (STRINGP (it->string))
2997 int bufpos, base_face_id;
2999 /* No face change past the end of the string (for the case
3000 we are padding with spaces). No face change before the
3001 string start. */
3002 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
3003 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
3004 return it->face_id;
3006 /* Set pos to the position before or after IT's current position. */
3007 if (before_p)
3008 pos = string_pos (IT_STRING_CHARPOS (*it) - 1, it->string);
3009 else
3010 /* For composition, we must check the character after the
3011 composition. */
3012 pos = (it->what == IT_COMPOSITION
3013 ? string_pos (IT_STRING_CHARPOS (*it) + it->cmp_len, it->string)
3014 : string_pos (IT_STRING_CHARPOS (*it) + 1, it->string));
3016 if (it->current.overlay_string_index >= 0)
3017 bufpos = IT_CHARPOS (*it);
3018 else
3019 bufpos = 0;
3021 base_face_id = underlying_face_id (it);
3023 /* Get the face for ASCII, or unibyte. */
3024 face_id = face_at_string_position (it->w,
3025 it->string,
3026 CHARPOS (pos),
3027 bufpos,
3028 it->region_beg_charpos,
3029 it->region_end_charpos,
3030 &next_check_charpos,
3031 base_face_id, 0);
3033 /* Correct the face for charsets different from ASCII. Do it
3034 for the multibyte case only. The face returned above is
3035 suitable for unibyte text if IT->string is unibyte. */
3036 if (STRING_MULTIBYTE (it->string))
3038 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos);
3039 int rest = SBYTES (it->string) - BYTEPOS (pos);
3040 int c, len;
3041 struct face *face = FACE_FROM_ID (it->f, face_id);
3043 c = string_char_and_length (p, rest, &len);
3044 face_id = FACE_FOR_CHAR (it->f, face, c);
3047 else
3049 if ((IT_CHARPOS (*it) >= ZV && !before_p)
3050 || (IT_CHARPOS (*it) <= BEGV && before_p))
3051 return it->face_id;
3053 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
3054 pos = it->current.pos;
3056 if (before_p)
3057 DEC_TEXT_POS (pos, it->multibyte_p);
3058 else
3060 if (it->what == IT_COMPOSITION)
3061 /* For composition, we must check the position after the
3062 composition. */
3063 pos.charpos += it->cmp_len, pos.bytepos += it->len;
3064 else
3065 INC_TEXT_POS (pos, it->multibyte_p);
3068 /* Determine face for CHARSET_ASCII, or unibyte. */
3069 face_id = face_at_buffer_position (it->w,
3070 CHARPOS (pos),
3071 it->region_beg_charpos,
3072 it->region_end_charpos,
3073 &next_check_charpos,
3074 limit, 0);
3076 /* Correct the face for charsets different from ASCII. Do it
3077 for the multibyte case only. The face returned above is
3078 suitable for unibyte text if current_buffer is unibyte. */
3079 if (it->multibyte_p)
3081 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
3082 struct face *face = FACE_FROM_ID (it->f, face_id);
3083 face_id = FACE_FOR_CHAR (it->f, face, c);
3087 return face_id;
3092 /***********************************************************************
3093 Invisible text
3094 ***********************************************************************/
3096 /* Set up iterator IT from invisible properties at its current
3097 position. Called from handle_stop. */
3099 static enum prop_handled
3100 handle_invisible_prop (it)
3101 struct it *it;
3103 enum prop_handled handled = HANDLED_NORMALLY;
3105 if (STRINGP (it->string))
3107 extern Lisp_Object Qinvisible;
3108 Lisp_Object prop, end_charpos, limit, charpos;
3110 /* Get the value of the invisible text property at the
3111 current position. Value will be nil if there is no such
3112 property. */
3113 charpos = make_number (IT_STRING_CHARPOS (*it));
3114 prop = Fget_text_property (charpos, Qinvisible, it->string);
3116 if (!NILP (prop)
3117 && IT_STRING_CHARPOS (*it) < it->end_charpos)
3119 handled = HANDLED_RECOMPUTE_PROPS;
3121 /* Get the position at which the next change of the
3122 invisible text property can be found in IT->string.
3123 Value will be nil if the property value is the same for
3124 all the rest of IT->string. */
3125 XSETINT (limit, SCHARS (it->string));
3126 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
3127 it->string, limit);
3129 /* Text at current position is invisible. The next
3130 change in the property is at position end_charpos.
3131 Move IT's current position to that position. */
3132 if (INTEGERP (end_charpos)
3133 && XFASTINT (end_charpos) < XFASTINT (limit))
3135 struct text_pos old;
3136 old = it->current.string_pos;
3137 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
3138 compute_string_pos (&it->current.string_pos, old, it->string);
3140 else
3142 /* The rest of the string is invisible. If this is an
3143 overlay string, proceed with the next overlay string
3144 or whatever comes and return a character from there. */
3145 if (it->current.overlay_string_index >= 0)
3147 next_overlay_string (it);
3148 /* Don't check for overlay strings when we just
3149 finished processing them. */
3150 handled = HANDLED_OVERLAY_STRING_CONSUMED;
3152 else
3154 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
3155 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
3160 else
3162 int invis_p, newpos, next_stop, start_charpos;
3163 Lisp_Object pos, prop, overlay;
3165 /* First of all, is there invisible text at this position? */
3166 start_charpos = IT_CHARPOS (*it);
3167 pos = make_number (IT_CHARPOS (*it));
3168 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
3169 &overlay);
3170 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3172 /* If we are on invisible text, skip over it. */
3173 if (invis_p && IT_CHARPOS (*it) < it->end_charpos)
3175 /* Record whether we have to display an ellipsis for the
3176 invisible text. */
3177 int display_ellipsis_p = invis_p == 2;
3179 handled = HANDLED_RECOMPUTE_PROPS;
3181 /* Loop skipping over invisible text. The loop is left at
3182 ZV or with IT on the first char being visible again. */
3185 /* Try to skip some invisible text. Return value is the
3186 position reached which can be equal to IT's position
3187 if there is nothing invisible here. This skips both
3188 over invisible text properties and overlays with
3189 invisible property. */
3190 newpos = skip_invisible (IT_CHARPOS (*it),
3191 &next_stop, ZV, it->window);
3193 /* If we skipped nothing at all we weren't at invisible
3194 text in the first place. If everything to the end of
3195 the buffer was skipped, end the loop. */
3196 if (newpos == IT_CHARPOS (*it) || newpos >= ZV)
3197 invis_p = 0;
3198 else
3200 /* We skipped some characters but not necessarily
3201 all there are. Check if we ended up on visible
3202 text. Fget_char_property returns the property of
3203 the char before the given position, i.e. if we
3204 get invis_p = 0, this means that the char at
3205 newpos is visible. */
3206 pos = make_number (newpos);
3207 prop = Fget_char_property (pos, Qinvisible, it->window);
3208 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3211 /* If we ended up on invisible text, proceed to
3212 skip starting with next_stop. */
3213 if (invis_p)
3214 IT_CHARPOS (*it) = next_stop;
3216 while (invis_p);
3218 /* The position newpos is now either ZV or on visible text. */
3219 IT_CHARPOS (*it) = newpos;
3220 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
3222 /* If there are before-strings at the start of invisible
3223 text, and the text is invisible because of a text
3224 property, arrange to show before-strings because 20.x did
3225 it that way. (If the text is invisible because of an
3226 overlay property instead of a text property, this is
3227 already handled in the overlay code.) */
3228 if (NILP (overlay)
3229 && get_overlay_strings (it, start_charpos))
3231 handled = HANDLED_RECOMPUTE_PROPS;
3232 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
3234 else if (display_ellipsis_p)
3235 setup_for_ellipsis (it, 0);
3239 return handled;
3243 /* Make iterator IT return `...' next.
3244 Replaces LEN characters from buffer. */
3246 static void
3247 setup_for_ellipsis (it, len)
3248 struct it *it;
3249 int len;
3251 /* Use the display table definition for `...'. Invalid glyphs
3252 will be handled by the method returning elements from dpvec. */
3253 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
3255 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
3256 it->dpvec = v->contents;
3257 it->dpend = v->contents + v->size;
3259 else
3261 /* Default `...'. */
3262 it->dpvec = default_invis_vector;
3263 it->dpend = default_invis_vector + 3;
3266 it->dpvec_char_len = len;
3267 it->current.dpvec_index = 0;
3269 /* Remember the current face id in case glyphs specify faces.
3270 IT's face is restored in set_iterator_to_next. */
3271 it->saved_face_id = it->face_id;
3272 it->method = next_element_from_display_vector;
3273 it->ellipsis_p = 1;
3278 /***********************************************************************
3279 'display' property
3280 ***********************************************************************/
3282 /* Set up iterator IT from `display' property at its current position.
3283 Called from handle_stop.
3284 We return HANDLED_RETURN if some part of the display property
3285 overrides the display of the buffer text itself.
3286 Otherwise we return HANDLED_NORMALLY. */
3288 static enum prop_handled
3289 handle_display_prop (it)
3290 struct it *it;
3292 Lisp_Object prop, object;
3293 struct text_pos *position;
3294 /* Nonzero if some property replaces the display of the text itself. */
3295 int display_replaced_p = 0;
3297 if (STRINGP (it->string))
3299 object = it->string;
3300 position = &it->current.string_pos;
3302 else
3304 object = it->w->buffer;
3305 position = &it->current.pos;
3308 /* Reset those iterator values set from display property values. */
3309 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
3310 it->space_width = Qnil;
3311 it->font_height = Qnil;
3312 it->voffset = 0;
3314 /* We don't support recursive `display' properties, i.e. string
3315 values that have a string `display' property, that have a string
3316 `display' property etc. */
3317 if (!it->string_from_display_prop_p)
3318 it->area = TEXT_AREA;
3320 prop = Fget_char_property (make_number (position->charpos),
3321 Qdisplay, object);
3322 if (NILP (prop))
3323 return HANDLED_NORMALLY;
3325 if (CONSP (prop)
3326 /* Simple properties. */
3327 && !EQ (XCAR (prop), Qimage)
3328 && !EQ (XCAR (prop), Qspace)
3329 && !EQ (XCAR (prop), Qwhen)
3330 && !EQ (XCAR (prop), Qslice)
3331 && !EQ (XCAR (prop), Qspace_width)
3332 && !EQ (XCAR (prop), Qheight)
3333 && !EQ (XCAR (prop), Qraise)
3334 /* Marginal area specifications. */
3335 && !(CONSP (XCAR (prop)) && EQ (XCAR (XCAR (prop)), Qmargin))
3336 && !EQ (XCAR (prop), Qleft_fringe)
3337 && !EQ (XCAR (prop), Qright_fringe)
3338 && !NILP (XCAR (prop)))
3340 for (; CONSP (prop); prop = XCDR (prop))
3342 if (handle_single_display_spec (it, XCAR (prop), object,
3343 position, display_replaced_p))
3344 display_replaced_p = 1;
3347 else if (VECTORP (prop))
3349 int i;
3350 for (i = 0; i < ASIZE (prop); ++i)
3351 if (handle_single_display_spec (it, AREF (prop, i), object,
3352 position, display_replaced_p))
3353 display_replaced_p = 1;
3355 else
3357 if (handle_single_display_spec (it, prop, object, position, 0))
3358 display_replaced_p = 1;
3361 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
3365 /* Value is the position of the end of the `display' property starting
3366 at START_POS in OBJECT. */
3368 static struct text_pos
3369 display_prop_end (it, object, start_pos)
3370 struct it *it;
3371 Lisp_Object object;
3372 struct text_pos start_pos;
3374 Lisp_Object end;
3375 struct text_pos end_pos;
3377 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
3378 Qdisplay, object, Qnil);
3379 CHARPOS (end_pos) = XFASTINT (end);
3380 if (STRINGP (object))
3381 compute_string_pos (&end_pos, start_pos, it->string);
3382 else
3383 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
3385 return end_pos;
3389 /* Set up IT from a single `display' specification PROP. OBJECT
3390 is the object in which the `display' property was found. *POSITION
3391 is the position at which it was found. DISPLAY_REPLACED_P non-zero
3392 means that we previously saw a display specification which already
3393 replaced text display with something else, for example an image;
3394 we ignore such properties after the first one has been processed.
3396 If PROP is a `space' or `image' specification, and in some other
3397 cases too, set *POSITION to the position where the `display'
3398 property ends.
3400 Value is non-zero if something was found which replaces the display
3401 of buffer or string text. */
3403 static int
3404 handle_single_display_spec (it, spec, object, position,
3405 display_replaced_before_p)
3406 struct it *it;
3407 Lisp_Object spec;
3408 Lisp_Object object;
3409 struct text_pos *position;
3410 int display_replaced_before_p;
3412 Lisp_Object form;
3413 Lisp_Object location, value;
3414 struct text_pos start_pos;
3415 int valid_p;
3417 /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
3418 If the result is non-nil, use VALUE instead of SPEC. */
3419 form = Qt;
3420 if (CONSP (spec) && EQ (XCAR (spec), Qwhen))
3422 spec = XCDR (spec);
3423 if (!CONSP (spec))
3424 return 0;
3425 form = XCAR (spec);
3426 spec = XCDR (spec);
3429 if (!NILP (form) && !EQ (form, Qt))
3431 int count = SPECPDL_INDEX ();
3432 struct gcpro gcpro1;
3434 /* Bind `object' to the object having the `display' property, a
3435 buffer or string. Bind `position' to the position in the
3436 object where the property was found, and `buffer-position'
3437 to the current position in the buffer. */
3438 specbind (Qobject, object);
3439 specbind (Qposition, make_number (CHARPOS (*position)));
3440 specbind (Qbuffer_position,
3441 make_number (STRINGP (object)
3442 ? IT_CHARPOS (*it) : CHARPOS (*position)));
3443 GCPRO1 (form);
3444 form = safe_eval (form);
3445 UNGCPRO;
3446 unbind_to (count, Qnil);
3449 if (NILP (form))
3450 return 0;
3452 /* Handle `(height HEIGHT)' specifications. */
3453 if (CONSP (spec)
3454 && EQ (XCAR (spec), Qheight)
3455 && CONSP (XCDR (spec)))
3457 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3458 return 0;
3460 it->font_height = XCAR (XCDR (spec));
3461 if (!NILP (it->font_height))
3463 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3464 int new_height = -1;
3466 if (CONSP (it->font_height)
3467 && (EQ (XCAR (it->font_height), Qplus)
3468 || EQ (XCAR (it->font_height), Qminus))
3469 && CONSP (XCDR (it->font_height))
3470 && INTEGERP (XCAR (XCDR (it->font_height))))
3472 /* `(+ N)' or `(- N)' where N is an integer. */
3473 int steps = XINT (XCAR (XCDR (it->font_height)));
3474 if (EQ (XCAR (it->font_height), Qplus))
3475 steps = - steps;
3476 it->face_id = smaller_face (it->f, it->face_id, steps);
3478 else if (FUNCTIONP (it->font_height))
3480 /* Call function with current height as argument.
3481 Value is the new height. */
3482 Lisp_Object height;
3483 height = safe_call1 (it->font_height,
3484 face->lface[LFACE_HEIGHT_INDEX]);
3485 if (NUMBERP (height))
3486 new_height = XFLOATINT (height);
3488 else if (NUMBERP (it->font_height))
3490 /* Value is a multiple of the canonical char height. */
3491 struct face *face;
3493 face = FACE_FROM_ID (it->f, DEFAULT_FACE_ID);
3494 new_height = (XFLOATINT (it->font_height)
3495 * XINT (face->lface[LFACE_HEIGHT_INDEX]));
3497 else
3499 /* Evaluate IT->font_height with `height' bound to the
3500 current specified height to get the new height. */
3501 int count = SPECPDL_INDEX ();
3503 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
3504 value = safe_eval (it->font_height);
3505 unbind_to (count, Qnil);
3507 if (NUMBERP (value))
3508 new_height = XFLOATINT (value);
3511 if (new_height > 0)
3512 it->face_id = face_with_height (it->f, it->face_id, new_height);
3515 return 0;
3518 /* Handle `(space_width WIDTH)'. */
3519 if (CONSP (spec)
3520 && EQ (XCAR (spec), Qspace_width)
3521 && CONSP (XCDR (spec)))
3523 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3524 return 0;
3526 value = XCAR (XCDR (spec));
3527 if (NUMBERP (value) && XFLOATINT (value) > 0)
3528 it->space_width = value;
3530 return 0;
3533 /* Handle `(slice X Y WIDTH HEIGHT)'. */
3534 if (CONSP (spec)
3535 && EQ (XCAR (spec), Qslice))
3537 Lisp_Object tem;
3539 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3540 return 0;
3542 if (tem = XCDR (spec), CONSP (tem))
3544 it->slice.x = XCAR (tem);
3545 if (tem = XCDR (tem), CONSP (tem))
3547 it->slice.y = XCAR (tem);
3548 if (tem = XCDR (tem), CONSP (tem))
3550 it->slice.width = XCAR (tem);
3551 if (tem = XCDR (tem), CONSP (tem))
3552 it->slice.height = XCAR (tem);
3557 return 0;
3560 /* Handle `(raise FACTOR)'. */
3561 if (CONSP (spec)
3562 && EQ (XCAR (spec), Qraise)
3563 && CONSP (XCDR (spec)))
3565 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3566 return 0;
3568 #ifdef HAVE_WINDOW_SYSTEM
3569 value = XCAR (XCDR (spec));
3570 if (NUMBERP (value))
3572 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3573 it->voffset = - (XFLOATINT (value)
3574 * (FONT_HEIGHT (face->font)));
3576 #endif /* HAVE_WINDOW_SYSTEM */
3578 return 0;
3581 /* Don't handle the other kinds of display specifications
3582 inside a string that we got from a `display' property. */
3583 if (it->string_from_display_prop_p)
3584 return 0;
3586 /* Characters having this form of property are not displayed, so
3587 we have to find the end of the property. */
3588 start_pos = *position;
3589 *position = display_prop_end (it, object, start_pos);
3590 value = Qnil;
3592 /* Stop the scan at that end position--we assume that all
3593 text properties change there. */
3594 it->stop_charpos = position->charpos;
3596 /* Handle `(left-fringe BITMAP [FACE])'
3597 and `(right-fringe BITMAP [FACE])'. */
3598 if (CONSP (spec)
3599 && (EQ (XCAR (spec), Qleft_fringe)
3600 || EQ (XCAR (spec), Qright_fringe))
3601 && CONSP (XCDR (spec)))
3603 int face_id = DEFAULT_FACE_ID;
3604 int fringe_bitmap;
3606 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3607 /* If we return here, POSITION has been advanced
3608 across the text with this property. */
3609 return 0;
3611 #ifdef HAVE_WINDOW_SYSTEM
3612 value = XCAR (XCDR (spec));
3613 if (!SYMBOLP (value)
3614 || !(fringe_bitmap = lookup_fringe_bitmap (value)))
3615 /* If we return here, POSITION has been advanced
3616 across the text with this property. */
3617 return 0;
3619 if (CONSP (XCDR (XCDR (spec))))
3621 Lisp_Object face_name = XCAR (XCDR (XCDR (spec)));
3622 int face_id2 = lookup_named_face (it->f, face_name, 'A', 0);
3623 if (face_id2 >= 0)
3624 face_id = face_id2;
3627 /* Save current settings of IT so that we can restore them
3628 when we are finished with the glyph property value. */
3630 push_it (it);
3632 it->area = TEXT_AREA;
3633 it->what = IT_IMAGE;
3634 it->image_id = -1; /* no image */
3635 it->position = start_pos;
3636 it->object = NILP (object) ? it->w->buffer : object;
3637 it->method = next_element_from_image;
3638 it->face_id = face_id;
3640 /* Say that we haven't consumed the characters with
3641 `display' property yet. The call to pop_it in
3642 set_iterator_to_next will clean this up. */
3643 *position = start_pos;
3645 if (EQ (XCAR (spec), Qleft_fringe))
3647 it->left_user_fringe_bitmap = fringe_bitmap;
3648 it->left_user_fringe_face_id = face_id;
3650 else
3652 it->right_user_fringe_bitmap = fringe_bitmap;
3653 it->right_user_fringe_face_id = face_id;
3655 #endif /* HAVE_WINDOW_SYSTEM */
3656 return 1;
3659 /* Prepare to handle `((margin left-margin) ...)',
3660 `((margin right-margin) ...)' and `((margin nil) ...)'
3661 prefixes for display specifications. */
3662 location = Qunbound;
3663 if (CONSP (spec) && CONSP (XCAR (spec)))
3665 Lisp_Object tem;
3667 value = XCDR (spec);
3668 if (CONSP (value))
3669 value = XCAR (value);
3671 tem = XCAR (spec);
3672 if (EQ (XCAR (tem), Qmargin)
3673 && (tem = XCDR (tem),
3674 tem = CONSP (tem) ? XCAR (tem) : Qnil,
3675 (NILP (tem)
3676 || EQ (tem, Qleft_margin)
3677 || EQ (tem, Qright_margin))))
3678 location = tem;
3681 if (EQ (location, Qunbound))
3683 location = Qnil;
3684 value = spec;
3687 /* After this point, VALUE is the property after any
3688 margin prefix has been stripped. It must be a string,
3689 an image specification, or `(space ...)'.
3691 LOCATION specifies where to display: `left-margin',
3692 `right-margin' or nil. */
3694 valid_p = (STRINGP (value)
3695 #ifdef HAVE_WINDOW_SYSTEM
3696 || (!FRAME_TERMCAP_P (it->f) && valid_image_p (value))
3697 #endif /* not HAVE_WINDOW_SYSTEM */
3698 || (CONSP (value) && EQ (XCAR (value), Qspace)));
3700 if (valid_p && !display_replaced_before_p)
3702 /* Save current settings of IT so that we can restore them
3703 when we are finished with the glyph property value. */
3704 push_it (it);
3706 if (NILP (location))
3707 it->area = TEXT_AREA;
3708 else if (EQ (location, Qleft_margin))
3709 it->area = LEFT_MARGIN_AREA;
3710 else
3711 it->area = RIGHT_MARGIN_AREA;
3713 if (STRINGP (value))
3715 it->string = value;
3716 it->multibyte_p = STRING_MULTIBYTE (it->string);
3717 it->current.overlay_string_index = -1;
3718 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
3719 it->end_charpos = it->string_nchars = SCHARS (it->string);
3720 it->method = next_element_from_string;
3721 it->stop_charpos = 0;
3722 it->string_from_display_prop_p = 1;
3723 /* Say that we haven't consumed the characters with
3724 `display' property yet. The call to pop_it in
3725 set_iterator_to_next will clean this up. */
3726 *position = start_pos;
3728 else if (CONSP (value) && EQ (XCAR (value), Qspace))
3730 it->method = next_element_from_stretch;
3731 it->object = value;
3732 it->current.pos = it->position = start_pos;
3734 #ifdef HAVE_WINDOW_SYSTEM
3735 else
3737 it->what = IT_IMAGE;
3738 it->image_id = lookup_image (it->f, value);
3739 it->position = start_pos;
3740 it->object = NILP (object) ? it->w->buffer : object;
3741 it->method = next_element_from_image;
3743 /* Say that we haven't consumed the characters with
3744 `display' property yet. The call to pop_it in
3745 set_iterator_to_next will clean this up. */
3746 *position = start_pos;
3748 #endif /* HAVE_WINDOW_SYSTEM */
3750 return 1;
3753 /* Invalid property or property not supported. Restore
3754 POSITION to what it was before. */
3755 *position = start_pos;
3756 return 0;
3760 /* Check if SPEC is a display specification value whose text should be
3761 treated as intangible. */
3763 static int
3764 single_display_spec_intangible_p (prop)
3765 Lisp_Object prop;
3767 /* Skip over `when FORM'. */
3768 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3770 prop = XCDR (prop);
3771 if (!CONSP (prop))
3772 return 0;
3773 prop = XCDR (prop);
3776 if (STRINGP (prop))
3777 return 1;
3779 if (!CONSP (prop))
3780 return 0;
3782 /* Skip over `margin LOCATION'. If LOCATION is in the margins,
3783 we don't need to treat text as intangible. */
3784 if (EQ (XCAR (prop), Qmargin))
3786 prop = XCDR (prop);
3787 if (!CONSP (prop))
3788 return 0;
3790 prop = XCDR (prop);
3791 if (!CONSP (prop)
3792 || EQ (XCAR (prop), Qleft_margin)
3793 || EQ (XCAR (prop), Qright_margin))
3794 return 0;
3797 return (CONSP (prop)
3798 && (EQ (XCAR (prop), Qimage)
3799 || EQ (XCAR (prop), Qspace)));
3803 /* Check if PROP is a display property value whose text should be
3804 treated as intangible. */
3807 display_prop_intangible_p (prop)
3808 Lisp_Object prop;
3810 if (CONSP (prop)
3811 && CONSP (XCAR (prop))
3812 && !EQ (Qmargin, XCAR (XCAR (prop))))
3814 /* A list of sub-properties. */
3815 while (CONSP (prop))
3817 if (single_display_spec_intangible_p (XCAR (prop)))
3818 return 1;
3819 prop = XCDR (prop);
3822 else if (VECTORP (prop))
3824 /* A vector of sub-properties. */
3825 int i;
3826 for (i = 0; i < ASIZE (prop); ++i)
3827 if (single_display_spec_intangible_p (AREF (prop, i)))
3828 return 1;
3830 else
3831 return single_display_spec_intangible_p (prop);
3833 return 0;
3837 /* Return 1 if PROP is a display sub-property value containing STRING. */
3839 static int
3840 single_display_spec_string_p (prop, string)
3841 Lisp_Object prop, string;
3843 if (EQ (string, prop))
3844 return 1;
3846 /* Skip over `when FORM'. */
3847 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3849 prop = XCDR (prop);
3850 if (!CONSP (prop))
3851 return 0;
3852 prop = XCDR (prop);
3855 if (CONSP (prop))
3856 /* Skip over `margin LOCATION'. */
3857 if (EQ (XCAR (prop), Qmargin))
3859 prop = XCDR (prop);
3860 if (!CONSP (prop))
3861 return 0;
3863 prop = XCDR (prop);
3864 if (!CONSP (prop))
3865 return 0;
3868 return CONSP (prop) && EQ (XCAR (prop), string);
3872 /* Return 1 if STRING appears in the `display' property PROP. */
3874 static int
3875 display_prop_string_p (prop, string)
3876 Lisp_Object prop, string;
3878 if (CONSP (prop)
3879 && CONSP (XCAR (prop))
3880 && !EQ (Qmargin, XCAR (XCAR (prop))))
3882 /* A list of sub-properties. */
3883 while (CONSP (prop))
3885 if (single_display_spec_string_p (XCAR (prop), string))
3886 return 1;
3887 prop = XCDR (prop);
3890 else if (VECTORP (prop))
3892 /* A vector of sub-properties. */
3893 int i;
3894 for (i = 0; i < ASIZE (prop); ++i)
3895 if (single_display_spec_string_p (AREF (prop, i), string))
3896 return 1;
3898 else
3899 return single_display_spec_string_p (prop, string);
3901 return 0;
3905 /* Determine from which buffer position in W's buffer STRING comes
3906 from. AROUND_CHARPOS is an approximate position where it could
3907 be from. Value is the buffer position or 0 if it couldn't be
3908 determined.
3910 W's buffer must be current.
3912 This function is necessary because we don't record buffer positions
3913 in glyphs generated from strings (to keep struct glyph small).
3914 This function may only use code that doesn't eval because it is
3915 called asynchronously from note_mouse_highlight. */
3918 string_buffer_position (w, string, around_charpos)
3919 struct window *w;
3920 Lisp_Object string;
3921 int around_charpos;
3923 Lisp_Object limit, prop, pos;
3924 const int MAX_DISTANCE = 1000;
3925 int found = 0;
3927 pos = make_number (around_charpos);
3928 limit = make_number (min (XINT (pos) + MAX_DISTANCE, ZV));
3929 while (!found && !EQ (pos, limit))
3931 prop = Fget_char_property (pos, Qdisplay, Qnil);
3932 if (!NILP (prop) && display_prop_string_p (prop, string))
3933 found = 1;
3934 else
3935 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil, limit);
3938 if (!found)
3940 pos = make_number (around_charpos);
3941 limit = make_number (max (XINT (pos) - MAX_DISTANCE, BEGV));
3942 while (!found && !EQ (pos, limit))
3944 prop = Fget_char_property (pos, Qdisplay, Qnil);
3945 if (!NILP (prop) && display_prop_string_p (prop, string))
3946 found = 1;
3947 else
3948 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
3949 limit);
3953 return found ? XINT (pos) : 0;
3958 /***********************************************************************
3959 `composition' property
3960 ***********************************************************************/
3962 /* Set up iterator IT from `composition' property at its current
3963 position. Called from handle_stop. */
3965 static enum prop_handled
3966 handle_composition_prop (it)
3967 struct it *it;
3969 Lisp_Object prop, string;
3970 int pos, pos_byte, end;
3971 enum prop_handled handled = HANDLED_NORMALLY;
3973 if (STRINGP (it->string))
3975 pos = IT_STRING_CHARPOS (*it);
3976 pos_byte = IT_STRING_BYTEPOS (*it);
3977 string = it->string;
3979 else
3981 pos = IT_CHARPOS (*it);
3982 pos_byte = IT_BYTEPOS (*it);
3983 string = Qnil;
3986 /* If there's a valid composition and point is not inside of the
3987 composition (in the case that the composition is from the current
3988 buffer), draw a glyph composed from the composition components. */
3989 if (find_composition (pos, -1, &pos, &end, &prop, string)
3990 && COMPOSITION_VALID_P (pos, end, prop)
3991 && (STRINGP (it->string) || (PT <= pos || PT >= end)))
3993 int id = get_composition_id (pos, pos_byte, end - pos, prop, string);
3995 if (id >= 0)
3997 it->method = next_element_from_composition;
3998 it->cmp_id = id;
3999 it->cmp_len = COMPOSITION_LENGTH (prop);
4000 /* For a terminal, draw only the first character of the
4001 components. */
4002 it->c = COMPOSITION_GLYPH (composition_table[id], 0);
4003 it->len = (STRINGP (it->string)
4004 ? string_char_to_byte (it->string, end)
4005 : CHAR_TO_BYTE (end)) - pos_byte;
4006 it->stop_charpos = end;
4007 handled = HANDLED_RETURN;
4011 return handled;
4016 /***********************************************************************
4017 Overlay strings
4018 ***********************************************************************/
4020 /* The following structure is used to record overlay strings for
4021 later sorting in load_overlay_strings. */
4023 struct overlay_entry
4025 Lisp_Object overlay;
4026 Lisp_Object string;
4027 int priority;
4028 int after_string_p;
4032 /* Set up iterator IT from overlay strings at its current position.
4033 Called from handle_stop. */
4035 static enum prop_handled
4036 handle_overlay_change (it)
4037 struct it *it;
4039 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
4040 return HANDLED_RECOMPUTE_PROPS;
4041 else
4042 return HANDLED_NORMALLY;
4046 /* Set up the next overlay string for delivery by IT, if there is an
4047 overlay string to deliver. Called by set_iterator_to_next when the
4048 end of the current overlay string is reached. If there are more
4049 overlay strings to display, IT->string and
4050 IT->current.overlay_string_index are set appropriately here.
4051 Otherwise IT->string is set to nil. */
4053 static void
4054 next_overlay_string (it)
4055 struct it *it;
4057 ++it->current.overlay_string_index;
4058 if (it->current.overlay_string_index == it->n_overlay_strings)
4060 /* No more overlay strings. Restore IT's settings to what
4061 they were before overlay strings were processed, and
4062 continue to deliver from current_buffer. */
4063 int display_ellipsis_p = it->stack[it->sp - 1].display_ellipsis_p;
4065 pop_it (it);
4066 xassert (it->stop_charpos >= BEGV
4067 && it->stop_charpos <= it->end_charpos);
4068 it->string = Qnil;
4069 it->current.overlay_string_index = -1;
4070 SET_TEXT_POS (it->current.string_pos, -1, -1);
4071 it->n_overlay_strings = 0;
4072 it->method = next_element_from_buffer;
4074 /* If we're at the end of the buffer, record that we have
4075 processed the overlay strings there already, so that
4076 next_element_from_buffer doesn't try it again. */
4077 if (IT_CHARPOS (*it) >= it->end_charpos)
4078 it->overlay_strings_at_end_processed_p = 1;
4080 /* If we have to display `...' for invisible text, set
4081 the iterator up for that. */
4082 if (display_ellipsis_p)
4083 setup_for_ellipsis (it, 0);
4085 else
4087 /* There are more overlay strings to process. If
4088 IT->current.overlay_string_index has advanced to a position
4089 where we must load IT->overlay_strings with more strings, do
4090 it. */
4091 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
4093 if (it->current.overlay_string_index && i == 0)
4094 load_overlay_strings (it, 0);
4096 /* Initialize IT to deliver display elements from the overlay
4097 string. */
4098 it->string = it->overlay_strings[i];
4099 it->multibyte_p = STRING_MULTIBYTE (it->string);
4100 SET_TEXT_POS (it->current.string_pos, 0, 0);
4101 it->method = next_element_from_string;
4102 it->stop_charpos = 0;
4105 CHECK_IT (it);
4109 /* Compare two overlay_entry structures E1 and E2. Used as a
4110 comparison function for qsort in load_overlay_strings. Overlay
4111 strings for the same position are sorted so that
4113 1. All after-strings come in front of before-strings, except
4114 when they come from the same overlay.
4116 2. Within after-strings, strings are sorted so that overlay strings
4117 from overlays with higher priorities come first.
4119 2. Within before-strings, strings are sorted so that overlay
4120 strings from overlays with higher priorities come last.
4122 Value is analogous to strcmp. */
4125 static int
4126 compare_overlay_entries (e1, e2)
4127 void *e1, *e2;
4129 struct overlay_entry *entry1 = (struct overlay_entry *) e1;
4130 struct overlay_entry *entry2 = (struct overlay_entry *) e2;
4131 int result;
4133 if (entry1->after_string_p != entry2->after_string_p)
4135 /* Let after-strings appear in front of before-strings if
4136 they come from different overlays. */
4137 if (EQ (entry1->overlay, entry2->overlay))
4138 result = entry1->after_string_p ? 1 : -1;
4139 else
4140 result = entry1->after_string_p ? -1 : 1;
4142 else if (entry1->after_string_p)
4143 /* After-strings sorted in order of decreasing priority. */
4144 result = entry2->priority - entry1->priority;
4145 else
4146 /* Before-strings sorted in order of increasing priority. */
4147 result = entry1->priority - entry2->priority;
4149 return result;
4153 /* Load the vector IT->overlay_strings with overlay strings from IT's
4154 current buffer position, or from CHARPOS if that is > 0. Set
4155 IT->n_overlays to the total number of overlay strings found.
4157 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
4158 a time. On entry into load_overlay_strings,
4159 IT->current.overlay_string_index gives the number of overlay
4160 strings that have already been loaded by previous calls to this
4161 function.
4163 IT->add_overlay_start contains an additional overlay start
4164 position to consider for taking overlay strings from, if non-zero.
4165 This position comes into play when the overlay has an `invisible'
4166 property, and both before and after-strings. When we've skipped to
4167 the end of the overlay, because of its `invisible' property, we
4168 nevertheless want its before-string to appear.
4169 IT->add_overlay_start will contain the overlay start position
4170 in this case.
4172 Overlay strings are sorted so that after-string strings come in
4173 front of before-string strings. Within before and after-strings,
4174 strings are sorted by overlay priority. See also function
4175 compare_overlay_entries. */
4177 static void
4178 load_overlay_strings (it, charpos)
4179 struct it *it;
4180 int charpos;
4182 extern Lisp_Object Qafter_string, Qbefore_string, Qwindow, Qpriority;
4183 Lisp_Object overlay, window, str, invisible;
4184 struct Lisp_Overlay *ov;
4185 int start, end;
4186 int size = 20;
4187 int n = 0, i, j, invis_p;
4188 struct overlay_entry *entries
4189 = (struct overlay_entry *) alloca (size * sizeof *entries);
4191 if (charpos <= 0)
4192 charpos = IT_CHARPOS (*it);
4194 /* Append the overlay string STRING of overlay OVERLAY to vector
4195 `entries' which has size `size' and currently contains `n'
4196 elements. AFTER_P non-zero means STRING is an after-string of
4197 OVERLAY. */
4198 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
4199 do \
4201 Lisp_Object priority; \
4203 if (n == size) \
4205 int new_size = 2 * size; \
4206 struct overlay_entry *old = entries; \
4207 entries = \
4208 (struct overlay_entry *) alloca (new_size \
4209 * sizeof *entries); \
4210 bcopy (old, entries, size * sizeof *entries); \
4211 size = new_size; \
4214 entries[n].string = (STRING); \
4215 entries[n].overlay = (OVERLAY); \
4216 priority = Foverlay_get ((OVERLAY), Qpriority); \
4217 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
4218 entries[n].after_string_p = (AFTER_P); \
4219 ++n; \
4221 while (0)
4223 /* Process overlay before the overlay center. */
4224 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
4226 XSETMISC (overlay, ov);
4227 xassert (OVERLAYP (overlay));
4228 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4229 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4231 if (end < charpos)
4232 break;
4234 /* Skip this overlay if it doesn't start or end at IT's current
4235 position. */
4236 if (end != charpos && start != charpos)
4237 continue;
4239 /* Skip this overlay if it doesn't apply to IT->w. */
4240 window = Foverlay_get (overlay, Qwindow);
4241 if (WINDOWP (window) && XWINDOW (window) != it->w)
4242 continue;
4244 /* If the text ``under'' the overlay is invisible, both before-
4245 and after-strings from this overlay are visible; start and
4246 end position are indistinguishable. */
4247 invisible = Foverlay_get (overlay, Qinvisible);
4248 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4250 /* If overlay has a non-empty before-string, record it. */
4251 if ((start == charpos || (end == charpos && invis_p))
4252 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4253 && SCHARS (str))
4254 RECORD_OVERLAY_STRING (overlay, str, 0);
4256 /* If overlay has a non-empty after-string, record it. */
4257 if ((end == charpos || (start == charpos && invis_p))
4258 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4259 && SCHARS (str))
4260 RECORD_OVERLAY_STRING (overlay, str, 1);
4263 /* Process overlays after the overlay center. */
4264 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
4266 XSETMISC (overlay, ov);
4267 xassert (OVERLAYP (overlay));
4268 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4269 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4271 if (start > charpos)
4272 break;
4274 /* Skip this overlay if it doesn't start or end at IT's current
4275 position. */
4276 if (end != charpos && start != charpos)
4277 continue;
4279 /* Skip this overlay if it doesn't apply to IT->w. */
4280 window = Foverlay_get (overlay, Qwindow);
4281 if (WINDOWP (window) && XWINDOW (window) != it->w)
4282 continue;
4284 /* If the text ``under'' the overlay is invisible, it has a zero
4285 dimension, and both before- and after-strings apply. */
4286 invisible = Foverlay_get (overlay, Qinvisible);
4287 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4289 /* If overlay has a non-empty before-string, record it. */
4290 if ((start == charpos || (end == charpos && invis_p))
4291 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4292 && SCHARS (str))
4293 RECORD_OVERLAY_STRING (overlay, str, 0);
4295 /* If overlay has a non-empty after-string, record it. */
4296 if ((end == charpos || (start == charpos && invis_p))
4297 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4298 && SCHARS (str))
4299 RECORD_OVERLAY_STRING (overlay, str, 1);
4302 #undef RECORD_OVERLAY_STRING
4304 /* Sort entries. */
4305 if (n > 1)
4306 qsort (entries, n, sizeof *entries, compare_overlay_entries);
4308 /* Record the total number of strings to process. */
4309 it->n_overlay_strings = n;
4311 /* IT->current.overlay_string_index is the number of overlay strings
4312 that have already been consumed by IT. Copy some of the
4313 remaining overlay strings to IT->overlay_strings. */
4314 i = 0;
4315 j = it->current.overlay_string_index;
4316 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
4317 it->overlay_strings[i++] = entries[j++].string;
4319 CHECK_IT (it);
4323 /* Get the first chunk of overlay strings at IT's current buffer
4324 position, or at CHARPOS if that is > 0. Value is non-zero if at
4325 least one overlay string was found. */
4327 static int
4328 get_overlay_strings (it, charpos)
4329 struct it *it;
4330 int charpos;
4332 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
4333 process. This fills IT->overlay_strings with strings, and sets
4334 IT->n_overlay_strings to the total number of strings to process.
4335 IT->pos.overlay_string_index has to be set temporarily to zero
4336 because load_overlay_strings needs this; it must be set to -1
4337 when no overlay strings are found because a zero value would
4338 indicate a position in the first overlay string. */
4339 it->current.overlay_string_index = 0;
4340 load_overlay_strings (it, charpos);
4342 /* If we found overlay strings, set up IT to deliver display
4343 elements from the first one. Otherwise set up IT to deliver
4344 from current_buffer. */
4345 if (it->n_overlay_strings)
4347 /* Make sure we know settings in current_buffer, so that we can
4348 restore meaningful values when we're done with the overlay
4349 strings. */
4350 compute_stop_pos (it);
4351 xassert (it->face_id >= 0);
4353 /* Save IT's settings. They are restored after all overlay
4354 strings have been processed. */
4355 xassert (it->sp == 0);
4356 push_it (it);
4358 /* Set up IT to deliver display elements from the first overlay
4359 string. */
4360 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
4361 it->string = it->overlay_strings[0];
4362 it->stop_charpos = 0;
4363 xassert (STRINGP (it->string));
4364 it->end_charpos = SCHARS (it->string);
4365 it->multibyte_p = STRING_MULTIBYTE (it->string);
4366 it->method = next_element_from_string;
4368 else
4370 it->string = Qnil;
4371 it->current.overlay_string_index = -1;
4372 it->method = next_element_from_buffer;
4375 CHECK_IT (it);
4377 /* Value is non-zero if we found at least one overlay string. */
4378 return STRINGP (it->string);
4383 /***********************************************************************
4384 Saving and restoring state
4385 ***********************************************************************/
4387 /* Save current settings of IT on IT->stack. Called, for example,
4388 before setting up IT for an overlay string, to be able to restore
4389 IT's settings to what they were after the overlay string has been
4390 processed. */
4392 static void
4393 push_it (it)
4394 struct it *it;
4396 struct iterator_stack_entry *p;
4398 xassert (it->sp < 2);
4399 p = it->stack + it->sp;
4401 p->stop_charpos = it->stop_charpos;
4402 xassert (it->face_id >= 0);
4403 p->face_id = it->face_id;
4404 p->string = it->string;
4405 p->pos = it->current;
4406 p->end_charpos = it->end_charpos;
4407 p->string_nchars = it->string_nchars;
4408 p->area = it->area;
4409 p->multibyte_p = it->multibyte_p;
4410 p->slice = it->slice;
4411 p->space_width = it->space_width;
4412 p->font_height = it->font_height;
4413 p->voffset = it->voffset;
4414 p->string_from_display_prop_p = it->string_from_display_prop_p;
4415 p->display_ellipsis_p = 0;
4416 ++it->sp;
4420 /* Restore IT's settings from IT->stack. Called, for example, when no
4421 more overlay strings must be processed, and we return to delivering
4422 display elements from a buffer, or when the end of a string from a
4423 `display' property is reached and we return to delivering display
4424 elements from an overlay string, or from a buffer. */
4426 static void
4427 pop_it (it)
4428 struct it *it;
4430 struct iterator_stack_entry *p;
4432 xassert (it->sp > 0);
4433 --it->sp;
4434 p = it->stack + it->sp;
4435 it->stop_charpos = p->stop_charpos;
4436 it->face_id = p->face_id;
4437 it->string = p->string;
4438 it->current = p->pos;
4439 it->end_charpos = p->end_charpos;
4440 it->string_nchars = p->string_nchars;
4441 it->area = p->area;
4442 it->multibyte_p = p->multibyte_p;
4443 it->slice = p->slice;
4444 it->space_width = p->space_width;
4445 it->font_height = p->font_height;
4446 it->voffset = p->voffset;
4447 it->string_from_display_prop_p = p->string_from_display_prop_p;
4452 /***********************************************************************
4453 Moving over lines
4454 ***********************************************************************/
4456 /* Set IT's current position to the previous line start. */
4458 static void
4459 back_to_previous_line_start (it)
4460 struct it *it;
4462 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
4463 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
4467 /* Move IT to the next line start.
4469 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
4470 we skipped over part of the text (as opposed to moving the iterator
4471 continuously over the text). Otherwise, don't change the value
4472 of *SKIPPED_P.
4474 Newlines may come from buffer text, overlay strings, or strings
4475 displayed via the `display' property. That's the reason we can't
4476 simply use find_next_newline_no_quit.
4478 Note that this function may not skip over invisible text that is so
4479 because of text properties and immediately follows a newline. If
4480 it would, function reseat_at_next_visible_line_start, when called
4481 from set_iterator_to_next, would effectively make invisible
4482 characters following a newline part of the wrong glyph row, which
4483 leads to wrong cursor motion. */
4485 static int
4486 forward_to_next_line_start (it, skipped_p)
4487 struct it *it;
4488 int *skipped_p;
4490 int old_selective, newline_found_p, n;
4491 const int MAX_NEWLINE_DISTANCE = 500;
4493 /* If already on a newline, just consume it to avoid unintended
4494 skipping over invisible text below. */
4495 if (it->what == IT_CHARACTER
4496 && it->c == '\n'
4497 && CHARPOS (it->position) == IT_CHARPOS (*it))
4499 set_iterator_to_next (it, 0);
4500 it->c = 0;
4501 return 1;
4504 /* Don't handle selective display in the following. It's (a)
4505 unnecessary because it's done by the caller, and (b) leads to an
4506 infinite recursion because next_element_from_ellipsis indirectly
4507 calls this function. */
4508 old_selective = it->selective;
4509 it->selective = 0;
4511 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
4512 from buffer text. */
4513 for (n = newline_found_p = 0;
4514 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
4515 n += STRINGP (it->string) ? 0 : 1)
4517 if (!get_next_display_element (it))
4518 return 0;
4519 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
4520 set_iterator_to_next (it, 0);
4523 /* If we didn't find a newline near enough, see if we can use a
4524 short-cut. */
4525 if (!newline_found_p)
4527 int start = IT_CHARPOS (*it);
4528 int limit = find_next_newline_no_quit (start, 1);
4529 Lisp_Object pos;
4531 xassert (!STRINGP (it->string));
4533 /* If there isn't any `display' property in sight, and no
4534 overlays, we can just use the position of the newline in
4535 buffer text. */
4536 if (it->stop_charpos >= limit
4537 || ((pos = Fnext_single_property_change (make_number (start),
4538 Qdisplay,
4539 Qnil, make_number (limit)),
4540 NILP (pos))
4541 && next_overlay_change (start) == ZV))
4543 IT_CHARPOS (*it) = limit;
4544 IT_BYTEPOS (*it) = CHAR_TO_BYTE (limit);
4545 *skipped_p = newline_found_p = 1;
4547 else
4549 while (get_next_display_element (it)
4550 && !newline_found_p)
4552 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
4553 set_iterator_to_next (it, 0);
4558 it->selective = old_selective;
4559 return newline_found_p;
4563 /* Set IT's current position to the previous visible line start. Skip
4564 invisible text that is so either due to text properties or due to
4565 selective display. Caution: this does not change IT->current_x and
4566 IT->hpos. */
4568 static void
4569 back_to_previous_visible_line_start (it)
4570 struct it *it;
4572 int visible_p = 0;
4574 /* Go back one newline if not on BEGV already. */
4575 if (IT_CHARPOS (*it) > BEGV)
4576 back_to_previous_line_start (it);
4578 /* Move over lines that are invisible because of selective display
4579 or text properties. */
4580 while (IT_CHARPOS (*it) > BEGV
4581 && !visible_p)
4583 visible_p = 1;
4585 /* If selective > 0, then lines indented more than that values
4586 are invisible. */
4587 if (it->selective > 0
4588 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
4589 (double) it->selective)) /* iftc */
4590 visible_p = 0;
4591 else
4593 Lisp_Object prop;
4595 /* Check the newline before point for invisibility. */
4596 prop = Fget_char_property (make_number (IT_CHARPOS (*it) - 1),
4597 Qinvisible, it->window);
4598 if (TEXT_PROP_MEANS_INVISIBLE (prop))
4599 visible_p = 0;
4602 #if 0
4603 /* Commenting this out fixes the bug described in
4604 http://www.math.ku.dk/~larsh/emacs/emacs-loops-on-large-images/test-case.txt. */
4605 if (visible_p)
4607 struct it it2 = *it;
4609 if (handle_display_prop (&it2) == HANDLED_RETURN)
4610 visible_p = 0;
4612 #endif
4614 /* Back one more newline if the current one is invisible. */
4615 if (!visible_p)
4616 back_to_previous_line_start (it);
4619 xassert (IT_CHARPOS (*it) >= BEGV);
4620 xassert (IT_CHARPOS (*it) == BEGV
4621 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
4622 CHECK_IT (it);
4626 /* Reseat iterator IT at the previous visible line start. Skip
4627 invisible text that is so either due to text properties or due to
4628 selective display. At the end, update IT's overlay information,
4629 face information etc. */
4631 void
4632 reseat_at_previous_visible_line_start (it)
4633 struct it *it;
4635 back_to_previous_visible_line_start (it);
4636 reseat (it, it->current.pos, 1);
4637 CHECK_IT (it);
4641 /* Reseat iterator IT on the next visible line start in the current
4642 buffer. ON_NEWLINE_P non-zero means position IT on the newline
4643 preceding the line start. Skip over invisible text that is so
4644 because of selective display. Compute faces, overlays etc at the
4645 new position. Note that this function does not skip over text that
4646 is invisible because of text properties. */
4648 static void
4649 reseat_at_next_visible_line_start (it, on_newline_p)
4650 struct it *it;
4651 int on_newline_p;
4653 int newline_found_p, skipped_p = 0;
4655 newline_found_p = forward_to_next_line_start (it, &skipped_p);
4657 /* Skip over lines that are invisible because they are indented
4658 more than the value of IT->selective. */
4659 if (it->selective > 0)
4660 while (IT_CHARPOS (*it) < ZV
4661 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
4662 (double) it->selective)) /* iftc */
4664 xassert (FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
4665 newline_found_p = forward_to_next_line_start (it, &skipped_p);
4668 /* Position on the newline if that's what's requested. */
4669 if (on_newline_p && newline_found_p)
4671 if (STRINGP (it->string))
4673 if (IT_STRING_CHARPOS (*it) > 0)
4675 --IT_STRING_CHARPOS (*it);
4676 --IT_STRING_BYTEPOS (*it);
4679 else if (IT_CHARPOS (*it) > BEGV)
4681 --IT_CHARPOS (*it);
4682 --IT_BYTEPOS (*it);
4683 reseat (it, it->current.pos, 0);
4686 else if (skipped_p)
4687 reseat (it, it->current.pos, 0);
4689 CHECK_IT (it);
4694 /***********************************************************************
4695 Changing an iterator's position
4696 ***********************************************************************/
4698 /* Change IT's current position to POS in current_buffer. If FORCE_P
4699 is non-zero, always check for text properties at the new position.
4700 Otherwise, text properties are only looked up if POS >=
4701 IT->check_charpos of a property. */
4703 static void
4704 reseat (it, pos, force_p)
4705 struct it *it;
4706 struct text_pos pos;
4707 int force_p;
4709 int original_pos = IT_CHARPOS (*it);
4711 reseat_1 (it, pos, 0);
4713 /* Determine where to check text properties. Avoid doing it
4714 where possible because text property lookup is very expensive. */
4715 if (force_p
4716 || CHARPOS (pos) > it->stop_charpos
4717 || CHARPOS (pos) < original_pos)
4718 handle_stop (it);
4720 CHECK_IT (it);
4724 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
4725 IT->stop_pos to POS, also. */
4727 static void
4728 reseat_1 (it, pos, set_stop_p)
4729 struct it *it;
4730 struct text_pos pos;
4731 int set_stop_p;
4733 /* Don't call this function when scanning a C string. */
4734 xassert (it->s == NULL);
4736 /* POS must be a reasonable value. */
4737 xassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
4739 it->current.pos = it->position = pos;
4740 XSETBUFFER (it->object, current_buffer);
4741 it->end_charpos = ZV;
4742 it->dpvec = NULL;
4743 it->current.dpvec_index = -1;
4744 it->current.overlay_string_index = -1;
4745 IT_STRING_CHARPOS (*it) = -1;
4746 IT_STRING_BYTEPOS (*it) = -1;
4747 it->string = Qnil;
4748 it->method = next_element_from_buffer;
4749 /* RMS: I added this to fix a bug in move_it_vertically_backward
4750 where it->area continued to relate to the starting point
4751 for the backward motion. Bug report from
4752 Nick Roberts <nick@nick.uklinux.net> on 19 May 2003.
4753 However, I am not sure whether reseat still does the right thing
4754 in general after this change. */
4755 it->area = TEXT_AREA;
4756 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
4757 it->sp = 0;
4758 it->face_before_selective_p = 0;
4760 if (set_stop_p)
4761 it->stop_charpos = CHARPOS (pos);
4765 /* Set up IT for displaying a string, starting at CHARPOS in window W.
4766 If S is non-null, it is a C string to iterate over. Otherwise,
4767 STRING gives a Lisp string to iterate over.
4769 If PRECISION > 0, don't return more then PRECISION number of
4770 characters from the string.
4772 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
4773 characters have been returned. FIELD_WIDTH < 0 means an infinite
4774 field width.
4776 MULTIBYTE = 0 means disable processing of multibyte characters,
4777 MULTIBYTE > 0 means enable it,
4778 MULTIBYTE < 0 means use IT->multibyte_p.
4780 IT must be initialized via a prior call to init_iterator before
4781 calling this function. */
4783 static void
4784 reseat_to_string (it, s, string, charpos, precision, field_width, multibyte)
4785 struct it *it;
4786 unsigned char *s;
4787 Lisp_Object string;
4788 int charpos;
4789 int precision, field_width, multibyte;
4791 /* No region in strings. */
4792 it->region_beg_charpos = it->region_end_charpos = -1;
4794 /* No text property checks performed by default, but see below. */
4795 it->stop_charpos = -1;
4797 /* Set iterator position and end position. */
4798 bzero (&it->current, sizeof it->current);
4799 it->current.overlay_string_index = -1;
4800 it->current.dpvec_index = -1;
4801 xassert (charpos >= 0);
4803 /* If STRING is specified, use its multibyteness, otherwise use the
4804 setting of MULTIBYTE, if specified. */
4805 if (multibyte >= 0)
4806 it->multibyte_p = multibyte > 0;
4808 if (s == NULL)
4810 xassert (STRINGP (string));
4811 it->string = string;
4812 it->s = NULL;
4813 it->end_charpos = it->string_nchars = SCHARS (string);
4814 it->method = next_element_from_string;
4815 it->current.string_pos = string_pos (charpos, string);
4817 else
4819 it->s = s;
4820 it->string = Qnil;
4822 /* Note that we use IT->current.pos, not it->current.string_pos,
4823 for displaying C strings. */
4824 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
4825 if (it->multibyte_p)
4827 it->current.pos = c_string_pos (charpos, s, 1);
4828 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
4830 else
4832 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
4833 it->end_charpos = it->string_nchars = strlen (s);
4836 it->method = next_element_from_c_string;
4839 /* PRECISION > 0 means don't return more than PRECISION characters
4840 from the string. */
4841 if (precision > 0 && it->end_charpos - charpos > precision)
4842 it->end_charpos = it->string_nchars = charpos + precision;
4844 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
4845 characters have been returned. FIELD_WIDTH == 0 means don't pad,
4846 FIELD_WIDTH < 0 means infinite field width. This is useful for
4847 padding with `-' at the end of a mode line. */
4848 if (field_width < 0)
4849 field_width = INFINITY;
4850 if (field_width > it->end_charpos - charpos)
4851 it->end_charpos = charpos + field_width;
4853 /* Use the standard display table for displaying strings. */
4854 if (DISP_TABLE_P (Vstandard_display_table))
4855 it->dp = XCHAR_TABLE (Vstandard_display_table);
4857 it->stop_charpos = charpos;
4858 CHECK_IT (it);
4863 /***********************************************************************
4864 Iteration
4865 ***********************************************************************/
4867 /* Load IT's display element fields with information about the next
4868 display element from the current position of IT. Value is zero if
4869 end of buffer (or C string) is reached. */
4872 get_next_display_element (it)
4873 struct it *it;
4875 /* Non-zero means that we found a display element. Zero means that
4876 we hit the end of what we iterate over. Performance note: the
4877 function pointer `method' used here turns out to be faster than
4878 using a sequence of if-statements. */
4879 int success_p;
4881 get_next:
4882 success_p = (*it->method) (it);
4884 if (it->what == IT_CHARACTER)
4886 /* Map via display table or translate control characters.
4887 IT->c, IT->len etc. have been set to the next character by
4888 the function call above. If we have a display table, and it
4889 contains an entry for IT->c, translate it. Don't do this if
4890 IT->c itself comes from a display table, otherwise we could
4891 end up in an infinite recursion. (An alternative could be to
4892 count the recursion depth of this function and signal an
4893 error when a certain maximum depth is reached.) Is it worth
4894 it? */
4895 if (success_p && it->dpvec == NULL)
4897 Lisp_Object dv;
4899 if (it->dp
4900 && (dv = DISP_CHAR_VECTOR (it->dp, it->c),
4901 VECTORP (dv)))
4903 struct Lisp_Vector *v = XVECTOR (dv);
4905 /* Return the first character from the display table
4906 entry, if not empty. If empty, don't display the
4907 current character. */
4908 if (v->size)
4910 it->dpvec_char_len = it->len;
4911 it->dpvec = v->contents;
4912 it->dpend = v->contents + v->size;
4913 it->current.dpvec_index = 0;
4914 it->saved_face_id = it->face_id;
4915 it->method = next_element_from_display_vector;
4916 it->ellipsis_p = 0;
4918 else
4920 set_iterator_to_next (it, 0);
4922 goto get_next;
4925 /* Translate control characters into `\003' or `^C' form.
4926 Control characters coming from a display table entry are
4927 currently not translated because we use IT->dpvec to hold
4928 the translation. This could easily be changed but I
4929 don't believe that it is worth doing.
4931 If it->multibyte_p is nonzero, eight-bit characters and
4932 non-printable multibyte characters are also translated to
4933 octal form.
4935 If it->multibyte_p is zero, eight-bit characters that
4936 don't have corresponding multibyte char code are also
4937 translated to octal form. */
4938 else if ((it->c < ' '
4939 && (it->area != TEXT_AREA
4940 /* In mode line, treat \n like other crl chars. */
4941 || (it->c != '\n'
4942 && it->glyph_row && it->glyph_row->mode_line_p)
4943 || (it->c != '\n' && it->c != '\t')))
4944 || (it->multibyte_p
4945 ? ((it->c >= 127
4946 && it->len == 1)
4947 || !CHAR_PRINTABLE_P (it->c)
4948 || it->c == 0x8ad
4949 || it->c == 0x8a0)
4950 : (it->c >= 127
4951 && (!unibyte_display_via_language_environment
4952 || it->c == unibyte_char_to_multibyte (it->c)))))
4954 /* IT->c is a control character which must be displayed
4955 either as '\003' or as `^C' where the '\\' and '^'
4956 can be defined in the display table. Fill
4957 IT->ctl_chars with glyphs for what we have to
4958 display. Then, set IT->dpvec to these glyphs. */
4959 GLYPH g;
4960 int ctl_len;
4961 int face_id = escape_glyph_face;
4963 /* Find the face id if `escape-glyph' unless we recently did. */
4964 if (face_id < 0)
4966 Lisp_Object tem = Fget (Qescape_glyph, Qface);
4967 if (INTEGERP (tem))
4968 face_id = XINT (tem);
4969 else
4970 face_id = 0;
4971 /* If there's overflow, use 0 instead. */
4972 if (FAST_GLYPH_FACE (FAST_MAKE_GLYPH (0, face_id)) != face_id)
4973 face_id = 0;
4974 escape_glyph_face = face_id;
4977 if (it->c < 128 && it->ctl_arrow_p)
4979 /* Set IT->ctl_chars[0] to the glyph for `^'. */
4980 if (it->dp
4981 && INTEGERP (DISP_CTRL_GLYPH (it->dp))
4982 && GLYPH_CHAR_VALID_P (XINT (DISP_CTRL_GLYPH (it->dp))))
4983 g = XINT (DISP_CTRL_GLYPH (it->dp));
4984 else
4985 g = FAST_MAKE_GLYPH ('^', face_id);
4986 XSETINT (it->ctl_chars[0], g);
4988 g = FAST_MAKE_GLYPH (it->c ^ 0100, face_id);
4989 XSETINT (it->ctl_chars[1], g);
4990 ctl_len = 2;
4992 else if (it->c == 0x8a0 || it->c == 0x8ad)
4994 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
4995 if (it->dp
4996 && INTEGERP (DISP_ESCAPE_GLYPH (it->dp))
4997 && GLYPH_CHAR_VALID_P (XINT (DISP_ESCAPE_GLYPH (it->dp))))
4998 g = XINT (DISP_ESCAPE_GLYPH (it->dp));
4999 else
5000 g = FAST_MAKE_GLYPH ('\\', face_id);
5001 XSETINT (it->ctl_chars[0], g);
5003 g = FAST_MAKE_GLYPH (it->c == 0x8ad ? '-' : ' ', face_id);
5004 XSETINT (it->ctl_chars[1], g);
5005 ctl_len = 2;
5007 else
5009 unsigned char str[MAX_MULTIBYTE_LENGTH];
5010 int len;
5011 int i;
5012 GLYPH escape_glyph;
5014 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
5015 if (it->dp
5016 && INTEGERP (DISP_ESCAPE_GLYPH (it->dp))
5017 && GLYPH_CHAR_VALID_P (XFASTINT (DISP_ESCAPE_GLYPH (it->dp))))
5018 escape_glyph = XFASTINT (DISP_ESCAPE_GLYPH (it->dp));
5019 else
5020 escape_glyph = FAST_MAKE_GLYPH ('\\', face_id);
5022 if (SINGLE_BYTE_CHAR_P (it->c))
5023 str[0] = it->c, len = 1;
5024 else
5026 len = CHAR_STRING_NO_SIGNAL (it->c, str);
5027 if (len < 0)
5029 /* It's an invalid character, which
5030 shouldn't happen actually, but due to
5031 bugs it may happen. Let's print the char
5032 as is, there's not much meaningful we can
5033 do with it. */
5034 str[0] = it->c;
5035 str[1] = it->c >> 8;
5036 str[2] = it->c >> 16;
5037 str[3] = it->c >> 24;
5038 len = 4;
5042 for (i = 0; i < len; i++)
5044 XSETINT (it->ctl_chars[i * 4], escape_glyph);
5045 /* Insert three more glyphs into IT->ctl_chars for
5046 the octal display of the character. */
5047 g = FAST_MAKE_GLYPH (((str[i] >> 6) & 7) + '0',
5048 face_id);
5049 XSETINT (it->ctl_chars[i * 4 + 1], g);
5050 g = FAST_MAKE_GLYPH (((str[i] >> 3) & 7) + '0',
5051 face_id);
5052 XSETINT (it->ctl_chars[i * 4 + 2], g);
5053 g = FAST_MAKE_GLYPH ((str[i] & 7) + '0',
5054 face_id);
5055 XSETINT (it->ctl_chars[i * 4 + 3], g);
5057 ctl_len = len * 4;
5060 /* Set up IT->dpvec and return first character from it. */
5061 it->dpvec_char_len = it->len;
5062 it->dpvec = it->ctl_chars;
5063 it->dpend = it->dpvec + ctl_len;
5064 it->current.dpvec_index = 0;
5065 it->saved_face_id = it->face_id;
5066 it->method = next_element_from_display_vector;
5067 it->ellipsis_p = 0;
5068 goto get_next;
5072 /* Adjust face id for a multibyte character. There are no
5073 multibyte character in unibyte text. */
5074 if (it->multibyte_p
5075 && success_p
5076 && FRAME_WINDOW_P (it->f))
5078 struct face *face = FACE_FROM_ID (it->f, it->face_id);
5079 it->face_id = FACE_FOR_CHAR (it->f, face, it->c);
5083 /* Is this character the last one of a run of characters with
5084 box? If yes, set IT->end_of_box_run_p to 1. */
5085 if (it->face_box_p
5086 && it->s == NULL)
5088 int face_id;
5089 struct face *face;
5091 it->end_of_box_run_p
5092 = ((face_id = face_after_it_pos (it),
5093 face_id != it->face_id)
5094 && (face = FACE_FROM_ID (it->f, face_id),
5095 face->box == FACE_NO_BOX));
5098 /* Value is 0 if end of buffer or string reached. */
5099 return success_p;
5103 /* Move IT to the next display element.
5105 RESEAT_P non-zero means if called on a newline in buffer text,
5106 skip to the next visible line start.
5108 Functions get_next_display_element and set_iterator_to_next are
5109 separate because I find this arrangement easier to handle than a
5110 get_next_display_element function that also increments IT's
5111 position. The way it is we can first look at an iterator's current
5112 display element, decide whether it fits on a line, and if it does,
5113 increment the iterator position. The other way around we probably
5114 would either need a flag indicating whether the iterator has to be
5115 incremented the next time, or we would have to implement a
5116 decrement position function which would not be easy to write. */
5118 void
5119 set_iterator_to_next (it, reseat_p)
5120 struct it *it;
5121 int reseat_p;
5123 /* Reset flags indicating start and end of a sequence of characters
5124 with box. Reset them at the start of this function because
5125 moving the iterator to a new position might set them. */
5126 it->start_of_box_run_p = it->end_of_box_run_p = 0;
5128 if (it->method == next_element_from_buffer)
5130 /* The current display element of IT is a character from
5131 current_buffer. Advance in the buffer, and maybe skip over
5132 invisible lines that are so because of selective display. */
5133 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
5134 reseat_at_next_visible_line_start (it, 0);
5135 else
5137 xassert (it->len != 0);
5138 IT_BYTEPOS (*it) += it->len;
5139 IT_CHARPOS (*it) += 1;
5140 xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
5143 else if (it->method == next_element_from_composition)
5145 xassert (it->cmp_id >= 0 && it ->cmp_id < n_compositions);
5146 if (STRINGP (it->string))
5148 IT_STRING_BYTEPOS (*it) += it->len;
5149 IT_STRING_CHARPOS (*it) += it->cmp_len;
5150 it->method = next_element_from_string;
5151 goto consider_string_end;
5153 else
5155 IT_BYTEPOS (*it) += it->len;
5156 IT_CHARPOS (*it) += it->cmp_len;
5157 it->method = next_element_from_buffer;
5160 else if (it->method == next_element_from_c_string)
5162 /* Current display element of IT is from a C string. */
5163 IT_BYTEPOS (*it) += it->len;
5164 IT_CHARPOS (*it) += 1;
5166 else if (it->method == next_element_from_display_vector)
5168 /* Current display element of IT is from a display table entry.
5169 Advance in the display table definition. Reset it to null if
5170 end reached, and continue with characters from buffers/
5171 strings. */
5172 ++it->current.dpvec_index;
5174 /* Restore face of the iterator to what they were before the
5175 display vector entry (these entries may contain faces). */
5176 it->face_id = it->saved_face_id;
5178 if (it->dpvec + it->current.dpvec_index == it->dpend)
5180 if (it->s)
5181 it->method = next_element_from_c_string;
5182 else if (STRINGP (it->string))
5183 it->method = next_element_from_string;
5184 else
5185 it->method = next_element_from_buffer;
5187 it->dpvec = NULL;
5188 it->current.dpvec_index = -1;
5190 /* Recheck faces after display vector */
5191 it->stop_charpos = 0;
5193 /* Skip over characters which were displayed via IT->dpvec. */
5194 if (it->dpvec_char_len < 0)
5195 reseat_at_next_visible_line_start (it, 1);
5196 else if (it->dpvec_char_len > 0)
5198 it->len = it->dpvec_char_len;
5199 set_iterator_to_next (it, reseat_p);
5203 else if (it->method == next_element_from_string)
5205 /* Current display element is a character from a Lisp string. */
5206 xassert (it->s == NULL && STRINGP (it->string));
5207 IT_STRING_BYTEPOS (*it) += it->len;
5208 IT_STRING_CHARPOS (*it) += 1;
5210 consider_string_end:
5212 if (it->current.overlay_string_index >= 0)
5214 /* IT->string is an overlay string. Advance to the
5215 next, if there is one. */
5216 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
5217 next_overlay_string (it);
5219 else
5221 /* IT->string is not an overlay string. If we reached
5222 its end, and there is something on IT->stack, proceed
5223 with what is on the stack. This can be either another
5224 string, this time an overlay string, or a buffer. */
5225 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
5226 && it->sp > 0)
5228 pop_it (it);
5229 if (!STRINGP (it->string))
5230 it->method = next_element_from_buffer;
5231 else
5232 goto consider_string_end;
5236 else if (it->method == next_element_from_image
5237 || it->method == next_element_from_stretch)
5239 /* The position etc with which we have to proceed are on
5240 the stack. The position may be at the end of a string,
5241 if the `display' property takes up the whole string. */
5242 pop_it (it);
5243 it->image_id = 0;
5244 if (STRINGP (it->string))
5246 it->method = next_element_from_string;
5247 goto consider_string_end;
5249 else
5250 it->method = next_element_from_buffer;
5252 else
5253 /* There are no other methods defined, so this should be a bug. */
5254 abort ();
5256 xassert (it->method != next_element_from_string
5257 || (STRINGP (it->string)
5258 && IT_STRING_CHARPOS (*it) >= 0));
5261 /* Load IT's display element fields with information about the next
5262 display element which comes from a display table entry or from the
5263 result of translating a control character to one of the forms `^C'
5264 or `\003'.
5266 IT->dpvec holds the glyphs to return as characters.
5267 IT->saved_face_id holds the face id before the display vector--
5268 it is restored into IT->face_idin set_iterator_to_next. */
5270 static int
5271 next_element_from_display_vector (it)
5272 struct it *it;
5274 /* Precondition. */
5275 xassert (it->dpvec && it->current.dpvec_index >= 0);
5277 if (INTEGERP (*it->dpvec)
5278 && GLYPH_CHAR_VALID_P (XFASTINT (*it->dpvec)))
5280 int lface_id;
5281 GLYPH g;
5283 g = XFASTINT (it->dpvec[it->current.dpvec_index]);
5284 it->c = FAST_GLYPH_CHAR (g);
5285 it->len = CHAR_BYTES (it->c);
5287 /* The entry may contain a face id to use. Such a face id is
5288 the id of a Lisp face, not a realized face. A face id of
5289 zero means no face is specified. */
5290 lface_id = FAST_GLYPH_FACE (g);
5291 if (lface_id)
5293 /* The function returns -1 if lface_id is invalid. */
5294 int face_id = ascii_face_of_lisp_face (it->f, lface_id);
5295 if (face_id >= 0)
5296 it->face_id = face_id;
5299 else
5300 /* Display table entry is invalid. Return a space. */
5301 it->c = ' ', it->len = 1;
5303 /* Don't change position and object of the iterator here. They are
5304 still the values of the character that had this display table
5305 entry or was translated, and that's what we want. */
5306 it->what = IT_CHARACTER;
5307 return 1;
5311 /* Load IT with the next display element from Lisp string IT->string.
5312 IT->current.string_pos is the current position within the string.
5313 If IT->current.overlay_string_index >= 0, the Lisp string is an
5314 overlay string. */
5316 static int
5317 next_element_from_string (it)
5318 struct it *it;
5320 struct text_pos position;
5322 xassert (STRINGP (it->string));
5323 xassert (IT_STRING_CHARPOS (*it) >= 0);
5324 position = it->current.string_pos;
5326 /* Time to check for invisible text? */
5327 if (IT_STRING_CHARPOS (*it) < it->end_charpos
5328 && IT_STRING_CHARPOS (*it) == it->stop_charpos)
5330 handle_stop (it);
5332 /* Since a handler may have changed IT->method, we must
5333 recurse here. */
5334 return get_next_display_element (it);
5337 if (it->current.overlay_string_index >= 0)
5339 /* Get the next character from an overlay string. In overlay
5340 strings, There is no field width or padding with spaces to
5341 do. */
5342 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
5344 it->what = IT_EOB;
5345 return 0;
5347 else if (STRING_MULTIBYTE (it->string))
5349 int remaining = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
5350 const unsigned char *s = (SDATA (it->string)
5351 + IT_STRING_BYTEPOS (*it));
5352 it->c = string_char_and_length (s, remaining, &it->len);
5354 else
5356 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
5357 it->len = 1;
5360 else
5362 /* Get the next character from a Lisp string that is not an
5363 overlay string. Such strings come from the mode line, for
5364 example. We may have to pad with spaces, or truncate the
5365 string. See also next_element_from_c_string. */
5366 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
5368 it->what = IT_EOB;
5369 return 0;
5371 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
5373 /* Pad with spaces. */
5374 it->c = ' ', it->len = 1;
5375 CHARPOS (position) = BYTEPOS (position) = -1;
5377 else if (STRING_MULTIBYTE (it->string))
5379 int maxlen = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
5380 const unsigned char *s = (SDATA (it->string)
5381 + IT_STRING_BYTEPOS (*it));
5382 it->c = string_char_and_length (s, maxlen, &it->len);
5384 else
5386 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
5387 it->len = 1;
5391 /* Record what we have and where it came from. Note that we store a
5392 buffer position in IT->position although it could arguably be a
5393 string position. */
5394 it->what = IT_CHARACTER;
5395 it->object = it->string;
5396 it->position = position;
5397 return 1;
5401 /* Load IT with next display element from C string IT->s.
5402 IT->string_nchars is the maximum number of characters to return
5403 from the string. IT->end_charpos may be greater than
5404 IT->string_nchars when this function is called, in which case we
5405 may have to return padding spaces. Value is zero if end of string
5406 reached, including padding spaces. */
5408 static int
5409 next_element_from_c_string (it)
5410 struct it *it;
5412 int success_p = 1;
5414 xassert (it->s);
5415 it->what = IT_CHARACTER;
5416 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
5417 it->object = Qnil;
5419 /* IT's position can be greater IT->string_nchars in case a field
5420 width or precision has been specified when the iterator was
5421 initialized. */
5422 if (IT_CHARPOS (*it) >= it->end_charpos)
5424 /* End of the game. */
5425 it->what = IT_EOB;
5426 success_p = 0;
5428 else if (IT_CHARPOS (*it) >= it->string_nchars)
5430 /* Pad with spaces. */
5431 it->c = ' ', it->len = 1;
5432 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
5434 else if (it->multibyte_p)
5436 /* Implementation note: The calls to strlen apparently aren't a
5437 performance problem because there is no noticeable performance
5438 difference between Emacs running in unibyte or multibyte mode. */
5439 int maxlen = strlen (it->s) - IT_BYTEPOS (*it);
5440 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it),
5441 maxlen, &it->len);
5443 else
5444 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
5446 return success_p;
5450 /* Set up IT to return characters from an ellipsis, if appropriate.
5451 The definition of the ellipsis glyphs may come from a display table
5452 entry. This function Fills IT with the first glyph from the
5453 ellipsis if an ellipsis is to be displayed. */
5455 static int
5456 next_element_from_ellipsis (it)
5457 struct it *it;
5459 if (it->selective_display_ellipsis_p)
5460 setup_for_ellipsis (it, it->len);
5461 else
5463 /* The face at the current position may be different from the
5464 face we find after the invisible text. Remember what it
5465 was in IT->saved_face_id, and signal that it's there by
5466 setting face_before_selective_p. */
5467 it->saved_face_id = it->face_id;
5468 it->method = next_element_from_buffer;
5469 reseat_at_next_visible_line_start (it, 1);
5470 it->face_before_selective_p = 1;
5473 return get_next_display_element (it);
5477 /* Deliver an image display element. The iterator IT is already
5478 filled with image information (done in handle_display_prop). Value
5479 is always 1. */
5482 static int
5483 next_element_from_image (it)
5484 struct it *it;
5486 it->what = IT_IMAGE;
5487 return 1;
5491 /* Fill iterator IT with next display element from a stretch glyph
5492 property. IT->object is the value of the text property. Value is
5493 always 1. */
5495 static int
5496 next_element_from_stretch (it)
5497 struct it *it;
5499 it->what = IT_STRETCH;
5500 return 1;
5504 /* Load IT with the next display element from current_buffer. Value
5505 is zero if end of buffer reached. IT->stop_charpos is the next
5506 position at which to stop and check for text properties or buffer
5507 end. */
5509 static int
5510 next_element_from_buffer (it)
5511 struct it *it;
5513 int success_p = 1;
5515 /* Check this assumption, otherwise, we would never enter the
5516 if-statement, below. */
5517 xassert (IT_CHARPOS (*it) >= BEGV
5518 && IT_CHARPOS (*it) <= it->stop_charpos);
5520 if (IT_CHARPOS (*it) >= it->stop_charpos)
5522 if (IT_CHARPOS (*it) >= it->end_charpos)
5524 int overlay_strings_follow_p;
5526 /* End of the game, except when overlay strings follow that
5527 haven't been returned yet. */
5528 if (it->overlay_strings_at_end_processed_p)
5529 overlay_strings_follow_p = 0;
5530 else
5532 it->overlay_strings_at_end_processed_p = 1;
5533 overlay_strings_follow_p = get_overlay_strings (it, 0);
5536 if (overlay_strings_follow_p)
5537 success_p = get_next_display_element (it);
5538 else
5540 it->what = IT_EOB;
5541 it->position = it->current.pos;
5542 success_p = 0;
5545 else
5547 handle_stop (it);
5548 return get_next_display_element (it);
5551 else
5553 /* No face changes, overlays etc. in sight, so just return a
5554 character from current_buffer. */
5555 unsigned char *p;
5557 /* Maybe run the redisplay end trigger hook. Performance note:
5558 This doesn't seem to cost measurable time. */
5559 if (it->redisplay_end_trigger_charpos
5560 && it->glyph_row
5561 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
5562 run_redisplay_end_trigger_hook (it);
5564 /* Get the next character, maybe multibyte. */
5565 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
5566 if (it->multibyte_p && !ASCII_BYTE_P (*p))
5568 int maxlen = ((IT_BYTEPOS (*it) >= GPT_BYTE ? ZV_BYTE : GPT_BYTE)
5569 - IT_BYTEPOS (*it));
5570 it->c = string_char_and_length (p, maxlen, &it->len);
5572 else
5573 it->c = *p, it->len = 1;
5575 /* Record what we have and where it came from. */
5576 it->what = IT_CHARACTER;;
5577 it->object = it->w->buffer;
5578 it->position = it->current.pos;
5580 /* Normally we return the character found above, except when we
5581 really want to return an ellipsis for selective display. */
5582 if (it->selective)
5584 if (it->c == '\n')
5586 /* A value of selective > 0 means hide lines indented more
5587 than that number of columns. */
5588 if (it->selective > 0
5589 && IT_CHARPOS (*it) + 1 < ZV
5590 && indented_beyond_p (IT_CHARPOS (*it) + 1,
5591 IT_BYTEPOS (*it) + 1,
5592 (double) it->selective)) /* iftc */
5594 success_p = next_element_from_ellipsis (it);
5595 it->dpvec_char_len = -1;
5598 else if (it->c == '\r' && it->selective == -1)
5600 /* A value of selective == -1 means that everything from the
5601 CR to the end of the line is invisible, with maybe an
5602 ellipsis displayed for it. */
5603 success_p = next_element_from_ellipsis (it);
5604 it->dpvec_char_len = -1;
5609 /* Value is zero if end of buffer reached. */
5610 xassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
5611 return success_p;
5615 /* Run the redisplay end trigger hook for IT. */
5617 static void
5618 run_redisplay_end_trigger_hook (it)
5619 struct it *it;
5621 Lisp_Object args[3];
5623 /* IT->glyph_row should be non-null, i.e. we should be actually
5624 displaying something, or otherwise we should not run the hook. */
5625 xassert (it->glyph_row);
5627 /* Set up hook arguments. */
5628 args[0] = Qredisplay_end_trigger_functions;
5629 args[1] = it->window;
5630 XSETINT (args[2], it->redisplay_end_trigger_charpos);
5631 it->redisplay_end_trigger_charpos = 0;
5633 /* Since we are *trying* to run these functions, don't try to run
5634 them again, even if they get an error. */
5635 it->w->redisplay_end_trigger = Qnil;
5636 Frun_hook_with_args (3, args);
5638 /* Notice if it changed the face of the character we are on. */
5639 handle_face_prop (it);
5643 /* Deliver a composition display element. The iterator IT is already
5644 filled with composition information (done in
5645 handle_composition_prop). Value is always 1. */
5647 static int
5648 next_element_from_composition (it)
5649 struct it *it;
5651 it->what = IT_COMPOSITION;
5652 it->position = (STRINGP (it->string)
5653 ? it->current.string_pos
5654 : it->current.pos);
5655 return 1;
5660 /***********************************************************************
5661 Moving an iterator without producing glyphs
5662 ***********************************************************************/
5664 /* Move iterator IT to a specified buffer or X position within one
5665 line on the display without producing glyphs.
5667 OP should be a bit mask including some or all of these bits:
5668 MOVE_TO_X: Stop on reaching x-position TO_X.
5669 MOVE_TO_POS: Stop on reaching buffer or string position TO_CHARPOS.
5670 Regardless of OP's value, stop in reaching the end of the display line.
5672 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
5673 This means, in particular, that TO_X includes window's horizontal
5674 scroll amount.
5676 The return value has several possible values that
5677 say what condition caused the scan to stop:
5679 MOVE_POS_MATCH_OR_ZV
5680 - when TO_POS or ZV was reached.
5682 MOVE_X_REACHED
5683 -when TO_X was reached before TO_POS or ZV were reached.
5685 MOVE_LINE_CONTINUED
5686 - when we reached the end of the display area and the line must
5687 be continued.
5689 MOVE_LINE_TRUNCATED
5690 - when we reached the end of the display area and the line is
5691 truncated.
5693 MOVE_NEWLINE_OR_CR
5694 - when we stopped at a line end, i.e. a newline or a CR and selective
5695 display is on. */
5697 static enum move_it_result
5698 move_it_in_display_line_to (it, to_charpos, to_x, op)
5699 struct it *it;
5700 int to_charpos, to_x, op;
5702 enum move_it_result result = MOVE_UNDEFINED;
5703 struct glyph_row *saved_glyph_row;
5705 /* Don't produce glyphs in produce_glyphs. */
5706 saved_glyph_row = it->glyph_row;
5707 it->glyph_row = NULL;
5709 #define BUFFER_POS_REACHED_P() \
5710 ((op & MOVE_TO_POS) != 0 \
5711 && BUFFERP (it->object) \
5712 && IT_CHARPOS (*it) >= to_charpos \
5713 && it->method == next_element_from_buffer)
5715 while (1)
5717 int x, i, ascent = 0, descent = 0;
5719 /* Stop when ZV reached.
5720 We used to stop here when TO_CHARPOS reached as well, but that is
5721 too soon if this glyph does not fit on this line. So we handle it
5722 explicitly below. */
5723 if (!get_next_display_element (it)
5724 || (it->truncate_lines_p
5725 && BUFFER_POS_REACHED_P ()))
5727 result = MOVE_POS_MATCH_OR_ZV;
5728 break;
5731 /* The call to produce_glyphs will get the metrics of the
5732 display element IT is loaded with. We record in x the
5733 x-position before this display element in case it does not
5734 fit on the line. */
5735 x = it->current_x;
5737 /* Remember the line height so far in case the next element doesn't
5738 fit on the line. */
5739 if (!it->truncate_lines_p)
5741 ascent = it->max_ascent;
5742 descent = it->max_descent;
5745 PRODUCE_GLYPHS (it);
5747 if (it->area != TEXT_AREA)
5749 set_iterator_to_next (it, 1);
5750 continue;
5753 /* The number of glyphs we get back in IT->nglyphs will normally
5754 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
5755 character on a terminal frame, or (iii) a line end. For the
5756 second case, IT->nglyphs - 1 padding glyphs will be present
5757 (on X frames, there is only one glyph produced for a
5758 composite character.
5760 The behavior implemented below means, for continuation lines,
5761 that as many spaces of a TAB as fit on the current line are
5762 displayed there. For terminal frames, as many glyphs of a
5763 multi-glyph character are displayed in the current line, too.
5764 This is what the old redisplay code did, and we keep it that
5765 way. Under X, the whole shape of a complex character must
5766 fit on the line or it will be completely displayed in the
5767 next line.
5769 Note that both for tabs and padding glyphs, all glyphs have
5770 the same width. */
5771 if (it->nglyphs)
5773 /* More than one glyph or glyph doesn't fit on line. All
5774 glyphs have the same width. */
5775 int single_glyph_width = it->pixel_width / it->nglyphs;
5776 int new_x;
5778 for (i = 0; i < it->nglyphs; ++i, x = new_x)
5780 new_x = x + single_glyph_width;
5782 /* We want to leave anything reaching TO_X to the caller. */
5783 if ((op & MOVE_TO_X) && new_x > to_x)
5785 if (BUFFER_POS_REACHED_P ())
5786 goto buffer_pos_reached;
5787 it->current_x = x;
5788 result = MOVE_X_REACHED;
5789 break;
5791 else if (/* Lines are continued. */
5792 !it->truncate_lines_p
5793 && (/* And glyph doesn't fit on the line. */
5794 new_x > it->last_visible_x
5795 /* Or it fits exactly and we're on a window
5796 system frame. */
5797 || (new_x == it->last_visible_x
5798 && FRAME_WINDOW_P (it->f))))
5800 if (/* IT->hpos == 0 means the very first glyph
5801 doesn't fit on the line, e.g. a wide image. */
5802 it->hpos == 0
5803 || (new_x == it->last_visible_x
5804 && FRAME_WINDOW_P (it->f)))
5806 ++it->hpos;
5807 it->current_x = new_x;
5808 if (i == it->nglyphs - 1)
5810 set_iterator_to_next (it, 1);
5811 #ifdef HAVE_WINDOW_SYSTEM
5812 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
5814 if (!get_next_display_element (it))
5816 result = MOVE_POS_MATCH_OR_ZV;
5817 break;
5819 if (BUFFER_POS_REACHED_P ())
5821 if (ITERATOR_AT_END_OF_LINE_P (it))
5822 result = MOVE_POS_MATCH_OR_ZV;
5823 else
5824 result = MOVE_LINE_CONTINUED;
5825 break;
5827 if (ITERATOR_AT_END_OF_LINE_P (it))
5829 result = MOVE_NEWLINE_OR_CR;
5830 break;
5833 #endif /* HAVE_WINDOW_SYSTEM */
5836 else
5838 it->current_x = x;
5839 it->max_ascent = ascent;
5840 it->max_descent = descent;
5843 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
5844 IT_CHARPOS (*it)));
5845 result = MOVE_LINE_CONTINUED;
5846 break;
5848 else if (BUFFER_POS_REACHED_P ())
5849 goto buffer_pos_reached;
5850 else if (new_x > it->first_visible_x)
5852 /* Glyph is visible. Increment number of glyphs that
5853 would be displayed. */
5854 ++it->hpos;
5856 else
5858 /* Glyph is completely off the left margin of the display
5859 area. Nothing to do. */
5863 if (result != MOVE_UNDEFINED)
5864 break;
5866 else if (BUFFER_POS_REACHED_P ())
5868 buffer_pos_reached:
5869 it->current_x = x;
5870 it->max_ascent = ascent;
5871 it->max_descent = descent;
5872 result = MOVE_POS_MATCH_OR_ZV;
5873 break;
5875 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
5877 /* Stop when TO_X specified and reached. This check is
5878 necessary here because of lines consisting of a line end,
5879 only. The line end will not produce any glyphs and we
5880 would never get MOVE_X_REACHED. */
5881 xassert (it->nglyphs == 0);
5882 result = MOVE_X_REACHED;
5883 break;
5886 /* Is this a line end? If yes, we're done. */
5887 if (ITERATOR_AT_END_OF_LINE_P (it))
5889 result = MOVE_NEWLINE_OR_CR;
5890 break;
5893 /* The current display element has been consumed. Advance
5894 to the next. */
5895 set_iterator_to_next (it, 1);
5897 /* Stop if lines are truncated and IT's current x-position is
5898 past the right edge of the window now. */
5899 if (it->truncate_lines_p
5900 && it->current_x >= it->last_visible_x)
5902 #ifdef HAVE_WINDOW_SYSTEM
5903 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
5905 if (!get_next_display_element (it)
5906 || BUFFER_POS_REACHED_P ())
5908 result = MOVE_POS_MATCH_OR_ZV;
5909 break;
5911 if (ITERATOR_AT_END_OF_LINE_P (it))
5913 result = MOVE_NEWLINE_OR_CR;
5914 break;
5917 #endif /* HAVE_WINDOW_SYSTEM */
5918 result = MOVE_LINE_TRUNCATED;
5919 break;
5923 #undef BUFFER_POS_REACHED_P
5925 /* Restore the iterator settings altered at the beginning of this
5926 function. */
5927 it->glyph_row = saved_glyph_row;
5928 return result;
5932 /* Move IT forward until it satisfies one or more of the criteria in
5933 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
5935 OP is a bit-mask that specifies where to stop, and in particular,
5936 which of those four position arguments makes a difference. See the
5937 description of enum move_operation_enum.
5939 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
5940 screen line, this function will set IT to the next position >
5941 TO_CHARPOS. */
5943 void
5944 move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
5945 struct it *it;
5946 int to_charpos, to_x, to_y, to_vpos;
5947 int op;
5949 enum move_it_result skip, skip2 = MOVE_X_REACHED;
5950 int line_height;
5951 int reached = 0;
5953 for (;;)
5955 if (op & MOVE_TO_VPOS)
5957 /* If no TO_CHARPOS and no TO_X specified, stop at the
5958 start of the line TO_VPOS. */
5959 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
5961 if (it->vpos == to_vpos)
5963 reached = 1;
5964 break;
5966 else
5967 skip = move_it_in_display_line_to (it, -1, -1, 0);
5969 else
5971 /* TO_VPOS >= 0 means stop at TO_X in the line at
5972 TO_VPOS, or at TO_POS, whichever comes first. */
5973 if (it->vpos == to_vpos)
5975 reached = 2;
5976 break;
5979 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
5981 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
5983 reached = 3;
5984 break;
5986 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
5988 /* We have reached TO_X but not in the line we want. */
5989 skip = move_it_in_display_line_to (it, to_charpos,
5990 -1, MOVE_TO_POS);
5991 if (skip == MOVE_POS_MATCH_OR_ZV)
5993 reached = 4;
5994 break;
5999 else if (op & MOVE_TO_Y)
6001 struct it it_backup;
6003 /* TO_Y specified means stop at TO_X in the line containing
6004 TO_Y---or at TO_CHARPOS if this is reached first. The
6005 problem is that we can't really tell whether the line
6006 contains TO_Y before we have completely scanned it, and
6007 this may skip past TO_X. What we do is to first scan to
6008 TO_X.
6010 If TO_X is not specified, use a TO_X of zero. The reason
6011 is to make the outcome of this function more predictable.
6012 If we didn't use TO_X == 0, we would stop at the end of
6013 the line which is probably not what a caller would expect
6014 to happen. */
6015 skip = move_it_in_display_line_to (it, to_charpos,
6016 ((op & MOVE_TO_X)
6017 ? to_x : 0),
6018 (MOVE_TO_X
6019 | (op & MOVE_TO_POS)));
6021 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
6022 if (skip == MOVE_POS_MATCH_OR_ZV)
6024 reached = 5;
6025 break;
6028 /* If TO_X was reached, we would like to know whether TO_Y
6029 is in the line. This can only be said if we know the
6030 total line height which requires us to scan the rest of
6031 the line. */
6032 if (skip == MOVE_X_REACHED)
6034 it_backup = *it;
6035 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
6036 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
6037 op & MOVE_TO_POS);
6038 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
6041 /* Now, decide whether TO_Y is in this line. */
6042 line_height = it->max_ascent + it->max_descent;
6043 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
6045 if (to_y >= it->current_y
6046 && to_y < it->current_y + line_height)
6048 if (skip == MOVE_X_REACHED)
6049 /* If TO_Y is in this line and TO_X was reached above,
6050 we scanned too far. We have to restore IT's settings
6051 to the ones before skipping. */
6052 *it = it_backup;
6053 reached = 6;
6055 else if (skip == MOVE_X_REACHED)
6057 skip = skip2;
6058 if (skip == MOVE_POS_MATCH_OR_ZV)
6059 reached = 7;
6062 if (reached)
6063 break;
6065 else
6066 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
6068 switch (skip)
6070 case MOVE_POS_MATCH_OR_ZV:
6071 reached = 8;
6072 goto out;
6074 case MOVE_NEWLINE_OR_CR:
6075 set_iterator_to_next (it, 1);
6076 it->continuation_lines_width = 0;
6077 break;
6079 case MOVE_LINE_TRUNCATED:
6080 it->continuation_lines_width = 0;
6081 reseat_at_next_visible_line_start (it, 0);
6082 if ((op & MOVE_TO_POS) != 0
6083 && IT_CHARPOS (*it) > to_charpos)
6085 reached = 9;
6086 goto out;
6088 break;
6090 case MOVE_LINE_CONTINUED:
6091 it->continuation_lines_width += it->current_x;
6092 break;
6094 default:
6095 abort ();
6098 /* Reset/increment for the next run. */
6099 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
6100 it->current_x = it->hpos = 0;
6101 it->current_y += it->max_ascent + it->max_descent;
6102 ++it->vpos;
6103 last_height = it->max_ascent + it->max_descent;
6104 last_max_ascent = it->max_ascent;
6105 it->max_ascent = it->max_descent = 0;
6108 out:
6110 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
6114 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
6116 If DY > 0, move IT backward at least that many pixels. DY = 0
6117 means move IT backward to the preceding line start or BEGV. This
6118 function may move over more than DY pixels if IT->current_y - DY
6119 ends up in the middle of a line; in this case IT->current_y will be
6120 set to the top of the line moved to. */
6122 void
6123 move_it_vertically_backward (it, dy)
6124 struct it *it;
6125 int dy;
6127 int nlines, h;
6128 struct it it2, it3;
6129 int start_pos;
6131 move_further_back:
6132 xassert (dy >= 0);
6134 start_pos = IT_CHARPOS (*it);
6136 /* Estimate how many newlines we must move back. */
6137 nlines = max (1, dy / FRAME_LINE_HEIGHT (it->f));
6139 /* Set the iterator's position that many lines back. */
6140 while (nlines-- && IT_CHARPOS (*it) > BEGV)
6141 back_to_previous_visible_line_start (it);
6143 /* Reseat the iterator here. When moving backward, we don't want
6144 reseat to skip forward over invisible text, set up the iterator
6145 to deliver from overlay strings at the new position etc. So,
6146 use reseat_1 here. */
6147 reseat_1 (it, it->current.pos, 1);
6149 /* We are now surely at a line start. */
6150 it->current_x = it->hpos = 0;
6151 it->continuation_lines_width = 0;
6153 /* Move forward and see what y-distance we moved. First move to the
6154 start of the next line so that we get its height. We need this
6155 height to be able to tell whether we reached the specified
6156 y-distance. */
6157 it2 = *it;
6158 it2.max_ascent = it2.max_descent = 0;
6159 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
6160 MOVE_TO_POS | MOVE_TO_VPOS);
6161 xassert (IT_CHARPOS (*it) >= BEGV);
6162 it3 = it2;
6164 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
6165 xassert (IT_CHARPOS (*it) >= BEGV);
6166 /* H is the actual vertical distance from the position in *IT
6167 and the starting position. */
6168 h = it2.current_y - it->current_y;
6169 /* NLINES is the distance in number of lines. */
6170 nlines = it2.vpos - it->vpos;
6172 /* Correct IT's y and vpos position
6173 so that they are relative to the starting point. */
6174 it->vpos -= nlines;
6175 it->current_y -= h;
6177 if (dy == 0)
6179 /* DY == 0 means move to the start of the screen line. The
6180 value of nlines is > 0 if continuation lines were involved. */
6181 if (nlines > 0)
6182 move_it_by_lines (it, nlines, 1);
6183 xassert (IT_CHARPOS (*it) <= start_pos);
6185 else
6187 /* The y-position we try to reach, relative to *IT.
6188 Note that H has been subtracted in front of the if-statement. */
6189 int target_y = it->current_y + h - dy;
6190 int y0 = it3.current_y;
6191 int y1 = line_bottom_y (&it3);
6192 int line_height = y1 - y0;
6194 /* If we did not reach target_y, try to move further backward if
6195 we can. If we moved too far backward, try to move forward. */
6196 if (target_y < it->current_y
6197 /* This is heuristic. In a window that's 3 lines high, with
6198 a line height of 13 pixels each, recentering with point
6199 on the bottom line will try to move -39/2 = 19 pixels
6200 backward. Try to avoid moving into the first line. */
6201 && it->current_y - target_y > line_height * 2 / 3
6202 && IT_CHARPOS (*it) > BEGV)
6204 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
6205 target_y - it->current_y));
6206 dy = it->current_y - target_y;
6207 goto move_further_back;
6209 else if (target_y >= it->current_y + line_height
6210 && IT_CHARPOS (*it) < ZV)
6212 /* Should move forward by at least one line, maybe more.
6214 Note: Calling move_it_by_lines can be expensive on
6215 terminal frames, where compute_motion is used (via
6216 vmotion) to do the job, when there are very long lines
6217 and truncate-lines is nil. That's the reason for
6218 treating terminal frames specially here. */
6220 if (!FRAME_WINDOW_P (it->f))
6221 move_it_vertically (it, target_y - (it->current_y + line_height));
6222 else
6226 move_it_by_lines (it, 1, 1);
6228 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
6231 xassert (IT_CHARPOS (*it) >= BEGV);
6237 /* Move IT by a specified amount of pixel lines DY. DY negative means
6238 move backwards. DY = 0 means move to start of screen line. At the
6239 end, IT will be on the start of a screen line. */
6241 void
6242 move_it_vertically (it, dy)
6243 struct it *it;
6244 int dy;
6246 if (dy <= 0)
6247 move_it_vertically_backward (it, -dy);
6248 else
6250 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
6251 move_it_to (it, ZV, -1, it->current_y + dy, -1,
6252 MOVE_TO_POS | MOVE_TO_Y);
6253 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
6255 /* If buffer ends in ZV without a newline, move to the start of
6256 the line to satisfy the post-condition. */
6257 if (IT_CHARPOS (*it) == ZV
6258 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
6259 move_it_by_lines (it, 0, 0);
6264 /* Move iterator IT past the end of the text line it is in. */
6266 void
6267 move_it_past_eol (it)
6268 struct it *it;
6270 enum move_it_result rc;
6272 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
6273 if (rc == MOVE_NEWLINE_OR_CR)
6274 set_iterator_to_next (it, 0);
6278 #if 0 /* Currently not used. */
6280 /* Return non-zero if some text between buffer positions START_CHARPOS
6281 and END_CHARPOS is invisible. IT->window is the window for text
6282 property lookup. */
6284 static int
6285 invisible_text_between_p (it, start_charpos, end_charpos)
6286 struct it *it;
6287 int start_charpos, end_charpos;
6289 Lisp_Object prop, limit;
6290 int invisible_found_p;
6292 xassert (it != NULL && start_charpos <= end_charpos);
6294 /* Is text at START invisible? */
6295 prop = Fget_char_property (make_number (start_charpos), Qinvisible,
6296 it->window);
6297 if (TEXT_PROP_MEANS_INVISIBLE (prop))
6298 invisible_found_p = 1;
6299 else
6301 limit = Fnext_single_char_property_change (make_number (start_charpos),
6302 Qinvisible, Qnil,
6303 make_number (end_charpos));
6304 invisible_found_p = XFASTINT (limit) < end_charpos;
6307 return invisible_found_p;
6310 #endif /* 0 */
6313 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
6314 negative means move up. DVPOS == 0 means move to the start of the
6315 screen line. NEED_Y_P non-zero means calculate IT->current_y. If
6316 NEED_Y_P is zero, IT->current_y will be left unchanged.
6318 Further optimization ideas: If we would know that IT->f doesn't use
6319 a face with proportional font, we could be faster for
6320 truncate-lines nil. */
6322 void
6323 move_it_by_lines (it, dvpos, need_y_p)
6324 struct it *it;
6325 int dvpos, need_y_p;
6327 struct position pos;
6329 if (!FRAME_WINDOW_P (it->f))
6331 struct text_pos textpos;
6333 /* We can use vmotion on frames without proportional fonts. */
6334 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
6335 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
6336 reseat (it, textpos, 1);
6337 it->vpos += pos.vpos;
6338 it->current_y += pos.vpos;
6340 else if (dvpos == 0)
6342 /* DVPOS == 0 means move to the start of the screen line. */
6343 move_it_vertically_backward (it, 0);
6344 xassert (it->current_x == 0 && it->hpos == 0);
6345 /* Let next call to line_bottom_y calculate real line height */
6346 last_height = 0;
6348 else if (dvpos > 0)
6349 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
6350 else
6352 struct it it2;
6353 int start_charpos, i;
6355 /* Start at the beginning of the screen line containing IT's
6356 position. */
6357 move_it_vertically_backward (it, 0);
6359 /* Go back -DVPOS visible lines and reseat the iterator there. */
6360 start_charpos = IT_CHARPOS (*it);
6361 for (i = -dvpos; i && IT_CHARPOS (*it) > BEGV; --i)
6362 back_to_previous_visible_line_start (it);
6363 reseat (it, it->current.pos, 1);
6364 it->current_x = it->hpos = 0;
6366 /* Above call may have moved too far if continuation lines
6367 are involved. Scan forward and see if it did. */
6368 it2 = *it;
6369 it2.vpos = it2.current_y = 0;
6370 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
6371 it->vpos -= it2.vpos;
6372 it->current_y -= it2.current_y;
6373 it->current_x = it->hpos = 0;
6375 /* If we moved too far, move IT some lines forward. */
6376 if (it2.vpos > -dvpos)
6378 int delta = it2.vpos + dvpos;
6379 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
6384 /* Return 1 if IT points into the middle of a display vector. */
6387 in_display_vector_p (it)
6388 struct it *it;
6390 return (it->method == next_element_from_display_vector
6391 && it->current.dpvec_index > 0
6392 && it->dpvec + it->current.dpvec_index != it->dpend);
6396 /***********************************************************************
6397 Messages
6398 ***********************************************************************/
6401 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
6402 to *Messages*. */
6404 void
6405 add_to_log (format, arg1, arg2)
6406 char *format;
6407 Lisp_Object arg1, arg2;
6409 Lisp_Object args[3];
6410 Lisp_Object msg, fmt;
6411 char *buffer;
6412 int len;
6413 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
6414 USE_SAFE_ALLOCA;
6416 /* Do nothing if called asynchronously. Inserting text into
6417 a buffer may call after-change-functions and alike and
6418 that would means running Lisp asynchronously. */
6419 if (handling_signal)
6420 return;
6422 fmt = msg = Qnil;
6423 GCPRO4 (fmt, msg, arg1, arg2);
6425 args[0] = fmt = build_string (format);
6426 args[1] = arg1;
6427 args[2] = arg2;
6428 msg = Fformat (3, args);
6430 len = SBYTES (msg) + 1;
6431 SAFE_ALLOCA (buffer, char *, len);
6432 bcopy (SDATA (msg), buffer, len);
6434 message_dolog (buffer, len - 1, 1, 0);
6435 SAFE_FREE ();
6437 UNGCPRO;
6441 /* Output a newline in the *Messages* buffer if "needs" one. */
6443 void
6444 message_log_maybe_newline ()
6446 if (message_log_need_newline)
6447 message_dolog ("", 0, 1, 0);
6451 /* Add a string M of length NBYTES to the message log, optionally
6452 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
6453 nonzero, means interpret the contents of M as multibyte. This
6454 function calls low-level routines in order to bypass text property
6455 hooks, etc. which might not be safe to run. */
6457 void
6458 message_dolog (m, nbytes, nlflag, multibyte)
6459 const char *m;
6460 int nbytes, nlflag, multibyte;
6462 if (!NILP (Vmemory_full))
6463 return;
6465 if (!NILP (Vmessage_log_max))
6467 struct buffer *oldbuf;
6468 Lisp_Object oldpoint, oldbegv, oldzv;
6469 int old_windows_or_buffers_changed = windows_or_buffers_changed;
6470 int point_at_end = 0;
6471 int zv_at_end = 0;
6472 Lisp_Object old_deactivate_mark, tem;
6473 struct gcpro gcpro1;
6475 old_deactivate_mark = Vdeactivate_mark;
6476 oldbuf = current_buffer;
6477 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
6478 current_buffer->undo_list = Qt;
6480 oldpoint = message_dolog_marker1;
6481 set_marker_restricted (oldpoint, make_number (PT), Qnil);
6482 oldbegv = message_dolog_marker2;
6483 set_marker_restricted (oldbegv, make_number (BEGV), Qnil);
6484 oldzv = message_dolog_marker3;
6485 set_marker_restricted (oldzv, make_number (ZV), Qnil);
6486 GCPRO1 (old_deactivate_mark);
6488 if (PT == Z)
6489 point_at_end = 1;
6490 if (ZV == Z)
6491 zv_at_end = 1;
6493 BEGV = BEG;
6494 BEGV_BYTE = BEG_BYTE;
6495 ZV = Z;
6496 ZV_BYTE = Z_BYTE;
6497 TEMP_SET_PT_BOTH (Z, Z_BYTE);
6499 /* Insert the string--maybe converting multibyte to single byte
6500 or vice versa, so that all the text fits the buffer. */
6501 if (multibyte
6502 && NILP (current_buffer->enable_multibyte_characters))
6504 int i, c, char_bytes;
6505 unsigned char work[1];
6507 /* Convert a multibyte string to single-byte
6508 for the *Message* buffer. */
6509 for (i = 0; i < nbytes; i += char_bytes)
6511 c = string_char_and_length (m + i, nbytes - i, &char_bytes);
6512 work[0] = (SINGLE_BYTE_CHAR_P (c)
6514 : multibyte_char_to_unibyte (c, Qnil));
6515 insert_1_both (work, 1, 1, 1, 0, 0);
6518 else if (! multibyte
6519 && ! NILP (current_buffer->enable_multibyte_characters))
6521 int i, c, char_bytes;
6522 unsigned char *msg = (unsigned char *) m;
6523 unsigned char str[MAX_MULTIBYTE_LENGTH];
6524 /* Convert a single-byte string to multibyte
6525 for the *Message* buffer. */
6526 for (i = 0; i < nbytes; i++)
6528 c = unibyte_char_to_multibyte (msg[i]);
6529 char_bytes = CHAR_STRING (c, str);
6530 insert_1_both (str, 1, char_bytes, 1, 0, 0);
6533 else if (nbytes)
6534 insert_1 (m, nbytes, 1, 0, 0);
6536 if (nlflag)
6538 int this_bol, this_bol_byte, prev_bol, prev_bol_byte, dup;
6539 insert_1 ("\n", 1, 1, 0, 0);
6541 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
6542 this_bol = PT;
6543 this_bol_byte = PT_BYTE;
6545 /* See if this line duplicates the previous one.
6546 If so, combine duplicates. */
6547 if (this_bol > BEG)
6549 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
6550 prev_bol = PT;
6551 prev_bol_byte = PT_BYTE;
6553 dup = message_log_check_duplicate (prev_bol, prev_bol_byte,
6554 this_bol, this_bol_byte);
6555 if (dup)
6557 del_range_both (prev_bol, prev_bol_byte,
6558 this_bol, this_bol_byte, 0);
6559 if (dup > 1)
6561 char dupstr[40];
6562 int duplen;
6564 /* If you change this format, don't forget to also
6565 change message_log_check_duplicate. */
6566 sprintf (dupstr, " [%d times]", dup);
6567 duplen = strlen (dupstr);
6568 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
6569 insert_1 (dupstr, duplen, 1, 0, 1);
6574 /* If we have more than the desired maximum number of lines
6575 in the *Messages* buffer now, delete the oldest ones.
6576 This is safe because we don't have undo in this buffer. */
6578 if (NATNUMP (Vmessage_log_max))
6580 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
6581 -XFASTINT (Vmessage_log_max) - 1, 0);
6582 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
6585 BEGV = XMARKER (oldbegv)->charpos;
6586 BEGV_BYTE = marker_byte_position (oldbegv);
6588 if (zv_at_end)
6590 ZV = Z;
6591 ZV_BYTE = Z_BYTE;
6593 else
6595 ZV = XMARKER (oldzv)->charpos;
6596 ZV_BYTE = marker_byte_position (oldzv);
6599 if (point_at_end)
6600 TEMP_SET_PT_BOTH (Z, Z_BYTE);
6601 else
6602 /* We can't do Fgoto_char (oldpoint) because it will run some
6603 Lisp code. */
6604 TEMP_SET_PT_BOTH (XMARKER (oldpoint)->charpos,
6605 XMARKER (oldpoint)->bytepos);
6607 UNGCPRO;
6608 unchain_marker (XMARKER (oldpoint));
6609 unchain_marker (XMARKER (oldbegv));
6610 unchain_marker (XMARKER (oldzv));
6612 tem = Fget_buffer_window (Fcurrent_buffer (), Qt);
6613 set_buffer_internal (oldbuf);
6614 if (NILP (tem))
6615 windows_or_buffers_changed = old_windows_or_buffers_changed;
6616 message_log_need_newline = !nlflag;
6617 Vdeactivate_mark = old_deactivate_mark;
6622 /* We are at the end of the buffer after just having inserted a newline.
6623 (Note: We depend on the fact we won't be crossing the gap.)
6624 Check to see if the most recent message looks a lot like the previous one.
6625 Return 0 if different, 1 if the new one should just replace it, or a
6626 value N > 1 if we should also append " [N times]". */
6628 static int
6629 message_log_check_duplicate (prev_bol, prev_bol_byte, this_bol, this_bol_byte)
6630 int prev_bol, this_bol;
6631 int prev_bol_byte, this_bol_byte;
6633 int i;
6634 int len = Z_BYTE - 1 - this_bol_byte;
6635 int seen_dots = 0;
6636 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
6637 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
6639 for (i = 0; i < len; i++)
6641 if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.')
6642 seen_dots = 1;
6643 if (p1[i] != p2[i])
6644 return seen_dots;
6646 p1 += len;
6647 if (*p1 == '\n')
6648 return 2;
6649 if (*p1++ == ' ' && *p1++ == '[')
6651 int n = 0;
6652 while (*p1 >= '0' && *p1 <= '9')
6653 n = n * 10 + *p1++ - '0';
6654 if (strncmp (p1, " times]\n", 8) == 0)
6655 return n+1;
6657 return 0;
6661 /* Display an echo area message M with a specified length of NBYTES
6662 bytes. The string may include null characters. If M is 0, clear
6663 out any existing message, and let the mini-buffer text show
6664 through.
6666 The buffer M must continue to exist until after the echo area gets
6667 cleared or some other message gets displayed there. This means do
6668 not pass text that is stored in a Lisp string; do not pass text in
6669 a buffer that was alloca'd. */
6671 void
6672 message2 (m, nbytes, multibyte)
6673 const char *m;
6674 int nbytes;
6675 int multibyte;
6677 /* First flush out any partial line written with print. */
6678 message_log_maybe_newline ();
6679 if (m)
6680 message_dolog (m, nbytes, 1, multibyte);
6681 message2_nolog (m, nbytes, multibyte);
6685 /* The non-logging counterpart of message2. */
6687 void
6688 message2_nolog (m, nbytes, multibyte)
6689 const char *m;
6690 int nbytes, multibyte;
6692 struct frame *sf = SELECTED_FRAME ();
6693 message_enable_multibyte = multibyte;
6695 if (noninteractive)
6697 if (noninteractive_need_newline)
6698 putc ('\n', stderr);
6699 noninteractive_need_newline = 0;
6700 if (m)
6701 fwrite (m, nbytes, 1, stderr);
6702 if (cursor_in_echo_area == 0)
6703 fprintf (stderr, "\n");
6704 fflush (stderr);
6706 /* A null message buffer means that the frame hasn't really been
6707 initialized yet. Error messages get reported properly by
6708 cmd_error, so this must be just an informative message; toss it. */
6709 else if (INTERACTIVE
6710 && sf->glyphs_initialized_p
6711 && FRAME_MESSAGE_BUF (sf))
6713 Lisp_Object mini_window;
6714 struct frame *f;
6716 /* Get the frame containing the mini-buffer
6717 that the selected frame is using. */
6718 mini_window = FRAME_MINIBUF_WINDOW (sf);
6719 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6721 FRAME_SAMPLE_VISIBILITY (f);
6722 if (FRAME_VISIBLE_P (sf)
6723 && ! FRAME_VISIBLE_P (f))
6724 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
6726 if (m)
6728 set_message (m, Qnil, nbytes, multibyte);
6729 if (minibuffer_auto_raise)
6730 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
6732 else
6733 clear_message (1, 1);
6735 do_pending_window_change (0);
6736 echo_area_display (1);
6737 do_pending_window_change (0);
6738 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
6739 (*frame_up_to_date_hook) (f);
6744 /* Display an echo area message M with a specified length of NBYTES
6745 bytes. The string may include null characters. If M is not a
6746 string, clear out any existing message, and let the mini-buffer
6747 text show through. */
6749 void
6750 message3 (m, nbytes, multibyte)
6751 Lisp_Object m;
6752 int nbytes;
6753 int multibyte;
6755 struct gcpro gcpro1;
6757 GCPRO1 (m);
6758 clear_message (1,1);
6760 /* First flush out any partial line written with print. */
6761 message_log_maybe_newline ();
6762 if (STRINGP (m))
6763 message_dolog (SDATA (m), nbytes, 1, multibyte);
6764 message3_nolog (m, nbytes, multibyte);
6766 UNGCPRO;
6770 /* The non-logging version of message3. */
6772 void
6773 message3_nolog (m, nbytes, multibyte)
6774 Lisp_Object m;
6775 int nbytes, multibyte;
6777 struct frame *sf = SELECTED_FRAME ();
6778 message_enable_multibyte = multibyte;
6780 if (noninteractive)
6782 if (noninteractive_need_newline)
6783 putc ('\n', stderr);
6784 noninteractive_need_newline = 0;
6785 if (STRINGP (m))
6786 fwrite (SDATA (m), nbytes, 1, stderr);
6787 if (cursor_in_echo_area == 0)
6788 fprintf (stderr, "\n");
6789 fflush (stderr);
6791 /* A null message buffer means that the frame hasn't really been
6792 initialized yet. Error messages get reported properly by
6793 cmd_error, so this must be just an informative message; toss it. */
6794 else if (INTERACTIVE
6795 && sf->glyphs_initialized_p
6796 && FRAME_MESSAGE_BUF (sf))
6798 Lisp_Object mini_window;
6799 Lisp_Object frame;
6800 struct frame *f;
6802 /* Get the frame containing the mini-buffer
6803 that the selected frame is using. */
6804 mini_window = FRAME_MINIBUF_WINDOW (sf);
6805 frame = XWINDOW (mini_window)->frame;
6806 f = XFRAME (frame);
6808 FRAME_SAMPLE_VISIBILITY (f);
6809 if (FRAME_VISIBLE_P (sf)
6810 && !FRAME_VISIBLE_P (f))
6811 Fmake_frame_visible (frame);
6813 if (STRINGP (m) && SCHARS (m) > 0)
6815 set_message (NULL, m, nbytes, multibyte);
6816 if (minibuffer_auto_raise)
6817 Fraise_frame (frame);
6819 else
6820 clear_message (1, 1);
6822 do_pending_window_change (0);
6823 echo_area_display (1);
6824 do_pending_window_change (0);
6825 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
6826 (*frame_up_to_date_hook) (f);
6831 /* Display a null-terminated echo area message M. If M is 0, clear
6832 out any existing message, and let the mini-buffer text show through.
6834 The buffer M must continue to exist until after the echo area gets
6835 cleared or some other message gets displayed there. Do not pass
6836 text that is stored in a Lisp string. Do not pass text in a buffer
6837 that was alloca'd. */
6839 void
6840 message1 (m)
6841 char *m;
6843 message2 (m, (m ? strlen (m) : 0), 0);
6847 /* The non-logging counterpart of message1. */
6849 void
6850 message1_nolog (m)
6851 char *m;
6853 message2_nolog (m, (m ? strlen (m) : 0), 0);
6856 /* Display a message M which contains a single %s
6857 which gets replaced with STRING. */
6859 void
6860 message_with_string (m, string, log)
6861 char *m;
6862 Lisp_Object string;
6863 int log;
6865 CHECK_STRING (string);
6867 if (noninteractive)
6869 if (m)
6871 if (noninteractive_need_newline)
6872 putc ('\n', stderr);
6873 noninteractive_need_newline = 0;
6874 fprintf (stderr, m, SDATA (string));
6875 if (cursor_in_echo_area == 0)
6876 fprintf (stderr, "\n");
6877 fflush (stderr);
6880 else if (INTERACTIVE)
6882 /* The frame whose minibuffer we're going to display the message on.
6883 It may be larger than the selected frame, so we need
6884 to use its buffer, not the selected frame's buffer. */
6885 Lisp_Object mini_window;
6886 struct frame *f, *sf = SELECTED_FRAME ();
6888 /* Get the frame containing the minibuffer
6889 that the selected frame is using. */
6890 mini_window = FRAME_MINIBUF_WINDOW (sf);
6891 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6893 /* A null message buffer means that the frame hasn't really been
6894 initialized yet. Error messages get reported properly by
6895 cmd_error, so this must be just an informative message; toss it. */
6896 if (FRAME_MESSAGE_BUF (f))
6898 Lisp_Object args[2], message;
6899 struct gcpro gcpro1, gcpro2;
6901 args[0] = build_string (m);
6902 args[1] = message = string;
6903 GCPRO2 (args[0], message);
6904 gcpro1.nvars = 2;
6906 message = Fformat (2, args);
6908 if (log)
6909 message3 (message, SBYTES (message), STRING_MULTIBYTE (message));
6910 else
6911 message3_nolog (message, SBYTES (message), STRING_MULTIBYTE (message));
6913 UNGCPRO;
6915 /* Print should start at the beginning of the message
6916 buffer next time. */
6917 message_buf_print = 0;
6923 /* Dump an informative message to the minibuf. If M is 0, clear out
6924 any existing message, and let the mini-buffer text show through. */
6926 /* VARARGS 1 */
6927 void
6928 message (m, a1, a2, a3)
6929 char *m;
6930 EMACS_INT a1, a2, a3;
6932 if (noninteractive)
6934 if (m)
6936 if (noninteractive_need_newline)
6937 putc ('\n', stderr);
6938 noninteractive_need_newline = 0;
6939 fprintf (stderr, m, a1, a2, a3);
6940 if (cursor_in_echo_area == 0)
6941 fprintf (stderr, "\n");
6942 fflush (stderr);
6945 else if (INTERACTIVE)
6947 /* The frame whose mini-buffer we're going to display the message
6948 on. It may be larger than the selected frame, so we need to
6949 use its buffer, not the selected frame's buffer. */
6950 Lisp_Object mini_window;
6951 struct frame *f, *sf = SELECTED_FRAME ();
6953 /* Get the frame containing the mini-buffer
6954 that the selected frame is using. */
6955 mini_window = FRAME_MINIBUF_WINDOW (sf);
6956 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6958 /* A null message buffer means that the frame hasn't really been
6959 initialized yet. Error messages get reported properly by
6960 cmd_error, so this must be just an informative message; toss
6961 it. */
6962 if (FRAME_MESSAGE_BUF (f))
6964 if (m)
6966 int len;
6967 #ifdef NO_ARG_ARRAY
6968 char *a[3];
6969 a[0] = (char *) a1;
6970 a[1] = (char *) a2;
6971 a[2] = (char *) a3;
6973 len = doprnt (FRAME_MESSAGE_BUF (f),
6974 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
6975 #else
6976 len = doprnt (FRAME_MESSAGE_BUF (f),
6977 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3,
6978 (char **) &a1);
6979 #endif /* NO_ARG_ARRAY */
6981 message2 (FRAME_MESSAGE_BUF (f), len, 0);
6983 else
6984 message1 (0);
6986 /* Print should start at the beginning of the message
6987 buffer next time. */
6988 message_buf_print = 0;
6994 /* The non-logging version of message. */
6996 void
6997 message_nolog (m, a1, a2, a3)
6998 char *m;
6999 EMACS_INT a1, a2, a3;
7001 Lisp_Object old_log_max;
7002 old_log_max = Vmessage_log_max;
7003 Vmessage_log_max = Qnil;
7004 message (m, a1, a2, a3);
7005 Vmessage_log_max = old_log_max;
7009 /* Display the current message in the current mini-buffer. This is
7010 only called from error handlers in process.c, and is not time
7011 critical. */
7013 void
7014 update_echo_area ()
7016 if (!NILP (echo_area_buffer[0]))
7018 Lisp_Object string;
7019 string = Fcurrent_message ();
7020 message3 (string, SBYTES (string),
7021 !NILP (current_buffer->enable_multibyte_characters));
7026 /* Make sure echo area buffers in `echo_buffers' are live.
7027 If they aren't, make new ones. */
7029 static void
7030 ensure_echo_area_buffers ()
7032 int i;
7034 for (i = 0; i < 2; ++i)
7035 if (!BUFFERP (echo_buffer[i])
7036 || NILP (XBUFFER (echo_buffer[i])->name))
7038 char name[30];
7039 Lisp_Object old_buffer;
7040 int j;
7042 old_buffer = echo_buffer[i];
7043 sprintf (name, " *Echo Area %d*", i);
7044 echo_buffer[i] = Fget_buffer_create (build_string (name));
7045 XBUFFER (echo_buffer[i])->truncate_lines = Qnil;
7047 for (j = 0; j < 2; ++j)
7048 if (EQ (old_buffer, echo_area_buffer[j]))
7049 echo_area_buffer[j] = echo_buffer[i];
7054 /* Call FN with args A1..A4 with either the current or last displayed
7055 echo_area_buffer as current buffer.
7057 WHICH zero means use the current message buffer
7058 echo_area_buffer[0]. If that is nil, choose a suitable buffer
7059 from echo_buffer[] and clear it.
7061 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
7062 suitable buffer from echo_buffer[] and clear it.
7064 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
7065 that the current message becomes the last displayed one, make
7066 choose a suitable buffer for echo_area_buffer[0], and clear it.
7068 Value is what FN returns. */
7070 static int
7071 with_echo_area_buffer (w, which, fn, a1, a2, a3, a4)
7072 struct window *w;
7073 int which;
7074 int (*fn) P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
7075 EMACS_INT a1;
7076 Lisp_Object a2;
7077 EMACS_INT a3, a4;
7079 Lisp_Object buffer;
7080 int this_one, the_other, clear_buffer_p, rc;
7081 int count = SPECPDL_INDEX ();
7083 /* If buffers aren't live, make new ones. */
7084 ensure_echo_area_buffers ();
7086 clear_buffer_p = 0;
7088 if (which == 0)
7089 this_one = 0, the_other = 1;
7090 else if (which > 0)
7091 this_one = 1, the_other = 0;
7092 else
7094 this_one = 0, the_other = 1;
7095 clear_buffer_p = 1;
7097 /* We need a fresh one in case the current echo buffer equals
7098 the one containing the last displayed echo area message. */
7099 if (!NILP (echo_area_buffer[this_one])
7100 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
7101 echo_area_buffer[this_one] = Qnil;
7104 /* Choose a suitable buffer from echo_buffer[] is we don't
7105 have one. */
7106 if (NILP (echo_area_buffer[this_one]))
7108 echo_area_buffer[this_one]
7109 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
7110 ? echo_buffer[the_other]
7111 : echo_buffer[this_one]);
7112 clear_buffer_p = 1;
7115 buffer = echo_area_buffer[this_one];
7117 /* Don't get confused by reusing the buffer used for echoing
7118 for a different purpose. */
7119 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
7120 cancel_echoing ();
7122 record_unwind_protect (unwind_with_echo_area_buffer,
7123 with_echo_area_buffer_unwind_data (w));
7125 /* Make the echo area buffer current. Note that for display
7126 purposes, it is not necessary that the displayed window's buffer
7127 == current_buffer, except for text property lookup. So, let's
7128 only set that buffer temporarily here without doing a full
7129 Fset_window_buffer. We must also change w->pointm, though,
7130 because otherwise an assertions in unshow_buffer fails, and Emacs
7131 aborts. */
7132 set_buffer_internal_1 (XBUFFER (buffer));
7133 if (w)
7135 w->buffer = buffer;
7136 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
7139 current_buffer->undo_list = Qt;
7140 current_buffer->read_only = Qnil;
7141 specbind (Qinhibit_read_only, Qt);
7142 specbind (Qinhibit_modification_hooks, Qt);
7144 if (clear_buffer_p && Z > BEG)
7145 del_range (BEG, Z);
7147 xassert (BEGV >= BEG);
7148 xassert (ZV <= Z && ZV >= BEGV);
7150 rc = fn (a1, a2, a3, a4);
7152 xassert (BEGV >= BEG);
7153 xassert (ZV <= Z && ZV >= BEGV);
7155 unbind_to (count, Qnil);
7156 return rc;
7160 /* Save state that should be preserved around the call to the function
7161 FN called in with_echo_area_buffer. */
7163 static Lisp_Object
7164 with_echo_area_buffer_unwind_data (w)
7165 struct window *w;
7167 int i = 0;
7168 Lisp_Object vector;
7170 /* Reduce consing by keeping one vector in
7171 Vwith_echo_area_save_vector. */
7172 vector = Vwith_echo_area_save_vector;
7173 Vwith_echo_area_save_vector = Qnil;
7175 if (NILP (vector))
7176 vector = Fmake_vector (make_number (7), Qnil);
7178 XSETBUFFER (AREF (vector, i), current_buffer); ++i;
7179 AREF (vector, i) = Vdeactivate_mark, ++i;
7180 AREF (vector, i) = make_number (windows_or_buffers_changed), ++i;
7182 if (w)
7184 XSETWINDOW (AREF (vector, i), w); ++i;
7185 AREF (vector, i) = w->buffer; ++i;
7186 AREF (vector, i) = make_number (XMARKER (w->pointm)->charpos); ++i;
7187 AREF (vector, i) = make_number (XMARKER (w->pointm)->bytepos); ++i;
7189 else
7191 int end = i + 4;
7192 for (; i < end; ++i)
7193 AREF (vector, i) = Qnil;
7196 xassert (i == ASIZE (vector));
7197 return vector;
7201 /* Restore global state from VECTOR which was created by
7202 with_echo_area_buffer_unwind_data. */
7204 static Lisp_Object
7205 unwind_with_echo_area_buffer (vector)
7206 Lisp_Object vector;
7208 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
7209 Vdeactivate_mark = AREF (vector, 1);
7210 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
7212 if (WINDOWP (AREF (vector, 3)))
7214 struct window *w;
7215 Lisp_Object buffer, charpos, bytepos;
7217 w = XWINDOW (AREF (vector, 3));
7218 buffer = AREF (vector, 4);
7219 charpos = AREF (vector, 5);
7220 bytepos = AREF (vector, 6);
7222 w->buffer = buffer;
7223 set_marker_both (w->pointm, buffer,
7224 XFASTINT (charpos), XFASTINT (bytepos));
7227 Vwith_echo_area_save_vector = vector;
7228 return Qnil;
7232 /* Set up the echo area for use by print functions. MULTIBYTE_P
7233 non-zero means we will print multibyte. */
7235 void
7236 setup_echo_area_for_printing (multibyte_p)
7237 int multibyte_p;
7239 /* If we can't find an echo area any more, exit. */
7240 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
7241 Fkill_emacs (Qnil);
7243 ensure_echo_area_buffers ();
7245 if (!message_buf_print)
7247 /* A message has been output since the last time we printed.
7248 Choose a fresh echo area buffer. */
7249 if (EQ (echo_area_buffer[1], echo_buffer[0]))
7250 echo_area_buffer[0] = echo_buffer[1];
7251 else
7252 echo_area_buffer[0] = echo_buffer[0];
7254 /* Switch to that buffer and clear it. */
7255 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
7256 current_buffer->truncate_lines = Qnil;
7258 if (Z > BEG)
7260 int count = SPECPDL_INDEX ();
7261 specbind (Qinhibit_read_only, Qt);
7262 /* Note that undo recording is always disabled. */
7263 del_range (BEG, Z);
7264 unbind_to (count, Qnil);
7266 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
7268 /* Set up the buffer for the multibyteness we need. */
7269 if (multibyte_p
7270 != !NILP (current_buffer->enable_multibyte_characters))
7271 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
7273 /* Raise the frame containing the echo area. */
7274 if (minibuffer_auto_raise)
7276 struct frame *sf = SELECTED_FRAME ();
7277 Lisp_Object mini_window;
7278 mini_window = FRAME_MINIBUF_WINDOW (sf);
7279 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
7282 message_log_maybe_newline ();
7283 message_buf_print = 1;
7285 else
7287 if (NILP (echo_area_buffer[0]))
7289 if (EQ (echo_area_buffer[1], echo_buffer[0]))
7290 echo_area_buffer[0] = echo_buffer[1];
7291 else
7292 echo_area_buffer[0] = echo_buffer[0];
7295 if (current_buffer != XBUFFER (echo_area_buffer[0]))
7297 /* Someone switched buffers between print requests. */
7298 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
7299 current_buffer->truncate_lines = Qnil;
7305 /* Display an echo area message in window W. Value is non-zero if W's
7306 height is changed. If display_last_displayed_message_p is
7307 non-zero, display the message that was last displayed, otherwise
7308 display the current message. */
7310 static int
7311 display_echo_area (w)
7312 struct window *w;
7314 int i, no_message_p, window_height_changed_p, count;
7316 /* Temporarily disable garbage collections while displaying the echo
7317 area. This is done because a GC can print a message itself.
7318 That message would modify the echo area buffer's contents while a
7319 redisplay of the buffer is going on, and seriously confuse
7320 redisplay. */
7321 count = inhibit_garbage_collection ();
7323 /* If there is no message, we must call display_echo_area_1
7324 nevertheless because it resizes the window. But we will have to
7325 reset the echo_area_buffer in question to nil at the end because
7326 with_echo_area_buffer will sets it to an empty buffer. */
7327 i = display_last_displayed_message_p ? 1 : 0;
7328 no_message_p = NILP (echo_area_buffer[i]);
7330 window_height_changed_p
7331 = with_echo_area_buffer (w, display_last_displayed_message_p,
7332 display_echo_area_1,
7333 (EMACS_INT) w, Qnil, 0, 0);
7335 if (no_message_p)
7336 echo_area_buffer[i] = Qnil;
7338 unbind_to (count, Qnil);
7339 return window_height_changed_p;
7343 /* Helper for display_echo_area. Display the current buffer which
7344 contains the current echo area message in window W, a mini-window,
7345 a pointer to which is passed in A1. A2..A4 are currently not used.
7346 Change the height of W so that all of the message is displayed.
7347 Value is non-zero if height of W was changed. */
7349 static int
7350 display_echo_area_1 (a1, a2, a3, a4)
7351 EMACS_INT a1;
7352 Lisp_Object a2;
7353 EMACS_INT a3, a4;
7355 struct window *w = (struct window *) a1;
7356 Lisp_Object window;
7357 struct text_pos start;
7358 int window_height_changed_p = 0;
7360 /* Do this before displaying, so that we have a large enough glyph
7361 matrix for the display. */
7362 window_height_changed_p = resize_mini_window (w, 0);
7364 /* Display. */
7365 clear_glyph_matrix (w->desired_matrix);
7366 XSETWINDOW (window, w);
7367 SET_TEXT_POS (start, BEG, BEG_BYTE);
7368 try_window (window, start);
7370 return window_height_changed_p;
7374 /* Resize the echo area window to exactly the size needed for the
7375 currently displayed message, if there is one. If a mini-buffer
7376 is active, don't shrink it. */
7378 void
7379 resize_echo_area_exactly ()
7381 if (BUFFERP (echo_area_buffer[0])
7382 && WINDOWP (echo_area_window))
7384 struct window *w = XWINDOW (echo_area_window);
7385 int resized_p;
7386 Lisp_Object resize_exactly;
7388 if (minibuf_level == 0)
7389 resize_exactly = Qt;
7390 else
7391 resize_exactly = Qnil;
7393 resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
7394 (EMACS_INT) w, resize_exactly, 0, 0);
7395 if (resized_p)
7397 ++windows_or_buffers_changed;
7398 ++update_mode_lines;
7399 redisplay_internal (0);
7405 /* Callback function for with_echo_area_buffer, when used from
7406 resize_echo_area_exactly. A1 contains a pointer to the window to
7407 resize, EXACTLY non-nil means resize the mini-window exactly to the
7408 size of the text displayed. A3 and A4 are not used. Value is what
7409 resize_mini_window returns. */
7411 static int
7412 resize_mini_window_1 (a1, exactly, a3, a4)
7413 EMACS_INT a1;
7414 Lisp_Object exactly;
7415 EMACS_INT a3, a4;
7417 return resize_mini_window ((struct window *) a1, !NILP (exactly));
7421 /* Resize mini-window W to fit the size of its contents. EXACT:P
7422 means size the window exactly to the size needed. Otherwise, it's
7423 only enlarged until W's buffer is empty. Value is non-zero if
7424 the window height has been changed. */
7427 resize_mini_window (w, exact_p)
7428 struct window *w;
7429 int exact_p;
7431 struct frame *f = XFRAME (w->frame);
7432 int window_height_changed_p = 0;
7434 xassert (MINI_WINDOW_P (w));
7436 /* Don't resize windows while redisplaying a window; it would
7437 confuse redisplay functions when the size of the window they are
7438 displaying changes from under them. Such a resizing can happen,
7439 for instance, when which-func prints a long message while
7440 we are running fontification-functions. We're running these
7441 functions with safe_call which binds inhibit-redisplay to t. */
7442 if (!NILP (Vinhibit_redisplay))
7443 return 0;
7445 /* Nil means don't try to resize. */
7446 if (NILP (Vresize_mini_windows)
7447 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
7448 return 0;
7450 if (!FRAME_MINIBUF_ONLY_P (f))
7452 struct it it;
7453 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
7454 int total_height = WINDOW_TOTAL_LINES (root) + WINDOW_TOTAL_LINES (w);
7455 int height, max_height;
7456 int unit = FRAME_LINE_HEIGHT (f);
7457 struct text_pos start;
7458 struct buffer *old_current_buffer = NULL;
7460 if (current_buffer != XBUFFER (w->buffer))
7462 old_current_buffer = current_buffer;
7463 set_buffer_internal (XBUFFER (w->buffer));
7466 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
7468 /* Compute the max. number of lines specified by the user. */
7469 if (FLOATP (Vmax_mini_window_height))
7470 max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_LINES (f);
7471 else if (INTEGERP (Vmax_mini_window_height))
7472 max_height = XINT (Vmax_mini_window_height);
7473 else
7474 max_height = total_height / 4;
7476 /* Correct that max. height if it's bogus. */
7477 max_height = max (1, max_height);
7478 max_height = min (total_height, max_height);
7480 /* Find out the height of the text in the window. */
7481 if (it.truncate_lines_p)
7482 height = 1;
7483 else
7485 last_height = 0;
7486 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
7487 if (it.max_ascent == 0 && it.max_descent == 0)
7488 height = it.current_y + last_height;
7489 else
7490 height = it.current_y + it.max_ascent + it.max_descent;
7491 height -= min (it.extra_line_spacing, it.max_extra_line_spacing);
7492 height = (height + unit - 1) / unit;
7495 /* Compute a suitable window start. */
7496 if (height > max_height)
7498 height = max_height;
7499 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
7500 move_it_vertically_backward (&it, (height - 1) * unit);
7501 start = it.current.pos;
7503 else
7504 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
7505 SET_MARKER_FROM_TEXT_POS (w->start, start);
7507 if (EQ (Vresize_mini_windows, Qgrow_only))
7509 /* Let it grow only, until we display an empty message, in which
7510 case the window shrinks again. */
7511 if (height > WINDOW_TOTAL_LINES (w))
7513 int old_height = WINDOW_TOTAL_LINES (w);
7514 freeze_window_starts (f, 1);
7515 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7516 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7518 else if (height < WINDOW_TOTAL_LINES (w)
7519 && (exact_p || BEGV == ZV))
7521 int old_height = WINDOW_TOTAL_LINES (w);
7522 freeze_window_starts (f, 0);
7523 shrink_mini_window (w);
7524 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7527 else
7529 /* Always resize to exact size needed. */
7530 if (height > WINDOW_TOTAL_LINES (w))
7532 int old_height = WINDOW_TOTAL_LINES (w);
7533 freeze_window_starts (f, 1);
7534 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7535 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7537 else if (height < WINDOW_TOTAL_LINES (w))
7539 int old_height = WINDOW_TOTAL_LINES (w);
7540 freeze_window_starts (f, 0);
7541 shrink_mini_window (w);
7543 if (height)
7545 freeze_window_starts (f, 1);
7546 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7549 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7553 if (old_current_buffer)
7554 set_buffer_internal (old_current_buffer);
7557 return window_height_changed_p;
7561 /* Value is the current message, a string, or nil if there is no
7562 current message. */
7564 Lisp_Object
7565 current_message ()
7567 Lisp_Object msg;
7569 if (NILP (echo_area_buffer[0]))
7570 msg = Qnil;
7571 else
7573 with_echo_area_buffer (0, 0, current_message_1,
7574 (EMACS_INT) &msg, Qnil, 0, 0);
7575 if (NILP (msg))
7576 echo_area_buffer[0] = Qnil;
7579 return msg;
7583 static int
7584 current_message_1 (a1, a2, a3, a4)
7585 EMACS_INT a1;
7586 Lisp_Object a2;
7587 EMACS_INT a3, a4;
7589 Lisp_Object *msg = (Lisp_Object *) a1;
7591 if (Z > BEG)
7592 *msg = make_buffer_string (BEG, Z, 1);
7593 else
7594 *msg = Qnil;
7595 return 0;
7599 /* Push the current message on Vmessage_stack for later restauration
7600 by restore_message. Value is non-zero if the current message isn't
7601 empty. This is a relatively infrequent operation, so it's not
7602 worth optimizing. */
7605 push_message ()
7607 Lisp_Object msg;
7608 msg = current_message ();
7609 Vmessage_stack = Fcons (msg, Vmessage_stack);
7610 return STRINGP (msg);
7614 /* Restore message display from the top of Vmessage_stack. */
7616 void
7617 restore_message ()
7619 Lisp_Object msg;
7621 xassert (CONSP (Vmessage_stack));
7622 msg = XCAR (Vmessage_stack);
7623 if (STRINGP (msg))
7624 message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
7625 else
7626 message3_nolog (msg, 0, 0);
7630 /* Handler for record_unwind_protect calling pop_message. */
7632 Lisp_Object
7633 pop_message_unwind (dummy)
7634 Lisp_Object dummy;
7636 pop_message ();
7637 return Qnil;
7640 /* Pop the top-most entry off Vmessage_stack. */
7642 void
7643 pop_message ()
7645 xassert (CONSP (Vmessage_stack));
7646 Vmessage_stack = XCDR (Vmessage_stack);
7650 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
7651 exits. If the stack is not empty, we have a missing pop_message
7652 somewhere. */
7654 void
7655 check_message_stack ()
7657 if (!NILP (Vmessage_stack))
7658 abort ();
7662 /* Truncate to NCHARS what will be displayed in the echo area the next
7663 time we display it---but don't redisplay it now. */
7665 void
7666 truncate_echo_area (nchars)
7667 int nchars;
7669 if (nchars == 0)
7670 echo_area_buffer[0] = Qnil;
7671 /* A null message buffer means that the frame hasn't really been
7672 initialized yet. Error messages get reported properly by
7673 cmd_error, so this must be just an informative message; toss it. */
7674 else if (!noninteractive
7675 && INTERACTIVE
7676 && !NILP (echo_area_buffer[0]))
7678 struct frame *sf = SELECTED_FRAME ();
7679 if (FRAME_MESSAGE_BUF (sf))
7680 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil, 0, 0);
7685 /* Helper function for truncate_echo_area. Truncate the current
7686 message to at most NCHARS characters. */
7688 static int
7689 truncate_message_1 (nchars, a2, a3, a4)
7690 EMACS_INT nchars;
7691 Lisp_Object a2;
7692 EMACS_INT a3, a4;
7694 if (BEG + nchars < Z)
7695 del_range (BEG + nchars, Z);
7696 if (Z == BEG)
7697 echo_area_buffer[0] = Qnil;
7698 return 0;
7702 /* Set the current message to a substring of S or STRING.
7704 If STRING is a Lisp string, set the message to the first NBYTES
7705 bytes from STRING. NBYTES zero means use the whole string. If
7706 STRING is multibyte, the message will be displayed multibyte.
7708 If S is not null, set the message to the first LEN bytes of S. LEN
7709 zero means use the whole string. MULTIBYTE_P non-zero means S is
7710 multibyte. Display the message multibyte in that case. */
7712 void
7713 set_message (s, string, nbytes, multibyte_p)
7714 const char *s;
7715 Lisp_Object string;
7716 int nbytes, multibyte_p;
7718 message_enable_multibyte
7719 = ((s && multibyte_p)
7720 || (STRINGP (string) && STRING_MULTIBYTE (string)));
7722 with_echo_area_buffer (0, -1, set_message_1,
7723 (EMACS_INT) s, string, nbytes, multibyte_p);
7724 message_buf_print = 0;
7725 help_echo_showing_p = 0;
7729 /* Helper function for set_message. Arguments have the same meaning
7730 as there, with A1 corresponding to S and A2 corresponding to STRING
7731 This function is called with the echo area buffer being
7732 current. */
7734 static int
7735 set_message_1 (a1, a2, nbytes, multibyte_p)
7736 EMACS_INT a1;
7737 Lisp_Object a2;
7738 EMACS_INT nbytes, multibyte_p;
7740 const char *s = (const char *) a1;
7741 Lisp_Object string = a2;
7743 xassert (BEG == Z);
7745 /* Change multibyteness of the echo buffer appropriately. */
7746 if (message_enable_multibyte
7747 != !NILP (current_buffer->enable_multibyte_characters))
7748 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
7750 current_buffer->truncate_lines = message_truncate_lines ? Qt : Qnil;
7752 /* Insert new message at BEG. */
7753 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
7755 if (STRINGP (string))
7757 int nchars;
7759 if (nbytes == 0)
7760 nbytes = SBYTES (string);
7761 nchars = string_byte_to_char (string, nbytes);
7763 /* This function takes care of single/multibyte conversion. We
7764 just have to ensure that the echo area buffer has the right
7765 setting of enable_multibyte_characters. */
7766 insert_from_string (string, 0, 0, nchars, nbytes, 1);
7768 else if (s)
7770 if (nbytes == 0)
7771 nbytes = strlen (s);
7773 if (multibyte_p && NILP (current_buffer->enable_multibyte_characters))
7775 /* Convert from multi-byte to single-byte. */
7776 int i, c, n;
7777 unsigned char work[1];
7779 /* Convert a multibyte string to single-byte. */
7780 for (i = 0; i < nbytes; i += n)
7782 c = string_char_and_length (s + i, nbytes - i, &n);
7783 work[0] = (SINGLE_BYTE_CHAR_P (c)
7785 : multibyte_char_to_unibyte (c, Qnil));
7786 insert_1_both (work, 1, 1, 1, 0, 0);
7789 else if (!multibyte_p
7790 && !NILP (current_buffer->enable_multibyte_characters))
7792 /* Convert from single-byte to multi-byte. */
7793 int i, c, n;
7794 const unsigned char *msg = (const unsigned char *) s;
7795 unsigned char str[MAX_MULTIBYTE_LENGTH];
7797 /* Convert a single-byte string to multibyte. */
7798 for (i = 0; i < nbytes; i++)
7800 c = unibyte_char_to_multibyte (msg[i]);
7801 n = CHAR_STRING (c, str);
7802 insert_1_both (str, 1, n, 1, 0, 0);
7805 else
7806 insert_1 (s, nbytes, 1, 0, 0);
7809 return 0;
7813 /* Clear messages. CURRENT_P non-zero means clear the current
7814 message. LAST_DISPLAYED_P non-zero means clear the message
7815 last displayed. */
7817 void
7818 clear_message (current_p, last_displayed_p)
7819 int current_p, last_displayed_p;
7821 if (current_p)
7823 echo_area_buffer[0] = Qnil;
7824 message_cleared_p = 1;
7827 if (last_displayed_p)
7828 echo_area_buffer[1] = Qnil;
7830 message_buf_print = 0;
7833 /* Clear garbaged frames.
7835 This function is used where the old redisplay called
7836 redraw_garbaged_frames which in turn called redraw_frame which in
7837 turn called clear_frame. The call to clear_frame was a source of
7838 flickering. I believe a clear_frame is not necessary. It should
7839 suffice in the new redisplay to invalidate all current matrices,
7840 and ensure a complete redisplay of all windows. */
7842 static void
7843 clear_garbaged_frames ()
7845 if (frame_garbaged)
7847 Lisp_Object tail, frame;
7848 int changed_count = 0;
7850 FOR_EACH_FRAME (tail, frame)
7852 struct frame *f = XFRAME (frame);
7854 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
7856 if (f->resized_p)
7858 Fredraw_frame (frame);
7859 f->force_flush_display_p = 1;
7861 clear_current_matrices (f);
7862 changed_count++;
7863 f->garbaged = 0;
7864 f->resized_p = 0;
7868 frame_garbaged = 0;
7869 if (changed_count)
7870 ++windows_or_buffers_changed;
7875 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
7876 is non-zero update selected_frame. Value is non-zero if the
7877 mini-windows height has been changed. */
7879 static int
7880 echo_area_display (update_frame_p)
7881 int update_frame_p;
7883 Lisp_Object mini_window;
7884 struct window *w;
7885 struct frame *f;
7886 int window_height_changed_p = 0;
7887 struct frame *sf = SELECTED_FRAME ();
7889 mini_window = FRAME_MINIBUF_WINDOW (sf);
7890 w = XWINDOW (mini_window);
7891 f = XFRAME (WINDOW_FRAME (w));
7893 /* Don't display if frame is invisible or not yet initialized. */
7894 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
7895 return 0;
7897 /* The terminal frame is used as the first Emacs frame on the Mac OS. */
7898 #ifndef MAC_OS8
7899 #ifdef HAVE_WINDOW_SYSTEM
7900 /* When Emacs starts, selected_frame may be a visible terminal
7901 frame, even if we run under a window system. If we let this
7902 through, a message would be displayed on the terminal. */
7903 if (EQ (selected_frame, Vterminal_frame)
7904 && !NILP (Vwindow_system))
7905 return 0;
7906 #endif /* HAVE_WINDOW_SYSTEM */
7907 #endif
7909 /* Redraw garbaged frames. */
7910 if (frame_garbaged)
7911 clear_garbaged_frames ();
7913 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
7915 echo_area_window = mini_window;
7916 window_height_changed_p = display_echo_area (w);
7917 w->must_be_updated_p = 1;
7919 /* Update the display, unless called from redisplay_internal.
7920 Also don't update the screen during redisplay itself. The
7921 update will happen at the end of redisplay, and an update
7922 here could cause confusion. */
7923 if (update_frame_p && !redisplaying_p)
7925 int n = 0;
7927 /* If the display update has been interrupted by pending
7928 input, update mode lines in the frame. Due to the
7929 pending input, it might have been that redisplay hasn't
7930 been called, so that mode lines above the echo area are
7931 garbaged. This looks odd, so we prevent it here. */
7932 if (!display_completed)
7933 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), 0);
7935 if (window_height_changed_p
7936 /* Don't do this if Emacs is shutting down. Redisplay
7937 needs to run hooks. */
7938 && !NILP (Vrun_hooks))
7940 /* Must update other windows. Likewise as in other
7941 cases, don't let this update be interrupted by
7942 pending input. */
7943 int count = SPECPDL_INDEX ();
7944 specbind (Qredisplay_dont_pause, Qt);
7945 windows_or_buffers_changed = 1;
7946 redisplay_internal (0);
7947 unbind_to (count, Qnil);
7949 else if (FRAME_WINDOW_P (f) && n == 0)
7951 /* Window configuration is the same as before.
7952 Can do with a display update of the echo area,
7953 unless we displayed some mode lines. */
7954 update_single_window (w, 1);
7955 rif->flush_display (f);
7957 else
7958 update_frame (f, 1, 1);
7960 /* If cursor is in the echo area, make sure that the next
7961 redisplay displays the minibuffer, so that the cursor will
7962 be replaced with what the minibuffer wants. */
7963 if (cursor_in_echo_area)
7964 ++windows_or_buffers_changed;
7967 else if (!EQ (mini_window, selected_window))
7968 windows_or_buffers_changed++;
7970 /* Last displayed message is now the current message. */
7971 echo_area_buffer[1] = echo_area_buffer[0];
7973 /* Prevent redisplay optimization in redisplay_internal by resetting
7974 this_line_start_pos. This is done because the mini-buffer now
7975 displays the message instead of its buffer text. */
7976 if (EQ (mini_window, selected_window))
7977 CHARPOS (this_line_start_pos) = 0;
7979 return window_height_changed_p;
7984 /***********************************************************************
7985 Frame Titles
7986 ***********************************************************************/
7989 /* The frame title buffering code is also used by Fformat_mode_line.
7990 So it is not conditioned by HAVE_WINDOW_SYSTEM. */
7992 /* A buffer for constructing frame titles in it; allocated from the
7993 heap in init_xdisp and resized as needed in store_frame_title_char. */
7995 static char *frame_title_buf;
7997 /* The buffer's end, and a current output position in it. */
7999 static char *frame_title_buf_end;
8000 static char *frame_title_ptr;
8003 /* Store a single character C for the frame title in frame_title_buf.
8004 Re-allocate frame_title_buf if necessary. */
8006 static void
8007 #ifdef PROTOTYPES
8008 store_frame_title_char (char c)
8009 #else
8010 store_frame_title_char (c)
8011 char c;
8012 #endif
8014 /* If output position has reached the end of the allocated buffer,
8015 double the buffer's size. */
8016 if (frame_title_ptr == frame_title_buf_end)
8018 int len = frame_title_ptr - frame_title_buf;
8019 int new_size = 2 * len * sizeof *frame_title_buf;
8020 frame_title_buf = (char *) xrealloc (frame_title_buf, new_size);
8021 frame_title_buf_end = frame_title_buf + new_size;
8022 frame_title_ptr = frame_title_buf + len;
8025 *frame_title_ptr++ = c;
8029 /* Store part of a frame title in frame_title_buf, beginning at
8030 frame_title_ptr. STR is the string to store. Do not copy
8031 characters that yield more columns than PRECISION; PRECISION <= 0
8032 means copy the whole string. Pad with spaces until FIELD_WIDTH
8033 number of characters have been copied; FIELD_WIDTH <= 0 means don't
8034 pad. Called from display_mode_element when it is used to build a
8035 frame title. */
8037 static int
8038 store_frame_title (str, field_width, precision)
8039 const unsigned char *str;
8040 int field_width, precision;
8042 int n = 0;
8043 int dummy, nbytes;
8045 /* Copy at most PRECISION chars from STR. */
8046 nbytes = strlen (str);
8047 n += c_string_width (str, nbytes, precision, &dummy, &nbytes);
8048 while (nbytes--)
8049 store_frame_title_char (*str++);
8051 /* Fill up with spaces until FIELD_WIDTH reached. */
8052 while (field_width > 0
8053 && n < field_width)
8055 store_frame_title_char (' ');
8056 ++n;
8059 return n;
8062 #ifdef HAVE_WINDOW_SYSTEM
8064 /* Set the title of FRAME, if it has changed. The title format is
8065 Vicon_title_format if FRAME is iconified, otherwise it is
8066 frame_title_format. */
8068 static void
8069 x_consider_frame_title (frame)
8070 Lisp_Object frame;
8072 struct frame *f = XFRAME (frame);
8074 if (FRAME_WINDOW_P (f)
8075 || FRAME_MINIBUF_ONLY_P (f)
8076 || f->explicit_name)
8078 /* Do we have more than one visible frame on this X display? */
8079 Lisp_Object tail;
8080 Lisp_Object fmt;
8081 struct buffer *obuf;
8082 int len;
8083 struct it it;
8085 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
8087 Lisp_Object other_frame = XCAR (tail);
8088 struct frame *tf = XFRAME (other_frame);
8090 if (tf != f
8091 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
8092 && !FRAME_MINIBUF_ONLY_P (tf)
8093 && !EQ (other_frame, tip_frame)
8094 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
8095 break;
8098 /* Set global variable indicating that multiple frames exist. */
8099 multiple_frames = CONSP (tail);
8101 /* Switch to the buffer of selected window of the frame. Set up
8102 frame_title_ptr so that display_mode_element will output into it;
8103 then display the title. */
8104 obuf = current_buffer;
8105 set_buffer_internal_1 (XBUFFER (XWINDOW (f->selected_window)->buffer));
8106 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
8107 frame_title_ptr = frame_title_buf;
8108 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
8109 NULL, DEFAULT_FACE_ID);
8110 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
8111 len = frame_title_ptr - frame_title_buf;
8112 frame_title_ptr = NULL;
8113 set_buffer_internal_1 (obuf);
8115 /* Set the title only if it's changed. This avoids consing in
8116 the common case where it hasn't. (If it turns out that we've
8117 already wasted too much time by walking through the list with
8118 display_mode_element, then we might need to optimize at a
8119 higher level than this.) */
8120 if (! STRINGP (f->name)
8121 || SBYTES (f->name) != len
8122 || bcmp (frame_title_buf, SDATA (f->name), len) != 0)
8123 x_implicitly_set_name (f, make_string (frame_title_buf, len), Qnil);
8127 #endif /* not HAVE_WINDOW_SYSTEM */
8132 /***********************************************************************
8133 Menu Bars
8134 ***********************************************************************/
8137 /* Prepare for redisplay by updating menu-bar item lists when
8138 appropriate. This can call eval. */
8140 void
8141 prepare_menu_bars ()
8143 int all_windows;
8144 struct gcpro gcpro1, gcpro2;
8145 struct frame *f;
8146 Lisp_Object tooltip_frame;
8148 #ifdef HAVE_WINDOW_SYSTEM
8149 tooltip_frame = tip_frame;
8150 #else
8151 tooltip_frame = Qnil;
8152 #endif
8154 /* Update all frame titles based on their buffer names, etc. We do
8155 this before the menu bars so that the buffer-menu will show the
8156 up-to-date frame titles. */
8157 #ifdef HAVE_WINDOW_SYSTEM
8158 if (windows_or_buffers_changed || update_mode_lines)
8160 Lisp_Object tail, frame;
8162 FOR_EACH_FRAME (tail, frame)
8164 f = XFRAME (frame);
8165 if (!EQ (frame, tooltip_frame)
8166 && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)))
8167 x_consider_frame_title (frame);
8170 #endif /* HAVE_WINDOW_SYSTEM */
8172 /* Update the menu bar item lists, if appropriate. This has to be
8173 done before any actual redisplay or generation of display lines. */
8174 all_windows = (update_mode_lines
8175 || buffer_shared > 1
8176 || windows_or_buffers_changed);
8177 if (all_windows)
8179 Lisp_Object tail, frame;
8180 int count = SPECPDL_INDEX ();
8182 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
8184 FOR_EACH_FRAME (tail, frame)
8186 f = XFRAME (frame);
8188 /* Ignore tooltip frame. */
8189 if (EQ (frame, tooltip_frame))
8190 continue;
8192 /* If a window on this frame changed size, report that to
8193 the user and clear the size-change flag. */
8194 if (FRAME_WINDOW_SIZES_CHANGED (f))
8196 Lisp_Object functions;
8198 /* Clear flag first in case we get an error below. */
8199 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
8200 functions = Vwindow_size_change_functions;
8201 GCPRO2 (tail, functions);
8203 while (CONSP (functions))
8205 call1 (XCAR (functions), frame);
8206 functions = XCDR (functions);
8208 UNGCPRO;
8211 GCPRO1 (tail);
8212 update_menu_bar (f, 0);
8213 #ifdef HAVE_WINDOW_SYSTEM
8214 update_tool_bar (f, 0);
8215 #endif
8216 UNGCPRO;
8219 unbind_to (count, Qnil);
8221 else
8223 struct frame *sf = SELECTED_FRAME ();
8224 update_menu_bar (sf, 1);
8225 #ifdef HAVE_WINDOW_SYSTEM
8226 update_tool_bar (sf, 1);
8227 #endif
8230 /* Motif needs this. See comment in xmenu.c. Turn it off when
8231 pending_menu_activation is not defined. */
8232 #ifdef USE_X_TOOLKIT
8233 pending_menu_activation = 0;
8234 #endif
8238 /* Update the menu bar item list for frame F. This has to be done
8239 before we start to fill in any display lines, because it can call
8240 eval.
8242 If SAVE_MATCH_DATA is non-zero, we must save and restore it here. */
8244 static void
8245 update_menu_bar (f, save_match_data)
8246 struct frame *f;
8247 int save_match_data;
8249 Lisp_Object window;
8250 register struct window *w;
8252 /* If called recursively during a menu update, do nothing. This can
8253 happen when, for instance, an activate-menubar-hook causes a
8254 redisplay. */
8255 if (inhibit_menubar_update)
8256 return;
8258 window = FRAME_SELECTED_WINDOW (f);
8259 w = XWINDOW (window);
8261 #if 0 /* The if statement below this if statement used to include the
8262 condition !NILP (w->update_mode_line), rather than using
8263 update_mode_lines directly, and this if statement may have
8264 been added to make that condition work. Now the if
8265 statement below matches its comment, this isn't needed. */
8266 if (update_mode_lines)
8267 w->update_mode_line = Qt;
8268 #endif
8270 if (FRAME_WINDOW_P (f)
8272 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
8273 || defined (USE_GTK)
8274 FRAME_EXTERNAL_MENU_BAR (f)
8275 #else
8276 FRAME_MENU_BAR_LINES (f) > 0
8277 #endif
8278 : FRAME_MENU_BAR_LINES (f) > 0)
8280 /* If the user has switched buffers or windows, we need to
8281 recompute to reflect the new bindings. But we'll
8282 recompute when update_mode_lines is set too; that means
8283 that people can use force-mode-line-update to request
8284 that the menu bar be recomputed. The adverse effect on
8285 the rest of the redisplay algorithm is about the same as
8286 windows_or_buffers_changed anyway. */
8287 if (windows_or_buffers_changed
8288 /* This used to test w->update_mode_line, but we believe
8289 there is no need to recompute the menu in that case. */
8290 || update_mode_lines
8291 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
8292 < BUF_MODIFF (XBUFFER (w->buffer)))
8293 != !NILP (w->last_had_star))
8294 || ((!NILP (Vtransient_mark_mode)
8295 && !NILP (XBUFFER (w->buffer)->mark_active))
8296 != !NILP (w->region_showing)))
8298 struct buffer *prev = current_buffer;
8299 int count = SPECPDL_INDEX ();
8301 specbind (Qinhibit_menubar_update, Qt);
8303 set_buffer_internal_1 (XBUFFER (w->buffer));
8304 if (save_match_data)
8305 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
8306 if (NILP (Voverriding_local_map_menu_flag))
8308 specbind (Qoverriding_terminal_local_map, Qnil);
8309 specbind (Qoverriding_local_map, Qnil);
8312 /* Run the Lucid hook. */
8313 safe_run_hooks (Qactivate_menubar_hook);
8315 /* If it has changed current-menubar from previous value,
8316 really recompute the menu-bar from the value. */
8317 if (! NILP (Vlucid_menu_bar_dirty_flag))
8318 call0 (Qrecompute_lucid_menubar);
8320 safe_run_hooks (Qmenu_bar_update_hook);
8321 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
8323 /* Redisplay the menu bar in case we changed it. */
8324 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
8325 || defined (USE_GTK)
8326 if (FRAME_WINDOW_P (f)
8327 #if defined (MAC_OS)
8328 /* All frames on Mac OS share the same menubar. So only the
8329 selected frame should be allowed to set it. */
8330 && f == SELECTED_FRAME ()
8331 #endif
8333 set_frame_menubar (f, 0, 0);
8334 else
8335 /* On a terminal screen, the menu bar is an ordinary screen
8336 line, and this makes it get updated. */
8337 w->update_mode_line = Qt;
8338 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
8339 /* In the non-toolkit version, the menu bar is an ordinary screen
8340 line, and this makes it get updated. */
8341 w->update_mode_line = Qt;
8342 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
8344 unbind_to (count, Qnil);
8345 set_buffer_internal_1 (prev);
8352 /***********************************************************************
8353 Output Cursor
8354 ***********************************************************************/
8356 #ifdef HAVE_WINDOW_SYSTEM
8358 /* EXPORT:
8359 Nominal cursor position -- where to draw output.
8360 HPOS and VPOS are window relative glyph matrix coordinates.
8361 X and Y are window relative pixel coordinates. */
8363 struct cursor_pos output_cursor;
8366 /* EXPORT:
8367 Set the global variable output_cursor to CURSOR. All cursor
8368 positions are relative to updated_window. */
8370 void
8371 set_output_cursor (cursor)
8372 struct cursor_pos *cursor;
8374 output_cursor.hpos = cursor->hpos;
8375 output_cursor.vpos = cursor->vpos;
8376 output_cursor.x = cursor->x;
8377 output_cursor.y = cursor->y;
8381 /* EXPORT for RIF:
8382 Set a nominal cursor position.
8384 HPOS and VPOS are column/row positions in a window glyph matrix. X
8385 and Y are window text area relative pixel positions.
8387 If this is done during an update, updated_window will contain the
8388 window that is being updated and the position is the future output
8389 cursor position for that window. If updated_window is null, use
8390 selected_window and display the cursor at the given position. */
8392 void
8393 x_cursor_to (vpos, hpos, y, x)
8394 int vpos, hpos, y, x;
8396 struct window *w;
8398 /* If updated_window is not set, work on selected_window. */
8399 if (updated_window)
8400 w = updated_window;
8401 else
8402 w = XWINDOW (selected_window);
8404 /* Set the output cursor. */
8405 output_cursor.hpos = hpos;
8406 output_cursor.vpos = vpos;
8407 output_cursor.x = x;
8408 output_cursor.y = y;
8410 /* If not called as part of an update, really display the cursor.
8411 This will also set the cursor position of W. */
8412 if (updated_window == NULL)
8414 BLOCK_INPUT;
8415 display_and_set_cursor (w, 1, hpos, vpos, x, y);
8416 if (rif->flush_display_optional)
8417 rif->flush_display_optional (SELECTED_FRAME ());
8418 UNBLOCK_INPUT;
8422 #endif /* HAVE_WINDOW_SYSTEM */
8425 /***********************************************************************
8426 Tool-bars
8427 ***********************************************************************/
8429 #ifdef HAVE_WINDOW_SYSTEM
8431 /* Where the mouse was last time we reported a mouse event. */
8433 FRAME_PTR last_mouse_frame;
8435 /* Tool-bar item index of the item on which a mouse button was pressed
8436 or -1. */
8438 int last_tool_bar_item;
8441 /* Update the tool-bar item list for frame F. This has to be done
8442 before we start to fill in any display lines. Called from
8443 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
8444 and restore it here. */
8446 static void
8447 update_tool_bar (f, save_match_data)
8448 struct frame *f;
8449 int save_match_data;
8451 #ifdef USE_GTK
8452 int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
8453 #else
8454 int do_update = WINDOWP (f->tool_bar_window)
8455 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0;
8456 #endif
8458 if (do_update)
8460 Lisp_Object window;
8461 struct window *w;
8463 window = FRAME_SELECTED_WINDOW (f);
8464 w = XWINDOW (window);
8466 /* If the user has switched buffers or windows, we need to
8467 recompute to reflect the new bindings. But we'll
8468 recompute when update_mode_lines is set too; that means
8469 that people can use force-mode-line-update to request
8470 that the menu bar be recomputed. The adverse effect on
8471 the rest of the redisplay algorithm is about the same as
8472 windows_or_buffers_changed anyway. */
8473 if (windows_or_buffers_changed
8474 || !NILP (w->update_mode_line)
8475 || update_mode_lines
8476 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
8477 < BUF_MODIFF (XBUFFER (w->buffer)))
8478 != !NILP (w->last_had_star))
8479 || ((!NILP (Vtransient_mark_mode)
8480 && !NILP (XBUFFER (w->buffer)->mark_active))
8481 != !NILP (w->region_showing)))
8483 struct buffer *prev = current_buffer;
8484 int count = SPECPDL_INDEX ();
8485 Lisp_Object new_tool_bar;
8486 int new_n_tool_bar;
8487 struct gcpro gcpro1;
8489 /* Set current_buffer to the buffer of the selected
8490 window of the frame, so that we get the right local
8491 keymaps. */
8492 set_buffer_internal_1 (XBUFFER (w->buffer));
8494 /* Save match data, if we must. */
8495 if (save_match_data)
8496 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
8498 /* Make sure that we don't accidentally use bogus keymaps. */
8499 if (NILP (Voverriding_local_map_menu_flag))
8501 specbind (Qoverriding_terminal_local_map, Qnil);
8502 specbind (Qoverriding_local_map, Qnil);
8505 GCPRO1 (new_tool_bar);
8507 /* Build desired tool-bar items from keymaps. */
8508 new_tool_bar = tool_bar_items (Fcopy_sequence (f->tool_bar_items),
8509 &new_n_tool_bar);
8511 /* Redisplay the tool-bar if we changed it. */
8512 if (NILP (Fequal (new_tool_bar, f->tool_bar_items)))
8514 /* Redisplay that happens asynchronously due to an expose event
8515 may access f->tool_bar_items. Make sure we update both
8516 variables within BLOCK_INPUT so no such event interrupts. */
8517 BLOCK_INPUT;
8518 f->tool_bar_items = new_tool_bar;
8519 f->n_tool_bar_items = new_n_tool_bar;
8520 w->update_mode_line = Qt;
8521 UNBLOCK_INPUT;
8524 UNGCPRO;
8526 unbind_to (count, Qnil);
8527 set_buffer_internal_1 (prev);
8533 /* Set F->desired_tool_bar_string to a Lisp string representing frame
8534 F's desired tool-bar contents. F->tool_bar_items must have
8535 been set up previously by calling prepare_menu_bars. */
8537 static void
8538 build_desired_tool_bar_string (f)
8539 struct frame *f;
8541 int i, size, size_needed;
8542 struct gcpro gcpro1, gcpro2, gcpro3;
8543 Lisp_Object image, plist, props;
8545 image = plist = props = Qnil;
8546 GCPRO3 (image, plist, props);
8548 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
8549 Otherwise, make a new string. */
8551 /* The size of the string we might be able to reuse. */
8552 size = (STRINGP (f->desired_tool_bar_string)
8553 ? SCHARS (f->desired_tool_bar_string)
8554 : 0);
8556 /* We need one space in the string for each image. */
8557 size_needed = f->n_tool_bar_items;
8559 /* Reuse f->desired_tool_bar_string, if possible. */
8560 if (size < size_needed || NILP (f->desired_tool_bar_string))
8561 f->desired_tool_bar_string = Fmake_string (make_number (size_needed),
8562 make_number (' '));
8563 else
8565 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
8566 Fremove_text_properties (make_number (0), make_number (size),
8567 props, f->desired_tool_bar_string);
8570 /* Put a `display' property on the string for the images to display,
8571 put a `menu_item' property on tool-bar items with a value that
8572 is the index of the item in F's tool-bar item vector. */
8573 for (i = 0; i < f->n_tool_bar_items; ++i)
8575 #define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
8577 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
8578 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
8579 int hmargin, vmargin, relief, idx, end;
8580 extern Lisp_Object QCrelief, QCmargin, QCconversion;
8582 /* If image is a vector, choose the image according to the
8583 button state. */
8584 image = PROP (TOOL_BAR_ITEM_IMAGES);
8585 if (VECTORP (image))
8587 if (enabled_p)
8588 idx = (selected_p
8589 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
8590 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
8591 else
8592 idx = (selected_p
8593 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
8594 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
8596 xassert (ASIZE (image) >= idx);
8597 image = AREF (image, idx);
8599 else
8600 idx = -1;
8602 /* Ignore invalid image specifications. */
8603 if (!valid_image_p (image))
8604 continue;
8606 /* Display the tool-bar button pressed, or depressed. */
8607 plist = Fcopy_sequence (XCDR (image));
8609 /* Compute margin and relief to draw. */
8610 relief = (tool_bar_button_relief >= 0
8611 ? tool_bar_button_relief
8612 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
8613 hmargin = vmargin = relief;
8615 if (INTEGERP (Vtool_bar_button_margin)
8616 && XINT (Vtool_bar_button_margin) > 0)
8618 hmargin += XFASTINT (Vtool_bar_button_margin);
8619 vmargin += XFASTINT (Vtool_bar_button_margin);
8621 else if (CONSP (Vtool_bar_button_margin))
8623 if (INTEGERP (XCAR (Vtool_bar_button_margin))
8624 && XINT (XCAR (Vtool_bar_button_margin)) > 0)
8625 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
8627 if (INTEGERP (XCDR (Vtool_bar_button_margin))
8628 && XINT (XCDR (Vtool_bar_button_margin)) > 0)
8629 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
8632 if (auto_raise_tool_bar_buttons_p)
8634 /* Add a `:relief' property to the image spec if the item is
8635 selected. */
8636 if (selected_p)
8638 plist = Fplist_put (plist, QCrelief, make_number (-relief));
8639 hmargin -= relief;
8640 vmargin -= relief;
8643 else
8645 /* If image is selected, display it pressed, i.e. with a
8646 negative relief. If it's not selected, display it with a
8647 raised relief. */
8648 plist = Fplist_put (plist, QCrelief,
8649 (selected_p
8650 ? make_number (-relief)
8651 : make_number (relief)));
8652 hmargin -= relief;
8653 vmargin -= relief;
8656 /* Put a margin around the image. */
8657 if (hmargin || vmargin)
8659 if (hmargin == vmargin)
8660 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
8661 else
8662 plist = Fplist_put (plist, QCmargin,
8663 Fcons (make_number (hmargin),
8664 make_number (vmargin)));
8667 /* If button is not enabled, and we don't have special images
8668 for the disabled state, make the image appear disabled by
8669 applying an appropriate algorithm to it. */
8670 if (!enabled_p && idx < 0)
8671 plist = Fplist_put (plist, QCconversion, Qdisabled);
8673 /* Put a `display' text property on the string for the image to
8674 display. Put a `menu-item' property on the string that gives
8675 the start of this item's properties in the tool-bar items
8676 vector. */
8677 image = Fcons (Qimage, plist);
8678 props = list4 (Qdisplay, image,
8679 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS));
8681 /* Let the last image hide all remaining spaces in the tool bar
8682 string. The string can be longer than needed when we reuse a
8683 previous string. */
8684 if (i + 1 == f->n_tool_bar_items)
8685 end = SCHARS (f->desired_tool_bar_string);
8686 else
8687 end = i + 1;
8688 Fadd_text_properties (make_number (i), make_number (end),
8689 props, f->desired_tool_bar_string);
8690 #undef PROP
8693 UNGCPRO;
8697 /* Display one line of the tool-bar of frame IT->f. */
8699 static void
8700 display_tool_bar_line (it)
8701 struct it *it;
8703 struct glyph_row *row = it->glyph_row;
8704 int max_x = it->last_visible_x;
8705 struct glyph *last;
8707 prepare_desired_row (row);
8708 row->y = it->current_y;
8710 /* Note that this isn't made use of if the face hasn't a box,
8711 so there's no need to check the face here. */
8712 it->start_of_box_run_p = 1;
8714 while (it->current_x < max_x)
8716 int x_before, x, n_glyphs_before, i, nglyphs;
8718 /* Get the next display element. */
8719 if (!get_next_display_element (it))
8720 break;
8722 /* Produce glyphs. */
8723 x_before = it->current_x;
8724 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
8725 PRODUCE_GLYPHS (it);
8727 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
8728 i = 0;
8729 x = x_before;
8730 while (i < nglyphs)
8732 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
8734 if (x + glyph->pixel_width > max_x)
8736 /* Glyph doesn't fit on line. */
8737 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
8738 it->current_x = x;
8739 goto out;
8742 ++it->hpos;
8743 x += glyph->pixel_width;
8744 ++i;
8747 /* Stop at line ends. */
8748 if (ITERATOR_AT_END_OF_LINE_P (it))
8749 break;
8751 set_iterator_to_next (it, 1);
8754 out:;
8756 row->displays_text_p = row->used[TEXT_AREA] != 0;
8757 extend_face_to_end_of_line (it);
8758 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
8759 last->right_box_line_p = 1;
8760 if (last == row->glyphs[TEXT_AREA])
8761 last->left_box_line_p = 1;
8762 compute_line_metrics (it);
8764 /* If line is empty, make it occupy the rest of the tool-bar. */
8765 if (!row->displays_text_p)
8767 row->height = row->phys_height = it->last_visible_y - row->y;
8768 row->ascent = row->phys_ascent = 0;
8769 row->extra_line_spacing = 0;
8772 row->full_width_p = 1;
8773 row->continued_p = 0;
8774 row->truncated_on_left_p = 0;
8775 row->truncated_on_right_p = 0;
8777 it->current_x = it->hpos = 0;
8778 it->current_y += row->height;
8779 ++it->vpos;
8780 ++it->glyph_row;
8784 /* Value is the number of screen lines needed to make all tool-bar
8785 items of frame F visible. */
8787 static int
8788 tool_bar_lines_needed (f)
8789 struct frame *f;
8791 struct window *w = XWINDOW (f->tool_bar_window);
8792 struct it it;
8794 /* Initialize an iterator for iteration over
8795 F->desired_tool_bar_string in the tool-bar window of frame F. */
8796 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
8797 it.first_visible_x = 0;
8798 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
8799 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
8801 while (!ITERATOR_AT_END_P (&it))
8803 it.glyph_row = w->desired_matrix->rows;
8804 clear_glyph_row (it.glyph_row);
8805 display_tool_bar_line (&it);
8808 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
8812 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
8813 0, 1, 0,
8814 doc: /* Return the number of lines occupied by the tool bar of FRAME. */)
8815 (frame)
8816 Lisp_Object frame;
8818 struct frame *f;
8819 struct window *w;
8820 int nlines = 0;
8822 if (NILP (frame))
8823 frame = selected_frame;
8824 else
8825 CHECK_FRAME (frame);
8826 f = XFRAME (frame);
8828 if (WINDOWP (f->tool_bar_window)
8829 || (w = XWINDOW (f->tool_bar_window),
8830 WINDOW_TOTAL_LINES (w) > 0))
8832 update_tool_bar (f, 1);
8833 if (f->n_tool_bar_items)
8835 build_desired_tool_bar_string (f);
8836 nlines = tool_bar_lines_needed (f);
8840 return make_number (nlines);
8844 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
8845 height should be changed. */
8847 static int
8848 redisplay_tool_bar (f)
8849 struct frame *f;
8851 struct window *w;
8852 struct it it;
8853 struct glyph_row *row;
8854 int change_height_p = 0;
8856 #ifdef USE_GTK
8857 if (FRAME_EXTERNAL_TOOL_BAR (f))
8858 update_frame_tool_bar (f);
8859 return 0;
8860 #endif
8862 /* If frame hasn't a tool-bar window or if it is zero-height, don't
8863 do anything. This means you must start with tool-bar-lines
8864 non-zero to get the auto-sizing effect. Or in other words, you
8865 can turn off tool-bars by specifying tool-bar-lines zero. */
8866 if (!WINDOWP (f->tool_bar_window)
8867 || (w = XWINDOW (f->tool_bar_window),
8868 WINDOW_TOTAL_LINES (w) == 0))
8869 return 0;
8871 /* Set up an iterator for the tool-bar window. */
8872 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
8873 it.first_visible_x = 0;
8874 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
8875 row = it.glyph_row;
8877 /* Build a string that represents the contents of the tool-bar. */
8878 build_desired_tool_bar_string (f);
8879 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
8881 /* Display as many lines as needed to display all tool-bar items. */
8882 while (it.current_y < it.last_visible_y)
8883 display_tool_bar_line (&it);
8885 /* It doesn't make much sense to try scrolling in the tool-bar
8886 window, so don't do it. */
8887 w->desired_matrix->no_scrolling_p = 1;
8888 w->must_be_updated_p = 1;
8890 if (auto_resize_tool_bars_p)
8892 int nlines;
8894 /* If we couldn't display everything, change the tool-bar's
8895 height. */
8896 if (IT_STRING_CHARPOS (it) < it.end_charpos)
8897 change_height_p = 1;
8899 /* If there are blank lines at the end, except for a partially
8900 visible blank line at the end that is smaller than
8901 FRAME_LINE_HEIGHT, change the tool-bar's height. */
8902 row = it.glyph_row - 1;
8903 if (!row->displays_text_p
8904 && row->height >= FRAME_LINE_HEIGHT (f))
8905 change_height_p = 1;
8907 /* If row displays tool-bar items, but is partially visible,
8908 change the tool-bar's height. */
8909 if (row->displays_text_p
8910 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y)
8911 change_height_p = 1;
8913 /* Resize windows as needed by changing the `tool-bar-lines'
8914 frame parameter. */
8915 if (change_height_p
8916 && (nlines = tool_bar_lines_needed (f),
8917 nlines != WINDOW_TOTAL_LINES (w)))
8919 extern Lisp_Object Qtool_bar_lines;
8920 Lisp_Object frame;
8921 int old_height = WINDOW_TOTAL_LINES (w);
8923 XSETFRAME (frame, f);
8924 clear_glyph_matrix (w->desired_matrix);
8925 Fmodify_frame_parameters (frame,
8926 Fcons (Fcons (Qtool_bar_lines,
8927 make_number (nlines)),
8928 Qnil));
8929 if (WINDOW_TOTAL_LINES (w) != old_height)
8930 fonts_changed_p = 1;
8934 return change_height_p;
8938 /* Get information about the tool-bar item which is displayed in GLYPH
8939 on frame F. Return in *PROP_IDX the index where tool-bar item
8940 properties start in F->tool_bar_items. Value is zero if
8941 GLYPH doesn't display a tool-bar item. */
8943 static int
8944 tool_bar_item_info (f, glyph, prop_idx)
8945 struct frame *f;
8946 struct glyph *glyph;
8947 int *prop_idx;
8949 Lisp_Object prop;
8950 int success_p;
8951 int charpos;
8953 /* This function can be called asynchronously, which means we must
8954 exclude any possibility that Fget_text_property signals an
8955 error. */
8956 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
8957 charpos = max (0, charpos);
8959 /* Get the text property `menu-item' at pos. The value of that
8960 property is the start index of this item's properties in
8961 F->tool_bar_items. */
8962 prop = Fget_text_property (make_number (charpos),
8963 Qmenu_item, f->current_tool_bar_string);
8964 if (INTEGERP (prop))
8966 *prop_idx = XINT (prop);
8967 success_p = 1;
8969 else
8970 success_p = 0;
8972 return success_p;
8976 /* Get information about the tool-bar item at position X/Y on frame F.
8977 Return in *GLYPH a pointer to the glyph of the tool-bar item in
8978 the current matrix of the tool-bar window of F, or NULL if not
8979 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
8980 item in F->tool_bar_items. Value is
8982 -1 if X/Y is not on a tool-bar item
8983 0 if X/Y is on the same item that was highlighted before.
8984 1 otherwise. */
8986 static int
8987 get_tool_bar_item (f, x, y, glyph, hpos, vpos, prop_idx)
8988 struct frame *f;
8989 int x, y;
8990 struct glyph **glyph;
8991 int *hpos, *vpos, *prop_idx;
8993 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
8994 struct window *w = XWINDOW (f->tool_bar_window);
8995 int area;
8997 /* Find the glyph under X/Y. */
8998 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
8999 if (*glyph == NULL)
9000 return -1;
9002 /* Get the start of this tool-bar item's properties in
9003 f->tool_bar_items. */
9004 if (!tool_bar_item_info (f, *glyph, prop_idx))
9005 return -1;
9007 /* Is mouse on the highlighted item? */
9008 if (EQ (f->tool_bar_window, dpyinfo->mouse_face_window)
9009 && *vpos >= dpyinfo->mouse_face_beg_row
9010 && *vpos <= dpyinfo->mouse_face_end_row
9011 && (*vpos > dpyinfo->mouse_face_beg_row
9012 || *hpos >= dpyinfo->mouse_face_beg_col)
9013 && (*vpos < dpyinfo->mouse_face_end_row
9014 || *hpos < dpyinfo->mouse_face_end_col
9015 || dpyinfo->mouse_face_past_end))
9016 return 0;
9018 return 1;
9022 /* EXPORT:
9023 Handle mouse button event on the tool-bar of frame F, at
9024 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
9025 0 for button release. MODIFIERS is event modifiers for button
9026 release. */
9028 void
9029 handle_tool_bar_click (f, x, y, down_p, modifiers)
9030 struct frame *f;
9031 int x, y, down_p;
9032 unsigned int modifiers;
9034 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
9035 struct window *w = XWINDOW (f->tool_bar_window);
9036 int hpos, vpos, prop_idx;
9037 struct glyph *glyph;
9038 Lisp_Object enabled_p;
9040 /* If not on the highlighted tool-bar item, return. */
9041 frame_to_window_pixel_xy (w, &x, &y);
9042 if (get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0)
9043 return;
9045 /* If item is disabled, do nothing. */
9046 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
9047 if (NILP (enabled_p))
9048 return;
9050 if (down_p)
9052 /* Show item in pressed state. */
9053 show_mouse_face (dpyinfo, DRAW_IMAGE_SUNKEN);
9054 dpyinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN;
9055 last_tool_bar_item = prop_idx;
9057 else
9059 Lisp_Object key, frame;
9060 struct input_event event;
9061 EVENT_INIT (event);
9063 /* Show item in released state. */
9064 show_mouse_face (dpyinfo, DRAW_IMAGE_RAISED);
9065 dpyinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
9067 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
9069 XSETFRAME (frame, f);
9070 event.kind = TOOL_BAR_EVENT;
9071 event.frame_or_window = frame;
9072 event.arg = frame;
9073 kbd_buffer_store_event (&event);
9075 event.kind = TOOL_BAR_EVENT;
9076 event.frame_or_window = frame;
9077 event.arg = key;
9078 event.modifiers = modifiers;
9079 kbd_buffer_store_event (&event);
9080 last_tool_bar_item = -1;
9085 /* Possibly highlight a tool-bar item on frame F when mouse moves to
9086 tool-bar window-relative coordinates X/Y. Called from
9087 note_mouse_highlight. */
9089 static void
9090 note_tool_bar_highlight (f, x, y)
9091 struct frame *f;
9092 int x, y;
9094 Lisp_Object window = f->tool_bar_window;
9095 struct window *w = XWINDOW (window);
9096 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
9097 int hpos, vpos;
9098 struct glyph *glyph;
9099 struct glyph_row *row;
9100 int i;
9101 Lisp_Object enabled_p;
9102 int prop_idx;
9103 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
9104 int mouse_down_p, rc;
9106 /* Function note_mouse_highlight is called with negative x(y
9107 values when mouse moves outside of the frame. */
9108 if (x <= 0 || y <= 0)
9110 clear_mouse_face (dpyinfo);
9111 return;
9114 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
9115 if (rc < 0)
9117 /* Not on tool-bar item. */
9118 clear_mouse_face (dpyinfo);
9119 return;
9121 else if (rc == 0)
9122 /* On same tool-bar item as before. */
9123 goto set_help_echo;
9125 clear_mouse_face (dpyinfo);
9127 /* Mouse is down, but on different tool-bar item? */
9128 mouse_down_p = (dpyinfo->grabbed
9129 && f == last_mouse_frame
9130 && FRAME_LIVE_P (f));
9131 if (mouse_down_p
9132 && last_tool_bar_item != prop_idx)
9133 return;
9135 dpyinfo->mouse_face_image_state = DRAW_NORMAL_TEXT;
9136 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
9138 /* If tool-bar item is not enabled, don't highlight it. */
9139 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
9140 if (!NILP (enabled_p))
9142 /* Compute the x-position of the glyph. In front and past the
9143 image is a space. We include this in the highlighted area. */
9144 row = MATRIX_ROW (w->current_matrix, vpos);
9145 for (i = x = 0; i < hpos; ++i)
9146 x += row->glyphs[TEXT_AREA][i].pixel_width;
9148 /* Record this as the current active region. */
9149 dpyinfo->mouse_face_beg_col = hpos;
9150 dpyinfo->mouse_face_beg_row = vpos;
9151 dpyinfo->mouse_face_beg_x = x;
9152 dpyinfo->mouse_face_beg_y = row->y;
9153 dpyinfo->mouse_face_past_end = 0;
9155 dpyinfo->mouse_face_end_col = hpos + 1;
9156 dpyinfo->mouse_face_end_row = vpos;
9157 dpyinfo->mouse_face_end_x = x + glyph->pixel_width;
9158 dpyinfo->mouse_face_end_y = row->y;
9159 dpyinfo->mouse_face_window = window;
9160 dpyinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
9162 /* Display it as active. */
9163 show_mouse_face (dpyinfo, draw);
9164 dpyinfo->mouse_face_image_state = draw;
9167 set_help_echo:
9169 /* Set help_echo_string to a help string to display for this tool-bar item.
9170 XTread_socket does the rest. */
9171 help_echo_object = help_echo_window = Qnil;
9172 help_echo_pos = -1;
9173 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
9174 if (NILP (help_echo_string))
9175 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
9178 #endif /* HAVE_WINDOW_SYSTEM */
9182 /************************************************************************
9183 Horizontal scrolling
9184 ************************************************************************/
9186 static int hscroll_window_tree P_ ((Lisp_Object));
9187 static int hscroll_windows P_ ((Lisp_Object));
9189 /* For all leaf windows in the window tree rooted at WINDOW, set their
9190 hscroll value so that PT is (i) visible in the window, and (ii) so
9191 that it is not within a certain margin at the window's left and
9192 right border. Value is non-zero if any window's hscroll has been
9193 changed. */
9195 static int
9196 hscroll_window_tree (window)
9197 Lisp_Object window;
9199 int hscrolled_p = 0;
9200 int hscroll_relative_p = FLOATP (Vhscroll_step);
9201 int hscroll_step_abs = 0;
9202 double hscroll_step_rel = 0;
9204 if (hscroll_relative_p)
9206 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
9207 if (hscroll_step_rel < 0)
9209 hscroll_relative_p = 0;
9210 hscroll_step_abs = 0;
9213 else if (INTEGERP (Vhscroll_step))
9215 hscroll_step_abs = XINT (Vhscroll_step);
9216 if (hscroll_step_abs < 0)
9217 hscroll_step_abs = 0;
9219 else
9220 hscroll_step_abs = 0;
9222 while (WINDOWP (window))
9224 struct window *w = XWINDOW (window);
9226 if (WINDOWP (w->hchild))
9227 hscrolled_p |= hscroll_window_tree (w->hchild);
9228 else if (WINDOWP (w->vchild))
9229 hscrolled_p |= hscroll_window_tree (w->vchild);
9230 else if (w->cursor.vpos >= 0)
9232 int h_margin;
9233 int text_area_width;
9234 struct glyph_row *current_cursor_row
9235 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
9236 struct glyph_row *desired_cursor_row
9237 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
9238 struct glyph_row *cursor_row
9239 = (desired_cursor_row->enabled_p
9240 ? desired_cursor_row
9241 : current_cursor_row);
9243 text_area_width = window_box_width (w, TEXT_AREA);
9245 /* Scroll when cursor is inside this scroll margin. */
9246 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
9248 if ((XFASTINT (w->hscroll)
9249 && w->cursor.x <= h_margin)
9250 || (cursor_row->enabled_p
9251 && cursor_row->truncated_on_right_p
9252 && (w->cursor.x >= text_area_width - h_margin)))
9254 struct it it;
9255 int hscroll;
9256 struct buffer *saved_current_buffer;
9257 int pt;
9258 int wanted_x;
9260 /* Find point in a display of infinite width. */
9261 saved_current_buffer = current_buffer;
9262 current_buffer = XBUFFER (w->buffer);
9264 if (w == XWINDOW (selected_window))
9265 pt = BUF_PT (current_buffer);
9266 else
9268 pt = marker_position (w->pointm);
9269 pt = max (BEGV, pt);
9270 pt = min (ZV, pt);
9273 /* Move iterator to pt starting at cursor_row->start in
9274 a line with infinite width. */
9275 init_to_row_start (&it, w, cursor_row);
9276 it.last_visible_x = INFINITY;
9277 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
9278 current_buffer = saved_current_buffer;
9280 /* Position cursor in window. */
9281 if (!hscroll_relative_p && hscroll_step_abs == 0)
9282 hscroll = max (0, (it.current_x
9283 - (ITERATOR_AT_END_OF_LINE_P (&it)
9284 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
9285 : (text_area_width / 2))))
9286 / FRAME_COLUMN_WIDTH (it.f);
9287 else if (w->cursor.x >= text_area_width - h_margin)
9289 if (hscroll_relative_p)
9290 wanted_x = text_area_width * (1 - hscroll_step_rel)
9291 - h_margin;
9292 else
9293 wanted_x = text_area_width
9294 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
9295 - h_margin;
9296 hscroll
9297 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
9299 else
9301 if (hscroll_relative_p)
9302 wanted_x = text_area_width * hscroll_step_rel
9303 + h_margin;
9304 else
9305 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
9306 + h_margin;
9307 hscroll
9308 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
9310 hscroll = max (hscroll, XFASTINT (w->min_hscroll));
9312 /* Don't call Fset_window_hscroll if value hasn't
9313 changed because it will prevent redisplay
9314 optimizations. */
9315 if (XFASTINT (w->hscroll) != hscroll)
9317 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
9318 w->hscroll = make_number (hscroll);
9319 hscrolled_p = 1;
9324 window = w->next;
9327 /* Value is non-zero if hscroll of any leaf window has been changed. */
9328 return hscrolled_p;
9332 /* Set hscroll so that cursor is visible and not inside horizontal
9333 scroll margins for all windows in the tree rooted at WINDOW. See
9334 also hscroll_window_tree above. Value is non-zero if any window's
9335 hscroll has been changed. If it has, desired matrices on the frame
9336 of WINDOW are cleared. */
9338 static int
9339 hscroll_windows (window)
9340 Lisp_Object window;
9342 int hscrolled_p;
9344 if (automatic_hscrolling_p)
9346 hscrolled_p = hscroll_window_tree (window);
9347 if (hscrolled_p)
9348 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
9350 else
9351 hscrolled_p = 0;
9352 return hscrolled_p;
9357 /************************************************************************
9358 Redisplay
9359 ************************************************************************/
9361 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
9362 to a non-zero value. This is sometimes handy to have in a debugger
9363 session. */
9365 #if GLYPH_DEBUG
9367 /* First and last unchanged row for try_window_id. */
9369 int debug_first_unchanged_at_end_vpos;
9370 int debug_last_unchanged_at_beg_vpos;
9372 /* Delta vpos and y. */
9374 int debug_dvpos, debug_dy;
9376 /* Delta in characters and bytes for try_window_id. */
9378 int debug_delta, debug_delta_bytes;
9380 /* Values of window_end_pos and window_end_vpos at the end of
9381 try_window_id. */
9383 EMACS_INT debug_end_pos, debug_end_vpos;
9385 /* Append a string to W->desired_matrix->method. FMT is a printf
9386 format string. A1...A9 are a supplement for a variable-length
9387 argument list. If trace_redisplay_p is non-zero also printf the
9388 resulting string to stderr. */
9390 static void
9391 debug_method_add (w, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
9392 struct window *w;
9393 char *fmt;
9394 int a1, a2, a3, a4, a5, a6, a7, a8, a9;
9396 char buffer[512];
9397 char *method = w->desired_matrix->method;
9398 int len = strlen (method);
9399 int size = sizeof w->desired_matrix->method;
9400 int remaining = size - len - 1;
9402 sprintf (buffer, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
9403 if (len && remaining)
9405 method[len] = '|';
9406 --remaining, ++len;
9409 strncpy (method + len, buffer, remaining);
9411 if (trace_redisplay_p)
9412 fprintf (stderr, "%p (%s): %s\n",
9414 ((BUFFERP (w->buffer)
9415 && STRINGP (XBUFFER (w->buffer)->name))
9416 ? (char *) SDATA (XBUFFER (w->buffer)->name)
9417 : "no buffer"),
9418 buffer);
9421 #endif /* GLYPH_DEBUG */
9424 /* Value is non-zero if all changes in window W, which displays
9425 current_buffer, are in the text between START and END. START is a
9426 buffer position, END is given as a distance from Z. Used in
9427 redisplay_internal for display optimization. */
9429 static INLINE int
9430 text_outside_line_unchanged_p (w, start, end)
9431 struct window *w;
9432 int start, end;
9434 int unchanged_p = 1;
9436 /* If text or overlays have changed, see where. */
9437 if (XFASTINT (w->last_modified) < MODIFF
9438 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
9440 /* Gap in the line? */
9441 if (GPT < start || Z - GPT < end)
9442 unchanged_p = 0;
9444 /* Changes start in front of the line, or end after it? */
9445 if (unchanged_p
9446 && (BEG_UNCHANGED < start - 1
9447 || END_UNCHANGED < end))
9448 unchanged_p = 0;
9450 /* If selective display, can't optimize if changes start at the
9451 beginning of the line. */
9452 if (unchanged_p
9453 && INTEGERP (current_buffer->selective_display)
9454 && XINT (current_buffer->selective_display) > 0
9455 && (BEG_UNCHANGED < start || GPT <= start))
9456 unchanged_p = 0;
9458 /* If there are overlays at the start or end of the line, these
9459 may have overlay strings with newlines in them. A change at
9460 START, for instance, may actually concern the display of such
9461 overlay strings as well, and they are displayed on different
9462 lines. So, quickly rule out this case. (For the future, it
9463 might be desirable to implement something more telling than
9464 just BEG/END_UNCHANGED.) */
9465 if (unchanged_p)
9467 if (BEG + BEG_UNCHANGED == start
9468 && overlay_touches_p (start))
9469 unchanged_p = 0;
9470 if (END_UNCHANGED == end
9471 && overlay_touches_p (Z - end))
9472 unchanged_p = 0;
9476 return unchanged_p;
9480 /* Do a frame update, taking possible shortcuts into account. This is
9481 the main external entry point for redisplay.
9483 If the last redisplay displayed an echo area message and that message
9484 is no longer requested, we clear the echo area or bring back the
9485 mini-buffer if that is in use. */
9487 void
9488 redisplay ()
9490 redisplay_internal (0);
9494 static Lisp_Object
9495 overlay_arrow_string_or_property (var, pbitmap)
9496 Lisp_Object var;
9497 int *pbitmap;
9499 Lisp_Object pstr = Fget (var, Qoverlay_arrow_string);
9500 Lisp_Object bitmap;
9502 if (pbitmap)
9504 *pbitmap = 0;
9505 if (bitmap = Fget (var, Qoverlay_arrow_bitmap), INTEGERP (bitmap))
9506 *pbitmap = XINT (bitmap);
9509 if (!NILP (pstr))
9510 return pstr;
9511 return Voverlay_arrow_string;
9514 /* Return 1 if there are any overlay-arrows in current_buffer. */
9515 static int
9516 overlay_arrow_in_current_buffer_p ()
9518 Lisp_Object vlist;
9520 for (vlist = Voverlay_arrow_variable_list;
9521 CONSP (vlist);
9522 vlist = XCDR (vlist))
9524 Lisp_Object var = XCAR (vlist);
9525 Lisp_Object val;
9527 if (!SYMBOLP (var))
9528 continue;
9529 val = find_symbol_value (var);
9530 if (MARKERP (val)
9531 && current_buffer == XMARKER (val)->buffer)
9532 return 1;
9534 return 0;
9538 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
9539 has changed. */
9541 static int
9542 overlay_arrows_changed_p ()
9544 Lisp_Object vlist;
9546 for (vlist = Voverlay_arrow_variable_list;
9547 CONSP (vlist);
9548 vlist = XCDR (vlist))
9550 Lisp_Object var = XCAR (vlist);
9551 Lisp_Object val, pstr;
9553 if (!SYMBOLP (var))
9554 continue;
9555 val = find_symbol_value (var);
9556 if (!MARKERP (val))
9557 continue;
9558 if (! EQ (COERCE_MARKER (val),
9559 Fget (var, Qlast_arrow_position))
9560 || ! (pstr = overlay_arrow_string_or_property (var, 0),
9561 EQ (pstr, Fget (var, Qlast_arrow_string))))
9562 return 1;
9564 return 0;
9567 /* Mark overlay arrows to be updated on next redisplay. */
9569 static void
9570 update_overlay_arrows (up_to_date)
9571 int up_to_date;
9573 Lisp_Object vlist;
9575 for (vlist = Voverlay_arrow_variable_list;
9576 CONSP (vlist);
9577 vlist = XCDR (vlist))
9579 Lisp_Object var = XCAR (vlist);
9581 if (!SYMBOLP (var))
9582 continue;
9584 if (up_to_date > 0)
9586 Lisp_Object val = find_symbol_value (var);
9587 Fput (var, Qlast_arrow_position,
9588 COERCE_MARKER (val));
9589 Fput (var, Qlast_arrow_string,
9590 overlay_arrow_string_or_property (var, 0));
9592 else if (up_to_date < 0
9593 || !NILP (Fget (var, Qlast_arrow_position)))
9595 Fput (var, Qlast_arrow_position, Qt);
9596 Fput (var, Qlast_arrow_string, Qt);
9602 /* Return overlay arrow string to display at row.
9603 Return t if display as bitmap in left fringe.
9604 Return nil if no overlay arrow. */
9606 static Lisp_Object
9607 overlay_arrow_at_row (it, row, pbitmap)
9608 struct it *it;
9609 struct glyph_row *row;
9610 int *pbitmap;
9612 Lisp_Object vlist;
9614 for (vlist = Voverlay_arrow_variable_list;
9615 CONSP (vlist);
9616 vlist = XCDR (vlist))
9618 Lisp_Object var = XCAR (vlist);
9619 Lisp_Object val;
9621 if (!SYMBOLP (var))
9622 continue;
9624 val = find_symbol_value (var);
9626 if (MARKERP (val)
9627 && current_buffer == XMARKER (val)->buffer
9628 && (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
9630 val = overlay_arrow_string_or_property (var, pbitmap);
9631 if (FRAME_WINDOW_P (it->f)
9632 && WINDOW_LEFT_FRINGE_WIDTH (it->w) > 0)
9633 return Qt;
9634 if (STRINGP (val))
9635 return val;
9636 break;
9640 *pbitmap = 0;
9641 return Qnil;
9644 /* Return 1 if point moved out of or into a composition. Otherwise
9645 return 0. PREV_BUF and PREV_PT are the last point buffer and
9646 position. BUF and PT are the current point buffer and position. */
9649 check_point_in_composition (prev_buf, prev_pt, buf, pt)
9650 struct buffer *prev_buf, *buf;
9651 int prev_pt, pt;
9653 int start, end;
9654 Lisp_Object prop;
9655 Lisp_Object buffer;
9657 XSETBUFFER (buffer, buf);
9658 /* Check a composition at the last point if point moved within the
9659 same buffer. */
9660 if (prev_buf == buf)
9662 if (prev_pt == pt)
9663 /* Point didn't move. */
9664 return 0;
9666 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
9667 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
9668 && COMPOSITION_VALID_P (start, end, prop)
9669 && start < prev_pt && end > prev_pt)
9670 /* The last point was within the composition. Return 1 iff
9671 point moved out of the composition. */
9672 return (pt <= start || pt >= end);
9675 /* Check a composition at the current point. */
9676 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
9677 && find_composition (pt, -1, &start, &end, &prop, buffer)
9678 && COMPOSITION_VALID_P (start, end, prop)
9679 && start < pt && end > pt);
9683 /* Reconsider the setting of B->clip_changed which is displayed
9684 in window W. */
9686 static INLINE void
9687 reconsider_clip_changes (w, b)
9688 struct window *w;
9689 struct buffer *b;
9691 if (b->clip_changed
9692 && !NILP (w->window_end_valid)
9693 && w->current_matrix->buffer == b
9694 && w->current_matrix->zv == BUF_ZV (b)
9695 && w->current_matrix->begv == BUF_BEGV (b))
9696 b->clip_changed = 0;
9698 /* If display wasn't paused, and W is not a tool bar window, see if
9699 point has been moved into or out of a composition. In that case,
9700 we set b->clip_changed to 1 to force updating the screen. If
9701 b->clip_changed has already been set to 1, we can skip this
9702 check. */
9703 if (!b->clip_changed
9704 && BUFFERP (w->buffer) && !NILP (w->window_end_valid))
9706 int pt;
9708 if (w == XWINDOW (selected_window))
9709 pt = BUF_PT (current_buffer);
9710 else
9711 pt = marker_position (w->pointm);
9713 if ((w->current_matrix->buffer != XBUFFER (w->buffer)
9714 || pt != XINT (w->last_point))
9715 && check_point_in_composition (w->current_matrix->buffer,
9716 XINT (w->last_point),
9717 XBUFFER (w->buffer), pt))
9718 b->clip_changed = 1;
9723 /* Select FRAME to forward the values of frame-local variables into C
9724 variables so that the redisplay routines can access those values
9725 directly. */
9727 static void
9728 select_frame_for_redisplay (frame)
9729 Lisp_Object frame;
9731 Lisp_Object tail, sym, val;
9732 Lisp_Object old = selected_frame;
9734 selected_frame = frame;
9736 for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail))
9737 if (CONSP (XCAR (tail))
9738 && (sym = XCAR (XCAR (tail)),
9739 SYMBOLP (sym))
9740 && (sym = indirect_variable (sym),
9741 val = SYMBOL_VALUE (sym),
9742 (BUFFER_LOCAL_VALUEP (val)
9743 || SOME_BUFFER_LOCAL_VALUEP (val)))
9744 && XBUFFER_LOCAL_VALUE (val)->check_frame)
9745 Fsymbol_value (sym);
9747 for (tail = XFRAME (old)->param_alist; CONSP (tail); tail = XCDR (tail))
9748 if (CONSP (XCAR (tail))
9749 && (sym = XCAR (XCAR (tail)),
9750 SYMBOLP (sym))
9751 && (sym = indirect_variable (sym),
9752 val = SYMBOL_VALUE (sym),
9753 (BUFFER_LOCAL_VALUEP (val)
9754 || SOME_BUFFER_LOCAL_VALUEP (val)))
9755 && XBUFFER_LOCAL_VALUE (val)->check_frame)
9756 Fsymbol_value (sym);
9760 #define STOP_POLLING \
9761 do { if (! polling_stopped_here) stop_polling (); \
9762 polling_stopped_here = 1; } while (0)
9764 #define RESUME_POLLING \
9765 do { if (polling_stopped_here) start_polling (); \
9766 polling_stopped_here = 0; } while (0)
9769 /* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
9770 response to any user action; therefore, we should preserve the echo
9771 area. (Actually, our caller does that job.) Perhaps in the future
9772 avoid recentering windows if it is not necessary; currently that
9773 causes some problems. */
9775 static void
9776 redisplay_internal (preserve_echo_area)
9777 int preserve_echo_area;
9779 struct window *w = XWINDOW (selected_window);
9780 struct frame *f = XFRAME (w->frame);
9781 int pause;
9782 int must_finish = 0;
9783 struct text_pos tlbufpos, tlendpos;
9784 int number_of_visible_frames;
9785 int count;
9786 struct frame *sf = SELECTED_FRAME ();
9787 int polling_stopped_here = 0;
9789 /* Non-zero means redisplay has to consider all windows on all
9790 frames. Zero means, only selected_window is considered. */
9791 int consider_all_windows_p;
9793 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
9795 /* No redisplay if running in batch mode or frame is not yet fully
9796 initialized, or redisplay is explicitly turned off by setting
9797 Vinhibit_redisplay. */
9798 if (noninteractive
9799 || !NILP (Vinhibit_redisplay)
9800 || !f->glyphs_initialized_p)
9801 return;
9803 /* The flag redisplay_performed_directly_p is set by
9804 direct_output_for_insert when it already did the whole screen
9805 update necessary. */
9806 if (redisplay_performed_directly_p)
9808 redisplay_performed_directly_p = 0;
9809 if (!hscroll_windows (selected_window))
9810 return;
9813 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
9814 if (popup_activated ())
9815 return;
9816 #endif
9818 /* I don't think this happens but let's be paranoid. */
9819 if (redisplaying_p)
9820 return;
9822 /* Record a function that resets redisplaying_p to its old value
9823 when we leave this function. */
9824 count = SPECPDL_INDEX ();
9825 record_unwind_protect (unwind_redisplay,
9826 Fcons (make_number (redisplaying_p), selected_frame));
9827 ++redisplaying_p;
9828 specbind (Qinhibit_free_realized_faces, Qnil);
9830 retry:
9831 pause = 0;
9832 reconsider_clip_changes (w, current_buffer);
9834 /* If new fonts have been loaded that make a glyph matrix adjustment
9835 necessary, do it. */
9836 if (fonts_changed_p)
9838 adjust_glyphs (NULL);
9839 ++windows_or_buffers_changed;
9840 fonts_changed_p = 0;
9843 /* If face_change_count is non-zero, init_iterator will free all
9844 realized faces, which includes the faces referenced from current
9845 matrices. So, we can't reuse current matrices in this case. */
9846 if (face_change_count)
9847 ++windows_or_buffers_changed;
9849 if (! FRAME_WINDOW_P (sf)
9850 && previous_terminal_frame != sf)
9852 /* Since frames on an ASCII terminal share the same display
9853 area, displaying a different frame means redisplay the whole
9854 thing. */
9855 windows_or_buffers_changed++;
9856 SET_FRAME_GARBAGED (sf);
9857 XSETFRAME (Vterminal_frame, sf);
9859 previous_terminal_frame = sf;
9861 /* Set the visible flags for all frames. Do this before checking
9862 for resized or garbaged frames; they want to know if their frames
9863 are visible. See the comment in frame.h for
9864 FRAME_SAMPLE_VISIBILITY. */
9866 Lisp_Object tail, frame;
9868 number_of_visible_frames = 0;
9870 FOR_EACH_FRAME (tail, frame)
9872 struct frame *f = XFRAME (frame);
9874 FRAME_SAMPLE_VISIBILITY (f);
9875 if (FRAME_VISIBLE_P (f))
9876 ++number_of_visible_frames;
9877 clear_desired_matrices (f);
9881 /* Notice any pending interrupt request to change frame size. */
9882 do_pending_window_change (1);
9884 /* Clear frames marked as garbaged. */
9885 if (frame_garbaged)
9886 clear_garbaged_frames ();
9888 /* Build menubar and tool-bar items. */
9889 prepare_menu_bars ();
9891 if (windows_or_buffers_changed)
9892 update_mode_lines++;
9894 /* Detect case that we need to write or remove a star in the mode line. */
9895 if ((SAVE_MODIFF < MODIFF) != !NILP (w->last_had_star))
9897 w->update_mode_line = Qt;
9898 if (buffer_shared > 1)
9899 update_mode_lines++;
9902 /* If %c is in the mode line, update it if needed. */
9903 if (!NILP (w->column_number_displayed)
9904 /* This alternative quickly identifies a common case
9905 where no change is needed. */
9906 && !(PT == XFASTINT (w->last_point)
9907 && XFASTINT (w->last_modified) >= MODIFF
9908 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
9909 && (XFASTINT (w->column_number_displayed)
9910 != (int) current_column ())) /* iftc */
9911 w->update_mode_line = Qt;
9913 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
9915 /* The variable buffer_shared is set in redisplay_window and
9916 indicates that we redisplay a buffer in different windows. See
9917 there. */
9918 consider_all_windows_p = (update_mode_lines || buffer_shared > 1
9919 || cursor_type_changed);
9921 /* If specs for an arrow have changed, do thorough redisplay
9922 to ensure we remove any arrow that should no longer exist. */
9923 if (overlay_arrows_changed_p ())
9924 consider_all_windows_p = windows_or_buffers_changed = 1;
9926 /* Normally the message* functions will have already displayed and
9927 updated the echo area, but the frame may have been trashed, or
9928 the update may have been preempted, so display the echo area
9929 again here. Checking message_cleared_p captures the case that
9930 the echo area should be cleared. */
9931 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
9932 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
9933 || (message_cleared_p
9934 && minibuf_level == 0
9935 /* If the mini-window is currently selected, this means the
9936 echo-area doesn't show through. */
9937 && !MINI_WINDOW_P (XWINDOW (selected_window))))
9939 int window_height_changed_p = echo_area_display (0);
9940 must_finish = 1;
9942 /* If we don't display the current message, don't clear the
9943 message_cleared_p flag, because, if we did, we wouldn't clear
9944 the echo area in the next redisplay which doesn't preserve
9945 the echo area. */
9946 if (!display_last_displayed_message_p)
9947 message_cleared_p = 0;
9949 if (fonts_changed_p)
9950 goto retry;
9951 else if (window_height_changed_p)
9953 consider_all_windows_p = 1;
9954 ++update_mode_lines;
9955 ++windows_or_buffers_changed;
9957 /* If window configuration was changed, frames may have been
9958 marked garbaged. Clear them or we will experience
9959 surprises wrt scrolling. */
9960 if (frame_garbaged)
9961 clear_garbaged_frames ();
9964 else if (EQ (selected_window, minibuf_window)
9965 && (current_buffer->clip_changed
9966 || XFASTINT (w->last_modified) < MODIFF
9967 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
9968 && resize_mini_window (w, 0))
9970 /* Resized active mini-window to fit the size of what it is
9971 showing if its contents might have changed. */
9972 must_finish = 1;
9973 consider_all_windows_p = 1;
9974 ++windows_or_buffers_changed;
9975 ++update_mode_lines;
9977 /* If window configuration was changed, frames may have been
9978 marked garbaged. Clear them or we will experience
9979 surprises wrt scrolling. */
9980 if (frame_garbaged)
9981 clear_garbaged_frames ();
9985 /* If showing the region, and mark has changed, we must redisplay
9986 the whole window. The assignment to this_line_start_pos prevents
9987 the optimization directly below this if-statement. */
9988 if (((!NILP (Vtransient_mark_mode)
9989 && !NILP (XBUFFER (w->buffer)->mark_active))
9990 != !NILP (w->region_showing))
9991 || (!NILP (w->region_showing)
9992 && !EQ (w->region_showing,
9993 Fmarker_position (XBUFFER (w->buffer)->mark))))
9994 CHARPOS (this_line_start_pos) = 0;
9996 /* Optimize the case that only the line containing the cursor in the
9997 selected window has changed. Variables starting with this_ are
9998 set in display_line and record information about the line
9999 containing the cursor. */
10000 tlbufpos = this_line_start_pos;
10001 tlendpos = this_line_end_pos;
10002 if (!consider_all_windows_p
10003 && CHARPOS (tlbufpos) > 0
10004 && NILP (w->update_mode_line)
10005 && !current_buffer->clip_changed
10006 && !current_buffer->prevent_redisplay_optimizations_p
10007 && FRAME_VISIBLE_P (XFRAME (w->frame))
10008 && !FRAME_OBSCURED_P (XFRAME (w->frame))
10009 /* Make sure recorded data applies to current buffer, etc. */
10010 && this_line_buffer == current_buffer
10011 && current_buffer == XBUFFER (w->buffer)
10012 && NILP (w->force_start)
10013 && NILP (w->optional_new_start)
10014 /* Point must be on the line that we have info recorded about. */
10015 && PT >= CHARPOS (tlbufpos)
10016 && PT <= Z - CHARPOS (tlendpos)
10017 /* All text outside that line, including its final newline,
10018 must be unchanged */
10019 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
10020 CHARPOS (tlendpos)))
10022 if (CHARPOS (tlbufpos) > BEGV
10023 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
10024 && (CHARPOS (tlbufpos) == ZV
10025 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
10026 /* Former continuation line has disappeared by becoming empty */
10027 goto cancel;
10028 else if (XFASTINT (w->last_modified) < MODIFF
10029 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF
10030 || MINI_WINDOW_P (w))
10032 /* We have to handle the case of continuation around a
10033 wide-column character (See the comment in indent.c around
10034 line 885).
10036 For instance, in the following case:
10038 -------- Insert --------
10039 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
10040 J_I_ ==> J_I_ `^^' are cursors.
10041 ^^ ^^
10042 -------- --------
10044 As we have to redraw the line above, we should goto cancel. */
10046 struct it it;
10047 int line_height_before = this_line_pixel_height;
10049 /* Note that start_display will handle the case that the
10050 line starting at tlbufpos is a continuation lines. */
10051 start_display (&it, w, tlbufpos);
10053 /* Implementation note: It this still necessary? */
10054 if (it.current_x != this_line_start_x)
10055 goto cancel;
10057 TRACE ((stderr, "trying display optimization 1\n"));
10058 w->cursor.vpos = -1;
10059 overlay_arrow_seen = 0;
10060 it.vpos = this_line_vpos;
10061 it.current_y = this_line_y;
10062 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
10063 display_line (&it);
10065 /* If line contains point, is not continued,
10066 and ends at same distance from eob as before, we win */
10067 if (w->cursor.vpos >= 0
10068 /* Line is not continued, otherwise this_line_start_pos
10069 would have been set to 0 in display_line. */
10070 && CHARPOS (this_line_start_pos)
10071 /* Line ends as before. */
10072 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
10073 /* Line has same height as before. Otherwise other lines
10074 would have to be shifted up or down. */
10075 && this_line_pixel_height == line_height_before)
10077 /* If this is not the window's last line, we must adjust
10078 the charstarts of the lines below. */
10079 if (it.current_y < it.last_visible_y)
10081 struct glyph_row *row
10082 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
10083 int delta, delta_bytes;
10085 if (Z - CHARPOS (tlendpos) == ZV)
10087 /* This line ends at end of (accessible part of)
10088 buffer. There is no newline to count. */
10089 delta = (Z
10090 - CHARPOS (tlendpos)
10091 - MATRIX_ROW_START_CHARPOS (row));
10092 delta_bytes = (Z_BYTE
10093 - BYTEPOS (tlendpos)
10094 - MATRIX_ROW_START_BYTEPOS (row));
10096 else
10098 /* This line ends in a newline. Must take
10099 account of the newline and the rest of the
10100 text that follows. */
10101 delta = (Z
10102 - CHARPOS (tlendpos)
10103 - MATRIX_ROW_START_CHARPOS (row));
10104 delta_bytes = (Z_BYTE
10105 - BYTEPOS (tlendpos)
10106 - MATRIX_ROW_START_BYTEPOS (row));
10109 increment_matrix_positions (w->current_matrix,
10110 this_line_vpos + 1,
10111 w->current_matrix->nrows,
10112 delta, delta_bytes);
10115 /* If this row displays text now but previously didn't,
10116 or vice versa, w->window_end_vpos may have to be
10117 adjusted. */
10118 if ((it.glyph_row - 1)->displays_text_p)
10120 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
10121 XSETINT (w->window_end_vpos, this_line_vpos);
10123 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
10124 && this_line_vpos > 0)
10125 XSETINT (w->window_end_vpos, this_line_vpos - 1);
10126 w->window_end_valid = Qnil;
10128 /* Update hint: No need to try to scroll in update_window. */
10129 w->desired_matrix->no_scrolling_p = 1;
10131 #if GLYPH_DEBUG
10132 *w->desired_matrix->method = 0;
10133 debug_method_add (w, "optimization 1");
10134 #endif
10135 #ifdef HAVE_WINDOW_SYSTEM
10136 update_window_fringes (w, 0);
10137 #endif
10138 goto update;
10140 else
10141 goto cancel;
10143 else if (/* Cursor position hasn't changed. */
10144 PT == XFASTINT (w->last_point)
10145 /* Make sure the cursor was last displayed
10146 in this window. Otherwise we have to reposition it. */
10147 && 0 <= w->cursor.vpos
10148 && WINDOW_TOTAL_LINES (w) > w->cursor.vpos)
10150 if (!must_finish)
10152 do_pending_window_change (1);
10154 /* We used to always goto end_of_redisplay here, but this
10155 isn't enough if we have a blinking cursor. */
10156 if (w->cursor_off_p == w->last_cursor_off_p)
10157 goto end_of_redisplay;
10159 goto update;
10161 /* If highlighting the region, or if the cursor is in the echo area,
10162 then we can't just move the cursor. */
10163 else if (! (!NILP (Vtransient_mark_mode)
10164 && !NILP (current_buffer->mark_active))
10165 && (EQ (selected_window, current_buffer->last_selected_window)
10166 || highlight_nonselected_windows)
10167 && NILP (w->region_showing)
10168 && NILP (Vshow_trailing_whitespace)
10169 && !cursor_in_echo_area)
10171 struct it it;
10172 struct glyph_row *row;
10174 /* Skip from tlbufpos to PT and see where it is. Note that
10175 PT may be in invisible text. If so, we will end at the
10176 next visible position. */
10177 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
10178 NULL, DEFAULT_FACE_ID);
10179 it.current_x = this_line_start_x;
10180 it.current_y = this_line_y;
10181 it.vpos = this_line_vpos;
10183 /* The call to move_it_to stops in front of PT, but
10184 moves over before-strings. */
10185 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
10187 if (it.vpos == this_line_vpos
10188 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
10189 row->enabled_p))
10191 xassert (this_line_vpos == it.vpos);
10192 xassert (this_line_y == it.current_y);
10193 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
10194 #if GLYPH_DEBUG
10195 *w->desired_matrix->method = 0;
10196 debug_method_add (w, "optimization 3");
10197 #endif
10198 goto update;
10200 else
10201 goto cancel;
10204 cancel:
10205 /* Text changed drastically or point moved off of line. */
10206 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
10209 CHARPOS (this_line_start_pos) = 0;
10210 consider_all_windows_p |= buffer_shared > 1;
10211 ++clear_face_cache_count;
10214 /* Build desired matrices, and update the display. If
10215 consider_all_windows_p is non-zero, do it for all windows on all
10216 frames. Otherwise do it for selected_window, only. */
10218 if (consider_all_windows_p)
10220 Lisp_Object tail, frame;
10221 int i, n = 0, size = 50;
10222 struct frame **updated
10223 = (struct frame **) alloca (size * sizeof *updated);
10225 /* Clear the face cache eventually. */
10226 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
10228 clear_face_cache (0);
10229 clear_face_cache_count = 0;
10232 /* Recompute # windows showing selected buffer. This will be
10233 incremented each time such a window is displayed. */
10234 buffer_shared = 0;
10236 FOR_EACH_FRAME (tail, frame)
10238 struct frame *f = XFRAME (frame);
10240 if (FRAME_WINDOW_P (f) || f == sf)
10242 if (! EQ (frame, selected_frame))
10243 /* Select the frame, for the sake of frame-local
10244 variables. */
10245 select_frame_for_redisplay (frame);
10247 #ifdef HAVE_WINDOW_SYSTEM
10248 if (clear_face_cache_count % 50 == 0
10249 && FRAME_WINDOW_P (f))
10250 clear_image_cache (f, 0);
10251 #endif /* HAVE_WINDOW_SYSTEM */
10253 /* Mark all the scroll bars to be removed; we'll redeem
10254 the ones we want when we redisplay their windows. */
10255 if (condemn_scroll_bars_hook)
10256 condemn_scroll_bars_hook (f);
10258 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
10259 redisplay_windows (FRAME_ROOT_WINDOW (f));
10261 /* Any scroll bars which redisplay_windows should have
10262 nuked should now go away. */
10263 if (judge_scroll_bars_hook)
10264 judge_scroll_bars_hook (f);
10266 /* If fonts changed, display again. */
10267 /* ??? rms: I suspect it is a mistake to jump all the way
10268 back to retry here. It should just retry this frame. */
10269 if (fonts_changed_p)
10270 goto retry;
10272 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
10274 /* See if we have to hscroll. */
10275 if (hscroll_windows (f->root_window))
10276 goto retry;
10278 /* Prevent various kinds of signals during display
10279 update. stdio is not robust about handling
10280 signals, which can cause an apparent I/O
10281 error. */
10282 if (interrupt_input)
10283 unrequest_sigio ();
10284 STOP_POLLING;
10286 /* Update the display. */
10287 set_window_update_flags (XWINDOW (f->root_window), 1);
10288 pause |= update_frame (f, 0, 0);
10289 #if 0 /* Exiting the loop can leave the wrong value for buffer_shared. */
10290 if (pause)
10291 break;
10292 #endif
10294 if (n == size)
10296 int nbytes = size * sizeof *updated;
10297 struct frame **p = (struct frame **) alloca (2 * nbytes);
10298 bcopy (updated, p, nbytes);
10299 size *= 2;
10302 updated[n++] = f;
10307 if (!pause)
10309 /* Do the mark_window_display_accurate after all windows have
10310 been redisplayed because this call resets flags in buffers
10311 which are needed for proper redisplay. */
10312 for (i = 0; i < n; ++i)
10314 struct frame *f = updated[i];
10315 mark_window_display_accurate (f->root_window, 1);
10316 if (frame_up_to_date_hook)
10317 frame_up_to_date_hook (f);
10321 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
10323 Lisp_Object mini_window;
10324 struct frame *mini_frame;
10326 displayed_buffer = XBUFFER (XWINDOW (selected_window)->buffer);
10327 /* Use list_of_error, not Qerror, so that
10328 we catch only errors and don't run the debugger. */
10329 internal_condition_case_1 (redisplay_window_1, selected_window,
10330 list_of_error,
10331 redisplay_window_error);
10333 /* Compare desired and current matrices, perform output. */
10335 update:
10336 /* If fonts changed, display again. */
10337 if (fonts_changed_p)
10338 goto retry;
10340 /* Prevent various kinds of signals during display update.
10341 stdio is not robust about handling signals,
10342 which can cause an apparent I/O error. */
10343 if (interrupt_input)
10344 unrequest_sigio ();
10345 STOP_POLLING;
10347 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
10349 if (hscroll_windows (selected_window))
10350 goto retry;
10352 XWINDOW (selected_window)->must_be_updated_p = 1;
10353 pause = update_frame (sf, 0, 0);
10356 /* We may have called echo_area_display at the top of this
10357 function. If the echo area is on another frame, that may
10358 have put text on a frame other than the selected one, so the
10359 above call to update_frame would not have caught it. Catch
10360 it here. */
10361 mini_window = FRAME_MINIBUF_WINDOW (sf);
10362 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
10364 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
10366 XWINDOW (mini_window)->must_be_updated_p = 1;
10367 pause |= update_frame (mini_frame, 0, 0);
10368 if (!pause && hscroll_windows (mini_window))
10369 goto retry;
10373 /* If display was paused because of pending input, make sure we do a
10374 thorough update the next time. */
10375 if (pause)
10377 /* Prevent the optimization at the beginning of
10378 redisplay_internal that tries a single-line update of the
10379 line containing the cursor in the selected window. */
10380 CHARPOS (this_line_start_pos) = 0;
10382 /* Let the overlay arrow be updated the next time. */
10383 update_overlay_arrows (0);
10385 /* If we pause after scrolling, some rows in the current
10386 matrices of some windows are not valid. */
10387 if (!WINDOW_FULL_WIDTH_P (w)
10388 && !FRAME_WINDOW_P (XFRAME (w->frame)))
10389 update_mode_lines = 1;
10391 else
10393 if (!consider_all_windows_p)
10395 /* This has already been done above if
10396 consider_all_windows_p is set. */
10397 mark_window_display_accurate_1 (w, 1);
10399 /* Say overlay arrows are up to date. */
10400 update_overlay_arrows (1);
10402 if (frame_up_to_date_hook != 0)
10403 frame_up_to_date_hook (sf);
10406 update_mode_lines = 0;
10407 windows_or_buffers_changed = 0;
10408 cursor_type_changed = 0;
10411 /* Start SIGIO interrupts coming again. Having them off during the
10412 code above makes it less likely one will discard output, but not
10413 impossible, since there might be stuff in the system buffer here.
10414 But it is much hairier to try to do anything about that. */
10415 if (interrupt_input)
10416 request_sigio ();
10417 RESUME_POLLING;
10419 /* If a frame has become visible which was not before, redisplay
10420 again, so that we display it. Expose events for such a frame
10421 (which it gets when becoming visible) don't call the parts of
10422 redisplay constructing glyphs, so simply exposing a frame won't
10423 display anything in this case. So, we have to display these
10424 frames here explicitly. */
10425 if (!pause)
10427 Lisp_Object tail, frame;
10428 int new_count = 0;
10430 FOR_EACH_FRAME (tail, frame)
10432 int this_is_visible = 0;
10434 if (XFRAME (frame)->visible)
10435 this_is_visible = 1;
10436 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
10437 if (XFRAME (frame)->visible)
10438 this_is_visible = 1;
10440 if (this_is_visible)
10441 new_count++;
10444 if (new_count != number_of_visible_frames)
10445 windows_or_buffers_changed++;
10448 /* Change frame size now if a change is pending. */
10449 do_pending_window_change (1);
10451 /* If we just did a pending size change, or have additional
10452 visible frames, redisplay again. */
10453 if (windows_or_buffers_changed && !pause)
10454 goto retry;
10456 end_of_redisplay:
10457 unbind_to (count, Qnil);
10458 RESUME_POLLING;
10462 /* Redisplay, but leave alone any recent echo area message unless
10463 another message has been requested in its place.
10465 This is useful in situations where you need to redisplay but no
10466 user action has occurred, making it inappropriate for the message
10467 area to be cleared. See tracking_off and
10468 wait_reading_process_output for examples of these situations.
10470 FROM_WHERE is an integer saying from where this function was
10471 called. This is useful for debugging. */
10473 void
10474 redisplay_preserve_echo_area (from_where)
10475 int from_where;
10477 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
10479 if (!NILP (echo_area_buffer[1]))
10481 /* We have a previously displayed message, but no current
10482 message. Redisplay the previous message. */
10483 display_last_displayed_message_p = 1;
10484 redisplay_internal (1);
10485 display_last_displayed_message_p = 0;
10487 else
10488 redisplay_internal (1);
10490 if (rif != NULL && rif->flush_display_optional)
10491 rif->flush_display_optional (NULL);
10495 /* Function registered with record_unwind_protect in
10496 redisplay_internal. Reset redisplaying_p to the value it had
10497 before redisplay_internal was called, and clear
10498 prevent_freeing_realized_faces_p. It also selects the previously
10499 selected frame. */
10501 static Lisp_Object
10502 unwind_redisplay (val)
10503 Lisp_Object val;
10505 Lisp_Object old_redisplaying_p, old_frame;
10507 old_redisplaying_p = XCAR (val);
10508 redisplaying_p = XFASTINT (old_redisplaying_p);
10509 old_frame = XCDR (val);
10510 if (! EQ (old_frame, selected_frame))
10511 select_frame_for_redisplay (old_frame);
10512 return Qnil;
10516 /* Mark the display of window W as accurate or inaccurate. If
10517 ACCURATE_P is non-zero mark display of W as accurate. If
10518 ACCURATE_P is zero, arrange for W to be redisplayed the next time
10519 redisplay_internal is called. */
10521 static void
10522 mark_window_display_accurate_1 (w, accurate_p)
10523 struct window *w;
10524 int accurate_p;
10526 if (BUFFERP (w->buffer))
10528 struct buffer *b = XBUFFER (w->buffer);
10530 w->last_modified
10531 = make_number (accurate_p ? BUF_MODIFF (b) : 0);
10532 w->last_overlay_modified
10533 = make_number (accurate_p ? BUF_OVERLAY_MODIFF (b) : 0);
10534 w->last_had_star
10535 = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b) ? Qt : Qnil;
10537 if (accurate_p)
10539 b->clip_changed = 0;
10540 b->prevent_redisplay_optimizations_p = 0;
10542 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
10543 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
10544 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
10545 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
10547 w->current_matrix->buffer = b;
10548 w->current_matrix->begv = BUF_BEGV (b);
10549 w->current_matrix->zv = BUF_ZV (b);
10551 w->last_cursor = w->cursor;
10552 w->last_cursor_off_p = w->cursor_off_p;
10554 if (w == XWINDOW (selected_window))
10555 w->last_point = make_number (BUF_PT (b));
10556 else
10557 w->last_point = make_number (XMARKER (w->pointm)->charpos);
10561 if (accurate_p)
10563 w->window_end_valid = w->buffer;
10564 #if 0 /* This is incorrect with variable-height lines. */
10565 xassert (XINT (w->window_end_vpos)
10566 < (WINDOW_TOTAL_LINES (w)
10567 - (WINDOW_WANTS_MODELINE_P (w) ? 1 : 0)));
10568 #endif
10569 w->update_mode_line = Qnil;
10574 /* Mark the display of windows in the window tree rooted at WINDOW as
10575 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
10576 windows as accurate. If ACCURATE_P is zero, arrange for windows to
10577 be redisplayed the next time redisplay_internal is called. */
10579 void
10580 mark_window_display_accurate (window, accurate_p)
10581 Lisp_Object window;
10582 int accurate_p;
10584 struct window *w;
10586 for (; !NILP (window); window = w->next)
10588 w = XWINDOW (window);
10589 mark_window_display_accurate_1 (w, accurate_p);
10591 if (!NILP (w->vchild))
10592 mark_window_display_accurate (w->vchild, accurate_p);
10593 if (!NILP (w->hchild))
10594 mark_window_display_accurate (w->hchild, accurate_p);
10597 if (accurate_p)
10599 update_overlay_arrows (1);
10601 else
10603 /* Force a thorough redisplay the next time by setting
10604 last_arrow_position and last_arrow_string to t, which is
10605 unequal to any useful value of Voverlay_arrow_... */
10606 update_overlay_arrows (-1);
10611 /* Return value in display table DP (Lisp_Char_Table *) for character
10612 C. Since a display table doesn't have any parent, we don't have to
10613 follow parent. Do not call this function directly but use the
10614 macro DISP_CHAR_VECTOR. */
10616 Lisp_Object
10617 disp_char_vector (dp, c)
10618 struct Lisp_Char_Table *dp;
10619 int c;
10621 int code[4], i;
10622 Lisp_Object val;
10624 if (SINGLE_BYTE_CHAR_P (c))
10625 return (dp->contents[c]);
10627 SPLIT_CHAR (c, code[0], code[1], code[2]);
10628 if (code[1] < 32)
10629 code[1] = -1;
10630 else if (code[2] < 32)
10631 code[2] = -1;
10633 /* Here, the possible range of code[0] (== charset ID) is
10634 128..max_charset. Since the top level char table contains data
10635 for multibyte characters after 256th element, we must increment
10636 code[0] by 128 to get a correct index. */
10637 code[0] += 128;
10638 code[3] = -1; /* anchor */
10640 for (i = 0; code[i] >= 0; i++, dp = XCHAR_TABLE (val))
10642 val = dp->contents[code[i]];
10643 if (!SUB_CHAR_TABLE_P (val))
10644 return (NILP (val) ? dp->defalt : val);
10647 /* Here, val is a sub char table. We return the default value of
10648 it. */
10649 return (dp->defalt);
10654 /***********************************************************************
10655 Window Redisplay
10656 ***********************************************************************/
10658 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
10660 static void
10661 redisplay_windows (window)
10662 Lisp_Object window;
10664 while (!NILP (window))
10666 struct window *w = XWINDOW (window);
10668 if (!NILP (w->hchild))
10669 redisplay_windows (w->hchild);
10670 else if (!NILP (w->vchild))
10671 redisplay_windows (w->vchild);
10672 else
10674 displayed_buffer = XBUFFER (w->buffer);
10675 /* Use list_of_error, not Qerror, so that
10676 we catch only errors and don't run the debugger. */
10677 internal_condition_case_1 (redisplay_window_0, window,
10678 list_of_error,
10679 redisplay_window_error);
10682 window = w->next;
10686 static Lisp_Object
10687 redisplay_window_error ()
10689 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
10690 return Qnil;
10693 static Lisp_Object
10694 redisplay_window_0 (window)
10695 Lisp_Object window;
10697 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
10698 redisplay_window (window, 0);
10699 return Qnil;
10702 static Lisp_Object
10703 redisplay_window_1 (window)
10704 Lisp_Object window;
10706 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
10707 redisplay_window (window, 1);
10708 return Qnil;
10712 /* Increment GLYPH until it reaches END or CONDITION fails while
10713 adding (GLYPH)->pixel_width to X. */
10715 #define SKIP_GLYPHS(glyph, end, x, condition) \
10716 do \
10718 (x) += (glyph)->pixel_width; \
10719 ++(glyph); \
10721 while ((glyph) < (end) && (condition))
10724 /* Set cursor position of W. PT is assumed to be displayed in ROW.
10725 DELTA is the number of bytes by which positions recorded in ROW
10726 differ from current buffer positions. */
10728 void
10729 set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
10730 struct window *w;
10731 struct glyph_row *row;
10732 struct glyph_matrix *matrix;
10733 int delta, delta_bytes, dy, dvpos;
10735 struct glyph *glyph = row->glyphs[TEXT_AREA];
10736 struct glyph *end = glyph + row->used[TEXT_AREA];
10737 struct glyph *cursor = NULL;
10738 /* The first glyph that starts a sequence of glyphs from string. */
10739 struct glyph *string_start;
10740 /* The X coordinate of string_start. */
10741 int string_start_x;
10742 /* The last known character position. */
10743 int last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
10744 /* The last known character position before string_start. */
10745 int string_before_pos;
10746 int x = row->x;
10747 int cursor_x = x;
10748 int cursor_from_overlay_pos = 0;
10749 int pt_old = PT - delta;
10751 /* Skip over glyphs not having an object at the start of the row.
10752 These are special glyphs like truncation marks on terminal
10753 frames. */
10754 if (row->displays_text_p)
10755 while (glyph < end
10756 && INTEGERP (glyph->object)
10757 && glyph->charpos < 0)
10759 x += glyph->pixel_width;
10760 ++glyph;
10763 string_start = NULL;
10764 while (glyph < end
10765 && !INTEGERP (glyph->object)
10766 && (!BUFFERP (glyph->object)
10767 || (last_pos = glyph->charpos) < pt_old))
10769 if (! STRINGP (glyph->object))
10771 string_start = NULL;
10772 x += glyph->pixel_width;
10773 ++glyph;
10774 if (cursor_from_overlay_pos
10775 && last_pos > cursor_from_overlay_pos)
10777 cursor_from_overlay_pos = 0;
10778 cursor = 0;
10781 else
10783 string_before_pos = last_pos;
10784 string_start = glyph;
10785 string_start_x = x;
10786 /* Skip all glyphs from string. */
10789 int pos;
10790 if ((cursor == NULL || glyph > cursor)
10791 && !NILP (Fget_char_property (make_number ((glyph)->charpos),
10792 Qcursor, (glyph)->object))
10793 && (pos = string_buffer_position (w, glyph->object,
10794 string_before_pos),
10795 (pos == 0 /* From overlay */
10796 || pos == pt_old)))
10798 /* Estimate overlay buffer position from the buffer
10799 positions of the glyphs before and after the overlay.
10800 Add 1 to last_pos so that if point corresponds to the
10801 glyph right after the overlay, we still use a 'cursor'
10802 property found in that overlay. */
10803 cursor_from_overlay_pos = pos == 0 ? last_pos+1 : 0;
10804 cursor = glyph;
10805 cursor_x = x;
10807 x += glyph->pixel_width;
10808 ++glyph;
10810 while (glyph < end && STRINGP (glyph->object));
10814 if (cursor != NULL)
10816 glyph = cursor;
10817 x = cursor_x;
10819 else if (row->ends_in_ellipsis_p && glyph == end)
10821 /* Scan back over the ellipsis glyphs, decrementing positions. */
10822 while (glyph > row->glyphs[TEXT_AREA]
10823 && (glyph - 1)->charpos == last_pos)
10824 glyph--, x -= glyph->pixel_width;
10825 /* That loop always goes one position too far,
10826 including the glyph before the ellipsis.
10827 So scan forward over that one. */
10828 x += glyph->pixel_width;
10829 glyph++;
10831 else if (string_start
10832 && (glyph == end || !BUFFERP (glyph->object) || last_pos > pt_old))
10834 /* We may have skipped over point because the previous glyphs
10835 are from string. As there's no easy way to know the
10836 character position of the current glyph, find the correct
10837 glyph on point by scanning from string_start again. */
10838 Lisp_Object limit;
10839 Lisp_Object string;
10840 int pos;
10842 limit = make_number (pt_old + 1);
10843 end = glyph;
10844 glyph = string_start;
10845 x = string_start_x;
10846 string = glyph->object;
10847 pos = string_buffer_position (w, string, string_before_pos);
10848 /* If STRING is from overlay, LAST_POS == 0. We skip such glyphs
10849 because we always put cursor after overlay strings. */
10850 while (pos == 0 && glyph < end)
10852 string = glyph->object;
10853 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10854 if (glyph < end)
10855 pos = string_buffer_position (w, glyph->object, string_before_pos);
10858 while (glyph < end)
10860 pos = XINT (Fnext_single_char_property_change
10861 (make_number (pos), Qdisplay, Qnil, limit));
10862 if (pos > pt_old)
10863 break;
10864 /* Skip glyphs from the same string. */
10865 string = glyph->object;
10866 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10867 /* Skip glyphs from an overlay. */
10868 while (glyph < end
10869 && ! string_buffer_position (w, glyph->object, pos))
10871 string = glyph->object;
10872 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10877 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
10878 w->cursor.x = x;
10879 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
10880 w->cursor.y = row->y + dy;
10882 if (w == XWINDOW (selected_window))
10884 if (!row->continued_p
10885 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
10886 && row->x == 0)
10888 this_line_buffer = XBUFFER (w->buffer);
10890 CHARPOS (this_line_start_pos)
10891 = MATRIX_ROW_START_CHARPOS (row) + delta;
10892 BYTEPOS (this_line_start_pos)
10893 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
10895 CHARPOS (this_line_end_pos)
10896 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
10897 BYTEPOS (this_line_end_pos)
10898 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
10900 this_line_y = w->cursor.y;
10901 this_line_pixel_height = row->height;
10902 this_line_vpos = w->cursor.vpos;
10903 this_line_start_x = row->x;
10905 else
10906 CHARPOS (this_line_start_pos) = 0;
10911 /* Run window scroll functions, if any, for WINDOW with new window
10912 start STARTP. Sets the window start of WINDOW to that position.
10914 We assume that the window's buffer is really current. */
10916 static INLINE struct text_pos
10917 run_window_scroll_functions (window, startp)
10918 Lisp_Object window;
10919 struct text_pos startp;
10921 struct window *w = XWINDOW (window);
10922 SET_MARKER_FROM_TEXT_POS (w->start, startp);
10924 if (current_buffer != XBUFFER (w->buffer))
10925 abort ();
10927 if (!NILP (Vwindow_scroll_functions))
10929 run_hook_with_args_2 (Qwindow_scroll_functions, window,
10930 make_number (CHARPOS (startp)));
10931 SET_TEXT_POS_FROM_MARKER (startp, w->start);
10932 /* In case the hook functions switch buffers. */
10933 if (current_buffer != XBUFFER (w->buffer))
10934 set_buffer_internal_1 (XBUFFER (w->buffer));
10937 return startp;
10941 /* Make sure the line containing the cursor is fully visible.
10942 A value of 1 means there is nothing to be done.
10943 (Either the line is fully visible, or it cannot be made so,
10944 or we cannot tell.)
10946 If FORCE_P is non-zero, return 0 even if partial visible cursor row
10947 is higher than window.
10949 A value of 0 means the caller should do scrolling
10950 as if point had gone off the screen. */
10952 static int
10953 make_cursor_line_fully_visible (w, force_p)
10954 struct window *w;
10955 int force_p;
10957 struct glyph_matrix *matrix;
10958 struct glyph_row *row;
10959 int window_height;
10961 if (!make_cursor_line_fully_visible_p)
10962 return 1;
10964 /* It's not always possible to find the cursor, e.g, when a window
10965 is full of overlay strings. Don't do anything in that case. */
10966 if (w->cursor.vpos < 0)
10967 return 1;
10969 matrix = w->desired_matrix;
10970 row = MATRIX_ROW (matrix, w->cursor.vpos);
10972 /* If the cursor row is not partially visible, there's nothing to do. */
10973 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row))
10974 return 1;
10976 /* If the row the cursor is in is taller than the window's height,
10977 it's not clear what to do, so do nothing. */
10978 window_height = window_box_height (w);
10979 if (row->height >= window_height)
10981 if (!force_p || w->vscroll)
10982 return 1;
10984 return 0;
10986 #if 0
10987 /* This code used to try to scroll the window just enough to make
10988 the line visible. It returned 0 to say that the caller should
10989 allocate larger glyph matrices. */
10991 if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row))
10993 int dy = row->height - row->visible_height;
10994 w->vscroll = 0;
10995 w->cursor.y += dy;
10996 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
10998 else /* MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row)) */
11000 int dy = - (row->height - row->visible_height);
11001 w->vscroll = dy;
11002 w->cursor.y += dy;
11003 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
11006 /* When we change the cursor y-position of the selected window,
11007 change this_line_y as well so that the display optimization for
11008 the cursor line of the selected window in redisplay_internal uses
11009 the correct y-position. */
11010 if (w == XWINDOW (selected_window))
11011 this_line_y = w->cursor.y;
11013 /* If vscrolling requires a larger glyph matrix, arrange for a fresh
11014 redisplay with larger matrices. */
11015 if (matrix->nrows < required_matrix_height (w))
11017 fonts_changed_p = 1;
11018 return 0;
11021 return 1;
11022 #endif /* 0 */
11026 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
11027 non-zero means only WINDOW is redisplayed in redisplay_internal.
11028 TEMP_SCROLL_STEP has the same meaning as scroll_step, and is used
11029 in redisplay_window to bring a partially visible line into view in
11030 the case that only the cursor has moved.
11032 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
11033 last screen line's vertical height extends past the end of the screen.
11035 Value is
11037 1 if scrolling succeeded
11039 0 if scrolling didn't find point.
11041 -1 if new fonts have been loaded so that we must interrupt
11042 redisplay, adjust glyph matrices, and try again. */
11044 enum
11046 SCROLLING_SUCCESS,
11047 SCROLLING_FAILED,
11048 SCROLLING_NEED_LARGER_MATRICES
11051 static int
11052 try_scrolling (window, just_this_one_p, scroll_conservatively,
11053 scroll_step, temp_scroll_step, last_line_misfit)
11054 Lisp_Object window;
11055 int just_this_one_p;
11056 EMACS_INT scroll_conservatively, scroll_step;
11057 int temp_scroll_step;
11058 int last_line_misfit;
11060 struct window *w = XWINDOW (window);
11061 struct frame *f = XFRAME (w->frame);
11062 struct text_pos scroll_margin_pos;
11063 struct text_pos pos;
11064 struct text_pos startp;
11065 struct it it;
11066 Lisp_Object window_end;
11067 int this_scroll_margin;
11068 int dy = 0;
11069 int scroll_max;
11070 int rc;
11071 int amount_to_scroll = 0;
11072 Lisp_Object aggressive;
11073 int height;
11074 int extra_scroll_margin_lines = last_line_misfit ? 1 : 0;
11076 #if GLYPH_DEBUG
11077 debug_method_add (w, "try_scrolling");
11078 #endif
11080 SET_TEXT_POS_FROM_MARKER (startp, w->start);
11082 /* Compute scroll margin height in pixels. We scroll when point is
11083 within this distance from the top or bottom of the window. */
11084 if (scroll_margin > 0)
11086 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
11087 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
11089 else
11090 this_scroll_margin = 0;
11092 /* Force scroll_conservatively to have a reasonable value so it doesn't
11093 cause an overflow while computing how much to scroll. */
11094 if (scroll_conservatively)
11095 scroll_conservatively = min (scroll_conservatively,
11096 MOST_POSITIVE_FIXNUM / FRAME_LINE_HEIGHT (f));
11098 /* Compute how much we should try to scroll maximally to bring point
11099 into view. */
11100 if (scroll_step || scroll_conservatively || temp_scroll_step)
11101 scroll_max = max (scroll_step,
11102 max (scroll_conservatively, temp_scroll_step));
11103 else if (NUMBERP (current_buffer->scroll_down_aggressively)
11104 || NUMBERP (current_buffer->scroll_up_aggressively))
11105 /* We're trying to scroll because of aggressive scrolling
11106 but no scroll_step is set. Choose an arbitrary one. Maybe
11107 there should be a variable for this. */
11108 scroll_max = 10;
11109 else
11110 scroll_max = 0;
11111 scroll_max *= FRAME_LINE_HEIGHT (f);
11113 /* Decide whether we have to scroll down. Start at the window end
11114 and move this_scroll_margin up to find the position of the scroll
11115 margin. */
11116 window_end = Fwindow_end (window, Qt);
11118 too_near_end:
11120 CHARPOS (scroll_margin_pos) = XINT (window_end);
11121 BYTEPOS (scroll_margin_pos) = CHAR_TO_BYTE (CHARPOS (scroll_margin_pos));
11123 if (this_scroll_margin || extra_scroll_margin_lines)
11125 start_display (&it, w, scroll_margin_pos);
11126 if (this_scroll_margin)
11127 move_it_vertically_backward (&it, this_scroll_margin);
11128 if (extra_scroll_margin_lines)
11129 move_it_by_lines (&it, - extra_scroll_margin_lines, 0);
11130 scroll_margin_pos = it.current.pos;
11133 if (PT >= CHARPOS (scroll_margin_pos))
11135 int y0;
11137 /* Point is in the scroll margin at the bottom of the window, or
11138 below. Compute a new window start that makes point visible. */
11140 /* Compute the distance from the scroll margin to PT.
11141 Give up if the distance is greater than scroll_max. */
11142 start_display (&it, w, scroll_margin_pos);
11143 y0 = it.current_y;
11144 move_it_to (&it, PT, 0, it.last_visible_y, -1,
11145 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
11147 /* To make point visible, we have to move the window start
11148 down so that the line the cursor is in is visible, which
11149 means we have to add in the height of the cursor line. */
11150 dy = line_bottom_y (&it) - y0;
11152 if (dy > scroll_max)
11153 return SCROLLING_FAILED;
11155 /* Move the window start down. If scrolling conservatively,
11156 move it just enough down to make point visible. If
11157 scroll_step is set, move it down by scroll_step. */
11158 start_display (&it, w, startp);
11160 if (scroll_conservatively)
11161 /* Set AMOUNT_TO_SCROLL to at least one line,
11162 and at most scroll_conservatively lines. */
11163 amount_to_scroll
11164 = min (max (dy, FRAME_LINE_HEIGHT (f)),
11165 FRAME_LINE_HEIGHT (f) * scroll_conservatively);
11166 else if (scroll_step || temp_scroll_step)
11167 amount_to_scroll = scroll_max;
11168 else
11170 aggressive = current_buffer->scroll_up_aggressively;
11171 height = WINDOW_BOX_TEXT_HEIGHT (w);
11172 if (NUMBERP (aggressive))
11174 double float_amount = XFLOATINT (aggressive) * height;
11175 amount_to_scroll = float_amount;
11176 if (amount_to_scroll == 0 && float_amount > 0)
11177 amount_to_scroll = 1;
11181 if (amount_to_scroll <= 0)
11182 return SCROLLING_FAILED;
11184 /* If moving by amount_to_scroll leaves STARTP unchanged,
11185 move it down one screen line. */
11187 move_it_vertically (&it, amount_to_scroll);
11188 if (CHARPOS (it.current.pos) == CHARPOS (startp))
11189 move_it_by_lines (&it, 1, 1);
11190 startp = it.current.pos;
11192 else
11194 /* See if point is inside the scroll margin at the top of the
11195 window. */
11196 scroll_margin_pos = startp;
11197 if (this_scroll_margin)
11199 start_display (&it, w, startp);
11200 move_it_vertically (&it, this_scroll_margin);
11201 scroll_margin_pos = it.current.pos;
11204 if (PT < CHARPOS (scroll_margin_pos))
11206 /* Point is in the scroll margin at the top of the window or
11207 above what is displayed in the window. */
11208 int y0;
11210 /* Compute the vertical distance from PT to the scroll
11211 margin position. Give up if distance is greater than
11212 scroll_max. */
11213 SET_TEXT_POS (pos, PT, PT_BYTE);
11214 start_display (&it, w, pos);
11215 y0 = it.current_y;
11216 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
11217 it.last_visible_y, -1,
11218 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
11219 dy = it.current_y - y0;
11220 if (dy > scroll_max)
11221 return SCROLLING_FAILED;
11223 /* Compute new window start. */
11224 start_display (&it, w, startp);
11226 if (scroll_conservatively)
11227 amount_to_scroll
11228 = max (dy, FRAME_LINE_HEIGHT (f) * max (scroll_step, temp_scroll_step));
11229 else if (scroll_step || temp_scroll_step)
11230 amount_to_scroll = scroll_max;
11231 else
11233 aggressive = current_buffer->scroll_down_aggressively;
11234 height = WINDOW_BOX_TEXT_HEIGHT (w);
11235 if (NUMBERP (aggressive))
11237 double float_amount = XFLOATINT (aggressive) * height;
11238 amount_to_scroll = float_amount;
11239 if (amount_to_scroll == 0 && float_amount > 0)
11240 amount_to_scroll = 1;
11244 if (amount_to_scroll <= 0)
11245 return SCROLLING_FAILED;
11247 move_it_vertically_backward (&it, amount_to_scroll);
11248 startp = it.current.pos;
11252 /* Run window scroll functions. */
11253 startp = run_window_scroll_functions (window, startp);
11255 /* Display the window. Give up if new fonts are loaded, or if point
11256 doesn't appear. */
11257 if (!try_window (window, startp))
11258 rc = SCROLLING_NEED_LARGER_MATRICES;
11259 else if (w->cursor.vpos < 0)
11261 clear_glyph_matrix (w->desired_matrix);
11262 rc = SCROLLING_FAILED;
11264 else
11266 /* Maybe forget recorded base line for line number display. */
11267 if (!just_this_one_p
11268 || current_buffer->clip_changed
11269 || BEG_UNCHANGED < CHARPOS (startp))
11270 w->base_line_number = Qnil;
11272 /* If cursor ends up on a partially visible line,
11273 treat that as being off the bottom of the screen. */
11274 if (! make_cursor_line_fully_visible (w, extra_scroll_margin_lines <= 1))
11276 clear_glyph_matrix (w->desired_matrix);
11277 ++extra_scroll_margin_lines;
11278 goto too_near_end;
11280 rc = SCROLLING_SUCCESS;
11283 return rc;
11287 /* Compute a suitable window start for window W if display of W starts
11288 on a continuation line. Value is non-zero if a new window start
11289 was computed.
11291 The new window start will be computed, based on W's width, starting
11292 from the start of the continued line. It is the start of the
11293 screen line with the minimum distance from the old start W->start. */
11295 static int
11296 compute_window_start_on_continuation_line (w)
11297 struct window *w;
11299 struct text_pos pos, start_pos;
11300 int window_start_changed_p = 0;
11302 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
11304 /* If window start is on a continuation line... Window start may be
11305 < BEGV in case there's invisible text at the start of the
11306 buffer (M-x rmail, for example). */
11307 if (CHARPOS (start_pos) > BEGV
11308 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
11310 struct it it;
11311 struct glyph_row *row;
11313 /* Handle the case that the window start is out of range. */
11314 if (CHARPOS (start_pos) < BEGV)
11315 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
11316 else if (CHARPOS (start_pos) > ZV)
11317 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
11319 /* Find the start of the continued line. This should be fast
11320 because scan_buffer is fast (newline cache). */
11321 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
11322 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
11323 row, DEFAULT_FACE_ID);
11324 reseat_at_previous_visible_line_start (&it);
11326 /* If the line start is "too far" away from the window start,
11327 say it takes too much time to compute a new window start. */
11328 if (CHARPOS (start_pos) - IT_CHARPOS (it)
11329 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
11331 int min_distance, distance;
11333 /* Move forward by display lines to find the new window
11334 start. If window width was enlarged, the new start can
11335 be expected to be > the old start. If window width was
11336 decreased, the new window start will be < the old start.
11337 So, we're looking for the display line start with the
11338 minimum distance from the old window start. */
11339 pos = it.current.pos;
11340 min_distance = INFINITY;
11341 while ((distance = abs (CHARPOS (start_pos) - IT_CHARPOS (it))),
11342 distance < min_distance)
11344 min_distance = distance;
11345 pos = it.current.pos;
11346 move_it_by_lines (&it, 1, 0);
11349 /* Set the window start there. */
11350 SET_MARKER_FROM_TEXT_POS (w->start, pos);
11351 window_start_changed_p = 1;
11355 return window_start_changed_p;
11359 /* Try cursor movement in case text has not changed in window WINDOW,
11360 with window start STARTP. Value is
11362 CURSOR_MOVEMENT_SUCCESS if successful
11364 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
11366 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
11367 display. *SCROLL_STEP is set to 1, under certain circumstances, if
11368 we want to scroll as if scroll-step were set to 1. See the code.
11370 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
11371 which case we have to abort this redisplay, and adjust matrices
11372 first. */
11374 enum
11376 CURSOR_MOVEMENT_SUCCESS,
11377 CURSOR_MOVEMENT_CANNOT_BE_USED,
11378 CURSOR_MOVEMENT_MUST_SCROLL,
11379 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
11382 static int
11383 try_cursor_movement (window, startp, scroll_step)
11384 Lisp_Object window;
11385 struct text_pos startp;
11386 int *scroll_step;
11388 struct window *w = XWINDOW (window);
11389 struct frame *f = XFRAME (w->frame);
11390 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
11392 #if GLYPH_DEBUG
11393 if (inhibit_try_cursor_movement)
11394 return rc;
11395 #endif
11397 /* Handle case where text has not changed, only point, and it has
11398 not moved off the frame. */
11399 if (/* Point may be in this window. */
11400 PT >= CHARPOS (startp)
11401 /* Selective display hasn't changed. */
11402 && !current_buffer->clip_changed
11403 /* Function force-mode-line-update is used to force a thorough
11404 redisplay. It sets either windows_or_buffers_changed or
11405 update_mode_lines. So don't take a shortcut here for these
11406 cases. */
11407 && !update_mode_lines
11408 && !windows_or_buffers_changed
11409 && !cursor_type_changed
11410 /* Can't use this case if highlighting a region. When a
11411 region exists, cursor movement has to do more than just
11412 set the cursor. */
11413 && !(!NILP (Vtransient_mark_mode)
11414 && !NILP (current_buffer->mark_active))
11415 && NILP (w->region_showing)
11416 && NILP (Vshow_trailing_whitespace)
11417 /* Right after splitting windows, last_point may be nil. */
11418 && INTEGERP (w->last_point)
11419 /* This code is not used for mini-buffer for the sake of the case
11420 of redisplaying to replace an echo area message; since in
11421 that case the mini-buffer contents per se are usually
11422 unchanged. This code is of no real use in the mini-buffer
11423 since the handling of this_line_start_pos, etc., in redisplay
11424 handles the same cases. */
11425 && !EQ (window, minibuf_window)
11426 /* When splitting windows or for new windows, it happens that
11427 redisplay is called with a nil window_end_vpos or one being
11428 larger than the window. This should really be fixed in
11429 window.c. I don't have this on my list, now, so we do
11430 approximately the same as the old redisplay code. --gerd. */
11431 && INTEGERP (w->window_end_vpos)
11432 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
11433 && (FRAME_WINDOW_P (f)
11434 || !overlay_arrow_in_current_buffer_p ()))
11436 int this_scroll_margin, top_scroll_margin;
11437 struct glyph_row *row = NULL;
11439 #if GLYPH_DEBUG
11440 debug_method_add (w, "cursor movement");
11441 #endif
11443 /* Scroll if point within this distance from the top or bottom
11444 of the window. This is a pixel value. */
11445 this_scroll_margin = max (0, scroll_margin);
11446 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
11447 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
11449 top_scroll_margin = this_scroll_margin;
11450 if (WINDOW_WANTS_HEADER_LINE_P (w))
11451 top_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w);
11453 /* Start with the row the cursor was displayed during the last
11454 not paused redisplay. Give up if that row is not valid. */
11455 if (w->last_cursor.vpos < 0
11456 || w->last_cursor.vpos >= w->current_matrix->nrows)
11457 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11458 else
11460 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
11461 if (row->mode_line_p)
11462 ++row;
11463 if (!row->enabled_p)
11464 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11467 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
11469 int scroll_p = 0;
11470 int last_y = window_text_bottom_y (w) - this_scroll_margin;
11472 if (PT > XFASTINT (w->last_point))
11474 /* Point has moved forward. */
11475 while (MATRIX_ROW_END_CHARPOS (row) < PT
11476 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
11478 xassert (row->enabled_p);
11479 ++row;
11482 /* The end position of a row equals the start position
11483 of the next row. If PT is there, we would rather
11484 display it in the next line. */
11485 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
11486 && MATRIX_ROW_END_CHARPOS (row) == PT
11487 && !cursor_row_p (w, row))
11488 ++row;
11490 /* If within the scroll margin, scroll. Note that
11491 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
11492 the next line would be drawn, and that
11493 this_scroll_margin can be zero. */
11494 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
11495 || PT > MATRIX_ROW_END_CHARPOS (row)
11496 /* Line is completely visible last line in window
11497 and PT is to be set in the next line. */
11498 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
11499 && PT == MATRIX_ROW_END_CHARPOS (row)
11500 && !row->ends_at_zv_p
11501 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
11502 scroll_p = 1;
11504 else if (PT < XFASTINT (w->last_point))
11506 /* Cursor has to be moved backward. Note that PT >=
11507 CHARPOS (startp) because of the outer if-statement. */
11508 while (!row->mode_line_p
11509 && (MATRIX_ROW_START_CHARPOS (row) > PT
11510 || (MATRIX_ROW_START_CHARPOS (row) == PT
11511 && MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)))
11512 && (row->y > top_scroll_margin
11513 || CHARPOS (startp) == BEGV))
11515 xassert (row->enabled_p);
11516 --row;
11519 /* Consider the following case: Window starts at BEGV,
11520 there is invisible, intangible text at BEGV, so that
11521 display starts at some point START > BEGV. It can
11522 happen that we are called with PT somewhere between
11523 BEGV and START. Try to handle that case. */
11524 if (row < w->current_matrix->rows
11525 || row->mode_line_p)
11527 row = w->current_matrix->rows;
11528 if (row->mode_line_p)
11529 ++row;
11532 /* Due to newlines in overlay strings, we may have to
11533 skip forward over overlay strings. */
11534 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
11535 && MATRIX_ROW_END_CHARPOS (row) == PT
11536 && !cursor_row_p (w, row))
11537 ++row;
11539 /* If within the scroll margin, scroll. */
11540 if (row->y < top_scroll_margin
11541 && CHARPOS (startp) != BEGV)
11542 scroll_p = 1;
11545 if (PT < MATRIX_ROW_START_CHARPOS (row)
11546 || PT > MATRIX_ROW_END_CHARPOS (row))
11548 /* if PT is not in the glyph row, give up. */
11549 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11551 else if (MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
11552 && make_cursor_line_fully_visible_p)
11554 if (PT == MATRIX_ROW_END_CHARPOS (row)
11555 && !row->ends_at_zv_p
11556 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
11557 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11558 else if (row->height > window_box_height (w))
11560 /* If we end up in a partially visible line, let's
11561 make it fully visible, except when it's taller
11562 than the window, in which case we can't do much
11563 about it. */
11564 *scroll_step = 1;
11565 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11567 else
11569 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11570 if (!make_cursor_line_fully_visible (w, 0))
11571 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11572 else
11573 rc = CURSOR_MOVEMENT_SUCCESS;
11576 else if (scroll_p)
11577 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11578 else
11580 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11581 rc = CURSOR_MOVEMENT_SUCCESS;
11586 return rc;
11589 void
11590 set_vertical_scroll_bar (w)
11591 struct window *w;
11593 int start, end, whole;
11595 /* Calculate the start and end positions for the current window.
11596 At some point, it would be nice to choose between scrollbars
11597 which reflect the whole buffer size, with special markers
11598 indicating narrowing, and scrollbars which reflect only the
11599 visible region.
11601 Note that mini-buffers sometimes aren't displaying any text. */
11602 if (!MINI_WINDOW_P (w)
11603 || (w == XWINDOW (minibuf_window)
11604 && NILP (echo_area_buffer[0])))
11606 struct buffer *buf = XBUFFER (w->buffer);
11607 whole = BUF_ZV (buf) - BUF_BEGV (buf);
11608 start = marker_position (w->start) - BUF_BEGV (buf);
11609 /* I don't think this is guaranteed to be right. For the
11610 moment, we'll pretend it is. */
11611 end = BUF_Z (buf) - XFASTINT (w->window_end_pos) - BUF_BEGV (buf);
11613 if (end < start)
11614 end = start;
11615 if (whole < (end - start))
11616 whole = end - start;
11618 else
11619 start = end = whole = 0;
11621 /* Indicate what this scroll bar ought to be displaying now. */
11622 set_vertical_scroll_bar_hook (w, end - start, whole, start);
11626 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
11627 selected_window is redisplayed.
11629 We can return without actually redisplaying the window if
11630 fonts_changed_p is nonzero. In that case, redisplay_internal will
11631 retry. */
11633 static void
11634 redisplay_window (window, just_this_one_p)
11635 Lisp_Object window;
11636 int just_this_one_p;
11638 struct window *w = XWINDOW (window);
11639 struct frame *f = XFRAME (w->frame);
11640 struct buffer *buffer = XBUFFER (w->buffer);
11641 struct buffer *old = current_buffer;
11642 struct text_pos lpoint, opoint, startp;
11643 int update_mode_line;
11644 int tem;
11645 struct it it;
11646 /* Record it now because it's overwritten. */
11647 int current_matrix_up_to_date_p = 0;
11648 int used_current_matrix_p = 0;
11649 /* This is less strict than current_matrix_up_to_date_p.
11650 It indictes that the buffer contents and narrowing are unchanged. */
11651 int buffer_unchanged_p = 0;
11652 int temp_scroll_step = 0;
11653 int count = SPECPDL_INDEX ();
11654 int rc;
11655 int centering_position;
11656 int last_line_misfit = 0;
11658 SET_TEXT_POS (lpoint, PT, PT_BYTE);
11659 opoint = lpoint;
11661 /* W must be a leaf window here. */
11662 xassert (!NILP (w->buffer));
11663 #if GLYPH_DEBUG
11664 *w->desired_matrix->method = 0;
11665 #endif
11667 /* Force this to be looked up again for each redisp of each window. */
11668 escape_glyph_face = -1;
11670 specbind (Qinhibit_point_motion_hooks, Qt);
11672 reconsider_clip_changes (w, buffer);
11674 /* Has the mode line to be updated? */
11675 update_mode_line = (!NILP (w->update_mode_line)
11676 || update_mode_lines
11677 || buffer->clip_changed
11678 || buffer->prevent_redisplay_optimizations_p);
11680 if (MINI_WINDOW_P (w))
11682 if (w == XWINDOW (echo_area_window)
11683 && !NILP (echo_area_buffer[0]))
11685 if (update_mode_line)
11686 /* We may have to update a tty frame's menu bar or a
11687 tool-bar. Example `M-x C-h C-h C-g'. */
11688 goto finish_menu_bars;
11689 else
11690 /* We've already displayed the echo area glyphs in this window. */
11691 goto finish_scroll_bars;
11693 else if ((w != XWINDOW (minibuf_window)
11694 || minibuf_level == 0)
11695 /* When buffer is nonempty, redisplay window normally. */
11696 && BUF_Z (XBUFFER (w->buffer)) == BUF_BEG (XBUFFER (w->buffer))
11697 /* Quail displays non-mini buffers in minibuffer window.
11698 In that case, redisplay the window normally. */
11699 && !NILP (Fmemq (w->buffer, Vminibuffer_list)))
11701 /* W is a mini-buffer window, but it's not active, so clear
11702 it. */
11703 int yb = window_text_bottom_y (w);
11704 struct glyph_row *row;
11705 int y;
11707 for (y = 0, row = w->desired_matrix->rows;
11708 y < yb;
11709 y += row->height, ++row)
11710 blank_row (w, row, y);
11711 goto finish_scroll_bars;
11714 clear_glyph_matrix (w->desired_matrix);
11717 /* Otherwise set up data on this window; select its buffer and point
11718 value. */
11719 /* Really select the buffer, for the sake of buffer-local
11720 variables. */
11721 set_buffer_internal_1 (XBUFFER (w->buffer));
11722 SET_TEXT_POS (opoint, PT, PT_BYTE);
11724 current_matrix_up_to_date_p
11725 = (!NILP (w->window_end_valid)
11726 && !current_buffer->clip_changed
11727 && !current_buffer->prevent_redisplay_optimizations_p
11728 && XFASTINT (w->last_modified) >= MODIFF
11729 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
11731 buffer_unchanged_p
11732 = (!NILP (w->window_end_valid)
11733 && !current_buffer->clip_changed
11734 && XFASTINT (w->last_modified) >= MODIFF
11735 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
11737 /* When windows_or_buffers_changed is non-zero, we can't rely on
11738 the window end being valid, so set it to nil there. */
11739 if (windows_or_buffers_changed)
11741 /* If window starts on a continuation line, maybe adjust the
11742 window start in case the window's width changed. */
11743 if (XMARKER (w->start)->buffer == current_buffer)
11744 compute_window_start_on_continuation_line (w);
11746 w->window_end_valid = Qnil;
11749 /* Some sanity checks. */
11750 CHECK_WINDOW_END (w);
11751 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
11752 abort ();
11753 if (BYTEPOS (opoint) < CHARPOS (opoint))
11754 abort ();
11756 /* If %c is in mode line, update it if needed. */
11757 if (!NILP (w->column_number_displayed)
11758 /* This alternative quickly identifies a common case
11759 where no change is needed. */
11760 && !(PT == XFASTINT (w->last_point)
11761 && XFASTINT (w->last_modified) >= MODIFF
11762 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
11763 && (XFASTINT (w->column_number_displayed)
11764 != (int) current_column ())) /* iftc */
11765 update_mode_line = 1;
11767 /* Count number of windows showing the selected buffer. An indirect
11768 buffer counts as its base buffer. */
11769 if (!just_this_one_p)
11771 struct buffer *current_base, *window_base;
11772 current_base = current_buffer;
11773 window_base = XBUFFER (XWINDOW (selected_window)->buffer);
11774 if (current_base->base_buffer)
11775 current_base = current_base->base_buffer;
11776 if (window_base->base_buffer)
11777 window_base = window_base->base_buffer;
11778 if (current_base == window_base)
11779 buffer_shared++;
11782 /* Point refers normally to the selected window. For any other
11783 window, set up appropriate value. */
11784 if (!EQ (window, selected_window))
11786 int new_pt = XMARKER (w->pointm)->charpos;
11787 int new_pt_byte = marker_byte_position (w->pointm);
11788 if (new_pt < BEGV)
11790 new_pt = BEGV;
11791 new_pt_byte = BEGV_BYTE;
11792 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
11794 else if (new_pt > (ZV - 1))
11796 new_pt = ZV;
11797 new_pt_byte = ZV_BYTE;
11798 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
11801 /* We don't use SET_PT so that the point-motion hooks don't run. */
11802 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
11805 /* If any of the character widths specified in the display table
11806 have changed, invalidate the width run cache. It's true that
11807 this may be a bit late to catch such changes, but the rest of
11808 redisplay goes (non-fatally) haywire when the display table is
11809 changed, so why should we worry about doing any better? */
11810 if (current_buffer->width_run_cache)
11812 struct Lisp_Char_Table *disptab = buffer_display_table ();
11814 if (! disptab_matches_widthtab (disptab,
11815 XVECTOR (current_buffer->width_table)))
11817 invalidate_region_cache (current_buffer,
11818 current_buffer->width_run_cache,
11819 BEG, Z);
11820 recompute_width_table (current_buffer, disptab);
11824 /* If window-start is screwed up, choose a new one. */
11825 if (XMARKER (w->start)->buffer != current_buffer)
11826 goto recenter;
11828 SET_TEXT_POS_FROM_MARKER (startp, w->start);
11830 /* If someone specified a new starting point but did not insist,
11831 check whether it can be used. */
11832 if (!NILP (w->optional_new_start)
11833 && CHARPOS (startp) >= BEGV
11834 && CHARPOS (startp) <= ZV)
11836 w->optional_new_start = Qnil;
11837 start_display (&it, w, startp);
11838 move_it_to (&it, PT, 0, it.last_visible_y, -1,
11839 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
11840 if (IT_CHARPOS (it) == PT)
11841 w->force_start = Qt;
11842 /* IT may overshoot PT if text at PT is invisible. */
11843 else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT)
11844 w->force_start = Qt;
11849 /* Handle case where place to start displaying has been specified,
11850 unless the specified location is outside the accessible range. */
11851 if (!NILP (w->force_start)
11852 || w->frozen_window_start_p)
11854 /* We set this later on if we have to adjust point. */
11855 int new_vpos = -1;
11857 w->force_start = Qnil;
11858 w->vscroll = 0;
11859 w->window_end_valid = Qnil;
11861 /* Forget any recorded base line for line number display. */
11862 if (!buffer_unchanged_p)
11863 w->base_line_number = Qnil;
11865 /* Redisplay the mode line. Select the buffer properly for that.
11866 Also, run the hook window-scroll-functions
11867 because we have scrolled. */
11868 /* Note, we do this after clearing force_start because
11869 if there's an error, it is better to forget about force_start
11870 than to get into an infinite loop calling the hook functions
11871 and having them get more errors. */
11872 if (!update_mode_line
11873 || ! NILP (Vwindow_scroll_functions))
11875 update_mode_line = 1;
11876 w->update_mode_line = Qt;
11877 startp = run_window_scroll_functions (window, startp);
11880 w->last_modified = make_number (0);
11881 w->last_overlay_modified = make_number (0);
11882 if (CHARPOS (startp) < BEGV)
11883 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
11884 else if (CHARPOS (startp) > ZV)
11885 SET_TEXT_POS (startp, ZV, ZV_BYTE);
11887 /* Redisplay, then check if cursor has been set during the
11888 redisplay. Give up if new fonts were loaded. */
11889 if (!try_window (window, startp))
11891 w->force_start = Qt;
11892 clear_glyph_matrix (w->desired_matrix);
11893 goto need_larger_matrices;
11896 if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
11898 /* If point does not appear, try to move point so it does
11899 appear. The desired matrix has been built above, so we
11900 can use it here. */
11901 new_vpos = window_box_height (w) / 2;
11904 if (!make_cursor_line_fully_visible (w, 0))
11906 /* Point does appear, but on a line partly visible at end of window.
11907 Move it back to a fully-visible line. */
11908 new_vpos = window_box_height (w);
11911 /* If we need to move point for either of the above reasons,
11912 now actually do it. */
11913 if (new_vpos >= 0)
11915 struct glyph_row *row;
11917 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
11918 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
11919 ++row;
11921 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
11922 MATRIX_ROW_START_BYTEPOS (row));
11924 if (w != XWINDOW (selected_window))
11925 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
11926 else if (current_buffer == old)
11927 SET_TEXT_POS (lpoint, PT, PT_BYTE);
11929 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
11931 /* If we are highlighting the region, then we just changed
11932 the region, so redisplay to show it. */
11933 if (!NILP (Vtransient_mark_mode)
11934 && !NILP (current_buffer->mark_active))
11936 clear_glyph_matrix (w->desired_matrix);
11937 if (!try_window (window, startp))
11938 goto need_larger_matrices;
11942 #if GLYPH_DEBUG
11943 debug_method_add (w, "forced window start");
11944 #endif
11945 goto done;
11948 /* Handle case where text has not changed, only point, and it has
11949 not moved off the frame, and we are not retrying after hscroll.
11950 (current_matrix_up_to_date_p is nonzero when retrying.) */
11951 if (current_matrix_up_to_date_p
11952 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
11953 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
11955 switch (rc)
11957 case CURSOR_MOVEMENT_SUCCESS:
11958 used_current_matrix_p = 1;
11959 goto done;
11961 #if 0 /* try_cursor_movement never returns this value. */
11962 case CURSOR_MOVEMENT_NEED_LARGER_MATRICES:
11963 goto need_larger_matrices;
11964 #endif
11966 case CURSOR_MOVEMENT_MUST_SCROLL:
11967 goto try_to_scroll;
11969 default:
11970 abort ();
11973 /* If current starting point was originally the beginning of a line
11974 but no longer is, find a new starting point. */
11975 else if (!NILP (w->start_at_line_beg)
11976 && !(CHARPOS (startp) <= BEGV
11977 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
11979 #if GLYPH_DEBUG
11980 debug_method_add (w, "recenter 1");
11981 #endif
11982 goto recenter;
11985 /* Try scrolling with try_window_id. Value is > 0 if update has
11986 been done, it is -1 if we know that the same window start will
11987 not work. It is 0 if unsuccessful for some other reason. */
11988 else if ((tem = try_window_id (w)) != 0)
11990 #if GLYPH_DEBUG
11991 debug_method_add (w, "try_window_id %d", tem);
11992 #endif
11994 if (fonts_changed_p)
11995 goto need_larger_matrices;
11996 if (tem > 0)
11997 goto done;
11999 /* Otherwise try_window_id has returned -1 which means that we
12000 don't want the alternative below this comment to execute. */
12002 else if (CHARPOS (startp) >= BEGV
12003 && CHARPOS (startp) <= ZV
12004 && PT >= CHARPOS (startp)
12005 && (CHARPOS (startp) < ZV
12006 /* Avoid starting at end of buffer. */
12007 || CHARPOS (startp) == BEGV
12008 || (XFASTINT (w->last_modified) >= MODIFF
12009 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)))
12011 #if GLYPH_DEBUG
12012 debug_method_add (w, "same window start");
12013 #endif
12015 /* Try to redisplay starting at same place as before.
12016 If point has not moved off frame, accept the results. */
12017 if (!current_matrix_up_to_date_p
12018 /* Don't use try_window_reusing_current_matrix in this case
12019 because a window scroll function can have changed the
12020 buffer. */
12021 || !NILP (Vwindow_scroll_functions)
12022 || MINI_WINDOW_P (w)
12023 || !(used_current_matrix_p
12024 = try_window_reusing_current_matrix (w)))
12026 IF_DEBUG (debug_method_add (w, "1"));
12027 try_window (window, startp);
12030 if (fonts_changed_p)
12031 goto need_larger_matrices;
12033 if (w->cursor.vpos >= 0)
12035 if (!just_this_one_p
12036 || current_buffer->clip_changed
12037 || BEG_UNCHANGED < CHARPOS (startp))
12038 /* Forget any recorded base line for line number display. */
12039 w->base_line_number = Qnil;
12041 if (!make_cursor_line_fully_visible (w, 1))
12043 clear_glyph_matrix (w->desired_matrix);
12044 last_line_misfit = 1;
12046 /* Drop through and scroll. */
12047 else
12048 goto done;
12050 else
12051 clear_glyph_matrix (w->desired_matrix);
12054 try_to_scroll:
12056 w->last_modified = make_number (0);
12057 w->last_overlay_modified = make_number (0);
12059 /* Redisplay the mode line. Select the buffer properly for that. */
12060 if (!update_mode_line)
12062 update_mode_line = 1;
12063 w->update_mode_line = Qt;
12066 /* Try to scroll by specified few lines. */
12067 if ((scroll_conservatively
12068 || scroll_step
12069 || temp_scroll_step
12070 || NUMBERP (current_buffer->scroll_up_aggressively)
12071 || NUMBERP (current_buffer->scroll_down_aggressively))
12072 && !current_buffer->clip_changed
12073 && CHARPOS (startp) >= BEGV
12074 && CHARPOS (startp) <= ZV)
12076 /* The function returns -1 if new fonts were loaded, 1 if
12077 successful, 0 if not successful. */
12078 int rc = try_scrolling (window, just_this_one_p,
12079 scroll_conservatively,
12080 scroll_step,
12081 temp_scroll_step, last_line_misfit);
12082 switch (rc)
12084 case SCROLLING_SUCCESS:
12085 goto done;
12087 case SCROLLING_NEED_LARGER_MATRICES:
12088 goto need_larger_matrices;
12090 case SCROLLING_FAILED:
12091 break;
12093 default:
12094 abort ();
12098 /* Finally, just choose place to start which centers point */
12100 recenter:
12101 centering_position = window_box_height (w) / 2;
12103 point_at_top:
12104 /* Jump here with centering_position already set to 0. */
12106 #if GLYPH_DEBUG
12107 debug_method_add (w, "recenter");
12108 #endif
12110 /* w->vscroll = 0; */
12112 /* Forget any previously recorded base line for line number display. */
12113 if (!buffer_unchanged_p)
12114 w->base_line_number = Qnil;
12116 /* Move backward half the height of the window. */
12117 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
12118 it.current_y = it.last_visible_y;
12119 move_it_vertically_backward (&it, centering_position);
12120 xassert (IT_CHARPOS (it) >= BEGV);
12122 /* The function move_it_vertically_backward may move over more
12123 than the specified y-distance. If it->w is small, e.g. a
12124 mini-buffer window, we may end up in front of the window's
12125 display area. Start displaying at the start of the line
12126 containing PT in this case. */
12127 if (it.current_y <= 0)
12129 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
12130 move_it_vertically_backward (&it, 0);
12131 xassert (IT_CHARPOS (it) <= PT);
12132 it.current_y = 0;
12135 it.current_x = it.hpos = 0;
12137 /* Set startp here explicitly in case that helps avoid an infinite loop
12138 in case the window-scroll-functions functions get errors. */
12139 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
12141 /* Run scroll hooks. */
12142 startp = run_window_scroll_functions (window, it.current.pos);
12144 /* Redisplay the window. */
12145 if (!current_matrix_up_to_date_p
12146 || windows_or_buffers_changed
12147 || cursor_type_changed
12148 /* Don't use try_window_reusing_current_matrix in this case
12149 because it can have changed the buffer. */
12150 || !NILP (Vwindow_scroll_functions)
12151 || !just_this_one_p
12152 || MINI_WINDOW_P (w)
12153 || !(used_current_matrix_p
12154 = try_window_reusing_current_matrix (w)))
12155 try_window (window, startp);
12157 /* If new fonts have been loaded (due to fontsets), give up. We
12158 have to start a new redisplay since we need to re-adjust glyph
12159 matrices. */
12160 if (fonts_changed_p)
12161 goto need_larger_matrices;
12163 /* If cursor did not appear assume that the middle of the window is
12164 in the first line of the window. Do it again with the next line.
12165 (Imagine a window of height 100, displaying two lines of height
12166 60. Moving back 50 from it->last_visible_y will end in the first
12167 line.) */
12168 if (w->cursor.vpos < 0)
12170 if (!NILP (w->window_end_valid)
12171 && PT >= Z - XFASTINT (w->window_end_pos))
12173 clear_glyph_matrix (w->desired_matrix);
12174 move_it_by_lines (&it, 1, 0);
12175 try_window (window, it.current.pos);
12177 else if (PT < IT_CHARPOS (it))
12179 clear_glyph_matrix (w->desired_matrix);
12180 move_it_by_lines (&it, -1, 0);
12181 try_window (window, it.current.pos);
12183 else
12185 /* Not much we can do about it. */
12189 /* Consider the following case: Window starts at BEGV, there is
12190 invisible, intangible text at BEGV, so that display starts at
12191 some point START > BEGV. It can happen that we are called with
12192 PT somewhere between BEGV and START. Try to handle that case. */
12193 if (w->cursor.vpos < 0)
12195 struct glyph_row *row = w->current_matrix->rows;
12196 if (row->mode_line_p)
12197 ++row;
12198 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
12201 if (!make_cursor_line_fully_visible (w, centering_position > 0))
12203 /* If vscroll is enabled, disable it and try again. */
12204 if (w->vscroll)
12206 w->vscroll = 0;
12207 clear_glyph_matrix (w->desired_matrix);
12208 goto recenter;
12211 /* If centering point failed to make the whole line visible,
12212 put point at the top instead. That has to make the whole line
12213 visible, if it can be done. */
12214 clear_glyph_matrix (w->desired_matrix);
12215 centering_position = 0;
12216 goto point_at_top;
12219 done:
12221 SET_TEXT_POS_FROM_MARKER (startp, w->start);
12222 w->start_at_line_beg = ((CHARPOS (startp) == BEGV
12223 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n')
12224 ? Qt : Qnil);
12226 /* Display the mode line, if we must. */
12227 if ((update_mode_line
12228 /* If window not full width, must redo its mode line
12229 if (a) the window to its side is being redone and
12230 (b) we do a frame-based redisplay. This is a consequence
12231 of how inverted lines are drawn in frame-based redisplay. */
12232 || (!just_this_one_p
12233 && !FRAME_WINDOW_P (f)
12234 && !WINDOW_FULL_WIDTH_P (w))
12235 /* Line number to display. */
12236 || INTEGERP (w->base_line_pos)
12237 /* Column number is displayed and different from the one displayed. */
12238 || (!NILP (w->column_number_displayed)
12239 && (XFASTINT (w->column_number_displayed)
12240 != (int) current_column ()))) /* iftc */
12241 /* This means that the window has a mode line. */
12242 && (WINDOW_WANTS_MODELINE_P (w)
12243 || WINDOW_WANTS_HEADER_LINE_P (w)))
12245 display_mode_lines (w);
12247 /* If mode line height has changed, arrange for a thorough
12248 immediate redisplay using the correct mode line height. */
12249 if (WINDOW_WANTS_MODELINE_P (w)
12250 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
12252 fonts_changed_p = 1;
12253 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
12254 = DESIRED_MODE_LINE_HEIGHT (w);
12257 /* If top line height has changed, arrange for a thorough
12258 immediate redisplay using the correct mode line height. */
12259 if (WINDOW_WANTS_HEADER_LINE_P (w)
12260 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
12262 fonts_changed_p = 1;
12263 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
12264 = DESIRED_HEADER_LINE_HEIGHT (w);
12267 if (fonts_changed_p)
12268 goto need_larger_matrices;
12271 if (!line_number_displayed
12272 && !BUFFERP (w->base_line_pos))
12274 w->base_line_pos = Qnil;
12275 w->base_line_number = Qnil;
12278 finish_menu_bars:
12280 /* When we reach a frame's selected window, redo the frame's menu bar. */
12281 if (update_mode_line
12282 && EQ (FRAME_SELECTED_WINDOW (f), window))
12284 int redisplay_menu_p = 0;
12285 int redisplay_tool_bar_p = 0;
12287 if (FRAME_WINDOW_P (f))
12289 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
12290 || defined (USE_GTK)
12291 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
12292 #else
12293 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
12294 #endif
12296 else
12297 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
12299 if (redisplay_menu_p)
12300 display_menu_bar (w);
12302 #ifdef HAVE_WINDOW_SYSTEM
12303 #ifdef USE_GTK
12304 redisplay_tool_bar_p = FRAME_EXTERNAL_TOOL_BAR (f);
12305 #else
12306 redisplay_tool_bar_p = WINDOWP (f->tool_bar_window)
12307 && (FRAME_TOOL_BAR_LINES (f) > 0
12308 || auto_resize_tool_bars_p);
12310 #endif
12312 if (redisplay_tool_bar_p)
12313 redisplay_tool_bar (f);
12314 #endif
12317 #ifdef HAVE_WINDOW_SYSTEM
12318 if (FRAME_WINDOW_P (f)
12319 && update_window_fringes (w, 0)
12320 && !just_this_one_p
12321 && (used_current_matrix_p || overlay_arrow_seen)
12322 && !w->pseudo_window_p)
12324 update_begin (f);
12325 BLOCK_INPUT;
12326 if (draw_window_fringes (w, 1))
12327 x_draw_vertical_border (w);
12328 UNBLOCK_INPUT;
12329 update_end (f);
12331 #endif /* HAVE_WINDOW_SYSTEM */
12333 /* We go to this label, with fonts_changed_p nonzero,
12334 if it is necessary to try again using larger glyph matrices.
12335 We have to redeem the scroll bar even in this case,
12336 because the loop in redisplay_internal expects that. */
12337 need_larger_matrices:
12339 finish_scroll_bars:
12341 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
12343 /* Set the thumb's position and size. */
12344 set_vertical_scroll_bar (w);
12346 /* Note that we actually used the scroll bar attached to this
12347 window, so it shouldn't be deleted at the end of redisplay. */
12348 redeem_scroll_bar_hook (w);
12351 /* Restore current_buffer and value of point in it. */
12352 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
12353 set_buffer_internal_1 (old);
12354 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
12356 unbind_to (count, Qnil);
12360 /* Build the complete desired matrix of WINDOW with a window start
12361 buffer position POS. Value is non-zero if successful. It is zero
12362 if fonts were loaded during redisplay which makes re-adjusting
12363 glyph matrices necessary. */
12366 try_window (window, pos)
12367 Lisp_Object window;
12368 struct text_pos pos;
12370 struct window *w = XWINDOW (window);
12371 struct it it;
12372 struct glyph_row *last_text_row = NULL;
12374 /* Make POS the new window start. */
12375 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
12377 /* Mark cursor position as unknown. No overlay arrow seen. */
12378 w->cursor.vpos = -1;
12379 overlay_arrow_seen = 0;
12381 /* Initialize iterator and info to start at POS. */
12382 start_display (&it, w, pos);
12384 /* Display all lines of W. */
12385 while (it.current_y < it.last_visible_y)
12387 if (display_line (&it))
12388 last_text_row = it.glyph_row - 1;
12389 if (fonts_changed_p)
12390 return 0;
12393 /* If bottom moved off end of frame, change mode line percentage. */
12394 if (XFASTINT (w->window_end_pos) <= 0
12395 && Z != IT_CHARPOS (it))
12396 w->update_mode_line = Qt;
12398 /* Set window_end_pos to the offset of the last character displayed
12399 on the window from the end of current_buffer. Set
12400 window_end_vpos to its row number. */
12401 if (last_text_row)
12403 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
12404 w->window_end_bytepos
12405 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12406 w->window_end_pos
12407 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12408 w->window_end_vpos
12409 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12410 xassert (MATRIX_ROW (w->desired_matrix, XFASTINT (w->window_end_vpos))
12411 ->displays_text_p);
12413 else
12415 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
12416 w->window_end_pos = make_number (Z - ZV);
12417 w->window_end_vpos = make_number (0);
12420 /* But that is not valid info until redisplay finishes. */
12421 w->window_end_valid = Qnil;
12422 return 1;
12427 /************************************************************************
12428 Window redisplay reusing current matrix when buffer has not changed
12429 ************************************************************************/
12431 /* Try redisplay of window W showing an unchanged buffer with a
12432 different window start than the last time it was displayed by
12433 reusing its current matrix. Value is non-zero if successful.
12434 W->start is the new window start. */
12436 static int
12437 try_window_reusing_current_matrix (w)
12438 struct window *w;
12440 struct frame *f = XFRAME (w->frame);
12441 struct glyph_row *row, *bottom_row;
12442 struct it it;
12443 struct run run;
12444 struct text_pos start, new_start;
12445 int nrows_scrolled, i;
12446 struct glyph_row *last_text_row;
12447 struct glyph_row *last_reused_text_row;
12448 struct glyph_row *start_row;
12449 int start_vpos, min_y, max_y;
12451 #if GLYPH_DEBUG
12452 if (inhibit_try_window_reusing)
12453 return 0;
12454 #endif
12456 if (/* This function doesn't handle terminal frames. */
12457 !FRAME_WINDOW_P (f)
12458 /* Don't try to reuse the display if windows have been split
12459 or such. */
12460 || windows_or_buffers_changed
12461 || cursor_type_changed)
12462 return 0;
12464 /* Can't do this if region may have changed. */
12465 if ((!NILP (Vtransient_mark_mode)
12466 && !NILP (current_buffer->mark_active))
12467 || !NILP (w->region_showing)
12468 || !NILP (Vshow_trailing_whitespace))
12469 return 0;
12471 /* If top-line visibility has changed, give up. */
12472 if (WINDOW_WANTS_HEADER_LINE_P (w)
12473 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
12474 return 0;
12476 /* Give up if old or new display is scrolled vertically. We could
12477 make this function handle this, but right now it doesn't. */
12478 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12479 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row))
12480 return 0;
12482 /* The variable new_start now holds the new window start. The old
12483 start `start' can be determined from the current matrix. */
12484 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
12485 start = start_row->start.pos;
12486 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
12488 /* Clear the desired matrix for the display below. */
12489 clear_glyph_matrix (w->desired_matrix);
12491 if (CHARPOS (new_start) <= CHARPOS (start))
12493 int first_row_y;
12495 /* Don't use this method if the display starts with an ellipsis
12496 displayed for invisible text. It's not easy to handle that case
12497 below, and it's certainly not worth the effort since this is
12498 not a frequent case. */
12499 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
12500 return 0;
12502 IF_DEBUG (debug_method_add (w, "twu1"));
12504 /* Display up to a row that can be reused. The variable
12505 last_text_row is set to the last row displayed that displays
12506 text. Note that it.vpos == 0 if or if not there is a
12507 header-line; it's not the same as the MATRIX_ROW_VPOS! */
12508 start_display (&it, w, new_start);
12509 first_row_y = it.current_y;
12510 w->cursor.vpos = -1;
12511 last_text_row = last_reused_text_row = NULL;
12513 while (it.current_y < it.last_visible_y
12514 && !fonts_changed_p)
12516 /* If we have reached into the characters in the START row,
12517 that means the line boundaries have changed. So we
12518 can't start copying with the row START. Maybe it will
12519 work to start copying with the following row. */
12520 while (IT_CHARPOS (it) > CHARPOS (start))
12522 /* Advance to the next row as the "start". */
12523 start_row++;
12524 start = start_row->start.pos;
12525 /* If there are no more rows to try, or just one, give up. */
12526 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
12527 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row)
12528 || CHARPOS (start) == ZV)
12530 clear_glyph_matrix (w->desired_matrix);
12531 return 0;
12534 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
12536 /* If we have reached alignment,
12537 we can copy the rest of the rows. */
12538 if (IT_CHARPOS (it) == CHARPOS (start))
12539 break;
12541 if (display_line (&it))
12542 last_text_row = it.glyph_row - 1;
12545 /* A value of current_y < last_visible_y means that we stopped
12546 at the previous window start, which in turn means that we
12547 have at least one reusable row. */
12548 if (it.current_y < it.last_visible_y)
12550 /* IT.vpos always starts from 0; it counts text lines. */
12551 nrows_scrolled = it.vpos - (start_row - MATRIX_FIRST_TEXT_ROW (w->current_matrix));
12553 /* Find PT if not already found in the lines displayed. */
12554 if (w->cursor.vpos < 0)
12556 int dy = it.current_y - start_row->y;
12558 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12559 row = row_containing_pos (w, PT, row, NULL, dy);
12560 if (row)
12561 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
12562 dy, nrows_scrolled);
12563 else
12565 clear_glyph_matrix (w->desired_matrix);
12566 return 0;
12570 /* Scroll the display. Do it before the current matrix is
12571 changed. The problem here is that update has not yet
12572 run, i.e. part of the current matrix is not up to date.
12573 scroll_run_hook will clear the cursor, and use the
12574 current matrix to get the height of the row the cursor is
12575 in. */
12576 run.current_y = start_row->y;
12577 run.desired_y = it.current_y;
12578 run.height = it.last_visible_y - it.current_y;
12580 if (run.height > 0 && run.current_y != run.desired_y)
12582 update_begin (f);
12583 rif->update_window_begin_hook (w);
12584 rif->clear_window_mouse_face (w);
12585 rif->scroll_run_hook (w, &run);
12586 rif->update_window_end_hook (w, 0, 0);
12587 update_end (f);
12590 /* Shift current matrix down by nrows_scrolled lines. */
12591 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
12592 rotate_matrix (w->current_matrix,
12593 start_vpos,
12594 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
12595 nrows_scrolled);
12597 /* Disable lines that must be updated. */
12598 for (i = 0; i < it.vpos; ++i)
12599 (start_row + i)->enabled_p = 0;
12601 /* Re-compute Y positions. */
12602 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
12603 max_y = it.last_visible_y;
12604 for (row = start_row + nrows_scrolled;
12605 row < bottom_row;
12606 ++row)
12608 row->y = it.current_y;
12609 row->visible_height = row->height;
12611 if (row->y < min_y)
12612 row->visible_height -= min_y - row->y;
12613 if (row->y + row->height > max_y)
12614 row->visible_height -= row->y + row->height - max_y;
12615 row->redraw_fringe_bitmaps_p = 1;
12617 it.current_y += row->height;
12619 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
12620 last_reused_text_row = row;
12621 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
12622 break;
12625 /* Disable lines in the current matrix which are now
12626 below the window. */
12627 for (++row; row < bottom_row; ++row)
12628 row->enabled_p = 0;
12631 /* Update window_end_pos etc.; last_reused_text_row is the last
12632 reused row from the current matrix containing text, if any.
12633 The value of last_text_row is the last displayed line
12634 containing text. */
12635 if (last_reused_text_row)
12637 w->window_end_bytepos
12638 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
12639 w->window_end_pos
12640 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_reused_text_row));
12641 w->window_end_vpos
12642 = make_number (MATRIX_ROW_VPOS (last_reused_text_row,
12643 w->current_matrix));
12645 else if (last_text_row)
12647 w->window_end_bytepos
12648 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12649 w->window_end_pos
12650 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12651 w->window_end_vpos
12652 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12654 else
12656 /* This window must be completely empty. */
12657 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
12658 w->window_end_pos = make_number (Z - ZV);
12659 w->window_end_vpos = make_number (0);
12661 w->window_end_valid = Qnil;
12663 /* Update hint: don't try scrolling again in update_window. */
12664 w->desired_matrix->no_scrolling_p = 1;
12666 #if GLYPH_DEBUG
12667 debug_method_add (w, "try_window_reusing_current_matrix 1");
12668 #endif
12669 return 1;
12671 else if (CHARPOS (new_start) > CHARPOS (start))
12673 struct glyph_row *pt_row, *row;
12674 struct glyph_row *first_reusable_row;
12675 struct glyph_row *first_row_to_display;
12676 int dy;
12677 int yb = window_text_bottom_y (w);
12679 /* Find the row starting at new_start, if there is one. Don't
12680 reuse a partially visible line at the end. */
12681 first_reusable_row = start_row;
12682 while (first_reusable_row->enabled_p
12683 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
12684 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
12685 < CHARPOS (new_start)))
12686 ++first_reusable_row;
12688 /* Give up if there is no row to reuse. */
12689 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
12690 || !first_reusable_row->enabled_p
12691 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
12692 != CHARPOS (new_start)))
12693 return 0;
12695 /* We can reuse fully visible rows beginning with
12696 first_reusable_row to the end of the window. Set
12697 first_row_to_display to the first row that cannot be reused.
12698 Set pt_row to the row containing point, if there is any. */
12699 pt_row = NULL;
12700 for (first_row_to_display = first_reusable_row;
12701 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
12702 ++first_row_to_display)
12704 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
12705 && PT < MATRIX_ROW_END_CHARPOS (first_row_to_display))
12706 pt_row = first_row_to_display;
12709 /* Start displaying at the start of first_row_to_display. */
12710 xassert (first_row_to_display->y < yb);
12711 init_to_row_start (&it, w, first_row_to_display);
12713 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
12714 - start_vpos);
12715 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
12716 - nrows_scrolled);
12717 it.current_y = (first_row_to_display->y - first_reusable_row->y
12718 + WINDOW_HEADER_LINE_HEIGHT (w));
12720 /* Display lines beginning with first_row_to_display in the
12721 desired matrix. Set last_text_row to the last row displayed
12722 that displays text. */
12723 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
12724 if (pt_row == NULL)
12725 w->cursor.vpos = -1;
12726 last_text_row = NULL;
12727 while (it.current_y < it.last_visible_y && !fonts_changed_p)
12728 if (display_line (&it))
12729 last_text_row = it.glyph_row - 1;
12731 /* Give up If point isn't in a row displayed or reused. */
12732 if (w->cursor.vpos < 0)
12734 clear_glyph_matrix (w->desired_matrix);
12735 return 0;
12738 /* If point is in a reused row, adjust y and vpos of the cursor
12739 position. */
12740 if (pt_row)
12742 w->cursor.vpos -= nrows_scrolled;
12743 w->cursor.y -= first_reusable_row->y - start_row->y;
12746 /* Scroll the display. */
12747 run.current_y = first_reusable_row->y;
12748 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
12749 run.height = it.last_visible_y - run.current_y;
12750 dy = run.current_y - run.desired_y;
12752 if (run.height)
12754 update_begin (f);
12755 rif->update_window_begin_hook (w);
12756 rif->clear_window_mouse_face (w);
12757 rif->scroll_run_hook (w, &run);
12758 rif->update_window_end_hook (w, 0, 0);
12759 update_end (f);
12762 /* Adjust Y positions of reused rows. */
12763 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
12764 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
12765 max_y = it.last_visible_y;
12766 for (row = first_reusable_row; row < first_row_to_display; ++row)
12768 row->y -= dy;
12769 row->visible_height = row->height;
12770 if (row->y < min_y)
12771 row->visible_height -= min_y - row->y;
12772 if (row->y + row->height > max_y)
12773 row->visible_height -= row->y + row->height - max_y;
12774 row->redraw_fringe_bitmaps_p = 1;
12777 /* Scroll the current matrix. */
12778 xassert (nrows_scrolled > 0);
12779 rotate_matrix (w->current_matrix,
12780 start_vpos,
12781 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
12782 -nrows_scrolled);
12784 /* Disable rows not reused. */
12785 for (row -= nrows_scrolled; row < bottom_row; ++row)
12786 row->enabled_p = 0;
12788 /* Point may have moved to a different line, so we cannot assume that
12789 the previous cursor position is valid; locate the correct row. */
12790 if (pt_row)
12792 for (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
12793 row < bottom_row && PT >= MATRIX_ROW_END_CHARPOS (row);
12794 row++)
12796 w->cursor.vpos++;
12797 w->cursor.y = row->y;
12799 if (row < bottom_row)
12801 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
12802 while (glyph->charpos < PT)
12804 w->cursor.hpos++;
12805 w->cursor.x += glyph->pixel_width;
12806 glyph++;
12811 /* Adjust window end. A null value of last_text_row means that
12812 the window end is in reused rows which in turn means that
12813 only its vpos can have changed. */
12814 if (last_text_row)
12816 w->window_end_bytepos
12817 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12818 w->window_end_pos
12819 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12820 w->window_end_vpos
12821 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12823 else
12825 w->window_end_vpos
12826 = make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled);
12829 w->window_end_valid = Qnil;
12830 w->desired_matrix->no_scrolling_p = 1;
12832 #if GLYPH_DEBUG
12833 debug_method_add (w, "try_window_reusing_current_matrix 2");
12834 #endif
12835 return 1;
12838 return 0;
12843 /************************************************************************
12844 Window redisplay reusing current matrix when buffer has changed
12845 ************************************************************************/
12847 static struct glyph_row *find_last_unchanged_at_beg_row P_ ((struct window *));
12848 static struct glyph_row *find_first_unchanged_at_end_row P_ ((struct window *,
12849 int *, int *));
12850 static struct glyph_row *
12851 find_last_row_displaying_text P_ ((struct glyph_matrix *, struct it *,
12852 struct glyph_row *));
12855 /* Return the last row in MATRIX displaying text. If row START is
12856 non-null, start searching with that row. IT gives the dimensions
12857 of the display. Value is null if matrix is empty; otherwise it is
12858 a pointer to the row found. */
12860 static struct glyph_row *
12861 find_last_row_displaying_text (matrix, it, start)
12862 struct glyph_matrix *matrix;
12863 struct it *it;
12864 struct glyph_row *start;
12866 struct glyph_row *row, *row_found;
12868 /* Set row_found to the last row in IT->w's current matrix
12869 displaying text. The loop looks funny but think of partially
12870 visible lines. */
12871 row_found = NULL;
12872 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
12873 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
12875 xassert (row->enabled_p);
12876 row_found = row;
12877 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
12878 break;
12879 ++row;
12882 return row_found;
12886 /* Return the last row in the current matrix of W that is not affected
12887 by changes at the start of current_buffer that occurred since W's
12888 current matrix was built. Value is null if no such row exists.
12890 BEG_UNCHANGED us the number of characters unchanged at the start of
12891 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
12892 first changed character in current_buffer. Characters at positions <
12893 BEG + BEG_UNCHANGED are at the same buffer positions as they were
12894 when the current matrix was built. */
12896 static struct glyph_row *
12897 find_last_unchanged_at_beg_row (w)
12898 struct window *w;
12900 int first_changed_pos = BEG + BEG_UNCHANGED;
12901 struct glyph_row *row;
12902 struct glyph_row *row_found = NULL;
12903 int yb = window_text_bottom_y (w);
12905 /* Find the last row displaying unchanged text. */
12906 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12907 while (MATRIX_ROW_DISPLAYS_TEXT_P (row)
12908 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos)
12910 if (/* If row ends before first_changed_pos, it is unchanged,
12911 except in some case. */
12912 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
12913 /* When row ends in ZV and we write at ZV it is not
12914 unchanged. */
12915 && !row->ends_at_zv_p
12916 /* When first_changed_pos is the end of a continued line,
12917 row is not unchanged because it may be no longer
12918 continued. */
12919 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
12920 && (row->continued_p
12921 || row->exact_window_width_line_p)))
12922 row_found = row;
12924 /* Stop if last visible row. */
12925 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
12926 break;
12928 ++row;
12931 return row_found;
12935 /* Find the first glyph row in the current matrix of W that is not
12936 affected by changes at the end of current_buffer since the
12937 time W's current matrix was built.
12939 Return in *DELTA the number of chars by which buffer positions in
12940 unchanged text at the end of current_buffer must be adjusted.
12942 Return in *DELTA_BYTES the corresponding number of bytes.
12944 Value is null if no such row exists, i.e. all rows are affected by
12945 changes. */
12947 static struct glyph_row *
12948 find_first_unchanged_at_end_row (w, delta, delta_bytes)
12949 struct window *w;
12950 int *delta, *delta_bytes;
12952 struct glyph_row *row;
12953 struct glyph_row *row_found = NULL;
12955 *delta = *delta_bytes = 0;
12957 /* Display must not have been paused, otherwise the current matrix
12958 is not up to date. */
12959 if (NILP (w->window_end_valid))
12960 abort ();
12962 /* A value of window_end_pos >= END_UNCHANGED means that the window
12963 end is in the range of changed text. If so, there is no
12964 unchanged row at the end of W's current matrix. */
12965 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
12966 return NULL;
12968 /* Set row to the last row in W's current matrix displaying text. */
12969 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
12971 /* If matrix is entirely empty, no unchanged row exists. */
12972 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
12974 /* The value of row is the last glyph row in the matrix having a
12975 meaningful buffer position in it. The end position of row
12976 corresponds to window_end_pos. This allows us to translate
12977 buffer positions in the current matrix to current buffer
12978 positions for characters not in changed text. */
12979 int Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
12980 int Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
12981 int last_unchanged_pos, last_unchanged_pos_old;
12982 struct glyph_row *first_text_row
12983 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12985 *delta = Z - Z_old;
12986 *delta_bytes = Z_BYTE - Z_BYTE_old;
12988 /* Set last_unchanged_pos to the buffer position of the last
12989 character in the buffer that has not been changed. Z is the
12990 index + 1 of the last character in current_buffer, i.e. by
12991 subtracting END_UNCHANGED we get the index of the last
12992 unchanged character, and we have to add BEG to get its buffer
12993 position. */
12994 last_unchanged_pos = Z - END_UNCHANGED + BEG;
12995 last_unchanged_pos_old = last_unchanged_pos - *delta;
12997 /* Search backward from ROW for a row displaying a line that
12998 starts at a minimum position >= last_unchanged_pos_old. */
12999 for (; row > first_text_row; --row)
13001 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
13002 abort ();
13004 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
13005 row_found = row;
13009 if (row_found && !MATRIX_ROW_DISPLAYS_TEXT_P (row_found))
13010 abort ();
13012 return row_found;
13016 /* Make sure that glyph rows in the current matrix of window W
13017 reference the same glyph memory as corresponding rows in the
13018 frame's frame matrix. This function is called after scrolling W's
13019 current matrix on a terminal frame in try_window_id and
13020 try_window_reusing_current_matrix. */
13022 static void
13023 sync_frame_with_window_matrix_rows (w)
13024 struct window *w;
13026 struct frame *f = XFRAME (w->frame);
13027 struct glyph_row *window_row, *window_row_end, *frame_row;
13029 /* Preconditions: W must be a leaf window and full-width. Its frame
13030 must have a frame matrix. */
13031 xassert (NILP (w->hchild) && NILP (w->vchild));
13032 xassert (WINDOW_FULL_WIDTH_P (w));
13033 xassert (!FRAME_WINDOW_P (f));
13035 /* If W is a full-width window, glyph pointers in W's current matrix
13036 have, by definition, to be the same as glyph pointers in the
13037 corresponding frame matrix. Note that frame matrices have no
13038 marginal areas (see build_frame_matrix). */
13039 window_row = w->current_matrix->rows;
13040 window_row_end = window_row + w->current_matrix->nrows;
13041 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
13042 while (window_row < window_row_end)
13044 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
13045 struct glyph *end = window_row->glyphs[LAST_AREA];
13047 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
13048 frame_row->glyphs[TEXT_AREA] = start;
13049 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
13050 frame_row->glyphs[LAST_AREA] = end;
13052 /* Disable frame rows whose corresponding window rows have
13053 been disabled in try_window_id. */
13054 if (!window_row->enabled_p)
13055 frame_row->enabled_p = 0;
13057 ++window_row, ++frame_row;
13062 /* Find the glyph row in window W containing CHARPOS. Consider all
13063 rows between START and END (not inclusive). END null means search
13064 all rows to the end of the display area of W. Value is the row
13065 containing CHARPOS or null. */
13067 struct glyph_row *
13068 row_containing_pos (w, charpos, start, end, dy)
13069 struct window *w;
13070 int charpos;
13071 struct glyph_row *start, *end;
13072 int dy;
13074 struct glyph_row *row = start;
13075 int last_y;
13077 /* If we happen to start on a header-line, skip that. */
13078 if (row->mode_line_p)
13079 ++row;
13081 if ((end && row >= end) || !row->enabled_p)
13082 return NULL;
13084 last_y = window_text_bottom_y (w) - dy;
13086 while (1)
13088 /* Give up if we have gone too far. */
13089 if (end && row >= end)
13090 return NULL;
13091 /* This formerly returned if they were equal.
13092 I think that both quantities are of a "last plus one" type;
13093 if so, when they are equal, the row is within the screen. -- rms. */
13094 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
13095 return NULL;
13097 /* If it is in this row, return this row. */
13098 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
13099 || (MATRIX_ROW_END_CHARPOS (row) == charpos
13100 /* The end position of a row equals the start
13101 position of the next row. If CHARPOS is there, we
13102 would rather display it in the next line, except
13103 when this line ends in ZV. */
13104 && !row->ends_at_zv_p
13105 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
13106 && charpos >= MATRIX_ROW_START_CHARPOS (row))
13107 return row;
13108 ++row;
13113 /* Try to redisplay window W by reusing its existing display. W's
13114 current matrix must be up to date when this function is called,
13115 i.e. window_end_valid must not be nil.
13117 Value is
13119 1 if display has been updated
13120 0 if otherwise unsuccessful
13121 -1 if redisplay with same window start is known not to succeed
13123 The following steps are performed:
13125 1. Find the last row in the current matrix of W that is not
13126 affected by changes at the start of current_buffer. If no such row
13127 is found, give up.
13129 2. Find the first row in W's current matrix that is not affected by
13130 changes at the end of current_buffer. Maybe there is no such row.
13132 3. Display lines beginning with the row + 1 found in step 1 to the
13133 row found in step 2 or, if step 2 didn't find a row, to the end of
13134 the window.
13136 4. If cursor is not known to appear on the window, give up.
13138 5. If display stopped at the row found in step 2, scroll the
13139 display and current matrix as needed.
13141 6. Maybe display some lines at the end of W, if we must. This can
13142 happen under various circumstances, like a partially visible line
13143 becoming fully visible, or because newly displayed lines are displayed
13144 in smaller font sizes.
13146 7. Update W's window end information. */
13148 static int
13149 try_window_id (w)
13150 struct window *w;
13152 struct frame *f = XFRAME (w->frame);
13153 struct glyph_matrix *current_matrix = w->current_matrix;
13154 struct glyph_matrix *desired_matrix = w->desired_matrix;
13155 struct glyph_row *last_unchanged_at_beg_row;
13156 struct glyph_row *first_unchanged_at_end_row;
13157 struct glyph_row *row;
13158 struct glyph_row *bottom_row;
13159 int bottom_vpos;
13160 struct it it;
13161 int delta = 0, delta_bytes = 0, stop_pos, dvpos, dy;
13162 struct text_pos start_pos;
13163 struct run run;
13164 int first_unchanged_at_end_vpos = 0;
13165 struct glyph_row *last_text_row, *last_text_row_at_end;
13166 struct text_pos start;
13167 int first_changed_charpos, last_changed_charpos;
13169 #if GLYPH_DEBUG
13170 if (inhibit_try_window_id)
13171 return 0;
13172 #endif
13174 /* This is handy for debugging. */
13175 #if 0
13176 #define GIVE_UP(X) \
13177 do { \
13178 fprintf (stderr, "try_window_id give up %d\n", (X)); \
13179 return 0; \
13180 } while (0)
13181 #else
13182 #define GIVE_UP(X) return 0
13183 #endif
13185 SET_TEXT_POS_FROM_MARKER (start, w->start);
13187 /* Don't use this for mini-windows because these can show
13188 messages and mini-buffers, and we don't handle that here. */
13189 if (MINI_WINDOW_P (w))
13190 GIVE_UP (1);
13192 /* This flag is used to prevent redisplay optimizations. */
13193 if (windows_or_buffers_changed || cursor_type_changed)
13194 GIVE_UP (2);
13196 /* Verify that narrowing has not changed.
13197 Also verify that we were not told to prevent redisplay optimizations.
13198 It would be nice to further
13199 reduce the number of cases where this prevents try_window_id. */
13200 if (current_buffer->clip_changed
13201 || current_buffer->prevent_redisplay_optimizations_p)
13202 GIVE_UP (3);
13204 /* Window must either use window-based redisplay or be full width. */
13205 if (!FRAME_WINDOW_P (f)
13206 && (!line_ins_del_ok
13207 || !WINDOW_FULL_WIDTH_P (w)))
13208 GIVE_UP (4);
13210 /* Give up if point is not known NOT to appear in W. */
13211 if (PT < CHARPOS (start))
13212 GIVE_UP (5);
13214 /* Another way to prevent redisplay optimizations. */
13215 if (XFASTINT (w->last_modified) == 0)
13216 GIVE_UP (6);
13218 /* Verify that window is not hscrolled. */
13219 if (XFASTINT (w->hscroll) != 0)
13220 GIVE_UP (7);
13222 /* Verify that display wasn't paused. */
13223 if (NILP (w->window_end_valid))
13224 GIVE_UP (8);
13226 /* Can't use this if highlighting a region because a cursor movement
13227 will do more than just set the cursor. */
13228 if (!NILP (Vtransient_mark_mode)
13229 && !NILP (current_buffer->mark_active))
13230 GIVE_UP (9);
13232 /* Likewise if highlighting trailing whitespace. */
13233 if (!NILP (Vshow_trailing_whitespace))
13234 GIVE_UP (11);
13236 /* Likewise if showing a region. */
13237 if (!NILP (w->region_showing))
13238 GIVE_UP (10);
13240 /* Can use this if overlay arrow position and or string have changed. */
13241 if (overlay_arrows_changed_p ())
13242 GIVE_UP (12);
13245 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
13246 only if buffer has really changed. The reason is that the gap is
13247 initially at Z for freshly visited files. The code below would
13248 set end_unchanged to 0 in that case. */
13249 if (MODIFF > SAVE_MODIFF
13250 /* This seems to happen sometimes after saving a buffer. */
13251 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
13253 if (GPT - BEG < BEG_UNCHANGED)
13254 BEG_UNCHANGED = GPT - BEG;
13255 if (Z - GPT < END_UNCHANGED)
13256 END_UNCHANGED = Z - GPT;
13259 /* The position of the first and last character that has been changed. */
13260 first_changed_charpos = BEG + BEG_UNCHANGED;
13261 last_changed_charpos = Z - END_UNCHANGED;
13263 /* If window starts after a line end, and the last change is in
13264 front of that newline, then changes don't affect the display.
13265 This case happens with stealth-fontification. Note that although
13266 the display is unchanged, glyph positions in the matrix have to
13267 be adjusted, of course. */
13268 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
13269 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
13270 && ((last_changed_charpos < CHARPOS (start)
13271 && CHARPOS (start) == BEGV)
13272 || (last_changed_charpos < CHARPOS (start) - 1
13273 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
13275 int Z_old, delta, Z_BYTE_old, delta_bytes;
13276 struct glyph_row *r0;
13278 /* Compute how many chars/bytes have been added to or removed
13279 from the buffer. */
13280 Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
13281 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
13282 delta = Z - Z_old;
13283 delta_bytes = Z_BYTE - Z_BYTE_old;
13285 /* Give up if PT is not in the window. Note that it already has
13286 been checked at the start of try_window_id that PT is not in
13287 front of the window start. */
13288 if (PT >= MATRIX_ROW_END_CHARPOS (row) + delta)
13289 GIVE_UP (13);
13291 /* If window start is unchanged, we can reuse the whole matrix
13292 as is, after adjusting glyph positions. No need to compute
13293 the window end again, since its offset from Z hasn't changed. */
13294 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
13295 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + delta
13296 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + delta_bytes
13297 /* PT must not be in a partially visible line. */
13298 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + delta
13299 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
13301 /* Adjust positions in the glyph matrix. */
13302 if (delta || delta_bytes)
13304 struct glyph_row *r1
13305 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
13306 increment_matrix_positions (w->current_matrix,
13307 MATRIX_ROW_VPOS (r0, current_matrix),
13308 MATRIX_ROW_VPOS (r1, current_matrix),
13309 delta, delta_bytes);
13312 /* Set the cursor. */
13313 row = row_containing_pos (w, PT, r0, NULL, 0);
13314 if (row)
13315 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
13316 else
13317 abort ();
13318 return 1;
13322 /* Handle the case that changes are all below what is displayed in
13323 the window, and that PT is in the window. This shortcut cannot
13324 be taken if ZV is visible in the window, and text has been added
13325 there that is visible in the window. */
13326 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
13327 /* ZV is not visible in the window, or there are no
13328 changes at ZV, actually. */
13329 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
13330 || first_changed_charpos == last_changed_charpos))
13332 struct glyph_row *r0;
13334 /* Give up if PT is not in the window. Note that it already has
13335 been checked at the start of try_window_id that PT is not in
13336 front of the window start. */
13337 if (PT >= MATRIX_ROW_END_CHARPOS (row))
13338 GIVE_UP (14);
13340 /* If window start is unchanged, we can reuse the whole matrix
13341 as is, without changing glyph positions since no text has
13342 been added/removed in front of the window end. */
13343 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
13344 if (TEXT_POS_EQUAL_P (start, r0->start.pos)
13345 /* PT must not be in a partially visible line. */
13346 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
13347 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
13349 /* We have to compute the window end anew since text
13350 can have been added/removed after it. */
13351 w->window_end_pos
13352 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13353 w->window_end_bytepos
13354 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13356 /* Set the cursor. */
13357 row = row_containing_pos (w, PT, r0, NULL, 0);
13358 if (row)
13359 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
13360 else
13361 abort ();
13362 return 2;
13366 /* Give up if window start is in the changed area.
13368 The condition used to read
13370 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
13372 but why that was tested escapes me at the moment. */
13373 if (CHARPOS (start) >= first_changed_charpos
13374 && CHARPOS (start) <= last_changed_charpos)
13375 GIVE_UP (15);
13377 /* Check that window start agrees with the start of the first glyph
13378 row in its current matrix. Check this after we know the window
13379 start is not in changed text, otherwise positions would not be
13380 comparable. */
13381 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
13382 if (!TEXT_POS_EQUAL_P (start, row->start.pos))
13383 GIVE_UP (16);
13385 /* Give up if the window ends in strings. Overlay strings
13386 at the end are difficult to handle, so don't try. */
13387 row = MATRIX_ROW (current_matrix, XFASTINT (w->window_end_vpos));
13388 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
13389 GIVE_UP (20);
13391 /* Compute the position at which we have to start displaying new
13392 lines. Some of the lines at the top of the window might be
13393 reusable because they are not displaying changed text. Find the
13394 last row in W's current matrix not affected by changes at the
13395 start of current_buffer. Value is null if changes start in the
13396 first line of window. */
13397 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
13398 if (last_unchanged_at_beg_row)
13400 /* Avoid starting to display in the moddle of a character, a TAB
13401 for instance. This is easier than to set up the iterator
13402 exactly, and it's not a frequent case, so the additional
13403 effort wouldn't really pay off. */
13404 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
13405 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
13406 && last_unchanged_at_beg_row > w->current_matrix->rows)
13407 --last_unchanged_at_beg_row;
13409 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
13410 GIVE_UP (17);
13412 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
13413 GIVE_UP (18);
13414 start_pos = it.current.pos;
13416 /* Start displaying new lines in the desired matrix at the same
13417 vpos we would use in the current matrix, i.e. below
13418 last_unchanged_at_beg_row. */
13419 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
13420 current_matrix);
13421 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
13422 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
13424 xassert (it.hpos == 0 && it.current_x == 0);
13426 else
13428 /* There are no reusable lines at the start of the window.
13429 Start displaying in the first text line. */
13430 start_display (&it, w, start);
13431 it.vpos = it.first_vpos;
13432 start_pos = it.current.pos;
13435 /* Find the first row that is not affected by changes at the end of
13436 the buffer. Value will be null if there is no unchanged row, in
13437 which case we must redisplay to the end of the window. delta
13438 will be set to the value by which buffer positions beginning with
13439 first_unchanged_at_end_row have to be adjusted due to text
13440 changes. */
13441 first_unchanged_at_end_row
13442 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
13443 IF_DEBUG (debug_delta = delta);
13444 IF_DEBUG (debug_delta_bytes = delta_bytes);
13446 /* Set stop_pos to the buffer position up to which we will have to
13447 display new lines. If first_unchanged_at_end_row != NULL, this
13448 is the buffer position of the start of the line displayed in that
13449 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
13450 that we don't stop at a buffer position. */
13451 stop_pos = 0;
13452 if (first_unchanged_at_end_row)
13454 xassert (last_unchanged_at_beg_row == NULL
13455 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
13457 /* If this is a continuation line, move forward to the next one
13458 that isn't. Changes in lines above affect this line.
13459 Caution: this may move first_unchanged_at_end_row to a row
13460 not displaying text. */
13461 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
13462 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
13463 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
13464 < it.last_visible_y))
13465 ++first_unchanged_at_end_row;
13467 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
13468 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
13469 >= it.last_visible_y))
13470 first_unchanged_at_end_row = NULL;
13471 else
13473 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
13474 + delta);
13475 first_unchanged_at_end_vpos
13476 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
13477 xassert (stop_pos >= Z - END_UNCHANGED);
13480 else if (last_unchanged_at_beg_row == NULL)
13481 GIVE_UP (19);
13484 #if GLYPH_DEBUG
13486 /* Either there is no unchanged row at the end, or the one we have
13487 now displays text. This is a necessary condition for the window
13488 end pos calculation at the end of this function. */
13489 xassert (first_unchanged_at_end_row == NULL
13490 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
13492 debug_last_unchanged_at_beg_vpos
13493 = (last_unchanged_at_beg_row
13494 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
13495 : -1);
13496 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
13498 #endif /* GLYPH_DEBUG != 0 */
13501 /* Display new lines. Set last_text_row to the last new line
13502 displayed which has text on it, i.e. might end up as being the
13503 line where the window_end_vpos is. */
13504 w->cursor.vpos = -1;
13505 last_text_row = NULL;
13506 overlay_arrow_seen = 0;
13507 while (it.current_y < it.last_visible_y
13508 && !fonts_changed_p
13509 && (first_unchanged_at_end_row == NULL
13510 || IT_CHARPOS (it) < stop_pos))
13512 if (display_line (&it))
13513 last_text_row = it.glyph_row - 1;
13516 if (fonts_changed_p)
13517 return -1;
13520 /* Compute differences in buffer positions, y-positions etc. for
13521 lines reused at the bottom of the window. Compute what we can
13522 scroll. */
13523 if (first_unchanged_at_end_row
13524 /* No lines reused because we displayed everything up to the
13525 bottom of the window. */
13526 && it.current_y < it.last_visible_y)
13528 dvpos = (it.vpos
13529 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
13530 current_matrix));
13531 dy = it.current_y - first_unchanged_at_end_row->y;
13532 run.current_y = first_unchanged_at_end_row->y;
13533 run.desired_y = run.current_y + dy;
13534 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
13536 else
13538 delta = dvpos = dy = run.current_y = run.desired_y = run.height = 0;
13539 first_unchanged_at_end_row = NULL;
13541 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
13544 /* Find the cursor if not already found. We have to decide whether
13545 PT will appear on this window (it sometimes doesn't, but this is
13546 not a very frequent case.) This decision has to be made before
13547 the current matrix is altered. A value of cursor.vpos < 0 means
13548 that PT is either in one of the lines beginning at
13549 first_unchanged_at_end_row or below the window. Don't care for
13550 lines that might be displayed later at the window end; as
13551 mentioned, this is not a frequent case. */
13552 if (w->cursor.vpos < 0)
13554 /* Cursor in unchanged rows at the top? */
13555 if (PT < CHARPOS (start_pos)
13556 && last_unchanged_at_beg_row)
13558 row = row_containing_pos (w, PT,
13559 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
13560 last_unchanged_at_beg_row + 1, 0);
13561 if (row)
13562 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
13565 /* Start from first_unchanged_at_end_row looking for PT. */
13566 else if (first_unchanged_at_end_row)
13568 row = row_containing_pos (w, PT - delta,
13569 first_unchanged_at_end_row, NULL, 0);
13570 if (row)
13571 set_cursor_from_row (w, row, w->current_matrix, delta,
13572 delta_bytes, dy, dvpos);
13575 /* Give up if cursor was not found. */
13576 if (w->cursor.vpos < 0)
13578 clear_glyph_matrix (w->desired_matrix);
13579 return -1;
13583 /* Don't let the cursor end in the scroll margins. */
13585 int this_scroll_margin, cursor_height;
13587 this_scroll_margin = max (0, scroll_margin);
13588 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
13589 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
13590 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
13592 if ((w->cursor.y < this_scroll_margin
13593 && CHARPOS (start) > BEGV)
13594 /* Old redisplay didn't take scroll margin into account at the bottom,
13595 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
13596 || (w->cursor.y + (make_cursor_line_fully_visible_p
13597 ? cursor_height + this_scroll_margin
13598 : 1)) > it.last_visible_y)
13600 w->cursor.vpos = -1;
13601 clear_glyph_matrix (w->desired_matrix);
13602 return -1;
13606 /* Scroll the display. Do it before changing the current matrix so
13607 that xterm.c doesn't get confused about where the cursor glyph is
13608 found. */
13609 if (dy && run.height)
13611 update_begin (f);
13613 if (FRAME_WINDOW_P (f))
13615 rif->update_window_begin_hook (w);
13616 rif->clear_window_mouse_face (w);
13617 rif->scroll_run_hook (w, &run);
13618 rif->update_window_end_hook (w, 0, 0);
13620 else
13622 /* Terminal frame. In this case, dvpos gives the number of
13623 lines to scroll by; dvpos < 0 means scroll up. */
13624 int first_unchanged_at_end_vpos
13625 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
13626 int from = WINDOW_TOP_EDGE_LINE (w) + first_unchanged_at_end_vpos;
13627 int end = (WINDOW_TOP_EDGE_LINE (w)
13628 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
13629 + window_internal_height (w));
13631 /* Perform the operation on the screen. */
13632 if (dvpos > 0)
13634 /* Scroll last_unchanged_at_beg_row to the end of the
13635 window down dvpos lines. */
13636 set_terminal_window (end);
13638 /* On dumb terminals delete dvpos lines at the end
13639 before inserting dvpos empty lines. */
13640 if (!scroll_region_ok)
13641 ins_del_lines (end - dvpos, -dvpos);
13643 /* Insert dvpos empty lines in front of
13644 last_unchanged_at_beg_row. */
13645 ins_del_lines (from, dvpos);
13647 else if (dvpos < 0)
13649 /* Scroll up last_unchanged_at_beg_vpos to the end of
13650 the window to last_unchanged_at_beg_vpos - |dvpos|. */
13651 set_terminal_window (end);
13653 /* Delete dvpos lines in front of
13654 last_unchanged_at_beg_vpos. ins_del_lines will set
13655 the cursor to the given vpos and emit |dvpos| delete
13656 line sequences. */
13657 ins_del_lines (from + dvpos, dvpos);
13659 /* On a dumb terminal insert dvpos empty lines at the
13660 end. */
13661 if (!scroll_region_ok)
13662 ins_del_lines (end + dvpos, -dvpos);
13665 set_terminal_window (0);
13668 update_end (f);
13671 /* Shift reused rows of the current matrix to the right position.
13672 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
13673 text. */
13674 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
13675 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
13676 if (dvpos < 0)
13678 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
13679 bottom_vpos, dvpos);
13680 enable_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
13681 bottom_vpos, 0);
13683 else if (dvpos > 0)
13685 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
13686 bottom_vpos, dvpos);
13687 enable_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
13688 first_unchanged_at_end_vpos + dvpos, 0);
13691 /* For frame-based redisplay, make sure that current frame and window
13692 matrix are in sync with respect to glyph memory. */
13693 if (!FRAME_WINDOW_P (f))
13694 sync_frame_with_window_matrix_rows (w);
13696 /* Adjust buffer positions in reused rows. */
13697 if (delta)
13698 increment_matrix_positions (current_matrix,
13699 first_unchanged_at_end_vpos + dvpos,
13700 bottom_vpos, delta, delta_bytes);
13702 /* Adjust Y positions. */
13703 if (dy)
13704 shift_glyph_matrix (w, current_matrix,
13705 first_unchanged_at_end_vpos + dvpos,
13706 bottom_vpos, dy);
13708 if (first_unchanged_at_end_row)
13709 first_unchanged_at_end_row += dvpos;
13711 /* If scrolling up, there may be some lines to display at the end of
13712 the window. */
13713 last_text_row_at_end = NULL;
13714 if (dy < 0)
13716 /* Scrolling up can leave for example a partially visible line
13717 at the end of the window to be redisplayed. */
13718 /* Set last_row to the glyph row in the current matrix where the
13719 window end line is found. It has been moved up or down in
13720 the matrix by dvpos. */
13721 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
13722 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
13724 /* If last_row is the window end line, it should display text. */
13725 xassert (last_row->displays_text_p);
13727 /* If window end line was partially visible before, begin
13728 displaying at that line. Otherwise begin displaying with the
13729 line following it. */
13730 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
13732 init_to_row_start (&it, w, last_row);
13733 it.vpos = last_vpos;
13734 it.current_y = last_row->y;
13736 else
13738 init_to_row_end (&it, w, last_row);
13739 it.vpos = 1 + last_vpos;
13740 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
13741 ++last_row;
13744 /* We may start in a continuation line. If so, we have to
13745 get the right continuation_lines_width and current_x. */
13746 it.continuation_lines_width = last_row->continuation_lines_width;
13747 it.hpos = it.current_x = 0;
13749 /* Display the rest of the lines at the window end. */
13750 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
13751 while (it.current_y < it.last_visible_y
13752 && !fonts_changed_p)
13754 /* Is it always sure that the display agrees with lines in
13755 the current matrix? I don't think so, so we mark rows
13756 displayed invalid in the current matrix by setting their
13757 enabled_p flag to zero. */
13758 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
13759 if (display_line (&it))
13760 last_text_row_at_end = it.glyph_row - 1;
13764 /* Update window_end_pos and window_end_vpos. */
13765 if (first_unchanged_at_end_row
13766 && first_unchanged_at_end_row->y < it.last_visible_y
13767 && !last_text_row_at_end)
13769 /* Window end line if one of the preserved rows from the current
13770 matrix. Set row to the last row displaying text in current
13771 matrix starting at first_unchanged_at_end_row, after
13772 scrolling. */
13773 xassert (first_unchanged_at_end_row->displays_text_p);
13774 row = find_last_row_displaying_text (w->current_matrix, &it,
13775 first_unchanged_at_end_row);
13776 xassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
13778 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13779 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13780 w->window_end_vpos
13781 = make_number (MATRIX_ROW_VPOS (row, w->current_matrix));
13782 xassert (w->window_end_bytepos >= 0);
13783 IF_DEBUG (debug_method_add (w, "A"));
13785 else if (last_text_row_at_end)
13787 w->window_end_pos
13788 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end));
13789 w->window_end_bytepos
13790 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
13791 w->window_end_vpos
13792 = make_number (MATRIX_ROW_VPOS (last_text_row_at_end, desired_matrix));
13793 xassert (w->window_end_bytepos >= 0);
13794 IF_DEBUG (debug_method_add (w, "B"));
13796 else if (last_text_row)
13798 /* We have displayed either to the end of the window or at the
13799 end of the window, i.e. the last row with text is to be found
13800 in the desired matrix. */
13801 w->window_end_pos
13802 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
13803 w->window_end_bytepos
13804 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
13805 w->window_end_vpos
13806 = make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix));
13807 xassert (w->window_end_bytepos >= 0);
13809 else if (first_unchanged_at_end_row == NULL
13810 && last_text_row == NULL
13811 && last_text_row_at_end == NULL)
13813 /* Displayed to end of window, but no line containing text was
13814 displayed. Lines were deleted at the end of the window. */
13815 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
13816 int vpos = XFASTINT (w->window_end_vpos);
13817 struct glyph_row *current_row = current_matrix->rows + vpos;
13818 struct glyph_row *desired_row = desired_matrix->rows + vpos;
13820 for (row = NULL;
13821 row == NULL && vpos >= first_vpos;
13822 --vpos, --current_row, --desired_row)
13824 if (desired_row->enabled_p)
13826 if (desired_row->displays_text_p)
13827 row = desired_row;
13829 else if (current_row->displays_text_p)
13830 row = current_row;
13833 xassert (row != NULL);
13834 w->window_end_vpos = make_number (vpos + 1);
13835 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13836 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13837 xassert (w->window_end_bytepos >= 0);
13838 IF_DEBUG (debug_method_add (w, "C"));
13840 else
13841 abort ();
13843 #if 0 /* This leads to problems, for instance when the cursor is
13844 at ZV, and the cursor line displays no text. */
13845 /* Disable rows below what's displayed in the window. This makes
13846 debugging easier. */
13847 enable_glyph_matrix_rows (current_matrix,
13848 XFASTINT (w->window_end_vpos) + 1,
13849 bottom_vpos, 0);
13850 #endif
13852 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
13853 debug_end_vpos = XFASTINT (w->window_end_vpos));
13855 /* Record that display has not been completed. */
13856 w->window_end_valid = Qnil;
13857 w->desired_matrix->no_scrolling_p = 1;
13858 return 3;
13860 #undef GIVE_UP
13865 /***********************************************************************
13866 More debugging support
13867 ***********************************************************************/
13869 #if GLYPH_DEBUG
13871 void dump_glyph_row P_ ((struct glyph_row *, int, int));
13872 void dump_glyph_matrix P_ ((struct glyph_matrix *, int));
13873 void dump_glyph P_ ((struct glyph_row *, struct glyph *, int));
13876 /* Dump the contents of glyph matrix MATRIX on stderr.
13878 GLYPHS 0 means don't show glyph contents.
13879 GLYPHS 1 means show glyphs in short form
13880 GLYPHS > 1 means show glyphs in long form. */
13882 void
13883 dump_glyph_matrix (matrix, glyphs)
13884 struct glyph_matrix *matrix;
13885 int glyphs;
13887 int i;
13888 for (i = 0; i < matrix->nrows; ++i)
13889 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
13893 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
13894 the glyph row and area where the glyph comes from. */
13896 void
13897 dump_glyph (row, glyph, area)
13898 struct glyph_row *row;
13899 struct glyph *glyph;
13900 int area;
13902 if (glyph->type == CHAR_GLYPH)
13904 fprintf (stderr,
13905 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13906 glyph - row->glyphs[TEXT_AREA],
13907 'C',
13908 glyph->charpos,
13909 (BUFFERP (glyph->object)
13910 ? 'B'
13911 : (STRINGP (glyph->object)
13912 ? 'S'
13913 : '-')),
13914 glyph->pixel_width,
13915 glyph->u.ch,
13916 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
13917 ? glyph->u.ch
13918 : '.'),
13919 glyph->face_id,
13920 glyph->left_box_line_p,
13921 glyph->right_box_line_p);
13923 else if (glyph->type == STRETCH_GLYPH)
13925 fprintf (stderr,
13926 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13927 glyph - row->glyphs[TEXT_AREA],
13928 'S',
13929 glyph->charpos,
13930 (BUFFERP (glyph->object)
13931 ? 'B'
13932 : (STRINGP (glyph->object)
13933 ? 'S'
13934 : '-')),
13935 glyph->pixel_width,
13937 '.',
13938 glyph->face_id,
13939 glyph->left_box_line_p,
13940 glyph->right_box_line_p);
13942 else if (glyph->type == IMAGE_GLYPH)
13944 fprintf (stderr,
13945 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13946 glyph - row->glyphs[TEXT_AREA],
13947 'I',
13948 glyph->charpos,
13949 (BUFFERP (glyph->object)
13950 ? 'B'
13951 : (STRINGP (glyph->object)
13952 ? 'S'
13953 : '-')),
13954 glyph->pixel_width,
13955 glyph->u.img_id,
13956 '.',
13957 glyph->face_id,
13958 glyph->left_box_line_p,
13959 glyph->right_box_line_p);
13964 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
13965 GLYPHS 0 means don't show glyph contents.
13966 GLYPHS 1 means show glyphs in short form
13967 GLYPHS > 1 means show glyphs in long form. */
13969 void
13970 dump_glyph_row (row, vpos, glyphs)
13971 struct glyph_row *row;
13972 int vpos, glyphs;
13974 if (glyphs != 1)
13976 fprintf (stderr, "Row Start End Used oEI><O\\CTZFesm X Y W H V A P\n");
13977 fprintf (stderr, "=======================================================================\n");
13979 fprintf (stderr, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d%1.1d\
13980 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
13981 vpos,
13982 MATRIX_ROW_START_CHARPOS (row),
13983 MATRIX_ROW_END_CHARPOS (row),
13984 row->used[TEXT_AREA],
13985 row->contains_overlapping_glyphs_p,
13986 row->enabled_p,
13987 row->truncated_on_left_p,
13988 row->truncated_on_right_p,
13989 row->overlay_arrow_p,
13990 row->continued_p,
13991 MATRIX_ROW_CONTINUATION_LINE_P (row),
13992 row->displays_text_p,
13993 row->ends_at_zv_p,
13994 row->fill_line_p,
13995 row->ends_in_middle_of_char_p,
13996 row->starts_in_middle_of_char_p,
13997 row->mouse_face_p,
13998 row->x,
13999 row->y,
14000 row->pixel_width,
14001 row->height,
14002 row->visible_height,
14003 row->ascent,
14004 row->phys_ascent);
14005 fprintf (stderr, "%9d %5d\t%5d\n", row->start.overlay_string_index,
14006 row->end.overlay_string_index,
14007 row->continuation_lines_width);
14008 fprintf (stderr, "%9d %5d\n",
14009 CHARPOS (row->start.string_pos),
14010 CHARPOS (row->end.string_pos));
14011 fprintf (stderr, "%9d %5d\n", row->start.dpvec_index,
14012 row->end.dpvec_index);
14015 if (glyphs > 1)
14017 int area;
14019 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
14021 struct glyph *glyph = row->glyphs[area];
14022 struct glyph *glyph_end = glyph + row->used[area];
14024 /* Glyph for a line end in text. */
14025 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
14026 ++glyph_end;
14028 if (glyph < glyph_end)
14029 fprintf (stderr, " Glyph Type Pos O W Code C Face LR\n");
14031 for (; glyph < glyph_end; ++glyph)
14032 dump_glyph (row, glyph, area);
14035 else if (glyphs == 1)
14037 int area;
14039 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
14041 char *s = (char *) alloca (row->used[area] + 1);
14042 int i;
14044 for (i = 0; i < row->used[area]; ++i)
14046 struct glyph *glyph = row->glyphs[area] + i;
14047 if (glyph->type == CHAR_GLYPH
14048 && glyph->u.ch < 0x80
14049 && glyph->u.ch >= ' ')
14050 s[i] = glyph->u.ch;
14051 else
14052 s[i] = '.';
14055 s[i] = '\0';
14056 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
14062 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
14063 Sdump_glyph_matrix, 0, 1, "p",
14064 doc: /* Dump the current matrix of the selected window to stderr.
14065 Shows contents of glyph row structures. With non-nil
14066 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
14067 glyphs in short form, otherwise show glyphs in long form. */)
14068 (glyphs)
14069 Lisp_Object glyphs;
14071 struct window *w = XWINDOW (selected_window);
14072 struct buffer *buffer = XBUFFER (w->buffer);
14074 fprintf (stderr, "PT = %d, BEGV = %d. ZV = %d\n",
14075 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
14076 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
14077 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
14078 fprintf (stderr, "=============================================\n");
14079 dump_glyph_matrix (w->current_matrix,
14080 NILP (glyphs) ? 0 : XINT (glyphs));
14081 return Qnil;
14085 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
14086 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
14089 struct frame *f = XFRAME (selected_frame);
14090 dump_glyph_matrix (f->current_matrix, 1);
14091 return Qnil;
14095 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
14096 doc: /* Dump glyph row ROW to stderr.
14097 GLYPH 0 means don't dump glyphs.
14098 GLYPH 1 means dump glyphs in short form.
14099 GLYPH > 1 or omitted means dump glyphs in long form. */)
14100 (row, glyphs)
14101 Lisp_Object row, glyphs;
14103 struct glyph_matrix *matrix;
14104 int vpos;
14106 CHECK_NUMBER (row);
14107 matrix = XWINDOW (selected_window)->current_matrix;
14108 vpos = XINT (row);
14109 if (vpos >= 0 && vpos < matrix->nrows)
14110 dump_glyph_row (MATRIX_ROW (matrix, vpos),
14111 vpos,
14112 INTEGERP (glyphs) ? XINT (glyphs) : 2);
14113 return Qnil;
14117 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
14118 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
14119 GLYPH 0 means don't dump glyphs.
14120 GLYPH 1 means dump glyphs in short form.
14121 GLYPH > 1 or omitted means dump glyphs in long form. */)
14122 (row, glyphs)
14123 Lisp_Object row, glyphs;
14125 struct frame *sf = SELECTED_FRAME ();
14126 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
14127 int vpos;
14129 CHECK_NUMBER (row);
14130 vpos = XINT (row);
14131 if (vpos >= 0 && vpos < m->nrows)
14132 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
14133 INTEGERP (glyphs) ? XINT (glyphs) : 2);
14134 return Qnil;
14138 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
14139 doc: /* Toggle tracing of redisplay.
14140 With ARG, turn tracing on if and only if ARG is positive. */)
14141 (arg)
14142 Lisp_Object arg;
14144 if (NILP (arg))
14145 trace_redisplay_p = !trace_redisplay_p;
14146 else
14148 arg = Fprefix_numeric_value (arg);
14149 trace_redisplay_p = XINT (arg) > 0;
14152 return Qnil;
14156 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
14157 doc: /* Like `format', but print result to stderr.
14158 usage: (trace-to-stderr STRING &rest OBJECTS) */)
14159 (nargs, args)
14160 int nargs;
14161 Lisp_Object *args;
14163 Lisp_Object s = Fformat (nargs, args);
14164 fprintf (stderr, "%s", SDATA (s));
14165 return Qnil;
14168 #endif /* GLYPH_DEBUG */
14172 /***********************************************************************
14173 Building Desired Matrix Rows
14174 ***********************************************************************/
14176 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
14177 Used for non-window-redisplay windows, and for windows w/o left fringe. */
14179 static struct glyph_row *
14180 get_overlay_arrow_glyph_row (w, overlay_arrow_string)
14181 struct window *w;
14182 Lisp_Object overlay_arrow_string;
14184 struct frame *f = XFRAME (WINDOW_FRAME (w));
14185 struct buffer *buffer = XBUFFER (w->buffer);
14186 struct buffer *old = current_buffer;
14187 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
14188 int arrow_len = SCHARS (overlay_arrow_string);
14189 const unsigned char *arrow_end = arrow_string + arrow_len;
14190 const unsigned char *p;
14191 struct it it;
14192 int multibyte_p;
14193 int n_glyphs_before;
14195 set_buffer_temp (buffer);
14196 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
14197 it.glyph_row->used[TEXT_AREA] = 0;
14198 SET_TEXT_POS (it.position, 0, 0);
14200 multibyte_p = !NILP (buffer->enable_multibyte_characters);
14201 p = arrow_string;
14202 while (p < arrow_end)
14204 Lisp_Object face, ilisp;
14206 /* Get the next character. */
14207 if (multibyte_p)
14208 it.c = string_char_and_length (p, arrow_len, &it.len);
14209 else
14210 it.c = *p, it.len = 1;
14211 p += it.len;
14213 /* Get its face. */
14214 ilisp = make_number (p - arrow_string);
14215 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
14216 it.face_id = compute_char_face (f, it.c, face);
14218 /* Compute its width, get its glyphs. */
14219 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
14220 SET_TEXT_POS (it.position, -1, -1);
14221 PRODUCE_GLYPHS (&it);
14223 /* If this character doesn't fit any more in the line, we have
14224 to remove some glyphs. */
14225 if (it.current_x > it.last_visible_x)
14227 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
14228 break;
14232 set_buffer_temp (old);
14233 return it.glyph_row;
14237 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
14238 glyphs are only inserted for terminal frames since we can't really
14239 win with truncation glyphs when partially visible glyphs are
14240 involved. Which glyphs to insert is determined by
14241 produce_special_glyphs. */
14243 static void
14244 insert_left_trunc_glyphs (it)
14245 struct it *it;
14247 struct it truncate_it;
14248 struct glyph *from, *end, *to, *toend;
14250 xassert (!FRAME_WINDOW_P (it->f));
14252 /* Get the truncation glyphs. */
14253 truncate_it = *it;
14254 truncate_it.current_x = 0;
14255 truncate_it.face_id = DEFAULT_FACE_ID;
14256 truncate_it.glyph_row = &scratch_glyph_row;
14257 truncate_it.glyph_row->used[TEXT_AREA] = 0;
14258 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
14259 truncate_it.object = make_number (0);
14260 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
14262 /* Overwrite glyphs from IT with truncation glyphs. */
14263 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
14264 end = from + truncate_it.glyph_row->used[TEXT_AREA];
14265 to = it->glyph_row->glyphs[TEXT_AREA];
14266 toend = to + it->glyph_row->used[TEXT_AREA];
14268 while (from < end)
14269 *to++ = *from++;
14271 /* There may be padding glyphs left over. Overwrite them too. */
14272 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
14274 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
14275 while (from < end)
14276 *to++ = *from++;
14279 if (to > toend)
14280 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
14284 /* Compute the pixel height and width of IT->glyph_row.
14286 Most of the time, ascent and height of a display line will be equal
14287 to the max_ascent and max_height values of the display iterator
14288 structure. This is not the case if
14290 1. We hit ZV without displaying anything. In this case, max_ascent
14291 and max_height will be zero.
14293 2. We have some glyphs that don't contribute to the line height.
14294 (The glyph row flag contributes_to_line_height_p is for future
14295 pixmap extensions).
14297 The first case is easily covered by using default values because in
14298 these cases, the line height does not really matter, except that it
14299 must not be zero. */
14301 static void
14302 compute_line_metrics (it)
14303 struct it *it;
14305 struct glyph_row *row = it->glyph_row;
14306 int area, i;
14308 if (FRAME_WINDOW_P (it->f))
14310 int i, min_y, max_y;
14312 /* The line may consist of one space only, that was added to
14313 place the cursor on it. If so, the row's height hasn't been
14314 computed yet. */
14315 if (row->height == 0)
14317 if (it->max_ascent + it->max_descent == 0)
14318 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
14319 row->ascent = it->max_ascent;
14320 row->height = it->max_ascent + it->max_descent;
14321 row->phys_ascent = it->max_phys_ascent;
14322 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
14323 row->extra_line_spacing = it->max_extra_line_spacing;
14326 /* Compute the width of this line. */
14327 row->pixel_width = row->x;
14328 for (i = 0; i < row->used[TEXT_AREA]; ++i)
14329 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
14331 xassert (row->pixel_width >= 0);
14332 xassert (row->ascent >= 0 && row->height > 0);
14334 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
14335 || MATRIX_ROW_OVERLAPS_PRED_P (row));
14337 /* If first line's physical ascent is larger than its logical
14338 ascent, use the physical ascent, and make the row taller.
14339 This makes accented characters fully visible. */
14340 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
14341 && row->phys_ascent > row->ascent)
14343 row->height += row->phys_ascent - row->ascent;
14344 row->ascent = row->phys_ascent;
14347 /* Compute how much of the line is visible. */
14348 row->visible_height = row->height;
14350 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
14351 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
14353 if (row->y < min_y)
14354 row->visible_height -= min_y - row->y;
14355 if (row->y + row->height > max_y)
14356 row->visible_height -= row->y + row->height - max_y;
14358 else
14360 row->pixel_width = row->used[TEXT_AREA];
14361 if (row->continued_p)
14362 row->pixel_width -= it->continuation_pixel_width;
14363 else if (row->truncated_on_right_p)
14364 row->pixel_width -= it->truncation_pixel_width;
14365 row->ascent = row->phys_ascent = 0;
14366 row->height = row->phys_height = row->visible_height = 1;
14367 row->extra_line_spacing = 0;
14370 /* Compute a hash code for this row. */
14371 row->hash = 0;
14372 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
14373 for (i = 0; i < row->used[area]; ++i)
14374 row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff)
14375 + row->glyphs[area][i].u.val
14376 + row->glyphs[area][i].face_id
14377 + row->glyphs[area][i].padding_p
14378 + (row->glyphs[area][i].type << 2));
14380 it->max_ascent = it->max_descent = 0;
14381 it->max_phys_ascent = it->max_phys_descent = 0;
14385 /* Append one space to the glyph row of iterator IT if doing a
14386 window-based redisplay. The space has the same face as
14387 IT->face_id. Value is non-zero if a space was added.
14389 This function is called to make sure that there is always one glyph
14390 at the end of a glyph row that the cursor can be set on under
14391 window-systems. (If there weren't such a glyph we would not know
14392 how wide and tall a box cursor should be displayed).
14394 At the same time this space let's a nicely handle clearing to the
14395 end of the line if the row ends in italic text. */
14397 static int
14398 append_space_for_newline (it, default_face_p)
14399 struct it *it;
14400 int default_face_p;
14402 if (FRAME_WINDOW_P (it->f))
14404 int n = it->glyph_row->used[TEXT_AREA];
14406 if (it->glyph_row->glyphs[TEXT_AREA] + n
14407 < it->glyph_row->glyphs[1 + TEXT_AREA])
14409 /* Save some values that must not be changed.
14410 Must save IT->c and IT->len because otherwise
14411 ITERATOR_AT_END_P wouldn't work anymore after
14412 append_space_for_newline has been called. */
14413 enum display_element_type saved_what = it->what;
14414 int saved_c = it->c, saved_len = it->len;
14415 int saved_x = it->current_x;
14416 int saved_face_id = it->face_id;
14417 struct text_pos saved_pos;
14418 Lisp_Object saved_object;
14419 struct face *face;
14421 saved_object = it->object;
14422 saved_pos = it->position;
14424 it->what = IT_CHARACTER;
14425 bzero (&it->position, sizeof it->position);
14426 it->object = make_number (0);
14427 it->c = ' ';
14428 it->len = 1;
14430 if (default_face_p)
14431 it->face_id = DEFAULT_FACE_ID;
14432 else if (it->face_before_selective_p)
14433 it->face_id = it->saved_face_id;
14434 face = FACE_FROM_ID (it->f, it->face_id);
14435 it->face_id = FACE_FOR_CHAR (it->f, face, 0);
14437 PRODUCE_GLYPHS (it);
14439 it->override_ascent = -1;
14440 it->constrain_row_ascent_descent_p = 0;
14441 it->current_x = saved_x;
14442 it->object = saved_object;
14443 it->position = saved_pos;
14444 it->what = saved_what;
14445 it->face_id = saved_face_id;
14446 it->len = saved_len;
14447 it->c = saved_c;
14448 return 1;
14452 return 0;
14456 /* Extend the face of the last glyph in the text area of IT->glyph_row
14457 to the end of the display line. Called from display_line.
14458 If the glyph row is empty, add a space glyph to it so that we
14459 know the face to draw. Set the glyph row flag fill_line_p. */
14461 static void
14462 extend_face_to_end_of_line (it)
14463 struct it *it;
14465 struct face *face;
14466 struct frame *f = it->f;
14468 /* If line is already filled, do nothing. */
14469 if (it->current_x >= it->last_visible_x)
14470 return;
14472 /* Face extension extends the background and box of IT->face_id
14473 to the end of the line. If the background equals the background
14474 of the frame, we don't have to do anything. */
14475 if (it->face_before_selective_p)
14476 face = FACE_FROM_ID (it->f, it->saved_face_id);
14477 else
14478 face = FACE_FROM_ID (f, it->face_id);
14480 if (FRAME_WINDOW_P (f)
14481 && face->box == FACE_NO_BOX
14482 && face->background == FRAME_BACKGROUND_PIXEL (f)
14483 && !face->stipple)
14484 return;
14486 /* Set the glyph row flag indicating that the face of the last glyph
14487 in the text area has to be drawn to the end of the text area. */
14488 it->glyph_row->fill_line_p = 1;
14490 /* If current character of IT is not ASCII, make sure we have the
14491 ASCII face. This will be automatically undone the next time
14492 get_next_display_element returns a multibyte character. Note
14493 that the character will always be single byte in unibyte text. */
14494 if (!SINGLE_BYTE_CHAR_P (it->c))
14496 it->face_id = FACE_FOR_CHAR (f, face, 0);
14499 if (FRAME_WINDOW_P (f))
14501 /* If the row is empty, add a space with the current face of IT,
14502 so that we know which face to draw. */
14503 if (it->glyph_row->used[TEXT_AREA] == 0)
14505 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
14506 it->glyph_row->glyphs[TEXT_AREA][0].face_id = it->face_id;
14507 it->glyph_row->used[TEXT_AREA] = 1;
14510 else
14512 /* Save some values that must not be changed. */
14513 int saved_x = it->current_x;
14514 struct text_pos saved_pos;
14515 Lisp_Object saved_object;
14516 enum display_element_type saved_what = it->what;
14517 int saved_face_id = it->face_id;
14519 saved_object = it->object;
14520 saved_pos = it->position;
14522 it->what = IT_CHARACTER;
14523 bzero (&it->position, sizeof it->position);
14524 it->object = make_number (0);
14525 it->c = ' ';
14526 it->len = 1;
14527 it->face_id = face->id;
14529 PRODUCE_GLYPHS (it);
14531 while (it->current_x <= it->last_visible_x)
14532 PRODUCE_GLYPHS (it);
14534 /* Don't count these blanks really. It would let us insert a left
14535 truncation glyph below and make us set the cursor on them, maybe. */
14536 it->current_x = saved_x;
14537 it->object = saved_object;
14538 it->position = saved_pos;
14539 it->what = saved_what;
14540 it->face_id = saved_face_id;
14545 /* Value is non-zero if text starting at CHARPOS in current_buffer is
14546 trailing whitespace. */
14548 static int
14549 trailing_whitespace_p (charpos)
14550 int charpos;
14552 int bytepos = CHAR_TO_BYTE (charpos);
14553 int c = 0;
14555 while (bytepos < ZV_BYTE
14556 && (c = FETCH_CHAR (bytepos),
14557 c == ' ' || c == '\t'))
14558 ++bytepos;
14560 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
14562 if (bytepos != PT_BYTE)
14563 return 1;
14565 return 0;
14569 /* Highlight trailing whitespace, if any, in ROW. */
14571 void
14572 highlight_trailing_whitespace (f, row)
14573 struct frame *f;
14574 struct glyph_row *row;
14576 int used = row->used[TEXT_AREA];
14578 if (used)
14580 struct glyph *start = row->glyphs[TEXT_AREA];
14581 struct glyph *glyph = start + used - 1;
14583 /* Skip over glyphs inserted to display the cursor at the
14584 end of a line, for extending the face of the last glyph
14585 to the end of the line on terminals, and for truncation
14586 and continuation glyphs. */
14587 while (glyph >= start
14588 && glyph->type == CHAR_GLYPH
14589 && INTEGERP (glyph->object))
14590 --glyph;
14592 /* If last glyph is a space or stretch, and it's trailing
14593 whitespace, set the face of all trailing whitespace glyphs in
14594 IT->glyph_row to `trailing-whitespace'. */
14595 if (glyph >= start
14596 && BUFFERP (glyph->object)
14597 && (glyph->type == STRETCH_GLYPH
14598 || (glyph->type == CHAR_GLYPH
14599 && glyph->u.ch == ' '))
14600 && trailing_whitespace_p (glyph->charpos))
14602 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0, 0);
14603 if (face_id < 0)
14604 return;
14606 while (glyph >= start
14607 && BUFFERP (glyph->object)
14608 && (glyph->type == STRETCH_GLYPH
14609 || (glyph->type == CHAR_GLYPH
14610 && glyph->u.ch == ' ')))
14611 (glyph--)->face_id = face_id;
14617 /* Value is non-zero if glyph row ROW in window W should be
14618 used to hold the cursor. */
14620 static int
14621 cursor_row_p (w, row)
14622 struct window *w;
14623 struct glyph_row *row;
14625 int cursor_row_p = 1;
14627 if (PT == MATRIX_ROW_END_CHARPOS (row))
14629 /* If the row ends with a newline from a string, we don't want
14630 the cursor there (if the row is continued it doesn't end in a
14631 newline). */
14632 if (CHARPOS (row->end.string_pos) >= 0)
14633 cursor_row_p = row->continued_p;
14634 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
14636 /* If the row ends in middle of a real character,
14637 and the line is continued, we want the cursor here.
14638 That's because MATRIX_ROW_END_CHARPOS would equal
14639 PT if PT is before the character. */
14640 if (!row->ends_in_ellipsis_p)
14641 cursor_row_p = row->continued_p;
14642 else
14643 /* If the row ends in an ellipsis, then
14644 MATRIX_ROW_END_CHARPOS will equal point after the invisible text.
14645 We want that position to be displayed after the ellipsis. */
14646 cursor_row_p = 0;
14648 /* If the row ends at ZV, display the cursor at the end of that
14649 row instead of at the start of the row below. */
14650 else if (row->ends_at_zv_p)
14651 cursor_row_p = 1;
14652 else
14653 cursor_row_p = 0;
14656 return cursor_row_p;
14660 /* Construct the glyph row IT->glyph_row in the desired matrix of
14661 IT->w from text at the current position of IT. See dispextern.h
14662 for an overview of struct it. Value is non-zero if
14663 IT->glyph_row displays text, as opposed to a line displaying ZV
14664 only. */
14666 static int
14667 display_line (it)
14668 struct it *it;
14670 struct glyph_row *row = it->glyph_row;
14671 int overlay_arrow_bitmap;
14672 Lisp_Object overlay_arrow_string;
14674 /* We always start displaying at hpos zero even if hscrolled. */
14675 xassert (it->hpos == 0 && it->current_x == 0);
14677 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
14678 >= it->w->desired_matrix->nrows)
14680 it->w->nrows_scale_factor++;
14681 fonts_changed_p = 1;
14682 return 0;
14685 /* Is IT->w showing the region? */
14686 it->w->region_showing = it->region_beg_charpos > 0 ? Qt : Qnil;
14688 /* Clear the result glyph row and enable it. */
14689 prepare_desired_row (row);
14691 row->y = it->current_y;
14692 row->start = it->start;
14693 row->continuation_lines_width = it->continuation_lines_width;
14694 row->displays_text_p = 1;
14695 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
14696 it->starts_in_middle_of_char_p = 0;
14698 /* Arrange the overlays nicely for our purposes. Usually, we call
14699 display_line on only one line at a time, in which case this
14700 can't really hurt too much, or we call it on lines which appear
14701 one after another in the buffer, in which case all calls to
14702 recenter_overlay_lists but the first will be pretty cheap. */
14703 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
14705 /* Move over display elements that are not visible because we are
14706 hscrolled. This may stop at an x-position < IT->first_visible_x
14707 if the first glyph is partially visible or if we hit a line end. */
14708 if (it->current_x < it->first_visible_x)
14710 move_it_in_display_line_to (it, ZV, it->first_visible_x,
14711 MOVE_TO_POS | MOVE_TO_X);
14714 /* Get the initial row height. This is either the height of the
14715 text hscrolled, if there is any, or zero. */
14716 row->ascent = it->max_ascent;
14717 row->height = it->max_ascent + it->max_descent;
14718 row->phys_ascent = it->max_phys_ascent;
14719 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
14720 row->extra_line_spacing = it->max_extra_line_spacing;
14722 /* Loop generating characters. The loop is left with IT on the next
14723 character to display. */
14724 while (1)
14726 int n_glyphs_before, hpos_before, x_before;
14727 int x, i, nglyphs;
14728 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
14730 /* Retrieve the next thing to display. Value is zero if end of
14731 buffer reached. */
14732 if (!get_next_display_element (it))
14734 /* Maybe add a space at the end of this line that is used to
14735 display the cursor there under X. Set the charpos of the
14736 first glyph of blank lines not corresponding to any text
14737 to -1. */
14738 #ifdef HAVE_WINDOW_SYSTEM
14739 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14740 row->exact_window_width_line_p = 1;
14741 else
14742 #endif /* HAVE_WINDOW_SYSTEM */
14743 if ((append_space_for_newline (it, 1) && row->used[TEXT_AREA] == 1)
14744 || row->used[TEXT_AREA] == 0)
14746 row->glyphs[TEXT_AREA]->charpos = -1;
14747 row->displays_text_p = 0;
14749 if (!NILP (XBUFFER (it->w->buffer)->indicate_empty_lines)
14750 && (!MINI_WINDOW_P (it->w)
14751 || (minibuf_level && EQ (it->window, minibuf_window))))
14752 row->indicate_empty_line_p = 1;
14755 it->continuation_lines_width = 0;
14756 row->ends_at_zv_p = 1;
14757 break;
14760 /* Now, get the metrics of what we want to display. This also
14761 generates glyphs in `row' (which is IT->glyph_row). */
14762 n_glyphs_before = row->used[TEXT_AREA];
14763 x = it->current_x;
14765 /* Remember the line height so far in case the next element doesn't
14766 fit on the line. */
14767 if (!it->truncate_lines_p)
14769 ascent = it->max_ascent;
14770 descent = it->max_descent;
14771 phys_ascent = it->max_phys_ascent;
14772 phys_descent = it->max_phys_descent;
14775 PRODUCE_GLYPHS (it);
14777 /* If this display element was in marginal areas, continue with
14778 the next one. */
14779 if (it->area != TEXT_AREA)
14781 row->ascent = max (row->ascent, it->max_ascent);
14782 row->height = max (row->height, it->max_ascent + it->max_descent);
14783 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14784 row->phys_height = max (row->phys_height,
14785 it->max_phys_ascent + it->max_phys_descent);
14786 row->extra_line_spacing = max (row->extra_line_spacing,
14787 it->max_extra_line_spacing);
14788 set_iterator_to_next (it, 1);
14789 continue;
14792 /* Does the display element fit on the line? If we truncate
14793 lines, we should draw past the right edge of the window. If
14794 we don't truncate, we want to stop so that we can display the
14795 continuation glyph before the right margin. If lines are
14796 continued, there are two possible strategies for characters
14797 resulting in more than 1 glyph (e.g. tabs): Display as many
14798 glyphs as possible in this line and leave the rest for the
14799 continuation line, or display the whole element in the next
14800 line. Original redisplay did the former, so we do it also. */
14801 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
14802 hpos_before = it->hpos;
14803 x_before = x;
14805 if (/* Not a newline. */
14806 nglyphs > 0
14807 /* Glyphs produced fit entirely in the line. */
14808 && it->current_x < it->last_visible_x)
14810 it->hpos += nglyphs;
14811 row->ascent = max (row->ascent, it->max_ascent);
14812 row->height = max (row->height, it->max_ascent + it->max_descent);
14813 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14814 row->phys_height = max (row->phys_height,
14815 it->max_phys_ascent + it->max_phys_descent);
14816 row->extra_line_spacing = max (row->extra_line_spacing,
14817 it->max_extra_line_spacing);
14818 if (it->current_x - it->pixel_width < it->first_visible_x)
14819 row->x = x - it->first_visible_x;
14821 else
14823 int new_x;
14824 struct glyph *glyph;
14826 for (i = 0; i < nglyphs; ++i, x = new_x)
14828 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
14829 new_x = x + glyph->pixel_width;
14831 if (/* Lines are continued. */
14832 !it->truncate_lines_p
14833 && (/* Glyph doesn't fit on the line. */
14834 new_x > it->last_visible_x
14835 /* Or it fits exactly on a window system frame. */
14836 || (new_x == it->last_visible_x
14837 && FRAME_WINDOW_P (it->f))))
14839 /* End of a continued line. */
14841 if (it->hpos == 0
14842 || (new_x == it->last_visible_x
14843 && FRAME_WINDOW_P (it->f)))
14845 /* Current glyph is the only one on the line or
14846 fits exactly on the line. We must continue
14847 the line because we can't draw the cursor
14848 after the glyph. */
14849 row->continued_p = 1;
14850 it->current_x = new_x;
14851 it->continuation_lines_width += new_x;
14852 ++it->hpos;
14853 if (i == nglyphs - 1)
14855 set_iterator_to_next (it, 1);
14856 #ifdef HAVE_WINDOW_SYSTEM
14857 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14859 if (!get_next_display_element (it))
14861 row->exact_window_width_line_p = 1;
14862 it->continuation_lines_width = 0;
14863 row->continued_p = 0;
14864 row->ends_at_zv_p = 1;
14866 else if (ITERATOR_AT_END_OF_LINE_P (it))
14868 row->continued_p = 0;
14869 row->exact_window_width_line_p = 1;
14872 #endif /* HAVE_WINDOW_SYSTEM */
14875 else if (CHAR_GLYPH_PADDING_P (*glyph)
14876 && !FRAME_WINDOW_P (it->f))
14878 /* A padding glyph that doesn't fit on this line.
14879 This means the whole character doesn't fit
14880 on the line. */
14881 row->used[TEXT_AREA] = n_glyphs_before;
14883 /* Fill the rest of the row with continuation
14884 glyphs like in 20.x. */
14885 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
14886 < row->glyphs[1 + TEXT_AREA])
14887 produce_special_glyphs (it, IT_CONTINUATION);
14889 row->continued_p = 1;
14890 it->current_x = x_before;
14891 it->continuation_lines_width += x_before;
14893 /* Restore the height to what it was before the
14894 element not fitting on the line. */
14895 it->max_ascent = ascent;
14896 it->max_descent = descent;
14897 it->max_phys_ascent = phys_ascent;
14898 it->max_phys_descent = phys_descent;
14900 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
14902 /* A TAB that extends past the right edge of the
14903 window. This produces a single glyph on
14904 window system frames. We leave the glyph in
14905 this row and let it fill the row, but don't
14906 consume the TAB. */
14907 it->continuation_lines_width += it->last_visible_x;
14908 row->ends_in_middle_of_char_p = 1;
14909 row->continued_p = 1;
14910 glyph->pixel_width = it->last_visible_x - x;
14911 it->starts_in_middle_of_char_p = 1;
14913 else
14915 /* Something other than a TAB that draws past
14916 the right edge of the window. Restore
14917 positions to values before the element. */
14918 row->used[TEXT_AREA] = n_glyphs_before + i;
14920 /* Display continuation glyphs. */
14921 if (!FRAME_WINDOW_P (it->f))
14922 produce_special_glyphs (it, IT_CONTINUATION);
14923 row->continued_p = 1;
14925 it->continuation_lines_width += x;
14927 if (nglyphs > 1 && i > 0)
14929 row->ends_in_middle_of_char_p = 1;
14930 it->starts_in_middle_of_char_p = 1;
14933 /* Restore the height to what it was before the
14934 element not fitting on the line. */
14935 it->max_ascent = ascent;
14936 it->max_descent = descent;
14937 it->max_phys_ascent = phys_ascent;
14938 it->max_phys_descent = phys_descent;
14941 break;
14943 else if (new_x > it->first_visible_x)
14945 /* Increment number of glyphs actually displayed. */
14946 ++it->hpos;
14948 if (x < it->first_visible_x)
14949 /* Glyph is partially visible, i.e. row starts at
14950 negative X position. */
14951 row->x = x - it->first_visible_x;
14953 else
14955 /* Glyph is completely off the left margin of the
14956 window. This should not happen because of the
14957 move_it_in_display_line at the start of this
14958 function, unless the text display area of the
14959 window is empty. */
14960 xassert (it->first_visible_x <= it->last_visible_x);
14964 row->ascent = max (row->ascent, it->max_ascent);
14965 row->height = max (row->height, it->max_ascent + it->max_descent);
14966 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14967 row->phys_height = max (row->phys_height,
14968 it->max_phys_ascent + it->max_phys_descent);
14969 row->extra_line_spacing = max (row->extra_line_spacing,
14970 it->max_extra_line_spacing);
14972 /* End of this display line if row is continued. */
14973 if (row->continued_p || row->ends_at_zv_p)
14974 break;
14977 at_end_of_line:
14978 /* Is this a line end? If yes, we're also done, after making
14979 sure that a non-default face is extended up to the right
14980 margin of the window. */
14981 if (ITERATOR_AT_END_OF_LINE_P (it))
14983 int used_before = row->used[TEXT_AREA];
14985 row->ends_in_newline_from_string_p = STRINGP (it->object);
14987 #ifdef HAVE_WINDOW_SYSTEM
14988 /* Add a space at the end of the line that is used to
14989 display the cursor there. */
14990 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14991 append_space_for_newline (it, 0);
14992 #endif /* HAVE_WINDOW_SYSTEM */
14994 /* Extend the face to the end of the line. */
14995 extend_face_to_end_of_line (it);
14997 /* Make sure we have the position. */
14998 if (used_before == 0)
14999 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
15001 /* Consume the line end. This skips over invisible lines. */
15002 set_iterator_to_next (it, 1);
15003 it->continuation_lines_width = 0;
15004 break;
15007 /* Proceed with next display element. Note that this skips
15008 over lines invisible because of selective display. */
15009 set_iterator_to_next (it, 1);
15011 /* If we truncate lines, we are done when the last displayed
15012 glyphs reach past the right margin of the window. */
15013 if (it->truncate_lines_p
15014 && (FRAME_WINDOW_P (it->f)
15015 ? (it->current_x >= it->last_visible_x)
15016 : (it->current_x > it->last_visible_x)))
15018 /* Maybe add truncation glyphs. */
15019 if (!FRAME_WINDOW_P (it->f))
15021 int i, n;
15023 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
15024 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
15025 break;
15027 for (n = row->used[TEXT_AREA]; i < n; ++i)
15029 row->used[TEXT_AREA] = i;
15030 produce_special_glyphs (it, IT_TRUNCATION);
15033 #ifdef HAVE_WINDOW_SYSTEM
15034 else
15036 /* Don't truncate if we can overflow newline into fringe. */
15037 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
15039 if (!get_next_display_element (it))
15041 it->continuation_lines_width = 0;
15042 row->ends_at_zv_p = 1;
15043 row->exact_window_width_line_p = 1;
15044 break;
15046 if (ITERATOR_AT_END_OF_LINE_P (it))
15048 row->exact_window_width_line_p = 1;
15049 goto at_end_of_line;
15053 #endif /* HAVE_WINDOW_SYSTEM */
15055 row->truncated_on_right_p = 1;
15056 it->continuation_lines_width = 0;
15057 reseat_at_next_visible_line_start (it, 0);
15058 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
15059 it->hpos = hpos_before;
15060 it->current_x = x_before;
15061 break;
15065 /* If line is not empty and hscrolled, maybe insert truncation glyphs
15066 at the left window margin. */
15067 if (it->first_visible_x
15068 && IT_CHARPOS (*it) != MATRIX_ROW_START_CHARPOS (row))
15070 if (!FRAME_WINDOW_P (it->f))
15071 insert_left_trunc_glyphs (it);
15072 row->truncated_on_left_p = 1;
15075 /* If the start of this line is the overlay arrow-position, then
15076 mark this glyph row as the one containing the overlay arrow.
15077 This is clearly a mess with variable size fonts. It would be
15078 better to let it be displayed like cursors under X. */
15079 if (! overlay_arrow_seen
15080 && (overlay_arrow_string
15081 = overlay_arrow_at_row (it, row, &overlay_arrow_bitmap),
15082 !NILP (overlay_arrow_string)))
15084 /* Overlay arrow in window redisplay is a fringe bitmap. */
15085 if (STRINGP (overlay_arrow_string))
15087 struct glyph_row *arrow_row
15088 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
15089 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
15090 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
15091 struct glyph *p = row->glyphs[TEXT_AREA];
15092 struct glyph *p2, *end;
15094 /* Copy the arrow glyphs. */
15095 while (glyph < arrow_end)
15096 *p++ = *glyph++;
15098 /* Throw away padding glyphs. */
15099 p2 = p;
15100 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
15101 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
15102 ++p2;
15103 if (p2 > p)
15105 while (p2 < end)
15106 *p++ = *p2++;
15107 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
15110 else
15112 it->w->overlay_arrow_bitmap = overlay_arrow_bitmap;
15113 row->overlay_arrow_p = 1;
15115 overlay_arrow_seen = 1;
15118 /* Compute pixel dimensions of this line. */
15119 compute_line_metrics (it);
15121 /* Remember the position at which this line ends. */
15122 row->end = it->current;
15124 /* Record whether this row ends inside an ellipsis. */
15125 row->ends_in_ellipsis_p
15126 = (it->method == next_element_from_display_vector
15127 && it->ellipsis_p);
15129 /* Save fringe bitmaps in this row. */
15130 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
15131 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
15132 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
15133 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
15135 it->left_user_fringe_bitmap = 0;
15136 it->left_user_fringe_face_id = 0;
15137 it->right_user_fringe_bitmap = 0;
15138 it->right_user_fringe_face_id = 0;
15140 /* Maybe set the cursor. */
15141 if (it->w->cursor.vpos < 0
15142 && PT >= MATRIX_ROW_START_CHARPOS (row)
15143 && PT <= MATRIX_ROW_END_CHARPOS (row)
15144 && cursor_row_p (it->w, row))
15145 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
15147 /* Highlight trailing whitespace. */
15148 if (!NILP (Vshow_trailing_whitespace))
15149 highlight_trailing_whitespace (it->f, it->glyph_row);
15151 /* Prepare for the next line. This line starts horizontally at (X
15152 HPOS) = (0 0). Vertical positions are incremented. As a
15153 convenience for the caller, IT->glyph_row is set to the next
15154 row to be used. */
15155 it->current_x = it->hpos = 0;
15156 it->current_y += row->height;
15157 ++it->vpos;
15158 ++it->glyph_row;
15159 it->start = it->current;
15160 return row->displays_text_p;
15165 /***********************************************************************
15166 Menu Bar
15167 ***********************************************************************/
15169 /* Redisplay the menu bar in the frame for window W.
15171 The menu bar of X frames that don't have X toolkit support is
15172 displayed in a special window W->frame->menu_bar_window.
15174 The menu bar of terminal frames is treated specially as far as
15175 glyph matrices are concerned. Menu bar lines are not part of
15176 windows, so the update is done directly on the frame matrix rows
15177 for the menu bar. */
15179 static void
15180 display_menu_bar (w)
15181 struct window *w;
15183 struct frame *f = XFRAME (WINDOW_FRAME (w));
15184 struct it it;
15185 Lisp_Object items;
15186 int i;
15188 /* Don't do all this for graphical frames. */
15189 #ifdef HAVE_NTGUI
15190 if (!NILP (Vwindow_system))
15191 return;
15192 #endif
15193 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
15194 if (FRAME_X_P (f))
15195 return;
15196 #endif
15197 #ifdef MAC_OS
15198 if (FRAME_MAC_P (f))
15199 return;
15200 #endif
15202 #ifdef USE_X_TOOLKIT
15203 xassert (!FRAME_WINDOW_P (f));
15204 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
15205 it.first_visible_x = 0;
15206 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
15207 #else /* not USE_X_TOOLKIT */
15208 if (FRAME_WINDOW_P (f))
15210 /* Menu bar lines are displayed in the desired matrix of the
15211 dummy window menu_bar_window. */
15212 struct window *menu_w;
15213 xassert (WINDOWP (f->menu_bar_window));
15214 menu_w = XWINDOW (f->menu_bar_window);
15215 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
15216 MENU_FACE_ID);
15217 it.first_visible_x = 0;
15218 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
15220 else
15222 /* This is a TTY frame, i.e. character hpos/vpos are used as
15223 pixel x/y. */
15224 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
15225 MENU_FACE_ID);
15226 it.first_visible_x = 0;
15227 it.last_visible_x = FRAME_COLS (f);
15229 #endif /* not USE_X_TOOLKIT */
15231 if (! mode_line_inverse_video)
15232 /* Force the menu-bar to be displayed in the default face. */
15233 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
15235 /* Clear all rows of the menu bar. */
15236 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
15238 struct glyph_row *row = it.glyph_row + i;
15239 clear_glyph_row (row);
15240 row->enabled_p = 1;
15241 row->full_width_p = 1;
15244 /* Display all items of the menu bar. */
15245 items = FRAME_MENU_BAR_ITEMS (it.f);
15246 for (i = 0; i < XVECTOR (items)->size; i += 4)
15248 Lisp_Object string;
15250 /* Stop at nil string. */
15251 string = AREF (items, i + 1);
15252 if (NILP (string))
15253 break;
15255 /* Remember where item was displayed. */
15256 AREF (items, i + 3) = make_number (it.hpos);
15258 /* Display the item, pad with one space. */
15259 if (it.current_x < it.last_visible_x)
15260 display_string (NULL, string, Qnil, 0, 0, &it,
15261 SCHARS (string) + 1, 0, 0, -1);
15264 /* Fill out the line with spaces. */
15265 if (it.current_x < it.last_visible_x)
15266 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
15268 /* Compute the total height of the lines. */
15269 compute_line_metrics (&it);
15274 /***********************************************************************
15275 Mode Line
15276 ***********************************************************************/
15278 /* Redisplay mode lines in the window tree whose root is WINDOW. If
15279 FORCE is non-zero, redisplay mode lines unconditionally.
15280 Otherwise, redisplay only mode lines that are garbaged. Value is
15281 the number of windows whose mode lines were redisplayed. */
15283 static int
15284 redisplay_mode_lines (window, force)
15285 Lisp_Object window;
15286 int force;
15288 int nwindows = 0;
15290 while (!NILP (window))
15292 struct window *w = XWINDOW (window);
15294 if (WINDOWP (w->hchild))
15295 nwindows += redisplay_mode_lines (w->hchild, force);
15296 else if (WINDOWP (w->vchild))
15297 nwindows += redisplay_mode_lines (w->vchild, force);
15298 else if (force
15299 || FRAME_GARBAGED_P (XFRAME (w->frame))
15300 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
15302 struct text_pos lpoint;
15303 struct buffer *old = current_buffer;
15305 /* Set the window's buffer for the mode line display. */
15306 SET_TEXT_POS (lpoint, PT, PT_BYTE);
15307 set_buffer_internal_1 (XBUFFER (w->buffer));
15309 /* Point refers normally to the selected window. For any
15310 other window, set up appropriate value. */
15311 if (!EQ (window, selected_window))
15313 struct text_pos pt;
15315 SET_TEXT_POS_FROM_MARKER (pt, w->pointm);
15316 if (CHARPOS (pt) < BEGV)
15317 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
15318 else if (CHARPOS (pt) > (ZV - 1))
15319 TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
15320 else
15321 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
15324 /* Display mode lines. */
15325 clear_glyph_matrix (w->desired_matrix);
15326 if (display_mode_lines (w))
15328 ++nwindows;
15329 w->must_be_updated_p = 1;
15332 /* Restore old settings. */
15333 set_buffer_internal_1 (old);
15334 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
15337 window = w->next;
15340 return nwindows;
15344 /* Display the mode and/or top line of window W. Value is the number
15345 of mode lines displayed. */
15347 static int
15348 display_mode_lines (w)
15349 struct window *w;
15351 Lisp_Object old_selected_window, old_selected_frame;
15352 int n = 0;
15354 old_selected_frame = selected_frame;
15355 selected_frame = w->frame;
15356 old_selected_window = selected_window;
15357 XSETWINDOW (selected_window, w);
15359 /* These will be set while the mode line specs are processed. */
15360 line_number_displayed = 0;
15361 w->column_number_displayed = Qnil;
15363 if (WINDOW_WANTS_MODELINE_P (w))
15365 struct window *sel_w = XWINDOW (old_selected_window);
15367 /* Select mode line face based on the real selected window. */
15368 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
15369 current_buffer->mode_line_format);
15370 ++n;
15373 if (WINDOW_WANTS_HEADER_LINE_P (w))
15375 display_mode_line (w, HEADER_LINE_FACE_ID,
15376 current_buffer->header_line_format);
15377 ++n;
15380 selected_frame = old_selected_frame;
15381 selected_window = old_selected_window;
15382 return n;
15386 /* Display mode or top line of window W. FACE_ID specifies which line
15387 to display; it is either MODE_LINE_FACE_ID or HEADER_LINE_FACE_ID.
15388 FORMAT is the mode line format to display. Value is the pixel
15389 height of the mode line displayed. */
15391 static int
15392 display_mode_line (w, face_id, format)
15393 struct window *w;
15394 enum face_id face_id;
15395 Lisp_Object format;
15397 struct it it;
15398 struct face *face;
15400 init_iterator (&it, w, -1, -1, NULL, face_id);
15401 prepare_desired_row (it.glyph_row);
15403 it.glyph_row->mode_line_p = 1;
15405 if (! mode_line_inverse_video)
15406 /* Force the mode-line to be displayed in the default face. */
15407 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
15409 /* Temporarily make frame's keyboard the current kboard so that
15410 kboard-local variables in the mode_line_format will get the right
15411 values. */
15412 push_frame_kboard (it.f);
15413 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
15414 pop_frame_kboard ();
15416 /* Fill up with spaces. */
15417 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
15419 compute_line_metrics (&it);
15420 it.glyph_row->full_width_p = 1;
15421 it.glyph_row->continued_p = 0;
15422 it.glyph_row->truncated_on_left_p = 0;
15423 it.glyph_row->truncated_on_right_p = 0;
15425 /* Make a 3D mode-line have a shadow at its right end. */
15426 face = FACE_FROM_ID (it.f, face_id);
15427 extend_face_to_end_of_line (&it);
15428 if (face->box != FACE_NO_BOX)
15430 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
15431 + it.glyph_row->used[TEXT_AREA] - 1);
15432 last->right_box_line_p = 1;
15435 return it.glyph_row->height;
15438 /* Alist that caches the results of :propertize.
15439 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
15440 Lisp_Object mode_line_proptrans_alist;
15442 /* List of strings making up the mode-line. */
15443 Lisp_Object mode_line_string_list;
15445 /* Base face property when building propertized mode line string. */
15446 static Lisp_Object mode_line_string_face;
15447 static Lisp_Object mode_line_string_face_prop;
15450 /* Contribute ELT to the mode line for window IT->w. How it
15451 translates into text depends on its data type.
15453 IT describes the display environment in which we display, as usual.
15455 DEPTH is the depth in recursion. It is used to prevent
15456 infinite recursion here.
15458 FIELD_WIDTH is the number of characters the display of ELT should
15459 occupy in the mode line, and PRECISION is the maximum number of
15460 characters to display from ELT's representation. See
15461 display_string for details.
15463 Returns the hpos of the end of the text generated by ELT.
15465 PROPS is a property list to add to any string we encounter.
15467 If RISKY is nonzero, remove (disregard) any properties in any string
15468 we encounter, and ignore :eval and :propertize.
15470 If the global variable `frame_title_ptr' is non-NULL, then the output
15471 is passed to `store_frame_title' instead of `display_string'. */
15473 static int
15474 display_mode_element (it, depth, field_width, precision, elt, props, risky)
15475 struct it *it;
15476 int depth;
15477 int field_width, precision;
15478 Lisp_Object elt, props;
15479 int risky;
15481 int n = 0, field, prec;
15482 int literal = 0;
15484 tail_recurse:
15485 if (depth > 100)
15486 elt = build_string ("*too-deep*");
15488 depth++;
15490 switch (SWITCH_ENUM_CAST (XTYPE (elt)))
15492 case Lisp_String:
15494 /* A string: output it and check for %-constructs within it. */
15495 unsigned char c;
15496 const unsigned char *this, *lisp_string;
15498 if (!NILP (props) || risky)
15500 Lisp_Object oprops, aelt;
15501 oprops = Ftext_properties_at (make_number (0), elt);
15503 /* If the starting string's properties are not what
15504 we want, translate the string. Also, if the string
15505 is risky, do that anyway. */
15507 if (NILP (Fequal (props, oprops)) || risky)
15509 /* If the starting string has properties,
15510 merge the specified ones onto the existing ones. */
15511 if (! NILP (oprops) && !risky)
15513 Lisp_Object tem;
15515 oprops = Fcopy_sequence (oprops);
15516 tem = props;
15517 while (CONSP (tem))
15519 oprops = Fplist_put (oprops, XCAR (tem),
15520 XCAR (XCDR (tem)));
15521 tem = XCDR (XCDR (tem));
15523 props = oprops;
15526 aelt = Fassoc (elt, mode_line_proptrans_alist);
15527 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
15529 mode_line_proptrans_alist
15530 = Fcons (aelt, Fdelq (aelt, mode_line_proptrans_alist));
15531 elt = XCAR (aelt);
15533 else
15535 Lisp_Object tem;
15537 elt = Fcopy_sequence (elt);
15538 Fset_text_properties (make_number (0), Flength (elt),
15539 props, elt);
15540 /* Add this item to mode_line_proptrans_alist. */
15541 mode_line_proptrans_alist
15542 = Fcons (Fcons (elt, props),
15543 mode_line_proptrans_alist);
15544 /* Truncate mode_line_proptrans_alist
15545 to at most 50 elements. */
15546 tem = Fnthcdr (make_number (50),
15547 mode_line_proptrans_alist);
15548 if (! NILP (tem))
15549 XSETCDR (tem, Qnil);
15554 this = SDATA (elt);
15555 lisp_string = this;
15557 if (literal)
15559 prec = precision - n;
15560 if (frame_title_ptr)
15561 n += store_frame_title (SDATA (elt), -1, prec);
15562 else if (!NILP (mode_line_string_list))
15563 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
15564 else
15565 n += display_string (NULL, elt, Qnil, 0, 0, it,
15566 0, prec, 0, STRING_MULTIBYTE (elt));
15568 break;
15571 while ((precision <= 0 || n < precision)
15572 && *this
15573 && (frame_title_ptr
15574 || !NILP (mode_line_string_list)
15575 || it->current_x < it->last_visible_x))
15577 const unsigned char *last = this;
15579 /* Advance to end of string or next format specifier. */
15580 while ((c = *this++) != '\0' && c != '%')
15583 if (this - 1 != last)
15585 int nchars, nbytes;
15587 /* Output to end of string or up to '%'. Field width
15588 is length of string. Don't output more than
15589 PRECISION allows us. */
15590 --this;
15592 prec = c_string_width (last, this - last, precision - n,
15593 &nchars, &nbytes);
15595 if (frame_title_ptr)
15596 n += store_frame_title (last, 0, prec);
15597 else if (!NILP (mode_line_string_list))
15599 int bytepos = last - lisp_string;
15600 int charpos = string_byte_to_char (elt, bytepos);
15601 int endpos = (precision <= 0
15602 ? string_byte_to_char (elt,
15603 this - lisp_string)
15604 : charpos + nchars);
15606 n += store_mode_line_string (NULL,
15607 Fsubstring (elt, make_number (charpos),
15608 make_number (endpos)),
15609 0, 0, 0, Qnil);
15611 else
15613 int bytepos = last - lisp_string;
15614 int charpos = string_byte_to_char (elt, bytepos);
15615 n += display_string (NULL, elt, Qnil, 0, charpos,
15616 it, 0, prec, 0,
15617 STRING_MULTIBYTE (elt));
15620 else /* c == '%' */
15622 const unsigned char *percent_position = this;
15624 /* Get the specified minimum width. Zero means
15625 don't pad. */
15626 field = 0;
15627 while ((c = *this++) >= '0' && c <= '9')
15628 field = field * 10 + c - '0';
15630 /* Don't pad beyond the total padding allowed. */
15631 if (field_width - n > 0 && field > field_width - n)
15632 field = field_width - n;
15634 /* Note that either PRECISION <= 0 or N < PRECISION. */
15635 prec = precision - n;
15637 if (c == 'M')
15638 n += display_mode_element (it, depth, field, prec,
15639 Vglobal_mode_string, props,
15640 risky);
15641 else if (c != 0)
15643 int multibyte;
15644 int bytepos, charpos;
15645 unsigned char *spec;
15647 bytepos = percent_position - lisp_string;
15648 charpos = (STRING_MULTIBYTE (elt)
15649 ? string_byte_to_char (elt, bytepos)
15650 : bytepos);
15652 spec
15653 = decode_mode_spec (it->w, c, field, prec, &multibyte);
15655 if (frame_title_ptr)
15656 n += store_frame_title (spec, field, prec);
15657 else if (!NILP (mode_line_string_list))
15659 int len = strlen (spec);
15660 Lisp_Object tem = make_string (spec, len);
15661 props = Ftext_properties_at (make_number (charpos), elt);
15662 /* Should only keep face property in props */
15663 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
15665 else
15667 int nglyphs_before, nwritten;
15669 nglyphs_before = it->glyph_row->used[TEXT_AREA];
15670 nwritten = display_string (spec, Qnil, elt,
15671 charpos, 0, it,
15672 field, prec, 0,
15673 multibyte);
15675 /* Assign to the glyphs written above the
15676 string where the `%x' came from, position
15677 of the `%'. */
15678 if (nwritten > 0)
15680 struct glyph *glyph
15681 = (it->glyph_row->glyphs[TEXT_AREA]
15682 + nglyphs_before);
15683 int i;
15685 for (i = 0; i < nwritten; ++i)
15687 glyph[i].object = elt;
15688 glyph[i].charpos = charpos;
15691 n += nwritten;
15695 else /* c == 0 */
15696 break;
15700 break;
15702 case Lisp_Symbol:
15703 /* A symbol: process the value of the symbol recursively
15704 as if it appeared here directly. Avoid error if symbol void.
15705 Special case: if value of symbol is a string, output the string
15706 literally. */
15708 register Lisp_Object tem;
15710 /* If the variable is not marked as risky to set
15711 then its contents are risky to use. */
15712 if (NILP (Fget (elt, Qrisky_local_variable)))
15713 risky = 1;
15715 tem = Fboundp (elt);
15716 if (!NILP (tem))
15718 tem = Fsymbol_value (elt);
15719 /* If value is a string, output that string literally:
15720 don't check for % within it. */
15721 if (STRINGP (tem))
15722 literal = 1;
15724 if (!EQ (tem, elt))
15726 /* Give up right away for nil or t. */
15727 elt = tem;
15728 goto tail_recurse;
15732 break;
15734 case Lisp_Cons:
15736 register Lisp_Object car, tem;
15738 /* A cons cell: five distinct cases.
15739 If first element is :eval or :propertize, do something special.
15740 If first element is a string or a cons, process all the elements
15741 and effectively concatenate them.
15742 If first element is a negative number, truncate displaying cdr to
15743 at most that many characters. If positive, pad (with spaces)
15744 to at least that many characters.
15745 If first element is a symbol, process the cadr or caddr recursively
15746 according to whether the symbol's value is non-nil or nil. */
15747 car = XCAR (elt);
15748 if (EQ (car, QCeval))
15750 /* An element of the form (:eval FORM) means evaluate FORM
15751 and use the result as mode line elements. */
15753 if (risky)
15754 break;
15756 if (CONSP (XCDR (elt)))
15758 Lisp_Object spec;
15759 spec = safe_eval (XCAR (XCDR (elt)));
15760 n += display_mode_element (it, depth, field_width - n,
15761 precision - n, spec, props,
15762 risky);
15765 else if (EQ (car, QCpropertize))
15767 /* An element of the form (:propertize ELT PROPS...)
15768 means display ELT but applying properties PROPS. */
15770 if (risky)
15771 break;
15773 if (CONSP (XCDR (elt)))
15774 n += display_mode_element (it, depth, field_width - n,
15775 precision - n, XCAR (XCDR (elt)),
15776 XCDR (XCDR (elt)), risky);
15778 else if (SYMBOLP (car))
15780 tem = Fboundp (car);
15781 elt = XCDR (elt);
15782 if (!CONSP (elt))
15783 goto invalid;
15784 /* elt is now the cdr, and we know it is a cons cell.
15785 Use its car if CAR has a non-nil value. */
15786 if (!NILP (tem))
15788 tem = Fsymbol_value (car);
15789 if (!NILP (tem))
15791 elt = XCAR (elt);
15792 goto tail_recurse;
15795 /* Symbol's value is nil (or symbol is unbound)
15796 Get the cddr of the original list
15797 and if possible find the caddr and use that. */
15798 elt = XCDR (elt);
15799 if (NILP (elt))
15800 break;
15801 else if (!CONSP (elt))
15802 goto invalid;
15803 elt = XCAR (elt);
15804 goto tail_recurse;
15806 else if (INTEGERP (car))
15808 register int lim = XINT (car);
15809 elt = XCDR (elt);
15810 if (lim < 0)
15812 /* Negative int means reduce maximum width. */
15813 if (precision <= 0)
15814 precision = -lim;
15815 else
15816 precision = min (precision, -lim);
15818 else if (lim > 0)
15820 /* Padding specified. Don't let it be more than
15821 current maximum. */
15822 if (precision > 0)
15823 lim = min (precision, lim);
15825 /* If that's more padding than already wanted, queue it.
15826 But don't reduce padding already specified even if
15827 that is beyond the current truncation point. */
15828 field_width = max (lim, field_width);
15830 goto tail_recurse;
15832 else if (STRINGP (car) || CONSP (car))
15834 register int limit = 50;
15835 /* Limit is to protect against circular lists. */
15836 while (CONSP (elt)
15837 && --limit > 0
15838 && (precision <= 0 || n < precision))
15840 n += display_mode_element (it, depth, field_width - n,
15841 precision - n, XCAR (elt),
15842 props, risky);
15843 elt = XCDR (elt);
15847 break;
15849 default:
15850 invalid:
15851 elt = build_string ("*invalid*");
15852 goto tail_recurse;
15855 /* Pad to FIELD_WIDTH. */
15856 if (field_width > 0 && n < field_width)
15858 if (frame_title_ptr)
15859 n += store_frame_title ("", field_width - n, 0);
15860 else if (!NILP (mode_line_string_list))
15861 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
15862 else
15863 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
15864 0, 0, 0);
15867 return n;
15870 /* Store a mode-line string element in mode_line_string_list.
15872 If STRING is non-null, display that C string. Otherwise, the Lisp
15873 string LISP_STRING is displayed.
15875 FIELD_WIDTH is the minimum number of output glyphs to produce.
15876 If STRING has fewer characters than FIELD_WIDTH, pad to the right
15877 with spaces. FIELD_WIDTH <= 0 means don't pad.
15879 PRECISION is the maximum number of characters to output from
15880 STRING. PRECISION <= 0 means don't truncate the string.
15882 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
15883 properties to the string.
15885 PROPS are the properties to add to the string.
15886 The mode_line_string_face face property is always added to the string.
15889 static int
15890 store_mode_line_string (string, lisp_string, copy_string, field_width, precision, props)
15891 char *string;
15892 Lisp_Object lisp_string;
15893 int copy_string;
15894 int field_width;
15895 int precision;
15896 Lisp_Object props;
15898 int len;
15899 int n = 0;
15901 if (string != NULL)
15903 len = strlen (string);
15904 if (precision > 0 && len > precision)
15905 len = precision;
15906 lisp_string = make_string (string, len);
15907 if (NILP (props))
15908 props = mode_line_string_face_prop;
15909 else if (!NILP (mode_line_string_face))
15911 Lisp_Object face = Fsafe_plist_get (props, Qface);
15912 props = Fcopy_sequence (props);
15913 if (NILP (face))
15914 face = mode_line_string_face;
15915 else
15916 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
15917 props = Fplist_put (props, Qface, face);
15919 Fadd_text_properties (make_number (0), make_number (len),
15920 props, lisp_string);
15922 else
15924 len = XFASTINT (Flength (lisp_string));
15925 if (precision > 0 && len > precision)
15927 len = precision;
15928 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
15929 precision = -1;
15931 if (!NILP (mode_line_string_face))
15933 Lisp_Object face;
15934 if (NILP (props))
15935 props = Ftext_properties_at (make_number (0), lisp_string);
15936 face = Fsafe_plist_get (props, Qface);
15937 if (NILP (face))
15938 face = mode_line_string_face;
15939 else
15940 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
15941 props = Fcons (Qface, Fcons (face, Qnil));
15942 if (copy_string)
15943 lisp_string = Fcopy_sequence (lisp_string);
15945 if (!NILP (props))
15946 Fadd_text_properties (make_number (0), make_number (len),
15947 props, lisp_string);
15950 if (len > 0)
15952 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
15953 n += len;
15956 if (field_width > len)
15958 field_width -= len;
15959 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
15960 if (!NILP (props))
15961 Fadd_text_properties (make_number (0), make_number (field_width),
15962 props, lisp_string);
15963 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
15964 n += field_width;
15967 return n;
15971 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
15972 1, 4, 0,
15973 doc: /* Return the mode-line of selected window as a string.
15974 First arg FORMAT specifies the mode line format (see `mode-line-format' for
15975 details) to use. Second optional arg WINDOW specifies a different window to
15976 use as the context for the formatting. If third optional arg NO-PROPS is
15977 non-nil, string is not propertized. Fourth optional arg BUFFER specifies
15978 which buffer to use. */)
15979 (format, window, no_props, buffer)
15980 Lisp_Object format, window, no_props, buffer;
15982 struct it it;
15983 int len;
15984 struct window *w;
15985 struct buffer *old_buffer = NULL;
15986 enum face_id face_id = DEFAULT_FACE_ID;
15988 if (NILP (window))
15989 window = selected_window;
15990 CHECK_WINDOW (window);
15991 w = XWINDOW (window);
15993 if (NILP (buffer))
15994 buffer = w->buffer;
15996 CHECK_BUFFER (buffer);
15998 if (XBUFFER (buffer) != current_buffer)
16000 old_buffer = current_buffer;
16001 set_buffer_internal_1 (XBUFFER (buffer));
16004 init_iterator (&it, w, -1, -1, NULL, face_id);
16006 if (NILP (no_props))
16008 mode_line_string_face
16009 = (face_id == MODE_LINE_FACE_ID ? Qmode_line
16010 : face_id == MODE_LINE_INACTIVE_FACE_ID ? Qmode_line_inactive
16011 : face_id == HEADER_LINE_FACE_ID ? Qheader_line : Qnil);
16013 mode_line_string_face_prop
16014 = (NILP (mode_line_string_face) ? Qnil
16015 : Fcons (Qface, Fcons (mode_line_string_face, Qnil)));
16017 /* We need a dummy last element in mode_line_string_list to
16018 indicate we are building the propertized mode-line string.
16019 Using mode_line_string_face_prop here GC protects it. */
16020 mode_line_string_list
16021 = Fcons (mode_line_string_face_prop, Qnil);
16022 frame_title_ptr = NULL;
16024 else
16026 mode_line_string_face_prop = Qnil;
16027 mode_line_string_list = Qnil;
16028 frame_title_ptr = frame_title_buf;
16031 push_frame_kboard (it.f);
16032 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
16033 pop_frame_kboard ();
16035 if (old_buffer)
16036 set_buffer_internal_1 (old_buffer);
16038 if (NILP (no_props))
16040 Lisp_Object str;
16041 mode_line_string_list = Fnreverse (mode_line_string_list);
16042 str = Fmapconcat (intern ("identity"), XCDR (mode_line_string_list),
16043 make_string ("", 0));
16044 mode_line_string_face_prop = Qnil;
16045 mode_line_string_list = Qnil;
16046 return str;
16049 len = frame_title_ptr - frame_title_buf;
16050 if (len > 0 && frame_title_ptr[-1] == '-')
16052 /* Mode lines typically ends with numerous dashes; reduce to two dashes. */
16053 while (frame_title_ptr > frame_title_buf && *--frame_title_ptr == '-')
16055 frame_title_ptr += 3; /* restore last non-dash + two dashes */
16056 if (len > frame_title_ptr - frame_title_buf)
16057 len = frame_title_ptr - frame_title_buf;
16060 frame_title_ptr = NULL;
16061 return make_string (frame_title_buf, len);
16064 /* Write a null-terminated, right justified decimal representation of
16065 the positive integer D to BUF using a minimal field width WIDTH. */
16067 static void
16068 pint2str (buf, width, d)
16069 register char *buf;
16070 register int width;
16071 register int d;
16073 register char *p = buf;
16075 if (d <= 0)
16076 *p++ = '0';
16077 else
16079 while (d > 0)
16081 *p++ = d % 10 + '0';
16082 d /= 10;
16086 for (width -= (int) (p - buf); width > 0; --width)
16087 *p++ = ' ';
16088 *p-- = '\0';
16089 while (p > buf)
16091 d = *buf;
16092 *buf++ = *p;
16093 *p-- = d;
16097 /* Write a null-terminated, right justified decimal and "human
16098 readable" representation of the nonnegative integer D to BUF using
16099 a minimal field width WIDTH. D should be smaller than 999.5e24. */
16101 static const char power_letter[] =
16103 0, /* not used */
16104 'k', /* kilo */
16105 'M', /* mega */
16106 'G', /* giga */
16107 'T', /* tera */
16108 'P', /* peta */
16109 'E', /* exa */
16110 'Z', /* zetta */
16111 'Y' /* yotta */
16114 static void
16115 pint2hrstr (buf, width, d)
16116 char *buf;
16117 int width;
16118 int d;
16120 /* We aim to represent the nonnegative integer D as
16121 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
16122 int quotient = d;
16123 int remainder = 0;
16124 /* -1 means: do not use TENTHS. */
16125 int tenths = -1;
16126 int exponent = 0;
16128 /* Length of QUOTIENT.TENTHS as a string. */
16129 int length;
16131 char * psuffix;
16132 char * p;
16134 if (1000 <= quotient)
16136 /* Scale to the appropriate EXPONENT. */
16139 remainder = quotient % 1000;
16140 quotient /= 1000;
16141 exponent++;
16143 while (1000 <= quotient);
16145 /* Round to nearest and decide whether to use TENTHS or not. */
16146 if (quotient <= 9)
16148 tenths = remainder / 100;
16149 if (50 <= remainder % 100)
16151 if (tenths < 9)
16152 tenths++;
16153 else
16155 quotient++;
16156 if (quotient == 10)
16157 tenths = -1;
16158 else
16159 tenths = 0;
16163 else
16164 if (500 <= remainder)
16166 if (quotient < 999)
16167 quotient++;
16168 else
16170 quotient = 1;
16171 exponent++;
16172 tenths = 0;
16177 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
16178 if (tenths == -1 && quotient <= 99)
16179 if (quotient <= 9)
16180 length = 1;
16181 else
16182 length = 2;
16183 else
16184 length = 3;
16185 p = psuffix = buf + max (width, length);
16187 /* Print EXPONENT. */
16188 if (exponent)
16189 *psuffix++ = power_letter[exponent];
16190 *psuffix = '\0';
16192 /* Print TENTHS. */
16193 if (tenths >= 0)
16195 *--p = '0' + tenths;
16196 *--p = '.';
16199 /* Print QUOTIENT. */
16202 int digit = quotient % 10;
16203 *--p = '0' + digit;
16205 while ((quotient /= 10) != 0);
16207 /* Print leading spaces. */
16208 while (buf < p)
16209 *--p = ' ';
16212 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
16213 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
16214 type of CODING_SYSTEM. Return updated pointer into BUF. */
16216 static unsigned char invalid_eol_type[] = "(*invalid*)";
16218 static char *
16219 decode_mode_spec_coding (coding_system, buf, eol_flag)
16220 Lisp_Object coding_system;
16221 register char *buf;
16222 int eol_flag;
16224 Lisp_Object val;
16225 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
16226 const unsigned char *eol_str;
16227 int eol_str_len;
16228 /* The EOL conversion we are using. */
16229 Lisp_Object eoltype;
16231 val = Fget (coding_system, Qcoding_system);
16232 eoltype = Qnil;
16234 if (!VECTORP (val)) /* Not yet decided. */
16236 if (multibyte)
16237 *buf++ = '-';
16238 if (eol_flag)
16239 eoltype = eol_mnemonic_undecided;
16240 /* Don't mention EOL conversion if it isn't decided. */
16242 else
16244 Lisp_Object eolvalue;
16246 eolvalue = Fget (coding_system, Qeol_type);
16248 if (multibyte)
16249 *buf++ = XFASTINT (AREF (val, 1));
16251 if (eol_flag)
16253 /* The EOL conversion that is normal on this system. */
16255 if (NILP (eolvalue)) /* Not yet decided. */
16256 eoltype = eol_mnemonic_undecided;
16257 else if (VECTORP (eolvalue)) /* Not yet decided. */
16258 eoltype = eol_mnemonic_undecided;
16259 else /* INTEGERP (eolvalue) -- 0:LF, 1:CRLF, 2:CR */
16260 eoltype = (XFASTINT (eolvalue) == 0
16261 ? eol_mnemonic_unix
16262 : (XFASTINT (eolvalue) == 1
16263 ? eol_mnemonic_dos : eol_mnemonic_mac));
16267 if (eol_flag)
16269 /* Mention the EOL conversion if it is not the usual one. */
16270 if (STRINGP (eoltype))
16272 eol_str = SDATA (eoltype);
16273 eol_str_len = SBYTES (eoltype);
16275 else if (INTEGERP (eoltype)
16276 && CHAR_VALID_P (XINT (eoltype), 0))
16278 unsigned char *tmp = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
16279 eol_str_len = CHAR_STRING (XINT (eoltype), tmp);
16280 eol_str = tmp;
16282 else
16284 eol_str = invalid_eol_type;
16285 eol_str_len = sizeof (invalid_eol_type) - 1;
16287 bcopy (eol_str, buf, eol_str_len);
16288 buf += eol_str_len;
16291 return buf;
16294 /* Return a string for the output of a mode line %-spec for window W,
16295 generated by character C. PRECISION >= 0 means don't return a
16296 string longer than that value. FIELD_WIDTH > 0 means pad the
16297 string returned with spaces to that value. Return 1 in *MULTIBYTE
16298 if the result is multibyte text.
16300 Note we operate on the current buffer for most purposes,
16301 the exception being w->base_line_pos. */
16303 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
16305 static char *
16306 decode_mode_spec (w, c, field_width, precision, multibyte)
16307 struct window *w;
16308 register int c;
16309 int field_width, precision;
16310 int *multibyte;
16312 Lisp_Object obj;
16313 struct frame *f = XFRAME (WINDOW_FRAME (w));
16314 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
16315 struct buffer *b = current_buffer;
16317 obj = Qnil;
16318 *multibyte = 0;
16320 switch (c)
16322 case '*':
16323 if (!NILP (b->read_only))
16324 return "%";
16325 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
16326 return "*";
16327 return "-";
16329 case '+':
16330 /* This differs from %* only for a modified read-only buffer. */
16331 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
16332 return "*";
16333 if (!NILP (b->read_only))
16334 return "%";
16335 return "-";
16337 case '&':
16338 /* This differs from %* in ignoring read-only-ness. */
16339 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
16340 return "*";
16341 return "-";
16343 case '%':
16344 return "%";
16346 case '[':
16348 int i;
16349 char *p;
16351 if (command_loop_level > 5)
16352 return "[[[... ";
16353 p = decode_mode_spec_buf;
16354 for (i = 0; i < command_loop_level; i++)
16355 *p++ = '[';
16356 *p = 0;
16357 return decode_mode_spec_buf;
16360 case ']':
16362 int i;
16363 char *p;
16365 if (command_loop_level > 5)
16366 return " ...]]]";
16367 p = decode_mode_spec_buf;
16368 for (i = 0; i < command_loop_level; i++)
16369 *p++ = ']';
16370 *p = 0;
16371 return decode_mode_spec_buf;
16374 case '-':
16376 register int i;
16378 /* Let lots_of_dashes be a string of infinite length. */
16379 if (!NILP (mode_line_string_list))
16380 return "--";
16381 if (field_width <= 0
16382 || field_width > sizeof (lots_of_dashes))
16384 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
16385 decode_mode_spec_buf[i] = '-';
16386 decode_mode_spec_buf[i] = '\0';
16387 return decode_mode_spec_buf;
16389 else
16390 return lots_of_dashes;
16393 case 'b':
16394 obj = b->name;
16395 break;
16397 case 'c':
16399 int col = (int) current_column (); /* iftc */
16400 w->column_number_displayed = make_number (col);
16401 pint2str (decode_mode_spec_buf, field_width, col);
16402 return decode_mode_spec_buf;
16405 case 'F':
16406 /* %F displays the frame name. */
16407 if (!NILP (f->title))
16408 return (char *) SDATA (f->title);
16409 if (f->explicit_name || ! FRAME_WINDOW_P (f))
16410 return (char *) SDATA (f->name);
16411 return "Emacs";
16413 case 'f':
16414 obj = b->filename;
16415 break;
16417 case 'i':
16419 int size = ZV - BEGV;
16420 pint2str (decode_mode_spec_buf, field_width, size);
16421 return decode_mode_spec_buf;
16424 case 'I':
16426 int size = ZV - BEGV;
16427 pint2hrstr (decode_mode_spec_buf, field_width, size);
16428 return decode_mode_spec_buf;
16431 case 'l':
16433 int startpos = XMARKER (w->start)->charpos;
16434 int startpos_byte = marker_byte_position (w->start);
16435 int line, linepos, linepos_byte, topline;
16436 int nlines, junk;
16437 int height = WINDOW_TOTAL_LINES (w);
16439 /* If we decided that this buffer isn't suitable for line numbers,
16440 don't forget that too fast. */
16441 if (EQ (w->base_line_pos, w->buffer))
16442 goto no_value;
16443 /* But do forget it, if the window shows a different buffer now. */
16444 else if (BUFFERP (w->base_line_pos))
16445 w->base_line_pos = Qnil;
16447 /* If the buffer is very big, don't waste time. */
16448 if (INTEGERP (Vline_number_display_limit)
16449 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
16451 w->base_line_pos = Qnil;
16452 w->base_line_number = Qnil;
16453 goto no_value;
16456 if (!NILP (w->base_line_number)
16457 && !NILP (w->base_line_pos)
16458 && XFASTINT (w->base_line_pos) <= startpos)
16460 line = XFASTINT (w->base_line_number);
16461 linepos = XFASTINT (w->base_line_pos);
16462 linepos_byte = buf_charpos_to_bytepos (b, linepos);
16464 else
16466 line = 1;
16467 linepos = BUF_BEGV (b);
16468 linepos_byte = BUF_BEGV_BYTE (b);
16471 /* Count lines from base line to window start position. */
16472 nlines = display_count_lines (linepos, linepos_byte,
16473 startpos_byte,
16474 startpos, &junk);
16476 topline = nlines + line;
16478 /* Determine a new base line, if the old one is too close
16479 or too far away, or if we did not have one.
16480 "Too close" means it's plausible a scroll-down would
16481 go back past it. */
16482 if (startpos == BUF_BEGV (b))
16484 w->base_line_number = make_number (topline);
16485 w->base_line_pos = make_number (BUF_BEGV (b));
16487 else if (nlines < height + 25 || nlines > height * 3 + 50
16488 || linepos == BUF_BEGV (b))
16490 int limit = BUF_BEGV (b);
16491 int limit_byte = BUF_BEGV_BYTE (b);
16492 int position;
16493 int distance = (height * 2 + 30) * line_number_display_limit_width;
16495 if (startpos - distance > limit)
16497 limit = startpos - distance;
16498 limit_byte = CHAR_TO_BYTE (limit);
16501 nlines = display_count_lines (startpos, startpos_byte,
16502 limit_byte,
16503 - (height * 2 + 30),
16504 &position);
16505 /* If we couldn't find the lines we wanted within
16506 line_number_display_limit_width chars per line,
16507 give up on line numbers for this window. */
16508 if (position == limit_byte && limit == startpos - distance)
16510 w->base_line_pos = w->buffer;
16511 w->base_line_number = Qnil;
16512 goto no_value;
16515 w->base_line_number = make_number (topline - nlines);
16516 w->base_line_pos = make_number (BYTE_TO_CHAR (position));
16519 /* Now count lines from the start pos to point. */
16520 nlines = display_count_lines (startpos, startpos_byte,
16521 PT_BYTE, PT, &junk);
16523 /* Record that we did display the line number. */
16524 line_number_displayed = 1;
16526 /* Make the string to show. */
16527 pint2str (decode_mode_spec_buf, field_width, topline + nlines);
16528 return decode_mode_spec_buf;
16529 no_value:
16531 char* p = decode_mode_spec_buf;
16532 int pad = field_width - 2;
16533 while (pad-- > 0)
16534 *p++ = ' ';
16535 *p++ = '?';
16536 *p++ = '?';
16537 *p = '\0';
16538 return decode_mode_spec_buf;
16541 break;
16543 case 'm':
16544 obj = b->mode_name;
16545 break;
16547 case 'n':
16548 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
16549 return " Narrow";
16550 break;
16552 case 'p':
16554 int pos = marker_position (w->start);
16555 int total = BUF_ZV (b) - BUF_BEGV (b);
16557 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
16559 if (pos <= BUF_BEGV (b))
16560 return "All";
16561 else
16562 return "Bottom";
16564 else if (pos <= BUF_BEGV (b))
16565 return "Top";
16566 else
16568 if (total > 1000000)
16569 /* Do it differently for a large value, to avoid overflow. */
16570 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
16571 else
16572 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
16573 /* We can't normally display a 3-digit number,
16574 so get us a 2-digit number that is close. */
16575 if (total == 100)
16576 total = 99;
16577 sprintf (decode_mode_spec_buf, "%2d%%", total);
16578 return decode_mode_spec_buf;
16582 /* Display percentage of size above the bottom of the screen. */
16583 case 'P':
16585 int toppos = marker_position (w->start);
16586 int botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
16587 int total = BUF_ZV (b) - BUF_BEGV (b);
16589 if (botpos >= BUF_ZV (b))
16591 if (toppos <= BUF_BEGV (b))
16592 return "All";
16593 else
16594 return "Bottom";
16596 else
16598 if (total > 1000000)
16599 /* Do it differently for a large value, to avoid overflow. */
16600 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
16601 else
16602 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
16603 /* We can't normally display a 3-digit number,
16604 so get us a 2-digit number that is close. */
16605 if (total == 100)
16606 total = 99;
16607 if (toppos <= BUF_BEGV (b))
16608 sprintf (decode_mode_spec_buf, "Top%2d%%", total);
16609 else
16610 sprintf (decode_mode_spec_buf, "%2d%%", total);
16611 return decode_mode_spec_buf;
16615 case 's':
16616 /* status of process */
16617 obj = Fget_buffer_process (Fcurrent_buffer ());
16618 if (NILP (obj))
16619 return "no process";
16620 #ifdef subprocesses
16621 obj = Fsymbol_name (Fprocess_status (obj));
16622 #endif
16623 break;
16625 case 't': /* indicate TEXT or BINARY */
16626 #ifdef MODE_LINE_BINARY_TEXT
16627 return MODE_LINE_BINARY_TEXT (b);
16628 #else
16629 return "T";
16630 #endif
16632 case 'z':
16633 /* coding-system (not including end-of-line format) */
16634 case 'Z':
16635 /* coding-system (including end-of-line type) */
16637 int eol_flag = (c == 'Z');
16638 char *p = decode_mode_spec_buf;
16640 if (! FRAME_WINDOW_P (f))
16642 /* No need to mention EOL here--the terminal never needs
16643 to do EOL conversion. */
16644 p = decode_mode_spec_coding (keyboard_coding.symbol, p, 0);
16645 p = decode_mode_spec_coding (terminal_coding.symbol, p, 0);
16647 p = decode_mode_spec_coding (b->buffer_file_coding_system,
16648 p, eol_flag);
16650 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
16651 #ifdef subprocesses
16652 obj = Fget_buffer_process (Fcurrent_buffer ());
16653 if (PROCESSP (obj))
16655 p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system,
16656 p, eol_flag);
16657 p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system,
16658 p, eol_flag);
16660 #endif /* subprocesses */
16661 #endif /* 0 */
16662 *p = 0;
16663 return decode_mode_spec_buf;
16667 if (STRINGP (obj))
16669 *multibyte = STRING_MULTIBYTE (obj);
16670 return (char *) SDATA (obj);
16672 else
16673 return "";
16677 /* Count up to COUNT lines starting from START / START_BYTE.
16678 But don't go beyond LIMIT_BYTE.
16679 Return the number of lines thus found (always nonnegative).
16681 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
16683 static int
16684 display_count_lines (start, start_byte, limit_byte, count, byte_pos_ptr)
16685 int start, start_byte, limit_byte, count;
16686 int *byte_pos_ptr;
16688 register unsigned char *cursor;
16689 unsigned char *base;
16691 register int ceiling;
16692 register unsigned char *ceiling_addr;
16693 int orig_count = count;
16695 /* If we are not in selective display mode,
16696 check only for newlines. */
16697 int selective_display = (!NILP (current_buffer->selective_display)
16698 && !INTEGERP (current_buffer->selective_display));
16700 if (count > 0)
16702 while (start_byte < limit_byte)
16704 ceiling = BUFFER_CEILING_OF (start_byte);
16705 ceiling = min (limit_byte - 1, ceiling);
16706 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
16707 base = (cursor = BYTE_POS_ADDR (start_byte));
16708 while (1)
16710 if (selective_display)
16711 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
16713 else
16714 while (*cursor != '\n' && ++cursor != ceiling_addr)
16717 if (cursor != ceiling_addr)
16719 if (--count == 0)
16721 start_byte += cursor - base + 1;
16722 *byte_pos_ptr = start_byte;
16723 return orig_count;
16725 else
16726 if (++cursor == ceiling_addr)
16727 break;
16729 else
16730 break;
16732 start_byte += cursor - base;
16735 else
16737 while (start_byte > limit_byte)
16739 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
16740 ceiling = max (limit_byte, ceiling);
16741 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1;
16742 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
16743 while (1)
16745 if (selective_display)
16746 while (--cursor != ceiling_addr
16747 && *cursor != '\n' && *cursor != 015)
16749 else
16750 while (--cursor != ceiling_addr && *cursor != '\n')
16753 if (cursor != ceiling_addr)
16755 if (++count == 0)
16757 start_byte += cursor - base + 1;
16758 *byte_pos_ptr = start_byte;
16759 /* When scanning backwards, we should
16760 not count the newline posterior to which we stop. */
16761 return - orig_count - 1;
16764 else
16765 break;
16767 /* Here we add 1 to compensate for the last decrement
16768 of CURSOR, which took it past the valid range. */
16769 start_byte += cursor - base + 1;
16773 *byte_pos_ptr = limit_byte;
16775 if (count < 0)
16776 return - orig_count + count;
16777 return orig_count - count;
16783 /***********************************************************************
16784 Displaying strings
16785 ***********************************************************************/
16787 /* Display a NUL-terminated string, starting with index START.
16789 If STRING is non-null, display that C string. Otherwise, the Lisp
16790 string LISP_STRING is displayed.
16792 If FACE_STRING is not nil, FACE_STRING_POS is a position in
16793 FACE_STRING. Display STRING or LISP_STRING with the face at
16794 FACE_STRING_POS in FACE_STRING:
16796 Display the string in the environment given by IT, but use the
16797 standard display table, temporarily.
16799 FIELD_WIDTH is the minimum number of output glyphs to produce.
16800 If STRING has fewer characters than FIELD_WIDTH, pad to the right
16801 with spaces. If STRING has more characters, more than FIELD_WIDTH
16802 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
16804 PRECISION is the maximum number of characters to output from
16805 STRING. PRECISION < 0 means don't truncate the string.
16807 This is roughly equivalent to printf format specifiers:
16809 FIELD_WIDTH PRECISION PRINTF
16810 ----------------------------------------
16811 -1 -1 %s
16812 -1 10 %.10s
16813 10 -1 %10s
16814 20 10 %20.10s
16816 MULTIBYTE zero means do not display multibyte chars, > 0 means do
16817 display them, and < 0 means obey the current buffer's value of
16818 enable_multibyte_characters.
16820 Value is the number of glyphs produced. */
16822 static int
16823 display_string (string, lisp_string, face_string, face_string_pos,
16824 start, it, field_width, precision, max_x, multibyte)
16825 unsigned char *string;
16826 Lisp_Object lisp_string;
16827 Lisp_Object face_string;
16828 int face_string_pos;
16829 int start;
16830 struct it *it;
16831 int field_width, precision, max_x;
16832 int multibyte;
16834 int hpos_at_start = it->hpos;
16835 int saved_face_id = it->face_id;
16836 struct glyph_row *row = it->glyph_row;
16838 /* Initialize the iterator IT for iteration over STRING beginning
16839 with index START. */
16840 reseat_to_string (it, string, lisp_string, start,
16841 precision, field_width, multibyte);
16843 /* If displaying STRING, set up the face of the iterator
16844 from LISP_STRING, if that's given. */
16845 if (STRINGP (face_string))
16847 int endptr;
16848 struct face *face;
16850 it->face_id
16851 = face_at_string_position (it->w, face_string, face_string_pos,
16852 0, it->region_beg_charpos,
16853 it->region_end_charpos,
16854 &endptr, it->base_face_id, 0);
16855 face = FACE_FROM_ID (it->f, it->face_id);
16856 it->face_box_p = face->box != FACE_NO_BOX;
16859 /* Set max_x to the maximum allowed X position. Don't let it go
16860 beyond the right edge of the window. */
16861 if (max_x <= 0)
16862 max_x = it->last_visible_x;
16863 else
16864 max_x = min (max_x, it->last_visible_x);
16866 /* Skip over display elements that are not visible. because IT->w is
16867 hscrolled. */
16868 if (it->current_x < it->first_visible_x)
16869 move_it_in_display_line_to (it, 100000, it->first_visible_x,
16870 MOVE_TO_POS | MOVE_TO_X);
16872 row->ascent = it->max_ascent;
16873 row->height = it->max_ascent + it->max_descent;
16874 row->phys_ascent = it->max_phys_ascent;
16875 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
16876 row->extra_line_spacing = it->max_extra_line_spacing;
16878 /* This condition is for the case that we are called with current_x
16879 past last_visible_x. */
16880 while (it->current_x < max_x)
16882 int x_before, x, n_glyphs_before, i, nglyphs;
16884 /* Get the next display element. */
16885 if (!get_next_display_element (it))
16886 break;
16888 /* Produce glyphs. */
16889 x_before = it->current_x;
16890 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
16891 PRODUCE_GLYPHS (it);
16893 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
16894 i = 0;
16895 x = x_before;
16896 while (i < nglyphs)
16898 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
16900 if (!it->truncate_lines_p
16901 && x + glyph->pixel_width > max_x)
16903 /* End of continued line or max_x reached. */
16904 if (CHAR_GLYPH_PADDING_P (*glyph))
16906 /* A wide character is unbreakable. */
16907 it->glyph_row->used[TEXT_AREA] = n_glyphs_before;
16908 it->current_x = x_before;
16910 else
16912 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
16913 it->current_x = x;
16915 break;
16917 else if (x + glyph->pixel_width > it->first_visible_x)
16919 /* Glyph is at least partially visible. */
16920 ++it->hpos;
16921 if (x < it->first_visible_x)
16922 it->glyph_row->x = x - it->first_visible_x;
16924 else
16926 /* Glyph is off the left margin of the display area.
16927 Should not happen. */
16928 abort ();
16931 row->ascent = max (row->ascent, it->max_ascent);
16932 row->height = max (row->height, it->max_ascent + it->max_descent);
16933 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
16934 row->phys_height = max (row->phys_height,
16935 it->max_phys_ascent + it->max_phys_descent);
16936 row->extra_line_spacing = max (row->extra_line_spacing,
16937 it->max_extra_line_spacing);
16938 x += glyph->pixel_width;
16939 ++i;
16942 /* Stop if max_x reached. */
16943 if (i < nglyphs)
16944 break;
16946 /* Stop at line ends. */
16947 if (ITERATOR_AT_END_OF_LINE_P (it))
16949 it->continuation_lines_width = 0;
16950 break;
16953 set_iterator_to_next (it, 1);
16955 /* Stop if truncating at the right edge. */
16956 if (it->truncate_lines_p
16957 && it->current_x >= it->last_visible_x)
16959 /* Add truncation mark, but don't do it if the line is
16960 truncated at a padding space. */
16961 if (IT_CHARPOS (*it) < it->string_nchars)
16963 if (!FRAME_WINDOW_P (it->f))
16965 int i, n;
16967 if (it->current_x > it->last_visible_x)
16969 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
16970 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
16971 break;
16972 for (n = row->used[TEXT_AREA]; i < n; ++i)
16974 row->used[TEXT_AREA] = i;
16975 produce_special_glyphs (it, IT_TRUNCATION);
16978 produce_special_glyphs (it, IT_TRUNCATION);
16980 it->glyph_row->truncated_on_right_p = 1;
16982 break;
16986 /* Maybe insert a truncation at the left. */
16987 if (it->first_visible_x
16988 && IT_CHARPOS (*it) > 0)
16990 if (!FRAME_WINDOW_P (it->f))
16991 insert_left_trunc_glyphs (it);
16992 it->glyph_row->truncated_on_left_p = 1;
16995 it->face_id = saved_face_id;
16997 /* Value is number of columns displayed. */
16998 return it->hpos - hpos_at_start;
17003 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
17004 appears as an element of LIST or as the car of an element of LIST.
17005 If PROPVAL is a list, compare each element against LIST in that
17006 way, and return 1/2 if any element of PROPVAL is found in LIST.
17007 Otherwise return 0. This function cannot quit.
17008 The return value is 2 if the text is invisible but with an ellipsis
17009 and 1 if it's invisible and without an ellipsis. */
17012 invisible_p (propval, list)
17013 register Lisp_Object propval;
17014 Lisp_Object list;
17016 register Lisp_Object tail, proptail;
17018 for (tail = list; CONSP (tail); tail = XCDR (tail))
17020 register Lisp_Object tem;
17021 tem = XCAR (tail);
17022 if (EQ (propval, tem))
17023 return 1;
17024 if (CONSP (tem) && EQ (propval, XCAR (tem)))
17025 return NILP (XCDR (tem)) ? 1 : 2;
17028 if (CONSP (propval))
17030 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
17032 Lisp_Object propelt;
17033 propelt = XCAR (proptail);
17034 for (tail = list; CONSP (tail); tail = XCDR (tail))
17036 register Lisp_Object tem;
17037 tem = XCAR (tail);
17038 if (EQ (propelt, tem))
17039 return 1;
17040 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
17041 return NILP (XCDR (tem)) ? 1 : 2;
17046 return 0;
17049 /* Calculate a width or height in pixels from a specification using
17050 the following elements:
17052 SPEC ::=
17053 NUM - a (fractional) multiple of the default font width/height
17054 (NUM) - specifies exactly NUM pixels
17055 UNIT - a fixed number of pixels, see below.
17056 ELEMENT - size of a display element in pixels, see below.
17057 (NUM . SPEC) - equals NUM * SPEC
17058 (+ SPEC SPEC ...) - add pixel values
17059 (- SPEC SPEC ...) - subtract pixel values
17060 (- SPEC) - negate pixel value
17062 NUM ::=
17063 INT or FLOAT - a number constant
17064 SYMBOL - use symbol's (buffer local) variable binding.
17066 UNIT ::=
17067 in - pixels per inch *)
17068 mm - pixels per 1/1000 meter *)
17069 cm - pixels per 1/100 meter *)
17070 width - width of current font in pixels.
17071 height - height of current font in pixels.
17073 *) using the ratio(s) defined in display-pixels-per-inch.
17075 ELEMENT ::=
17077 left-fringe - left fringe width in pixels
17078 right-fringe - right fringe width in pixels
17080 left-margin - left margin width in pixels
17081 right-margin - right margin width in pixels
17083 scroll-bar - scroll-bar area width in pixels
17085 Examples:
17087 Pixels corresponding to 5 inches:
17088 (5 . in)
17090 Total width of non-text areas on left side of window (if scroll-bar is on left):
17091 '(space :width (+ left-fringe left-margin scroll-bar))
17093 Align to first text column (in header line):
17094 '(space :align-to 0)
17096 Align to middle of text area minus half the width of variable `my-image'
17097 containing a loaded image:
17098 '(space :align-to (0.5 . (- text my-image)))
17100 Width of left margin minus width of 1 character in the default font:
17101 '(space :width (- left-margin 1))
17103 Width of left margin minus width of 2 characters in the current font:
17104 '(space :width (- left-margin (2 . width)))
17106 Center 1 character over left-margin (in header line):
17107 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
17109 Different ways to express width of left fringe plus left margin minus one pixel:
17110 '(space :width (- (+ left-fringe left-margin) (1)))
17111 '(space :width (+ left-fringe left-margin (- (1))))
17112 '(space :width (+ left-fringe left-margin (-1)))
17116 #define NUMVAL(X) \
17117 ((INTEGERP (X) || FLOATP (X)) \
17118 ? XFLOATINT (X) \
17119 : - 1)
17122 calc_pixel_width_or_height (res, it, prop, font, width_p, align_to)
17123 double *res;
17124 struct it *it;
17125 Lisp_Object prop;
17126 void *font;
17127 int width_p, *align_to;
17129 double pixels;
17131 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
17132 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
17134 if (NILP (prop))
17135 return OK_PIXELS (0);
17137 if (SYMBOLP (prop))
17139 if (SCHARS (SYMBOL_NAME (prop)) == 2)
17141 char *unit = SDATA (SYMBOL_NAME (prop));
17143 if (unit[0] == 'i' && unit[1] == 'n')
17144 pixels = 1.0;
17145 else if (unit[0] == 'm' && unit[1] == 'm')
17146 pixels = 25.4;
17147 else if (unit[0] == 'c' && unit[1] == 'm')
17148 pixels = 2.54;
17149 else
17150 pixels = 0;
17151 if (pixels > 0)
17153 double ppi;
17154 if ((ppi = NUMVAL (Vdisplay_pixels_per_inch), ppi > 0)
17155 || (CONSP (Vdisplay_pixels_per_inch)
17156 && (ppi = (width_p
17157 ? NUMVAL (XCAR (Vdisplay_pixels_per_inch))
17158 : NUMVAL (XCDR (Vdisplay_pixels_per_inch))),
17159 ppi > 0)))
17160 return OK_PIXELS (ppi / pixels);
17162 return 0;
17166 #ifdef HAVE_WINDOW_SYSTEM
17167 if (EQ (prop, Qheight))
17168 return OK_PIXELS (font ? FONT_HEIGHT ((XFontStruct *)font) : FRAME_LINE_HEIGHT (it->f));
17169 if (EQ (prop, Qwidth))
17170 return OK_PIXELS (font ? FONT_WIDTH ((XFontStruct *)font) : FRAME_COLUMN_WIDTH (it->f));
17171 #else
17172 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
17173 return OK_PIXELS (1);
17174 #endif
17176 if (EQ (prop, Qtext))
17177 return OK_PIXELS (width_p
17178 ? window_box_width (it->w, TEXT_AREA)
17179 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
17181 if (align_to && *align_to < 0)
17183 *res = 0;
17184 if (EQ (prop, Qleft))
17185 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA));
17186 if (EQ (prop, Qright))
17187 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
17188 if (EQ (prop, Qcenter))
17189 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
17190 + window_box_width (it->w, TEXT_AREA) / 2);
17191 if (EQ (prop, Qleft_fringe))
17192 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
17193 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
17194 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
17195 if (EQ (prop, Qright_fringe))
17196 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
17197 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
17198 : window_box_right_offset (it->w, TEXT_AREA));
17199 if (EQ (prop, Qleft_margin))
17200 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
17201 if (EQ (prop, Qright_margin))
17202 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
17203 if (EQ (prop, Qscroll_bar))
17204 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
17206 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
17207 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
17208 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
17209 : 0)));
17211 else
17213 if (EQ (prop, Qleft_fringe))
17214 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
17215 if (EQ (prop, Qright_fringe))
17216 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
17217 if (EQ (prop, Qleft_margin))
17218 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
17219 if (EQ (prop, Qright_margin))
17220 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
17221 if (EQ (prop, Qscroll_bar))
17222 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
17225 prop = Fbuffer_local_value (prop, it->w->buffer);
17228 if (INTEGERP (prop) || FLOATP (prop))
17230 int base_unit = (width_p
17231 ? FRAME_COLUMN_WIDTH (it->f)
17232 : FRAME_LINE_HEIGHT (it->f));
17233 return OK_PIXELS (XFLOATINT (prop) * base_unit);
17236 if (CONSP (prop))
17238 Lisp_Object car = XCAR (prop);
17239 Lisp_Object cdr = XCDR (prop);
17241 if (SYMBOLP (car))
17243 #ifdef HAVE_WINDOW_SYSTEM
17244 if (valid_image_p (prop))
17246 int id = lookup_image (it->f, prop);
17247 struct image *img = IMAGE_FROM_ID (it->f, id);
17249 return OK_PIXELS (width_p ? img->width : img->height);
17251 #endif
17252 if (EQ (car, Qplus) || EQ (car, Qminus))
17254 int first = 1;
17255 double px;
17257 pixels = 0;
17258 while (CONSP (cdr))
17260 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
17261 font, width_p, align_to))
17262 return 0;
17263 if (first)
17264 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
17265 else
17266 pixels += px;
17267 cdr = XCDR (cdr);
17269 if (EQ (car, Qminus))
17270 pixels = -pixels;
17271 return OK_PIXELS (pixels);
17274 car = Fbuffer_local_value (car, it->w->buffer);
17277 if (INTEGERP (car) || FLOATP (car))
17279 double fact;
17280 pixels = XFLOATINT (car);
17281 if (NILP (cdr))
17282 return OK_PIXELS (pixels);
17283 if (calc_pixel_width_or_height (&fact, it, cdr,
17284 font, width_p, align_to))
17285 return OK_PIXELS (pixels * fact);
17286 return 0;
17289 return 0;
17292 return 0;
17296 /***********************************************************************
17297 Glyph Display
17298 ***********************************************************************/
17300 #ifdef HAVE_WINDOW_SYSTEM
17302 #if GLYPH_DEBUG
17304 void
17305 dump_glyph_string (s)
17306 struct glyph_string *s;
17308 fprintf (stderr, "glyph string\n");
17309 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
17310 s->x, s->y, s->width, s->height);
17311 fprintf (stderr, " ybase = %d\n", s->ybase);
17312 fprintf (stderr, " hl = %d\n", s->hl);
17313 fprintf (stderr, " left overhang = %d, right = %d\n",
17314 s->left_overhang, s->right_overhang);
17315 fprintf (stderr, " nchars = %d\n", s->nchars);
17316 fprintf (stderr, " extends to end of line = %d\n",
17317 s->extends_to_end_of_line_p);
17318 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
17319 fprintf (stderr, " bg width = %d\n", s->background_width);
17322 #endif /* GLYPH_DEBUG */
17324 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
17325 of XChar2b structures for S; it can't be allocated in
17326 init_glyph_string because it must be allocated via `alloca'. W
17327 is the window on which S is drawn. ROW and AREA are the glyph row
17328 and area within the row from which S is constructed. START is the
17329 index of the first glyph structure covered by S. HL is a
17330 face-override for drawing S. */
17332 #ifdef HAVE_NTGUI
17333 #define OPTIONAL_HDC(hdc) hdc,
17334 #define DECLARE_HDC(hdc) HDC hdc;
17335 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
17336 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
17337 #endif
17339 #ifndef OPTIONAL_HDC
17340 #define OPTIONAL_HDC(hdc)
17341 #define DECLARE_HDC(hdc)
17342 #define ALLOCATE_HDC(hdc, f)
17343 #define RELEASE_HDC(hdc, f)
17344 #endif
17346 static void
17347 init_glyph_string (s, OPTIONAL_HDC (hdc) char2b, w, row, area, start, hl)
17348 struct glyph_string *s;
17349 DECLARE_HDC (hdc)
17350 XChar2b *char2b;
17351 struct window *w;
17352 struct glyph_row *row;
17353 enum glyph_row_area area;
17354 int start;
17355 enum draw_glyphs_face hl;
17357 bzero (s, sizeof *s);
17358 s->w = w;
17359 s->f = XFRAME (w->frame);
17360 #ifdef HAVE_NTGUI
17361 s->hdc = hdc;
17362 #endif
17363 s->display = FRAME_X_DISPLAY (s->f);
17364 s->window = FRAME_X_WINDOW (s->f);
17365 s->char2b = char2b;
17366 s->hl = hl;
17367 s->row = row;
17368 s->area = area;
17369 s->first_glyph = row->glyphs[area] + start;
17370 s->height = row->height;
17371 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
17373 /* Display the internal border below the tool-bar window. */
17374 if (WINDOWP (s->f->tool_bar_window)
17375 && s->w == XWINDOW (s->f->tool_bar_window))
17376 s->y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
17378 s->ybase = s->y + row->ascent;
17382 /* Append the list of glyph strings with head H and tail T to the list
17383 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
17385 static INLINE void
17386 append_glyph_string_lists (head, tail, h, t)
17387 struct glyph_string **head, **tail;
17388 struct glyph_string *h, *t;
17390 if (h)
17392 if (*head)
17393 (*tail)->next = h;
17394 else
17395 *head = h;
17396 h->prev = *tail;
17397 *tail = t;
17402 /* Prepend the list of glyph strings with head H and tail T to the
17403 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
17404 result. */
17406 static INLINE void
17407 prepend_glyph_string_lists (head, tail, h, t)
17408 struct glyph_string **head, **tail;
17409 struct glyph_string *h, *t;
17411 if (h)
17413 if (*head)
17414 (*head)->prev = t;
17415 else
17416 *tail = t;
17417 t->next = *head;
17418 *head = h;
17423 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
17424 Set *HEAD and *TAIL to the resulting list. */
17426 static INLINE void
17427 append_glyph_string (head, tail, s)
17428 struct glyph_string **head, **tail;
17429 struct glyph_string *s;
17431 s->next = s->prev = NULL;
17432 append_glyph_string_lists (head, tail, s, s);
17436 /* Get face and two-byte form of character glyph GLYPH on frame F.
17437 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
17438 a pointer to a realized face that is ready for display. */
17440 static INLINE struct face *
17441 get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
17442 struct frame *f;
17443 struct glyph *glyph;
17444 XChar2b *char2b;
17445 int *two_byte_p;
17447 struct face *face;
17449 xassert (glyph->type == CHAR_GLYPH);
17450 face = FACE_FROM_ID (f, glyph->face_id);
17452 if (two_byte_p)
17453 *two_byte_p = 0;
17455 if (!glyph->multibyte_p)
17457 /* Unibyte case. We don't have to encode, but we have to make
17458 sure to use a face suitable for unibyte. */
17459 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
17461 else if (glyph->u.ch < 128
17462 && glyph->face_id < BASIC_FACE_ID_SENTINEL)
17464 /* Case of ASCII in a face known to fit ASCII. */
17465 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
17467 else
17469 int c1, c2, charset;
17471 /* Split characters into bytes. If c2 is -1 afterwards, C is
17472 really a one-byte character so that byte1 is zero. */
17473 SPLIT_CHAR (glyph->u.ch, charset, c1, c2);
17474 if (c2 > 0)
17475 STORE_XCHAR2B (char2b, c1, c2);
17476 else
17477 STORE_XCHAR2B (char2b, 0, c1);
17479 /* Maybe encode the character in *CHAR2B. */
17480 if (charset != CHARSET_ASCII)
17482 struct font_info *font_info
17483 = FONT_INFO_FROM_ID (f, face->font_info_id);
17484 if (font_info)
17485 glyph->font_type
17486 = rif->encode_char (glyph->u.ch, char2b, font_info, two_byte_p);
17490 /* Make sure X resources of the face are allocated. */
17491 xassert (face != NULL);
17492 PREPARE_FACE_FOR_DISPLAY (f, face);
17493 return face;
17497 /* Fill glyph string S with composition components specified by S->cmp.
17499 FACES is an array of faces for all components of this composition.
17500 S->gidx is the index of the first component for S.
17501 OVERLAPS_P non-zero means S should draw the foreground only, and
17502 use its physical height for clipping.
17504 Value is the index of a component not in S. */
17506 static int
17507 fill_composite_glyph_string (s, faces, overlaps_p)
17508 struct glyph_string *s;
17509 struct face **faces;
17510 int overlaps_p;
17512 int i;
17514 xassert (s);
17516 s->for_overlaps_p = overlaps_p;
17518 s->face = faces[s->gidx];
17519 s->font = s->face->font;
17520 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
17522 /* For all glyphs of this composition, starting at the offset
17523 S->gidx, until we reach the end of the definition or encounter a
17524 glyph that requires the different face, add it to S. */
17525 ++s->nchars;
17526 for (i = s->gidx + 1; i < s->cmp->glyph_len && faces[i] == s->face; ++i)
17527 ++s->nchars;
17529 /* All glyph strings for the same composition has the same width,
17530 i.e. the width set for the first component of the composition. */
17532 s->width = s->first_glyph->pixel_width;
17534 /* If the specified font could not be loaded, use the frame's
17535 default font, but record the fact that we couldn't load it in
17536 the glyph string so that we can draw rectangles for the
17537 characters of the glyph string. */
17538 if (s->font == NULL)
17540 s->font_not_found_p = 1;
17541 s->font = FRAME_FONT (s->f);
17544 /* Adjust base line for subscript/superscript text. */
17545 s->ybase += s->first_glyph->voffset;
17547 xassert (s->face && s->face->gc);
17549 /* This glyph string must always be drawn with 16-bit functions. */
17550 s->two_byte_p = 1;
17552 return s->gidx + s->nchars;
17556 /* Fill glyph string S from a sequence of character glyphs.
17558 FACE_ID is the face id of the string. START is the index of the
17559 first glyph to consider, END is the index of the last + 1.
17560 OVERLAPS_P non-zero means S should draw the foreground only, and
17561 use its physical height for clipping.
17563 Value is the index of the first glyph not in S. */
17565 static int
17566 fill_glyph_string (s, face_id, start, end, overlaps_p)
17567 struct glyph_string *s;
17568 int face_id;
17569 int start, end, overlaps_p;
17571 struct glyph *glyph, *last;
17572 int voffset;
17573 int glyph_not_available_p;
17575 xassert (s->f == XFRAME (s->w->frame));
17576 xassert (s->nchars == 0);
17577 xassert (start >= 0 && end > start);
17579 s->for_overlaps_p = overlaps_p,
17580 glyph = s->row->glyphs[s->area] + start;
17581 last = s->row->glyphs[s->area] + end;
17582 voffset = glyph->voffset;
17584 glyph_not_available_p = glyph->glyph_not_available_p;
17586 while (glyph < last
17587 && glyph->type == CHAR_GLYPH
17588 && glyph->voffset == voffset
17589 /* Same face id implies same font, nowadays. */
17590 && glyph->face_id == face_id
17591 && glyph->glyph_not_available_p == glyph_not_available_p)
17593 int two_byte_p;
17595 s->face = get_glyph_face_and_encoding (s->f, glyph,
17596 s->char2b + s->nchars,
17597 &two_byte_p);
17598 s->two_byte_p = two_byte_p;
17599 ++s->nchars;
17600 xassert (s->nchars <= end - start);
17601 s->width += glyph->pixel_width;
17602 ++glyph;
17605 s->font = s->face->font;
17606 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
17608 /* If the specified font could not be loaded, use the frame's font,
17609 but record the fact that we couldn't load it in
17610 S->font_not_found_p so that we can draw rectangles for the
17611 characters of the glyph string. */
17612 if (s->font == NULL || glyph_not_available_p)
17614 s->font_not_found_p = 1;
17615 s->font = FRAME_FONT (s->f);
17618 /* Adjust base line for subscript/superscript text. */
17619 s->ybase += voffset;
17621 xassert (s->face && s->face->gc);
17622 return glyph - s->row->glyphs[s->area];
17626 /* Fill glyph string S from image glyph S->first_glyph. */
17628 static void
17629 fill_image_glyph_string (s)
17630 struct glyph_string *s;
17632 xassert (s->first_glyph->type == IMAGE_GLYPH);
17633 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
17634 xassert (s->img);
17635 s->slice = s->first_glyph->slice;
17636 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
17637 s->font = s->face->font;
17638 s->width = s->first_glyph->pixel_width;
17640 /* Adjust base line for subscript/superscript text. */
17641 s->ybase += s->first_glyph->voffset;
17645 /* Fill glyph string S from a sequence of stretch glyphs.
17647 ROW is the glyph row in which the glyphs are found, AREA is the
17648 area within the row. START is the index of the first glyph to
17649 consider, END is the index of the last + 1.
17651 Value is the index of the first glyph not in S. */
17653 static int
17654 fill_stretch_glyph_string (s, row, area, start, end)
17655 struct glyph_string *s;
17656 struct glyph_row *row;
17657 enum glyph_row_area area;
17658 int start, end;
17660 struct glyph *glyph, *last;
17661 int voffset, face_id;
17663 xassert (s->first_glyph->type == STRETCH_GLYPH);
17665 glyph = s->row->glyphs[s->area] + start;
17666 last = s->row->glyphs[s->area] + end;
17667 face_id = glyph->face_id;
17668 s->face = FACE_FROM_ID (s->f, face_id);
17669 s->font = s->face->font;
17670 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
17671 s->width = glyph->pixel_width;
17672 voffset = glyph->voffset;
17674 for (++glyph;
17675 (glyph < last
17676 && glyph->type == STRETCH_GLYPH
17677 && glyph->voffset == voffset
17678 && glyph->face_id == face_id);
17679 ++glyph)
17680 s->width += glyph->pixel_width;
17682 /* Adjust base line for subscript/superscript text. */
17683 s->ybase += voffset;
17685 /* The case that face->gc == 0 is handled when drawing the glyph
17686 string by calling PREPARE_FACE_FOR_DISPLAY. */
17687 xassert (s->face);
17688 return glyph - s->row->glyphs[s->area];
17692 /* EXPORT for RIF:
17693 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
17694 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
17695 assumed to be zero. */
17697 void
17698 x_get_glyph_overhangs (glyph, f, left, right)
17699 struct glyph *glyph;
17700 struct frame *f;
17701 int *left, *right;
17703 *left = *right = 0;
17705 if (glyph->type == CHAR_GLYPH)
17707 XFontStruct *font;
17708 struct face *face;
17709 struct font_info *font_info;
17710 XChar2b char2b;
17711 XCharStruct *pcm;
17713 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
17714 font = face->font;
17715 font_info = FONT_INFO_FROM_ID (f, face->font_info_id);
17716 if (font /* ++KFS: Should this be font_info ? */
17717 && (pcm = rif->per_char_metric (font, &char2b, glyph->font_type)))
17719 if (pcm->rbearing > pcm->width)
17720 *right = pcm->rbearing - pcm->width;
17721 if (pcm->lbearing < 0)
17722 *left = -pcm->lbearing;
17728 /* Return the index of the first glyph preceding glyph string S that
17729 is overwritten by S because of S's left overhang. Value is -1
17730 if no glyphs are overwritten. */
17732 static int
17733 left_overwritten (s)
17734 struct glyph_string *s;
17736 int k;
17738 if (s->left_overhang)
17740 int x = 0, i;
17741 struct glyph *glyphs = s->row->glyphs[s->area];
17742 int first = s->first_glyph - glyphs;
17744 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
17745 x -= glyphs[i].pixel_width;
17747 k = i + 1;
17749 else
17750 k = -1;
17752 return k;
17756 /* Return the index of the first glyph preceding glyph string S that
17757 is overwriting S because of its right overhang. Value is -1 if no
17758 glyph in front of S overwrites S. */
17760 static int
17761 left_overwriting (s)
17762 struct glyph_string *s;
17764 int i, k, x;
17765 struct glyph *glyphs = s->row->glyphs[s->area];
17766 int first = s->first_glyph - glyphs;
17768 k = -1;
17769 x = 0;
17770 for (i = first - 1; i >= 0; --i)
17772 int left, right;
17773 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
17774 if (x + right > 0)
17775 k = i;
17776 x -= glyphs[i].pixel_width;
17779 return k;
17783 /* Return the index of the last glyph following glyph string S that is
17784 not overwritten by S because of S's right overhang. Value is -1 if
17785 no such glyph is found. */
17787 static int
17788 right_overwritten (s)
17789 struct glyph_string *s;
17791 int k = -1;
17793 if (s->right_overhang)
17795 int x = 0, i;
17796 struct glyph *glyphs = s->row->glyphs[s->area];
17797 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
17798 int end = s->row->used[s->area];
17800 for (i = first; i < end && s->right_overhang > x; ++i)
17801 x += glyphs[i].pixel_width;
17803 k = i;
17806 return k;
17810 /* Return the index of the last glyph following glyph string S that
17811 overwrites S because of its left overhang. Value is negative
17812 if no such glyph is found. */
17814 static int
17815 right_overwriting (s)
17816 struct glyph_string *s;
17818 int i, k, x;
17819 int end = s->row->used[s->area];
17820 struct glyph *glyphs = s->row->glyphs[s->area];
17821 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
17823 k = -1;
17824 x = 0;
17825 for (i = first; i < end; ++i)
17827 int left, right;
17828 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
17829 if (x - left < 0)
17830 k = i;
17831 x += glyphs[i].pixel_width;
17834 return k;
17838 /* Get face and two-byte form of character C in face FACE_ID on frame
17839 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
17840 means we want to display multibyte text. DISPLAY_P non-zero means
17841 make sure that X resources for the face returned are allocated.
17842 Value is a pointer to a realized face that is ready for display if
17843 DISPLAY_P is non-zero. */
17845 static INLINE struct face *
17846 get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p, display_p)
17847 struct frame *f;
17848 int c, face_id;
17849 XChar2b *char2b;
17850 int multibyte_p, display_p;
17852 struct face *face = FACE_FROM_ID (f, face_id);
17854 if (!multibyte_p)
17856 /* Unibyte case. We don't have to encode, but we have to make
17857 sure to use a face suitable for unibyte. */
17858 STORE_XCHAR2B (char2b, 0, c);
17859 face_id = FACE_FOR_CHAR (f, face, c);
17860 face = FACE_FROM_ID (f, face_id);
17862 else if (c < 128 && face_id < BASIC_FACE_ID_SENTINEL)
17864 /* Case of ASCII in a face known to fit ASCII. */
17865 STORE_XCHAR2B (char2b, 0, c);
17867 else
17869 int c1, c2, charset;
17871 /* Split characters into bytes. If c2 is -1 afterwards, C is
17872 really a one-byte character so that byte1 is zero. */
17873 SPLIT_CHAR (c, charset, c1, c2);
17874 if (c2 > 0)
17875 STORE_XCHAR2B (char2b, c1, c2);
17876 else
17877 STORE_XCHAR2B (char2b, 0, c1);
17879 /* Maybe encode the character in *CHAR2B. */
17880 if (face->font != NULL)
17882 struct font_info *font_info
17883 = FONT_INFO_FROM_ID (f, face->font_info_id);
17884 if (font_info)
17885 rif->encode_char (c, char2b, font_info, 0);
17889 /* Make sure X resources of the face are allocated. */
17890 #ifdef HAVE_X_WINDOWS
17891 if (display_p)
17892 #endif
17894 xassert (face != NULL);
17895 PREPARE_FACE_FOR_DISPLAY (f, face);
17898 return face;
17902 /* Set background width of glyph string S. START is the index of the
17903 first glyph following S. LAST_X is the right-most x-position + 1
17904 in the drawing area. */
17906 static INLINE void
17907 set_glyph_string_background_width (s, start, last_x)
17908 struct glyph_string *s;
17909 int start;
17910 int last_x;
17912 /* If the face of this glyph string has to be drawn to the end of
17913 the drawing area, set S->extends_to_end_of_line_p. */
17914 struct face *default_face = FACE_FROM_ID (s->f, DEFAULT_FACE_ID);
17916 if (start == s->row->used[s->area]
17917 && s->area == TEXT_AREA
17918 && ((s->hl == DRAW_NORMAL_TEXT
17919 && (s->row->fill_line_p
17920 || s->face->background != default_face->background
17921 || s->face->stipple != default_face->stipple
17922 || s->row->mouse_face_p))
17923 || s->hl == DRAW_MOUSE_FACE
17924 || ((s->hl == DRAW_IMAGE_RAISED || s->hl == DRAW_IMAGE_SUNKEN)
17925 && s->row->fill_line_p)))
17926 s->extends_to_end_of_line_p = 1;
17928 /* If S extends its face to the end of the line, set its
17929 background_width to the distance to the right edge of the drawing
17930 area. */
17931 if (s->extends_to_end_of_line_p)
17932 s->background_width = last_x - s->x + 1;
17933 else
17934 s->background_width = s->width;
17938 /* Compute overhangs and x-positions for glyph string S and its
17939 predecessors, or successors. X is the starting x-position for S.
17940 BACKWARD_P non-zero means process predecessors. */
17942 static void
17943 compute_overhangs_and_x (s, x, backward_p)
17944 struct glyph_string *s;
17945 int x;
17946 int backward_p;
17948 if (backward_p)
17950 while (s)
17952 if (rif->compute_glyph_string_overhangs)
17953 rif->compute_glyph_string_overhangs (s);
17954 x -= s->width;
17955 s->x = x;
17956 s = s->prev;
17959 else
17961 while (s)
17963 if (rif->compute_glyph_string_overhangs)
17964 rif->compute_glyph_string_overhangs (s);
17965 s->x = x;
17966 x += s->width;
17967 s = s->next;
17974 /* The following macros are only called from draw_glyphs below.
17975 They reference the following parameters of that function directly:
17976 `w', `row', `area', and `overlap_p'
17977 as well as the following local variables:
17978 `s', `f', and `hdc' (in W32) */
17980 #ifdef HAVE_NTGUI
17981 /* On W32, silently add local `hdc' variable to argument list of
17982 init_glyph_string. */
17983 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
17984 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
17985 #else
17986 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
17987 init_glyph_string (s, char2b, w, row, area, start, hl)
17988 #endif
17990 /* Add a glyph string for a stretch glyph to the list of strings
17991 between HEAD and TAIL. START is the index of the stretch glyph in
17992 row area AREA of glyph row ROW. END is the index of the last glyph
17993 in that glyph row area. X is the current output position assigned
17994 to the new glyph string constructed. HL overrides that face of the
17995 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
17996 is the right-most x-position of the drawing area. */
17998 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
17999 and below -- keep them on one line. */
18000 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
18001 do \
18003 s = (struct glyph_string *) alloca (sizeof *s); \
18004 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
18005 START = fill_stretch_glyph_string (s, row, area, START, END); \
18006 append_glyph_string (&HEAD, &TAIL, s); \
18007 s->x = (X); \
18009 while (0)
18012 /* Add a glyph string for an image glyph to the list of strings
18013 between HEAD and TAIL. START is the index of the image glyph in
18014 row area AREA of glyph row ROW. END is the index of the last glyph
18015 in that glyph row area. X is the current output position assigned
18016 to the new glyph string constructed. HL overrides that face of the
18017 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
18018 is the right-most x-position of the drawing area. */
18020 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
18021 do \
18023 s = (struct glyph_string *) alloca (sizeof *s); \
18024 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
18025 fill_image_glyph_string (s); \
18026 append_glyph_string (&HEAD, &TAIL, s); \
18027 ++START; \
18028 s->x = (X); \
18030 while (0)
18033 /* Add a glyph string for a sequence of character glyphs to the list
18034 of strings between HEAD and TAIL. START is the index of the first
18035 glyph in row area AREA of glyph row ROW that is part of the new
18036 glyph string. END is the index of the last glyph in that glyph row
18037 area. X is the current output position assigned to the new glyph
18038 string constructed. HL overrides that face of the glyph; e.g. it
18039 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
18040 right-most x-position of the drawing area. */
18042 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
18043 do \
18045 int c, face_id; \
18046 XChar2b *char2b; \
18048 c = (row)->glyphs[area][START].u.ch; \
18049 face_id = (row)->glyphs[area][START].face_id; \
18051 s = (struct glyph_string *) alloca (sizeof *s); \
18052 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
18053 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
18054 append_glyph_string (&HEAD, &TAIL, s); \
18055 s->x = (X); \
18056 START = fill_glyph_string (s, face_id, START, END, overlaps_p); \
18058 while (0)
18061 /* Add a glyph string for a composite sequence to the list of strings
18062 between HEAD and TAIL. START is the index of the first glyph in
18063 row area AREA of glyph row ROW that is part of the new glyph
18064 string. END is the index of the last glyph in that glyph row area.
18065 X is the current output position assigned to the new glyph string
18066 constructed. HL overrides that face of the glyph; e.g. it is
18067 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
18068 x-position of the drawing area. */
18070 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
18071 do { \
18072 int cmp_id = (row)->glyphs[area][START].u.cmp_id; \
18073 int face_id = (row)->glyphs[area][START].face_id; \
18074 struct face *base_face = FACE_FROM_ID (f, face_id); \
18075 struct composition *cmp = composition_table[cmp_id]; \
18076 int glyph_len = cmp->glyph_len; \
18077 XChar2b *char2b; \
18078 struct face **faces; \
18079 struct glyph_string *first_s = NULL; \
18080 int n; \
18082 base_face = base_face->ascii_face; \
18083 char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len); \
18084 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
18085 /* At first, fill in `char2b' and `faces'. */ \
18086 for (n = 0; n < glyph_len; n++) \
18088 int c = COMPOSITION_GLYPH (cmp, n); \
18089 int this_face_id = FACE_FOR_CHAR (f, base_face, c); \
18090 faces[n] = FACE_FROM_ID (f, this_face_id); \
18091 get_char_face_and_encoding (f, c, this_face_id, \
18092 char2b + n, 1, 1); \
18095 /* Make glyph_strings for each glyph sequence that is drawable by \
18096 the same face, and append them to HEAD/TAIL. */ \
18097 for (n = 0; n < cmp->glyph_len;) \
18099 s = (struct glyph_string *) alloca (sizeof *s); \
18100 INIT_GLYPH_STRING (s, char2b + n, w, row, area, START, HL); \
18101 append_glyph_string (&(HEAD), &(TAIL), s); \
18102 s->cmp = cmp; \
18103 s->gidx = n; \
18104 s->x = (X); \
18106 if (n == 0) \
18107 first_s = s; \
18109 n = fill_composite_glyph_string (s, faces, overlaps_p); \
18112 ++START; \
18113 s = first_s; \
18114 } while (0)
18117 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
18118 of AREA of glyph row ROW on window W between indices START and END.
18119 HL overrides the face for drawing glyph strings, e.g. it is
18120 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
18121 x-positions of the drawing area.
18123 This is an ugly monster macro construct because we must use alloca
18124 to allocate glyph strings (because draw_glyphs can be called
18125 asynchronously). */
18127 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
18128 do \
18130 HEAD = TAIL = NULL; \
18131 while (START < END) \
18133 struct glyph *first_glyph = (row)->glyphs[area] + START; \
18134 switch (first_glyph->type) \
18136 case CHAR_GLYPH: \
18137 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
18138 HL, X, LAST_X); \
18139 break; \
18141 case COMPOSITE_GLYPH: \
18142 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
18143 HL, X, LAST_X); \
18144 break; \
18146 case STRETCH_GLYPH: \
18147 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
18148 HL, X, LAST_X); \
18149 break; \
18151 case IMAGE_GLYPH: \
18152 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
18153 HL, X, LAST_X); \
18154 break; \
18156 default: \
18157 abort (); \
18160 set_glyph_string_background_width (s, START, LAST_X); \
18161 (X) += s->width; \
18164 while (0)
18167 /* Draw glyphs between START and END in AREA of ROW on window W,
18168 starting at x-position X. X is relative to AREA in W. HL is a
18169 face-override with the following meaning:
18171 DRAW_NORMAL_TEXT draw normally
18172 DRAW_CURSOR draw in cursor face
18173 DRAW_MOUSE_FACE draw in mouse face.
18174 DRAW_INVERSE_VIDEO draw in mode line face
18175 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
18176 DRAW_IMAGE_RAISED draw an image with a raised relief around it
18178 If OVERLAPS_P is non-zero, draw only the foreground of characters
18179 and clip to the physical height of ROW.
18181 Value is the x-position reached, relative to AREA of W. */
18183 static int
18184 draw_glyphs (w, x, row, area, start, end, hl, overlaps_p)
18185 struct window *w;
18186 int x;
18187 struct glyph_row *row;
18188 enum glyph_row_area area;
18189 int start, end;
18190 enum draw_glyphs_face hl;
18191 int overlaps_p;
18193 struct glyph_string *head, *tail;
18194 struct glyph_string *s;
18195 int last_x, area_width;
18196 int x_reached;
18197 int i, j;
18198 struct frame *f = XFRAME (WINDOW_FRAME (w));
18199 DECLARE_HDC (hdc);
18201 ALLOCATE_HDC (hdc, f);
18203 /* Let's rather be paranoid than getting a SEGV. */
18204 end = min (end, row->used[area]);
18205 start = max (0, start);
18206 start = min (end, start);
18208 /* Translate X to frame coordinates. Set last_x to the right
18209 end of the drawing area. */
18210 if (row->full_width_p)
18212 /* X is relative to the left edge of W, without scroll bars
18213 or fringes. */
18214 x += WINDOW_LEFT_EDGE_X (w);
18215 last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
18217 else
18219 int area_left = window_box_left (w, area);
18220 x += area_left;
18221 area_width = window_box_width (w, area);
18222 last_x = area_left + area_width;
18225 /* Build a doubly-linked list of glyph_string structures between
18226 head and tail from what we have to draw. Note that the macro
18227 BUILD_GLYPH_STRINGS will modify its start parameter. That's
18228 the reason we use a separate variable `i'. */
18229 i = start;
18230 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
18231 if (tail)
18232 x_reached = tail->x + tail->background_width;
18233 else
18234 x_reached = x;
18236 /* If there are any glyphs with lbearing < 0 or rbearing > width in
18237 the row, redraw some glyphs in front or following the glyph
18238 strings built above. */
18239 if (head && !overlaps_p && row->contains_overlapping_glyphs_p)
18241 int dummy_x = 0;
18242 struct glyph_string *h, *t;
18244 /* Compute overhangs for all glyph strings. */
18245 if (rif->compute_glyph_string_overhangs)
18246 for (s = head; s; s = s->next)
18247 rif->compute_glyph_string_overhangs (s);
18249 /* Prepend glyph strings for glyphs in front of the first glyph
18250 string that are overwritten because of the first glyph
18251 string's left overhang. The background of all strings
18252 prepended must be drawn because the first glyph string
18253 draws over it. */
18254 i = left_overwritten (head);
18255 if (i >= 0)
18257 j = i;
18258 BUILD_GLYPH_STRINGS (j, start, h, t,
18259 DRAW_NORMAL_TEXT, dummy_x, last_x);
18260 start = i;
18261 compute_overhangs_and_x (t, head->x, 1);
18262 prepend_glyph_string_lists (&head, &tail, h, t);
18265 /* Prepend glyph strings for glyphs in front of the first glyph
18266 string that overwrite that glyph string because of their
18267 right overhang. For these strings, only the foreground must
18268 be drawn, because it draws over the glyph string at `head'.
18269 The background must not be drawn because this would overwrite
18270 right overhangs of preceding glyphs for which no glyph
18271 strings exist. */
18272 i = left_overwriting (head);
18273 if (i >= 0)
18275 BUILD_GLYPH_STRINGS (i, start, h, t,
18276 DRAW_NORMAL_TEXT, dummy_x, last_x);
18277 for (s = h; s; s = s->next)
18278 s->background_filled_p = 1;
18279 compute_overhangs_and_x (t, head->x, 1);
18280 prepend_glyph_string_lists (&head, &tail, h, t);
18283 /* Append glyphs strings for glyphs following the last glyph
18284 string tail that are overwritten by tail. The background of
18285 these strings has to be drawn because tail's foreground draws
18286 over it. */
18287 i = right_overwritten (tail);
18288 if (i >= 0)
18290 BUILD_GLYPH_STRINGS (end, i, h, t,
18291 DRAW_NORMAL_TEXT, x, last_x);
18292 compute_overhangs_and_x (h, tail->x + tail->width, 0);
18293 append_glyph_string_lists (&head, &tail, h, t);
18296 /* Append glyph strings for glyphs following the last glyph
18297 string tail that overwrite tail. The foreground of such
18298 glyphs has to be drawn because it writes into the background
18299 of tail. The background must not be drawn because it could
18300 paint over the foreground of following glyphs. */
18301 i = right_overwriting (tail);
18302 if (i >= 0)
18304 BUILD_GLYPH_STRINGS (end, i, h, t,
18305 DRAW_NORMAL_TEXT, x, last_x);
18306 for (s = h; s; s = s->next)
18307 s->background_filled_p = 1;
18308 compute_overhangs_and_x (h, tail->x + tail->width, 0);
18309 append_glyph_string_lists (&head, &tail, h, t);
18313 /* Draw all strings. */
18314 for (s = head; s; s = s->next)
18315 rif->draw_glyph_string (s);
18317 if (area == TEXT_AREA
18318 && !row->full_width_p
18319 /* When drawing overlapping rows, only the glyph strings'
18320 foreground is drawn, which doesn't erase a cursor
18321 completely. */
18322 && !overlaps_p)
18324 int x0 = head ? head->x : x;
18325 int x1 = tail ? tail->x + tail->background_width : x;
18327 int text_left = window_box_left (w, TEXT_AREA);
18328 x0 -= text_left;
18329 x1 -= text_left;
18331 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
18332 row->y, MATRIX_ROW_BOTTOM_Y (row));
18335 /* Value is the x-position up to which drawn, relative to AREA of W.
18336 This doesn't include parts drawn because of overhangs. */
18337 if (row->full_width_p)
18338 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
18339 else
18340 x_reached -= window_box_left (w, area);
18342 RELEASE_HDC (hdc, f);
18344 return x_reached;
18347 /* Expand row matrix if too narrow. Don't expand if area
18348 is not present. */
18350 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
18352 if (!fonts_changed_p \
18353 && (it->glyph_row->glyphs[area] \
18354 < it->glyph_row->glyphs[area + 1])) \
18356 it->w->ncols_scale_factor++; \
18357 fonts_changed_p = 1; \
18361 /* Store one glyph for IT->char_to_display in IT->glyph_row.
18362 Called from x_produce_glyphs when IT->glyph_row is non-null. */
18364 static INLINE void
18365 append_glyph (it)
18366 struct it *it;
18368 struct glyph *glyph;
18369 enum glyph_row_area area = it->area;
18371 xassert (it->glyph_row);
18372 xassert (it->char_to_display != '\n' && it->char_to_display != '\t');
18374 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18375 if (glyph < it->glyph_row->glyphs[area + 1])
18377 glyph->charpos = CHARPOS (it->position);
18378 glyph->object = it->object;
18379 glyph->pixel_width = it->pixel_width;
18380 glyph->ascent = it->ascent;
18381 glyph->descent = it->descent;
18382 glyph->voffset = it->voffset;
18383 glyph->type = CHAR_GLYPH;
18384 glyph->multibyte_p = it->multibyte_p;
18385 glyph->left_box_line_p = it->start_of_box_run_p;
18386 glyph->right_box_line_p = it->end_of_box_run_p;
18387 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
18388 || it->phys_descent > it->descent);
18389 glyph->padding_p = 0;
18390 glyph->glyph_not_available_p = it->glyph_not_available_p;
18391 glyph->face_id = it->face_id;
18392 glyph->u.ch = it->char_to_display;
18393 glyph->slice = null_glyph_slice;
18394 glyph->font_type = FONT_TYPE_UNKNOWN;
18395 ++it->glyph_row->used[area];
18397 else
18398 IT_EXPAND_MATRIX_WIDTH (it, area);
18401 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
18402 Called from x_produce_glyphs when IT->glyph_row is non-null. */
18404 static INLINE void
18405 append_composite_glyph (it)
18406 struct it *it;
18408 struct glyph *glyph;
18409 enum glyph_row_area area = it->area;
18411 xassert (it->glyph_row);
18413 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18414 if (glyph < it->glyph_row->glyphs[area + 1])
18416 glyph->charpos = CHARPOS (it->position);
18417 glyph->object = it->object;
18418 glyph->pixel_width = it->pixel_width;
18419 glyph->ascent = it->ascent;
18420 glyph->descent = it->descent;
18421 glyph->voffset = it->voffset;
18422 glyph->type = COMPOSITE_GLYPH;
18423 glyph->multibyte_p = it->multibyte_p;
18424 glyph->left_box_line_p = it->start_of_box_run_p;
18425 glyph->right_box_line_p = it->end_of_box_run_p;
18426 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
18427 || it->phys_descent > it->descent);
18428 glyph->padding_p = 0;
18429 glyph->glyph_not_available_p = 0;
18430 glyph->face_id = it->face_id;
18431 glyph->u.cmp_id = it->cmp_id;
18432 glyph->slice = null_glyph_slice;
18433 glyph->font_type = FONT_TYPE_UNKNOWN;
18434 ++it->glyph_row->used[area];
18436 else
18437 IT_EXPAND_MATRIX_WIDTH (it, area);
18441 /* Change IT->ascent and IT->height according to the setting of
18442 IT->voffset. */
18444 static INLINE void
18445 take_vertical_position_into_account (it)
18446 struct it *it;
18448 if (it->voffset)
18450 if (it->voffset < 0)
18451 /* Increase the ascent so that we can display the text higher
18452 in the line. */
18453 it->ascent -= it->voffset;
18454 else
18455 /* Increase the descent so that we can display the text lower
18456 in the line. */
18457 it->descent += it->voffset;
18462 /* Produce glyphs/get display metrics for the image IT is loaded with.
18463 See the description of struct display_iterator in dispextern.h for
18464 an overview of struct display_iterator. */
18466 static void
18467 produce_image_glyph (it)
18468 struct it *it;
18470 struct image *img;
18471 struct face *face;
18472 int glyph_ascent;
18473 struct glyph_slice slice;
18475 xassert (it->what == IT_IMAGE);
18477 face = FACE_FROM_ID (it->f, it->face_id);
18478 xassert (face);
18479 /* Make sure X resources of the face is loaded. */
18480 PREPARE_FACE_FOR_DISPLAY (it->f, face);
18482 if (it->image_id < 0)
18484 /* Fringe bitmap. */
18485 it->ascent = it->phys_ascent = 0;
18486 it->descent = it->phys_descent = 0;
18487 it->pixel_width = 0;
18488 it->nglyphs = 0;
18489 return;
18492 img = IMAGE_FROM_ID (it->f, it->image_id);
18493 xassert (img);
18494 /* Make sure X resources of the image is loaded. */
18495 prepare_image_for_display (it->f, img);
18497 slice.x = slice.y = 0;
18498 slice.width = img->width;
18499 slice.height = img->height;
18501 if (INTEGERP (it->slice.x))
18502 slice.x = XINT (it->slice.x);
18503 else if (FLOATP (it->slice.x))
18504 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
18506 if (INTEGERP (it->slice.y))
18507 slice.y = XINT (it->slice.y);
18508 else if (FLOATP (it->slice.y))
18509 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
18511 if (INTEGERP (it->slice.width))
18512 slice.width = XINT (it->slice.width);
18513 else if (FLOATP (it->slice.width))
18514 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
18516 if (INTEGERP (it->slice.height))
18517 slice.height = XINT (it->slice.height);
18518 else if (FLOATP (it->slice.height))
18519 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
18521 if (slice.x >= img->width)
18522 slice.x = img->width;
18523 if (slice.y >= img->height)
18524 slice.y = img->height;
18525 if (slice.x + slice.width >= img->width)
18526 slice.width = img->width - slice.x;
18527 if (slice.y + slice.height > img->height)
18528 slice.height = img->height - slice.y;
18530 if (slice.width == 0 || slice.height == 0)
18531 return;
18533 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
18535 it->descent = slice.height - glyph_ascent;
18536 if (slice.y == 0)
18537 it->descent += img->vmargin;
18538 if (slice.y + slice.height == img->height)
18539 it->descent += img->vmargin;
18540 it->phys_descent = it->descent;
18542 it->pixel_width = slice.width;
18543 if (slice.x == 0)
18544 it->pixel_width += img->hmargin;
18545 if (slice.x + slice.width == img->width)
18546 it->pixel_width += img->hmargin;
18548 /* It's quite possible for images to have an ascent greater than
18549 their height, so don't get confused in that case. */
18550 if (it->descent < 0)
18551 it->descent = 0;
18553 #if 0 /* this breaks image tiling */
18554 /* If this glyph is alone on the last line, adjust it.ascent to minimum row ascent. */
18555 int face_ascent = face->font ? FONT_BASE (face->font) : FRAME_BASELINE_OFFSET (it->f);
18556 if (face_ascent > it->ascent)
18557 it->ascent = it->phys_ascent = face_ascent;
18558 #endif
18560 it->nglyphs = 1;
18562 if (face->box != FACE_NO_BOX)
18564 if (face->box_line_width > 0)
18566 if (slice.y == 0)
18567 it->ascent += face->box_line_width;
18568 if (slice.y + slice.height == img->height)
18569 it->descent += face->box_line_width;
18572 if (it->start_of_box_run_p && slice.x == 0)
18573 it->pixel_width += abs (face->box_line_width);
18574 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
18575 it->pixel_width += abs (face->box_line_width);
18578 take_vertical_position_into_account (it);
18580 if (it->glyph_row)
18582 struct glyph *glyph;
18583 enum glyph_row_area area = it->area;
18585 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18586 if (glyph < it->glyph_row->glyphs[area + 1])
18588 glyph->charpos = CHARPOS (it->position);
18589 glyph->object = it->object;
18590 glyph->pixel_width = it->pixel_width;
18591 glyph->ascent = glyph_ascent;
18592 glyph->descent = it->descent;
18593 glyph->voffset = it->voffset;
18594 glyph->type = IMAGE_GLYPH;
18595 glyph->multibyte_p = it->multibyte_p;
18596 glyph->left_box_line_p = it->start_of_box_run_p;
18597 glyph->right_box_line_p = it->end_of_box_run_p;
18598 glyph->overlaps_vertically_p = 0;
18599 glyph->padding_p = 0;
18600 glyph->glyph_not_available_p = 0;
18601 glyph->face_id = it->face_id;
18602 glyph->u.img_id = img->id;
18603 glyph->slice = slice;
18604 glyph->font_type = FONT_TYPE_UNKNOWN;
18605 ++it->glyph_row->used[area];
18607 else
18608 IT_EXPAND_MATRIX_WIDTH (it, area);
18613 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
18614 of the glyph, WIDTH and HEIGHT are the width and height of the
18615 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
18617 static void
18618 append_stretch_glyph (it, object, width, height, ascent)
18619 struct it *it;
18620 Lisp_Object object;
18621 int width, height;
18622 int ascent;
18624 struct glyph *glyph;
18625 enum glyph_row_area area = it->area;
18627 xassert (ascent >= 0 && ascent <= height);
18629 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18630 if (glyph < it->glyph_row->glyphs[area + 1])
18632 glyph->charpos = CHARPOS (it->position);
18633 glyph->object = object;
18634 glyph->pixel_width = width;
18635 glyph->ascent = ascent;
18636 glyph->descent = height - ascent;
18637 glyph->voffset = it->voffset;
18638 glyph->type = STRETCH_GLYPH;
18639 glyph->multibyte_p = it->multibyte_p;
18640 glyph->left_box_line_p = it->start_of_box_run_p;
18641 glyph->right_box_line_p = it->end_of_box_run_p;
18642 glyph->overlaps_vertically_p = 0;
18643 glyph->padding_p = 0;
18644 glyph->glyph_not_available_p = 0;
18645 glyph->face_id = it->face_id;
18646 glyph->u.stretch.ascent = ascent;
18647 glyph->u.stretch.height = height;
18648 glyph->slice = null_glyph_slice;
18649 glyph->font_type = FONT_TYPE_UNKNOWN;
18650 ++it->glyph_row->used[area];
18652 else
18653 IT_EXPAND_MATRIX_WIDTH (it, area);
18657 /* Produce a stretch glyph for iterator IT. IT->object is the value
18658 of the glyph property displayed. The value must be a list
18659 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
18660 being recognized:
18662 1. `:width WIDTH' specifies that the space should be WIDTH *
18663 canonical char width wide. WIDTH may be an integer or floating
18664 point number.
18666 2. `:relative-width FACTOR' specifies that the width of the stretch
18667 should be computed from the width of the first character having the
18668 `glyph' property, and should be FACTOR times that width.
18670 3. `:align-to HPOS' specifies that the space should be wide enough
18671 to reach HPOS, a value in canonical character units.
18673 Exactly one of the above pairs must be present.
18675 4. `:height HEIGHT' specifies that the height of the stretch produced
18676 should be HEIGHT, measured in canonical character units.
18678 5. `:relative-height FACTOR' specifies that the height of the
18679 stretch should be FACTOR times the height of the characters having
18680 the glyph property.
18682 Either none or exactly one of 4 or 5 must be present.
18684 6. `:ascent ASCENT' specifies that ASCENT percent of the height
18685 of the stretch should be used for the ascent of the stretch.
18686 ASCENT must be in the range 0 <= ASCENT <= 100. */
18688 static void
18689 produce_stretch_glyph (it)
18690 struct it *it;
18692 /* (space :width WIDTH :height HEIGHT ...) */
18693 Lisp_Object prop, plist;
18694 int width = 0, height = 0, align_to = -1;
18695 int zero_width_ok_p = 0, zero_height_ok_p = 0;
18696 int ascent = 0;
18697 double tem;
18698 struct face *face = FACE_FROM_ID (it->f, it->face_id);
18699 XFontStruct *font = face->font ? face->font : FRAME_FONT (it->f);
18701 PREPARE_FACE_FOR_DISPLAY (it->f, face);
18703 /* List should start with `space'. */
18704 xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
18705 plist = XCDR (it->object);
18707 /* Compute the width of the stretch. */
18708 if ((prop = Fsafe_plist_get (plist, QCwidth), !NILP (prop))
18709 && calc_pixel_width_or_height (&tem, it, prop, font, 1, 0))
18711 /* Absolute width `:width WIDTH' specified and valid. */
18712 zero_width_ok_p = 1;
18713 width = (int)tem;
18715 else if (prop = Fsafe_plist_get (plist, QCrelative_width),
18716 NUMVAL (prop) > 0)
18718 /* Relative width `:relative-width FACTOR' specified and valid.
18719 Compute the width of the characters having the `glyph'
18720 property. */
18721 struct it it2;
18722 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
18724 it2 = *it;
18725 if (it->multibyte_p)
18727 int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT)
18728 - IT_BYTEPOS (*it));
18729 it2.c = STRING_CHAR_AND_LENGTH (p, maxlen, it2.len);
18731 else
18732 it2.c = *p, it2.len = 1;
18734 it2.glyph_row = NULL;
18735 it2.what = IT_CHARACTER;
18736 x_produce_glyphs (&it2);
18737 width = NUMVAL (prop) * it2.pixel_width;
18739 else if ((prop = Fsafe_plist_get (plist, QCalign_to), !NILP (prop))
18740 && calc_pixel_width_or_height (&tem, it, prop, font, 1, &align_to))
18742 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
18743 align_to = (align_to < 0
18745 : align_to - window_box_left_offset (it->w, TEXT_AREA));
18746 else if (align_to < 0)
18747 align_to = window_box_left_offset (it->w, TEXT_AREA);
18748 width = max (0, (int)tem + align_to - it->current_x);
18749 zero_width_ok_p = 1;
18751 else
18752 /* Nothing specified -> width defaults to canonical char width. */
18753 width = FRAME_COLUMN_WIDTH (it->f);
18755 if (width <= 0 && (width < 0 || !zero_width_ok_p))
18756 width = 1;
18758 /* Compute height. */
18759 if ((prop = Fsafe_plist_get (plist, QCheight), !NILP (prop))
18760 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
18762 height = (int)tem;
18763 zero_height_ok_p = 1;
18765 else if (prop = Fsafe_plist_get (plist, QCrelative_height),
18766 NUMVAL (prop) > 0)
18767 height = FONT_HEIGHT (font) * NUMVAL (prop);
18768 else
18769 height = FONT_HEIGHT (font);
18771 if (height <= 0 && (height < 0 || !zero_height_ok_p))
18772 height = 1;
18774 /* Compute percentage of height used for ascent. If
18775 `:ascent ASCENT' is present and valid, use that. Otherwise,
18776 derive the ascent from the font in use. */
18777 if (prop = Fsafe_plist_get (plist, QCascent),
18778 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
18779 ascent = height * NUMVAL (prop) / 100.0;
18780 else if (!NILP (prop)
18781 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
18782 ascent = min (max (0, (int)tem), height);
18783 else
18784 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
18786 if (width > 0 && height > 0 && it->glyph_row)
18788 Lisp_Object object = it->stack[it->sp - 1].string;
18789 if (!STRINGP (object))
18790 object = it->w->buffer;
18791 append_stretch_glyph (it, object, width, height, ascent);
18794 it->pixel_width = width;
18795 it->ascent = it->phys_ascent = ascent;
18796 it->descent = it->phys_descent = height - it->ascent;
18797 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
18799 if (width > 0 && height > 0 && face->box != FACE_NO_BOX)
18801 if (face->box_line_width > 0)
18803 it->ascent += face->box_line_width;
18804 it->descent += face->box_line_width;
18807 if (it->start_of_box_run_p)
18808 it->pixel_width += abs (face->box_line_width);
18809 if (it->end_of_box_run_p)
18810 it->pixel_width += abs (face->box_line_width);
18813 take_vertical_position_into_account (it);
18816 /* Get line-height and line-spacing property at point.
18817 If line-height has format (HEIGHT TOTAL), return TOTAL
18818 in TOTAL_HEIGHT. */
18820 static Lisp_Object
18821 get_line_height_property (it, prop)
18822 struct it *it;
18823 Lisp_Object prop;
18825 Lisp_Object position, val;
18827 if (STRINGP (it->object))
18828 position = make_number (IT_STRING_CHARPOS (*it));
18829 else if (BUFFERP (it->object))
18830 position = make_number (IT_CHARPOS (*it));
18831 else
18832 return Qnil;
18834 return Fget_char_property (position, prop, it->object);
18837 /* Calculate line-height and line-spacing properties.
18838 An integer value specifies explicit pixel value.
18839 A float value specifies relative value to current face height.
18840 A cons (float . face-name) specifies relative value to
18841 height of specified face font.
18843 Returns height in pixels, or nil. */
18846 static Lisp_Object
18847 calc_line_height_property (it, val, font, boff, override)
18848 struct it *it;
18849 Lisp_Object val;
18850 XFontStruct *font;
18851 int boff, override;
18853 Lisp_Object face_name = Qnil;
18854 int ascent, descent, height;
18856 if (NILP (val) || INTEGERP (val) || (override && EQ (val, Qt)))
18857 return val;
18859 if (CONSP (val))
18861 face_name = XCAR (val);
18862 val = XCDR (val);
18863 if (!NUMBERP (val))
18864 val = make_number (1);
18865 if (NILP (face_name))
18867 height = it->ascent + it->descent;
18868 goto scale;
18872 if (NILP (face_name))
18874 font = FRAME_FONT (it->f);
18875 boff = FRAME_BASELINE_OFFSET (it->f);
18877 else if (EQ (face_name, Qt))
18879 override = 0;
18881 else
18883 int face_id;
18884 struct face *face;
18885 struct font_info *font_info;
18887 face_id = lookup_named_face (it->f, face_name, ' ', 0);
18888 if (face_id < 0)
18889 return make_number (-1);
18891 face = FACE_FROM_ID (it->f, face_id);
18892 font = face->font;
18893 if (font == NULL)
18894 return make_number (-1);
18896 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
18897 boff = font_info->baseline_offset;
18898 if (font_info->vertical_centering)
18899 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
18902 ascent = FONT_BASE (font) + boff;
18903 descent = FONT_DESCENT (font) - boff;
18905 if (override)
18907 it->override_ascent = ascent;
18908 it->override_descent = descent;
18909 it->override_boff = boff;
18912 height = ascent + descent;
18914 scale:
18915 if (FLOATP (val))
18916 height = (int)(XFLOAT_DATA (val) * height);
18917 else if (INTEGERP (val))
18918 height *= XINT (val);
18920 return make_number (height);
18924 /* RIF:
18925 Produce glyphs/get display metrics for the display element IT is
18926 loaded with. See the description of struct display_iterator in
18927 dispextern.h for an overview of struct display_iterator. */
18929 void
18930 x_produce_glyphs (it)
18931 struct it *it;
18933 int extra_line_spacing = it->extra_line_spacing;
18935 it->glyph_not_available_p = 0;
18937 if (it->what == IT_CHARACTER)
18939 XChar2b char2b;
18940 XFontStruct *font;
18941 struct face *face = FACE_FROM_ID (it->f, it->face_id);
18942 XCharStruct *pcm;
18943 int font_not_found_p;
18944 struct font_info *font_info;
18945 int boff; /* baseline offset */
18946 /* We may change it->multibyte_p upon unibyte<->multibyte
18947 conversion. So, save the current value now and restore it
18948 later.
18950 Note: It seems that we don't have to record multibyte_p in
18951 struct glyph because the character code itself tells if or
18952 not the character is multibyte. Thus, in the future, we must
18953 consider eliminating the field `multibyte_p' in the struct
18954 glyph. */
18955 int saved_multibyte_p = it->multibyte_p;
18957 /* Maybe translate single-byte characters to multibyte, or the
18958 other way. */
18959 it->char_to_display = it->c;
18960 if (!ASCII_BYTE_P (it->c))
18962 if (unibyte_display_via_language_environment
18963 && SINGLE_BYTE_CHAR_P (it->c)
18964 && (it->c >= 0240
18965 || !NILP (Vnonascii_translation_table)))
18967 it->char_to_display = unibyte_char_to_multibyte (it->c);
18968 it->multibyte_p = 1;
18969 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
18970 face = FACE_FROM_ID (it->f, it->face_id);
18972 else if (!SINGLE_BYTE_CHAR_P (it->c)
18973 && !it->multibyte_p)
18975 it->multibyte_p = 1;
18976 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
18977 face = FACE_FROM_ID (it->f, it->face_id);
18981 /* Get font to use. Encode IT->char_to_display. */
18982 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
18983 &char2b, it->multibyte_p, 0);
18984 font = face->font;
18986 /* When no suitable font found, use the default font. */
18987 font_not_found_p = font == NULL;
18988 if (font_not_found_p)
18990 font = FRAME_FONT (it->f);
18991 boff = FRAME_BASELINE_OFFSET (it->f);
18992 font_info = NULL;
18994 else
18996 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
18997 boff = font_info->baseline_offset;
18998 if (font_info->vertical_centering)
18999 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
19002 if (it->char_to_display >= ' '
19003 && (!it->multibyte_p || it->char_to_display < 128))
19005 /* Either unibyte or ASCII. */
19006 int stretched_p;
19008 it->nglyphs = 1;
19010 pcm = rif->per_char_metric (font, &char2b,
19011 FONT_TYPE_FOR_UNIBYTE (font, it->char_to_display));
19013 if (it->override_ascent >= 0)
19015 it->ascent = it->override_ascent;
19016 it->descent = it->override_descent;
19017 boff = it->override_boff;
19019 else
19021 it->ascent = FONT_BASE (font) + boff;
19022 it->descent = FONT_DESCENT (font) - boff;
19025 if (pcm)
19027 it->phys_ascent = pcm->ascent + boff;
19028 it->phys_descent = pcm->descent - boff;
19029 it->pixel_width = pcm->width;
19031 else
19033 it->glyph_not_available_p = 1;
19034 it->phys_ascent = it->ascent;
19035 it->phys_descent = it->descent;
19036 it->pixel_width = FONT_WIDTH (font);
19039 if (it->constrain_row_ascent_descent_p)
19041 if (it->descent > it->max_descent)
19043 it->ascent += it->descent - it->max_descent;
19044 it->descent = it->max_descent;
19046 if (it->ascent > it->max_ascent)
19048 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
19049 it->ascent = it->max_ascent;
19051 it->phys_ascent = min (it->phys_ascent, it->ascent);
19052 it->phys_descent = min (it->phys_descent, it->descent);
19053 extra_line_spacing = 0;
19056 /* If this is a space inside a region of text with
19057 `space-width' property, change its width. */
19058 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
19059 if (stretched_p)
19060 it->pixel_width *= XFLOATINT (it->space_width);
19062 /* If face has a box, add the box thickness to the character
19063 height. If character has a box line to the left and/or
19064 right, add the box line width to the character's width. */
19065 if (face->box != FACE_NO_BOX)
19067 int thick = face->box_line_width;
19069 if (thick > 0)
19071 it->ascent += thick;
19072 it->descent += thick;
19074 else
19075 thick = -thick;
19077 if (it->start_of_box_run_p)
19078 it->pixel_width += thick;
19079 if (it->end_of_box_run_p)
19080 it->pixel_width += thick;
19083 /* If face has an overline, add the height of the overline
19084 (1 pixel) and a 1 pixel margin to the character height. */
19085 if (face->overline_p)
19086 it->ascent += 2;
19088 if (it->constrain_row_ascent_descent_p)
19090 if (it->ascent > it->max_ascent)
19091 it->ascent = it->max_ascent;
19092 if (it->descent > it->max_descent)
19093 it->descent = it->max_descent;
19096 take_vertical_position_into_account (it);
19098 /* If we have to actually produce glyphs, do it. */
19099 if (it->glyph_row)
19101 if (stretched_p)
19103 /* Translate a space with a `space-width' property
19104 into a stretch glyph. */
19105 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
19106 / FONT_HEIGHT (font));
19107 append_stretch_glyph (it, it->object, it->pixel_width,
19108 it->ascent + it->descent, ascent);
19110 else
19111 append_glyph (it);
19113 /* If characters with lbearing or rbearing are displayed
19114 in this line, record that fact in a flag of the
19115 glyph row. This is used to optimize X output code. */
19116 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
19117 it->glyph_row->contains_overlapping_glyphs_p = 1;
19120 else if (it->char_to_display == '\n')
19122 /* A newline has no width but we need the height of the line.
19123 But if previous part of the line set a height, don't
19124 increase that height */
19126 Lisp_Object height;
19127 Lisp_Object total_height = Qnil;
19129 it->override_ascent = -1;
19130 it->pixel_width = 0;
19131 it->nglyphs = 0;
19133 height = get_line_height_property(it, Qline_height);
19134 /* Split (line-height total-height) list */
19135 if (CONSP (height)
19136 && CONSP (XCDR (height))
19137 && NILP (XCDR (XCDR (height))))
19139 total_height = XCAR (XCDR (height));
19140 height = XCAR (height);
19142 height = calc_line_height_property(it, height, font, boff, 1);
19144 if (it->override_ascent >= 0)
19146 it->ascent = it->override_ascent;
19147 it->descent = it->override_descent;
19148 boff = it->override_boff;
19150 else
19152 it->ascent = FONT_BASE (font) + boff;
19153 it->descent = FONT_DESCENT (font) - boff;
19156 if (EQ (height, Qt))
19158 if (it->descent > it->max_descent)
19160 it->ascent += it->descent - it->max_descent;
19161 it->descent = it->max_descent;
19163 if (it->ascent > it->max_ascent)
19165 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
19166 it->ascent = it->max_ascent;
19168 it->phys_ascent = min (it->phys_ascent, it->ascent);
19169 it->phys_descent = min (it->phys_descent, it->descent);
19170 it->constrain_row_ascent_descent_p = 1;
19171 extra_line_spacing = 0;
19173 else
19175 Lisp_Object spacing;
19176 int total = 0;
19178 it->phys_ascent = it->ascent;
19179 it->phys_descent = it->descent;
19181 if ((it->max_ascent > 0 || it->max_descent > 0)
19182 && face->box != FACE_NO_BOX
19183 && face->box_line_width > 0)
19185 it->ascent += face->box_line_width;
19186 it->descent += face->box_line_width;
19188 if (!NILP (height)
19189 && XINT (height) > it->ascent + it->descent)
19190 it->ascent = XINT (height) - it->descent;
19192 if (!NILP (total_height))
19193 spacing = calc_line_height_property(it, total_height, font, boff, 0);
19194 else
19196 spacing = get_line_height_property(it, Qline_spacing);
19197 spacing = calc_line_height_property(it, spacing, font, boff, 0);
19199 if (INTEGERP (spacing))
19201 extra_line_spacing = XINT (spacing);
19202 if (!NILP (total_height))
19203 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
19207 else if (it->char_to_display == '\t')
19209 int tab_width = it->tab_width * FRAME_SPACE_WIDTH (it->f);
19210 int x = it->current_x + it->continuation_lines_width;
19211 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
19213 /* If the distance from the current position to the next tab
19214 stop is less than a space character width, use the
19215 tab stop after that. */
19216 if (next_tab_x - x < FRAME_SPACE_WIDTH (it->f))
19217 next_tab_x += tab_width;
19219 it->pixel_width = next_tab_x - x;
19220 it->nglyphs = 1;
19221 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
19222 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
19224 if (it->glyph_row)
19226 append_stretch_glyph (it, it->object, it->pixel_width,
19227 it->ascent + it->descent, it->ascent);
19230 else
19232 /* A multi-byte character. Assume that the display width of the
19233 character is the width of the character multiplied by the
19234 width of the font. */
19236 /* If we found a font, this font should give us the right
19237 metrics. If we didn't find a font, use the frame's
19238 default font and calculate the width of the character
19239 from the charset width; this is what old redisplay code
19240 did. */
19242 pcm = rif->per_char_metric (font, &char2b,
19243 FONT_TYPE_FOR_MULTIBYTE (font, it->c));
19245 if (font_not_found_p || !pcm)
19247 int charset = CHAR_CHARSET (it->char_to_display);
19249 it->glyph_not_available_p = 1;
19250 it->pixel_width = (FRAME_COLUMN_WIDTH (it->f)
19251 * CHARSET_WIDTH (charset));
19252 it->phys_ascent = FONT_BASE (font) + boff;
19253 it->phys_descent = FONT_DESCENT (font) - boff;
19255 else
19257 it->pixel_width = pcm->width;
19258 it->phys_ascent = pcm->ascent + boff;
19259 it->phys_descent = pcm->descent - boff;
19260 if (it->glyph_row
19261 && (pcm->lbearing < 0
19262 || pcm->rbearing > pcm->width))
19263 it->glyph_row->contains_overlapping_glyphs_p = 1;
19265 it->nglyphs = 1;
19266 it->ascent = FONT_BASE (font) + boff;
19267 it->descent = FONT_DESCENT (font) - boff;
19268 if (face->box != FACE_NO_BOX)
19270 int thick = face->box_line_width;
19272 if (thick > 0)
19274 it->ascent += thick;
19275 it->descent += thick;
19277 else
19278 thick = - thick;
19280 if (it->start_of_box_run_p)
19281 it->pixel_width += thick;
19282 if (it->end_of_box_run_p)
19283 it->pixel_width += thick;
19286 /* If face has an overline, add the height of the overline
19287 (1 pixel) and a 1 pixel margin to the character height. */
19288 if (face->overline_p)
19289 it->ascent += 2;
19291 take_vertical_position_into_account (it);
19293 if (it->glyph_row)
19294 append_glyph (it);
19296 it->multibyte_p = saved_multibyte_p;
19298 else if (it->what == IT_COMPOSITION)
19300 /* Note: A composition is represented as one glyph in the
19301 glyph matrix. There are no padding glyphs. */
19302 XChar2b char2b;
19303 XFontStruct *font;
19304 struct face *face = FACE_FROM_ID (it->f, it->face_id);
19305 XCharStruct *pcm;
19306 int font_not_found_p;
19307 struct font_info *font_info;
19308 int boff; /* baseline offset */
19309 struct composition *cmp = composition_table[it->cmp_id];
19311 /* Maybe translate single-byte characters to multibyte. */
19312 it->char_to_display = it->c;
19313 if (unibyte_display_via_language_environment
19314 && SINGLE_BYTE_CHAR_P (it->c)
19315 && (it->c >= 0240
19316 || (it->c >= 0200
19317 && !NILP (Vnonascii_translation_table))))
19319 it->char_to_display = unibyte_char_to_multibyte (it->c);
19322 /* Get face and font to use. Encode IT->char_to_display. */
19323 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
19324 face = FACE_FROM_ID (it->f, it->face_id);
19325 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
19326 &char2b, it->multibyte_p, 0);
19327 font = face->font;
19329 /* When no suitable font found, use the default font. */
19330 font_not_found_p = font == NULL;
19331 if (font_not_found_p)
19333 font = FRAME_FONT (it->f);
19334 boff = FRAME_BASELINE_OFFSET (it->f);
19335 font_info = NULL;
19337 else
19339 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
19340 boff = font_info->baseline_offset;
19341 if (font_info->vertical_centering)
19342 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
19345 /* There are no padding glyphs, so there is only one glyph to
19346 produce for the composition. Important is that pixel_width,
19347 ascent and descent are the values of what is drawn by
19348 draw_glyphs (i.e. the values of the overall glyphs composed). */
19349 it->nglyphs = 1;
19351 /* If we have not yet calculated pixel size data of glyphs of
19352 the composition for the current face font, calculate them
19353 now. Theoretically, we have to check all fonts for the
19354 glyphs, but that requires much time and memory space. So,
19355 here we check only the font of the first glyph. This leads
19356 to incorrect display very rarely, and C-l (recenter) can
19357 correct the display anyway. */
19358 if (cmp->font != (void *) font)
19360 /* Ascent and descent of the font of the first character of
19361 this composition (adjusted by baseline offset). Ascent
19362 and descent of overall glyphs should not be less than
19363 them respectively. */
19364 int font_ascent = FONT_BASE (font) + boff;
19365 int font_descent = FONT_DESCENT (font) - boff;
19366 /* Bounding box of the overall glyphs. */
19367 int leftmost, rightmost, lowest, highest;
19368 int i, width, ascent, descent;
19370 cmp->font = (void *) font;
19372 /* Initialize the bounding box. */
19373 if (font_info
19374 && (pcm = rif->per_char_metric (font, &char2b,
19375 FONT_TYPE_FOR_MULTIBYTE (font, it->c))))
19377 width = pcm->width;
19378 ascent = pcm->ascent;
19379 descent = pcm->descent;
19381 else
19383 width = FONT_WIDTH (font);
19384 ascent = FONT_BASE (font);
19385 descent = FONT_DESCENT (font);
19388 rightmost = width;
19389 lowest = - descent + boff;
19390 highest = ascent + boff;
19391 leftmost = 0;
19393 if (font_info
19394 && font_info->default_ascent
19395 && CHAR_TABLE_P (Vuse_default_ascent)
19396 && !NILP (Faref (Vuse_default_ascent,
19397 make_number (it->char_to_display))))
19398 highest = font_info->default_ascent + boff;
19400 /* Draw the first glyph at the normal position. It may be
19401 shifted to right later if some other glyphs are drawn at
19402 the left. */
19403 cmp->offsets[0] = 0;
19404 cmp->offsets[1] = boff;
19406 /* Set cmp->offsets for the remaining glyphs. */
19407 for (i = 1; i < cmp->glyph_len; i++)
19409 int left, right, btm, top;
19410 int ch = COMPOSITION_GLYPH (cmp, i);
19411 int face_id = FACE_FOR_CHAR (it->f, face, ch);
19413 face = FACE_FROM_ID (it->f, face_id);
19414 get_char_face_and_encoding (it->f, ch, face->id,
19415 &char2b, it->multibyte_p, 0);
19416 font = face->font;
19417 if (font == NULL)
19419 font = FRAME_FONT (it->f);
19420 boff = FRAME_BASELINE_OFFSET (it->f);
19421 font_info = NULL;
19423 else
19425 font_info
19426 = FONT_INFO_FROM_ID (it->f, face->font_info_id);
19427 boff = font_info->baseline_offset;
19428 if (font_info->vertical_centering)
19429 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
19432 if (font_info
19433 && (pcm = rif->per_char_metric (font, &char2b,
19434 FONT_TYPE_FOR_MULTIBYTE (font, ch))))
19436 width = pcm->width;
19437 ascent = pcm->ascent;
19438 descent = pcm->descent;
19440 else
19442 width = FONT_WIDTH (font);
19443 ascent = 1;
19444 descent = 0;
19447 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
19449 /* Relative composition with or without
19450 alternate chars. */
19451 left = (leftmost + rightmost - width) / 2;
19452 btm = - descent + boff;
19453 if (font_info && font_info->relative_compose
19454 && (! CHAR_TABLE_P (Vignore_relative_composition)
19455 || NILP (Faref (Vignore_relative_composition,
19456 make_number (ch)))))
19459 if (- descent >= font_info->relative_compose)
19460 /* One extra pixel between two glyphs. */
19461 btm = highest + 1;
19462 else if (ascent <= 0)
19463 /* One extra pixel between two glyphs. */
19464 btm = lowest - 1 - ascent - descent;
19467 else
19469 /* A composition rule is specified by an integer
19470 value that encodes global and new reference
19471 points (GREF and NREF). GREF and NREF are
19472 specified by numbers as below:
19474 0---1---2 -- ascent
19478 9--10--11 -- center
19480 ---3---4---5--- baseline
19482 6---7---8 -- descent
19484 int rule = COMPOSITION_RULE (cmp, i);
19485 int gref, nref, grefx, grefy, nrefx, nrefy;
19487 COMPOSITION_DECODE_RULE (rule, gref, nref);
19488 grefx = gref % 3, nrefx = nref % 3;
19489 grefy = gref / 3, nrefy = nref / 3;
19491 left = (leftmost
19492 + grefx * (rightmost - leftmost) / 2
19493 - nrefx * width / 2);
19494 btm = ((grefy == 0 ? highest
19495 : grefy == 1 ? 0
19496 : grefy == 2 ? lowest
19497 : (highest + lowest) / 2)
19498 - (nrefy == 0 ? ascent + descent
19499 : nrefy == 1 ? descent - boff
19500 : nrefy == 2 ? 0
19501 : (ascent + descent) / 2));
19504 cmp->offsets[i * 2] = left;
19505 cmp->offsets[i * 2 + 1] = btm + descent;
19507 /* Update the bounding box of the overall glyphs. */
19508 right = left + width;
19509 top = btm + descent + ascent;
19510 if (left < leftmost)
19511 leftmost = left;
19512 if (right > rightmost)
19513 rightmost = right;
19514 if (top > highest)
19515 highest = top;
19516 if (btm < lowest)
19517 lowest = btm;
19520 /* If there are glyphs whose x-offsets are negative,
19521 shift all glyphs to the right and make all x-offsets
19522 non-negative. */
19523 if (leftmost < 0)
19525 for (i = 0; i < cmp->glyph_len; i++)
19526 cmp->offsets[i * 2] -= leftmost;
19527 rightmost -= leftmost;
19530 cmp->pixel_width = rightmost;
19531 cmp->ascent = highest;
19532 cmp->descent = - lowest;
19533 if (cmp->ascent < font_ascent)
19534 cmp->ascent = font_ascent;
19535 if (cmp->descent < font_descent)
19536 cmp->descent = font_descent;
19539 it->pixel_width = cmp->pixel_width;
19540 it->ascent = it->phys_ascent = cmp->ascent;
19541 it->descent = it->phys_descent = cmp->descent;
19543 if (face->box != FACE_NO_BOX)
19545 int thick = face->box_line_width;
19547 if (thick > 0)
19549 it->ascent += thick;
19550 it->descent += thick;
19552 else
19553 thick = - thick;
19555 if (it->start_of_box_run_p)
19556 it->pixel_width += thick;
19557 if (it->end_of_box_run_p)
19558 it->pixel_width += thick;
19561 /* If face has an overline, add the height of the overline
19562 (1 pixel) and a 1 pixel margin to the character height. */
19563 if (face->overline_p)
19564 it->ascent += 2;
19566 take_vertical_position_into_account (it);
19568 if (it->glyph_row)
19569 append_composite_glyph (it);
19571 else if (it->what == IT_IMAGE)
19572 produce_image_glyph (it);
19573 else if (it->what == IT_STRETCH)
19574 produce_stretch_glyph (it);
19576 /* Accumulate dimensions. Note: can't assume that it->descent > 0
19577 because this isn't true for images with `:ascent 100'. */
19578 xassert (it->ascent >= 0 && it->descent >= 0);
19579 if (it->area == TEXT_AREA)
19580 it->current_x += it->pixel_width;
19582 if (extra_line_spacing > 0)
19584 it->descent += extra_line_spacing;
19585 if (extra_line_spacing > it->max_extra_line_spacing)
19586 it->max_extra_line_spacing = extra_line_spacing;
19589 it->max_ascent = max (it->max_ascent, it->ascent);
19590 it->max_descent = max (it->max_descent, it->descent);
19591 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
19592 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
19595 /* EXPORT for RIF:
19596 Output LEN glyphs starting at START at the nominal cursor position.
19597 Advance the nominal cursor over the text. The global variable
19598 updated_window contains the window being updated, updated_row is
19599 the glyph row being updated, and updated_area is the area of that
19600 row being updated. */
19602 void
19603 x_write_glyphs (start, len)
19604 struct glyph *start;
19605 int len;
19607 int x, hpos;
19609 xassert (updated_window && updated_row);
19610 BLOCK_INPUT;
19612 /* Write glyphs. */
19614 hpos = start - updated_row->glyphs[updated_area];
19615 x = draw_glyphs (updated_window, output_cursor.x,
19616 updated_row, updated_area,
19617 hpos, hpos + len,
19618 DRAW_NORMAL_TEXT, 0);
19620 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
19621 if (updated_area == TEXT_AREA
19622 && updated_window->phys_cursor_on_p
19623 && updated_window->phys_cursor.vpos == output_cursor.vpos
19624 && updated_window->phys_cursor.hpos >= hpos
19625 && updated_window->phys_cursor.hpos < hpos + len)
19626 updated_window->phys_cursor_on_p = 0;
19628 UNBLOCK_INPUT;
19630 /* Advance the output cursor. */
19631 output_cursor.hpos += len;
19632 output_cursor.x = x;
19636 /* EXPORT for RIF:
19637 Insert LEN glyphs from START at the nominal cursor position. */
19639 void
19640 x_insert_glyphs (start, len)
19641 struct glyph *start;
19642 int len;
19644 struct frame *f;
19645 struct window *w;
19646 int line_height, shift_by_width, shifted_region_width;
19647 struct glyph_row *row;
19648 struct glyph *glyph;
19649 int frame_x, frame_y, hpos;
19651 xassert (updated_window && updated_row);
19652 BLOCK_INPUT;
19653 w = updated_window;
19654 f = XFRAME (WINDOW_FRAME (w));
19656 /* Get the height of the line we are in. */
19657 row = updated_row;
19658 line_height = row->height;
19660 /* Get the width of the glyphs to insert. */
19661 shift_by_width = 0;
19662 for (glyph = start; glyph < start + len; ++glyph)
19663 shift_by_width += glyph->pixel_width;
19665 /* Get the width of the region to shift right. */
19666 shifted_region_width = (window_box_width (w, updated_area)
19667 - output_cursor.x
19668 - shift_by_width);
19670 /* Shift right. */
19671 frame_x = window_box_left (w, updated_area) + output_cursor.x;
19672 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
19674 rif->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
19675 line_height, shift_by_width);
19677 /* Write the glyphs. */
19678 hpos = start - row->glyphs[updated_area];
19679 draw_glyphs (w, output_cursor.x, row, updated_area,
19680 hpos, hpos + len,
19681 DRAW_NORMAL_TEXT, 0);
19683 /* Advance the output cursor. */
19684 output_cursor.hpos += len;
19685 output_cursor.x += shift_by_width;
19686 UNBLOCK_INPUT;
19690 /* EXPORT for RIF:
19691 Erase the current text line from the nominal cursor position
19692 (inclusive) to pixel column TO_X (exclusive). The idea is that
19693 everything from TO_X onward is already erased.
19695 TO_X is a pixel position relative to updated_area of
19696 updated_window. TO_X == -1 means clear to the end of this area. */
19698 void
19699 x_clear_end_of_line (to_x)
19700 int to_x;
19702 struct frame *f;
19703 struct window *w = updated_window;
19704 int max_x, min_y, max_y;
19705 int from_x, from_y, to_y;
19707 xassert (updated_window && updated_row);
19708 f = XFRAME (w->frame);
19710 if (updated_row->full_width_p)
19711 max_x = WINDOW_TOTAL_WIDTH (w);
19712 else
19713 max_x = window_box_width (w, updated_area);
19714 max_y = window_text_bottom_y (w);
19716 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
19717 of window. For TO_X > 0, truncate to end of drawing area. */
19718 if (to_x == 0)
19719 return;
19720 else if (to_x < 0)
19721 to_x = max_x;
19722 else
19723 to_x = min (to_x, max_x);
19725 to_y = min (max_y, output_cursor.y + updated_row->height);
19727 /* Notice if the cursor will be cleared by this operation. */
19728 if (!updated_row->full_width_p)
19729 notice_overwritten_cursor (w, updated_area,
19730 output_cursor.x, -1,
19731 updated_row->y,
19732 MATRIX_ROW_BOTTOM_Y (updated_row));
19734 from_x = output_cursor.x;
19736 /* Translate to frame coordinates. */
19737 if (updated_row->full_width_p)
19739 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
19740 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
19742 else
19744 int area_left = window_box_left (w, updated_area);
19745 from_x += area_left;
19746 to_x += area_left;
19749 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
19750 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
19751 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
19753 /* Prevent inadvertently clearing to end of the X window. */
19754 if (to_x > from_x && to_y > from_y)
19756 BLOCK_INPUT;
19757 rif->clear_frame_area (f, from_x, from_y,
19758 to_x - from_x, to_y - from_y);
19759 UNBLOCK_INPUT;
19763 #endif /* HAVE_WINDOW_SYSTEM */
19767 /***********************************************************************
19768 Cursor types
19769 ***********************************************************************/
19771 /* Value is the internal representation of the specified cursor type
19772 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
19773 of the bar cursor. */
19775 static enum text_cursor_kinds
19776 get_specified_cursor_type (arg, width)
19777 Lisp_Object arg;
19778 int *width;
19780 enum text_cursor_kinds type;
19782 if (NILP (arg))
19783 return NO_CURSOR;
19785 if (EQ (arg, Qbox))
19786 return FILLED_BOX_CURSOR;
19788 if (EQ (arg, Qhollow))
19789 return HOLLOW_BOX_CURSOR;
19791 if (EQ (arg, Qbar))
19793 *width = 2;
19794 return BAR_CURSOR;
19797 if (CONSP (arg)
19798 && EQ (XCAR (arg), Qbar)
19799 && INTEGERP (XCDR (arg))
19800 && XINT (XCDR (arg)) >= 0)
19802 *width = XINT (XCDR (arg));
19803 return BAR_CURSOR;
19806 if (EQ (arg, Qhbar))
19808 *width = 2;
19809 return HBAR_CURSOR;
19812 if (CONSP (arg)
19813 && EQ (XCAR (arg), Qhbar)
19814 && INTEGERP (XCDR (arg))
19815 && XINT (XCDR (arg)) >= 0)
19817 *width = XINT (XCDR (arg));
19818 return HBAR_CURSOR;
19821 /* Treat anything unknown as "hollow box cursor".
19822 It was bad to signal an error; people have trouble fixing
19823 .Xdefaults with Emacs, when it has something bad in it. */
19824 type = HOLLOW_BOX_CURSOR;
19826 return type;
19829 /* Set the default cursor types for specified frame. */
19830 void
19831 set_frame_cursor_types (f, arg)
19832 struct frame *f;
19833 Lisp_Object arg;
19835 int width;
19836 Lisp_Object tem;
19838 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
19839 FRAME_CURSOR_WIDTH (f) = width;
19841 /* By default, set up the blink-off state depending on the on-state. */
19843 tem = Fassoc (arg, Vblink_cursor_alist);
19844 if (!NILP (tem))
19846 FRAME_BLINK_OFF_CURSOR (f)
19847 = get_specified_cursor_type (XCDR (tem), &width);
19848 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
19850 else
19851 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
19855 /* Return the cursor we want to be displayed in window W. Return
19856 width of bar/hbar cursor through WIDTH arg. Return with
19857 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
19858 (i.e. if the `system caret' should track this cursor).
19860 In a mini-buffer window, we want the cursor only to appear if we
19861 are reading input from this window. For the selected window, we
19862 want the cursor type given by the frame parameter or buffer local
19863 setting of cursor-type. If explicitly marked off, draw no cursor.
19864 In all other cases, we want a hollow box cursor. */
19866 static enum text_cursor_kinds
19867 get_window_cursor_type (w, glyph, width, active_cursor)
19868 struct window *w;
19869 struct glyph *glyph;
19870 int *width;
19871 int *active_cursor;
19873 struct frame *f = XFRAME (w->frame);
19874 struct buffer *b = XBUFFER (w->buffer);
19875 int cursor_type = DEFAULT_CURSOR;
19876 Lisp_Object alt_cursor;
19877 int non_selected = 0;
19879 *active_cursor = 1;
19881 /* Echo area */
19882 if (cursor_in_echo_area
19883 && FRAME_HAS_MINIBUF_P (f)
19884 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
19886 if (w == XWINDOW (echo_area_window))
19888 *width = FRAME_CURSOR_WIDTH (f);
19889 return FRAME_DESIRED_CURSOR (f);
19892 *active_cursor = 0;
19893 non_selected = 1;
19896 /* Nonselected window or nonselected frame. */
19897 else if (w != XWINDOW (f->selected_window)
19898 #ifdef HAVE_WINDOW_SYSTEM
19899 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame
19900 #endif
19903 *active_cursor = 0;
19905 if (MINI_WINDOW_P (w) && minibuf_level == 0)
19906 return NO_CURSOR;
19908 non_selected = 1;
19911 /* Never display a cursor in a window in which cursor-type is nil. */
19912 if (NILP (b->cursor_type))
19913 return NO_CURSOR;
19915 /* Use cursor-in-non-selected-windows for non-selected window or frame. */
19916 if (non_selected)
19918 alt_cursor = Fbuffer_local_value (Qcursor_in_non_selected_windows, w->buffer);
19919 return get_specified_cursor_type (alt_cursor, width);
19922 /* Get the normal cursor type for this window. */
19923 if (EQ (b->cursor_type, Qt))
19925 cursor_type = FRAME_DESIRED_CURSOR (f);
19926 *width = FRAME_CURSOR_WIDTH (f);
19928 else
19929 cursor_type = get_specified_cursor_type (b->cursor_type, width);
19931 /* Use normal cursor if not blinked off. */
19932 if (!w->cursor_off_p)
19934 if (glyph != NULL && glyph->type == IMAGE_GLYPH) {
19935 if (cursor_type == FILLED_BOX_CURSOR)
19936 cursor_type = HOLLOW_BOX_CURSOR;
19938 return cursor_type;
19941 /* Cursor is blinked off, so determine how to "toggle" it. */
19943 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
19944 if ((alt_cursor = Fassoc (b->cursor_type, Vblink_cursor_alist), !NILP (alt_cursor)))
19945 return get_specified_cursor_type (XCDR (alt_cursor), width);
19947 /* Then see if frame has specified a specific blink off cursor type. */
19948 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
19950 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
19951 return FRAME_BLINK_OFF_CURSOR (f);
19954 #if 0
19955 /* Some people liked having a permanently visible blinking cursor,
19956 while others had very strong opinions against it. So it was
19957 decided to remove it. KFS 2003-09-03 */
19959 /* Finally perform built-in cursor blinking:
19960 filled box <-> hollow box
19961 wide [h]bar <-> narrow [h]bar
19962 narrow [h]bar <-> no cursor
19963 other type <-> no cursor */
19965 if (cursor_type == FILLED_BOX_CURSOR)
19966 return HOLLOW_BOX_CURSOR;
19968 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
19970 *width = 1;
19971 return cursor_type;
19973 #endif
19975 return NO_CURSOR;
19979 #ifdef HAVE_WINDOW_SYSTEM
19981 /* Notice when the text cursor of window W has been completely
19982 overwritten by a drawing operation that outputs glyphs in AREA
19983 starting at X0 and ending at X1 in the line starting at Y0 and
19984 ending at Y1. X coordinates are area-relative. X1 < 0 means all
19985 the rest of the line after X0 has been written. Y coordinates
19986 are window-relative. */
19988 static void
19989 notice_overwritten_cursor (w, area, x0, x1, y0, y1)
19990 struct window *w;
19991 enum glyph_row_area area;
19992 int x0, y0, x1, y1;
19994 int cx0, cx1, cy0, cy1;
19995 struct glyph_row *row;
19997 if (!w->phys_cursor_on_p)
19998 return;
19999 if (area != TEXT_AREA)
20000 return;
20002 row = w->current_matrix->rows + w->phys_cursor.vpos;
20003 if (!row->displays_text_p)
20004 return;
20006 if (row->cursor_in_fringe_p)
20008 row->cursor_in_fringe_p = 0;
20009 draw_fringe_bitmap (w, row, 0);
20010 w->phys_cursor_on_p = 0;
20011 return;
20014 cx0 = w->phys_cursor.x;
20015 cx1 = cx0 + w->phys_cursor_width;
20016 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
20017 return;
20019 /* The cursor image will be completely removed from the
20020 screen if the output area intersects the cursor area in
20021 y-direction. When we draw in [y0 y1[, and some part of
20022 the cursor is at y < y0, that part must have been drawn
20023 before. When scrolling, the cursor is erased before
20024 actually scrolling, so we don't come here. When not
20025 scrolling, the rows above the old cursor row must have
20026 changed, and in this case these rows must have written
20027 over the cursor image.
20029 Likewise if part of the cursor is below y1, with the
20030 exception of the cursor being in the first blank row at
20031 the buffer and window end because update_text_area
20032 doesn't draw that row. (Except when it does, but
20033 that's handled in update_text_area.) */
20035 cy0 = w->phys_cursor.y;
20036 cy1 = cy0 + w->phys_cursor_height;
20037 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
20038 return;
20040 w->phys_cursor_on_p = 0;
20043 #endif /* HAVE_WINDOW_SYSTEM */
20046 /************************************************************************
20047 Mouse Face
20048 ************************************************************************/
20050 #ifdef HAVE_WINDOW_SYSTEM
20052 /* EXPORT for RIF:
20053 Fix the display of area AREA of overlapping row ROW in window W. */
20055 void
20056 x_fix_overlapping_area (w, row, area)
20057 struct window *w;
20058 struct glyph_row *row;
20059 enum glyph_row_area area;
20061 int i, x;
20063 BLOCK_INPUT;
20065 x = 0;
20066 for (i = 0; i < row->used[area];)
20068 if (row->glyphs[area][i].overlaps_vertically_p)
20070 int start = i, start_x = x;
20074 x += row->glyphs[area][i].pixel_width;
20075 ++i;
20077 while (i < row->used[area]
20078 && row->glyphs[area][i].overlaps_vertically_p);
20080 draw_glyphs (w, start_x, row, area,
20081 start, i,
20082 DRAW_NORMAL_TEXT, 1);
20084 else
20086 x += row->glyphs[area][i].pixel_width;
20087 ++i;
20091 UNBLOCK_INPUT;
20095 /* EXPORT:
20096 Draw the cursor glyph of window W in glyph row ROW. See the
20097 comment of draw_glyphs for the meaning of HL. */
20099 void
20100 draw_phys_cursor_glyph (w, row, hl)
20101 struct window *w;
20102 struct glyph_row *row;
20103 enum draw_glyphs_face hl;
20105 /* If cursor hpos is out of bounds, don't draw garbage. This can
20106 happen in mini-buffer windows when switching between echo area
20107 glyphs and mini-buffer. */
20108 if (w->phys_cursor.hpos < row->used[TEXT_AREA])
20110 int on_p = w->phys_cursor_on_p;
20111 int x1;
20112 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
20113 w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
20114 hl, 0);
20115 w->phys_cursor_on_p = on_p;
20117 if (hl == DRAW_CURSOR)
20118 w->phys_cursor_width = x1 - w->phys_cursor.x;
20119 /* When we erase the cursor, and ROW is overlapped by other
20120 rows, make sure that these overlapping parts of other rows
20121 are redrawn. */
20122 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
20124 if (row > w->current_matrix->rows
20125 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
20126 x_fix_overlapping_area (w, row - 1, TEXT_AREA);
20128 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
20129 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
20130 x_fix_overlapping_area (w, row + 1, TEXT_AREA);
20136 /* EXPORT:
20137 Erase the image of a cursor of window W from the screen. */
20139 void
20140 erase_phys_cursor (w)
20141 struct window *w;
20143 struct frame *f = XFRAME (w->frame);
20144 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
20145 int hpos = w->phys_cursor.hpos;
20146 int vpos = w->phys_cursor.vpos;
20147 int mouse_face_here_p = 0;
20148 struct glyph_matrix *active_glyphs = w->current_matrix;
20149 struct glyph_row *cursor_row;
20150 struct glyph *cursor_glyph;
20151 enum draw_glyphs_face hl;
20153 /* No cursor displayed or row invalidated => nothing to do on the
20154 screen. */
20155 if (w->phys_cursor_type == NO_CURSOR)
20156 goto mark_cursor_off;
20158 /* VPOS >= active_glyphs->nrows means that window has been resized.
20159 Don't bother to erase the cursor. */
20160 if (vpos >= active_glyphs->nrows)
20161 goto mark_cursor_off;
20163 /* If row containing cursor is marked invalid, there is nothing we
20164 can do. */
20165 cursor_row = MATRIX_ROW (active_glyphs, vpos);
20166 if (!cursor_row->enabled_p)
20167 goto mark_cursor_off;
20169 /* If line spacing is > 0, old cursor may only be partially visible in
20170 window after split-window. So adjust visible height. */
20171 cursor_row->visible_height = min (cursor_row->visible_height,
20172 window_text_bottom_y (w) - cursor_row->y);
20174 /* If row is completely invisible, don't attempt to delete a cursor which
20175 isn't there. This can happen if cursor is at top of a window, and
20176 we switch to a buffer with a header line in that window. */
20177 if (cursor_row->visible_height <= 0)
20178 goto mark_cursor_off;
20180 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
20181 if (cursor_row->cursor_in_fringe_p)
20183 cursor_row->cursor_in_fringe_p = 0;
20184 draw_fringe_bitmap (w, cursor_row, 0);
20185 goto mark_cursor_off;
20188 /* This can happen when the new row is shorter than the old one.
20189 In this case, either draw_glyphs or clear_end_of_line
20190 should have cleared the cursor. Note that we wouldn't be
20191 able to erase the cursor in this case because we don't have a
20192 cursor glyph at hand. */
20193 if (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])
20194 goto mark_cursor_off;
20196 /* If the cursor is in the mouse face area, redisplay that when
20197 we clear the cursor. */
20198 if (! NILP (dpyinfo->mouse_face_window)
20199 && w == XWINDOW (dpyinfo->mouse_face_window)
20200 && (vpos > dpyinfo->mouse_face_beg_row
20201 || (vpos == dpyinfo->mouse_face_beg_row
20202 && hpos >= dpyinfo->mouse_face_beg_col))
20203 && (vpos < dpyinfo->mouse_face_end_row
20204 || (vpos == dpyinfo->mouse_face_end_row
20205 && hpos < dpyinfo->mouse_face_end_col))
20206 /* Don't redraw the cursor's spot in mouse face if it is at the
20207 end of a line (on a newline). The cursor appears there, but
20208 mouse highlighting does not. */
20209 && cursor_row->used[TEXT_AREA] > hpos)
20210 mouse_face_here_p = 1;
20212 /* Maybe clear the display under the cursor. */
20213 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
20215 int x, y;
20216 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
20217 int width;
20219 cursor_glyph = get_phys_cursor_glyph (w);
20220 if (cursor_glyph == NULL)
20221 goto mark_cursor_off;
20223 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
20224 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
20225 width = min (cursor_glyph->pixel_width,
20226 window_box_width (w, TEXT_AREA) - w->phys_cursor.x);
20228 rif->clear_frame_area (f, x, y, width, cursor_row->visible_height);
20231 /* Erase the cursor by redrawing the character underneath it. */
20232 if (mouse_face_here_p)
20233 hl = DRAW_MOUSE_FACE;
20234 else
20235 hl = DRAW_NORMAL_TEXT;
20236 draw_phys_cursor_glyph (w, cursor_row, hl);
20238 mark_cursor_off:
20239 w->phys_cursor_on_p = 0;
20240 w->phys_cursor_type = NO_CURSOR;
20244 /* EXPORT:
20245 Display or clear cursor of window W. If ON is zero, clear the
20246 cursor. If it is non-zero, display the cursor. If ON is nonzero,
20247 where to put the cursor is specified by HPOS, VPOS, X and Y. */
20249 void
20250 display_and_set_cursor (w, on, hpos, vpos, x, y)
20251 struct window *w;
20252 int on, hpos, vpos, x, y;
20254 struct frame *f = XFRAME (w->frame);
20255 int new_cursor_type;
20256 int new_cursor_width;
20257 int active_cursor;
20258 struct glyph_row *glyph_row;
20259 struct glyph *glyph;
20261 /* This is pointless on invisible frames, and dangerous on garbaged
20262 windows and frames; in the latter case, the frame or window may
20263 be in the midst of changing its size, and x and y may be off the
20264 window. */
20265 if (! FRAME_VISIBLE_P (f)
20266 || FRAME_GARBAGED_P (f)
20267 || vpos >= w->current_matrix->nrows
20268 || hpos >= w->current_matrix->matrix_w)
20269 return;
20271 /* If cursor is off and we want it off, return quickly. */
20272 if (!on && !w->phys_cursor_on_p)
20273 return;
20275 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
20276 /* If cursor row is not enabled, we don't really know where to
20277 display the cursor. */
20278 if (!glyph_row->enabled_p)
20280 w->phys_cursor_on_p = 0;
20281 return;
20284 glyph = NULL;
20285 if (!glyph_row->exact_window_width_line_p
20286 || hpos < glyph_row->used[TEXT_AREA])
20287 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
20289 xassert (interrupt_input_blocked);
20291 /* Set new_cursor_type to the cursor we want to be displayed. */
20292 new_cursor_type = get_window_cursor_type (w, glyph,
20293 &new_cursor_width, &active_cursor);
20295 /* If cursor is currently being shown and we don't want it to be or
20296 it is in the wrong place, or the cursor type is not what we want,
20297 erase it. */
20298 if (w->phys_cursor_on_p
20299 && (!on
20300 || w->phys_cursor.x != x
20301 || w->phys_cursor.y != y
20302 || new_cursor_type != w->phys_cursor_type
20303 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
20304 && new_cursor_width != w->phys_cursor_width)))
20305 erase_phys_cursor (w);
20307 /* Don't check phys_cursor_on_p here because that flag is only set
20308 to zero in some cases where we know that the cursor has been
20309 completely erased, to avoid the extra work of erasing the cursor
20310 twice. In other words, phys_cursor_on_p can be 1 and the cursor
20311 still not be visible, or it has only been partly erased. */
20312 if (on)
20314 w->phys_cursor_ascent = glyph_row->ascent;
20315 w->phys_cursor_height = glyph_row->height;
20317 /* Set phys_cursor_.* before x_draw_.* is called because some
20318 of them may need the information. */
20319 w->phys_cursor.x = x;
20320 w->phys_cursor.y = glyph_row->y;
20321 w->phys_cursor.hpos = hpos;
20322 w->phys_cursor.vpos = vpos;
20325 rif->draw_window_cursor (w, glyph_row, x, y,
20326 new_cursor_type, new_cursor_width,
20327 on, active_cursor);
20331 /* Switch the display of W's cursor on or off, according to the value
20332 of ON. */
20334 static void
20335 update_window_cursor (w, on)
20336 struct window *w;
20337 int on;
20339 /* Don't update cursor in windows whose frame is in the process
20340 of being deleted. */
20341 if (w->current_matrix)
20343 BLOCK_INPUT;
20344 display_and_set_cursor (w, on, w->phys_cursor.hpos, w->phys_cursor.vpos,
20345 w->phys_cursor.x, w->phys_cursor.y);
20346 UNBLOCK_INPUT;
20351 /* Call update_window_cursor with parameter ON_P on all leaf windows
20352 in the window tree rooted at W. */
20354 static void
20355 update_cursor_in_window_tree (w, on_p)
20356 struct window *w;
20357 int on_p;
20359 while (w)
20361 if (!NILP (w->hchild))
20362 update_cursor_in_window_tree (XWINDOW (w->hchild), on_p);
20363 else if (!NILP (w->vchild))
20364 update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
20365 else
20366 update_window_cursor (w, on_p);
20368 w = NILP (w->next) ? 0 : XWINDOW (w->next);
20373 /* EXPORT:
20374 Display the cursor on window W, or clear it, according to ON_P.
20375 Don't change the cursor's position. */
20377 void
20378 x_update_cursor (f, on_p)
20379 struct frame *f;
20380 int on_p;
20382 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
20386 /* EXPORT:
20387 Clear the cursor of window W to background color, and mark the
20388 cursor as not shown. This is used when the text where the cursor
20389 is is about to be rewritten. */
20391 void
20392 x_clear_cursor (w)
20393 struct window *w;
20395 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
20396 update_window_cursor (w, 0);
20400 /* EXPORT:
20401 Display the active region described by mouse_face_* according to DRAW. */
20403 void
20404 show_mouse_face (dpyinfo, draw)
20405 Display_Info *dpyinfo;
20406 enum draw_glyphs_face draw;
20408 struct window *w = XWINDOW (dpyinfo->mouse_face_window);
20409 struct frame *f = XFRAME (WINDOW_FRAME (w));
20411 if (/* If window is in the process of being destroyed, don't bother
20412 to do anything. */
20413 w->current_matrix != NULL
20414 /* Don't update mouse highlight if hidden */
20415 && (draw != DRAW_MOUSE_FACE || !dpyinfo->mouse_face_hidden)
20416 /* Recognize when we are called to operate on rows that don't exist
20417 anymore. This can happen when a window is split. */
20418 && dpyinfo->mouse_face_end_row < w->current_matrix->nrows)
20420 int phys_cursor_on_p = w->phys_cursor_on_p;
20421 struct glyph_row *row, *first, *last;
20423 first = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row);
20424 last = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row);
20426 for (row = first; row <= last && row->enabled_p; ++row)
20428 int start_hpos, end_hpos, start_x;
20430 /* For all but the first row, the highlight starts at column 0. */
20431 if (row == first)
20433 start_hpos = dpyinfo->mouse_face_beg_col;
20434 start_x = dpyinfo->mouse_face_beg_x;
20436 else
20438 start_hpos = 0;
20439 start_x = 0;
20442 if (row == last)
20443 end_hpos = dpyinfo->mouse_face_end_col;
20444 else
20445 end_hpos = row->used[TEXT_AREA];
20447 if (end_hpos > start_hpos)
20449 draw_glyphs (w, start_x, row, TEXT_AREA,
20450 start_hpos, end_hpos,
20451 draw, 0);
20453 row->mouse_face_p
20454 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
20458 /* When we've written over the cursor, arrange for it to
20459 be displayed again. */
20460 if (phys_cursor_on_p && !w->phys_cursor_on_p)
20462 BLOCK_INPUT;
20463 display_and_set_cursor (w, 1,
20464 w->phys_cursor.hpos, w->phys_cursor.vpos,
20465 w->phys_cursor.x, w->phys_cursor.y);
20466 UNBLOCK_INPUT;
20470 /* Change the mouse cursor. */
20471 if (draw == DRAW_NORMAL_TEXT)
20472 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
20473 else if (draw == DRAW_MOUSE_FACE)
20474 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
20475 else
20476 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
20479 /* EXPORT:
20480 Clear out the mouse-highlighted active region.
20481 Redraw it un-highlighted first. Value is non-zero if mouse
20482 face was actually drawn unhighlighted. */
20485 clear_mouse_face (dpyinfo)
20486 Display_Info *dpyinfo;
20488 int cleared = 0;
20490 if (!dpyinfo->mouse_face_hidden && !NILP (dpyinfo->mouse_face_window))
20492 show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT);
20493 cleared = 1;
20496 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
20497 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
20498 dpyinfo->mouse_face_window = Qnil;
20499 dpyinfo->mouse_face_overlay = Qnil;
20500 return cleared;
20504 /* EXPORT:
20505 Non-zero if physical cursor of window W is within mouse face. */
20508 cursor_in_mouse_face_p (w)
20509 struct window *w;
20511 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
20512 int in_mouse_face = 0;
20514 if (WINDOWP (dpyinfo->mouse_face_window)
20515 && XWINDOW (dpyinfo->mouse_face_window) == w)
20517 int hpos = w->phys_cursor.hpos;
20518 int vpos = w->phys_cursor.vpos;
20520 if (vpos >= dpyinfo->mouse_face_beg_row
20521 && vpos <= dpyinfo->mouse_face_end_row
20522 && (vpos > dpyinfo->mouse_face_beg_row
20523 || hpos >= dpyinfo->mouse_face_beg_col)
20524 && (vpos < dpyinfo->mouse_face_end_row
20525 || hpos < dpyinfo->mouse_face_end_col
20526 || dpyinfo->mouse_face_past_end))
20527 in_mouse_face = 1;
20530 return in_mouse_face;
20536 /* Find the glyph matrix position of buffer position CHARPOS in window
20537 *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's
20538 current glyphs must be up to date. If CHARPOS is above window
20539 start return (0, 0, 0, 0). If CHARPOS is after end of W, return end
20540 of last line in W. In the row containing CHARPOS, stop before glyphs
20541 having STOP as object. */
20543 #if 1 /* This is a version of fast_find_position that's more correct
20544 in the presence of hscrolling, for example. I didn't install
20545 it right away because the problem fixed is minor, it failed
20546 in 20.x as well, and I think it's too risky to install
20547 so near the release of 21.1. 2001-09-25 gerd. */
20549 static int
20550 fast_find_position (w, charpos, hpos, vpos, x, y, stop)
20551 struct window *w;
20552 int charpos;
20553 int *hpos, *vpos, *x, *y;
20554 Lisp_Object stop;
20556 struct glyph_row *row, *first;
20557 struct glyph *glyph, *end;
20558 int past_end = 0;
20560 first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
20561 if (charpos < MATRIX_ROW_START_CHARPOS (first))
20563 *x = first->x;
20564 *y = first->y;
20565 *hpos = 0;
20566 *vpos = MATRIX_ROW_VPOS (first, w->current_matrix);
20567 return 1;
20570 row = row_containing_pos (w, charpos, first, NULL, 0);
20571 if (row == NULL)
20573 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
20574 past_end = 1;
20577 *x = row->x;
20578 *y = row->y;
20579 *vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
20581 glyph = row->glyphs[TEXT_AREA];
20582 end = glyph + row->used[TEXT_AREA];
20584 /* Skip over glyphs not having an object at the start of the row.
20585 These are special glyphs like truncation marks on terminal
20586 frames. */
20587 if (row->displays_text_p)
20588 while (glyph < end
20589 && INTEGERP (glyph->object)
20590 && !EQ (stop, glyph->object)
20591 && glyph->charpos < 0)
20593 *x += glyph->pixel_width;
20594 ++glyph;
20597 while (glyph < end
20598 && !INTEGERP (glyph->object)
20599 && !EQ (stop, glyph->object)
20600 && (!BUFFERP (glyph->object)
20601 || glyph->charpos < charpos))
20603 *x += glyph->pixel_width;
20604 ++glyph;
20607 *hpos = glyph - row->glyphs[TEXT_AREA];
20608 return !past_end;
20611 #else /* not 1 */
20613 static int
20614 fast_find_position (w, pos, hpos, vpos, x, y, stop)
20615 struct window *w;
20616 int pos;
20617 int *hpos, *vpos, *x, *y;
20618 Lisp_Object stop;
20620 int i;
20621 int lastcol;
20622 int maybe_next_line_p = 0;
20623 int line_start_position;
20624 int yb = window_text_bottom_y (w);
20625 struct glyph_row *row, *best_row;
20626 int row_vpos, best_row_vpos;
20627 int current_x;
20629 row = best_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
20630 row_vpos = best_row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
20632 while (row->y < yb)
20634 if (row->used[TEXT_AREA])
20635 line_start_position = row->glyphs[TEXT_AREA]->charpos;
20636 else
20637 line_start_position = 0;
20639 if (line_start_position > pos)
20640 break;
20641 /* If the position sought is the end of the buffer,
20642 don't include the blank lines at the bottom of the window. */
20643 else if (line_start_position == pos
20644 && pos == BUF_ZV (XBUFFER (w->buffer)))
20646 maybe_next_line_p = 1;
20647 break;
20649 else if (line_start_position > 0)
20651 best_row = row;
20652 best_row_vpos = row_vpos;
20655 if (row->y + row->height >= yb)
20656 break;
20658 ++row;
20659 ++row_vpos;
20662 /* Find the right column within BEST_ROW. */
20663 lastcol = 0;
20664 current_x = best_row->x;
20665 for (i = 0; i < best_row->used[TEXT_AREA]; i++)
20667 struct glyph *glyph = best_row->glyphs[TEXT_AREA] + i;
20668 int charpos = glyph->charpos;
20670 if (BUFFERP (glyph->object))
20672 if (charpos == pos)
20674 *hpos = i;
20675 *vpos = best_row_vpos;
20676 *x = current_x;
20677 *y = best_row->y;
20678 return 1;
20680 else if (charpos > pos)
20681 break;
20683 else if (EQ (glyph->object, stop))
20684 break;
20686 if (charpos > 0)
20687 lastcol = i;
20688 current_x += glyph->pixel_width;
20691 /* If we're looking for the end of the buffer,
20692 and we didn't find it in the line we scanned,
20693 use the start of the following line. */
20694 if (maybe_next_line_p)
20696 ++best_row;
20697 ++best_row_vpos;
20698 lastcol = 0;
20699 current_x = best_row->x;
20702 *vpos = best_row_vpos;
20703 *hpos = lastcol + 1;
20704 *x = current_x;
20705 *y = best_row->y;
20706 return 0;
20709 #endif /* not 1 */
20712 /* Find the position of the glyph for position POS in OBJECT in
20713 window W's current matrix, and return in *X, *Y the pixel
20714 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
20716 RIGHT_P non-zero means return the position of the right edge of the
20717 glyph, RIGHT_P zero means return the left edge position.
20719 If no glyph for POS exists in the matrix, return the position of
20720 the glyph with the next smaller position that is in the matrix, if
20721 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
20722 exists in the matrix, return the position of the glyph with the
20723 next larger position in OBJECT.
20725 Value is non-zero if a glyph was found. */
20727 static int
20728 fast_find_string_pos (w, pos, object, hpos, vpos, x, y, right_p)
20729 struct window *w;
20730 int pos;
20731 Lisp_Object object;
20732 int *hpos, *vpos, *x, *y;
20733 int right_p;
20735 int yb = window_text_bottom_y (w);
20736 struct glyph_row *r;
20737 struct glyph *best_glyph = NULL;
20738 struct glyph_row *best_row = NULL;
20739 int best_x = 0;
20741 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
20742 r->enabled_p && r->y < yb;
20743 ++r)
20745 struct glyph *g = r->glyphs[TEXT_AREA];
20746 struct glyph *e = g + r->used[TEXT_AREA];
20747 int gx;
20749 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
20750 if (EQ (g->object, object))
20752 if (g->charpos == pos)
20754 best_glyph = g;
20755 best_x = gx;
20756 best_row = r;
20757 goto found;
20759 else if (best_glyph == NULL
20760 || ((abs (g->charpos - pos)
20761 < abs (best_glyph->charpos - pos))
20762 && (right_p
20763 ? g->charpos < pos
20764 : g->charpos > pos)))
20766 best_glyph = g;
20767 best_x = gx;
20768 best_row = r;
20773 found:
20775 if (best_glyph)
20777 *x = best_x;
20778 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
20780 if (right_p)
20782 *x += best_glyph->pixel_width;
20783 ++*hpos;
20786 *y = best_row->y;
20787 *vpos = best_row - w->current_matrix->rows;
20790 return best_glyph != NULL;
20794 /* See if position X, Y is within a hot-spot of an image. */
20796 static int
20797 on_hot_spot_p (hot_spot, x, y)
20798 Lisp_Object hot_spot;
20799 int x, y;
20801 if (!CONSP (hot_spot))
20802 return 0;
20804 if (EQ (XCAR (hot_spot), Qrect))
20806 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
20807 Lisp_Object rect = XCDR (hot_spot);
20808 Lisp_Object tem;
20809 if (!CONSP (rect))
20810 return 0;
20811 if (!CONSP (XCAR (rect)))
20812 return 0;
20813 if (!CONSP (XCDR (rect)))
20814 return 0;
20815 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
20816 return 0;
20817 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
20818 return 0;
20819 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
20820 return 0;
20821 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
20822 return 0;
20823 return 1;
20825 else if (EQ (XCAR (hot_spot), Qcircle))
20827 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
20828 Lisp_Object circ = XCDR (hot_spot);
20829 Lisp_Object lr, lx0, ly0;
20830 if (CONSP (circ)
20831 && CONSP (XCAR (circ))
20832 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
20833 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
20834 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
20836 double r = XFLOATINT (lr);
20837 double dx = XINT (lx0) - x;
20838 double dy = XINT (ly0) - y;
20839 return (dx * dx + dy * dy <= r * r);
20842 else if (EQ (XCAR (hot_spot), Qpoly))
20844 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
20845 if (VECTORP (XCDR (hot_spot)))
20847 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
20848 Lisp_Object *poly = v->contents;
20849 int n = v->size;
20850 int i;
20851 int inside = 0;
20852 Lisp_Object lx, ly;
20853 int x0, y0;
20855 /* Need an even number of coordinates, and at least 3 edges. */
20856 if (n < 6 || n & 1)
20857 return 0;
20859 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
20860 If count is odd, we are inside polygon. Pixels on edges
20861 may or may not be included depending on actual geometry of the
20862 polygon. */
20863 if ((lx = poly[n-2], !INTEGERP (lx))
20864 || (ly = poly[n-1], !INTEGERP (lx)))
20865 return 0;
20866 x0 = XINT (lx), y0 = XINT (ly);
20867 for (i = 0; i < n; i += 2)
20869 int x1 = x0, y1 = y0;
20870 if ((lx = poly[i], !INTEGERP (lx))
20871 || (ly = poly[i+1], !INTEGERP (ly)))
20872 return 0;
20873 x0 = XINT (lx), y0 = XINT (ly);
20875 /* Does this segment cross the X line? */
20876 if (x0 >= x)
20878 if (x1 >= x)
20879 continue;
20881 else if (x1 < x)
20882 continue;
20883 if (y > y0 && y > y1)
20884 continue;
20885 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
20886 inside = !inside;
20888 return inside;
20891 /* If we don't understand the format, pretend we're not in the hot-spot. */
20892 return 0;
20895 Lisp_Object
20896 find_hot_spot (map, x, y)
20897 Lisp_Object map;
20898 int x, y;
20900 while (CONSP (map))
20902 if (CONSP (XCAR (map))
20903 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
20904 return XCAR (map);
20905 map = XCDR (map);
20908 return Qnil;
20911 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
20912 3, 3, 0,
20913 doc: /* Lookup in image map MAP coordinates X and Y.
20914 An image map is an alist where each element has the format (AREA ID PLIST).
20915 An AREA is specified as either a rectangle, a circle, or a polygon:
20916 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
20917 pixel coordinates of the upper left and bottom right corners.
20918 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
20919 and the radius of the circle; r may be a float or integer.
20920 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
20921 vector describes one corner in the polygon.
20922 Returns the alist element for the first matching AREA in MAP. */)
20923 (map, x, y)
20924 Lisp_Object map;
20925 Lisp_Object x, y;
20927 if (NILP (map))
20928 return Qnil;
20930 CHECK_NUMBER (x);
20931 CHECK_NUMBER (y);
20933 return find_hot_spot (map, XINT (x), XINT (y));
20937 /* Display frame CURSOR, optionally using shape defined by POINTER. */
20938 static void
20939 define_frame_cursor1 (f, cursor, pointer)
20940 struct frame *f;
20941 Cursor cursor;
20942 Lisp_Object pointer;
20944 /* Do not change cursor shape while dragging mouse. */
20945 if (!NILP (do_mouse_tracking))
20946 return;
20948 if (!NILP (pointer))
20950 if (EQ (pointer, Qarrow))
20951 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20952 else if (EQ (pointer, Qhand))
20953 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
20954 else if (EQ (pointer, Qtext))
20955 cursor = FRAME_X_OUTPUT (f)->text_cursor;
20956 else if (EQ (pointer, intern ("hdrag")))
20957 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
20958 #ifdef HAVE_X_WINDOWS
20959 else if (EQ (pointer, intern ("vdrag")))
20960 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
20961 #endif
20962 else if (EQ (pointer, intern ("hourglass")))
20963 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
20964 else if (EQ (pointer, Qmodeline))
20965 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
20966 else
20967 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20970 if (cursor != No_Cursor)
20971 rif->define_frame_cursor (f, cursor);
20974 /* Take proper action when mouse has moved to the mode or header line
20975 or marginal area AREA of window W, x-position X and y-position Y.
20976 X is relative to the start of the text display area of W, so the
20977 width of bitmap areas and scroll bars must be subtracted to get a
20978 position relative to the start of the mode line. */
20980 static void
20981 note_mode_line_or_margin_highlight (w, x, y, area)
20982 struct window *w;
20983 int x, y;
20984 enum window_part area;
20986 struct frame *f = XFRAME (w->frame);
20987 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
20988 Cursor cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20989 Lisp_Object pointer = Qnil;
20990 int charpos, dx, dy, width, height;
20991 Lisp_Object string, object = Qnil;
20992 Lisp_Object pos, help;
20994 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
20995 string = mode_line_string (w, area, &x, &y, &charpos,
20996 &object, &dx, &dy, &width, &height);
20997 else
20999 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
21000 string = marginal_area_string (w, area, &x, &y, &charpos,
21001 &object, &dx, &dy, &width, &height);
21004 help = Qnil;
21006 if (IMAGEP (object))
21008 Lisp_Object image_map, hotspot;
21009 if ((image_map = Fsafe_plist_get (XCDR (object), QCmap),
21010 !NILP (image_map))
21011 && (hotspot = find_hot_spot (image_map, dx, dy),
21012 CONSP (hotspot))
21013 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
21015 Lisp_Object area_id, plist;
21017 area_id = XCAR (hotspot);
21018 /* Could check AREA_ID to see if we enter/leave this hot-spot.
21019 If so, we could look for mouse-enter, mouse-leave
21020 properties in PLIST (and do something...). */
21021 hotspot = XCDR (hotspot);
21022 if (CONSP (hotspot)
21023 && (plist = XCAR (hotspot), CONSP (plist)))
21025 pointer = Fsafe_plist_get (plist, Qpointer);
21026 if (NILP (pointer))
21027 pointer = Qhand;
21028 help = Fsafe_plist_get (plist, Qhelp_echo);
21029 if (!NILP (help))
21031 help_echo_string = help;
21032 /* Is this correct? ++kfs */
21033 XSETWINDOW (help_echo_window, w);
21034 help_echo_object = w->buffer;
21035 help_echo_pos = charpos;
21038 if (NILP (pointer))
21039 pointer = Fsafe_plist_get (XCDR (object), QCpointer);
21043 if (STRINGP (string))
21045 pos = make_number (charpos);
21046 /* If we're on a string with `help-echo' text property, arrange
21047 for the help to be displayed. This is done by setting the
21048 global variable help_echo_string to the help string. */
21049 if (NILP (help))
21051 help = Fget_text_property (pos, Qhelp_echo, string);
21052 if (!NILP (help))
21054 help_echo_string = help;
21055 XSETWINDOW (help_echo_window, w);
21056 help_echo_object = string;
21057 help_echo_pos = charpos;
21061 if (NILP (pointer))
21062 pointer = Fget_text_property (pos, Qpointer, string);
21064 /* Change the mouse pointer according to what is under X/Y. */
21065 if (NILP (pointer) && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
21067 Lisp_Object map;
21068 map = Fget_text_property (pos, Qlocal_map, string);
21069 if (!KEYMAPP (map))
21070 map = Fget_text_property (pos, Qkeymap, string);
21071 if (!KEYMAPP (map))
21072 cursor = dpyinfo->vertical_scroll_bar_cursor;
21076 define_frame_cursor1 (f, cursor, pointer);
21080 /* EXPORT:
21081 Take proper action when the mouse has moved to position X, Y on
21082 frame F as regards highlighting characters that have mouse-face
21083 properties. Also de-highlighting chars where the mouse was before.
21084 X and Y can be negative or out of range. */
21086 void
21087 note_mouse_highlight (f, x, y)
21088 struct frame *f;
21089 int x, y;
21091 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
21092 enum window_part part;
21093 Lisp_Object window;
21094 struct window *w;
21095 Cursor cursor = No_Cursor;
21096 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
21097 struct buffer *b;
21099 /* When a menu is active, don't highlight because this looks odd. */
21100 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NTGUI)
21101 if (popup_activated ())
21102 return;
21103 #endif
21105 if (NILP (Vmouse_highlight)
21106 || !f->glyphs_initialized_p)
21107 return;
21109 dpyinfo->mouse_face_mouse_x = x;
21110 dpyinfo->mouse_face_mouse_y = y;
21111 dpyinfo->mouse_face_mouse_frame = f;
21113 if (dpyinfo->mouse_face_defer)
21114 return;
21116 if (gc_in_progress)
21118 dpyinfo->mouse_face_deferred_gc = 1;
21119 return;
21122 /* Which window is that in? */
21123 window = window_from_coordinates (f, x, y, &part, 0, 0, 1);
21125 /* If we were displaying active text in another window, clear that.
21126 Also clear if we move out of text area in same window. */
21127 if (! EQ (window, dpyinfo->mouse_face_window)
21128 || (part != ON_TEXT && !NILP (dpyinfo->mouse_face_window)))
21129 clear_mouse_face (dpyinfo);
21131 /* Not on a window -> return. */
21132 if (!WINDOWP (window))
21133 return;
21135 /* Reset help_echo_string. It will get recomputed below. */
21136 help_echo_string = Qnil;
21138 /* Convert to window-relative pixel coordinates. */
21139 w = XWINDOW (window);
21140 frame_to_window_pixel_xy (w, &x, &y);
21142 /* Handle tool-bar window differently since it doesn't display a
21143 buffer. */
21144 if (EQ (window, f->tool_bar_window))
21146 note_tool_bar_highlight (f, x, y);
21147 return;
21150 /* Mouse is on the mode, header line or margin? */
21151 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
21152 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
21154 note_mode_line_or_margin_highlight (w, x, y, part);
21155 return;
21158 if (part == ON_VERTICAL_BORDER)
21159 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
21160 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
21161 || part == ON_SCROLL_BAR)
21162 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
21163 else
21164 cursor = FRAME_X_OUTPUT (f)->text_cursor;
21166 /* Are we in a window whose display is up to date?
21167 And verify the buffer's text has not changed. */
21168 b = XBUFFER (w->buffer);
21169 if (part == ON_TEXT
21170 && EQ (w->window_end_valid, w->buffer)
21171 && XFASTINT (w->last_modified) == BUF_MODIFF (b)
21172 && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
21174 int hpos, vpos, pos, i, dx, dy, area;
21175 struct glyph *glyph;
21176 Lisp_Object object;
21177 Lisp_Object mouse_face = Qnil, overlay = Qnil, position;
21178 Lisp_Object *overlay_vec = NULL;
21179 int noverlays;
21180 struct buffer *obuf;
21181 int obegv, ozv, same_region;
21183 /* Find the glyph under X/Y. */
21184 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
21186 /* Look for :pointer property on image. */
21187 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
21189 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
21190 if (img != NULL && IMAGEP (img->spec))
21192 Lisp_Object image_map, hotspot;
21193 if ((image_map = Fsafe_plist_get (XCDR (img->spec), QCmap),
21194 !NILP (image_map))
21195 && (hotspot = find_hot_spot (image_map,
21196 glyph->slice.x + dx,
21197 glyph->slice.y + dy),
21198 CONSP (hotspot))
21199 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
21201 Lisp_Object area_id, plist;
21203 area_id = XCAR (hotspot);
21204 /* Could check AREA_ID to see if we enter/leave this hot-spot.
21205 If so, we could look for mouse-enter, mouse-leave
21206 properties in PLIST (and do something...). */
21207 hotspot = XCDR (hotspot);
21208 if (CONSP (hotspot)
21209 && (plist = XCAR (hotspot), CONSP (plist)))
21211 pointer = Fsafe_plist_get (plist, Qpointer);
21212 if (NILP (pointer))
21213 pointer = Qhand;
21214 help_echo_string = Fsafe_plist_get (plist, Qhelp_echo);
21215 if (!NILP (help_echo_string))
21217 help_echo_window = window;
21218 help_echo_object = glyph->object;
21219 help_echo_pos = glyph->charpos;
21223 if (NILP (pointer))
21224 pointer = Fsafe_plist_get (XCDR (img->spec), QCpointer);
21228 /* Clear mouse face if X/Y not over text. */
21229 if (glyph == NULL
21230 || area != TEXT_AREA
21231 || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p)
21233 if (clear_mouse_face (dpyinfo))
21234 cursor = No_Cursor;
21235 if (NILP (pointer))
21237 if (area != TEXT_AREA)
21238 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
21239 else
21240 pointer = Vvoid_text_area_pointer;
21242 goto set_cursor;
21245 pos = glyph->charpos;
21246 object = glyph->object;
21247 if (!STRINGP (object) && !BUFFERP (object))
21248 goto set_cursor;
21250 /* If we get an out-of-range value, return now; avoid an error. */
21251 if (BUFFERP (object) && pos > BUF_Z (b))
21252 goto set_cursor;
21254 /* Make the window's buffer temporarily current for
21255 overlays_at and compute_char_face. */
21256 obuf = current_buffer;
21257 current_buffer = b;
21258 obegv = BEGV;
21259 ozv = ZV;
21260 BEGV = BEG;
21261 ZV = Z;
21263 /* Is this char mouse-active or does it have help-echo? */
21264 position = make_number (pos);
21266 if (BUFFERP (object))
21268 /* Put all the overlays we want in a vector in overlay_vec. */
21269 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
21270 /* Sort overlays into increasing priority order. */
21271 noverlays = sort_overlays (overlay_vec, noverlays, w);
21273 else
21274 noverlays = 0;
21276 same_region = (EQ (window, dpyinfo->mouse_face_window)
21277 && vpos >= dpyinfo->mouse_face_beg_row
21278 && vpos <= dpyinfo->mouse_face_end_row
21279 && (vpos > dpyinfo->mouse_face_beg_row
21280 || hpos >= dpyinfo->mouse_face_beg_col)
21281 && (vpos < dpyinfo->mouse_face_end_row
21282 || hpos < dpyinfo->mouse_face_end_col
21283 || dpyinfo->mouse_face_past_end));
21285 if (same_region)
21286 cursor = No_Cursor;
21288 /* Check mouse-face highlighting. */
21289 if (! same_region
21290 /* If there exists an overlay with mouse-face overlapping
21291 the one we are currently highlighting, we have to
21292 check if we enter the overlapping overlay, and then
21293 highlight only that. */
21294 || (OVERLAYP (dpyinfo->mouse_face_overlay)
21295 && mouse_face_overlay_overlaps (dpyinfo->mouse_face_overlay)))
21297 /* Find the highest priority overlay that has a mouse-face
21298 property. */
21299 overlay = Qnil;
21300 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
21302 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
21303 if (!NILP (mouse_face))
21304 overlay = overlay_vec[i];
21307 /* If we're actually highlighting the same overlay as
21308 before, there's no need to do that again. */
21309 if (!NILP (overlay)
21310 && EQ (overlay, dpyinfo->mouse_face_overlay))
21311 goto check_help_echo;
21313 dpyinfo->mouse_face_overlay = overlay;
21315 /* Clear the display of the old active region, if any. */
21316 if (clear_mouse_face (dpyinfo))
21317 cursor = No_Cursor;
21319 /* If no overlay applies, get a text property. */
21320 if (NILP (overlay))
21321 mouse_face = Fget_text_property (position, Qmouse_face, object);
21323 /* Handle the overlay case. */
21324 if (!NILP (overlay))
21326 /* Find the range of text around this char that
21327 should be active. */
21328 Lisp_Object before, after;
21329 int ignore;
21331 before = Foverlay_start (overlay);
21332 after = Foverlay_end (overlay);
21333 /* Record this as the current active region. */
21334 fast_find_position (w, XFASTINT (before),
21335 &dpyinfo->mouse_face_beg_col,
21336 &dpyinfo->mouse_face_beg_row,
21337 &dpyinfo->mouse_face_beg_x,
21338 &dpyinfo->mouse_face_beg_y, Qnil);
21340 dpyinfo->mouse_face_past_end
21341 = !fast_find_position (w, XFASTINT (after),
21342 &dpyinfo->mouse_face_end_col,
21343 &dpyinfo->mouse_face_end_row,
21344 &dpyinfo->mouse_face_end_x,
21345 &dpyinfo->mouse_face_end_y, Qnil);
21346 dpyinfo->mouse_face_window = window;
21348 dpyinfo->mouse_face_face_id
21349 = face_at_buffer_position (w, pos, 0, 0,
21350 &ignore, pos + 1,
21351 !dpyinfo->mouse_face_hidden);
21353 /* Display it as active. */
21354 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21355 cursor = No_Cursor;
21357 /* Handle the text property case. */
21358 else if (!NILP (mouse_face) && BUFFERP (object))
21360 /* Find the range of text around this char that
21361 should be active. */
21362 Lisp_Object before, after, beginning, end;
21363 int ignore;
21365 beginning = Fmarker_position (w->start);
21366 end = make_number (BUF_Z (XBUFFER (object))
21367 - XFASTINT (w->window_end_pos));
21368 before
21369 = Fprevious_single_property_change (make_number (pos + 1),
21370 Qmouse_face,
21371 object, beginning);
21372 after
21373 = Fnext_single_property_change (position, Qmouse_face,
21374 object, end);
21376 /* Record this as the current active region. */
21377 fast_find_position (w, XFASTINT (before),
21378 &dpyinfo->mouse_face_beg_col,
21379 &dpyinfo->mouse_face_beg_row,
21380 &dpyinfo->mouse_face_beg_x,
21381 &dpyinfo->mouse_face_beg_y, Qnil);
21382 dpyinfo->mouse_face_past_end
21383 = !fast_find_position (w, XFASTINT (after),
21384 &dpyinfo->mouse_face_end_col,
21385 &dpyinfo->mouse_face_end_row,
21386 &dpyinfo->mouse_face_end_x,
21387 &dpyinfo->mouse_face_end_y, Qnil);
21388 dpyinfo->mouse_face_window = window;
21390 if (BUFFERP (object))
21391 dpyinfo->mouse_face_face_id
21392 = face_at_buffer_position (w, pos, 0, 0,
21393 &ignore, pos + 1,
21394 !dpyinfo->mouse_face_hidden);
21396 /* Display it as active. */
21397 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21398 cursor = No_Cursor;
21400 else if (!NILP (mouse_face) && STRINGP (object))
21402 Lisp_Object b, e;
21403 int ignore;
21405 b = Fprevious_single_property_change (make_number (pos + 1),
21406 Qmouse_face,
21407 object, Qnil);
21408 e = Fnext_single_property_change (position, Qmouse_face,
21409 object, Qnil);
21410 if (NILP (b))
21411 b = make_number (0);
21412 if (NILP (e))
21413 e = make_number (SCHARS (object) - 1);
21414 fast_find_string_pos (w, XINT (b), object,
21415 &dpyinfo->mouse_face_beg_col,
21416 &dpyinfo->mouse_face_beg_row,
21417 &dpyinfo->mouse_face_beg_x,
21418 &dpyinfo->mouse_face_beg_y, 0);
21419 fast_find_string_pos (w, XINT (e), object,
21420 &dpyinfo->mouse_face_end_col,
21421 &dpyinfo->mouse_face_end_row,
21422 &dpyinfo->mouse_face_end_x,
21423 &dpyinfo->mouse_face_end_y, 1);
21424 dpyinfo->mouse_face_past_end = 0;
21425 dpyinfo->mouse_face_window = window;
21426 dpyinfo->mouse_face_face_id
21427 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
21428 glyph->face_id, 1);
21429 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21430 cursor = No_Cursor;
21432 else if (STRINGP (object) && NILP (mouse_face))
21434 /* A string which doesn't have mouse-face, but
21435 the text ``under'' it might have. */
21436 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
21437 int start = MATRIX_ROW_START_CHARPOS (r);
21439 pos = string_buffer_position (w, object, start);
21440 if (pos > 0)
21441 mouse_face = get_char_property_and_overlay (make_number (pos),
21442 Qmouse_face,
21443 w->buffer,
21444 &overlay);
21445 if (!NILP (mouse_face) && !NILP (overlay))
21447 Lisp_Object before = Foverlay_start (overlay);
21448 Lisp_Object after = Foverlay_end (overlay);
21449 int ignore;
21451 /* Note that we might not be able to find position
21452 BEFORE in the glyph matrix if the overlay is
21453 entirely covered by a `display' property. In
21454 this case, we overshoot. So let's stop in
21455 the glyph matrix before glyphs for OBJECT. */
21456 fast_find_position (w, XFASTINT (before),
21457 &dpyinfo->mouse_face_beg_col,
21458 &dpyinfo->mouse_face_beg_row,
21459 &dpyinfo->mouse_face_beg_x,
21460 &dpyinfo->mouse_face_beg_y,
21461 object);
21463 dpyinfo->mouse_face_past_end
21464 = !fast_find_position (w, XFASTINT (after),
21465 &dpyinfo->mouse_face_end_col,
21466 &dpyinfo->mouse_face_end_row,
21467 &dpyinfo->mouse_face_end_x,
21468 &dpyinfo->mouse_face_end_y,
21469 Qnil);
21470 dpyinfo->mouse_face_window = window;
21471 dpyinfo->mouse_face_face_id
21472 = face_at_buffer_position (w, pos, 0, 0,
21473 &ignore, pos + 1,
21474 !dpyinfo->mouse_face_hidden);
21476 /* Display it as active. */
21477 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21478 cursor = No_Cursor;
21483 check_help_echo:
21485 /* Look for a `help-echo' property. */
21486 if (NILP (help_echo_string)) {
21487 Lisp_Object help, overlay;
21489 /* Check overlays first. */
21490 help = overlay = Qnil;
21491 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
21493 overlay = overlay_vec[i];
21494 help = Foverlay_get (overlay, Qhelp_echo);
21497 if (!NILP (help))
21499 help_echo_string = help;
21500 help_echo_window = window;
21501 help_echo_object = overlay;
21502 help_echo_pos = pos;
21504 else
21506 Lisp_Object object = glyph->object;
21507 int charpos = glyph->charpos;
21509 /* Try text properties. */
21510 if (STRINGP (object)
21511 && charpos >= 0
21512 && charpos < SCHARS (object))
21514 help = Fget_text_property (make_number (charpos),
21515 Qhelp_echo, object);
21516 if (NILP (help))
21518 /* If the string itself doesn't specify a help-echo,
21519 see if the buffer text ``under'' it does. */
21520 struct glyph_row *r
21521 = MATRIX_ROW (w->current_matrix, vpos);
21522 int start = MATRIX_ROW_START_CHARPOS (r);
21523 int pos = string_buffer_position (w, object, start);
21524 if (pos > 0)
21526 help = Fget_char_property (make_number (pos),
21527 Qhelp_echo, w->buffer);
21528 if (!NILP (help))
21530 charpos = pos;
21531 object = w->buffer;
21536 else if (BUFFERP (object)
21537 && charpos >= BEGV
21538 && charpos < ZV)
21539 help = Fget_text_property (make_number (charpos), Qhelp_echo,
21540 object);
21542 if (!NILP (help))
21544 help_echo_string = help;
21545 help_echo_window = window;
21546 help_echo_object = object;
21547 help_echo_pos = charpos;
21552 /* Look for a `pointer' property. */
21553 if (NILP (pointer))
21555 /* Check overlays first. */
21556 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
21557 pointer = Foverlay_get (overlay_vec[i], Qpointer);
21559 if (NILP (pointer))
21561 Lisp_Object object = glyph->object;
21562 int charpos = glyph->charpos;
21564 /* Try text properties. */
21565 if (STRINGP (object)
21566 && charpos >= 0
21567 && charpos < SCHARS (object))
21569 pointer = Fget_text_property (make_number (charpos),
21570 Qpointer, object);
21571 if (NILP (pointer))
21573 /* If the string itself doesn't specify a pointer,
21574 see if the buffer text ``under'' it does. */
21575 struct glyph_row *r
21576 = MATRIX_ROW (w->current_matrix, vpos);
21577 int start = MATRIX_ROW_START_CHARPOS (r);
21578 int pos = string_buffer_position (w, object, start);
21579 if (pos > 0)
21580 pointer = Fget_char_property (make_number (pos),
21581 Qpointer, w->buffer);
21584 else if (BUFFERP (object)
21585 && charpos >= BEGV
21586 && charpos < ZV)
21587 pointer = Fget_text_property (make_number (charpos),
21588 Qpointer, object);
21592 BEGV = obegv;
21593 ZV = ozv;
21594 current_buffer = obuf;
21597 set_cursor:
21599 define_frame_cursor1 (f, cursor, pointer);
21603 /* EXPORT for RIF:
21604 Clear any mouse-face on window W. This function is part of the
21605 redisplay interface, and is called from try_window_id and similar
21606 functions to ensure the mouse-highlight is off. */
21608 void
21609 x_clear_window_mouse_face (w)
21610 struct window *w;
21612 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
21613 Lisp_Object window;
21615 BLOCK_INPUT;
21616 XSETWINDOW (window, w);
21617 if (EQ (window, dpyinfo->mouse_face_window))
21618 clear_mouse_face (dpyinfo);
21619 UNBLOCK_INPUT;
21623 /* EXPORT:
21624 Just discard the mouse face information for frame F, if any.
21625 This is used when the size of F is changed. */
21627 void
21628 cancel_mouse_face (f)
21629 struct frame *f;
21631 Lisp_Object window;
21632 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
21634 window = dpyinfo->mouse_face_window;
21635 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
21637 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
21638 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
21639 dpyinfo->mouse_face_window = Qnil;
21644 #endif /* HAVE_WINDOW_SYSTEM */
21647 /***********************************************************************
21648 Exposure Events
21649 ***********************************************************************/
21651 #ifdef HAVE_WINDOW_SYSTEM
21653 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
21654 which intersects rectangle R. R is in window-relative coordinates. */
21656 static void
21657 expose_area (w, row, r, area)
21658 struct window *w;
21659 struct glyph_row *row;
21660 XRectangle *r;
21661 enum glyph_row_area area;
21663 struct glyph *first = row->glyphs[area];
21664 struct glyph *end = row->glyphs[area] + row->used[area];
21665 struct glyph *last;
21666 int first_x, start_x, x;
21668 if (area == TEXT_AREA && row->fill_line_p)
21669 /* If row extends face to end of line write the whole line. */
21670 draw_glyphs (w, 0, row, area,
21671 0, row->used[area],
21672 DRAW_NORMAL_TEXT, 0);
21673 else
21675 /* Set START_X to the window-relative start position for drawing glyphs of
21676 AREA. The first glyph of the text area can be partially visible.
21677 The first glyphs of other areas cannot. */
21678 start_x = window_box_left_offset (w, area);
21679 x = start_x;
21680 if (area == TEXT_AREA)
21681 x += row->x;
21683 /* Find the first glyph that must be redrawn. */
21684 while (first < end
21685 && x + first->pixel_width < r->x)
21687 x += first->pixel_width;
21688 ++first;
21691 /* Find the last one. */
21692 last = first;
21693 first_x = x;
21694 while (last < end
21695 && x < r->x + r->width)
21697 x += last->pixel_width;
21698 ++last;
21701 /* Repaint. */
21702 if (last > first)
21703 draw_glyphs (w, first_x - start_x, row, area,
21704 first - row->glyphs[area], last - row->glyphs[area],
21705 DRAW_NORMAL_TEXT, 0);
21710 /* Redraw the parts of the glyph row ROW on window W intersecting
21711 rectangle R. R is in window-relative coordinates. Value is
21712 non-zero if mouse-face was overwritten. */
21714 static int
21715 expose_line (w, row, r)
21716 struct window *w;
21717 struct glyph_row *row;
21718 XRectangle *r;
21720 xassert (row->enabled_p);
21722 if (row->mode_line_p || w->pseudo_window_p)
21723 draw_glyphs (w, 0, row, TEXT_AREA,
21724 0, row->used[TEXT_AREA],
21725 DRAW_NORMAL_TEXT, 0);
21726 else
21728 if (row->used[LEFT_MARGIN_AREA])
21729 expose_area (w, row, r, LEFT_MARGIN_AREA);
21730 if (row->used[TEXT_AREA])
21731 expose_area (w, row, r, TEXT_AREA);
21732 if (row->used[RIGHT_MARGIN_AREA])
21733 expose_area (w, row, r, RIGHT_MARGIN_AREA);
21734 draw_row_fringe_bitmaps (w, row);
21737 return row->mouse_face_p;
21741 /* Redraw those parts of glyphs rows during expose event handling that
21742 overlap other rows. Redrawing of an exposed line writes over parts
21743 of lines overlapping that exposed line; this function fixes that.
21745 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
21746 row in W's current matrix that is exposed and overlaps other rows.
21747 LAST_OVERLAPPING_ROW is the last such row. */
21749 static void
21750 expose_overlaps (w, first_overlapping_row, last_overlapping_row)
21751 struct window *w;
21752 struct glyph_row *first_overlapping_row;
21753 struct glyph_row *last_overlapping_row;
21755 struct glyph_row *row;
21757 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
21758 if (row->overlapping_p)
21760 xassert (row->enabled_p && !row->mode_line_p);
21762 if (row->used[LEFT_MARGIN_AREA])
21763 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA);
21765 if (row->used[TEXT_AREA])
21766 x_fix_overlapping_area (w, row, TEXT_AREA);
21768 if (row->used[RIGHT_MARGIN_AREA])
21769 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA);
21774 /* Return non-zero if W's cursor intersects rectangle R. */
21776 static int
21777 phys_cursor_in_rect_p (w, r)
21778 struct window *w;
21779 XRectangle *r;
21781 XRectangle cr, result;
21782 struct glyph *cursor_glyph;
21784 cursor_glyph = get_phys_cursor_glyph (w);
21785 if (cursor_glyph)
21787 /* r is relative to W's box, but w->phys_cursor.x is relative
21788 to left edge of W's TEXT area. Adjust it. */
21789 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
21790 cr.y = w->phys_cursor.y;
21791 cr.width = cursor_glyph->pixel_width;
21792 cr.height = w->phys_cursor_height;
21793 /* ++KFS: W32 version used W32-specific IntersectRect here, but
21794 I assume the effect is the same -- and this is portable. */
21795 return x_intersect_rectangles (&cr, r, &result);
21797 else
21798 return 0;
21802 /* EXPORT:
21803 Draw a vertical window border to the right of window W if W doesn't
21804 have vertical scroll bars. */
21806 void
21807 x_draw_vertical_border (w)
21808 struct window *w;
21810 /* We could do better, if we knew what type of scroll-bar the adjacent
21811 windows (on either side) have... But we don't :-(
21812 However, I think this works ok. ++KFS 2003-04-25 */
21814 /* Redraw borders between horizontally adjacent windows. Don't
21815 do it for frames with vertical scroll bars because either the
21816 right scroll bar of a window, or the left scroll bar of its
21817 neighbor will suffice as a border. */
21818 if (FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (w->frame)))
21819 return;
21821 if (!WINDOW_RIGHTMOST_P (w)
21822 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
21824 int x0, x1, y0, y1;
21826 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
21827 y1 -= 1;
21829 rif->draw_vertical_window_border (w, x1, y0, y1);
21831 else if (!WINDOW_LEFTMOST_P (w)
21832 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
21834 int x0, x1, y0, y1;
21836 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
21837 y1 -= 1;
21839 rif->draw_vertical_window_border (w, x0, y0, y1);
21844 /* Redraw the part of window W intersection rectangle FR. Pixel
21845 coordinates in FR are frame-relative. Call this function with
21846 input blocked. Value is non-zero if the exposure overwrites
21847 mouse-face. */
21849 static int
21850 expose_window (w, fr)
21851 struct window *w;
21852 XRectangle *fr;
21854 struct frame *f = XFRAME (w->frame);
21855 XRectangle wr, r;
21856 int mouse_face_overwritten_p = 0;
21858 /* If window is not yet fully initialized, do nothing. This can
21859 happen when toolkit scroll bars are used and a window is split.
21860 Reconfiguring the scroll bar will generate an expose for a newly
21861 created window. */
21862 if (w->current_matrix == NULL)
21863 return 0;
21865 /* When we're currently updating the window, display and current
21866 matrix usually don't agree. Arrange for a thorough display
21867 later. */
21868 if (w == updated_window)
21870 SET_FRAME_GARBAGED (f);
21871 return 0;
21874 /* Frame-relative pixel rectangle of W. */
21875 wr.x = WINDOW_LEFT_EDGE_X (w);
21876 wr.y = WINDOW_TOP_EDGE_Y (w);
21877 wr.width = WINDOW_TOTAL_WIDTH (w);
21878 wr.height = WINDOW_TOTAL_HEIGHT (w);
21880 if (x_intersect_rectangles (fr, &wr, &r))
21882 int yb = window_text_bottom_y (w);
21883 struct glyph_row *row;
21884 int cursor_cleared_p;
21885 struct glyph_row *first_overlapping_row, *last_overlapping_row;
21887 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
21888 r.x, r.y, r.width, r.height));
21890 /* Convert to window coordinates. */
21891 r.x -= WINDOW_LEFT_EDGE_X (w);
21892 r.y -= WINDOW_TOP_EDGE_Y (w);
21894 /* Turn off the cursor. */
21895 if (!w->pseudo_window_p
21896 && phys_cursor_in_rect_p (w, &r))
21898 x_clear_cursor (w);
21899 cursor_cleared_p = 1;
21901 else
21902 cursor_cleared_p = 0;
21904 /* Update lines intersecting rectangle R. */
21905 first_overlapping_row = last_overlapping_row = NULL;
21906 for (row = w->current_matrix->rows;
21907 row->enabled_p;
21908 ++row)
21910 int y0 = row->y;
21911 int y1 = MATRIX_ROW_BOTTOM_Y (row);
21913 if ((y0 >= r.y && y0 < r.y + r.height)
21914 || (y1 > r.y && y1 < r.y + r.height)
21915 || (r.y >= y0 && r.y < y1)
21916 || (r.y + r.height > y0 && r.y + r.height < y1))
21918 if (row->overlapping_p)
21920 if (first_overlapping_row == NULL)
21921 first_overlapping_row = row;
21922 last_overlapping_row = row;
21925 if (expose_line (w, row, &r))
21926 mouse_face_overwritten_p = 1;
21929 if (y1 >= yb)
21930 break;
21933 /* Display the mode line if there is one. */
21934 if (WINDOW_WANTS_MODELINE_P (w)
21935 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
21936 row->enabled_p)
21937 && row->y < r.y + r.height)
21939 if (expose_line (w, row, &r))
21940 mouse_face_overwritten_p = 1;
21943 if (!w->pseudo_window_p)
21945 /* Fix the display of overlapping rows. */
21946 if (first_overlapping_row)
21947 expose_overlaps (w, first_overlapping_row, last_overlapping_row);
21949 /* Draw border between windows. */
21950 x_draw_vertical_border (w);
21952 /* Turn the cursor on again. */
21953 if (cursor_cleared_p)
21954 update_window_cursor (w, 1);
21958 return mouse_face_overwritten_p;
21963 /* Redraw (parts) of all windows in the window tree rooted at W that
21964 intersect R. R contains frame pixel coordinates. Value is
21965 non-zero if the exposure overwrites mouse-face. */
21967 static int
21968 expose_window_tree (w, r)
21969 struct window *w;
21970 XRectangle *r;
21972 struct frame *f = XFRAME (w->frame);
21973 int mouse_face_overwritten_p = 0;
21975 while (w && !FRAME_GARBAGED_P (f))
21977 if (!NILP (w->hchild))
21978 mouse_face_overwritten_p
21979 |= expose_window_tree (XWINDOW (w->hchild), r);
21980 else if (!NILP (w->vchild))
21981 mouse_face_overwritten_p
21982 |= expose_window_tree (XWINDOW (w->vchild), r);
21983 else
21984 mouse_face_overwritten_p |= expose_window (w, r);
21986 w = NILP (w->next) ? NULL : XWINDOW (w->next);
21989 return mouse_face_overwritten_p;
21993 /* EXPORT:
21994 Redisplay an exposed area of frame F. X and Y are the upper-left
21995 corner of the exposed rectangle. W and H are width and height of
21996 the exposed area. All are pixel values. W or H zero means redraw
21997 the entire frame. */
21999 void
22000 expose_frame (f, x, y, w, h)
22001 struct frame *f;
22002 int x, y, w, h;
22004 XRectangle r;
22005 int mouse_face_overwritten_p = 0;
22007 TRACE ((stderr, "expose_frame "));
22009 /* No need to redraw if frame will be redrawn soon. */
22010 if (FRAME_GARBAGED_P (f))
22012 TRACE ((stderr, " garbaged\n"));
22013 return;
22016 /* If basic faces haven't been realized yet, there is no point in
22017 trying to redraw anything. This can happen when we get an expose
22018 event while Emacs is starting, e.g. by moving another window. */
22019 if (FRAME_FACE_CACHE (f) == NULL
22020 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
22022 TRACE ((stderr, " no faces\n"));
22023 return;
22026 if (w == 0 || h == 0)
22028 r.x = r.y = 0;
22029 r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f);
22030 r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f);
22032 else
22034 r.x = x;
22035 r.y = y;
22036 r.width = w;
22037 r.height = h;
22040 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
22041 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
22043 if (WINDOWP (f->tool_bar_window))
22044 mouse_face_overwritten_p
22045 |= expose_window (XWINDOW (f->tool_bar_window), &r);
22047 #ifdef HAVE_X_WINDOWS
22048 #ifndef MSDOS
22049 #ifndef USE_X_TOOLKIT
22050 if (WINDOWP (f->menu_bar_window))
22051 mouse_face_overwritten_p
22052 |= expose_window (XWINDOW (f->menu_bar_window), &r);
22053 #endif /* not USE_X_TOOLKIT */
22054 #endif
22055 #endif
22057 /* Some window managers support a focus-follows-mouse style with
22058 delayed raising of frames. Imagine a partially obscured frame,
22059 and moving the mouse into partially obscured mouse-face on that
22060 frame. The visible part of the mouse-face will be highlighted,
22061 then the WM raises the obscured frame. With at least one WM, KDE
22062 2.1, Emacs is not getting any event for the raising of the frame
22063 (even tried with SubstructureRedirectMask), only Expose events.
22064 These expose events will draw text normally, i.e. not
22065 highlighted. Which means we must redo the highlight here.
22066 Subsume it under ``we love X''. --gerd 2001-08-15 */
22067 /* Included in Windows version because Windows most likely does not
22068 do the right thing if any third party tool offers
22069 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
22070 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
22072 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
22073 if (f == dpyinfo->mouse_face_mouse_frame)
22075 int x = dpyinfo->mouse_face_mouse_x;
22076 int y = dpyinfo->mouse_face_mouse_y;
22077 clear_mouse_face (dpyinfo);
22078 note_mouse_highlight (f, x, y);
22084 /* EXPORT:
22085 Determine the intersection of two rectangles R1 and R2. Return
22086 the intersection in *RESULT. Value is non-zero if RESULT is not
22087 empty. */
22090 x_intersect_rectangles (r1, r2, result)
22091 XRectangle *r1, *r2, *result;
22093 XRectangle *left, *right;
22094 XRectangle *upper, *lower;
22095 int intersection_p = 0;
22097 /* Rearrange so that R1 is the left-most rectangle. */
22098 if (r1->x < r2->x)
22099 left = r1, right = r2;
22100 else
22101 left = r2, right = r1;
22103 /* X0 of the intersection is right.x0, if this is inside R1,
22104 otherwise there is no intersection. */
22105 if (right->x <= left->x + left->width)
22107 result->x = right->x;
22109 /* The right end of the intersection is the minimum of the
22110 the right ends of left and right. */
22111 result->width = (min (left->x + left->width, right->x + right->width)
22112 - result->x);
22114 /* Same game for Y. */
22115 if (r1->y < r2->y)
22116 upper = r1, lower = r2;
22117 else
22118 upper = r2, lower = r1;
22120 /* The upper end of the intersection is lower.y0, if this is inside
22121 of upper. Otherwise, there is no intersection. */
22122 if (lower->y <= upper->y + upper->height)
22124 result->y = lower->y;
22126 /* The lower end of the intersection is the minimum of the lower
22127 ends of upper and lower. */
22128 result->height = (min (lower->y + lower->height,
22129 upper->y + upper->height)
22130 - result->y);
22131 intersection_p = 1;
22135 return intersection_p;
22138 #endif /* HAVE_WINDOW_SYSTEM */
22141 /***********************************************************************
22142 Initialization
22143 ***********************************************************************/
22145 void
22146 syms_of_xdisp ()
22148 Vwith_echo_area_save_vector = Qnil;
22149 staticpro (&Vwith_echo_area_save_vector);
22151 Vmessage_stack = Qnil;
22152 staticpro (&Vmessage_stack);
22154 Qinhibit_redisplay = intern ("inhibit-redisplay");
22155 staticpro (&Qinhibit_redisplay);
22157 message_dolog_marker1 = Fmake_marker ();
22158 staticpro (&message_dolog_marker1);
22159 message_dolog_marker2 = Fmake_marker ();
22160 staticpro (&message_dolog_marker2);
22161 message_dolog_marker3 = Fmake_marker ();
22162 staticpro (&message_dolog_marker3);
22164 #if GLYPH_DEBUG
22165 defsubr (&Sdump_frame_glyph_matrix);
22166 defsubr (&Sdump_glyph_matrix);
22167 defsubr (&Sdump_glyph_row);
22168 defsubr (&Sdump_tool_bar_row);
22169 defsubr (&Strace_redisplay);
22170 defsubr (&Strace_to_stderr);
22171 #endif
22172 #ifdef HAVE_WINDOW_SYSTEM
22173 defsubr (&Stool_bar_lines_needed);
22174 defsubr (&Slookup_image_map);
22175 #endif
22176 defsubr (&Sformat_mode_line);
22178 staticpro (&Qmenu_bar_update_hook);
22179 Qmenu_bar_update_hook = intern ("menu-bar-update-hook");
22181 staticpro (&Qoverriding_terminal_local_map);
22182 Qoverriding_terminal_local_map = intern ("overriding-terminal-local-map");
22184 staticpro (&Qoverriding_local_map);
22185 Qoverriding_local_map = intern ("overriding-local-map");
22187 staticpro (&Qwindow_scroll_functions);
22188 Qwindow_scroll_functions = intern ("window-scroll-functions");
22190 staticpro (&Qredisplay_end_trigger_functions);
22191 Qredisplay_end_trigger_functions = intern ("redisplay-end-trigger-functions");
22193 staticpro (&Qinhibit_point_motion_hooks);
22194 Qinhibit_point_motion_hooks = intern ("inhibit-point-motion-hooks");
22196 QCdata = intern (":data");
22197 staticpro (&QCdata);
22198 Qdisplay = intern ("display");
22199 staticpro (&Qdisplay);
22200 Qspace_width = intern ("space-width");
22201 staticpro (&Qspace_width);
22202 Qraise = intern ("raise");
22203 staticpro (&Qraise);
22204 Qslice = intern ("slice");
22205 staticpro (&Qslice);
22206 Qspace = intern ("space");
22207 staticpro (&Qspace);
22208 Qmargin = intern ("margin");
22209 staticpro (&Qmargin);
22210 Qpointer = intern ("pointer");
22211 staticpro (&Qpointer);
22212 Qleft_margin = intern ("left-margin");
22213 staticpro (&Qleft_margin);
22214 Qright_margin = intern ("right-margin");
22215 staticpro (&Qright_margin);
22216 Qcenter = intern ("center");
22217 staticpro (&Qcenter);
22218 Qline_height = intern ("line-height");
22219 staticpro (&Qline_height);
22220 QCalign_to = intern (":align-to");
22221 staticpro (&QCalign_to);
22222 QCrelative_width = intern (":relative-width");
22223 staticpro (&QCrelative_width);
22224 QCrelative_height = intern (":relative-height");
22225 staticpro (&QCrelative_height);
22226 QCeval = intern (":eval");
22227 staticpro (&QCeval);
22228 QCpropertize = intern (":propertize");
22229 staticpro (&QCpropertize);
22230 QCfile = intern (":file");
22231 staticpro (&QCfile);
22232 Qfontified = intern ("fontified");
22233 staticpro (&Qfontified);
22234 Qfontification_functions = intern ("fontification-functions");
22235 staticpro (&Qfontification_functions);
22236 Qtrailing_whitespace = intern ("trailing-whitespace");
22237 staticpro (&Qtrailing_whitespace);
22238 Qescape_glyph = intern ("escape-glyph");
22239 staticpro (&Qescape_glyph);
22240 Qimage = intern ("image");
22241 staticpro (&Qimage);
22242 QCmap = intern (":map");
22243 staticpro (&QCmap);
22244 QCpointer = intern (":pointer");
22245 staticpro (&QCpointer);
22246 Qrect = intern ("rect");
22247 staticpro (&Qrect);
22248 Qcircle = intern ("circle");
22249 staticpro (&Qcircle);
22250 Qpoly = intern ("poly");
22251 staticpro (&Qpoly);
22252 Qmessage_truncate_lines = intern ("message-truncate-lines");
22253 staticpro (&Qmessage_truncate_lines);
22254 Qcursor_in_non_selected_windows = intern ("cursor-in-non-selected-windows");
22255 staticpro (&Qcursor_in_non_selected_windows);
22256 Qgrow_only = intern ("grow-only");
22257 staticpro (&Qgrow_only);
22258 Qinhibit_menubar_update = intern ("inhibit-menubar-update");
22259 staticpro (&Qinhibit_menubar_update);
22260 Qinhibit_eval_during_redisplay = intern ("inhibit-eval-during-redisplay");
22261 staticpro (&Qinhibit_eval_during_redisplay);
22262 Qposition = intern ("position");
22263 staticpro (&Qposition);
22264 Qbuffer_position = intern ("buffer-position");
22265 staticpro (&Qbuffer_position);
22266 Qobject = intern ("object");
22267 staticpro (&Qobject);
22268 Qbar = intern ("bar");
22269 staticpro (&Qbar);
22270 Qhbar = intern ("hbar");
22271 staticpro (&Qhbar);
22272 Qbox = intern ("box");
22273 staticpro (&Qbox);
22274 Qhollow = intern ("hollow");
22275 staticpro (&Qhollow);
22276 Qhand = intern ("hand");
22277 staticpro (&Qhand);
22278 Qarrow = intern ("arrow");
22279 staticpro (&Qarrow);
22280 Qtext = intern ("text");
22281 staticpro (&Qtext);
22282 Qrisky_local_variable = intern ("risky-local-variable");
22283 staticpro (&Qrisky_local_variable);
22284 Qinhibit_free_realized_faces = intern ("inhibit-free-realized-faces");
22285 staticpro (&Qinhibit_free_realized_faces);
22287 list_of_error = Fcons (Fcons (intern ("error"),
22288 Fcons (intern ("void-variable"), Qnil)),
22289 Qnil);
22290 staticpro (&list_of_error);
22292 Qlast_arrow_position = intern ("last-arrow-position");
22293 staticpro (&Qlast_arrow_position);
22294 Qlast_arrow_string = intern ("last-arrow-string");
22295 staticpro (&Qlast_arrow_string);
22297 Qoverlay_arrow_string = intern ("overlay-arrow-string");
22298 staticpro (&Qoverlay_arrow_string);
22299 Qoverlay_arrow_bitmap = intern ("overlay-arrow-bitmap");
22300 staticpro (&Qoverlay_arrow_bitmap);
22302 echo_buffer[0] = echo_buffer[1] = Qnil;
22303 staticpro (&echo_buffer[0]);
22304 staticpro (&echo_buffer[1]);
22306 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
22307 staticpro (&echo_area_buffer[0]);
22308 staticpro (&echo_area_buffer[1]);
22310 Vmessages_buffer_name = build_string ("*Messages*");
22311 staticpro (&Vmessages_buffer_name);
22313 mode_line_proptrans_alist = Qnil;
22314 staticpro (&mode_line_proptrans_alist);
22316 mode_line_string_list = Qnil;
22317 staticpro (&mode_line_string_list);
22319 help_echo_string = Qnil;
22320 staticpro (&help_echo_string);
22321 help_echo_object = Qnil;
22322 staticpro (&help_echo_object);
22323 help_echo_window = Qnil;
22324 staticpro (&help_echo_window);
22325 previous_help_echo_string = Qnil;
22326 staticpro (&previous_help_echo_string);
22327 help_echo_pos = -1;
22329 #ifdef HAVE_WINDOW_SYSTEM
22330 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p,
22331 doc: /* *Non-nil means draw block cursor as wide as the glyph under it.
22332 For example, if a block cursor is over a tab, it will be drawn as
22333 wide as that tab on the display. */);
22334 x_stretch_cursor_p = 0;
22335 #endif
22337 DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace,
22338 doc: /* *Non-nil means highlight trailing whitespace.
22339 The face used for trailing whitespace is `trailing-whitespace'. */);
22340 Vshow_trailing_whitespace = Qnil;
22342 DEFVAR_LISP ("void-text-area-pointer", &Vvoid_text_area_pointer,
22343 doc: /* *The pointer shape to show in void text areas.
22344 Nil means to show the text pointer. Other options are `arrow', `text',
22345 `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
22346 Vvoid_text_area_pointer = Qarrow;
22348 DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay,
22349 doc: /* Non-nil means don't actually do any redisplay.
22350 This is used for internal purposes. */);
22351 Vinhibit_redisplay = Qnil;
22353 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string,
22354 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
22355 Vglobal_mode_string = Qnil;
22357 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position,
22358 doc: /* Marker for where to display an arrow on top of the buffer text.
22359 This must be the beginning of a line in order to work.
22360 See also `overlay-arrow-string'. */);
22361 Voverlay_arrow_position = Qnil;
22363 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string,
22364 doc: /* String to display as an arrow in non-window frames.
22365 See also `overlay-arrow-position'. */);
22366 Voverlay_arrow_string = Qnil;
22368 DEFVAR_LISP ("overlay-arrow-variable-list", &Voverlay_arrow_variable_list,
22369 doc: /* List of variables (symbols) which hold markers for overlay arrows.
22370 The symbols on this list are examined during redisplay to determine
22371 where to display overlay arrows. */);
22372 Voverlay_arrow_variable_list
22373 = Fcons (intern ("overlay-arrow-position"), Qnil);
22375 DEFVAR_INT ("scroll-step", &scroll_step,
22376 doc: /* *The number of lines to try scrolling a window by when point moves out.
22377 If that fails to bring point back on frame, point is centered instead.
22378 If this is zero, point is always centered after it moves off frame.
22379 If you want scrolling to always be a line at a time, you should set
22380 `scroll-conservatively' to a large value rather than set this to 1. */);
22382 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively,
22383 doc: /* *Scroll up to this many lines, to bring point back on screen.
22384 A value of zero means to scroll the text to center point vertically
22385 in the window. */);
22386 scroll_conservatively = 0;
22388 DEFVAR_INT ("scroll-margin", &scroll_margin,
22389 doc: /* *Number of lines of margin at the top and bottom of a window.
22390 Recenter the window whenever point gets within this many lines
22391 of the top or bottom of the window. */);
22392 scroll_margin = 0;
22394 DEFVAR_LISP ("display-pixels-per-inch", &Vdisplay_pixels_per_inch,
22395 doc: /* Pixels per inch on current display.
22396 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
22397 Vdisplay_pixels_per_inch = make_float (72.0);
22399 #if GLYPH_DEBUG
22400 DEFVAR_INT ("debug-end-pos", &debug_end_pos, doc: /* Don't ask. */);
22401 #endif
22403 DEFVAR_BOOL ("truncate-partial-width-windows",
22404 &truncate_partial_width_windows,
22405 doc: /* *Non-nil means truncate lines in all windows less than full frame wide. */);
22406 truncate_partial_width_windows = 1;
22408 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video,
22409 doc: /* nil means display the mode-line/header-line/menu-bar in the default face.
22410 Any other value means to use the appropriate face, `mode-line',
22411 `header-line', or `menu' respectively. */);
22412 mode_line_inverse_video = 1;
22414 DEFVAR_LISP ("line-number-display-limit", &Vline_number_display_limit,
22415 doc: /* *Maximum buffer size for which line number should be displayed.
22416 If the buffer is bigger than this, the line number does not appear
22417 in the mode line. A value of nil means no limit. */);
22418 Vline_number_display_limit = Qnil;
22420 DEFVAR_INT ("line-number-display-limit-width",
22421 &line_number_display_limit_width,
22422 doc: /* *Maximum line width (in characters) for line number display.
22423 If the average length of the lines near point is bigger than this, then the
22424 line number may be omitted from the mode line. */);
22425 line_number_display_limit_width = 200;
22427 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows,
22428 doc: /* *Non-nil means highlight region even in nonselected windows. */);
22429 highlight_nonselected_windows = 0;
22431 DEFVAR_BOOL ("multiple-frames", &multiple_frames,
22432 doc: /* Non-nil if more than one frame is visible on this display.
22433 Minibuffer-only frames don't count, but iconified frames do.
22434 This variable is not guaranteed to be accurate except while processing
22435 `frame-title-format' and `icon-title-format'. */);
22437 DEFVAR_LISP ("frame-title-format", &Vframe_title_format,
22438 doc: /* Template for displaying the title bar of visible frames.
22439 \(Assuming the window manager supports this feature.)
22440 This variable has the same structure as `mode-line-format' (which see),
22441 and is used only on frames for which no explicit name has been set
22442 \(see `modify-frame-parameters'). */);
22444 DEFVAR_LISP ("icon-title-format", &Vicon_title_format,
22445 doc: /* Template for displaying the title bar of an iconified frame.
22446 \(Assuming the window manager supports this feature.)
22447 This variable has the same structure as `mode-line-format' (which see),
22448 and is used only on frames for which no explicit name has been set
22449 \(see `modify-frame-parameters'). */);
22450 Vicon_title_format
22451 = Vframe_title_format
22452 = Fcons (intern ("multiple-frames"),
22453 Fcons (build_string ("%b"),
22454 Fcons (Fcons (empty_string,
22455 Fcons (intern ("invocation-name"),
22456 Fcons (build_string ("@"),
22457 Fcons (intern ("system-name"),
22458 Qnil)))),
22459 Qnil)));
22461 DEFVAR_LISP ("message-log-max", &Vmessage_log_max,
22462 doc: /* Maximum number of lines to keep in the message log buffer.
22463 If nil, disable message logging. If t, log messages but don't truncate
22464 the buffer when it becomes large. */);
22465 Vmessage_log_max = make_number (50);
22467 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions,
22468 doc: /* Functions called before redisplay, if window sizes have changed.
22469 The value should be a list of functions that take one argument.
22470 Just before redisplay, for each frame, if any of its windows have changed
22471 size since the last redisplay, or have been split or deleted,
22472 all the functions in the list are called, with the frame as argument. */);
22473 Vwindow_size_change_functions = Qnil;
22475 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions,
22476 doc: /* List of functions to call before redisplaying a window with scrolling.
22477 Each function is called with two arguments, the window
22478 and its new display-start position. Note that the value of `window-end'
22479 is not valid when these functions are called. */);
22480 Vwindow_scroll_functions = Qnil;
22482 DEFVAR_BOOL ("mouse-autoselect-window", &mouse_autoselect_window,
22483 doc: /* *Non-nil means autoselect window with mouse pointer. */);
22484 mouse_autoselect_window = 0;
22486 DEFVAR_BOOL ("auto-resize-tool-bars", &auto_resize_tool_bars_p,
22487 doc: /* *Non-nil means automatically resize tool-bars.
22488 This increases a tool-bar's height if not all tool-bar items are visible.
22489 It decreases a tool-bar's height when it would display blank lines
22490 otherwise. */);
22491 auto_resize_tool_bars_p = 1;
22493 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", &auto_raise_tool_bar_buttons_p,
22494 doc: /* *Non-nil means raise tool-bar buttons when the mouse moves over them. */);
22495 auto_raise_tool_bar_buttons_p = 1;
22497 DEFVAR_BOOL ("make-cursor-line-fully-visible", &make_cursor_line_fully_visible_p,
22498 doc: /* *Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
22499 make_cursor_line_fully_visible_p = 1;
22501 DEFVAR_LISP ("tool-bar-button-margin", &Vtool_bar_button_margin,
22502 doc: /* *Margin around tool-bar buttons in pixels.
22503 If an integer, use that for both horizontal and vertical margins.
22504 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
22505 HORZ specifying the horizontal margin, and VERT specifying the
22506 vertical margin. */);
22507 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
22509 DEFVAR_INT ("tool-bar-button-relief", &tool_bar_button_relief,
22510 doc: /* *Relief thickness of tool-bar buttons. */);
22511 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
22513 DEFVAR_LISP ("fontification-functions", &Vfontification_functions,
22514 doc: /* List of functions to call to fontify regions of text.
22515 Each function is called with one argument POS. Functions must
22516 fontify a region starting at POS in the current buffer, and give
22517 fontified regions the property `fontified'. */);
22518 Vfontification_functions = Qnil;
22519 Fmake_variable_buffer_local (Qfontification_functions);
22521 DEFVAR_BOOL ("unibyte-display-via-language-environment",
22522 &unibyte_display_via_language_environment,
22523 doc: /* *Non-nil means display unibyte text according to language environment.
22524 Specifically this means that unibyte non-ASCII characters
22525 are displayed by converting them to the equivalent multibyte characters
22526 according to the current language environment. As a result, they are
22527 displayed according to the current fontset. */);
22528 unibyte_display_via_language_environment = 0;
22530 DEFVAR_LISP ("max-mini-window-height", &Vmax_mini_window_height,
22531 doc: /* *Maximum height for resizing mini-windows.
22532 If a float, it specifies a fraction of the mini-window frame's height.
22533 If an integer, it specifies a number of lines. */);
22534 Vmax_mini_window_height = make_float (0.25);
22536 DEFVAR_LISP ("resize-mini-windows", &Vresize_mini_windows,
22537 doc: /* *How to resize mini-windows.
22538 A value of nil means don't automatically resize mini-windows.
22539 A value of t means resize them to fit the text displayed in them.
22540 A value of `grow-only', the default, means let mini-windows grow
22541 only, until their display becomes empty, at which point the windows
22542 go back to their normal size. */);
22543 Vresize_mini_windows = Qgrow_only;
22545 DEFVAR_LISP ("cursor-in-non-selected-windows",
22546 &Vcursor_in_non_selected_windows,
22547 doc: /* *Cursor type to display in non-selected windows.
22548 t means to use hollow box cursor. See `cursor-type' for other values. */);
22549 Vcursor_in_non_selected_windows = Qt;
22551 DEFVAR_LISP ("blink-cursor-alist", &Vblink_cursor_alist,
22552 doc: /* Alist specifying how to blink the cursor off.
22553 Each element has the form (ON-STATE . OFF-STATE). Whenever the
22554 `cursor-type' frame-parameter or variable equals ON-STATE,
22555 comparing using `equal', Emacs uses OFF-STATE to specify
22556 how to blink it off. */);
22557 Vblink_cursor_alist = Qnil;
22559 DEFVAR_BOOL ("auto-hscroll-mode", &automatic_hscrolling_p,
22560 doc: /* *Non-nil means scroll the display automatically to make point visible. */);
22561 automatic_hscrolling_p = 1;
22563 DEFVAR_INT ("hscroll-margin", &hscroll_margin,
22564 doc: /* *How many columns away from the window edge point is allowed to get
22565 before automatic hscrolling will horizontally scroll the window. */);
22566 hscroll_margin = 5;
22568 DEFVAR_LISP ("hscroll-step", &Vhscroll_step,
22569 doc: /* *How many columns to scroll the window when point gets too close to the edge.
22570 When point is less than `automatic-hscroll-margin' columns from the window
22571 edge, automatic hscrolling will scroll the window by the amount of columns
22572 determined by this variable. If its value is a positive integer, scroll that
22573 many columns. If it's a positive floating-point number, it specifies the
22574 fraction of the window's width to scroll. If it's nil or zero, point will be
22575 centered horizontally after the scroll. Any other value, including negative
22576 numbers, are treated as if the value were zero.
22578 Automatic hscrolling always moves point outside the scroll margin, so if
22579 point was more than scroll step columns inside the margin, the window will
22580 scroll more than the value given by the scroll step.
22582 Note that the lower bound for automatic hscrolling specified by `scroll-left'
22583 and `scroll-right' overrides this variable's effect. */);
22584 Vhscroll_step = make_number (0);
22586 DEFVAR_BOOL ("message-truncate-lines", &message_truncate_lines,
22587 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
22588 Bind this around calls to `message' to let it take effect. */);
22589 message_truncate_lines = 0;
22591 DEFVAR_LISP ("menu-bar-update-hook", &Vmenu_bar_update_hook,
22592 doc: /* Normal hook run for clicks on menu bar, before displaying a submenu.
22593 Can be used to update submenus whose contents should vary. */);
22594 Vmenu_bar_update_hook = Qnil;
22596 DEFVAR_BOOL ("inhibit-menubar-update", &inhibit_menubar_update,
22597 doc: /* Non-nil means don't update menu bars. Internal use only. */);
22598 inhibit_menubar_update = 0;
22600 DEFVAR_BOOL ("inhibit-eval-during-redisplay", &inhibit_eval_during_redisplay,
22601 doc: /* Non-nil means don't eval Lisp during redisplay. */);
22602 inhibit_eval_during_redisplay = 0;
22604 DEFVAR_BOOL ("inhibit-free-realized-faces", &inhibit_free_realized_faces,
22605 doc: /* Non-nil means don't free realized faces. Internal use only. */);
22606 inhibit_free_realized_faces = 0;
22608 #if GLYPH_DEBUG
22609 DEFVAR_BOOL ("inhibit-try-window-id", &inhibit_try_window_id,
22610 doc: /* Inhibit try_window_id display optimization. */);
22611 inhibit_try_window_id = 0;
22613 DEFVAR_BOOL ("inhibit-try-window-reusing", &inhibit_try_window_reusing,
22614 doc: /* Inhibit try_window_reusing display optimization. */);
22615 inhibit_try_window_reusing = 0;
22617 DEFVAR_BOOL ("inhibit-try-cursor-movement", &inhibit_try_cursor_movement,
22618 doc: /* Inhibit try_cursor_movement display optimization. */);
22619 inhibit_try_cursor_movement = 0;
22620 #endif /* GLYPH_DEBUG */
22624 /* Initialize this module when Emacs starts. */
22626 void
22627 init_xdisp ()
22629 Lisp_Object root_window;
22630 struct window *mini_w;
22632 current_header_line_height = current_mode_line_height = -1;
22634 CHARPOS (this_line_start_pos) = 0;
22636 mini_w = XWINDOW (minibuf_window);
22637 root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w)));
22639 if (!noninteractive)
22641 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (root_window)));
22642 int i;
22644 XWINDOW (root_window)->top_line = make_number (FRAME_TOP_MARGIN (f));
22645 set_window_height (root_window,
22646 FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f),
22648 mini_w->top_line = make_number (FRAME_LINES (f) - 1);
22649 set_window_height (minibuf_window, 1, 0);
22651 XWINDOW (root_window)->total_cols = make_number (FRAME_COLS (f));
22652 mini_w->total_cols = make_number (FRAME_COLS (f));
22654 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
22655 scratch_glyph_row.glyphs[TEXT_AREA + 1]
22656 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
22658 /* The default ellipsis glyphs `...'. */
22659 for (i = 0; i < 3; ++i)
22660 default_invis_vector[i] = make_number ('.');
22664 /* Allocate the buffer for frame titles.
22665 Also used for `format-mode-line'. */
22666 int size = 100;
22667 frame_title_buf = (char *) xmalloc (size);
22668 frame_title_buf_end = frame_title_buf + size;
22669 frame_title_ptr = NULL;
22672 help_echo_showing_p = 0;
22676 /* arch-tag: eacc864d-bb6a-4b74-894a-1a4399a1358b
22677 (do not change this comment) */