(gnus-summary-mode-map): Map follow-link to mouse-face.
[emacs.git] / src / xdisp.c
blobb27b5e2e744d6f0b27fc953f0aeb7ff7d7b18e4a
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, Qtotal;
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_prop_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_prop_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_prop 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;
3277 /***********************************************************************
3278 'display' property
3279 ***********************************************************************/
3281 /* Set up iterator IT from `display' property at its current position.
3282 Called from handle_stop. */
3284 static enum prop_handled
3285 handle_display_prop (it)
3286 struct it *it;
3288 Lisp_Object prop, object;
3289 struct text_pos *position;
3290 int display_replaced_p = 0;
3292 if (STRINGP (it->string))
3294 object = it->string;
3295 position = &it->current.string_pos;
3297 else
3299 object = it->w->buffer;
3300 position = &it->current.pos;
3303 /* Reset those iterator values set from display property values. */
3304 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
3305 it->space_width = Qnil;
3306 it->font_height = Qnil;
3307 it->voffset = 0;
3309 /* We don't support recursive `display' properties, i.e. string
3310 values that have a string `display' property, that have a string
3311 `display' property etc. */
3312 if (!it->string_from_display_prop_p)
3313 it->area = TEXT_AREA;
3315 prop = Fget_char_property (make_number (position->charpos),
3316 Qdisplay, object);
3317 if (NILP (prop))
3318 return HANDLED_NORMALLY;
3320 if (CONSP (prop)
3321 /* Simple properties. */
3322 && !EQ (XCAR (prop), Qimage)
3323 && !EQ (XCAR (prop), Qspace)
3324 && !EQ (XCAR (prop), Qwhen)
3325 && !EQ (XCAR (prop), Qslice)
3326 && !EQ (XCAR (prop), Qspace_width)
3327 && !EQ (XCAR (prop), Qheight)
3328 && !EQ (XCAR (prop), Qraise)
3329 /* Marginal area specifications. */
3330 && !(CONSP (XCAR (prop)) && EQ (XCAR (XCAR (prop)), Qmargin))
3331 && !EQ (XCAR (prop), Qleft_fringe)
3332 && !EQ (XCAR (prop), Qright_fringe)
3333 && !NILP (XCAR (prop)))
3335 for (; CONSP (prop); prop = XCDR (prop))
3337 if (handle_single_display_prop (it, XCAR (prop), object,
3338 position, display_replaced_p))
3339 display_replaced_p = 1;
3342 else if (VECTORP (prop))
3344 int i;
3345 for (i = 0; i < ASIZE (prop); ++i)
3346 if (handle_single_display_prop (it, AREF (prop, i), object,
3347 position, display_replaced_p))
3348 display_replaced_p = 1;
3350 else
3352 if (handle_single_display_prop (it, prop, object, position, 0))
3353 display_replaced_p = 1;
3356 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
3360 /* Value is the position of the end of the `display' property starting
3361 at START_POS in OBJECT. */
3363 static struct text_pos
3364 display_prop_end (it, object, start_pos)
3365 struct it *it;
3366 Lisp_Object object;
3367 struct text_pos start_pos;
3369 Lisp_Object end;
3370 struct text_pos end_pos;
3372 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
3373 Qdisplay, object, Qnil);
3374 CHARPOS (end_pos) = XFASTINT (end);
3375 if (STRINGP (object))
3376 compute_string_pos (&end_pos, start_pos, it->string);
3377 else
3378 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
3380 return end_pos;
3384 /* Set up IT from a single `display' sub-property value PROP. OBJECT
3385 is the object in which the `display' property was found. *POSITION
3386 is the position at which it was found. DISPLAY_REPLACED_P non-zero
3387 means that we previously saw a display sub-property which already
3388 replaced text display with something else, for example an image;
3389 ignore such properties after the first one has been processed.
3391 If PROP is a `space' or `image' sub-property, set *POSITION to the
3392 end position of the `display' property.
3394 Value is non-zero if something was found which replaces the display
3395 of buffer or string text. */
3397 static int
3398 handle_single_display_prop (it, prop, object, position,
3399 display_replaced_before_p)
3400 struct it *it;
3401 Lisp_Object prop;
3402 Lisp_Object object;
3403 struct text_pos *position;
3404 int display_replaced_before_p;
3406 Lisp_Object value;
3407 int replaces_text_display_p = 0;
3408 Lisp_Object form;
3410 /* If PROP is a list of the form `(when FORM . VALUE)', FORM is
3411 evaluated. If the result is nil, VALUE is ignored. */
3412 form = Qt;
3413 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3415 prop = XCDR (prop);
3416 if (!CONSP (prop))
3417 return 0;
3418 form = XCAR (prop);
3419 prop = XCDR (prop);
3422 if (!NILP (form) && !EQ (form, Qt))
3424 int count = SPECPDL_INDEX ();
3425 struct gcpro gcpro1;
3427 /* Bind `object' to the object having the `display' property, a
3428 buffer or string. Bind `position' to the position in the
3429 object where the property was found, and `buffer-position'
3430 to the current position in the buffer. */
3431 specbind (Qobject, object);
3432 specbind (Qposition, make_number (CHARPOS (*position)));
3433 specbind (Qbuffer_position,
3434 make_number (STRINGP (object)
3435 ? IT_CHARPOS (*it) : CHARPOS (*position)));
3436 GCPRO1 (form);
3437 form = safe_eval (form);
3438 UNGCPRO;
3439 unbind_to (count, Qnil);
3442 if (NILP (form))
3443 return 0;
3445 if (CONSP (prop)
3446 && EQ (XCAR (prop), Qheight)
3447 && CONSP (XCDR (prop)))
3449 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3450 return 0;
3452 /* `(height HEIGHT)'. */
3453 it->font_height = XCAR (XCDR (prop));
3454 if (!NILP (it->font_height))
3456 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3457 int new_height = -1;
3459 if (CONSP (it->font_height)
3460 && (EQ (XCAR (it->font_height), Qplus)
3461 || EQ (XCAR (it->font_height), Qminus))
3462 && CONSP (XCDR (it->font_height))
3463 && INTEGERP (XCAR (XCDR (it->font_height))))
3465 /* `(+ N)' or `(- N)' where N is an integer. */
3466 int steps = XINT (XCAR (XCDR (it->font_height)));
3467 if (EQ (XCAR (it->font_height), Qplus))
3468 steps = - steps;
3469 it->face_id = smaller_face (it->f, it->face_id, steps);
3471 else if (FUNCTIONP (it->font_height))
3473 /* Call function with current height as argument.
3474 Value is the new height. */
3475 Lisp_Object height;
3476 height = safe_call1 (it->font_height,
3477 face->lface[LFACE_HEIGHT_INDEX]);
3478 if (NUMBERP (height))
3479 new_height = XFLOATINT (height);
3481 else if (NUMBERP (it->font_height))
3483 /* Value is a multiple of the canonical char height. */
3484 struct face *face;
3486 face = FACE_FROM_ID (it->f, DEFAULT_FACE_ID);
3487 new_height = (XFLOATINT (it->font_height)
3488 * XINT (face->lface[LFACE_HEIGHT_INDEX]));
3490 else
3492 /* Evaluate IT->font_height with `height' bound to the
3493 current specified height to get the new height. */
3494 Lisp_Object value;
3495 int count = SPECPDL_INDEX ();
3497 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
3498 value = safe_eval (it->font_height);
3499 unbind_to (count, Qnil);
3501 if (NUMBERP (value))
3502 new_height = XFLOATINT (value);
3505 if (new_height > 0)
3506 it->face_id = face_with_height (it->f, it->face_id, new_height);
3509 else if (CONSP (prop)
3510 && EQ (XCAR (prop), Qspace_width)
3511 && CONSP (XCDR (prop)))
3513 /* `(space_width WIDTH)'. */
3514 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3515 return 0;
3517 value = XCAR (XCDR (prop));
3518 if (NUMBERP (value) && XFLOATINT (value) > 0)
3519 it->space_width = value;
3521 else if (CONSP (prop)
3522 && EQ (XCAR (prop), Qslice))
3524 /* `(slice X Y WIDTH HEIGHT)'. */
3525 Lisp_Object tem;
3527 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3528 return 0;
3530 if (tem = XCDR (prop), CONSP (tem))
3532 it->slice.x = XCAR (tem);
3533 if (tem = XCDR (tem), CONSP (tem))
3535 it->slice.y = XCAR (tem);
3536 if (tem = XCDR (tem), CONSP (tem))
3538 it->slice.width = XCAR (tem);
3539 if (tem = XCDR (tem), CONSP (tem))
3540 it->slice.height = XCAR (tem);
3545 else if (CONSP (prop)
3546 && EQ (XCAR (prop), Qraise)
3547 && CONSP (XCDR (prop)))
3549 /* `(raise FACTOR)'. */
3550 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3551 return 0;
3553 #ifdef HAVE_WINDOW_SYSTEM
3554 value = XCAR (XCDR (prop));
3555 if (NUMBERP (value))
3557 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3558 it->voffset = - (XFLOATINT (value)
3559 * (FONT_HEIGHT (face->font)));
3561 #endif /* HAVE_WINDOW_SYSTEM */
3563 else if (!it->string_from_display_prop_p)
3565 /* `((margin left-margin) VALUE)' or `((margin right-margin)
3566 VALUE) or `((margin nil) VALUE)' or VALUE. */
3567 Lisp_Object location, value;
3568 struct text_pos start_pos;
3569 int valid_p;
3571 /* Characters having this form of property are not displayed, so
3572 we have to find the end of the property. */
3573 start_pos = *position;
3574 *position = display_prop_end (it, object, start_pos);
3575 value = Qnil;
3577 /* Let's stop at the new position and assume that all
3578 text properties change there. */
3579 it->stop_charpos = position->charpos;
3581 if (CONSP (prop)
3582 && (EQ (XCAR (prop), Qleft_fringe)
3583 || EQ (XCAR (prop), Qright_fringe))
3584 && CONSP (XCDR (prop)))
3586 int face_id = DEFAULT_FACE_ID;
3587 int fringe_bitmap;
3589 /* Save current settings of IT so that we can restore them
3590 when we are finished with the glyph property value. */
3592 /* `(left-fringe BITMAP FACE)'. */
3593 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3594 return 0;
3596 #ifdef HAVE_WINDOW_SYSTEM
3597 value = XCAR (XCDR (prop));
3598 if (!SYMBOLP (value)
3599 || !(fringe_bitmap = lookup_fringe_bitmap (value)))
3600 return 0;
3602 if (CONSP (XCDR (XCDR (prop))))
3604 Lisp_Object face_name = XCAR (XCDR (XCDR (prop)));
3605 int face_id2 = lookup_named_face (it->f, face_name, 'A', 0);
3606 if (face_id2 >= 0)
3607 face_id = face_id2;
3610 push_it (it);
3612 it->area = TEXT_AREA;
3613 it->what = IT_IMAGE;
3614 it->image_id = -1; /* no image */
3615 it->position = start_pos;
3616 it->object = NILP (object) ? it->w->buffer : object;
3617 it->method = next_element_from_image;
3618 it->face_id = face_id;
3620 /* Say that we haven't consumed the characters with
3621 `display' property yet. The call to pop_it in
3622 set_iterator_to_next will clean this up. */
3623 *position = start_pos;
3625 if (EQ (XCAR (prop), Qleft_fringe))
3627 it->left_user_fringe_bitmap = fringe_bitmap;
3628 it->left_user_fringe_face_id = face_id;
3630 else
3632 it->right_user_fringe_bitmap = fringe_bitmap;
3633 it->right_user_fringe_face_id = face_id;
3635 #endif /* HAVE_WINDOW_SYSTEM */
3636 return 1;
3639 location = Qunbound;
3640 if (CONSP (prop) && CONSP (XCAR (prop)))
3642 Lisp_Object tem;
3644 value = XCDR (prop);
3645 if (CONSP (value))
3646 value = XCAR (value);
3648 tem = XCAR (prop);
3649 if (EQ (XCAR (tem), Qmargin)
3650 && (tem = XCDR (tem),
3651 tem = CONSP (tem) ? XCAR (tem) : Qnil,
3652 (NILP (tem)
3653 || EQ (tem, Qleft_margin)
3654 || EQ (tem, Qright_margin))))
3655 location = tem;
3658 if (EQ (location, Qunbound))
3660 location = Qnil;
3661 value = prop;
3664 valid_p = (STRINGP (value)
3665 #ifdef HAVE_WINDOW_SYSTEM
3666 || (!FRAME_TERMCAP_P (it->f) && valid_image_p (value))
3667 #endif /* not HAVE_WINDOW_SYSTEM */
3668 || (CONSP (value) && EQ (XCAR (value), Qspace)));
3670 if ((EQ (location, Qleft_margin)
3671 || EQ (location, Qright_margin)
3672 || NILP (location))
3673 && valid_p
3674 && !display_replaced_before_p)
3676 replaces_text_display_p = 1;
3678 /* Save current settings of IT so that we can restore them
3679 when we are finished with the glyph property value. */
3680 push_it (it);
3682 if (NILP (location))
3683 it->area = TEXT_AREA;
3684 else if (EQ (location, Qleft_margin))
3685 it->area = LEFT_MARGIN_AREA;
3686 else
3687 it->area = RIGHT_MARGIN_AREA;
3689 if (STRINGP (value))
3691 it->string = value;
3692 it->multibyte_p = STRING_MULTIBYTE (it->string);
3693 it->current.overlay_string_index = -1;
3694 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
3695 it->end_charpos = it->string_nchars = SCHARS (it->string);
3696 it->method = next_element_from_string;
3697 it->stop_charpos = 0;
3698 it->string_from_display_prop_p = 1;
3699 /* Say that we haven't consumed the characters with
3700 `display' property yet. The call to pop_it in
3701 set_iterator_to_next will clean this up. */
3702 *position = start_pos;
3704 else if (CONSP (value) && EQ (XCAR (value), Qspace))
3706 it->method = next_element_from_stretch;
3707 it->object = value;
3708 it->current.pos = it->position = start_pos;
3710 #ifdef HAVE_WINDOW_SYSTEM
3711 else
3713 it->what = IT_IMAGE;
3714 it->image_id = lookup_image (it->f, value);
3715 it->position = start_pos;
3716 it->object = NILP (object) ? it->w->buffer : object;
3717 it->method = next_element_from_image;
3719 /* Say that we haven't consumed the characters with
3720 `display' property yet. The call to pop_it in
3721 set_iterator_to_next will clean this up. */
3722 *position = start_pos;
3724 #endif /* HAVE_WINDOW_SYSTEM */
3726 else
3727 /* Invalid property or property not supported. Restore
3728 the position to what it was before. */
3729 *position = start_pos;
3732 return replaces_text_display_p;
3736 /* Check if PROP is a display sub-property value whose text should be
3737 treated as intangible. */
3739 static int
3740 single_display_prop_intangible_p (prop)
3741 Lisp_Object prop;
3743 /* Skip over `when FORM'. */
3744 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3746 prop = XCDR (prop);
3747 if (!CONSP (prop))
3748 return 0;
3749 prop = XCDR (prop);
3752 if (STRINGP (prop))
3753 return 1;
3755 if (!CONSP (prop))
3756 return 0;
3758 /* Skip over `margin LOCATION'. If LOCATION is in the margins,
3759 we don't need to treat text as intangible. */
3760 if (EQ (XCAR (prop), Qmargin))
3762 prop = XCDR (prop);
3763 if (!CONSP (prop))
3764 return 0;
3766 prop = XCDR (prop);
3767 if (!CONSP (prop)
3768 || EQ (XCAR (prop), Qleft_margin)
3769 || EQ (XCAR (prop), Qright_margin))
3770 return 0;
3773 return (CONSP (prop)
3774 && (EQ (XCAR (prop), Qimage)
3775 || EQ (XCAR (prop), Qspace)));
3779 /* Check if PROP is a display property value whose text should be
3780 treated as intangible. */
3783 display_prop_intangible_p (prop)
3784 Lisp_Object prop;
3786 if (CONSP (prop)
3787 && CONSP (XCAR (prop))
3788 && !EQ (Qmargin, XCAR (XCAR (prop))))
3790 /* A list of sub-properties. */
3791 while (CONSP (prop))
3793 if (single_display_prop_intangible_p (XCAR (prop)))
3794 return 1;
3795 prop = XCDR (prop);
3798 else if (VECTORP (prop))
3800 /* A vector of sub-properties. */
3801 int i;
3802 for (i = 0; i < ASIZE (prop); ++i)
3803 if (single_display_prop_intangible_p (AREF (prop, i)))
3804 return 1;
3806 else
3807 return single_display_prop_intangible_p (prop);
3809 return 0;
3813 /* Return 1 if PROP is a display sub-property value containing STRING. */
3815 static int
3816 single_display_prop_string_p (prop, string)
3817 Lisp_Object prop, string;
3819 if (EQ (string, prop))
3820 return 1;
3822 /* Skip over `when FORM'. */
3823 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3825 prop = XCDR (prop);
3826 if (!CONSP (prop))
3827 return 0;
3828 prop = XCDR (prop);
3831 if (CONSP (prop))
3832 /* Skip over `margin LOCATION'. */
3833 if (EQ (XCAR (prop), Qmargin))
3835 prop = XCDR (prop);
3836 if (!CONSP (prop))
3837 return 0;
3839 prop = XCDR (prop);
3840 if (!CONSP (prop))
3841 return 0;
3844 return CONSP (prop) && EQ (XCAR (prop), string);
3848 /* Return 1 if STRING appears in the `display' property PROP. */
3850 static int
3851 display_prop_string_p (prop, string)
3852 Lisp_Object prop, string;
3854 if (CONSP (prop)
3855 && CONSP (XCAR (prop))
3856 && !EQ (Qmargin, XCAR (XCAR (prop))))
3858 /* A list of sub-properties. */
3859 while (CONSP (prop))
3861 if (single_display_prop_string_p (XCAR (prop), string))
3862 return 1;
3863 prop = XCDR (prop);
3866 else if (VECTORP (prop))
3868 /* A vector of sub-properties. */
3869 int i;
3870 for (i = 0; i < ASIZE (prop); ++i)
3871 if (single_display_prop_string_p (AREF (prop, i), string))
3872 return 1;
3874 else
3875 return single_display_prop_string_p (prop, string);
3877 return 0;
3881 /* Determine from which buffer position in W's buffer STRING comes
3882 from. AROUND_CHARPOS is an approximate position where it could
3883 be from. Value is the buffer position or 0 if it couldn't be
3884 determined.
3886 W's buffer must be current.
3888 This function is necessary because we don't record buffer positions
3889 in glyphs generated from strings (to keep struct glyph small).
3890 This function may only use code that doesn't eval because it is
3891 called asynchronously from note_mouse_highlight. */
3894 string_buffer_position (w, string, around_charpos)
3895 struct window *w;
3896 Lisp_Object string;
3897 int around_charpos;
3899 Lisp_Object limit, prop, pos;
3900 const int MAX_DISTANCE = 1000;
3901 int found = 0;
3903 pos = make_number (around_charpos);
3904 limit = make_number (min (XINT (pos) + MAX_DISTANCE, ZV));
3905 while (!found && !EQ (pos, limit))
3907 prop = Fget_char_property (pos, Qdisplay, Qnil);
3908 if (!NILP (prop) && display_prop_string_p (prop, string))
3909 found = 1;
3910 else
3911 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil, limit);
3914 if (!found)
3916 pos = make_number (around_charpos);
3917 limit = make_number (max (XINT (pos) - MAX_DISTANCE, BEGV));
3918 while (!found && !EQ (pos, limit))
3920 prop = Fget_char_property (pos, Qdisplay, Qnil);
3921 if (!NILP (prop) && display_prop_string_p (prop, string))
3922 found = 1;
3923 else
3924 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
3925 limit);
3929 return found ? XINT (pos) : 0;
3934 /***********************************************************************
3935 `composition' property
3936 ***********************************************************************/
3938 /* Set up iterator IT from `composition' property at its current
3939 position. Called from handle_stop. */
3941 static enum prop_handled
3942 handle_composition_prop (it)
3943 struct it *it;
3945 Lisp_Object prop, string;
3946 int pos, pos_byte, end;
3947 enum prop_handled handled = HANDLED_NORMALLY;
3949 if (STRINGP (it->string))
3951 pos = IT_STRING_CHARPOS (*it);
3952 pos_byte = IT_STRING_BYTEPOS (*it);
3953 string = it->string;
3955 else
3957 pos = IT_CHARPOS (*it);
3958 pos_byte = IT_BYTEPOS (*it);
3959 string = Qnil;
3962 /* If there's a valid composition and point is not inside of the
3963 composition (in the case that the composition is from the current
3964 buffer), draw a glyph composed from the composition components. */
3965 if (find_composition (pos, -1, &pos, &end, &prop, string)
3966 && COMPOSITION_VALID_P (pos, end, prop)
3967 && (STRINGP (it->string) || (PT <= pos || PT >= end)))
3969 int id = get_composition_id (pos, pos_byte, end - pos, prop, string);
3971 if (id >= 0)
3973 it->method = next_element_from_composition;
3974 it->cmp_id = id;
3975 it->cmp_len = COMPOSITION_LENGTH (prop);
3976 /* For a terminal, draw only the first character of the
3977 components. */
3978 it->c = COMPOSITION_GLYPH (composition_table[id], 0);
3979 it->len = (STRINGP (it->string)
3980 ? string_char_to_byte (it->string, end)
3981 : CHAR_TO_BYTE (end)) - pos_byte;
3982 it->stop_charpos = end;
3983 handled = HANDLED_RETURN;
3987 return handled;
3992 /***********************************************************************
3993 Overlay strings
3994 ***********************************************************************/
3996 /* The following structure is used to record overlay strings for
3997 later sorting in load_overlay_strings. */
3999 struct overlay_entry
4001 Lisp_Object overlay;
4002 Lisp_Object string;
4003 int priority;
4004 int after_string_p;
4008 /* Set up iterator IT from overlay strings at its current position.
4009 Called from handle_stop. */
4011 static enum prop_handled
4012 handle_overlay_change (it)
4013 struct it *it;
4015 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
4016 return HANDLED_RECOMPUTE_PROPS;
4017 else
4018 return HANDLED_NORMALLY;
4022 /* Set up the next overlay string for delivery by IT, if there is an
4023 overlay string to deliver. Called by set_iterator_to_next when the
4024 end of the current overlay string is reached. If there are more
4025 overlay strings to display, IT->string and
4026 IT->current.overlay_string_index are set appropriately here.
4027 Otherwise IT->string is set to nil. */
4029 static void
4030 next_overlay_string (it)
4031 struct it *it;
4033 ++it->current.overlay_string_index;
4034 if (it->current.overlay_string_index == it->n_overlay_strings)
4036 /* No more overlay strings. Restore IT's settings to what
4037 they were before overlay strings were processed, and
4038 continue to deliver from current_buffer. */
4039 int display_ellipsis_p = it->stack[it->sp - 1].display_ellipsis_p;
4041 pop_it (it);
4042 xassert (it->stop_charpos >= BEGV
4043 && it->stop_charpos <= it->end_charpos);
4044 it->string = Qnil;
4045 it->current.overlay_string_index = -1;
4046 SET_TEXT_POS (it->current.string_pos, -1, -1);
4047 it->n_overlay_strings = 0;
4048 it->method = next_element_from_buffer;
4050 /* If we're at the end of the buffer, record that we have
4051 processed the overlay strings there already, so that
4052 next_element_from_buffer doesn't try it again. */
4053 if (IT_CHARPOS (*it) >= it->end_charpos)
4054 it->overlay_strings_at_end_processed_p = 1;
4056 /* If we have to display `...' for invisible text, set
4057 the iterator up for that. */
4058 if (display_ellipsis_p)
4059 setup_for_ellipsis (it, 0);
4061 else
4063 /* There are more overlay strings to process. If
4064 IT->current.overlay_string_index has advanced to a position
4065 where we must load IT->overlay_strings with more strings, do
4066 it. */
4067 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
4069 if (it->current.overlay_string_index && i == 0)
4070 load_overlay_strings (it, 0);
4072 /* Initialize IT to deliver display elements from the overlay
4073 string. */
4074 it->string = it->overlay_strings[i];
4075 it->multibyte_p = STRING_MULTIBYTE (it->string);
4076 SET_TEXT_POS (it->current.string_pos, 0, 0);
4077 it->method = next_element_from_string;
4078 it->stop_charpos = 0;
4081 CHECK_IT (it);
4085 /* Compare two overlay_entry structures E1 and E2. Used as a
4086 comparison function for qsort in load_overlay_strings. Overlay
4087 strings for the same position are sorted so that
4089 1. All after-strings come in front of before-strings, except
4090 when they come from the same overlay.
4092 2. Within after-strings, strings are sorted so that overlay strings
4093 from overlays with higher priorities come first.
4095 2. Within before-strings, strings are sorted so that overlay
4096 strings from overlays with higher priorities come last.
4098 Value is analogous to strcmp. */
4101 static int
4102 compare_overlay_entries (e1, e2)
4103 void *e1, *e2;
4105 struct overlay_entry *entry1 = (struct overlay_entry *) e1;
4106 struct overlay_entry *entry2 = (struct overlay_entry *) e2;
4107 int result;
4109 if (entry1->after_string_p != entry2->after_string_p)
4111 /* Let after-strings appear in front of before-strings if
4112 they come from different overlays. */
4113 if (EQ (entry1->overlay, entry2->overlay))
4114 result = entry1->after_string_p ? 1 : -1;
4115 else
4116 result = entry1->after_string_p ? -1 : 1;
4118 else if (entry1->after_string_p)
4119 /* After-strings sorted in order of decreasing priority. */
4120 result = entry2->priority - entry1->priority;
4121 else
4122 /* Before-strings sorted in order of increasing priority. */
4123 result = entry1->priority - entry2->priority;
4125 return result;
4129 /* Load the vector IT->overlay_strings with overlay strings from IT's
4130 current buffer position, or from CHARPOS if that is > 0. Set
4131 IT->n_overlays to the total number of overlay strings found.
4133 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
4134 a time. On entry into load_overlay_strings,
4135 IT->current.overlay_string_index gives the number of overlay
4136 strings that have already been loaded by previous calls to this
4137 function.
4139 IT->add_overlay_start contains an additional overlay start
4140 position to consider for taking overlay strings from, if non-zero.
4141 This position comes into play when the overlay has an `invisible'
4142 property, and both before and after-strings. When we've skipped to
4143 the end of the overlay, because of its `invisible' property, we
4144 nevertheless want its before-string to appear.
4145 IT->add_overlay_start will contain the overlay start position
4146 in this case.
4148 Overlay strings are sorted so that after-string strings come in
4149 front of before-string strings. Within before and after-strings,
4150 strings are sorted by overlay priority. See also function
4151 compare_overlay_entries. */
4153 static void
4154 load_overlay_strings (it, charpos)
4155 struct it *it;
4156 int charpos;
4158 extern Lisp_Object Qafter_string, Qbefore_string, Qwindow, Qpriority;
4159 Lisp_Object overlay, window, str, invisible;
4160 struct Lisp_Overlay *ov;
4161 int start, end;
4162 int size = 20;
4163 int n = 0, i, j, invis_p;
4164 struct overlay_entry *entries
4165 = (struct overlay_entry *) alloca (size * sizeof *entries);
4167 if (charpos <= 0)
4168 charpos = IT_CHARPOS (*it);
4170 /* Append the overlay string STRING of overlay OVERLAY to vector
4171 `entries' which has size `size' and currently contains `n'
4172 elements. AFTER_P non-zero means STRING is an after-string of
4173 OVERLAY. */
4174 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
4175 do \
4177 Lisp_Object priority; \
4179 if (n == size) \
4181 int new_size = 2 * size; \
4182 struct overlay_entry *old = entries; \
4183 entries = \
4184 (struct overlay_entry *) alloca (new_size \
4185 * sizeof *entries); \
4186 bcopy (old, entries, size * sizeof *entries); \
4187 size = new_size; \
4190 entries[n].string = (STRING); \
4191 entries[n].overlay = (OVERLAY); \
4192 priority = Foverlay_get ((OVERLAY), Qpriority); \
4193 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
4194 entries[n].after_string_p = (AFTER_P); \
4195 ++n; \
4197 while (0)
4199 /* Process overlay before the overlay center. */
4200 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
4202 XSETMISC (overlay, ov);
4203 xassert (OVERLAYP (overlay));
4204 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4205 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4207 if (end < charpos)
4208 break;
4210 /* Skip this overlay if it doesn't start or end at IT's current
4211 position. */
4212 if (end != charpos && start != charpos)
4213 continue;
4215 /* Skip this overlay if it doesn't apply to IT->w. */
4216 window = Foverlay_get (overlay, Qwindow);
4217 if (WINDOWP (window) && XWINDOW (window) != it->w)
4218 continue;
4220 /* If the text ``under'' the overlay is invisible, both before-
4221 and after-strings from this overlay are visible; start and
4222 end position are indistinguishable. */
4223 invisible = Foverlay_get (overlay, Qinvisible);
4224 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4226 /* If overlay has a non-empty before-string, record it. */
4227 if ((start == charpos || (end == charpos && invis_p))
4228 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4229 && SCHARS (str))
4230 RECORD_OVERLAY_STRING (overlay, str, 0);
4232 /* If overlay has a non-empty after-string, record it. */
4233 if ((end == charpos || (start == charpos && invis_p))
4234 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4235 && SCHARS (str))
4236 RECORD_OVERLAY_STRING (overlay, str, 1);
4239 /* Process overlays after the overlay center. */
4240 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
4242 XSETMISC (overlay, ov);
4243 xassert (OVERLAYP (overlay));
4244 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4245 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4247 if (start > charpos)
4248 break;
4250 /* Skip this overlay if it doesn't start or end at IT's current
4251 position. */
4252 if (end != charpos && start != charpos)
4253 continue;
4255 /* Skip this overlay if it doesn't apply to IT->w. */
4256 window = Foverlay_get (overlay, Qwindow);
4257 if (WINDOWP (window) && XWINDOW (window) != it->w)
4258 continue;
4260 /* If the text ``under'' the overlay is invisible, it has a zero
4261 dimension, and both before- and after-strings apply. */
4262 invisible = Foverlay_get (overlay, Qinvisible);
4263 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4265 /* If overlay has a non-empty before-string, record it. */
4266 if ((start == charpos || (end == charpos && invis_p))
4267 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4268 && SCHARS (str))
4269 RECORD_OVERLAY_STRING (overlay, str, 0);
4271 /* If overlay has a non-empty after-string, record it. */
4272 if ((end == charpos || (start == charpos && invis_p))
4273 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4274 && SCHARS (str))
4275 RECORD_OVERLAY_STRING (overlay, str, 1);
4278 #undef RECORD_OVERLAY_STRING
4280 /* Sort entries. */
4281 if (n > 1)
4282 qsort (entries, n, sizeof *entries, compare_overlay_entries);
4284 /* Record the total number of strings to process. */
4285 it->n_overlay_strings = n;
4287 /* IT->current.overlay_string_index is the number of overlay strings
4288 that have already been consumed by IT. Copy some of the
4289 remaining overlay strings to IT->overlay_strings. */
4290 i = 0;
4291 j = it->current.overlay_string_index;
4292 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
4293 it->overlay_strings[i++] = entries[j++].string;
4295 CHECK_IT (it);
4299 /* Get the first chunk of overlay strings at IT's current buffer
4300 position, or at CHARPOS if that is > 0. Value is non-zero if at
4301 least one overlay string was found. */
4303 static int
4304 get_overlay_strings (it, charpos)
4305 struct it *it;
4306 int charpos;
4308 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
4309 process. This fills IT->overlay_strings with strings, and sets
4310 IT->n_overlay_strings to the total number of strings to process.
4311 IT->pos.overlay_string_index has to be set temporarily to zero
4312 because load_overlay_strings needs this; it must be set to -1
4313 when no overlay strings are found because a zero value would
4314 indicate a position in the first overlay string. */
4315 it->current.overlay_string_index = 0;
4316 load_overlay_strings (it, charpos);
4318 /* If we found overlay strings, set up IT to deliver display
4319 elements from the first one. Otherwise set up IT to deliver
4320 from current_buffer. */
4321 if (it->n_overlay_strings)
4323 /* Make sure we know settings in current_buffer, so that we can
4324 restore meaningful values when we're done with the overlay
4325 strings. */
4326 compute_stop_pos (it);
4327 xassert (it->face_id >= 0);
4329 /* Save IT's settings. They are restored after all overlay
4330 strings have been processed. */
4331 xassert (it->sp == 0);
4332 push_it (it);
4334 /* Set up IT to deliver display elements from the first overlay
4335 string. */
4336 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
4337 it->string = it->overlay_strings[0];
4338 it->stop_charpos = 0;
4339 xassert (STRINGP (it->string));
4340 it->end_charpos = SCHARS (it->string);
4341 it->multibyte_p = STRING_MULTIBYTE (it->string);
4342 it->method = next_element_from_string;
4344 else
4346 it->string = Qnil;
4347 it->current.overlay_string_index = -1;
4348 it->method = next_element_from_buffer;
4351 CHECK_IT (it);
4353 /* Value is non-zero if we found at least one overlay string. */
4354 return STRINGP (it->string);
4359 /***********************************************************************
4360 Saving and restoring state
4361 ***********************************************************************/
4363 /* Save current settings of IT on IT->stack. Called, for example,
4364 before setting up IT for an overlay string, to be able to restore
4365 IT's settings to what they were after the overlay string has been
4366 processed. */
4368 static void
4369 push_it (it)
4370 struct it *it;
4372 struct iterator_stack_entry *p;
4374 xassert (it->sp < 2);
4375 p = it->stack + it->sp;
4377 p->stop_charpos = it->stop_charpos;
4378 xassert (it->face_id >= 0);
4379 p->face_id = it->face_id;
4380 p->string = it->string;
4381 p->pos = it->current;
4382 p->end_charpos = it->end_charpos;
4383 p->string_nchars = it->string_nchars;
4384 p->area = it->area;
4385 p->multibyte_p = it->multibyte_p;
4386 p->slice = it->slice;
4387 p->space_width = it->space_width;
4388 p->font_height = it->font_height;
4389 p->voffset = it->voffset;
4390 p->string_from_display_prop_p = it->string_from_display_prop_p;
4391 p->display_ellipsis_p = 0;
4392 ++it->sp;
4396 /* Restore IT's settings from IT->stack. Called, for example, when no
4397 more overlay strings must be processed, and we return to delivering
4398 display elements from a buffer, or when the end of a string from a
4399 `display' property is reached and we return to delivering display
4400 elements from an overlay string, or from a buffer. */
4402 static void
4403 pop_it (it)
4404 struct it *it;
4406 struct iterator_stack_entry *p;
4408 xassert (it->sp > 0);
4409 --it->sp;
4410 p = it->stack + it->sp;
4411 it->stop_charpos = p->stop_charpos;
4412 it->face_id = p->face_id;
4413 it->string = p->string;
4414 it->current = p->pos;
4415 it->end_charpos = p->end_charpos;
4416 it->string_nchars = p->string_nchars;
4417 it->area = p->area;
4418 it->multibyte_p = p->multibyte_p;
4419 it->slice = p->slice;
4420 it->space_width = p->space_width;
4421 it->font_height = p->font_height;
4422 it->voffset = p->voffset;
4423 it->string_from_display_prop_p = p->string_from_display_prop_p;
4428 /***********************************************************************
4429 Moving over lines
4430 ***********************************************************************/
4432 /* Set IT's current position to the previous line start. */
4434 static void
4435 back_to_previous_line_start (it)
4436 struct it *it;
4438 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
4439 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
4443 /* Move IT to the next line start.
4445 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
4446 we skipped over part of the text (as opposed to moving the iterator
4447 continuously over the text). Otherwise, don't change the value
4448 of *SKIPPED_P.
4450 Newlines may come from buffer text, overlay strings, or strings
4451 displayed via the `display' property. That's the reason we can't
4452 simply use find_next_newline_no_quit.
4454 Note that this function may not skip over invisible text that is so
4455 because of text properties and immediately follows a newline. If
4456 it would, function reseat_at_next_visible_line_start, when called
4457 from set_iterator_to_next, would effectively make invisible
4458 characters following a newline part of the wrong glyph row, which
4459 leads to wrong cursor motion. */
4461 static int
4462 forward_to_next_line_start (it, skipped_p)
4463 struct it *it;
4464 int *skipped_p;
4466 int old_selective, newline_found_p, n;
4467 const int MAX_NEWLINE_DISTANCE = 500;
4469 /* If already on a newline, just consume it to avoid unintended
4470 skipping over invisible text below. */
4471 if (it->what == IT_CHARACTER
4472 && it->c == '\n'
4473 && CHARPOS (it->position) == IT_CHARPOS (*it))
4475 set_iterator_to_next (it, 0);
4476 it->c = 0;
4477 return 1;
4480 /* Don't handle selective display in the following. It's (a)
4481 unnecessary because it's done by the caller, and (b) leads to an
4482 infinite recursion because next_element_from_ellipsis indirectly
4483 calls this function. */
4484 old_selective = it->selective;
4485 it->selective = 0;
4487 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
4488 from buffer text. */
4489 for (n = newline_found_p = 0;
4490 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
4491 n += STRINGP (it->string) ? 0 : 1)
4493 if (!get_next_display_element (it))
4494 return 0;
4495 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
4496 set_iterator_to_next (it, 0);
4499 /* If we didn't find a newline near enough, see if we can use a
4500 short-cut. */
4501 if (!newline_found_p)
4503 int start = IT_CHARPOS (*it);
4504 int limit = find_next_newline_no_quit (start, 1);
4505 Lisp_Object pos;
4507 xassert (!STRINGP (it->string));
4509 /* If there isn't any `display' property in sight, and no
4510 overlays, we can just use the position of the newline in
4511 buffer text. */
4512 if (it->stop_charpos >= limit
4513 || ((pos = Fnext_single_property_change (make_number (start),
4514 Qdisplay,
4515 Qnil, make_number (limit)),
4516 NILP (pos))
4517 && next_overlay_change (start) == ZV))
4519 IT_CHARPOS (*it) = limit;
4520 IT_BYTEPOS (*it) = CHAR_TO_BYTE (limit);
4521 *skipped_p = newline_found_p = 1;
4523 else
4525 while (get_next_display_element (it)
4526 && !newline_found_p)
4528 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
4529 set_iterator_to_next (it, 0);
4534 it->selective = old_selective;
4535 return newline_found_p;
4539 /* Set IT's current position to the previous visible line start. Skip
4540 invisible text that is so either due to text properties or due to
4541 selective display. Caution: this does not change IT->current_x and
4542 IT->hpos. */
4544 static void
4545 back_to_previous_visible_line_start (it)
4546 struct it *it;
4548 int visible_p = 0;
4550 /* Go back one newline if not on BEGV already. */
4551 if (IT_CHARPOS (*it) > BEGV)
4552 back_to_previous_line_start (it);
4554 /* Move over lines that are invisible because of selective display
4555 or text properties. */
4556 while (IT_CHARPOS (*it) > BEGV
4557 && !visible_p)
4559 visible_p = 1;
4561 /* If selective > 0, then lines indented more than that values
4562 are invisible. */
4563 if (it->selective > 0
4564 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
4565 (double) it->selective)) /* iftc */
4566 visible_p = 0;
4567 else
4569 Lisp_Object prop;
4571 /* Check the newline before point for invisibility. */
4572 prop = Fget_char_property (make_number (IT_CHARPOS (*it) - 1),
4573 Qinvisible, it->window);
4574 if (TEXT_PROP_MEANS_INVISIBLE (prop))
4575 visible_p = 0;
4578 if (visible_p)
4580 struct it it2 = *it;
4582 if (handle_display_prop (&it2) == HANDLED_RETURN)
4583 visible_p = 0;
4586 /* Back one more newline if the current one is invisible. */
4587 if (!visible_p)
4588 back_to_previous_line_start (it);
4591 xassert (IT_CHARPOS (*it) >= BEGV);
4592 xassert (IT_CHARPOS (*it) == BEGV
4593 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
4594 CHECK_IT (it);
4598 /* Reseat iterator IT at the previous visible line start. Skip
4599 invisible text that is so either due to text properties or due to
4600 selective display. At the end, update IT's overlay information,
4601 face information etc. */
4603 void
4604 reseat_at_previous_visible_line_start (it)
4605 struct it *it;
4607 back_to_previous_visible_line_start (it);
4608 reseat (it, it->current.pos, 1);
4609 CHECK_IT (it);
4613 /* Reseat iterator IT on the next visible line start in the current
4614 buffer. ON_NEWLINE_P non-zero means position IT on the newline
4615 preceding the line start. Skip over invisible text that is so
4616 because of selective display. Compute faces, overlays etc at the
4617 new position. Note that this function does not skip over text that
4618 is invisible because of text properties. */
4620 static void
4621 reseat_at_next_visible_line_start (it, on_newline_p)
4622 struct it *it;
4623 int on_newline_p;
4625 int newline_found_p, skipped_p = 0;
4627 newline_found_p = forward_to_next_line_start (it, &skipped_p);
4629 /* Skip over lines that are invisible because they are indented
4630 more than the value of IT->selective. */
4631 if (it->selective > 0)
4632 while (IT_CHARPOS (*it) < ZV
4633 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
4634 (double) it->selective)) /* iftc */
4636 xassert (FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
4637 newline_found_p = forward_to_next_line_start (it, &skipped_p);
4640 /* Position on the newline if that's what's requested. */
4641 if (on_newline_p && newline_found_p)
4643 if (STRINGP (it->string))
4645 if (IT_STRING_CHARPOS (*it) > 0)
4647 --IT_STRING_CHARPOS (*it);
4648 --IT_STRING_BYTEPOS (*it);
4651 else if (IT_CHARPOS (*it) > BEGV)
4653 --IT_CHARPOS (*it);
4654 --IT_BYTEPOS (*it);
4655 reseat (it, it->current.pos, 0);
4658 else if (skipped_p)
4659 reseat (it, it->current.pos, 0);
4661 CHECK_IT (it);
4666 /***********************************************************************
4667 Changing an iterator's position
4668 ***********************************************************************/
4670 /* Change IT's current position to POS in current_buffer. If FORCE_P
4671 is non-zero, always check for text properties at the new position.
4672 Otherwise, text properties are only looked up if POS >=
4673 IT->check_charpos of a property. */
4675 static void
4676 reseat (it, pos, force_p)
4677 struct it *it;
4678 struct text_pos pos;
4679 int force_p;
4681 int original_pos = IT_CHARPOS (*it);
4683 reseat_1 (it, pos, 0);
4685 /* Determine where to check text properties. Avoid doing it
4686 where possible because text property lookup is very expensive. */
4687 if (force_p
4688 || CHARPOS (pos) > it->stop_charpos
4689 || CHARPOS (pos) < original_pos)
4690 handle_stop (it);
4692 CHECK_IT (it);
4696 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
4697 IT->stop_pos to POS, also. */
4699 static void
4700 reseat_1 (it, pos, set_stop_p)
4701 struct it *it;
4702 struct text_pos pos;
4703 int set_stop_p;
4705 /* Don't call this function when scanning a C string. */
4706 xassert (it->s == NULL);
4708 /* POS must be a reasonable value. */
4709 xassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
4711 it->current.pos = it->position = pos;
4712 XSETBUFFER (it->object, current_buffer);
4713 it->end_charpos = ZV;
4714 it->dpvec = NULL;
4715 it->current.dpvec_index = -1;
4716 it->current.overlay_string_index = -1;
4717 IT_STRING_CHARPOS (*it) = -1;
4718 IT_STRING_BYTEPOS (*it) = -1;
4719 it->string = Qnil;
4720 it->method = next_element_from_buffer;
4721 /* RMS: I added this to fix a bug in move_it_vertically_backward
4722 where it->area continued to relate to the starting point
4723 for the backward motion. Bug report from
4724 Nick Roberts <nick@nick.uklinux.net> on 19 May 2003.
4725 However, I am not sure whether reseat still does the right thing
4726 in general after this change. */
4727 it->area = TEXT_AREA;
4728 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
4729 it->sp = 0;
4730 it->face_before_selective_p = 0;
4732 if (set_stop_p)
4733 it->stop_charpos = CHARPOS (pos);
4737 /* Set up IT for displaying a string, starting at CHARPOS in window W.
4738 If S is non-null, it is a C string to iterate over. Otherwise,
4739 STRING gives a Lisp string to iterate over.
4741 If PRECISION > 0, don't return more then PRECISION number of
4742 characters from the string.
4744 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
4745 characters have been returned. FIELD_WIDTH < 0 means an infinite
4746 field width.
4748 MULTIBYTE = 0 means disable processing of multibyte characters,
4749 MULTIBYTE > 0 means enable it,
4750 MULTIBYTE < 0 means use IT->multibyte_p.
4752 IT must be initialized via a prior call to init_iterator before
4753 calling this function. */
4755 static void
4756 reseat_to_string (it, s, string, charpos, precision, field_width, multibyte)
4757 struct it *it;
4758 unsigned char *s;
4759 Lisp_Object string;
4760 int charpos;
4761 int precision, field_width, multibyte;
4763 /* No region in strings. */
4764 it->region_beg_charpos = it->region_end_charpos = -1;
4766 /* No text property checks performed by default, but see below. */
4767 it->stop_charpos = -1;
4769 /* Set iterator position and end position. */
4770 bzero (&it->current, sizeof it->current);
4771 it->current.overlay_string_index = -1;
4772 it->current.dpvec_index = -1;
4773 xassert (charpos >= 0);
4775 /* If STRING is specified, use its multibyteness, otherwise use the
4776 setting of MULTIBYTE, if specified. */
4777 if (multibyte >= 0)
4778 it->multibyte_p = multibyte > 0;
4780 if (s == NULL)
4782 xassert (STRINGP (string));
4783 it->string = string;
4784 it->s = NULL;
4785 it->end_charpos = it->string_nchars = SCHARS (string);
4786 it->method = next_element_from_string;
4787 it->current.string_pos = string_pos (charpos, string);
4789 else
4791 it->s = s;
4792 it->string = Qnil;
4794 /* Note that we use IT->current.pos, not it->current.string_pos,
4795 for displaying C strings. */
4796 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
4797 if (it->multibyte_p)
4799 it->current.pos = c_string_pos (charpos, s, 1);
4800 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
4802 else
4804 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
4805 it->end_charpos = it->string_nchars = strlen (s);
4808 it->method = next_element_from_c_string;
4811 /* PRECISION > 0 means don't return more than PRECISION characters
4812 from the string. */
4813 if (precision > 0 && it->end_charpos - charpos > precision)
4814 it->end_charpos = it->string_nchars = charpos + precision;
4816 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
4817 characters have been returned. FIELD_WIDTH == 0 means don't pad,
4818 FIELD_WIDTH < 0 means infinite field width. This is useful for
4819 padding with `-' at the end of a mode line. */
4820 if (field_width < 0)
4821 field_width = INFINITY;
4822 if (field_width > it->end_charpos - charpos)
4823 it->end_charpos = charpos + field_width;
4825 /* Use the standard display table for displaying strings. */
4826 if (DISP_TABLE_P (Vstandard_display_table))
4827 it->dp = XCHAR_TABLE (Vstandard_display_table);
4829 it->stop_charpos = charpos;
4830 CHECK_IT (it);
4835 /***********************************************************************
4836 Iteration
4837 ***********************************************************************/
4839 /* Load IT's display element fields with information about the next
4840 display element from the current position of IT. Value is zero if
4841 end of buffer (or C string) is reached. */
4844 get_next_display_element (it)
4845 struct it *it;
4847 /* Non-zero means that we found a display element. Zero means that
4848 we hit the end of what we iterate over. Performance note: the
4849 function pointer `method' used here turns out to be faster than
4850 using a sequence of if-statements. */
4851 int success_p;
4853 get_next:
4854 success_p = (*it->method) (it);
4856 if (it->what == IT_CHARACTER)
4858 /* Map via display table or translate control characters.
4859 IT->c, IT->len etc. have been set to the next character by
4860 the function call above. If we have a display table, and it
4861 contains an entry for IT->c, translate it. Don't do this if
4862 IT->c itself comes from a display table, otherwise we could
4863 end up in an infinite recursion. (An alternative could be to
4864 count the recursion depth of this function and signal an
4865 error when a certain maximum depth is reached.) Is it worth
4866 it? */
4867 if (success_p && it->dpvec == NULL)
4869 Lisp_Object dv;
4871 if (it->dp
4872 && (dv = DISP_CHAR_VECTOR (it->dp, it->c),
4873 VECTORP (dv)))
4875 struct Lisp_Vector *v = XVECTOR (dv);
4877 /* Return the first character from the display table
4878 entry, if not empty. If empty, don't display the
4879 current character. */
4880 if (v->size)
4882 it->dpvec_char_len = it->len;
4883 it->dpvec = v->contents;
4884 it->dpend = v->contents + v->size;
4885 it->current.dpvec_index = 0;
4886 it->saved_face_id = it->face_id;
4887 it->method = next_element_from_display_vector;
4889 else
4891 set_iterator_to_next (it, 0);
4893 goto get_next;
4896 /* Translate control characters into `\003' or `^C' form.
4897 Control characters coming from a display table entry are
4898 currently not translated because we use IT->dpvec to hold
4899 the translation. This could easily be changed but I
4900 don't believe that it is worth doing.
4902 If it->multibyte_p is nonzero, eight-bit characters and
4903 non-printable multibyte characters are also translated to
4904 octal form.
4906 If it->multibyte_p is zero, eight-bit characters that
4907 don't have corresponding multibyte char code are also
4908 translated to octal form. */
4909 else if ((it->c < ' '
4910 && (it->area != TEXT_AREA
4911 /* In mode line, treat \n like other crl chars. */
4912 || (it->c != '\n'
4913 && it->glyph_row && it->glyph_row->mode_line_p)
4914 || (it->c != '\n' && it->c != '\t')))
4915 || (it->multibyte_p
4916 ? ((it->c >= 127
4917 && it->len == 1)
4918 || !CHAR_PRINTABLE_P (it->c))
4919 : (it->c >= 127
4920 && (!unibyte_display_via_language_environment
4921 || it->c == unibyte_char_to_multibyte (it->c)))))
4923 /* IT->c is a control character which must be displayed
4924 either as '\003' or as `^C' where the '\\' and '^'
4925 can be defined in the display table. Fill
4926 IT->ctl_chars with glyphs for what we have to
4927 display. Then, set IT->dpvec to these glyphs. */
4928 GLYPH g;
4929 int ctl_len;
4930 int face_id = escape_glyph_face;
4932 /* Find the face id if `escape-glyph' unless we recently did. */
4933 if (face_id < 0)
4935 Lisp_Object tem = Fget (Qescape_glyph, Qface);
4936 if (INTEGERP (tem))
4937 face_id = XINT (tem);
4938 else
4939 face_id = 0;
4940 /* If there's overflow, use 0 instead. */
4941 if (FAST_GLYPH_FACE (FAST_MAKE_GLYPH (0, face_id)) != face_id)
4942 face_id = 0;
4943 escape_glyph_face = face_id;
4946 if (it->c < 128 && it->ctl_arrow_p)
4948 /* Set IT->ctl_chars[0] to the glyph for `^'. */
4949 if (it->dp
4950 && INTEGERP (DISP_CTRL_GLYPH (it->dp))
4951 && GLYPH_CHAR_VALID_P (XINT (DISP_CTRL_GLYPH (it->dp))))
4952 g = XINT (DISP_CTRL_GLYPH (it->dp));
4953 else
4954 g = FAST_MAKE_GLYPH ('^', face_id);
4955 XSETINT (it->ctl_chars[0], g);
4957 g = FAST_MAKE_GLYPH (it->c ^ 0100, face_id);
4958 XSETINT (it->ctl_chars[1], g);
4959 ctl_len = 2;
4961 else
4963 unsigned char str[MAX_MULTIBYTE_LENGTH];
4964 int len;
4965 int i;
4966 GLYPH escape_glyph;
4968 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
4969 if (it->dp
4970 && INTEGERP (DISP_ESCAPE_GLYPH (it->dp))
4971 && GLYPH_CHAR_VALID_P (XFASTINT (DISP_ESCAPE_GLYPH (it->dp))))
4972 escape_glyph = XFASTINT (DISP_ESCAPE_GLYPH (it->dp));
4973 else
4974 escape_glyph = FAST_MAKE_GLYPH ('\\', face_id);
4976 if (SINGLE_BYTE_CHAR_P (it->c))
4977 str[0] = it->c, len = 1;
4978 else
4980 len = CHAR_STRING_NO_SIGNAL (it->c, str);
4981 if (len < 0)
4983 /* It's an invalid character, which
4984 shouldn't happen actually, but due to
4985 bugs it may happen. Let's print the char
4986 as is, there's not much meaningful we can
4987 do with it. */
4988 str[0] = it->c;
4989 str[1] = it->c >> 8;
4990 str[2] = it->c >> 16;
4991 str[3] = it->c >> 24;
4992 len = 4;
4996 for (i = 0; i < len; i++)
4998 XSETINT (it->ctl_chars[i * 4], escape_glyph);
4999 /* Insert three more glyphs into IT->ctl_chars for
5000 the octal display of the character. */
5001 g = FAST_MAKE_GLYPH (((str[i] >> 6) & 7) + '0',
5002 face_id);
5003 XSETINT (it->ctl_chars[i * 4 + 1], g);
5004 g = FAST_MAKE_GLYPH (((str[i] >> 3) & 7) + '0',
5005 face_id);
5006 XSETINT (it->ctl_chars[i * 4 + 2], g);
5007 g = FAST_MAKE_GLYPH ((str[i] & 7) + '0',
5008 face_id);
5009 XSETINT (it->ctl_chars[i * 4 + 3], g);
5011 ctl_len = len * 4;
5014 /* Set up IT->dpvec and return first character from it. */
5015 it->dpvec_char_len = it->len;
5016 it->dpvec = it->ctl_chars;
5017 it->dpend = it->dpvec + ctl_len;
5018 it->current.dpvec_index = 0;
5019 it->saved_face_id = it->face_id;
5020 it->method = next_element_from_display_vector;
5021 goto get_next;
5025 /* Adjust face id for a multibyte character. There are no
5026 multibyte character in unibyte text. */
5027 if (it->multibyte_p
5028 && success_p
5029 && FRAME_WINDOW_P (it->f))
5031 struct face *face = FACE_FROM_ID (it->f, it->face_id);
5032 it->face_id = FACE_FOR_CHAR (it->f, face, it->c);
5036 /* Is this character the last one of a run of characters with
5037 box? If yes, set IT->end_of_box_run_p to 1. */
5038 if (it->face_box_p
5039 && it->s == NULL)
5041 int face_id;
5042 struct face *face;
5044 it->end_of_box_run_p
5045 = ((face_id = face_after_it_pos (it),
5046 face_id != it->face_id)
5047 && (face = FACE_FROM_ID (it->f, face_id),
5048 face->box == FACE_NO_BOX));
5051 /* Value is 0 if end of buffer or string reached. */
5052 return success_p;
5056 /* Move IT to the next display element.
5058 RESEAT_P non-zero means if called on a newline in buffer text,
5059 skip to the next visible line start.
5061 Functions get_next_display_element and set_iterator_to_next are
5062 separate because I find this arrangement easier to handle than a
5063 get_next_display_element function that also increments IT's
5064 position. The way it is we can first look at an iterator's current
5065 display element, decide whether it fits on a line, and if it does,
5066 increment the iterator position. The other way around we probably
5067 would either need a flag indicating whether the iterator has to be
5068 incremented the next time, or we would have to implement a
5069 decrement position function which would not be easy to write. */
5071 void
5072 set_iterator_to_next (it, reseat_p)
5073 struct it *it;
5074 int reseat_p;
5076 /* Reset flags indicating start and end of a sequence of characters
5077 with box. Reset them at the start of this function because
5078 moving the iterator to a new position might set them. */
5079 it->start_of_box_run_p = it->end_of_box_run_p = 0;
5081 if (it->method == next_element_from_buffer)
5083 /* The current display element of IT is a character from
5084 current_buffer. Advance in the buffer, and maybe skip over
5085 invisible lines that are so because of selective display. */
5086 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
5087 reseat_at_next_visible_line_start (it, 0);
5088 else
5090 xassert (it->len != 0);
5091 IT_BYTEPOS (*it) += it->len;
5092 IT_CHARPOS (*it) += 1;
5093 xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
5096 else if (it->method == next_element_from_composition)
5098 xassert (it->cmp_id >= 0 && it ->cmp_id < n_compositions);
5099 if (STRINGP (it->string))
5101 IT_STRING_BYTEPOS (*it) += it->len;
5102 IT_STRING_CHARPOS (*it) += it->cmp_len;
5103 it->method = next_element_from_string;
5104 goto consider_string_end;
5106 else
5108 IT_BYTEPOS (*it) += it->len;
5109 IT_CHARPOS (*it) += it->cmp_len;
5110 it->method = next_element_from_buffer;
5113 else if (it->method == next_element_from_c_string)
5115 /* Current display element of IT is from a C string. */
5116 IT_BYTEPOS (*it) += it->len;
5117 IT_CHARPOS (*it) += 1;
5119 else if (it->method == next_element_from_display_vector)
5121 /* Current display element of IT is from a display table entry.
5122 Advance in the display table definition. Reset it to null if
5123 end reached, and continue with characters from buffers/
5124 strings. */
5125 ++it->current.dpvec_index;
5127 /* Restore face of the iterator to what they were before the
5128 display vector entry (these entries may contain faces). */
5129 it->face_id = it->saved_face_id;
5131 if (it->dpvec + it->current.dpvec_index == it->dpend)
5133 if (it->s)
5134 it->method = next_element_from_c_string;
5135 else if (STRINGP (it->string))
5136 it->method = next_element_from_string;
5137 else
5138 it->method = next_element_from_buffer;
5140 it->dpvec = NULL;
5141 it->current.dpvec_index = -1;
5143 /* Recheck faces after display vector */
5144 it->stop_charpos = 0;
5146 /* Skip over characters which were displayed via IT->dpvec. */
5147 if (it->dpvec_char_len < 0)
5148 reseat_at_next_visible_line_start (it, 1);
5149 else if (it->dpvec_char_len > 0)
5151 it->len = it->dpvec_char_len;
5152 set_iterator_to_next (it, reseat_p);
5156 else if (it->method == next_element_from_string)
5158 /* Current display element is a character from a Lisp string. */
5159 xassert (it->s == NULL && STRINGP (it->string));
5160 IT_STRING_BYTEPOS (*it) += it->len;
5161 IT_STRING_CHARPOS (*it) += 1;
5163 consider_string_end:
5165 if (it->current.overlay_string_index >= 0)
5167 /* IT->string is an overlay string. Advance to the
5168 next, if there is one. */
5169 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
5170 next_overlay_string (it);
5172 else
5174 /* IT->string is not an overlay string. If we reached
5175 its end, and there is something on IT->stack, proceed
5176 with what is on the stack. This can be either another
5177 string, this time an overlay string, or a buffer. */
5178 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
5179 && it->sp > 0)
5181 pop_it (it);
5182 if (!STRINGP (it->string))
5183 it->method = next_element_from_buffer;
5184 else
5185 goto consider_string_end;
5189 else if (it->method == next_element_from_image
5190 || it->method == next_element_from_stretch)
5192 /* The position etc with which we have to proceed are on
5193 the stack. The position may be at the end of a string,
5194 if the `display' property takes up the whole string. */
5195 pop_it (it);
5196 it->image_id = 0;
5197 if (STRINGP (it->string))
5199 it->method = next_element_from_string;
5200 goto consider_string_end;
5202 else
5203 it->method = next_element_from_buffer;
5205 else
5206 /* There are no other methods defined, so this should be a bug. */
5207 abort ();
5209 xassert (it->method != next_element_from_string
5210 || (STRINGP (it->string)
5211 && IT_STRING_CHARPOS (*it) >= 0));
5214 /* Load IT's display element fields with information about the next
5215 display element which comes from a display table entry or from the
5216 result of translating a control character to one of the forms `^C'
5217 or `\003'.
5219 IT->dpvec holds the glyphs to return as characters.
5220 IT->saved_face_id holds the face id before the display vector--
5221 it is restored into IT->face_idin set_iterator_to_next. */
5223 static int
5224 next_element_from_display_vector (it)
5225 struct it *it;
5227 /* Precondition. */
5228 xassert (it->dpvec && it->current.dpvec_index >= 0);
5230 if (INTEGERP (*it->dpvec)
5231 && GLYPH_CHAR_VALID_P (XFASTINT (*it->dpvec)))
5233 int lface_id;
5234 GLYPH g;
5236 g = XFASTINT (it->dpvec[it->current.dpvec_index]);
5237 it->c = FAST_GLYPH_CHAR (g);
5238 it->len = CHAR_BYTES (it->c);
5240 /* The entry may contain a face id to use. Such a face id is
5241 the id of a Lisp face, not a realized face. A face id of
5242 zero means no face is specified. */
5243 lface_id = FAST_GLYPH_FACE (g);
5244 if (lface_id)
5246 /* The function returns -1 if lface_id is invalid. */
5247 int face_id = ascii_face_of_lisp_face (it->f, lface_id);
5248 if (face_id >= 0)
5249 it->face_id = face_id;
5252 else
5253 /* Display table entry is invalid. Return a space. */
5254 it->c = ' ', it->len = 1;
5256 /* Don't change position and object of the iterator here. They are
5257 still the values of the character that had this display table
5258 entry or was translated, and that's what we want. */
5259 it->what = IT_CHARACTER;
5260 return 1;
5264 /* Load IT with the next display element from Lisp string IT->string.
5265 IT->current.string_pos is the current position within the string.
5266 If IT->current.overlay_string_index >= 0, the Lisp string is an
5267 overlay string. */
5269 static int
5270 next_element_from_string (it)
5271 struct it *it;
5273 struct text_pos position;
5275 xassert (STRINGP (it->string));
5276 xassert (IT_STRING_CHARPOS (*it) >= 0);
5277 position = it->current.string_pos;
5279 /* Time to check for invisible text? */
5280 if (IT_STRING_CHARPOS (*it) < it->end_charpos
5281 && IT_STRING_CHARPOS (*it) == it->stop_charpos)
5283 handle_stop (it);
5285 /* Since a handler may have changed IT->method, we must
5286 recurse here. */
5287 return get_next_display_element (it);
5290 if (it->current.overlay_string_index >= 0)
5292 /* Get the next character from an overlay string. In overlay
5293 strings, There is no field width or padding with spaces to
5294 do. */
5295 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
5297 it->what = IT_EOB;
5298 return 0;
5300 else if (STRING_MULTIBYTE (it->string))
5302 int remaining = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
5303 const unsigned char *s = (SDATA (it->string)
5304 + IT_STRING_BYTEPOS (*it));
5305 it->c = string_char_and_length (s, remaining, &it->len);
5307 else
5309 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
5310 it->len = 1;
5313 else
5315 /* Get the next character from a Lisp string that is not an
5316 overlay string. Such strings come from the mode line, for
5317 example. We may have to pad with spaces, or truncate the
5318 string. See also next_element_from_c_string. */
5319 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
5321 it->what = IT_EOB;
5322 return 0;
5324 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
5326 /* Pad with spaces. */
5327 it->c = ' ', it->len = 1;
5328 CHARPOS (position) = BYTEPOS (position) = -1;
5330 else if (STRING_MULTIBYTE (it->string))
5332 int maxlen = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
5333 const unsigned char *s = (SDATA (it->string)
5334 + IT_STRING_BYTEPOS (*it));
5335 it->c = string_char_and_length (s, maxlen, &it->len);
5337 else
5339 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
5340 it->len = 1;
5344 /* Record what we have and where it came from. Note that we store a
5345 buffer position in IT->position although it could arguably be a
5346 string position. */
5347 it->what = IT_CHARACTER;
5348 it->object = it->string;
5349 it->position = position;
5350 return 1;
5354 /* Load IT with next display element from C string IT->s.
5355 IT->string_nchars is the maximum number of characters to return
5356 from the string. IT->end_charpos may be greater than
5357 IT->string_nchars when this function is called, in which case we
5358 may have to return padding spaces. Value is zero if end of string
5359 reached, including padding spaces. */
5361 static int
5362 next_element_from_c_string (it)
5363 struct it *it;
5365 int success_p = 1;
5367 xassert (it->s);
5368 it->what = IT_CHARACTER;
5369 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
5370 it->object = Qnil;
5372 /* IT's position can be greater IT->string_nchars in case a field
5373 width or precision has been specified when the iterator was
5374 initialized. */
5375 if (IT_CHARPOS (*it) >= it->end_charpos)
5377 /* End of the game. */
5378 it->what = IT_EOB;
5379 success_p = 0;
5381 else if (IT_CHARPOS (*it) >= it->string_nchars)
5383 /* Pad with spaces. */
5384 it->c = ' ', it->len = 1;
5385 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
5387 else if (it->multibyte_p)
5389 /* Implementation note: The calls to strlen apparently aren't a
5390 performance problem because there is no noticeable performance
5391 difference between Emacs running in unibyte or multibyte mode. */
5392 int maxlen = strlen (it->s) - IT_BYTEPOS (*it);
5393 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it),
5394 maxlen, &it->len);
5396 else
5397 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
5399 return success_p;
5403 /* Set up IT to return characters from an ellipsis, if appropriate.
5404 The definition of the ellipsis glyphs may come from a display table
5405 entry. This function Fills IT with the first glyph from the
5406 ellipsis if an ellipsis is to be displayed. */
5408 static int
5409 next_element_from_ellipsis (it)
5410 struct it *it;
5412 if (it->selective_display_ellipsis_p)
5413 setup_for_ellipsis (it, it->len);
5414 else
5416 /* The face at the current position may be different from the
5417 face we find after the invisible text. Remember what it
5418 was in IT->saved_face_id, and signal that it's there by
5419 setting face_before_selective_p. */
5420 it->saved_face_id = it->face_id;
5421 it->method = next_element_from_buffer;
5422 reseat_at_next_visible_line_start (it, 1);
5423 it->face_before_selective_p = 1;
5426 return get_next_display_element (it);
5430 /* Deliver an image display element. The iterator IT is already
5431 filled with image information (done in handle_display_prop). Value
5432 is always 1. */
5435 static int
5436 next_element_from_image (it)
5437 struct it *it;
5439 it->what = IT_IMAGE;
5440 return 1;
5444 /* Fill iterator IT with next display element from a stretch glyph
5445 property. IT->object is the value of the text property. Value is
5446 always 1. */
5448 static int
5449 next_element_from_stretch (it)
5450 struct it *it;
5452 it->what = IT_STRETCH;
5453 return 1;
5457 /* Load IT with the next display element from current_buffer. Value
5458 is zero if end of buffer reached. IT->stop_charpos is the next
5459 position at which to stop and check for text properties or buffer
5460 end. */
5462 static int
5463 next_element_from_buffer (it)
5464 struct it *it;
5466 int success_p = 1;
5468 /* Check this assumption, otherwise, we would never enter the
5469 if-statement, below. */
5470 xassert (IT_CHARPOS (*it) >= BEGV
5471 && IT_CHARPOS (*it) <= it->stop_charpos);
5473 if (IT_CHARPOS (*it) >= it->stop_charpos)
5475 if (IT_CHARPOS (*it) >= it->end_charpos)
5477 int overlay_strings_follow_p;
5479 /* End of the game, except when overlay strings follow that
5480 haven't been returned yet. */
5481 if (it->overlay_strings_at_end_processed_p)
5482 overlay_strings_follow_p = 0;
5483 else
5485 it->overlay_strings_at_end_processed_p = 1;
5486 overlay_strings_follow_p = get_overlay_strings (it, 0);
5489 if (overlay_strings_follow_p)
5490 success_p = get_next_display_element (it);
5491 else
5493 it->what = IT_EOB;
5494 it->position = it->current.pos;
5495 success_p = 0;
5498 else
5500 handle_stop (it);
5501 return get_next_display_element (it);
5504 else
5506 /* No face changes, overlays etc. in sight, so just return a
5507 character from current_buffer. */
5508 unsigned char *p;
5510 /* Maybe run the redisplay end trigger hook. Performance note:
5511 This doesn't seem to cost measurable time. */
5512 if (it->redisplay_end_trigger_charpos
5513 && it->glyph_row
5514 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
5515 run_redisplay_end_trigger_hook (it);
5517 /* Get the next character, maybe multibyte. */
5518 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
5519 if (it->multibyte_p && !ASCII_BYTE_P (*p))
5521 int maxlen = ((IT_BYTEPOS (*it) >= GPT_BYTE ? ZV_BYTE : GPT_BYTE)
5522 - IT_BYTEPOS (*it));
5523 it->c = string_char_and_length (p, maxlen, &it->len);
5525 else
5526 it->c = *p, it->len = 1;
5528 /* Record what we have and where it came from. */
5529 it->what = IT_CHARACTER;;
5530 it->object = it->w->buffer;
5531 it->position = it->current.pos;
5533 /* Normally we return the character found above, except when we
5534 really want to return an ellipsis for selective display. */
5535 if (it->selective)
5537 if (it->c == '\n')
5539 /* A value of selective > 0 means hide lines indented more
5540 than that number of columns. */
5541 if (it->selective > 0
5542 && IT_CHARPOS (*it) + 1 < ZV
5543 && indented_beyond_p (IT_CHARPOS (*it) + 1,
5544 IT_BYTEPOS (*it) + 1,
5545 (double) it->selective)) /* iftc */
5547 success_p = next_element_from_ellipsis (it);
5548 it->dpvec_char_len = -1;
5551 else if (it->c == '\r' && it->selective == -1)
5553 /* A value of selective == -1 means that everything from the
5554 CR to the end of the line is invisible, with maybe an
5555 ellipsis displayed for it. */
5556 success_p = next_element_from_ellipsis (it);
5557 it->dpvec_char_len = -1;
5562 /* Value is zero if end of buffer reached. */
5563 xassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
5564 return success_p;
5568 /* Run the redisplay end trigger hook for IT. */
5570 static void
5571 run_redisplay_end_trigger_hook (it)
5572 struct it *it;
5574 Lisp_Object args[3];
5576 /* IT->glyph_row should be non-null, i.e. we should be actually
5577 displaying something, or otherwise we should not run the hook. */
5578 xassert (it->glyph_row);
5580 /* Set up hook arguments. */
5581 args[0] = Qredisplay_end_trigger_functions;
5582 args[1] = it->window;
5583 XSETINT (args[2], it->redisplay_end_trigger_charpos);
5584 it->redisplay_end_trigger_charpos = 0;
5586 /* Since we are *trying* to run these functions, don't try to run
5587 them again, even if they get an error. */
5588 it->w->redisplay_end_trigger = Qnil;
5589 Frun_hook_with_args (3, args);
5591 /* Notice if it changed the face of the character we are on. */
5592 handle_face_prop (it);
5596 /* Deliver a composition display element. The iterator IT is already
5597 filled with composition information (done in
5598 handle_composition_prop). Value is always 1. */
5600 static int
5601 next_element_from_composition (it)
5602 struct it *it;
5604 it->what = IT_COMPOSITION;
5605 it->position = (STRINGP (it->string)
5606 ? it->current.string_pos
5607 : it->current.pos);
5608 return 1;
5613 /***********************************************************************
5614 Moving an iterator without producing glyphs
5615 ***********************************************************************/
5617 /* Move iterator IT to a specified buffer or X position within one
5618 line on the display without producing glyphs.
5620 OP should be a bit mask including some or all of these bits:
5621 MOVE_TO_X: Stop on reaching x-position TO_X.
5622 MOVE_TO_POS: Stop on reaching buffer or string position TO_CHARPOS.
5623 Regardless of OP's value, stop in reaching the end of the display line.
5625 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
5626 This means, in particular, that TO_X includes window's horizontal
5627 scroll amount.
5629 The return value has several possible values that
5630 say what condition caused the scan to stop:
5632 MOVE_POS_MATCH_OR_ZV
5633 - when TO_POS or ZV was reached.
5635 MOVE_X_REACHED
5636 -when TO_X was reached before TO_POS or ZV were reached.
5638 MOVE_LINE_CONTINUED
5639 - when we reached the end of the display area and the line must
5640 be continued.
5642 MOVE_LINE_TRUNCATED
5643 - when we reached the end of the display area and the line is
5644 truncated.
5646 MOVE_NEWLINE_OR_CR
5647 - when we stopped at a line end, i.e. a newline or a CR and selective
5648 display is on. */
5650 static enum move_it_result
5651 move_it_in_display_line_to (it, to_charpos, to_x, op)
5652 struct it *it;
5653 int to_charpos, to_x, op;
5655 enum move_it_result result = MOVE_UNDEFINED;
5656 struct glyph_row *saved_glyph_row;
5658 /* Don't produce glyphs in produce_glyphs. */
5659 saved_glyph_row = it->glyph_row;
5660 it->glyph_row = NULL;
5662 #define BUFFER_POS_REACHED_P() \
5663 ((op & MOVE_TO_POS) != 0 \
5664 && BUFFERP (it->object) \
5665 && IT_CHARPOS (*it) >= to_charpos)
5667 while (1)
5669 int x, i, ascent = 0, descent = 0;
5671 /* Stop when ZV reached.
5672 We used to stop here when TO_CHARPOS reached as well, but that is
5673 too soon if this glyph does not fit on this line. So we handle it
5674 explicitly below. */
5675 if (!get_next_display_element (it)
5676 || (it->truncate_lines_p
5677 && BUFFER_POS_REACHED_P ()))
5679 result = MOVE_POS_MATCH_OR_ZV;
5680 break;
5683 /* The call to produce_glyphs will get the metrics of the
5684 display element IT is loaded with. We record in x the
5685 x-position before this display element in case it does not
5686 fit on the line. */
5687 x = it->current_x;
5689 /* Remember the line height so far in case the next element doesn't
5690 fit on the line. */
5691 if (!it->truncate_lines_p)
5693 ascent = it->max_ascent;
5694 descent = it->max_descent;
5697 PRODUCE_GLYPHS (it);
5699 if (it->area != TEXT_AREA)
5701 set_iterator_to_next (it, 1);
5702 continue;
5705 /* The number of glyphs we get back in IT->nglyphs will normally
5706 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
5707 character on a terminal frame, or (iii) a line end. For the
5708 second case, IT->nglyphs - 1 padding glyphs will be present
5709 (on X frames, there is only one glyph produced for a
5710 composite character.
5712 The behavior implemented below means, for continuation lines,
5713 that as many spaces of a TAB as fit on the current line are
5714 displayed there. For terminal frames, as many glyphs of a
5715 multi-glyph character are displayed in the current line, too.
5716 This is what the old redisplay code did, and we keep it that
5717 way. Under X, the whole shape of a complex character must
5718 fit on the line or it will be completely displayed in the
5719 next line.
5721 Note that both for tabs and padding glyphs, all glyphs have
5722 the same width. */
5723 if (it->nglyphs)
5725 /* More than one glyph or glyph doesn't fit on line. All
5726 glyphs have the same width. */
5727 int single_glyph_width = it->pixel_width / it->nglyphs;
5728 int new_x;
5730 for (i = 0; i < it->nglyphs; ++i, x = new_x)
5732 new_x = x + single_glyph_width;
5734 /* We want to leave anything reaching TO_X to the caller. */
5735 if ((op & MOVE_TO_X) && new_x > to_x)
5737 if (BUFFER_POS_REACHED_P ())
5738 goto buffer_pos_reached;
5739 it->current_x = x;
5740 result = MOVE_X_REACHED;
5741 break;
5743 else if (/* Lines are continued. */
5744 !it->truncate_lines_p
5745 && (/* And glyph doesn't fit on the line. */
5746 new_x > it->last_visible_x
5747 /* Or it fits exactly and we're on a window
5748 system frame. */
5749 || (new_x == it->last_visible_x
5750 && FRAME_WINDOW_P (it->f))))
5752 if (/* IT->hpos == 0 means the very first glyph
5753 doesn't fit on the line, e.g. a wide image. */
5754 it->hpos == 0
5755 || (new_x == it->last_visible_x
5756 && FRAME_WINDOW_P (it->f)))
5758 ++it->hpos;
5759 it->current_x = new_x;
5760 if (i == it->nglyphs - 1)
5762 set_iterator_to_next (it, 1);
5763 #ifdef HAVE_WINDOW_SYSTEM
5764 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
5766 if (!get_next_display_element (it))
5768 result = MOVE_POS_MATCH_OR_ZV;
5769 break;
5771 if (BUFFER_POS_REACHED_P ())
5773 if (ITERATOR_AT_END_OF_LINE_P (it))
5774 result = MOVE_POS_MATCH_OR_ZV;
5775 else
5776 result = MOVE_LINE_CONTINUED;
5777 break;
5779 if (ITERATOR_AT_END_OF_LINE_P (it))
5781 result = MOVE_NEWLINE_OR_CR;
5782 break;
5785 #endif /* HAVE_WINDOW_SYSTEM */
5788 else
5790 it->current_x = x;
5791 it->max_ascent = ascent;
5792 it->max_descent = descent;
5795 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
5796 IT_CHARPOS (*it)));
5797 result = MOVE_LINE_CONTINUED;
5798 break;
5800 else if (BUFFER_POS_REACHED_P ())
5801 goto buffer_pos_reached;
5802 else if (new_x > it->first_visible_x)
5804 /* Glyph is visible. Increment number of glyphs that
5805 would be displayed. */
5806 ++it->hpos;
5808 else
5810 /* Glyph is completely off the left margin of the display
5811 area. Nothing to do. */
5815 if (result != MOVE_UNDEFINED)
5816 break;
5818 else if (BUFFER_POS_REACHED_P ())
5820 buffer_pos_reached:
5821 it->current_x = x;
5822 it->max_ascent = ascent;
5823 it->max_descent = descent;
5824 result = MOVE_POS_MATCH_OR_ZV;
5825 break;
5827 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
5829 /* Stop when TO_X specified and reached. This check is
5830 necessary here because of lines consisting of a line end,
5831 only. The line end will not produce any glyphs and we
5832 would never get MOVE_X_REACHED. */
5833 xassert (it->nglyphs == 0);
5834 result = MOVE_X_REACHED;
5835 break;
5838 /* Is this a line end? If yes, we're done. */
5839 if (ITERATOR_AT_END_OF_LINE_P (it))
5841 result = MOVE_NEWLINE_OR_CR;
5842 break;
5845 /* The current display element has been consumed. Advance
5846 to the next. */
5847 set_iterator_to_next (it, 1);
5849 /* Stop if lines are truncated and IT's current x-position is
5850 past the right edge of the window now. */
5851 if (it->truncate_lines_p
5852 && it->current_x >= it->last_visible_x)
5854 #ifdef HAVE_WINDOW_SYSTEM
5855 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
5857 if (!get_next_display_element (it)
5858 || BUFFER_POS_REACHED_P ())
5860 result = MOVE_POS_MATCH_OR_ZV;
5861 break;
5863 if (ITERATOR_AT_END_OF_LINE_P (it))
5865 result = MOVE_NEWLINE_OR_CR;
5866 break;
5869 #endif /* HAVE_WINDOW_SYSTEM */
5870 result = MOVE_LINE_TRUNCATED;
5871 break;
5875 #undef BUFFER_POS_REACHED_P
5877 /* Restore the iterator settings altered at the beginning of this
5878 function. */
5879 it->glyph_row = saved_glyph_row;
5880 return result;
5884 /* Move IT forward until it satisfies one or more of the criteria in
5885 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
5887 OP is a bit-mask that specifies where to stop, and in particular,
5888 which of those four position arguments makes a difference. See the
5889 description of enum move_operation_enum.
5891 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
5892 screen line, this function will set IT to the next position >
5893 TO_CHARPOS. */
5895 void
5896 move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
5897 struct it *it;
5898 int to_charpos, to_x, to_y, to_vpos;
5899 int op;
5901 enum move_it_result skip, skip2 = MOVE_X_REACHED;
5902 int line_height;
5903 int reached = 0;
5905 for (;;)
5907 if (op & MOVE_TO_VPOS)
5909 /* If no TO_CHARPOS and no TO_X specified, stop at the
5910 start of the line TO_VPOS. */
5911 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
5913 if (it->vpos == to_vpos)
5915 reached = 1;
5916 break;
5918 else
5919 skip = move_it_in_display_line_to (it, -1, -1, 0);
5921 else
5923 /* TO_VPOS >= 0 means stop at TO_X in the line at
5924 TO_VPOS, or at TO_POS, whichever comes first. */
5925 if (it->vpos == to_vpos)
5927 reached = 2;
5928 break;
5931 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
5933 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
5935 reached = 3;
5936 break;
5938 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
5940 /* We have reached TO_X but not in the line we want. */
5941 skip = move_it_in_display_line_to (it, to_charpos,
5942 -1, MOVE_TO_POS);
5943 if (skip == MOVE_POS_MATCH_OR_ZV)
5945 reached = 4;
5946 break;
5951 else if (op & MOVE_TO_Y)
5953 struct it it_backup;
5955 /* TO_Y specified means stop at TO_X in the line containing
5956 TO_Y---or at TO_CHARPOS if this is reached first. The
5957 problem is that we can't really tell whether the line
5958 contains TO_Y before we have completely scanned it, and
5959 this may skip past TO_X. What we do is to first scan to
5960 TO_X.
5962 If TO_X is not specified, use a TO_X of zero. The reason
5963 is to make the outcome of this function more predictable.
5964 If we didn't use TO_X == 0, we would stop at the end of
5965 the line which is probably not what a caller would expect
5966 to happen. */
5967 skip = move_it_in_display_line_to (it, to_charpos,
5968 ((op & MOVE_TO_X)
5969 ? to_x : 0),
5970 (MOVE_TO_X
5971 | (op & MOVE_TO_POS)));
5973 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
5974 if (skip == MOVE_POS_MATCH_OR_ZV)
5976 reached = 5;
5977 break;
5980 /* If TO_X was reached, we would like to know whether TO_Y
5981 is in the line. This can only be said if we know the
5982 total line height which requires us to scan the rest of
5983 the line. */
5984 if (skip == MOVE_X_REACHED)
5986 it_backup = *it;
5987 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
5988 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
5989 op & MOVE_TO_POS);
5990 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
5993 /* Now, decide whether TO_Y is in this line. */
5994 line_height = it->max_ascent + it->max_descent;
5995 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
5997 if (to_y >= it->current_y
5998 && to_y < it->current_y + line_height)
6000 if (skip == MOVE_X_REACHED)
6001 /* If TO_Y is in this line and TO_X was reached above,
6002 we scanned too far. We have to restore IT's settings
6003 to the ones before skipping. */
6004 *it = it_backup;
6005 reached = 6;
6007 else if (skip == MOVE_X_REACHED)
6009 skip = skip2;
6010 if (skip == MOVE_POS_MATCH_OR_ZV)
6011 reached = 7;
6014 if (reached)
6015 break;
6017 else
6018 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
6020 switch (skip)
6022 case MOVE_POS_MATCH_OR_ZV:
6023 reached = 8;
6024 goto out;
6026 case MOVE_NEWLINE_OR_CR:
6027 set_iterator_to_next (it, 1);
6028 it->continuation_lines_width = 0;
6029 break;
6031 case MOVE_LINE_TRUNCATED:
6032 it->continuation_lines_width = 0;
6033 reseat_at_next_visible_line_start (it, 0);
6034 if ((op & MOVE_TO_POS) != 0
6035 && IT_CHARPOS (*it) > to_charpos)
6037 reached = 9;
6038 goto out;
6040 break;
6042 case MOVE_LINE_CONTINUED:
6043 it->continuation_lines_width += it->current_x;
6044 break;
6046 default:
6047 abort ();
6050 /* Reset/increment for the next run. */
6051 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
6052 it->current_x = it->hpos = 0;
6053 it->current_y += it->max_ascent + it->max_descent;
6054 ++it->vpos;
6055 last_height = it->max_ascent + it->max_descent;
6056 last_max_ascent = it->max_ascent;
6057 it->max_ascent = it->max_descent = 0;
6060 out:
6062 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
6066 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
6068 If DY > 0, move IT backward at least that many pixels. DY = 0
6069 means move IT backward to the preceding line start or BEGV. This
6070 function may move over more than DY pixels if IT->current_y - DY
6071 ends up in the middle of a line; in this case IT->current_y will be
6072 set to the top of the line moved to. */
6074 void
6075 move_it_vertically_backward (it, dy)
6076 struct it *it;
6077 int dy;
6079 int nlines, h;
6080 struct it it2, it3;
6081 int start_pos;
6083 move_further_back:
6084 xassert (dy >= 0);
6086 start_pos = IT_CHARPOS (*it);
6088 /* Estimate how many newlines we must move back. */
6089 nlines = max (1, dy / FRAME_LINE_HEIGHT (it->f));
6091 /* Set the iterator's position that many lines back. */
6092 while (nlines-- && IT_CHARPOS (*it) > BEGV)
6093 back_to_previous_visible_line_start (it);
6095 /* Reseat the iterator here. When moving backward, we don't want
6096 reseat to skip forward over invisible text, set up the iterator
6097 to deliver from overlay strings at the new position etc. So,
6098 use reseat_1 here. */
6099 reseat_1 (it, it->current.pos, 1);
6101 /* We are now surely at a line start. */
6102 it->current_x = it->hpos = 0;
6103 it->continuation_lines_width = 0;
6105 /* Move forward and see what y-distance we moved. First move to the
6106 start of the next line so that we get its height. We need this
6107 height to be able to tell whether we reached the specified
6108 y-distance. */
6109 it2 = *it;
6110 it2.max_ascent = it2.max_descent = 0;
6111 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
6112 MOVE_TO_POS | MOVE_TO_VPOS);
6113 xassert (IT_CHARPOS (*it) >= BEGV);
6114 it3 = it2;
6116 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
6117 xassert (IT_CHARPOS (*it) >= BEGV);
6118 /* H is the actual vertical distance from the position in *IT
6119 and the starting position. */
6120 h = it2.current_y - it->current_y;
6121 /* NLINES is the distance in number of lines. */
6122 nlines = it2.vpos - it->vpos;
6124 /* Correct IT's y and vpos position
6125 so that they are relative to the starting point. */
6126 it->vpos -= nlines;
6127 it->current_y -= h;
6129 if (dy == 0)
6131 /* DY == 0 means move to the start of the screen line. The
6132 value of nlines is > 0 if continuation lines were involved. */
6133 if (nlines > 0)
6134 move_it_by_lines (it, nlines, 1);
6135 xassert (IT_CHARPOS (*it) <= start_pos);
6137 else
6139 /* The y-position we try to reach, relative to *IT.
6140 Note that H has been subtracted in front of the if-statement. */
6141 int target_y = it->current_y + h - dy;
6142 int y0 = it3.current_y;
6143 int y1 = line_bottom_y (&it3);
6144 int line_height = y1 - y0;
6146 /* If we did not reach target_y, try to move further backward if
6147 we can. If we moved too far backward, try to move forward. */
6148 if (target_y < it->current_y
6149 /* This is heuristic. In a window that's 3 lines high, with
6150 a line height of 13 pixels each, recentering with point
6151 on the bottom line will try to move -39/2 = 19 pixels
6152 backward. Try to avoid moving into the first line. */
6153 && it->current_y - target_y > line_height * 2 / 3
6154 && IT_CHARPOS (*it) > BEGV)
6156 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
6157 target_y - it->current_y));
6158 dy = it->current_y - target_y;
6159 goto move_further_back;
6161 else if (target_y >= it->current_y + line_height
6162 && IT_CHARPOS (*it) < ZV)
6164 /* Should move forward by at least one line, maybe more.
6166 Note: Calling move_it_by_lines can be expensive on
6167 terminal frames, where compute_motion is used (via
6168 vmotion) to do the job, when there are very long lines
6169 and truncate-lines is nil. That's the reason for
6170 treating terminal frames specially here. */
6172 if (!FRAME_WINDOW_P (it->f))
6173 move_it_vertically (it, target_y - (it->current_y + line_height));
6174 else
6178 move_it_by_lines (it, 1, 1);
6180 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
6183 xassert (IT_CHARPOS (*it) >= BEGV);
6189 /* Move IT by a specified amount of pixel lines DY. DY negative means
6190 move backwards. DY = 0 means move to start of screen line. At the
6191 end, IT will be on the start of a screen line. */
6193 void
6194 move_it_vertically (it, dy)
6195 struct it *it;
6196 int dy;
6198 if (dy <= 0)
6199 move_it_vertically_backward (it, -dy);
6200 else
6202 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
6203 move_it_to (it, ZV, -1, it->current_y + dy, -1,
6204 MOVE_TO_POS | MOVE_TO_Y);
6205 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
6207 /* If buffer ends in ZV without a newline, move to the start of
6208 the line to satisfy the post-condition. */
6209 if (IT_CHARPOS (*it) == ZV
6210 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
6211 move_it_by_lines (it, 0, 0);
6216 /* Move iterator IT past the end of the text line it is in. */
6218 void
6219 move_it_past_eol (it)
6220 struct it *it;
6222 enum move_it_result rc;
6224 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
6225 if (rc == MOVE_NEWLINE_OR_CR)
6226 set_iterator_to_next (it, 0);
6230 #if 0 /* Currently not used. */
6232 /* Return non-zero if some text between buffer positions START_CHARPOS
6233 and END_CHARPOS is invisible. IT->window is the window for text
6234 property lookup. */
6236 static int
6237 invisible_text_between_p (it, start_charpos, end_charpos)
6238 struct it *it;
6239 int start_charpos, end_charpos;
6241 Lisp_Object prop, limit;
6242 int invisible_found_p;
6244 xassert (it != NULL && start_charpos <= end_charpos);
6246 /* Is text at START invisible? */
6247 prop = Fget_char_property (make_number (start_charpos), Qinvisible,
6248 it->window);
6249 if (TEXT_PROP_MEANS_INVISIBLE (prop))
6250 invisible_found_p = 1;
6251 else
6253 limit = Fnext_single_char_property_change (make_number (start_charpos),
6254 Qinvisible, Qnil,
6255 make_number (end_charpos));
6256 invisible_found_p = XFASTINT (limit) < end_charpos;
6259 return invisible_found_p;
6262 #endif /* 0 */
6265 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
6266 negative means move up. DVPOS == 0 means move to the start of the
6267 screen line. NEED_Y_P non-zero means calculate IT->current_y. If
6268 NEED_Y_P is zero, IT->current_y will be left unchanged.
6270 Further optimization ideas: If we would know that IT->f doesn't use
6271 a face with proportional font, we could be faster for
6272 truncate-lines nil. */
6274 void
6275 move_it_by_lines (it, dvpos, need_y_p)
6276 struct it *it;
6277 int dvpos, need_y_p;
6279 struct position pos;
6281 if (!FRAME_WINDOW_P (it->f))
6283 struct text_pos textpos;
6285 /* We can use vmotion on frames without proportional fonts. */
6286 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
6287 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
6288 reseat (it, textpos, 1);
6289 it->vpos += pos.vpos;
6290 it->current_y += pos.vpos;
6292 else if (dvpos == 0)
6294 /* DVPOS == 0 means move to the start of the screen line. */
6295 move_it_vertically_backward (it, 0);
6296 xassert (it->current_x == 0 && it->hpos == 0);
6297 /* Let next call to line_bottom_y calculate real line height */
6298 last_height = 0;
6300 else if (dvpos > 0)
6301 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
6302 else
6304 struct it it2;
6305 int start_charpos, i;
6307 /* Start at the beginning of the screen line containing IT's
6308 position. */
6309 move_it_vertically_backward (it, 0);
6311 /* Go back -DVPOS visible lines and reseat the iterator there. */
6312 start_charpos = IT_CHARPOS (*it);
6313 for (i = -dvpos; i && IT_CHARPOS (*it) > BEGV; --i)
6314 back_to_previous_visible_line_start (it);
6315 reseat (it, it->current.pos, 1);
6316 it->current_x = it->hpos = 0;
6318 /* Above call may have moved too far if continuation lines
6319 are involved. Scan forward and see if it did. */
6320 it2 = *it;
6321 it2.vpos = it2.current_y = 0;
6322 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
6323 it->vpos -= it2.vpos;
6324 it->current_y -= it2.current_y;
6325 it->current_x = it->hpos = 0;
6327 /* If we moved too far, move IT some lines forward. */
6328 if (it2.vpos > -dvpos)
6330 int delta = it2.vpos + dvpos;
6331 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
6336 /* Return 1 if IT points into the middle of a display vector. */
6339 in_display_vector_p (it)
6340 struct it *it;
6342 return (it->method == next_element_from_display_vector
6343 && it->current.dpvec_index > 0
6344 && it->dpvec + it->current.dpvec_index != it->dpend);
6348 /***********************************************************************
6349 Messages
6350 ***********************************************************************/
6353 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
6354 to *Messages*. */
6356 void
6357 add_to_log (format, arg1, arg2)
6358 char *format;
6359 Lisp_Object arg1, arg2;
6361 Lisp_Object args[3];
6362 Lisp_Object msg, fmt;
6363 char *buffer;
6364 int len;
6365 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
6366 USE_SAFE_ALLOCA;
6368 /* Do nothing if called asynchronously. Inserting text into
6369 a buffer may call after-change-functions and alike and
6370 that would means running Lisp asynchronously. */
6371 if (handling_signal)
6372 return;
6374 fmt = msg = Qnil;
6375 GCPRO4 (fmt, msg, arg1, arg2);
6377 args[0] = fmt = build_string (format);
6378 args[1] = arg1;
6379 args[2] = arg2;
6380 msg = Fformat (3, args);
6382 len = SBYTES (msg) + 1;
6383 SAFE_ALLOCA (buffer, char *, len);
6384 bcopy (SDATA (msg), buffer, len);
6386 message_dolog (buffer, len - 1, 1, 0);
6387 SAFE_FREE ();
6389 UNGCPRO;
6393 /* Output a newline in the *Messages* buffer if "needs" one. */
6395 void
6396 message_log_maybe_newline ()
6398 if (message_log_need_newline)
6399 message_dolog ("", 0, 1, 0);
6403 /* Add a string M of length NBYTES to the message log, optionally
6404 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
6405 nonzero, means interpret the contents of M as multibyte. This
6406 function calls low-level routines in order to bypass text property
6407 hooks, etc. which might not be safe to run. */
6409 void
6410 message_dolog (m, nbytes, nlflag, multibyte)
6411 const char *m;
6412 int nbytes, nlflag, multibyte;
6414 if (!NILP (Vmemory_full))
6415 return;
6417 if (!NILP (Vmessage_log_max))
6419 struct buffer *oldbuf;
6420 Lisp_Object oldpoint, oldbegv, oldzv;
6421 int old_windows_or_buffers_changed = windows_or_buffers_changed;
6422 int point_at_end = 0;
6423 int zv_at_end = 0;
6424 Lisp_Object old_deactivate_mark, tem;
6425 struct gcpro gcpro1;
6427 old_deactivate_mark = Vdeactivate_mark;
6428 oldbuf = current_buffer;
6429 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
6430 current_buffer->undo_list = Qt;
6432 oldpoint = message_dolog_marker1;
6433 set_marker_restricted (oldpoint, make_number (PT), Qnil);
6434 oldbegv = message_dolog_marker2;
6435 set_marker_restricted (oldbegv, make_number (BEGV), Qnil);
6436 oldzv = message_dolog_marker3;
6437 set_marker_restricted (oldzv, make_number (ZV), Qnil);
6438 GCPRO1 (old_deactivate_mark);
6440 if (PT == Z)
6441 point_at_end = 1;
6442 if (ZV == Z)
6443 zv_at_end = 1;
6445 BEGV = BEG;
6446 BEGV_BYTE = BEG_BYTE;
6447 ZV = Z;
6448 ZV_BYTE = Z_BYTE;
6449 TEMP_SET_PT_BOTH (Z, Z_BYTE);
6451 /* Insert the string--maybe converting multibyte to single byte
6452 or vice versa, so that all the text fits the buffer. */
6453 if (multibyte
6454 && NILP (current_buffer->enable_multibyte_characters))
6456 int i, c, char_bytes;
6457 unsigned char work[1];
6459 /* Convert a multibyte string to single-byte
6460 for the *Message* buffer. */
6461 for (i = 0; i < nbytes; i += char_bytes)
6463 c = string_char_and_length (m + i, nbytes - i, &char_bytes);
6464 work[0] = (SINGLE_BYTE_CHAR_P (c)
6466 : multibyte_char_to_unibyte (c, Qnil));
6467 insert_1_both (work, 1, 1, 1, 0, 0);
6470 else if (! multibyte
6471 && ! NILP (current_buffer->enable_multibyte_characters))
6473 int i, c, char_bytes;
6474 unsigned char *msg = (unsigned char *) m;
6475 unsigned char str[MAX_MULTIBYTE_LENGTH];
6476 /* Convert a single-byte string to multibyte
6477 for the *Message* buffer. */
6478 for (i = 0; i < nbytes; i++)
6480 c = unibyte_char_to_multibyte (msg[i]);
6481 char_bytes = CHAR_STRING (c, str);
6482 insert_1_both (str, 1, char_bytes, 1, 0, 0);
6485 else if (nbytes)
6486 insert_1 (m, nbytes, 1, 0, 0);
6488 if (nlflag)
6490 int this_bol, this_bol_byte, prev_bol, prev_bol_byte, dup;
6491 insert_1 ("\n", 1, 1, 0, 0);
6493 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
6494 this_bol = PT;
6495 this_bol_byte = PT_BYTE;
6497 /* See if this line duplicates the previous one.
6498 If so, combine duplicates. */
6499 if (this_bol > BEG)
6501 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
6502 prev_bol = PT;
6503 prev_bol_byte = PT_BYTE;
6505 dup = message_log_check_duplicate (prev_bol, prev_bol_byte,
6506 this_bol, this_bol_byte);
6507 if (dup)
6509 del_range_both (prev_bol, prev_bol_byte,
6510 this_bol, this_bol_byte, 0);
6511 if (dup > 1)
6513 char dupstr[40];
6514 int duplen;
6516 /* If you change this format, don't forget to also
6517 change message_log_check_duplicate. */
6518 sprintf (dupstr, " [%d times]", dup);
6519 duplen = strlen (dupstr);
6520 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
6521 insert_1 (dupstr, duplen, 1, 0, 1);
6526 /* If we have more than the desired maximum number of lines
6527 in the *Messages* buffer now, delete the oldest ones.
6528 This is safe because we don't have undo in this buffer. */
6530 if (NATNUMP (Vmessage_log_max))
6532 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
6533 -XFASTINT (Vmessage_log_max) - 1, 0);
6534 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
6537 BEGV = XMARKER (oldbegv)->charpos;
6538 BEGV_BYTE = marker_byte_position (oldbegv);
6540 if (zv_at_end)
6542 ZV = Z;
6543 ZV_BYTE = Z_BYTE;
6545 else
6547 ZV = XMARKER (oldzv)->charpos;
6548 ZV_BYTE = marker_byte_position (oldzv);
6551 if (point_at_end)
6552 TEMP_SET_PT_BOTH (Z, Z_BYTE);
6553 else
6554 /* We can't do Fgoto_char (oldpoint) because it will run some
6555 Lisp code. */
6556 TEMP_SET_PT_BOTH (XMARKER (oldpoint)->charpos,
6557 XMARKER (oldpoint)->bytepos);
6559 UNGCPRO;
6560 unchain_marker (XMARKER (oldpoint));
6561 unchain_marker (XMARKER (oldbegv));
6562 unchain_marker (XMARKER (oldzv));
6564 tem = Fget_buffer_window (Fcurrent_buffer (), Qt);
6565 set_buffer_internal (oldbuf);
6566 if (NILP (tem))
6567 windows_or_buffers_changed = old_windows_or_buffers_changed;
6568 message_log_need_newline = !nlflag;
6569 Vdeactivate_mark = old_deactivate_mark;
6574 /* We are at the end of the buffer after just having inserted a newline.
6575 (Note: We depend on the fact we won't be crossing the gap.)
6576 Check to see if the most recent message looks a lot like the previous one.
6577 Return 0 if different, 1 if the new one should just replace it, or a
6578 value N > 1 if we should also append " [N times]". */
6580 static int
6581 message_log_check_duplicate (prev_bol, prev_bol_byte, this_bol, this_bol_byte)
6582 int prev_bol, this_bol;
6583 int prev_bol_byte, this_bol_byte;
6585 int i;
6586 int len = Z_BYTE - 1 - this_bol_byte;
6587 int seen_dots = 0;
6588 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
6589 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
6591 for (i = 0; i < len; i++)
6593 if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.')
6594 seen_dots = 1;
6595 if (p1[i] != p2[i])
6596 return seen_dots;
6598 p1 += len;
6599 if (*p1 == '\n')
6600 return 2;
6601 if (*p1++ == ' ' && *p1++ == '[')
6603 int n = 0;
6604 while (*p1 >= '0' && *p1 <= '9')
6605 n = n * 10 + *p1++ - '0';
6606 if (strncmp (p1, " times]\n", 8) == 0)
6607 return n+1;
6609 return 0;
6613 /* Display an echo area message M with a specified length of NBYTES
6614 bytes. The string may include null characters. If M is 0, clear
6615 out any existing message, and let the mini-buffer text show
6616 through.
6618 The buffer M must continue to exist until after the echo area gets
6619 cleared or some other message gets displayed there. This means do
6620 not pass text that is stored in a Lisp string; do not pass text in
6621 a buffer that was alloca'd. */
6623 void
6624 message2 (m, nbytes, multibyte)
6625 const char *m;
6626 int nbytes;
6627 int multibyte;
6629 /* First flush out any partial line written with print. */
6630 message_log_maybe_newline ();
6631 if (m)
6632 message_dolog (m, nbytes, 1, multibyte);
6633 message2_nolog (m, nbytes, multibyte);
6637 /* The non-logging counterpart of message2. */
6639 void
6640 message2_nolog (m, nbytes, multibyte)
6641 const char *m;
6642 int nbytes, multibyte;
6644 struct frame *sf = SELECTED_FRAME ();
6645 message_enable_multibyte = multibyte;
6647 if (noninteractive)
6649 if (noninteractive_need_newline)
6650 putc ('\n', stderr);
6651 noninteractive_need_newline = 0;
6652 if (m)
6653 fwrite (m, nbytes, 1, stderr);
6654 if (cursor_in_echo_area == 0)
6655 fprintf (stderr, "\n");
6656 fflush (stderr);
6658 /* A null message buffer means that the frame hasn't really been
6659 initialized yet. Error messages get reported properly by
6660 cmd_error, so this must be just an informative message; toss it. */
6661 else if (INTERACTIVE
6662 && sf->glyphs_initialized_p
6663 && FRAME_MESSAGE_BUF (sf))
6665 Lisp_Object mini_window;
6666 struct frame *f;
6668 /* Get the frame containing the mini-buffer
6669 that the selected frame is using. */
6670 mini_window = FRAME_MINIBUF_WINDOW (sf);
6671 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6673 FRAME_SAMPLE_VISIBILITY (f);
6674 if (FRAME_VISIBLE_P (sf)
6675 && ! FRAME_VISIBLE_P (f))
6676 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
6678 if (m)
6680 set_message (m, Qnil, nbytes, multibyte);
6681 if (minibuffer_auto_raise)
6682 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
6684 else
6685 clear_message (1, 1);
6687 do_pending_window_change (0);
6688 echo_area_display (1);
6689 do_pending_window_change (0);
6690 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
6691 (*frame_up_to_date_hook) (f);
6696 /* Display an echo area message M with a specified length of NBYTES
6697 bytes. The string may include null characters. If M is not a
6698 string, clear out any existing message, and let the mini-buffer
6699 text show through. */
6701 void
6702 message3 (m, nbytes, multibyte)
6703 Lisp_Object m;
6704 int nbytes;
6705 int multibyte;
6707 struct gcpro gcpro1;
6709 GCPRO1 (m);
6710 clear_message (1,1);
6712 /* First flush out any partial line written with print. */
6713 message_log_maybe_newline ();
6714 if (STRINGP (m))
6715 message_dolog (SDATA (m), nbytes, 1, multibyte);
6716 message3_nolog (m, nbytes, multibyte);
6718 UNGCPRO;
6722 /* The non-logging version of message3. */
6724 void
6725 message3_nolog (m, nbytes, multibyte)
6726 Lisp_Object m;
6727 int nbytes, multibyte;
6729 struct frame *sf = SELECTED_FRAME ();
6730 message_enable_multibyte = multibyte;
6732 if (noninteractive)
6734 if (noninteractive_need_newline)
6735 putc ('\n', stderr);
6736 noninteractive_need_newline = 0;
6737 if (STRINGP (m))
6738 fwrite (SDATA (m), nbytes, 1, stderr);
6739 if (cursor_in_echo_area == 0)
6740 fprintf (stderr, "\n");
6741 fflush (stderr);
6743 /* A null message buffer means that the frame hasn't really been
6744 initialized yet. Error messages get reported properly by
6745 cmd_error, so this must be just an informative message; toss it. */
6746 else if (INTERACTIVE
6747 && sf->glyphs_initialized_p
6748 && FRAME_MESSAGE_BUF (sf))
6750 Lisp_Object mini_window;
6751 Lisp_Object frame;
6752 struct frame *f;
6754 /* Get the frame containing the mini-buffer
6755 that the selected frame is using. */
6756 mini_window = FRAME_MINIBUF_WINDOW (sf);
6757 frame = XWINDOW (mini_window)->frame;
6758 f = XFRAME (frame);
6760 FRAME_SAMPLE_VISIBILITY (f);
6761 if (FRAME_VISIBLE_P (sf)
6762 && !FRAME_VISIBLE_P (f))
6763 Fmake_frame_visible (frame);
6765 if (STRINGP (m) && SCHARS (m) > 0)
6767 set_message (NULL, m, nbytes, multibyte);
6768 if (minibuffer_auto_raise)
6769 Fraise_frame (frame);
6771 else
6772 clear_message (1, 1);
6774 do_pending_window_change (0);
6775 echo_area_display (1);
6776 do_pending_window_change (0);
6777 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
6778 (*frame_up_to_date_hook) (f);
6783 /* Display a null-terminated echo area message M. If M is 0, clear
6784 out any existing message, and let the mini-buffer text show through.
6786 The buffer M must continue to exist until after the echo area gets
6787 cleared or some other message gets displayed there. Do not pass
6788 text that is stored in a Lisp string. Do not pass text in a buffer
6789 that was alloca'd. */
6791 void
6792 message1 (m)
6793 char *m;
6795 message2 (m, (m ? strlen (m) : 0), 0);
6799 /* The non-logging counterpart of message1. */
6801 void
6802 message1_nolog (m)
6803 char *m;
6805 message2_nolog (m, (m ? strlen (m) : 0), 0);
6808 /* Display a message M which contains a single %s
6809 which gets replaced with STRING. */
6811 void
6812 message_with_string (m, string, log)
6813 char *m;
6814 Lisp_Object string;
6815 int log;
6817 CHECK_STRING (string);
6819 if (noninteractive)
6821 if (m)
6823 if (noninteractive_need_newline)
6824 putc ('\n', stderr);
6825 noninteractive_need_newline = 0;
6826 fprintf (stderr, m, SDATA (string));
6827 if (cursor_in_echo_area == 0)
6828 fprintf (stderr, "\n");
6829 fflush (stderr);
6832 else if (INTERACTIVE)
6834 /* The frame whose minibuffer we're going to display the message on.
6835 It may be larger than the selected frame, so we need
6836 to use its buffer, not the selected frame's buffer. */
6837 Lisp_Object mini_window;
6838 struct frame *f, *sf = SELECTED_FRAME ();
6840 /* Get the frame containing the minibuffer
6841 that the selected frame is using. */
6842 mini_window = FRAME_MINIBUF_WINDOW (sf);
6843 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6845 /* A null message buffer means that the frame hasn't really been
6846 initialized yet. Error messages get reported properly by
6847 cmd_error, so this must be just an informative message; toss it. */
6848 if (FRAME_MESSAGE_BUF (f))
6850 Lisp_Object args[2], message;
6851 struct gcpro gcpro1, gcpro2;
6853 args[0] = build_string (m);
6854 args[1] = message = string;
6855 GCPRO2 (args[0], message);
6856 gcpro1.nvars = 2;
6858 message = Fformat (2, args);
6860 if (log)
6861 message3 (message, SBYTES (message), STRING_MULTIBYTE (message));
6862 else
6863 message3_nolog (message, SBYTES (message), STRING_MULTIBYTE (message));
6865 UNGCPRO;
6867 /* Print should start at the beginning of the message
6868 buffer next time. */
6869 message_buf_print = 0;
6875 /* Dump an informative message to the minibuf. If M is 0, clear out
6876 any existing message, and let the mini-buffer text show through. */
6878 /* VARARGS 1 */
6879 void
6880 message (m, a1, a2, a3)
6881 char *m;
6882 EMACS_INT a1, a2, a3;
6884 if (noninteractive)
6886 if (m)
6888 if (noninteractive_need_newline)
6889 putc ('\n', stderr);
6890 noninteractive_need_newline = 0;
6891 fprintf (stderr, m, a1, a2, a3);
6892 if (cursor_in_echo_area == 0)
6893 fprintf (stderr, "\n");
6894 fflush (stderr);
6897 else if (INTERACTIVE)
6899 /* The frame whose mini-buffer we're going to display the message
6900 on. It may be larger than the selected frame, so we need to
6901 use its buffer, not the selected frame's buffer. */
6902 Lisp_Object mini_window;
6903 struct frame *f, *sf = SELECTED_FRAME ();
6905 /* Get the frame containing the mini-buffer
6906 that the selected frame is using. */
6907 mini_window = FRAME_MINIBUF_WINDOW (sf);
6908 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6910 /* A null message buffer means that the frame hasn't really been
6911 initialized yet. Error messages get reported properly by
6912 cmd_error, so this must be just an informative message; toss
6913 it. */
6914 if (FRAME_MESSAGE_BUF (f))
6916 if (m)
6918 int len;
6919 #ifdef NO_ARG_ARRAY
6920 char *a[3];
6921 a[0] = (char *) a1;
6922 a[1] = (char *) a2;
6923 a[2] = (char *) a3;
6925 len = doprnt (FRAME_MESSAGE_BUF (f),
6926 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
6927 #else
6928 len = doprnt (FRAME_MESSAGE_BUF (f),
6929 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3,
6930 (char **) &a1);
6931 #endif /* NO_ARG_ARRAY */
6933 message2 (FRAME_MESSAGE_BUF (f), len, 0);
6935 else
6936 message1 (0);
6938 /* Print should start at the beginning of the message
6939 buffer next time. */
6940 message_buf_print = 0;
6946 /* The non-logging version of message. */
6948 void
6949 message_nolog (m, a1, a2, a3)
6950 char *m;
6951 EMACS_INT a1, a2, a3;
6953 Lisp_Object old_log_max;
6954 old_log_max = Vmessage_log_max;
6955 Vmessage_log_max = Qnil;
6956 message (m, a1, a2, a3);
6957 Vmessage_log_max = old_log_max;
6961 /* Display the current message in the current mini-buffer. This is
6962 only called from error handlers in process.c, and is not time
6963 critical. */
6965 void
6966 update_echo_area ()
6968 if (!NILP (echo_area_buffer[0]))
6970 Lisp_Object string;
6971 string = Fcurrent_message ();
6972 message3 (string, SBYTES (string),
6973 !NILP (current_buffer->enable_multibyte_characters));
6978 /* Make sure echo area buffers in `echo_buffers' are live.
6979 If they aren't, make new ones. */
6981 static void
6982 ensure_echo_area_buffers ()
6984 int i;
6986 for (i = 0; i < 2; ++i)
6987 if (!BUFFERP (echo_buffer[i])
6988 || NILP (XBUFFER (echo_buffer[i])->name))
6990 char name[30];
6991 Lisp_Object old_buffer;
6992 int j;
6994 old_buffer = echo_buffer[i];
6995 sprintf (name, " *Echo Area %d*", i);
6996 echo_buffer[i] = Fget_buffer_create (build_string (name));
6997 XBUFFER (echo_buffer[i])->truncate_lines = Qnil;
6999 for (j = 0; j < 2; ++j)
7000 if (EQ (old_buffer, echo_area_buffer[j]))
7001 echo_area_buffer[j] = echo_buffer[i];
7006 /* Call FN with args A1..A4 with either the current or last displayed
7007 echo_area_buffer as current buffer.
7009 WHICH zero means use the current message buffer
7010 echo_area_buffer[0]. If that is nil, choose a suitable buffer
7011 from echo_buffer[] and clear it.
7013 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
7014 suitable buffer from echo_buffer[] and clear it.
7016 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
7017 that the current message becomes the last displayed one, make
7018 choose a suitable buffer for echo_area_buffer[0], and clear it.
7020 Value is what FN returns. */
7022 static int
7023 with_echo_area_buffer (w, which, fn, a1, a2, a3, a4)
7024 struct window *w;
7025 int which;
7026 int (*fn) P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
7027 EMACS_INT a1;
7028 Lisp_Object a2;
7029 EMACS_INT a3, a4;
7031 Lisp_Object buffer;
7032 int this_one, the_other, clear_buffer_p, rc;
7033 int count = SPECPDL_INDEX ();
7035 /* If buffers aren't live, make new ones. */
7036 ensure_echo_area_buffers ();
7038 clear_buffer_p = 0;
7040 if (which == 0)
7041 this_one = 0, the_other = 1;
7042 else if (which > 0)
7043 this_one = 1, the_other = 0;
7044 else
7046 this_one = 0, the_other = 1;
7047 clear_buffer_p = 1;
7049 /* We need a fresh one in case the current echo buffer equals
7050 the one containing the last displayed echo area message. */
7051 if (!NILP (echo_area_buffer[this_one])
7052 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
7053 echo_area_buffer[this_one] = Qnil;
7056 /* Choose a suitable buffer from echo_buffer[] is we don't
7057 have one. */
7058 if (NILP (echo_area_buffer[this_one]))
7060 echo_area_buffer[this_one]
7061 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
7062 ? echo_buffer[the_other]
7063 : echo_buffer[this_one]);
7064 clear_buffer_p = 1;
7067 buffer = echo_area_buffer[this_one];
7069 /* Don't get confused by reusing the buffer used for echoing
7070 for a different purpose. */
7071 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
7072 cancel_echoing ();
7074 record_unwind_protect (unwind_with_echo_area_buffer,
7075 with_echo_area_buffer_unwind_data (w));
7077 /* Make the echo area buffer current. Note that for display
7078 purposes, it is not necessary that the displayed window's buffer
7079 == current_buffer, except for text property lookup. So, let's
7080 only set that buffer temporarily here without doing a full
7081 Fset_window_buffer. We must also change w->pointm, though,
7082 because otherwise an assertions in unshow_buffer fails, and Emacs
7083 aborts. */
7084 set_buffer_internal_1 (XBUFFER (buffer));
7085 if (w)
7087 w->buffer = buffer;
7088 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
7091 current_buffer->undo_list = Qt;
7092 current_buffer->read_only = Qnil;
7093 specbind (Qinhibit_read_only, Qt);
7094 specbind (Qinhibit_modification_hooks, Qt);
7096 if (clear_buffer_p && Z > BEG)
7097 del_range (BEG, Z);
7099 xassert (BEGV >= BEG);
7100 xassert (ZV <= Z && ZV >= BEGV);
7102 rc = fn (a1, a2, a3, a4);
7104 xassert (BEGV >= BEG);
7105 xassert (ZV <= Z && ZV >= BEGV);
7107 unbind_to (count, Qnil);
7108 return rc;
7112 /* Save state that should be preserved around the call to the function
7113 FN called in with_echo_area_buffer. */
7115 static Lisp_Object
7116 with_echo_area_buffer_unwind_data (w)
7117 struct window *w;
7119 int i = 0;
7120 Lisp_Object vector;
7122 /* Reduce consing by keeping one vector in
7123 Vwith_echo_area_save_vector. */
7124 vector = Vwith_echo_area_save_vector;
7125 Vwith_echo_area_save_vector = Qnil;
7127 if (NILP (vector))
7128 vector = Fmake_vector (make_number (7), Qnil);
7130 XSETBUFFER (AREF (vector, i), current_buffer); ++i;
7131 AREF (vector, i) = Vdeactivate_mark, ++i;
7132 AREF (vector, i) = make_number (windows_or_buffers_changed), ++i;
7134 if (w)
7136 XSETWINDOW (AREF (vector, i), w); ++i;
7137 AREF (vector, i) = w->buffer; ++i;
7138 AREF (vector, i) = make_number (XMARKER (w->pointm)->charpos); ++i;
7139 AREF (vector, i) = make_number (XMARKER (w->pointm)->bytepos); ++i;
7141 else
7143 int end = i + 4;
7144 for (; i < end; ++i)
7145 AREF (vector, i) = Qnil;
7148 xassert (i == ASIZE (vector));
7149 return vector;
7153 /* Restore global state from VECTOR which was created by
7154 with_echo_area_buffer_unwind_data. */
7156 static Lisp_Object
7157 unwind_with_echo_area_buffer (vector)
7158 Lisp_Object vector;
7160 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
7161 Vdeactivate_mark = AREF (vector, 1);
7162 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
7164 if (WINDOWP (AREF (vector, 3)))
7166 struct window *w;
7167 Lisp_Object buffer, charpos, bytepos;
7169 w = XWINDOW (AREF (vector, 3));
7170 buffer = AREF (vector, 4);
7171 charpos = AREF (vector, 5);
7172 bytepos = AREF (vector, 6);
7174 w->buffer = buffer;
7175 set_marker_both (w->pointm, buffer,
7176 XFASTINT (charpos), XFASTINT (bytepos));
7179 Vwith_echo_area_save_vector = vector;
7180 return Qnil;
7184 /* Set up the echo area for use by print functions. MULTIBYTE_P
7185 non-zero means we will print multibyte. */
7187 void
7188 setup_echo_area_for_printing (multibyte_p)
7189 int multibyte_p;
7191 /* If we can't find an echo area any more, exit. */
7192 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
7193 Fkill_emacs (Qnil);
7195 ensure_echo_area_buffers ();
7197 if (!message_buf_print)
7199 /* A message has been output since the last time we printed.
7200 Choose a fresh echo area buffer. */
7201 if (EQ (echo_area_buffer[1], echo_buffer[0]))
7202 echo_area_buffer[0] = echo_buffer[1];
7203 else
7204 echo_area_buffer[0] = echo_buffer[0];
7206 /* Switch to that buffer and clear it. */
7207 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
7208 current_buffer->truncate_lines = Qnil;
7210 if (Z > BEG)
7212 int count = SPECPDL_INDEX ();
7213 specbind (Qinhibit_read_only, Qt);
7214 /* Note that undo recording is always disabled. */
7215 del_range (BEG, Z);
7216 unbind_to (count, Qnil);
7218 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
7220 /* Set up the buffer for the multibyteness we need. */
7221 if (multibyte_p
7222 != !NILP (current_buffer->enable_multibyte_characters))
7223 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
7225 /* Raise the frame containing the echo area. */
7226 if (minibuffer_auto_raise)
7228 struct frame *sf = SELECTED_FRAME ();
7229 Lisp_Object mini_window;
7230 mini_window = FRAME_MINIBUF_WINDOW (sf);
7231 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
7234 message_log_maybe_newline ();
7235 message_buf_print = 1;
7237 else
7239 if (NILP (echo_area_buffer[0]))
7241 if (EQ (echo_area_buffer[1], echo_buffer[0]))
7242 echo_area_buffer[0] = echo_buffer[1];
7243 else
7244 echo_area_buffer[0] = echo_buffer[0];
7247 if (current_buffer != XBUFFER (echo_area_buffer[0]))
7249 /* Someone switched buffers between print requests. */
7250 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
7251 current_buffer->truncate_lines = Qnil;
7257 /* Display an echo area message in window W. Value is non-zero if W's
7258 height is changed. If display_last_displayed_message_p is
7259 non-zero, display the message that was last displayed, otherwise
7260 display the current message. */
7262 static int
7263 display_echo_area (w)
7264 struct window *w;
7266 int i, no_message_p, window_height_changed_p, count;
7268 /* Temporarily disable garbage collections while displaying the echo
7269 area. This is done because a GC can print a message itself.
7270 That message would modify the echo area buffer's contents while a
7271 redisplay of the buffer is going on, and seriously confuse
7272 redisplay. */
7273 count = inhibit_garbage_collection ();
7275 /* If there is no message, we must call display_echo_area_1
7276 nevertheless because it resizes the window. But we will have to
7277 reset the echo_area_buffer in question to nil at the end because
7278 with_echo_area_buffer will sets it to an empty buffer. */
7279 i = display_last_displayed_message_p ? 1 : 0;
7280 no_message_p = NILP (echo_area_buffer[i]);
7282 window_height_changed_p
7283 = with_echo_area_buffer (w, display_last_displayed_message_p,
7284 display_echo_area_1,
7285 (EMACS_INT) w, Qnil, 0, 0);
7287 if (no_message_p)
7288 echo_area_buffer[i] = Qnil;
7290 unbind_to (count, Qnil);
7291 return window_height_changed_p;
7295 /* Helper for display_echo_area. Display the current buffer which
7296 contains the current echo area message in window W, a mini-window,
7297 a pointer to which is passed in A1. A2..A4 are currently not used.
7298 Change the height of W so that all of the message is displayed.
7299 Value is non-zero if height of W was changed. */
7301 static int
7302 display_echo_area_1 (a1, a2, a3, a4)
7303 EMACS_INT a1;
7304 Lisp_Object a2;
7305 EMACS_INT a3, a4;
7307 struct window *w = (struct window *) a1;
7308 Lisp_Object window;
7309 struct text_pos start;
7310 int window_height_changed_p = 0;
7312 /* Do this before displaying, so that we have a large enough glyph
7313 matrix for the display. */
7314 window_height_changed_p = resize_mini_window (w, 0);
7316 /* Display. */
7317 clear_glyph_matrix (w->desired_matrix);
7318 XSETWINDOW (window, w);
7319 SET_TEXT_POS (start, BEG, BEG_BYTE);
7320 try_window (window, start);
7322 return window_height_changed_p;
7326 /* Resize the echo area window to exactly the size needed for the
7327 currently displayed message, if there is one. If a mini-buffer
7328 is active, don't shrink it. */
7330 void
7331 resize_echo_area_exactly ()
7333 if (BUFFERP (echo_area_buffer[0])
7334 && WINDOWP (echo_area_window))
7336 struct window *w = XWINDOW (echo_area_window);
7337 int resized_p;
7338 Lisp_Object resize_exactly;
7340 if (minibuf_level == 0)
7341 resize_exactly = Qt;
7342 else
7343 resize_exactly = Qnil;
7345 resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
7346 (EMACS_INT) w, resize_exactly, 0, 0);
7347 if (resized_p)
7349 ++windows_or_buffers_changed;
7350 ++update_mode_lines;
7351 redisplay_internal (0);
7357 /* Callback function for with_echo_area_buffer, when used from
7358 resize_echo_area_exactly. A1 contains a pointer to the window to
7359 resize, EXACTLY non-nil means resize the mini-window exactly to the
7360 size of the text displayed. A3 and A4 are not used. Value is what
7361 resize_mini_window returns. */
7363 static int
7364 resize_mini_window_1 (a1, exactly, a3, a4)
7365 EMACS_INT a1;
7366 Lisp_Object exactly;
7367 EMACS_INT a3, a4;
7369 return resize_mini_window ((struct window *) a1, !NILP (exactly));
7373 /* Resize mini-window W to fit the size of its contents. EXACT:P
7374 means size the window exactly to the size needed. Otherwise, it's
7375 only enlarged until W's buffer is empty. Value is non-zero if
7376 the window height has been changed. */
7379 resize_mini_window (w, exact_p)
7380 struct window *w;
7381 int exact_p;
7383 struct frame *f = XFRAME (w->frame);
7384 int window_height_changed_p = 0;
7386 xassert (MINI_WINDOW_P (w));
7388 /* Don't resize windows while redisplaying a window; it would
7389 confuse redisplay functions when the size of the window they are
7390 displaying changes from under them. Such a resizing can happen,
7391 for instance, when which-func prints a long message while
7392 we are running fontification-functions. We're running these
7393 functions with safe_call which binds inhibit-redisplay to t. */
7394 if (!NILP (Vinhibit_redisplay))
7395 return 0;
7397 /* Nil means don't try to resize. */
7398 if (NILP (Vresize_mini_windows)
7399 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
7400 return 0;
7402 if (!FRAME_MINIBUF_ONLY_P (f))
7404 struct it it;
7405 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
7406 int total_height = WINDOW_TOTAL_LINES (root) + WINDOW_TOTAL_LINES (w);
7407 int height, max_height;
7408 int unit = FRAME_LINE_HEIGHT (f);
7409 struct text_pos start;
7410 struct buffer *old_current_buffer = NULL;
7412 if (current_buffer != XBUFFER (w->buffer))
7414 old_current_buffer = current_buffer;
7415 set_buffer_internal (XBUFFER (w->buffer));
7418 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
7420 /* Compute the max. number of lines specified by the user. */
7421 if (FLOATP (Vmax_mini_window_height))
7422 max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_LINES (f);
7423 else if (INTEGERP (Vmax_mini_window_height))
7424 max_height = XINT (Vmax_mini_window_height);
7425 else
7426 max_height = total_height / 4;
7428 /* Correct that max. height if it's bogus. */
7429 max_height = max (1, max_height);
7430 max_height = min (total_height, max_height);
7432 /* Find out the height of the text in the window. */
7433 if (it.truncate_lines_p)
7434 height = 1;
7435 else
7437 last_height = 0;
7438 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
7439 if (it.max_ascent == 0 && it.max_descent == 0)
7440 height = it.current_y + last_height;
7441 else
7442 height = it.current_y + it.max_ascent + it.max_descent;
7443 height -= min (it.extra_line_spacing, it.max_extra_line_spacing);
7444 height = (height + unit - 1) / unit;
7447 /* Compute a suitable window start. */
7448 if (height > max_height)
7450 height = max_height;
7451 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
7452 move_it_vertically_backward (&it, (height - 1) * unit);
7453 start = it.current.pos;
7455 else
7456 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
7457 SET_MARKER_FROM_TEXT_POS (w->start, start);
7459 if (EQ (Vresize_mini_windows, Qgrow_only))
7461 /* Let it grow only, until we display an empty message, in which
7462 case the window shrinks again. */
7463 if (height > WINDOW_TOTAL_LINES (w))
7465 int old_height = WINDOW_TOTAL_LINES (w);
7466 freeze_window_starts (f, 1);
7467 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7468 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7470 else if (height < WINDOW_TOTAL_LINES (w)
7471 && (exact_p || BEGV == ZV))
7473 int old_height = WINDOW_TOTAL_LINES (w);
7474 freeze_window_starts (f, 0);
7475 shrink_mini_window (w);
7476 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7479 else
7481 /* Always resize to exact size needed. */
7482 if (height > WINDOW_TOTAL_LINES (w))
7484 int old_height = WINDOW_TOTAL_LINES (w);
7485 freeze_window_starts (f, 1);
7486 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7487 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7489 else if (height < WINDOW_TOTAL_LINES (w))
7491 int old_height = WINDOW_TOTAL_LINES (w);
7492 freeze_window_starts (f, 0);
7493 shrink_mini_window (w);
7495 if (height)
7497 freeze_window_starts (f, 1);
7498 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7501 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7505 if (old_current_buffer)
7506 set_buffer_internal (old_current_buffer);
7509 return window_height_changed_p;
7513 /* Value is the current message, a string, or nil if there is no
7514 current message. */
7516 Lisp_Object
7517 current_message ()
7519 Lisp_Object msg;
7521 if (NILP (echo_area_buffer[0]))
7522 msg = Qnil;
7523 else
7525 with_echo_area_buffer (0, 0, current_message_1,
7526 (EMACS_INT) &msg, Qnil, 0, 0);
7527 if (NILP (msg))
7528 echo_area_buffer[0] = Qnil;
7531 return msg;
7535 static int
7536 current_message_1 (a1, a2, a3, a4)
7537 EMACS_INT a1;
7538 Lisp_Object a2;
7539 EMACS_INT a3, a4;
7541 Lisp_Object *msg = (Lisp_Object *) a1;
7543 if (Z > BEG)
7544 *msg = make_buffer_string (BEG, Z, 1);
7545 else
7546 *msg = Qnil;
7547 return 0;
7551 /* Push the current message on Vmessage_stack for later restauration
7552 by restore_message. Value is non-zero if the current message isn't
7553 empty. This is a relatively infrequent operation, so it's not
7554 worth optimizing. */
7557 push_message ()
7559 Lisp_Object msg;
7560 msg = current_message ();
7561 Vmessage_stack = Fcons (msg, Vmessage_stack);
7562 return STRINGP (msg);
7566 /* Restore message display from the top of Vmessage_stack. */
7568 void
7569 restore_message ()
7571 Lisp_Object msg;
7573 xassert (CONSP (Vmessage_stack));
7574 msg = XCAR (Vmessage_stack);
7575 if (STRINGP (msg))
7576 message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
7577 else
7578 message3_nolog (msg, 0, 0);
7582 /* Handler for record_unwind_protect calling pop_message. */
7584 Lisp_Object
7585 pop_message_unwind (dummy)
7586 Lisp_Object dummy;
7588 pop_message ();
7589 return Qnil;
7592 /* Pop the top-most entry off Vmessage_stack. */
7594 void
7595 pop_message ()
7597 xassert (CONSP (Vmessage_stack));
7598 Vmessage_stack = XCDR (Vmessage_stack);
7602 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
7603 exits. If the stack is not empty, we have a missing pop_message
7604 somewhere. */
7606 void
7607 check_message_stack ()
7609 if (!NILP (Vmessage_stack))
7610 abort ();
7614 /* Truncate to NCHARS what will be displayed in the echo area the next
7615 time we display it---but don't redisplay it now. */
7617 void
7618 truncate_echo_area (nchars)
7619 int nchars;
7621 if (nchars == 0)
7622 echo_area_buffer[0] = Qnil;
7623 /* A null message buffer means that the frame hasn't really been
7624 initialized yet. Error messages get reported properly by
7625 cmd_error, so this must be just an informative message; toss it. */
7626 else if (!noninteractive
7627 && INTERACTIVE
7628 && !NILP (echo_area_buffer[0]))
7630 struct frame *sf = SELECTED_FRAME ();
7631 if (FRAME_MESSAGE_BUF (sf))
7632 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil, 0, 0);
7637 /* Helper function for truncate_echo_area. Truncate the current
7638 message to at most NCHARS characters. */
7640 static int
7641 truncate_message_1 (nchars, a2, a3, a4)
7642 EMACS_INT nchars;
7643 Lisp_Object a2;
7644 EMACS_INT a3, a4;
7646 if (BEG + nchars < Z)
7647 del_range (BEG + nchars, Z);
7648 if (Z == BEG)
7649 echo_area_buffer[0] = Qnil;
7650 return 0;
7654 /* Set the current message to a substring of S or STRING.
7656 If STRING is a Lisp string, set the message to the first NBYTES
7657 bytes from STRING. NBYTES zero means use the whole string. If
7658 STRING is multibyte, the message will be displayed multibyte.
7660 If S is not null, set the message to the first LEN bytes of S. LEN
7661 zero means use the whole string. MULTIBYTE_P non-zero means S is
7662 multibyte. Display the message multibyte in that case. */
7664 void
7665 set_message (s, string, nbytes, multibyte_p)
7666 const char *s;
7667 Lisp_Object string;
7668 int nbytes, multibyte_p;
7670 message_enable_multibyte
7671 = ((s && multibyte_p)
7672 || (STRINGP (string) && STRING_MULTIBYTE (string)));
7674 with_echo_area_buffer (0, -1, set_message_1,
7675 (EMACS_INT) s, string, nbytes, multibyte_p);
7676 message_buf_print = 0;
7677 help_echo_showing_p = 0;
7681 /* Helper function for set_message. Arguments have the same meaning
7682 as there, with A1 corresponding to S and A2 corresponding to STRING
7683 This function is called with the echo area buffer being
7684 current. */
7686 static int
7687 set_message_1 (a1, a2, nbytes, multibyte_p)
7688 EMACS_INT a1;
7689 Lisp_Object a2;
7690 EMACS_INT nbytes, multibyte_p;
7692 const char *s = (const char *) a1;
7693 Lisp_Object string = a2;
7695 xassert (BEG == Z);
7697 /* Change multibyteness of the echo buffer appropriately. */
7698 if (message_enable_multibyte
7699 != !NILP (current_buffer->enable_multibyte_characters))
7700 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
7702 current_buffer->truncate_lines = message_truncate_lines ? Qt : Qnil;
7704 /* Insert new message at BEG. */
7705 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
7707 if (STRINGP (string))
7709 int nchars;
7711 if (nbytes == 0)
7712 nbytes = SBYTES (string);
7713 nchars = string_byte_to_char (string, nbytes);
7715 /* This function takes care of single/multibyte conversion. We
7716 just have to ensure that the echo area buffer has the right
7717 setting of enable_multibyte_characters. */
7718 insert_from_string (string, 0, 0, nchars, nbytes, 1);
7720 else if (s)
7722 if (nbytes == 0)
7723 nbytes = strlen (s);
7725 if (multibyte_p && NILP (current_buffer->enable_multibyte_characters))
7727 /* Convert from multi-byte to single-byte. */
7728 int i, c, n;
7729 unsigned char work[1];
7731 /* Convert a multibyte string to single-byte. */
7732 for (i = 0; i < nbytes; i += n)
7734 c = string_char_and_length (s + i, nbytes - i, &n);
7735 work[0] = (SINGLE_BYTE_CHAR_P (c)
7737 : multibyte_char_to_unibyte (c, Qnil));
7738 insert_1_both (work, 1, 1, 1, 0, 0);
7741 else if (!multibyte_p
7742 && !NILP (current_buffer->enable_multibyte_characters))
7744 /* Convert from single-byte to multi-byte. */
7745 int i, c, n;
7746 const unsigned char *msg = (const unsigned char *) s;
7747 unsigned char str[MAX_MULTIBYTE_LENGTH];
7749 /* Convert a single-byte string to multibyte. */
7750 for (i = 0; i < nbytes; i++)
7752 c = unibyte_char_to_multibyte (msg[i]);
7753 n = CHAR_STRING (c, str);
7754 insert_1_both (str, 1, n, 1, 0, 0);
7757 else
7758 insert_1 (s, nbytes, 1, 0, 0);
7761 return 0;
7765 /* Clear messages. CURRENT_P non-zero means clear the current
7766 message. LAST_DISPLAYED_P non-zero means clear the message
7767 last displayed. */
7769 void
7770 clear_message (current_p, last_displayed_p)
7771 int current_p, last_displayed_p;
7773 if (current_p)
7775 echo_area_buffer[0] = Qnil;
7776 message_cleared_p = 1;
7779 if (last_displayed_p)
7780 echo_area_buffer[1] = Qnil;
7782 message_buf_print = 0;
7785 /* Clear garbaged frames.
7787 This function is used where the old redisplay called
7788 redraw_garbaged_frames which in turn called redraw_frame which in
7789 turn called clear_frame. The call to clear_frame was a source of
7790 flickering. I believe a clear_frame is not necessary. It should
7791 suffice in the new redisplay to invalidate all current matrices,
7792 and ensure a complete redisplay of all windows. */
7794 static void
7795 clear_garbaged_frames ()
7797 if (frame_garbaged)
7799 Lisp_Object tail, frame;
7800 int changed_count = 0;
7802 FOR_EACH_FRAME (tail, frame)
7804 struct frame *f = XFRAME (frame);
7806 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
7808 if (f->resized_p)
7810 Fredraw_frame (frame);
7811 f->force_flush_display_p = 1;
7813 clear_current_matrices (f);
7814 changed_count++;
7815 f->garbaged = 0;
7816 f->resized_p = 0;
7820 frame_garbaged = 0;
7821 if (changed_count)
7822 ++windows_or_buffers_changed;
7827 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
7828 is non-zero update selected_frame. Value is non-zero if the
7829 mini-windows height has been changed. */
7831 static int
7832 echo_area_display (update_frame_p)
7833 int update_frame_p;
7835 Lisp_Object mini_window;
7836 struct window *w;
7837 struct frame *f;
7838 int window_height_changed_p = 0;
7839 struct frame *sf = SELECTED_FRAME ();
7841 mini_window = FRAME_MINIBUF_WINDOW (sf);
7842 w = XWINDOW (mini_window);
7843 f = XFRAME (WINDOW_FRAME (w));
7845 /* Don't display if frame is invisible or not yet initialized. */
7846 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
7847 return 0;
7849 /* The terminal frame is used as the first Emacs frame on the Mac OS. */
7850 #ifndef MAC_OS8
7851 #ifdef HAVE_WINDOW_SYSTEM
7852 /* When Emacs starts, selected_frame may be a visible terminal
7853 frame, even if we run under a window system. If we let this
7854 through, a message would be displayed on the terminal. */
7855 if (EQ (selected_frame, Vterminal_frame)
7856 && !NILP (Vwindow_system))
7857 return 0;
7858 #endif /* HAVE_WINDOW_SYSTEM */
7859 #endif
7861 /* Redraw garbaged frames. */
7862 if (frame_garbaged)
7863 clear_garbaged_frames ();
7865 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
7867 echo_area_window = mini_window;
7868 window_height_changed_p = display_echo_area (w);
7869 w->must_be_updated_p = 1;
7871 /* Update the display, unless called from redisplay_internal.
7872 Also don't update the screen during redisplay itself. The
7873 update will happen at the end of redisplay, and an update
7874 here could cause confusion. */
7875 if (update_frame_p && !redisplaying_p)
7877 int n = 0;
7879 /* If the display update has been interrupted by pending
7880 input, update mode lines in the frame. Due to the
7881 pending input, it might have been that redisplay hasn't
7882 been called, so that mode lines above the echo area are
7883 garbaged. This looks odd, so we prevent it here. */
7884 if (!display_completed)
7885 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), 0);
7887 if (window_height_changed_p
7888 /* Don't do this if Emacs is shutting down. Redisplay
7889 needs to run hooks. */
7890 && !NILP (Vrun_hooks))
7892 /* Must update other windows. Likewise as in other
7893 cases, don't let this update be interrupted by
7894 pending input. */
7895 int count = SPECPDL_INDEX ();
7896 specbind (Qredisplay_dont_pause, Qt);
7897 windows_or_buffers_changed = 1;
7898 redisplay_internal (0);
7899 unbind_to (count, Qnil);
7901 else if (FRAME_WINDOW_P (f) && n == 0)
7903 /* Window configuration is the same as before.
7904 Can do with a display update of the echo area,
7905 unless we displayed some mode lines. */
7906 update_single_window (w, 1);
7907 rif->flush_display (f);
7909 else
7910 update_frame (f, 1, 1);
7912 /* If cursor is in the echo area, make sure that the next
7913 redisplay displays the minibuffer, so that the cursor will
7914 be replaced with what the minibuffer wants. */
7915 if (cursor_in_echo_area)
7916 ++windows_or_buffers_changed;
7919 else if (!EQ (mini_window, selected_window))
7920 windows_or_buffers_changed++;
7922 /* Last displayed message is now the current message. */
7923 echo_area_buffer[1] = echo_area_buffer[0];
7925 /* Prevent redisplay optimization in redisplay_internal by resetting
7926 this_line_start_pos. This is done because the mini-buffer now
7927 displays the message instead of its buffer text. */
7928 if (EQ (mini_window, selected_window))
7929 CHARPOS (this_line_start_pos) = 0;
7931 return window_height_changed_p;
7936 /***********************************************************************
7937 Frame Titles
7938 ***********************************************************************/
7941 /* The frame title buffering code is also used by Fformat_mode_line.
7942 So it is not conditioned by HAVE_WINDOW_SYSTEM. */
7944 /* A buffer for constructing frame titles in it; allocated from the
7945 heap in init_xdisp and resized as needed in store_frame_title_char. */
7947 static char *frame_title_buf;
7949 /* The buffer's end, and a current output position in it. */
7951 static char *frame_title_buf_end;
7952 static char *frame_title_ptr;
7955 /* Store a single character C for the frame title in frame_title_buf.
7956 Re-allocate frame_title_buf if necessary. */
7958 static void
7959 #ifdef PROTOTYPES
7960 store_frame_title_char (char c)
7961 #else
7962 store_frame_title_char (c)
7963 char c;
7964 #endif
7966 /* If output position has reached the end of the allocated buffer,
7967 double the buffer's size. */
7968 if (frame_title_ptr == frame_title_buf_end)
7970 int len = frame_title_ptr - frame_title_buf;
7971 int new_size = 2 * len * sizeof *frame_title_buf;
7972 frame_title_buf = (char *) xrealloc (frame_title_buf, new_size);
7973 frame_title_buf_end = frame_title_buf + new_size;
7974 frame_title_ptr = frame_title_buf + len;
7977 *frame_title_ptr++ = c;
7981 /* Store part of a frame title in frame_title_buf, beginning at
7982 frame_title_ptr. STR is the string to store. Do not copy
7983 characters that yield more columns than PRECISION; PRECISION <= 0
7984 means copy the whole string. Pad with spaces until FIELD_WIDTH
7985 number of characters have been copied; FIELD_WIDTH <= 0 means don't
7986 pad. Called from display_mode_element when it is used to build a
7987 frame title. */
7989 static int
7990 store_frame_title (str, field_width, precision)
7991 const unsigned char *str;
7992 int field_width, precision;
7994 int n = 0;
7995 int dummy, nbytes;
7997 /* Copy at most PRECISION chars from STR. */
7998 nbytes = strlen (str);
7999 n += c_string_width (str, nbytes, precision, &dummy, &nbytes);
8000 while (nbytes--)
8001 store_frame_title_char (*str++);
8003 /* Fill up with spaces until FIELD_WIDTH reached. */
8004 while (field_width > 0
8005 && n < field_width)
8007 store_frame_title_char (' ');
8008 ++n;
8011 return n;
8014 #ifdef HAVE_WINDOW_SYSTEM
8016 /* Set the title of FRAME, if it has changed. The title format is
8017 Vicon_title_format if FRAME is iconified, otherwise it is
8018 frame_title_format. */
8020 static void
8021 x_consider_frame_title (frame)
8022 Lisp_Object frame;
8024 struct frame *f = XFRAME (frame);
8026 if (FRAME_WINDOW_P (f)
8027 || FRAME_MINIBUF_ONLY_P (f)
8028 || f->explicit_name)
8030 /* Do we have more than one visible frame on this X display? */
8031 Lisp_Object tail;
8032 Lisp_Object fmt;
8033 struct buffer *obuf;
8034 int len;
8035 struct it it;
8037 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
8039 Lisp_Object other_frame = XCAR (tail);
8040 struct frame *tf = XFRAME (other_frame);
8042 if (tf != f
8043 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
8044 && !FRAME_MINIBUF_ONLY_P (tf)
8045 && !EQ (other_frame, tip_frame)
8046 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
8047 break;
8050 /* Set global variable indicating that multiple frames exist. */
8051 multiple_frames = CONSP (tail);
8053 /* Switch to the buffer of selected window of the frame. Set up
8054 frame_title_ptr so that display_mode_element will output into it;
8055 then display the title. */
8056 obuf = current_buffer;
8057 set_buffer_internal_1 (XBUFFER (XWINDOW (f->selected_window)->buffer));
8058 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
8059 frame_title_ptr = frame_title_buf;
8060 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
8061 NULL, DEFAULT_FACE_ID);
8062 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
8063 len = frame_title_ptr - frame_title_buf;
8064 frame_title_ptr = NULL;
8065 set_buffer_internal_1 (obuf);
8067 /* Set the title only if it's changed. This avoids consing in
8068 the common case where it hasn't. (If it turns out that we've
8069 already wasted too much time by walking through the list with
8070 display_mode_element, then we might need to optimize at a
8071 higher level than this.) */
8072 if (! STRINGP (f->name)
8073 || SBYTES (f->name) != len
8074 || bcmp (frame_title_buf, SDATA (f->name), len) != 0)
8075 x_implicitly_set_name (f, make_string (frame_title_buf, len), Qnil);
8079 #endif /* not HAVE_WINDOW_SYSTEM */
8084 /***********************************************************************
8085 Menu Bars
8086 ***********************************************************************/
8089 /* Prepare for redisplay by updating menu-bar item lists when
8090 appropriate. This can call eval. */
8092 void
8093 prepare_menu_bars ()
8095 int all_windows;
8096 struct gcpro gcpro1, gcpro2;
8097 struct frame *f;
8098 Lisp_Object tooltip_frame;
8100 #ifdef HAVE_WINDOW_SYSTEM
8101 tooltip_frame = tip_frame;
8102 #else
8103 tooltip_frame = Qnil;
8104 #endif
8106 /* Update all frame titles based on their buffer names, etc. We do
8107 this before the menu bars so that the buffer-menu will show the
8108 up-to-date frame titles. */
8109 #ifdef HAVE_WINDOW_SYSTEM
8110 if (windows_or_buffers_changed || update_mode_lines)
8112 Lisp_Object tail, frame;
8114 FOR_EACH_FRAME (tail, frame)
8116 f = XFRAME (frame);
8117 if (!EQ (frame, tooltip_frame)
8118 && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)))
8119 x_consider_frame_title (frame);
8122 #endif /* HAVE_WINDOW_SYSTEM */
8124 /* Update the menu bar item lists, if appropriate. This has to be
8125 done before any actual redisplay or generation of display lines. */
8126 all_windows = (update_mode_lines
8127 || buffer_shared > 1
8128 || windows_or_buffers_changed);
8129 if (all_windows)
8131 Lisp_Object tail, frame;
8132 int count = SPECPDL_INDEX ();
8134 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
8136 FOR_EACH_FRAME (tail, frame)
8138 f = XFRAME (frame);
8140 /* Ignore tooltip frame. */
8141 if (EQ (frame, tooltip_frame))
8142 continue;
8144 /* If a window on this frame changed size, report that to
8145 the user and clear the size-change flag. */
8146 if (FRAME_WINDOW_SIZES_CHANGED (f))
8148 Lisp_Object functions;
8150 /* Clear flag first in case we get an error below. */
8151 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
8152 functions = Vwindow_size_change_functions;
8153 GCPRO2 (tail, functions);
8155 while (CONSP (functions))
8157 call1 (XCAR (functions), frame);
8158 functions = XCDR (functions);
8160 UNGCPRO;
8163 GCPRO1 (tail);
8164 update_menu_bar (f, 0);
8165 #ifdef HAVE_WINDOW_SYSTEM
8166 update_tool_bar (f, 0);
8167 #endif
8168 UNGCPRO;
8171 unbind_to (count, Qnil);
8173 else
8175 struct frame *sf = SELECTED_FRAME ();
8176 update_menu_bar (sf, 1);
8177 #ifdef HAVE_WINDOW_SYSTEM
8178 update_tool_bar (sf, 1);
8179 #endif
8182 /* Motif needs this. See comment in xmenu.c. Turn it off when
8183 pending_menu_activation is not defined. */
8184 #ifdef USE_X_TOOLKIT
8185 pending_menu_activation = 0;
8186 #endif
8190 /* Update the menu bar item list for frame F. This has to be done
8191 before we start to fill in any display lines, because it can call
8192 eval.
8194 If SAVE_MATCH_DATA is non-zero, we must save and restore it here. */
8196 static void
8197 update_menu_bar (f, save_match_data)
8198 struct frame *f;
8199 int save_match_data;
8201 Lisp_Object window;
8202 register struct window *w;
8204 /* If called recursively during a menu update, do nothing. This can
8205 happen when, for instance, an activate-menubar-hook causes a
8206 redisplay. */
8207 if (inhibit_menubar_update)
8208 return;
8210 window = FRAME_SELECTED_WINDOW (f);
8211 w = XWINDOW (window);
8213 #if 0 /* The if statement below this if statement used to include the
8214 condition !NILP (w->update_mode_line), rather than using
8215 update_mode_lines directly, and this if statement may have
8216 been added to make that condition work. Now the if
8217 statement below matches its comment, this isn't needed. */
8218 if (update_mode_lines)
8219 w->update_mode_line = Qt;
8220 #endif
8222 if (FRAME_WINDOW_P (f)
8224 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
8225 || defined (USE_GTK)
8226 FRAME_EXTERNAL_MENU_BAR (f)
8227 #else
8228 FRAME_MENU_BAR_LINES (f) > 0
8229 #endif
8230 : FRAME_MENU_BAR_LINES (f) > 0)
8232 /* If the user has switched buffers or windows, we need to
8233 recompute to reflect the new bindings. But we'll
8234 recompute when update_mode_lines is set too; that means
8235 that people can use force-mode-line-update to request
8236 that the menu bar be recomputed. The adverse effect on
8237 the rest of the redisplay algorithm is about the same as
8238 windows_or_buffers_changed anyway. */
8239 if (windows_or_buffers_changed
8240 /* This used to test w->update_mode_line, but we believe
8241 there is no need to recompute the menu in that case. */
8242 || update_mode_lines
8243 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
8244 < BUF_MODIFF (XBUFFER (w->buffer)))
8245 != !NILP (w->last_had_star))
8246 || ((!NILP (Vtransient_mark_mode)
8247 && !NILP (XBUFFER (w->buffer)->mark_active))
8248 != !NILP (w->region_showing)))
8250 struct buffer *prev = current_buffer;
8251 int count = SPECPDL_INDEX ();
8253 specbind (Qinhibit_menubar_update, Qt);
8255 set_buffer_internal_1 (XBUFFER (w->buffer));
8256 if (save_match_data)
8257 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
8258 if (NILP (Voverriding_local_map_menu_flag))
8260 specbind (Qoverriding_terminal_local_map, Qnil);
8261 specbind (Qoverriding_local_map, Qnil);
8264 /* Run the Lucid hook. */
8265 safe_run_hooks (Qactivate_menubar_hook);
8267 /* If it has changed current-menubar from previous value,
8268 really recompute the menu-bar from the value. */
8269 if (! NILP (Vlucid_menu_bar_dirty_flag))
8270 call0 (Qrecompute_lucid_menubar);
8272 safe_run_hooks (Qmenu_bar_update_hook);
8273 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
8275 /* Redisplay the menu bar in case we changed it. */
8276 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
8277 || defined (USE_GTK)
8278 if (FRAME_WINDOW_P (f)
8279 #if defined (MAC_OS)
8280 /* All frames on Mac OS share the same menubar. So only the
8281 selected frame should be allowed to set it. */
8282 && f == SELECTED_FRAME ()
8283 #endif
8285 set_frame_menubar (f, 0, 0);
8286 else
8287 /* On a terminal screen, the menu bar is an ordinary screen
8288 line, and this makes it get updated. */
8289 w->update_mode_line = Qt;
8290 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
8291 /* In the non-toolkit version, the menu bar is an ordinary screen
8292 line, and this makes it get updated. */
8293 w->update_mode_line = Qt;
8294 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
8296 unbind_to (count, Qnil);
8297 set_buffer_internal_1 (prev);
8304 /***********************************************************************
8305 Output Cursor
8306 ***********************************************************************/
8308 #ifdef HAVE_WINDOW_SYSTEM
8310 /* EXPORT:
8311 Nominal cursor position -- where to draw output.
8312 HPOS and VPOS are window relative glyph matrix coordinates.
8313 X and Y are window relative pixel coordinates. */
8315 struct cursor_pos output_cursor;
8318 /* EXPORT:
8319 Set the global variable output_cursor to CURSOR. All cursor
8320 positions are relative to updated_window. */
8322 void
8323 set_output_cursor (cursor)
8324 struct cursor_pos *cursor;
8326 output_cursor.hpos = cursor->hpos;
8327 output_cursor.vpos = cursor->vpos;
8328 output_cursor.x = cursor->x;
8329 output_cursor.y = cursor->y;
8333 /* EXPORT for RIF:
8334 Set a nominal cursor position.
8336 HPOS and VPOS are column/row positions in a window glyph matrix. X
8337 and Y are window text area relative pixel positions.
8339 If this is done during an update, updated_window will contain the
8340 window that is being updated and the position is the future output
8341 cursor position for that window. If updated_window is null, use
8342 selected_window and display the cursor at the given position. */
8344 void
8345 x_cursor_to (vpos, hpos, y, x)
8346 int vpos, hpos, y, x;
8348 struct window *w;
8350 /* If updated_window is not set, work on selected_window. */
8351 if (updated_window)
8352 w = updated_window;
8353 else
8354 w = XWINDOW (selected_window);
8356 /* Set the output cursor. */
8357 output_cursor.hpos = hpos;
8358 output_cursor.vpos = vpos;
8359 output_cursor.x = x;
8360 output_cursor.y = y;
8362 /* If not called as part of an update, really display the cursor.
8363 This will also set the cursor position of W. */
8364 if (updated_window == NULL)
8366 BLOCK_INPUT;
8367 display_and_set_cursor (w, 1, hpos, vpos, x, y);
8368 if (rif->flush_display_optional)
8369 rif->flush_display_optional (SELECTED_FRAME ());
8370 UNBLOCK_INPUT;
8374 #endif /* HAVE_WINDOW_SYSTEM */
8377 /***********************************************************************
8378 Tool-bars
8379 ***********************************************************************/
8381 #ifdef HAVE_WINDOW_SYSTEM
8383 /* Where the mouse was last time we reported a mouse event. */
8385 FRAME_PTR last_mouse_frame;
8387 /* Tool-bar item index of the item on which a mouse button was pressed
8388 or -1. */
8390 int last_tool_bar_item;
8393 /* Update the tool-bar item list for frame F. This has to be done
8394 before we start to fill in any display lines. Called from
8395 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
8396 and restore it here. */
8398 static void
8399 update_tool_bar (f, save_match_data)
8400 struct frame *f;
8401 int save_match_data;
8403 #ifdef USE_GTK
8404 int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
8405 #else
8406 int do_update = WINDOWP (f->tool_bar_window)
8407 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0;
8408 #endif
8410 if (do_update)
8412 Lisp_Object window;
8413 struct window *w;
8415 window = FRAME_SELECTED_WINDOW (f);
8416 w = XWINDOW (window);
8418 /* If the user has switched buffers or windows, we need to
8419 recompute to reflect the new bindings. But we'll
8420 recompute when update_mode_lines is set too; that means
8421 that people can use force-mode-line-update to request
8422 that the menu bar be recomputed. The adverse effect on
8423 the rest of the redisplay algorithm is about the same as
8424 windows_or_buffers_changed anyway. */
8425 if (windows_or_buffers_changed
8426 || !NILP (w->update_mode_line)
8427 || update_mode_lines
8428 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
8429 < BUF_MODIFF (XBUFFER (w->buffer)))
8430 != !NILP (w->last_had_star))
8431 || ((!NILP (Vtransient_mark_mode)
8432 && !NILP (XBUFFER (w->buffer)->mark_active))
8433 != !NILP (w->region_showing)))
8435 struct buffer *prev = current_buffer;
8436 int count = SPECPDL_INDEX ();
8437 Lisp_Object new_tool_bar;
8438 int new_n_tool_bar;
8439 struct gcpro gcpro1;
8441 /* Set current_buffer to the buffer of the selected
8442 window of the frame, so that we get the right local
8443 keymaps. */
8444 set_buffer_internal_1 (XBUFFER (w->buffer));
8446 /* Save match data, if we must. */
8447 if (save_match_data)
8448 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
8450 /* Make sure that we don't accidentally use bogus keymaps. */
8451 if (NILP (Voverriding_local_map_menu_flag))
8453 specbind (Qoverriding_terminal_local_map, Qnil);
8454 specbind (Qoverriding_local_map, Qnil);
8457 GCPRO1 (new_tool_bar);
8459 /* Build desired tool-bar items from keymaps. */
8460 new_tool_bar = tool_bar_items (Fcopy_sequence (f->tool_bar_items),
8461 &new_n_tool_bar);
8463 /* Redisplay the tool-bar if we changed it. */
8464 if (NILP (Fequal (new_tool_bar, f->tool_bar_items)))
8466 /* Redisplay that happens asynchronously due to an expose event
8467 may access f->tool_bar_items. Make sure we update both
8468 variables within BLOCK_INPUT so no such event interrupts. */
8469 BLOCK_INPUT;
8470 f->tool_bar_items = new_tool_bar;
8471 f->n_tool_bar_items = new_n_tool_bar;
8472 w->update_mode_line = Qt;
8473 UNBLOCK_INPUT;
8476 UNGCPRO;
8478 unbind_to (count, Qnil);
8479 set_buffer_internal_1 (prev);
8485 /* Set F->desired_tool_bar_string to a Lisp string representing frame
8486 F's desired tool-bar contents. F->tool_bar_items must have
8487 been set up previously by calling prepare_menu_bars. */
8489 static void
8490 build_desired_tool_bar_string (f)
8491 struct frame *f;
8493 int i, size, size_needed;
8494 struct gcpro gcpro1, gcpro2, gcpro3;
8495 Lisp_Object image, plist, props;
8497 image = plist = props = Qnil;
8498 GCPRO3 (image, plist, props);
8500 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
8501 Otherwise, make a new string. */
8503 /* The size of the string we might be able to reuse. */
8504 size = (STRINGP (f->desired_tool_bar_string)
8505 ? SCHARS (f->desired_tool_bar_string)
8506 : 0);
8508 /* We need one space in the string for each image. */
8509 size_needed = f->n_tool_bar_items;
8511 /* Reuse f->desired_tool_bar_string, if possible. */
8512 if (size < size_needed || NILP (f->desired_tool_bar_string))
8513 f->desired_tool_bar_string = Fmake_string (make_number (size_needed),
8514 make_number (' '));
8515 else
8517 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
8518 Fremove_text_properties (make_number (0), make_number (size),
8519 props, f->desired_tool_bar_string);
8522 /* Put a `display' property on the string for the images to display,
8523 put a `menu_item' property on tool-bar items with a value that
8524 is the index of the item in F's tool-bar item vector. */
8525 for (i = 0; i < f->n_tool_bar_items; ++i)
8527 #define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
8529 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
8530 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
8531 int hmargin, vmargin, relief, idx, end;
8532 extern Lisp_Object QCrelief, QCmargin, QCconversion;
8534 /* If image is a vector, choose the image according to the
8535 button state. */
8536 image = PROP (TOOL_BAR_ITEM_IMAGES);
8537 if (VECTORP (image))
8539 if (enabled_p)
8540 idx = (selected_p
8541 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
8542 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
8543 else
8544 idx = (selected_p
8545 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
8546 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
8548 xassert (ASIZE (image) >= idx);
8549 image = AREF (image, idx);
8551 else
8552 idx = -1;
8554 /* Ignore invalid image specifications. */
8555 if (!valid_image_p (image))
8556 continue;
8558 /* Display the tool-bar button pressed, or depressed. */
8559 plist = Fcopy_sequence (XCDR (image));
8561 /* Compute margin and relief to draw. */
8562 relief = (tool_bar_button_relief >= 0
8563 ? tool_bar_button_relief
8564 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
8565 hmargin = vmargin = relief;
8567 if (INTEGERP (Vtool_bar_button_margin)
8568 && XINT (Vtool_bar_button_margin) > 0)
8570 hmargin += XFASTINT (Vtool_bar_button_margin);
8571 vmargin += XFASTINT (Vtool_bar_button_margin);
8573 else if (CONSP (Vtool_bar_button_margin))
8575 if (INTEGERP (XCAR (Vtool_bar_button_margin))
8576 && XINT (XCAR (Vtool_bar_button_margin)) > 0)
8577 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
8579 if (INTEGERP (XCDR (Vtool_bar_button_margin))
8580 && XINT (XCDR (Vtool_bar_button_margin)) > 0)
8581 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
8584 if (auto_raise_tool_bar_buttons_p)
8586 /* Add a `:relief' property to the image spec if the item is
8587 selected. */
8588 if (selected_p)
8590 plist = Fplist_put (plist, QCrelief, make_number (-relief));
8591 hmargin -= relief;
8592 vmargin -= relief;
8595 else
8597 /* If image is selected, display it pressed, i.e. with a
8598 negative relief. If it's not selected, display it with a
8599 raised relief. */
8600 plist = Fplist_put (plist, QCrelief,
8601 (selected_p
8602 ? make_number (-relief)
8603 : make_number (relief)));
8604 hmargin -= relief;
8605 vmargin -= relief;
8608 /* Put a margin around the image. */
8609 if (hmargin || vmargin)
8611 if (hmargin == vmargin)
8612 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
8613 else
8614 plist = Fplist_put (plist, QCmargin,
8615 Fcons (make_number (hmargin),
8616 make_number (vmargin)));
8619 /* If button is not enabled, and we don't have special images
8620 for the disabled state, make the image appear disabled by
8621 applying an appropriate algorithm to it. */
8622 if (!enabled_p && idx < 0)
8623 plist = Fplist_put (plist, QCconversion, Qdisabled);
8625 /* Put a `display' text property on the string for the image to
8626 display. Put a `menu-item' property on the string that gives
8627 the start of this item's properties in the tool-bar items
8628 vector. */
8629 image = Fcons (Qimage, plist);
8630 props = list4 (Qdisplay, image,
8631 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS));
8633 /* Let the last image hide all remaining spaces in the tool bar
8634 string. The string can be longer than needed when we reuse a
8635 previous string. */
8636 if (i + 1 == f->n_tool_bar_items)
8637 end = SCHARS (f->desired_tool_bar_string);
8638 else
8639 end = i + 1;
8640 Fadd_text_properties (make_number (i), make_number (end),
8641 props, f->desired_tool_bar_string);
8642 #undef PROP
8645 UNGCPRO;
8649 /* Display one line of the tool-bar of frame IT->f. */
8651 static void
8652 display_tool_bar_line (it)
8653 struct it *it;
8655 struct glyph_row *row = it->glyph_row;
8656 int max_x = it->last_visible_x;
8657 struct glyph *last;
8659 prepare_desired_row (row);
8660 row->y = it->current_y;
8662 /* Note that this isn't made use of if the face hasn't a box,
8663 so there's no need to check the face here. */
8664 it->start_of_box_run_p = 1;
8666 while (it->current_x < max_x)
8668 int x_before, x, n_glyphs_before, i, nglyphs;
8670 /* Get the next display element. */
8671 if (!get_next_display_element (it))
8672 break;
8674 /* Produce glyphs. */
8675 x_before = it->current_x;
8676 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
8677 PRODUCE_GLYPHS (it);
8679 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
8680 i = 0;
8681 x = x_before;
8682 while (i < nglyphs)
8684 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
8686 if (x + glyph->pixel_width > max_x)
8688 /* Glyph doesn't fit on line. */
8689 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
8690 it->current_x = x;
8691 goto out;
8694 ++it->hpos;
8695 x += glyph->pixel_width;
8696 ++i;
8699 /* Stop at line ends. */
8700 if (ITERATOR_AT_END_OF_LINE_P (it))
8701 break;
8703 set_iterator_to_next (it, 1);
8706 out:;
8708 row->displays_text_p = row->used[TEXT_AREA] != 0;
8709 extend_face_to_end_of_line (it);
8710 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
8711 last->right_box_line_p = 1;
8712 if (last == row->glyphs[TEXT_AREA])
8713 last->left_box_line_p = 1;
8714 compute_line_metrics (it);
8716 /* If line is empty, make it occupy the rest of the tool-bar. */
8717 if (!row->displays_text_p)
8719 row->height = row->phys_height = it->last_visible_y - row->y;
8720 row->ascent = row->phys_ascent = 0;
8721 row->extra_line_spacing = 0;
8724 row->full_width_p = 1;
8725 row->continued_p = 0;
8726 row->truncated_on_left_p = 0;
8727 row->truncated_on_right_p = 0;
8729 it->current_x = it->hpos = 0;
8730 it->current_y += row->height;
8731 ++it->vpos;
8732 ++it->glyph_row;
8736 /* Value is the number of screen lines needed to make all tool-bar
8737 items of frame F visible. */
8739 static int
8740 tool_bar_lines_needed (f)
8741 struct frame *f;
8743 struct window *w = XWINDOW (f->tool_bar_window);
8744 struct it it;
8746 /* Initialize an iterator for iteration over
8747 F->desired_tool_bar_string in the tool-bar window of frame F. */
8748 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
8749 it.first_visible_x = 0;
8750 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
8751 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
8753 while (!ITERATOR_AT_END_P (&it))
8755 it.glyph_row = w->desired_matrix->rows;
8756 clear_glyph_row (it.glyph_row);
8757 display_tool_bar_line (&it);
8760 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
8764 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
8765 0, 1, 0,
8766 doc: /* Return the number of lines occupied by the tool bar of FRAME. */)
8767 (frame)
8768 Lisp_Object frame;
8770 struct frame *f;
8771 struct window *w;
8772 int nlines = 0;
8774 if (NILP (frame))
8775 frame = selected_frame;
8776 else
8777 CHECK_FRAME (frame);
8778 f = XFRAME (frame);
8780 if (WINDOWP (f->tool_bar_window)
8781 || (w = XWINDOW (f->tool_bar_window),
8782 WINDOW_TOTAL_LINES (w) > 0))
8784 update_tool_bar (f, 1);
8785 if (f->n_tool_bar_items)
8787 build_desired_tool_bar_string (f);
8788 nlines = tool_bar_lines_needed (f);
8792 return make_number (nlines);
8796 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
8797 height should be changed. */
8799 static int
8800 redisplay_tool_bar (f)
8801 struct frame *f;
8803 struct window *w;
8804 struct it it;
8805 struct glyph_row *row;
8806 int change_height_p = 0;
8808 #ifdef USE_GTK
8809 if (FRAME_EXTERNAL_TOOL_BAR (f))
8810 update_frame_tool_bar (f);
8811 return 0;
8812 #endif
8814 /* If frame hasn't a tool-bar window or if it is zero-height, don't
8815 do anything. This means you must start with tool-bar-lines
8816 non-zero to get the auto-sizing effect. Or in other words, you
8817 can turn off tool-bars by specifying tool-bar-lines zero. */
8818 if (!WINDOWP (f->tool_bar_window)
8819 || (w = XWINDOW (f->tool_bar_window),
8820 WINDOW_TOTAL_LINES (w) == 0))
8821 return 0;
8823 /* Set up an iterator for the tool-bar window. */
8824 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
8825 it.first_visible_x = 0;
8826 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
8827 row = it.glyph_row;
8829 /* Build a string that represents the contents of the tool-bar. */
8830 build_desired_tool_bar_string (f);
8831 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
8833 /* Display as many lines as needed to display all tool-bar items. */
8834 while (it.current_y < it.last_visible_y)
8835 display_tool_bar_line (&it);
8837 /* It doesn't make much sense to try scrolling in the tool-bar
8838 window, so don't do it. */
8839 w->desired_matrix->no_scrolling_p = 1;
8840 w->must_be_updated_p = 1;
8842 if (auto_resize_tool_bars_p)
8844 int nlines;
8846 /* If we couldn't display everything, change the tool-bar's
8847 height. */
8848 if (IT_STRING_CHARPOS (it) < it.end_charpos)
8849 change_height_p = 1;
8851 /* If there are blank lines at the end, except for a partially
8852 visible blank line at the end that is smaller than
8853 FRAME_LINE_HEIGHT, change the tool-bar's height. */
8854 row = it.glyph_row - 1;
8855 if (!row->displays_text_p
8856 && row->height >= FRAME_LINE_HEIGHT (f))
8857 change_height_p = 1;
8859 /* If row displays tool-bar items, but is partially visible,
8860 change the tool-bar's height. */
8861 if (row->displays_text_p
8862 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y)
8863 change_height_p = 1;
8865 /* Resize windows as needed by changing the `tool-bar-lines'
8866 frame parameter. */
8867 if (change_height_p
8868 && (nlines = tool_bar_lines_needed (f),
8869 nlines != WINDOW_TOTAL_LINES (w)))
8871 extern Lisp_Object Qtool_bar_lines;
8872 Lisp_Object frame;
8873 int old_height = WINDOW_TOTAL_LINES (w);
8875 XSETFRAME (frame, f);
8876 clear_glyph_matrix (w->desired_matrix);
8877 Fmodify_frame_parameters (frame,
8878 Fcons (Fcons (Qtool_bar_lines,
8879 make_number (nlines)),
8880 Qnil));
8881 if (WINDOW_TOTAL_LINES (w) != old_height)
8882 fonts_changed_p = 1;
8886 return change_height_p;
8890 /* Get information about the tool-bar item which is displayed in GLYPH
8891 on frame F. Return in *PROP_IDX the index where tool-bar item
8892 properties start in F->tool_bar_items. Value is zero if
8893 GLYPH doesn't display a tool-bar item. */
8895 static int
8896 tool_bar_item_info (f, glyph, prop_idx)
8897 struct frame *f;
8898 struct glyph *glyph;
8899 int *prop_idx;
8901 Lisp_Object prop;
8902 int success_p;
8903 int charpos;
8905 /* This function can be called asynchronously, which means we must
8906 exclude any possibility that Fget_text_property signals an
8907 error. */
8908 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
8909 charpos = max (0, charpos);
8911 /* Get the text property `menu-item' at pos. The value of that
8912 property is the start index of this item's properties in
8913 F->tool_bar_items. */
8914 prop = Fget_text_property (make_number (charpos),
8915 Qmenu_item, f->current_tool_bar_string);
8916 if (INTEGERP (prop))
8918 *prop_idx = XINT (prop);
8919 success_p = 1;
8921 else
8922 success_p = 0;
8924 return success_p;
8928 /* Get information about the tool-bar item at position X/Y on frame F.
8929 Return in *GLYPH a pointer to the glyph of the tool-bar item in
8930 the current matrix of the tool-bar window of F, or NULL if not
8931 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
8932 item in F->tool_bar_items. Value is
8934 -1 if X/Y is not on a tool-bar item
8935 0 if X/Y is on the same item that was highlighted before.
8936 1 otherwise. */
8938 static int
8939 get_tool_bar_item (f, x, y, glyph, hpos, vpos, prop_idx)
8940 struct frame *f;
8941 int x, y;
8942 struct glyph **glyph;
8943 int *hpos, *vpos, *prop_idx;
8945 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
8946 struct window *w = XWINDOW (f->tool_bar_window);
8947 int area;
8949 /* Find the glyph under X/Y. */
8950 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
8951 if (*glyph == NULL)
8952 return -1;
8954 /* Get the start of this tool-bar item's properties in
8955 f->tool_bar_items. */
8956 if (!tool_bar_item_info (f, *glyph, prop_idx))
8957 return -1;
8959 /* Is mouse on the highlighted item? */
8960 if (EQ (f->tool_bar_window, dpyinfo->mouse_face_window)
8961 && *vpos >= dpyinfo->mouse_face_beg_row
8962 && *vpos <= dpyinfo->mouse_face_end_row
8963 && (*vpos > dpyinfo->mouse_face_beg_row
8964 || *hpos >= dpyinfo->mouse_face_beg_col)
8965 && (*vpos < dpyinfo->mouse_face_end_row
8966 || *hpos < dpyinfo->mouse_face_end_col
8967 || dpyinfo->mouse_face_past_end))
8968 return 0;
8970 return 1;
8974 /* EXPORT:
8975 Handle mouse button event on the tool-bar of frame F, at
8976 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
8977 0 for button release. MODIFIERS is event modifiers for button
8978 release. */
8980 void
8981 handle_tool_bar_click (f, x, y, down_p, modifiers)
8982 struct frame *f;
8983 int x, y, down_p;
8984 unsigned int modifiers;
8986 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
8987 struct window *w = XWINDOW (f->tool_bar_window);
8988 int hpos, vpos, prop_idx;
8989 struct glyph *glyph;
8990 Lisp_Object enabled_p;
8992 /* If not on the highlighted tool-bar item, return. */
8993 frame_to_window_pixel_xy (w, &x, &y);
8994 if (get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0)
8995 return;
8997 /* If item is disabled, do nothing. */
8998 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
8999 if (NILP (enabled_p))
9000 return;
9002 if (down_p)
9004 /* Show item in pressed state. */
9005 show_mouse_face (dpyinfo, DRAW_IMAGE_SUNKEN);
9006 dpyinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN;
9007 last_tool_bar_item = prop_idx;
9009 else
9011 Lisp_Object key, frame;
9012 struct input_event event;
9013 EVENT_INIT (event);
9015 /* Show item in released state. */
9016 show_mouse_face (dpyinfo, DRAW_IMAGE_RAISED);
9017 dpyinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
9019 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
9021 XSETFRAME (frame, f);
9022 event.kind = TOOL_BAR_EVENT;
9023 event.frame_or_window = frame;
9024 event.arg = frame;
9025 kbd_buffer_store_event (&event);
9027 event.kind = TOOL_BAR_EVENT;
9028 event.frame_or_window = frame;
9029 event.arg = key;
9030 event.modifiers = modifiers;
9031 kbd_buffer_store_event (&event);
9032 last_tool_bar_item = -1;
9037 /* Possibly highlight a tool-bar item on frame F when mouse moves to
9038 tool-bar window-relative coordinates X/Y. Called from
9039 note_mouse_highlight. */
9041 static void
9042 note_tool_bar_highlight (f, x, y)
9043 struct frame *f;
9044 int x, y;
9046 Lisp_Object window = f->tool_bar_window;
9047 struct window *w = XWINDOW (window);
9048 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
9049 int hpos, vpos;
9050 struct glyph *glyph;
9051 struct glyph_row *row;
9052 int i;
9053 Lisp_Object enabled_p;
9054 int prop_idx;
9055 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
9056 int mouse_down_p, rc;
9058 /* Function note_mouse_highlight is called with negative x(y
9059 values when mouse moves outside of the frame. */
9060 if (x <= 0 || y <= 0)
9062 clear_mouse_face (dpyinfo);
9063 return;
9066 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
9067 if (rc < 0)
9069 /* Not on tool-bar item. */
9070 clear_mouse_face (dpyinfo);
9071 return;
9073 else if (rc == 0)
9074 /* On same tool-bar item as before. */
9075 goto set_help_echo;
9077 clear_mouse_face (dpyinfo);
9079 /* Mouse is down, but on different tool-bar item? */
9080 mouse_down_p = (dpyinfo->grabbed
9081 && f == last_mouse_frame
9082 && FRAME_LIVE_P (f));
9083 if (mouse_down_p
9084 && last_tool_bar_item != prop_idx)
9085 return;
9087 dpyinfo->mouse_face_image_state = DRAW_NORMAL_TEXT;
9088 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
9090 /* If tool-bar item is not enabled, don't highlight it. */
9091 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
9092 if (!NILP (enabled_p))
9094 /* Compute the x-position of the glyph. In front and past the
9095 image is a space. We include this in the highlighted area. */
9096 row = MATRIX_ROW (w->current_matrix, vpos);
9097 for (i = x = 0; i < hpos; ++i)
9098 x += row->glyphs[TEXT_AREA][i].pixel_width;
9100 /* Record this as the current active region. */
9101 dpyinfo->mouse_face_beg_col = hpos;
9102 dpyinfo->mouse_face_beg_row = vpos;
9103 dpyinfo->mouse_face_beg_x = x;
9104 dpyinfo->mouse_face_beg_y = row->y;
9105 dpyinfo->mouse_face_past_end = 0;
9107 dpyinfo->mouse_face_end_col = hpos + 1;
9108 dpyinfo->mouse_face_end_row = vpos;
9109 dpyinfo->mouse_face_end_x = x + glyph->pixel_width;
9110 dpyinfo->mouse_face_end_y = row->y;
9111 dpyinfo->mouse_face_window = window;
9112 dpyinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
9114 /* Display it as active. */
9115 show_mouse_face (dpyinfo, draw);
9116 dpyinfo->mouse_face_image_state = draw;
9119 set_help_echo:
9121 /* Set help_echo_string to a help string to display for this tool-bar item.
9122 XTread_socket does the rest. */
9123 help_echo_object = help_echo_window = Qnil;
9124 help_echo_pos = -1;
9125 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
9126 if (NILP (help_echo_string))
9127 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
9130 #endif /* HAVE_WINDOW_SYSTEM */
9134 /************************************************************************
9135 Horizontal scrolling
9136 ************************************************************************/
9138 static int hscroll_window_tree P_ ((Lisp_Object));
9139 static int hscroll_windows P_ ((Lisp_Object));
9141 /* For all leaf windows in the window tree rooted at WINDOW, set their
9142 hscroll value so that PT is (i) visible in the window, and (ii) so
9143 that it is not within a certain margin at the window's left and
9144 right border. Value is non-zero if any window's hscroll has been
9145 changed. */
9147 static int
9148 hscroll_window_tree (window)
9149 Lisp_Object window;
9151 int hscrolled_p = 0;
9152 int hscroll_relative_p = FLOATP (Vhscroll_step);
9153 int hscroll_step_abs = 0;
9154 double hscroll_step_rel = 0;
9156 if (hscroll_relative_p)
9158 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
9159 if (hscroll_step_rel < 0)
9161 hscroll_relative_p = 0;
9162 hscroll_step_abs = 0;
9165 else if (INTEGERP (Vhscroll_step))
9167 hscroll_step_abs = XINT (Vhscroll_step);
9168 if (hscroll_step_abs < 0)
9169 hscroll_step_abs = 0;
9171 else
9172 hscroll_step_abs = 0;
9174 while (WINDOWP (window))
9176 struct window *w = XWINDOW (window);
9178 if (WINDOWP (w->hchild))
9179 hscrolled_p |= hscroll_window_tree (w->hchild);
9180 else if (WINDOWP (w->vchild))
9181 hscrolled_p |= hscroll_window_tree (w->vchild);
9182 else if (w->cursor.vpos >= 0)
9184 int h_margin;
9185 int text_area_width;
9186 struct glyph_row *current_cursor_row
9187 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
9188 struct glyph_row *desired_cursor_row
9189 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
9190 struct glyph_row *cursor_row
9191 = (desired_cursor_row->enabled_p
9192 ? desired_cursor_row
9193 : current_cursor_row);
9195 text_area_width = window_box_width (w, TEXT_AREA);
9197 /* Scroll when cursor is inside this scroll margin. */
9198 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
9200 if ((XFASTINT (w->hscroll)
9201 && w->cursor.x <= h_margin)
9202 || (cursor_row->enabled_p
9203 && cursor_row->truncated_on_right_p
9204 && (w->cursor.x >= text_area_width - h_margin)))
9206 struct it it;
9207 int hscroll;
9208 struct buffer *saved_current_buffer;
9209 int pt;
9210 int wanted_x;
9212 /* Find point in a display of infinite width. */
9213 saved_current_buffer = current_buffer;
9214 current_buffer = XBUFFER (w->buffer);
9216 if (w == XWINDOW (selected_window))
9217 pt = BUF_PT (current_buffer);
9218 else
9220 pt = marker_position (w->pointm);
9221 pt = max (BEGV, pt);
9222 pt = min (ZV, pt);
9225 /* Move iterator to pt starting at cursor_row->start in
9226 a line with infinite width. */
9227 init_to_row_start (&it, w, cursor_row);
9228 it.last_visible_x = INFINITY;
9229 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
9230 current_buffer = saved_current_buffer;
9232 /* Position cursor in window. */
9233 if (!hscroll_relative_p && hscroll_step_abs == 0)
9234 hscroll = max (0, (it.current_x
9235 - (ITERATOR_AT_END_OF_LINE_P (&it)
9236 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
9237 : (text_area_width / 2))))
9238 / FRAME_COLUMN_WIDTH (it.f);
9239 else if (w->cursor.x >= text_area_width - h_margin)
9241 if (hscroll_relative_p)
9242 wanted_x = text_area_width * (1 - hscroll_step_rel)
9243 - h_margin;
9244 else
9245 wanted_x = text_area_width
9246 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
9247 - h_margin;
9248 hscroll
9249 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
9251 else
9253 if (hscroll_relative_p)
9254 wanted_x = text_area_width * hscroll_step_rel
9255 + h_margin;
9256 else
9257 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
9258 + h_margin;
9259 hscroll
9260 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
9262 hscroll = max (hscroll, XFASTINT (w->min_hscroll));
9264 /* Don't call Fset_window_hscroll if value hasn't
9265 changed because it will prevent redisplay
9266 optimizations. */
9267 if (XFASTINT (w->hscroll) != hscroll)
9269 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
9270 w->hscroll = make_number (hscroll);
9271 hscrolled_p = 1;
9276 window = w->next;
9279 /* Value is non-zero if hscroll of any leaf window has been changed. */
9280 return hscrolled_p;
9284 /* Set hscroll so that cursor is visible and not inside horizontal
9285 scroll margins for all windows in the tree rooted at WINDOW. See
9286 also hscroll_window_tree above. Value is non-zero if any window's
9287 hscroll has been changed. If it has, desired matrices on the frame
9288 of WINDOW are cleared. */
9290 static int
9291 hscroll_windows (window)
9292 Lisp_Object window;
9294 int hscrolled_p;
9296 if (automatic_hscrolling_p)
9298 hscrolled_p = hscroll_window_tree (window);
9299 if (hscrolled_p)
9300 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
9302 else
9303 hscrolled_p = 0;
9304 return hscrolled_p;
9309 /************************************************************************
9310 Redisplay
9311 ************************************************************************/
9313 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
9314 to a non-zero value. This is sometimes handy to have in a debugger
9315 session. */
9317 #if GLYPH_DEBUG
9319 /* First and last unchanged row for try_window_id. */
9321 int debug_first_unchanged_at_end_vpos;
9322 int debug_last_unchanged_at_beg_vpos;
9324 /* Delta vpos and y. */
9326 int debug_dvpos, debug_dy;
9328 /* Delta in characters and bytes for try_window_id. */
9330 int debug_delta, debug_delta_bytes;
9332 /* Values of window_end_pos and window_end_vpos at the end of
9333 try_window_id. */
9335 EMACS_INT debug_end_pos, debug_end_vpos;
9337 /* Append a string to W->desired_matrix->method. FMT is a printf
9338 format string. A1...A9 are a supplement for a variable-length
9339 argument list. If trace_redisplay_p is non-zero also printf the
9340 resulting string to stderr. */
9342 static void
9343 debug_method_add (w, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
9344 struct window *w;
9345 char *fmt;
9346 int a1, a2, a3, a4, a5, a6, a7, a8, a9;
9348 char buffer[512];
9349 char *method = w->desired_matrix->method;
9350 int len = strlen (method);
9351 int size = sizeof w->desired_matrix->method;
9352 int remaining = size - len - 1;
9354 sprintf (buffer, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
9355 if (len && remaining)
9357 method[len] = '|';
9358 --remaining, ++len;
9361 strncpy (method + len, buffer, remaining);
9363 if (trace_redisplay_p)
9364 fprintf (stderr, "%p (%s): %s\n",
9366 ((BUFFERP (w->buffer)
9367 && STRINGP (XBUFFER (w->buffer)->name))
9368 ? (char *) SDATA (XBUFFER (w->buffer)->name)
9369 : "no buffer"),
9370 buffer);
9373 #endif /* GLYPH_DEBUG */
9376 /* Value is non-zero if all changes in window W, which displays
9377 current_buffer, are in the text between START and END. START is a
9378 buffer position, END is given as a distance from Z. Used in
9379 redisplay_internal for display optimization. */
9381 static INLINE int
9382 text_outside_line_unchanged_p (w, start, end)
9383 struct window *w;
9384 int start, end;
9386 int unchanged_p = 1;
9388 /* If text or overlays have changed, see where. */
9389 if (XFASTINT (w->last_modified) < MODIFF
9390 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
9392 /* Gap in the line? */
9393 if (GPT < start || Z - GPT < end)
9394 unchanged_p = 0;
9396 /* Changes start in front of the line, or end after it? */
9397 if (unchanged_p
9398 && (BEG_UNCHANGED < start - 1
9399 || END_UNCHANGED < end))
9400 unchanged_p = 0;
9402 /* If selective display, can't optimize if changes start at the
9403 beginning of the line. */
9404 if (unchanged_p
9405 && INTEGERP (current_buffer->selective_display)
9406 && XINT (current_buffer->selective_display) > 0
9407 && (BEG_UNCHANGED < start || GPT <= start))
9408 unchanged_p = 0;
9410 /* If there are overlays at the start or end of the line, these
9411 may have overlay strings with newlines in them. A change at
9412 START, for instance, may actually concern the display of such
9413 overlay strings as well, and they are displayed on different
9414 lines. So, quickly rule out this case. (For the future, it
9415 might be desirable to implement something more telling than
9416 just BEG/END_UNCHANGED.) */
9417 if (unchanged_p)
9419 if (BEG + BEG_UNCHANGED == start
9420 && overlay_touches_p (start))
9421 unchanged_p = 0;
9422 if (END_UNCHANGED == end
9423 && overlay_touches_p (Z - end))
9424 unchanged_p = 0;
9428 return unchanged_p;
9432 /* Do a frame update, taking possible shortcuts into account. This is
9433 the main external entry point for redisplay.
9435 If the last redisplay displayed an echo area message and that message
9436 is no longer requested, we clear the echo area or bring back the
9437 mini-buffer if that is in use. */
9439 void
9440 redisplay ()
9442 redisplay_internal (0);
9446 static Lisp_Object
9447 overlay_arrow_string_or_property (var, pbitmap)
9448 Lisp_Object var;
9449 int *pbitmap;
9451 Lisp_Object pstr = Fget (var, Qoverlay_arrow_string);
9452 Lisp_Object bitmap;
9454 if (pbitmap)
9456 *pbitmap = 0;
9457 if (bitmap = Fget (var, Qoverlay_arrow_bitmap), INTEGERP (bitmap))
9458 *pbitmap = XINT (bitmap);
9461 if (!NILP (pstr))
9462 return pstr;
9463 return Voverlay_arrow_string;
9466 /* Return 1 if there are any overlay-arrows in current_buffer. */
9467 static int
9468 overlay_arrow_in_current_buffer_p ()
9470 Lisp_Object vlist;
9472 for (vlist = Voverlay_arrow_variable_list;
9473 CONSP (vlist);
9474 vlist = XCDR (vlist))
9476 Lisp_Object var = XCAR (vlist);
9477 Lisp_Object val;
9479 if (!SYMBOLP (var))
9480 continue;
9481 val = find_symbol_value (var);
9482 if (MARKERP (val)
9483 && current_buffer == XMARKER (val)->buffer)
9484 return 1;
9486 return 0;
9490 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
9491 has changed. */
9493 static int
9494 overlay_arrows_changed_p ()
9496 Lisp_Object vlist;
9498 for (vlist = Voverlay_arrow_variable_list;
9499 CONSP (vlist);
9500 vlist = XCDR (vlist))
9502 Lisp_Object var = XCAR (vlist);
9503 Lisp_Object val, pstr;
9505 if (!SYMBOLP (var))
9506 continue;
9507 val = find_symbol_value (var);
9508 if (!MARKERP (val))
9509 continue;
9510 if (! EQ (COERCE_MARKER (val),
9511 Fget (var, Qlast_arrow_position))
9512 || ! (pstr = overlay_arrow_string_or_property (var, 0),
9513 EQ (pstr, Fget (var, Qlast_arrow_string))))
9514 return 1;
9516 return 0;
9519 /* Mark overlay arrows to be updated on next redisplay. */
9521 static void
9522 update_overlay_arrows (up_to_date)
9523 int up_to_date;
9525 Lisp_Object vlist;
9527 for (vlist = Voverlay_arrow_variable_list;
9528 CONSP (vlist);
9529 vlist = XCDR (vlist))
9531 Lisp_Object var = XCAR (vlist);
9533 if (!SYMBOLP (var))
9534 continue;
9536 if (up_to_date > 0)
9538 Lisp_Object val = find_symbol_value (var);
9539 Fput (var, Qlast_arrow_position,
9540 COERCE_MARKER (val));
9541 Fput (var, Qlast_arrow_string,
9542 overlay_arrow_string_or_property (var, 0));
9544 else if (up_to_date < 0
9545 || !NILP (Fget (var, Qlast_arrow_position)))
9547 Fput (var, Qlast_arrow_position, Qt);
9548 Fput (var, Qlast_arrow_string, Qt);
9554 /* Return overlay arrow string to display at row.
9555 Return t if display as bitmap in left fringe.
9556 Return nil if no overlay arrow. */
9558 static Lisp_Object
9559 overlay_arrow_at_row (it, row, pbitmap)
9560 struct it *it;
9561 struct glyph_row *row;
9562 int *pbitmap;
9564 Lisp_Object vlist;
9566 for (vlist = Voverlay_arrow_variable_list;
9567 CONSP (vlist);
9568 vlist = XCDR (vlist))
9570 Lisp_Object var = XCAR (vlist);
9571 Lisp_Object val;
9573 if (!SYMBOLP (var))
9574 continue;
9576 val = find_symbol_value (var);
9578 if (MARKERP (val)
9579 && current_buffer == XMARKER (val)->buffer
9580 && (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
9582 val = overlay_arrow_string_or_property (var, pbitmap);
9583 if (FRAME_WINDOW_P (it->f)
9584 && WINDOW_LEFT_FRINGE_WIDTH (it->w) > 0)
9585 return Qt;
9586 if (STRINGP (val))
9587 return val;
9588 break;
9592 *pbitmap = 0;
9593 return Qnil;
9596 /* Return 1 if point moved out of or into a composition. Otherwise
9597 return 0. PREV_BUF and PREV_PT are the last point buffer and
9598 position. BUF and PT are the current point buffer and position. */
9601 check_point_in_composition (prev_buf, prev_pt, buf, pt)
9602 struct buffer *prev_buf, *buf;
9603 int prev_pt, pt;
9605 int start, end;
9606 Lisp_Object prop;
9607 Lisp_Object buffer;
9609 XSETBUFFER (buffer, buf);
9610 /* Check a composition at the last point if point moved within the
9611 same buffer. */
9612 if (prev_buf == buf)
9614 if (prev_pt == pt)
9615 /* Point didn't move. */
9616 return 0;
9618 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
9619 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
9620 && COMPOSITION_VALID_P (start, end, prop)
9621 && start < prev_pt && end > prev_pt)
9622 /* The last point was within the composition. Return 1 iff
9623 point moved out of the composition. */
9624 return (pt <= start || pt >= end);
9627 /* Check a composition at the current point. */
9628 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
9629 && find_composition (pt, -1, &start, &end, &prop, buffer)
9630 && COMPOSITION_VALID_P (start, end, prop)
9631 && start < pt && end > pt);
9635 /* Reconsider the setting of B->clip_changed which is displayed
9636 in window W. */
9638 static INLINE void
9639 reconsider_clip_changes (w, b)
9640 struct window *w;
9641 struct buffer *b;
9643 if (b->clip_changed
9644 && !NILP (w->window_end_valid)
9645 && w->current_matrix->buffer == b
9646 && w->current_matrix->zv == BUF_ZV (b)
9647 && w->current_matrix->begv == BUF_BEGV (b))
9648 b->clip_changed = 0;
9650 /* If display wasn't paused, and W is not a tool bar window, see if
9651 point has been moved into or out of a composition. In that case,
9652 we set b->clip_changed to 1 to force updating the screen. If
9653 b->clip_changed has already been set to 1, we can skip this
9654 check. */
9655 if (!b->clip_changed
9656 && BUFFERP (w->buffer) && !NILP (w->window_end_valid))
9658 int pt;
9660 if (w == XWINDOW (selected_window))
9661 pt = BUF_PT (current_buffer);
9662 else
9663 pt = marker_position (w->pointm);
9665 if ((w->current_matrix->buffer != XBUFFER (w->buffer)
9666 || pt != XINT (w->last_point))
9667 && check_point_in_composition (w->current_matrix->buffer,
9668 XINT (w->last_point),
9669 XBUFFER (w->buffer), pt))
9670 b->clip_changed = 1;
9675 /* Select FRAME to forward the values of frame-local variables into C
9676 variables so that the redisplay routines can access those values
9677 directly. */
9679 static void
9680 select_frame_for_redisplay (frame)
9681 Lisp_Object frame;
9683 Lisp_Object tail, sym, val;
9684 Lisp_Object old = selected_frame;
9686 selected_frame = frame;
9688 for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail))
9689 if (CONSP (XCAR (tail))
9690 && (sym = XCAR (XCAR (tail)),
9691 SYMBOLP (sym))
9692 && (sym = indirect_variable (sym),
9693 val = SYMBOL_VALUE (sym),
9694 (BUFFER_LOCAL_VALUEP (val)
9695 || SOME_BUFFER_LOCAL_VALUEP (val)))
9696 && XBUFFER_LOCAL_VALUE (val)->check_frame)
9697 Fsymbol_value (sym);
9699 for (tail = XFRAME (old)->param_alist; CONSP (tail); tail = XCDR (tail))
9700 if (CONSP (XCAR (tail))
9701 && (sym = XCAR (XCAR (tail)),
9702 SYMBOLP (sym))
9703 && (sym = indirect_variable (sym),
9704 val = SYMBOL_VALUE (sym),
9705 (BUFFER_LOCAL_VALUEP (val)
9706 || SOME_BUFFER_LOCAL_VALUEP (val)))
9707 && XBUFFER_LOCAL_VALUE (val)->check_frame)
9708 Fsymbol_value (sym);
9712 #define STOP_POLLING \
9713 do { if (! polling_stopped_here) stop_polling (); \
9714 polling_stopped_here = 1; } while (0)
9716 #define RESUME_POLLING \
9717 do { if (polling_stopped_here) start_polling (); \
9718 polling_stopped_here = 0; } while (0)
9721 /* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
9722 response to any user action; therefore, we should preserve the echo
9723 area. (Actually, our caller does that job.) Perhaps in the future
9724 avoid recentering windows if it is not necessary; currently that
9725 causes some problems. */
9727 static void
9728 redisplay_internal (preserve_echo_area)
9729 int preserve_echo_area;
9731 struct window *w = XWINDOW (selected_window);
9732 struct frame *f = XFRAME (w->frame);
9733 int pause;
9734 int must_finish = 0;
9735 struct text_pos tlbufpos, tlendpos;
9736 int number_of_visible_frames;
9737 int count;
9738 struct frame *sf = SELECTED_FRAME ();
9739 int polling_stopped_here = 0;
9741 /* Non-zero means redisplay has to consider all windows on all
9742 frames. Zero means, only selected_window is considered. */
9743 int consider_all_windows_p;
9745 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
9747 /* No redisplay if running in batch mode or frame is not yet fully
9748 initialized, or redisplay is explicitly turned off by setting
9749 Vinhibit_redisplay. */
9750 if (noninteractive
9751 || !NILP (Vinhibit_redisplay)
9752 || !f->glyphs_initialized_p)
9753 return;
9755 /* The flag redisplay_performed_directly_p is set by
9756 direct_output_for_insert when it already did the whole screen
9757 update necessary. */
9758 if (redisplay_performed_directly_p)
9760 redisplay_performed_directly_p = 0;
9761 if (!hscroll_windows (selected_window))
9762 return;
9765 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
9766 if (popup_activated ())
9767 return;
9768 #endif
9770 /* I don't think this happens but let's be paranoid. */
9771 if (redisplaying_p)
9772 return;
9774 /* Record a function that resets redisplaying_p to its old value
9775 when we leave this function. */
9776 count = SPECPDL_INDEX ();
9777 record_unwind_protect (unwind_redisplay,
9778 Fcons (make_number (redisplaying_p), selected_frame));
9779 ++redisplaying_p;
9780 specbind (Qinhibit_free_realized_faces, Qnil);
9782 retry:
9783 pause = 0;
9784 reconsider_clip_changes (w, current_buffer);
9786 /* If new fonts have been loaded that make a glyph matrix adjustment
9787 necessary, do it. */
9788 if (fonts_changed_p)
9790 adjust_glyphs (NULL);
9791 ++windows_or_buffers_changed;
9792 fonts_changed_p = 0;
9795 /* If face_change_count is non-zero, init_iterator will free all
9796 realized faces, which includes the faces referenced from current
9797 matrices. So, we can't reuse current matrices in this case. */
9798 if (face_change_count)
9799 ++windows_or_buffers_changed;
9801 if (! FRAME_WINDOW_P (sf)
9802 && previous_terminal_frame != sf)
9804 /* Since frames on an ASCII terminal share the same display
9805 area, displaying a different frame means redisplay the whole
9806 thing. */
9807 windows_or_buffers_changed++;
9808 SET_FRAME_GARBAGED (sf);
9809 XSETFRAME (Vterminal_frame, sf);
9811 previous_terminal_frame = sf;
9813 /* Set the visible flags for all frames. Do this before checking
9814 for resized or garbaged frames; they want to know if their frames
9815 are visible. See the comment in frame.h for
9816 FRAME_SAMPLE_VISIBILITY. */
9818 Lisp_Object tail, frame;
9820 number_of_visible_frames = 0;
9822 FOR_EACH_FRAME (tail, frame)
9824 struct frame *f = XFRAME (frame);
9826 FRAME_SAMPLE_VISIBILITY (f);
9827 if (FRAME_VISIBLE_P (f))
9828 ++number_of_visible_frames;
9829 clear_desired_matrices (f);
9833 /* Notice any pending interrupt request to change frame size. */
9834 do_pending_window_change (1);
9836 /* Clear frames marked as garbaged. */
9837 if (frame_garbaged)
9838 clear_garbaged_frames ();
9840 /* Build menubar and tool-bar items. */
9841 prepare_menu_bars ();
9843 if (windows_or_buffers_changed)
9844 update_mode_lines++;
9846 /* Detect case that we need to write or remove a star in the mode line. */
9847 if ((SAVE_MODIFF < MODIFF) != !NILP (w->last_had_star))
9849 w->update_mode_line = Qt;
9850 if (buffer_shared > 1)
9851 update_mode_lines++;
9854 /* If %c is in the mode line, update it if needed. */
9855 if (!NILP (w->column_number_displayed)
9856 /* This alternative quickly identifies a common case
9857 where no change is needed. */
9858 && !(PT == XFASTINT (w->last_point)
9859 && XFASTINT (w->last_modified) >= MODIFF
9860 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
9861 && (XFASTINT (w->column_number_displayed)
9862 != (int) current_column ())) /* iftc */
9863 w->update_mode_line = Qt;
9865 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
9867 /* The variable buffer_shared is set in redisplay_window and
9868 indicates that we redisplay a buffer in different windows. See
9869 there. */
9870 consider_all_windows_p = (update_mode_lines || buffer_shared > 1
9871 || cursor_type_changed);
9873 /* If specs for an arrow have changed, do thorough redisplay
9874 to ensure we remove any arrow that should no longer exist. */
9875 if (overlay_arrows_changed_p ())
9876 consider_all_windows_p = windows_or_buffers_changed = 1;
9878 /* Normally the message* functions will have already displayed and
9879 updated the echo area, but the frame may have been trashed, or
9880 the update may have been preempted, so display the echo area
9881 again here. Checking message_cleared_p captures the case that
9882 the echo area should be cleared. */
9883 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
9884 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
9885 || (message_cleared_p
9886 && minibuf_level == 0
9887 /* If the mini-window is currently selected, this means the
9888 echo-area doesn't show through. */
9889 && !MINI_WINDOW_P (XWINDOW (selected_window))))
9891 int window_height_changed_p = echo_area_display (0);
9892 must_finish = 1;
9894 /* If we don't display the current message, don't clear the
9895 message_cleared_p flag, because, if we did, we wouldn't clear
9896 the echo area in the next redisplay which doesn't preserve
9897 the echo area. */
9898 if (!display_last_displayed_message_p)
9899 message_cleared_p = 0;
9901 if (fonts_changed_p)
9902 goto retry;
9903 else if (window_height_changed_p)
9905 consider_all_windows_p = 1;
9906 ++update_mode_lines;
9907 ++windows_or_buffers_changed;
9909 /* If window configuration was changed, frames may have been
9910 marked garbaged. Clear them or we will experience
9911 surprises wrt scrolling. */
9912 if (frame_garbaged)
9913 clear_garbaged_frames ();
9916 else if (EQ (selected_window, minibuf_window)
9917 && (current_buffer->clip_changed
9918 || XFASTINT (w->last_modified) < MODIFF
9919 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
9920 && resize_mini_window (w, 0))
9922 /* Resized active mini-window to fit the size of what it is
9923 showing if its contents might have changed. */
9924 must_finish = 1;
9925 consider_all_windows_p = 1;
9926 ++windows_or_buffers_changed;
9927 ++update_mode_lines;
9929 /* If window configuration was changed, frames may have been
9930 marked garbaged. Clear them or we will experience
9931 surprises wrt scrolling. */
9932 if (frame_garbaged)
9933 clear_garbaged_frames ();
9937 /* If showing the region, and mark has changed, we must redisplay
9938 the whole window. The assignment to this_line_start_pos prevents
9939 the optimization directly below this if-statement. */
9940 if (((!NILP (Vtransient_mark_mode)
9941 && !NILP (XBUFFER (w->buffer)->mark_active))
9942 != !NILP (w->region_showing))
9943 || (!NILP (w->region_showing)
9944 && !EQ (w->region_showing,
9945 Fmarker_position (XBUFFER (w->buffer)->mark))))
9946 CHARPOS (this_line_start_pos) = 0;
9948 /* Optimize the case that only the line containing the cursor in the
9949 selected window has changed. Variables starting with this_ are
9950 set in display_line and record information about the line
9951 containing the cursor. */
9952 tlbufpos = this_line_start_pos;
9953 tlendpos = this_line_end_pos;
9954 if (!consider_all_windows_p
9955 && CHARPOS (tlbufpos) > 0
9956 && NILP (w->update_mode_line)
9957 && !current_buffer->clip_changed
9958 && !current_buffer->prevent_redisplay_optimizations_p
9959 && FRAME_VISIBLE_P (XFRAME (w->frame))
9960 && !FRAME_OBSCURED_P (XFRAME (w->frame))
9961 /* Make sure recorded data applies to current buffer, etc. */
9962 && this_line_buffer == current_buffer
9963 && current_buffer == XBUFFER (w->buffer)
9964 && NILP (w->force_start)
9965 && NILP (w->optional_new_start)
9966 /* Point must be on the line that we have info recorded about. */
9967 && PT >= CHARPOS (tlbufpos)
9968 && PT <= Z - CHARPOS (tlendpos)
9969 /* All text outside that line, including its final newline,
9970 must be unchanged */
9971 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
9972 CHARPOS (tlendpos)))
9974 if (CHARPOS (tlbufpos) > BEGV
9975 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
9976 && (CHARPOS (tlbufpos) == ZV
9977 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
9978 /* Former continuation line has disappeared by becoming empty */
9979 goto cancel;
9980 else if (XFASTINT (w->last_modified) < MODIFF
9981 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF
9982 || MINI_WINDOW_P (w))
9984 /* We have to handle the case of continuation around a
9985 wide-column character (See the comment in indent.c around
9986 line 885).
9988 For instance, in the following case:
9990 -------- Insert --------
9991 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
9992 J_I_ ==> J_I_ `^^' are cursors.
9993 ^^ ^^
9994 -------- --------
9996 As we have to redraw the line above, we should goto cancel. */
9998 struct it it;
9999 int line_height_before = this_line_pixel_height;
10001 /* Note that start_display will handle the case that the
10002 line starting at tlbufpos is a continuation lines. */
10003 start_display (&it, w, tlbufpos);
10005 /* Implementation note: It this still necessary? */
10006 if (it.current_x != this_line_start_x)
10007 goto cancel;
10009 TRACE ((stderr, "trying display optimization 1\n"));
10010 w->cursor.vpos = -1;
10011 overlay_arrow_seen = 0;
10012 it.vpos = this_line_vpos;
10013 it.current_y = this_line_y;
10014 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
10015 display_line (&it);
10017 /* If line contains point, is not continued,
10018 and ends at same distance from eob as before, we win */
10019 if (w->cursor.vpos >= 0
10020 /* Line is not continued, otherwise this_line_start_pos
10021 would have been set to 0 in display_line. */
10022 && CHARPOS (this_line_start_pos)
10023 /* Line ends as before. */
10024 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
10025 /* Line has same height as before. Otherwise other lines
10026 would have to be shifted up or down. */
10027 && this_line_pixel_height == line_height_before)
10029 /* If this is not the window's last line, we must adjust
10030 the charstarts of the lines below. */
10031 if (it.current_y < it.last_visible_y)
10033 struct glyph_row *row
10034 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
10035 int delta, delta_bytes;
10037 if (Z - CHARPOS (tlendpos) == ZV)
10039 /* This line ends at end of (accessible part of)
10040 buffer. There is no newline to count. */
10041 delta = (Z
10042 - CHARPOS (tlendpos)
10043 - MATRIX_ROW_START_CHARPOS (row));
10044 delta_bytes = (Z_BYTE
10045 - BYTEPOS (tlendpos)
10046 - MATRIX_ROW_START_BYTEPOS (row));
10048 else
10050 /* This line ends in a newline. Must take
10051 account of the newline and the rest of the
10052 text that follows. */
10053 delta = (Z
10054 - CHARPOS (tlendpos)
10055 - MATRIX_ROW_START_CHARPOS (row));
10056 delta_bytes = (Z_BYTE
10057 - BYTEPOS (tlendpos)
10058 - MATRIX_ROW_START_BYTEPOS (row));
10061 increment_matrix_positions (w->current_matrix,
10062 this_line_vpos + 1,
10063 w->current_matrix->nrows,
10064 delta, delta_bytes);
10067 /* If this row displays text now but previously didn't,
10068 or vice versa, w->window_end_vpos may have to be
10069 adjusted. */
10070 if ((it.glyph_row - 1)->displays_text_p)
10072 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
10073 XSETINT (w->window_end_vpos, this_line_vpos);
10075 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
10076 && this_line_vpos > 0)
10077 XSETINT (w->window_end_vpos, this_line_vpos - 1);
10078 w->window_end_valid = Qnil;
10080 /* Update hint: No need to try to scroll in update_window. */
10081 w->desired_matrix->no_scrolling_p = 1;
10083 #if GLYPH_DEBUG
10084 *w->desired_matrix->method = 0;
10085 debug_method_add (w, "optimization 1");
10086 #endif
10087 #ifdef HAVE_WINDOW_SYSTEM
10088 update_window_fringes (w, 0);
10089 #endif
10090 goto update;
10092 else
10093 goto cancel;
10095 else if (/* Cursor position hasn't changed. */
10096 PT == XFASTINT (w->last_point)
10097 /* Make sure the cursor was last displayed
10098 in this window. Otherwise we have to reposition it. */
10099 && 0 <= w->cursor.vpos
10100 && WINDOW_TOTAL_LINES (w) > w->cursor.vpos)
10102 if (!must_finish)
10104 do_pending_window_change (1);
10106 /* We used to always goto end_of_redisplay here, but this
10107 isn't enough if we have a blinking cursor. */
10108 if (w->cursor_off_p == w->last_cursor_off_p)
10109 goto end_of_redisplay;
10111 goto update;
10113 /* If highlighting the region, or if the cursor is in the echo area,
10114 then we can't just move the cursor. */
10115 else if (! (!NILP (Vtransient_mark_mode)
10116 && !NILP (current_buffer->mark_active))
10117 && (EQ (selected_window, current_buffer->last_selected_window)
10118 || highlight_nonselected_windows)
10119 && NILP (w->region_showing)
10120 && NILP (Vshow_trailing_whitespace)
10121 && !cursor_in_echo_area)
10123 struct it it;
10124 struct glyph_row *row;
10126 /* Skip from tlbufpos to PT and see where it is. Note that
10127 PT may be in invisible text. If so, we will end at the
10128 next visible position. */
10129 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
10130 NULL, DEFAULT_FACE_ID);
10131 it.current_x = this_line_start_x;
10132 it.current_y = this_line_y;
10133 it.vpos = this_line_vpos;
10135 /* The call to move_it_to stops in front of PT, but
10136 moves over before-strings. */
10137 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
10139 if (it.vpos == this_line_vpos
10140 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
10141 row->enabled_p))
10143 xassert (this_line_vpos == it.vpos);
10144 xassert (this_line_y == it.current_y);
10145 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
10146 #if GLYPH_DEBUG
10147 *w->desired_matrix->method = 0;
10148 debug_method_add (w, "optimization 3");
10149 #endif
10150 goto update;
10152 else
10153 goto cancel;
10156 cancel:
10157 /* Text changed drastically or point moved off of line. */
10158 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
10161 CHARPOS (this_line_start_pos) = 0;
10162 consider_all_windows_p |= buffer_shared > 1;
10163 ++clear_face_cache_count;
10166 /* Build desired matrices, and update the display. If
10167 consider_all_windows_p is non-zero, do it for all windows on all
10168 frames. Otherwise do it for selected_window, only. */
10170 if (consider_all_windows_p)
10172 Lisp_Object tail, frame;
10173 int i, n = 0, size = 50;
10174 struct frame **updated
10175 = (struct frame **) alloca (size * sizeof *updated);
10177 /* Clear the face cache eventually. */
10178 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
10180 clear_face_cache (0);
10181 clear_face_cache_count = 0;
10184 /* Recompute # windows showing selected buffer. This will be
10185 incremented each time such a window is displayed. */
10186 buffer_shared = 0;
10188 FOR_EACH_FRAME (tail, frame)
10190 struct frame *f = XFRAME (frame);
10192 if (FRAME_WINDOW_P (f) || f == sf)
10194 if (! EQ (frame, selected_frame))
10195 /* Select the frame, for the sake of frame-local
10196 variables. */
10197 select_frame_for_redisplay (frame);
10199 #ifdef HAVE_WINDOW_SYSTEM
10200 if (clear_face_cache_count % 50 == 0
10201 && FRAME_WINDOW_P (f))
10202 clear_image_cache (f, 0);
10203 #endif /* HAVE_WINDOW_SYSTEM */
10205 /* Mark all the scroll bars to be removed; we'll redeem
10206 the ones we want when we redisplay their windows. */
10207 if (condemn_scroll_bars_hook)
10208 condemn_scroll_bars_hook (f);
10210 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
10211 redisplay_windows (FRAME_ROOT_WINDOW (f));
10213 /* Any scroll bars which redisplay_windows should have
10214 nuked should now go away. */
10215 if (judge_scroll_bars_hook)
10216 judge_scroll_bars_hook (f);
10218 /* If fonts changed, display again. */
10219 /* ??? rms: I suspect it is a mistake to jump all the way
10220 back to retry here. It should just retry this frame. */
10221 if (fonts_changed_p)
10222 goto retry;
10224 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
10226 /* See if we have to hscroll. */
10227 if (hscroll_windows (f->root_window))
10228 goto retry;
10230 /* Prevent various kinds of signals during display
10231 update. stdio is not robust about handling
10232 signals, which can cause an apparent I/O
10233 error. */
10234 if (interrupt_input)
10235 unrequest_sigio ();
10236 STOP_POLLING;
10238 /* Update the display. */
10239 set_window_update_flags (XWINDOW (f->root_window), 1);
10240 pause |= update_frame (f, 0, 0);
10241 #if 0 /* Exiting the loop can leave the wrong value for buffer_shared. */
10242 if (pause)
10243 break;
10244 #endif
10246 if (n == size)
10248 int nbytes = size * sizeof *updated;
10249 struct frame **p = (struct frame **) alloca (2 * nbytes);
10250 bcopy (updated, p, nbytes);
10251 size *= 2;
10254 updated[n++] = f;
10259 if (!pause)
10261 /* Do the mark_window_display_accurate after all windows have
10262 been redisplayed because this call resets flags in buffers
10263 which are needed for proper redisplay. */
10264 for (i = 0; i < n; ++i)
10266 struct frame *f = updated[i];
10267 mark_window_display_accurate (f->root_window, 1);
10268 if (frame_up_to_date_hook)
10269 frame_up_to_date_hook (f);
10273 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
10275 Lisp_Object mini_window;
10276 struct frame *mini_frame;
10278 displayed_buffer = XBUFFER (XWINDOW (selected_window)->buffer);
10279 /* Use list_of_error, not Qerror, so that
10280 we catch only errors and don't run the debugger. */
10281 internal_condition_case_1 (redisplay_window_1, selected_window,
10282 list_of_error,
10283 redisplay_window_error);
10285 /* Compare desired and current matrices, perform output. */
10287 update:
10288 /* If fonts changed, display again. */
10289 if (fonts_changed_p)
10290 goto retry;
10292 /* Prevent various kinds of signals during display update.
10293 stdio is not robust about handling signals,
10294 which can cause an apparent I/O error. */
10295 if (interrupt_input)
10296 unrequest_sigio ();
10297 STOP_POLLING;
10299 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
10301 if (hscroll_windows (selected_window))
10302 goto retry;
10304 XWINDOW (selected_window)->must_be_updated_p = 1;
10305 pause = update_frame (sf, 0, 0);
10308 /* We may have called echo_area_display at the top of this
10309 function. If the echo area is on another frame, that may
10310 have put text on a frame other than the selected one, so the
10311 above call to update_frame would not have caught it. Catch
10312 it here. */
10313 mini_window = FRAME_MINIBUF_WINDOW (sf);
10314 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
10316 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
10318 XWINDOW (mini_window)->must_be_updated_p = 1;
10319 pause |= update_frame (mini_frame, 0, 0);
10320 if (!pause && hscroll_windows (mini_window))
10321 goto retry;
10325 /* If display was paused because of pending input, make sure we do a
10326 thorough update the next time. */
10327 if (pause)
10329 /* Prevent the optimization at the beginning of
10330 redisplay_internal that tries a single-line update of the
10331 line containing the cursor in the selected window. */
10332 CHARPOS (this_line_start_pos) = 0;
10334 /* Let the overlay arrow be updated the next time. */
10335 update_overlay_arrows (0);
10337 /* If we pause after scrolling, some rows in the current
10338 matrices of some windows are not valid. */
10339 if (!WINDOW_FULL_WIDTH_P (w)
10340 && !FRAME_WINDOW_P (XFRAME (w->frame)))
10341 update_mode_lines = 1;
10343 else
10345 if (!consider_all_windows_p)
10347 /* This has already been done above if
10348 consider_all_windows_p is set. */
10349 mark_window_display_accurate_1 (w, 1);
10351 /* Say overlay arrows are up to date. */
10352 update_overlay_arrows (1);
10354 if (frame_up_to_date_hook != 0)
10355 frame_up_to_date_hook (sf);
10358 update_mode_lines = 0;
10359 windows_or_buffers_changed = 0;
10360 cursor_type_changed = 0;
10363 /* Start SIGIO interrupts coming again. Having them off during the
10364 code above makes it less likely one will discard output, but not
10365 impossible, since there might be stuff in the system buffer here.
10366 But it is much hairier to try to do anything about that. */
10367 if (interrupt_input)
10368 request_sigio ();
10369 RESUME_POLLING;
10371 /* If a frame has become visible which was not before, redisplay
10372 again, so that we display it. Expose events for such a frame
10373 (which it gets when becoming visible) don't call the parts of
10374 redisplay constructing glyphs, so simply exposing a frame won't
10375 display anything in this case. So, we have to display these
10376 frames here explicitly. */
10377 if (!pause)
10379 Lisp_Object tail, frame;
10380 int new_count = 0;
10382 FOR_EACH_FRAME (tail, frame)
10384 int this_is_visible = 0;
10386 if (XFRAME (frame)->visible)
10387 this_is_visible = 1;
10388 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
10389 if (XFRAME (frame)->visible)
10390 this_is_visible = 1;
10392 if (this_is_visible)
10393 new_count++;
10396 if (new_count != number_of_visible_frames)
10397 windows_or_buffers_changed++;
10400 /* Change frame size now if a change is pending. */
10401 do_pending_window_change (1);
10403 /* If we just did a pending size change, or have additional
10404 visible frames, redisplay again. */
10405 if (windows_or_buffers_changed && !pause)
10406 goto retry;
10408 end_of_redisplay:
10409 unbind_to (count, Qnil);
10410 RESUME_POLLING;
10414 /* Redisplay, but leave alone any recent echo area message unless
10415 another message has been requested in its place.
10417 This is useful in situations where you need to redisplay but no
10418 user action has occurred, making it inappropriate for the message
10419 area to be cleared. See tracking_off and
10420 wait_reading_process_output for examples of these situations.
10422 FROM_WHERE is an integer saying from where this function was
10423 called. This is useful for debugging. */
10425 void
10426 redisplay_preserve_echo_area (from_where)
10427 int from_where;
10429 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
10431 if (!NILP (echo_area_buffer[1]))
10433 /* We have a previously displayed message, but no current
10434 message. Redisplay the previous message. */
10435 display_last_displayed_message_p = 1;
10436 redisplay_internal (1);
10437 display_last_displayed_message_p = 0;
10439 else
10440 redisplay_internal (1);
10442 if (rif != NULL && rif->flush_display_optional)
10443 rif->flush_display_optional (NULL);
10447 /* Function registered with record_unwind_protect in
10448 redisplay_internal. Reset redisplaying_p to the value it had
10449 before redisplay_internal was called, and clear
10450 prevent_freeing_realized_faces_p. It also selects the previously
10451 selected frame. */
10453 static Lisp_Object
10454 unwind_redisplay (val)
10455 Lisp_Object val;
10457 Lisp_Object old_redisplaying_p, old_frame;
10459 old_redisplaying_p = XCAR (val);
10460 redisplaying_p = XFASTINT (old_redisplaying_p);
10461 old_frame = XCDR (val);
10462 if (! EQ (old_frame, selected_frame))
10463 select_frame_for_redisplay (old_frame);
10464 return Qnil;
10468 /* Mark the display of window W as accurate or inaccurate. If
10469 ACCURATE_P is non-zero mark display of W as accurate. If
10470 ACCURATE_P is zero, arrange for W to be redisplayed the next time
10471 redisplay_internal is called. */
10473 static void
10474 mark_window_display_accurate_1 (w, accurate_p)
10475 struct window *w;
10476 int accurate_p;
10478 if (BUFFERP (w->buffer))
10480 struct buffer *b = XBUFFER (w->buffer);
10482 w->last_modified
10483 = make_number (accurate_p ? BUF_MODIFF (b) : 0);
10484 w->last_overlay_modified
10485 = make_number (accurate_p ? BUF_OVERLAY_MODIFF (b) : 0);
10486 w->last_had_star
10487 = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b) ? Qt : Qnil;
10489 if (accurate_p)
10491 b->clip_changed = 0;
10492 b->prevent_redisplay_optimizations_p = 0;
10494 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
10495 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
10496 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
10497 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
10499 w->current_matrix->buffer = b;
10500 w->current_matrix->begv = BUF_BEGV (b);
10501 w->current_matrix->zv = BUF_ZV (b);
10503 w->last_cursor = w->cursor;
10504 w->last_cursor_off_p = w->cursor_off_p;
10506 if (w == XWINDOW (selected_window))
10507 w->last_point = make_number (BUF_PT (b));
10508 else
10509 w->last_point = make_number (XMARKER (w->pointm)->charpos);
10513 if (accurate_p)
10515 w->window_end_valid = w->buffer;
10516 #if 0 /* This is incorrect with variable-height lines. */
10517 xassert (XINT (w->window_end_vpos)
10518 < (WINDOW_TOTAL_LINES (w)
10519 - (WINDOW_WANTS_MODELINE_P (w) ? 1 : 0)));
10520 #endif
10521 w->update_mode_line = Qnil;
10526 /* Mark the display of windows in the window tree rooted at WINDOW as
10527 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
10528 windows as accurate. If ACCURATE_P is zero, arrange for windows to
10529 be redisplayed the next time redisplay_internal is called. */
10531 void
10532 mark_window_display_accurate (window, accurate_p)
10533 Lisp_Object window;
10534 int accurate_p;
10536 struct window *w;
10538 for (; !NILP (window); window = w->next)
10540 w = XWINDOW (window);
10541 mark_window_display_accurate_1 (w, accurate_p);
10543 if (!NILP (w->vchild))
10544 mark_window_display_accurate (w->vchild, accurate_p);
10545 if (!NILP (w->hchild))
10546 mark_window_display_accurate (w->hchild, accurate_p);
10549 if (accurate_p)
10551 update_overlay_arrows (1);
10553 else
10555 /* Force a thorough redisplay the next time by setting
10556 last_arrow_position and last_arrow_string to t, which is
10557 unequal to any useful value of Voverlay_arrow_... */
10558 update_overlay_arrows (-1);
10563 /* Return value in display table DP (Lisp_Char_Table *) for character
10564 C. Since a display table doesn't have any parent, we don't have to
10565 follow parent. Do not call this function directly but use the
10566 macro DISP_CHAR_VECTOR. */
10568 Lisp_Object
10569 disp_char_vector (dp, c)
10570 struct Lisp_Char_Table *dp;
10571 int c;
10573 int code[4], i;
10574 Lisp_Object val;
10576 if (SINGLE_BYTE_CHAR_P (c))
10577 return (dp->contents[c]);
10579 SPLIT_CHAR (c, code[0], code[1], code[2]);
10580 if (code[1] < 32)
10581 code[1] = -1;
10582 else if (code[2] < 32)
10583 code[2] = -1;
10585 /* Here, the possible range of code[0] (== charset ID) is
10586 128..max_charset. Since the top level char table contains data
10587 for multibyte characters after 256th element, we must increment
10588 code[0] by 128 to get a correct index. */
10589 code[0] += 128;
10590 code[3] = -1; /* anchor */
10592 for (i = 0; code[i] >= 0; i++, dp = XCHAR_TABLE (val))
10594 val = dp->contents[code[i]];
10595 if (!SUB_CHAR_TABLE_P (val))
10596 return (NILP (val) ? dp->defalt : val);
10599 /* Here, val is a sub char table. We return the default value of
10600 it. */
10601 return (dp->defalt);
10606 /***********************************************************************
10607 Window Redisplay
10608 ***********************************************************************/
10610 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
10612 static void
10613 redisplay_windows (window)
10614 Lisp_Object window;
10616 while (!NILP (window))
10618 struct window *w = XWINDOW (window);
10620 if (!NILP (w->hchild))
10621 redisplay_windows (w->hchild);
10622 else if (!NILP (w->vchild))
10623 redisplay_windows (w->vchild);
10624 else
10626 displayed_buffer = XBUFFER (w->buffer);
10627 /* Use list_of_error, not Qerror, so that
10628 we catch only errors and don't run the debugger. */
10629 internal_condition_case_1 (redisplay_window_0, window,
10630 list_of_error,
10631 redisplay_window_error);
10634 window = w->next;
10638 static Lisp_Object
10639 redisplay_window_error ()
10641 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
10642 return Qnil;
10645 static Lisp_Object
10646 redisplay_window_0 (window)
10647 Lisp_Object window;
10649 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
10650 redisplay_window (window, 0);
10651 return Qnil;
10654 static Lisp_Object
10655 redisplay_window_1 (window)
10656 Lisp_Object window;
10658 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
10659 redisplay_window (window, 1);
10660 return Qnil;
10664 /* Increment GLYPH until it reaches END or CONDITION fails while
10665 adding (GLYPH)->pixel_width to X. */
10667 #define SKIP_GLYPHS(glyph, end, x, condition) \
10668 do \
10670 (x) += (glyph)->pixel_width; \
10671 ++(glyph); \
10673 while ((glyph) < (end) && (condition))
10676 /* Set cursor position of W. PT is assumed to be displayed in ROW.
10677 DELTA is the number of bytes by which positions recorded in ROW
10678 differ from current buffer positions. */
10680 void
10681 set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
10682 struct window *w;
10683 struct glyph_row *row;
10684 struct glyph_matrix *matrix;
10685 int delta, delta_bytes, dy, dvpos;
10687 struct glyph *glyph = row->glyphs[TEXT_AREA];
10688 struct glyph *end = glyph + row->used[TEXT_AREA];
10689 struct glyph *cursor = NULL;
10690 /* The first glyph that starts a sequence of glyphs from string. */
10691 struct glyph *string_start;
10692 /* The X coordinate of string_start. */
10693 int string_start_x;
10694 /* The last known character position. */
10695 int last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
10696 /* The last known character position before string_start. */
10697 int string_before_pos;
10698 int x = row->x;
10699 int cursor_x = x;
10700 int cursor_from_overlay_pos = 0;
10701 int pt_old = PT - delta;
10703 /* Skip over glyphs not having an object at the start of the row.
10704 These are special glyphs like truncation marks on terminal
10705 frames. */
10706 if (row->displays_text_p)
10707 while (glyph < end
10708 && INTEGERP (glyph->object)
10709 && glyph->charpos < 0)
10711 x += glyph->pixel_width;
10712 ++glyph;
10715 string_start = NULL;
10716 while (glyph < end
10717 && !INTEGERP (glyph->object)
10718 && (!BUFFERP (glyph->object)
10719 || (last_pos = glyph->charpos) < pt_old))
10721 if (! STRINGP (glyph->object))
10723 string_start = NULL;
10724 x += glyph->pixel_width;
10725 ++glyph;
10726 if (cursor_from_overlay_pos
10727 && last_pos > cursor_from_overlay_pos)
10729 cursor_from_overlay_pos = 0;
10730 cursor = 0;
10733 else
10735 string_before_pos = last_pos;
10736 string_start = glyph;
10737 string_start_x = x;
10738 /* Skip all glyphs from string. */
10741 int pos;
10742 if ((cursor == NULL || glyph > cursor)
10743 && !NILP (Fget_char_property (make_number ((glyph)->charpos),
10744 Qcursor, (glyph)->object))
10745 && (pos = string_buffer_position (w, glyph->object,
10746 string_before_pos),
10747 (pos == 0 /* From overlay */
10748 || pos == pt_old)))
10750 /* Estimate overlay buffer position from the buffer
10751 positions of the glyphs before and after the overlay.
10752 Add 1 to last_pos so that if point corresponds to the
10753 glyph right after the overlay, we still use a 'cursor'
10754 property found in that overlay. */
10755 cursor_from_overlay_pos = pos == 0 ? last_pos+1 : 0;
10756 cursor = glyph;
10757 cursor_x = x;
10759 x += glyph->pixel_width;
10760 ++glyph;
10762 while (glyph < end && STRINGP (glyph->object));
10766 if (cursor != NULL)
10768 glyph = cursor;
10769 x = cursor_x;
10771 else if (string_start
10772 && (glyph == end || !BUFFERP (glyph->object) || last_pos > pt_old))
10774 /* We may have skipped over point because the previous glyphs
10775 are from string. As there's no easy way to know the
10776 character position of the current glyph, find the correct
10777 glyph on point by scanning from string_start again. */
10778 Lisp_Object limit;
10779 Lisp_Object string;
10780 int pos;
10782 limit = make_number (pt_old + 1);
10783 end = glyph;
10784 glyph = string_start;
10785 x = string_start_x;
10786 string = glyph->object;
10787 pos = string_buffer_position (w, string, string_before_pos);
10788 /* If STRING is from overlay, LAST_POS == 0. We skip such glyphs
10789 because we always put cursor after overlay strings. */
10790 while (pos == 0 && glyph < end)
10792 string = glyph->object;
10793 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10794 if (glyph < end)
10795 pos = string_buffer_position (w, glyph->object, string_before_pos);
10798 while (glyph < end)
10800 pos = XINT (Fnext_single_char_property_change
10801 (make_number (pos), Qdisplay, Qnil, limit));
10802 if (pos > pt_old)
10803 break;
10804 /* Skip glyphs from the same string. */
10805 string = glyph->object;
10806 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10807 /* Skip glyphs from an overlay. */
10808 while (glyph < end
10809 && ! string_buffer_position (w, glyph->object, pos))
10811 string = glyph->object;
10812 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10817 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
10818 w->cursor.x = x;
10819 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
10820 w->cursor.y = row->y + dy;
10822 if (w == XWINDOW (selected_window))
10824 if (!row->continued_p
10825 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
10826 && row->x == 0)
10828 this_line_buffer = XBUFFER (w->buffer);
10830 CHARPOS (this_line_start_pos)
10831 = MATRIX_ROW_START_CHARPOS (row) + delta;
10832 BYTEPOS (this_line_start_pos)
10833 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
10835 CHARPOS (this_line_end_pos)
10836 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
10837 BYTEPOS (this_line_end_pos)
10838 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
10840 this_line_y = w->cursor.y;
10841 this_line_pixel_height = row->height;
10842 this_line_vpos = w->cursor.vpos;
10843 this_line_start_x = row->x;
10845 else
10846 CHARPOS (this_line_start_pos) = 0;
10851 /* Run window scroll functions, if any, for WINDOW with new window
10852 start STARTP. Sets the window start of WINDOW to that position.
10854 We assume that the window's buffer is really current. */
10856 static INLINE struct text_pos
10857 run_window_scroll_functions (window, startp)
10858 Lisp_Object window;
10859 struct text_pos startp;
10861 struct window *w = XWINDOW (window);
10862 SET_MARKER_FROM_TEXT_POS (w->start, startp);
10864 if (current_buffer != XBUFFER (w->buffer))
10865 abort ();
10867 if (!NILP (Vwindow_scroll_functions))
10869 run_hook_with_args_2 (Qwindow_scroll_functions, window,
10870 make_number (CHARPOS (startp)));
10871 SET_TEXT_POS_FROM_MARKER (startp, w->start);
10872 /* In case the hook functions switch buffers. */
10873 if (current_buffer != XBUFFER (w->buffer))
10874 set_buffer_internal_1 (XBUFFER (w->buffer));
10877 return startp;
10881 /* Make sure the line containing the cursor is fully visible.
10882 A value of 1 means there is nothing to be done.
10883 (Either the line is fully visible, or it cannot be made so,
10884 or we cannot tell.)
10886 If FORCE_P is non-zero, return 0 even if partial visible cursor row
10887 is higher than window.
10889 A value of 0 means the caller should do scrolling
10890 as if point had gone off the screen. */
10892 static int
10893 make_cursor_line_fully_visible (w, force_p)
10894 struct window *w;
10895 int force_p;
10897 struct glyph_matrix *matrix;
10898 struct glyph_row *row;
10899 int window_height;
10901 if (!make_cursor_line_fully_visible_p)
10902 return 1;
10904 /* It's not always possible to find the cursor, e.g, when a window
10905 is full of overlay strings. Don't do anything in that case. */
10906 if (w->cursor.vpos < 0)
10907 return 1;
10909 matrix = w->desired_matrix;
10910 row = MATRIX_ROW (matrix, w->cursor.vpos);
10912 /* If the cursor row is not partially visible, there's nothing to do. */
10913 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row))
10914 return 1;
10916 /* If the row the cursor is in is taller than the window's height,
10917 it's not clear what to do, so do nothing. */
10918 window_height = window_box_height (w);
10919 if (row->height >= window_height)
10921 if (!force_p || w->vscroll)
10922 return 1;
10924 return 0;
10926 #if 0
10927 /* This code used to try to scroll the window just enough to make
10928 the line visible. It returned 0 to say that the caller should
10929 allocate larger glyph matrices. */
10931 if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row))
10933 int dy = row->height - row->visible_height;
10934 w->vscroll = 0;
10935 w->cursor.y += dy;
10936 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
10938 else /* MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row)) */
10940 int dy = - (row->height - row->visible_height);
10941 w->vscroll = dy;
10942 w->cursor.y += dy;
10943 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
10946 /* When we change the cursor y-position of the selected window,
10947 change this_line_y as well so that the display optimization for
10948 the cursor line of the selected window in redisplay_internal uses
10949 the correct y-position. */
10950 if (w == XWINDOW (selected_window))
10951 this_line_y = w->cursor.y;
10953 /* If vscrolling requires a larger glyph matrix, arrange for a fresh
10954 redisplay with larger matrices. */
10955 if (matrix->nrows < required_matrix_height (w))
10957 fonts_changed_p = 1;
10958 return 0;
10961 return 1;
10962 #endif /* 0 */
10966 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
10967 non-zero means only WINDOW is redisplayed in redisplay_internal.
10968 TEMP_SCROLL_STEP has the same meaning as scroll_step, and is used
10969 in redisplay_window to bring a partially visible line into view in
10970 the case that only the cursor has moved.
10972 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
10973 last screen line's vertical height extends past the end of the screen.
10975 Value is
10977 1 if scrolling succeeded
10979 0 if scrolling didn't find point.
10981 -1 if new fonts have been loaded so that we must interrupt
10982 redisplay, adjust glyph matrices, and try again. */
10984 enum
10986 SCROLLING_SUCCESS,
10987 SCROLLING_FAILED,
10988 SCROLLING_NEED_LARGER_MATRICES
10991 static int
10992 try_scrolling (window, just_this_one_p, scroll_conservatively,
10993 scroll_step, temp_scroll_step, last_line_misfit)
10994 Lisp_Object window;
10995 int just_this_one_p;
10996 EMACS_INT scroll_conservatively, scroll_step;
10997 int temp_scroll_step;
10998 int last_line_misfit;
11000 struct window *w = XWINDOW (window);
11001 struct frame *f = XFRAME (w->frame);
11002 struct text_pos scroll_margin_pos;
11003 struct text_pos pos;
11004 struct text_pos startp;
11005 struct it it;
11006 Lisp_Object window_end;
11007 int this_scroll_margin;
11008 int dy = 0;
11009 int scroll_max;
11010 int rc;
11011 int amount_to_scroll = 0;
11012 Lisp_Object aggressive;
11013 int height;
11014 int extra_scroll_margin_lines = last_line_misfit ? 1 : 0;
11016 #if GLYPH_DEBUG
11017 debug_method_add (w, "try_scrolling");
11018 #endif
11020 SET_TEXT_POS_FROM_MARKER (startp, w->start);
11022 /* Compute scroll margin height in pixels. We scroll when point is
11023 within this distance from the top or bottom of the window. */
11024 if (scroll_margin > 0)
11026 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
11027 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
11029 else
11030 this_scroll_margin = 0;
11032 /* Force scroll_conservatively to have a reasonable value so it doesn't
11033 cause an overflow while computing how much to scroll. */
11034 if (scroll_conservatively)
11035 scroll_conservatively = min (scroll_conservatively,
11036 MOST_POSITIVE_FIXNUM / FRAME_LINE_HEIGHT (f));
11038 /* Compute how much we should try to scroll maximally to bring point
11039 into view. */
11040 if (scroll_step || scroll_conservatively || temp_scroll_step)
11041 scroll_max = max (scroll_step,
11042 max (scroll_conservatively, temp_scroll_step));
11043 else if (NUMBERP (current_buffer->scroll_down_aggressively)
11044 || NUMBERP (current_buffer->scroll_up_aggressively))
11045 /* We're trying to scroll because of aggressive scrolling
11046 but no scroll_step is set. Choose an arbitrary one. Maybe
11047 there should be a variable for this. */
11048 scroll_max = 10;
11049 else
11050 scroll_max = 0;
11051 scroll_max *= FRAME_LINE_HEIGHT (f);
11053 /* Decide whether we have to scroll down. Start at the window end
11054 and move this_scroll_margin up to find the position of the scroll
11055 margin. */
11056 window_end = Fwindow_end (window, Qt);
11058 too_near_end:
11060 CHARPOS (scroll_margin_pos) = XINT (window_end);
11061 BYTEPOS (scroll_margin_pos) = CHAR_TO_BYTE (CHARPOS (scroll_margin_pos));
11063 if (this_scroll_margin || extra_scroll_margin_lines)
11065 start_display (&it, w, scroll_margin_pos);
11066 if (this_scroll_margin)
11067 move_it_vertically_backward (&it, this_scroll_margin);
11068 if (extra_scroll_margin_lines)
11069 move_it_by_lines (&it, - extra_scroll_margin_lines, 0);
11070 scroll_margin_pos = it.current.pos;
11073 if (PT >= CHARPOS (scroll_margin_pos))
11075 int y0;
11077 /* Point is in the scroll margin at the bottom of the window, or
11078 below. Compute a new window start that makes point visible. */
11080 /* Compute the distance from the scroll margin to PT.
11081 Give up if the distance is greater than scroll_max. */
11082 start_display (&it, w, scroll_margin_pos);
11083 y0 = it.current_y;
11084 move_it_to (&it, PT, 0, it.last_visible_y, -1,
11085 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
11087 /* To make point visible, we have to move the window start
11088 down so that the line the cursor is in is visible, which
11089 means we have to add in the height of the cursor line. */
11090 dy = line_bottom_y (&it) - y0;
11092 if (dy > scroll_max)
11093 return SCROLLING_FAILED;
11095 /* Move the window start down. If scrolling conservatively,
11096 move it just enough down to make point visible. If
11097 scroll_step is set, move it down by scroll_step. */
11098 start_display (&it, w, startp);
11100 if (scroll_conservatively)
11101 /* Set AMOUNT_TO_SCROLL to at least one line,
11102 and at most scroll_conservatively lines. */
11103 amount_to_scroll
11104 = min (max (dy, FRAME_LINE_HEIGHT (f)),
11105 FRAME_LINE_HEIGHT (f) * scroll_conservatively);
11106 else if (scroll_step || temp_scroll_step)
11107 amount_to_scroll = scroll_max;
11108 else
11110 aggressive = current_buffer->scroll_up_aggressively;
11111 height = WINDOW_BOX_TEXT_HEIGHT (w);
11112 if (NUMBERP (aggressive))
11114 double float_amount = XFLOATINT (aggressive) * height;
11115 amount_to_scroll = float_amount;
11116 if (amount_to_scroll == 0 && float_amount > 0)
11117 amount_to_scroll = 1;
11121 if (amount_to_scroll <= 0)
11122 return SCROLLING_FAILED;
11124 /* If moving by amount_to_scroll leaves STARTP unchanged,
11125 move it down one screen line. */
11127 move_it_vertically (&it, amount_to_scroll);
11128 if (CHARPOS (it.current.pos) == CHARPOS (startp))
11129 move_it_by_lines (&it, 1, 1);
11130 startp = it.current.pos;
11132 else
11134 /* See if point is inside the scroll margin at the top of the
11135 window. */
11136 scroll_margin_pos = startp;
11137 if (this_scroll_margin)
11139 start_display (&it, w, startp);
11140 move_it_vertically (&it, this_scroll_margin);
11141 scroll_margin_pos = it.current.pos;
11144 if (PT < CHARPOS (scroll_margin_pos))
11146 /* Point is in the scroll margin at the top of the window or
11147 above what is displayed in the window. */
11148 int y0;
11150 /* Compute the vertical distance from PT to the scroll
11151 margin position. Give up if distance is greater than
11152 scroll_max. */
11153 SET_TEXT_POS (pos, PT, PT_BYTE);
11154 start_display (&it, w, pos);
11155 y0 = it.current_y;
11156 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
11157 it.last_visible_y, -1,
11158 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
11159 dy = it.current_y - y0;
11160 if (dy > scroll_max)
11161 return SCROLLING_FAILED;
11163 /* Compute new window start. */
11164 start_display (&it, w, startp);
11166 if (scroll_conservatively)
11167 amount_to_scroll
11168 = max (dy, FRAME_LINE_HEIGHT (f) * max (scroll_step, temp_scroll_step));
11169 else if (scroll_step || temp_scroll_step)
11170 amount_to_scroll = scroll_max;
11171 else
11173 aggressive = current_buffer->scroll_down_aggressively;
11174 height = WINDOW_BOX_TEXT_HEIGHT (w);
11175 if (NUMBERP (aggressive))
11177 double float_amount = XFLOATINT (aggressive) * height;
11178 amount_to_scroll = float_amount;
11179 if (amount_to_scroll == 0 && float_amount > 0)
11180 amount_to_scroll = 1;
11184 if (amount_to_scroll <= 0)
11185 return SCROLLING_FAILED;
11187 move_it_vertically_backward (&it, amount_to_scroll);
11188 startp = it.current.pos;
11192 /* Run window scroll functions. */
11193 startp = run_window_scroll_functions (window, startp);
11195 /* Display the window. Give up if new fonts are loaded, or if point
11196 doesn't appear. */
11197 if (!try_window (window, startp))
11198 rc = SCROLLING_NEED_LARGER_MATRICES;
11199 else if (w->cursor.vpos < 0)
11201 clear_glyph_matrix (w->desired_matrix);
11202 rc = SCROLLING_FAILED;
11204 else
11206 /* Maybe forget recorded base line for line number display. */
11207 if (!just_this_one_p
11208 || current_buffer->clip_changed
11209 || BEG_UNCHANGED < CHARPOS (startp))
11210 w->base_line_number = Qnil;
11212 /* If cursor ends up on a partially visible line,
11213 treat that as being off the bottom of the screen. */
11214 if (! make_cursor_line_fully_visible (w, extra_scroll_margin_lines <= 1))
11216 clear_glyph_matrix (w->desired_matrix);
11217 ++extra_scroll_margin_lines;
11218 goto too_near_end;
11220 rc = SCROLLING_SUCCESS;
11223 return rc;
11227 /* Compute a suitable window start for window W if display of W starts
11228 on a continuation line. Value is non-zero if a new window start
11229 was computed.
11231 The new window start will be computed, based on W's width, starting
11232 from the start of the continued line. It is the start of the
11233 screen line with the minimum distance from the old start W->start. */
11235 static int
11236 compute_window_start_on_continuation_line (w)
11237 struct window *w;
11239 struct text_pos pos, start_pos;
11240 int window_start_changed_p = 0;
11242 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
11244 /* If window start is on a continuation line... Window start may be
11245 < BEGV in case there's invisible text at the start of the
11246 buffer (M-x rmail, for example). */
11247 if (CHARPOS (start_pos) > BEGV
11248 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
11250 struct it it;
11251 struct glyph_row *row;
11253 /* Handle the case that the window start is out of range. */
11254 if (CHARPOS (start_pos) < BEGV)
11255 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
11256 else if (CHARPOS (start_pos) > ZV)
11257 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
11259 /* Find the start of the continued line. This should be fast
11260 because scan_buffer is fast (newline cache). */
11261 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
11262 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
11263 row, DEFAULT_FACE_ID);
11264 reseat_at_previous_visible_line_start (&it);
11266 /* If the line start is "too far" away from the window start,
11267 say it takes too much time to compute a new window start. */
11268 if (CHARPOS (start_pos) - IT_CHARPOS (it)
11269 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
11271 int min_distance, distance;
11273 /* Move forward by display lines to find the new window
11274 start. If window width was enlarged, the new start can
11275 be expected to be > the old start. If window width was
11276 decreased, the new window start will be < the old start.
11277 So, we're looking for the display line start with the
11278 minimum distance from the old window start. */
11279 pos = it.current.pos;
11280 min_distance = INFINITY;
11281 while ((distance = abs (CHARPOS (start_pos) - IT_CHARPOS (it))),
11282 distance < min_distance)
11284 min_distance = distance;
11285 pos = it.current.pos;
11286 move_it_by_lines (&it, 1, 0);
11289 /* Set the window start there. */
11290 SET_MARKER_FROM_TEXT_POS (w->start, pos);
11291 window_start_changed_p = 1;
11295 return window_start_changed_p;
11299 /* Try cursor movement in case text has not changed in window WINDOW,
11300 with window start STARTP. Value is
11302 CURSOR_MOVEMENT_SUCCESS if successful
11304 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
11306 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
11307 display. *SCROLL_STEP is set to 1, under certain circumstances, if
11308 we want to scroll as if scroll-step were set to 1. See the code.
11310 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
11311 which case we have to abort this redisplay, and adjust matrices
11312 first. */
11314 enum
11316 CURSOR_MOVEMENT_SUCCESS,
11317 CURSOR_MOVEMENT_CANNOT_BE_USED,
11318 CURSOR_MOVEMENT_MUST_SCROLL,
11319 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
11322 static int
11323 try_cursor_movement (window, startp, scroll_step)
11324 Lisp_Object window;
11325 struct text_pos startp;
11326 int *scroll_step;
11328 struct window *w = XWINDOW (window);
11329 struct frame *f = XFRAME (w->frame);
11330 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
11332 #if GLYPH_DEBUG
11333 if (inhibit_try_cursor_movement)
11334 return rc;
11335 #endif
11337 /* Handle case where text has not changed, only point, and it has
11338 not moved off the frame. */
11339 if (/* Point may be in this window. */
11340 PT >= CHARPOS (startp)
11341 /* Selective display hasn't changed. */
11342 && !current_buffer->clip_changed
11343 /* Function force-mode-line-update is used to force a thorough
11344 redisplay. It sets either windows_or_buffers_changed or
11345 update_mode_lines. So don't take a shortcut here for these
11346 cases. */
11347 && !update_mode_lines
11348 && !windows_or_buffers_changed
11349 && !cursor_type_changed
11350 /* Can't use this case if highlighting a region. When a
11351 region exists, cursor movement has to do more than just
11352 set the cursor. */
11353 && !(!NILP (Vtransient_mark_mode)
11354 && !NILP (current_buffer->mark_active))
11355 && NILP (w->region_showing)
11356 && NILP (Vshow_trailing_whitespace)
11357 /* Right after splitting windows, last_point may be nil. */
11358 && INTEGERP (w->last_point)
11359 /* This code is not used for mini-buffer for the sake of the case
11360 of redisplaying to replace an echo area message; since in
11361 that case the mini-buffer contents per se are usually
11362 unchanged. This code is of no real use in the mini-buffer
11363 since the handling of this_line_start_pos, etc., in redisplay
11364 handles the same cases. */
11365 && !EQ (window, minibuf_window)
11366 /* When splitting windows or for new windows, it happens that
11367 redisplay is called with a nil window_end_vpos or one being
11368 larger than the window. This should really be fixed in
11369 window.c. I don't have this on my list, now, so we do
11370 approximately the same as the old redisplay code. --gerd. */
11371 && INTEGERP (w->window_end_vpos)
11372 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
11373 && (FRAME_WINDOW_P (f)
11374 || !overlay_arrow_in_current_buffer_p ()))
11376 int this_scroll_margin, top_scroll_margin;
11377 struct glyph_row *row = NULL;
11379 #if GLYPH_DEBUG
11380 debug_method_add (w, "cursor movement");
11381 #endif
11383 /* Scroll if point within this distance from the top or bottom
11384 of the window. This is a pixel value. */
11385 this_scroll_margin = max (0, scroll_margin);
11386 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
11387 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
11389 top_scroll_margin = this_scroll_margin;
11390 if (WINDOW_WANTS_HEADER_LINE_P (w))
11391 top_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w);
11393 /* Start with the row the cursor was displayed during the last
11394 not paused redisplay. Give up if that row is not valid. */
11395 if (w->last_cursor.vpos < 0
11396 || w->last_cursor.vpos >= w->current_matrix->nrows)
11397 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11398 else
11400 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
11401 if (row->mode_line_p)
11402 ++row;
11403 if (!row->enabled_p)
11404 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11407 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
11409 int scroll_p = 0;
11410 int last_y = window_text_bottom_y (w) - this_scroll_margin;
11412 if (PT > XFASTINT (w->last_point))
11414 /* Point has moved forward. */
11415 while (MATRIX_ROW_END_CHARPOS (row) < PT
11416 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
11418 xassert (row->enabled_p);
11419 ++row;
11422 /* The end position of a row equals the start position
11423 of the next row. If PT is there, we would rather
11424 display it in the next line. */
11425 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
11426 && MATRIX_ROW_END_CHARPOS (row) == PT
11427 && !cursor_row_p (w, row))
11428 ++row;
11430 /* If within the scroll margin, scroll. Note that
11431 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
11432 the next line would be drawn, and that
11433 this_scroll_margin can be zero. */
11434 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
11435 || PT > MATRIX_ROW_END_CHARPOS (row)
11436 /* Line is completely visible last line in window
11437 and PT is to be set in the next line. */
11438 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
11439 && PT == MATRIX_ROW_END_CHARPOS (row)
11440 && !row->ends_at_zv_p
11441 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
11442 scroll_p = 1;
11444 else if (PT < XFASTINT (w->last_point))
11446 /* Cursor has to be moved backward. Note that PT >=
11447 CHARPOS (startp) because of the outer if-statement. */
11448 while (!row->mode_line_p
11449 && (MATRIX_ROW_START_CHARPOS (row) > PT
11450 || (MATRIX_ROW_START_CHARPOS (row) == PT
11451 && MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)))
11452 && (row->y > top_scroll_margin
11453 || CHARPOS (startp) == BEGV))
11455 xassert (row->enabled_p);
11456 --row;
11459 /* Consider the following case: Window starts at BEGV,
11460 there is invisible, intangible text at BEGV, so that
11461 display starts at some point START > BEGV. It can
11462 happen that we are called with PT somewhere between
11463 BEGV and START. Try to handle that case. */
11464 if (row < w->current_matrix->rows
11465 || row->mode_line_p)
11467 row = w->current_matrix->rows;
11468 if (row->mode_line_p)
11469 ++row;
11472 /* Due to newlines in overlay strings, we may have to
11473 skip forward over overlay strings. */
11474 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
11475 && MATRIX_ROW_END_CHARPOS (row) == PT
11476 && !cursor_row_p (w, row))
11477 ++row;
11479 /* If within the scroll margin, scroll. */
11480 if (row->y < top_scroll_margin
11481 && CHARPOS (startp) != BEGV)
11482 scroll_p = 1;
11485 if (PT < MATRIX_ROW_START_CHARPOS (row)
11486 || PT > MATRIX_ROW_END_CHARPOS (row))
11488 /* if PT is not in the glyph row, give up. */
11489 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11491 else if (MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
11492 && make_cursor_line_fully_visible_p)
11494 if (PT == MATRIX_ROW_END_CHARPOS (row)
11495 && !row->ends_at_zv_p
11496 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
11497 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11498 else if (row->height > window_box_height (w))
11500 /* If we end up in a partially visible line, let's
11501 make it fully visible, except when it's taller
11502 than the window, in which case we can't do much
11503 about it. */
11504 *scroll_step = 1;
11505 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11507 else
11509 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11510 if (!make_cursor_line_fully_visible (w, 0))
11511 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11512 else
11513 rc = CURSOR_MOVEMENT_SUCCESS;
11516 else if (scroll_p)
11517 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11518 else
11520 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11521 rc = CURSOR_MOVEMENT_SUCCESS;
11526 return rc;
11529 void
11530 set_vertical_scroll_bar (w)
11531 struct window *w;
11533 int start, end, whole;
11535 /* Calculate the start and end positions for the current window.
11536 At some point, it would be nice to choose between scrollbars
11537 which reflect the whole buffer size, with special markers
11538 indicating narrowing, and scrollbars which reflect only the
11539 visible region.
11541 Note that mini-buffers sometimes aren't displaying any text. */
11542 if (!MINI_WINDOW_P (w)
11543 || (w == XWINDOW (minibuf_window)
11544 && NILP (echo_area_buffer[0])))
11546 struct buffer *buf = XBUFFER (w->buffer);
11547 whole = BUF_ZV (buf) - BUF_BEGV (buf);
11548 start = marker_position (w->start) - BUF_BEGV (buf);
11549 /* I don't think this is guaranteed to be right. For the
11550 moment, we'll pretend it is. */
11551 end = BUF_Z (buf) - XFASTINT (w->window_end_pos) - BUF_BEGV (buf);
11553 if (end < start)
11554 end = start;
11555 if (whole < (end - start))
11556 whole = end - start;
11558 else
11559 start = end = whole = 0;
11561 /* Indicate what this scroll bar ought to be displaying now. */
11562 set_vertical_scroll_bar_hook (w, end - start, whole, start);
11566 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
11567 selected_window is redisplayed.
11569 We can return without actually redisplaying the window if
11570 fonts_changed_p is nonzero. In that case, redisplay_internal will
11571 retry. */
11573 static void
11574 redisplay_window (window, just_this_one_p)
11575 Lisp_Object window;
11576 int just_this_one_p;
11578 struct window *w = XWINDOW (window);
11579 struct frame *f = XFRAME (w->frame);
11580 struct buffer *buffer = XBUFFER (w->buffer);
11581 struct buffer *old = current_buffer;
11582 struct text_pos lpoint, opoint, startp;
11583 int update_mode_line;
11584 int tem;
11585 struct it it;
11586 /* Record it now because it's overwritten. */
11587 int current_matrix_up_to_date_p = 0;
11588 int used_current_matrix_p = 0;
11589 /* This is less strict than current_matrix_up_to_date_p.
11590 It indictes that the buffer contents and narrowing are unchanged. */
11591 int buffer_unchanged_p = 0;
11592 int temp_scroll_step = 0;
11593 int count = SPECPDL_INDEX ();
11594 int rc;
11595 int centering_position;
11596 int last_line_misfit = 0;
11598 SET_TEXT_POS (lpoint, PT, PT_BYTE);
11599 opoint = lpoint;
11601 /* W must be a leaf window here. */
11602 xassert (!NILP (w->buffer));
11603 #if GLYPH_DEBUG
11604 *w->desired_matrix->method = 0;
11605 #endif
11607 /* Force this to be looked up again for each redisp of each window. */
11608 escape_glyph_face = -1;
11610 specbind (Qinhibit_point_motion_hooks, Qt);
11612 reconsider_clip_changes (w, buffer);
11614 /* Has the mode line to be updated? */
11615 update_mode_line = (!NILP (w->update_mode_line)
11616 || update_mode_lines
11617 || buffer->clip_changed
11618 || buffer->prevent_redisplay_optimizations_p);
11620 if (MINI_WINDOW_P (w))
11622 if (w == XWINDOW (echo_area_window)
11623 && !NILP (echo_area_buffer[0]))
11625 if (update_mode_line)
11626 /* We may have to update a tty frame's menu bar or a
11627 tool-bar. Example `M-x C-h C-h C-g'. */
11628 goto finish_menu_bars;
11629 else
11630 /* We've already displayed the echo area glyphs in this window. */
11631 goto finish_scroll_bars;
11633 else if ((w != XWINDOW (minibuf_window)
11634 || minibuf_level == 0)
11635 /* When buffer is nonempty, redisplay window normally. */
11636 && BUF_Z (XBUFFER (w->buffer)) == BUF_BEG (XBUFFER (w->buffer))
11637 /* Quail displays non-mini buffers in minibuffer window.
11638 In that case, redisplay the window normally. */
11639 && !NILP (Fmemq (w->buffer, Vminibuffer_list)))
11641 /* W is a mini-buffer window, but it's not active, so clear
11642 it. */
11643 int yb = window_text_bottom_y (w);
11644 struct glyph_row *row;
11645 int y;
11647 for (y = 0, row = w->desired_matrix->rows;
11648 y < yb;
11649 y += row->height, ++row)
11650 blank_row (w, row, y);
11651 goto finish_scroll_bars;
11654 clear_glyph_matrix (w->desired_matrix);
11657 /* Otherwise set up data on this window; select its buffer and point
11658 value. */
11659 /* Really select the buffer, for the sake of buffer-local
11660 variables. */
11661 set_buffer_internal_1 (XBUFFER (w->buffer));
11662 SET_TEXT_POS (opoint, PT, PT_BYTE);
11664 current_matrix_up_to_date_p
11665 = (!NILP (w->window_end_valid)
11666 && !current_buffer->clip_changed
11667 && !current_buffer->prevent_redisplay_optimizations_p
11668 && XFASTINT (w->last_modified) >= MODIFF
11669 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
11671 buffer_unchanged_p
11672 = (!NILP (w->window_end_valid)
11673 && !current_buffer->clip_changed
11674 && XFASTINT (w->last_modified) >= MODIFF
11675 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
11677 /* When windows_or_buffers_changed is non-zero, we can't rely on
11678 the window end being valid, so set it to nil there. */
11679 if (windows_or_buffers_changed)
11681 /* If window starts on a continuation line, maybe adjust the
11682 window start in case the window's width changed. */
11683 if (XMARKER (w->start)->buffer == current_buffer)
11684 compute_window_start_on_continuation_line (w);
11686 w->window_end_valid = Qnil;
11689 /* Some sanity checks. */
11690 CHECK_WINDOW_END (w);
11691 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
11692 abort ();
11693 if (BYTEPOS (opoint) < CHARPOS (opoint))
11694 abort ();
11696 /* If %c is in mode line, update it if needed. */
11697 if (!NILP (w->column_number_displayed)
11698 /* This alternative quickly identifies a common case
11699 where no change is needed. */
11700 && !(PT == XFASTINT (w->last_point)
11701 && XFASTINT (w->last_modified) >= MODIFF
11702 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
11703 && (XFASTINT (w->column_number_displayed)
11704 != (int) current_column ())) /* iftc */
11705 update_mode_line = 1;
11707 /* Count number of windows showing the selected buffer. An indirect
11708 buffer counts as its base buffer. */
11709 if (!just_this_one_p)
11711 struct buffer *current_base, *window_base;
11712 current_base = current_buffer;
11713 window_base = XBUFFER (XWINDOW (selected_window)->buffer);
11714 if (current_base->base_buffer)
11715 current_base = current_base->base_buffer;
11716 if (window_base->base_buffer)
11717 window_base = window_base->base_buffer;
11718 if (current_base == window_base)
11719 buffer_shared++;
11722 /* Point refers normally to the selected window. For any other
11723 window, set up appropriate value. */
11724 if (!EQ (window, selected_window))
11726 int new_pt = XMARKER (w->pointm)->charpos;
11727 int new_pt_byte = marker_byte_position (w->pointm);
11728 if (new_pt < BEGV)
11730 new_pt = BEGV;
11731 new_pt_byte = BEGV_BYTE;
11732 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
11734 else if (new_pt > (ZV - 1))
11736 new_pt = ZV;
11737 new_pt_byte = ZV_BYTE;
11738 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
11741 /* We don't use SET_PT so that the point-motion hooks don't run. */
11742 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
11745 /* If any of the character widths specified in the display table
11746 have changed, invalidate the width run cache. It's true that
11747 this may be a bit late to catch such changes, but the rest of
11748 redisplay goes (non-fatally) haywire when the display table is
11749 changed, so why should we worry about doing any better? */
11750 if (current_buffer->width_run_cache)
11752 struct Lisp_Char_Table *disptab = buffer_display_table ();
11754 if (! disptab_matches_widthtab (disptab,
11755 XVECTOR (current_buffer->width_table)))
11757 invalidate_region_cache (current_buffer,
11758 current_buffer->width_run_cache,
11759 BEG, Z);
11760 recompute_width_table (current_buffer, disptab);
11764 /* If window-start is screwed up, choose a new one. */
11765 if (XMARKER (w->start)->buffer != current_buffer)
11766 goto recenter;
11768 SET_TEXT_POS_FROM_MARKER (startp, w->start);
11770 /* If someone specified a new starting point but did not insist,
11771 check whether it can be used. */
11772 if (!NILP (w->optional_new_start)
11773 && CHARPOS (startp) >= BEGV
11774 && CHARPOS (startp) <= ZV)
11776 w->optional_new_start = Qnil;
11777 start_display (&it, w, startp);
11778 move_it_to (&it, PT, 0, it.last_visible_y, -1,
11779 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
11780 if (IT_CHARPOS (it) == PT)
11781 w->force_start = Qt;
11782 /* IT may overshoot PT if text at PT is invisible. */
11783 else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT)
11784 w->force_start = Qt;
11789 /* Handle case where place to start displaying has been specified,
11790 unless the specified location is outside the accessible range. */
11791 if (!NILP (w->force_start)
11792 || w->frozen_window_start_p)
11794 /* We set this later on if we have to adjust point. */
11795 int new_vpos = -1;
11797 w->force_start = Qnil;
11798 w->vscroll = 0;
11799 w->window_end_valid = Qnil;
11801 /* Forget any recorded base line for line number display. */
11802 if (!buffer_unchanged_p)
11803 w->base_line_number = Qnil;
11805 /* Redisplay the mode line. Select the buffer properly for that.
11806 Also, run the hook window-scroll-functions
11807 because we have scrolled. */
11808 /* Note, we do this after clearing force_start because
11809 if there's an error, it is better to forget about force_start
11810 than to get into an infinite loop calling the hook functions
11811 and having them get more errors. */
11812 if (!update_mode_line
11813 || ! NILP (Vwindow_scroll_functions))
11815 update_mode_line = 1;
11816 w->update_mode_line = Qt;
11817 startp = run_window_scroll_functions (window, startp);
11820 w->last_modified = make_number (0);
11821 w->last_overlay_modified = make_number (0);
11822 if (CHARPOS (startp) < BEGV)
11823 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
11824 else if (CHARPOS (startp) > ZV)
11825 SET_TEXT_POS (startp, ZV, ZV_BYTE);
11827 /* Redisplay, then check if cursor has been set during the
11828 redisplay. Give up if new fonts were loaded. */
11829 if (!try_window (window, startp))
11831 w->force_start = Qt;
11832 clear_glyph_matrix (w->desired_matrix);
11833 goto need_larger_matrices;
11836 if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
11838 /* If point does not appear, try to move point so it does
11839 appear. The desired matrix has been built above, so we
11840 can use it here. */
11841 new_vpos = window_box_height (w) / 2;
11844 if (!make_cursor_line_fully_visible (w, 0))
11846 /* Point does appear, but on a line partly visible at end of window.
11847 Move it back to a fully-visible line. */
11848 new_vpos = window_box_height (w);
11851 /* If we need to move point for either of the above reasons,
11852 now actually do it. */
11853 if (new_vpos >= 0)
11855 struct glyph_row *row;
11857 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
11858 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
11859 ++row;
11861 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
11862 MATRIX_ROW_START_BYTEPOS (row));
11864 if (w != XWINDOW (selected_window))
11865 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
11866 else if (current_buffer == old)
11867 SET_TEXT_POS (lpoint, PT, PT_BYTE);
11869 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
11871 /* If we are highlighting the region, then we just changed
11872 the region, so redisplay to show it. */
11873 if (!NILP (Vtransient_mark_mode)
11874 && !NILP (current_buffer->mark_active))
11876 clear_glyph_matrix (w->desired_matrix);
11877 if (!try_window (window, startp))
11878 goto need_larger_matrices;
11882 #if GLYPH_DEBUG
11883 debug_method_add (w, "forced window start");
11884 #endif
11885 goto done;
11888 /* Handle case where text has not changed, only point, and it has
11889 not moved off the frame, and we are not retrying after hscroll.
11890 (current_matrix_up_to_date_p is nonzero when retrying.) */
11891 if (current_matrix_up_to_date_p
11892 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
11893 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
11895 switch (rc)
11897 case CURSOR_MOVEMENT_SUCCESS:
11898 used_current_matrix_p = 1;
11899 goto done;
11901 #if 0 /* try_cursor_movement never returns this value. */
11902 case CURSOR_MOVEMENT_NEED_LARGER_MATRICES:
11903 goto need_larger_matrices;
11904 #endif
11906 case CURSOR_MOVEMENT_MUST_SCROLL:
11907 goto try_to_scroll;
11909 default:
11910 abort ();
11913 /* If current starting point was originally the beginning of a line
11914 but no longer is, find a new starting point. */
11915 else if (!NILP (w->start_at_line_beg)
11916 && !(CHARPOS (startp) <= BEGV
11917 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
11919 #if GLYPH_DEBUG
11920 debug_method_add (w, "recenter 1");
11921 #endif
11922 goto recenter;
11925 /* Try scrolling with try_window_id. Value is > 0 if update has
11926 been done, it is -1 if we know that the same window start will
11927 not work. It is 0 if unsuccessful for some other reason. */
11928 else if ((tem = try_window_id (w)) != 0)
11930 #if GLYPH_DEBUG
11931 debug_method_add (w, "try_window_id %d", tem);
11932 #endif
11934 if (fonts_changed_p)
11935 goto need_larger_matrices;
11936 if (tem > 0)
11937 goto done;
11939 /* Otherwise try_window_id has returned -1 which means that we
11940 don't want the alternative below this comment to execute. */
11942 else if (CHARPOS (startp) >= BEGV
11943 && CHARPOS (startp) <= ZV
11944 && PT >= CHARPOS (startp)
11945 && (CHARPOS (startp) < ZV
11946 /* Avoid starting at end of buffer. */
11947 || CHARPOS (startp) == BEGV
11948 || (XFASTINT (w->last_modified) >= MODIFF
11949 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)))
11951 #if GLYPH_DEBUG
11952 debug_method_add (w, "same window start");
11953 #endif
11955 /* Try to redisplay starting at same place as before.
11956 If point has not moved off frame, accept the results. */
11957 if (!current_matrix_up_to_date_p
11958 /* Don't use try_window_reusing_current_matrix in this case
11959 because a window scroll function can have changed the
11960 buffer. */
11961 || !NILP (Vwindow_scroll_functions)
11962 || MINI_WINDOW_P (w)
11963 || !(used_current_matrix_p
11964 = try_window_reusing_current_matrix (w)))
11966 IF_DEBUG (debug_method_add (w, "1"));
11967 try_window (window, startp);
11970 if (fonts_changed_p)
11971 goto need_larger_matrices;
11973 if (w->cursor.vpos >= 0)
11975 if (!just_this_one_p
11976 || current_buffer->clip_changed
11977 || BEG_UNCHANGED < CHARPOS (startp))
11978 /* Forget any recorded base line for line number display. */
11979 w->base_line_number = Qnil;
11981 if (!make_cursor_line_fully_visible (w, 1))
11983 clear_glyph_matrix (w->desired_matrix);
11984 last_line_misfit = 1;
11986 /* Drop through and scroll. */
11987 else
11988 goto done;
11990 else
11991 clear_glyph_matrix (w->desired_matrix);
11994 try_to_scroll:
11996 w->last_modified = make_number (0);
11997 w->last_overlay_modified = make_number (0);
11999 /* Redisplay the mode line. Select the buffer properly for that. */
12000 if (!update_mode_line)
12002 update_mode_line = 1;
12003 w->update_mode_line = Qt;
12006 /* Try to scroll by specified few lines. */
12007 if ((scroll_conservatively
12008 || scroll_step
12009 || temp_scroll_step
12010 || NUMBERP (current_buffer->scroll_up_aggressively)
12011 || NUMBERP (current_buffer->scroll_down_aggressively))
12012 && !current_buffer->clip_changed
12013 && CHARPOS (startp) >= BEGV
12014 && CHARPOS (startp) <= ZV)
12016 /* The function returns -1 if new fonts were loaded, 1 if
12017 successful, 0 if not successful. */
12018 int rc = try_scrolling (window, just_this_one_p,
12019 scroll_conservatively,
12020 scroll_step,
12021 temp_scroll_step, last_line_misfit);
12022 switch (rc)
12024 case SCROLLING_SUCCESS:
12025 goto done;
12027 case SCROLLING_NEED_LARGER_MATRICES:
12028 goto need_larger_matrices;
12030 case SCROLLING_FAILED:
12031 break;
12033 default:
12034 abort ();
12038 /* Finally, just choose place to start which centers point */
12040 recenter:
12041 centering_position = window_box_height (w) / 2;
12043 point_at_top:
12044 /* Jump here with centering_position already set to 0. */
12046 #if GLYPH_DEBUG
12047 debug_method_add (w, "recenter");
12048 #endif
12050 /* w->vscroll = 0; */
12052 /* Forget any previously recorded base line for line number display. */
12053 if (!buffer_unchanged_p)
12054 w->base_line_number = Qnil;
12056 /* Move backward half the height of the window. */
12057 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
12058 it.current_y = it.last_visible_y;
12059 move_it_vertically_backward (&it, centering_position);
12060 xassert (IT_CHARPOS (it) >= BEGV);
12062 /* The function move_it_vertically_backward may move over more
12063 than the specified y-distance. If it->w is small, e.g. a
12064 mini-buffer window, we may end up in front of the window's
12065 display area. Start displaying at the start of the line
12066 containing PT in this case. */
12067 if (it.current_y <= 0)
12069 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
12070 move_it_vertically_backward (&it, 0);
12071 xassert (IT_CHARPOS (it) <= PT);
12072 it.current_y = 0;
12075 it.current_x = it.hpos = 0;
12077 /* Set startp here explicitly in case that helps avoid an infinite loop
12078 in case the window-scroll-functions functions get errors. */
12079 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
12081 /* Run scroll hooks. */
12082 startp = run_window_scroll_functions (window, it.current.pos);
12084 /* Redisplay the window. */
12085 if (!current_matrix_up_to_date_p
12086 || windows_or_buffers_changed
12087 || cursor_type_changed
12088 /* Don't use try_window_reusing_current_matrix in this case
12089 because it can have changed the buffer. */
12090 || !NILP (Vwindow_scroll_functions)
12091 || !just_this_one_p
12092 || MINI_WINDOW_P (w)
12093 || !(used_current_matrix_p
12094 = try_window_reusing_current_matrix (w)))
12095 try_window (window, startp);
12097 /* If new fonts have been loaded (due to fontsets), give up. We
12098 have to start a new redisplay since we need to re-adjust glyph
12099 matrices. */
12100 if (fonts_changed_p)
12101 goto need_larger_matrices;
12103 /* If cursor did not appear assume that the middle of the window is
12104 in the first line of the window. Do it again with the next line.
12105 (Imagine a window of height 100, displaying two lines of height
12106 60. Moving back 50 from it->last_visible_y will end in the first
12107 line.) */
12108 if (w->cursor.vpos < 0)
12110 if (!NILP (w->window_end_valid)
12111 && PT >= Z - XFASTINT (w->window_end_pos))
12113 clear_glyph_matrix (w->desired_matrix);
12114 move_it_by_lines (&it, 1, 0);
12115 try_window (window, it.current.pos);
12117 else if (PT < IT_CHARPOS (it))
12119 clear_glyph_matrix (w->desired_matrix);
12120 move_it_by_lines (&it, -1, 0);
12121 try_window (window, it.current.pos);
12123 else
12125 /* Not much we can do about it. */
12129 /* Consider the following case: Window starts at BEGV, there is
12130 invisible, intangible text at BEGV, so that display starts at
12131 some point START > BEGV. It can happen that we are called with
12132 PT somewhere between BEGV and START. Try to handle that case. */
12133 if (w->cursor.vpos < 0)
12135 struct glyph_row *row = w->current_matrix->rows;
12136 if (row->mode_line_p)
12137 ++row;
12138 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
12141 if (!make_cursor_line_fully_visible (w, centering_position > 0))
12143 /* If vscroll is enabled, disable it and try again. */
12144 if (w->vscroll)
12146 w->vscroll = 0;
12147 clear_glyph_matrix (w->desired_matrix);
12148 goto recenter;
12151 /* If centering point failed to make the whole line visible,
12152 put point at the top instead. That has to make the whole line
12153 visible, if it can be done. */
12154 clear_glyph_matrix (w->desired_matrix);
12155 centering_position = 0;
12156 goto point_at_top;
12159 done:
12161 SET_TEXT_POS_FROM_MARKER (startp, w->start);
12162 w->start_at_line_beg = ((CHARPOS (startp) == BEGV
12163 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n')
12164 ? Qt : Qnil);
12166 /* Display the mode line, if we must. */
12167 if ((update_mode_line
12168 /* If window not full width, must redo its mode line
12169 if (a) the window to its side is being redone and
12170 (b) we do a frame-based redisplay. This is a consequence
12171 of how inverted lines are drawn in frame-based redisplay. */
12172 || (!just_this_one_p
12173 && !FRAME_WINDOW_P (f)
12174 && !WINDOW_FULL_WIDTH_P (w))
12175 /* Line number to display. */
12176 || INTEGERP (w->base_line_pos)
12177 /* Column number is displayed and different from the one displayed. */
12178 || (!NILP (w->column_number_displayed)
12179 && (XFASTINT (w->column_number_displayed)
12180 != (int) current_column ()))) /* iftc */
12181 /* This means that the window has a mode line. */
12182 && (WINDOW_WANTS_MODELINE_P (w)
12183 || WINDOW_WANTS_HEADER_LINE_P (w)))
12185 display_mode_lines (w);
12187 /* If mode line height has changed, arrange for a thorough
12188 immediate redisplay using the correct mode line height. */
12189 if (WINDOW_WANTS_MODELINE_P (w)
12190 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
12192 fonts_changed_p = 1;
12193 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
12194 = DESIRED_MODE_LINE_HEIGHT (w);
12197 /* If top line height has changed, arrange for a thorough
12198 immediate redisplay using the correct mode line height. */
12199 if (WINDOW_WANTS_HEADER_LINE_P (w)
12200 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
12202 fonts_changed_p = 1;
12203 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
12204 = DESIRED_HEADER_LINE_HEIGHT (w);
12207 if (fonts_changed_p)
12208 goto need_larger_matrices;
12211 if (!line_number_displayed
12212 && !BUFFERP (w->base_line_pos))
12214 w->base_line_pos = Qnil;
12215 w->base_line_number = Qnil;
12218 finish_menu_bars:
12220 /* When we reach a frame's selected window, redo the frame's menu bar. */
12221 if (update_mode_line
12222 && EQ (FRAME_SELECTED_WINDOW (f), window))
12224 int redisplay_menu_p = 0;
12225 int redisplay_tool_bar_p = 0;
12227 if (FRAME_WINDOW_P (f))
12229 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
12230 || defined (USE_GTK)
12231 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
12232 #else
12233 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
12234 #endif
12236 else
12237 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
12239 if (redisplay_menu_p)
12240 display_menu_bar (w);
12242 #ifdef HAVE_WINDOW_SYSTEM
12243 #ifdef USE_GTK
12244 redisplay_tool_bar_p = FRAME_EXTERNAL_TOOL_BAR (f);
12245 #else
12246 redisplay_tool_bar_p = WINDOWP (f->tool_bar_window)
12247 && (FRAME_TOOL_BAR_LINES (f) > 0
12248 || auto_resize_tool_bars_p);
12250 #endif
12252 if (redisplay_tool_bar_p)
12253 redisplay_tool_bar (f);
12254 #endif
12257 #ifdef HAVE_WINDOW_SYSTEM
12258 if (FRAME_WINDOW_P (f)
12259 && update_window_fringes (w, 0)
12260 && !just_this_one_p
12261 && (used_current_matrix_p || overlay_arrow_seen)
12262 && !w->pseudo_window_p)
12264 update_begin (f);
12265 BLOCK_INPUT;
12266 if (draw_window_fringes (w, 1))
12267 x_draw_vertical_border (w);
12268 UNBLOCK_INPUT;
12269 update_end (f);
12271 #endif /* HAVE_WINDOW_SYSTEM */
12273 /* We go to this label, with fonts_changed_p nonzero,
12274 if it is necessary to try again using larger glyph matrices.
12275 We have to redeem the scroll bar even in this case,
12276 because the loop in redisplay_internal expects that. */
12277 need_larger_matrices:
12279 finish_scroll_bars:
12281 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
12283 /* Set the thumb's position and size. */
12284 set_vertical_scroll_bar (w);
12286 /* Note that we actually used the scroll bar attached to this
12287 window, so it shouldn't be deleted at the end of redisplay. */
12288 redeem_scroll_bar_hook (w);
12291 /* Restore current_buffer and value of point in it. */
12292 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
12293 set_buffer_internal_1 (old);
12294 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
12296 unbind_to (count, Qnil);
12300 /* Build the complete desired matrix of WINDOW with a window start
12301 buffer position POS. Value is non-zero if successful. It is zero
12302 if fonts were loaded during redisplay which makes re-adjusting
12303 glyph matrices necessary. */
12306 try_window (window, pos)
12307 Lisp_Object window;
12308 struct text_pos pos;
12310 struct window *w = XWINDOW (window);
12311 struct it it;
12312 struct glyph_row *last_text_row = NULL;
12314 /* Make POS the new window start. */
12315 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
12317 /* Mark cursor position as unknown. No overlay arrow seen. */
12318 w->cursor.vpos = -1;
12319 overlay_arrow_seen = 0;
12321 /* Initialize iterator and info to start at POS. */
12322 start_display (&it, w, pos);
12324 /* Display all lines of W. */
12325 while (it.current_y < it.last_visible_y)
12327 if (display_line (&it))
12328 last_text_row = it.glyph_row - 1;
12329 if (fonts_changed_p)
12330 return 0;
12333 /* If bottom moved off end of frame, change mode line percentage. */
12334 if (XFASTINT (w->window_end_pos) <= 0
12335 && Z != IT_CHARPOS (it))
12336 w->update_mode_line = Qt;
12338 /* Set window_end_pos to the offset of the last character displayed
12339 on the window from the end of current_buffer. Set
12340 window_end_vpos to its row number. */
12341 if (last_text_row)
12343 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
12344 w->window_end_bytepos
12345 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12346 w->window_end_pos
12347 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12348 w->window_end_vpos
12349 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12350 xassert (MATRIX_ROW (w->desired_matrix, XFASTINT (w->window_end_vpos))
12351 ->displays_text_p);
12353 else
12355 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
12356 w->window_end_pos = make_number (Z - ZV);
12357 w->window_end_vpos = make_number (0);
12360 /* But that is not valid info until redisplay finishes. */
12361 w->window_end_valid = Qnil;
12362 return 1;
12367 /************************************************************************
12368 Window redisplay reusing current matrix when buffer has not changed
12369 ************************************************************************/
12371 /* Try redisplay of window W showing an unchanged buffer with a
12372 different window start than the last time it was displayed by
12373 reusing its current matrix. Value is non-zero if successful.
12374 W->start is the new window start. */
12376 static int
12377 try_window_reusing_current_matrix (w)
12378 struct window *w;
12380 struct frame *f = XFRAME (w->frame);
12381 struct glyph_row *row, *bottom_row;
12382 struct it it;
12383 struct run run;
12384 struct text_pos start, new_start;
12385 int nrows_scrolled, i;
12386 struct glyph_row *last_text_row;
12387 struct glyph_row *last_reused_text_row;
12388 struct glyph_row *start_row;
12389 int start_vpos, min_y, max_y;
12391 #if GLYPH_DEBUG
12392 if (inhibit_try_window_reusing)
12393 return 0;
12394 #endif
12396 if (/* This function doesn't handle terminal frames. */
12397 !FRAME_WINDOW_P (f)
12398 /* Don't try to reuse the display if windows have been split
12399 or such. */
12400 || windows_or_buffers_changed
12401 || cursor_type_changed)
12402 return 0;
12404 /* Can't do this if region may have changed. */
12405 if ((!NILP (Vtransient_mark_mode)
12406 && !NILP (current_buffer->mark_active))
12407 || !NILP (w->region_showing)
12408 || !NILP (Vshow_trailing_whitespace))
12409 return 0;
12411 /* If top-line visibility has changed, give up. */
12412 if (WINDOW_WANTS_HEADER_LINE_P (w)
12413 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
12414 return 0;
12416 /* Give up if old or new display is scrolled vertically. We could
12417 make this function handle this, but right now it doesn't. */
12418 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12419 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row))
12420 return 0;
12422 /* The variable new_start now holds the new window start. The old
12423 start `start' can be determined from the current matrix. */
12424 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
12425 start = start_row->start.pos;
12426 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
12428 /* Clear the desired matrix for the display below. */
12429 clear_glyph_matrix (w->desired_matrix);
12431 if (CHARPOS (new_start) <= CHARPOS (start))
12433 int first_row_y;
12435 /* Don't use this method if the display starts with an ellipsis
12436 displayed for invisible text. It's not easy to handle that case
12437 below, and it's certainly not worth the effort since this is
12438 not a frequent case. */
12439 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
12440 return 0;
12442 IF_DEBUG (debug_method_add (w, "twu1"));
12444 /* Display up to a row that can be reused. The variable
12445 last_text_row is set to the last row displayed that displays
12446 text. Note that it.vpos == 0 if or if not there is a
12447 header-line; it's not the same as the MATRIX_ROW_VPOS! */
12448 start_display (&it, w, new_start);
12449 first_row_y = it.current_y;
12450 w->cursor.vpos = -1;
12451 last_text_row = last_reused_text_row = NULL;
12453 while (it.current_y < it.last_visible_y
12454 && !fonts_changed_p)
12456 /* If we have reached into the characters in the START row,
12457 that means the line boundaries have changed. So we
12458 can't start copying with the row START. Maybe it will
12459 work to start copying with the following row. */
12460 while (IT_CHARPOS (it) > CHARPOS (start))
12462 /* Advance to the next row as the "start". */
12463 start_row++;
12464 start = start_row->start.pos;
12465 /* If there are no more rows to try, or just one, give up. */
12466 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
12467 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row)
12468 || CHARPOS (start) == ZV)
12470 clear_glyph_matrix (w->desired_matrix);
12471 return 0;
12474 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
12476 /* If we have reached alignment,
12477 we can copy the rest of the rows. */
12478 if (IT_CHARPOS (it) == CHARPOS (start))
12479 break;
12481 if (display_line (&it))
12482 last_text_row = it.glyph_row - 1;
12485 /* A value of current_y < last_visible_y means that we stopped
12486 at the previous window start, which in turn means that we
12487 have at least one reusable row. */
12488 if (it.current_y < it.last_visible_y)
12490 /* IT.vpos always starts from 0; it counts text lines. */
12491 nrows_scrolled = it.vpos - (start_row - MATRIX_FIRST_TEXT_ROW (w->current_matrix));
12493 /* Find PT if not already found in the lines displayed. */
12494 if (w->cursor.vpos < 0)
12496 int dy = it.current_y - start_row->y;
12498 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12499 row = row_containing_pos (w, PT, row, NULL, dy);
12500 if (row)
12501 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
12502 dy, nrows_scrolled);
12503 else
12505 clear_glyph_matrix (w->desired_matrix);
12506 return 0;
12510 /* Scroll the display. Do it before the current matrix is
12511 changed. The problem here is that update has not yet
12512 run, i.e. part of the current matrix is not up to date.
12513 scroll_run_hook will clear the cursor, and use the
12514 current matrix to get the height of the row the cursor is
12515 in. */
12516 run.current_y = start_row->y;
12517 run.desired_y = it.current_y;
12518 run.height = it.last_visible_y - it.current_y;
12520 if (run.height > 0 && run.current_y != run.desired_y)
12522 update_begin (f);
12523 rif->update_window_begin_hook (w);
12524 rif->clear_window_mouse_face (w);
12525 rif->scroll_run_hook (w, &run);
12526 rif->update_window_end_hook (w, 0, 0);
12527 update_end (f);
12530 /* Shift current matrix down by nrows_scrolled lines. */
12531 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
12532 rotate_matrix (w->current_matrix,
12533 start_vpos,
12534 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
12535 nrows_scrolled);
12537 /* Disable lines that must be updated. */
12538 for (i = 0; i < it.vpos; ++i)
12539 (start_row + i)->enabled_p = 0;
12541 /* Re-compute Y positions. */
12542 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
12543 max_y = it.last_visible_y;
12544 for (row = start_row + nrows_scrolled;
12545 row < bottom_row;
12546 ++row)
12548 row->y = it.current_y;
12549 row->visible_height = row->height;
12551 if (row->y < min_y)
12552 row->visible_height -= min_y - row->y;
12553 if (row->y + row->height > max_y)
12554 row->visible_height -= row->y + row->height - max_y;
12555 row->redraw_fringe_bitmaps_p = 1;
12557 it.current_y += row->height;
12559 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
12560 last_reused_text_row = row;
12561 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
12562 break;
12565 /* Disable lines in the current matrix which are now
12566 below the window. */
12567 for (++row; row < bottom_row; ++row)
12568 row->enabled_p = 0;
12571 /* Update window_end_pos etc.; last_reused_text_row is the last
12572 reused row from the current matrix containing text, if any.
12573 The value of last_text_row is the last displayed line
12574 containing text. */
12575 if (last_reused_text_row)
12577 w->window_end_bytepos
12578 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
12579 w->window_end_pos
12580 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_reused_text_row));
12581 w->window_end_vpos
12582 = make_number (MATRIX_ROW_VPOS (last_reused_text_row,
12583 w->current_matrix));
12585 else if (last_text_row)
12587 w->window_end_bytepos
12588 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12589 w->window_end_pos
12590 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12591 w->window_end_vpos
12592 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12594 else
12596 /* This window must be completely empty. */
12597 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
12598 w->window_end_pos = make_number (Z - ZV);
12599 w->window_end_vpos = make_number (0);
12601 w->window_end_valid = Qnil;
12603 /* Update hint: don't try scrolling again in update_window. */
12604 w->desired_matrix->no_scrolling_p = 1;
12606 #if GLYPH_DEBUG
12607 debug_method_add (w, "try_window_reusing_current_matrix 1");
12608 #endif
12609 return 1;
12611 else if (CHARPOS (new_start) > CHARPOS (start))
12613 struct glyph_row *pt_row, *row;
12614 struct glyph_row *first_reusable_row;
12615 struct glyph_row *first_row_to_display;
12616 int dy;
12617 int yb = window_text_bottom_y (w);
12619 /* Find the row starting at new_start, if there is one. Don't
12620 reuse a partially visible line at the end. */
12621 first_reusable_row = start_row;
12622 while (first_reusable_row->enabled_p
12623 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
12624 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
12625 < CHARPOS (new_start)))
12626 ++first_reusable_row;
12628 /* Give up if there is no row to reuse. */
12629 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
12630 || !first_reusable_row->enabled_p
12631 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
12632 != CHARPOS (new_start)))
12633 return 0;
12635 /* We can reuse fully visible rows beginning with
12636 first_reusable_row to the end of the window. Set
12637 first_row_to_display to the first row that cannot be reused.
12638 Set pt_row to the row containing point, if there is any. */
12639 pt_row = NULL;
12640 for (first_row_to_display = first_reusable_row;
12641 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
12642 ++first_row_to_display)
12644 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
12645 && PT < MATRIX_ROW_END_CHARPOS (first_row_to_display))
12646 pt_row = first_row_to_display;
12649 /* Start displaying at the start of first_row_to_display. */
12650 xassert (first_row_to_display->y < yb);
12651 init_to_row_start (&it, w, first_row_to_display);
12653 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
12654 - start_vpos);
12655 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
12656 - nrows_scrolled);
12657 it.current_y = (first_row_to_display->y - first_reusable_row->y
12658 + WINDOW_HEADER_LINE_HEIGHT (w));
12660 /* Display lines beginning with first_row_to_display in the
12661 desired matrix. Set last_text_row to the last row displayed
12662 that displays text. */
12663 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
12664 if (pt_row == NULL)
12665 w->cursor.vpos = -1;
12666 last_text_row = NULL;
12667 while (it.current_y < it.last_visible_y && !fonts_changed_p)
12668 if (display_line (&it))
12669 last_text_row = it.glyph_row - 1;
12671 /* Give up If point isn't in a row displayed or reused. */
12672 if (w->cursor.vpos < 0)
12674 clear_glyph_matrix (w->desired_matrix);
12675 return 0;
12678 /* If point is in a reused row, adjust y and vpos of the cursor
12679 position. */
12680 if (pt_row)
12682 w->cursor.vpos -= nrows_scrolled;
12683 w->cursor.y -= first_reusable_row->y - start_row->y;
12686 /* Scroll the display. */
12687 run.current_y = first_reusable_row->y;
12688 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
12689 run.height = it.last_visible_y - run.current_y;
12690 dy = run.current_y - run.desired_y;
12692 if (run.height)
12694 update_begin (f);
12695 rif->update_window_begin_hook (w);
12696 rif->clear_window_mouse_face (w);
12697 rif->scroll_run_hook (w, &run);
12698 rif->update_window_end_hook (w, 0, 0);
12699 update_end (f);
12702 /* Adjust Y positions of reused rows. */
12703 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
12704 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
12705 max_y = it.last_visible_y;
12706 for (row = first_reusable_row; row < first_row_to_display; ++row)
12708 row->y -= dy;
12709 row->visible_height = row->height;
12710 if (row->y < min_y)
12711 row->visible_height -= min_y - row->y;
12712 if (row->y + row->height > max_y)
12713 row->visible_height -= row->y + row->height - max_y;
12714 row->redraw_fringe_bitmaps_p = 1;
12717 /* Scroll the current matrix. */
12718 xassert (nrows_scrolled > 0);
12719 rotate_matrix (w->current_matrix,
12720 start_vpos,
12721 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
12722 -nrows_scrolled);
12724 /* Disable rows not reused. */
12725 for (row -= nrows_scrolled; row < bottom_row; ++row)
12726 row->enabled_p = 0;
12728 /* Point may have moved to a different line, so we cannot assume that
12729 the previous cursor position is valid; locate the correct row. */
12730 if (pt_row)
12732 for (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
12733 row < bottom_row && PT >= MATRIX_ROW_END_CHARPOS (row);
12734 row++)
12736 w->cursor.vpos++;
12737 w->cursor.y = row->y;
12739 if (row < bottom_row)
12741 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
12742 while (glyph->charpos < PT)
12744 w->cursor.hpos++;
12745 w->cursor.x += glyph->pixel_width;
12746 glyph++;
12751 /* Adjust window end. A null value of last_text_row means that
12752 the window end is in reused rows which in turn means that
12753 only its vpos can have changed. */
12754 if (last_text_row)
12756 w->window_end_bytepos
12757 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12758 w->window_end_pos
12759 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12760 w->window_end_vpos
12761 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12763 else
12765 w->window_end_vpos
12766 = make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled);
12769 w->window_end_valid = Qnil;
12770 w->desired_matrix->no_scrolling_p = 1;
12772 #if GLYPH_DEBUG
12773 debug_method_add (w, "try_window_reusing_current_matrix 2");
12774 #endif
12775 return 1;
12778 return 0;
12783 /************************************************************************
12784 Window redisplay reusing current matrix when buffer has changed
12785 ************************************************************************/
12787 static struct glyph_row *find_last_unchanged_at_beg_row P_ ((struct window *));
12788 static struct glyph_row *find_first_unchanged_at_end_row P_ ((struct window *,
12789 int *, int *));
12790 static struct glyph_row *
12791 find_last_row_displaying_text P_ ((struct glyph_matrix *, struct it *,
12792 struct glyph_row *));
12795 /* Return the last row in MATRIX displaying text. If row START is
12796 non-null, start searching with that row. IT gives the dimensions
12797 of the display. Value is null if matrix is empty; otherwise it is
12798 a pointer to the row found. */
12800 static struct glyph_row *
12801 find_last_row_displaying_text (matrix, it, start)
12802 struct glyph_matrix *matrix;
12803 struct it *it;
12804 struct glyph_row *start;
12806 struct glyph_row *row, *row_found;
12808 /* Set row_found to the last row in IT->w's current matrix
12809 displaying text. The loop looks funny but think of partially
12810 visible lines. */
12811 row_found = NULL;
12812 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
12813 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
12815 xassert (row->enabled_p);
12816 row_found = row;
12817 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
12818 break;
12819 ++row;
12822 return row_found;
12826 /* Return the last row in the current matrix of W that is not affected
12827 by changes at the start of current_buffer that occurred since W's
12828 current matrix was built. Value is null if no such row exists.
12830 BEG_UNCHANGED us the number of characters unchanged at the start of
12831 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
12832 first changed character in current_buffer. Characters at positions <
12833 BEG + BEG_UNCHANGED are at the same buffer positions as they were
12834 when the current matrix was built. */
12836 static struct glyph_row *
12837 find_last_unchanged_at_beg_row (w)
12838 struct window *w;
12840 int first_changed_pos = BEG + BEG_UNCHANGED;
12841 struct glyph_row *row;
12842 struct glyph_row *row_found = NULL;
12843 int yb = window_text_bottom_y (w);
12845 /* Find the last row displaying unchanged text. */
12846 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12847 while (MATRIX_ROW_DISPLAYS_TEXT_P (row)
12848 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos)
12850 if (/* If row ends before first_changed_pos, it is unchanged,
12851 except in some case. */
12852 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
12853 /* When row ends in ZV and we write at ZV it is not
12854 unchanged. */
12855 && !row->ends_at_zv_p
12856 /* When first_changed_pos is the end of a continued line,
12857 row is not unchanged because it may be no longer
12858 continued. */
12859 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
12860 && (row->continued_p
12861 || row->exact_window_width_line_p)))
12862 row_found = row;
12864 /* Stop if last visible row. */
12865 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
12866 break;
12868 ++row;
12871 return row_found;
12875 /* Find the first glyph row in the current matrix of W that is not
12876 affected by changes at the end of current_buffer since the
12877 time W's current matrix was built.
12879 Return in *DELTA the number of chars by which buffer positions in
12880 unchanged text at the end of current_buffer must be adjusted.
12882 Return in *DELTA_BYTES the corresponding number of bytes.
12884 Value is null if no such row exists, i.e. all rows are affected by
12885 changes. */
12887 static struct glyph_row *
12888 find_first_unchanged_at_end_row (w, delta, delta_bytes)
12889 struct window *w;
12890 int *delta, *delta_bytes;
12892 struct glyph_row *row;
12893 struct glyph_row *row_found = NULL;
12895 *delta = *delta_bytes = 0;
12897 /* Display must not have been paused, otherwise the current matrix
12898 is not up to date. */
12899 if (NILP (w->window_end_valid))
12900 abort ();
12902 /* A value of window_end_pos >= END_UNCHANGED means that the window
12903 end is in the range of changed text. If so, there is no
12904 unchanged row at the end of W's current matrix. */
12905 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
12906 return NULL;
12908 /* Set row to the last row in W's current matrix displaying text. */
12909 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
12911 /* If matrix is entirely empty, no unchanged row exists. */
12912 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
12914 /* The value of row is the last glyph row in the matrix having a
12915 meaningful buffer position in it. The end position of row
12916 corresponds to window_end_pos. This allows us to translate
12917 buffer positions in the current matrix to current buffer
12918 positions for characters not in changed text. */
12919 int Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
12920 int Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
12921 int last_unchanged_pos, last_unchanged_pos_old;
12922 struct glyph_row *first_text_row
12923 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12925 *delta = Z - Z_old;
12926 *delta_bytes = Z_BYTE - Z_BYTE_old;
12928 /* Set last_unchanged_pos to the buffer position of the last
12929 character in the buffer that has not been changed. Z is the
12930 index + 1 of the last character in current_buffer, i.e. by
12931 subtracting END_UNCHANGED we get the index of the last
12932 unchanged character, and we have to add BEG to get its buffer
12933 position. */
12934 last_unchanged_pos = Z - END_UNCHANGED + BEG;
12935 last_unchanged_pos_old = last_unchanged_pos - *delta;
12937 /* Search backward from ROW for a row displaying a line that
12938 starts at a minimum position >= last_unchanged_pos_old. */
12939 for (; row > first_text_row; --row)
12941 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
12942 abort ();
12944 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
12945 row_found = row;
12949 if (row_found && !MATRIX_ROW_DISPLAYS_TEXT_P (row_found))
12950 abort ();
12952 return row_found;
12956 /* Make sure that glyph rows in the current matrix of window W
12957 reference the same glyph memory as corresponding rows in the
12958 frame's frame matrix. This function is called after scrolling W's
12959 current matrix on a terminal frame in try_window_id and
12960 try_window_reusing_current_matrix. */
12962 static void
12963 sync_frame_with_window_matrix_rows (w)
12964 struct window *w;
12966 struct frame *f = XFRAME (w->frame);
12967 struct glyph_row *window_row, *window_row_end, *frame_row;
12969 /* Preconditions: W must be a leaf window and full-width. Its frame
12970 must have a frame matrix. */
12971 xassert (NILP (w->hchild) && NILP (w->vchild));
12972 xassert (WINDOW_FULL_WIDTH_P (w));
12973 xassert (!FRAME_WINDOW_P (f));
12975 /* If W is a full-width window, glyph pointers in W's current matrix
12976 have, by definition, to be the same as glyph pointers in the
12977 corresponding frame matrix. Note that frame matrices have no
12978 marginal areas (see build_frame_matrix). */
12979 window_row = w->current_matrix->rows;
12980 window_row_end = window_row + w->current_matrix->nrows;
12981 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
12982 while (window_row < window_row_end)
12984 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
12985 struct glyph *end = window_row->glyphs[LAST_AREA];
12987 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
12988 frame_row->glyphs[TEXT_AREA] = start;
12989 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
12990 frame_row->glyphs[LAST_AREA] = end;
12992 /* Disable frame rows whose corresponding window rows have
12993 been disabled in try_window_id. */
12994 if (!window_row->enabled_p)
12995 frame_row->enabled_p = 0;
12997 ++window_row, ++frame_row;
13002 /* Find the glyph row in window W containing CHARPOS. Consider all
13003 rows between START and END (not inclusive). END null means search
13004 all rows to the end of the display area of W. Value is the row
13005 containing CHARPOS or null. */
13007 struct glyph_row *
13008 row_containing_pos (w, charpos, start, end, dy)
13009 struct window *w;
13010 int charpos;
13011 struct glyph_row *start, *end;
13012 int dy;
13014 struct glyph_row *row = start;
13015 int last_y;
13017 /* If we happen to start on a header-line, skip that. */
13018 if (row->mode_line_p)
13019 ++row;
13021 if ((end && row >= end) || !row->enabled_p)
13022 return NULL;
13024 last_y = window_text_bottom_y (w) - dy;
13026 while (1)
13028 /* Give up if we have gone too far. */
13029 if (end && row >= end)
13030 return NULL;
13031 /* This formerly returned if they were equal.
13032 I think that both quantities are of a "last plus one" type;
13033 if so, when they are equal, the row is within the screen. -- rms. */
13034 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
13035 return NULL;
13037 /* If it is in this row, return this row. */
13038 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
13039 || (MATRIX_ROW_END_CHARPOS (row) == charpos
13040 /* The end position of a row equals the start
13041 position of the next row. If CHARPOS is there, we
13042 would rather display it in the next line, except
13043 when this line ends in ZV. */
13044 && !row->ends_at_zv_p
13045 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
13046 && charpos >= MATRIX_ROW_START_CHARPOS (row))
13047 return row;
13048 ++row;
13053 /* Try to redisplay window W by reusing its existing display. W's
13054 current matrix must be up to date when this function is called,
13055 i.e. window_end_valid must not be nil.
13057 Value is
13059 1 if display has been updated
13060 0 if otherwise unsuccessful
13061 -1 if redisplay with same window start is known not to succeed
13063 The following steps are performed:
13065 1. Find the last row in the current matrix of W that is not
13066 affected by changes at the start of current_buffer. If no such row
13067 is found, give up.
13069 2. Find the first row in W's current matrix that is not affected by
13070 changes at the end of current_buffer. Maybe there is no such row.
13072 3. Display lines beginning with the row + 1 found in step 1 to the
13073 row found in step 2 or, if step 2 didn't find a row, to the end of
13074 the window.
13076 4. If cursor is not known to appear on the window, give up.
13078 5. If display stopped at the row found in step 2, scroll the
13079 display and current matrix as needed.
13081 6. Maybe display some lines at the end of W, if we must. This can
13082 happen under various circumstances, like a partially visible line
13083 becoming fully visible, or because newly displayed lines are displayed
13084 in smaller font sizes.
13086 7. Update W's window end information. */
13088 static int
13089 try_window_id (w)
13090 struct window *w;
13092 struct frame *f = XFRAME (w->frame);
13093 struct glyph_matrix *current_matrix = w->current_matrix;
13094 struct glyph_matrix *desired_matrix = w->desired_matrix;
13095 struct glyph_row *last_unchanged_at_beg_row;
13096 struct glyph_row *first_unchanged_at_end_row;
13097 struct glyph_row *row;
13098 struct glyph_row *bottom_row;
13099 int bottom_vpos;
13100 struct it it;
13101 int delta = 0, delta_bytes = 0, stop_pos, dvpos, dy;
13102 struct text_pos start_pos;
13103 struct run run;
13104 int first_unchanged_at_end_vpos = 0;
13105 struct glyph_row *last_text_row, *last_text_row_at_end;
13106 struct text_pos start;
13107 int first_changed_charpos, last_changed_charpos;
13109 #if GLYPH_DEBUG
13110 if (inhibit_try_window_id)
13111 return 0;
13112 #endif
13114 /* This is handy for debugging. */
13115 #if 0
13116 #define GIVE_UP(X) \
13117 do { \
13118 fprintf (stderr, "try_window_id give up %d\n", (X)); \
13119 return 0; \
13120 } while (0)
13121 #else
13122 #define GIVE_UP(X) return 0
13123 #endif
13125 SET_TEXT_POS_FROM_MARKER (start, w->start);
13127 /* Don't use this for mini-windows because these can show
13128 messages and mini-buffers, and we don't handle that here. */
13129 if (MINI_WINDOW_P (w))
13130 GIVE_UP (1);
13132 /* This flag is used to prevent redisplay optimizations. */
13133 if (windows_or_buffers_changed || cursor_type_changed)
13134 GIVE_UP (2);
13136 /* Verify that narrowing has not changed.
13137 Also verify that we were not told to prevent redisplay optimizations.
13138 It would be nice to further
13139 reduce the number of cases where this prevents try_window_id. */
13140 if (current_buffer->clip_changed
13141 || current_buffer->prevent_redisplay_optimizations_p)
13142 GIVE_UP (3);
13144 /* Window must either use window-based redisplay or be full width. */
13145 if (!FRAME_WINDOW_P (f)
13146 && (!line_ins_del_ok
13147 || !WINDOW_FULL_WIDTH_P (w)))
13148 GIVE_UP (4);
13150 /* Give up if point is not known NOT to appear in W. */
13151 if (PT < CHARPOS (start))
13152 GIVE_UP (5);
13154 /* Another way to prevent redisplay optimizations. */
13155 if (XFASTINT (w->last_modified) == 0)
13156 GIVE_UP (6);
13158 /* Verify that window is not hscrolled. */
13159 if (XFASTINT (w->hscroll) != 0)
13160 GIVE_UP (7);
13162 /* Verify that display wasn't paused. */
13163 if (NILP (w->window_end_valid))
13164 GIVE_UP (8);
13166 /* Can't use this if highlighting a region because a cursor movement
13167 will do more than just set the cursor. */
13168 if (!NILP (Vtransient_mark_mode)
13169 && !NILP (current_buffer->mark_active))
13170 GIVE_UP (9);
13172 /* Likewise if highlighting trailing whitespace. */
13173 if (!NILP (Vshow_trailing_whitespace))
13174 GIVE_UP (11);
13176 /* Likewise if showing a region. */
13177 if (!NILP (w->region_showing))
13178 GIVE_UP (10);
13180 /* Can use this if overlay arrow position and or string have changed. */
13181 if (overlay_arrows_changed_p ())
13182 GIVE_UP (12);
13185 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
13186 only if buffer has really changed. The reason is that the gap is
13187 initially at Z for freshly visited files. The code below would
13188 set end_unchanged to 0 in that case. */
13189 if (MODIFF > SAVE_MODIFF
13190 /* This seems to happen sometimes after saving a buffer. */
13191 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
13193 if (GPT - BEG < BEG_UNCHANGED)
13194 BEG_UNCHANGED = GPT - BEG;
13195 if (Z - GPT < END_UNCHANGED)
13196 END_UNCHANGED = Z - GPT;
13199 /* The position of the first and last character that has been changed. */
13200 first_changed_charpos = BEG + BEG_UNCHANGED;
13201 last_changed_charpos = Z - END_UNCHANGED;
13203 /* If window starts after a line end, and the last change is in
13204 front of that newline, then changes don't affect the display.
13205 This case happens with stealth-fontification. Note that although
13206 the display is unchanged, glyph positions in the matrix have to
13207 be adjusted, of course. */
13208 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
13209 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
13210 && ((last_changed_charpos < CHARPOS (start)
13211 && CHARPOS (start) == BEGV)
13212 || (last_changed_charpos < CHARPOS (start) - 1
13213 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
13215 int Z_old, delta, Z_BYTE_old, delta_bytes;
13216 struct glyph_row *r0;
13218 /* Compute how many chars/bytes have been added to or removed
13219 from the buffer. */
13220 Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
13221 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
13222 delta = Z - Z_old;
13223 delta_bytes = Z_BYTE - Z_BYTE_old;
13225 /* Give up if PT is not in the window. Note that it already has
13226 been checked at the start of try_window_id that PT is not in
13227 front of the window start. */
13228 if (PT >= MATRIX_ROW_END_CHARPOS (row) + delta)
13229 GIVE_UP (13);
13231 /* If window start is unchanged, we can reuse the whole matrix
13232 as is, after adjusting glyph positions. No need to compute
13233 the window end again, since its offset from Z hasn't changed. */
13234 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
13235 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + delta
13236 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + delta_bytes
13237 /* PT must not be in a partially visible line. */
13238 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + delta
13239 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
13241 /* Adjust positions in the glyph matrix. */
13242 if (delta || delta_bytes)
13244 struct glyph_row *r1
13245 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
13246 increment_matrix_positions (w->current_matrix,
13247 MATRIX_ROW_VPOS (r0, current_matrix),
13248 MATRIX_ROW_VPOS (r1, current_matrix),
13249 delta, delta_bytes);
13252 /* Set the cursor. */
13253 row = row_containing_pos (w, PT, r0, NULL, 0);
13254 if (row)
13255 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
13256 else
13257 abort ();
13258 return 1;
13262 /* Handle the case that changes are all below what is displayed in
13263 the window, and that PT is in the window. This shortcut cannot
13264 be taken if ZV is visible in the window, and text has been added
13265 there that is visible in the window. */
13266 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
13267 /* ZV is not visible in the window, or there are no
13268 changes at ZV, actually. */
13269 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
13270 || first_changed_charpos == last_changed_charpos))
13272 struct glyph_row *r0;
13274 /* Give up if PT is not in the window. Note that it already has
13275 been checked at the start of try_window_id that PT is not in
13276 front of the window start. */
13277 if (PT >= MATRIX_ROW_END_CHARPOS (row))
13278 GIVE_UP (14);
13280 /* If window start is unchanged, we can reuse the whole matrix
13281 as is, without changing glyph positions since no text has
13282 been added/removed in front of the window end. */
13283 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
13284 if (TEXT_POS_EQUAL_P (start, r0->start.pos)
13285 /* PT must not be in a partially visible line. */
13286 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
13287 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
13289 /* We have to compute the window end anew since text
13290 can have been added/removed after it. */
13291 w->window_end_pos
13292 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13293 w->window_end_bytepos
13294 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13296 /* Set the cursor. */
13297 row = row_containing_pos (w, PT, r0, NULL, 0);
13298 if (row)
13299 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
13300 else
13301 abort ();
13302 return 2;
13306 /* Give up if window start is in the changed area.
13308 The condition used to read
13310 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
13312 but why that was tested escapes me at the moment. */
13313 if (CHARPOS (start) >= first_changed_charpos
13314 && CHARPOS (start) <= last_changed_charpos)
13315 GIVE_UP (15);
13317 /* Check that window start agrees with the start of the first glyph
13318 row in its current matrix. Check this after we know the window
13319 start is not in changed text, otherwise positions would not be
13320 comparable. */
13321 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
13322 if (!TEXT_POS_EQUAL_P (start, row->start.pos))
13323 GIVE_UP (16);
13325 /* Give up if the window ends in strings. Overlay strings
13326 at the end are difficult to handle, so don't try. */
13327 row = MATRIX_ROW (current_matrix, XFASTINT (w->window_end_vpos));
13328 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
13329 GIVE_UP (20);
13331 /* Compute the position at which we have to start displaying new
13332 lines. Some of the lines at the top of the window might be
13333 reusable because they are not displaying changed text. Find the
13334 last row in W's current matrix not affected by changes at the
13335 start of current_buffer. Value is null if changes start in the
13336 first line of window. */
13337 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
13338 if (last_unchanged_at_beg_row)
13340 /* Avoid starting to display in the moddle of a character, a TAB
13341 for instance. This is easier than to set up the iterator
13342 exactly, and it's not a frequent case, so the additional
13343 effort wouldn't really pay off. */
13344 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
13345 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
13346 && last_unchanged_at_beg_row > w->current_matrix->rows)
13347 --last_unchanged_at_beg_row;
13349 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
13350 GIVE_UP (17);
13352 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
13353 GIVE_UP (18);
13354 start_pos = it.current.pos;
13356 /* Start displaying new lines in the desired matrix at the same
13357 vpos we would use in the current matrix, i.e. below
13358 last_unchanged_at_beg_row. */
13359 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
13360 current_matrix);
13361 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
13362 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
13364 xassert (it.hpos == 0 && it.current_x == 0);
13366 else
13368 /* There are no reusable lines at the start of the window.
13369 Start displaying in the first text line. */
13370 start_display (&it, w, start);
13371 it.vpos = it.first_vpos;
13372 start_pos = it.current.pos;
13375 /* Find the first row that is not affected by changes at the end of
13376 the buffer. Value will be null if there is no unchanged row, in
13377 which case we must redisplay to the end of the window. delta
13378 will be set to the value by which buffer positions beginning with
13379 first_unchanged_at_end_row have to be adjusted due to text
13380 changes. */
13381 first_unchanged_at_end_row
13382 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
13383 IF_DEBUG (debug_delta = delta);
13384 IF_DEBUG (debug_delta_bytes = delta_bytes);
13386 /* Set stop_pos to the buffer position up to which we will have to
13387 display new lines. If first_unchanged_at_end_row != NULL, this
13388 is the buffer position of the start of the line displayed in that
13389 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
13390 that we don't stop at a buffer position. */
13391 stop_pos = 0;
13392 if (first_unchanged_at_end_row)
13394 xassert (last_unchanged_at_beg_row == NULL
13395 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
13397 /* If this is a continuation line, move forward to the next one
13398 that isn't. Changes in lines above affect this line.
13399 Caution: this may move first_unchanged_at_end_row to a row
13400 not displaying text. */
13401 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
13402 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
13403 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
13404 < it.last_visible_y))
13405 ++first_unchanged_at_end_row;
13407 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
13408 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
13409 >= it.last_visible_y))
13410 first_unchanged_at_end_row = NULL;
13411 else
13413 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
13414 + delta);
13415 first_unchanged_at_end_vpos
13416 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
13417 xassert (stop_pos >= Z - END_UNCHANGED);
13420 else if (last_unchanged_at_beg_row == NULL)
13421 GIVE_UP (19);
13424 #if GLYPH_DEBUG
13426 /* Either there is no unchanged row at the end, or the one we have
13427 now displays text. This is a necessary condition for the window
13428 end pos calculation at the end of this function. */
13429 xassert (first_unchanged_at_end_row == NULL
13430 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
13432 debug_last_unchanged_at_beg_vpos
13433 = (last_unchanged_at_beg_row
13434 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
13435 : -1);
13436 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
13438 #endif /* GLYPH_DEBUG != 0 */
13441 /* Display new lines. Set last_text_row to the last new line
13442 displayed which has text on it, i.e. might end up as being the
13443 line where the window_end_vpos is. */
13444 w->cursor.vpos = -1;
13445 last_text_row = NULL;
13446 overlay_arrow_seen = 0;
13447 while (it.current_y < it.last_visible_y
13448 && !fonts_changed_p
13449 && (first_unchanged_at_end_row == NULL
13450 || IT_CHARPOS (it) < stop_pos))
13452 if (display_line (&it))
13453 last_text_row = it.glyph_row - 1;
13456 if (fonts_changed_p)
13457 return -1;
13460 /* Compute differences in buffer positions, y-positions etc. for
13461 lines reused at the bottom of the window. Compute what we can
13462 scroll. */
13463 if (first_unchanged_at_end_row
13464 /* No lines reused because we displayed everything up to the
13465 bottom of the window. */
13466 && it.current_y < it.last_visible_y)
13468 dvpos = (it.vpos
13469 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
13470 current_matrix));
13471 dy = it.current_y - first_unchanged_at_end_row->y;
13472 run.current_y = first_unchanged_at_end_row->y;
13473 run.desired_y = run.current_y + dy;
13474 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
13476 else
13478 delta = dvpos = dy = run.current_y = run.desired_y = run.height = 0;
13479 first_unchanged_at_end_row = NULL;
13481 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
13484 /* Find the cursor if not already found. We have to decide whether
13485 PT will appear on this window (it sometimes doesn't, but this is
13486 not a very frequent case.) This decision has to be made before
13487 the current matrix is altered. A value of cursor.vpos < 0 means
13488 that PT is either in one of the lines beginning at
13489 first_unchanged_at_end_row or below the window. Don't care for
13490 lines that might be displayed later at the window end; as
13491 mentioned, this is not a frequent case. */
13492 if (w->cursor.vpos < 0)
13494 /* Cursor in unchanged rows at the top? */
13495 if (PT < CHARPOS (start_pos)
13496 && last_unchanged_at_beg_row)
13498 row = row_containing_pos (w, PT,
13499 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
13500 last_unchanged_at_beg_row + 1, 0);
13501 if (row)
13502 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
13505 /* Start from first_unchanged_at_end_row looking for PT. */
13506 else if (first_unchanged_at_end_row)
13508 row = row_containing_pos (w, PT - delta,
13509 first_unchanged_at_end_row, NULL, 0);
13510 if (row)
13511 set_cursor_from_row (w, row, w->current_matrix, delta,
13512 delta_bytes, dy, dvpos);
13515 /* Give up if cursor was not found. */
13516 if (w->cursor.vpos < 0)
13518 clear_glyph_matrix (w->desired_matrix);
13519 return -1;
13523 /* Don't let the cursor end in the scroll margins. */
13525 int this_scroll_margin, cursor_height;
13527 this_scroll_margin = max (0, scroll_margin);
13528 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
13529 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
13530 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
13532 if ((w->cursor.y < this_scroll_margin
13533 && CHARPOS (start) > BEGV)
13534 /* Old redisplay didn't take scroll margin into account at the bottom,
13535 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
13536 || (w->cursor.y + (make_cursor_line_fully_visible_p
13537 ? cursor_height + this_scroll_margin
13538 : 1)) > it.last_visible_y)
13540 w->cursor.vpos = -1;
13541 clear_glyph_matrix (w->desired_matrix);
13542 return -1;
13546 /* Scroll the display. Do it before changing the current matrix so
13547 that xterm.c doesn't get confused about where the cursor glyph is
13548 found. */
13549 if (dy && run.height)
13551 update_begin (f);
13553 if (FRAME_WINDOW_P (f))
13555 rif->update_window_begin_hook (w);
13556 rif->clear_window_mouse_face (w);
13557 rif->scroll_run_hook (w, &run);
13558 rif->update_window_end_hook (w, 0, 0);
13560 else
13562 /* Terminal frame. In this case, dvpos gives the number of
13563 lines to scroll by; dvpos < 0 means scroll up. */
13564 int first_unchanged_at_end_vpos
13565 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
13566 int from = WINDOW_TOP_EDGE_LINE (w) + first_unchanged_at_end_vpos;
13567 int end = (WINDOW_TOP_EDGE_LINE (w)
13568 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
13569 + window_internal_height (w));
13571 /* Perform the operation on the screen. */
13572 if (dvpos > 0)
13574 /* Scroll last_unchanged_at_beg_row to the end of the
13575 window down dvpos lines. */
13576 set_terminal_window (end);
13578 /* On dumb terminals delete dvpos lines at the end
13579 before inserting dvpos empty lines. */
13580 if (!scroll_region_ok)
13581 ins_del_lines (end - dvpos, -dvpos);
13583 /* Insert dvpos empty lines in front of
13584 last_unchanged_at_beg_row. */
13585 ins_del_lines (from, dvpos);
13587 else if (dvpos < 0)
13589 /* Scroll up last_unchanged_at_beg_vpos to the end of
13590 the window to last_unchanged_at_beg_vpos - |dvpos|. */
13591 set_terminal_window (end);
13593 /* Delete dvpos lines in front of
13594 last_unchanged_at_beg_vpos. ins_del_lines will set
13595 the cursor to the given vpos and emit |dvpos| delete
13596 line sequences. */
13597 ins_del_lines (from + dvpos, dvpos);
13599 /* On a dumb terminal insert dvpos empty lines at the
13600 end. */
13601 if (!scroll_region_ok)
13602 ins_del_lines (end + dvpos, -dvpos);
13605 set_terminal_window (0);
13608 update_end (f);
13611 /* Shift reused rows of the current matrix to the right position.
13612 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
13613 text. */
13614 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
13615 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
13616 if (dvpos < 0)
13618 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
13619 bottom_vpos, dvpos);
13620 enable_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
13621 bottom_vpos, 0);
13623 else if (dvpos > 0)
13625 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
13626 bottom_vpos, dvpos);
13627 enable_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
13628 first_unchanged_at_end_vpos + dvpos, 0);
13631 /* For frame-based redisplay, make sure that current frame and window
13632 matrix are in sync with respect to glyph memory. */
13633 if (!FRAME_WINDOW_P (f))
13634 sync_frame_with_window_matrix_rows (w);
13636 /* Adjust buffer positions in reused rows. */
13637 if (delta)
13638 increment_matrix_positions (current_matrix,
13639 first_unchanged_at_end_vpos + dvpos,
13640 bottom_vpos, delta, delta_bytes);
13642 /* Adjust Y positions. */
13643 if (dy)
13644 shift_glyph_matrix (w, current_matrix,
13645 first_unchanged_at_end_vpos + dvpos,
13646 bottom_vpos, dy);
13648 if (first_unchanged_at_end_row)
13649 first_unchanged_at_end_row += dvpos;
13651 /* If scrolling up, there may be some lines to display at the end of
13652 the window. */
13653 last_text_row_at_end = NULL;
13654 if (dy < 0)
13656 /* Scrolling up can leave for example a partially visible line
13657 at the end of the window to be redisplayed. */
13658 /* Set last_row to the glyph row in the current matrix where the
13659 window end line is found. It has been moved up or down in
13660 the matrix by dvpos. */
13661 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
13662 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
13664 /* If last_row is the window end line, it should display text. */
13665 xassert (last_row->displays_text_p);
13667 /* If window end line was partially visible before, begin
13668 displaying at that line. Otherwise begin displaying with the
13669 line following it. */
13670 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
13672 init_to_row_start (&it, w, last_row);
13673 it.vpos = last_vpos;
13674 it.current_y = last_row->y;
13676 else
13678 init_to_row_end (&it, w, last_row);
13679 it.vpos = 1 + last_vpos;
13680 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
13681 ++last_row;
13684 /* We may start in a continuation line. If so, we have to
13685 get the right continuation_lines_width and current_x. */
13686 it.continuation_lines_width = last_row->continuation_lines_width;
13687 it.hpos = it.current_x = 0;
13689 /* Display the rest of the lines at the window end. */
13690 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
13691 while (it.current_y < it.last_visible_y
13692 && !fonts_changed_p)
13694 /* Is it always sure that the display agrees with lines in
13695 the current matrix? I don't think so, so we mark rows
13696 displayed invalid in the current matrix by setting their
13697 enabled_p flag to zero. */
13698 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
13699 if (display_line (&it))
13700 last_text_row_at_end = it.glyph_row - 1;
13704 /* Update window_end_pos and window_end_vpos. */
13705 if (first_unchanged_at_end_row
13706 && first_unchanged_at_end_row->y < it.last_visible_y
13707 && !last_text_row_at_end)
13709 /* Window end line if one of the preserved rows from the current
13710 matrix. Set row to the last row displaying text in current
13711 matrix starting at first_unchanged_at_end_row, after
13712 scrolling. */
13713 xassert (first_unchanged_at_end_row->displays_text_p);
13714 row = find_last_row_displaying_text (w->current_matrix, &it,
13715 first_unchanged_at_end_row);
13716 xassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
13718 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13719 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13720 w->window_end_vpos
13721 = make_number (MATRIX_ROW_VPOS (row, w->current_matrix));
13722 xassert (w->window_end_bytepos >= 0);
13723 IF_DEBUG (debug_method_add (w, "A"));
13725 else if (last_text_row_at_end)
13727 w->window_end_pos
13728 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end));
13729 w->window_end_bytepos
13730 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
13731 w->window_end_vpos
13732 = make_number (MATRIX_ROW_VPOS (last_text_row_at_end, desired_matrix));
13733 xassert (w->window_end_bytepos >= 0);
13734 IF_DEBUG (debug_method_add (w, "B"));
13736 else if (last_text_row)
13738 /* We have displayed either to the end of the window or at the
13739 end of the window, i.e. the last row with text is to be found
13740 in the desired matrix. */
13741 w->window_end_pos
13742 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
13743 w->window_end_bytepos
13744 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
13745 w->window_end_vpos
13746 = make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix));
13747 xassert (w->window_end_bytepos >= 0);
13749 else if (first_unchanged_at_end_row == NULL
13750 && last_text_row == NULL
13751 && last_text_row_at_end == NULL)
13753 /* Displayed to end of window, but no line containing text was
13754 displayed. Lines were deleted at the end of the window. */
13755 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
13756 int vpos = XFASTINT (w->window_end_vpos);
13757 struct glyph_row *current_row = current_matrix->rows + vpos;
13758 struct glyph_row *desired_row = desired_matrix->rows + vpos;
13760 for (row = NULL;
13761 row == NULL && vpos >= first_vpos;
13762 --vpos, --current_row, --desired_row)
13764 if (desired_row->enabled_p)
13766 if (desired_row->displays_text_p)
13767 row = desired_row;
13769 else if (current_row->displays_text_p)
13770 row = current_row;
13773 xassert (row != NULL);
13774 w->window_end_vpos = make_number (vpos + 1);
13775 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13776 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13777 xassert (w->window_end_bytepos >= 0);
13778 IF_DEBUG (debug_method_add (w, "C"));
13780 else
13781 abort ();
13783 #if 0 /* This leads to problems, for instance when the cursor is
13784 at ZV, and the cursor line displays no text. */
13785 /* Disable rows below what's displayed in the window. This makes
13786 debugging easier. */
13787 enable_glyph_matrix_rows (current_matrix,
13788 XFASTINT (w->window_end_vpos) + 1,
13789 bottom_vpos, 0);
13790 #endif
13792 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
13793 debug_end_vpos = XFASTINT (w->window_end_vpos));
13795 /* Record that display has not been completed. */
13796 w->window_end_valid = Qnil;
13797 w->desired_matrix->no_scrolling_p = 1;
13798 return 3;
13800 #undef GIVE_UP
13805 /***********************************************************************
13806 More debugging support
13807 ***********************************************************************/
13809 #if GLYPH_DEBUG
13811 void dump_glyph_row P_ ((struct glyph_row *, int, int));
13812 void dump_glyph_matrix P_ ((struct glyph_matrix *, int));
13813 void dump_glyph P_ ((struct glyph_row *, struct glyph *, int));
13816 /* Dump the contents of glyph matrix MATRIX on stderr.
13818 GLYPHS 0 means don't show glyph contents.
13819 GLYPHS 1 means show glyphs in short form
13820 GLYPHS > 1 means show glyphs in long form. */
13822 void
13823 dump_glyph_matrix (matrix, glyphs)
13824 struct glyph_matrix *matrix;
13825 int glyphs;
13827 int i;
13828 for (i = 0; i < matrix->nrows; ++i)
13829 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
13833 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
13834 the glyph row and area where the glyph comes from. */
13836 void
13837 dump_glyph (row, glyph, area)
13838 struct glyph_row *row;
13839 struct glyph *glyph;
13840 int area;
13842 if (glyph->type == CHAR_GLYPH)
13844 fprintf (stderr,
13845 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13846 glyph - row->glyphs[TEXT_AREA],
13847 'C',
13848 glyph->charpos,
13849 (BUFFERP (glyph->object)
13850 ? 'B'
13851 : (STRINGP (glyph->object)
13852 ? 'S'
13853 : '-')),
13854 glyph->pixel_width,
13855 glyph->u.ch,
13856 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
13857 ? glyph->u.ch
13858 : '.'),
13859 glyph->face_id,
13860 glyph->left_box_line_p,
13861 glyph->right_box_line_p);
13863 else if (glyph->type == STRETCH_GLYPH)
13865 fprintf (stderr,
13866 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13867 glyph - row->glyphs[TEXT_AREA],
13868 'S',
13869 glyph->charpos,
13870 (BUFFERP (glyph->object)
13871 ? 'B'
13872 : (STRINGP (glyph->object)
13873 ? 'S'
13874 : '-')),
13875 glyph->pixel_width,
13877 '.',
13878 glyph->face_id,
13879 glyph->left_box_line_p,
13880 glyph->right_box_line_p);
13882 else if (glyph->type == IMAGE_GLYPH)
13884 fprintf (stderr,
13885 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13886 glyph - row->glyphs[TEXT_AREA],
13887 'I',
13888 glyph->charpos,
13889 (BUFFERP (glyph->object)
13890 ? 'B'
13891 : (STRINGP (glyph->object)
13892 ? 'S'
13893 : '-')),
13894 glyph->pixel_width,
13895 glyph->u.img_id,
13896 '.',
13897 glyph->face_id,
13898 glyph->left_box_line_p,
13899 glyph->right_box_line_p);
13904 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
13905 GLYPHS 0 means don't show glyph contents.
13906 GLYPHS 1 means show glyphs in short form
13907 GLYPHS > 1 means show glyphs in long form. */
13909 void
13910 dump_glyph_row (row, vpos, glyphs)
13911 struct glyph_row *row;
13912 int vpos, glyphs;
13914 if (glyphs != 1)
13916 fprintf (stderr, "Row Start End Used oEI><O\\CTZFesm X Y W H V A P\n");
13917 fprintf (stderr, "=======================================================================\n");
13919 fprintf (stderr, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d%1.1d\
13920 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
13921 vpos,
13922 MATRIX_ROW_START_CHARPOS (row),
13923 MATRIX_ROW_END_CHARPOS (row),
13924 row->used[TEXT_AREA],
13925 row->contains_overlapping_glyphs_p,
13926 row->enabled_p,
13927 row->truncated_on_left_p,
13928 row->truncated_on_right_p,
13929 row->overlay_arrow_p,
13930 row->continued_p,
13931 MATRIX_ROW_CONTINUATION_LINE_P (row),
13932 row->displays_text_p,
13933 row->ends_at_zv_p,
13934 row->fill_line_p,
13935 row->ends_in_middle_of_char_p,
13936 row->starts_in_middle_of_char_p,
13937 row->mouse_face_p,
13938 row->x,
13939 row->y,
13940 row->pixel_width,
13941 row->height,
13942 row->visible_height,
13943 row->ascent,
13944 row->phys_ascent);
13945 fprintf (stderr, "%9d %5d\t%5d\n", row->start.overlay_string_index,
13946 row->end.overlay_string_index,
13947 row->continuation_lines_width);
13948 fprintf (stderr, "%9d %5d\n",
13949 CHARPOS (row->start.string_pos),
13950 CHARPOS (row->end.string_pos));
13951 fprintf (stderr, "%9d %5d\n", row->start.dpvec_index,
13952 row->end.dpvec_index);
13955 if (glyphs > 1)
13957 int area;
13959 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
13961 struct glyph *glyph = row->glyphs[area];
13962 struct glyph *glyph_end = glyph + row->used[area];
13964 /* Glyph for a line end in text. */
13965 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
13966 ++glyph_end;
13968 if (glyph < glyph_end)
13969 fprintf (stderr, " Glyph Type Pos O W Code C Face LR\n");
13971 for (; glyph < glyph_end; ++glyph)
13972 dump_glyph (row, glyph, area);
13975 else if (glyphs == 1)
13977 int area;
13979 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
13981 char *s = (char *) alloca (row->used[area] + 1);
13982 int i;
13984 for (i = 0; i < row->used[area]; ++i)
13986 struct glyph *glyph = row->glyphs[area] + i;
13987 if (glyph->type == CHAR_GLYPH
13988 && glyph->u.ch < 0x80
13989 && glyph->u.ch >= ' ')
13990 s[i] = glyph->u.ch;
13991 else
13992 s[i] = '.';
13995 s[i] = '\0';
13996 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
14002 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
14003 Sdump_glyph_matrix, 0, 1, "p",
14004 doc: /* Dump the current matrix of the selected window to stderr.
14005 Shows contents of glyph row structures. With non-nil
14006 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
14007 glyphs in short form, otherwise show glyphs in long form. */)
14008 (glyphs)
14009 Lisp_Object glyphs;
14011 struct window *w = XWINDOW (selected_window);
14012 struct buffer *buffer = XBUFFER (w->buffer);
14014 fprintf (stderr, "PT = %d, BEGV = %d. ZV = %d\n",
14015 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
14016 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
14017 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
14018 fprintf (stderr, "=============================================\n");
14019 dump_glyph_matrix (w->current_matrix,
14020 NILP (glyphs) ? 0 : XINT (glyphs));
14021 return Qnil;
14025 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
14026 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
14029 struct frame *f = XFRAME (selected_frame);
14030 dump_glyph_matrix (f->current_matrix, 1);
14031 return Qnil;
14035 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
14036 doc: /* Dump glyph row ROW to stderr.
14037 GLYPH 0 means don't dump glyphs.
14038 GLYPH 1 means dump glyphs in short form.
14039 GLYPH > 1 or omitted means dump glyphs in long form. */)
14040 (row, glyphs)
14041 Lisp_Object row, glyphs;
14043 struct glyph_matrix *matrix;
14044 int vpos;
14046 CHECK_NUMBER (row);
14047 matrix = XWINDOW (selected_window)->current_matrix;
14048 vpos = XINT (row);
14049 if (vpos >= 0 && vpos < matrix->nrows)
14050 dump_glyph_row (MATRIX_ROW (matrix, vpos),
14051 vpos,
14052 INTEGERP (glyphs) ? XINT (glyphs) : 2);
14053 return Qnil;
14057 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
14058 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
14059 GLYPH 0 means don't dump glyphs.
14060 GLYPH 1 means dump glyphs in short form.
14061 GLYPH > 1 or omitted means dump glyphs in long form. */)
14062 (row, glyphs)
14063 Lisp_Object row, glyphs;
14065 struct frame *sf = SELECTED_FRAME ();
14066 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
14067 int vpos;
14069 CHECK_NUMBER (row);
14070 vpos = XINT (row);
14071 if (vpos >= 0 && vpos < m->nrows)
14072 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
14073 INTEGERP (glyphs) ? XINT (glyphs) : 2);
14074 return Qnil;
14078 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
14079 doc: /* Toggle tracing of redisplay.
14080 With ARG, turn tracing on if and only if ARG is positive. */)
14081 (arg)
14082 Lisp_Object arg;
14084 if (NILP (arg))
14085 trace_redisplay_p = !trace_redisplay_p;
14086 else
14088 arg = Fprefix_numeric_value (arg);
14089 trace_redisplay_p = XINT (arg) > 0;
14092 return Qnil;
14096 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
14097 doc: /* Like `format', but print result to stderr.
14098 usage: (trace-to-stderr STRING &rest OBJECTS) */)
14099 (nargs, args)
14100 int nargs;
14101 Lisp_Object *args;
14103 Lisp_Object s = Fformat (nargs, args);
14104 fprintf (stderr, "%s", SDATA (s));
14105 return Qnil;
14108 #endif /* GLYPH_DEBUG */
14112 /***********************************************************************
14113 Building Desired Matrix Rows
14114 ***********************************************************************/
14116 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
14117 Used for non-window-redisplay windows, and for windows w/o left fringe. */
14119 static struct glyph_row *
14120 get_overlay_arrow_glyph_row (w, overlay_arrow_string)
14121 struct window *w;
14122 Lisp_Object overlay_arrow_string;
14124 struct frame *f = XFRAME (WINDOW_FRAME (w));
14125 struct buffer *buffer = XBUFFER (w->buffer);
14126 struct buffer *old = current_buffer;
14127 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
14128 int arrow_len = SCHARS (overlay_arrow_string);
14129 const unsigned char *arrow_end = arrow_string + arrow_len;
14130 const unsigned char *p;
14131 struct it it;
14132 int multibyte_p;
14133 int n_glyphs_before;
14135 set_buffer_temp (buffer);
14136 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
14137 it.glyph_row->used[TEXT_AREA] = 0;
14138 SET_TEXT_POS (it.position, 0, 0);
14140 multibyte_p = !NILP (buffer->enable_multibyte_characters);
14141 p = arrow_string;
14142 while (p < arrow_end)
14144 Lisp_Object face, ilisp;
14146 /* Get the next character. */
14147 if (multibyte_p)
14148 it.c = string_char_and_length (p, arrow_len, &it.len);
14149 else
14150 it.c = *p, it.len = 1;
14151 p += it.len;
14153 /* Get its face. */
14154 ilisp = make_number (p - arrow_string);
14155 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
14156 it.face_id = compute_char_face (f, it.c, face);
14158 /* Compute its width, get its glyphs. */
14159 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
14160 SET_TEXT_POS (it.position, -1, -1);
14161 PRODUCE_GLYPHS (&it);
14163 /* If this character doesn't fit any more in the line, we have
14164 to remove some glyphs. */
14165 if (it.current_x > it.last_visible_x)
14167 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
14168 break;
14172 set_buffer_temp (old);
14173 return it.glyph_row;
14177 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
14178 glyphs are only inserted for terminal frames since we can't really
14179 win with truncation glyphs when partially visible glyphs are
14180 involved. Which glyphs to insert is determined by
14181 produce_special_glyphs. */
14183 static void
14184 insert_left_trunc_glyphs (it)
14185 struct it *it;
14187 struct it truncate_it;
14188 struct glyph *from, *end, *to, *toend;
14190 xassert (!FRAME_WINDOW_P (it->f));
14192 /* Get the truncation glyphs. */
14193 truncate_it = *it;
14194 truncate_it.current_x = 0;
14195 truncate_it.face_id = DEFAULT_FACE_ID;
14196 truncate_it.glyph_row = &scratch_glyph_row;
14197 truncate_it.glyph_row->used[TEXT_AREA] = 0;
14198 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
14199 truncate_it.object = make_number (0);
14200 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
14202 /* Overwrite glyphs from IT with truncation glyphs. */
14203 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
14204 end = from + truncate_it.glyph_row->used[TEXT_AREA];
14205 to = it->glyph_row->glyphs[TEXT_AREA];
14206 toend = to + it->glyph_row->used[TEXT_AREA];
14208 while (from < end)
14209 *to++ = *from++;
14211 /* There may be padding glyphs left over. Overwrite them too. */
14212 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
14214 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
14215 while (from < end)
14216 *to++ = *from++;
14219 if (to > toend)
14220 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
14224 /* Compute the pixel height and width of IT->glyph_row.
14226 Most of the time, ascent and height of a display line will be equal
14227 to the max_ascent and max_height values of the display iterator
14228 structure. This is not the case if
14230 1. We hit ZV without displaying anything. In this case, max_ascent
14231 and max_height will be zero.
14233 2. We have some glyphs that don't contribute to the line height.
14234 (The glyph row flag contributes_to_line_height_p is for future
14235 pixmap extensions).
14237 The first case is easily covered by using default values because in
14238 these cases, the line height does not really matter, except that it
14239 must not be zero. */
14241 static void
14242 compute_line_metrics (it)
14243 struct it *it;
14245 struct glyph_row *row = it->glyph_row;
14246 int area, i;
14248 if (FRAME_WINDOW_P (it->f))
14250 int i, min_y, max_y;
14252 /* The line may consist of one space only, that was added to
14253 place the cursor on it. If so, the row's height hasn't been
14254 computed yet. */
14255 if (row->height == 0)
14257 if (it->max_ascent + it->max_descent == 0)
14258 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
14259 row->ascent = it->max_ascent;
14260 row->height = it->max_ascent + it->max_descent;
14261 row->phys_ascent = it->max_phys_ascent;
14262 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
14263 row->extra_line_spacing = it->max_extra_line_spacing;
14266 /* Compute the width of this line. */
14267 row->pixel_width = row->x;
14268 for (i = 0; i < row->used[TEXT_AREA]; ++i)
14269 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
14271 xassert (row->pixel_width >= 0);
14272 xassert (row->ascent >= 0 && row->height > 0);
14274 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
14275 || MATRIX_ROW_OVERLAPS_PRED_P (row));
14277 /* If first line's physical ascent is larger than its logical
14278 ascent, use the physical ascent, and make the row taller.
14279 This makes accented characters fully visible. */
14280 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
14281 && row->phys_ascent > row->ascent)
14283 row->height += row->phys_ascent - row->ascent;
14284 row->ascent = row->phys_ascent;
14287 /* Compute how much of the line is visible. */
14288 row->visible_height = row->height;
14290 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
14291 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
14293 if (row->y < min_y)
14294 row->visible_height -= min_y - row->y;
14295 if (row->y + row->height > max_y)
14296 row->visible_height -= row->y + row->height - max_y;
14298 else
14300 row->pixel_width = row->used[TEXT_AREA];
14301 if (row->continued_p)
14302 row->pixel_width -= it->continuation_pixel_width;
14303 else if (row->truncated_on_right_p)
14304 row->pixel_width -= it->truncation_pixel_width;
14305 row->ascent = row->phys_ascent = 0;
14306 row->height = row->phys_height = row->visible_height = 1;
14307 row->extra_line_spacing = 0;
14310 /* Compute a hash code for this row. */
14311 row->hash = 0;
14312 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
14313 for (i = 0; i < row->used[area]; ++i)
14314 row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff)
14315 + row->glyphs[area][i].u.val
14316 + row->glyphs[area][i].face_id
14317 + row->glyphs[area][i].padding_p
14318 + (row->glyphs[area][i].type << 2));
14320 it->max_ascent = it->max_descent = 0;
14321 it->max_phys_ascent = it->max_phys_descent = 0;
14325 /* Append one space to the glyph row of iterator IT if doing a
14326 window-based redisplay. The space has the same face as
14327 IT->face_id. Value is non-zero if a space was added.
14329 This function is called to make sure that there is always one glyph
14330 at the end of a glyph row that the cursor can be set on under
14331 window-systems. (If there weren't such a glyph we would not know
14332 how wide and tall a box cursor should be displayed).
14334 At the same time this space let's a nicely handle clearing to the
14335 end of the line if the row ends in italic text. */
14337 static int
14338 append_space_for_newline (it, default_face_p)
14339 struct it *it;
14340 int default_face_p;
14342 if (FRAME_WINDOW_P (it->f))
14344 int n = it->glyph_row->used[TEXT_AREA];
14346 if (it->glyph_row->glyphs[TEXT_AREA] + n
14347 < it->glyph_row->glyphs[1 + TEXT_AREA])
14349 /* Save some values that must not be changed.
14350 Must save IT->c and IT->len because otherwise
14351 ITERATOR_AT_END_P wouldn't work anymore after
14352 append_space_for_newline has been called. */
14353 enum display_element_type saved_what = it->what;
14354 int saved_c = it->c, saved_len = it->len;
14355 int saved_x = it->current_x;
14356 int saved_face_id = it->face_id;
14357 struct text_pos saved_pos;
14358 Lisp_Object saved_object;
14359 struct face *face;
14361 saved_object = it->object;
14362 saved_pos = it->position;
14364 it->what = IT_CHARACTER;
14365 bzero (&it->position, sizeof it->position);
14366 it->object = make_number (0);
14367 it->c = ' ';
14368 it->len = 1;
14370 if (default_face_p)
14371 it->face_id = DEFAULT_FACE_ID;
14372 else if (it->face_before_selective_p)
14373 it->face_id = it->saved_face_id;
14374 face = FACE_FROM_ID (it->f, it->face_id);
14375 it->face_id = FACE_FOR_CHAR (it->f, face, 0);
14377 PRODUCE_GLYPHS (it);
14379 it->override_ascent = -1;
14380 it->constrain_row_ascent_descent_p = 0;
14381 it->current_x = saved_x;
14382 it->object = saved_object;
14383 it->position = saved_pos;
14384 it->what = saved_what;
14385 it->face_id = saved_face_id;
14386 it->len = saved_len;
14387 it->c = saved_c;
14388 return 1;
14392 return 0;
14396 /* Extend the face of the last glyph in the text area of IT->glyph_row
14397 to the end of the display line. Called from display_line.
14398 If the glyph row is empty, add a space glyph to it so that we
14399 know the face to draw. Set the glyph row flag fill_line_p. */
14401 static void
14402 extend_face_to_end_of_line (it)
14403 struct it *it;
14405 struct face *face;
14406 struct frame *f = it->f;
14408 /* If line is already filled, do nothing. */
14409 if (it->current_x >= it->last_visible_x)
14410 return;
14412 /* Face extension extends the background and box of IT->face_id
14413 to the end of the line. If the background equals the background
14414 of the frame, we don't have to do anything. */
14415 if (it->face_before_selective_p)
14416 face = FACE_FROM_ID (it->f, it->saved_face_id);
14417 else
14418 face = FACE_FROM_ID (f, it->face_id);
14420 if (FRAME_WINDOW_P (f)
14421 && face->box == FACE_NO_BOX
14422 && face->background == FRAME_BACKGROUND_PIXEL (f)
14423 && !face->stipple)
14424 return;
14426 /* Set the glyph row flag indicating that the face of the last glyph
14427 in the text area has to be drawn to the end of the text area. */
14428 it->glyph_row->fill_line_p = 1;
14430 /* If current character of IT is not ASCII, make sure we have the
14431 ASCII face. This will be automatically undone the next time
14432 get_next_display_element returns a multibyte character. Note
14433 that the character will always be single byte in unibyte text. */
14434 if (!SINGLE_BYTE_CHAR_P (it->c))
14436 it->face_id = FACE_FOR_CHAR (f, face, 0);
14439 if (FRAME_WINDOW_P (f))
14441 /* If the row is empty, add a space with the current face of IT,
14442 so that we know which face to draw. */
14443 if (it->glyph_row->used[TEXT_AREA] == 0)
14445 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
14446 it->glyph_row->glyphs[TEXT_AREA][0].face_id = it->face_id;
14447 it->glyph_row->used[TEXT_AREA] = 1;
14450 else
14452 /* Save some values that must not be changed. */
14453 int saved_x = it->current_x;
14454 struct text_pos saved_pos;
14455 Lisp_Object saved_object;
14456 enum display_element_type saved_what = it->what;
14457 int saved_face_id = it->face_id;
14459 saved_object = it->object;
14460 saved_pos = it->position;
14462 it->what = IT_CHARACTER;
14463 bzero (&it->position, sizeof it->position);
14464 it->object = make_number (0);
14465 it->c = ' ';
14466 it->len = 1;
14467 it->face_id = face->id;
14469 PRODUCE_GLYPHS (it);
14471 while (it->current_x <= it->last_visible_x)
14472 PRODUCE_GLYPHS (it);
14474 /* Don't count these blanks really. It would let us insert a left
14475 truncation glyph below and make us set the cursor on them, maybe. */
14476 it->current_x = saved_x;
14477 it->object = saved_object;
14478 it->position = saved_pos;
14479 it->what = saved_what;
14480 it->face_id = saved_face_id;
14485 /* Value is non-zero if text starting at CHARPOS in current_buffer is
14486 trailing whitespace. */
14488 static int
14489 trailing_whitespace_p (charpos)
14490 int charpos;
14492 int bytepos = CHAR_TO_BYTE (charpos);
14493 int c = 0;
14495 while (bytepos < ZV_BYTE
14496 && (c = FETCH_CHAR (bytepos),
14497 c == ' ' || c == '\t'))
14498 ++bytepos;
14500 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
14502 if (bytepos != PT_BYTE)
14503 return 1;
14505 return 0;
14509 /* Highlight trailing whitespace, if any, in ROW. */
14511 void
14512 highlight_trailing_whitespace (f, row)
14513 struct frame *f;
14514 struct glyph_row *row;
14516 int used = row->used[TEXT_AREA];
14518 if (used)
14520 struct glyph *start = row->glyphs[TEXT_AREA];
14521 struct glyph *glyph = start + used - 1;
14523 /* Skip over glyphs inserted to display the cursor at the
14524 end of a line, for extending the face of the last glyph
14525 to the end of the line on terminals, and for truncation
14526 and continuation glyphs. */
14527 while (glyph >= start
14528 && glyph->type == CHAR_GLYPH
14529 && INTEGERP (glyph->object))
14530 --glyph;
14532 /* If last glyph is a space or stretch, and it's trailing
14533 whitespace, set the face of all trailing whitespace glyphs in
14534 IT->glyph_row to `trailing-whitespace'. */
14535 if (glyph >= start
14536 && BUFFERP (glyph->object)
14537 && (glyph->type == STRETCH_GLYPH
14538 || (glyph->type == CHAR_GLYPH
14539 && glyph->u.ch == ' '))
14540 && trailing_whitespace_p (glyph->charpos))
14542 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0, 0);
14543 if (face_id < 0)
14544 return;
14546 while (glyph >= start
14547 && BUFFERP (glyph->object)
14548 && (glyph->type == STRETCH_GLYPH
14549 || (glyph->type == CHAR_GLYPH
14550 && glyph->u.ch == ' ')))
14551 (glyph--)->face_id = face_id;
14557 /* Value is non-zero if glyph row ROW in window W should be
14558 used to hold the cursor. */
14560 static int
14561 cursor_row_p (w, row)
14562 struct window *w;
14563 struct glyph_row *row;
14565 int cursor_row_p = 1;
14567 if (PT == MATRIX_ROW_END_CHARPOS (row))
14569 /* If the row ends with a newline from a string, we don't want
14570 the cursor there (if the row is continued it doesn't end in a
14571 newline). */
14572 if (CHARPOS (row->end.string_pos) >= 0
14573 || MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
14574 cursor_row_p = row->continued_p;
14576 /* If the row ends at ZV, display the cursor at the end of that
14577 row instead of at the start of the row below. */
14578 else if (row->ends_at_zv_p)
14579 cursor_row_p = 1;
14580 else
14581 cursor_row_p = 0;
14584 return cursor_row_p;
14588 /* Construct the glyph row IT->glyph_row in the desired matrix of
14589 IT->w from text at the current position of IT. See dispextern.h
14590 for an overview of struct it. Value is non-zero if
14591 IT->glyph_row displays text, as opposed to a line displaying ZV
14592 only. */
14594 static int
14595 display_line (it)
14596 struct it *it;
14598 struct glyph_row *row = it->glyph_row;
14599 int overlay_arrow_bitmap;
14600 Lisp_Object overlay_arrow_string;
14602 /* We always start displaying at hpos zero even if hscrolled. */
14603 xassert (it->hpos == 0 && it->current_x == 0);
14605 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
14606 >= it->w->desired_matrix->nrows)
14608 it->w->nrows_scale_factor++;
14609 fonts_changed_p = 1;
14610 return 0;
14613 /* Is IT->w showing the region? */
14614 it->w->region_showing = it->region_beg_charpos > 0 ? Qt : Qnil;
14616 /* Clear the result glyph row and enable it. */
14617 prepare_desired_row (row);
14619 row->y = it->current_y;
14620 row->start = it->start;
14621 row->continuation_lines_width = it->continuation_lines_width;
14622 row->displays_text_p = 1;
14623 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
14624 it->starts_in_middle_of_char_p = 0;
14626 /* Arrange the overlays nicely for our purposes. Usually, we call
14627 display_line on only one line at a time, in which case this
14628 can't really hurt too much, or we call it on lines which appear
14629 one after another in the buffer, in which case all calls to
14630 recenter_overlay_lists but the first will be pretty cheap. */
14631 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
14633 /* Move over display elements that are not visible because we are
14634 hscrolled. This may stop at an x-position < IT->first_visible_x
14635 if the first glyph is partially visible or if we hit a line end. */
14636 if (it->current_x < it->first_visible_x)
14638 move_it_in_display_line_to (it, ZV, it->first_visible_x,
14639 MOVE_TO_POS | MOVE_TO_X);
14642 /* Get the initial row height. This is either the height of the
14643 text hscrolled, if there is any, or zero. */
14644 row->ascent = it->max_ascent;
14645 row->height = it->max_ascent + it->max_descent;
14646 row->phys_ascent = it->max_phys_ascent;
14647 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
14648 row->extra_line_spacing = it->max_extra_line_spacing;
14650 /* Loop generating characters. The loop is left with IT on the next
14651 character to display. */
14652 while (1)
14654 int n_glyphs_before, hpos_before, x_before;
14655 int x, i, nglyphs;
14656 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
14658 /* Retrieve the next thing to display. Value is zero if end of
14659 buffer reached. */
14660 if (!get_next_display_element (it))
14662 /* Maybe add a space at the end of this line that is used to
14663 display the cursor there under X. Set the charpos of the
14664 first glyph of blank lines not corresponding to any text
14665 to -1. */
14666 #ifdef HAVE_WINDOW_SYSTEM
14667 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14668 row->exact_window_width_line_p = 1;
14669 else
14670 #endif /* HAVE_WINDOW_SYSTEM */
14671 if ((append_space_for_newline (it, 1) && row->used[TEXT_AREA] == 1)
14672 || row->used[TEXT_AREA] == 0)
14674 row->glyphs[TEXT_AREA]->charpos = -1;
14675 row->displays_text_p = 0;
14677 if (!NILP (XBUFFER (it->w->buffer)->indicate_empty_lines)
14678 && (!MINI_WINDOW_P (it->w)
14679 || (minibuf_level && EQ (it->window, minibuf_window))))
14680 row->indicate_empty_line_p = 1;
14683 it->continuation_lines_width = 0;
14684 row->ends_at_zv_p = 1;
14685 break;
14688 /* Now, get the metrics of what we want to display. This also
14689 generates glyphs in `row' (which is IT->glyph_row). */
14690 n_glyphs_before = row->used[TEXT_AREA];
14691 x = it->current_x;
14693 /* Remember the line height so far in case the next element doesn't
14694 fit on the line. */
14695 if (!it->truncate_lines_p)
14697 ascent = it->max_ascent;
14698 descent = it->max_descent;
14699 phys_ascent = it->max_phys_ascent;
14700 phys_descent = it->max_phys_descent;
14703 PRODUCE_GLYPHS (it);
14705 /* If this display element was in marginal areas, continue with
14706 the next one. */
14707 if (it->area != TEXT_AREA)
14709 row->ascent = max (row->ascent, it->max_ascent);
14710 row->height = max (row->height, it->max_ascent + it->max_descent);
14711 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14712 row->phys_height = max (row->phys_height,
14713 it->max_phys_ascent + it->max_phys_descent);
14714 row->extra_line_spacing = max (row->extra_line_spacing,
14715 it->max_extra_line_spacing);
14716 set_iterator_to_next (it, 1);
14717 continue;
14720 /* Does the display element fit on the line? If we truncate
14721 lines, we should draw past the right edge of the window. If
14722 we don't truncate, we want to stop so that we can display the
14723 continuation glyph before the right margin. If lines are
14724 continued, there are two possible strategies for characters
14725 resulting in more than 1 glyph (e.g. tabs): Display as many
14726 glyphs as possible in this line and leave the rest for the
14727 continuation line, or display the whole element in the next
14728 line. Original redisplay did the former, so we do it also. */
14729 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
14730 hpos_before = it->hpos;
14731 x_before = x;
14733 if (/* Not a newline. */
14734 nglyphs > 0
14735 /* Glyphs produced fit entirely in the line. */
14736 && it->current_x < it->last_visible_x)
14738 it->hpos += nglyphs;
14739 row->ascent = max (row->ascent, it->max_ascent);
14740 row->height = max (row->height, it->max_ascent + it->max_descent);
14741 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14742 row->phys_height = max (row->phys_height,
14743 it->max_phys_ascent + it->max_phys_descent);
14744 row->extra_line_spacing = max (row->extra_line_spacing,
14745 it->max_extra_line_spacing);
14746 if (it->current_x - it->pixel_width < it->first_visible_x)
14747 row->x = x - it->first_visible_x;
14749 else
14751 int new_x;
14752 struct glyph *glyph;
14754 for (i = 0; i < nglyphs; ++i, x = new_x)
14756 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
14757 new_x = x + glyph->pixel_width;
14759 if (/* Lines are continued. */
14760 !it->truncate_lines_p
14761 && (/* Glyph doesn't fit on the line. */
14762 new_x > it->last_visible_x
14763 /* Or it fits exactly on a window system frame. */
14764 || (new_x == it->last_visible_x
14765 && FRAME_WINDOW_P (it->f))))
14767 /* End of a continued line. */
14769 if (it->hpos == 0
14770 || (new_x == it->last_visible_x
14771 && FRAME_WINDOW_P (it->f)))
14773 /* Current glyph is the only one on the line or
14774 fits exactly on the line. We must continue
14775 the line because we can't draw the cursor
14776 after the glyph. */
14777 row->continued_p = 1;
14778 it->current_x = new_x;
14779 it->continuation_lines_width += new_x;
14780 ++it->hpos;
14781 if (i == nglyphs - 1)
14783 set_iterator_to_next (it, 1);
14784 #ifdef HAVE_WINDOW_SYSTEM
14785 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14787 if (!get_next_display_element (it))
14789 row->exact_window_width_line_p = 1;
14790 it->continuation_lines_width = 0;
14791 row->continued_p = 0;
14792 row->ends_at_zv_p = 1;
14794 else if (ITERATOR_AT_END_OF_LINE_P (it))
14796 row->continued_p = 0;
14797 row->exact_window_width_line_p = 1;
14800 #endif /* HAVE_WINDOW_SYSTEM */
14803 else if (CHAR_GLYPH_PADDING_P (*glyph)
14804 && !FRAME_WINDOW_P (it->f))
14806 /* A padding glyph that doesn't fit on this line.
14807 This means the whole character doesn't fit
14808 on the line. */
14809 row->used[TEXT_AREA] = n_glyphs_before;
14811 /* Fill the rest of the row with continuation
14812 glyphs like in 20.x. */
14813 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
14814 < row->glyphs[1 + TEXT_AREA])
14815 produce_special_glyphs (it, IT_CONTINUATION);
14817 row->continued_p = 1;
14818 it->current_x = x_before;
14819 it->continuation_lines_width += x_before;
14821 /* Restore the height to what it was before the
14822 element not fitting on the line. */
14823 it->max_ascent = ascent;
14824 it->max_descent = descent;
14825 it->max_phys_ascent = phys_ascent;
14826 it->max_phys_descent = phys_descent;
14828 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
14830 /* A TAB that extends past the right edge of the
14831 window. This produces a single glyph on
14832 window system frames. We leave the glyph in
14833 this row and let it fill the row, but don't
14834 consume the TAB. */
14835 it->continuation_lines_width += it->last_visible_x;
14836 row->ends_in_middle_of_char_p = 1;
14837 row->continued_p = 1;
14838 glyph->pixel_width = it->last_visible_x - x;
14839 it->starts_in_middle_of_char_p = 1;
14841 else
14843 /* Something other than a TAB that draws past
14844 the right edge of the window. Restore
14845 positions to values before the element. */
14846 row->used[TEXT_AREA] = n_glyphs_before + i;
14848 /* Display continuation glyphs. */
14849 if (!FRAME_WINDOW_P (it->f))
14850 produce_special_glyphs (it, IT_CONTINUATION);
14851 row->continued_p = 1;
14853 it->continuation_lines_width += x;
14855 if (nglyphs > 1 && i > 0)
14857 row->ends_in_middle_of_char_p = 1;
14858 it->starts_in_middle_of_char_p = 1;
14861 /* Restore the height to what it was before the
14862 element not fitting on the line. */
14863 it->max_ascent = ascent;
14864 it->max_descent = descent;
14865 it->max_phys_ascent = phys_ascent;
14866 it->max_phys_descent = phys_descent;
14869 break;
14871 else if (new_x > it->first_visible_x)
14873 /* Increment number of glyphs actually displayed. */
14874 ++it->hpos;
14876 if (x < it->first_visible_x)
14877 /* Glyph is partially visible, i.e. row starts at
14878 negative X position. */
14879 row->x = x - it->first_visible_x;
14881 else
14883 /* Glyph is completely off the left margin of the
14884 window. This should not happen because of the
14885 move_it_in_display_line at the start of this
14886 function, unless the text display area of the
14887 window is empty. */
14888 xassert (it->first_visible_x <= it->last_visible_x);
14892 row->ascent = max (row->ascent, it->max_ascent);
14893 row->height = max (row->height, it->max_ascent + it->max_descent);
14894 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14895 row->phys_height = max (row->phys_height,
14896 it->max_phys_ascent + it->max_phys_descent);
14897 row->extra_line_spacing = max (row->extra_line_spacing,
14898 it->max_extra_line_spacing);
14900 /* End of this display line if row is continued. */
14901 if (row->continued_p || row->ends_at_zv_p)
14902 break;
14905 at_end_of_line:
14906 /* Is this a line end? If yes, we're also done, after making
14907 sure that a non-default face is extended up to the right
14908 margin of the window. */
14909 if (ITERATOR_AT_END_OF_LINE_P (it))
14911 int used_before = row->used[TEXT_AREA];
14913 row->ends_in_newline_from_string_p = STRINGP (it->object);
14915 #ifdef HAVE_WINDOW_SYSTEM
14916 /* Add a space at the end of the line that is used to
14917 display the cursor there. */
14918 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14919 append_space_for_newline (it, 0);
14920 #endif /* HAVE_WINDOW_SYSTEM */
14922 /* Extend the face to the end of the line. */
14923 extend_face_to_end_of_line (it);
14925 /* Make sure we have the position. */
14926 if (used_before == 0)
14927 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
14929 /* Consume the line end. This skips over invisible lines. */
14930 set_iterator_to_next (it, 1);
14931 it->continuation_lines_width = 0;
14932 break;
14935 /* Proceed with next display element. Note that this skips
14936 over lines invisible because of selective display. */
14937 set_iterator_to_next (it, 1);
14939 /* If we truncate lines, we are done when the last displayed
14940 glyphs reach past the right margin of the window. */
14941 if (it->truncate_lines_p
14942 && (FRAME_WINDOW_P (it->f)
14943 ? (it->current_x >= it->last_visible_x)
14944 : (it->current_x > it->last_visible_x)))
14946 /* Maybe add truncation glyphs. */
14947 if (!FRAME_WINDOW_P (it->f))
14949 int i, n;
14951 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
14952 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
14953 break;
14955 for (n = row->used[TEXT_AREA]; i < n; ++i)
14957 row->used[TEXT_AREA] = i;
14958 produce_special_glyphs (it, IT_TRUNCATION);
14961 #ifdef HAVE_WINDOW_SYSTEM
14962 else
14964 /* Don't truncate if we can overflow newline into fringe. */
14965 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14967 if (!get_next_display_element (it))
14969 it->continuation_lines_width = 0;
14970 row->ends_at_zv_p = 1;
14971 row->exact_window_width_line_p = 1;
14972 break;
14974 if (ITERATOR_AT_END_OF_LINE_P (it))
14976 row->exact_window_width_line_p = 1;
14977 goto at_end_of_line;
14981 #endif /* HAVE_WINDOW_SYSTEM */
14983 row->truncated_on_right_p = 1;
14984 it->continuation_lines_width = 0;
14985 reseat_at_next_visible_line_start (it, 0);
14986 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
14987 it->hpos = hpos_before;
14988 it->current_x = x_before;
14989 break;
14993 /* If line is not empty and hscrolled, maybe insert truncation glyphs
14994 at the left window margin. */
14995 if (it->first_visible_x
14996 && IT_CHARPOS (*it) != MATRIX_ROW_START_CHARPOS (row))
14998 if (!FRAME_WINDOW_P (it->f))
14999 insert_left_trunc_glyphs (it);
15000 row->truncated_on_left_p = 1;
15003 /* If the start of this line is the overlay arrow-position, then
15004 mark this glyph row as the one containing the overlay arrow.
15005 This is clearly a mess with variable size fonts. It would be
15006 better to let it be displayed like cursors under X. */
15007 if (! overlay_arrow_seen
15008 && (overlay_arrow_string
15009 = overlay_arrow_at_row (it, row, &overlay_arrow_bitmap),
15010 !NILP (overlay_arrow_string)))
15012 /* Overlay arrow in window redisplay is a fringe bitmap. */
15013 if (STRINGP (overlay_arrow_string))
15015 struct glyph_row *arrow_row
15016 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
15017 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
15018 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
15019 struct glyph *p = row->glyphs[TEXT_AREA];
15020 struct glyph *p2, *end;
15022 /* Copy the arrow glyphs. */
15023 while (glyph < arrow_end)
15024 *p++ = *glyph++;
15026 /* Throw away padding glyphs. */
15027 p2 = p;
15028 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
15029 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
15030 ++p2;
15031 if (p2 > p)
15033 while (p2 < end)
15034 *p++ = *p2++;
15035 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
15038 else
15040 it->w->overlay_arrow_bitmap = overlay_arrow_bitmap;
15041 row->overlay_arrow_p = 1;
15043 overlay_arrow_seen = 1;
15046 /* Compute pixel dimensions of this line. */
15047 compute_line_metrics (it);
15049 /* Remember the position at which this line ends. */
15050 row->end = it->current;
15052 /* Save fringe bitmaps in this row. */
15053 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
15054 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
15055 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
15056 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
15058 it->left_user_fringe_bitmap = 0;
15059 it->left_user_fringe_face_id = 0;
15060 it->right_user_fringe_bitmap = 0;
15061 it->right_user_fringe_face_id = 0;
15063 /* Maybe set the cursor. */
15064 if (it->w->cursor.vpos < 0
15065 && PT >= MATRIX_ROW_START_CHARPOS (row)
15066 && PT <= MATRIX_ROW_END_CHARPOS (row)
15067 && cursor_row_p (it->w, row))
15068 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
15070 /* Highlight trailing whitespace. */
15071 if (!NILP (Vshow_trailing_whitespace))
15072 highlight_trailing_whitespace (it->f, it->glyph_row);
15074 /* Prepare for the next line. This line starts horizontally at (X
15075 HPOS) = (0 0). Vertical positions are incremented. As a
15076 convenience for the caller, IT->glyph_row is set to the next
15077 row to be used. */
15078 it->current_x = it->hpos = 0;
15079 it->current_y += row->height;
15080 ++it->vpos;
15081 ++it->glyph_row;
15082 it->start = it->current;
15083 return row->displays_text_p;
15088 /***********************************************************************
15089 Menu Bar
15090 ***********************************************************************/
15092 /* Redisplay the menu bar in the frame for window W.
15094 The menu bar of X frames that don't have X toolkit support is
15095 displayed in a special window W->frame->menu_bar_window.
15097 The menu bar of terminal frames is treated specially as far as
15098 glyph matrices are concerned. Menu bar lines are not part of
15099 windows, so the update is done directly on the frame matrix rows
15100 for the menu bar. */
15102 static void
15103 display_menu_bar (w)
15104 struct window *w;
15106 struct frame *f = XFRAME (WINDOW_FRAME (w));
15107 struct it it;
15108 Lisp_Object items;
15109 int i;
15111 /* Don't do all this for graphical frames. */
15112 #ifdef HAVE_NTGUI
15113 if (!NILP (Vwindow_system))
15114 return;
15115 #endif
15116 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
15117 if (FRAME_X_P (f))
15118 return;
15119 #endif
15120 #ifdef MAC_OS
15121 if (FRAME_MAC_P (f))
15122 return;
15123 #endif
15125 #ifdef USE_X_TOOLKIT
15126 xassert (!FRAME_WINDOW_P (f));
15127 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
15128 it.first_visible_x = 0;
15129 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
15130 #else /* not USE_X_TOOLKIT */
15131 if (FRAME_WINDOW_P (f))
15133 /* Menu bar lines are displayed in the desired matrix of the
15134 dummy window menu_bar_window. */
15135 struct window *menu_w;
15136 xassert (WINDOWP (f->menu_bar_window));
15137 menu_w = XWINDOW (f->menu_bar_window);
15138 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
15139 MENU_FACE_ID);
15140 it.first_visible_x = 0;
15141 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
15143 else
15145 /* This is a TTY frame, i.e. character hpos/vpos are used as
15146 pixel x/y. */
15147 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
15148 MENU_FACE_ID);
15149 it.first_visible_x = 0;
15150 it.last_visible_x = FRAME_COLS (f);
15152 #endif /* not USE_X_TOOLKIT */
15154 if (! mode_line_inverse_video)
15155 /* Force the menu-bar to be displayed in the default face. */
15156 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
15158 /* Clear all rows of the menu bar. */
15159 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
15161 struct glyph_row *row = it.glyph_row + i;
15162 clear_glyph_row (row);
15163 row->enabled_p = 1;
15164 row->full_width_p = 1;
15167 /* Display all items of the menu bar. */
15168 items = FRAME_MENU_BAR_ITEMS (it.f);
15169 for (i = 0; i < XVECTOR (items)->size; i += 4)
15171 Lisp_Object string;
15173 /* Stop at nil string. */
15174 string = AREF (items, i + 1);
15175 if (NILP (string))
15176 break;
15178 /* Remember where item was displayed. */
15179 AREF (items, i + 3) = make_number (it.hpos);
15181 /* Display the item, pad with one space. */
15182 if (it.current_x < it.last_visible_x)
15183 display_string (NULL, string, Qnil, 0, 0, &it,
15184 SCHARS (string) + 1, 0, 0, -1);
15187 /* Fill out the line with spaces. */
15188 if (it.current_x < it.last_visible_x)
15189 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
15191 /* Compute the total height of the lines. */
15192 compute_line_metrics (&it);
15197 /***********************************************************************
15198 Mode Line
15199 ***********************************************************************/
15201 /* Redisplay mode lines in the window tree whose root is WINDOW. If
15202 FORCE is non-zero, redisplay mode lines unconditionally.
15203 Otherwise, redisplay only mode lines that are garbaged. Value is
15204 the number of windows whose mode lines were redisplayed. */
15206 static int
15207 redisplay_mode_lines (window, force)
15208 Lisp_Object window;
15209 int force;
15211 int nwindows = 0;
15213 while (!NILP (window))
15215 struct window *w = XWINDOW (window);
15217 if (WINDOWP (w->hchild))
15218 nwindows += redisplay_mode_lines (w->hchild, force);
15219 else if (WINDOWP (w->vchild))
15220 nwindows += redisplay_mode_lines (w->vchild, force);
15221 else if (force
15222 || FRAME_GARBAGED_P (XFRAME (w->frame))
15223 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
15225 struct text_pos lpoint;
15226 struct buffer *old = current_buffer;
15228 /* Set the window's buffer for the mode line display. */
15229 SET_TEXT_POS (lpoint, PT, PT_BYTE);
15230 set_buffer_internal_1 (XBUFFER (w->buffer));
15232 /* Point refers normally to the selected window. For any
15233 other window, set up appropriate value. */
15234 if (!EQ (window, selected_window))
15236 struct text_pos pt;
15238 SET_TEXT_POS_FROM_MARKER (pt, w->pointm);
15239 if (CHARPOS (pt) < BEGV)
15240 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
15241 else if (CHARPOS (pt) > (ZV - 1))
15242 TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
15243 else
15244 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
15247 /* Display mode lines. */
15248 clear_glyph_matrix (w->desired_matrix);
15249 if (display_mode_lines (w))
15251 ++nwindows;
15252 w->must_be_updated_p = 1;
15255 /* Restore old settings. */
15256 set_buffer_internal_1 (old);
15257 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
15260 window = w->next;
15263 return nwindows;
15267 /* Display the mode and/or top line of window W. Value is the number
15268 of mode lines displayed. */
15270 static int
15271 display_mode_lines (w)
15272 struct window *w;
15274 Lisp_Object old_selected_window, old_selected_frame;
15275 int n = 0;
15277 old_selected_frame = selected_frame;
15278 selected_frame = w->frame;
15279 old_selected_window = selected_window;
15280 XSETWINDOW (selected_window, w);
15282 /* These will be set while the mode line specs are processed. */
15283 line_number_displayed = 0;
15284 w->column_number_displayed = Qnil;
15286 if (WINDOW_WANTS_MODELINE_P (w))
15288 struct window *sel_w = XWINDOW (old_selected_window);
15290 /* Select mode line face based on the real selected window. */
15291 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
15292 current_buffer->mode_line_format);
15293 ++n;
15296 if (WINDOW_WANTS_HEADER_LINE_P (w))
15298 display_mode_line (w, HEADER_LINE_FACE_ID,
15299 current_buffer->header_line_format);
15300 ++n;
15303 selected_frame = old_selected_frame;
15304 selected_window = old_selected_window;
15305 return n;
15309 /* Display mode or top line of window W. FACE_ID specifies which line
15310 to display; it is either MODE_LINE_FACE_ID or HEADER_LINE_FACE_ID.
15311 FORMAT is the mode line format to display. Value is the pixel
15312 height of the mode line displayed. */
15314 static int
15315 display_mode_line (w, face_id, format)
15316 struct window *w;
15317 enum face_id face_id;
15318 Lisp_Object format;
15320 struct it it;
15321 struct face *face;
15323 init_iterator (&it, w, -1, -1, NULL, face_id);
15324 prepare_desired_row (it.glyph_row);
15326 it.glyph_row->mode_line_p = 1;
15328 if (! mode_line_inverse_video)
15329 /* Force the mode-line to be displayed in the default face. */
15330 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
15332 /* Temporarily make frame's keyboard the current kboard so that
15333 kboard-local variables in the mode_line_format will get the right
15334 values. */
15335 push_frame_kboard (it.f);
15336 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
15337 pop_frame_kboard ();
15339 /* Fill up with spaces. */
15340 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
15342 compute_line_metrics (&it);
15343 it.glyph_row->full_width_p = 1;
15344 it.glyph_row->continued_p = 0;
15345 it.glyph_row->truncated_on_left_p = 0;
15346 it.glyph_row->truncated_on_right_p = 0;
15348 /* Make a 3D mode-line have a shadow at its right end. */
15349 face = FACE_FROM_ID (it.f, face_id);
15350 extend_face_to_end_of_line (&it);
15351 if (face->box != FACE_NO_BOX)
15353 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
15354 + it.glyph_row->used[TEXT_AREA] - 1);
15355 last->right_box_line_p = 1;
15358 return it.glyph_row->height;
15361 /* Alist that caches the results of :propertize.
15362 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
15363 Lisp_Object mode_line_proptrans_alist;
15365 /* List of strings making up the mode-line. */
15366 Lisp_Object mode_line_string_list;
15368 /* Base face property when building propertized mode line string. */
15369 static Lisp_Object mode_line_string_face;
15370 static Lisp_Object mode_line_string_face_prop;
15373 /* Contribute ELT to the mode line for window IT->w. How it
15374 translates into text depends on its data type.
15376 IT describes the display environment in which we display, as usual.
15378 DEPTH is the depth in recursion. It is used to prevent
15379 infinite recursion here.
15381 FIELD_WIDTH is the number of characters the display of ELT should
15382 occupy in the mode line, and PRECISION is the maximum number of
15383 characters to display from ELT's representation. See
15384 display_string for details.
15386 Returns the hpos of the end of the text generated by ELT.
15388 PROPS is a property list to add to any string we encounter.
15390 If RISKY is nonzero, remove (disregard) any properties in any string
15391 we encounter, and ignore :eval and :propertize.
15393 If the global variable `frame_title_ptr' is non-NULL, then the output
15394 is passed to `store_frame_title' instead of `display_string'. */
15396 static int
15397 display_mode_element (it, depth, field_width, precision, elt, props, risky)
15398 struct it *it;
15399 int depth;
15400 int field_width, precision;
15401 Lisp_Object elt, props;
15402 int risky;
15404 int n = 0, field, prec;
15405 int literal = 0;
15407 tail_recurse:
15408 if (depth > 100)
15409 elt = build_string ("*too-deep*");
15411 depth++;
15413 switch (SWITCH_ENUM_CAST (XTYPE (elt)))
15415 case Lisp_String:
15417 /* A string: output it and check for %-constructs within it. */
15418 unsigned char c;
15419 const unsigned char *this, *lisp_string;
15421 if (!NILP (props) || risky)
15423 Lisp_Object oprops, aelt;
15424 oprops = Ftext_properties_at (make_number (0), elt);
15426 /* If the starting string's properties are not what
15427 we want, translate the string. Also, if the string
15428 is risky, do that anyway. */
15430 if (NILP (Fequal (props, oprops)) || risky)
15432 /* If the starting string has properties,
15433 merge the specified ones onto the existing ones. */
15434 if (! NILP (oprops) && !risky)
15436 Lisp_Object tem;
15438 oprops = Fcopy_sequence (oprops);
15439 tem = props;
15440 while (CONSP (tem))
15442 oprops = Fplist_put (oprops, XCAR (tem),
15443 XCAR (XCDR (tem)));
15444 tem = XCDR (XCDR (tem));
15446 props = oprops;
15449 aelt = Fassoc (elt, mode_line_proptrans_alist);
15450 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
15452 mode_line_proptrans_alist
15453 = Fcons (aelt, Fdelq (aelt, mode_line_proptrans_alist));
15454 elt = XCAR (aelt);
15456 else
15458 Lisp_Object tem;
15460 elt = Fcopy_sequence (elt);
15461 Fset_text_properties (make_number (0), Flength (elt),
15462 props, elt);
15463 /* Add this item to mode_line_proptrans_alist. */
15464 mode_line_proptrans_alist
15465 = Fcons (Fcons (elt, props),
15466 mode_line_proptrans_alist);
15467 /* Truncate mode_line_proptrans_alist
15468 to at most 50 elements. */
15469 tem = Fnthcdr (make_number (50),
15470 mode_line_proptrans_alist);
15471 if (! NILP (tem))
15472 XSETCDR (tem, Qnil);
15477 this = SDATA (elt);
15478 lisp_string = this;
15480 if (literal)
15482 prec = precision - n;
15483 if (frame_title_ptr)
15484 n += store_frame_title (SDATA (elt), -1, prec);
15485 else if (!NILP (mode_line_string_list))
15486 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
15487 else
15488 n += display_string (NULL, elt, Qnil, 0, 0, it,
15489 0, prec, 0, STRING_MULTIBYTE (elt));
15491 break;
15494 while ((precision <= 0 || n < precision)
15495 && *this
15496 && (frame_title_ptr
15497 || !NILP (mode_line_string_list)
15498 || it->current_x < it->last_visible_x))
15500 const unsigned char *last = this;
15502 /* Advance to end of string or next format specifier. */
15503 while ((c = *this++) != '\0' && c != '%')
15506 if (this - 1 != last)
15508 int nchars, nbytes;
15510 /* Output to end of string or up to '%'. Field width
15511 is length of string. Don't output more than
15512 PRECISION allows us. */
15513 --this;
15515 prec = c_string_width (last, this - last, precision - n,
15516 &nchars, &nbytes);
15518 if (frame_title_ptr)
15519 n += store_frame_title (last, 0, prec);
15520 else if (!NILP (mode_line_string_list))
15522 int bytepos = last - lisp_string;
15523 int charpos = string_byte_to_char (elt, bytepos);
15524 int endpos = (precision <= 0
15525 ? string_byte_to_char (elt,
15526 this - lisp_string)
15527 : charpos + nchars);
15529 n += store_mode_line_string (NULL,
15530 Fsubstring (elt, make_number (charpos),
15531 make_number (endpos)),
15532 0, 0, 0, Qnil);
15534 else
15536 int bytepos = last - lisp_string;
15537 int charpos = string_byte_to_char (elt, bytepos);
15538 n += display_string (NULL, elt, Qnil, 0, charpos,
15539 it, 0, prec, 0,
15540 STRING_MULTIBYTE (elt));
15543 else /* c == '%' */
15545 const unsigned char *percent_position = this;
15547 /* Get the specified minimum width. Zero means
15548 don't pad. */
15549 field = 0;
15550 while ((c = *this++) >= '0' && c <= '9')
15551 field = field * 10 + c - '0';
15553 /* Don't pad beyond the total padding allowed. */
15554 if (field_width - n > 0 && field > field_width - n)
15555 field = field_width - n;
15557 /* Note that either PRECISION <= 0 or N < PRECISION. */
15558 prec = precision - n;
15560 if (c == 'M')
15561 n += display_mode_element (it, depth, field, prec,
15562 Vglobal_mode_string, props,
15563 risky);
15564 else if (c != 0)
15566 int multibyte;
15567 int bytepos, charpos;
15568 unsigned char *spec;
15570 bytepos = percent_position - lisp_string;
15571 charpos = (STRING_MULTIBYTE (elt)
15572 ? string_byte_to_char (elt, bytepos)
15573 : bytepos);
15575 spec
15576 = decode_mode_spec (it->w, c, field, prec, &multibyte);
15578 if (frame_title_ptr)
15579 n += store_frame_title (spec, field, prec);
15580 else if (!NILP (mode_line_string_list))
15582 int len = strlen (spec);
15583 Lisp_Object tem = make_string (spec, len);
15584 props = Ftext_properties_at (make_number (charpos), elt);
15585 /* Should only keep face property in props */
15586 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
15588 else
15590 int nglyphs_before, nwritten;
15592 nglyphs_before = it->glyph_row->used[TEXT_AREA];
15593 nwritten = display_string (spec, Qnil, elt,
15594 charpos, 0, it,
15595 field, prec, 0,
15596 multibyte);
15598 /* Assign to the glyphs written above the
15599 string where the `%x' came from, position
15600 of the `%'. */
15601 if (nwritten > 0)
15603 struct glyph *glyph
15604 = (it->glyph_row->glyphs[TEXT_AREA]
15605 + nglyphs_before);
15606 int i;
15608 for (i = 0; i < nwritten; ++i)
15610 glyph[i].object = elt;
15611 glyph[i].charpos = charpos;
15614 n += nwritten;
15618 else /* c == 0 */
15619 break;
15623 break;
15625 case Lisp_Symbol:
15626 /* A symbol: process the value of the symbol recursively
15627 as if it appeared here directly. Avoid error if symbol void.
15628 Special case: if value of symbol is a string, output the string
15629 literally. */
15631 register Lisp_Object tem;
15633 /* If the variable is not marked as risky to set
15634 then its contents are risky to use. */
15635 if (NILP (Fget (elt, Qrisky_local_variable)))
15636 risky = 1;
15638 tem = Fboundp (elt);
15639 if (!NILP (tem))
15641 tem = Fsymbol_value (elt);
15642 /* If value is a string, output that string literally:
15643 don't check for % within it. */
15644 if (STRINGP (tem))
15645 literal = 1;
15647 if (!EQ (tem, elt))
15649 /* Give up right away for nil or t. */
15650 elt = tem;
15651 goto tail_recurse;
15655 break;
15657 case Lisp_Cons:
15659 register Lisp_Object car, tem;
15661 /* A cons cell: five distinct cases.
15662 If first element is :eval or :propertize, do something special.
15663 If first element is a string or a cons, process all the elements
15664 and effectively concatenate them.
15665 If first element is a negative number, truncate displaying cdr to
15666 at most that many characters. If positive, pad (with spaces)
15667 to at least that many characters.
15668 If first element is a symbol, process the cadr or caddr recursively
15669 according to whether the symbol's value is non-nil or nil. */
15670 car = XCAR (elt);
15671 if (EQ (car, QCeval))
15673 /* An element of the form (:eval FORM) means evaluate FORM
15674 and use the result as mode line elements. */
15676 if (risky)
15677 break;
15679 if (CONSP (XCDR (elt)))
15681 Lisp_Object spec;
15682 spec = safe_eval (XCAR (XCDR (elt)));
15683 n += display_mode_element (it, depth, field_width - n,
15684 precision - n, spec, props,
15685 risky);
15688 else if (EQ (car, QCpropertize))
15690 /* An element of the form (:propertize ELT PROPS...)
15691 means display ELT but applying properties PROPS. */
15693 if (risky)
15694 break;
15696 if (CONSP (XCDR (elt)))
15697 n += display_mode_element (it, depth, field_width - n,
15698 precision - n, XCAR (XCDR (elt)),
15699 XCDR (XCDR (elt)), risky);
15701 else if (SYMBOLP (car))
15703 tem = Fboundp (car);
15704 elt = XCDR (elt);
15705 if (!CONSP (elt))
15706 goto invalid;
15707 /* elt is now the cdr, and we know it is a cons cell.
15708 Use its car if CAR has a non-nil value. */
15709 if (!NILP (tem))
15711 tem = Fsymbol_value (car);
15712 if (!NILP (tem))
15714 elt = XCAR (elt);
15715 goto tail_recurse;
15718 /* Symbol's value is nil (or symbol is unbound)
15719 Get the cddr of the original list
15720 and if possible find the caddr and use that. */
15721 elt = XCDR (elt);
15722 if (NILP (elt))
15723 break;
15724 else if (!CONSP (elt))
15725 goto invalid;
15726 elt = XCAR (elt);
15727 goto tail_recurse;
15729 else if (INTEGERP (car))
15731 register int lim = XINT (car);
15732 elt = XCDR (elt);
15733 if (lim < 0)
15735 /* Negative int means reduce maximum width. */
15736 if (precision <= 0)
15737 precision = -lim;
15738 else
15739 precision = min (precision, -lim);
15741 else if (lim > 0)
15743 /* Padding specified. Don't let it be more than
15744 current maximum. */
15745 if (precision > 0)
15746 lim = min (precision, lim);
15748 /* If that's more padding than already wanted, queue it.
15749 But don't reduce padding already specified even if
15750 that is beyond the current truncation point. */
15751 field_width = max (lim, field_width);
15753 goto tail_recurse;
15755 else if (STRINGP (car) || CONSP (car))
15757 register int limit = 50;
15758 /* Limit is to protect against circular lists. */
15759 while (CONSP (elt)
15760 && --limit > 0
15761 && (precision <= 0 || n < precision))
15763 n += display_mode_element (it, depth, field_width - n,
15764 precision - n, XCAR (elt),
15765 props, risky);
15766 elt = XCDR (elt);
15770 break;
15772 default:
15773 invalid:
15774 elt = build_string ("*invalid*");
15775 goto tail_recurse;
15778 /* Pad to FIELD_WIDTH. */
15779 if (field_width > 0 && n < field_width)
15781 if (frame_title_ptr)
15782 n += store_frame_title ("", field_width - n, 0);
15783 else if (!NILP (mode_line_string_list))
15784 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
15785 else
15786 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
15787 0, 0, 0);
15790 return n;
15793 /* Store a mode-line string element in mode_line_string_list.
15795 If STRING is non-null, display that C string. Otherwise, the Lisp
15796 string LISP_STRING is displayed.
15798 FIELD_WIDTH is the minimum number of output glyphs to produce.
15799 If STRING has fewer characters than FIELD_WIDTH, pad to the right
15800 with spaces. FIELD_WIDTH <= 0 means don't pad.
15802 PRECISION is the maximum number of characters to output from
15803 STRING. PRECISION <= 0 means don't truncate the string.
15805 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
15806 properties to the string.
15808 PROPS are the properties to add to the string.
15809 The mode_line_string_face face property is always added to the string.
15812 static int
15813 store_mode_line_string (string, lisp_string, copy_string, field_width, precision, props)
15814 char *string;
15815 Lisp_Object lisp_string;
15816 int copy_string;
15817 int field_width;
15818 int precision;
15819 Lisp_Object props;
15821 int len;
15822 int n = 0;
15824 if (string != NULL)
15826 len = strlen (string);
15827 if (precision > 0 && len > precision)
15828 len = precision;
15829 lisp_string = make_string (string, len);
15830 if (NILP (props))
15831 props = mode_line_string_face_prop;
15832 else if (!NILP (mode_line_string_face))
15834 Lisp_Object face = Fsafe_plist_get (props, Qface);
15835 props = Fcopy_sequence (props);
15836 if (NILP (face))
15837 face = mode_line_string_face;
15838 else
15839 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
15840 props = Fplist_put (props, Qface, face);
15842 Fadd_text_properties (make_number (0), make_number (len),
15843 props, lisp_string);
15845 else
15847 len = XFASTINT (Flength (lisp_string));
15848 if (precision > 0 && len > precision)
15850 len = precision;
15851 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
15852 precision = -1;
15854 if (!NILP (mode_line_string_face))
15856 Lisp_Object face;
15857 if (NILP (props))
15858 props = Ftext_properties_at (make_number (0), lisp_string);
15859 face = Fsafe_plist_get (props, Qface);
15860 if (NILP (face))
15861 face = mode_line_string_face;
15862 else
15863 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
15864 props = Fcons (Qface, Fcons (face, Qnil));
15865 if (copy_string)
15866 lisp_string = Fcopy_sequence (lisp_string);
15868 if (!NILP (props))
15869 Fadd_text_properties (make_number (0), make_number (len),
15870 props, lisp_string);
15873 if (len > 0)
15875 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
15876 n += len;
15879 if (field_width > len)
15881 field_width -= len;
15882 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
15883 if (!NILP (props))
15884 Fadd_text_properties (make_number (0), make_number (field_width),
15885 props, lisp_string);
15886 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
15887 n += field_width;
15890 return n;
15894 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
15895 0, 4, 0,
15896 doc: /* Return the mode-line of selected window as a string.
15897 First optional arg FORMAT specifies a different format string (see
15898 `mode-line-format' for details) to use. If FORMAT is t, return
15899 the buffer's header-line. Second optional arg WINDOW specifies a
15900 different window to use as the context for the formatting.
15901 If third optional arg NO-PROPS is non-nil, string is not propertized.
15902 Fourth optional arg BUFFER specifies which buffer to use. */)
15903 (format, window, no_props, buffer)
15904 Lisp_Object format, window, no_props, buffer;
15906 struct it it;
15907 int len;
15908 struct window *w;
15909 struct buffer *old_buffer = NULL;
15910 enum face_id face_id = DEFAULT_FACE_ID;
15912 if (NILP (window))
15913 window = selected_window;
15914 CHECK_WINDOW (window);
15915 w = XWINDOW (window);
15917 if (NILP (buffer))
15918 buffer = w->buffer;
15920 CHECK_BUFFER (buffer);
15922 if (XBUFFER (buffer) != current_buffer)
15924 old_buffer = current_buffer;
15925 set_buffer_internal_1 (XBUFFER (buffer));
15928 if (NILP (format) || EQ (format, Qt))
15930 face_id = (NILP (format)
15931 ? CURRENT_MODE_LINE_FACE_ID (w)
15932 : HEADER_LINE_FACE_ID);
15933 format = (NILP (format)
15934 ? current_buffer->mode_line_format
15935 : current_buffer->header_line_format);
15938 init_iterator (&it, w, -1, -1, NULL, face_id);
15940 if (NILP (no_props))
15942 mode_line_string_face
15943 = (face_id == MODE_LINE_FACE_ID ? Qmode_line
15944 : face_id == MODE_LINE_INACTIVE_FACE_ID ? Qmode_line_inactive
15945 : face_id == HEADER_LINE_FACE_ID ? Qheader_line : Qnil);
15947 mode_line_string_face_prop
15948 = (NILP (mode_line_string_face) ? Qnil
15949 : Fcons (Qface, Fcons (mode_line_string_face, Qnil)));
15951 /* We need a dummy last element in mode_line_string_list to
15952 indicate we are building the propertized mode-line string.
15953 Using mode_line_string_face_prop here GC protects it. */
15954 mode_line_string_list
15955 = Fcons (mode_line_string_face_prop, Qnil);
15956 frame_title_ptr = NULL;
15958 else
15960 mode_line_string_face_prop = Qnil;
15961 mode_line_string_list = Qnil;
15962 frame_title_ptr = frame_title_buf;
15965 push_frame_kboard (it.f);
15966 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
15967 pop_frame_kboard ();
15969 if (old_buffer)
15970 set_buffer_internal_1 (old_buffer);
15972 if (NILP (no_props))
15974 Lisp_Object str;
15975 mode_line_string_list = Fnreverse (mode_line_string_list);
15976 str = Fmapconcat (intern ("identity"), XCDR (mode_line_string_list),
15977 make_string ("", 0));
15978 mode_line_string_face_prop = Qnil;
15979 mode_line_string_list = Qnil;
15980 return str;
15983 len = frame_title_ptr - frame_title_buf;
15984 if (len > 0 && frame_title_ptr[-1] == '-')
15986 /* Mode lines typically ends with numerous dashes; reduce to two dashes. */
15987 while (frame_title_ptr > frame_title_buf && *--frame_title_ptr == '-')
15989 frame_title_ptr += 3; /* restore last non-dash + two dashes */
15990 if (len > frame_title_ptr - frame_title_buf)
15991 len = frame_title_ptr - frame_title_buf;
15994 frame_title_ptr = NULL;
15995 return make_string (frame_title_buf, len);
15998 /* Write a null-terminated, right justified decimal representation of
15999 the positive integer D to BUF using a minimal field width WIDTH. */
16001 static void
16002 pint2str (buf, width, d)
16003 register char *buf;
16004 register int width;
16005 register int d;
16007 register char *p = buf;
16009 if (d <= 0)
16010 *p++ = '0';
16011 else
16013 while (d > 0)
16015 *p++ = d % 10 + '0';
16016 d /= 10;
16020 for (width -= (int) (p - buf); width > 0; --width)
16021 *p++ = ' ';
16022 *p-- = '\0';
16023 while (p > buf)
16025 d = *buf;
16026 *buf++ = *p;
16027 *p-- = d;
16031 /* Write a null-terminated, right justified decimal and "human
16032 readable" representation of the nonnegative integer D to BUF using
16033 a minimal field width WIDTH. D should be smaller than 999.5e24. */
16035 static const char power_letter[] =
16037 0, /* not used */
16038 'k', /* kilo */
16039 'M', /* mega */
16040 'G', /* giga */
16041 'T', /* tera */
16042 'P', /* peta */
16043 'E', /* exa */
16044 'Z', /* zetta */
16045 'Y' /* yotta */
16048 static void
16049 pint2hrstr (buf, width, d)
16050 char *buf;
16051 int width;
16052 int d;
16054 /* We aim to represent the nonnegative integer D as
16055 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
16056 int quotient = d;
16057 int remainder = 0;
16058 /* -1 means: do not use TENTHS. */
16059 int tenths = -1;
16060 int exponent = 0;
16062 /* Length of QUOTIENT.TENTHS as a string. */
16063 int length;
16065 char * psuffix;
16066 char * p;
16068 if (1000 <= quotient)
16070 /* Scale to the appropriate EXPONENT. */
16073 remainder = quotient % 1000;
16074 quotient /= 1000;
16075 exponent++;
16077 while (1000 <= quotient);
16079 /* Round to nearest and decide whether to use TENTHS or not. */
16080 if (quotient <= 9)
16082 tenths = remainder / 100;
16083 if (50 <= remainder % 100)
16085 if (tenths < 9)
16086 tenths++;
16087 else
16089 quotient++;
16090 if (quotient == 10)
16091 tenths = -1;
16092 else
16093 tenths = 0;
16097 else
16098 if (500 <= remainder)
16100 if (quotient < 999)
16101 quotient++;
16102 else
16104 quotient = 1;
16105 exponent++;
16106 tenths = 0;
16111 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
16112 if (tenths == -1 && quotient <= 99)
16113 if (quotient <= 9)
16114 length = 1;
16115 else
16116 length = 2;
16117 else
16118 length = 3;
16119 p = psuffix = buf + max (width, length);
16121 /* Print EXPONENT. */
16122 if (exponent)
16123 *psuffix++ = power_letter[exponent];
16124 *psuffix = '\0';
16126 /* Print TENTHS. */
16127 if (tenths >= 0)
16129 *--p = '0' + tenths;
16130 *--p = '.';
16133 /* Print QUOTIENT. */
16136 int digit = quotient % 10;
16137 *--p = '0' + digit;
16139 while ((quotient /= 10) != 0);
16141 /* Print leading spaces. */
16142 while (buf < p)
16143 *--p = ' ';
16146 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
16147 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
16148 type of CODING_SYSTEM. Return updated pointer into BUF. */
16150 static unsigned char invalid_eol_type[] = "(*invalid*)";
16152 static char *
16153 decode_mode_spec_coding (coding_system, buf, eol_flag)
16154 Lisp_Object coding_system;
16155 register char *buf;
16156 int eol_flag;
16158 Lisp_Object val;
16159 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
16160 const unsigned char *eol_str;
16161 int eol_str_len;
16162 /* The EOL conversion we are using. */
16163 Lisp_Object eoltype;
16165 val = Fget (coding_system, Qcoding_system);
16166 eoltype = Qnil;
16168 if (!VECTORP (val)) /* Not yet decided. */
16170 if (multibyte)
16171 *buf++ = '-';
16172 if (eol_flag)
16173 eoltype = eol_mnemonic_undecided;
16174 /* Don't mention EOL conversion if it isn't decided. */
16176 else
16178 Lisp_Object eolvalue;
16180 eolvalue = Fget (coding_system, Qeol_type);
16182 if (multibyte)
16183 *buf++ = XFASTINT (AREF (val, 1));
16185 if (eol_flag)
16187 /* The EOL conversion that is normal on this system. */
16189 if (NILP (eolvalue)) /* Not yet decided. */
16190 eoltype = eol_mnemonic_undecided;
16191 else if (VECTORP (eolvalue)) /* Not yet decided. */
16192 eoltype = eol_mnemonic_undecided;
16193 else /* INTEGERP (eolvalue) -- 0:LF, 1:CRLF, 2:CR */
16194 eoltype = (XFASTINT (eolvalue) == 0
16195 ? eol_mnemonic_unix
16196 : (XFASTINT (eolvalue) == 1
16197 ? eol_mnemonic_dos : eol_mnemonic_mac));
16201 if (eol_flag)
16203 /* Mention the EOL conversion if it is not the usual one. */
16204 if (STRINGP (eoltype))
16206 eol_str = SDATA (eoltype);
16207 eol_str_len = SBYTES (eoltype);
16209 else if (INTEGERP (eoltype)
16210 && CHAR_VALID_P (XINT (eoltype), 0))
16212 unsigned char *tmp = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
16213 eol_str_len = CHAR_STRING (XINT (eoltype), tmp);
16214 eol_str = tmp;
16216 else
16218 eol_str = invalid_eol_type;
16219 eol_str_len = sizeof (invalid_eol_type) - 1;
16221 bcopy (eol_str, buf, eol_str_len);
16222 buf += eol_str_len;
16225 return buf;
16228 /* Return a string for the output of a mode line %-spec for window W,
16229 generated by character C. PRECISION >= 0 means don't return a
16230 string longer than that value. FIELD_WIDTH > 0 means pad the
16231 string returned with spaces to that value. Return 1 in *MULTIBYTE
16232 if the result is multibyte text.
16234 Note we operate on the current buffer for most purposes,
16235 the exception being w->base_line_pos. */
16237 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
16239 static char *
16240 decode_mode_spec (w, c, field_width, precision, multibyte)
16241 struct window *w;
16242 register int c;
16243 int field_width, precision;
16244 int *multibyte;
16246 Lisp_Object obj;
16247 struct frame *f = XFRAME (WINDOW_FRAME (w));
16248 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
16249 struct buffer *b = current_buffer;
16251 obj = Qnil;
16252 *multibyte = 0;
16254 switch (c)
16256 case '*':
16257 if (!NILP (b->read_only))
16258 return "%";
16259 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
16260 return "*";
16261 return "-";
16263 case '+':
16264 /* This differs from %* only for a modified read-only buffer. */
16265 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
16266 return "*";
16267 if (!NILP (b->read_only))
16268 return "%";
16269 return "-";
16271 case '&':
16272 /* This differs from %* in ignoring read-only-ness. */
16273 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
16274 return "*";
16275 return "-";
16277 case '%':
16278 return "%";
16280 case '[':
16282 int i;
16283 char *p;
16285 if (command_loop_level > 5)
16286 return "[[[... ";
16287 p = decode_mode_spec_buf;
16288 for (i = 0; i < command_loop_level; i++)
16289 *p++ = '[';
16290 *p = 0;
16291 return decode_mode_spec_buf;
16294 case ']':
16296 int i;
16297 char *p;
16299 if (command_loop_level > 5)
16300 return " ...]]]";
16301 p = decode_mode_spec_buf;
16302 for (i = 0; i < command_loop_level; i++)
16303 *p++ = ']';
16304 *p = 0;
16305 return decode_mode_spec_buf;
16308 case '-':
16310 register int i;
16312 /* Let lots_of_dashes be a string of infinite length. */
16313 if (!NILP (mode_line_string_list))
16314 return "--";
16315 if (field_width <= 0
16316 || field_width > sizeof (lots_of_dashes))
16318 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
16319 decode_mode_spec_buf[i] = '-';
16320 decode_mode_spec_buf[i] = '\0';
16321 return decode_mode_spec_buf;
16323 else
16324 return lots_of_dashes;
16327 case 'b':
16328 obj = b->name;
16329 break;
16331 case 'c':
16333 int col = (int) current_column (); /* iftc */
16334 w->column_number_displayed = make_number (col);
16335 pint2str (decode_mode_spec_buf, field_width, col);
16336 return decode_mode_spec_buf;
16339 case 'F':
16340 /* %F displays the frame name. */
16341 if (!NILP (f->title))
16342 return (char *) SDATA (f->title);
16343 if (f->explicit_name || ! FRAME_WINDOW_P (f))
16344 return (char *) SDATA (f->name);
16345 return "Emacs";
16347 case 'f':
16348 obj = b->filename;
16349 break;
16351 case 'i':
16353 int size = ZV - BEGV;
16354 pint2str (decode_mode_spec_buf, field_width, size);
16355 return decode_mode_spec_buf;
16358 case 'I':
16360 int size = ZV - BEGV;
16361 pint2hrstr (decode_mode_spec_buf, field_width, size);
16362 return decode_mode_spec_buf;
16365 case 'l':
16367 int startpos = XMARKER (w->start)->charpos;
16368 int startpos_byte = marker_byte_position (w->start);
16369 int line, linepos, linepos_byte, topline;
16370 int nlines, junk;
16371 int height = WINDOW_TOTAL_LINES (w);
16373 /* If we decided that this buffer isn't suitable for line numbers,
16374 don't forget that too fast. */
16375 if (EQ (w->base_line_pos, w->buffer))
16376 goto no_value;
16377 /* But do forget it, if the window shows a different buffer now. */
16378 else if (BUFFERP (w->base_line_pos))
16379 w->base_line_pos = Qnil;
16381 /* If the buffer is very big, don't waste time. */
16382 if (INTEGERP (Vline_number_display_limit)
16383 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
16385 w->base_line_pos = Qnil;
16386 w->base_line_number = Qnil;
16387 goto no_value;
16390 if (!NILP (w->base_line_number)
16391 && !NILP (w->base_line_pos)
16392 && XFASTINT (w->base_line_pos) <= startpos)
16394 line = XFASTINT (w->base_line_number);
16395 linepos = XFASTINT (w->base_line_pos);
16396 linepos_byte = buf_charpos_to_bytepos (b, linepos);
16398 else
16400 line = 1;
16401 linepos = BUF_BEGV (b);
16402 linepos_byte = BUF_BEGV_BYTE (b);
16405 /* Count lines from base line to window start position. */
16406 nlines = display_count_lines (linepos, linepos_byte,
16407 startpos_byte,
16408 startpos, &junk);
16410 topline = nlines + line;
16412 /* Determine a new base line, if the old one is too close
16413 or too far away, or if we did not have one.
16414 "Too close" means it's plausible a scroll-down would
16415 go back past it. */
16416 if (startpos == BUF_BEGV (b))
16418 w->base_line_number = make_number (topline);
16419 w->base_line_pos = make_number (BUF_BEGV (b));
16421 else if (nlines < height + 25 || nlines > height * 3 + 50
16422 || linepos == BUF_BEGV (b))
16424 int limit = BUF_BEGV (b);
16425 int limit_byte = BUF_BEGV_BYTE (b);
16426 int position;
16427 int distance = (height * 2 + 30) * line_number_display_limit_width;
16429 if (startpos - distance > limit)
16431 limit = startpos - distance;
16432 limit_byte = CHAR_TO_BYTE (limit);
16435 nlines = display_count_lines (startpos, startpos_byte,
16436 limit_byte,
16437 - (height * 2 + 30),
16438 &position);
16439 /* If we couldn't find the lines we wanted within
16440 line_number_display_limit_width chars per line,
16441 give up on line numbers for this window. */
16442 if (position == limit_byte && limit == startpos - distance)
16444 w->base_line_pos = w->buffer;
16445 w->base_line_number = Qnil;
16446 goto no_value;
16449 w->base_line_number = make_number (topline - nlines);
16450 w->base_line_pos = make_number (BYTE_TO_CHAR (position));
16453 /* Now count lines from the start pos to point. */
16454 nlines = display_count_lines (startpos, startpos_byte,
16455 PT_BYTE, PT, &junk);
16457 /* Record that we did display the line number. */
16458 line_number_displayed = 1;
16460 /* Make the string to show. */
16461 pint2str (decode_mode_spec_buf, field_width, topline + nlines);
16462 return decode_mode_spec_buf;
16463 no_value:
16465 char* p = decode_mode_spec_buf;
16466 int pad = field_width - 2;
16467 while (pad-- > 0)
16468 *p++ = ' ';
16469 *p++ = '?';
16470 *p++ = '?';
16471 *p = '\0';
16472 return decode_mode_spec_buf;
16475 break;
16477 case 'm':
16478 obj = b->mode_name;
16479 break;
16481 case 'n':
16482 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
16483 return " Narrow";
16484 break;
16486 case 'p':
16488 int pos = marker_position (w->start);
16489 int total = BUF_ZV (b) - BUF_BEGV (b);
16491 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
16493 if (pos <= BUF_BEGV (b))
16494 return "All";
16495 else
16496 return "Bottom";
16498 else if (pos <= BUF_BEGV (b))
16499 return "Top";
16500 else
16502 if (total > 1000000)
16503 /* Do it differently for a large value, to avoid overflow. */
16504 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
16505 else
16506 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
16507 /* We can't normally display a 3-digit number,
16508 so get us a 2-digit number that is close. */
16509 if (total == 100)
16510 total = 99;
16511 sprintf (decode_mode_spec_buf, "%2d%%", total);
16512 return decode_mode_spec_buf;
16516 /* Display percentage of size above the bottom of the screen. */
16517 case 'P':
16519 int toppos = marker_position (w->start);
16520 int botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
16521 int total = BUF_ZV (b) - BUF_BEGV (b);
16523 if (botpos >= BUF_ZV (b))
16525 if (toppos <= BUF_BEGV (b))
16526 return "All";
16527 else
16528 return "Bottom";
16530 else
16532 if (total > 1000000)
16533 /* Do it differently for a large value, to avoid overflow. */
16534 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
16535 else
16536 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
16537 /* We can't normally display a 3-digit number,
16538 so get us a 2-digit number that is close. */
16539 if (total == 100)
16540 total = 99;
16541 if (toppos <= BUF_BEGV (b))
16542 sprintf (decode_mode_spec_buf, "Top%2d%%", total);
16543 else
16544 sprintf (decode_mode_spec_buf, "%2d%%", total);
16545 return decode_mode_spec_buf;
16549 case 's':
16550 /* status of process */
16551 obj = Fget_buffer_process (Fcurrent_buffer ());
16552 if (NILP (obj))
16553 return "no process";
16554 #ifdef subprocesses
16555 obj = Fsymbol_name (Fprocess_status (obj));
16556 #endif
16557 break;
16559 case 't': /* indicate TEXT or BINARY */
16560 #ifdef MODE_LINE_BINARY_TEXT
16561 return MODE_LINE_BINARY_TEXT (b);
16562 #else
16563 return "T";
16564 #endif
16566 case 'z':
16567 /* coding-system (not including end-of-line format) */
16568 case 'Z':
16569 /* coding-system (including end-of-line type) */
16571 int eol_flag = (c == 'Z');
16572 char *p = decode_mode_spec_buf;
16574 if (! FRAME_WINDOW_P (f))
16576 /* No need to mention EOL here--the terminal never needs
16577 to do EOL conversion. */
16578 p = decode_mode_spec_coding (keyboard_coding.symbol, p, 0);
16579 p = decode_mode_spec_coding (terminal_coding.symbol, p, 0);
16581 p = decode_mode_spec_coding (b->buffer_file_coding_system,
16582 p, eol_flag);
16584 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
16585 #ifdef subprocesses
16586 obj = Fget_buffer_process (Fcurrent_buffer ());
16587 if (PROCESSP (obj))
16589 p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system,
16590 p, eol_flag);
16591 p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system,
16592 p, eol_flag);
16594 #endif /* subprocesses */
16595 #endif /* 0 */
16596 *p = 0;
16597 return decode_mode_spec_buf;
16601 if (STRINGP (obj))
16603 *multibyte = STRING_MULTIBYTE (obj);
16604 return (char *) SDATA (obj);
16606 else
16607 return "";
16611 /* Count up to COUNT lines starting from START / START_BYTE.
16612 But don't go beyond LIMIT_BYTE.
16613 Return the number of lines thus found (always nonnegative).
16615 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
16617 static int
16618 display_count_lines (start, start_byte, limit_byte, count, byte_pos_ptr)
16619 int start, start_byte, limit_byte, count;
16620 int *byte_pos_ptr;
16622 register unsigned char *cursor;
16623 unsigned char *base;
16625 register int ceiling;
16626 register unsigned char *ceiling_addr;
16627 int orig_count = count;
16629 /* If we are not in selective display mode,
16630 check only for newlines. */
16631 int selective_display = (!NILP (current_buffer->selective_display)
16632 && !INTEGERP (current_buffer->selective_display));
16634 if (count > 0)
16636 while (start_byte < limit_byte)
16638 ceiling = BUFFER_CEILING_OF (start_byte);
16639 ceiling = min (limit_byte - 1, ceiling);
16640 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
16641 base = (cursor = BYTE_POS_ADDR (start_byte));
16642 while (1)
16644 if (selective_display)
16645 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
16647 else
16648 while (*cursor != '\n' && ++cursor != ceiling_addr)
16651 if (cursor != ceiling_addr)
16653 if (--count == 0)
16655 start_byte += cursor - base + 1;
16656 *byte_pos_ptr = start_byte;
16657 return orig_count;
16659 else
16660 if (++cursor == ceiling_addr)
16661 break;
16663 else
16664 break;
16666 start_byte += cursor - base;
16669 else
16671 while (start_byte > limit_byte)
16673 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
16674 ceiling = max (limit_byte, ceiling);
16675 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1;
16676 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
16677 while (1)
16679 if (selective_display)
16680 while (--cursor != ceiling_addr
16681 && *cursor != '\n' && *cursor != 015)
16683 else
16684 while (--cursor != ceiling_addr && *cursor != '\n')
16687 if (cursor != ceiling_addr)
16689 if (++count == 0)
16691 start_byte += cursor - base + 1;
16692 *byte_pos_ptr = start_byte;
16693 /* When scanning backwards, we should
16694 not count the newline posterior to which we stop. */
16695 return - orig_count - 1;
16698 else
16699 break;
16701 /* Here we add 1 to compensate for the last decrement
16702 of CURSOR, which took it past the valid range. */
16703 start_byte += cursor - base + 1;
16707 *byte_pos_ptr = limit_byte;
16709 if (count < 0)
16710 return - orig_count + count;
16711 return orig_count - count;
16717 /***********************************************************************
16718 Displaying strings
16719 ***********************************************************************/
16721 /* Display a NUL-terminated string, starting with index START.
16723 If STRING is non-null, display that C string. Otherwise, the Lisp
16724 string LISP_STRING is displayed.
16726 If FACE_STRING is not nil, FACE_STRING_POS is a position in
16727 FACE_STRING. Display STRING or LISP_STRING with the face at
16728 FACE_STRING_POS in FACE_STRING:
16730 Display the string in the environment given by IT, but use the
16731 standard display table, temporarily.
16733 FIELD_WIDTH is the minimum number of output glyphs to produce.
16734 If STRING has fewer characters than FIELD_WIDTH, pad to the right
16735 with spaces. If STRING has more characters, more than FIELD_WIDTH
16736 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
16738 PRECISION is the maximum number of characters to output from
16739 STRING. PRECISION < 0 means don't truncate the string.
16741 This is roughly equivalent to printf format specifiers:
16743 FIELD_WIDTH PRECISION PRINTF
16744 ----------------------------------------
16745 -1 -1 %s
16746 -1 10 %.10s
16747 10 -1 %10s
16748 20 10 %20.10s
16750 MULTIBYTE zero means do not display multibyte chars, > 0 means do
16751 display them, and < 0 means obey the current buffer's value of
16752 enable_multibyte_characters.
16754 Value is the number of glyphs produced. */
16756 static int
16757 display_string (string, lisp_string, face_string, face_string_pos,
16758 start, it, field_width, precision, max_x, multibyte)
16759 unsigned char *string;
16760 Lisp_Object lisp_string;
16761 Lisp_Object face_string;
16762 int face_string_pos;
16763 int start;
16764 struct it *it;
16765 int field_width, precision, max_x;
16766 int multibyte;
16768 int hpos_at_start = it->hpos;
16769 int saved_face_id = it->face_id;
16770 struct glyph_row *row = it->glyph_row;
16772 /* Initialize the iterator IT for iteration over STRING beginning
16773 with index START. */
16774 reseat_to_string (it, string, lisp_string, start,
16775 precision, field_width, multibyte);
16777 /* If displaying STRING, set up the face of the iterator
16778 from LISP_STRING, if that's given. */
16779 if (STRINGP (face_string))
16781 int endptr;
16782 struct face *face;
16784 it->face_id
16785 = face_at_string_position (it->w, face_string, face_string_pos,
16786 0, it->region_beg_charpos,
16787 it->region_end_charpos,
16788 &endptr, it->base_face_id, 0);
16789 face = FACE_FROM_ID (it->f, it->face_id);
16790 it->face_box_p = face->box != FACE_NO_BOX;
16793 /* Set max_x to the maximum allowed X position. Don't let it go
16794 beyond the right edge of the window. */
16795 if (max_x <= 0)
16796 max_x = it->last_visible_x;
16797 else
16798 max_x = min (max_x, it->last_visible_x);
16800 /* Skip over display elements that are not visible. because IT->w is
16801 hscrolled. */
16802 if (it->current_x < it->first_visible_x)
16803 move_it_in_display_line_to (it, 100000, it->first_visible_x,
16804 MOVE_TO_POS | MOVE_TO_X);
16806 row->ascent = it->max_ascent;
16807 row->height = it->max_ascent + it->max_descent;
16808 row->phys_ascent = it->max_phys_ascent;
16809 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
16810 row->extra_line_spacing = it->max_extra_line_spacing;
16812 /* This condition is for the case that we are called with current_x
16813 past last_visible_x. */
16814 while (it->current_x < max_x)
16816 int x_before, x, n_glyphs_before, i, nglyphs;
16818 /* Get the next display element. */
16819 if (!get_next_display_element (it))
16820 break;
16822 /* Produce glyphs. */
16823 x_before = it->current_x;
16824 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
16825 PRODUCE_GLYPHS (it);
16827 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
16828 i = 0;
16829 x = x_before;
16830 while (i < nglyphs)
16832 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
16834 if (!it->truncate_lines_p
16835 && x + glyph->pixel_width > max_x)
16837 /* End of continued line or max_x reached. */
16838 if (CHAR_GLYPH_PADDING_P (*glyph))
16840 /* A wide character is unbreakable. */
16841 it->glyph_row->used[TEXT_AREA] = n_glyphs_before;
16842 it->current_x = x_before;
16844 else
16846 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
16847 it->current_x = x;
16849 break;
16851 else if (x + glyph->pixel_width > it->first_visible_x)
16853 /* Glyph is at least partially visible. */
16854 ++it->hpos;
16855 if (x < it->first_visible_x)
16856 it->glyph_row->x = x - it->first_visible_x;
16858 else
16860 /* Glyph is off the left margin of the display area.
16861 Should not happen. */
16862 abort ();
16865 row->ascent = max (row->ascent, it->max_ascent);
16866 row->height = max (row->height, it->max_ascent + it->max_descent);
16867 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
16868 row->phys_height = max (row->phys_height,
16869 it->max_phys_ascent + it->max_phys_descent);
16870 row->extra_line_spacing = max (row->extra_line_spacing,
16871 it->max_extra_line_spacing);
16872 x += glyph->pixel_width;
16873 ++i;
16876 /* Stop if max_x reached. */
16877 if (i < nglyphs)
16878 break;
16880 /* Stop at line ends. */
16881 if (ITERATOR_AT_END_OF_LINE_P (it))
16883 it->continuation_lines_width = 0;
16884 break;
16887 set_iterator_to_next (it, 1);
16889 /* Stop if truncating at the right edge. */
16890 if (it->truncate_lines_p
16891 && it->current_x >= it->last_visible_x)
16893 /* Add truncation mark, but don't do it if the line is
16894 truncated at a padding space. */
16895 if (IT_CHARPOS (*it) < it->string_nchars)
16897 if (!FRAME_WINDOW_P (it->f))
16899 int i, n;
16901 if (it->current_x > it->last_visible_x)
16903 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
16904 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
16905 break;
16906 for (n = row->used[TEXT_AREA]; i < n; ++i)
16908 row->used[TEXT_AREA] = i;
16909 produce_special_glyphs (it, IT_TRUNCATION);
16912 produce_special_glyphs (it, IT_TRUNCATION);
16914 it->glyph_row->truncated_on_right_p = 1;
16916 break;
16920 /* Maybe insert a truncation at the left. */
16921 if (it->first_visible_x
16922 && IT_CHARPOS (*it) > 0)
16924 if (!FRAME_WINDOW_P (it->f))
16925 insert_left_trunc_glyphs (it);
16926 it->glyph_row->truncated_on_left_p = 1;
16929 it->face_id = saved_face_id;
16931 /* Value is number of columns displayed. */
16932 return it->hpos - hpos_at_start;
16937 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
16938 appears as an element of LIST or as the car of an element of LIST.
16939 If PROPVAL is a list, compare each element against LIST in that
16940 way, and return 1/2 if any element of PROPVAL is found in LIST.
16941 Otherwise return 0. This function cannot quit.
16942 The return value is 2 if the text is invisible but with an ellipsis
16943 and 1 if it's invisible and without an ellipsis. */
16946 invisible_p (propval, list)
16947 register Lisp_Object propval;
16948 Lisp_Object list;
16950 register Lisp_Object tail, proptail;
16952 for (tail = list; CONSP (tail); tail = XCDR (tail))
16954 register Lisp_Object tem;
16955 tem = XCAR (tail);
16956 if (EQ (propval, tem))
16957 return 1;
16958 if (CONSP (tem) && EQ (propval, XCAR (tem)))
16959 return NILP (XCDR (tem)) ? 1 : 2;
16962 if (CONSP (propval))
16964 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
16966 Lisp_Object propelt;
16967 propelt = XCAR (proptail);
16968 for (tail = list; CONSP (tail); tail = XCDR (tail))
16970 register Lisp_Object tem;
16971 tem = XCAR (tail);
16972 if (EQ (propelt, tem))
16973 return 1;
16974 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
16975 return NILP (XCDR (tem)) ? 1 : 2;
16980 return 0;
16983 /* Calculate a width or height in pixels from a specification using
16984 the following elements:
16986 SPEC ::=
16987 NUM - a (fractional) multiple of the default font width/height
16988 (NUM) - specifies exactly NUM pixels
16989 UNIT - a fixed number of pixels, see below.
16990 ELEMENT - size of a display element in pixels, see below.
16991 (NUM . SPEC) - equals NUM * SPEC
16992 (+ SPEC SPEC ...) - add pixel values
16993 (- SPEC SPEC ...) - subtract pixel values
16994 (- SPEC) - negate pixel value
16996 NUM ::=
16997 INT or FLOAT - a number constant
16998 SYMBOL - use symbol's (buffer local) variable binding.
17000 UNIT ::=
17001 in - pixels per inch *)
17002 mm - pixels per 1/1000 meter *)
17003 cm - pixels per 1/100 meter *)
17004 width - width of current font in pixels.
17005 height - height of current font in pixels.
17007 *) using the ratio(s) defined in display-pixels-per-inch.
17009 ELEMENT ::=
17011 left-fringe - left fringe width in pixels
17012 right-fringe - right fringe width in pixels
17014 left-margin - left margin width in pixels
17015 right-margin - right margin width in pixels
17017 scroll-bar - scroll-bar area width in pixels
17019 Examples:
17021 Pixels corresponding to 5 inches:
17022 (5 . in)
17024 Total width of non-text areas on left side of window (if scroll-bar is on left):
17025 '(space :width (+ left-fringe left-margin scroll-bar))
17027 Align to first text column (in header line):
17028 '(space :align-to 0)
17030 Align to middle of text area minus half the width of variable `my-image'
17031 containing a loaded image:
17032 '(space :align-to (0.5 . (- text my-image)))
17034 Width of left margin minus width of 1 character in the default font:
17035 '(space :width (- left-margin 1))
17037 Width of left margin minus width of 2 characters in the current font:
17038 '(space :width (- left-margin (2 . width)))
17040 Center 1 character over left-margin (in header line):
17041 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
17043 Different ways to express width of left fringe plus left margin minus one pixel:
17044 '(space :width (- (+ left-fringe left-margin) (1)))
17045 '(space :width (+ left-fringe left-margin (- (1))))
17046 '(space :width (+ left-fringe left-margin (-1)))
17050 #define NUMVAL(X) \
17051 ((INTEGERP (X) || FLOATP (X)) \
17052 ? XFLOATINT (X) \
17053 : - 1)
17056 calc_pixel_width_or_height (res, it, prop, font, width_p, align_to)
17057 double *res;
17058 struct it *it;
17059 Lisp_Object prop;
17060 void *font;
17061 int width_p, *align_to;
17063 double pixels;
17065 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
17066 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
17068 if (NILP (prop))
17069 return OK_PIXELS (0);
17071 if (SYMBOLP (prop))
17073 if (SCHARS (SYMBOL_NAME (prop)) == 2)
17075 char *unit = SDATA (SYMBOL_NAME (prop));
17077 if (unit[0] == 'i' && unit[1] == 'n')
17078 pixels = 1.0;
17079 else if (unit[0] == 'm' && unit[1] == 'm')
17080 pixels = 25.4;
17081 else if (unit[0] == 'c' && unit[1] == 'm')
17082 pixels = 2.54;
17083 else
17084 pixels = 0;
17085 if (pixels > 0)
17087 double ppi;
17088 if ((ppi = NUMVAL (Vdisplay_pixels_per_inch), ppi > 0)
17089 || (CONSP (Vdisplay_pixels_per_inch)
17090 && (ppi = (width_p
17091 ? NUMVAL (XCAR (Vdisplay_pixels_per_inch))
17092 : NUMVAL (XCDR (Vdisplay_pixels_per_inch))),
17093 ppi > 0)))
17094 return OK_PIXELS (ppi / pixels);
17096 return 0;
17100 #ifdef HAVE_WINDOW_SYSTEM
17101 if (EQ (prop, Qheight))
17102 return OK_PIXELS (font ? FONT_HEIGHT ((XFontStruct *)font) : FRAME_LINE_HEIGHT (it->f));
17103 if (EQ (prop, Qwidth))
17104 return OK_PIXELS (font ? FONT_WIDTH ((XFontStruct *)font) : FRAME_COLUMN_WIDTH (it->f));
17105 #else
17106 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
17107 return OK_PIXELS (1);
17108 #endif
17110 if (EQ (prop, Qtext))
17111 return OK_PIXELS (width_p
17112 ? window_box_width (it->w, TEXT_AREA)
17113 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
17115 if (align_to && *align_to < 0)
17117 *res = 0;
17118 if (EQ (prop, Qleft))
17119 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA));
17120 if (EQ (prop, Qright))
17121 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
17122 if (EQ (prop, Qcenter))
17123 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
17124 + window_box_width (it->w, TEXT_AREA) / 2);
17125 if (EQ (prop, Qleft_fringe))
17126 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
17127 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
17128 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
17129 if (EQ (prop, Qright_fringe))
17130 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
17131 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
17132 : window_box_right_offset (it->w, TEXT_AREA));
17133 if (EQ (prop, Qleft_margin))
17134 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
17135 if (EQ (prop, Qright_margin))
17136 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
17137 if (EQ (prop, Qscroll_bar))
17138 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
17140 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
17141 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
17142 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
17143 : 0)));
17145 else
17147 if (EQ (prop, Qleft_fringe))
17148 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
17149 if (EQ (prop, Qright_fringe))
17150 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
17151 if (EQ (prop, Qleft_margin))
17152 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
17153 if (EQ (prop, Qright_margin))
17154 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
17155 if (EQ (prop, Qscroll_bar))
17156 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
17159 prop = Fbuffer_local_value (prop, it->w->buffer);
17162 if (INTEGERP (prop) || FLOATP (prop))
17164 int base_unit = (width_p
17165 ? FRAME_COLUMN_WIDTH (it->f)
17166 : FRAME_LINE_HEIGHT (it->f));
17167 return OK_PIXELS (XFLOATINT (prop) * base_unit);
17170 if (CONSP (prop))
17172 Lisp_Object car = XCAR (prop);
17173 Lisp_Object cdr = XCDR (prop);
17175 if (SYMBOLP (car))
17177 #ifdef HAVE_WINDOW_SYSTEM
17178 if (valid_image_p (prop))
17180 int id = lookup_image (it->f, prop);
17181 struct image *img = IMAGE_FROM_ID (it->f, id);
17183 return OK_PIXELS (width_p ? img->width : img->height);
17185 #endif
17186 if (EQ (car, Qplus) || EQ (car, Qminus))
17188 int first = 1;
17189 double px;
17191 pixels = 0;
17192 while (CONSP (cdr))
17194 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
17195 font, width_p, align_to))
17196 return 0;
17197 if (first)
17198 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
17199 else
17200 pixels += px;
17201 cdr = XCDR (cdr);
17203 if (EQ (car, Qminus))
17204 pixels = -pixels;
17205 return OK_PIXELS (pixels);
17208 car = Fbuffer_local_value (car, it->w->buffer);
17211 if (INTEGERP (car) || FLOATP (car))
17213 double fact;
17214 pixels = XFLOATINT (car);
17215 if (NILP (cdr))
17216 return OK_PIXELS (pixels);
17217 if (calc_pixel_width_or_height (&fact, it, cdr,
17218 font, width_p, align_to))
17219 return OK_PIXELS (pixels * fact);
17220 return 0;
17223 return 0;
17226 return 0;
17230 /***********************************************************************
17231 Glyph Display
17232 ***********************************************************************/
17234 #ifdef HAVE_WINDOW_SYSTEM
17236 #if GLYPH_DEBUG
17238 void
17239 dump_glyph_string (s)
17240 struct glyph_string *s;
17242 fprintf (stderr, "glyph string\n");
17243 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
17244 s->x, s->y, s->width, s->height);
17245 fprintf (stderr, " ybase = %d\n", s->ybase);
17246 fprintf (stderr, " hl = %d\n", s->hl);
17247 fprintf (stderr, " left overhang = %d, right = %d\n",
17248 s->left_overhang, s->right_overhang);
17249 fprintf (stderr, " nchars = %d\n", s->nchars);
17250 fprintf (stderr, " extends to end of line = %d\n",
17251 s->extends_to_end_of_line_p);
17252 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
17253 fprintf (stderr, " bg width = %d\n", s->background_width);
17256 #endif /* GLYPH_DEBUG */
17258 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
17259 of XChar2b structures for S; it can't be allocated in
17260 init_glyph_string because it must be allocated via `alloca'. W
17261 is the window on which S is drawn. ROW and AREA are the glyph row
17262 and area within the row from which S is constructed. START is the
17263 index of the first glyph structure covered by S. HL is a
17264 face-override for drawing S. */
17266 #ifdef HAVE_NTGUI
17267 #define OPTIONAL_HDC(hdc) hdc,
17268 #define DECLARE_HDC(hdc) HDC hdc;
17269 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
17270 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
17271 #endif
17273 #ifndef OPTIONAL_HDC
17274 #define OPTIONAL_HDC(hdc)
17275 #define DECLARE_HDC(hdc)
17276 #define ALLOCATE_HDC(hdc, f)
17277 #define RELEASE_HDC(hdc, f)
17278 #endif
17280 static void
17281 init_glyph_string (s, OPTIONAL_HDC (hdc) char2b, w, row, area, start, hl)
17282 struct glyph_string *s;
17283 DECLARE_HDC (hdc)
17284 XChar2b *char2b;
17285 struct window *w;
17286 struct glyph_row *row;
17287 enum glyph_row_area area;
17288 int start;
17289 enum draw_glyphs_face hl;
17291 bzero (s, sizeof *s);
17292 s->w = w;
17293 s->f = XFRAME (w->frame);
17294 #ifdef HAVE_NTGUI
17295 s->hdc = hdc;
17296 #endif
17297 s->display = FRAME_X_DISPLAY (s->f);
17298 s->window = FRAME_X_WINDOW (s->f);
17299 s->char2b = char2b;
17300 s->hl = hl;
17301 s->row = row;
17302 s->area = area;
17303 s->first_glyph = row->glyphs[area] + start;
17304 s->height = row->height;
17305 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
17307 /* Display the internal border below the tool-bar window. */
17308 if (WINDOWP (s->f->tool_bar_window)
17309 && s->w == XWINDOW (s->f->tool_bar_window))
17310 s->y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
17312 s->ybase = s->y + row->ascent;
17316 /* Append the list of glyph strings with head H and tail T to the list
17317 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
17319 static INLINE void
17320 append_glyph_string_lists (head, tail, h, t)
17321 struct glyph_string **head, **tail;
17322 struct glyph_string *h, *t;
17324 if (h)
17326 if (*head)
17327 (*tail)->next = h;
17328 else
17329 *head = h;
17330 h->prev = *tail;
17331 *tail = t;
17336 /* Prepend the list of glyph strings with head H and tail T to the
17337 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
17338 result. */
17340 static INLINE void
17341 prepend_glyph_string_lists (head, tail, h, t)
17342 struct glyph_string **head, **tail;
17343 struct glyph_string *h, *t;
17345 if (h)
17347 if (*head)
17348 (*head)->prev = t;
17349 else
17350 *tail = t;
17351 t->next = *head;
17352 *head = h;
17357 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
17358 Set *HEAD and *TAIL to the resulting list. */
17360 static INLINE void
17361 append_glyph_string (head, tail, s)
17362 struct glyph_string **head, **tail;
17363 struct glyph_string *s;
17365 s->next = s->prev = NULL;
17366 append_glyph_string_lists (head, tail, s, s);
17370 /* Get face and two-byte form of character glyph GLYPH on frame F.
17371 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
17372 a pointer to a realized face that is ready for display. */
17374 static INLINE struct face *
17375 get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
17376 struct frame *f;
17377 struct glyph *glyph;
17378 XChar2b *char2b;
17379 int *two_byte_p;
17381 struct face *face;
17383 xassert (glyph->type == CHAR_GLYPH);
17384 face = FACE_FROM_ID (f, glyph->face_id);
17386 if (two_byte_p)
17387 *two_byte_p = 0;
17389 if (!glyph->multibyte_p)
17391 /* Unibyte case. We don't have to encode, but we have to make
17392 sure to use a face suitable for unibyte. */
17393 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
17395 else if (glyph->u.ch < 128
17396 && glyph->face_id < BASIC_FACE_ID_SENTINEL)
17398 /* Case of ASCII in a face known to fit ASCII. */
17399 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
17401 else
17403 int c1, c2, charset;
17405 /* Split characters into bytes. If c2 is -1 afterwards, C is
17406 really a one-byte character so that byte1 is zero. */
17407 SPLIT_CHAR (glyph->u.ch, charset, c1, c2);
17408 if (c2 > 0)
17409 STORE_XCHAR2B (char2b, c1, c2);
17410 else
17411 STORE_XCHAR2B (char2b, 0, c1);
17413 /* Maybe encode the character in *CHAR2B. */
17414 if (charset != CHARSET_ASCII)
17416 struct font_info *font_info
17417 = FONT_INFO_FROM_ID (f, face->font_info_id);
17418 if (font_info)
17419 glyph->font_type
17420 = rif->encode_char (glyph->u.ch, char2b, font_info, two_byte_p);
17424 /* Make sure X resources of the face are allocated. */
17425 xassert (face != NULL);
17426 PREPARE_FACE_FOR_DISPLAY (f, face);
17427 return face;
17431 /* Fill glyph string S with composition components specified by S->cmp.
17433 FACES is an array of faces for all components of this composition.
17434 S->gidx is the index of the first component for S.
17435 OVERLAPS_P non-zero means S should draw the foreground only, and
17436 use its physical height for clipping.
17438 Value is the index of a component not in S. */
17440 static int
17441 fill_composite_glyph_string (s, faces, overlaps_p)
17442 struct glyph_string *s;
17443 struct face **faces;
17444 int overlaps_p;
17446 int i;
17448 xassert (s);
17450 s->for_overlaps_p = overlaps_p;
17452 s->face = faces[s->gidx];
17453 s->font = s->face->font;
17454 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
17456 /* For all glyphs of this composition, starting at the offset
17457 S->gidx, until we reach the end of the definition or encounter a
17458 glyph that requires the different face, add it to S. */
17459 ++s->nchars;
17460 for (i = s->gidx + 1; i < s->cmp->glyph_len && faces[i] == s->face; ++i)
17461 ++s->nchars;
17463 /* All glyph strings for the same composition has the same width,
17464 i.e. the width set for the first component of the composition. */
17466 s->width = s->first_glyph->pixel_width;
17468 /* If the specified font could not be loaded, use the frame's
17469 default font, but record the fact that we couldn't load it in
17470 the glyph string so that we can draw rectangles for the
17471 characters of the glyph string. */
17472 if (s->font == NULL)
17474 s->font_not_found_p = 1;
17475 s->font = FRAME_FONT (s->f);
17478 /* Adjust base line for subscript/superscript text. */
17479 s->ybase += s->first_glyph->voffset;
17481 xassert (s->face && s->face->gc);
17483 /* This glyph string must always be drawn with 16-bit functions. */
17484 s->two_byte_p = 1;
17486 return s->gidx + s->nchars;
17490 /* Fill glyph string S from a sequence of character glyphs.
17492 FACE_ID is the face id of the string. START is the index of the
17493 first glyph to consider, END is the index of the last + 1.
17494 OVERLAPS_P non-zero means S should draw the foreground only, and
17495 use its physical height for clipping.
17497 Value is the index of the first glyph not in S. */
17499 static int
17500 fill_glyph_string (s, face_id, start, end, overlaps_p)
17501 struct glyph_string *s;
17502 int face_id;
17503 int start, end, overlaps_p;
17505 struct glyph *glyph, *last;
17506 int voffset;
17507 int glyph_not_available_p;
17509 xassert (s->f == XFRAME (s->w->frame));
17510 xassert (s->nchars == 0);
17511 xassert (start >= 0 && end > start);
17513 s->for_overlaps_p = overlaps_p,
17514 glyph = s->row->glyphs[s->area] + start;
17515 last = s->row->glyphs[s->area] + end;
17516 voffset = glyph->voffset;
17518 glyph_not_available_p = glyph->glyph_not_available_p;
17520 while (glyph < last
17521 && glyph->type == CHAR_GLYPH
17522 && glyph->voffset == voffset
17523 /* Same face id implies same font, nowadays. */
17524 && glyph->face_id == face_id
17525 && glyph->glyph_not_available_p == glyph_not_available_p)
17527 int two_byte_p;
17529 s->face = get_glyph_face_and_encoding (s->f, glyph,
17530 s->char2b + s->nchars,
17531 &two_byte_p);
17532 s->two_byte_p = two_byte_p;
17533 ++s->nchars;
17534 xassert (s->nchars <= end - start);
17535 s->width += glyph->pixel_width;
17536 ++glyph;
17539 s->font = s->face->font;
17540 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
17542 /* If the specified font could not be loaded, use the frame's font,
17543 but record the fact that we couldn't load it in
17544 S->font_not_found_p so that we can draw rectangles for the
17545 characters of the glyph string. */
17546 if (s->font == NULL || glyph_not_available_p)
17548 s->font_not_found_p = 1;
17549 s->font = FRAME_FONT (s->f);
17552 /* Adjust base line for subscript/superscript text. */
17553 s->ybase += voffset;
17555 xassert (s->face && s->face->gc);
17556 return glyph - s->row->glyphs[s->area];
17560 /* Fill glyph string S from image glyph S->first_glyph. */
17562 static void
17563 fill_image_glyph_string (s)
17564 struct glyph_string *s;
17566 xassert (s->first_glyph->type == IMAGE_GLYPH);
17567 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
17568 xassert (s->img);
17569 s->slice = s->first_glyph->slice;
17570 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
17571 s->font = s->face->font;
17572 s->width = s->first_glyph->pixel_width;
17574 /* Adjust base line for subscript/superscript text. */
17575 s->ybase += s->first_glyph->voffset;
17579 /* Fill glyph string S from a sequence of stretch glyphs.
17581 ROW is the glyph row in which the glyphs are found, AREA is the
17582 area within the row. START is the index of the first glyph to
17583 consider, END is the index of the last + 1.
17585 Value is the index of the first glyph not in S. */
17587 static int
17588 fill_stretch_glyph_string (s, row, area, start, end)
17589 struct glyph_string *s;
17590 struct glyph_row *row;
17591 enum glyph_row_area area;
17592 int start, end;
17594 struct glyph *glyph, *last;
17595 int voffset, face_id;
17597 xassert (s->first_glyph->type == STRETCH_GLYPH);
17599 glyph = s->row->glyphs[s->area] + start;
17600 last = s->row->glyphs[s->area] + end;
17601 face_id = glyph->face_id;
17602 s->face = FACE_FROM_ID (s->f, face_id);
17603 s->font = s->face->font;
17604 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
17605 s->width = glyph->pixel_width;
17606 voffset = glyph->voffset;
17608 for (++glyph;
17609 (glyph < last
17610 && glyph->type == STRETCH_GLYPH
17611 && glyph->voffset == voffset
17612 && glyph->face_id == face_id);
17613 ++glyph)
17614 s->width += glyph->pixel_width;
17616 /* Adjust base line for subscript/superscript text. */
17617 s->ybase += voffset;
17619 /* The case that face->gc == 0 is handled when drawing the glyph
17620 string by calling PREPARE_FACE_FOR_DISPLAY. */
17621 xassert (s->face);
17622 return glyph - s->row->glyphs[s->area];
17626 /* EXPORT for RIF:
17627 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
17628 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
17629 assumed to be zero. */
17631 void
17632 x_get_glyph_overhangs (glyph, f, left, right)
17633 struct glyph *glyph;
17634 struct frame *f;
17635 int *left, *right;
17637 *left = *right = 0;
17639 if (glyph->type == CHAR_GLYPH)
17641 XFontStruct *font;
17642 struct face *face;
17643 struct font_info *font_info;
17644 XChar2b char2b;
17645 XCharStruct *pcm;
17647 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
17648 font = face->font;
17649 font_info = FONT_INFO_FROM_ID (f, face->font_info_id);
17650 if (font /* ++KFS: Should this be font_info ? */
17651 && (pcm = rif->per_char_metric (font, &char2b, glyph->font_type)))
17653 if (pcm->rbearing > pcm->width)
17654 *right = pcm->rbearing - pcm->width;
17655 if (pcm->lbearing < 0)
17656 *left = -pcm->lbearing;
17662 /* Return the index of the first glyph preceding glyph string S that
17663 is overwritten by S because of S's left overhang. Value is -1
17664 if no glyphs are overwritten. */
17666 static int
17667 left_overwritten (s)
17668 struct glyph_string *s;
17670 int k;
17672 if (s->left_overhang)
17674 int x = 0, i;
17675 struct glyph *glyphs = s->row->glyphs[s->area];
17676 int first = s->first_glyph - glyphs;
17678 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
17679 x -= glyphs[i].pixel_width;
17681 k = i + 1;
17683 else
17684 k = -1;
17686 return k;
17690 /* Return the index of the first glyph preceding glyph string S that
17691 is overwriting S because of its right overhang. Value is -1 if no
17692 glyph in front of S overwrites S. */
17694 static int
17695 left_overwriting (s)
17696 struct glyph_string *s;
17698 int i, k, x;
17699 struct glyph *glyphs = s->row->glyphs[s->area];
17700 int first = s->first_glyph - glyphs;
17702 k = -1;
17703 x = 0;
17704 for (i = first - 1; i >= 0; --i)
17706 int left, right;
17707 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
17708 if (x + right > 0)
17709 k = i;
17710 x -= glyphs[i].pixel_width;
17713 return k;
17717 /* Return the index of the last glyph following glyph string S that is
17718 not overwritten by S because of S's right overhang. Value is -1 if
17719 no such glyph is found. */
17721 static int
17722 right_overwritten (s)
17723 struct glyph_string *s;
17725 int k = -1;
17727 if (s->right_overhang)
17729 int x = 0, i;
17730 struct glyph *glyphs = s->row->glyphs[s->area];
17731 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
17732 int end = s->row->used[s->area];
17734 for (i = first; i < end && s->right_overhang > x; ++i)
17735 x += glyphs[i].pixel_width;
17737 k = i;
17740 return k;
17744 /* Return the index of the last glyph following glyph string S that
17745 overwrites S because of its left overhang. Value is negative
17746 if no such glyph is found. */
17748 static int
17749 right_overwriting (s)
17750 struct glyph_string *s;
17752 int i, k, x;
17753 int end = s->row->used[s->area];
17754 struct glyph *glyphs = s->row->glyphs[s->area];
17755 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
17757 k = -1;
17758 x = 0;
17759 for (i = first; i < end; ++i)
17761 int left, right;
17762 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
17763 if (x - left < 0)
17764 k = i;
17765 x += glyphs[i].pixel_width;
17768 return k;
17772 /* Get face and two-byte form of character C in face FACE_ID on frame
17773 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
17774 means we want to display multibyte text. DISPLAY_P non-zero means
17775 make sure that X resources for the face returned are allocated.
17776 Value is a pointer to a realized face that is ready for display if
17777 DISPLAY_P is non-zero. */
17779 static INLINE struct face *
17780 get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p, display_p)
17781 struct frame *f;
17782 int c, face_id;
17783 XChar2b *char2b;
17784 int multibyte_p, display_p;
17786 struct face *face = FACE_FROM_ID (f, face_id);
17788 if (!multibyte_p)
17790 /* Unibyte case. We don't have to encode, but we have to make
17791 sure to use a face suitable for unibyte. */
17792 STORE_XCHAR2B (char2b, 0, c);
17793 face_id = FACE_FOR_CHAR (f, face, c);
17794 face = FACE_FROM_ID (f, face_id);
17796 else if (c < 128 && face_id < BASIC_FACE_ID_SENTINEL)
17798 /* Case of ASCII in a face known to fit ASCII. */
17799 STORE_XCHAR2B (char2b, 0, c);
17801 else
17803 int c1, c2, charset;
17805 /* Split characters into bytes. If c2 is -1 afterwards, C is
17806 really a one-byte character so that byte1 is zero. */
17807 SPLIT_CHAR (c, charset, c1, c2);
17808 if (c2 > 0)
17809 STORE_XCHAR2B (char2b, c1, c2);
17810 else
17811 STORE_XCHAR2B (char2b, 0, c1);
17813 /* Maybe encode the character in *CHAR2B. */
17814 if (face->font != NULL)
17816 struct font_info *font_info
17817 = FONT_INFO_FROM_ID (f, face->font_info_id);
17818 if (font_info)
17819 rif->encode_char (c, char2b, font_info, 0);
17823 /* Make sure X resources of the face are allocated. */
17824 #ifdef HAVE_X_WINDOWS
17825 if (display_p)
17826 #endif
17828 xassert (face != NULL);
17829 PREPARE_FACE_FOR_DISPLAY (f, face);
17832 return face;
17836 /* Set background width of glyph string S. START is the index of the
17837 first glyph following S. LAST_X is the right-most x-position + 1
17838 in the drawing area. */
17840 static INLINE void
17841 set_glyph_string_background_width (s, start, last_x)
17842 struct glyph_string *s;
17843 int start;
17844 int last_x;
17846 /* If the face of this glyph string has to be drawn to the end of
17847 the drawing area, set S->extends_to_end_of_line_p. */
17848 struct face *default_face = FACE_FROM_ID (s->f, DEFAULT_FACE_ID);
17850 if (start == s->row->used[s->area]
17851 && s->area == TEXT_AREA
17852 && ((s->hl == DRAW_NORMAL_TEXT
17853 && (s->row->fill_line_p
17854 || s->face->background != default_face->background
17855 || s->face->stipple != default_face->stipple
17856 || s->row->mouse_face_p))
17857 || s->hl == DRAW_MOUSE_FACE
17858 || ((s->hl == DRAW_IMAGE_RAISED || s->hl == DRAW_IMAGE_SUNKEN)
17859 && s->row->fill_line_p)))
17860 s->extends_to_end_of_line_p = 1;
17862 /* If S extends its face to the end of the line, set its
17863 background_width to the distance to the right edge of the drawing
17864 area. */
17865 if (s->extends_to_end_of_line_p)
17866 s->background_width = last_x - s->x + 1;
17867 else
17868 s->background_width = s->width;
17872 /* Compute overhangs and x-positions for glyph string S and its
17873 predecessors, or successors. X is the starting x-position for S.
17874 BACKWARD_P non-zero means process predecessors. */
17876 static void
17877 compute_overhangs_and_x (s, x, backward_p)
17878 struct glyph_string *s;
17879 int x;
17880 int backward_p;
17882 if (backward_p)
17884 while (s)
17886 if (rif->compute_glyph_string_overhangs)
17887 rif->compute_glyph_string_overhangs (s);
17888 x -= s->width;
17889 s->x = x;
17890 s = s->prev;
17893 else
17895 while (s)
17897 if (rif->compute_glyph_string_overhangs)
17898 rif->compute_glyph_string_overhangs (s);
17899 s->x = x;
17900 x += s->width;
17901 s = s->next;
17908 /* The following macros are only called from draw_glyphs below.
17909 They reference the following parameters of that function directly:
17910 `w', `row', `area', and `overlap_p'
17911 as well as the following local variables:
17912 `s', `f', and `hdc' (in W32) */
17914 #ifdef HAVE_NTGUI
17915 /* On W32, silently add local `hdc' variable to argument list of
17916 init_glyph_string. */
17917 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
17918 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
17919 #else
17920 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
17921 init_glyph_string (s, char2b, w, row, area, start, hl)
17922 #endif
17924 /* Add a glyph string for a stretch glyph to the list of strings
17925 between HEAD and TAIL. START is the index of the stretch glyph in
17926 row area AREA of glyph row ROW. END is the index of the last glyph
17927 in that glyph row area. X is the current output position assigned
17928 to the new glyph string constructed. HL overrides that face of the
17929 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
17930 is the right-most x-position of the drawing area. */
17932 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
17933 and below -- keep them on one line. */
17934 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17935 do \
17937 s = (struct glyph_string *) alloca (sizeof *s); \
17938 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
17939 START = fill_stretch_glyph_string (s, row, area, START, END); \
17940 append_glyph_string (&HEAD, &TAIL, s); \
17941 s->x = (X); \
17943 while (0)
17946 /* Add a glyph string for an image glyph to the list of strings
17947 between HEAD and TAIL. START is the index of the image glyph in
17948 row area AREA of glyph row ROW. END is the index of the last glyph
17949 in that glyph row area. X is the current output position assigned
17950 to the new glyph string constructed. HL overrides that face of the
17951 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
17952 is the right-most x-position of the drawing area. */
17954 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17955 do \
17957 s = (struct glyph_string *) alloca (sizeof *s); \
17958 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
17959 fill_image_glyph_string (s); \
17960 append_glyph_string (&HEAD, &TAIL, s); \
17961 ++START; \
17962 s->x = (X); \
17964 while (0)
17967 /* Add a glyph string for a sequence of character glyphs to the list
17968 of strings between HEAD and TAIL. START is the index of the first
17969 glyph in row area AREA of glyph row ROW that is part of the new
17970 glyph string. END is the index of the last glyph in that glyph row
17971 area. X is the current output position assigned to the new glyph
17972 string constructed. HL overrides that face of the glyph; e.g. it
17973 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
17974 right-most x-position of the drawing area. */
17976 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
17977 do \
17979 int c, face_id; \
17980 XChar2b *char2b; \
17982 c = (row)->glyphs[area][START].u.ch; \
17983 face_id = (row)->glyphs[area][START].face_id; \
17985 s = (struct glyph_string *) alloca (sizeof *s); \
17986 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
17987 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
17988 append_glyph_string (&HEAD, &TAIL, s); \
17989 s->x = (X); \
17990 START = fill_glyph_string (s, face_id, START, END, overlaps_p); \
17992 while (0)
17995 /* Add a glyph string for a composite sequence to the list of strings
17996 between HEAD and TAIL. START is the index of the first glyph in
17997 row area AREA of glyph row ROW that is part of the new glyph
17998 string. END is the index of the last glyph in that glyph row area.
17999 X is the current output position assigned to the new glyph string
18000 constructed. HL overrides that face of the glyph; e.g. it is
18001 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
18002 x-position of the drawing area. */
18004 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
18005 do { \
18006 int cmp_id = (row)->glyphs[area][START].u.cmp_id; \
18007 int face_id = (row)->glyphs[area][START].face_id; \
18008 struct face *base_face = FACE_FROM_ID (f, face_id); \
18009 struct composition *cmp = composition_table[cmp_id]; \
18010 int glyph_len = cmp->glyph_len; \
18011 XChar2b *char2b; \
18012 struct face **faces; \
18013 struct glyph_string *first_s = NULL; \
18014 int n; \
18016 base_face = base_face->ascii_face; \
18017 char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len); \
18018 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
18019 /* At first, fill in `char2b' and `faces'. */ \
18020 for (n = 0; n < glyph_len; n++) \
18022 int c = COMPOSITION_GLYPH (cmp, n); \
18023 int this_face_id = FACE_FOR_CHAR (f, base_face, c); \
18024 faces[n] = FACE_FROM_ID (f, this_face_id); \
18025 get_char_face_and_encoding (f, c, this_face_id, \
18026 char2b + n, 1, 1); \
18029 /* Make glyph_strings for each glyph sequence that is drawable by \
18030 the same face, and append them to HEAD/TAIL. */ \
18031 for (n = 0; n < cmp->glyph_len;) \
18033 s = (struct glyph_string *) alloca (sizeof *s); \
18034 INIT_GLYPH_STRING (s, char2b + n, w, row, area, START, HL); \
18035 append_glyph_string (&(HEAD), &(TAIL), s); \
18036 s->cmp = cmp; \
18037 s->gidx = n; \
18038 s->x = (X); \
18040 if (n == 0) \
18041 first_s = s; \
18043 n = fill_composite_glyph_string (s, faces, overlaps_p); \
18046 ++START; \
18047 s = first_s; \
18048 } while (0)
18051 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
18052 of AREA of glyph row ROW on window W between indices START and END.
18053 HL overrides the face for drawing glyph strings, e.g. it is
18054 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
18055 x-positions of the drawing area.
18057 This is an ugly monster macro construct because we must use alloca
18058 to allocate glyph strings (because draw_glyphs can be called
18059 asynchronously). */
18061 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
18062 do \
18064 HEAD = TAIL = NULL; \
18065 while (START < END) \
18067 struct glyph *first_glyph = (row)->glyphs[area] + START; \
18068 switch (first_glyph->type) \
18070 case CHAR_GLYPH: \
18071 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
18072 HL, X, LAST_X); \
18073 break; \
18075 case COMPOSITE_GLYPH: \
18076 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
18077 HL, X, LAST_X); \
18078 break; \
18080 case STRETCH_GLYPH: \
18081 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
18082 HL, X, LAST_X); \
18083 break; \
18085 case IMAGE_GLYPH: \
18086 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
18087 HL, X, LAST_X); \
18088 break; \
18090 default: \
18091 abort (); \
18094 set_glyph_string_background_width (s, START, LAST_X); \
18095 (X) += s->width; \
18098 while (0)
18101 /* Draw glyphs between START and END in AREA of ROW on window W,
18102 starting at x-position X. X is relative to AREA in W. HL is a
18103 face-override with the following meaning:
18105 DRAW_NORMAL_TEXT draw normally
18106 DRAW_CURSOR draw in cursor face
18107 DRAW_MOUSE_FACE draw in mouse face.
18108 DRAW_INVERSE_VIDEO draw in mode line face
18109 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
18110 DRAW_IMAGE_RAISED draw an image with a raised relief around it
18112 If OVERLAPS_P is non-zero, draw only the foreground of characters
18113 and clip to the physical height of ROW.
18115 Value is the x-position reached, relative to AREA of W. */
18117 static int
18118 draw_glyphs (w, x, row, area, start, end, hl, overlaps_p)
18119 struct window *w;
18120 int x;
18121 struct glyph_row *row;
18122 enum glyph_row_area area;
18123 int start, end;
18124 enum draw_glyphs_face hl;
18125 int overlaps_p;
18127 struct glyph_string *head, *tail;
18128 struct glyph_string *s;
18129 int last_x, area_width;
18130 int x_reached;
18131 int i, j;
18132 struct frame *f = XFRAME (WINDOW_FRAME (w));
18133 DECLARE_HDC (hdc);
18135 ALLOCATE_HDC (hdc, f);
18137 /* Let's rather be paranoid than getting a SEGV. */
18138 end = min (end, row->used[area]);
18139 start = max (0, start);
18140 start = min (end, start);
18142 /* Translate X to frame coordinates. Set last_x to the right
18143 end of the drawing area. */
18144 if (row->full_width_p)
18146 /* X is relative to the left edge of W, without scroll bars
18147 or fringes. */
18148 x += WINDOW_LEFT_EDGE_X (w);
18149 last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
18151 else
18153 int area_left = window_box_left (w, area);
18154 x += area_left;
18155 area_width = window_box_width (w, area);
18156 last_x = area_left + area_width;
18159 /* Build a doubly-linked list of glyph_string structures between
18160 head and tail from what we have to draw. Note that the macro
18161 BUILD_GLYPH_STRINGS will modify its start parameter. That's
18162 the reason we use a separate variable `i'. */
18163 i = start;
18164 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
18165 if (tail)
18166 x_reached = tail->x + tail->background_width;
18167 else
18168 x_reached = x;
18170 /* If there are any glyphs with lbearing < 0 or rbearing > width in
18171 the row, redraw some glyphs in front or following the glyph
18172 strings built above. */
18173 if (head && !overlaps_p && row->contains_overlapping_glyphs_p)
18175 int dummy_x = 0;
18176 struct glyph_string *h, *t;
18178 /* Compute overhangs for all glyph strings. */
18179 if (rif->compute_glyph_string_overhangs)
18180 for (s = head; s; s = s->next)
18181 rif->compute_glyph_string_overhangs (s);
18183 /* Prepend glyph strings for glyphs in front of the first glyph
18184 string that are overwritten because of the first glyph
18185 string's left overhang. The background of all strings
18186 prepended must be drawn because the first glyph string
18187 draws over it. */
18188 i = left_overwritten (head);
18189 if (i >= 0)
18191 j = i;
18192 BUILD_GLYPH_STRINGS (j, start, h, t,
18193 DRAW_NORMAL_TEXT, dummy_x, last_x);
18194 start = i;
18195 compute_overhangs_and_x (t, head->x, 1);
18196 prepend_glyph_string_lists (&head, &tail, h, t);
18199 /* Prepend glyph strings for glyphs in front of the first glyph
18200 string that overwrite that glyph string because of their
18201 right overhang. For these strings, only the foreground must
18202 be drawn, because it draws over the glyph string at `head'.
18203 The background must not be drawn because this would overwrite
18204 right overhangs of preceding glyphs for which no glyph
18205 strings exist. */
18206 i = left_overwriting (head);
18207 if (i >= 0)
18209 BUILD_GLYPH_STRINGS (i, start, h, t,
18210 DRAW_NORMAL_TEXT, dummy_x, last_x);
18211 for (s = h; s; s = s->next)
18212 s->background_filled_p = 1;
18213 compute_overhangs_and_x (t, head->x, 1);
18214 prepend_glyph_string_lists (&head, &tail, h, t);
18217 /* Append glyphs strings for glyphs following the last glyph
18218 string tail that are overwritten by tail. The background of
18219 these strings has to be drawn because tail's foreground draws
18220 over it. */
18221 i = right_overwritten (tail);
18222 if (i >= 0)
18224 BUILD_GLYPH_STRINGS (end, i, h, t,
18225 DRAW_NORMAL_TEXT, x, last_x);
18226 compute_overhangs_and_x (h, tail->x + tail->width, 0);
18227 append_glyph_string_lists (&head, &tail, h, t);
18230 /* Append glyph strings for glyphs following the last glyph
18231 string tail that overwrite tail. The foreground of such
18232 glyphs has to be drawn because it writes into the background
18233 of tail. The background must not be drawn because it could
18234 paint over the foreground of following glyphs. */
18235 i = right_overwriting (tail);
18236 if (i >= 0)
18238 BUILD_GLYPH_STRINGS (end, i, h, t,
18239 DRAW_NORMAL_TEXT, x, last_x);
18240 for (s = h; s; s = s->next)
18241 s->background_filled_p = 1;
18242 compute_overhangs_and_x (h, tail->x + tail->width, 0);
18243 append_glyph_string_lists (&head, &tail, h, t);
18247 /* Draw all strings. */
18248 for (s = head; s; s = s->next)
18249 rif->draw_glyph_string (s);
18251 if (area == TEXT_AREA
18252 && !row->full_width_p
18253 /* When drawing overlapping rows, only the glyph strings'
18254 foreground is drawn, which doesn't erase a cursor
18255 completely. */
18256 && !overlaps_p)
18258 int x0 = head ? head->x : x;
18259 int x1 = tail ? tail->x + tail->background_width : x;
18261 int text_left = window_box_left (w, TEXT_AREA);
18262 x0 -= text_left;
18263 x1 -= text_left;
18265 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
18266 row->y, MATRIX_ROW_BOTTOM_Y (row));
18269 /* Value is the x-position up to which drawn, relative to AREA of W.
18270 This doesn't include parts drawn because of overhangs. */
18271 if (row->full_width_p)
18272 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
18273 else
18274 x_reached -= window_box_left (w, area);
18276 RELEASE_HDC (hdc, f);
18278 return x_reached;
18281 /* Expand row matrix if too narrow. Don't expand if area
18282 is not present. */
18284 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
18286 if (!fonts_changed_p \
18287 && (it->glyph_row->glyphs[area] \
18288 < it->glyph_row->glyphs[area + 1])) \
18290 it->w->ncols_scale_factor++; \
18291 fonts_changed_p = 1; \
18295 /* Store one glyph for IT->char_to_display in IT->glyph_row.
18296 Called from x_produce_glyphs when IT->glyph_row is non-null. */
18298 static INLINE void
18299 append_glyph (it)
18300 struct it *it;
18302 struct glyph *glyph;
18303 enum glyph_row_area area = it->area;
18305 xassert (it->glyph_row);
18306 xassert (it->char_to_display != '\n' && it->char_to_display != '\t');
18308 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18309 if (glyph < it->glyph_row->glyphs[area + 1])
18311 glyph->charpos = CHARPOS (it->position);
18312 glyph->object = it->object;
18313 glyph->pixel_width = it->pixel_width;
18314 glyph->ascent = it->ascent;
18315 glyph->descent = it->descent;
18316 glyph->voffset = it->voffset;
18317 glyph->type = CHAR_GLYPH;
18318 glyph->multibyte_p = it->multibyte_p;
18319 glyph->left_box_line_p = it->start_of_box_run_p;
18320 glyph->right_box_line_p = it->end_of_box_run_p;
18321 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
18322 || it->phys_descent > it->descent);
18323 glyph->padding_p = 0;
18324 glyph->glyph_not_available_p = it->glyph_not_available_p;
18325 glyph->face_id = it->face_id;
18326 glyph->u.ch = it->char_to_display;
18327 glyph->slice = null_glyph_slice;
18328 glyph->font_type = FONT_TYPE_UNKNOWN;
18329 ++it->glyph_row->used[area];
18331 else
18332 IT_EXPAND_MATRIX_WIDTH (it, area);
18335 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
18336 Called from x_produce_glyphs when IT->glyph_row is non-null. */
18338 static INLINE void
18339 append_composite_glyph (it)
18340 struct it *it;
18342 struct glyph *glyph;
18343 enum glyph_row_area area = it->area;
18345 xassert (it->glyph_row);
18347 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18348 if (glyph < it->glyph_row->glyphs[area + 1])
18350 glyph->charpos = CHARPOS (it->position);
18351 glyph->object = it->object;
18352 glyph->pixel_width = it->pixel_width;
18353 glyph->ascent = it->ascent;
18354 glyph->descent = it->descent;
18355 glyph->voffset = it->voffset;
18356 glyph->type = COMPOSITE_GLYPH;
18357 glyph->multibyte_p = it->multibyte_p;
18358 glyph->left_box_line_p = it->start_of_box_run_p;
18359 glyph->right_box_line_p = it->end_of_box_run_p;
18360 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
18361 || it->phys_descent > it->descent);
18362 glyph->padding_p = 0;
18363 glyph->glyph_not_available_p = 0;
18364 glyph->face_id = it->face_id;
18365 glyph->u.cmp_id = it->cmp_id;
18366 glyph->slice = null_glyph_slice;
18367 glyph->font_type = FONT_TYPE_UNKNOWN;
18368 ++it->glyph_row->used[area];
18370 else
18371 IT_EXPAND_MATRIX_WIDTH (it, area);
18375 /* Change IT->ascent and IT->height according to the setting of
18376 IT->voffset. */
18378 static INLINE void
18379 take_vertical_position_into_account (it)
18380 struct it *it;
18382 if (it->voffset)
18384 if (it->voffset < 0)
18385 /* Increase the ascent so that we can display the text higher
18386 in the line. */
18387 it->ascent -= it->voffset;
18388 else
18389 /* Increase the descent so that we can display the text lower
18390 in the line. */
18391 it->descent += it->voffset;
18396 /* Produce glyphs/get display metrics for the image IT is loaded with.
18397 See the description of struct display_iterator in dispextern.h for
18398 an overview of struct display_iterator. */
18400 static void
18401 produce_image_glyph (it)
18402 struct it *it;
18404 struct image *img;
18405 struct face *face;
18406 int glyph_ascent;
18407 struct glyph_slice slice;
18409 xassert (it->what == IT_IMAGE);
18411 face = FACE_FROM_ID (it->f, it->face_id);
18412 xassert (face);
18413 /* Make sure X resources of the face is loaded. */
18414 PREPARE_FACE_FOR_DISPLAY (it->f, face);
18416 if (it->image_id < 0)
18418 /* Fringe bitmap. */
18419 it->ascent = it->phys_ascent = 0;
18420 it->descent = it->phys_descent = 0;
18421 it->pixel_width = 0;
18422 it->nglyphs = 0;
18423 return;
18426 img = IMAGE_FROM_ID (it->f, it->image_id);
18427 xassert (img);
18428 /* Make sure X resources of the image is loaded. */
18429 prepare_image_for_display (it->f, img);
18431 slice.x = slice.y = 0;
18432 slice.width = img->width;
18433 slice.height = img->height;
18435 if (INTEGERP (it->slice.x))
18436 slice.x = XINT (it->slice.x);
18437 else if (FLOATP (it->slice.x))
18438 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
18440 if (INTEGERP (it->slice.y))
18441 slice.y = XINT (it->slice.y);
18442 else if (FLOATP (it->slice.y))
18443 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
18445 if (INTEGERP (it->slice.width))
18446 slice.width = XINT (it->slice.width);
18447 else if (FLOATP (it->slice.width))
18448 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
18450 if (INTEGERP (it->slice.height))
18451 slice.height = XINT (it->slice.height);
18452 else if (FLOATP (it->slice.height))
18453 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
18455 if (slice.x >= img->width)
18456 slice.x = img->width;
18457 if (slice.y >= img->height)
18458 slice.y = img->height;
18459 if (slice.x + slice.width >= img->width)
18460 slice.width = img->width - slice.x;
18461 if (slice.y + slice.height > img->height)
18462 slice.height = img->height - slice.y;
18464 if (slice.width == 0 || slice.height == 0)
18465 return;
18467 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
18469 it->descent = slice.height - glyph_ascent;
18470 if (slice.y == 0)
18471 it->descent += img->vmargin;
18472 if (slice.y + slice.height == img->height)
18473 it->descent += img->vmargin;
18474 it->phys_descent = it->descent;
18476 it->pixel_width = slice.width;
18477 if (slice.x == 0)
18478 it->pixel_width += img->hmargin;
18479 if (slice.x + slice.width == img->width)
18480 it->pixel_width += img->hmargin;
18482 /* It's quite possible for images to have an ascent greater than
18483 their height, so don't get confused in that case. */
18484 if (it->descent < 0)
18485 it->descent = 0;
18487 #if 0 /* this breaks image tiling */
18488 /* If this glyph is alone on the last line, adjust it.ascent to minimum row ascent. */
18489 int face_ascent = face->font ? FONT_BASE (face->font) : FRAME_BASELINE_OFFSET (it->f);
18490 if (face_ascent > it->ascent)
18491 it->ascent = it->phys_ascent = face_ascent;
18492 #endif
18494 it->nglyphs = 1;
18496 if (face->box != FACE_NO_BOX)
18498 if (face->box_line_width > 0)
18500 if (slice.y == 0)
18501 it->ascent += face->box_line_width;
18502 if (slice.y + slice.height == img->height)
18503 it->descent += face->box_line_width;
18506 if (it->start_of_box_run_p && slice.x == 0)
18507 it->pixel_width += abs (face->box_line_width);
18508 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
18509 it->pixel_width += abs (face->box_line_width);
18512 take_vertical_position_into_account (it);
18514 if (it->glyph_row)
18516 struct glyph *glyph;
18517 enum glyph_row_area area = it->area;
18519 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18520 if (glyph < it->glyph_row->glyphs[area + 1])
18522 glyph->charpos = CHARPOS (it->position);
18523 glyph->object = it->object;
18524 glyph->pixel_width = it->pixel_width;
18525 glyph->ascent = glyph_ascent;
18526 glyph->descent = it->descent;
18527 glyph->voffset = it->voffset;
18528 glyph->type = IMAGE_GLYPH;
18529 glyph->multibyte_p = it->multibyte_p;
18530 glyph->left_box_line_p = it->start_of_box_run_p;
18531 glyph->right_box_line_p = it->end_of_box_run_p;
18532 glyph->overlaps_vertically_p = 0;
18533 glyph->padding_p = 0;
18534 glyph->glyph_not_available_p = 0;
18535 glyph->face_id = it->face_id;
18536 glyph->u.img_id = img->id;
18537 glyph->slice = slice;
18538 glyph->font_type = FONT_TYPE_UNKNOWN;
18539 ++it->glyph_row->used[area];
18541 else
18542 IT_EXPAND_MATRIX_WIDTH (it, area);
18547 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
18548 of the glyph, WIDTH and HEIGHT are the width and height of the
18549 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
18551 static void
18552 append_stretch_glyph (it, object, width, height, ascent)
18553 struct it *it;
18554 Lisp_Object object;
18555 int width, height;
18556 int ascent;
18558 struct glyph *glyph;
18559 enum glyph_row_area area = it->area;
18561 xassert (ascent >= 0 && ascent <= height);
18563 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18564 if (glyph < it->glyph_row->glyphs[area + 1])
18566 glyph->charpos = CHARPOS (it->position);
18567 glyph->object = object;
18568 glyph->pixel_width = width;
18569 glyph->ascent = ascent;
18570 glyph->descent = height - ascent;
18571 glyph->voffset = it->voffset;
18572 glyph->type = STRETCH_GLYPH;
18573 glyph->multibyte_p = it->multibyte_p;
18574 glyph->left_box_line_p = it->start_of_box_run_p;
18575 glyph->right_box_line_p = it->end_of_box_run_p;
18576 glyph->overlaps_vertically_p = 0;
18577 glyph->padding_p = 0;
18578 glyph->glyph_not_available_p = 0;
18579 glyph->face_id = it->face_id;
18580 glyph->u.stretch.ascent = ascent;
18581 glyph->u.stretch.height = height;
18582 glyph->slice = null_glyph_slice;
18583 glyph->font_type = FONT_TYPE_UNKNOWN;
18584 ++it->glyph_row->used[area];
18586 else
18587 IT_EXPAND_MATRIX_WIDTH (it, area);
18591 /* Produce a stretch glyph for iterator IT. IT->object is the value
18592 of the glyph property displayed. The value must be a list
18593 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
18594 being recognized:
18596 1. `:width WIDTH' specifies that the space should be WIDTH *
18597 canonical char width wide. WIDTH may be an integer or floating
18598 point number.
18600 2. `:relative-width FACTOR' specifies that the width of the stretch
18601 should be computed from the width of the first character having the
18602 `glyph' property, and should be FACTOR times that width.
18604 3. `:align-to HPOS' specifies that the space should be wide enough
18605 to reach HPOS, a value in canonical character units.
18607 Exactly one of the above pairs must be present.
18609 4. `:height HEIGHT' specifies that the height of the stretch produced
18610 should be HEIGHT, measured in canonical character units.
18612 5. `:relative-height FACTOR' specifies that the height of the
18613 stretch should be FACTOR times the height of the characters having
18614 the glyph property.
18616 Either none or exactly one of 4 or 5 must be present.
18618 6. `:ascent ASCENT' specifies that ASCENT percent of the height
18619 of the stretch should be used for the ascent of the stretch.
18620 ASCENT must be in the range 0 <= ASCENT <= 100. */
18622 static void
18623 produce_stretch_glyph (it)
18624 struct it *it;
18626 /* (space :width WIDTH :height HEIGHT ...) */
18627 Lisp_Object prop, plist;
18628 int width = 0, height = 0, align_to = -1;
18629 int zero_width_ok_p = 0, zero_height_ok_p = 0;
18630 int ascent = 0;
18631 double tem;
18632 struct face *face = FACE_FROM_ID (it->f, it->face_id);
18633 XFontStruct *font = face->font ? face->font : FRAME_FONT (it->f);
18635 PREPARE_FACE_FOR_DISPLAY (it->f, face);
18637 /* List should start with `space'. */
18638 xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
18639 plist = XCDR (it->object);
18641 /* Compute the width of the stretch. */
18642 if ((prop = Fsafe_plist_get (plist, QCwidth), !NILP (prop))
18643 && calc_pixel_width_or_height (&tem, it, prop, font, 1, 0))
18645 /* Absolute width `:width WIDTH' specified and valid. */
18646 zero_width_ok_p = 1;
18647 width = (int)tem;
18649 else if (prop = Fsafe_plist_get (plist, QCrelative_width),
18650 NUMVAL (prop) > 0)
18652 /* Relative width `:relative-width FACTOR' specified and valid.
18653 Compute the width of the characters having the `glyph'
18654 property. */
18655 struct it it2;
18656 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
18658 it2 = *it;
18659 if (it->multibyte_p)
18661 int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT)
18662 - IT_BYTEPOS (*it));
18663 it2.c = STRING_CHAR_AND_LENGTH (p, maxlen, it2.len);
18665 else
18666 it2.c = *p, it2.len = 1;
18668 it2.glyph_row = NULL;
18669 it2.what = IT_CHARACTER;
18670 x_produce_glyphs (&it2);
18671 width = NUMVAL (prop) * it2.pixel_width;
18673 else if ((prop = Fsafe_plist_get (plist, QCalign_to), !NILP (prop))
18674 && calc_pixel_width_or_height (&tem, it, prop, font, 1, &align_to))
18676 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
18677 align_to = (align_to < 0
18679 : align_to - window_box_left_offset (it->w, TEXT_AREA));
18680 else if (align_to < 0)
18681 align_to = window_box_left_offset (it->w, TEXT_AREA);
18682 width = max (0, (int)tem + align_to - it->current_x);
18683 zero_width_ok_p = 1;
18685 else
18686 /* Nothing specified -> width defaults to canonical char width. */
18687 width = FRAME_COLUMN_WIDTH (it->f);
18689 if (width <= 0 && (width < 0 || !zero_width_ok_p))
18690 width = 1;
18692 /* Compute height. */
18693 if ((prop = Fsafe_plist_get (plist, QCheight), !NILP (prop))
18694 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
18696 height = (int)tem;
18697 zero_height_ok_p = 1;
18699 else if (prop = Fsafe_plist_get (plist, QCrelative_height),
18700 NUMVAL (prop) > 0)
18701 height = FONT_HEIGHT (font) * NUMVAL (prop);
18702 else
18703 height = FONT_HEIGHT (font);
18705 if (height <= 0 && (height < 0 || !zero_height_ok_p))
18706 height = 1;
18708 /* Compute percentage of height used for ascent. If
18709 `:ascent ASCENT' is present and valid, use that. Otherwise,
18710 derive the ascent from the font in use. */
18711 if (prop = Fsafe_plist_get (plist, QCascent),
18712 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
18713 ascent = height * NUMVAL (prop) / 100.0;
18714 else if (!NILP (prop)
18715 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
18716 ascent = min (max (0, (int)tem), height);
18717 else
18718 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
18720 if (width > 0 && height > 0 && it->glyph_row)
18722 Lisp_Object object = it->stack[it->sp - 1].string;
18723 if (!STRINGP (object))
18724 object = it->w->buffer;
18725 append_stretch_glyph (it, object, width, height, ascent);
18728 it->pixel_width = width;
18729 it->ascent = it->phys_ascent = ascent;
18730 it->descent = it->phys_descent = height - it->ascent;
18731 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
18733 if (width > 0 && height > 0 && face->box != FACE_NO_BOX)
18735 if (face->box_line_width > 0)
18737 it->ascent += face->box_line_width;
18738 it->descent += face->box_line_width;
18741 if (it->start_of_box_run_p)
18742 it->pixel_width += abs (face->box_line_width);
18743 if (it->end_of_box_run_p)
18744 it->pixel_width += abs (face->box_line_width);
18747 take_vertical_position_into_account (it);
18750 /* Calculate line-height and line-spacing properties.
18751 An integer value specifies explicit pixel value.
18752 A float value specifies relative value to current face height.
18753 A cons (float . face-name) specifies relative value to
18754 height of specified face font.
18756 Returns height in pixels, or nil. */
18758 static Lisp_Object
18759 calc_line_height_property (it, prop, font, boff, total)
18760 struct it *it;
18761 Lisp_Object prop;
18762 XFontStruct *font;
18763 int boff, *total;
18765 Lisp_Object position, val;
18766 Lisp_Object face_name = Qnil;
18767 int ascent, descent, height, override;
18769 if (STRINGP (it->object))
18770 position = make_number (IT_STRING_CHARPOS (*it));
18771 else if (BUFFERP (it->object))
18772 position = make_number (IT_CHARPOS (*it));
18773 else
18774 return Qnil;
18776 val = Fget_char_property (position, prop, it->object);
18778 if (NILP (val))
18779 return val;
18781 if (total && CONSP (val) && EQ (XCAR (val), Qtotal))
18783 *total = 1;
18784 val = XCDR (val);
18787 if (INTEGERP (val))
18788 return val;
18790 if (CONSP (val))
18792 face_name = XCDR (val);
18793 val = XCAR (val);
18795 else if (SYMBOLP (val))
18797 face_name = val;
18798 val = Qnil;
18801 override = EQ (prop, Qline_height);
18803 if (NILP (face_name))
18805 font = FRAME_FONT (it->f);
18806 boff = FRAME_BASELINE_OFFSET (it->f);
18808 else if (EQ (face_name, Qt))
18810 override = 0;
18812 else
18814 int face_id;
18815 struct face *face;
18816 struct font_info *font_info;
18818 face_id = lookup_named_face (it->f, face_name, ' ', 0);
18819 if (face_id < 0)
18820 return make_number (-1);
18822 face = FACE_FROM_ID (it->f, face_id);
18823 font = face->font;
18824 if (font == NULL)
18825 return make_number (-1);
18827 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
18828 boff = font_info->baseline_offset;
18829 if (font_info->vertical_centering)
18830 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
18833 ascent = FONT_BASE (font) + boff;
18834 descent = FONT_DESCENT (font) - boff;
18836 if (override)
18838 it->override_ascent = ascent;
18839 it->override_descent = descent;
18840 it->override_boff = boff;
18843 height = ascent + descent;
18844 if (FLOATP (val))
18845 height = (int)(XFLOAT_DATA (val) * height);
18846 else if (INTEGERP (val))
18847 height *= XINT (val);
18849 return make_number (height);
18853 /* RIF:
18854 Produce glyphs/get display metrics for the display element IT is
18855 loaded with. See the description of struct display_iterator in
18856 dispextern.h for an overview of struct display_iterator. */
18858 void
18859 x_produce_glyphs (it)
18860 struct it *it;
18862 int extra_line_spacing = it->extra_line_spacing;
18864 it->glyph_not_available_p = 0;
18866 if (it->what == IT_CHARACTER)
18868 XChar2b char2b;
18869 XFontStruct *font;
18870 struct face *face = FACE_FROM_ID (it->f, it->face_id);
18871 XCharStruct *pcm;
18872 int font_not_found_p;
18873 struct font_info *font_info;
18874 int boff; /* baseline offset */
18875 /* We may change it->multibyte_p upon unibyte<->multibyte
18876 conversion. So, save the current value now and restore it
18877 later.
18879 Note: It seems that we don't have to record multibyte_p in
18880 struct glyph because the character code itself tells if or
18881 not the character is multibyte. Thus, in the future, we must
18882 consider eliminating the field `multibyte_p' in the struct
18883 glyph. */
18884 int saved_multibyte_p = it->multibyte_p;
18886 /* Maybe translate single-byte characters to multibyte, or the
18887 other way. */
18888 it->char_to_display = it->c;
18889 if (!ASCII_BYTE_P (it->c))
18891 if (unibyte_display_via_language_environment
18892 && SINGLE_BYTE_CHAR_P (it->c)
18893 && (it->c >= 0240
18894 || !NILP (Vnonascii_translation_table)))
18896 it->char_to_display = unibyte_char_to_multibyte (it->c);
18897 it->multibyte_p = 1;
18898 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
18899 face = FACE_FROM_ID (it->f, it->face_id);
18901 else if (!SINGLE_BYTE_CHAR_P (it->c)
18902 && !it->multibyte_p)
18904 it->multibyte_p = 1;
18905 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
18906 face = FACE_FROM_ID (it->f, it->face_id);
18910 /* Get font to use. Encode IT->char_to_display. */
18911 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
18912 &char2b, it->multibyte_p, 0);
18913 font = face->font;
18915 /* When no suitable font found, use the default font. */
18916 font_not_found_p = font == NULL;
18917 if (font_not_found_p)
18919 font = FRAME_FONT (it->f);
18920 boff = FRAME_BASELINE_OFFSET (it->f);
18921 font_info = NULL;
18923 else
18925 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
18926 boff = font_info->baseline_offset;
18927 if (font_info->vertical_centering)
18928 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
18931 if (it->char_to_display >= ' '
18932 && (!it->multibyte_p || it->char_to_display < 128))
18934 /* Either unibyte or ASCII. */
18935 int stretched_p;
18937 it->nglyphs = 1;
18939 pcm = rif->per_char_metric (font, &char2b,
18940 FONT_TYPE_FOR_UNIBYTE (font, it->char_to_display));
18942 if (it->override_ascent >= 0)
18944 it->ascent = it->override_ascent;
18945 it->descent = it->override_descent;
18946 boff = it->override_boff;
18948 else
18950 it->ascent = FONT_BASE (font) + boff;
18951 it->descent = FONT_DESCENT (font) - boff;
18954 if (pcm)
18956 it->phys_ascent = pcm->ascent + boff;
18957 it->phys_descent = pcm->descent - boff;
18958 it->pixel_width = pcm->width;
18960 else
18962 it->glyph_not_available_p = 1;
18963 it->phys_ascent = it->ascent;
18964 it->phys_descent = it->descent;
18965 it->pixel_width = FONT_WIDTH (font);
18968 if (it->constrain_row_ascent_descent_p)
18970 if (it->descent > it->max_descent)
18972 it->ascent += it->descent - it->max_descent;
18973 it->descent = it->max_descent;
18975 if (it->ascent > it->max_ascent)
18977 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
18978 it->ascent = it->max_ascent;
18980 it->phys_ascent = min (it->phys_ascent, it->ascent);
18981 it->phys_descent = min (it->phys_descent, it->descent);
18982 extra_line_spacing = 0;
18985 /* If this is a space inside a region of text with
18986 `space-width' property, change its width. */
18987 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
18988 if (stretched_p)
18989 it->pixel_width *= XFLOATINT (it->space_width);
18991 /* If face has a box, add the box thickness to the character
18992 height. If character has a box line to the left and/or
18993 right, add the box line width to the character's width. */
18994 if (face->box != FACE_NO_BOX)
18996 int thick = face->box_line_width;
18998 if (thick > 0)
19000 it->ascent += thick;
19001 it->descent += thick;
19003 else
19004 thick = -thick;
19006 if (it->start_of_box_run_p)
19007 it->pixel_width += thick;
19008 if (it->end_of_box_run_p)
19009 it->pixel_width += thick;
19012 /* If face has an overline, add the height of the overline
19013 (1 pixel) and a 1 pixel margin to the character height. */
19014 if (face->overline_p)
19015 it->ascent += 2;
19017 if (it->constrain_row_ascent_descent_p)
19019 if (it->ascent > it->max_ascent)
19020 it->ascent = it->max_ascent;
19021 if (it->descent > it->max_descent)
19022 it->descent = it->max_descent;
19025 take_vertical_position_into_account (it);
19027 /* If we have to actually produce glyphs, do it. */
19028 if (it->glyph_row)
19030 if (stretched_p)
19032 /* Translate a space with a `space-width' property
19033 into a stretch glyph. */
19034 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
19035 / FONT_HEIGHT (font));
19036 append_stretch_glyph (it, it->object, it->pixel_width,
19037 it->ascent + it->descent, ascent);
19039 else
19040 append_glyph (it);
19042 /* If characters with lbearing or rbearing are displayed
19043 in this line, record that fact in a flag of the
19044 glyph row. This is used to optimize X output code. */
19045 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
19046 it->glyph_row->contains_overlapping_glyphs_p = 1;
19049 else if (it->char_to_display == '\n')
19051 /* A newline has no width but we need the height of the line.
19052 But if previous part of the line set a height, don't
19053 increase that height */
19055 Lisp_Object height;
19057 it->override_ascent = -1;
19058 it->pixel_width = 0;
19059 it->nglyphs = 0;
19061 height = calc_line_height_property(it, Qline_height, font, boff, 0);
19063 if (it->override_ascent >= 0)
19065 it->ascent = it->override_ascent;
19066 it->descent = it->override_descent;
19067 boff = it->override_boff;
19069 else
19071 it->ascent = FONT_BASE (font) + boff;
19072 it->descent = FONT_DESCENT (font) - boff;
19075 if (EQ (height, make_number(0)))
19077 if (it->descent > it->max_descent)
19079 it->ascent += it->descent - it->max_descent;
19080 it->descent = it->max_descent;
19082 if (it->ascent > it->max_ascent)
19084 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
19085 it->ascent = it->max_ascent;
19087 it->phys_ascent = min (it->phys_ascent, it->ascent);
19088 it->phys_descent = min (it->phys_descent, it->descent);
19089 it->constrain_row_ascent_descent_p = 1;
19090 extra_line_spacing = 0;
19092 else
19094 Lisp_Object spacing;
19095 int total = 0;
19097 it->phys_ascent = it->ascent;
19098 it->phys_descent = it->descent;
19100 if ((it->max_ascent > 0 || it->max_descent > 0)
19101 && face->box != FACE_NO_BOX
19102 && face->box_line_width > 0)
19104 it->ascent += face->box_line_width;
19105 it->descent += face->box_line_width;
19107 if (!NILP (height)
19108 && XINT (height) > it->ascent + it->descent)
19109 it->ascent = XINT (height) - it->descent;
19111 spacing = calc_line_height_property(it, Qline_spacing, font, boff, &total);
19112 if (INTEGERP (spacing))
19114 extra_line_spacing = XINT (spacing);
19115 if (total)
19116 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
19120 else if (it->char_to_display == '\t')
19122 int tab_width = it->tab_width * FRAME_COLUMN_WIDTH (it->f);
19123 int x = it->current_x + it->continuation_lines_width;
19124 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
19126 /* If the distance from the current position to the next tab
19127 stop is less than a canonical character width, use the
19128 tab stop after that. */
19129 if (next_tab_x - x < FRAME_COLUMN_WIDTH (it->f))
19130 next_tab_x += tab_width;
19132 it->pixel_width = next_tab_x - x;
19133 it->nglyphs = 1;
19134 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
19135 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
19137 if (it->glyph_row)
19139 append_stretch_glyph (it, it->object, it->pixel_width,
19140 it->ascent + it->descent, it->ascent);
19143 else
19145 /* A multi-byte character. Assume that the display width of the
19146 character is the width of the character multiplied by the
19147 width of the font. */
19149 /* If we found a font, this font should give us the right
19150 metrics. If we didn't find a font, use the frame's
19151 default font and calculate the width of the character
19152 from the charset width; this is what old redisplay code
19153 did. */
19155 pcm = rif->per_char_metric (font, &char2b,
19156 FONT_TYPE_FOR_MULTIBYTE (font, it->c));
19158 if (font_not_found_p || !pcm)
19160 int charset = CHAR_CHARSET (it->char_to_display);
19162 it->glyph_not_available_p = 1;
19163 it->pixel_width = (FRAME_COLUMN_WIDTH (it->f)
19164 * CHARSET_WIDTH (charset));
19165 it->phys_ascent = FONT_BASE (font) + boff;
19166 it->phys_descent = FONT_DESCENT (font) - boff;
19168 else
19170 it->pixel_width = pcm->width;
19171 it->phys_ascent = pcm->ascent + boff;
19172 it->phys_descent = pcm->descent - boff;
19173 if (it->glyph_row
19174 && (pcm->lbearing < 0
19175 || pcm->rbearing > pcm->width))
19176 it->glyph_row->contains_overlapping_glyphs_p = 1;
19178 it->nglyphs = 1;
19179 it->ascent = FONT_BASE (font) + boff;
19180 it->descent = FONT_DESCENT (font) - boff;
19181 if (face->box != FACE_NO_BOX)
19183 int thick = face->box_line_width;
19185 if (thick > 0)
19187 it->ascent += thick;
19188 it->descent += thick;
19190 else
19191 thick = - thick;
19193 if (it->start_of_box_run_p)
19194 it->pixel_width += thick;
19195 if (it->end_of_box_run_p)
19196 it->pixel_width += thick;
19199 /* If face has an overline, add the height of the overline
19200 (1 pixel) and a 1 pixel margin to the character height. */
19201 if (face->overline_p)
19202 it->ascent += 2;
19204 take_vertical_position_into_account (it);
19206 if (it->glyph_row)
19207 append_glyph (it);
19209 it->multibyte_p = saved_multibyte_p;
19211 else if (it->what == IT_COMPOSITION)
19213 /* Note: A composition is represented as one glyph in the
19214 glyph matrix. There are no padding glyphs. */
19215 XChar2b char2b;
19216 XFontStruct *font;
19217 struct face *face = FACE_FROM_ID (it->f, it->face_id);
19218 XCharStruct *pcm;
19219 int font_not_found_p;
19220 struct font_info *font_info;
19221 int boff; /* baseline offset */
19222 struct composition *cmp = composition_table[it->cmp_id];
19224 /* Maybe translate single-byte characters to multibyte. */
19225 it->char_to_display = it->c;
19226 if (unibyte_display_via_language_environment
19227 && SINGLE_BYTE_CHAR_P (it->c)
19228 && (it->c >= 0240
19229 || (it->c >= 0200
19230 && !NILP (Vnonascii_translation_table))))
19232 it->char_to_display = unibyte_char_to_multibyte (it->c);
19235 /* Get face and font to use. Encode IT->char_to_display. */
19236 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
19237 face = FACE_FROM_ID (it->f, it->face_id);
19238 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
19239 &char2b, it->multibyte_p, 0);
19240 font = face->font;
19242 /* When no suitable font found, use the default font. */
19243 font_not_found_p = font == NULL;
19244 if (font_not_found_p)
19246 font = FRAME_FONT (it->f);
19247 boff = FRAME_BASELINE_OFFSET (it->f);
19248 font_info = NULL;
19250 else
19252 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
19253 boff = font_info->baseline_offset;
19254 if (font_info->vertical_centering)
19255 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
19258 /* There are no padding glyphs, so there is only one glyph to
19259 produce for the composition. Important is that pixel_width,
19260 ascent and descent are the values of what is drawn by
19261 draw_glyphs (i.e. the values of the overall glyphs composed). */
19262 it->nglyphs = 1;
19264 /* If we have not yet calculated pixel size data of glyphs of
19265 the composition for the current face font, calculate them
19266 now. Theoretically, we have to check all fonts for the
19267 glyphs, but that requires much time and memory space. So,
19268 here we check only the font of the first glyph. This leads
19269 to incorrect display very rarely, and C-l (recenter) can
19270 correct the display anyway. */
19271 if (cmp->font != (void *) font)
19273 /* Ascent and descent of the font of the first character of
19274 this composition (adjusted by baseline offset). Ascent
19275 and descent of overall glyphs should not be less than
19276 them respectively. */
19277 int font_ascent = FONT_BASE (font) + boff;
19278 int font_descent = FONT_DESCENT (font) - boff;
19279 /* Bounding box of the overall glyphs. */
19280 int leftmost, rightmost, lowest, highest;
19281 int i, width, ascent, descent;
19283 cmp->font = (void *) font;
19285 /* Initialize the bounding box. */
19286 if (font_info
19287 && (pcm = rif->per_char_metric (font, &char2b,
19288 FONT_TYPE_FOR_MULTIBYTE (font, it->c))))
19290 width = pcm->width;
19291 ascent = pcm->ascent;
19292 descent = pcm->descent;
19294 else
19296 width = FONT_WIDTH (font);
19297 ascent = FONT_BASE (font);
19298 descent = FONT_DESCENT (font);
19301 rightmost = width;
19302 lowest = - descent + boff;
19303 highest = ascent + boff;
19304 leftmost = 0;
19306 if (font_info
19307 && font_info->default_ascent
19308 && CHAR_TABLE_P (Vuse_default_ascent)
19309 && !NILP (Faref (Vuse_default_ascent,
19310 make_number (it->char_to_display))))
19311 highest = font_info->default_ascent + boff;
19313 /* Draw the first glyph at the normal position. It may be
19314 shifted to right later if some other glyphs are drawn at
19315 the left. */
19316 cmp->offsets[0] = 0;
19317 cmp->offsets[1] = boff;
19319 /* Set cmp->offsets for the remaining glyphs. */
19320 for (i = 1; i < cmp->glyph_len; i++)
19322 int left, right, btm, top;
19323 int ch = COMPOSITION_GLYPH (cmp, i);
19324 int face_id = FACE_FOR_CHAR (it->f, face, ch);
19326 face = FACE_FROM_ID (it->f, face_id);
19327 get_char_face_and_encoding (it->f, ch, face->id,
19328 &char2b, it->multibyte_p, 0);
19329 font = face->font;
19330 if (font == NULL)
19332 font = FRAME_FONT (it->f);
19333 boff = FRAME_BASELINE_OFFSET (it->f);
19334 font_info = NULL;
19336 else
19338 font_info
19339 = 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 if (font_info
19346 && (pcm = rif->per_char_metric (font, &char2b,
19347 FONT_TYPE_FOR_MULTIBYTE (font, ch))))
19349 width = pcm->width;
19350 ascent = pcm->ascent;
19351 descent = pcm->descent;
19353 else
19355 width = FONT_WIDTH (font);
19356 ascent = 1;
19357 descent = 0;
19360 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
19362 /* Relative composition with or without
19363 alternate chars. */
19364 left = (leftmost + rightmost - width) / 2;
19365 btm = - descent + boff;
19366 if (font_info && font_info->relative_compose
19367 && (! CHAR_TABLE_P (Vignore_relative_composition)
19368 || NILP (Faref (Vignore_relative_composition,
19369 make_number (ch)))))
19372 if (- descent >= font_info->relative_compose)
19373 /* One extra pixel between two glyphs. */
19374 btm = highest + 1;
19375 else if (ascent <= 0)
19376 /* One extra pixel between two glyphs. */
19377 btm = lowest - 1 - ascent - descent;
19380 else
19382 /* A composition rule is specified by an integer
19383 value that encodes global and new reference
19384 points (GREF and NREF). GREF and NREF are
19385 specified by numbers as below:
19387 0---1---2 -- ascent
19391 9--10--11 -- center
19393 ---3---4---5--- baseline
19395 6---7---8 -- descent
19397 int rule = COMPOSITION_RULE (cmp, i);
19398 int gref, nref, grefx, grefy, nrefx, nrefy;
19400 COMPOSITION_DECODE_RULE (rule, gref, nref);
19401 grefx = gref % 3, nrefx = nref % 3;
19402 grefy = gref / 3, nrefy = nref / 3;
19404 left = (leftmost
19405 + grefx * (rightmost - leftmost) / 2
19406 - nrefx * width / 2);
19407 btm = ((grefy == 0 ? highest
19408 : grefy == 1 ? 0
19409 : grefy == 2 ? lowest
19410 : (highest + lowest) / 2)
19411 - (nrefy == 0 ? ascent + descent
19412 : nrefy == 1 ? descent - boff
19413 : nrefy == 2 ? 0
19414 : (ascent + descent) / 2));
19417 cmp->offsets[i * 2] = left;
19418 cmp->offsets[i * 2 + 1] = btm + descent;
19420 /* Update the bounding box of the overall glyphs. */
19421 right = left + width;
19422 top = btm + descent + ascent;
19423 if (left < leftmost)
19424 leftmost = left;
19425 if (right > rightmost)
19426 rightmost = right;
19427 if (top > highest)
19428 highest = top;
19429 if (btm < lowest)
19430 lowest = btm;
19433 /* If there are glyphs whose x-offsets are negative,
19434 shift all glyphs to the right and make all x-offsets
19435 non-negative. */
19436 if (leftmost < 0)
19438 for (i = 0; i < cmp->glyph_len; i++)
19439 cmp->offsets[i * 2] -= leftmost;
19440 rightmost -= leftmost;
19443 cmp->pixel_width = rightmost;
19444 cmp->ascent = highest;
19445 cmp->descent = - lowest;
19446 if (cmp->ascent < font_ascent)
19447 cmp->ascent = font_ascent;
19448 if (cmp->descent < font_descent)
19449 cmp->descent = font_descent;
19452 it->pixel_width = cmp->pixel_width;
19453 it->ascent = it->phys_ascent = cmp->ascent;
19454 it->descent = it->phys_descent = cmp->descent;
19456 if (face->box != FACE_NO_BOX)
19458 int thick = face->box_line_width;
19460 if (thick > 0)
19462 it->ascent += thick;
19463 it->descent += thick;
19465 else
19466 thick = - thick;
19468 if (it->start_of_box_run_p)
19469 it->pixel_width += thick;
19470 if (it->end_of_box_run_p)
19471 it->pixel_width += thick;
19474 /* If face has an overline, add the height of the overline
19475 (1 pixel) and a 1 pixel margin to the character height. */
19476 if (face->overline_p)
19477 it->ascent += 2;
19479 take_vertical_position_into_account (it);
19481 if (it->glyph_row)
19482 append_composite_glyph (it);
19484 else if (it->what == IT_IMAGE)
19485 produce_image_glyph (it);
19486 else if (it->what == IT_STRETCH)
19487 produce_stretch_glyph (it);
19489 /* Accumulate dimensions. Note: can't assume that it->descent > 0
19490 because this isn't true for images with `:ascent 100'. */
19491 xassert (it->ascent >= 0 && it->descent >= 0);
19492 if (it->area == TEXT_AREA)
19493 it->current_x += it->pixel_width;
19495 if (extra_line_spacing > 0)
19497 it->descent += extra_line_spacing;
19498 if (extra_line_spacing > it->max_extra_line_spacing)
19499 it->max_extra_line_spacing = extra_line_spacing;
19502 it->max_ascent = max (it->max_ascent, it->ascent);
19503 it->max_descent = max (it->max_descent, it->descent);
19504 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
19505 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
19508 /* EXPORT for RIF:
19509 Output LEN glyphs starting at START at the nominal cursor position.
19510 Advance the nominal cursor over the text. The global variable
19511 updated_window contains the window being updated, updated_row is
19512 the glyph row being updated, and updated_area is the area of that
19513 row being updated. */
19515 void
19516 x_write_glyphs (start, len)
19517 struct glyph *start;
19518 int len;
19520 int x, hpos;
19522 xassert (updated_window && updated_row);
19523 BLOCK_INPUT;
19525 /* Write glyphs. */
19527 hpos = start - updated_row->glyphs[updated_area];
19528 x = draw_glyphs (updated_window, output_cursor.x,
19529 updated_row, updated_area,
19530 hpos, hpos + len,
19531 DRAW_NORMAL_TEXT, 0);
19533 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
19534 if (updated_area == TEXT_AREA
19535 && updated_window->phys_cursor_on_p
19536 && updated_window->phys_cursor.vpos == output_cursor.vpos
19537 && updated_window->phys_cursor.hpos >= hpos
19538 && updated_window->phys_cursor.hpos < hpos + len)
19539 updated_window->phys_cursor_on_p = 0;
19541 UNBLOCK_INPUT;
19543 /* Advance the output cursor. */
19544 output_cursor.hpos += len;
19545 output_cursor.x = x;
19549 /* EXPORT for RIF:
19550 Insert LEN glyphs from START at the nominal cursor position. */
19552 void
19553 x_insert_glyphs (start, len)
19554 struct glyph *start;
19555 int len;
19557 struct frame *f;
19558 struct window *w;
19559 int line_height, shift_by_width, shifted_region_width;
19560 struct glyph_row *row;
19561 struct glyph *glyph;
19562 int frame_x, frame_y, hpos;
19564 xassert (updated_window && updated_row);
19565 BLOCK_INPUT;
19566 w = updated_window;
19567 f = XFRAME (WINDOW_FRAME (w));
19569 /* Get the height of the line we are in. */
19570 row = updated_row;
19571 line_height = row->height;
19573 /* Get the width of the glyphs to insert. */
19574 shift_by_width = 0;
19575 for (glyph = start; glyph < start + len; ++glyph)
19576 shift_by_width += glyph->pixel_width;
19578 /* Get the width of the region to shift right. */
19579 shifted_region_width = (window_box_width (w, updated_area)
19580 - output_cursor.x
19581 - shift_by_width);
19583 /* Shift right. */
19584 frame_x = window_box_left (w, updated_area) + output_cursor.x;
19585 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
19587 rif->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
19588 line_height, shift_by_width);
19590 /* Write the glyphs. */
19591 hpos = start - row->glyphs[updated_area];
19592 draw_glyphs (w, output_cursor.x, row, updated_area,
19593 hpos, hpos + len,
19594 DRAW_NORMAL_TEXT, 0);
19596 /* Advance the output cursor. */
19597 output_cursor.hpos += len;
19598 output_cursor.x += shift_by_width;
19599 UNBLOCK_INPUT;
19603 /* EXPORT for RIF:
19604 Erase the current text line from the nominal cursor position
19605 (inclusive) to pixel column TO_X (exclusive). The idea is that
19606 everything from TO_X onward is already erased.
19608 TO_X is a pixel position relative to updated_area of
19609 updated_window. TO_X == -1 means clear to the end of this area. */
19611 void
19612 x_clear_end_of_line (to_x)
19613 int to_x;
19615 struct frame *f;
19616 struct window *w = updated_window;
19617 int max_x, min_y, max_y;
19618 int from_x, from_y, to_y;
19620 xassert (updated_window && updated_row);
19621 f = XFRAME (w->frame);
19623 if (updated_row->full_width_p)
19624 max_x = WINDOW_TOTAL_WIDTH (w);
19625 else
19626 max_x = window_box_width (w, updated_area);
19627 max_y = window_text_bottom_y (w);
19629 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
19630 of window. For TO_X > 0, truncate to end of drawing area. */
19631 if (to_x == 0)
19632 return;
19633 else if (to_x < 0)
19634 to_x = max_x;
19635 else
19636 to_x = min (to_x, max_x);
19638 to_y = min (max_y, output_cursor.y + updated_row->height);
19640 /* Notice if the cursor will be cleared by this operation. */
19641 if (!updated_row->full_width_p)
19642 notice_overwritten_cursor (w, updated_area,
19643 output_cursor.x, -1,
19644 updated_row->y,
19645 MATRIX_ROW_BOTTOM_Y (updated_row));
19647 from_x = output_cursor.x;
19649 /* Translate to frame coordinates. */
19650 if (updated_row->full_width_p)
19652 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
19653 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
19655 else
19657 int area_left = window_box_left (w, updated_area);
19658 from_x += area_left;
19659 to_x += area_left;
19662 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
19663 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
19664 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
19666 /* Prevent inadvertently clearing to end of the X window. */
19667 if (to_x > from_x && to_y > from_y)
19669 BLOCK_INPUT;
19670 rif->clear_frame_area (f, from_x, from_y,
19671 to_x - from_x, to_y - from_y);
19672 UNBLOCK_INPUT;
19676 #endif /* HAVE_WINDOW_SYSTEM */
19680 /***********************************************************************
19681 Cursor types
19682 ***********************************************************************/
19684 /* Value is the internal representation of the specified cursor type
19685 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
19686 of the bar cursor. */
19688 static enum text_cursor_kinds
19689 get_specified_cursor_type (arg, width)
19690 Lisp_Object arg;
19691 int *width;
19693 enum text_cursor_kinds type;
19695 if (NILP (arg))
19696 return NO_CURSOR;
19698 if (EQ (arg, Qbox))
19699 return FILLED_BOX_CURSOR;
19701 if (EQ (arg, Qhollow))
19702 return HOLLOW_BOX_CURSOR;
19704 if (EQ (arg, Qbar))
19706 *width = 2;
19707 return BAR_CURSOR;
19710 if (CONSP (arg)
19711 && EQ (XCAR (arg), Qbar)
19712 && INTEGERP (XCDR (arg))
19713 && XINT (XCDR (arg)) >= 0)
19715 *width = XINT (XCDR (arg));
19716 return BAR_CURSOR;
19719 if (EQ (arg, Qhbar))
19721 *width = 2;
19722 return HBAR_CURSOR;
19725 if (CONSP (arg)
19726 && EQ (XCAR (arg), Qhbar)
19727 && INTEGERP (XCDR (arg))
19728 && XINT (XCDR (arg)) >= 0)
19730 *width = XINT (XCDR (arg));
19731 return HBAR_CURSOR;
19734 /* Treat anything unknown as "hollow box cursor".
19735 It was bad to signal an error; people have trouble fixing
19736 .Xdefaults with Emacs, when it has something bad in it. */
19737 type = HOLLOW_BOX_CURSOR;
19739 return type;
19742 /* Set the default cursor types for specified frame. */
19743 void
19744 set_frame_cursor_types (f, arg)
19745 struct frame *f;
19746 Lisp_Object arg;
19748 int width;
19749 Lisp_Object tem;
19751 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
19752 FRAME_CURSOR_WIDTH (f) = width;
19754 /* By default, set up the blink-off state depending on the on-state. */
19756 tem = Fassoc (arg, Vblink_cursor_alist);
19757 if (!NILP (tem))
19759 FRAME_BLINK_OFF_CURSOR (f)
19760 = get_specified_cursor_type (XCDR (tem), &width);
19761 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
19763 else
19764 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
19768 /* Return the cursor we want to be displayed in window W. Return
19769 width of bar/hbar cursor through WIDTH arg. Return with
19770 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
19771 (i.e. if the `system caret' should track this cursor).
19773 In a mini-buffer window, we want the cursor only to appear if we
19774 are reading input from this window. For the selected window, we
19775 want the cursor type given by the frame parameter or buffer local
19776 setting of cursor-type. If explicitly marked off, draw no cursor.
19777 In all other cases, we want a hollow box cursor. */
19779 static enum text_cursor_kinds
19780 get_window_cursor_type (w, glyph, width, active_cursor)
19781 struct window *w;
19782 struct glyph *glyph;
19783 int *width;
19784 int *active_cursor;
19786 struct frame *f = XFRAME (w->frame);
19787 struct buffer *b = XBUFFER (w->buffer);
19788 int cursor_type = DEFAULT_CURSOR;
19789 Lisp_Object alt_cursor;
19790 int non_selected = 0;
19792 *active_cursor = 1;
19794 /* Echo area */
19795 if (cursor_in_echo_area
19796 && FRAME_HAS_MINIBUF_P (f)
19797 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
19799 if (w == XWINDOW (echo_area_window))
19801 *width = FRAME_CURSOR_WIDTH (f);
19802 return FRAME_DESIRED_CURSOR (f);
19805 *active_cursor = 0;
19806 non_selected = 1;
19809 /* Nonselected window or nonselected frame. */
19810 else if (w != XWINDOW (f->selected_window)
19811 #ifdef HAVE_WINDOW_SYSTEM
19812 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame
19813 #endif
19816 *active_cursor = 0;
19818 if (MINI_WINDOW_P (w) && minibuf_level == 0)
19819 return NO_CURSOR;
19821 non_selected = 1;
19824 /* Never display a cursor in a window in which cursor-type is nil. */
19825 if (NILP (b->cursor_type))
19826 return NO_CURSOR;
19828 /* Use cursor-in-non-selected-windows for non-selected window or frame. */
19829 if (non_selected)
19831 alt_cursor = Fbuffer_local_value (Qcursor_in_non_selected_windows, w->buffer);
19832 return get_specified_cursor_type (alt_cursor, width);
19835 /* Get the normal cursor type for this window. */
19836 if (EQ (b->cursor_type, Qt))
19838 cursor_type = FRAME_DESIRED_CURSOR (f);
19839 *width = FRAME_CURSOR_WIDTH (f);
19841 else
19842 cursor_type = get_specified_cursor_type (b->cursor_type, width);
19844 /* Use normal cursor if not blinked off. */
19845 if (!w->cursor_off_p)
19847 if (glyph != NULL && glyph->type == IMAGE_GLYPH) {
19848 if (cursor_type == FILLED_BOX_CURSOR)
19849 cursor_type = HOLLOW_BOX_CURSOR;
19851 return cursor_type;
19854 /* Cursor is blinked off, so determine how to "toggle" it. */
19856 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
19857 if ((alt_cursor = Fassoc (b->cursor_type, Vblink_cursor_alist), !NILP (alt_cursor)))
19858 return get_specified_cursor_type (XCDR (alt_cursor), width);
19860 /* Then see if frame has specified a specific blink off cursor type. */
19861 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
19863 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
19864 return FRAME_BLINK_OFF_CURSOR (f);
19867 #if 0
19868 /* Some people liked having a permanently visible blinking cursor,
19869 while others had very strong opinions against it. So it was
19870 decided to remove it. KFS 2003-09-03 */
19872 /* Finally perform built-in cursor blinking:
19873 filled box <-> hollow box
19874 wide [h]bar <-> narrow [h]bar
19875 narrow [h]bar <-> no cursor
19876 other type <-> no cursor */
19878 if (cursor_type == FILLED_BOX_CURSOR)
19879 return HOLLOW_BOX_CURSOR;
19881 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
19883 *width = 1;
19884 return cursor_type;
19886 #endif
19888 return NO_CURSOR;
19892 #ifdef HAVE_WINDOW_SYSTEM
19894 /* Notice when the text cursor of window W has been completely
19895 overwritten by a drawing operation that outputs glyphs in AREA
19896 starting at X0 and ending at X1 in the line starting at Y0 and
19897 ending at Y1. X coordinates are area-relative. X1 < 0 means all
19898 the rest of the line after X0 has been written. Y coordinates
19899 are window-relative. */
19901 static void
19902 notice_overwritten_cursor (w, area, x0, x1, y0, y1)
19903 struct window *w;
19904 enum glyph_row_area area;
19905 int x0, y0, x1, y1;
19907 int cx0, cx1, cy0, cy1;
19908 struct glyph_row *row;
19910 if (!w->phys_cursor_on_p)
19911 return;
19912 if (area != TEXT_AREA)
19913 return;
19915 row = w->current_matrix->rows + w->phys_cursor.vpos;
19916 if (!row->displays_text_p)
19917 return;
19919 if (row->cursor_in_fringe_p)
19921 row->cursor_in_fringe_p = 0;
19922 draw_fringe_bitmap (w, row, 0);
19923 w->phys_cursor_on_p = 0;
19924 return;
19927 cx0 = w->phys_cursor.x;
19928 cx1 = cx0 + w->phys_cursor_width;
19929 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
19930 return;
19932 /* The cursor image will be completely removed from the
19933 screen if the output area intersects the cursor area in
19934 y-direction. When we draw in [y0 y1[, and some part of
19935 the cursor is at y < y0, that part must have been drawn
19936 before. When scrolling, the cursor is erased before
19937 actually scrolling, so we don't come here. When not
19938 scrolling, the rows above the old cursor row must have
19939 changed, and in this case these rows must have written
19940 over the cursor image.
19942 Likewise if part of the cursor is below y1, with the
19943 exception of the cursor being in the first blank row at
19944 the buffer and window end because update_text_area
19945 doesn't draw that row. (Except when it does, but
19946 that's handled in update_text_area.) */
19948 cy0 = w->phys_cursor.y;
19949 cy1 = cy0 + w->phys_cursor_height;
19950 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
19951 return;
19953 w->phys_cursor_on_p = 0;
19956 #endif /* HAVE_WINDOW_SYSTEM */
19959 /************************************************************************
19960 Mouse Face
19961 ************************************************************************/
19963 #ifdef HAVE_WINDOW_SYSTEM
19965 /* EXPORT for RIF:
19966 Fix the display of area AREA of overlapping row ROW in window W. */
19968 void
19969 x_fix_overlapping_area (w, row, area)
19970 struct window *w;
19971 struct glyph_row *row;
19972 enum glyph_row_area area;
19974 int i, x;
19976 BLOCK_INPUT;
19978 x = 0;
19979 for (i = 0; i < row->used[area];)
19981 if (row->glyphs[area][i].overlaps_vertically_p)
19983 int start = i, start_x = x;
19987 x += row->glyphs[area][i].pixel_width;
19988 ++i;
19990 while (i < row->used[area]
19991 && row->glyphs[area][i].overlaps_vertically_p);
19993 draw_glyphs (w, start_x, row, area,
19994 start, i,
19995 DRAW_NORMAL_TEXT, 1);
19997 else
19999 x += row->glyphs[area][i].pixel_width;
20000 ++i;
20004 UNBLOCK_INPUT;
20008 /* EXPORT:
20009 Draw the cursor glyph of window W in glyph row ROW. See the
20010 comment of draw_glyphs for the meaning of HL. */
20012 void
20013 draw_phys_cursor_glyph (w, row, hl)
20014 struct window *w;
20015 struct glyph_row *row;
20016 enum draw_glyphs_face hl;
20018 /* If cursor hpos is out of bounds, don't draw garbage. This can
20019 happen in mini-buffer windows when switching between echo area
20020 glyphs and mini-buffer. */
20021 if (w->phys_cursor.hpos < row->used[TEXT_AREA])
20023 int on_p = w->phys_cursor_on_p;
20024 int x1;
20025 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
20026 w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
20027 hl, 0);
20028 w->phys_cursor_on_p = on_p;
20030 if (hl == DRAW_CURSOR)
20031 w->phys_cursor_width = x1 - w->phys_cursor.x;
20032 /* When we erase the cursor, and ROW is overlapped by other
20033 rows, make sure that these overlapping parts of other rows
20034 are redrawn. */
20035 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
20037 if (row > w->current_matrix->rows
20038 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
20039 x_fix_overlapping_area (w, row - 1, TEXT_AREA);
20041 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
20042 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
20043 x_fix_overlapping_area (w, row + 1, TEXT_AREA);
20049 /* EXPORT:
20050 Erase the image of a cursor of window W from the screen. */
20052 void
20053 erase_phys_cursor (w)
20054 struct window *w;
20056 struct frame *f = XFRAME (w->frame);
20057 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
20058 int hpos = w->phys_cursor.hpos;
20059 int vpos = w->phys_cursor.vpos;
20060 int mouse_face_here_p = 0;
20061 struct glyph_matrix *active_glyphs = w->current_matrix;
20062 struct glyph_row *cursor_row;
20063 struct glyph *cursor_glyph;
20064 enum draw_glyphs_face hl;
20066 /* No cursor displayed or row invalidated => nothing to do on the
20067 screen. */
20068 if (w->phys_cursor_type == NO_CURSOR)
20069 goto mark_cursor_off;
20071 /* VPOS >= active_glyphs->nrows means that window has been resized.
20072 Don't bother to erase the cursor. */
20073 if (vpos >= active_glyphs->nrows)
20074 goto mark_cursor_off;
20076 /* If row containing cursor is marked invalid, there is nothing we
20077 can do. */
20078 cursor_row = MATRIX_ROW (active_glyphs, vpos);
20079 if (!cursor_row->enabled_p)
20080 goto mark_cursor_off;
20082 /* If line spacing is > 0, old cursor may only be partially visible in
20083 window after split-window. So adjust visible height. */
20084 cursor_row->visible_height = min (cursor_row->visible_height,
20085 window_text_bottom_y (w) - cursor_row->y);
20087 /* If row is completely invisible, don't attempt to delete a cursor which
20088 isn't there. This can happen if cursor is at top of a window, and
20089 we switch to a buffer with a header line in that window. */
20090 if (cursor_row->visible_height <= 0)
20091 goto mark_cursor_off;
20093 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
20094 if (cursor_row->cursor_in_fringe_p)
20096 cursor_row->cursor_in_fringe_p = 0;
20097 draw_fringe_bitmap (w, cursor_row, 0);
20098 goto mark_cursor_off;
20101 /* This can happen when the new row is shorter than the old one.
20102 In this case, either draw_glyphs or clear_end_of_line
20103 should have cleared the cursor. Note that we wouldn't be
20104 able to erase the cursor in this case because we don't have a
20105 cursor glyph at hand. */
20106 if (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])
20107 goto mark_cursor_off;
20109 /* If the cursor is in the mouse face area, redisplay that when
20110 we clear the cursor. */
20111 if (! NILP (dpyinfo->mouse_face_window)
20112 && w == XWINDOW (dpyinfo->mouse_face_window)
20113 && (vpos > dpyinfo->mouse_face_beg_row
20114 || (vpos == dpyinfo->mouse_face_beg_row
20115 && hpos >= dpyinfo->mouse_face_beg_col))
20116 && (vpos < dpyinfo->mouse_face_end_row
20117 || (vpos == dpyinfo->mouse_face_end_row
20118 && hpos < dpyinfo->mouse_face_end_col))
20119 /* Don't redraw the cursor's spot in mouse face if it is at the
20120 end of a line (on a newline). The cursor appears there, but
20121 mouse highlighting does not. */
20122 && cursor_row->used[TEXT_AREA] > hpos)
20123 mouse_face_here_p = 1;
20125 /* Maybe clear the display under the cursor. */
20126 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
20128 int x, y;
20129 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
20130 int width;
20132 cursor_glyph = get_phys_cursor_glyph (w);
20133 if (cursor_glyph == NULL)
20134 goto mark_cursor_off;
20136 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
20137 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
20138 width = min (cursor_glyph->pixel_width,
20139 window_box_width (w, TEXT_AREA) - w->phys_cursor.x);
20141 rif->clear_frame_area (f, x, y, width, cursor_row->visible_height);
20144 /* Erase the cursor by redrawing the character underneath it. */
20145 if (mouse_face_here_p)
20146 hl = DRAW_MOUSE_FACE;
20147 else
20148 hl = DRAW_NORMAL_TEXT;
20149 draw_phys_cursor_glyph (w, cursor_row, hl);
20151 mark_cursor_off:
20152 w->phys_cursor_on_p = 0;
20153 w->phys_cursor_type = NO_CURSOR;
20157 /* EXPORT:
20158 Display or clear cursor of window W. If ON is zero, clear the
20159 cursor. If it is non-zero, display the cursor. If ON is nonzero,
20160 where to put the cursor is specified by HPOS, VPOS, X and Y. */
20162 void
20163 display_and_set_cursor (w, on, hpos, vpos, x, y)
20164 struct window *w;
20165 int on, hpos, vpos, x, y;
20167 struct frame *f = XFRAME (w->frame);
20168 int new_cursor_type;
20169 int new_cursor_width;
20170 int active_cursor;
20171 struct glyph_row *glyph_row;
20172 struct glyph *glyph;
20174 /* This is pointless on invisible frames, and dangerous on garbaged
20175 windows and frames; in the latter case, the frame or window may
20176 be in the midst of changing its size, and x and y may be off the
20177 window. */
20178 if (! FRAME_VISIBLE_P (f)
20179 || FRAME_GARBAGED_P (f)
20180 || vpos >= w->current_matrix->nrows
20181 || hpos >= w->current_matrix->matrix_w)
20182 return;
20184 /* If cursor is off and we want it off, return quickly. */
20185 if (!on && !w->phys_cursor_on_p)
20186 return;
20188 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
20189 /* If cursor row is not enabled, we don't really know where to
20190 display the cursor. */
20191 if (!glyph_row->enabled_p)
20193 w->phys_cursor_on_p = 0;
20194 return;
20197 glyph = NULL;
20198 if (!glyph_row->exact_window_width_line_p
20199 || hpos < glyph_row->used[TEXT_AREA])
20200 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
20202 xassert (interrupt_input_blocked);
20204 /* Set new_cursor_type to the cursor we want to be displayed. */
20205 new_cursor_type = get_window_cursor_type (w, glyph,
20206 &new_cursor_width, &active_cursor);
20208 /* If cursor is currently being shown and we don't want it to be or
20209 it is in the wrong place, or the cursor type is not what we want,
20210 erase it. */
20211 if (w->phys_cursor_on_p
20212 && (!on
20213 || w->phys_cursor.x != x
20214 || w->phys_cursor.y != y
20215 || new_cursor_type != w->phys_cursor_type
20216 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
20217 && new_cursor_width != w->phys_cursor_width)))
20218 erase_phys_cursor (w);
20220 /* Don't check phys_cursor_on_p here because that flag is only set
20221 to zero in some cases where we know that the cursor has been
20222 completely erased, to avoid the extra work of erasing the cursor
20223 twice. In other words, phys_cursor_on_p can be 1 and the cursor
20224 still not be visible, or it has only been partly erased. */
20225 if (on)
20227 w->phys_cursor_ascent = glyph_row->ascent;
20228 w->phys_cursor_height = glyph_row->height;
20230 /* Set phys_cursor_.* before x_draw_.* is called because some
20231 of them may need the information. */
20232 w->phys_cursor.x = x;
20233 w->phys_cursor.y = glyph_row->y;
20234 w->phys_cursor.hpos = hpos;
20235 w->phys_cursor.vpos = vpos;
20238 rif->draw_window_cursor (w, glyph_row, x, y,
20239 new_cursor_type, new_cursor_width,
20240 on, active_cursor);
20244 /* Switch the display of W's cursor on or off, according to the value
20245 of ON. */
20247 static void
20248 update_window_cursor (w, on)
20249 struct window *w;
20250 int on;
20252 /* Don't update cursor in windows whose frame is in the process
20253 of being deleted. */
20254 if (w->current_matrix)
20256 BLOCK_INPUT;
20257 display_and_set_cursor (w, on, w->phys_cursor.hpos, w->phys_cursor.vpos,
20258 w->phys_cursor.x, w->phys_cursor.y);
20259 UNBLOCK_INPUT;
20264 /* Call update_window_cursor with parameter ON_P on all leaf windows
20265 in the window tree rooted at W. */
20267 static void
20268 update_cursor_in_window_tree (w, on_p)
20269 struct window *w;
20270 int on_p;
20272 while (w)
20274 if (!NILP (w->hchild))
20275 update_cursor_in_window_tree (XWINDOW (w->hchild), on_p);
20276 else if (!NILP (w->vchild))
20277 update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
20278 else
20279 update_window_cursor (w, on_p);
20281 w = NILP (w->next) ? 0 : XWINDOW (w->next);
20286 /* EXPORT:
20287 Display the cursor on window W, or clear it, according to ON_P.
20288 Don't change the cursor's position. */
20290 void
20291 x_update_cursor (f, on_p)
20292 struct frame *f;
20293 int on_p;
20295 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
20299 /* EXPORT:
20300 Clear the cursor of window W to background color, and mark the
20301 cursor as not shown. This is used when the text where the cursor
20302 is is about to be rewritten. */
20304 void
20305 x_clear_cursor (w)
20306 struct window *w;
20308 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
20309 update_window_cursor (w, 0);
20313 /* EXPORT:
20314 Display the active region described by mouse_face_* according to DRAW. */
20316 void
20317 show_mouse_face (dpyinfo, draw)
20318 Display_Info *dpyinfo;
20319 enum draw_glyphs_face draw;
20321 struct window *w = XWINDOW (dpyinfo->mouse_face_window);
20322 struct frame *f = XFRAME (WINDOW_FRAME (w));
20324 if (/* If window is in the process of being destroyed, don't bother
20325 to do anything. */
20326 w->current_matrix != NULL
20327 /* Don't update mouse highlight if hidden */
20328 && (draw != DRAW_MOUSE_FACE || !dpyinfo->mouse_face_hidden)
20329 /* Recognize when we are called to operate on rows that don't exist
20330 anymore. This can happen when a window is split. */
20331 && dpyinfo->mouse_face_end_row < w->current_matrix->nrows)
20333 int phys_cursor_on_p = w->phys_cursor_on_p;
20334 struct glyph_row *row, *first, *last;
20336 first = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row);
20337 last = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row);
20339 for (row = first; row <= last && row->enabled_p; ++row)
20341 int start_hpos, end_hpos, start_x;
20343 /* For all but the first row, the highlight starts at column 0. */
20344 if (row == first)
20346 start_hpos = dpyinfo->mouse_face_beg_col;
20347 start_x = dpyinfo->mouse_face_beg_x;
20349 else
20351 start_hpos = 0;
20352 start_x = 0;
20355 if (row == last)
20356 end_hpos = dpyinfo->mouse_face_end_col;
20357 else
20358 end_hpos = row->used[TEXT_AREA];
20360 if (end_hpos > start_hpos)
20362 draw_glyphs (w, start_x, row, TEXT_AREA,
20363 start_hpos, end_hpos,
20364 draw, 0);
20366 row->mouse_face_p
20367 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
20371 /* When we've written over the cursor, arrange for it to
20372 be displayed again. */
20373 if (phys_cursor_on_p && !w->phys_cursor_on_p)
20375 BLOCK_INPUT;
20376 display_and_set_cursor (w, 1,
20377 w->phys_cursor.hpos, w->phys_cursor.vpos,
20378 w->phys_cursor.x, w->phys_cursor.y);
20379 UNBLOCK_INPUT;
20383 /* Change the mouse cursor. */
20384 if (draw == DRAW_NORMAL_TEXT)
20385 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
20386 else if (draw == DRAW_MOUSE_FACE)
20387 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
20388 else
20389 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
20392 /* EXPORT:
20393 Clear out the mouse-highlighted active region.
20394 Redraw it un-highlighted first. Value is non-zero if mouse
20395 face was actually drawn unhighlighted. */
20398 clear_mouse_face (dpyinfo)
20399 Display_Info *dpyinfo;
20401 int cleared = 0;
20403 if (!dpyinfo->mouse_face_hidden && !NILP (dpyinfo->mouse_face_window))
20405 show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT);
20406 cleared = 1;
20409 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
20410 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
20411 dpyinfo->mouse_face_window = Qnil;
20412 dpyinfo->mouse_face_overlay = Qnil;
20413 return cleared;
20417 /* EXPORT:
20418 Non-zero if physical cursor of window W is within mouse face. */
20421 cursor_in_mouse_face_p (w)
20422 struct window *w;
20424 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
20425 int in_mouse_face = 0;
20427 if (WINDOWP (dpyinfo->mouse_face_window)
20428 && XWINDOW (dpyinfo->mouse_face_window) == w)
20430 int hpos = w->phys_cursor.hpos;
20431 int vpos = w->phys_cursor.vpos;
20433 if (vpos >= dpyinfo->mouse_face_beg_row
20434 && vpos <= dpyinfo->mouse_face_end_row
20435 && (vpos > dpyinfo->mouse_face_beg_row
20436 || hpos >= dpyinfo->mouse_face_beg_col)
20437 && (vpos < dpyinfo->mouse_face_end_row
20438 || hpos < dpyinfo->mouse_face_end_col
20439 || dpyinfo->mouse_face_past_end))
20440 in_mouse_face = 1;
20443 return in_mouse_face;
20449 /* Find the glyph matrix position of buffer position CHARPOS in window
20450 *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's
20451 current glyphs must be up to date. If CHARPOS is above window
20452 start return (0, 0, 0, 0). If CHARPOS is after end of W, return end
20453 of last line in W. In the row containing CHARPOS, stop before glyphs
20454 having STOP as object. */
20456 #if 1 /* This is a version of fast_find_position that's more correct
20457 in the presence of hscrolling, for example. I didn't install
20458 it right away because the problem fixed is minor, it failed
20459 in 20.x as well, and I think it's too risky to install
20460 so near the release of 21.1. 2001-09-25 gerd. */
20462 static int
20463 fast_find_position (w, charpos, hpos, vpos, x, y, stop)
20464 struct window *w;
20465 int charpos;
20466 int *hpos, *vpos, *x, *y;
20467 Lisp_Object stop;
20469 struct glyph_row *row, *first;
20470 struct glyph *glyph, *end;
20471 int past_end = 0;
20473 first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
20474 if (charpos < MATRIX_ROW_START_CHARPOS (first))
20476 *x = first->x;
20477 *y = first->y;
20478 *hpos = 0;
20479 *vpos = MATRIX_ROW_VPOS (first, w->current_matrix);
20480 return 1;
20483 row = row_containing_pos (w, charpos, first, NULL, 0);
20484 if (row == NULL)
20486 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
20487 past_end = 1;
20490 *x = row->x;
20491 *y = row->y;
20492 *vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
20494 glyph = row->glyphs[TEXT_AREA];
20495 end = glyph + row->used[TEXT_AREA];
20497 /* Skip over glyphs not having an object at the start of the row.
20498 These are special glyphs like truncation marks on terminal
20499 frames. */
20500 if (row->displays_text_p)
20501 while (glyph < end
20502 && INTEGERP (glyph->object)
20503 && !EQ (stop, glyph->object)
20504 && glyph->charpos < 0)
20506 *x += glyph->pixel_width;
20507 ++glyph;
20510 while (glyph < end
20511 && !INTEGERP (glyph->object)
20512 && !EQ (stop, glyph->object)
20513 && (!BUFFERP (glyph->object)
20514 || glyph->charpos < charpos))
20516 *x += glyph->pixel_width;
20517 ++glyph;
20520 *hpos = glyph - row->glyphs[TEXT_AREA];
20521 return !past_end;
20524 #else /* not 1 */
20526 static int
20527 fast_find_position (w, pos, hpos, vpos, x, y, stop)
20528 struct window *w;
20529 int pos;
20530 int *hpos, *vpos, *x, *y;
20531 Lisp_Object stop;
20533 int i;
20534 int lastcol;
20535 int maybe_next_line_p = 0;
20536 int line_start_position;
20537 int yb = window_text_bottom_y (w);
20538 struct glyph_row *row, *best_row;
20539 int row_vpos, best_row_vpos;
20540 int current_x;
20542 row = best_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
20543 row_vpos = best_row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
20545 while (row->y < yb)
20547 if (row->used[TEXT_AREA])
20548 line_start_position = row->glyphs[TEXT_AREA]->charpos;
20549 else
20550 line_start_position = 0;
20552 if (line_start_position > pos)
20553 break;
20554 /* If the position sought is the end of the buffer,
20555 don't include the blank lines at the bottom of the window. */
20556 else if (line_start_position == pos
20557 && pos == BUF_ZV (XBUFFER (w->buffer)))
20559 maybe_next_line_p = 1;
20560 break;
20562 else if (line_start_position > 0)
20564 best_row = row;
20565 best_row_vpos = row_vpos;
20568 if (row->y + row->height >= yb)
20569 break;
20571 ++row;
20572 ++row_vpos;
20575 /* Find the right column within BEST_ROW. */
20576 lastcol = 0;
20577 current_x = best_row->x;
20578 for (i = 0; i < best_row->used[TEXT_AREA]; i++)
20580 struct glyph *glyph = best_row->glyphs[TEXT_AREA] + i;
20581 int charpos = glyph->charpos;
20583 if (BUFFERP (glyph->object))
20585 if (charpos == pos)
20587 *hpos = i;
20588 *vpos = best_row_vpos;
20589 *x = current_x;
20590 *y = best_row->y;
20591 return 1;
20593 else if (charpos > pos)
20594 break;
20596 else if (EQ (glyph->object, stop))
20597 break;
20599 if (charpos > 0)
20600 lastcol = i;
20601 current_x += glyph->pixel_width;
20604 /* If we're looking for the end of the buffer,
20605 and we didn't find it in the line we scanned,
20606 use the start of the following line. */
20607 if (maybe_next_line_p)
20609 ++best_row;
20610 ++best_row_vpos;
20611 lastcol = 0;
20612 current_x = best_row->x;
20615 *vpos = best_row_vpos;
20616 *hpos = lastcol + 1;
20617 *x = current_x;
20618 *y = best_row->y;
20619 return 0;
20622 #endif /* not 1 */
20625 /* Find the position of the glyph for position POS in OBJECT in
20626 window W's current matrix, and return in *X, *Y the pixel
20627 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
20629 RIGHT_P non-zero means return the position of the right edge of the
20630 glyph, RIGHT_P zero means return the left edge position.
20632 If no glyph for POS exists in the matrix, return the position of
20633 the glyph with the next smaller position that is in the matrix, if
20634 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
20635 exists in the matrix, return the position of the glyph with the
20636 next larger position in OBJECT.
20638 Value is non-zero if a glyph was found. */
20640 static int
20641 fast_find_string_pos (w, pos, object, hpos, vpos, x, y, right_p)
20642 struct window *w;
20643 int pos;
20644 Lisp_Object object;
20645 int *hpos, *vpos, *x, *y;
20646 int right_p;
20648 int yb = window_text_bottom_y (w);
20649 struct glyph_row *r;
20650 struct glyph *best_glyph = NULL;
20651 struct glyph_row *best_row = NULL;
20652 int best_x = 0;
20654 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
20655 r->enabled_p && r->y < yb;
20656 ++r)
20658 struct glyph *g = r->glyphs[TEXT_AREA];
20659 struct glyph *e = g + r->used[TEXT_AREA];
20660 int gx;
20662 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
20663 if (EQ (g->object, object))
20665 if (g->charpos == pos)
20667 best_glyph = g;
20668 best_x = gx;
20669 best_row = r;
20670 goto found;
20672 else if (best_glyph == NULL
20673 || ((abs (g->charpos - pos)
20674 < abs (best_glyph->charpos - pos))
20675 && (right_p
20676 ? g->charpos < pos
20677 : g->charpos > pos)))
20679 best_glyph = g;
20680 best_x = gx;
20681 best_row = r;
20686 found:
20688 if (best_glyph)
20690 *x = best_x;
20691 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
20693 if (right_p)
20695 *x += best_glyph->pixel_width;
20696 ++*hpos;
20699 *y = best_row->y;
20700 *vpos = best_row - w->current_matrix->rows;
20703 return best_glyph != NULL;
20707 /* See if position X, Y is within a hot-spot of an image. */
20709 static int
20710 on_hot_spot_p (hot_spot, x, y)
20711 Lisp_Object hot_spot;
20712 int x, y;
20714 if (!CONSP (hot_spot))
20715 return 0;
20717 if (EQ (XCAR (hot_spot), Qrect))
20719 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
20720 Lisp_Object rect = XCDR (hot_spot);
20721 Lisp_Object tem;
20722 if (!CONSP (rect))
20723 return 0;
20724 if (!CONSP (XCAR (rect)))
20725 return 0;
20726 if (!CONSP (XCDR (rect)))
20727 return 0;
20728 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
20729 return 0;
20730 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
20731 return 0;
20732 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
20733 return 0;
20734 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
20735 return 0;
20736 return 1;
20738 else if (EQ (XCAR (hot_spot), Qcircle))
20740 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
20741 Lisp_Object circ = XCDR (hot_spot);
20742 Lisp_Object lr, lx0, ly0;
20743 if (CONSP (circ)
20744 && CONSP (XCAR (circ))
20745 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
20746 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
20747 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
20749 double r = XFLOATINT (lr);
20750 double dx = XINT (lx0) - x;
20751 double dy = XINT (ly0) - y;
20752 return (dx * dx + dy * dy <= r * r);
20755 else if (EQ (XCAR (hot_spot), Qpoly))
20757 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
20758 if (VECTORP (XCDR (hot_spot)))
20760 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
20761 Lisp_Object *poly = v->contents;
20762 int n = v->size;
20763 int i;
20764 int inside = 0;
20765 Lisp_Object lx, ly;
20766 int x0, y0;
20768 /* Need an even number of coordinates, and at least 3 edges. */
20769 if (n < 6 || n & 1)
20770 return 0;
20772 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
20773 If count is odd, we are inside polygon. Pixels on edges
20774 may or may not be included depending on actual geometry of the
20775 polygon. */
20776 if ((lx = poly[n-2], !INTEGERP (lx))
20777 || (ly = poly[n-1], !INTEGERP (lx)))
20778 return 0;
20779 x0 = XINT (lx), y0 = XINT (ly);
20780 for (i = 0; i < n; i += 2)
20782 int x1 = x0, y1 = y0;
20783 if ((lx = poly[i], !INTEGERP (lx))
20784 || (ly = poly[i+1], !INTEGERP (ly)))
20785 return 0;
20786 x0 = XINT (lx), y0 = XINT (ly);
20788 /* Does this segment cross the X line? */
20789 if (x0 >= x)
20791 if (x1 >= x)
20792 continue;
20794 else if (x1 < x)
20795 continue;
20796 if (y > y0 && y > y1)
20797 continue;
20798 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
20799 inside = !inside;
20801 return inside;
20804 /* If we don't understand the format, pretend we're not in the hot-spot. */
20805 return 0;
20808 Lisp_Object
20809 find_hot_spot (map, x, y)
20810 Lisp_Object map;
20811 int x, y;
20813 while (CONSP (map))
20815 if (CONSP (XCAR (map))
20816 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
20817 return XCAR (map);
20818 map = XCDR (map);
20821 return Qnil;
20824 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
20825 3, 3, 0,
20826 doc: /* Lookup in image map MAP coordinates X and Y.
20827 An image map is an alist where each element has the format (AREA ID PLIST).
20828 An AREA is specified as either a rectangle, a circle, or a polygon:
20829 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
20830 pixel coordinates of the upper left and bottom right corners.
20831 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
20832 and the radius of the circle; r may be a float or integer.
20833 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
20834 vector describes one corner in the polygon.
20835 Returns the alist element for the first matching AREA in MAP. */)
20836 (map, x, y)
20837 Lisp_Object map;
20838 Lisp_Object x, y;
20840 if (NILP (map))
20841 return Qnil;
20843 CHECK_NUMBER (x);
20844 CHECK_NUMBER (y);
20846 return find_hot_spot (map, XINT (x), XINT (y));
20850 /* Display frame CURSOR, optionally using shape defined by POINTER. */
20851 static void
20852 define_frame_cursor1 (f, cursor, pointer)
20853 struct frame *f;
20854 Cursor cursor;
20855 Lisp_Object pointer;
20857 /* Do not change cursor shape while dragging mouse. */
20858 if (!NILP (do_mouse_tracking))
20859 return;
20861 if (!NILP (pointer))
20863 if (EQ (pointer, Qarrow))
20864 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20865 else if (EQ (pointer, Qhand))
20866 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
20867 else if (EQ (pointer, Qtext))
20868 cursor = FRAME_X_OUTPUT (f)->text_cursor;
20869 else if (EQ (pointer, intern ("hdrag")))
20870 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
20871 #ifdef HAVE_X_WINDOWS
20872 else if (EQ (pointer, intern ("vdrag")))
20873 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
20874 #endif
20875 else if (EQ (pointer, intern ("hourglass")))
20876 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
20877 else if (EQ (pointer, Qmodeline))
20878 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
20879 else
20880 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20883 if (cursor != No_Cursor)
20884 rif->define_frame_cursor (f, cursor);
20887 /* Take proper action when mouse has moved to the mode or header line
20888 or marginal area AREA of window W, x-position X and y-position Y.
20889 X is relative to the start of the text display area of W, so the
20890 width of bitmap areas and scroll bars must be subtracted to get a
20891 position relative to the start of the mode line. */
20893 static void
20894 note_mode_line_or_margin_highlight (w, x, y, area)
20895 struct window *w;
20896 int x, y;
20897 enum window_part area;
20899 struct frame *f = XFRAME (w->frame);
20900 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
20901 Cursor cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20902 Lisp_Object pointer = Qnil;
20903 int charpos, dx, dy, width, height;
20904 Lisp_Object string, object = Qnil;
20905 Lisp_Object pos, help;
20907 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
20908 string = mode_line_string (w, area, &x, &y, &charpos,
20909 &object, &dx, &dy, &width, &height);
20910 else
20912 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
20913 string = marginal_area_string (w, area, &x, &y, &charpos,
20914 &object, &dx, &dy, &width, &height);
20917 help = Qnil;
20919 if (IMAGEP (object))
20921 Lisp_Object image_map, hotspot;
20922 if ((image_map = Fsafe_plist_get (XCDR (object), QCmap),
20923 !NILP (image_map))
20924 && (hotspot = find_hot_spot (image_map, dx, dy),
20925 CONSP (hotspot))
20926 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
20928 Lisp_Object area_id, plist;
20930 area_id = XCAR (hotspot);
20931 /* Could check AREA_ID to see if we enter/leave this hot-spot.
20932 If so, we could look for mouse-enter, mouse-leave
20933 properties in PLIST (and do something...). */
20934 hotspot = XCDR (hotspot);
20935 if (CONSP (hotspot)
20936 && (plist = XCAR (hotspot), CONSP (plist)))
20938 pointer = Fsafe_plist_get (plist, Qpointer);
20939 if (NILP (pointer))
20940 pointer = Qhand;
20941 help = Fsafe_plist_get (plist, Qhelp_echo);
20942 if (!NILP (help))
20944 help_echo_string = help;
20945 /* Is this correct? ++kfs */
20946 XSETWINDOW (help_echo_window, w);
20947 help_echo_object = w->buffer;
20948 help_echo_pos = charpos;
20951 if (NILP (pointer))
20952 pointer = Fsafe_plist_get (XCDR (object), QCpointer);
20956 if (STRINGP (string))
20958 pos = make_number (charpos);
20959 /* If we're on a string with `help-echo' text property, arrange
20960 for the help to be displayed. This is done by setting the
20961 global variable help_echo_string to the help string. */
20962 if (NILP (help))
20964 help = Fget_text_property (pos, Qhelp_echo, string);
20965 if (!NILP (help))
20967 help_echo_string = help;
20968 XSETWINDOW (help_echo_window, w);
20969 help_echo_object = string;
20970 help_echo_pos = charpos;
20974 if (NILP (pointer))
20975 pointer = Fget_text_property (pos, Qpointer, string);
20977 /* Change the mouse pointer according to what is under X/Y. */
20978 if (NILP (pointer) && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
20980 Lisp_Object map;
20981 map = Fget_text_property (pos, Qlocal_map, string);
20982 if (!KEYMAPP (map))
20983 map = Fget_text_property (pos, Qkeymap, string);
20984 if (!KEYMAPP (map))
20985 cursor = dpyinfo->vertical_scroll_bar_cursor;
20989 define_frame_cursor1 (f, cursor, pointer);
20993 /* EXPORT:
20994 Take proper action when the mouse has moved to position X, Y on
20995 frame F as regards highlighting characters that have mouse-face
20996 properties. Also de-highlighting chars where the mouse was before.
20997 X and Y can be negative or out of range. */
20999 void
21000 note_mouse_highlight (f, x, y)
21001 struct frame *f;
21002 int x, y;
21004 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
21005 enum window_part part;
21006 Lisp_Object window;
21007 struct window *w;
21008 Cursor cursor = No_Cursor;
21009 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
21010 struct buffer *b;
21012 /* When a menu is active, don't highlight because this looks odd. */
21013 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NTGUI)
21014 if (popup_activated ())
21015 return;
21016 #endif
21018 if (NILP (Vmouse_highlight)
21019 || !f->glyphs_initialized_p)
21020 return;
21022 dpyinfo->mouse_face_mouse_x = x;
21023 dpyinfo->mouse_face_mouse_y = y;
21024 dpyinfo->mouse_face_mouse_frame = f;
21026 if (dpyinfo->mouse_face_defer)
21027 return;
21029 if (gc_in_progress)
21031 dpyinfo->mouse_face_deferred_gc = 1;
21032 return;
21035 /* Which window is that in? */
21036 window = window_from_coordinates (f, x, y, &part, 0, 0, 1);
21038 /* If we were displaying active text in another window, clear that.
21039 Also clear if we move out of text area in same window. */
21040 if (! EQ (window, dpyinfo->mouse_face_window)
21041 || (part != ON_TEXT && !NILP (dpyinfo->mouse_face_window)))
21042 clear_mouse_face (dpyinfo);
21044 /* Not on a window -> return. */
21045 if (!WINDOWP (window))
21046 return;
21048 /* Reset help_echo_string. It will get recomputed below. */
21049 help_echo_string = Qnil;
21051 /* Convert to window-relative pixel coordinates. */
21052 w = XWINDOW (window);
21053 frame_to_window_pixel_xy (w, &x, &y);
21055 /* Handle tool-bar window differently since it doesn't display a
21056 buffer. */
21057 if (EQ (window, f->tool_bar_window))
21059 note_tool_bar_highlight (f, x, y);
21060 return;
21063 /* Mouse is on the mode, header line or margin? */
21064 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
21065 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
21067 note_mode_line_or_margin_highlight (w, x, y, part);
21068 return;
21071 if (part == ON_VERTICAL_BORDER)
21072 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
21073 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
21074 || part == ON_SCROLL_BAR)
21075 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
21076 else
21077 cursor = FRAME_X_OUTPUT (f)->text_cursor;
21079 /* Are we in a window whose display is up to date?
21080 And verify the buffer's text has not changed. */
21081 b = XBUFFER (w->buffer);
21082 if (part == ON_TEXT
21083 && EQ (w->window_end_valid, w->buffer)
21084 && XFASTINT (w->last_modified) == BUF_MODIFF (b)
21085 && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
21087 int hpos, vpos, pos, i, dx, dy, area;
21088 struct glyph *glyph;
21089 Lisp_Object object;
21090 Lisp_Object mouse_face = Qnil, overlay = Qnil, position;
21091 Lisp_Object *overlay_vec = NULL;
21092 int noverlays;
21093 struct buffer *obuf;
21094 int obegv, ozv, same_region;
21096 /* Find the glyph under X/Y. */
21097 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
21099 /* Look for :pointer property on image. */
21100 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
21102 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
21103 if (img != NULL && IMAGEP (img->spec))
21105 Lisp_Object image_map, hotspot;
21106 if ((image_map = Fsafe_plist_get (XCDR (img->spec), QCmap),
21107 !NILP (image_map))
21108 && (hotspot = find_hot_spot (image_map,
21109 glyph->slice.x + dx,
21110 glyph->slice.y + dy),
21111 CONSP (hotspot))
21112 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
21114 Lisp_Object area_id, plist;
21116 area_id = XCAR (hotspot);
21117 /* Could check AREA_ID to see if we enter/leave this hot-spot.
21118 If so, we could look for mouse-enter, mouse-leave
21119 properties in PLIST (and do something...). */
21120 hotspot = XCDR (hotspot);
21121 if (CONSP (hotspot)
21122 && (plist = XCAR (hotspot), CONSP (plist)))
21124 pointer = Fsafe_plist_get (plist, Qpointer);
21125 if (NILP (pointer))
21126 pointer = Qhand;
21127 help_echo_string = Fsafe_plist_get (plist, Qhelp_echo);
21128 if (!NILP (help_echo_string))
21130 help_echo_window = window;
21131 help_echo_object = glyph->object;
21132 help_echo_pos = glyph->charpos;
21136 if (NILP (pointer))
21137 pointer = Fsafe_plist_get (XCDR (img->spec), QCpointer);
21141 /* Clear mouse face if X/Y not over text. */
21142 if (glyph == NULL
21143 || area != TEXT_AREA
21144 || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p)
21146 if (clear_mouse_face (dpyinfo))
21147 cursor = No_Cursor;
21148 if (NILP (pointer))
21150 if (area != TEXT_AREA)
21151 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
21152 else
21153 pointer = Vvoid_text_area_pointer;
21155 goto set_cursor;
21158 pos = glyph->charpos;
21159 object = glyph->object;
21160 if (!STRINGP (object) && !BUFFERP (object))
21161 goto set_cursor;
21163 /* If we get an out-of-range value, return now; avoid an error. */
21164 if (BUFFERP (object) && pos > BUF_Z (b))
21165 goto set_cursor;
21167 /* Make the window's buffer temporarily current for
21168 overlays_at and compute_char_face. */
21169 obuf = current_buffer;
21170 current_buffer = b;
21171 obegv = BEGV;
21172 ozv = ZV;
21173 BEGV = BEG;
21174 ZV = Z;
21176 /* Is this char mouse-active or does it have help-echo? */
21177 position = make_number (pos);
21179 if (BUFFERP (object))
21181 /* Put all the overlays we want in a vector in overlay_vec. */
21182 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
21183 /* Sort overlays into increasing priority order. */
21184 noverlays = sort_overlays (overlay_vec, noverlays, w);
21186 else
21187 noverlays = 0;
21189 same_region = (EQ (window, dpyinfo->mouse_face_window)
21190 && vpos >= dpyinfo->mouse_face_beg_row
21191 && vpos <= dpyinfo->mouse_face_end_row
21192 && (vpos > dpyinfo->mouse_face_beg_row
21193 || hpos >= dpyinfo->mouse_face_beg_col)
21194 && (vpos < dpyinfo->mouse_face_end_row
21195 || hpos < dpyinfo->mouse_face_end_col
21196 || dpyinfo->mouse_face_past_end));
21198 if (same_region)
21199 cursor = No_Cursor;
21201 /* Check mouse-face highlighting. */
21202 if (! same_region
21203 /* If there exists an overlay with mouse-face overlapping
21204 the one we are currently highlighting, we have to
21205 check if we enter the overlapping overlay, and then
21206 highlight only that. */
21207 || (OVERLAYP (dpyinfo->mouse_face_overlay)
21208 && mouse_face_overlay_overlaps (dpyinfo->mouse_face_overlay)))
21210 /* Find the highest priority overlay that has a mouse-face
21211 property. */
21212 overlay = Qnil;
21213 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
21215 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
21216 if (!NILP (mouse_face))
21217 overlay = overlay_vec[i];
21220 /* If we're actually highlighting the same overlay as
21221 before, there's no need to do that again. */
21222 if (!NILP (overlay)
21223 && EQ (overlay, dpyinfo->mouse_face_overlay))
21224 goto check_help_echo;
21226 dpyinfo->mouse_face_overlay = overlay;
21228 /* Clear the display of the old active region, if any. */
21229 if (clear_mouse_face (dpyinfo))
21230 cursor = No_Cursor;
21232 /* If no overlay applies, get a text property. */
21233 if (NILP (overlay))
21234 mouse_face = Fget_text_property (position, Qmouse_face, object);
21236 /* Handle the overlay case. */
21237 if (!NILP (overlay))
21239 /* Find the range of text around this char that
21240 should be active. */
21241 Lisp_Object before, after;
21242 int ignore;
21244 before = Foverlay_start (overlay);
21245 after = Foverlay_end (overlay);
21246 /* Record this as the current active region. */
21247 fast_find_position (w, XFASTINT (before),
21248 &dpyinfo->mouse_face_beg_col,
21249 &dpyinfo->mouse_face_beg_row,
21250 &dpyinfo->mouse_face_beg_x,
21251 &dpyinfo->mouse_face_beg_y, Qnil);
21253 dpyinfo->mouse_face_past_end
21254 = !fast_find_position (w, XFASTINT (after),
21255 &dpyinfo->mouse_face_end_col,
21256 &dpyinfo->mouse_face_end_row,
21257 &dpyinfo->mouse_face_end_x,
21258 &dpyinfo->mouse_face_end_y, Qnil);
21259 dpyinfo->mouse_face_window = window;
21261 dpyinfo->mouse_face_face_id
21262 = face_at_buffer_position (w, pos, 0, 0,
21263 &ignore, pos + 1,
21264 !dpyinfo->mouse_face_hidden);
21266 /* Display it as active. */
21267 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21268 cursor = No_Cursor;
21270 /* Handle the text property case. */
21271 else if (!NILP (mouse_face) && BUFFERP (object))
21273 /* Find the range of text around this char that
21274 should be active. */
21275 Lisp_Object before, after, beginning, end;
21276 int ignore;
21278 beginning = Fmarker_position (w->start);
21279 end = make_number (BUF_Z (XBUFFER (object))
21280 - XFASTINT (w->window_end_pos));
21281 before
21282 = Fprevious_single_property_change (make_number (pos + 1),
21283 Qmouse_face,
21284 object, beginning);
21285 after
21286 = Fnext_single_property_change (position, Qmouse_face,
21287 object, end);
21289 /* Record this as the current active region. */
21290 fast_find_position (w, XFASTINT (before),
21291 &dpyinfo->mouse_face_beg_col,
21292 &dpyinfo->mouse_face_beg_row,
21293 &dpyinfo->mouse_face_beg_x,
21294 &dpyinfo->mouse_face_beg_y, Qnil);
21295 dpyinfo->mouse_face_past_end
21296 = !fast_find_position (w, XFASTINT (after),
21297 &dpyinfo->mouse_face_end_col,
21298 &dpyinfo->mouse_face_end_row,
21299 &dpyinfo->mouse_face_end_x,
21300 &dpyinfo->mouse_face_end_y, Qnil);
21301 dpyinfo->mouse_face_window = window;
21303 if (BUFFERP (object))
21304 dpyinfo->mouse_face_face_id
21305 = face_at_buffer_position (w, pos, 0, 0,
21306 &ignore, pos + 1,
21307 !dpyinfo->mouse_face_hidden);
21309 /* Display it as active. */
21310 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21311 cursor = No_Cursor;
21313 else if (!NILP (mouse_face) && STRINGP (object))
21315 Lisp_Object b, e;
21316 int ignore;
21318 b = Fprevious_single_property_change (make_number (pos + 1),
21319 Qmouse_face,
21320 object, Qnil);
21321 e = Fnext_single_property_change (position, Qmouse_face,
21322 object, Qnil);
21323 if (NILP (b))
21324 b = make_number (0);
21325 if (NILP (e))
21326 e = make_number (SCHARS (object) - 1);
21327 fast_find_string_pos (w, XINT (b), object,
21328 &dpyinfo->mouse_face_beg_col,
21329 &dpyinfo->mouse_face_beg_row,
21330 &dpyinfo->mouse_face_beg_x,
21331 &dpyinfo->mouse_face_beg_y, 0);
21332 fast_find_string_pos (w, XINT (e), object,
21333 &dpyinfo->mouse_face_end_col,
21334 &dpyinfo->mouse_face_end_row,
21335 &dpyinfo->mouse_face_end_x,
21336 &dpyinfo->mouse_face_end_y, 1);
21337 dpyinfo->mouse_face_past_end = 0;
21338 dpyinfo->mouse_face_window = window;
21339 dpyinfo->mouse_face_face_id
21340 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
21341 glyph->face_id, 1);
21342 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21343 cursor = No_Cursor;
21345 else if (STRINGP (object) && NILP (mouse_face))
21347 /* A string which doesn't have mouse-face, but
21348 the text ``under'' it might have. */
21349 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
21350 int start = MATRIX_ROW_START_CHARPOS (r);
21352 pos = string_buffer_position (w, object, start);
21353 if (pos > 0)
21354 mouse_face = get_char_property_and_overlay (make_number (pos),
21355 Qmouse_face,
21356 w->buffer,
21357 &overlay);
21358 if (!NILP (mouse_face) && !NILP (overlay))
21360 Lisp_Object before = Foverlay_start (overlay);
21361 Lisp_Object after = Foverlay_end (overlay);
21362 int ignore;
21364 /* Note that we might not be able to find position
21365 BEFORE in the glyph matrix if the overlay is
21366 entirely covered by a `display' property. In
21367 this case, we overshoot. So let's stop in
21368 the glyph matrix before glyphs for OBJECT. */
21369 fast_find_position (w, XFASTINT (before),
21370 &dpyinfo->mouse_face_beg_col,
21371 &dpyinfo->mouse_face_beg_row,
21372 &dpyinfo->mouse_face_beg_x,
21373 &dpyinfo->mouse_face_beg_y,
21374 object);
21376 dpyinfo->mouse_face_past_end
21377 = !fast_find_position (w, XFASTINT (after),
21378 &dpyinfo->mouse_face_end_col,
21379 &dpyinfo->mouse_face_end_row,
21380 &dpyinfo->mouse_face_end_x,
21381 &dpyinfo->mouse_face_end_y,
21382 Qnil);
21383 dpyinfo->mouse_face_window = window;
21384 dpyinfo->mouse_face_face_id
21385 = face_at_buffer_position (w, pos, 0, 0,
21386 &ignore, pos + 1,
21387 !dpyinfo->mouse_face_hidden);
21389 /* Display it as active. */
21390 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21391 cursor = No_Cursor;
21396 check_help_echo:
21398 /* Look for a `help-echo' property. */
21399 if (NILP (help_echo_string)) {
21400 Lisp_Object help, overlay;
21402 /* Check overlays first. */
21403 help = overlay = Qnil;
21404 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
21406 overlay = overlay_vec[i];
21407 help = Foverlay_get (overlay, Qhelp_echo);
21410 if (!NILP (help))
21412 help_echo_string = help;
21413 help_echo_window = window;
21414 help_echo_object = overlay;
21415 help_echo_pos = pos;
21417 else
21419 Lisp_Object object = glyph->object;
21420 int charpos = glyph->charpos;
21422 /* Try text properties. */
21423 if (STRINGP (object)
21424 && charpos >= 0
21425 && charpos < SCHARS (object))
21427 help = Fget_text_property (make_number (charpos),
21428 Qhelp_echo, object);
21429 if (NILP (help))
21431 /* If the string itself doesn't specify a help-echo,
21432 see if the buffer text ``under'' it does. */
21433 struct glyph_row *r
21434 = MATRIX_ROW (w->current_matrix, vpos);
21435 int start = MATRIX_ROW_START_CHARPOS (r);
21436 int pos = string_buffer_position (w, object, start);
21437 if (pos > 0)
21439 help = Fget_char_property (make_number (pos),
21440 Qhelp_echo, w->buffer);
21441 if (!NILP (help))
21443 charpos = pos;
21444 object = w->buffer;
21449 else if (BUFFERP (object)
21450 && charpos >= BEGV
21451 && charpos < ZV)
21452 help = Fget_text_property (make_number (charpos), Qhelp_echo,
21453 object);
21455 if (!NILP (help))
21457 help_echo_string = help;
21458 help_echo_window = window;
21459 help_echo_object = object;
21460 help_echo_pos = charpos;
21465 /* Look for a `pointer' property. */
21466 if (NILP (pointer))
21468 /* Check overlays first. */
21469 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
21470 pointer = Foverlay_get (overlay_vec[i], Qpointer);
21472 if (NILP (pointer))
21474 Lisp_Object object = glyph->object;
21475 int charpos = glyph->charpos;
21477 /* Try text properties. */
21478 if (STRINGP (object)
21479 && charpos >= 0
21480 && charpos < SCHARS (object))
21482 pointer = Fget_text_property (make_number (charpos),
21483 Qpointer, object);
21484 if (NILP (pointer))
21486 /* If the string itself doesn't specify a pointer,
21487 see if the buffer text ``under'' it does. */
21488 struct glyph_row *r
21489 = MATRIX_ROW (w->current_matrix, vpos);
21490 int start = MATRIX_ROW_START_CHARPOS (r);
21491 int pos = string_buffer_position (w, object, start);
21492 if (pos > 0)
21493 pointer = Fget_char_property (make_number (pos),
21494 Qpointer, w->buffer);
21497 else if (BUFFERP (object)
21498 && charpos >= BEGV
21499 && charpos < ZV)
21500 pointer = Fget_text_property (make_number (charpos),
21501 Qpointer, object);
21505 BEGV = obegv;
21506 ZV = ozv;
21507 current_buffer = obuf;
21510 set_cursor:
21512 define_frame_cursor1 (f, cursor, pointer);
21516 /* EXPORT for RIF:
21517 Clear any mouse-face on window W. This function is part of the
21518 redisplay interface, and is called from try_window_id and similar
21519 functions to ensure the mouse-highlight is off. */
21521 void
21522 x_clear_window_mouse_face (w)
21523 struct window *w;
21525 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
21526 Lisp_Object window;
21528 BLOCK_INPUT;
21529 XSETWINDOW (window, w);
21530 if (EQ (window, dpyinfo->mouse_face_window))
21531 clear_mouse_face (dpyinfo);
21532 UNBLOCK_INPUT;
21536 /* EXPORT:
21537 Just discard the mouse face information for frame F, if any.
21538 This is used when the size of F is changed. */
21540 void
21541 cancel_mouse_face (f)
21542 struct frame *f;
21544 Lisp_Object window;
21545 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
21547 window = dpyinfo->mouse_face_window;
21548 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
21550 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
21551 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
21552 dpyinfo->mouse_face_window = Qnil;
21557 #endif /* HAVE_WINDOW_SYSTEM */
21560 /***********************************************************************
21561 Exposure Events
21562 ***********************************************************************/
21564 #ifdef HAVE_WINDOW_SYSTEM
21566 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
21567 which intersects rectangle R. R is in window-relative coordinates. */
21569 static void
21570 expose_area (w, row, r, area)
21571 struct window *w;
21572 struct glyph_row *row;
21573 XRectangle *r;
21574 enum glyph_row_area area;
21576 struct glyph *first = row->glyphs[area];
21577 struct glyph *end = row->glyphs[area] + row->used[area];
21578 struct glyph *last;
21579 int first_x, start_x, x;
21581 if (area == TEXT_AREA && row->fill_line_p)
21582 /* If row extends face to end of line write the whole line. */
21583 draw_glyphs (w, 0, row, area,
21584 0, row->used[area],
21585 DRAW_NORMAL_TEXT, 0);
21586 else
21588 /* Set START_X to the window-relative start position for drawing glyphs of
21589 AREA. The first glyph of the text area can be partially visible.
21590 The first glyphs of other areas cannot. */
21591 start_x = window_box_left_offset (w, area);
21592 x = start_x;
21593 if (area == TEXT_AREA)
21594 x += row->x;
21596 /* Find the first glyph that must be redrawn. */
21597 while (first < end
21598 && x + first->pixel_width < r->x)
21600 x += first->pixel_width;
21601 ++first;
21604 /* Find the last one. */
21605 last = first;
21606 first_x = x;
21607 while (last < end
21608 && x < r->x + r->width)
21610 x += last->pixel_width;
21611 ++last;
21614 /* Repaint. */
21615 if (last > first)
21616 draw_glyphs (w, first_x - start_x, row, area,
21617 first - row->glyphs[area], last - row->glyphs[area],
21618 DRAW_NORMAL_TEXT, 0);
21623 /* Redraw the parts of the glyph row ROW on window W intersecting
21624 rectangle R. R is in window-relative coordinates. Value is
21625 non-zero if mouse-face was overwritten. */
21627 static int
21628 expose_line (w, row, r)
21629 struct window *w;
21630 struct glyph_row *row;
21631 XRectangle *r;
21633 xassert (row->enabled_p);
21635 if (row->mode_line_p || w->pseudo_window_p)
21636 draw_glyphs (w, 0, row, TEXT_AREA,
21637 0, row->used[TEXT_AREA],
21638 DRAW_NORMAL_TEXT, 0);
21639 else
21641 if (row->used[LEFT_MARGIN_AREA])
21642 expose_area (w, row, r, LEFT_MARGIN_AREA);
21643 if (row->used[TEXT_AREA])
21644 expose_area (w, row, r, TEXT_AREA);
21645 if (row->used[RIGHT_MARGIN_AREA])
21646 expose_area (w, row, r, RIGHT_MARGIN_AREA);
21647 draw_row_fringe_bitmaps (w, row);
21650 return row->mouse_face_p;
21654 /* Redraw those parts of glyphs rows during expose event handling that
21655 overlap other rows. Redrawing of an exposed line writes over parts
21656 of lines overlapping that exposed line; this function fixes that.
21658 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
21659 row in W's current matrix that is exposed and overlaps other rows.
21660 LAST_OVERLAPPING_ROW is the last such row. */
21662 static void
21663 expose_overlaps (w, first_overlapping_row, last_overlapping_row)
21664 struct window *w;
21665 struct glyph_row *first_overlapping_row;
21666 struct glyph_row *last_overlapping_row;
21668 struct glyph_row *row;
21670 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
21671 if (row->overlapping_p)
21673 xassert (row->enabled_p && !row->mode_line_p);
21675 if (row->used[LEFT_MARGIN_AREA])
21676 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA);
21678 if (row->used[TEXT_AREA])
21679 x_fix_overlapping_area (w, row, TEXT_AREA);
21681 if (row->used[RIGHT_MARGIN_AREA])
21682 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA);
21687 /* Return non-zero if W's cursor intersects rectangle R. */
21689 static int
21690 phys_cursor_in_rect_p (w, r)
21691 struct window *w;
21692 XRectangle *r;
21694 XRectangle cr, result;
21695 struct glyph *cursor_glyph;
21697 cursor_glyph = get_phys_cursor_glyph (w);
21698 if (cursor_glyph)
21700 /* r is relative to W's box, but w->phys_cursor.x is relative
21701 to left edge of W's TEXT area. Adjust it. */
21702 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
21703 cr.y = w->phys_cursor.y;
21704 cr.width = cursor_glyph->pixel_width;
21705 cr.height = w->phys_cursor_height;
21706 /* ++KFS: W32 version used W32-specific IntersectRect here, but
21707 I assume the effect is the same -- and this is portable. */
21708 return x_intersect_rectangles (&cr, r, &result);
21710 else
21711 return 0;
21715 /* EXPORT:
21716 Draw a vertical window border to the right of window W if W doesn't
21717 have vertical scroll bars. */
21719 void
21720 x_draw_vertical_border (w)
21721 struct window *w;
21723 /* We could do better, if we knew what type of scroll-bar the adjacent
21724 windows (on either side) have... But we don't :-(
21725 However, I think this works ok. ++KFS 2003-04-25 */
21727 /* Redraw borders between horizontally adjacent windows. Don't
21728 do it for frames with vertical scroll bars because either the
21729 right scroll bar of a window, or the left scroll bar of its
21730 neighbor will suffice as a border. */
21731 if (FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (w->frame)))
21732 return;
21734 if (!WINDOW_RIGHTMOST_P (w)
21735 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
21737 int x0, x1, y0, y1;
21739 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
21740 y1 -= 1;
21742 rif->draw_vertical_window_border (w, x1, y0, y1);
21744 else if (!WINDOW_LEFTMOST_P (w)
21745 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
21747 int x0, x1, y0, y1;
21749 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
21750 y1 -= 1;
21752 rif->draw_vertical_window_border (w, x0, y0, y1);
21757 /* Redraw the part of window W intersection rectangle FR. Pixel
21758 coordinates in FR are frame-relative. Call this function with
21759 input blocked. Value is non-zero if the exposure overwrites
21760 mouse-face. */
21762 static int
21763 expose_window (w, fr)
21764 struct window *w;
21765 XRectangle *fr;
21767 struct frame *f = XFRAME (w->frame);
21768 XRectangle wr, r;
21769 int mouse_face_overwritten_p = 0;
21771 /* If window is not yet fully initialized, do nothing. This can
21772 happen when toolkit scroll bars are used and a window is split.
21773 Reconfiguring the scroll bar will generate an expose for a newly
21774 created window. */
21775 if (w->current_matrix == NULL)
21776 return 0;
21778 /* When we're currently updating the window, display and current
21779 matrix usually don't agree. Arrange for a thorough display
21780 later. */
21781 if (w == updated_window)
21783 SET_FRAME_GARBAGED (f);
21784 return 0;
21787 /* Frame-relative pixel rectangle of W. */
21788 wr.x = WINDOW_LEFT_EDGE_X (w);
21789 wr.y = WINDOW_TOP_EDGE_Y (w);
21790 wr.width = WINDOW_TOTAL_WIDTH (w);
21791 wr.height = WINDOW_TOTAL_HEIGHT (w);
21793 if (x_intersect_rectangles (fr, &wr, &r))
21795 int yb = window_text_bottom_y (w);
21796 struct glyph_row *row;
21797 int cursor_cleared_p;
21798 struct glyph_row *first_overlapping_row, *last_overlapping_row;
21800 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
21801 r.x, r.y, r.width, r.height));
21803 /* Convert to window coordinates. */
21804 r.x -= WINDOW_LEFT_EDGE_X (w);
21805 r.y -= WINDOW_TOP_EDGE_Y (w);
21807 /* Turn off the cursor. */
21808 if (!w->pseudo_window_p
21809 && phys_cursor_in_rect_p (w, &r))
21811 x_clear_cursor (w);
21812 cursor_cleared_p = 1;
21814 else
21815 cursor_cleared_p = 0;
21817 /* Update lines intersecting rectangle R. */
21818 first_overlapping_row = last_overlapping_row = NULL;
21819 for (row = w->current_matrix->rows;
21820 row->enabled_p;
21821 ++row)
21823 int y0 = row->y;
21824 int y1 = MATRIX_ROW_BOTTOM_Y (row);
21826 if ((y0 >= r.y && y0 < r.y + r.height)
21827 || (y1 > r.y && y1 < r.y + r.height)
21828 || (r.y >= y0 && r.y < y1)
21829 || (r.y + r.height > y0 && r.y + r.height < y1))
21831 if (row->overlapping_p)
21833 if (first_overlapping_row == NULL)
21834 first_overlapping_row = row;
21835 last_overlapping_row = row;
21838 if (expose_line (w, row, &r))
21839 mouse_face_overwritten_p = 1;
21842 if (y1 >= yb)
21843 break;
21846 /* Display the mode line if there is one. */
21847 if (WINDOW_WANTS_MODELINE_P (w)
21848 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
21849 row->enabled_p)
21850 && row->y < r.y + r.height)
21852 if (expose_line (w, row, &r))
21853 mouse_face_overwritten_p = 1;
21856 if (!w->pseudo_window_p)
21858 /* Fix the display of overlapping rows. */
21859 if (first_overlapping_row)
21860 expose_overlaps (w, first_overlapping_row, last_overlapping_row);
21862 /* Draw border between windows. */
21863 x_draw_vertical_border (w);
21865 /* Turn the cursor on again. */
21866 if (cursor_cleared_p)
21867 update_window_cursor (w, 1);
21871 #ifdef HAVE_CARBON
21872 /* Display scroll bar for this window. */
21873 if (!NILP (w->vertical_scroll_bar))
21875 /* ++KFS:
21876 If this doesn't work here (maybe some header files are missing),
21877 make a function in macterm.c and call it to do the job! */
21878 ControlHandle ch
21879 = SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (w->vertical_scroll_bar));
21881 Draw1Control (ch);
21883 #endif
21885 return mouse_face_overwritten_p;
21890 /* Redraw (parts) of all windows in the window tree rooted at W that
21891 intersect R. R contains frame pixel coordinates. Value is
21892 non-zero if the exposure overwrites mouse-face. */
21894 static int
21895 expose_window_tree (w, r)
21896 struct window *w;
21897 XRectangle *r;
21899 struct frame *f = XFRAME (w->frame);
21900 int mouse_face_overwritten_p = 0;
21902 while (w && !FRAME_GARBAGED_P (f))
21904 if (!NILP (w->hchild))
21905 mouse_face_overwritten_p
21906 |= expose_window_tree (XWINDOW (w->hchild), r);
21907 else if (!NILP (w->vchild))
21908 mouse_face_overwritten_p
21909 |= expose_window_tree (XWINDOW (w->vchild), r);
21910 else
21911 mouse_face_overwritten_p |= expose_window (w, r);
21913 w = NILP (w->next) ? NULL : XWINDOW (w->next);
21916 return mouse_face_overwritten_p;
21920 /* EXPORT:
21921 Redisplay an exposed area of frame F. X and Y are the upper-left
21922 corner of the exposed rectangle. W and H are width and height of
21923 the exposed area. All are pixel values. W or H zero means redraw
21924 the entire frame. */
21926 void
21927 expose_frame (f, x, y, w, h)
21928 struct frame *f;
21929 int x, y, w, h;
21931 XRectangle r;
21932 int mouse_face_overwritten_p = 0;
21934 TRACE ((stderr, "expose_frame "));
21936 /* No need to redraw if frame will be redrawn soon. */
21937 if (FRAME_GARBAGED_P (f))
21939 TRACE ((stderr, " garbaged\n"));
21940 return;
21943 #ifdef HAVE_CARBON
21944 /* MAC_TODO: this is a kludge, but if scroll bars are not activated
21945 or deactivated here, for unknown reasons, activated scroll bars
21946 are shown in deactivated frames in some instances. */
21947 if (f == FRAME_MAC_DISPLAY_INFO (f)->x_focus_frame)
21948 activate_scroll_bars (f);
21949 else
21950 deactivate_scroll_bars (f);
21951 #endif
21953 /* If basic faces haven't been realized yet, there is no point in
21954 trying to redraw anything. This can happen when we get an expose
21955 event while Emacs is starting, e.g. by moving another window. */
21956 if (FRAME_FACE_CACHE (f) == NULL
21957 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
21959 TRACE ((stderr, " no faces\n"));
21960 return;
21963 if (w == 0 || h == 0)
21965 r.x = r.y = 0;
21966 r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f);
21967 r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f);
21969 else
21971 r.x = x;
21972 r.y = y;
21973 r.width = w;
21974 r.height = h;
21977 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
21978 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
21980 if (WINDOWP (f->tool_bar_window))
21981 mouse_face_overwritten_p
21982 |= expose_window (XWINDOW (f->tool_bar_window), &r);
21984 #ifdef HAVE_X_WINDOWS
21985 #ifndef MSDOS
21986 #ifndef USE_X_TOOLKIT
21987 if (WINDOWP (f->menu_bar_window))
21988 mouse_face_overwritten_p
21989 |= expose_window (XWINDOW (f->menu_bar_window), &r);
21990 #endif /* not USE_X_TOOLKIT */
21991 #endif
21992 #endif
21994 /* Some window managers support a focus-follows-mouse style with
21995 delayed raising of frames. Imagine a partially obscured frame,
21996 and moving the mouse into partially obscured mouse-face on that
21997 frame. The visible part of the mouse-face will be highlighted,
21998 then the WM raises the obscured frame. With at least one WM, KDE
21999 2.1, Emacs is not getting any event for the raising of the frame
22000 (even tried with SubstructureRedirectMask), only Expose events.
22001 These expose events will draw text normally, i.e. not
22002 highlighted. Which means we must redo the highlight here.
22003 Subsume it under ``we love X''. --gerd 2001-08-15 */
22004 /* Included in Windows version because Windows most likely does not
22005 do the right thing if any third party tool offers
22006 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
22007 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
22009 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
22010 if (f == dpyinfo->mouse_face_mouse_frame)
22012 int x = dpyinfo->mouse_face_mouse_x;
22013 int y = dpyinfo->mouse_face_mouse_y;
22014 clear_mouse_face (dpyinfo);
22015 note_mouse_highlight (f, x, y);
22021 /* EXPORT:
22022 Determine the intersection of two rectangles R1 and R2. Return
22023 the intersection in *RESULT. Value is non-zero if RESULT is not
22024 empty. */
22027 x_intersect_rectangles (r1, r2, result)
22028 XRectangle *r1, *r2, *result;
22030 XRectangle *left, *right;
22031 XRectangle *upper, *lower;
22032 int intersection_p = 0;
22034 /* Rearrange so that R1 is the left-most rectangle. */
22035 if (r1->x < r2->x)
22036 left = r1, right = r2;
22037 else
22038 left = r2, right = r1;
22040 /* X0 of the intersection is right.x0, if this is inside R1,
22041 otherwise there is no intersection. */
22042 if (right->x <= left->x + left->width)
22044 result->x = right->x;
22046 /* The right end of the intersection is the minimum of the
22047 the right ends of left and right. */
22048 result->width = (min (left->x + left->width, right->x + right->width)
22049 - result->x);
22051 /* Same game for Y. */
22052 if (r1->y < r2->y)
22053 upper = r1, lower = r2;
22054 else
22055 upper = r2, lower = r1;
22057 /* The upper end of the intersection is lower.y0, if this is inside
22058 of upper. Otherwise, there is no intersection. */
22059 if (lower->y <= upper->y + upper->height)
22061 result->y = lower->y;
22063 /* The lower end of the intersection is the minimum of the lower
22064 ends of upper and lower. */
22065 result->height = (min (lower->y + lower->height,
22066 upper->y + upper->height)
22067 - result->y);
22068 intersection_p = 1;
22072 return intersection_p;
22075 #endif /* HAVE_WINDOW_SYSTEM */
22078 /***********************************************************************
22079 Initialization
22080 ***********************************************************************/
22082 void
22083 syms_of_xdisp ()
22085 Vwith_echo_area_save_vector = Qnil;
22086 staticpro (&Vwith_echo_area_save_vector);
22088 Vmessage_stack = Qnil;
22089 staticpro (&Vmessage_stack);
22091 Qinhibit_redisplay = intern ("inhibit-redisplay");
22092 staticpro (&Qinhibit_redisplay);
22094 message_dolog_marker1 = Fmake_marker ();
22095 staticpro (&message_dolog_marker1);
22096 message_dolog_marker2 = Fmake_marker ();
22097 staticpro (&message_dolog_marker2);
22098 message_dolog_marker3 = Fmake_marker ();
22099 staticpro (&message_dolog_marker3);
22101 #if GLYPH_DEBUG
22102 defsubr (&Sdump_frame_glyph_matrix);
22103 defsubr (&Sdump_glyph_matrix);
22104 defsubr (&Sdump_glyph_row);
22105 defsubr (&Sdump_tool_bar_row);
22106 defsubr (&Strace_redisplay);
22107 defsubr (&Strace_to_stderr);
22108 #endif
22109 #ifdef HAVE_WINDOW_SYSTEM
22110 defsubr (&Stool_bar_lines_needed);
22111 defsubr (&Slookup_image_map);
22112 #endif
22113 defsubr (&Sformat_mode_line);
22115 staticpro (&Qmenu_bar_update_hook);
22116 Qmenu_bar_update_hook = intern ("menu-bar-update-hook");
22118 staticpro (&Qoverriding_terminal_local_map);
22119 Qoverriding_terminal_local_map = intern ("overriding-terminal-local-map");
22121 staticpro (&Qoverriding_local_map);
22122 Qoverriding_local_map = intern ("overriding-local-map");
22124 staticpro (&Qwindow_scroll_functions);
22125 Qwindow_scroll_functions = intern ("window-scroll-functions");
22127 staticpro (&Qredisplay_end_trigger_functions);
22128 Qredisplay_end_trigger_functions = intern ("redisplay-end-trigger-functions");
22130 staticpro (&Qinhibit_point_motion_hooks);
22131 Qinhibit_point_motion_hooks = intern ("inhibit-point-motion-hooks");
22133 QCdata = intern (":data");
22134 staticpro (&QCdata);
22135 Qdisplay = intern ("display");
22136 staticpro (&Qdisplay);
22137 Qspace_width = intern ("space-width");
22138 staticpro (&Qspace_width);
22139 Qraise = intern ("raise");
22140 staticpro (&Qraise);
22141 Qslice = intern ("slice");
22142 staticpro (&Qslice);
22143 Qspace = intern ("space");
22144 staticpro (&Qspace);
22145 Qmargin = intern ("margin");
22146 staticpro (&Qmargin);
22147 Qpointer = intern ("pointer");
22148 staticpro (&Qpointer);
22149 Qleft_margin = intern ("left-margin");
22150 staticpro (&Qleft_margin);
22151 Qright_margin = intern ("right-margin");
22152 staticpro (&Qright_margin);
22153 Qcenter = intern ("center");
22154 staticpro (&Qcenter);
22155 Qline_height = intern ("line-height");
22156 staticpro (&Qline_height);
22157 Qtotal = intern ("total");
22158 staticpro (&Qtotal);
22159 QCalign_to = intern (":align-to");
22160 staticpro (&QCalign_to);
22161 QCrelative_width = intern (":relative-width");
22162 staticpro (&QCrelative_width);
22163 QCrelative_height = intern (":relative-height");
22164 staticpro (&QCrelative_height);
22165 QCeval = intern (":eval");
22166 staticpro (&QCeval);
22167 QCpropertize = intern (":propertize");
22168 staticpro (&QCpropertize);
22169 QCfile = intern (":file");
22170 staticpro (&QCfile);
22171 Qfontified = intern ("fontified");
22172 staticpro (&Qfontified);
22173 Qfontification_functions = intern ("fontification-functions");
22174 staticpro (&Qfontification_functions);
22175 Qtrailing_whitespace = intern ("trailing-whitespace");
22176 staticpro (&Qtrailing_whitespace);
22177 Qescape_glyph = intern ("escape-glyph");
22178 staticpro (&Qescape_glyph);
22179 Qimage = intern ("image");
22180 staticpro (&Qimage);
22181 QCmap = intern (":map");
22182 staticpro (&QCmap);
22183 QCpointer = intern (":pointer");
22184 staticpro (&QCpointer);
22185 Qrect = intern ("rect");
22186 staticpro (&Qrect);
22187 Qcircle = intern ("circle");
22188 staticpro (&Qcircle);
22189 Qpoly = intern ("poly");
22190 staticpro (&Qpoly);
22191 Qmessage_truncate_lines = intern ("message-truncate-lines");
22192 staticpro (&Qmessage_truncate_lines);
22193 Qcursor_in_non_selected_windows = intern ("cursor-in-non-selected-windows");
22194 staticpro (&Qcursor_in_non_selected_windows);
22195 Qgrow_only = intern ("grow-only");
22196 staticpro (&Qgrow_only);
22197 Qinhibit_menubar_update = intern ("inhibit-menubar-update");
22198 staticpro (&Qinhibit_menubar_update);
22199 Qinhibit_eval_during_redisplay = intern ("inhibit-eval-during-redisplay");
22200 staticpro (&Qinhibit_eval_during_redisplay);
22201 Qposition = intern ("position");
22202 staticpro (&Qposition);
22203 Qbuffer_position = intern ("buffer-position");
22204 staticpro (&Qbuffer_position);
22205 Qobject = intern ("object");
22206 staticpro (&Qobject);
22207 Qbar = intern ("bar");
22208 staticpro (&Qbar);
22209 Qhbar = intern ("hbar");
22210 staticpro (&Qhbar);
22211 Qbox = intern ("box");
22212 staticpro (&Qbox);
22213 Qhollow = intern ("hollow");
22214 staticpro (&Qhollow);
22215 Qhand = intern ("hand");
22216 staticpro (&Qhand);
22217 Qarrow = intern ("arrow");
22218 staticpro (&Qarrow);
22219 Qtext = intern ("text");
22220 staticpro (&Qtext);
22221 Qrisky_local_variable = intern ("risky-local-variable");
22222 staticpro (&Qrisky_local_variable);
22223 Qinhibit_free_realized_faces = intern ("inhibit-free-realized-faces");
22224 staticpro (&Qinhibit_free_realized_faces);
22226 list_of_error = Fcons (Fcons (intern ("error"),
22227 Fcons (intern ("void-variable"), Qnil)),
22228 Qnil);
22229 staticpro (&list_of_error);
22231 Qlast_arrow_position = intern ("last-arrow-position");
22232 staticpro (&Qlast_arrow_position);
22233 Qlast_arrow_string = intern ("last-arrow-string");
22234 staticpro (&Qlast_arrow_string);
22236 Qoverlay_arrow_string = intern ("overlay-arrow-string");
22237 staticpro (&Qoverlay_arrow_string);
22238 Qoverlay_arrow_bitmap = intern ("overlay-arrow-bitmap");
22239 staticpro (&Qoverlay_arrow_bitmap);
22241 echo_buffer[0] = echo_buffer[1] = Qnil;
22242 staticpro (&echo_buffer[0]);
22243 staticpro (&echo_buffer[1]);
22245 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
22246 staticpro (&echo_area_buffer[0]);
22247 staticpro (&echo_area_buffer[1]);
22249 Vmessages_buffer_name = build_string ("*Messages*");
22250 staticpro (&Vmessages_buffer_name);
22252 mode_line_proptrans_alist = Qnil;
22253 staticpro (&mode_line_proptrans_alist);
22255 mode_line_string_list = Qnil;
22256 staticpro (&mode_line_string_list);
22258 help_echo_string = Qnil;
22259 staticpro (&help_echo_string);
22260 help_echo_object = Qnil;
22261 staticpro (&help_echo_object);
22262 help_echo_window = Qnil;
22263 staticpro (&help_echo_window);
22264 previous_help_echo_string = Qnil;
22265 staticpro (&previous_help_echo_string);
22266 help_echo_pos = -1;
22268 #ifdef HAVE_WINDOW_SYSTEM
22269 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p,
22270 doc: /* *Non-nil means draw block cursor as wide as the glyph under it.
22271 For example, if a block cursor is over a tab, it will be drawn as
22272 wide as that tab on the display. */);
22273 x_stretch_cursor_p = 0;
22274 #endif
22276 DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace,
22277 doc: /* *Non-nil means highlight trailing whitespace.
22278 The face used for trailing whitespace is `trailing-whitespace'. */);
22279 Vshow_trailing_whitespace = Qnil;
22281 DEFVAR_LISP ("void-text-area-pointer", &Vvoid_text_area_pointer,
22282 doc: /* *The pointer shape to show in void text areas.
22283 Nil means to show the text pointer. Other options are `arrow', `text',
22284 `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
22285 Vvoid_text_area_pointer = Qarrow;
22287 DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay,
22288 doc: /* Non-nil means don't actually do any redisplay.
22289 This is used for internal purposes. */);
22290 Vinhibit_redisplay = Qnil;
22292 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string,
22293 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
22294 Vglobal_mode_string = Qnil;
22296 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position,
22297 doc: /* Marker for where to display an arrow on top of the buffer text.
22298 This must be the beginning of a line in order to work.
22299 See also `overlay-arrow-string'. */);
22300 Voverlay_arrow_position = Qnil;
22302 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string,
22303 doc: /* String to display as an arrow in non-window frames.
22304 See also `overlay-arrow-position'. */);
22305 Voverlay_arrow_string = Qnil;
22307 DEFVAR_LISP ("overlay-arrow-variable-list", &Voverlay_arrow_variable_list,
22308 doc: /* List of variables (symbols) which hold markers for overlay arrows.
22309 The symbols on this list are examined during redisplay to determine
22310 where to display overlay arrows. */);
22311 Voverlay_arrow_variable_list
22312 = Fcons (intern ("overlay-arrow-position"), Qnil);
22314 DEFVAR_INT ("scroll-step", &scroll_step,
22315 doc: /* *The number of lines to try scrolling a window by when point moves out.
22316 If that fails to bring point back on frame, point is centered instead.
22317 If this is zero, point is always centered after it moves off frame.
22318 If you want scrolling to always be a line at a time, you should set
22319 `scroll-conservatively' to a large value rather than set this to 1. */);
22321 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively,
22322 doc: /* *Scroll up to this many lines, to bring point back on screen.
22323 A value of zero means to scroll the text to center point vertically
22324 in the window. */);
22325 scroll_conservatively = 0;
22327 DEFVAR_INT ("scroll-margin", &scroll_margin,
22328 doc: /* *Number of lines of margin at the top and bottom of a window.
22329 Recenter the window whenever point gets within this many lines
22330 of the top or bottom of the window. */);
22331 scroll_margin = 0;
22333 DEFVAR_LISP ("display-pixels-per-inch", &Vdisplay_pixels_per_inch,
22334 doc: /* Pixels per inch on current display.
22335 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
22336 Vdisplay_pixels_per_inch = make_float (72.0);
22338 #if GLYPH_DEBUG
22339 DEFVAR_INT ("debug-end-pos", &debug_end_pos, doc: /* Don't ask. */);
22340 #endif
22342 DEFVAR_BOOL ("truncate-partial-width-windows",
22343 &truncate_partial_width_windows,
22344 doc: /* *Non-nil means truncate lines in all windows less than full frame wide. */);
22345 truncate_partial_width_windows = 1;
22347 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video,
22348 doc: /* nil means display the mode-line/header-line/menu-bar in the default face.
22349 Any other value means to use the appropriate face, `mode-line',
22350 `header-line', or `menu' respectively. */);
22351 mode_line_inverse_video = 1;
22353 DEFVAR_LISP ("line-number-display-limit", &Vline_number_display_limit,
22354 doc: /* *Maximum buffer size for which line number should be displayed.
22355 If the buffer is bigger than this, the line number does not appear
22356 in the mode line. A value of nil means no limit. */);
22357 Vline_number_display_limit = Qnil;
22359 DEFVAR_INT ("line-number-display-limit-width",
22360 &line_number_display_limit_width,
22361 doc: /* *Maximum line width (in characters) for line number display.
22362 If the average length of the lines near point is bigger than this, then the
22363 line number may be omitted from the mode line. */);
22364 line_number_display_limit_width = 200;
22366 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows,
22367 doc: /* *Non-nil means highlight region even in nonselected windows. */);
22368 highlight_nonselected_windows = 0;
22370 DEFVAR_BOOL ("multiple-frames", &multiple_frames,
22371 doc: /* Non-nil if more than one frame is visible on this display.
22372 Minibuffer-only frames don't count, but iconified frames do.
22373 This variable is not guaranteed to be accurate except while processing
22374 `frame-title-format' and `icon-title-format'. */);
22376 DEFVAR_LISP ("frame-title-format", &Vframe_title_format,
22377 doc: /* Template for displaying the title bar of visible frames.
22378 \(Assuming the window manager supports this feature.)
22379 This variable has the same structure as `mode-line-format' (which see),
22380 and is used only on frames for which no explicit name has been set
22381 \(see `modify-frame-parameters'). */);
22383 DEFVAR_LISP ("icon-title-format", &Vicon_title_format,
22384 doc: /* Template for displaying the title bar of an iconified frame.
22385 \(Assuming the window manager supports this feature.)
22386 This variable has the same structure as `mode-line-format' (which see),
22387 and is used only on frames for which no explicit name has been set
22388 \(see `modify-frame-parameters'). */);
22389 Vicon_title_format
22390 = Vframe_title_format
22391 = Fcons (intern ("multiple-frames"),
22392 Fcons (build_string ("%b"),
22393 Fcons (Fcons (empty_string,
22394 Fcons (intern ("invocation-name"),
22395 Fcons (build_string ("@"),
22396 Fcons (intern ("system-name"),
22397 Qnil)))),
22398 Qnil)));
22400 DEFVAR_LISP ("message-log-max", &Vmessage_log_max,
22401 doc: /* Maximum number of lines to keep in the message log buffer.
22402 If nil, disable message logging. If t, log messages but don't truncate
22403 the buffer when it becomes large. */);
22404 Vmessage_log_max = make_number (50);
22406 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions,
22407 doc: /* Functions called before redisplay, if window sizes have changed.
22408 The value should be a list of functions that take one argument.
22409 Just before redisplay, for each frame, if any of its windows have changed
22410 size since the last redisplay, or have been split or deleted,
22411 all the functions in the list are called, with the frame as argument. */);
22412 Vwindow_size_change_functions = Qnil;
22414 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions,
22415 doc: /* List of functions to call before redisplaying a window with scrolling.
22416 Each function is called with two arguments, the window
22417 and its new display-start position. Note that the value of `window-end'
22418 is not valid when these functions are called. */);
22419 Vwindow_scroll_functions = Qnil;
22421 DEFVAR_BOOL ("mouse-autoselect-window", &mouse_autoselect_window,
22422 doc: /* *Non-nil means autoselect window with mouse pointer. */);
22423 mouse_autoselect_window = 0;
22425 DEFVAR_BOOL ("auto-resize-tool-bars", &auto_resize_tool_bars_p,
22426 doc: /* *Non-nil means automatically resize tool-bars.
22427 This increases a tool-bar's height if not all tool-bar items are visible.
22428 It decreases a tool-bar's height when it would display blank lines
22429 otherwise. */);
22430 auto_resize_tool_bars_p = 1;
22432 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", &auto_raise_tool_bar_buttons_p,
22433 doc: /* *Non-nil means raise tool-bar buttons when the mouse moves over them. */);
22434 auto_raise_tool_bar_buttons_p = 1;
22436 DEFVAR_BOOL ("make-cursor-line-fully-visible", &make_cursor_line_fully_visible_p,
22437 doc: /* *Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
22438 make_cursor_line_fully_visible_p = 1;
22440 DEFVAR_LISP ("tool-bar-button-margin", &Vtool_bar_button_margin,
22441 doc: /* *Margin around tool-bar buttons in pixels.
22442 If an integer, use that for both horizontal and vertical margins.
22443 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
22444 HORZ specifying the horizontal margin, and VERT specifying the
22445 vertical margin. */);
22446 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
22448 DEFVAR_INT ("tool-bar-button-relief", &tool_bar_button_relief,
22449 doc: /* *Relief thickness of tool-bar buttons. */);
22450 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
22452 DEFVAR_LISP ("fontification-functions", &Vfontification_functions,
22453 doc: /* List of functions to call to fontify regions of text.
22454 Each function is called with one argument POS. Functions must
22455 fontify a region starting at POS in the current buffer, and give
22456 fontified regions the property `fontified'. */);
22457 Vfontification_functions = Qnil;
22458 Fmake_variable_buffer_local (Qfontification_functions);
22460 DEFVAR_BOOL ("unibyte-display-via-language-environment",
22461 &unibyte_display_via_language_environment,
22462 doc: /* *Non-nil means display unibyte text according to language environment.
22463 Specifically this means that unibyte non-ASCII characters
22464 are displayed by converting them to the equivalent multibyte characters
22465 according to the current language environment. As a result, they are
22466 displayed according to the current fontset. */);
22467 unibyte_display_via_language_environment = 0;
22469 DEFVAR_LISP ("max-mini-window-height", &Vmax_mini_window_height,
22470 doc: /* *Maximum height for resizing mini-windows.
22471 If a float, it specifies a fraction of the mini-window frame's height.
22472 If an integer, it specifies a number of lines. */);
22473 Vmax_mini_window_height = make_float (0.25);
22475 DEFVAR_LISP ("resize-mini-windows", &Vresize_mini_windows,
22476 doc: /* *How to resize mini-windows.
22477 A value of nil means don't automatically resize mini-windows.
22478 A value of t means resize them to fit the text displayed in them.
22479 A value of `grow-only', the default, means let mini-windows grow
22480 only, until their display becomes empty, at which point the windows
22481 go back to their normal size. */);
22482 Vresize_mini_windows = Qgrow_only;
22484 DEFVAR_LISP ("cursor-in-non-selected-windows",
22485 &Vcursor_in_non_selected_windows,
22486 doc: /* *Cursor type to display in non-selected windows.
22487 t means to use hollow box cursor. See `cursor-type' for other values. */);
22488 Vcursor_in_non_selected_windows = Qt;
22490 DEFVAR_LISP ("blink-cursor-alist", &Vblink_cursor_alist,
22491 doc: /* Alist specifying how to blink the cursor off.
22492 Each element has the form (ON-STATE . OFF-STATE). Whenever the
22493 `cursor-type' frame-parameter or variable equals ON-STATE,
22494 comparing using `equal', Emacs uses OFF-STATE to specify
22495 how to blink it off. */);
22496 Vblink_cursor_alist = Qnil;
22498 DEFVAR_BOOL ("auto-hscroll-mode", &automatic_hscrolling_p,
22499 doc: /* *Non-nil means scroll the display automatically to make point visible. */);
22500 automatic_hscrolling_p = 1;
22502 DEFVAR_INT ("hscroll-margin", &hscroll_margin,
22503 doc: /* *How many columns away from the window edge point is allowed to get
22504 before automatic hscrolling will horizontally scroll the window. */);
22505 hscroll_margin = 5;
22507 DEFVAR_LISP ("hscroll-step", &Vhscroll_step,
22508 doc: /* *How many columns to scroll the window when point gets too close to the edge.
22509 When point is less than `automatic-hscroll-margin' columns from the window
22510 edge, automatic hscrolling will scroll the window by the amount of columns
22511 determined by this variable. If its value is a positive integer, scroll that
22512 many columns. If it's a positive floating-point number, it specifies the
22513 fraction of the window's width to scroll. If it's nil or zero, point will be
22514 centered horizontally after the scroll. Any other value, including negative
22515 numbers, are treated as if the value were zero.
22517 Automatic hscrolling always moves point outside the scroll margin, so if
22518 point was more than scroll step columns inside the margin, the window will
22519 scroll more than the value given by the scroll step.
22521 Note that the lower bound for automatic hscrolling specified by `scroll-left'
22522 and `scroll-right' overrides this variable's effect. */);
22523 Vhscroll_step = make_number (0);
22525 DEFVAR_BOOL ("message-truncate-lines", &message_truncate_lines,
22526 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
22527 Bind this around calls to `message' to let it take effect. */);
22528 message_truncate_lines = 0;
22530 DEFVAR_LISP ("menu-bar-update-hook", &Vmenu_bar_update_hook,
22531 doc: /* Normal hook run for clicks on menu bar, before displaying a submenu.
22532 Can be used to update submenus whose contents should vary. */);
22533 Vmenu_bar_update_hook = Qnil;
22535 DEFVAR_BOOL ("inhibit-menubar-update", &inhibit_menubar_update,
22536 doc: /* Non-nil means don't update menu bars. Internal use only. */);
22537 inhibit_menubar_update = 0;
22539 DEFVAR_BOOL ("inhibit-eval-during-redisplay", &inhibit_eval_during_redisplay,
22540 doc: /* Non-nil means don't eval Lisp during redisplay. */);
22541 inhibit_eval_during_redisplay = 0;
22543 DEFVAR_BOOL ("inhibit-free-realized-faces", &inhibit_free_realized_faces,
22544 doc: /* Non-nil means don't free realized faces. Internal use only. */);
22545 inhibit_free_realized_faces = 0;
22547 #if GLYPH_DEBUG
22548 DEFVAR_BOOL ("inhibit-try-window-id", &inhibit_try_window_id,
22549 doc: /* Inhibit try_window_id display optimization. */);
22550 inhibit_try_window_id = 0;
22552 DEFVAR_BOOL ("inhibit-try-window-reusing", &inhibit_try_window_reusing,
22553 doc: /* Inhibit try_window_reusing display optimization. */);
22554 inhibit_try_window_reusing = 0;
22556 DEFVAR_BOOL ("inhibit-try-cursor-movement", &inhibit_try_cursor_movement,
22557 doc: /* Inhibit try_cursor_movement display optimization. */);
22558 inhibit_try_cursor_movement = 0;
22559 #endif /* GLYPH_DEBUG */
22563 /* Initialize this module when Emacs starts. */
22565 void
22566 init_xdisp ()
22568 Lisp_Object root_window;
22569 struct window *mini_w;
22571 current_header_line_height = current_mode_line_height = -1;
22573 CHARPOS (this_line_start_pos) = 0;
22575 mini_w = XWINDOW (minibuf_window);
22576 root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w)));
22578 if (!noninteractive)
22580 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (root_window)));
22581 int i;
22583 XWINDOW (root_window)->top_line = make_number (FRAME_TOP_MARGIN (f));
22584 set_window_height (root_window,
22585 FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f),
22587 mini_w->top_line = make_number (FRAME_LINES (f) - 1);
22588 set_window_height (minibuf_window, 1, 0);
22590 XWINDOW (root_window)->total_cols = make_number (FRAME_COLS (f));
22591 mini_w->total_cols = make_number (FRAME_COLS (f));
22593 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
22594 scratch_glyph_row.glyphs[TEXT_AREA + 1]
22595 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
22597 /* The default ellipsis glyphs `...'. */
22598 for (i = 0; i < 3; ++i)
22599 default_invis_vector[i] = make_number ('.');
22603 /* Allocate the buffer for frame titles.
22604 Also used for `format-mode-line'. */
22605 int size = 100;
22606 frame_title_buf = (char *) xmalloc (size);
22607 frame_title_buf_end = frame_title_buf + size;
22608 frame_title_ptr = NULL;
22611 help_echo_showing_p = 0;
22615 /* arch-tag: eacc864d-bb6a-4b74-894a-1a4399a1358b
22616 (do not change this comment) */